SHORE API
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
berry.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 
26 
27 #ifndef SHORE_STATISTICS_BERRY_HPP__
28 #define SHORE_STATISTICS_BERRY_HPP__
29 
30 #include "shore/statistics/glm.hpp"
31 #include "shore/base/mathops.hpp"
32 
33 namespace shore {
34 
41 class berry
42 {
43  public:
44 
45  typedef long double obs_t;
46 
47  private:
48 
49  glm& m_lm;
50 
51  struct workspace
52  {
53  obs_t* Cs;
54  obs_t* g0;
55 
56  obs_t* log_obs;
57  obs_t* residuals;
58 
59  obs_t skewkurt[2];
60 
61  workspace(const int g,const size_t rows);
62  ~workspace();
63 
64  } m_ws;
65 
66  int m_depth;
67  int m_grid_size;
68  obs_t m_conv_crit;
69  obs_t m_min_num;
70 
71  public:
72 
73  berry(glm* lm,
74  const int d=5,
75  const int g=100,
76  const obs_t cc=.001,
77  const obs_t mn=1);
78 
79  template<class Iter>
80  obs_t search(Iter observations)
81  {
82  const int DF=m_lm.get_residual_df();
83 
84  const obs_t min=
85  *std::min_element(observations,observations+m_lm.nrows());
86  const obs_t max=
87  *std::max_element(observations,observations+m_lm.nrows());
88 
89  shore::seq(m_min_num-min,9.999*max,m_grid_size,m_ws.Cs);
90 
91  obs_t last_g0=0.0;
92  obs_t last_c=0.0;
93 
94  for(int i=0;i<m_depth;++i)
95  {
96  for(int j=0;j<m_grid_size;++j)
97  {
98  const obs_t c=m_ws.Cs[j];
99 
100  for(size_t k=0;k<m_lm.nrows();++k)
101  {
102  m_ws.log_obs[k]=shore::log2(observations[k]+c);
103  }
104 
105  m_lm.fit(m_ws.log_obs);
106  m_lm.get_residuals(m_ws.residuals);
107 
108  shore::skewness_kurtosis(m_ws.residuals,
109  m_ws.residuals+m_lm.nrows(),m_ws.skewkurt,true);
110 
111  m_ws.g0[j]=std::abs(m_ws.skewkurt[0])
112  +std::abs(m_ws.skewkurt[1]+6.0/(DF+2));
113  }
114 
115  const obs_t*const min_ptr=
116  std::min_element(m_ws.g0,m_ws.g0+m_grid_size);
117 
118  const obs_t min_g0= *min_ptr;
119  const obs_t min_c=m_ws.Cs[min_ptr-m_ws.g0];
120 
121  // convergence crit. reached?
122  if((i!=0)&&(std::abs(last_g0-min_g0)<=m_conv_crit))
123  {
124  return (last_g0<min_g0)?last_c:min_c;
125  }
126 
127  last_g0=min_g0;
128  last_c=min_c;
129 
130  if(min_ptr==m_ws.g0)
131  {
132  shore::seq(m_ws.Cs[0],m_ws.Cs[1],m_grid_size,m_ws.Cs);
133  }
134  else if(min_ptr==(&m_ws.g0[m_grid_size-1]))
135  {
136  shore::seq(m_ws.Cs[m_grid_size-2],
137  m_ws.Cs[m_grid_size-1],m_grid_size,m_ws.Cs);
138  }
139  else
140  {
141  shore::seq(m_ws.Cs[min_ptr-m_ws.g0-1],
142  m_ws.Cs[min_ptr-m_ws.g0+1],m_grid_size,m_ws.Cs);
143  }
144  }
145 
146  return last_c;
147  }
148 };
149 
150 } // namespace
151 
152 #endif // SHORE_STATISTICS_BERRY_HPP__
153