X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fstats%2Fregression.c;h=6fa114338eb344daca89cd15bf0a1041491548ef;hb=6b6718a372daeaa66d69e126f9ee4a9bf46bf059;hp=a200cdaadc307dc0038542b548f2208573102f60;hpb=45bf7997c965658221cc7132e09bd18a04486e79;p=pspp diff --git a/src/language/stats/regression.c b/src/language/stats/regression.c index a200cdaadc..6fa114338e 100644 --- a/src/language/stats/regression.c +++ b/src/language/stats/regression.c @@ -60,7 +60,7 @@ #define STATS_OUTS 8 #define STATS_CI 16 #define STATS_BCOV 32 -#define STATS_COLLIN 64 +#define STATS_TOL 64 #define STATS_DEFAULT (STATS_R | STATS_COEFF | STATS_ANOVA | STATS_OUTS) @@ -309,9 +309,9 @@ cmd_regression (struct lexer *lexer, struct dataset *ds) { statistics |= STATS_BCOV; } - else if (lex_match_id (lexer, "COLLIN")) + else if (lex_match_id (lexer, "TOL")) { - statistics |= STATS_COLLIN; + statistics |= STATS_TOL; } else if (lex_match_id (lexer, "CI")) { @@ -649,22 +649,22 @@ fill_covariance (gsl_matrix * cov, struct covariance *all_cov, +struct model_container +{ + struct linreg **models; +}; + /* STATISTICS subcommand output functions. */ static void reg_stats_r (const struct linreg *, const struct variable *); -static void reg_stats_coeff (const struct regression *, - const struct linreg *, const struct linreg *, - const gsl_matrix *, const struct variable *); +static void reg_stats_coeff (const struct regression *, const struct linreg *, + const struct model_container *, const gsl_matrix *, + const struct variable *); static void reg_stats_anova (const struct linreg *, const struct variable *); static void reg_stats_bcov (const struct linreg *, const struct variable *); -struct model_container -{ - struct linreg **models; -}; - static struct linreg ** run_regression_get_models (const struct regression *cmd, struct casereader *input, @@ -678,7 +678,7 @@ run_regression_get_models (const struct regression *cmd, struct covariance *cov; struct casereader *reader; - if (cmd->stats & STATS_COLLIN) + if (cmd->stats & STATS_TOL) { for (i = 0; i < cmd->n_vars; i++) { @@ -706,8 +706,13 @@ run_regression_get_models (const struct regression *cmd, size_t n_all_vars = get_n_all_vars (cmd); const struct variable **all_vars = xnmalloc (n_all_vars, sizeof (*all_vars)); - double *means = xnmalloc (n_all_vars, sizeof (*means)); - + /* In the (rather pointless) case where the dependent variable is + the independent variable, n_all_vars == 1. + However this would result in a buffer overflow so we must + over-allocate the space required in this malloc call. + See bug #58599 */ + double *means = xnmalloc (n_all_vars <= 1 ? 2 : n_all_vars, + sizeof (*means)); fill_all_vars (all_vars, cmd); cov = covariance_1pass_create (n_all_vars, all_vars, dict_get_weight (dataset_dict (cmd->ds)), @@ -716,8 +721,7 @@ run_regression_get_models (const struct regression *cmd, reader = casereader_clone (input); reader = casereader_create_filter_missing (reader, all_vars, n_all_vars, MV_ANY, NULL, NULL); - - { +{ struct casereader *r = casereader_clone (reader); for (; (c = casereader_read (r)) != NULL; case_unref (c)) @@ -760,12 +764,12 @@ run_regression_get_models (const struct regression *cmd, if (cmd->stats & STATS_COEFF) reg_stats_coeff (cmd, models[k], - model_container[k].models ? model_container[k].models[0] : NULL, + model_container, cov_matrix, dep_var); if (cmd->stats & STATS_BCOV) reg_stats_bcov (models[k], dep_var); - } + } } else { @@ -857,7 +861,8 @@ reg_stats_r (const struct linreg * c, const struct variable *var) { struct pivot_table *table = pivot_table_create__ ( pivot_value_new_text_format (N_("Model Summary (%s)"), - var_to_string (var))); + var_to_string (var)), + "Model Summary"); pivot_dimension_create (table, PIVOT_AXIS_COLUMN, N_("Statistics"), N_("R"), N_("R Square"), N_("Adjusted R Square"), @@ -882,13 +887,13 @@ reg_stats_r (const struct linreg * c, const struct variable *var) Table showing estimated regression coefficients. */ static void -reg_stats_coeff (const struct regression *cmd, - const struct linreg *c, const struct linreg *c_x, - const gsl_matrix *cov, const struct variable *var) +reg_stats_coeff (const struct regression *cmd, const struct linreg *c, + const struct model_container *mc, const gsl_matrix *cov, + const struct variable *var) { struct pivot_table *table = pivot_table_create__ ( - pivot_value_new_text_format (N_("Coefficients (%s)"), - var_to_string (var))); + pivot_value_new_text_format (N_("Coefficients (%s)"), var_to_string (var)), + "Coefficients"); struct pivot_dimension *statistics = pivot_dimension_create ( table, PIVOT_AXIS_COLUMN, N_("Statistics")); @@ -909,7 +914,7 @@ reg_stats_coeff (const struct regression *cmd, N_("Upper Bound")); } - if (cmd->stats & STATS_COLLIN) + if (cmd->stats & STATS_TOL) pivot_category_create_group (statistics->root, N_("Collinearity Statistics"), N_("Tolerance"), N_("VIF")); @@ -991,19 +996,14 @@ reg_stats_coeff (const struct regression *cmd, pivot_value_new_number (interval_entries[i])); } - if (cmd->stats & STATS_COLLIN) + if (cmd->stats & STATS_TOL) { - assert (c_x); - double rsq = linreg_ssreg (c_x) / linreg_sst (c_x); - - double collin_entries[] = { - 1.0 - rsq, - 1.0 / (1.0 - rsq), - }; - - for (size_t i = 0; i < sizeof collin_entries / sizeof *collin_entries; i++) - pivot_table_put2 (table, col++, var_idx, - pivot_value_new_number (collin_entries[i])); + { + struct linreg *m = mc[j].models[0]; + double rsq = linreg_ssreg (m) / linreg_sst (m); + pivot_table_put2 (table, col++, var_idx, pivot_value_new_number (1.0 - rsq)); + pivot_table_put2 (table, col++, var_idx, pivot_value_new_number (1.0 / (1.0 - rsq))); + } } } @@ -1017,7 +1017,8 @@ static void reg_stats_anova (const struct linreg * c, const struct variable *var) { struct pivot_table *table = pivot_table_create__ ( - pivot_value_new_text_format (N_("ANOVA (%s)"), var_to_string (var))); + pivot_value_new_text_format (N_("ANOVA (%s)"), var_to_string (var)), + "ANOVA"); pivot_dimension_create (table, PIVOT_AXIS_COLUMN, N_("Statistics"), N_("Sum of Squares"), PIVOT_RC_OTHER, @@ -1072,7 +1073,8 @@ reg_stats_bcov (const struct linreg * c, const struct variable *var) { struct pivot_table *table = pivot_table_create__ ( pivot_value_new_text_format (N_("Coefficient Correlations (%s)"), - var_to_string (var))); + var_to_string (var)), + "Coefficient Correlations"); for (size_t i = 0; i < 2; i++) {