struct
{
- size_t vaa_idx;
+ size_t stack_idx;
struct ctables_cell_value
{
const struct ctables_category *category;
size_t *domains[N_CTDTS];
size_t n_domains[N_CTDTS];
- struct ctables_summary_spec_set cell_summaries;
- struct ctables_summary_spec_set total_summaries;
+ struct ctables_summary_spec_set cell_sss;
+ struct ctables_summary_spec_set total_sss;
};
-struct var_array2
+/* A stack of nestings, e.g. this represents (...) + (...) + ... + (...). */
+struct ctables_stack
{
struct var_array *vas;
size_t n;
struct ctables_table
{
struct ctables_axis *axes[PIVOT_N_AXES];
- struct var_array2 vaas[PIVOT_N_AXES];
+ struct ctables_stack stacks[PIVOT_N_AXES];
enum pivot_axis_type summary_axis;
struct hmap cells;
struct hmap domains[N_CTDTS];
{
struct ctables_var var;
bool scale;
- struct ctables_summary_spec_set cell_summaries;
- struct ctables_summary_spec_set total_summaries;
+ struct ctables_summary_spec_set cell_sss;
+ struct ctables_summary_spec_set total_sss;
};
/* Nonterminals. */
switch (axis->op)
{
case CTAO_VAR:
- ctables_summary_spec_set_uninit (&axis->cell_summaries);
- ctables_summary_spec_set_uninit (&axis->total_summaries);
+ ctables_summary_spec_set_uninit (&axis->cell_sss);
+ ctables_summary_spec_set_uninit (&axis->total_sss);
break;
case CTAO_STACK:
break;
}
- struct ctables_summary_spec_set *set = (totals ? &axis->total_summaries
- : &axis->cell_summaries);
+ struct ctables_summary_spec_set *set = (totals ? &axis->total_sss
+ : &axis->cell_sss);
if (set->n >= set->allocated)
set->summaries = x2nrealloc (set->summaries, &set->allocated,
sizeof *set->summaries);
{
if (!lex_force_match (ctx->lexer, T_LBRACK))
goto error;
+ totals = true;
}
}
else if (lex_force_match (ctx->lexer, T_RBRACK))
if (!axis)
return NULL;
else if (axis->op == CTAO_VAR)
- return !axis->scale && axis->cell_summaries.n ? axis : NULL;
+ return !axis->scale && axis->cell_sss.n ? axis : NULL;
else
{
for (size_t i = 0; i < 2; i++)
}
static void
-var_array2_uninit (struct var_array2 *vaa)
+ctables_stack_uninit (struct ctables_stack *stack)
{
- if (vaa)
+ if (stack)
{
- for (size_t i = 0; i < vaa->n; i++)
- var_array_uninit (&vaa->vas[i]);
- free (vaa->vas);
+ for (size_t i = 0; i < stack->n; i++)
+ var_array_uninit (&stack->vas[i]);
+ free (stack->vas);
}
}
-static struct var_array2
-nest_fts (struct var_array2 va0, struct var_array2 va1)
+static struct ctables_stack
+nest_fts (struct ctables_stack va0, struct ctables_stack va1)
{
if (!va0.n)
return va1;
else if (!va1.n)
return va0;
- struct var_array2 vaa = { .vas = xnmalloc (va0.n, va1.n * sizeof *vaa.vas) };
+ struct ctables_stack stack = { .vas = xnmalloc (va0.n, va1.n * sizeof *stack.vas) };
for (size_t i = 0; i < va0.n; i++)
for (size_t j = 0; j < va1.n; j++)
{
assert (n == allocate);
const struct var_array *summary_src;
- if (!a->cell_summaries.var)
+ if (!a->cell_sss.var)
summary_src = b;
- else if (!b->cell_summaries.var)
+ else if (!b->cell_sss.var)
summary_src = a;
else
NOT_REACHED ();
- vaa.vas[vaa.n++] = (struct var_array) {
+ stack.vas[stack.n++] = (struct var_array) {
.vars = vars,
.scale_idx = (a->scale_idx != SIZE_MAX ? a->scale_idx
: b->scale_idx != SIZE_MAX ? a->n + b->scale_idx
: SIZE_MAX),
.n = n,
- .cell_summaries = summary_src->cell_summaries,
- .total_summaries = summary_src->total_summaries,
+ .cell_sss = summary_src->cell_sss,
+ .total_sss = summary_src->total_sss,
};
}
- var_array2_uninit (&va0);
- var_array2_uninit (&va1);
- return vaa;
+ ctables_stack_uninit (&va0);
+ ctables_stack_uninit (&va1);
+ return stack;
}
-static struct var_array2
-stack_fts (struct var_array2 va0, struct var_array2 va1)
+static struct ctables_stack
+stack_fts (struct ctables_stack s0, struct ctables_stack s1)
{
- struct var_array2 vaa = { .vas = xnmalloc (va0.n + va1.n, sizeof *vaa.vas) };
- for (size_t i = 0; i < va0.n; i++)
- vaa.vas[vaa.n++] = va0.vas[i];
- for (size_t i = 0; i < va1.n; i++)
- vaa.vas[vaa.n++] = va1.vas[i];
- assert (vaa.n == va0.n + va1.n);
- free (va0.vas);
- free (va1.vas);
- return vaa;
+ struct ctables_stack stack = { .vas = xnmalloc (s0.n + s1.n, sizeof *stack.vas) };
+ for (size_t i = 0; i < s0.n; i++)
+ stack.vas[stack.n++] = s0.vas[i];
+ for (size_t i = 0; i < s1.n; i++)
+ stack.vas[stack.n++] = s1.vas[i];
+ assert (stack.n == s0.n + s1.n);
+ free (s0.vas);
+ free (s1.vas);
+ return stack;
}
-static struct var_array2
+static struct ctables_stack
enumerate_fts (enum pivot_axis_type axis_type, const struct ctables_axis *a)
{
if (!a)
- return (struct var_array2) { .n = 0 };
+ return (struct ctables_stack) { .n = 0 };
switch (a->op)
{
.n = 1,
.scale_idx = a->scale ? 0 : SIZE_MAX,
};
- if (a->cell_summaries.n || a->scale)
+ if (a->cell_sss.n || a->scale)
{
- va->cell_summaries = a->cell_summaries;
- va->total_summaries = a->total_summaries;
- va->cell_summaries.var = a->var.var;
- va->total_summaries.var = a->var.var;
+ va->cell_sss = a->cell_sss;
+ va->total_sss = a->total_sss;
+ va->cell_sss.var = a->var.var;
+ va->total_sss.var = a->var.var;
}
- return (struct var_array2) { .vas = va, .n = 1 };
+ return (struct ctables_stack) { .vas = va, .n = 1 };
case CTAO_STACK:
return stack_fts (enumerate_fts (axis_type, a->subs[0]),
const struct ctables_cell *a = *ap;
const struct ctables_cell *b = *bp;
- size_t a_idx = a->axes[aux->a].vaa_idx;
- size_t b_idx = b->axes[aux->a].vaa_idx;
+ size_t a_idx = a->axes[aux->a].stack_idx;
+ size_t b_idx = b->axes[aux->a].stack_idx;
if (a_idx != b_idx)
return a_idx < b_idx ? -1 : 1;
- const struct var_array *va = &aux->t->vaas[aux->a].vas[a_idx];
+ const struct var_array *va = &aux->t->stacks[aux->a].vas[a_idx];
for (size_t i = 0; i < va->n; i++)
if (i != va->scale_idx)
{
size_t hash = 0;
for (enum pivot_axis_type a = 0; a < PIVOT_N_AXES; a++)
{
- size_t idx = cell->axes[a].vaa_idx;
- const struct var_array *va = &t->vaas[a].vas[idx];
+ size_t idx = cell->axes[a].stack_idx;
+ const struct var_array *va = &t->stacks[a].vas[idx];
hash = hash_int (idx, hash);
for (size_t i = 0; i < va->n_domains[domain]; i++)
{
const struct ctables_cell *df = d->example;
for (enum pivot_axis_type a = 0; a < PIVOT_N_AXES; a++)
{
- size_t idx = cell->axes[a].vaa_idx;
- if (idx != df->axes[a].vaa_idx)
+ size_t idx = cell->axes[a].stack_idx;
+ if (idx != df->axes[a].stack_idx)
goto not_equal;
- const struct var_array *va = &t->vaas[a].vas[idx];
+ const struct var_array *va = &t->stacks[a].vas[idx];
for (size_t i = 0; i < va->n_domains[domain]; i++)
{
size_t v_idx = va->domains[domain][i];
const struct ctables_category *cats[PIVOT_N_AXES][10],
double weight)
{
- const struct var_array *ss = &t->vaas[t->summary_axis].vas[ix[t->summary_axis]];
+ const struct var_array *ss = &t->stacks[t->summary_axis].vas[ix[t->summary_axis]];
size_t hash = 0;
bool total = false;
for (enum pivot_axis_type a = 0; a < PIVOT_N_AXES; a++)
{
- const struct var_array *va = &t->vaas[a].vas[ix[a]];
+ const struct var_array *va = &t->stacks[a].vas[ix[a]];
hash = hash_int (ix[a], hash);
for (size_t i = 0; i < va->n; i++)
if (i != va->scale_idx)
{
for (enum pivot_axis_type a = 0; a < PIVOT_N_AXES; a++)
{
- const struct var_array *va = &t->vaas[a].vas[ix[a]];
- if (cell->axes[a].vaa_idx != ix[a])
+ const struct var_array *va = &t->stacks[a].vas[ix[a]];
+ if (cell->axes[a].stack_idx != ix[a])
goto not_equal;
for (size_t i = 0; i < va->n; i++)
if (i != va->scale_idx
cell->total = total;
for (enum pivot_axis_type a = 0; a < PIVOT_N_AXES; a++)
{
- const struct var_array *va = &t->vaas[a].vas[ix[a]];
- cell->axes[a].vaa_idx = ix[a];
+ const struct var_array *va = &t->stacks[a].vas[ix[a]];
+ cell->axes[a].stack_idx = ix[a];
cell->axes[a].cvs = (va->n
? xnmalloc (va->n, sizeof *cell->axes[a].cvs)
: NULL);
}
{
- const struct ctables_summary_spec_set *sss = &ss->cell_summaries;
+ const struct ctables_summary_spec_set *sss
+ = (cell->total ? &ss->total_sss : &ss->cell_sss);
cell->summaries = xmalloc (sss->n * sizeof *cell->summaries);
for (size_t i = 0; i < sss->n; i++)
ctables_summary_init (&cell->summaries[i], &sss->summaries[i]);
hmap_insert (&t->cells, &cell->node, hash);
summarize: ;
- const struct ctables_summary_spec_set *sss = &ss->cell_summaries;
+ const struct ctables_summary_spec_set *sss
+ = (cell->total ? &ss->total_sss : &ss->cell_sss);
for (size_t i = 0; i < sss->n; i++)
ctables_summary_add (&cell->summaries[i], &sss->summaries[i], sss->var,
case_data (c, sss->var), weight);
{
for (enum pivot_axis_type a = start_a; a < PIVOT_N_AXES; a++)
{
- const struct var_array *va = &t->vaas[a].vas[ix[a]];
+ const struct var_array *va = &t->stacks[a].vas[ix[a]];
for (size_t i = start_va; i < va->n; i++)
{
if (i == va->scale_idx)
const struct ctables_category *cats[PIVOT_N_AXES][10];
for (enum pivot_axis_type a = 0; a < PIVOT_N_AXES; a++)
{
- const struct var_array *va = &t->vaas[a].vas[ix[a]];
+ const struct var_array *va = &t->stacks[a].vas[ix[a]];
for (size_t i = 0; i < va->n; i++)
{
if (i == va->scale_idx)
for (enum pivot_axis_type a = 0; a < PIVOT_N_AXES; a++)
{
- const struct var_array *va = &t->vaas[a].vas[ix[a]];
+ const struct var_array *va = &t->stacks[a].vas[ix[a]];
for (size_t i = 0; i < va->n; i++)
{
if (i == va->scale_idx)
for (enum pivot_axis_type a = 0; a < PIVOT_N_AXES; a++)
if (t->axes[a])
{
- t->vaas[a] = enumerate_fts (a, t->axes[a]);
+ t->stacks[a] = enumerate_fts (a, t->axes[a]);
- for (size_t j = 0; j < t->vaas[a].n; j++)
+ for (size_t j = 0; j < t->stacks[a].n; j++)
{
- struct var_array *va = &t->vaas[a].vas[j];
+ struct var_array *va = &t->stacks[a].vas[j];
for (enum ctables_domain_type dt = 0; dt < N_CTDTS; dt++)
{
va->domains[dt] = xmalloc (va->n * sizeof *va->domains[dt]);
{
struct var_array *va = xmalloc (sizeof *va);
*va = (struct var_array) { .n = 0 };
- t->vaas[a] = (struct var_array2) { .vas = va, .n = 1 };
+ t->stacks[a] = (struct ctables_stack) { .vas = va, .n = 1 };
}
- for (size_t i = 0; i < t->vaas[t->summary_axis].n; i++)
+ for (size_t i = 0; i < t->stacks[t->summary_axis].n; i++)
{
- struct var_array *va = &t->vaas[t->summary_axis].vas[i];
- if (!va->cell_summaries.n)
+ struct var_array *va = &t->stacks[t->summary_axis].vas[i];
+ if (!va->cell_sss.n)
{
- struct ctables_summary_spec_set *css = &va->cell_summaries;
- css->summaries = xmalloc (sizeof *css->summaries);
- css->n = 1;
+ struct ctables_summary_spec_set *sss = &va->cell_sss;
+ sss->summaries = xmalloc (sizeof *sss->summaries);
+ sss->n = 1;
enum ctables_summary_function function
- = css->var ? CTSF_MEAN : CTSF_COUNT;
- struct ctables_var var = { .is_mrset = false, .var = css->var };
+ = sss->var ? CTSF_MEAN : CTSF_COUNT;
+ struct ctables_var var = { .is_mrset = false, .var = sss->var };
- *css->summaries = (struct ctables_summary_spec) {
+ *sss->summaries = (struct ctables_summary_spec) {
.function = function,
.format = ctables_summary_default_format (function, &var),
.label = ctables_summary_default_label (function, 0),
};
- if (!css->var)
- css->var = va->vars[0];
+ if (!sss->var)
+ sss->var = va->vars[0];
- va->total_summaries = va->cell_summaries;
+ va->total_sss = va->cell_sss;
}
+ else if (!va->total_sss.n)
+ va->total_sss = va->cell_sss;
}
}
{
struct ctables_table *t = ct->tables[i];
- for (size_t ir = 0; ir < t->vaas[PIVOT_AXIS_ROW].n; ir++)
- for (size_t ic = 0; ic < t->vaas[PIVOT_AXIS_COLUMN].n; ic++)
- for (size_t il = 0; il < t->vaas[PIVOT_AXIS_LAYER].n; il++)
+ for (size_t ir = 0; ir < t->stacks[PIVOT_AXIS_ROW].n; ir++)
+ for (size_t ic = 0; ic < t->stacks[PIVOT_AXIS_COLUMN].n; ic++)
+ for (size_t il = 0; il < t->stacks[PIVOT_AXIS_LAYER].n; il++)
ctables_cell_insert (t, c, ir, ic, il, weight);
}
}
sort (sorted, n, sizeof *sorted, ctables_cell_compare_3way, &aux);
size_t max_depth = 0;
- for (size_t j = 0; j < t->vaas[a].n; j++)
- if (t->vaas[a].vas[j].n > max_depth)
- max_depth = t->vaas[a].vas[j].n;
+ for (size_t j = 0; j < t->stacks[a].n; j++)
+ if (t->stacks[a].vas[j].n > max_depth)
+ max_depth = t->stacks[a].vas[j].n;
struct pivot_category **groups = xnmalloc (max_depth, sizeof *groups);
struct pivot_category *top = NULL;
for (size_t j = 0; j < n; j++)
{
struct ctables_cell *cell = sorted[j];
- const struct var_array *va = &t->vaas[a].vas[cell->axes[a].vaa_idx];
+ const struct var_array *va = &t->stacks[a].vas[cell->axes[a].stack_idx];
size_t n_common = 0;
bool new_subtable = false;
if (j > 0)
{
struct ctables_cell *prev = sorted[j - 1];
- if (prev->axes[a].vaa_idx == cell->axes[a].vaa_idx)
+ if (prev->axes[a].stack_idx == cell->axes[a].stack_idx)
{
for (; n_common < va->n; n_common++)
if (n_common != va->scale_idx
{
if (label)
parent = pivot_category_create_group__ (parent, label);
- for (size_t m = 0; m < va->cell_summaries.n; m++)
+ const struct ctables_summary_spec_set *sss
+ = cell->total ? &va->total_sss : &va->cell_sss;
+ for (size_t m = 0; m < sss->n; m++)
{
int leaf = pivot_category_create_leaf (
- parent, pivot_value_new_text (va->cell_summaries.summaries[m].label));
+ parent, pivot_value_new_text (sss->summaries[m].label));
if (m == 0)
prev_leaf = leaf;
}
if (cell->hide)
continue;
- const struct ctables_summary_spec_set *sss = &t->vaas[t->summary_axis].vas[cell->axes[t->summary_axis].vaa_idx].cell_summaries;
+ const struct var_array *va = &t->stacks[t->summary_axis].vas[cell->axes[t->summary_axis].stack_idx];
+ const struct ctables_summary_spec_set *sss = cell->total ? &va->total_sss : &va->cell_sss;
for (size_t j = 0; j < sss->n; j++)
{
size_t dindexes[3];