X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fmath%2Fcovariance.c;h=adad3439e056e0baad8c35b515972c89747b8ac0;hb=8ebbf609a32c5dc24043c02559749e07695ece2b;hp=61f54f50752704e7e9717378574930f3a01b4752;hpb=5f68c60b8283f6a410de20f927e9b12792ea58b3;p=pspp-builds.git diff --git a/src/math/covariance.c b/src/math/covariance.c index 61f54f50..adad3439 100644 --- a/src/math/covariance.c +++ b/src/math/covariance.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2009 Free Software Foundation, Inc. + Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -16,15 +16,18 @@ #include -#include -#include "covariance.h" -#include -#include "moments.h" +#include "math/covariance.h" + #include -#include -#include -#include -#include "categoricals.h" + +#include "data/case.h" +#include "data/variable.h" +#include "libpspp/assertion.h" +#include "libpspp/misc.h" +#include "math/categoricals.h" +#include "math/moments.h" + +#include "gl/xalloc.h" #define n_MOMENTS (MOMENT_VARIANCE + 1) @@ -68,7 +71,7 @@ struct covariance { /* The variables for which the covariance matrix is to be calculated. */ size_t n_vars; - const struct variable **vars; + const struct variable *const *vars; /* Categorical variables. */ struct categoricals *categoricals; @@ -131,7 +134,7 @@ covariance_moments (const struct covariance *cov, int m) /* Create a covariance struct. */ struct covariance * -covariance_1pass_create (size_t n_vars, const struct variable **vars, +covariance_1pass_create (size_t n_vars, const struct variable *const *vars, const struct variable *weight, enum mv_class exclude) { size_t i; @@ -170,8 +173,8 @@ covariance_1pass_create (size_t n_vars, const struct variable **vars, until then. */ struct covariance * -covariance_2pass_create (size_t n_vars, const struct variable **vars, - size_t n_catvars, const struct variable **catvars, +covariance_2pass_create (size_t n_vars, const struct variable *const *vars, + struct categoricals *cats, const struct variable *wv, enum mv_class exclude) { size_t i; @@ -197,7 +200,7 @@ covariance_2pass_create (size_t n_vars, const struct variable **vars, cov->n_cm = -1; cov->cm = NULL; - cov->categoricals = categoricals_create (catvars, n_catvars, wv, exclude); + cov->categoricals = cats; return cov; } @@ -296,7 +299,8 @@ covariance_accumulate_pass1 (struct covariance *cov, const struct ccase *c) cov->state = 1; } - categoricals_update (cov->categoricals, c); + if (cov->categoricals) + categoricals_update (cov->categoricals, c); for (i = 0 ; i < cov->dim; ++i) { @@ -342,8 +346,11 @@ covariance_accumulate_pass2 (struct covariance *cov, const struct ccase *c) assert (cov->state == 1); cov->state = 2; - cov->dim = cov->n_vars + - categoricals_total (cov->categoricals) - categoricals_get_n_variables (cov->categoricals); + cov->dim = cov->n_vars; + + if (cov->categoricals) + cov->dim += categoricals_total (cov->categoricals) + - categoricals_get_n_variables (cov->categoricals); cov->n_cm = (cov->dim * (cov->dim - 1) ) / 2; cov->cm = xcalloc (sizeof *cov->cm, cov->n_cm); @@ -355,7 +362,8 @@ covariance_accumulate_pass2 (struct covariance *cov, const struct ccase *c) cov->moments[i] = resize_matrix (cov->moments[i], cov->dim); } - categoricals_done (cov->categoricals); + if (cov->categoricals) + categoricals_done (cov->categoricals); /* Populate the moments matrices with the categorical value elements */ for (i = cov->n_vars; i < cov->dim; ++i) @@ -524,7 +532,7 @@ cm_to_gsl (struct covariance *cov) } -static const gsl_matrix * +static gsl_matrix * covariance_calculate_double_pass (struct covariance *cov) { size_t i, j; @@ -548,7 +556,7 @@ covariance_calculate_double_pass (struct covariance *cov) return cm_to_gsl (cov); } -static const gsl_matrix * +static gsl_matrix * covariance_calculate_single_pass (struct covariance *cov) { size_t i, j; @@ -593,15 +601,16 @@ 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. - Call this function only after all data have been accumulated. -*/ -const gsl_matrix * +/* Return a pointer to gsl_matrix containing the pairwise covariances. The + caller owns the returned matrix and must free it when it is no longer + needed. + + Call this function only after all data have been accumulated. */ +gsl_matrix * covariance_calculate (struct covariance *cov) { - assert ( cov->state > 0 ); + if ( cov->state <= 0 ) + return NULL; switch (cov->passes) { @@ -619,7 +628,7 @@ covariance_calculate (struct covariance *cov) /* Covariance computed without dividing by the sample size. */ -static const gsl_matrix * +static gsl_matrix * covariance_calculate_double_pass_unnormalized (struct covariance *cov) { size_t i, j; @@ -641,7 +650,7 @@ covariance_calculate_double_pass_unnormalized (struct covariance *cov) return cm_to_gsl (cov); } -static const gsl_matrix * +static gsl_matrix * covariance_calculate_single_pass_unnormalized (struct covariance *cov) { size_t i, j; @@ -673,15 +682,16 @@ covariance_calculate_single_pass_unnormalized (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. - Call this function only after all data have been accumulated. -*/ -const gsl_matrix * +/* Return a pointer to gsl_matrix containing the pairwise covariances. The + caller owns the returned matrix and must free it when it is no longer + needed. + + Call this function only after all data have been accumulated. */ +gsl_matrix * covariance_calculate_unnormalized (struct covariance *cov) { - assert ( cov->state > 0 ); + if ( cov->state <= 0 ) + return NULL; switch (cov->passes) { @@ -696,6 +706,14 @@ covariance_calculate_unnormalized (struct covariance *cov) } } +/* Function to access the categoricals used by COV + The return value is owned by the COV +*/ +const struct categoricals * +covariance_get_categoricals (const struct covariance *cov) +{ + return cov->categoricals; +} /* Destroy the COV object */ @@ -713,3 +731,28 @@ covariance_destroy (struct covariance *cov) free (cov->cm); free (cov); } + +size_t +covariance_dim (const struct covariance * cov) +{ + return (cov->dim); +} + +/* + Returns an array of variables corresponding to rows of the covariance matrix. + In other words, element i of the array is the variable corresponding to + row (and column) i of the covariance matrix. + */ +void +covariance_get_var_indices (const struct covariance *cov, const struct variable **vars) +{ + int i; + for (i = 0; i < cov->n_vars; i++) + { + vars[i] = cov->vars[i]; + } + for (i = cov->n_vars; i < cov->dim; i++) + { + vars[i] = categoricals_get_variable_by_subscript (cov->categoricals, i - cov->n_vars); + } +}