From 56c42d61d46aea9d13dcf55e9e2252805282570b Mon Sep 17 00:00:00 2001 From: Jason H Stover Date: Mon, 17 May 2010 16:40:38 -0400 Subject: [PATCH] New function covariance_calculate_unnormalized --- src/math/covariance.c | 83 +++++++++++++++++++++++++++++++++++++++++-- src/math/covariance.h | 1 + 2 files changed, 82 insertions(+), 2 deletions(-) diff --git a/src/math/covariance.c b/src/math/covariance.c index 1b5a2385..dc316692 100644 --- a/src/math/covariance.c +++ b/src/math/covariance.c @@ -590,7 +590,6 @@ covariance_calculate_single_pass (struct covariance *cov) } - /* Return a pointer to gsl_matrix containing the pairwise covariances. The matrix remains owned by the COV object, and must not be freed. @@ -614,6 +613,86 @@ covariance_calculate (struct covariance *cov) } } +/* + Covariance computed without dividing by the sample size. + */ +static const 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 const gsl_matrix * +covariance_calculate_single_pass_unnormalized (struct covariance *cov) +{ + size_t i, j; + size_t m; + + 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); +} + + +/* + Return a pointer to gsl_matrix containing the pairwise covariances. + The matrix remains owned by the COV object, and must not be freed. + Call this function only after all data have been accumulated. +*/ +const gsl_matrix * +covariance_calculate_unnormalized (struct covariance *cov) +{ + assert ( cov->state > 0 ); + + switch (cov->passes) + { + case 1: + return covariance_calculate_single_pass_unnormalized (cov); + break; + case 2: + return covariance_calculate_double_pass_unnormalized (cov); + break; + default: + NOT_REACHED (); + } +} @@ -622,7 +701,7 @@ void covariance_destroy (struct covariance *cov) { size_t i; - free (cov->vars); + categoricals_destroy (cov->categoricals); for (i = 0; i < n_MOMENTS; ++i) diff --git a/src/math/covariance.h b/src/math/covariance.h index 22e38e1e..3d29dcea 100644 --- a/src/math/covariance.h +++ b/src/math/covariance.h @@ -40,6 +40,7 @@ void covariance_accumulate_pass1 (struct covariance *, const struct ccase *); void covariance_accumulate_pass2 (struct covariance *, const struct ccase *); const gsl_matrix * covariance_calculate (struct covariance *cov); +const gsl_matrix * covariance_calculate_unnormalized (struct covariance *); void covariance_destroy (struct covariance *cov); -- 2.30.2