X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=src%2Flanguage%2Fstats%2Fcorrelations.c;h=acb12fb3228f86c1938bc43724d044021ee32119;hb=ea5c4e8eb004d6414d03b65bd3407cc7ad3e2dfd;hp=ad90ef409051f47d12d8fcc2e48f5280fadf75aa;hpb=cb586666724d5fcbdb658ce471b85484f0a7babe;p=pspp diff --git a/src/language/stats/correlations.c b/src/language/stats/correlations.c index ad90ef4090..acb12fb322 100644 --- a/src/language/stats/correlations.c +++ b/src/language/stats/correlations.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,51 +16,36 @@ #include -#include -#include -#include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - #include -#include "xalloc.h" -#include "minmax.h" -#include -#include + +#include "data/casegrouper.h" +#include "data/casereader.h" +#include "data/dataset.h" +#include "data/dictionary.h" +#include "data/format.h" +#include "data/variable.h" +#include "language/command.h" +#include "language/dictionary/split-file.h" +#include "language/lexer/lexer.h" +#include "language/lexer/variable-parser.h" +#include "libpspp/assertion.h" +#include "libpspp/message.h" +#include "libpspp/misc.h" +#include "math/correlation.h" +#include "math/covariance.h" +#include "math/moments.h" +#include "output/tab.h" + +#include "gl/xalloc.h" +#include "gl/minmax.h" #include "gettext.h" #define _(msgid) gettext (msgid) #define N_(msgid) msgid -static double -significance_of_correlation (double rho, double w) -{ - double t = w - 2; - t /= 1 - MIN (1, pow2 (rho)); - t = sqrt (t); - t *= rho; - - if (t > 0) - return gsl_cdf_tdist_Q (t, w - 2); - else - return gsl_cdf_tdist_P (t, w - 2); -} - - struct corr { size_t n_vars_total; @@ -110,7 +95,6 @@ output_descriptives (const struct corr *corr, const gsl_matrix *means, struct tab_table *t = tab_create (nc, nr); tab_title (t, _("Descriptive Statistics")); - tab_dim (t, tab_natural_dimensions, NULL, NULL); tab_headers (t, heading_columns, 0, heading_rows, 0); @@ -205,7 +189,6 @@ output_correlation (const struct corr *corr, const struct corr_opts *opts, t = tab_create (nc, nr); tab_title (t, _("Correlations")); - tab_dim (t, tab_natural_dimensions, NULL, NULL); tab_headers (t, heading_columns, 0, heading_rows, 0); @@ -224,8 +207,10 @@ output_correlation (const struct corr *corr, const struct corr_opts *opts, nc - 1, nr - 1); tab_vline (t, TAL_2, heading_columns, 0, nr - 1); + tab_vline (t, TAL_1, 1, heading_rows, nr - 1); + /* Row Headers */ for (r = 0 ; r < corr->n_vars1 ; ++r) { tab_text (t, 0, 1 + r * rows_per_variable, TAB_LEFT | TAT_TITLE, @@ -247,9 +232,11 @@ output_correlation (const struct corr *corr, const struct corr_opts *opts, tab_hline (t, TAL_1, 0, nc - 1, r * rows_per_variable + 1); } + /* Column Headers */ for (c = 0 ; c < matrix_cols ; ++c) { - const struct variable *v = corr->n_vars_total > corr->n_vars1 ? corr->vars[corr->n_vars_total - corr->n_vars1 + c] : corr->vars[c]; + const struct variable *v = corr->n_vars_total > corr->n_vars1 ? + corr->vars[corr->n_vars1 + c] : corr->vars[c]; tab_text (t, heading_columns + c, 0, TAB_LEFT | TAT_TITLE, var_to_string (v)); } @@ -259,7 +246,9 @@ output_correlation (const struct corr *corr, const struct corr_opts *opts, for (c = 0 ; c < matrix_cols ; ++c) { unsigned char flags = 0; - const int col_index = corr->n_vars_total - corr->n_vars1 + c; + const int col_index = corr->n_vars_total > corr->n_vars1 ? + corr->n_vars1 + c : + c; double pearson = gsl_matrix_get (cm, r, col_index); double w = gsl_matrix_get (samples, r, col_index); double sig = opts->tails * significance_of_correlation (pearson, w); @@ -267,10 +256,10 @@ output_correlation (const struct corr *corr, const struct corr_opts *opts, if ( opts->missing_type != CORR_LISTWISE ) tab_double (t, c + heading_columns, row + rows_per_variable - 1, 0, w, wfmt); - if ( c != r) + if ( col_index != r) tab_double (t, c + heading_columns, row + 1, 0, sig, NULL); - if ( opts->sig && c != r && sig < 0.05) + if ( opts->sig && col_index != r && sig < 0.05) flags = TAB_EMPH; tab_double (t, c + heading_columns, row, flags, pearson, NULL); @@ -291,49 +280,32 @@ output_correlation (const struct corr *corr, const struct corr_opts *opts, } -static gsl_matrix * -correlation_from_covariance (const gsl_matrix *cv, const gsl_matrix *v) -{ - size_t i, j; - gsl_matrix *corr = gsl_matrix_calloc (cv->size1, cv->size2); - - for (i = 0 ; i < cv->size1; ++i) - { - for (j = 0 ; j < cv->size2; ++j) - { - double rho = gsl_matrix_get (cv, i, j); - - rho /= sqrt (gsl_matrix_get (v, i, j)) - * - sqrt (gsl_matrix_get (v, j, i)); - - gsl_matrix_set (corr, i, j, rho); - } - } - - return corr; -} - - - - static void run_corr (struct casereader *r, const struct corr_opts *opts, const struct corr *corr) { struct ccase *c; const gsl_matrix *var_matrix, *samples_matrix, *mean_matrix; - const gsl_matrix *cov_matrix; + gsl_matrix *cov_matrix; gsl_matrix *corr_matrix; - struct covariance *cov = covariance_create (corr->n_vars_total, corr->vars, - opts->wv, opts->exclude); + struct covariance *cov = covariance_2pass_create (corr->n_vars_total, corr->vars, + NULL, + opts->wv, opts->exclude); + struct casereader *rc = casereader_clone (r); for ( ; (c = casereader_read (r) ); case_unref (c)) { - covariance_accumulate (cov, c); + covariance_accumulate_pass1 (cov, c); + } + + for ( ; (c = casereader_read (rc) ); case_unref (c)) + { + covariance_accumulate_pass2 (cov, c); } cov_matrix = covariance_calculate (cov); + casereader_destroy (rc); + samples_matrix = covariance_moments (cov, MOMENT_NONE); var_matrix = covariance_moments (cov, MOMENT_VARIANCE); mean_matrix = covariance_moments (cov, MOMENT_MEAN); @@ -343,13 +315,12 @@ run_corr (struct casereader *r, const struct corr_opts *opts, const struct corr if ( opts->statistics & STATS_DESCRIPTIVES) output_descriptives (corr, mean_matrix, var_matrix, samples_matrix); - output_correlation (corr, opts, - corr_matrix, - samples_matrix, - cov_matrix); + output_correlation (corr, opts, corr_matrix, + samples_matrix, cov_matrix); covariance_destroy (cov); gsl_matrix_free (corr_matrix); + gsl_matrix_free (cov_matrix); } int @@ -376,13 +347,13 @@ cmd_correlation (struct lexer *lexer, struct dataset *ds) opts.statistics = 0; /* Parse CORRELATIONS. */ - while (lex_token (lexer) != '.') + while (lex_token (lexer) != T_ENDCMD) { - lex_match (lexer, '/'); + lex_match (lexer, T_SLASH); if (lex_match_id (lexer, "MISSING")) { - lex_match (lexer, '='); - while (lex_token (lexer) != '.' && lex_token (lexer) != '/') + lex_match (lexer, T_EQUALS); + while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH) { if (lex_match_id (lexer, "PAIRWISE")) opts.missing_type = CORR_PAIRWISE; @@ -398,13 +369,13 @@ cmd_correlation (struct lexer *lexer, struct dataset *ds) lex_error (lexer, NULL); goto error; } - lex_match (lexer, ','); + lex_match (lexer, T_COMMA); } } else if (lex_match_id (lexer, "PRINT")) { - lex_match (lexer, '='); - while (lex_token (lexer) != '.' && lex_token (lexer) != '/') + lex_match (lexer, T_EQUALS); + while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH) { if ( lex_match_id (lexer, "TWOTAIL")) opts.tails = 2; @@ -420,13 +391,13 @@ cmd_correlation (struct lexer *lexer, struct dataset *ds) goto error; } - lex_match (lexer, ','); + lex_match (lexer, T_COMMA); } } else if (lex_match_id (lexer, "STATISTICS")) { - lex_match (lexer, '='); - while (lex_token (lexer) != '.' && lex_token (lexer) != '/') + lex_match (lexer, T_EQUALS); + while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH) { if ( lex_match_id (lexer, "DESCRIPTIVES")) opts.statistics = STATS_DESCRIPTIVES; @@ -443,14 +414,14 @@ cmd_correlation (struct lexer *lexer, struct dataset *ds) goto error; } - lex_match (lexer, ','); + lex_match (lexer, T_COMMA); } } else { if (lex_match_id (lexer, "VARIABLES")) { - lex_match (lexer, '='); + lex_match (lexer, T_EQUALS); } corr = xrealloc (corr, sizeof (*corr) * (n_corrs + 1)); @@ -533,10 +504,13 @@ cmd_correlation (struct lexer *lexer, struct dataset *ds) /* Done. */ + free (corr->vars); free (corr); + return ok ? CMD_SUCCESS : CMD_CASCADING_FAILURE; error: + free (corr->vars); free (corr); return CMD_FAILURE; }