81c9c2aa0238b5ebf86a5792eb5fae8887270462
[pspp] / 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
41 /* (specification)
42    "T-TEST" (tts_):
43      groups=custom;
44      testval=double;
45      variables=varlist("PV_NO_SCRATCH | PV_NUMERIC");
46      pairs=custom;
47      +missing=miss:!analysis/listwise,
48              incl:include/!exclude;
49      format=fmt:!labels/nolabels;
50      criteria=:cin(d:criteria,"%s > 0. && %s < 1.").
51 */
52 /* (declarations) */
53 /* (functions) */
54
55 static struct cmd_t_test cmd;
56
57
58
59 static struct pool *t_test_pool ;
60
61 /* Variable for the GROUPS subcommand, if given. */
62 static struct variable *groups;
63
64 /* GROUPS: Number of values specified by the user; the values
65    specified if any. */
66 static int n_groups_values;
67 static union value groups_values[2];
68
69 /* PAIRS: Number of pairs to be compared ; each pair. */
70 static int n_pairs ;
71 typedef struct variable *pair_t[2] ;
72 static pair_t *pairs;
73
74
75 static int parse_value (union value * v, int type) ;
76
77
78 /* Structures and Functions for the Statistics Summary Box */
79 struct ssbox;
80 typedef void populate_ssbox_func(struct ssbox *ssb,
81                                             struct cmd_t_test *cmd);
82 typedef void finalize_ssbox_func(struct ssbox *ssb);
83
84 struct ssbox
85 {
86   struct tab_table *t;
87
88   populate_ssbox_func *populate;
89   finalize_ssbox_func *finalize;
90
91 };
92
93 /* Create a ssbox */
94 void ssbox_create(struct ssbox *ssb,   struct cmd_t_test *cmd, int mode);
95
96 /* Populate a ssbox according to cmd */
97 void ssbox_populate(struct ssbox *ssb, struct cmd_t_test *cmd);
98
99 /* Submit and destroy a ssbox */
100 void ssbox_finalize(struct ssbox *ssb);
101
102
103
104 /* Structures and Functions for the Test Results Box */
105 struct trbox;
106
107 typedef void populate_trbox_func(struct trbox *trb,
108                                  struct cmd_t_test *cmd);
109 typedef void finalize_trbox_func(struct trbox *trb);
110
111 struct trbox {
112   struct tab_table *t;
113   populate_trbox_func *populate;
114   finalize_trbox_func *finalize;
115 };
116
117 /* Create a trbox */
118 void trbox_create(struct trbox *trb,   struct cmd_t_test *cmd, int mode);
119
120 /* Populate a ssbox according to cmd */
121 void trbox_populate(struct trbox *trb, struct cmd_t_test *cmd);
122
123 /* Submit and destroy a ssbox */
124 void trbox_finalize(struct trbox *trb);
125
126 /* Which mode was T-TEST invoked */
127 enum {
128   T_1_SAMPLE = 0 ,
129   T_IND_SAMPLES, 
130   T_PAIRED
131 };
132
133
134 static int common_calc (struct ccase *);
135 static void common_precalc (void);
136 static void common_postcalc (void);
137
138 static int one_sample_calc (struct ccase *);
139 static void one_sample_precalc (void);
140 static void one_sample_postcalc (void);
141
142
143 int
144 cmd_t_test(void)
145 {
146   int mode;
147
148   struct ssbox stat_summary_box;
149   struct trbox test_results_box;
150
151   if (!lex_force_match_id ("T"))
152     return CMD_FAILURE;
153
154   lex_match ('-');
155   lex_match_id ("TEST");
156
157   if ( !parse_t_test(&cmd) )
158     return CMD_FAILURE;
159
160   if (! cmd.sbc_criteria)
161     cmd.criteria=0.95;
162
163   if ( cmd.sbc_testval + cmd.sbc_groups + cmd.sbc_pairs != 1 ) 
164     {
165       msg(SE, 
166           _("Exactly one of TESTVAL, GROUPS or PAIRS subcommands is required")
167           );
168       return CMD_FAILURE;
169     }
170
171   if (cmd.sbc_testval) 
172     mode=T_1_SAMPLE;
173   else if (cmd.sbc_groups)
174     mode=T_IND_SAMPLES;
175   else
176     mode=T_PAIRED;
177
178   if ( mode == T_PAIRED && cmd.sbc_variables) 
179     {
180       msg(SE, _("VARIABLES subcommand is not appropriate with PAIRS"));
181       return CMD_FAILURE;
182     }
183
184   procedure(common_precalc,common_calc,common_postcalc);
185
186   if (mode == T_1_SAMPLE)
187     procedure(one_sample_precalc,one_sample_calc,one_sample_postcalc);
188
189   t_test_pool = pool_create ();
190
191   ssbox_create(&stat_summary_box,&cmd,mode);
192   trbox_create(&test_results_box,&cmd,mode);
193
194   ssbox_populate(&stat_summary_box,&cmd);
195   trbox_populate(&test_results_box,&cmd);
196
197   ssbox_finalize(&stat_summary_box);
198   trbox_finalize(&test_results_box);
199
200   pool_destroy (t_test_pool);
201
202   t_test_pool=0;
203     
204   return CMD_SUCCESS;
205 }
206
207 static int
208 tts_custom_groups (struct cmd_t_test *cmd unused)
209 {
210   lex_match('=');
211
212   if (token != T_ALL && 
213       (token != T_ID || dict_lookup_var (default_dict, tokid) == NULL)
214      ) 
215   {
216     msg(SE,_("`%s' is not a variable name"),tokid);
217     return 0;
218   }
219
220   groups = parse_variable ();
221   if (!groups)
222     {
223       lex_error ("expecting variable name in GROUPS subcommand");
224       return 0;
225     }
226
227   if (groups->type == T_STRING && groups->width > MAX_SHORT_STRING)
228     {
229       msg (SE, _("Long string variable %s is not valid here."),
230            groups->name);
231       return 0;
232     }
233
234   if (!lex_match ('('))
235     {
236       if (groups->type == NUMERIC)
237         {
238           n_groups_values = 2;
239           groups_values[0].f = 1;
240           groups_values[1].f = 2;
241           return 1;
242         }
243       else
244         {
245           msg (SE, _("When applying GROUPS to a string variable, at "
246                      "least one value must be specified."));
247           return 0;
248         }
249     }
250
251   if (!parse_value (&groups_values[0],groups->type))
252     return 0;
253   n_groups_values = 1;
254
255   lex_match (',');
256   if (lex_match (')'))
257     return 1;
258
259   if (!parse_value (&groups_values[1],groups->type))
260     return 0;
261   n_groups_values = 2;
262
263   if (!lex_force_match (')'))
264     return 0;
265
266   return 1;
267 }
268
269
270
271
272 static int
273 tts_custom_pairs (struct cmd_t_test *cmd unused)
274 {
275   struct variable **vars;
276   int n_vars;
277
278   int n_before_WITH ;
279   int n_after_WITH = -1;
280   int paired ; /* Was the PAIRED keyword given ? */
281
282   lex_match('=');
283
284   if ((token != T_ID || dict_lookup_var (default_dict, tokid) == NULL)
285       && token != T_ALL)
286     {
287       msg(SE,_("`%s' is not a variable name"),tokid);
288       return 0;
289     }
290
291   n_vars=0;
292   if (!parse_variables (default_dict, &vars, &n_vars,
293                         PV_DUPLICATE | PV_NUMERIC | PV_NO_SCRATCH))
294     {
295       free (vars);
296       return 0;
297     }
298   assert (n_vars);
299
300   n_before_WITH=0;
301   if (lex_match (T_WITH))
302     {
303       n_before_WITH = n_vars;
304       if (!parse_variables (default_dict, &vars, &n_vars,
305                             PV_DUPLICATE | PV_APPEND
306                             | PV_NUMERIC | PV_NO_SCRATCH))
307         {
308           free (vars);
309           return 0;
310         }
311       n_after_WITH = n_vars - n_before_WITH;
312     }
313
314   paired = (lex_match ('(') && lex_match_id ("PAIRED") && lex_match (')'));
315
316   /* Determine the number of pairs needed */
317   if (paired)
318     {
319       if (n_before_WITH != n_after_WITH)
320         {
321           free (vars);
322           msg (SE, _("PAIRED was specified but the number of variables "
323                      "preceding WITH (%d) did not match the number "
324                      "following (%d)."),
325                n_before_WITH, n_after_WITH );
326           return 0;
327         }
328       n_pairs=n_before_WITH;
329     }
330   else if (n_before_WITH > 0) /* WITH keyword given, but not PAIRED keyword */
331     {
332       n_pairs=n_before_WITH * n_after_WITH ;
333     }
334   else /* Neither WITH nor PAIRED keyword given */
335     {
336       if (n_vars < 2)
337         {
338           free (vars);
339           msg (SE, _("At least two variables must be specified "
340                      "on PAIRS."));
341           return 0;
342         }
343
344       /* how many ways can you pick 2 from n_vars ? */
345       n_pairs = n_vars * (n_vars -1 ) /2 ;
346     }
347
348   /* Allocate storage for the pairs */
349   pairs = xrealloc(pairs,sizeof(pair_t) *n_pairs);
350
351   /* Populate the pairs with the appropriate variables */
352   if ( paired ) 
353     {
354       int i;
355
356       assert(n_pairs == n_vars/2);
357       for (i = 0; i < n_pairs ; ++i)
358         {
359           pairs[i][0] = vars[i];
360           pairs[i][1] = vars[i+n_pairs];
361         }
362     }
363   else if (n_before_WITH > 0) /* WITH keyword given, but not PAIRED keyword */
364     {
365       int i,j;
366       int p=0;
367
368       for(i=0 ; i < n_before_WITH ; ++i ) 
369         {
370           for(j=0 ; j < n_after_WITH ; ++j)
371             {
372               pairs[p][0] = vars[i];
373               pairs[p][1] = vars[j+n_before_WITH];
374               ++p;
375             }
376         }
377     }
378   else /* Neither WITH nor PAIRED given */
379     {
380       int i,j;
381       int p=0;
382       
383       for(i=0 ; i < n_vars ; ++i ) 
384         {
385           for(j=i+1 ; j < n_vars ; ++j)
386             {
387               pairs[p][0] = vars[i];
388               pairs[p][1] = vars[j];
389               ++p;
390             }
391         }
392     }
393
394   return 1;
395 }
396
397 /* Parses the current token (numeric or string, depending on type)
398     value v and returns success. */
399 static int
400 parse_value (union value * v, int type )
401 {
402   if (type == NUMERIC)
403     {
404       if (!lex_force_num ())
405         return 0;
406       v->f = tokval;
407     }
408   else
409     {
410       if (!lex_force_string ())
411         return 0;
412       strncpy (v->s, ds_value (&tokstr), ds_length (&tokstr));
413     }
414
415   lex_get ();
416
417   return 1;
418 }
419
420
421 /* Implementation of the SSBOX object */
422
423 void ssbox_base_init(struct ssbox *this, int cols,int rows);
424
425 void ssbox_base_finalize(struct ssbox *ssb);
426
427 void ssbox_one_sample_init(struct ssbox *this, 
428                            struct cmd_t_test *cmd );
429
430 void ssbox_independent_samples_init(struct ssbox *this,
431                                     struct cmd_t_test *cmd);
432
433 void ssbox_paired_init(struct ssbox *this,
434                            struct cmd_t_test *cmd);
435
436 /* Factory to create an ssbox */
437 void 
438 ssbox_create(struct ssbox *ssb, struct cmd_t_test *cmd, int mode)
439 {
440     switch (mode) 
441       {
442       case T_1_SAMPLE:
443         ssbox_one_sample_init(ssb,cmd);
444         break;
445       case T_IND_SAMPLES:
446         ssbox_independent_samples_init(ssb,cmd);
447         break;
448       case T_PAIRED:
449         ssbox_paired_init(ssb,cmd);
450         break;
451       default:
452         assert(0);
453       }
454 }
455
456
457 /* Despatcher for the populate method */
458 void
459 ssbox_populate(struct ssbox *ssb,struct cmd_t_test *cmd)
460 {
461   ssb->populate(ssb,cmd);
462 }
463
464
465 /* Despatcher for finalize */
466 void
467 ssbox_finalize(struct ssbox *ssb)
468 {
469   ssb->finalize(ssb);
470 }
471
472
473 /* Submit the box and clear up */
474 void 
475 ssbox_base_finalize(struct ssbox *ssb)
476 {
477   tab_submit(ssb->t);
478 }
479
480 /* Initialize a ssbox struct */
481 void 
482 ssbox_base_init(struct ssbox *this, int cols,int rows)
483 {
484   this->finalize = ssbox_base_finalize;
485   this->t = tab_create (cols, rows, 0);
486
487   tab_columns (this->t, SOM_COL_DOWN, 1);
488   tab_headers (this->t,0,0,1,0); 
489   tab_box (this->t, TAL_2, TAL_2, TAL_0, TAL_1, 0, 0, cols -1, rows -1 );
490   tab_hline(this->t, TAL_2,0,cols-1,1);
491   tab_dim (this->t, tab_natural_dimensions);
492 }
493
494 void  ssbox_one_sample_populate(struct ssbox *ssb,
495                               struct cmd_t_test *cmd);
496
497 /* Initialize the one_sample ssbox */
498 void 
499 ssbox_one_sample_init(struct ssbox *this, 
500                            struct cmd_t_test *cmd )
501 {
502   const int hsize=5;
503   const int vsize=cmd->n_variables+1;
504
505   this->populate = ssbox_one_sample_populate;
506
507   ssbox_base_init(this, hsize,vsize);
508   tab_title (this->t, 0, _("One-Sample Statistics"));
509   tab_vline(this->t, TAL_2, 1,0,vsize);
510   tab_text (this->t, 1, 0, TAB_CENTER | TAT_TITLE, _("N"));
511   tab_text (this->t, 2, 0, TAB_CENTER | TAT_TITLE, _("Mean"));
512   tab_text (this->t, 3, 0, TAB_CENTER | TAT_TITLE, _("Std. Deviation"));
513   tab_text (this->t, 4, 0, TAB_CENTER | TAT_TITLE, _("SE. Mean"));
514 }
515
516 void ssbox_independent_samples_populate(struct ssbox *ssb,
517                                         struct cmd_t_test *cmd);
518
519 /* Initialize the independent samples ssbox */
520 void 
521 ssbox_independent_samples_init(struct ssbox *this, 
522         struct cmd_t_test *cmd)
523 {
524   int hsize=6;
525   int vsize = cmd->n_variables*2 +1;
526
527   this->populate = ssbox_independent_samples_populate;
528
529   ssbox_base_init(this, hsize,vsize);
530   tab_title (this->t, 0, _("Group Statistics"));
531   tab_vline(this->t,0,1,0,vsize);
532   tab_text (this->t, 1, 0, TAB_CENTER | TAT_TITLE, groups->name);
533   tab_text (this->t, 2, 0, TAB_CENTER | TAT_TITLE, _("N"));
534   tab_text (this->t, 3, 0, TAB_CENTER | TAT_TITLE, _("Mean"));
535   tab_text (this->t, 4, 0, TAB_CENTER | TAT_TITLE, _("Std. Deviation"));
536   tab_text (this->t, 5, 0, TAB_CENTER | TAT_TITLE, _("SE. Mean"));
537 }
538
539
540 /* Populate the ssbox for independent samples */
541 void 
542 ssbox_independent_samples_populate(struct ssbox *ssb,
543                               struct cmd_t_test *cmd)
544 {
545   int i;
546
547   char *val_lab1=0;
548   char *val_lab2=0;
549
550   if ( groups->type == NUMERIC ) 
551     {
552       val_lab1 = val_labs_find( groups->val_labs,groups_values[0]); 
553       val_lab2 = val_labs_find( groups->val_labs,groups_values[1]);
554     }
555   else
556     {
557       val_lab1 = groups_values[0].s;
558       val_lab2 = groups_values[1].s;
559     }
560
561   assert(ssb->t);
562
563   for (i=0; i < cmd->n_variables; ++i)
564     {
565       tab_text (ssb->t, 0, i*2+1, TAB_LEFT, cmd->v_variables[i]->name);
566
567       if (val_lab1)
568         tab_text (ssb->t, 1, i*2+1, TAB_LEFT, val_lab1);
569       else
570         tab_float(ssb->t, 1 ,i*2+1, TAB_LEFT, groups_values[0].f, 2,0);
571
572       if (val_lab2)
573         tab_text (ssb->t, 1, i*2+1+1, TAB_LEFT, val_lab2);
574       else
575         tab_float(ssb->t, 1 ,i*2+1+1, TAB_LEFT, groups_values[1].f,2,0);
576     }
577 }
578
579
580 void ssbox_paired_populate(struct ssbox *ssb,
581                            struct cmd_t_test *cmd);
582
583 /* Initialize the paired values ssbox */
584 void 
585 ssbox_paired_init(struct ssbox *this, struct cmd_t_test *cmd unused)
586 {
587   int hsize=6;
588
589   int vsize = n_pairs*2+1;
590
591   this->populate = ssbox_paired_populate;
592
593   ssbox_base_init(this, hsize,vsize);
594   tab_title (this->t, 0, _("Paired Sample Statistics"));
595   tab_vline(this->t,TAL_0,1,0,vsize-1);
596   tab_vline(this->t,TAL_2,2,0,vsize-1);
597   tab_text (this->t, 2, 0, TAB_CENTER | TAT_TITLE, _("Mean"));
598   tab_text (this->t, 3, 0, TAB_CENTER | TAT_TITLE, _("N"));
599   tab_text (this->t, 4, 0, TAB_CENTER | TAT_TITLE, _("Std. Deviation"));
600   tab_text (this->t, 5, 0, TAB_CENTER | TAT_TITLE, _("SE. Mean"));
601 }
602
603
604 /* Populate the ssbox for paired values */
605 void 
606 ssbox_paired_populate(struct ssbox *ssb,struct cmd_t_test *cmd unused)
607 {
608   int i;
609   struct string ds;
610
611   assert(ssb->t);
612   ds_init(t_test_pool,&ds,15);
613
614   for (i=0; i < n_pairs; ++i)
615     {
616       ds_clear(&ds);
617
618       ds_printf(&ds,_("Pair %d"),i);
619
620       tab_text (ssb->t, 0, i*2+1, TAB_LEFT, ds.string);
621       tab_text (ssb->t, 1, i*2+1, TAB_LEFT, pairs[i][0]->name);
622       tab_text (ssb->t, 1, i*2+2, TAB_LEFT, pairs[i][1]->name);
623     }
624
625   ds_destroy(&ds);
626 }
627
628 /* Populate the one sample ssbox */
629 void 
630 ssbox_one_sample_populate(struct ssbox *ssb, struct cmd_t_test *cmd)
631 {
632   int i;
633
634   assert(ssb->t);
635
636   for (i=0; i < cmd->n_variables; ++i)
637     {
638       struct t_test_proc *ttp;
639       ttp= &cmd->v_variables[i]->p.t_t;
640
641       tab_text (ssb->t, 0, i+1, TAB_LEFT, cmd->v_variables[i]->name);
642       tab_float (ssb->t,1, i+1, TAB_RIGHT, ttp->n, 2, 0);
643       tab_float (ssb->t,2, i+1, TAB_RIGHT, ttp->mean, 8, 2);
644       tab_float (ssb->t,3, i+1, TAB_RIGHT, ttp->std_dev, 8, 2);
645       tab_float (ssb->t,4, i+1, TAB_RIGHT, ttp->se_mean, 8, 3);
646     }
647   
648 }
649
650
651
652 /* Implementation of the Test Results box struct */
653
654 void trbox_base_init(struct trbox *self,int n_vars, int cols);
655 void trbox_base_finalize(struct trbox *trb);
656
657 void trbox_independent_samples_init(struct trbox *trb,
658                                     struct cmd_t_test *cmd );
659
660 void trbox_independent_samples_populate(struct trbox *trb,
661                                         struct cmd_t_test *cmd);
662
663 void trbox_one_sample_init(struct trbox *self,
664                       struct cmd_t_test *cmd );
665
666 void trbox_one_sample_populate(struct trbox *trb,
667                                struct cmd_t_test *cmd);
668
669 void trbox_paired_init(struct trbox *self,
670                        struct cmd_t_test *cmd );
671
672 void trbox_paired_populate(struct trbox *trb,
673                       struct cmd_t_test *cmd);
674
675
676
677 /* Create a trbox according to mode*/
678 void 
679 trbox_create(struct trbox *trb,   
680              struct cmd_t_test *cmd, int mode)
681 {
682     switch (mode) 
683       {
684       case T_1_SAMPLE:
685         trbox_one_sample_init(trb,cmd);
686         break;
687       case T_IND_SAMPLES:
688         trbox_independent_samples_init(trb,cmd);
689         break;
690       case T_PAIRED:
691         trbox_paired_init(trb,cmd);
692         break;
693       default:
694         assert(0);
695       }
696 }
697
698 /* Populate a trbox according to cmd */
699 void 
700 trbox_populate(struct trbox *trb, struct cmd_t_test *cmd)
701 {
702   trb->populate(trb,cmd);
703 }
704
705 /* Submit and destroy a trbox */
706 void 
707 trbox_finalize(struct trbox *trb)
708 {
709   trb->finalize(trb);
710 }
711
712 /* Initialize the independent samples trbox */
713 void 
714 trbox_independent_samples_init(struct trbox *self,
715                            struct cmd_t_test *cmd unused)
716 {
717   const int hsize=11;
718   const int vsize=cmd->n_variables*2+3;
719
720   struct string ds;
721
722   assert(self);
723   self->populate = trbox_independent_samples_populate;
724
725   trbox_base_init(self,cmd->n_variables*2,hsize);
726   tab_title(self->t,0,_("Independent Samples Test"));
727   tab_hline(self->t,TAL_1,2,hsize-1,1);
728   tab_vline(self->t,TAL_2,2,0,vsize-1);
729   tab_vline(self->t,TAL_1,4,0,vsize-1);
730   tab_box(self->t,-1,-1,-1,TAL_1, 2,1,hsize-2,vsize-1);
731   tab_hline(self->t,TAL_1, hsize-2,hsize-1,2);
732   tab_box(self->t,-1,-1,-1,TAL_1, hsize-2,2,hsize-1,vsize-1);
733   tab_joint_text(self->t, 2, 0, 3, 0, 
734                  TAB_CENTER,_("Levine's Test for Equality of Variances"));
735   tab_joint_text(self->t, 4,0,hsize-1,0,
736                  TAB_CENTER,_("t-test for Equality of Means"));
737
738   tab_text(self->t,2,2, TAB_CENTER | TAT_TITLE,_("F"));
739   tab_text(self->t,3,2, TAB_CENTER | TAT_TITLE,_("Sig."));
740   tab_text(self->t,4,2, TAB_CENTER | TAT_TITLE,_("t"));
741   tab_text(self->t,5,2, TAB_CENTER | TAT_TITLE,_("df"));
742   tab_text(self->t,6,2, TAB_CENTER | TAT_TITLE,_("Sig. (2-tailed)"));
743   tab_text(self->t,7,2, TAB_CENTER | TAT_TITLE,_("Mean Difference"));
744   tab_text(self->t,8,2, TAB_CENTER | TAT_TITLE,_("Std. Error Difference"));
745   tab_text(self->t,9,2, TAB_CENTER | TAT_TITLE,_("Lower"));
746   tab_text(self->t,10,2, TAB_CENTER | TAT_TITLE,_("Upper"));
747
748   ds_init(t_test_pool,&ds,80);
749                 
750   ds_printf(&ds,_("%d%% Confidence Interval of the Difference"),
751             (int)round(cmd->criteria*100.0));
752
753   tab_joint_text(self->t,9,1,10,1,TAB_CENTER, ds.string);
754
755   ds_destroy(&ds);
756 }
757
758 /* Populate the independent samples trbox */
759 void 
760 trbox_independent_samples_populate(struct trbox *self,
761                                    struct cmd_t_test *cmd )
762 {
763   int i;
764
765   assert(self);
766   for (i=0; i < cmd->n_variables; ++i)
767     {
768       tab_text (self->t, 0, i*2+3, TAB_LEFT, cmd->v_variables[i]->name);
769
770       tab_text (self->t, 1, i*2+3, TAB_LEFT, _("Equal variances assumed"));
771
772       tab_text (self->t, 1, i*2+3+1, 
773                 TAB_LEFT, _("Equal variances not assumed"));
774     }
775 }
776
777 /* Initialize the paired samples trbox */
778 void 
779 trbox_paired_init(struct trbox *self,
780                            struct cmd_t_test *cmd unused)
781 {
782
783   const int hsize=10;
784   const int vsize=n_pairs*2+3;
785
786   struct string ds;
787
788   self->populate = trbox_paired_populate;
789
790   trbox_base_init(self,n_pairs*2,hsize);
791   tab_title (self->t, 0, _("Paired Samples Test"));
792   tab_hline(self->t,TAL_1,2,6,1);
793   tab_vline(self->t,TAL_2,2,0,vsize);
794   tab_joint_text(self->t,2,0,6,0,TAB_CENTER,_("Paired Differences"));
795   tab_box(self->t,-1,-1,-1,TAL_1, 2,1,6,vsize-1);
796   tab_box(self->t,-1,-1,-1,TAL_1, 6,0,hsize-1,vsize-1);
797   tab_hline(self->t,TAL_1,5,6, 2);
798   tab_vline(self->t,TAL_0,6,0,1);
799
800   ds_init(t_test_pool,&ds,80);
801                 
802   ds_printf(&ds,_("%d%% Confidence Interval of the Difference"),
803             (int)round(cmd->criteria*100.0));
804
805   tab_joint_text(self->t,5,1,6,1,TAB_CENTER, ds.string);
806
807   ds_destroy(&ds);
808
809   tab_text (self->t, 2, 2, TAB_CENTER | TAT_TITLE, _("Mean"));
810   tab_text (self->t, 3, 2, TAB_CENTER | TAT_TITLE, _("Std. Deviation"));
811   tab_text (self->t, 4, 2, TAB_CENTER | TAT_TITLE, _("Std. Error Mean"));
812   tab_text (self->t, 5, 2, TAB_CENTER | TAT_TITLE, _("Lower"));
813   tab_text (self->t, 6, 2, TAB_CENTER | TAT_TITLE, _("Upper"));
814   tab_text (self->t, 7, 2, TAB_CENTER | TAT_TITLE, _("t"));
815   tab_text (self->t, 8, 2, TAB_CENTER | TAT_TITLE, _("df"));
816   tab_text (self->t, 9, 2, TAB_CENTER | TAT_TITLE, _("Sig. (2-tailed)"));
817 }
818
819 /* Populate the paired samples trbox */
820 void 
821 trbox_paired_populate(struct trbox *trb,
822                               struct cmd_t_test *cmd unused)
823 {
824   int i;
825   struct string ds;
826
827   ds_init(t_test_pool,&ds,15);  
828
829   for (i=0; i < n_pairs; ++i)
830     {
831       ds_clear(&ds);
832       ds_printf(&ds,_("Pair %d"),i);
833
834       tab_text (trb->t, 0, i*2+3, TAB_LEFT, ds.string);
835       tab_text (trb->t, 1, i*2+3, TAB_LEFT, pairs[i][0]->name);
836       tab_text (trb->t, 1, i*2+4, TAB_LEFT, pairs[i][1]->name);
837     }
838   ds_destroy(&ds);
839 }
840
841 /* Initialize the one sample trbox */
842 void 
843 trbox_one_sample_init(struct trbox *self, struct cmd_t_test *cmd )
844 {
845   const int hsize=7;
846   const int vsize=cmd->n_variables+3;
847
848   struct string ds;
849   
850   self->populate = trbox_one_sample_populate;
851
852   trbox_base_init(self, cmd->n_variables,hsize);
853   tab_title (self->t, 0, _("One-Sample Test"));
854   tab_hline(self->t, TAL_1, 1, hsize - 1, 1);
855   tab_vline(self->t, TAL_2, 1, 0, vsize);
856   ds_init(t_test_pool, &ds, 80);
857   ds_printf(&ds,_("Test Value = %f"),cmd->n_testval);
858   tab_joint_text(self->t, 1, 0, hsize-1,0, TAB_CENTER,ds.string);
859   tab_box(self->t, -1, -1, -1, TAL_1, 1,1,hsize-1,vsize-1);
860
861   ds_clear(&ds);
862   ds_printf(&ds,_("%d%% Confidence Interval of the Difference"),
863             (int)round(cmd->criteria*100.0));
864   tab_joint_text(self->t,5,1,6,1,TAB_CENTER, ds.string);
865   ds_destroy(&ds);
866   tab_vline(self->t,TAL_0,6,1,1);
867   tab_hline(self->t,TAL_1,5,6,2);
868   tab_text (self->t, 1, 2, TAB_CENTER | TAT_TITLE, _("t"));
869   tab_text (self->t, 2, 2, TAB_CENTER | TAT_TITLE, _("df"));
870   tab_text (self->t, 3, 2, TAB_CENTER | TAT_TITLE, _("Sig. (2-tailed)"));
871   tab_text (self->t, 4, 2, TAB_CENTER | TAT_TITLE, _("Mean Difference"));
872   tab_text (self->t, 5, 2, TAB_CENTER | TAT_TITLE, _("Lower"));
873   tab_text (self->t, 6, 2, TAB_CENTER | TAT_TITLE, _("Upper"));
874
875 }
876
877
878 /* Populate the one sample trbox */
879 void 
880 trbox_one_sample_populate(struct trbox *trb, struct cmd_t_test *cmd)
881 {
882   int i;
883
884   assert(trb->t);
885
886   for (i=0; i < cmd->n_variables; ++i)
887     {
888       int which =1;
889       double t;
890       double p,q;
891       double df;
892       int status;
893       double bound;
894       struct t_test_proc *ttp;
895       ttp= &cmd->v_variables[i]->p.t_t;
896
897
898       tab_text (trb->t, 0, i+3, TAB_LEFT, cmd->v_variables[i]->name);
899
900       t = (ttp->mean - cmd->n_testval ) * sqrt(ttp->n) / ttp->std_dev ;
901
902       tab_float (trb->t, 1, i+3, TAB_RIGHT, t, 8,3);
903
904       /* degrees of freedom */
905       df = ttp->n - 1;
906
907       tab_float (trb->t, 2, i+3, TAB_RIGHT, df, 8,0);
908
909       cdft(&which, &p, &q, &t, &df, &status, &bound);
910
911       if ( 0 != status )
912         {
913           msg( SE, _("Error calculating T statistic (cdft returned %d)."),status);
914         }
915
916
917       /* Multiply by 2 to get 2-tailed significance */
918       tab_float (trb->t, 3, i+3, TAB_RIGHT, q*2.0, 8,3);
919
920       tab_float (trb->t, 4, i+3, TAB_RIGHT, ttp->mean_diff, 8,3);
921
922
923       q = (1 - cmd->criteria)/2.0;  /* 2-tailed test */
924       p = 1 - q ;
925       which=2; /* Calc T from p,q and df */
926       cdft(&which, &p, &q, &t, &df, &status, &bound);
927       if ( 0 != status )
928         {
929           msg( SE, _("Error calculating T statistic (cdft returned %d)."),status);
930         }
931
932       tab_float (trb->t, 5, i+3, TAB_RIGHT,
933                  ttp->mean_diff - t * ttp->se_mean, 8,4);
934
935       tab_float (trb->t, 6, i+3, TAB_RIGHT,
936                  ttp->mean_diff + t * ttp->se_mean, 8,4);
937     }
938 }
939
940 /* Base initializer for the generalized trbox */
941 void 
942 trbox_base_init(struct trbox *self, int data_rows, int cols)
943 {
944   const int rows = 3 + data_rows;
945
946   self->finalize = trbox_base_finalize;
947   self->t = tab_create (cols, rows, 0);
948   tab_headers (self->t,0,0,3,0); 
949   tab_box (self->t, TAL_2, TAL_2, TAL_0, TAL_0, 0, 0, cols -1, rows -1);
950   tab_hline(self->t, TAL_2,0,cols-1,3);
951   tab_dim (self->t, tab_natural_dimensions);
952 }
953
954
955 /* Base finalizer for the trbox */
956 void 
957 trbox_base_finalize(struct trbox *trb)
958 {
959   tab_submit(trb->t);
960 }
961
962
963 /* Calculation Implementation */
964
965 /* Per case calculations common to all variants of the T test */
966 static int 
967 common_calc (struct ccase *c)
968 {
969   int i;
970
971   double weight = dict_get_case_weight(default_dict,c);
972
973   for(i=0; i< cmd.n_variables ; ++i) 
974     {
975       struct t_test_proc *ttp;
976       struct variable *v = cmd.v_variables[i];
977       union value *val = &c->data[v->fv];
978
979       ttp= &cmd.v_variables[i]->p.t_t;
980
981       if (val->f != SYSMIS) 
982         {
983           ttp->n+=weight;
984           ttp->sum+=weight * val->f;
985           ttp->ssq+=weight * val->f * val->f;
986         }
987     }
988   return 0;
989 }
990
991 /* Pre calculations common to all variants of the T test */
992 static void 
993 common_precalc (void)
994 {
995   int i=0;
996   
997   for(i=0; i< cmd.n_variables ; ++i) 
998     {
999       struct t_test_proc *ttp;
1000       ttp= &cmd.v_variables[i]->p.t_t;
1001       
1002       ttp->sum=0;
1003       ttp->n=0;
1004       ttp->ssq=0;
1005       ttp->sum_diff=0;
1006     }
1007 }
1008
1009 /* Post calculations common to all variants of the T test */
1010 void 
1011 common_postcalc (void)
1012 {
1013   int i=0;
1014
1015   for(i=0; i< cmd.n_variables ; ++i) 
1016     {
1017       struct t_test_proc *ttp;
1018       ttp= &cmd.v_variables[i]->p.t_t;
1019       
1020       ttp->mean=ttp->sum / ttp->n;
1021       ttp->std_dev= sqrt(
1022                          ttp->n/(ttp->n-1) *
1023                          ( (ttp->ssq / ttp->n ) - ttp->mean * ttp->mean )
1024                          ) ;
1025
1026       ttp->se_mean = ttp->std_dev / sqrt(ttp->n);
1027
1028       ttp->mean_diff= ttp->sum_diff / ttp->n;
1029     }
1030 }
1031
1032 /* Per case calculations for one sample t test  */
1033 static int 
1034 one_sample_calc (struct ccase *c)
1035 {
1036   int i;
1037
1038   double weight = dict_get_case_weight(default_dict,c);
1039
1040   for(i=0; i< cmd.n_variables ; ++i) 
1041     {
1042       struct t_test_proc *ttp;
1043       struct variable *v = cmd.v_variables[i];
1044       union value *val = &c->data[v->fv];
1045
1046       ttp= &cmd.v_variables[i]->p.t_t;
1047       
1048       if (val->f != SYSMIS) 
1049         ttp->sum_diff += weight * (val->f - cmd.n_testval);
1050     }
1051
1052   return 0;
1053 }
1054
1055 /* Pre calculations for one sample t test */
1056 static void 
1057 one_sample_precalc (void)
1058 {
1059   int i=0;
1060   
1061   for(i=0; i< cmd.n_variables ; ++i) 
1062     {
1063       struct t_test_proc *ttp;
1064       ttp= &cmd.v_variables[i]->p.t_t;
1065       
1066       ttp->sum_diff=0;
1067     }
1068 }
1069
1070 /* Post calculations for one sample t test */
1071 static void 
1072 one_sample_postcalc (void)
1073 {
1074   int i=0;
1075   
1076   for(i=0; i< cmd.n_variables ; ++i) 
1077     {
1078       struct t_test_proc *ttp;
1079       ttp= &cmd.v_variables[i]->p.t_t;
1080
1081       
1082       ttp->mean_diff = ttp->sum_diff / ttp->n ;
1083     }
1084 }