bool resid;
bool pred;
+};
+struct regression_workspace
+{
linreg **models;
};
-
static void run_regression (const struct regression *cmd,
+ linreg **models,
struct casereader *input);
*/
struct reg_trns
{
- int n_trns; /* Number of transformations. */
- int trns_id; /* Which trns is this one? */
linreg *c; /* Linear model for this trns. */
+ const struct variable *var;
};
/*
size_t i;
size_t n_vals;
struct reg_trns *trns = t_;
- linreg *model;
+ const linreg *model;
union value *output = NULL;
const union value *tmp;
double *vals;
model = trns->c;
assert (model != NULL);
assert (model->depvar != NULL);
- assert (model->pred != NULL);
vars = linreg_get_vars (model);
n_vals = linreg_n_coeffs (model);
vals = xnmalloc (n_vals, sizeof (*vals));
*c = case_unshare (*c);
- output = case_data_rw (*c, model->pred);
+ output = case_data_rw (*c, trns->var);
for (i = 0; i < n_vals; i++)
{
size_t i;
size_t n_vals;
struct reg_trns *trns = t_;
- linreg *model;
+ const linreg *model;
union value *output = NULL;
const union value *tmp;
double *vals = NULL;
model = trns->c;
assert (model != NULL);
assert (model->depvar != NULL);
- assert (model->resid != NULL);
vars = linreg_get_vars (model);
n_vals = linreg_n_coeffs (model);
vals = xnmalloc (n_vals, sizeof (*vals));
*c = case_unshare (*c);
- output = case_data_rw (*c, model->resid);
+ output = case_data_rw (*c, trns->var);
assert (output != NULL);
for (i = 0; i < n_vals; i++)
{
struct reg_trns *t = t_;
- if (t->trns_id == t->n_trns)
- {
- linreg_unref (t->c);
- }
+ linreg_unref (t->c);
+
free (t);
return true;
}
-static void
-reg_save_var (struct dataset *ds, const char *prefix, trns_proc_func * f,
- linreg * c, struct variable **v, int n_trns)
+
+static const struct variable *
+create_aux_var (struct dataset *ds, const char *prefix)
{
+ struct variable *var;
struct dictionary *dict = dataset_dict (ds);
- static int trns_index = 1;
- char *name;
- struct variable *new_var;
- struct reg_trns *t = NULL;
+ char *name = reg_get_name (dict, prefix);
+ var = dict_create_var_assert (dict, name, 0);
+ free (name);
+ return var;
+}
- t = xmalloc (sizeof (*t));
- t->trns_id = trns_index;
- t->n_trns = n_trns;
+static void
+reg_save_var (struct dataset *ds, trns_proc_func * f,
+ const struct variable *var,
+ linreg *c)
+{
+ struct reg_trns *t = xmalloc (sizeof (*t));
t->c = c;
+ t->var = var;
+ linreg_ref (c);
- name = reg_get_name (dict, prefix);
- new_var = dict_create_var_assert (dict, name, 0);
- free (name);
-
- *v = new_var;
add_transformation (ds, f, regression_trns_free, t);
- trns_index++;
}
static void
-subcommand_save (const struct regression *cmd)
+subcommand_save (const struct regression *cmd,
+ struct regression_workspace *workspace,
+ size_t n_m)
{
- linreg **lc;
- int n_trns = 0;
-
- if (cmd->resid)
- n_trns++;
- if (cmd->pred)
- n_trns++;
-
- n_trns *= cmd->n_dep_vars;
-
- for (lc = cmd->models; lc < cmd->models + cmd->n_dep_vars; lc++)
+ int i;
+ for (i = 0; i < cmd->n_dep_vars; ++i)
{
- if (*lc != NULL)
- {
- if ((*lc)->depvar != NULL)
- {
- (*lc)->refcnt++;
- if (cmd->resid)
- {
- reg_save_var (cmd->ds, "RES", regression_trns_resid_proc,
- *lc, &(*lc)->resid, n_trns);
- }
- if (cmd->pred)
- {
- reg_save_var (cmd->ds, "PRED", regression_trns_pred_proc,
- *lc, &(*lc)->pred, n_trns);
- }
- }
- }
+ int w;
+ const struct variable *resvar = NULL;
+ const struct variable *predvar = NULL;
+
+ if (cmd->resid)
+ resvar = create_aux_var (cmd->ds, "RES");
+
+ if (cmd->pred)
+ predvar = create_aux_var (cmd->ds, "PRED");
+
+ for (w = 0 ; w < n_m; ++w)
+ {
+ linreg **models = workspace[w].models;
+ linreg *lc = models[i];
+ if (lc == NULL)
+ continue;
+
+ if (lc->depvar == NULL)
+ continue;
+
+ if (cmd->resid)
+ {
+ reg_save_var (cmd->ds, regression_trns_resid_proc, resvar, lc);
+ }
+
+ if (cmd->pred)
+ {
+ reg_save_var (cmd->ds, regression_trns_pred_proc, predvar, lc);
+ }
+ }
}
}
int
cmd_regression (struct lexer *lexer, struct dataset *ds)
{
- int k;
+ int w;
+ struct regression_workspace *workspace = NULL;
+ size_t n_workspaces = 0;
struct regression regression;
const struct dictionary *dict = dataset_dict (ds);
bool save;
}
- regression.models =
- xcalloc (regression.n_dep_vars, sizeof *regression.models);
-
save = regression.pred || regression.resid;
if (save)
{
grouper = casegrouper_create_splits (proc_open_filtering (ds, !save),
dict);
while (casegrouper_get_next_group (grouper, &group))
- run_regression (®ression, group);
+ {
+ workspace = xrealloc (workspace, sizeof (workspace) * (n_workspaces + 1));
+ workspace[n_workspaces].models = xcalloc (regression.n_dep_vars, sizeof (linreg *));
+ run_regression (®ression, workspace[n_workspaces++].models, group);
+ }
ok = casegrouper_destroy (grouper);
ok = proc_commit (ds) && ok;
}
if (save)
{
- subcommand_save (®ression);
+ subcommand_save (®ression, workspace, n_workspaces);
}
+ for (w = 0 ; w < n_workspaces; ++w)
+ {
+ int i;
+ linreg **models = workspace[w].models;
+ for (i = 0; i < regression.n_dep_vars; ++i)
+ linreg_unref (models[i]);
+ free (models);
+ }
+ free (workspace);
- for (k = 0; k < regression.n_dep_vars; k++)
- linreg_unref (regression.models[k]);
- free (regression.models);
free (regression.vars);
free (regression.dep_vars);
return CMD_SUCCESS;
error:
- if (regression.models)
+ for (w = 0 ; w < n_workspaces; ++w)
{
- for (k = 0; k < regression.n_dep_vars; k++)
- linreg_unref (regression.models[k]);
- free (regression.models);
+ int i;
+ linreg **models = workspace[w].models;
+ for (i = 0; i < regression.n_dep_vars; ++i)
+ linreg_unref (models[i]);
+ free (models);
}
+ free (workspace);
+
free (regression.vars);
free (regression.dep_vars);
return CMD_FAILURE;
static void
-run_regression (const struct regression *cmd, struct casereader *input)
+run_regression (const struct regression *cmd, linreg **models, struct casereader *input)
{
size_t i;
int n_indep = 0;
struct casereader *reader;
size_t n_all_vars;
- linreg **models = cmd->models;
-
n_all_vars = get_n_all_vars (cmd);
all_vars = xnmalloc (n_all_vars, sizeof (*all_vars));
fill_all_vars (all_vars, cmd);
else
{
msg (SE, _("No valid data found. This command was skipped."));
- linreg_unref (models[k]);
- models[k] = NULL;
}
gsl_matrix_free (this_cm);
}