Added Levene test. Added T-TEST section to pspp.texi
[pspp-builds.git] / src / t-test.q
1 /* PSPP - computes sample statistics. -*-c-*-
2
3    Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
4    Written by John Williams <johnr.williams@stonebow.otago.ac.nz>.
5    Almost completly re-written by John Darrington 2004
6
7    This program is free software; you can redistribute it and/or
8    modify it under the terms of the GNU General Public License as
9    published by the Free Software Foundation; either version 2 of the
10    License, or (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful, but
13    WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20    02111-1307, USA. */
21
22 #include <config.h>
23 #include <assert.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <math.h>
27 #include "alloc.h"
28 #include "str.h"
29 #include "dcdflib/cdflib.h"
30 #include "command.h"
31 #include "lexer.h"
32 #include "error.h"
33 #include "magic.h"
34 #include "tab.h"
35 #include "som.h"
36 #include "value-labels.h"
37 #include "var.h"
38 #include "vfm.h"
39 #include "pool.h"
40 #include "hash.h"
41 #include "stats.h"
42 #include "t-test.h"
43 #include "levene.h"
44
45 /* (specification)
46    "T-TEST" (tts_):
47      +groups=custom;
48      +testval=double;
49      variables=varlist("PV_NO_SCRATCH | PV_NUMERIC");
50      pairs=custom;
51      +missing=miss:!analysis/listwise,
52              incl:include/!exclude;
53      format=fmt:!labels/nolabels;
54      criteria=:cin(d:criteria,"%s > 0. && %s < 1.").
55 */
56 /* (declarations) */
57 /* (functions) */
58
59 static struct cmd_t_test cmd;
60
61
62 static struct pool *t_test_pool ;
63
64 /* Variable for the GROUPS subcommand, if given. */
65 static struct variable *groups;
66
67 /* GROUPS: Number of values specified by the user; the values
68    specified if any. */
69
70 static int n_groups_values;
71 static union value groups_values[2];
72
73
74 /* PAIRS: Number of pairs to be compared ; each pair. */
75 static int n_pairs = 0 ;
76 struct pair 
77 {
78   /* The variables comprising the pair */
79   struct variable *v[2];
80
81   /* The correlation coefficient between the variables */
82   double correlation;
83
84   /* The sum of the differences */
85   double sum_of_diffs;
86
87   /* The mean of the differences */
88   double mean_diff;
89
90   /* The sum of the squares of the differences */
91   double ssq_diffs;
92
93   /* The std deviation of the differences */
94   double std_dev_diff;
95 };
96 static struct pair *pairs=0;
97
98
99 static int parse_value (union value * v, int type) ;
100
101
102 /* Structures and Functions for the Statistics Summary Box */
103 struct ssbox;
104 typedef void populate_ssbox_func(struct ssbox *ssb,
105                                             struct cmd_t_test *cmd);
106 typedef void finalize_ssbox_func(struct ssbox *ssb);
107
108 struct ssbox
109 {
110   struct tab_table *t;
111
112   populate_ssbox_func *populate;
113   finalize_ssbox_func *finalize;
114
115 };
116
117 /* Create a ssbox */
118 void ssbox_create(struct ssbox *ssb,   struct cmd_t_test *cmd, int mode);
119
120 /* Populate a ssbox according to cmd */
121 void ssbox_populate(struct ssbox *ssb, struct cmd_t_test *cmd);
122
123 /* Submit and destroy a ssbox */
124 void ssbox_finalize(struct ssbox *ssb);
125
126 /* A function to create, populate and submit the Paired Samples Correlation 
127    box */
128 void pscbox(void);
129
130
131 /* Structures and Functions for the Test Results Box */
132 struct trbox;
133
134 typedef void populate_trbox_func(struct trbox *trb,
135                                  struct cmd_t_test *cmd);
136 typedef void finalize_trbox_func(struct trbox *trb);
137
138 struct trbox {
139   struct tab_table *t;
140   populate_trbox_func *populate;
141   finalize_trbox_func *finalize;
142 };
143
144 /* Create a trbox */
145 void trbox_create(struct trbox *trb,   struct cmd_t_test *cmd, int mode);
146
147 /* Populate a ssbox according to cmd */
148 void trbox_populate(struct trbox *trb, struct cmd_t_test *cmd);
149
150 /* Submit and destroy a ssbox */
151 void trbox_finalize(struct trbox *trb);
152
153 /* Which mode was T-TEST invoked */
154 enum {
155   T_1_SAMPLE = 0 ,
156   T_IND_SAMPLES, 
157   T_PAIRED
158 };
159
160
161 static int common_calc (struct ccase *, void *);
162 static void common_precalc (void *);
163 static void common_postcalc (void *);
164
165 static int one_sample_calc (struct ccase *, void *);
166 static void one_sample_precalc (void *);
167 static void one_sample_postcalc (void *);
168
169 static int  paired_calc (struct ccase *, void *);
170 static void paired_precalc (void *);
171 static void paired_postcalc (void *);
172
173 static void group_precalc (void *);
174 static int  group_calc (struct ccase *, void *);
175 static void group_postcalc (void *);
176
177
178 static int compare_var_name (const void *a_, const void *b_, void *v_ UNUSED);
179 static unsigned hash_var_name (const void *a_, void *v_ UNUSED);
180
181
182
183 int
184 cmd_t_test(void)
185 {
186   int mode;
187
188   struct ssbox stat_summary_box;
189   struct trbox test_results_box;
190
191   if (!lex_force_match_id ("T"))
192     return CMD_FAILURE;
193
194   lex_match ('-');
195   lex_match_id ("TEST");
196
197   if ( !parse_t_test(&cmd) )
198     return CMD_FAILURE;
199
200   if (! cmd.sbc_criteria)
201     cmd.criteria=0.95;
202
203   {
204     int m=0;
205     if (cmd.sbc_testval) ++m;
206     if (cmd.sbc_groups) ++m;
207     if (cmd.sbc_pairs) ++m;
208
209     if ( m != 1)
210       {
211         msg(SE, 
212             _("TESTVAL, GROUPS and PAIRS subcommands are mutually exclusive.")
213             );
214         return CMD_FAILURE;
215       }
216   }
217
218   if (cmd.sbc_testval) 
219     mode=T_1_SAMPLE;
220   else if (cmd.sbc_groups)
221     mode=T_IND_SAMPLES;
222   else
223     mode=T_PAIRED;
224
225   if ( mode == T_PAIRED) 
226     {
227       if (cmd.sbc_variables) 
228         {
229           msg(SE, _("VARIABLES subcommand is not appropriate with PAIRS"));
230           return CMD_FAILURE;
231         }
232       else
233         {
234           /* Iterate through the pairs and put each variable that is a 
235              member of a pair into cmd.v_variables */
236
237           int i;
238           struct hsh_iterator hi;
239           struct hsh_table *hash;
240           struct variable *v;
241
242           hash=hsh_create(n_pairs,compare_var_name,hash_var_name,0,0);
243
244           for (i=0; i < n_pairs; ++i)
245             {
246               hsh_insert(hash,pairs[i].v[0]);
247               hsh_insert(hash,pairs[i].v[1]);
248             }
249
250           assert(cmd.n_variables == 0);
251           cmd.n_variables = hsh_count(hash);
252
253           cmd.v_variables = xrealloc(cmd.v_variables,
254                                      sizeof(struct variable) * cmd.n_variables);
255           /* Iterate through the hash */
256           for (i=0,v = (struct variable *) hsh_first(hash,&hi);
257                v != 0;
258                v=hsh_next(hash,&hi) ) 
259             cmd.v_variables[i++]=v;
260
261           hsh_destroy(hash);
262         }
263     }
264
265
266   procedure(common_precalc,common_calc,common_postcalc, NULL);
267
268   switch(mode)
269     {
270     case T_1_SAMPLE:
271       procedure(one_sample_precalc,one_sample_calc,one_sample_postcalc, NULL);
272       break;
273     case T_PAIRED:
274       procedure(paired_precalc,paired_calc,paired_postcalc, NULL);
275       break;
276     case T_IND_SAMPLES:
277       procedure(group_precalc,group_calc,group_postcalc, NULL);
278       levene(groups, cmd.n_variables, cmd.v_variables);
279       break;
280     }
281
282   t_test_pool = pool_create ();
283
284   ssbox_create(&stat_summary_box,&cmd,mode);
285   ssbox_populate(&stat_summary_box,&cmd);
286   ssbox_finalize(&stat_summary_box);
287
288   if ( mode == T_PAIRED) 
289       pscbox();
290
291   trbox_create(&test_results_box,&cmd,mode);
292   trbox_populate(&test_results_box,&cmd);
293   trbox_finalize(&test_results_box);
294
295   pool_destroy (t_test_pool);
296
297   t_test_pool=0;
298
299
300   n_pairs=0;
301   free(pairs);
302   pairs=0;
303
304
305   if ( mode == T_IND_SAMPLES) 
306     {
307       int i;
308       /* Destroy any group statistics we created */
309       for (i= 0 ; i < cmd.n_variables ; ++i ) 
310         {
311           free(cmd.v_variables[i]->p.t_t.gs);
312         }
313     }
314     
315   return CMD_SUCCESS;
316 }
317
318 static int
319 tts_custom_groups (struct cmd_t_test *cmd UNUSED)
320 {
321   lex_match('=');
322
323   if (token != T_ALL && 
324       (token != T_ID || dict_lookup_var (default_dict, tokid) == NULL)
325      ) 
326   {
327     msg(SE,_("`%s' is not a variable name"),tokid);
328     return 0;
329   }
330
331   groups = parse_variable ();
332   if (!groups)
333     {
334       lex_error ("expecting variable name in GROUPS subcommand");
335       return 0;
336     }
337
338   if (groups->type == T_STRING && groups->width > MAX_SHORT_STRING)
339     {
340       msg (SE, _("Long string variable %s is not valid here."),
341            groups->name);
342       return 0;
343     }
344
345   if (!lex_match ('('))
346     {
347       if (groups->type == NUMERIC)
348         {
349           n_groups_values = 2;
350           groups_values[0].f = 1;
351           groups_values[1].f = 2;
352           return 1;
353         }
354       else
355         {
356           msg (SE, _("When applying GROUPS to a string variable, at "
357                      "least one value must be specified."));
358           return 0;
359         }
360     }
361
362   if (!parse_value (&groups_values[0],groups->type))
363     return 0;
364   n_groups_values = 1;
365
366   lex_match (',');
367   if (lex_match (')'))
368     return 1;
369
370   if (!parse_value (&groups_values[1],groups->type))
371     return 0;
372   n_groups_values = 2;
373
374   if (!lex_force_match (')'))
375     return 0;
376
377   return 1;
378 }
379
380
381
382
383 static int
384 tts_custom_pairs (struct cmd_t_test *cmd UNUSED)
385 {
386   struct variable **vars;
387   int n_vars;
388   int n_pairs_local;
389
390   int n_before_WITH ;
391   int n_after_WITH = -1;
392   int paired ; /* Was the PAIRED keyword given ? */
393
394   lex_match('=');
395
396   if ((token != T_ID || dict_lookup_var (default_dict, tokid) == NULL)
397       && token != T_ALL)
398     {
399       msg(SE,_("`%s' is not a variable name"),tokid);
400       return 0;
401     }
402
403   n_vars=0;
404   if (!parse_variables (default_dict, &vars, &n_vars,
405                         PV_DUPLICATE | PV_NUMERIC | PV_NO_SCRATCH))
406     {
407       free (vars);
408       return 0;
409     }
410   assert (n_vars);
411
412   n_before_WITH=0;
413   if (lex_match (T_WITH))
414     {
415       n_before_WITH = n_vars;
416       if (!parse_variables (default_dict, &vars, &n_vars,
417                             PV_DUPLICATE | PV_APPEND
418                             | PV_NUMERIC | PV_NO_SCRATCH))
419         {
420           free (vars);
421           return 0;
422         }
423       n_after_WITH = n_vars - n_before_WITH;
424     }
425
426   paired = (lex_match ('(') && lex_match_id ("PAIRED") && lex_match (')'));
427
428   /* Determine the number of pairs needed */
429   if (paired)
430     {
431       if (n_before_WITH != n_after_WITH)
432         {
433           free (vars);
434           msg (SE, _("PAIRED was specified but the number of variables "
435                      "preceding WITH (%d) did not match the number "
436                      "following (%d)."),
437                n_before_WITH, n_after_WITH );
438           return 0;
439         }
440       n_pairs_local=n_before_WITH;
441     }
442   else if (n_before_WITH > 0) /* WITH keyword given, but not PAIRED keyword */
443     {
444       n_pairs_local=n_before_WITH * n_after_WITH ;
445     }
446   else /* Neither WITH nor PAIRED keyword given */
447     {
448       if (n_vars < 2)
449         {
450           free (vars);
451           msg (SE, _("At least two variables must be specified "
452                      "on PAIRS."));
453           return 0;
454         }
455
456       /* how many ways can you pick 2 from n_vars ? */
457       n_pairs_local = n_vars * (n_vars -1 ) /2 ;
458     }
459
460
461   /* Allocate storage for the pairs */
462   pairs = xrealloc(pairs, sizeof(struct pair) * (n_pairs + n_pairs_local) );
463
464   /* Populate the pairs with the appropriate variables */
465   if ( paired ) 
466     {
467       int i;
468
469       assert(n_pairs_local == n_vars/2);
470       for (i = 0; i < n_pairs_local ; ++i)
471         {
472           pairs[i].v[n_pairs+0] = vars[i];
473           pairs[i].v[n_pairs+1] = vars[i+n_pairs_local];
474         }
475     }
476   else if (n_before_WITH > 0) /* WITH keyword given, but not PAIRED keyword */
477     {
478       int i,j;
479       int p=n_pairs;
480
481       for(i=0 ; i < n_before_WITH ; ++i ) 
482         {
483           for(j=0 ; j < n_after_WITH ; ++j)
484             {
485               pairs[p].v[0] = vars[i];
486               pairs[p].v[1] = vars[j+n_before_WITH];
487               ++p;
488             }
489         }
490     }
491   else /* Neither WITH nor PAIRED given */
492     {
493       int i,j;
494       int p=n_pairs;
495       
496       for(i=0 ; i < n_vars ; ++i ) 
497         {
498           for(j=i+1 ; j < n_vars ; ++j)
499             {
500               pairs[p].v[0] = vars[i];
501               pairs[p].v[1] = vars[j];
502               ++p;
503             }
504         }
505     }
506
507   n_pairs+=n_pairs_local;
508
509   return 1;
510 }
511
512 /* Parses the current token (numeric or string, depending on type)
513     value v and returns success. */
514 static int
515 parse_value (union value * v, int type )
516 {
517   if (type == NUMERIC)
518     {
519       if (!lex_force_num ())
520         return 0;
521       v->f = tokval;
522     }
523   else
524     {
525       if (!lex_force_string ())
526         return 0;
527       strncpy (v->s, ds_value (&tokstr), ds_length (&tokstr));
528     }
529
530   lex_get ();
531
532   return 1;
533 }
534
535
536 /* Implementation of the SSBOX object */
537
538 void ssbox_base_init(struct ssbox *this, int cols,int rows);
539
540 void ssbox_base_finalize(struct ssbox *ssb);
541
542 void ssbox_one_sample_init(struct ssbox *this, 
543                            struct cmd_t_test *cmd );
544
545 void ssbox_independent_samples_init(struct ssbox *this,
546                                     struct cmd_t_test *cmd);
547
548 void ssbox_paired_init(struct ssbox *this,
549                            struct cmd_t_test *cmd);
550
551 /* Factory to create an ssbox */
552 void 
553 ssbox_create(struct ssbox *ssb, struct cmd_t_test *cmd, int mode)
554 {
555     switch (mode) 
556       {
557       case T_1_SAMPLE:
558         ssbox_one_sample_init(ssb,cmd);
559         break;
560       case T_IND_SAMPLES:
561         ssbox_independent_samples_init(ssb,cmd);
562         break;
563       case T_PAIRED:
564         ssbox_paired_init(ssb,cmd);
565         break;
566       default:
567         assert(0);
568       }
569 }
570
571
572 /* Despatcher for the populate method */
573 void
574 ssbox_populate(struct ssbox *ssb,struct cmd_t_test *cmd)
575 {
576   ssb->populate(ssb,cmd);
577 }
578
579
580 /* Despatcher for finalize */
581 void
582 ssbox_finalize(struct ssbox *ssb)
583 {
584   ssb->finalize(ssb);
585 }
586
587
588 /* Submit the box and clear up */
589 void 
590 ssbox_base_finalize(struct ssbox *ssb)
591 {
592   tab_submit(ssb->t);
593 }
594
595 /* Initialize a ssbox struct */
596 void 
597 ssbox_base_init(struct ssbox *this, int cols,int rows)
598 {
599   this->finalize = ssbox_base_finalize;
600   this->t = tab_create (cols, rows, 0);
601
602   tab_columns (this->t, SOM_COL_DOWN, 1);
603   tab_headers (this->t,0,0,1,0); 
604   tab_box (this->t, TAL_2, TAL_2, TAL_0, TAL_1, 0, 0, cols -1, rows -1 );
605   tab_hline(this->t, TAL_2,0,cols-1,1);
606   tab_dim (this->t, tab_natural_dimensions);
607 }
608
609 void  ssbox_one_sample_populate(struct ssbox *ssb,
610                               struct cmd_t_test *cmd);
611
612 /* Initialize the one_sample ssbox */
613 void 
614 ssbox_one_sample_init(struct ssbox *this, 
615                            struct cmd_t_test *cmd )
616 {
617   const int hsize=5;
618   const int vsize=cmd->n_variables+1;
619
620   this->populate = ssbox_one_sample_populate;
621
622   ssbox_base_init(this, hsize,vsize);
623   tab_title (this->t, 0, _("One-Sample Statistics"));
624   tab_vline(this->t, TAL_2, 1,0,vsize);
625   tab_text (this->t, 1, 0, TAB_CENTER | TAT_TITLE, _("N"));
626   tab_text (this->t, 2, 0, TAB_CENTER | TAT_TITLE, _("Mean"));
627   tab_text (this->t, 3, 0, TAB_CENTER | TAT_TITLE, _("Std. Deviation"));
628   tab_text (this->t, 4, 0, TAB_CENTER | TAT_TITLE, _("SE. Mean"));
629 }
630
631 void ssbox_independent_samples_populate(struct ssbox *ssb,
632                                         struct cmd_t_test *cmd);
633
634 /* Initialize the independent samples ssbox */
635 void 
636 ssbox_independent_samples_init(struct ssbox *this, 
637         struct cmd_t_test *cmd)
638 {
639   int hsize=6;
640   int vsize = cmd->n_variables*2 +1;
641
642   this->populate = ssbox_independent_samples_populate;
643
644   ssbox_base_init(this, hsize,vsize);
645   tab_title (this->t, 0, _("Group Statistics"));
646   tab_vline(this->t,0,1,0,vsize);
647   tab_text (this->t, 1, 0, TAB_CENTER | TAT_TITLE, groups->name);
648   tab_text (this->t, 2, 0, TAB_CENTER | TAT_TITLE, _("N"));
649   tab_text (this->t, 3, 0, TAB_CENTER | TAT_TITLE, _("Mean"));
650   tab_text (this->t, 4, 0, TAB_CENTER | TAT_TITLE, _("Std. Deviation"));
651   tab_text (this->t, 5, 0, TAB_CENTER | TAT_TITLE, _("SE. Mean"));
652 }
653
654
655 /* Populate the ssbox for independent samples */
656 void 
657 ssbox_independent_samples_populate(struct ssbox *ssb,
658                               struct cmd_t_test *cmd)
659 {
660   int i;
661
662   char *val_lab1=0;
663   char *val_lab2=0;
664
665   if ( groups->type == NUMERIC ) 
666     {
667       val_lab1 = val_labs_find( groups->val_labs,groups_values[0]); 
668       val_lab2 = val_labs_find( groups->val_labs,groups_values[1]);
669     }
670   else
671     {
672       val_lab1 = groups_values[0].s;
673       val_lab2 = groups_values[1].s;
674     }
675
676   assert(ssb->t);
677
678   for (i=0; i < cmd->n_variables; ++i)
679     {
680       int g;
681
682       tab_text (ssb->t, 0, i*2+1, TAB_LEFT, cmd->v_variables[i]->name);
683
684       if (val_lab1)
685         tab_text (ssb->t, 1, i*2+1, TAB_LEFT, val_lab1);
686       else
687         tab_float(ssb->t, 1 ,i*2+1, TAB_LEFT, groups_values[0].f, 2,0);
688
689
690       if (val_lab2)
691         tab_text (ssb->t, 1, i*2+1+1, TAB_LEFT, val_lab2);
692       else
693         tab_float(ssb->t, 1 ,i*2+1+1, TAB_LEFT, groups_values[1].f,2,0);
694
695       /* Fill in the group statistics */
696       for ( g=0; g < 2 ; ++g ) 
697         {
698           struct group_statistics *gs = &cmd->v_variables[i]->p.t_t.gs[g];
699
700           tab_float(ssb->t, 2 ,i*2+g+1, TAB_RIGHT, gs->n, 2, 0);
701           tab_float(ssb->t, 3 ,i*2+g+1, TAB_RIGHT, gs->mean, 8, 2);
702           tab_float(ssb->t, 4 ,i*2+g+1, TAB_RIGHT, gs->std_dev, 8, 3);
703           tab_float(ssb->t, 5 ,i*2+g+1, TAB_RIGHT, gs->se_mean, 8, 3);
704         }
705     }
706 }
707
708
709 void ssbox_paired_populate(struct ssbox *ssb,
710                            struct cmd_t_test *cmd);
711
712 /* Initialize the paired values ssbox */
713 void 
714 ssbox_paired_init(struct ssbox *this, struct cmd_t_test *cmd UNUSED)
715 {
716   int hsize=6;
717
718   int vsize = n_pairs*2+1;
719
720   this->populate = ssbox_paired_populate;
721
722   ssbox_base_init(this, hsize,vsize);
723   tab_title (this->t, 0, _("Paired Sample Statistics"));
724   tab_vline(this->t,TAL_0,1,0,vsize-1);
725   tab_vline(this->t,TAL_2,2,0,vsize-1);
726   tab_text (this->t, 2, 0, TAB_CENTER | TAT_TITLE, _("Mean"));
727   tab_text (this->t, 3, 0, TAB_CENTER | TAT_TITLE, _("N"));
728   tab_text (this->t, 4, 0, TAB_CENTER | TAT_TITLE, _("Std. Deviation"));
729   tab_text (this->t, 5, 0, TAB_CENTER | TAT_TITLE, _("SE. Mean"));
730 }
731
732
733 /* Populate the ssbox for paired values */
734 void 
735 ssbox_paired_populate(struct ssbox *ssb,struct cmd_t_test *cmd UNUSED)
736 {
737   int i;
738
739   assert(ssb->t);
740
741   for (i=0; i < n_pairs; ++i)
742     {
743       int j;
744
745       tab_text (ssb->t, 0, i*2+1, TAB_LEFT | TAT_PRINTF , _("Pair %d"),i);
746
747       for (j=0 ; j < 2 ; ++j) 
748         {
749           struct group_statistics *gs;
750
751           gs=&pairs[i].v[j]->p.t_t.ugs;
752
753           /* Titles */
754
755           tab_text (ssb->t, 1, i*2+j+1, TAB_LEFT, pairs[i].v[j]->name);
756
757           /* Values */
758           tab_float (ssb->t,2, i*2+j+1, TAB_RIGHT, gs->mean, 8, 2);
759           tab_float (ssb->t,3, i*2+j+1, TAB_RIGHT, gs->n, 2, 0);
760           tab_float (ssb->t,4, i*2+j+1, TAB_RIGHT, gs->std_dev, 8, 3);
761           tab_float (ssb->t,5, i*2+j+1, TAB_RIGHT, gs->se_mean, 8, 3);
762
763         }
764
765     }
766
767 }
768
769 /* Populate the one sample ssbox */
770 void 
771 ssbox_one_sample_populate(struct ssbox *ssb, struct cmd_t_test *cmd)
772 {
773   int i;
774
775   assert(ssb->t);
776
777   for (i=0; i < cmd->n_variables; ++i)
778     {
779       struct group_statistics *gs;
780       gs= &cmd->v_variables[i]->p.t_t.ugs;
781
782       tab_text (ssb->t, 0, i+1, TAB_LEFT, cmd->v_variables[i]->name);
783       tab_float (ssb->t,1, i+1, TAB_RIGHT, gs->n, 2, 0);
784       tab_float (ssb->t,2, i+1, TAB_RIGHT, gs->mean, 8, 2);
785       tab_float (ssb->t,3, i+1, TAB_RIGHT, gs->std_dev, 8, 2);
786       tab_float (ssb->t,4, i+1, TAB_RIGHT, gs->se_mean, 8, 3);
787     }
788   
789 }
790
791
792
793 /* Implementation of the Test Results box struct */
794
795 void trbox_base_init(struct trbox *self,int n_vars, int cols);
796 void trbox_base_finalize(struct trbox *trb);
797
798 void trbox_independent_samples_init(struct trbox *trb,
799                                     struct cmd_t_test *cmd );
800
801 void trbox_independent_samples_populate(struct trbox *trb,
802                                         struct cmd_t_test *cmd);
803
804 void trbox_one_sample_init(struct trbox *self,
805                       struct cmd_t_test *cmd );
806
807 void trbox_one_sample_populate(struct trbox *trb,
808                                struct cmd_t_test *cmd);
809
810 void trbox_paired_init(struct trbox *self,
811                        struct cmd_t_test *cmd );
812
813 void trbox_paired_populate(struct trbox *trb,
814                       struct cmd_t_test *cmd);
815
816
817
818 /* Create a trbox according to mode*/
819 void 
820 trbox_create(struct trbox *trb,   
821              struct cmd_t_test *cmd, int mode)
822 {
823     switch (mode) 
824       {
825       case T_1_SAMPLE:
826         trbox_one_sample_init(trb,cmd);
827         break;
828       case T_IND_SAMPLES:
829         trbox_independent_samples_init(trb,cmd);
830         break;
831       case T_PAIRED:
832         trbox_paired_init(trb,cmd);
833         break;
834       default:
835         assert(0);
836       }
837 }
838
839 /* Populate a trbox according to cmd */
840 void 
841 trbox_populate(struct trbox *trb, struct cmd_t_test *cmd)
842 {
843   trb->populate(trb,cmd);
844 }
845
846 /* Submit and destroy a trbox */
847 void 
848 trbox_finalize(struct trbox *trb)
849 {
850   trb->finalize(trb);
851 }
852
853 /* Initialize the independent samples trbox */
854 void 
855 trbox_independent_samples_init(struct trbox *self,
856                            struct cmd_t_test *cmd UNUSED)
857 {
858   const int hsize=11;
859   const int vsize=cmd->n_variables*2+3;
860
861   assert(self);
862   self->populate = trbox_independent_samples_populate;
863
864   trbox_base_init(self,cmd->n_variables*2,hsize);
865   tab_title(self->t,0,_("Independent Samples Test"));
866   tab_hline(self->t,TAL_1,2,hsize-1,1);
867   tab_vline(self->t,TAL_2,2,0,vsize-1);
868   tab_vline(self->t,TAL_1,4,0,vsize-1);
869   tab_box(self->t,-1,-1,-1,TAL_1, 2,1,hsize-2,vsize-1);
870   tab_hline(self->t,TAL_1, hsize-2,hsize-1,2);
871   tab_box(self->t,-1,-1,-1,TAL_1, hsize-2,2,hsize-1,vsize-1);
872   tab_joint_text(self->t, 2, 0, 3, 0, 
873                  TAB_CENTER,_("Levene's Test for Equality of Variances"));
874   tab_joint_text(self->t, 4,0,hsize-1,0,
875                  TAB_CENTER,_("t-test for Equality of Means"));
876
877   tab_text(self->t,2,2, TAB_CENTER | TAT_TITLE,_("F"));
878   tab_text(self->t,3,2, TAB_CENTER | TAT_TITLE,_("Sig."));
879   tab_text(self->t,4,2, TAB_CENTER | TAT_TITLE,_("t"));
880   tab_text(self->t,5,2, TAB_CENTER | TAT_TITLE,_("df"));
881   tab_text(self->t,6,2, TAB_CENTER | TAT_TITLE,_("Sig. (2-tailed)"));
882   tab_text(self->t,7,2, TAB_CENTER | TAT_TITLE,_("Mean Difference"));
883   tab_text(self->t,8,2, TAB_CENTER | TAT_TITLE,_("Std. Error Difference"));
884   tab_text(self->t,9,2, TAB_CENTER | TAT_TITLE,_("Lower"));
885   tab_text(self->t,10,2, TAB_CENTER | TAT_TITLE,_("Upper"));
886
887   tab_joint_text(self->t, 9, 1, 10, 1, TAB_CENTER | TAT_PRINTF, 
888                  _("%d%% Confidence Interval of the Difference"),
889                  (int)round(cmd->criteria*100.0));
890
891 }
892
893 /* Populate the independent samples trbox */
894 void 
895 trbox_independent_samples_populate(struct trbox *self,
896                                    struct cmd_t_test *cmd )
897 {
898   int i;
899
900   assert(self);
901   for (i=0; i < cmd->n_variables; ++i)
902     {
903       int which =1;
904       double p,q;
905       int status;
906       double bound;
907
908       double t;
909       double df;
910
911       double df1, df2;
912
913       double pooled_variance;
914       double std_err_diff;
915       double mean_diff;
916
917       struct group_statistics *gs0 = &cmd->v_variables[i]->p.t_t.gs[0];
918       struct group_statistics *gs1 = &cmd->v_variables[i]->p.t_t.gs[1];
919           
920       tab_text (self->t, 0, i*2+3, TAB_LEFT, cmd->v_variables[i]->name);
921
922       tab_text (self->t, 1, i*2+3, TAB_LEFT, _("Equal variances assumed"));
923
924
925       tab_float(self->t, 2, i*2+3, TAB_CENTER, 
926                 cmd->v_variables[i]->p.t_t.levene, 8,3);
927
928
929       /* Now work out the significance of the Levene test */
930
931       which=1; df1 = 1; df2 = cmd->v_variables[i]->p.t_t.ugs.n - 2;
932       cdff(&which,&p,&q,&cmd->v_variables[i]->p.t_t.levene,
933            &df1,&df2,&status,&bound);
934
935       if ( 0 != status )
936         {
937           msg( SE, _("Error calculating F statistic (cdff returned %d)."),status);
938         }
939
940       tab_float(self->t, 3, i*2+3, TAB_CENTER, q, 8,3 );
941
942       df = gs0->n + gs1->n - 2.0 ;
943       tab_float (self->t, 5, i*2+3, TAB_RIGHT, df, 2, 0);
944
945       pooled_variance = ( (gs0->n )*sqr(gs0->s_std_dev)
946                           + 
947                           (gs1->n )*sqr(gs1->s_std_dev) 
948                         ) / df  ;
949
950       t = (gs0->mean - gs1->mean) / sqrt(pooled_variance) ;
951       t /= sqrt((gs0->n + gs1->n)/(gs0->n*gs1->n)); 
952
953       tab_float (self->t, 4, i*2+3, TAB_RIGHT, t, 8, 3);
954
955
956       which=1; /* get p & q from t & df */
957       cdft(&which, &p, &q, &t, &df, &status, &bound);
958       if ( 0 != status )
959         {
960           msg( SE, _("Error calculating T statistic (cdft returned %d)."),status);
961         }
962
963       tab_float(self->t, 6, i*2+3, TAB_RIGHT, 2.0*(t>0?q:p) , 8, 3);
964
965       mean_diff = gs0->mean - gs1->mean;
966       tab_float(self->t, 7, i*2+3, TAB_RIGHT, mean_diff, 8, 3);
967
968
969       std_err_diff = sqrt( sqr(gs0->se_mean) + sqr(gs1->se_mean));
970       tab_float(self->t, 8, i*2+3, TAB_RIGHT, std_err_diff, 8, 3);
971
972
973       /* Now work out the confidence interval */
974       q = (1 - cmd->criteria)/2.0;  /* 2-tailed test */
975       p = 1 - q ;
976       which=2; /* Calc T from p,q and df */
977       cdft(&which, &p, &q, &t, &df, &status, &bound);
978       if ( 0 != status )
979         {
980           msg( SE, _("Error calculating T statistic (cdft returned %d)."),status);
981         }
982
983       tab_float(self->t, 9, i*2+3, TAB_RIGHT, 
984                 mean_diff - t * std_err_diff, 8, 3); 
985
986       tab_float(self->t, 10, i*2+3, TAB_RIGHT, 
987                 mean_diff + t * std_err_diff, 8, 3); 
988
989
990       {
991         double se2;
992       /* Now for the \sigma_1 != \sigma_2 case */
993       tab_text (self->t, 1, i*2+3+1, 
994                 TAB_LEFT, _("Equal variances not assumed"));
995
996
997       se2 = (sqr(gs0->s_std_dev)/(gs0->n -1) ) +
998         (sqr(gs1->s_std_dev)/(gs1->n -1) );
999
1000       t = mean_diff / sqrt(se2) ;
1001       tab_float (self->t, 4, i*2+3+1, TAB_RIGHT, t, 8, 3);
1002                 
1003       df = sqr(se2) / ( 
1004                        (sqr(sqr(gs0->s_std_dev)/(gs0->n - 1 )) 
1005                         /(gs0->n -1 )
1006                         )
1007                        + 
1008                        (sqr(sqr(gs1->s_std_dev)/(gs1->n - 1 ))
1009                         /(gs1->n -1 )
1010                         )
1011                        ) ;
1012       tab_float (self->t, 5, i*2+3+1, TAB_RIGHT, df, 8, 3);
1013
1014       which=1; /* get p & q from t & df */
1015       cdft(&which, &p, &q, &t, &df, &status, &bound);
1016       if ( 0 != status )
1017         {
1018           msg( SE, _("Error calculating T statistic (cdft returned %d)."),status);
1019         }
1020
1021       tab_float(self->t, 6, i*2+3+1, TAB_RIGHT, 2.0*(t>0?q:p) , 8, 3);
1022
1023       /* Now work out the confidence interval */
1024       q = (1 - cmd->criteria)/2.0;  /* 2-tailed test */
1025       p = 1 - q ;
1026       which=2; /* Calc T from p,q and df */
1027       cdft(&which, &p, &q, &t, &df, &status, &bound);
1028       if ( 0 != status )
1029         {
1030           msg( SE, _("Error calculating T statistic (cdft returned %d)."),status);
1031         }
1032
1033
1034       tab_float(self->t, 7, i*2+3+1, TAB_RIGHT, mean_diff, 8, 3);
1035
1036
1037       tab_float(self->t, 8, i*2+3+1, TAB_RIGHT, std_err_diff, 8, 3);
1038
1039
1040       tab_float(self->t, 9, i*2+3+1, TAB_RIGHT, 
1041                 mean_diff - t * std_err_diff, 8, 3); 
1042
1043       tab_float(self->t, 10, i*2+3+1, TAB_RIGHT, 
1044                 mean_diff + t * std_err_diff, 8, 3); 
1045
1046       }
1047     }
1048 }
1049
1050 /* Initialize the paired samples trbox */
1051 void 
1052 trbox_paired_init(struct trbox *self,
1053                            struct cmd_t_test *cmd UNUSED)
1054 {
1055
1056   const int hsize=10;
1057   const int vsize=n_pairs+3;
1058
1059   self->populate = trbox_paired_populate;
1060
1061   trbox_base_init(self,n_pairs,hsize);
1062   tab_title (self->t, 0, _("Paired Samples Test"));
1063   tab_hline(self->t,TAL_1,2,6,1);
1064   tab_vline(self->t,TAL_2,2,0,vsize);
1065   tab_joint_text(self->t,2,0,6,0,TAB_CENTER,_("Paired Differences"));
1066   tab_box(self->t,-1,-1,-1,TAL_1, 2,1,6,vsize-1);
1067   tab_box(self->t,-1,-1,-1,TAL_1, 6,0,hsize-1,vsize-1);
1068   tab_hline(self->t,TAL_1,5,6, 2);
1069   tab_vline(self->t,TAL_0,6,0,1);
1070
1071   tab_joint_text(self->t, 5, 1, 6, 1, TAB_CENTER | TAT_PRINTF, 
1072                  _("%d%% Confidence Interval of the Difference"),
1073                  (int)round(cmd->criteria*100.0));
1074
1075   tab_text (self->t, 2, 2, TAB_CENTER | TAT_TITLE, _("Mean"));
1076   tab_text (self->t, 3, 2, TAB_CENTER | TAT_TITLE, _("Std. Deviation"));
1077   tab_text (self->t, 4, 2, TAB_CENTER | TAT_TITLE, _("Std. Error Mean"));
1078   tab_text (self->t, 5, 2, TAB_CENTER | TAT_TITLE, _("Lower"));
1079   tab_text (self->t, 6, 2, TAB_CENTER | TAT_TITLE, _("Upper"));
1080   tab_text (self->t, 7, 2, TAB_CENTER | TAT_TITLE, _("t"));
1081   tab_text (self->t, 8, 2, TAB_CENTER | TAT_TITLE, _("df"));
1082   tab_text (self->t, 9, 2, TAB_CENTER | TAT_TITLE, _("Sig. (2-tailed)"));
1083 }
1084
1085 /* Populate the paired samples trbox */
1086 void 
1087 trbox_paired_populate(struct trbox *trb,
1088                               struct cmd_t_test *cmd UNUSED)
1089 {
1090   int i;
1091
1092   for (i=0; i < n_pairs; ++i)
1093     {
1094       int which =1;
1095       double p,q;
1096       int status;
1097       double bound;
1098       double se_mean;
1099
1100       struct variable *v0 = pairs[i].v[0];
1101       struct variable *v1 = pairs[i].v[1];
1102
1103       struct group_statistics *gs0 = &v0->p.t_t.ugs;
1104       struct group_statistics *gs1 = &v1->p.t_t.ugs;
1105
1106       double n = gs0->n;
1107       double t;
1108       double df = n - 1;
1109       
1110       tab_text (trb->t, 0, i+3, TAB_LEFT | TAT_PRINTF, _("Pair %d"),i); 
1111
1112       tab_text (trb->t, 1, i+3, TAB_LEFT | TAT_PRINTF, "%s - %s",
1113                 pairs[i].v[0]->name, pairs[i].v[1]->name);
1114
1115       tab_float(trb->t, 2, i+3, TAB_RIGHT, pairs[i].mean_diff, 8, 4);
1116
1117       tab_float(trb->t, 3, i+3, TAB_RIGHT, pairs[i].std_dev_diff, 8, 5);
1118
1119       /* SE Mean */
1120       se_mean = pairs[i].std_dev_diff / sqrt(n) ;
1121       tab_float(trb->t, 4, i+3, TAB_RIGHT, se_mean, 8,5 );
1122
1123       /* Now work out the confidence interval */
1124       q = (1 - cmd->criteria)/2.0;  /* 2-tailed test */
1125       p = 1 - q ;
1126       which=2; /* Calc T from p,q and df */
1127       cdft(&which, &p, &q, &t, &df, &status, &bound);
1128
1129       if ( 0 != status )
1130         {
1131           msg( SE, _("Error calculating T statistic (cdft returned %d)."),status);
1132         }
1133
1134       tab_float(trb->t, 5, i+3, TAB_RIGHT, 
1135                 pairs[i].mean_diff - t * se_mean , 8, 4); 
1136
1137       tab_float(trb->t, 6, i+3, TAB_RIGHT, 
1138                 pairs[i].mean_diff + t * se_mean , 8, 4); 
1139
1140       t = ( gs0->mean - gs1->mean)
1141         / sqrt ( 
1142                 (  sqr(gs0->s_std_dev) + sqr(gs1->s_std_dev)  - 
1143                    2 * pairs[i].correlation * gs0->s_std_dev * gs1->s_std_dev              )
1144                 / (n-1) )
1145         ;
1146
1147       tab_float(trb->t, 7, i+3, TAB_RIGHT, t , 8,3 );
1148
1149       /* Degrees of freedom */
1150       tab_float(trb->t, 8, i+3, TAB_RIGHT, df , 2, 0 );
1151
1152       which=1;
1153       cdft(&which, &p, &q, &t, &df, &status, &bound);
1154
1155       if ( 0 != status )
1156         {
1157           msg( SE, _("Error calculating T statistic (cdft returned %d)."),status);
1158         }
1159
1160
1161       tab_float(trb->t, 9, i+3, TAB_RIGHT, 2.0*(t>0?q:p) , 8, 3);
1162
1163     }
1164 }
1165
1166 /* Initialize the one sample trbox */
1167 void 
1168 trbox_one_sample_init(struct trbox *self, struct cmd_t_test *cmd )
1169 {
1170   const int hsize=7;
1171   const int vsize=cmd->n_variables+3;
1172
1173   self->populate = trbox_one_sample_populate;
1174
1175   trbox_base_init(self, cmd->n_variables,hsize);
1176   tab_title (self->t, 0, _("One-Sample Test"));
1177   tab_hline(self->t, TAL_1, 1, hsize - 1, 1);
1178   tab_vline(self->t, TAL_2, 1, 0, vsize);
1179
1180   tab_joint_text(self->t, 1, 0, hsize-1,0, TAB_CENTER | TAT_PRINTF, 
1181                  _("Test Value = %f"),cmd->n_testval);
1182
1183   tab_box(self->t, -1, -1, -1, TAL_1, 1,1,hsize-1,vsize-1);
1184
1185
1186   tab_joint_text(self->t,5,1,6,1,TAB_CENTER  | TAT_PRINTF, 
1187                  _("%d%% Confidence Interval of the Difference"),
1188                  (int)round(cmd->criteria*100.0));
1189
1190   tab_vline(self->t,TAL_0,6,1,1);
1191   tab_hline(self->t,TAL_1,5,6,2);
1192   tab_text (self->t, 1, 2, TAB_CENTER | TAT_TITLE, _("t"));
1193   tab_text (self->t, 2, 2, TAB_CENTER | TAT_TITLE, _("df"));
1194   tab_text (self->t, 3, 2, TAB_CENTER | TAT_TITLE, _("Sig. (2-tailed)"));
1195   tab_text (self->t, 4, 2, TAB_CENTER | TAT_TITLE, _("Mean Difference"));
1196   tab_text (self->t, 5, 2, TAB_CENTER | TAT_TITLE, _("Lower"));
1197   tab_text (self->t, 6, 2, TAB_CENTER | TAT_TITLE, _("Upper"));
1198
1199 }
1200
1201
1202 /* Populate the one sample trbox */
1203 void 
1204 trbox_one_sample_populate(struct trbox *trb, struct cmd_t_test *cmd)
1205 {
1206   int i;
1207
1208   assert(trb->t);
1209
1210   for (i=0; i < cmd->n_variables; ++i)
1211     {
1212       int which =1;
1213       double t;
1214       double p,q;
1215       double df;
1216       int status;
1217       double bound;
1218       struct group_statistics *gs;
1219       gs= &cmd->v_variables[i]->p.t_t.ugs;
1220
1221
1222       tab_text (trb->t, 0, i+3, TAB_LEFT, cmd->v_variables[i]->name);
1223
1224       t = (gs->mean - cmd->n_testval ) * sqrt(gs->n) / gs->std_dev ;
1225
1226       tab_float (trb->t, 1, i+3, TAB_RIGHT, t, 8,3);
1227
1228       /* degrees of freedom */
1229       df = gs->n - 1;
1230
1231       tab_float (trb->t, 2, i+3, TAB_RIGHT, df, 8,0);
1232
1233       cdft(&which, &p, &q, &t, &df, &status, &bound);
1234
1235       if ( 0 != status )
1236         {
1237           msg( SE, _("Error calculating T statistic (cdft returned %d)."),status);
1238         }
1239
1240
1241       /* Multiply by 2 to get 2-tailed significance, makeing sure we've got 
1242          the correct tail*/
1243       tab_float (trb->t, 3, i+3, TAB_RIGHT, 2.0*(t>0?q:p), 8,3);
1244
1245       tab_float (trb->t, 4, i+3, TAB_RIGHT, gs->mean_diff, 8,3);
1246
1247
1248       q = (1 - cmd->criteria)/2.0;  /* 2-tailed test */
1249       p = 1 - q ;
1250       which=2; /* Calc T from p,q and df */
1251       cdft(&which, &p, &q, &t, &df, &status, &bound);
1252       if ( 0 != status )
1253         {
1254           msg( SE, _("Error calculating T statistic (cdft returned %d)."),status);
1255         }
1256
1257       tab_float (trb->t, 5, i+3, TAB_RIGHT,
1258                  gs->mean_diff - t * gs->se_mean, 8,4);
1259
1260       tab_float (trb->t, 6, i+3, TAB_RIGHT,
1261                  gs->mean_diff + t * gs->se_mean, 8,4);
1262     }
1263 }
1264
1265 /* Base initializer for the generalized trbox */
1266 void 
1267 trbox_base_init(struct trbox *self, int data_rows, int cols)
1268 {
1269   const int rows = 3 + data_rows;
1270
1271   self->finalize = trbox_base_finalize;
1272   self->t = tab_create (cols, rows, 0);
1273   tab_headers (self->t,0,0,3,0); 
1274   tab_box (self->t, TAL_2, TAL_2, TAL_0, TAL_0, 0, 0, cols -1, rows -1);
1275   tab_hline(self->t, TAL_2,0,cols-1,3);
1276   tab_dim (self->t, tab_natural_dimensions);
1277 }
1278
1279
1280 /* Base finalizer for the trbox */
1281 void 
1282 trbox_base_finalize(struct trbox *trb)
1283 {
1284   tab_submit(trb->t);
1285 }
1286
1287
1288 /* Create , populate and submit the Paired Samples Correlation box */
1289 void
1290 pscbox(void)
1291 {
1292   const int rows=1+n_pairs;
1293   const int cols=5;
1294   int i;
1295   
1296   struct tab_table *table;
1297   
1298   table = tab_create (cols,rows,0);
1299
1300   tab_columns (table, SOM_COL_DOWN, 1);
1301   tab_headers (table,0,0,1,0); 
1302   tab_box (table, TAL_2, TAL_2, TAL_0, TAL_1, 0, 0, cols -1, rows -1 );
1303   tab_hline(table, TAL_2, 0, cols - 1, 1);
1304   tab_vline(table, TAL_2, 2, 0, rows - 1);
1305   tab_dim(table, tab_natural_dimensions);
1306   tab_title(table, 0, _("Paired Samples Correlations"));
1307
1308   /* column headings */
1309   tab_text(table, 2,0, TAB_CENTER | TAT_TITLE, _("N"));
1310   tab_text(table, 3,0, TAB_CENTER | TAT_TITLE, _("Correlation"));
1311   tab_text(table, 4,0, TAB_CENTER | TAT_TITLE, _("Sig."));
1312
1313   for (i=0; i < n_pairs; ++i)
1314     {
1315       int which =1;
1316       double p,q;
1317
1318       int status;
1319       double bound;
1320
1321       double df = pairs[i].v[0]->p.t_t.ugs.n -2;
1322
1323       double correlation_t = 
1324         pairs[i].correlation * sqrt(df) /
1325         sqrt(1 - sqr(pairs[i].correlation));
1326
1327
1328       /* row headings */
1329       tab_text(table, 0,i+1, TAB_LEFT | TAT_TITLE | TAT_PRINTF, 
1330                _("Pair %d"), i);
1331       
1332       tab_text(table, 1,i+1, TAB_LEFT | TAT_TITLE | TAT_PRINTF, 
1333                _("%s & %s"), pairs[i].v[0]->name, pairs[i].v[1]->name);
1334
1335
1336       /* row data */
1337       tab_float(table, 3, i+1, TAB_RIGHT, pairs[i].correlation, 8, 3);
1338       tab_float(table, 2, i+1, TAB_RIGHT, pairs[i].v[0]->p.t_t.ugs.n , 4, 0);
1339
1340
1341       cdft(&which, &p, &q, &correlation_t, &df, &status, &bound);
1342
1343       if ( 0 != status )
1344         {
1345           msg( SE, _("Error calculating T statistic (cdft returned %d)."),status);
1346         }
1347
1348
1349       tab_float(table, 4, i+1, TAB_RIGHT, 2.0*(correlation_t>0?q:p), 8, 3);
1350       
1351     }
1352
1353   tab_submit(table);
1354 }
1355
1356
1357
1358 /* Calculation Implementation */
1359
1360 /* Per case calculations common to all variants of the T test */
1361 static int 
1362 common_calc (struct ccase *c, void *aux UNUSED)
1363 {
1364   int i;
1365
1366   double weight = dict_get_case_weight(default_dict,c);
1367
1368   for(i=0; i< cmd.n_variables ; ++i) 
1369     {
1370       struct group_statistics *gs;
1371       struct variable *v = cmd.v_variables[i];
1372       union value *val = &c->data[v->fv];
1373
1374       gs= &cmd.v_variables[i]->p.t_t.ugs;
1375
1376       if (val->f != SYSMIS) 
1377         {
1378           gs->n+=weight;
1379           gs->sum+=weight * val->f;
1380           gs->ssq+=weight * val->f * val->f;
1381         }
1382     }
1383   return 0;
1384 }
1385
1386 /* Pre calculations common to all variants of the T test */
1387 static void 
1388 common_precalc (void *aux UNUSED)
1389 {
1390   int i=0;
1391
1392   for(i=0; i< cmd.n_variables ; ++i) 
1393     {
1394       struct group_statistics *gs;
1395       gs= &cmd.v_variables[i]->p.t_t.ugs;
1396       
1397       gs->sum=0;
1398       gs->n=0;
1399       gs->ssq=0;
1400       gs->sum_diff=0;
1401     }
1402 }
1403
1404 /* Post calculations common to all variants of the T test */
1405 void 
1406 common_postcalc (void *aux UNUSED)
1407 {
1408   int i=0;
1409
1410   for(i=0; i< cmd.n_variables ; ++i) 
1411     {
1412       struct group_statistics *gs;
1413       gs= &cmd.v_variables[i]->p.t_t.ugs;
1414       
1415       gs->mean=gs->sum / gs->n;
1416       gs->s_std_dev= sqrt(
1417                          ( (gs->ssq / gs->n ) - gs->mean * gs->mean )
1418                          ) ;
1419
1420       gs->std_dev= sqrt(
1421                          gs->n/(gs->n-1) *
1422                          ( (gs->ssq / gs->n ) - gs->mean * gs->mean )
1423                          ) ;
1424
1425       gs->se_mean = gs->std_dev / sqrt(gs->n);
1426       gs->mean_diff= gs->sum_diff / gs->n;
1427     }
1428 }
1429
1430 /* Per case calculations for one sample t test  */
1431 static int 
1432 one_sample_calc (struct ccase *c, void *aux UNUSED)
1433 {
1434   int i;
1435
1436   double weight = dict_get_case_weight(default_dict,c);
1437
1438   for(i=0; i< cmd.n_variables ; ++i) 
1439     {
1440       struct group_statistics *gs;
1441       struct variable *v = cmd.v_variables[i];
1442       union value *val = &c->data[v->fv];
1443
1444       gs= &cmd.v_variables[i]->p.t_t.ugs;
1445       
1446       if (val->f != SYSMIS) 
1447         gs->sum_diff += weight * (val->f - cmd.n_testval);
1448     }
1449
1450   return 0;
1451 }
1452
1453 /* Pre calculations for one sample t test */
1454 static void 
1455 one_sample_precalc (void *aux UNUSED)
1456 {
1457   int i=0;
1458   
1459   for(i=0; i< cmd.n_variables ; ++i) 
1460     {
1461       struct group_statistics *gs;
1462       gs= &cmd.v_variables[i]->p.t_t.ugs;
1463       
1464       gs->sum_diff=0;
1465     }
1466 }
1467
1468 /* Post calculations for one sample t test */
1469 static void 
1470 one_sample_postcalc (void *aux UNUSED)
1471 {
1472   int i=0;
1473   
1474   for(i=0; i< cmd.n_variables ; ++i) 
1475     {
1476       struct group_statistics *gs;
1477       gs= &cmd.v_variables[i]->p.t_t.ugs;
1478
1479       
1480       gs->mean_diff = gs->sum_diff / gs->n ;
1481     }
1482 }
1483
1484
1485
1486 static int
1487 compare_var_name (const void *a_, const void *b_, void *v_ UNUSED)
1488 {
1489   const struct variable *a = a_;
1490   const struct variable *b = b_;
1491
1492   return strcmp(a->name,b->name);
1493 }
1494
1495 static unsigned
1496 hash_var_name (const void *a_, void *v_ UNUSED)
1497 {
1498   const struct variable *a = a_;
1499
1500   return hsh_hash_bytes (a->name, strlen(a->name));
1501 }
1502
1503
1504
1505 static void 
1506 paired_precalc (void *aux UNUSED)
1507 {
1508   int i;
1509
1510   for(i=0; i < n_pairs ; ++i )
1511     {
1512       pairs[i].correlation=0;
1513       pairs[i].sum_of_diffs=0;
1514       pairs[i].ssq_diffs=0;
1515     }
1516
1517 }
1518
1519
1520 static int  
1521 paired_calc (struct ccase *c, void *aux UNUSED)
1522 {
1523   int i;
1524
1525   for(i=0; i < n_pairs ; ++i )
1526     {
1527       struct variable *v0 = pairs[i].v[0];
1528       struct variable *v1 = pairs[i].v[1];
1529
1530       union value *val0 = &c->data[v0->fv];
1531       union value *val1 = &c->data[v1->fv];
1532
1533       pairs[i].correlation += ( val0->f - pairs[i].v[0]->p.t_t.ugs.mean )
1534                               *
1535                               ( val1->f - pairs[i].v[1]->p.t_t.ugs.mean );
1536
1537       pairs[i].sum_of_diffs += val0->f - val1->f ;
1538       pairs[i].ssq_diffs += sqr(val0->f - val1->f);
1539
1540     }
1541
1542   return 0;
1543 }
1544
1545 static void 
1546 paired_postcalc (void *aux UNUSED)
1547 {
1548   int i;
1549
1550   for(i=0; i < n_pairs ; ++i )
1551     {
1552       const double n = pairs[i].v[0]->p.t_t.ugs.n ;
1553       
1554       pairs[i].correlation /= pairs[i].v[0]->p.t_t.ugs.std_dev * 
1555                               pairs[i].v[1]->p.t_t.ugs.std_dev ;
1556       pairs[i].correlation /= pairs[i].v[0]->p.t_t.ugs.n -1; 
1557
1558
1559       pairs[i].mean_diff = pairs[i].sum_of_diffs / n ;
1560
1561
1562       pairs[i].std_dev_diff = sqrt (  n / (n - 1) * (
1563                                     ( pairs[i].ssq_diffs / n )
1564                                     - 
1565                                     sqr(pairs[i].mean_diff )
1566                                     ) );
1567     }
1568 }
1569
1570 static int
1571 get_group(const union value *val, struct variable *var)
1572 {
1573   if ( 0 == compare_values(val,&groups_values[0],var->width) )
1574     return 0;
1575   else if (0 == compare_values(val,&groups_values[1],var->width) )
1576     return 1;
1577
1578   /* Never reached */
1579   assert(0);
1580   return -1;
1581 }
1582
1583
1584 static void 
1585 group_precalc (void *aux UNUSED)
1586 {
1587   int i;
1588   int j;
1589
1590   for(i=0; i< cmd.n_variables ; ++i) 
1591     {
1592       struct t_test_proc *ttpr = &cmd.v_variables[i]->p.t_t;
1593
1594       /* There's always 2 groups for a T - TEST */
1595       ttpr->n_groups = 2;
1596       ttpr->gs = xmalloc(sizeof(struct group_statistics) * 2) ;
1597
1598       for (j=0 ; j < 2 ; ++j)
1599         {
1600           ttpr->gs[j].sum=0;
1601           ttpr->gs[j].n=0;
1602           ttpr->gs[j].ssq=0;
1603           ttpr->gs[j].id = groups_values[j];
1604         }
1605     }
1606
1607 }
1608
1609 static int  
1610 group_calc (struct ccase *c, void *aux UNUSED)
1611 {
1612   int i;
1613   union value *gv = &c->data[groups->fv];
1614
1615   double weight = dict_get_case_weight(default_dict,c);
1616
1617   gv = &c->data[groups->fv];
1618
1619   for(i=0; i< cmd.n_variables ; ++i) 
1620     {
1621       int g = get_group(gv,groups);
1622
1623       struct group_statistics *gs = &cmd.v_variables[i]->p.t_t.gs[g];
1624
1625       union value *val=&c->data[cmd.v_variables[i]->fv];
1626
1627       gs->n+=weight;
1628       gs->sum+=weight * val->f;
1629       gs->ssq+=weight * sqr(val->f);
1630     }
1631
1632   return 0;
1633 }
1634
1635
1636 static void 
1637 group_postcalc (void *aux UNUSED)
1638 {
1639   int i;
1640   int j;
1641
1642   for(i=0; i< cmd.n_variables ; ++i) 
1643     {
1644       for (j=0 ; j < 2 ; ++j)
1645         {
1646           struct group_statistics *gs;
1647           gs=&cmd.v_variables[i]->p.t_t.gs[j];
1648
1649           gs->mean = gs->sum / gs->n;
1650           
1651           gs->s_std_dev= sqrt(
1652                          ( (gs->ssq / gs->n ) - gs->mean * gs->mean )
1653                          ) ;
1654
1655           gs->std_dev= sqrt(
1656                          gs->n/(gs->n-1) *
1657                          ( (gs->ssq / gs->n ) - gs->mean * gs->mean )
1658                          ) ;
1659           
1660           gs->se_mean = gs->std_dev / sqrt(gs->n);
1661         }
1662     }
1663 }
1664