+
+
+/* ONEWAY ANOVA Calculations */
+
+static void postcalc ( struct cmd_oneway *cmd UNUSED );
+
+static void precalc ( struct cmd_oneway *cmd UNUSED );
+
+
+
+/* Pre calculations */
+static void
+precalc ( struct cmd_oneway *cmd UNUSED )
+{
+ size_t i=0;
+
+ for(i=0; i< n_vars ; ++i)
+ {
+ struct group_proc *gp = group_proc_get (vars[i]);
+ struct group_statistics *totals = &gp->ugs;
+
+ /* Create a hash for each of the dependent variables.
+ The hash contains a group_statistics structure,
+ and is keyed by value of the independent variable */
+
+ gp->group_hash =
+ hsh_create(4,
+ (hsh_compare_func *) compare_group,
+ (hsh_hash_func *) hash_group,
+ (hsh_free_func *) free_group,
+ (void *) indep_var->width );
+
+
+ totals->sum=0;
+ totals->n=0;
+ totals->ssq=0;
+ totals->sum_diff=0;
+ totals->maximum = - DBL_MAX;
+ totals->minimum = DBL_MAX;
+ }
+}
+
+
+static void
+run_oneway(const struct casefile *cf, void *cmd_)
+{
+ struct casereader *r;
+ struct ccase c;
+
+ struct cmd_oneway *cmd = (struct cmd_oneway *) cmd_;
+
+ global_group_hash = hsh_create(4,
+ (hsh_compare_func *) compare_values,
+ (hsh_hash_func *) hash_value,
+ 0,
+ (void *) indep_var->width );
+ precalc(cmd);
+
+ for(r = casefile_get_reader (cf);
+ casereader_read (r, &c) ;
+ case_destroy (&c))
+ {
+ size_t i;
+
+ const double weight =
+ dict_get_case_weight(default_dict,&c,&bad_weight_warn);
+
+ const union value *indep_val = case_data (&c, indep_var->fv);
+
+ /* Deal with missing values */
+ if ( value_is_missing(&indep_var->miss, indep_val) )
+ continue;
+
+ /* Skip the entire case if /MISSING=LISTWISE is set */
+ if ( cmd->miss == ONEWAY_LISTWISE )
+ {
+ for(i = 0; i < n_vars ; ++i)
+ {
+ const struct variable *v = vars[i];
+ const union value *val = case_data (&c, v->fv);
+
+ if (value_is_missing(&v->miss, val) )
+ break;
+ }
+ if ( i != n_vars )
+ continue;
+
+ }
+
+
+ hsh_insert ( global_group_hash, (void *) indep_val );
+
+ for ( i = 0 ; i < n_vars ; ++i )
+ {
+ const struct variable *v = vars[i];
+
+ const union value *val = case_data (&c, v->fv);
+
+ struct group_proc *gp = group_proc_get (vars[i]);
+ struct hsh_table *group_hash = gp->group_hash;
+
+ struct group_statistics *gs;
+
+ gs = hsh_find(group_hash, (void *) indep_val );
+
+ if ( ! gs )
+ {
+ gs = xmalloc (sizeof *gs);
+ gs->id = *indep_val;
+ gs->sum=0;
+ gs->n=0;
+ gs->ssq=0;
+ gs->sum_diff=0;
+ gs->minimum = DBL_MAX;
+ gs->maximum = -DBL_MAX;
+
+ hsh_insert ( group_hash, (void *) gs );
+ }
+
+ if (! value_is_missing(&v->miss, val) )
+ {
+ struct group_statistics *totals = &gp->ugs;
+
+ totals->n+=weight;
+ totals->sum+=weight * val->f;
+ totals->ssq+=weight * val->f * val->f;
+
+ if ( val->f * weight < totals->minimum )
+ totals->minimum = val->f * weight;
+
+ if ( val->f * weight > totals->maximum )
+ totals->maximum = val->f * weight;
+
+ gs->n+=weight;
+ gs->sum+=weight * val->f;
+ gs->ssq+=weight * val->f * val->f;
+
+ if ( val->f * weight < gs->minimum )
+ gs->minimum = val->f * weight;
+
+ if ( val->f * weight > gs->maximum )
+ gs->maximum = val->f * weight;
+ }
+
+ gp->n_groups = hsh_count ( group_hash );
+ }
+
+ }
+ casereader_destroy (r);
+
+ postcalc(cmd);
+
+
+ if ( stat_tables & STAT_HOMO )
+ levene(cf, indep_var, n_vars, vars,
+ (cmd->miss == ONEWAY_LISTWISE) ? LEV_LISTWISE : LEV_ANALYSIS ,
+ value_is_missing);
+
+ ostensible_number_of_groups = hsh_count (global_group_hash);
+
+
+ output_oneway();
+
+
+}
+
+
+/* Post calculations for the ONEWAY command */
+void
+postcalc ( struct cmd_oneway *cmd UNUSED )
+{
+ size_t i=0;
+
+
+ for(i = 0; i < n_vars ; ++i)
+ {
+ struct group_proc *gp = group_proc_get (vars[i]);
+ struct hsh_table *group_hash = gp->group_hash;
+ struct group_statistics *totals = &gp->ugs;
+
+ struct hsh_iterator g;
+ struct group_statistics *gs;
+
+ for (gs = hsh_first (group_hash,&g);
+ gs != 0;
+ gs = hsh_next(group_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);
+ gs->mean_diff= gs->sum_diff / gs->n;
+
+ }
+
+
+
+ totals->mean = totals->sum / totals->n;
+ totals->std_dev= sqrt(
+ totals->n/(totals->n-1) *
+ ( (totals->ssq / totals->n ) - totals->mean * totals->mean )
+ ) ;
+
+ totals->se_mean = totals->std_dev / sqrt(totals->n);
+
+ }
+}