Added Levene test. Added T-TEST section to pspp.texi
[pspp-builds.git] / src / vars-atr.c
1 /* PSPP - computes sample statistics.
2    Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
3    Written by Ben Pfaff <blp@gnu.org>.
4
5    This program is free software; you can redistribute it and/or
6    modify it under the terms of the GNU General Public License as
7    published by the Free Software Foundation; either version 2 of the
8    License, or (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful, but
11    WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
18    02111-1307, USA. */
19
20 #include <config.h>
21 #include "var.h"
22 #include <assert.h>
23 #include <stdlib.h>
24 #include "alloc.h"
25 #include "approx.h"
26 #include "command.h"
27 #include "do-ifP.h"
28 #include "expr.h"
29 #include "file-handle.h"
30 #include "hash.h"
31 #include "misc.h"
32 #include "str.h"
33 #include "value-labels.h"
34 #include "vfm.h"
35
36 #include "debug-print.h"
37
38 /* Compares A and B, which both have the given WIDTH, and returns
39    a strcmp()-type result. */
40 int
41 compare_values (const union value *a, const union value *b, int width) 
42 {
43   if (width == 0) 
44     return a->f < b->f ? -1 : a->f > b->f;
45   else
46     return memcmp (a->s, b->s, width);
47 }
48
49 /* Discards all the current state in preparation for a data-input
50    command like DATA LIST or GET. */
51 void
52 discard_variables (void)
53 {
54   dict_clear (default_dict);
55   default_handle = inline_file;
56
57   n_lag = 0;
58   
59   if (vfm_source)
60     {
61       vfm_source->destroy_source ();
62       vfm_source = NULL;
63     }
64
65   cancel_transformations ();
66
67   ctl_stack = NULL;
68
69   expr_free (process_if_expr);
70   process_if_expr = NULL;
71
72   cancel_temporary ();
73
74   pgm_state = STATE_INIT;
75 }
76
77 /* Return nonzero only if X is a user-missing value for numeric
78    variable V. */
79 inline int
80 is_num_user_missing (double x, const struct variable *v)
81 {
82   switch (v->miss_type)
83     {
84     case MISSING_NONE:
85       return 0;
86     case MISSING_1:
87       return approx_eq (x, v->missing[0].f);
88     case MISSING_2:
89       return (approx_eq (x, v->missing[0].f)
90               || approx_eq (x, v->missing[1].f));
91     case MISSING_3:
92       return (approx_eq (x, v->missing[0].f)
93               || approx_eq (x, v->missing[1].f)
94               || approx_eq (x, v->missing[2].f));
95     case MISSING_RANGE:
96       return (approx_ge (x, v->missing[0].f)
97               && approx_le (x, v->missing[1].f));
98     case MISSING_LOW:
99       return approx_le (x, v->missing[0].f);
100     case MISSING_HIGH:
101       return approx_ge (x, v->missing[0].f);
102     case MISSING_RANGE_1:
103       return ((approx_ge (x, v->missing[0].f)
104                && approx_le (x, v->missing[1].f))
105               || approx_eq (x, v->missing[2].f));
106     case MISSING_LOW_1:
107       return (approx_le (x, v->missing[0].f)
108               || approx_eq (x, v->missing[1].f));
109     case MISSING_HIGH_1:
110       return (approx_ge (x, v->missing[0].f)
111               || approx_eq (x, v->missing[1].f));
112     default:
113       assert (0);
114     }
115   abort ();
116 }
117
118 /* Return nonzero only if string S is a user-missing variable for
119    string variable V. */
120 inline int
121 is_str_user_missing (const unsigned char s[], const struct variable *v)
122 {
123   switch (v->miss_type)
124     {
125     case MISSING_NONE:
126       return 0;
127     case MISSING_1:
128       return !strncmp (s, v->missing[0].s, v->width);
129     case MISSING_2:
130       return (!strncmp (s, v->missing[0].s, v->width)
131               || !strncmp (s, v->missing[1].s, v->width));
132     case MISSING_3:
133       return (!strncmp (s, v->missing[0].s, v->width)
134               || !strncmp (s, v->missing[1].s, v->width)
135               || !strncmp (s, v->missing[2].s, v->width));
136     default:
137       assert (0);
138     }
139   abort ();
140 }
141
142 /* Return nonzero only if value VAL is system-missing for variable
143    V. */
144 int
145 is_system_missing (const union value *val, const struct variable *v)
146 {
147   return v->type == NUMERIC && val->f == SYSMIS;
148 }
149
150 /* Return nonzero only if value VAL is system- or user-missing for
151    variable V. */
152 int
153 is_missing (const union value *val, const struct variable *v)
154 {
155   switch (v->type)
156     {
157     case NUMERIC:
158       if (val->f == SYSMIS)
159         return 1;
160       return is_num_user_missing (val->f, v);
161     case ALPHA:
162       return is_str_user_missing (val->s, v);
163     default:
164       assert (0);
165     }
166   abort ();
167 }
168
169 /* Return nonzero only if value VAL is user-missing for variable V. */
170 int
171 is_user_missing (const union value *val, const struct variable *v)
172 {
173   switch (v->type)
174     {
175     case NUMERIC:
176       return is_num_user_missing (val->f, v);
177     case ALPHA:
178       return is_str_user_missing (val->s, v);
179     default:
180       assert (0);
181     }
182   abort ();
183 }
184 \f
185 /* A hsh_compare_func that orders variables A and B by their
186    names. */
187 int
188 compare_variables (const void *a_, const void *b_, void *foo UNUSED) 
189 {
190   const struct variable *a = a_;
191   const struct variable *b = b_;
192
193   return strcmp (a->name, b->name);
194 }
195
196 /* A hsh_hash_func that hashes variable V based on its name. */
197 unsigned
198 hash_variable (const void *v_, void *foo UNUSED) 
199 {
200   const struct variable *v = v_;
201
202   return hsh_hash_string (v->name);
203 }