def accumulate_covariance_estimators(data, C):
    """
    Accumulate covariance estimators for each cluster with a pass through the data.

    :param ndarray data:
        NxD array - observations on the rows
    :param ndarray C:
        VxD array of cluster centroids

    :returns ndarray A:
        VxDxD array - total sum of residual outer products for each cluster
    :returns ndarray mu:
        VxD array of total sum of residuals per cluster
    :returns ndarray count:
        Vx1 array of cluster sizes
    :returns ndarray assignments:
        Nx1 array of cluster assignments
    :returns ndarray residuals:
        NxD array of data residuals
    """

    V = C.shape[0]
    N = data.shape[0]
    D = data.shape[1]

    # Essential variables
    A = np.zeros((V, D, D))                 # accumulators for covariance estimator per cluster
    mu = np.zeros((V, D))                   # residual means
    count = np.zeros(V, dtype=int)          # count of points per cluster
    assignments = np.zeros(N, dtype=int)    # point cluster assignments
    residuals = np.zeros((N, D))            # residual for data points given cluster assignment

    # Iterate data points, accumulate estimators
    for i in xrange(N):
        d = data[i]

        # Find cluster assignment and residual
        cluster = predict_cluster(d, C)
        centroid = C[cluster]
        residual = d - centroid
        assignments[i] = cluster

        # Accumulate estimators for covariance matrix for the assigned cluster
        mu[cluster] += residual
        count[cluster] += 1
        A[cluster] += np.outer(residual, residual)
        residuals[i] = residual

    return A, mu, count, assignments, residuals
dataset/ETHPy150Open yahoo/lopq/python/lopq/model.py/accumulate_covariance_estimators/original