8 #include <gsl/gsl_multimin.h> 9 #include <gsl/gsl_sf.h> 23 const vector<double> *
x,*
y;
27 double lsq(
const vector<double> &
y,
const vector<double> &yFit)
30 ofstream f(
"debugfit.txt");
32 for(
auto ui=0;ui<yFit.size();ui++)
33 f << y[ui] <<
"\t" << yFit[ui] << endl;
37 for(
auto ui=0u;ui<y.size();ui++)
38 dySqr+=(y[ui]-yFit[ui])*(y[ui]-yFit[ui]);
42 void voigtProfile(
const vector<double> &
x,
double sigma,
double gamma, vector<double> &
y);
46 double sigma=v->data[0];
47 double gamma=v->data[1];
49 double amp=v->data[3];
56 const vector<double> &yV = *(vParams->
y);
65 double amp=v->data[3];
74 const vector<double> &yV = *(vParams->
y);
84 double xp =v->data[0];
85 double sigma=v->data[1];
86 double lambda=v->data[2];
87 double amp=v->data[3];
96 const vector<double> &yV = *(vParams->
y);
97 double lsqV =
lsq(yV,yFit);
106 double mu=v->data[1];
107 double amp=v->data[2];
108 double sigma=v->data[3];
114 expNorm(*(vParams->
x),K,mu,sigma, amp,yFit);
115 const vector<double> &yV = *(vParams->
y);
117 double lsqV =
lsq(yV,yFit);
123 bool fitVoigt(
const vector<double> &x,
const vector<double> &y,
double &sigma,
double &gamma,
double &mu,
double &,
bool autoInit)
130 sigma= (*std::max_element(x.begin(),x.end()) - *std::min_element(x.begin(),x.end()))/4;
134 const double VOIGT_NORM_MAX=0.3;
135 amp = *(std::max_element(y.begin(),y.end()))*VOIGT_NORM_MAX;
141 gsl_vector *xZero = gsl_vector_alloc (4);
142 gsl_vector *stepSize= gsl_vector_alloc (4);
144 xZero->data[0] = sigma;
145 xZero->data[1] = gamma;
147 xZero->data[3] = amp;
150 stepSize->data[0] = sigma/10;
151 stepSize->data[1] = gamma/10;
152 stepSize->data[2] = mu/2;
153 stepSize->data[3] = amp;
157 const gsl_multimin_fminimizer_type *t= gsl_multimin_fminimizer_nmsimplex2rand;
158 gsl_multimin_fminimizer *s = gsl_multimin_fminimizer_alloc (t, 4);
164 gsl_multimin_function minFunc;
167 minFunc.params=(
void*)(&vParams);
169 gsl_multimin_fminimizer_set (s, &minFunc, xZero, stepSize);
171 const unsigned int MAX_NM_STEPS=5000;
172 unsigned int it=0,status;
176 status = gsl_multimin_fminimizer_iterate(s);
181 auto size = gsl_multimin_fminimizer_size (s);
182 status = gsl_multimin_test_size (size, 1e-6);
188 if (status == GSL_SUCCESS)
190 gsl_vector_free(stepSize);
191 gsl_vector_free(xZero);
192 gsl_multimin_fminimizer_free(s);
195 }
while( it< MAX_NM_STEPS && status == GSL_CONTINUE);
197 gsl_vector_free(stepSize);
198 gsl_vector_free(xZero);
199 gsl_multimin_fminimizer_free(s);
204 bool fitDoniachSunjic(
const vector<double> &x,
const vector<double> &y,
double &a,
double &f,
double &mu,
double &,
bool autoInit)
211 a= (*std::max_element(x.begin(),x.end()) - *std::min_element(x.begin(),x.end()))/12;
214 amp = *(std::max_element(y.begin(),y.end()))*50;
219 gsl_vector *xZero = gsl_vector_alloc (4);
220 gsl_vector *stepSize= gsl_vector_alloc (4);
225 xZero->data[3] = amp;
228 gsl_vector_set_all(stepSize,1.0);
231 const gsl_multimin_fminimizer_type *t= gsl_multimin_fminimizer_nmsimplex2rand;
232 gsl_multimin_fminimizer *s = gsl_multimin_fminimizer_alloc (t, 4);
238 gsl_multimin_function minFunc;
241 minFunc.params=(
void*)(&vParams);
243 gsl_multimin_fminimizer_set (s, &minFunc, xZero, stepSize);
245 const unsigned int MAX_NM_STEPS=5000;
246 unsigned int it=0,status;
250 status = gsl_multimin_fminimizer_iterate(s);
255 auto size = gsl_multimin_fminimizer_size (s);
256 status = gsl_multimin_test_size (size, 1e-6);
263 if (status == GSL_SUCCESS)
265 gsl_vector_free(stepSize);
266 gsl_vector_free(xZero);
267 gsl_multimin_fminimizer_free(s);
270 }
while( it< MAX_NM_STEPS && status == GSL_CONTINUE);
272 gsl_vector_free(stepSize);
273 gsl_vector_free(xZero);
274 gsl_multimin_fminimizer_free(s);
280 bool fitExpNorm(
const vector<double> &x,
const vector<double> &y,
281 double &K,
double &mu,
double &sigma,
double &,
bool autoInit)
291 amp = *(std::max_element(y.begin(),y.end()))*2.0;
295 const unsigned int DIMENSION=4;
296 gsl_vector *xZero = gsl_vector_alloc (DIMENSION);
297 gsl_vector *stepSize= gsl_vector_alloc (DIMENSION);
301 xZero->data[2] = amp;
302 xZero->data[3] = sigma;
305 stepSize->data[0] = K;
306 stepSize->data[1] = mu;
307 stepSize->data[3] = 0.1;
308 stepSize->data[2] = amp*10;
311 const gsl_multimin_fminimizer_type *t= gsl_multimin_fminimizer_nmsimplex2rand;
312 gsl_multimin_fminimizer *s = gsl_multimin_fminimizer_alloc (t, DIMENSION);
318 gsl_multimin_function minFunc;
321 minFunc.params=(
void*)(&vParams);
323 gsl_multimin_fminimizer_set (s, &minFunc, xZero, stepSize);
325 const unsigned int MAX_NM_STEPS=100;
326 unsigned int it=0,status;
330 status = gsl_multimin_fminimizer_iterate(s);
335 auto size = gsl_multimin_fminimizer_size (s);
336 status = gsl_multimin_test_size (size, 1e-8);
344 if (status == GSL_SUCCESS)
346 gsl_vector_free(stepSize);
347 gsl_vector_free(xZero);
348 gsl_multimin_fminimizer_free(s);
351 }
while( it< MAX_NM_STEPS && status == GSL_CONTINUE);
353 gsl_vector_free(stepSize);
354 gsl_vector_free(xZero);
355 gsl_multimin_fminimizer_free(s);
360 bool fitLikeLogGaussian(
const vector<double> &x,
const vector<double> &y,
double &lambda,
double &sigma,
double &xp,
double &,
double &h,
bool autoInit)
367 lambda= (*std::max_element(x.begin(),x.end()) - *std::min_element(x.begin(),x.end()))/12;
370 amp = *(std::max_element(y.begin(),y.end()));
375 gsl_vector *xZero = gsl_vector_alloc (5);
376 gsl_vector *stepSize= gsl_vector_alloc (5);
384 xZero->data[1] = sigma;
385 xZero->data[2] = lambda;
386 xZero->data[3] = amp;
391 stepSize->data[0]=xp/10;
392 stepSize->data[1]=sigma/2.0;
393 stepSize->data[2]=0.6;
394 stepSize->data[3]=amp/2;
395 stepSize->data[4]=.5;
398 const gsl_multimin_fminimizer_type *t= gsl_multimin_fminimizer_nmsimplex2rand;
399 gsl_multimin_fminimizer *s = gsl_multimin_fminimizer_alloc (t, 5);
405 gsl_multimin_function minFunc;
408 minFunc.params=(
void*)(&vParams);
410 gsl_multimin_fminimizer_set (s, &minFunc, xZero, stepSize);
412 const unsigned int MAX_NM_STEPS=500;
413 unsigned int it=0,status;
417 status = gsl_multimin_fminimizer_iterate(s);
422 auto size = gsl_multimin_fminimizer_size (s);
423 status = gsl_multimin_test_size (size, 1e-6);
427 lambda=s->x->data[2];
434 if (status == GSL_SUCCESS)
436 gsl_vector_free(stepSize);
437 gsl_vector_free(xZero);
438 gsl_multimin_fminimizer_free(s);
441 }
while( it< MAX_NM_STEPS && status == GSL_CONTINUE);
443 gsl_vector_free(stepSize);
444 gsl_vector_free(xZero);
445 gsl_multimin_fminimizer_free(s);
449 void voigtProfile(
const vector<double> &x,
double sigma,
double gamma, vector<double> &y)
458 const double fwhmG= 2*sqrt(log(2))*sigma;
460 const double fwhmL= 2*gamma;
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);
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++)
475 L = 1.0/(
M_PI*gamma)/( 1.0 + x[ui]*x[ui]/(gamma*gamma));
477 G = 1.0/(sigma*sqrt(2.0*
M_PI))*exp(-(x[ui]*x[ui])/(2.0*sigma*sigma));
479 y[ui]=(mix)*L+(1-mix)*G;
487 double gamma,
double mu,
double amp, vector<double> &y)
489 vector<double> shiftX;
491 for(
auto &v : shiftX)
502 void doniachSunjic(
const std::vector<double> &x,
double &a,
double &F,
double &mu,
double &,
503 std::vector<double> &y)
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));
510 void likeLogGaussian(
const std::vector<double> &x,
double &xp,
double &sigma,
double &lambda,
double &,
double &h,
511 std::vector<double> &y)
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);
519 for(
auto ui=0;ui<x.size();ui++)
523 lgvc=1 + 2.0*z*lambda*(x[ui]-xp)/(z*z +1);
526 y[ui] = amp*A*exp(-1.0/(2.0*sigma*sigma)*log(lgvc));
532 void expNorm(
const std::vector<double> &x,
double &K,
double &mu,
double &sigma,
double &, vector<double> &y)
535 for(
auto ui=0;ui<x.size();ui++)
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);
555 const vector<double> &y = *(vParams->
y);
556 const vector<double> &x = *(vParams->
x);
560 float amp=v->data[2];
561 float sigma=v->data[3];
568 for(
auto ui=0;ui<y.size();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));
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));
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;
const vector< double > * y
bool fitLikeLogGaussian(const std::vector< double > &x, const std::vector< double > &y, double &lambda, double &sigma, double &xp, double &, double &h, bool autoInit=true)
Fit a smoothed log-gaussian curve (arxiv:0711.4449)
const vector< double > * x
void doniachSunjic(const std::vector< double > &x, double &a, double &F, double &mu, double &, std::vector< double > &y)
generate a Doniach-Sunjic profile
bool fitDoniachSunjic(const std::vector< double > &x, const std::vector< double > &y, double &a, double &f, double &mu, double &, bool autoInit=true)
Fit a Doniach-Sunjic curve.
void voigtProfile(const std::vector< double > &x, double sigma, double gamma, double mu, double amp, std::vector< double > &y)
Generate a shifted voigt profile.
double fitVoigtFunc(const gsl_vector *v, void *params)
T weightedMean(const std::vector< T > &values, const std::vector< T > &weight)
void expNorm(const std::vector< double > &x, double &K, double &mu, double &sigma, double &, std::vector< double > &y)
Exponentially decaying normal distribution.
bool fitExpNorm(const std::vector< double > &x, const std::vector< double > &y, double &K, double &mu, double &sigma, double &, bool autoInit=true)
Fit a smoothed log-gaussian curve (arxiv:0711.4449)
bool fitVoigt(const std::vector< double > &x, const std::vector< double > &y, double &sigma, double &gamma, double &mu, double &, bool autoInit=true)
Fit a Voigt function to the given X/Y values. Internally, a function minimiser is used...
void expNormLSQDerivs(const gsl_vector *v, void *params, gsl_vector *df)
void likeLogGaussian(const std::vector< double > &x, double &xp, double &sigma, double &lambda, double &, double &h, std::vector< double > &y)
Generate a smoothed log-gaussian curve.
double lsq(const std::vector< double > &y, const std::vector< double > &yFit)