};
+struct layer
+{
+ size_t n_factor_vars;
+ const struct variable **factor_vars;
+};
+
/* The thing parsed after TABLES= */
struct mtable
{
size_t n_dep_vars;
const struct variable **dep_vars;
- size_t n_interactions;
+ int n_layers;
+ struct layer *layers;
+
struct interaction **interactions;
struct summary *summary;
- size_t *n_factor_vars;
- const struct variable ***factor_vars;
-
int ii;
- int n_layers;
-
struct categoricals *cats;
};
run_means (struct means *cmd, struct casereader *input,
const struct dataset *ds);
-/* Append all the variables belonging to layer and all subsequent layers
- to iact. And then append iact to the means->interaction.
- This is a recursive function.
- */
-static void
-iact_append_factor (struct mtable *means, int layer,
- const struct interaction *iact)
-{
- int v;
- const struct variable **fv;
- if (layer >= means->n_layers)
- return;
-
- fv = means->factor_vars[layer];
-
- for (v = 0; v < means->n_factor_vars[layer]; ++v)
- {
- struct interaction *nexti = interaction_clone (iact);
-
- interaction_add_variable (nexti, fv[v]);
-
- iact_append_factor (means, layer + 1, nexti);
-
- if (layer == means->n_layers - 1)
- {
- means->interactions[means->ii++] = nexti;
- }
- }
-}
static bool
parse_means_table_syntax (struct lexer *lexer, const struct means *cmd, struct mtable *table)
{
table->ii = 0;
table->n_layers = 0;
- table->factor_vars = NULL;
- table->n_factor_vars = NULL;
+ table->layers = NULL;
/* Dependent variable (s) */
- if (!parse_variables_const (lexer, cmd->dict,
+ if (!parse_variables_const_pool (lexer, cmd->pool, cmd->dict,
&table->dep_vars, &table->n_dep_vars,
PV_NO_DUPLICATE | PV_NUMERIC))
return false;
if (lex_match (lexer, T_BY))
{
table->n_layers++;
- table->factor_vars =
- xrealloc (table->factor_vars,
- sizeof (*table->factor_vars) * table->n_layers);
-
- table->n_factor_vars =
- xrealloc (table->n_factor_vars,
- sizeof (*table->n_factor_vars) * table->n_layers);
-
- if (!parse_variables_const (lexer, cmd->dict,
- &table->factor_vars[table->n_layers - 1],
- &table->n_factor_vars[table->n_layers -
- 1],
- PV_NO_DUPLICATE))
+ table->layers =
+ pool_realloc (cmd->pool, table->layers,
+ sizeof (*table->layers) * table->n_layers);
+
+ if (!parse_variables_const_pool
+ (lexer, cmd->pool, cmd->dict,
+ &table->layers[table->n_layers - 1].factor_vars,
+ &table->layers[table->n_layers - 1].n_factor_vars,
+ PV_NO_DUPLICATE))
return false;
}
}
+ /* There is always at least one layer.
+ However the final layer is the total, and not
+ normally considered by the user as a
+ layer.
+ */
+
+ table->n_layers++;
+ table->layers =
+ pool_realloc (cmd->pool, table->layers,
+ sizeof (*table->layers) * table->n_layers);
+ table->layers[table->n_layers - 1].factor_vars = NULL;
+ table->layers[table->n_layers - 1].n_factor_vars = 0;
+
return true;
}
struct means means;
bool more_tables = true;
+ means.pool = pool_create ();
+
means.exclude = MV_ANY;
means.dep_exclude = MV_ANY;
means.listwise_exclude = false;
means.dict = dataset_dict (ds);
means.n_cells = 3;
- means.cells = xcalloc (means.n_cells, sizeof (*means.cells));
+ means.cells = pool_calloc (means.pool, means.n_cells, sizeof (*means.cells));
/* The first three items (MEAN, COUNT, STDDEV) are the default */
while (more_tables)
{
means.n_tables ++;
- means.table = xrealloc (means.table, means.n_tables * sizeof (*means.table));
+ means.table = pool_realloc (means.pool, means.table, means.n_tables * sizeof (*means.table));
if (! parse_means_table_syntax (lexer, &means,
&means.table[means.n_tables - 1]))
{
int x;
means.cells =
- xrealloc (means.cells,
+ pool_realloc (means.pool, means.cells,
(means.n_cells += n_C) * sizeof (*means.cells));
for (x = 0; x < n_C; ++x)
else if (lex_match_id (lexer, "DEFAULT"))
{
means.cells =
- xrealloc (means.cells,
+ pool_realloc (means.pool, means.cells,
(means.n_cells += 3) * sizeof (*means.cells));
means.cells[means.n_cells - 2 - 1] = MEANS_MEAN;
if (lex_match_id (lexer, cell_spec[k].keyword))
{
means.cells =
- xrealloc (means.cells,
+ pool_realloc (means.pool, means.cells,
++means.n_cells * sizeof (*means.cells));
means.cells[means.n_cells - 1] = k;
}
}
- means.pool = pool_create ();
for (t = 0; t < means.n_tables; ++t)
{
struct mtable *table = &means.table[t];
- table->n_interactions = 1;
- for (l = 0; l < table->n_layers; ++l)
- {
- const int n_vars = table->n_factor_vars[l];
- table->n_interactions *= n_vars;
- }
table->interactions =
- xcalloc (table->n_interactions, sizeof (*table->interactions));
+ pool_calloc (means.pool, table->n_layers, sizeof (*table->interactions));
table->summary =
- xcalloc (table->n_dep_vars * table->n_interactions, sizeof (*table->summary));
-
-
- if (table->n_layers > 0)
- iact_append_factor (table, 0, interaction_create (NULL));
- else
- table->interactions[0] = interaction_create (NULL);
+ pool_calloc (means.pool, table->n_dep_vars * table->n_layers, sizeof (*table->summary));
+ for (l = 0; l < table->n_layers; ++l)
+ {
+ int v;
+ const struct layer *lyr = &table->layers[l];
+ const int n_vars = lyr->n_factor_vars;
+ table->interactions[l] = interaction_create (NULL);
+ for (v = 0 ; v < n_vars ; ++v)
+ {
+ interaction_add_variable (table->interactions[l],
+ lyr->factor_vars[v]);
+ }
+ }
}
-
{
struct casegrouper *grouper;
struct casereader *group;
}
+ pool_destroy (means.pool);
return CMD_SUCCESS;
error:
+ pool_destroy (means.pool);
return CMD_FAILURE;
}
bool warn;
};
+
+static void
+destroy_n (const void *aux1 UNUSED, void *aux2, void *user_data)
+{
+ struct mtable *table = aux2;
+ int v;
+ struct per_cat_data *per_cat_data = user_data;
+ struct per_var_data *pvd = per_cat_data->pvd;
+
+ for (v = 0; v < table->n_dep_vars; ++v)
+ {
+ struct per_var_data *pp = &pvd[v];
+ moments1_destroy (pp->mom);
+ }
+}
+
static void *
create_n (const void *aux1, void *aux2)
{
int i, v;
const struct means *means = aux1;
struct mtable *table = aux2;
- struct per_cat_data *per_cat_data = xmalloc (sizeof *per_cat_data);
+ struct per_cat_data *per_cat_data = pool_malloc (means->pool, sizeof *per_cat_data);
- struct per_var_data *pvd = xcalloc (table->n_dep_vars, sizeof *pvd);
+ struct per_var_data *pvd = pool_calloc (means->pool, table->n_dep_vars, sizeof *pvd);
for (v = 0; v < table->n_dep_vars; ++v)
{
enum moment maxmom = MOMENT_KURTOSIS;
struct per_var_data *pp = &pvd[v];
- pp->cell_stats = xcalloc (means->n_cells, sizeof *pp->cell_stats);
+ pp->cell_stats = pool_calloc (means->pool, means->n_cells, sizeof *pp->cell_stats);
for (i = 0; i < means->n_cells; ++i)
const double x = case_data (c, table->dep_vars[v])->f;
- for (i = 0; i < table->n_interactions; ++i)
+ for (i = 0; i < table->n_layers; ++i)
{
- if ( is_missing (means, table->dep_vars[v], table->interactions[i], c))
+ if ( is_missing (means, table->dep_vars[v],
+ table->interactions[i], c))
goto end;
}
}
}
-
static void
run_means (struct means *cmd, struct casereader *input,
const struct dataset *ds UNUSED)
{
- int i,t;
+ int t;
const struct variable *wv = dict_get_weight (cmd->dict);
struct ccase *c;
struct casereader *reader;
struct payload payload;
payload.create = create_n;
payload.update = update_n;
- payload.destroy = calculate_n;
+ payload.calculate = calculate_n;
+ payload.destroy = destroy_n;
for (t = 0; t < cmd->n_tables; ++t)
{
struct mtable *table = &cmd->table[t];
table->cats
= categoricals_create (table->interactions,
- table->n_interactions, wv, cmd->exclude);
+ table->n_layers, wv, cmd->dep_exclude, cmd->exclude);
categoricals_set_payload (table->cats, &payload, cmd, table);
}
- for (reader = casereader_clone (input);
+ for (reader = input;
(c = casereader_read (reader)) != NULL; case_unref (c))
{
for (t = 0; t < cmd->n_tables; ++t)
for (v = 0; v < table->n_dep_vars; ++v)
{
int i;
- for (i = 0; i < table->n_interactions; ++i)
+ for (i = 0; i < table->n_layers; ++i)
{
const bool missing =
is_missing (cmd, table->dep_vars[v],
if (missing)
{
something_missing = true;
- table->summary[v * table->n_interactions + i].missing++;
+ table->summary[v * table->n_layers + i].missing++;
}
else
- table->summary[v * table->n_interactions + i].non_missing++;
+ table->summary[v * table->n_layers + i].non_missing++;
}
}
if ( something_missing && cmd->listwise_exclude)
for (t = 0; t < cmd->n_tables; ++t)
{
+ int i;
const struct mtable *table = &cmd->table[t];
output_case_processing_summary (table);
- for (i = 0; i < table->n_interactions; ++i)
+ for (i = 0; i < table->n_layers; ++i)
{
output_report (cmd, i, table);
}
-
categoricals_destroy (table->cats);
}
+
}
+
static void
output_case_processing_summary (const struct mtable *table)
{
const int heading_rows = 3;
struct tab_table *t;
- const int nr = heading_rows + table->n_interactions * table->n_dep_vars;
+ const int nr = heading_rows + table->n_layers * table->n_dep_vars;
const int nc = 7;
t = tab_create (nc, nr);
{
const struct variable *var = table->dep_vars[v];
const char *dv_name = var_to_string (var);
- for (i = 0; i < table->n_interactions; ++i)
+ for (i = 0; i < table->n_layers; ++i)
{
- const int row = v * table->n_interactions + i;
+ const int row = v * table->n_layers + i;
const struct interaction *iact = table->interactions[i];
casenumber n_total;
}
-
static void
output_report (const struct means *cmd, int iact_idx,
const struct mtable *table)
tab_box (t, TAL_2, TAL_2, -1, TAL_1, 0, 0, nc - 1, nr - 1);
tab_hline (t, TAL_2, 0, nc - 1, heading_rows);
- tab_vline (t, TAL_2, iact->n_vars, 0, nr - 1);
+ tab_vline (t, TAL_2, heading_columns, 0, nr - 1);
for (i = 0; i < iact->n_vars; ++i)
{
tab_text (t, 0,
heading_rows + dv * n_cats,
TAB_RIGHT | TAT_TITLE,
- var_get_name (table->dep_vars[dv])
+ var_to_string (table->dep_vars[dv])
);
if ( dv > 0)