#define STATS_OUTS 8
#define STATS_CI 16
#define STATS_BCOV 32
-#define STATS_TOL 64
+#define STATS_TOL 64
#define STATS_DEFAULT (STATS_R | STATS_COEFF | STATS_ANOVA | STATS_OUTS)
return true;
}
-static int
+static enum trns_result
save_trans_func (void *aux, struct ccase **c, casenumber x UNUSED)
{
struct save_trans_data *save_trans_data = aux;
{
if (ws->pred_idx != -1)
{
- double pred = case_data_idx (in, ws->extras * k + ws->pred_idx)->f;
- case_data_rw (*c, ws->predvars[k])->f = pred;
+ double pred = case_num_idx (in, ws->extras * k + ws->pred_idx);
+ *case_num_rw (*c, ws->predvars[k]) = pred;
}
if (ws->res_idx != -1)
{
- double resid = case_data_idx (in, ws->extras * k + ws->res_idx)->f;
- case_data_rw (*c, ws->residvars[k])->f = resid;
+ double resid = case_num_idx (in, ws->extras * k + ws->res_idx);
+ *case_num_rw (*c, ws->residvars[k]) = resid;
}
}
case_unref (in);
return TRNS_CONTINUE;
}
-
int
cmd_regression (struct lexer *lexer, struct dataset *ds)
{
memcpy (save_trans_data->ws, &workspace, sizeof (workspace));
save_trans_data->n_dep_vars = regression.n_dep_vars;
- add_transformation (ds, save_trans_func, save_trans_free, save_trans_data);
+ static const struct trns_class trns_class = {
+ .name = "REGRESSION",
+ .execute = save_trans_func,
+ .destroy = save_trans_free,
+ };
+ add_transformation (ds, &trns_class, save_trans_data);
}
\f
+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,
bool output)
{
size_t i;
- struct linreg **models = NULL;
- struct model_container *model_container = xzalloc (sizeof (*model_container) * cmd->n_vars);
+ struct model_container *model_container = XCALLOC (cmd->n_vars, struct model_container);
struct ccase *c;
struct covariance *cov;
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)),
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))
casereader_destroy (r);
}
- models = xcalloc (cmd->n_dep_vars, sizeof (*models));
+ struct linreg **models = XCALLOC (cmd->n_dep_vars, struct linreg*);
for (int k = 0; k < cmd->n_dep_vars; k++)
{
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
{
if (cmd->pred)
{
double pred = linreg_predict (models[k], vals, n_indep);
- case_data_rw_idx (outc, k * ws->extras + ws->pred_idx)->f = pred;
+ *case_num_rw_idx (outc, k * ws->extras + ws->pred_idx) = pred;
}
if (cmd->resid)
{
- double obs = case_data (c, linreg_dep_var (models[k]))->f;
+ double obs = case_num (c, linreg_dep_var (models[k]));
double res = linreg_residual (models[k], obs, vals, n_indep);
- case_data_rw_idx (outc, k * ws->extras + ws->res_idx)->f = res;
+ *case_num_rw_idx (outc, k * ws->extras + ws->res_idx) = res;
}
free (vals);
free (vars);
{
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"),
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"));
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)));
+ }
}
}
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,
{
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++)
{