All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
fit_linear.h
Go to the documentation of this file.
1 /*
2  -------------------------------------------------------------------
3 
4  Copyright (C) 2013-2014, Andrew W. Steiner
5 
6  This file is part of O2scl.
7 
8  O2scl 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  O2scl 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 O2scl. If not, see <http://www.gnu.org/licenses/>.
20 
21  -------------------------------------------------------------------
22 */
23 /* multifit/multilinear.c
24  *
25  * Copyright (C) 2000, 2007, 2010 Brian Gough
26  *
27  * This program is free software; you can redistribute it and/or modify
28  * it under the terms of the GNU General Public License as published by
29  * the Free Software Foundation; either version 3 of the License, or (at
30  * your option) any later version.
31  *
32  * This program is distributed in the hope that it will be useful, but
33  * WITHOUT ANY WARRANTY; without even the implied warranty of
34  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
35  * General Public License for more details.
36  *
37  * You should have received a copy of the GNU General Public License
38  * along with this program; if not, write to the Free Software
39  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
40  * 02110-1301, USA.
41  */
42 #ifndef O2SCL_FIT_LINEAR_H
43 #define O2SCL_FIT_LINEAR_H
44 
45 /** \file fit_linear.h
46  \brief File defining \ref o2scl::fit_linear
47 */
48 
49 #include <boost/numeric/ublas/vector.hpp>
50 #include <boost/numeric/ublas/matrix.hpp>
51 
52 #include <o2scl/vector.h>
53 #include <o2scl/fit_base.h>
54 #include <o2scl/permutation.h>
55 #include <o2scl/cblas.h>
56 #include <o2scl/svd.h>
57 
58 #ifndef DOXYGEN_NO_O2NS
59 namespace o2scl {
60 #endif
61 
62  /** \brief Linear least-squares fitting class (GSL)
63  */
64  template<class vec_t=boost::numeric::ublas::vector<double>,
65  class mat_t=boost::numeric::ublas::matrix<double> >
66  class fit_linear {
67 
68  protected:
69 
70  /// \name Storage
71  //@{
72  /** \brief Local copy of <tt>xpred</tt>
73  (and used as workspace by the SV decomposition)
74  */
75  mat_t A;
76  /// The first unitary matrix from the SV decomposition
77  mat_t Q;
78  /// Workspace for the SV decomposition and storage for \f$ Q S^{-1} \f$
79  mat_t QSI;
80 
81  /// The singular values from the SV decomposition
82  vec_t S;
83  /// SV decomposition workspace and also used to store new predicted values
84  vec_t xt;
85  /// Balancing factors for A
86  vec_t D;
87  /// Only used for the weighted fit (not yet implemented)
88  vec_t t;
89  //@}
90 
91  /// Number of parameters
92  size_t size_par;
93  /// Number of data points
94  size_t size_dat;
95 
96  public:
97 
98  fit_linear() {
99  column_scaling=true;
100  tol=2.2204460492503131e-16;
101  size_par=0;
102  size_dat=0;
103  }
104 
105  virtual ~fit_linear() {
106  }
107 
108  /** \brief If true, discard fit components if the associated singular
109  value becomes too small (default true)
110  */
112 
113  /// Tolerance (default \f$ \sim 2.22\times 10^{-16} \f$)
114  double tol;
115 
116  /** \brief The rank of the linear system from the last call to
117  <tt>fit_linear()</tt>
118  */
119  size_t rank;
120 
121  /** \brief Perform the SV decomposition
122  */
123  virtual void fit_svd(size_t ndat, size_t npar) {
124  o2scl_linalg::SV_decomp_mod(ndat,npar,A,QSI,Q,S,xt);
125  return;
126  }
127 
128  /** \brief Perform a least-squares fit of a linear system
129 
130  This function performs a least-squares fit of the
131  system
132  \f[
133  \mathrm{xpred} \cdot \mathrm{parms} = \mathrm{ydat}
134  \f]
135 
136  The variance-covariance matrix for the parameters is returned in
137  \c covar and the value of \f$ \chi^2 \f$ is returned in \c chi2.
138  */
139  virtual void fit(size_t npar, size_t ndat, const vec_t &ydat,
140  const mat_t &xpred, vec_t &parms,
141  mat_t &covar, double &chi2) {
142 
143  if (npar>ndat) {
144  O2SCL_ERR2("Insufficient data points in ",
145  "fit_linear::fit_linear().",exc_einval);
146  }
147 
148  if (npar!=size_par || ndat!=size_dat) {
149  A.resize(ndat,npar);
150  Q.resize(npar,npar);
151  QSI.resize(npar,npar);
152  S.resize(npar);
153  t.resize(ndat);
154  xt.resize(npar);
155  D.resize(npar);
156  size_par=npar;
157  size_dat=ndat;
158  }
159 
160  // necessary?
161  for(size_t i=0;i<npar;i++) {
162  xt[i]=0.0;
163  D[i]=0.0;
164  }
165 
166  for(size_t i=0;i<ndat;i++) {
167  for(size_t j=0;j<npar;j++) {
168  A(i,j)=xpred(i,j);
169  }
170  }
171 
172  if (column_scaling) {
173  o2scl_linalg::balance_columns(ndat,npar,A,D);
174  } else {
175  for(size_t i=0;i<npar;i++) {
176  D[i]=1.0;
177  }
178  }
179 
180  // [GSL] Decompose A into U S Q^T
181  fit_svd(ndat,npar);
182 
183  // [GSL] Solve y = A c for c
185  (o2scl_cblas::o2cblas_RowMajor,
186  o2scl_cblas::o2cblas_Trans,ndat,npar,1.0,A,ydat,0.0,xt);
187 
188  // [GSL] Scale the matrix Q, Q' = Q S^-1
189  for(size_t i=0;i<npar;i++) {
190  for(size_t j=0;j<npar;j++) {
191  QSI(i,j)=Q(i,j);
192  }
193  }
194 
195  double alpha0=S[0];
196  size_t p_eff=0;
197 
198  for(size_t j=0;j<npar;j++) {
199  double alpha=S[j];
200  if (alpha<=tol*alpha0) {
201  alpha=0.0;
202  } else {
203  alpha=1.0/alpha;
204  p_eff++;
205  }
206  o2scl_cblas::dscal_subcol(QSI,0,j,npar,alpha);
207  }
208 
209  rank=p_eff;
210  for(size_t i=0;i<npar;i++) {
211  parms[i]=0.0;
212  }
213 
215  (o2scl_cblas::o2cblas_RowMajor,
216  o2scl_cblas::o2cblas_NoTrans,npar,npar,
217  1.0,QSI,xt,0.0,parms);
218 
219  // [GSL] Unscale the balancing factors
220 
221  for(size_t i=0;i<npar;i++) {
222  parms[i]/=D[i];
223  }
224 
225  // [GSL] Compute chi-squared from residual, r = y - X c
226 
227  double s2=0.0, r2=0.0;
228  for(size_t i=0;i<ndat;i++) {
229  double yi=ydat[i];
230  double y_est=o2scl_cblas::ddot_subrow(npar,xpred,i,0,parms);
231  double ri=yi-y_est;
232  r2+=ri*ri;
233  }
234  s2=r2/(ndat-p_eff);
235  chi2=r2;
236 
237  // [GSL] Form variance-covariance matrix, cov = s2 * (Q S^-1) (Q S^-1)^T
238 
239  for(size_t i=0;i<npar;i++) {
240  double d_i=D[i];
241  for(size_t j=i;j<npar;j++) {
242  double d_j=D[j];
243  double s=0.0;
244  for(size_t k=0;k<npar;k++) {
245  s+=QSI(i,k)*QSI(j,k);
246  }
247  covar(i,j)=s*s2/(d_i*d_j);
248  covar(j,i)=s*s2/(d_i*d_j);
249  }
250  }
251 
252  return;
253  }
254 
255  /// Return string denoting type ("fit_linear")
256  virtual const char *type() { return "fit_linear"; }
257 
258  };
259 
260 #ifndef DOXYGEN_NO_O2NS
261 }
262 #endif
263 
264 #endif
size_t rank
The rank of the linear system from the last call to fit_linear()
Definition: fit_linear.h:119
double tol
Tolerance (default )
Definition: fit_linear.h:114
Linear least-squares fitting class (GSL)
Definition: fit_linear.h:66
size_t size_par
Number of parameters.
Definition: fit_linear.h:92
invalid argument supplied by user
Definition: err_hnd.h:59
void balance_columns(size_t M, size_t N, mat_t &A, vec_t &D)
Balance a general matrix A by scaling the columns by the diagonal matrix D.
Definition: svd_base.h:609
double ddot_subrow(const size_t N, const mat_t &X, const size_t ir, const size_t ic, const vec_t &Y)
Compute for a subrow of a matrix.
Definition: cblas_base.h:1223
size_t size_dat
Number of data points.
Definition: fit_linear.h:94
vec_t D
Balancing factors for A.
Definition: fit_linear.h:86
virtual void fit_svd(size_t ndat, size_t npar)
Perform the SV decomposition.
Definition: fit_linear.h:123
virtual void fit(size_t npar, size_t ndat, const vec_t &ydat, const mat_t &xpred, vec_t &parms, mat_t &covar, double &chi2)
Perform a least-squares fit of a linear system.
Definition: fit_linear.h:139
void dgemv(const enum o2cblas_order order, const enum o2cblas_transpose TransA, const size_t M, const size_t N, const double alpha, const mat_t &A, const vec_t &X, const double beta, vec2_t &Y)
Compute .
Definition: cblas_base.h:218
mat_t QSI
Workspace for the SV decomposition and storage for .
Definition: fit_linear.h:79
#define O2SCL_ERR2(d, d2, n)
Set an error, two-string version.
Definition: err_hnd.h:281
vec_t S
The singular values from the SV decomposition.
Definition: fit_linear.h:82
mat_t A
Local copy of xpred (and used as workspace by the SV decomposition)
Definition: fit_linear.h:75
mat_t Q
The first unitary matrix from the SV decomposition.
Definition: fit_linear.h:77
virtual const char * type()
Return string denoting type ("fit_linear")
Definition: fit_linear.h:256
void SV_decomp_mod(size_t M, size_t N, mat_t &A, mat2_t &X, mat3_t &V, vec_t &S, vec2_t &work)
SV decomposition by the modified Golub-Reinsch algorithm which is better for .
Definition: svd_base.h:290
vec_t t
Only used for the weighted fit (not yet implemented)
Definition: fit_linear.h:88
bool column_scaling
If true, discard fit components if the associated singular value becomes too small (default true) ...
Definition: fit_linear.h:111
void dscal_subcol(mat_t &A, const size_t ir, const size_t ic, const size_t M, const double alpha)
Compute for a subcolumn of a matrix.
Definition: cblas_base.h:1093
vec_t xt
SV decomposition workspace and also used to store new predicted values.
Definition: fit_linear.h:84

Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).
Hosted at Get Object-oriented Scientific Computing
Lib at SourceForge.net. Fast, secure and Free Open Source software
downloads..