mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
fitExpModGaussian.hpp
Go to the documentation of this file.
1 /** \file fitExpModGaussian.hpp
2  * \author Jared R. Males
3  * \brief Tools for fitting the GammaDistribution distribution to data.
4  * \ingroup fitting_files
5  *
6  */
7 
8 //***********************************************************************//
9 // Copyright 2023 Jared R. Males (jaredmales@gmail.com)
10 //
11 // This file is part of mxlib.
12 //
13 // mxlib is free software: you can redistribute it and/or modify
14 // it under the terms of the GNU General Public License as published by
15 // the Free Software Foundation, either version 3 of the License, or
16 // (at your option) any later version.
17 //
18 // mxlib is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 // GNU General Public License for more details.
22 //
23 // You should have received a copy of the GNU General Public License
24 // along with mxlib. If not, see <http://www.gnu.org/licenses/>.
25 //***********************************************************************//
26 
27 #ifndef fitExpModGaussian_hpp
28 #define fitExpModGaussian_hpp
29 
30 #include "levmarInterface.hpp"
31 #include "../func/expModGaussian.hpp"
32 
33 namespace mx
34 {
35 namespace math
36 {
37 namespace fit
38 {
39 
40 template<typename realT>
41 struct array2FitExpModGaussian;
42 
43 
44 /** \defgroup expModGauss_peak_fit Exponetially Modified Gaussian Distribution
45  * \brief Fitting the Exponetially Modified Gaussian Distribution to data.
46  *
47  * The Exponetially Modified Gaussian Distribution is fit to data.
48  *
49  * \ingroup peak_fit
50  */
51 
52 ///Class to manage fitting the Exponetially Modified Gaussian Distribution to data via the \ref levmarInterface
53 /** In addition to the requirements on fitterT specified by \ref levmarInterface
54  * this class also requires this definition in fitterT
55  * \code
56  * static const int nparams = 3;
57  * \endcode
58  * where the number 3 is replaced by the number of parameters that fitterT expects to fit.
59  *
60  * \tparam fitterT a type meeting the above requirements.
61  *
62  * \ingroup expModGauss_peak_fit
63  *
64  */
65 template<typename fitterT>
66 class fitExpModGaussian : public levmarInterface<fitterT>
67 {
68 
69 public:
70 
71  typedef typename fitterT::realT realT;
72 
73  static const int nparams = fitterT::nparams;
74 
76 
77  void initialize()
78  {
79  this->allocate_params(nparams);
80  this->adata = &arr;
81  }
82 
84  {
85  initialize();
86  }
87 
89  {
90  }
91 
92  ///Set the initial guess.
93  void setGuess( realT G0, ///< [in] the location parameter
94  realT mu, ///< [in] the shape parameter
95  realT sigma, ///< [in] the scale parameter
96  realT lambda ///< [in] the denominator or 1/peak-scale
97  )
98  {
99  static_assert( nparams==4 , "fitExpModGaussian: Wrong setGuess called for no location parameter.");
100 
101  this->p[3] = G0; //this is p[2] to make it easy to leave out
102  this->p[0] = mu;
103  this->p[1] = sigma;
104  this->p[2] = lambda;
105  }
106 
107  ///Set the initial guess.
108  void setGuess( realT mu, ///< [in] the location parameter
109  realT sigma, ///< [in] the shape parameter
110  realT lambda ///< [in] the scale parameter
111  )
112  {
113  static_assert( nparams==3 , "fitExpModGaussian: Wrong setGuess called for no location parameter.");
114 
115  this->p[0] = mu; //this is p[2] to make it easy to leave out
116  this->p[1] = sigma;
117  this->p[2] = lambda;
118  }
119 
120  void setArray(realT *data, int n)
121  {
122  arr.data = data;
123  arr.n = n;
124 
125  this->n = n;
126 
127  }
128 
129  void G0( realT nG0 )
130  {
131  arr.G0 = nG0;
132  if(nparams == 4)
133  {
134  this->p[3] = nG0; //this is p[2] to make it easy to leave out
135  }
136  }
137 
138  void mu( realT nmu )
139  {
140  arr.mu = nmu;
141  this->p[0] = nmu;
142  }
143 
144  void sigma( realT ns )
145  {
146  arr.sigma = ns;
147  this->p[1] = ns;
148  }
149 
150  void lambda( realT nl)
151  {
152  arr.lambda = nl;
153  this->p[2] = nl;
154  }
155 
156  int fit()
157  {
159  }
160 
161  realT G0()
162  {
163  if(nparams == 4)
164  {
165  return this->p[3];
166  }
167  else
168  {
169  return 0;
170  }
171  }
172 
173  realT mu()
174  {
175  return this->p[0];
176  }
177 
178  realT sigma()
179  {
180  return this->p[1];
181  }
182 
183  realT lambda()
184  {
185  return this->p[2];
186  }
187 
188 
189 };
190 
191 
192 ///Wrapper for a native array to pass to \ref levmarInterface, with Exponentially Modified Gaussian details.
193 /** \ingroup gammaDist_peak_fit
194  */
195 template<typename realT>
197 {
198  realT * data {nullptr}; ///< Pointer to the array
199  size_t n {0}; ///< dimension of the array
200 
201  realT G0 {0}; ///< the location parameter.
202  realT mu {0}; ///< the shape parameter
203  realT sigma {0}; ///< the scale parameter
204  realT lambda {0}; ///< the denominator or 1/peak-scale
205 };
206 
207 ///\ref levmarInterface fitter structure for the Exponentially Modified Gaussian with fixed constant level.
208 /**
209  *
210  * \ingroup gammaDist_peak_fit
211  *
212  */
213 template<typename _realT>
215 {
216  typedef _realT realT;
217 
218  static const int nparams = 3;
219 
220  static void func(realT *p, realT *hx, int m, int n, void *adata)
221  {
223 
224  for(int i=0;i<arr->n; i++)
225  {
226  hx[i] = func::expModGaussian<realT>(i, p[0], p[1], p[2]) - arr->data[i];
227  }
228  }
229 };
230 
231 ///\ref levmarInterface fitter structure for the Exponentially Modified Gaussian with arbitrary constant level.
232 /**
233  *
234  * \ingroup gammaDist_peak_fit
235  *
236  */
237 template<typename _realT>
239 {
240  typedef _realT realT;
241 
242  static const int nparams = 4;
243 
244  static void func(realT *p, realT *hx, int m, int n, void *adata)
245  {
247 
248  for(int i=0;i<arr->n; i++)
249  {
250  hx[i] = p[3] + func::expModGaussian<realT>(i, p[0], p[1], p[2]) - arr->data[i];
251  }
252  }
253 };
254 
255 
256 
257 } //namespace fit
258 } //namespace math
259 } //namespace mx
260 
261 #endif //fitExpModGaussian_hpp
262 
Class to manage fitting the Exponetially Modified Gaussian Distribution to data via the levmarInterfa...
void setGuess(realT mu, realT sigma, realT lambda)
Set the initial guess.
void setGuess(realT G0, realT mu, realT sigma, realT lambda)
Set the initial guess.
A templatized interface to the levmar package.
void allocate_params()
Allocate parameters array based on previous call to nParams.
realT * p
Parameter array. On input is the initial estimates. On output has the estimated solution.
int n
I: measurement vector dimension.
void * adata
Pointer to possibly additional data, passed uninterpreted to func & jacf.
A c++ interface to the templatized levmar minimization routines..
The mxlib c++ namespace.
Definition: mxError.hpp:107
Wrapper for a native array to pass to levmarInterface, with Exponentially Modified Gaussian details.
realT lambda
the denominator or 1/peak-scale
levmarInterface fitter structure for the Exponentially Modified Gaussian with fixed constant level.
levmarInterface fitter structure for the Exponentially Modified Gaussian with arbitrary constant leve...