+ int i=0;
+
+
+ for(i=0; i< cmd->n_variables ; ++i)
+ {
+ struct group_statistics *gs;
+ gs= &group_proc_get (cmd->v_variables[i])->ugs;
+
+ 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);
+ gs->mean_diff= gs->sum_diff / gs->n;
+ }
+}
+
+/* Per case calculations for one sample t test */
+static int
+one_sample_calc (const struct ccase *c, void *cmd_)
+{
+ int i;
+ struct cmd_t_test *cmd = (struct cmd_t_test *)cmd_;
+
+
+ double weight = dict_get_case_weight(default_dict,c,&bad_weight_warn);
+
+ /* Skip the entire case if /MISSING=LISTWISE is set */
+ 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(val,v) )
+ {
+ return 0;
+ }
+ }
+ }
+
+ for(i=0; i< cmd->n_variables ; ++i)
+ {
+ struct group_statistics *gs;
+ struct variable *v = cmd->v_variables[i];
+ const union value *val = case_data (c, v->fv);
+
+ gs= &group_proc_get (cmd->v_variables[i])->ugs;
+
+ if ( ! value_is_missing(val,v))
+ gs->sum_diff += weight * (val->f - cmd->n_testval[0]);
+ }
+
+ return 0;
+}
+
+/* Pre calculations for one sample t test */
+static void
+one_sample_precalc ( struct cmd_t_test *cmd )
+{
+ int i=0;
+
+ for(i=0; i< cmd->n_variables ; ++i)
+ {
+ struct group_statistics *gs;
+ gs= &group_proc_get (cmd->v_variables[i])->ugs;
+
+ gs->sum_diff=0;
+ }
+}
+
+/* Post calculations for one sample t test */
+static void
+one_sample_postcalc (struct cmd_t_test *cmd)
+{
+ int i=0;
+
+ for(i=0; i< cmd->n_variables ; ++i)
+ {
+ struct group_statistics *gs;
+ gs= &group_proc_get (cmd->v_variables[i])->ugs;
+
+ gs->mean_diff = gs->sum_diff / gs->n ;
+ }
+}
+
+
+
+static int
+compare_var_name (const void *a_, const void *b_, void *v_ UNUSED)
+{
+ const struct variable *a = a_;
+ const struct variable *b = b_;
+
+ return strcmp(a->name,b->name);
+}
+
+static unsigned
+hash_var_name (const void *a_, void *v_ UNUSED)
+{
+ const struct variable *a = a_;
+
+ return hsh_hash_bytes (a->name, strlen(a->name));
+}
+
+
+
+static void
+paired_precalc (struct cmd_t_test *cmd UNUSED)
+{
+ int i;
+
+ for(i=0; i < n_pairs ; ++i )
+ {
+ pairs[i].n = 0;
+ pairs[i].sum[0] = 0; pairs[i].sum[1] = 0;
+ pairs[i].ssq[0] = 0; pairs[i].ssq[1] = 0;
+ pairs[i].sum_of_prod = 0;
+ pairs[i].correlation = 0;
+ pairs[i].sum_of_diffs = 0;
+ pairs[i].ssq_diffs = 0;
+ }
+
+}
+
+
+static int
+paired_calc (const struct ccase *c, void *cmd_)
+{
+ int i;
+
+ struct cmd_t_test *cmd = (struct cmd_t_test *) cmd_;
+
+ double weight = dict_get_case_weight(default_dict,c,&bad_weight_warn);
+
+ /* Skip the entire case if /MISSING=LISTWISE is set ,
+ AND one member of a pair is missing */
+ if ( cmd->miss == TTS_LISTWISE )
+ {
+ for(i=0; i < n_pairs ; ++i )
+ {
+ struct variable *v0 = pairs[i].v[0];
+ struct variable *v1 = pairs[i].v[1];
+
+ const union value *val0 = case_data (c, v0->fv);
+ const union value *val1 = case_data (c, v1->fv);
+
+ if ( value_is_missing(val0,v0) ||
+ value_is_missing(val1,v1) )
+ {
+ return 0;
+ }
+ }
+ }
+
+ for(i=0; i < n_pairs ; ++i )
+ {
+ struct variable *v0 = pairs[i].v[0];
+ struct variable *v1 = pairs[i].v[1];
+
+ const union value *val0 = case_data (c, v0->fv);
+ const union value *val1 = case_data (c, v1->fv);
+
+ if ( ( !value_is_missing(val0,v0) && !value_is_missing(val1,v1) ) )
+ {
+ pairs[i].n += weight;
+ pairs[i].sum[0] += weight * val0->f;
+ pairs[i].sum[1] += weight * val1->f;
+
+ pairs[i].ssq[0] += weight * pow2(val0->f);
+ pairs[i].ssq[1] += weight * pow2(val1->f);
+
+ pairs[i].sum_of_prod += weight * val0->f * val1->f ;
+
+ pairs[i].sum_of_diffs += weight * ( val0->f - val1->f ) ;
+ pairs[i].ssq_diffs += weight * pow2(val0->f - val1->f);
+ }
+ }
+
+ return 0;
+}
+
+static void
+paired_postcalc (struct cmd_t_test *cmd UNUSED)
+{
+ int i;
+
+ for(i=0; i < n_pairs ; ++i )
+ {
+ int j;
+ const double n = pairs[i].n;
+
+ for (j=0; j < 2 ; ++j)
+ {
+ pairs[i].mean[j] = pairs[i].sum[j] / n ;
+ pairs[i].s_std_dev[j] = sqrt((pairs[i].ssq[j] / n -
+ pow2(pairs[i].mean[j]))
+ );
+
+ pairs[i].std_dev[j] = sqrt(n/(n-1)*(pairs[i].ssq[j] / n -
+ pow2(pairs[i].mean[j]))
+ );
+ }
+
+ pairs[i].correlation = pairs[i].sum_of_prod / pairs[i].n -
+ pairs[i].mean[0] * pairs[i].mean[1] ;
+ /* correlation now actually contains the covariance */
+
+ pairs[i].correlation /= pairs[i].std_dev[0] * pairs[i].std_dev[1];
+ pairs[i].correlation *= pairs[i].n / ( pairs[i].n - 1 );
+
+ pairs[i].mean_diff = pairs[i].sum_of_diffs / n ;
+
+ pairs[i].std_dev_diff = sqrt ( n / (n - 1) * (
+ ( pairs[i].ssq_diffs / n )
+ -
+ pow2(pairs[i].mean_diff )
+ ) );
+ }
+}
+
+static void
+group_precalc (struct cmd_t_test *cmd )
+{
+ int i;
+ int j;
+
+ for(i=0; i< cmd->n_variables ; ++i)
+ {
+ struct group_proc *ttpr = group_proc_get (cmd->v_variables[i]);
+
+ /* There's always 2 groups for a T - TEST */
+ ttpr->n_groups = 2;
+
+ gp.indep_width = indep_var->width;
+
+ ttpr->group_hash = hsh_create(2,
+ (hsh_compare_func *) compare_group_binary,
+ (hsh_hash_func *) hash_group_binary,
+ (hsh_free_func *) free_group,
+ (void *) &gp );
+
+ for (j=0 ; j < 2 ; ++j)
+ {
+
+ struct group_statistics *gs = (struct group_statistics *)
+ xmalloc (sizeof(struct group_statistics));
+
+ gs->sum = 0;
+ gs->n = 0;
+ gs->ssq = 0;
+
+ if ( gp.criterion == CMP_EQ )
+ {
+ gs->id = gp.v.g_value[j];
+ }
+ else
+ {
+ if ( j == 0 )
+ gs->id.f = gp.v.critical_value - 1.0 ;
+ else
+ gs->id.f = gp.v.critical_value + 1.0 ;
+ }
+
+ hsh_insert ( ttpr->group_hash, (void *) gs );
+
+ }
+ }
+
+}
+
+static int
+group_calc (const struct ccase *c, struct cmd_t_test *cmd)
+{
+ int i;
+
+ const union value *gv = case_data (c, indep_var->fv);
+
+ const double weight = dict_get_case_weight(default_dict,c,&bad_weight_warn);
+
+ if ( value_is_missing(gv,indep_var) )
+ {
+ return 0;
+ }
+
+ 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(val,v) )
+ {
+ 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(val,var) )
+ {
+ 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);
+
+}
+
+
+/* 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 )
+ {
+ 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 = ( a->id.f == p->v.critical_value ) ;
+ flag_b = ( b->id.f == p->v.critical_value ) ;
+ }
+
+ if ( flag_a == flag_b)
+ return 0 ;
+
+ 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)
+ {
+ if ( 0 == compare_values (&g->id, &p->v.g_value[0], p->indep_width ))
+ flag = 0 ;
+ else if ( 0 == compare_values (&g->id, &p->v.g_value[1], p->indep_width ))
+ flag = 1 ;
+ else
+ flag = 2 ;
+ }
+ else
+ assert(0);
+
+ return flag;