libatomprobe
Library for Atom Probe Tomography (APT) computation
fitting.cpp
Go to the documentation of this file.
1 #include <vector>
2 #include <cmath>
3 #include <algorithm>
4 
7 
8 #include <gsl/gsl_multimin.h>
9 #include <gsl/gsl_sf.h>
10 
11 using std::vector;
12 
13 //DEBUG ONLY
14 #include <fstream>
15 using std::cerr;
16 using std::endl;
17 using std::ofstream;
18 
19 namespace AtomProbe
20 {
21 struct DATA_FIT
22 {
23  const vector<double> *x,*y;
24 };
25 
26 //Return least-squares values (y-y')^2
27 double lsq(const vector<double> &y, const vector<double> &yFit)
28 {
29 // ASSERT(y.size() ==yFit.size());
30  ofstream f("debugfit.txt");
31 
32  for(auto ui=0;ui<yFit.size();ui++)
33  f << y[ui] << "\t" << yFit[ui] << endl;
34 
35 
36  double dySqr=0;
37  for(auto ui=0u;ui<y.size();ui++)
38  dySqr+=(y[ui]-yFit[ui])*(y[ui]-yFit[ui]);
39  return dySqr;
40 }
41 
42 void voigtProfile(const vector<double> &x, double sigma, double gamma, vector<double> &y);
43 
44 double fitVoigtFunc(const gsl_vector *v, void *params)
45 {
46  double sigma=v->data[0];
47  double gamma=v->data[1];
48  double mu=v->data[2];
49  double amp=v->data[3];
50 
51  DATA_FIT *vParams=(DATA_FIT*)params;
52 
53  vector<double> yFit;
54  voigtProfile(*(vParams->x),sigma,gamma,mu,amp,yFit);
55 
56  const vector<double> &yV = *(vParams->y);
57  return lsq(yV,yFit);
58 }
59 
60 double fitDoniachSunjic(const gsl_vector *v, void *params)
61 {
62  double a=v->data[0];
63  double f=v->data[1];
64  double mu=v->data[2];
65  double amp=v->data[3];
66 
67  vector<double> xFit;
68  DATA_FIT *vParams=(DATA_FIT*)params;
69 
70  vector<double> yFit;
71  doniachSunjic(*(vParams->x),a,f,mu,amp,yFit);
72 
73  //Least-squares
74  const vector<double> &yV = *(vParams->y);
75  return lsq(yV,yFit);
76 }
77 
78 //Arxiv : 0711.4449, Equations (1-4)
79 // A "smoothed" log-gaussian like profile
80 double fitLikeLogGaussian( const gsl_vector *v, void *params)
81 {
82  //FIXME :Is amp & h redudant??
83  //xp : x-positioning
84  double xp =v->data[0];
85  double sigma=v->data[1];
86  double lambda=v->data[2];
87  double amp=v->data[3];
88  double h=v->data[4];
89 
90  vector<double> xFit;
91  DATA_FIT *vParams=(DATA_FIT*)params;
92 
93  vector<double> yFit;
94  likeLogGaussian(*(vParams->x),xp,sigma, lambda,amp,h,yFit);
95 
96  const vector<double> &yV = *(vParams->y);
97  double lsqV = lsq(yV,yFit);
98  //cerr << "LSQ :" << lsqV << endl;
99  return lsqV;
100 }
101 
102 //Exponential-modified normal
103 double fitExpNorm(const gsl_vector *v, void *params)
104 {
105  double K=v->data[0];
106  double mu=v->data[1];
107  double amp=v->data[2];
108  double sigma=v->data[3];
109 
110  vector<double> xFit;
111  DATA_FIT *vParams=(DATA_FIT*)params;
112 
113  vector<double> yFit;
114  expNorm(*(vParams->x),K,mu,sigma, amp,yFit);
115  const vector<double> &yV = *(vParams->y);
116 
117  double lsqV = lsq(yV,yFit);
118 // cerr << "lsq :" << lsqV << endl;
119  return lsqV;
120 }
121 
122 //Values should be X-positions and y- counts
123 bool fitVoigt(const vector<double> &x, const vector<double> &y, double &sigma, double &gamma, double &mu, double &amp, bool autoInit)
124 {
125  // == Initial guess ==
126  //find the mean of the X values
127  if(autoInit)
128  {
129  mu= weightedMean(x,y);
130  sigma= (*std::max_element(x.begin(),x.end()) - *std::min_element(x.begin(),x.end()))/4;
131  gamma=1.0;
132  //Find the maximum y value
133  // FIXME: More stable to use area under curve, rather than max-y
134  const double VOIGT_NORM_MAX=0.3; //The maximum for the voigt function is parameter dependent.
135  amp = *(std::max_element(y.begin(),y.end()))*VOIGT_NORM_MAX;
136 
137  }
138  //=====================
139 
140 
141  gsl_vector *xZero = gsl_vector_alloc (4);
142  gsl_vector *stepSize= gsl_vector_alloc (4);
143 
144  xZero->data[0] = sigma;
145  xZero->data[1] = gamma;
146  xZero->data[2] = mu;
147  xZero->data[3] = amp;
148 
149  //set step sizes
150  stepSize->data[0] = sigma/10;
151  stepSize->data[1] = gamma/10;
152  stepSize->data[2] = mu/2;
153  stepSize->data[3] = amp;
154 
155 
156  //Use nelder mead (random initial direction) to find solution
157  const gsl_multimin_fminimizer_type *t= gsl_multimin_fminimizer_nmsimplex2rand;
158  gsl_multimin_fminimizer *s = gsl_multimin_fminimizer_alloc (t, 4);
159 
160  DATA_FIT vParams;
161  vParams.x = &x;
162  vParams.y = &y;
163 
164  gsl_multimin_function minFunc;
165  minFunc.n=4;
166  minFunc.f=fitVoigtFunc;
167  minFunc.params=(void*)(&vParams);
168 
169  gsl_multimin_fminimizer_set (s, &minFunc, xZero, stepSize);
170 
171  const unsigned int MAX_NM_STEPS=5000;
172  unsigned int it=0,status;
173  do
174  {
175  it++;
176  status = gsl_multimin_fminimizer_iterate(s);
177 
178  if (status)
179  break;
180 
181  auto size = gsl_multimin_fminimizer_size (s);
182  status = gsl_multimin_test_size (size, 1e-6);
183 
184  sigma=s->x->data[0];
185  gamma=s->x->data[1];
186  mu=s->x->data[2];
187  amp=s->x->data[3];
188  if (status == GSL_SUCCESS)
189  {
190  gsl_vector_free(stepSize);
191  gsl_vector_free(xZero);
192  gsl_multimin_fminimizer_free(s);
193  return true;
194  }
195  } while( it< MAX_NM_STEPS && status == GSL_CONTINUE);
196 
197  gsl_vector_free(stepSize);
198  gsl_vector_free(xZero);
199  gsl_multimin_fminimizer_free(s);
200  //Failed to successfully minimise
201  return false;
202 }
203 
204 bool fitDoniachSunjic(const vector<double> &x, const vector<double> &y, double &a, double &f, double &mu, double &amp, bool autoInit)
205 {
206  // == Initial guess ==
207  //find the mean of the X values
208  if(autoInit)
209  {
210  mu= weightedMean(x,y);
211  a= (*std::max_element(x.begin(),x.end()) - *std::min_element(x.begin(),x.end()))/12;
212  f=1.0;
213  //Find the maximum y value
214  amp = *(std::max_element(y.begin(),y.end()))*50;
215  }
216  //=====================
217 
218 
219  gsl_vector *xZero = gsl_vector_alloc (4);
220  gsl_vector *stepSize= gsl_vector_alloc (4);
221 
222  xZero->data[0] = a;
223  xZero->data[1] = f;
224  xZero->data[2] = mu;
225  xZero->data[3] = amp;
226 
227  //set step sizes
228  gsl_vector_set_all(stepSize,1.0);
229 
230  //Use nelder mead (random initial direction) to find solution
231  const gsl_multimin_fminimizer_type *t= gsl_multimin_fminimizer_nmsimplex2rand;
232  gsl_multimin_fminimizer *s = gsl_multimin_fminimizer_alloc (t, 4);
233 
234  DATA_FIT vParams;
235  vParams.x = &x;
236  vParams.y = &y;
237 
238  gsl_multimin_function minFunc;
239  minFunc.n=4;
240  minFunc.f=fitDoniachSunjic;
241  minFunc.params=(void*)(&vParams);
242 
243  gsl_multimin_fminimizer_set (s, &minFunc, xZero, stepSize);
244 
245  const unsigned int MAX_NM_STEPS=5000;
246  unsigned int it=0,status;
247  do
248  {
249  it++;
250  status = gsl_multimin_fminimizer_iterate(s);
251 
252  if (status)
253  break;
254 
255  auto size = gsl_multimin_fminimizer_size (s);
256  status = gsl_multimin_test_size (size, 1e-6);
257 
258  a=s->x->data[0];
259  f=s->x->data[1];
260  mu=s->x->data[2];
261  amp=s->x->data[3];
262  //--
263  if (status == GSL_SUCCESS)
264  {
265  gsl_vector_free(stepSize);
266  gsl_vector_free(xZero);
267  gsl_multimin_fminimizer_free(s);
268  return true;
269  }
270  } while( it< MAX_NM_STEPS && status == GSL_CONTINUE);
271 
272  gsl_vector_free(stepSize);
273  gsl_vector_free(xZero);
274  gsl_multimin_fminimizer_free(s);
275  //Failed to successfully minimise
276  return false;
277 }
278 
279 
280 bool fitExpNorm(const vector<double> &x, const vector<double> &y,
281  double &K, double &mu,double &sigma,double &amp,bool autoInit)
282 {
283  if(autoInit)
284  {
285  //These are pretty heuristic. Weighted mean initialises X position
286  // K is right-tailed, so >1. amp is adjusted for K against some sample peaks
287  // and sigma is a wild guess, based on some examples
288  mu=weightedMean(x,y);
289  K=1.5;
290  //Find the maximum y value
291  amp = *(std::max_element(y.begin(),y.end()))*2.0;
292  sigma=0.05;
293  }
294 
295  const unsigned int DIMENSION=4;
296  gsl_vector *xZero = gsl_vector_alloc (DIMENSION);
297  gsl_vector *stepSize= gsl_vector_alloc (DIMENSION);
298 
299  xZero->data[0] = K;
300  xZero->data[1] = mu;
301  xZero->data[2] = amp;
302  xZero->data[3] = sigma;
303 
304  //set step sizes
305  stepSize->data[0] = K;
306  stepSize->data[1] = mu;
307  stepSize->data[3] = 0.1;
308  stepSize->data[2] = amp*10;
309 
310  //Use nelder mead (random initial direction) to find solution
311  const gsl_multimin_fminimizer_type *t= gsl_multimin_fminimizer_nmsimplex2rand;
312  gsl_multimin_fminimizer *s = gsl_multimin_fminimizer_alloc (t, DIMENSION);
313 
314  DATA_FIT vParams;
315  vParams.x = &x;
316  vParams.y = &y;
317 
318  gsl_multimin_function minFunc;
319  minFunc.n=DIMENSION;
320  minFunc.f=fitExpNorm;
321  minFunc.params=(void*)(&vParams);
322 
323  gsl_multimin_fminimizer_set (s, &minFunc, xZero, stepSize);
324 
325  const unsigned int MAX_NM_STEPS=100;
326  unsigned int it=0,status;
327  do
328  {
329  it++;
330  status = gsl_multimin_fminimizer_iterate(s);
331 
332  if (status)
333  break;
334 
335  auto size = gsl_multimin_fminimizer_size (s);
336  status = gsl_multimin_test_size (size, 1e-8);
337 
338  K=s->x->data[0];
339  mu=s->x->data[1];
340  amp=s->x->data[2];
341  sigma=s->x->data[3];
342 
343 // cerr << "K:" << K << " mu:" << mu << " amp :" << amp << endl;
344  if (status == GSL_SUCCESS)
345  {
346  gsl_vector_free(stepSize);
347  gsl_vector_free(xZero);
348  gsl_multimin_fminimizer_free(s);
349  return true;
350  }
351  } while( it< MAX_NM_STEPS && status == GSL_CONTINUE);
352 
353  gsl_vector_free(stepSize);
354  gsl_vector_free(xZero);
355  gsl_multimin_fminimizer_free(s);
356  //Failed to successfully minimise
357  return false;
358 }
359 
360 bool fitLikeLogGaussian(const vector<double> &x, const vector<double> &y, double &lambda, double &sigma, double &xp, double &amp, double &h, bool autoInit)
361 {
362  // == Initial guess ==
363  //find the mean of the X values
364  if(autoInit)
365  {
366  xp= weightedMean(x,y);
367  lambda= (*std::max_element(x.begin(),x.end()) - *std::min_element(x.begin(),x.end()))/12;
368  sigma=lambda*2;
369  //Find the maximum y value
370  amp = *(std::max_element(y.begin(),y.end()));
371  }
372  //=====================
373 
374 
375  gsl_vector *xZero = gsl_vector_alloc (5);
376  gsl_vector *stepSize= gsl_vector_alloc (5);
377 
378  //Note that we re-arrange this here
379  // so that the external interface to this
380  // function is consistent with others.
381  // but that the function parameter orders
382  // is consistent with the paper
383  xZero->data[0] = xp;
384  xZero->data[1] = sigma;
385  xZero->data[2] = lambda;
386  xZero->data[3] = amp;
387  xZero->data[4] = h;
388 
389  //set step sizes
390 
391  stepSize->data[0]=xp/10; //xp
392  stepSize->data[1]=sigma/2.0; //sigma
393  stepSize->data[2]=0.6;//lambda
394  stepSize->data[3]=amp/2;//amp
395  stepSize->data[4]=.5;//h
396 
397  //Use nelder mead (random initial direction) to find solution
398  const gsl_multimin_fminimizer_type *t= gsl_multimin_fminimizer_nmsimplex2rand;
399  gsl_multimin_fminimizer *s = gsl_multimin_fminimizer_alloc (t, 5);
400 
401  DATA_FIT vParams;
402  vParams.x = &x;
403  vParams.y = &y;
404 
405  gsl_multimin_function minFunc;
406  minFunc.n=5;
407  minFunc.f=fitLikeLogGaussian;
408  minFunc.params=(void*)(&vParams);
409 
410  gsl_multimin_fminimizer_set (s, &minFunc, xZero, stepSize);
411 
412  const unsigned int MAX_NM_STEPS=500;
413  unsigned int it=0,status;
414  do
415  {
416  it++;
417  status = gsl_multimin_fminimizer_iterate(s);
418 
419  if (status)
420  break;
421 
422  auto size = gsl_multimin_fminimizer_size (s);
423  status = gsl_multimin_test_size (size, 1e-6);
424 
425  xp=s->x->data[0];
426  sigma=s->x->data[1];
427  lambda=s->x->data[2];
428  amp=s->x->data[3];
429  h = s->x->data[4];
430 
431 // cerr << "Fit : xp" <<xp << " sigma:" << sigma << " lambda:" << lambda<<
432 // " amp:" << amp << " h :" << h << endl;
433  //--
434  if (status == GSL_SUCCESS)
435  {
436  gsl_vector_free(stepSize);
437  gsl_vector_free(xZero);
438  gsl_multimin_fminimizer_free(s);
439  return true;
440  }
441  } while( it< MAX_NM_STEPS && status == GSL_CONTINUE);
442 
443  gsl_vector_free(stepSize);
444  gsl_vector_free(xZero);
445  gsl_multimin_fminimizer_free(s);
446  //Failed to successfully minimise
447  return false;
448 }
449 void voigtProfile(const vector<double> &x, double sigma, double gamma, vector<double> &y)
450 {
451  y.resize(x.size());
452 
453  //Simple approximation. I think arxiv:1901.08366v1
454  // has more detailed versions
455  // My old code has L = 1/pi() * ( 0.5*gammaV./( (x-x0).^2 + 0.5*gammaV^2));
456 
457  //Full-width-half-maximum gaussian
458  const double fwhmG= 2*sqrt(log(2))*sigma;
459  //Full-width-half-maximum lorentizan
460  const double fwhmL= 2*gamma;
461  //Equation 10,Ida et al, Extended pseudo-Voigt function for approximating the Voigt profile
462  const double tch = pow(fwhmG*fwhmG*fwhmG*fwhmG*fwhmG +
463  2.69269*fwhmG*fwhmG*fwhmG*fwhmG*fwhmL+
464  2.42843*fwhmG*fwhmG*fwhmG*fwhmL*fwhmL +
465  4.47163*fwhmG*fwhmG*fwhmL*fwhmL*fwhmL +
466  0.07842*fwhmG*fwhmL*fwhmL*fwhmL*fwhmL +
467  fwhmL*fwhmL*fwhmL*fwhmL*fwhmL,0.2);
468 
469  const double mix = 1.36603*fwhmL/tch -0.47719*(fwhmL/tch)*(fwhmL/tch) +
470  0.11116*(fwhmL/tch)*(fwhmL/tch)*(fwhmL/tch) ;
471  for(auto ui=0;ui<x.size();ui++)
472  {
473  double L,G;
474  //Lorentizan (Cauchy)
475  L = 1.0/(M_PI*gamma)/( 1.0 + x[ui]*x[ui]/(gamma*gamma));
476  //Gaussian
477  G = 1.0/(sigma*sqrt(2.0*M_PI))*exp(-(x[ui]*x[ui])/(2.0*sigma*sigma));
478 
479  y[ui]=(mix)*L+(1-mix)*G;
480  }
481 
482 
483 }
484 
485 //Convenience wrapper with additional parameters
486 void voigtProfile(const vector<double> &x, double sigma,
487  double gamma, double mu, double amp, vector<double> &y)
488 {
489  vector<double> shiftX;
490  shiftX =x;
491  for( auto &v : shiftX)
492  v=v-mu;
493 
494  //Generate prfoile
495  voigtProfile(shiftX,sigma,gamma,y);
496 
497  //Scale y
498  for(auto &v : y)
499  v*=amp;
500 }
501 
502 void doniachSunjic(const std::vector<double> &x, double &a, double &F, double &mu,double &amp,
503  std::vector<double> &y)
504 {
505  y.resize(x.size());
506  for(auto ui=0;ui<x.size();ui++)
507  y[ui] = amp*( M_PI*a/2 + (1-a)*atan( (x[ui]-mu)/F))/(F + (x[ui]-mu)*(x[ui]-mu));
508 }
509 
510 void likeLogGaussian(const std::vector<double> &x, double &xp, double &sigma, double &lambda,double &amp, double &h,
511  std::vector<double> &y)
512 {
513  double z = sqrt(h*abs(lambda) + sqrt(h*h*lambda*lambda + 1));
514  double A = sqrt(2.0/M_PI) * abs(lambda)/( (z+ 1.0/z)*sigma)*exp(-sigma*sigma/2.0);
515 
516 
517 
518  y.resize(x.size());
519  for(auto ui=0;ui<x.size();ui++)
520  {
521  //Log contents
522  double lgvc;
523  lgvc=1 + 2.0*z*lambda*(x[ui]-xp)/(z*z +1);
524 
525  if(lgvc >0)
526  y[ui] = amp*A*exp(-1.0/(2.0*sigma*sigma)*log(lgvc));
527  else
528  y[ui]=0;
529  }
530 }
531 
532 void expNorm(const std::vector<double> &x, double &K, double &mu, double &sigma,double &amp, vector<double> &y)
533 {
534  y.resize(x.size());
535  for(auto ui=0;ui<x.size();ui++)
536  {
537  double cInp;
538  cInp= -((x[ui]-mu)/sigma-1.0/K)/sqrt(2.0);
539  y[ui] = amp/(2.0*K)*exp(1.0/(2.0*K*K)-(x[ui]-mu)/(K*sigma))*gsl_sf_erfc(cInp);
540  }
541 }
542 
543 //Find the partial derivatives of f= (c-expNom(x,k,mu,sigma,amp))^2
544 // f = (c - ((x - m) erfc((m - x)/σ - 1/K))/(sqrt(2) K σ) - (β e^(1/(2 K^2)))/(2 K))^2
545 //Partial/partial(m) =
546 // df/dm =2 (erfc((m - x)/σ - 1/K)/(sqrt(2) K σ) + (sqrt(2/π) (x - m) e^(-((m - x)/σ - 1/K)^2))/(K σ^2)) (c - ((x - m) erfc((m - x)/σ - 1/K))/(sqrt(2) K σ) - (β e^(1/(2 K^2)))/(2 K))
547 // df/dK = 2 (((x - m) erfc((m - x)/σ - 1/K))/(sqrt(2) K^2 σ) + (sqrt(2/π) (x - m) e^(-((m - x)/σ - 1/K)^2))/(K^3 σ) + (β e^(1/(2 K^2)))/(2 K^2) + (β e^(1/(2 K^2)))/(2 K^4)) (c - ((x - m) erfc((m - x)/σ - 1/K))/(sqrt(2) K σ) - (β e^(1/(2 K^2)))/(2 K))
548 // df/dσ= 2 (((x - m) erfc((m - x)/σ - 1/K))/(sqrt(2) K σ^2) - (sqrt(2/π) (m - x) (x - m) e^(-((m - x)/σ - 1/K)^2))/(K σ^3)) (c - ((x - m) erfc((m - x)/σ - 1/K))/(sqrt(2) K σ) - (β e^(1/(2 K^2)))/(2 K))
549 // df/da = -(e^(1/(2 K^2)) (-(a e^(1/(2 K^2)))/(2 K) + c - ((x - m) erfc((m - x)/σ - 1/K))/(sqrt(2) K σ)))/K
550 
551 void expNormLSQDerivs(const gsl_vector *v, void *params, gsl_vector *df)
552 {
553 
554  DATA_FIT *vParams=(DATA_FIT*)params;
555  const vector<double> &y = *(vParams->y);
556  const vector<double> &x = *(vParams->x);
557 
558  float K=v->data[0];
559  float m=v->data[1];
560  float amp=v->data[2];
561  float sigma=v->data[3];
562 
563  double dfdK=0; // K
564  double dfdm=0; //Mu
565  double dfda=0;// amp
566  double dfds=0; //sigma
567 
568  for(auto ui=0;ui<y.size();ui++)
569  {
570  float c;
571  c = y[ui];
572  dfdm+=2.0*(gsl_sf_erfc((m - x[ui])/sigma - 1.0/K)/(sqrt(2.0)*K*sigma) +
573  (sqrt(2.0/M_PI)*(x[ui] - m)*exp(-pow(((m - x[ui])/sigma - 1.0/K),2.0)))/(K*sigma*sigma)) *
574  (c - ((x[ui] - m)*gsl_sf_erfc((m - x[ui])/sigma - 1.0/K))/(sqrt(2.0)*K*sigma) - (amp*exp(1.0/(2.0*K*K)))/(2.0*K));
575 
576  dfdK+=2.0*(((x[ui] - m)*gsl_sf_erfc((m - x[ui])/sigma - 1.0/K))/(sqrt(2.0)*K*K*sigma) +
577  (sqrt(2.0/M_PI)*(x[ui] - m)*exp(-pow(((m - x[ui])/sigma - 1.0/K),2.0))/(K*K*K*sigma)) +
578  (amp*exp(1.0/(2.0*K*K)))/(2.0*K*K) + (amp*exp(1.0/(2.0*K*K)))/(2.0*K*K*K*K))*
579  (c - ((x[ui] - m)*gsl_sf_erfc((m - x[ui])/sigma - 1.0/K))/(sqrt(2.0)*K*sigma) - (amp*exp(1.0/(2.0*K*K)))/(2.0*K));
580  dfds+=2.0*(((x[ui] - m)*gsl_sf_erfc((m - x[ui])/sigma - 1.0/K))/(sqrt(2.0)*K*sigma*sigma) -
581  (sqrt(2.0/M_PI)*(m - x[ui])*(x[ui] - m)*exp(-pow(((m - x[ui])/sigma - 1.0/K),2.0)))/(K*sigma*sigma*sigma))*
582  (c - ((x[ui] - m)*gsl_sf_erfc((m - x[ui])/sigma - 1.0/K))/(sqrt(2.0)*K*sigma) - (amp*exp(1.0/(2.0*K*K)))/(2.0*K));
583 
584  dfda+= -(exp(1.0/(2.0*K*K))*(-(amp*exp(1.0/(2.0*K*K)))/(2.0*K) + c - ((x[ui] - m)*gsl_sf_erfc((m - x[ui])/sigma - 1.0/K))/(sqrt(2.0)*K*sigma)))/K;
585  }
586 
587  df->data[0]=dfdK;
588  df->data[1]=dfdm;
589  df->data[2]=dfda;
590  df->data[3]=dfds;
591 }
592 
593 
594 }
const vector< double > * y
Definition: fitting.cpp:23
bool fitLikeLogGaussian(const std::vector< double > &x, const std::vector< double > &y, double &lambda, double &sigma, double &xp, double &amp, double &h, bool autoInit=true)
Fit a smoothed log-gaussian curve (arxiv:0711.4449)
Definition: fitting.cpp:360
const vector< double > * x
Definition: fitting.cpp:23
void doniachSunjic(const std::vector< double > &x, double &a, double &F, double &mu, double &amp, std::vector< double > &y)
generate a Doniach-Sunjic profile
Definition: fitting.cpp:502
bool fitDoniachSunjic(const std::vector< double > &x, const std::vector< double > &y, double &a, double &f, double &mu, double &amp, bool autoInit=true)
Fit a Doniach-Sunjic curve.
Definition: fitting.cpp:204
void voigtProfile(const std::vector< double > &x, double sigma, double gamma, double mu, double amp, std::vector< double > &y)
Generate a shifted voigt profile.
Definition: fitting.cpp:486
double fitVoigtFunc(const gsl_vector *v, void *params)
Definition: fitting.cpp:44
T weightedMean(const std::vector< T > &values, const std::vector< T > &weight)
Definition: misc.h:52
#define M_PI
Definition: kd-example.cpp:34
void expNorm(const std::vector< double > &x, double &K, double &mu, double &sigma, double &amp, std::vector< double > &y)
Exponentially decaying normal distribution.
Definition: fitting.cpp:532
bool fitExpNorm(const std::vector< double > &x, const std::vector< double > &y, double &K, double &mu, double &sigma, double &amp, bool autoInit=true)
Fit a smoothed log-gaussian curve (arxiv:0711.4449)
Definition: fitting.cpp:280
bool fitVoigt(const std::vector< double > &x, const std::vector< double > &y, double &sigma, double &gamma, double &mu, double &amp, bool autoInit=true)
Fit a Voigt function to the given X/Y values. Internally, a function minimiser is used...
Definition: fitting.cpp:123
void expNormLSQDerivs(const gsl_vector *v, void *params, gsl_vector *df)
Definition: fitting.cpp:551
void likeLogGaussian(const std::vector< double > &x, double &xp, double &sigma, double &lambda, double &amp, double &h, std::vector< double > &y)
Generate a smoothed log-gaussian curve.
Definition: fitting.cpp:510
double lsq(const std::vector< double > &y, const std::vector< double > &yFit)
Definition: fitting.cpp:27