SHORE API
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
glm.hpp
Go to the documentation of this file.
1 
2 /*
3  * Copyright 2008,2009,2010,2011,2012 Stephan Ossowski, Korbinian Schneeberger,
4  * Felix Ott, Joerg Hagmann, Alf Scotland, Sebastian Bender
5  *
6  * This file is part of SHORE.
7  *
8  * SHORE is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * SHORE is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with SHORE. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
25 
26 #ifndef SHORE_STATISTICS_GLM_HPP__
27 #define SHORE_STATISTICS_GLM_HPP__
28 
29 #include <cmath>
30 #include <iostream>
31 #include <vector>
32 
33 #include <gsl/gsl_multifit.h>
34 #include <gsl/gsl_cdf.h>
35 #include <gsl/gsl_blas.h>
36 #include <gsl/gsl_linalg.h>
37 
38 namespace shore {
39 
40 class glht;
41 
43 class glm
44 {
45  private:
46 
47  friend class glht;
48 
50  const size_t m_rows;
52  const size_t m_cols;
53 
55  void *m_modelmatrix;
56 
57  void *m_workspace;
58 
59  void *m_observations;
60 
61  void *m_coefficients;
62  void *m_covariance;
63  void *m_residuals;
64 
65  double m_chisq;
66 
68  size_t m_rank;
69 
70 
71  void alloc();
72 
73  void set_modelmatrix(size_t i,size_t j,double value);
74 
76  size_t modelmatrix_rank(const double eps=1e-7);
77 
78  void set_observation(size_t i,double x);
79 
80  void fit();
81 
82  double get_coefficient(size_t i) const;
83 
84  void calc_residuals();
85  double get_residual(size_t i) const;
86 
87  double get_vcov(size_t i,size_t j) const;
88 
89  public:
90 
91  template<class T,size_t rows,size_t columns>
92  glm(const T (&design)[rows][columns])
93  :m_rows(rows),
94  m_cols(columns)
95  {
96  alloc();
97 
98  for(size_t i=0;i<m_rows;++i)
99  {
100  for(size_t j=0;j<m_cols;++j)
101  {
102  set_modelmatrix(i,j,design[i][j]);
103  }
104  }
105 
106  m_rank=modelmatrix_rank(1e-7);
107 
108  std::cerr<<"GLM: columns="<<m_cols
109  <<", rank="<<m_rank<<", res. df="<<get_residual_df()<<std::endl;
110  }
111 
112  glm(const std::vector<std::vector<double> >& design);
113 
114  ~glm();
115 
117  size_t get_design_rank() const;
118 
119  size_t get_residual_df() const;
120 
122  size_t nrows() const;
123 
125  size_t ncols() const;
126 
130  template<class Iter>
131  void fit(Iter obs)
132  {
133  // init vector
134  for(size_t i=0;i<m_rows;++i)
135  set_observation(i,*obs++);
136 
137  fit();
138  }
139 
141  template<class Iter>
142  void get_coefficients(Iter dest) const
143  {
144  for(size_t i=0;i<m_cols;++i)
145  (*dest++)=get_coefficient(i);
146  }
147 
149  template<class Iter>
150  void get_residuals(Iter dest)
151  {
152  calc_residuals();
153 
154  for(size_t i=0;i<m_rows;++i)
155  (*dest++)=get_residual(i);
156  }
157 
161  template<class Twodim>
162  void get_vcov(Twodim& res) const
163  {
164  for(size_t i=0;i<m_cols;++i)
165  {
166  for(size_t j=0;j<m_cols;++j)
167  {
168  res[i][j]=get_vcov(i,j);
169  }
170  }
171  }
172 };
173 
175 class glht
176 {
177  private:
178 
179  const glm& m_glm;
180 
181  const size_t m_rows;
182  const size_t m_cols;
183 
184  void *m_lh;
185 
186  void *m_tcross;
187  void *m_covm;
188 
189  int m_alternative;
190 
191  // results:
192 
193  void *m_estimates;
194 
195  double *m_stderr;
196  double *m_tstats;
197  double *m_pvalues;
198 
199 
200  void alloc();
201 
203  void mmprod(void *const A,void *const B,void *const C);
204 
206  void tcrossprod(void *const A,void *const B,void *const C);
207 
209  void mvprod(void *const A,void *const x,void *const y);
210 
211  void set_lhmatrix(size_t i,size_t j,double x);
212 
213  double get_estimate(size_t i) const;
214 
215  public:
216 
217  enum Alternative
218  {
219  ALT_TWOSIDED=0,
220  ALT_LESS=1,
221  ALT_GREATER=2
222  };
223 
224  template<class T,size_t rows,size_t columns>
225  glht(const glm*const m,const T (&lh)[rows][columns])
226  :m_glm(*m),
227  m_rows(rows),m_cols(columns),
228  m_alternative(ALT_TWOSIDED)
229  {
230  if(m_glm.ncols()!=m_cols)
231  throw "column counts of glm and glht must match";
232 
233  alloc();
234 
235  for(size_t i=0;i<m_rows;++i)
236  {
237  for(size_t j=0;j<m_cols;++j)
238  {
239  set_lhmatrix(i,j,lh[i][j]);
240  }
241  }
242  }
243 
244  glht(const glm*const m,const std::vector<std::vector<double> >& lh);
245 
246  ~glht();
247 
248  size_t nrows() const;
249 
250  size_t ncols() const;
251 
252  void set_alternative(const Alternative alt);
253 
255  void run();
256 
257  template<class Iter>
258  void get_estimates(Iter dest)
259  {
260  for(size_t i=0;i<m_rows;++i)
261  (*dest++)=get_estimate(i);
262  }
263 
264  template<class Iter>
265  void get_stderrs(Iter dest)
266  {
267  for(size_t i=0;i<m_rows;++i)
268  (*dest++)=m_stderr[i];
269  }
270 
271  template<class Iter>
272  void get_tstats(Iter dest)
273  {
274  for(size_t i=0;i<m_rows;++i)
275  (*dest++)=m_tstats[i];
276  }
277 
278  template<class Iter>
279  void get_pvalues(Iter dest)
280  {
281  for(size_t i=0;i<m_rows;++i)
282  (*dest++)=m_pvalues[i];
283  }
284 };
285 
286 } // namespace
287 
288 #endif // SHORE_STATISTICS_GLM_HPP__
289