def _maximization(X, posterior, force_weights=None):
n_examples, n_features = X.shape<EOL>n_clusters, n_examples = posterior.shape<EOL>concentrations = np.zeros((n_clusters,))<EOL>centers = np.zeros((n_clusters, n_features))<EOL>if force_weights is None:<EOL><INDENT>weights = np.zeros((n_clusters,))<EOL><DEDENT>for cc in range(n_clusters):<EOL><INDENT>if force_weights is None:<EOL><INDENT>weights[cc] = np.mean(posterior[cc, :])<EOL><DEDENT>else:<EOL><INDENT>weights = force_weights<EOL><DEDENT>X_scaled = X.copy()<EOL>if sp.issparse(X):<EOL><INDENT>X_scaled.data *= posterior[cc, :].repeat(np.diff(X_scaled.indptr))<EOL><DEDENT>else:<EOL><INDENT>for ee in range(n_examples):<EOL><INDENT>X_scaled[ee, :] *= posterior[cc, ee]<EOL><DEDENT><DEDENT>centers[cc, :] = X_scaled.sum(axis=<NUM_LIT:0>)<EOL>center_norm = np.linalg.norm(centers[cc, :])<EOL>if center_norm > <NUM_LIT>:<EOL><INDENT>centers[cc, :] = centers[cc, :] / center_norm<EOL><DEDENT>rbar = center_norm / (n_examples * weights[cc])<EOL>concentrations[cc] = rbar * n_features - np.power(rbar, <NUM_LIT>)<EOL>if np.abs(rbar - <NUM_LIT:1.0>) < <NUM_LIT>:<EOL><INDENT>concentrations[cc] = MAX_CONTENTRATION<EOL><DEDENT>else:<EOL><INDENT>concentrations[cc] /= <NUM_LIT:1.> - np.power(rbar, <NUM_LIT>)<EOL><DEDENT>del X_scaled<EOL><DEDENT>return centers, weights, concentrations<EOL>
Estimate new centers, weights, and concentrations from

    Parameters
    ----------
    posterior : array, [n_centers, n_examples]
        The posterior matrix from the expectation step.

    force_weights : None or array, [n_centers, ]
        If None is passed, will estimate weights.
        If an array is passed, will use instead of estimating.

    Returns
    ----------
    centers (mu) : array, [n_centers x n_features]
    weights (alpha) : array, [n_centers, ] (alpha)
    concentrations (kappa) : array, [n_centers, ]