Changed include paths to be explicitly specified in the #include directive.
[pspp-builds.git] / src / math / linreg / coefficient.c
1 /* lib/linreg/coefficient.c
2
3    Copyright (C) 2005 Free Software Foundation, Inc.
4    Written by Jason H Stover.
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or (at
9    your option) any later version.
10
11    This program is distributed in the hope that it will be useful, but
12    WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19    02111-1307, USA.
20  */
21
22 /*
23   Accessor functions for matching coefficients and variables.
24  */
25 #include <assert.h>
26 #include <math/linreg/coefficient.h>
27 #include <math/linreg/linreg.h>
28 #include "src/math/design-matrix.h"
29 #include "src/data/variable.h"
30 #include "src/data/value.h"
31
32 #include <gl/xalloc.h>
33
34
35 struct varinfo
36 {
37   const struct variable *v; /* Variable associated with this
38                                coefficient. Note this variable may not
39                                be unique. In other words, a
40                                coefficient structure may have other
41                                v_info's, each with its own variable.
42                              */
43   const union value *val; /* Value of the variable v which this
44                              varinfo refers to. This member is relevant
45                              only to categorical variables.
46                           */
47 };
48
49 void pspp_linreg_coeff_free (struct pspp_linreg_coeff *c)
50 {
51   free (c);
52 }
53
54 /*
55   Initialize the variable and value pointers inside the
56   coefficient structures for the linear model.
57  */
58 void
59 pspp_linreg_coeff_init (pspp_linreg_cache *c, struct design_matrix *X)
60 {
61   size_t i;
62   size_t j;
63   int n_vals = 1;
64   struct pspp_linreg_coeff *coeff;
65   
66   c->coeff = 
67         xnmalloc (X->m->size2 + 1, 
68         sizeof (*c->coeff));
69   for (i = 0; i < X->m->size2; i++)
70     {
71       j = i + 1;                /* The first coefficient is the intercept. */
72       coeff = c->coeff + j;
73       coeff->n_vars = n_vals; /* Currently, no procedures allow interactions.
74                                  This will have to change when procedures that
75                                  allow interaction terms are written.
76                               */
77       coeff->v_info = xnmalloc (coeff->n_vars, sizeof (*coeff->v_info));
78       assert (coeff->v_info != NULL);
79       coeff->v_info->v = (const struct variable *) design_matrix_col_to_var (X, i);
80       
81       if (coeff->v_info->v->type == ALPHA)
82         {
83           size_t k;
84           k = design_matrix_var_to_column (X, coeff->v_info->v);
85           assert (k <= i);
86           k = i - k;
87           coeff->v_info->val = cat_subscript_to_value (k, (struct variable *) coeff->v_info->v);
88         }
89     }
90 }
91 void
92 pspp_linreg_coeff_set_estimate (struct pspp_linreg_coeff *c,
93                                 double estimate)
94 {
95   c->estimate = estimate;
96 }
97 void
98 pspp_linreg_coeff_set_std_err (struct pspp_linreg_coeff *c,
99                                double std_err)
100 {
101   c->std_err = std_err;
102 }
103 /*
104   How many variables are associated with this coefficient?
105  */
106 int
107 pspp_linreg_coeff_get_n_vars (struct pspp_linreg_coeff *c)
108 {
109   return c->n_vars;
110 }                             
111 /*
112   Which variable does this coefficient match?
113  */
114 const struct variable *
115 pspp_linreg_coeff_get_var (struct pspp_linreg_coeff *c, int i)
116 {
117   assert (i < c->n_vars);
118   return (c->v_info + i)->v;
119 }
120 /* 
121    Which value is associated with this coefficient/variable comination? 
122 */
123 const union value *
124 pspp_linreg_coeff_get_value (struct pspp_linreg_coeff *c,
125                              const struct variable *v)
126 {
127   int i = 0;
128   const struct variable *candidate;
129
130   while (i < c->n_vars)
131     {
132       candidate = pspp_linreg_coeff_get_var (c, i);
133       if (v->index == candidate->index)
134         {
135           return (c->v_info + i)->val;
136         }
137       i++;
138     }
139   return NULL;
140 }