+
+ if ( cmd->miss == TTS_LISTWISE )
+ {
+ for(i=0; i< cmd->n_variables ; ++i)
+ {
+ struct variable *v = cmd->v_variables[i];
+ const union value *val = case_data (c, v->fv);
+
+ if (value_is_missing(&v->miss, val) )
+ {
+ return 0;
+ }
+ }
+ }
+
+ gv = case_data (c, indep_var->fv);
+
+ for(i=0; i< cmd->n_variables ; ++i)
+ {
+ struct variable *var = cmd->v_variables[i];
+ const union value *val = case_data (c, var->fv);
+ struct hsh_table *grp_hash = group_proc_get (var)->group_hash;
+ struct group_statistics *gs;
+
+ gs = hsh_find(grp_hash, (void *) gv);
+
+ /* If the independent variable doesn't match either of the values
+ for this case then move on to the next case */
+ if ( ! gs )
+ return 0;
+
+ if ( !value_is_missing(&var->miss, val) )
+ {
+ gs->n+=weight;
+ gs->sum+=weight * val->f;
+ gs->ssq+=weight * pow2(val->f);
+ }
+ }
+
+ return 0;
+}
+
+
+static void
+group_postcalc ( struct cmd_t_test *cmd )
+{
+ int i;
+
+ for(i=0; i< cmd->n_variables ; ++i)
+ {
+ struct variable *var = cmd->v_variables[i];
+ struct hsh_table *grp_hash = group_proc_get (var)->group_hash;
+ struct hsh_iterator g;
+ struct group_statistics *gs;
+ int count=0;
+
+ for (gs = hsh_first (grp_hash,&g);
+ gs != 0;
+ gs = hsh_next(grp_hash,&g))
+ {
+ gs->mean = gs->sum / gs->n;
+
+ gs->s_std_dev= sqrt(
+ ( (gs->ssq / gs->n ) - gs->mean * gs->mean )
+ ) ;
+
+ gs->std_dev= sqrt(
+ gs->n/(gs->n-1) *
+ ( (gs->ssq / gs->n ) - gs->mean * gs->mean )
+ ) ;
+
+ gs->se_mean = gs->std_dev / sqrt(gs->n);
+ count ++;
+ }
+ assert(count == 2);
+ }
+}
+
+
+
+static void
+calculate(const struct casefile *cf, void *cmd_)
+{
+ struct ssbox stat_summary_box;
+ struct trbox test_results_box;
+
+ struct casereader *r;
+ struct ccase c;
+
+ struct cmd_t_test *cmd = (struct cmd_t_test *) cmd_;
+
+ common_precalc(cmd);
+ for(r = casefile_get_reader (cf);
+ casereader_read (r, &c) ;
+ case_destroy (&c))
+ {
+ common_calc(&c,cmd);
+ }
+ casereader_destroy (r);
+ common_postcalc(cmd);
+
+ switch(mode)
+ {
+ case T_1_SAMPLE:
+ one_sample_precalc(cmd);
+ for(r = casefile_get_reader (cf);
+ casereader_read (r, &c) ;
+ case_destroy (&c))
+ {
+ one_sample_calc(&c,cmd);
+ }
+ casereader_destroy (r);
+ one_sample_postcalc(cmd);
+
+ break;
+ case T_PAIRED:
+ paired_precalc(cmd);
+ for(r = casefile_get_reader (cf);
+ casereader_read (r, &c) ;
+ case_destroy (&c))
+ {
+ paired_calc(&c,cmd);
+ }
+ casereader_destroy (r);
+ paired_postcalc(cmd);
+
+ break;
+ case T_IND_SAMPLES:
+
+ group_precalc(cmd);
+ for(r = casefile_get_reader (cf);
+ casereader_read (r, &c) ;
+ case_destroy (&c))
+ {
+ group_calc(&c,cmd);
+ }
+ casereader_destroy (r);
+ group_postcalc(cmd);
+
+ levene(cf, indep_var, cmd->n_variables, cmd->v_variables,
+ (cmd->miss == TTS_LISTWISE)?LEV_LISTWISE:LEV_ANALYSIS ,
+ value_is_missing);
+ break;
+ }
+
+ ssbox_create(&stat_summary_box,cmd,mode);
+ ssbox_populate(&stat_summary_box,cmd);
+ ssbox_finalize(&stat_summary_box);
+
+ if ( mode == T_PAIRED)
+ pscbox();
+
+ trbox_create(&test_results_box,cmd,mode);
+ trbox_populate(&test_results_box,cmd);
+ trbox_finalize(&test_results_box);
+
+}
+
+short which_group(const struct group_statistics *g,
+ const struct group_properties *p);
+
+/* Return -1 if the id of a is less than b; +1 if greater than and
+ 0 if equal */
+static int
+compare_group_binary(const struct group_statistics *a,
+ const struct group_statistics *b,
+ const struct group_properties *p)
+{
+ short flag_a;
+ short flag_b;
+
+ if ( p->criterion == CMP_LE )
+ {
+ /* less-than-or-equal comparision is not meaningfull for
+ alpha variables, so we shouldn't ever arrive here */
+ assert(p->indep_width == 0 ) ;
+
+ flag_a = ( a->id.f < p->v.critical_value ) ;
+ flag_b = ( b->id.f < p->v.critical_value ) ;
+ }
+ else
+ {
+ flag_a = which_group(a, p);
+ flag_b = which_group(b, p);
+ }
+
+ if (flag_a < flag_b )
+ return -1;
+
+ return (flag_a > flag_b);
+}
+
+/* This is a degenerate case of a hash, since it can only return three possible
+ values. It's really a comparison, being used as a hash function */
+
+static unsigned
+hash_group_binary(const struct group_statistics *g,
+ const struct group_properties *p)
+{
+ short flag = -1;
+
+ if ( p->criterion == CMP_LE )
+ {
+ /* Not meaningfull to do a less than compare for alpha values ? */
+ assert(p->indep_width == 0 ) ;
+ flag = ( g->id.f < p->v.critical_value ) ;
+ }
+ else if ( p->criterion == CMP_EQ)
+ {
+ flag = which_group(g,p);
+ }
+ else
+ assert(0);
+
+ return flag;
+}
+
+/* return 0 if G belongs to group 0,
+ 1 if it belongs to group 1,
+ 2 if it belongs to neither group */
+short
+which_group(const struct group_statistics *g,
+ const struct group_properties *p)
+{
+
+ if ( 0 == compare_values (&g->id, &p->v.g_value[0], p->indep_width))
+ return 0;
+
+ if ( 0 == compare_values (&g->id, &p->v.g_value[1], p->indep_width))
+ return 1;
+
+ return 2;