X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fstats%2Ffactor.c;h=316b64a71e0b824d7b63710943b0b5a0fe8eb93d;hb=2a76184b55a8c229adc0b31d3436d29076de0ef8;hp=18341b8db50d470e2c4ac5d3c2128ec63f512921;hpb=1aef11b9589a534333bbecd528efe1022a4bb9bb;p=pspp diff --git a/src/language/stats/factor.c b/src/language/stats/factor.c index 18341b8db5..316b64a71e 100644 --- a/src/language/stats/factor.c +++ b/src/language/stats/factor.c @@ -45,7 +45,6 @@ #include "math/correlation.h" #include "math/covariance.h" #include "math/moments.h" -#include "output/chart-item.h" #include "output/charts/scree.h" #include "output/pivot-table.h" @@ -107,13 +106,13 @@ enum rotation_type typedef void (*rotation_coefficients) (double *x, double *y, double a, double b, double c, double d, - const gsl_matrix *loadings ); + const gsl_matrix *loadings); static void varimax_coefficients (double *x, double *y, double a, double b, double c, double d, - const gsl_matrix *loadings ) + const gsl_matrix *loadings) { *x = d - 2 * a * b / loadings->size1; *y = c - (a * a - b * b) / loadings->size1; @@ -122,7 +121,7 @@ varimax_coefficients (double *x, double *y, static void equamax_coefficients (double *x, double *y, double a, double b, double c, double d, - const gsl_matrix *loadings ) + const gsl_matrix *loadings) { *x = d - loadings->size2 * a * b / loadings->size1; *y = c - loadings->size2 * (a * a - b * b) / (2 * loadings->size1); @@ -251,7 +250,7 @@ struct idata static struct idata * idata_alloc (size_t n_vars) { - struct idata *id = xzalloc (sizeof (*id)); + struct idata *id = XZALLOC (struct idata); id->n_extractions = 0; id->msr = gsl_vector_alloc (n_vars); @@ -286,7 +285,7 @@ ssq_row_od_n (const gsl_matrix *m, int j) for (i = 0; i < m->size1; ++i) { - if (i == j ) continue; + if (i == j) continue; ss += pow2 (gsl_matrix_get (m, i, j)); } @@ -416,7 +415,7 @@ n_extracted_factors (const struct cmd_factor *factor, struct idata *idata) int i; /* If there is a cached value, then return that. */ - if ( idata->n_extractions != 0) + if (idata->n_extractions != 0) return idata->n_extractions; /* Otherwise, if the number of factors has been explicitly requested, @@ -444,7 +443,7 @@ n_extracted_factors (const struct cmd_factor *factor, struct idata *idata) /* Returns a newly allocated matrix identical to M. - It it the callers responsibility to free the returned value. + It is the callers responsibility to free the returned value. */ static gsl_matrix * matrix_dup (const gsl_matrix *m) @@ -645,7 +644,7 @@ sort_matrix_indirect (const gsl_matrix *input, gsl_permutation *perm) gsl_vector_view row = gsl_matrix_row (mat, p->data[n - 1 - i]); size_t maxindex = gsl_vector_max_index (&row.vector); - if ( maxindex > column_n ) + if (maxindex > column_n) break; /* All subsequent elements of this row, are of no interest. @@ -663,7 +662,7 @@ sort_matrix_indirect (const gsl_matrix *input, gsl_permutation *perm) gsl_permutation_free (p); gsl_matrix_free (mat); - assert ( 0 == gsl_permutation_valid (perm)); + assert (0 == gsl_permutation_valid (perm)); /* We want the biggest value to be first */ gsl_permutation_reverse (perm); @@ -720,7 +719,7 @@ initial_sv (const gsl_matrix *fm) l4s += lambda_4; l2s += lambda_sq; } - sv += ( fm->size1 * l4s - (l2s * l2s) ) / (fm->size1 * fm->size1 ); + sv += (fm->size1 * l4s - (l2s * l2s)) / (fm->size1 * fm->size1); } return sv; } @@ -805,7 +804,7 @@ rotate (const struct cmd_factor *cf, const gsl_matrix *unrot, phi = atan2 (x, y) / 4.0 ; /* Don't bother rotating if the angle is small */ - if ( fabs (sin (phi) ) <= pow (10.0, -15.0)) + if (fabs (sin (phi)) <= pow (10.0, -15.0)) continue; for (p = 0; p < normalised->size1; ++p) @@ -825,10 +824,10 @@ rotate (const struct cmd_factor *cf, const gsl_matrix *unrot, l2s += lambda_sq; } } - sv += ( normalised->size1 * l4s - (l2s * l2s) ) / (normalised->size1 * normalised->size1 ); + sv += (normalised->size1 * l4s - (l2s * l2s)) / (normalised->size1 * normalised->size1); } - if ( fabs (sv - prev_sv) <= cf->rconverge) + if (fabs (sv - prev_sv) <= cf->rconverge) break; prev_sv = sv; @@ -991,7 +990,7 @@ rotate (const struct cmd_factor *cf, const gsl_matrix *unrot, gsl_vector_set (rotated_loadings, i, ssq); - if ( sum < 0 ) + if (sum < 0) for (j = 0 ; j < result->size1; ++j) { double *lambda = gsl_matrix_ptr (result, j, i); @@ -1146,8 +1145,9 @@ cmd_factor (struct lexer *lexer, struct dataset *ds) if (! lex_force_match (lexer, T_RPAREN)) goto error; - mr = create_matrix_reader_from_case_reader (dict, matrix_reader, - &factor.vars, &factor.n_vars); + mr = matrix_reader_create (dict, matrix_reader); + factor.vars = xmemdup (mr->cvars, mr->n_cvars * sizeof *mr->cvars); + factor.n_vars = mr->n_cvars; } else { @@ -1178,6 +1178,13 @@ cmd_factor (struct lexer *lexer, struct dataset *ds) free (factor.vars); factor.vars = vars; factor.n_vars = n_vars; + + if (mr) + { + free (mr->cvars); + mr->cvars = xmemdup (vars, n_vars * sizeof *vars); + mr->n_cvars = n_vars; + } } else if (lex_match_id (lexer, "PLOT")) { @@ -1270,7 +1277,7 @@ cmd_factor (struct lexer *lexer, struct dataset *ds) { if (lex_match_id (lexer, "FACTORS")) { - if ( lex_force_match (lexer, T_LPAREN) + if (lex_force_match (lexer, T_LPAREN) && lex_force_int (lexer)) { factor.n_factors = lex_integer (lexer); @@ -1281,7 +1288,7 @@ cmd_factor (struct lexer *lexer, struct dataset *ds) } else if (lex_match_id (lexer, "MINEIGEN")) { - if ( lex_force_match (lexer, T_LPAREN) + if (lex_force_match (lexer, T_LPAREN) && lex_force_num (lexer)) { factor.min_eigen = lex_number (lexer); @@ -1292,7 +1299,7 @@ cmd_factor (struct lexer *lexer, struct dataset *ds) } else if (lex_match_id (lexer, "ECONVERGE")) { - if ( lex_force_match (lexer, T_LPAREN) + if (lex_force_match (lexer, T_LPAREN) && lex_force_num (lexer)) { factor.econverge = lex_number (lexer); @@ -1314,8 +1321,8 @@ cmd_factor (struct lexer *lexer, struct dataset *ds) } else if (lex_match_id (lexer, "ITERATE")) { - if ( lex_force_match (lexer, T_LPAREN) - && lex_force_int (lexer)) + if (lex_force_match (lexer, T_LPAREN) + && lex_force_int_range (lexer, "ITERATE", 0, INT_MAX)) { n_iterations = lex_integer (lexer); lex_get (lexer); @@ -1376,7 +1383,7 @@ cmd_factor (struct lexer *lexer, struct dataset *ds) } else if (lex_match_id (lexer, "BLANK")) { - if ( lex_force_match (lexer, T_LPAREN) + if (lex_force_match (lexer, T_LPAREN) && lex_force_num (lexer)) { factor.blank = lex_number (lexer); @@ -1512,7 +1519,7 @@ cmd_factor (struct lexer *lexer, struct dataset *ds) } } - if ( factor.rotation == ROT_NONE ) + if (factor.rotation == ROT_NONE) factor.print &= ~PRINT_ROTATION; if (factor.n_vars < 2) @@ -1528,8 +1535,7 @@ cmd_factor (struct lexer *lexer, struct dataset *ds) { struct idata *id = idata_alloc (factor.n_vars); - while (next_matrix_from_reader (&id->mm, mr, - factor.vars, factor.n_vars)) + while (matrix_reader_next (&id->mm, mr, NULL)) { do_factor_by_matrix (&factor, id); @@ -1537,25 +1543,22 @@ cmd_factor (struct lexer *lexer, struct dataset *ds) id->ai_cov = NULL; gsl_matrix_free (id->ai_cor); id->ai_cor = NULL; - gsl_matrix_free (id->mm.corr); - id->mm.corr = NULL; - gsl_matrix_free (id->mm.cov); - id->mm.cov = NULL; + + matrix_material_uninit (&id->mm); } idata_free (id); } else - if ( ! run_factor (ds, &factor)) + if (! run_factor (ds, &factor)) goto error; - - destroy_matrix_reader (mr); + matrix_reader_destroy (mr); free (factor.vars); return CMD_SUCCESS; error: - destroy_matrix_reader (mr); + matrix_reader_destroy (mr); free (factor.vars); return CMD_FAILURE; } @@ -1574,7 +1577,7 @@ run_factor (struct dataset *ds, const struct cmd_factor *factor) while (casegrouper_get_next_group (grouper, &group)) { - if ( factor->missing_type == MISS_LISTWISE ) + if (factor->missing_type == MISS_LISTWISE) group = casereader_create_filter_missing (group, factor->vars, factor->n_vars, factor->exclude, NULL, NULL); @@ -1627,7 +1630,7 @@ show_scree (const struct cmd_factor *f, const struct idata *idata) struct scree *s; const char *label ; - if ( !(f->plot & PLOT_SCREE) ) + if (!(f->plot & PLOT_SCREE)) return; @@ -1703,7 +1706,7 @@ show_factor_matrix (const struct cmd_factor *factor, const struct idata *idata, /* Initialise to the identity permutation */ gsl_permutation *perm = gsl_permutation_calloc (factor->n_vars); - if ( factor->sort) + if (factor->sort) sort_matrix_indirect (fm, perm); for (size_t i = 0 ; i < factor->n_vars; ++i) @@ -1716,7 +1719,7 @@ show_factor_matrix (const struct cmd_factor *factor, const struct idata *idata, for (size_t j = 0 ; j < n_factors; ++j) { double x = gsl_matrix_get (fm, matrix_row, j); - if ( fabs (x) < factor->blank) + if (fabs (x) < factor->blank) continue; pivot_table_put2 (table, j, var_idx, pivot_value_new_number (x)); @@ -1750,12 +1753,12 @@ show_explained_variance (const struct cmd_factor * factor, struct pivot_table *table = pivot_table_create ( N_("Total Variance Explained")); - table->omit_empty = true; - /* xgettext:no-c-format */ pivot_dimension_create (table, PIVOT_AXIS_COLUMN, N_("Statistics"), N_("Total"), PIVOT_RC_OTHER, + /* xgettext:no-c-format */ N_("% of Variance"), PIVOT_RC_PERCENT, + /* xgettext:no-c-format */ N_("Cumulative %"), PIVOT_RC_PERCENT); struct pivot_dimension *phase = pivot_dimension_create ( @@ -1942,8 +1945,11 @@ show_correlation_matrix (const struct cmd_factor *factor, const struct idata *id } if (factor->print & PRINT_DETERMINANT) - table->caption = pivot_value_new_user_text_nocopy ( - xasprintf ("%s: %.2f", _("Determinant"), idata->detR)); + { + struct pivot_value *caption = pivot_value_new_user_text_nocopy ( + xasprintf ("%s: %.2f", _("Determinant"), idata->detR)); + pivot_table_set_caption (table, caption); + } pivot_table_submit (table); } @@ -1977,7 +1983,7 @@ do_factor (const struct cmd_factor *factor, struct casereader *r) idata->cvm = covariance_1pass_create (factor->n_vars, factor->vars, factor->wv, factor->exclude, true); - for ( ; (c = casereader_read (r) ); case_unref (c)) + for (; (c = casereader_read (r)); case_unref (c)) { covariance_accumulate (idata->cvm, c); } @@ -2008,9 +2014,10 @@ do_factor (const struct cmd_factor *factor, struct casereader *r) static void do_factor_by_matrix (const struct cmd_factor *factor, struct idata *idata) { - if (!idata->mm.cov && !idata->mm.corr) + if (!idata->mm.cov && !(idata->mm.corr && idata->mm.var_matrix)) { - msg (ME, _("The dataset has no complete covariance or correlation matrix.")); + msg (ME, _("The dataset has no covariance matrix or a " + "correlation matrix along with standard deviations.")); return; } @@ -2058,7 +2065,8 @@ do_factor_by_matrix (const struct cmd_factor *factor, struct idata *idata) gsl_matrix_free (tmp); } - if ( factor->print & PRINT_UNIVARIATE) + if (factor->print & PRINT_UNIVARIATE + && idata->mm.n && idata->mm.mean_matrix && idata->mm.var_matrix) { struct pivot_table *table = pivot_table_create ( N_("Descriptive Statistics")); @@ -2092,7 +2100,7 @@ do_factor_by_matrix (const struct cmd_factor *factor, struct idata *idata) pivot_table_submit (table); } - if (factor->print & PRINT_KMO) + if (factor->print & PRINT_KMO && idata->mm.n) { struct pivot_table *table = pivot_table_create ( N_("KMO and Bartlett's Test")); @@ -2175,7 +2183,7 @@ do_factor_by_matrix (const struct cmd_factor *factor, struct idata *idata) struct factor_matrix_workspace *fmw = factor_matrix_workspace_alloc (idata->msr->size, idata->n_extractions); gsl_matrix *factor_matrix = gsl_matrix_calloc (factor->n_vars, fmw->n_factors); - if ( factor->extraction == EXTRACTION_PAF) + if (factor->extraction == EXTRACTION_PAF) { gsl_vector *diff = gsl_vector_alloc (idata->msr->size); struct smr_workspace *ws = ws_create (idata->analysis_matrix); @@ -2201,7 +2209,7 @@ do_factor_by_matrix (const struct cmd_factor *factor, struct idata *idata) gsl_vector_minmax (diff, &min, &max); - if ( fabs (min) < factor->econverge && fabs (max) < factor->econverge) + if (fabs (min) < factor->econverge && fabs (max) < factor->econverge) break; } gsl_vector_free (diff); @@ -2228,7 +2236,7 @@ do_factor_by_matrix (const struct cmd_factor *factor, struct idata *idata) show_aic (factor, idata); show_communalities (factor, initial_communalities, extracted_communalities); - if ( factor->rotation != ROT_NONE) + if (factor->rotation != ROT_NONE) { rotated_factors = gsl_matrix_calloc (factor_matrix->size1, factor_matrix->size2); rotated_loadings = gsl_vector_calloc (factor_matrix->size2); @@ -2253,14 +2261,14 @@ do_factor_by_matrix (const struct cmd_factor *factor, struct idata *idata) ? N_("Component Matrix") : N_("Factor Matrix")), factor_matrix); - if ( factor->rotation == ROT_PROMAX) + if (factor->rotation == ROT_PROMAX) { show_factor_matrix (factor, idata, N_("Pattern Matrix"), pattern_matrix); gsl_matrix_free (pattern_matrix); } - if ( factor->rotation != ROT_NONE) + if (factor->rotation != ROT_NONE) { show_factor_matrix (factor, idata, (factor->rotation == ROT_PROMAX @@ -2273,7 +2281,7 @@ do_factor_by_matrix (const struct cmd_factor *factor, struct idata *idata) gsl_matrix_free (rotated_factors); } - if ( factor->rotation == ROT_PROMAX) + if (factor->rotation == ROT_PROMAX) { show_factor_correlation (factor, fcm); gsl_matrix_free (fcm);