+/*
+ Covariance computed without dividing by the sample size.
+ */
+static gsl_matrix *
+covariance_calculate_double_pass_unnormalized (struct covariance *cov)
+{
+ size_t i, j;
+ for (i = 0 ; i < cov->dim; ++i)
+ {
+ for (j = 0 ; j < cov->dim; ++j)
+ {
+ int idx;
+ double *x = gsl_matrix_ptr (cov->moments[MOMENT_VARIANCE], i, j);
+
+ idx = cm_idx (cov, i, j);
+ if ( idx >= 0)
+ {
+ x = &cov->cm [idx];
+ }
+ }
+ }
+
+ return cm_to_gsl (cov);
+}
+
+static gsl_matrix *
+covariance_calculate_single_pass_unnormalized (struct covariance *cov)
+{
+ size_t i, j;
+
+ for (i = 0 ; i < cov->dim; ++i)
+ {
+ for (j = 0 ; j < cov->dim; ++j)
+ {
+ double *x = gsl_matrix_ptr (cov->moments[MOMENT_VARIANCE], i, j);
+ *x -= pow2 (gsl_matrix_get (cov->moments[MOMENT_MEAN], i, j))
+ / gsl_matrix_get (cov->moments[MOMENT_NONE], i, j);
+ }
+ }
+ for ( j = 0 ; j < cov->dim - 1; ++j)
+ {
+ for (i = j + 1 ; i < cov->dim; ++i)
+ {
+ double *x = &cov->cm [cm_idx (cov, i, j)];
+
+ *x -=
+ gsl_matrix_get (cov->moments[MOMENT_MEAN], i, j)
+ *
+ gsl_matrix_get (cov->moments[MOMENT_MEAN], j, i)
+ / gsl_matrix_get (cov->moments[MOMENT_NONE], i, j);
+ }
+ }
+
+ return cm_to_gsl (cov);
+}
+