fed45b64675cd3e763775ad1ac38838d7325addb
[pspp-builds.git] / src / math / coefficient.c
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 2005 Free Software Foundation, Inc.
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
16
17 /*
18   Accessor functions for matching coefficients and variables.
19  */
20 #include <config.h>
21 #include <math/coefficient.h>
22 #include "src/math/design-matrix.h"
23
24 #include <gl/xalloc.h>
25
26
27 struct varinfo
28 {
29   const struct variable *v;     /* Variable associated with this
30                                    coefficient. Note this variable
31                                    may not be unique. In other words,
32                                    a coefficient structure may have
33                                    other v_info's, each with its own
34                                    variable. */
35   const union value *val;       /* Value of the variable v which this varinfo
36                                    refers to. This member is relevant only to
37                                    categorical variables. */
38 };
39
40 void
41 pspp_coeff_free (struct pspp_coeff *c)
42 {
43   free (c->v_info);
44   free (c);
45 }
46
47 /*
48   Initialize the variable and value pointers inside the
49   coefficient structures for the model.
50  */
51 void
52 pspp_coeff_init (struct pspp_coeff ** c, const struct design_matrix *X)
53 {
54   size_t i;
55   int n_vals = 1;
56
57   assert (c != NULL);
58   for (i = 0; i < X->m->size2; i++)
59     {
60       c[i] = xmalloc (sizeof (*c[i]));
61       c[i]->n_vars = n_vals;    /* Currently, no procedures allow
62                                    interactions.  This line will have to
63                                    change when procedures that allow
64                                    interaction terms are written.
65                                  */
66       c[i]->v_info = xnmalloc (c[i]->n_vars, sizeof (*c[i]->v_info));
67       assert (c[i]->v_info != NULL);
68       c[i]->v_info->v = design_matrix_col_to_var (X, i);
69
70       if (var_is_alpha (c[i]->v_info->v))
71         {
72           size_t k;
73           k = design_matrix_var_to_column (X, c[i]->v_info->v);
74           assert (k <= i);
75           k = i - k;
76           c[i]->v_info->val =
77             cat_subscript_to_value (k, c[i]->v_info->v);
78         }
79     }
80 }
81 void
82 pspp_coeff_set_estimate (struct pspp_coeff *c, double estimate)
83 {
84   c->estimate = estimate;
85 }
86
87 void
88 pspp_coeff_set_std_err (struct pspp_coeff *c, double std_err)
89 {
90   c->std_err = std_err;
91 }
92
93 /*
94   Return the estimated value of the coefficient.
95  */
96 double
97 pspp_coeff_get_est (const struct pspp_coeff *c)
98 {
99   if (c == NULL)
100     {
101       return 0.0;
102     }
103   return c->estimate;
104 }
105
106 /*
107   Return the standard error of the estimated coefficient.
108 */
109 double
110 pspp_coeff_get_std_err (const struct pspp_coeff *c)
111 {
112   if (c == NULL)
113     {
114       return 0.0;
115     }
116   return c->std_err;
117 }
118
119 /*
120   How many variables are associated with this coefficient?
121  */
122 int
123 pspp_coeff_get_n_vars (struct pspp_coeff *c)
124 {
125   if (c == NULL)
126     {
127       return 0;
128     }
129   return c->n_vars;
130 }
131
132 /*
133   Which variable does this coefficient match? I should be
134   0 unless the coefficient refers to an interaction term.
135  */
136 const struct variable *
137 pspp_coeff_get_var (struct pspp_coeff *c, int i)
138 {
139   if (c == NULL)
140     {
141       return NULL;
142     }
143   assert (i < c->n_vars);
144   return (c->v_info + i)->v;
145 }
146
147 /*
148   Which value is associated with this coefficient/variable combination?
149  */
150 const union value *
151 pspp_coeff_get_value (struct pspp_coeff *c,
152                              const struct variable *v)
153 {
154   int i = 0;
155   const struct variable *candidate;
156
157   if (c == NULL || v == NULL)
158     {
159       return NULL;
160     }
161   if (var_is_numeric (v))
162     {
163       return NULL;
164     }
165   while (i < c->n_vars)
166     {
167       candidate = pspp_coeff_get_var (c, i);
168       if (v == candidate)
169         {
170           return (c->v_info + i)->val;
171         }
172       i++;
173     }
174   return NULL;
175 }
176