8 void MarqFitAlg::fgauss(
const float yd[],
const float p[],
const int npar,
const int ndat, std::vector<float> &res){
9 #if defined WITH_OPENMP 12 for(
int i=0;i<ndat;i++){
14 for(
int j=0;j<npar;j+=3){
15 yf = yf + p[j]*std::exp(-0.5*
std::pow((
float(i)-p[j+1])/p[j+2],2));
23 #if defined WITH_OPENMP 27 for(
int i=0;i<ndat;i++){
28 for(
int j=0;j<npar;j+=3){
29 const float xmu=
float(i)-p[j+1];
30 const float xmu_sg=xmu/p[j+2];
31 const float xmu_sg2=xmu_sg*xmu_sg;
32 dydp[i*npar+j] = std::exp(-0.5*xmu_sg2);
33 dydp[i*npar+j+1]=p[j]*dydp[i*npar+j]*xmu_sg/p[j+2];
34 dydp[i*npar+j+2]=dydp[i*npar+j+1]*xmu_sg;
51 void MarqFitAlg::setup_matrix(
const std::vector<float> &res,
const std::vector<float> &dydp,
const int npar,
const int ndat, std::vector<float> &
beta, std::vector<float> &
alpha)
56 #if defined WITH_OPENMP 63 beta[j]+=res[i]*dydp[i*npar+j];
68 #if defined WITH_OPENMP 72 for (j = 0; j < npar; j++){
73 for (k = j; k < npar; k++){
76 alpha[j*npar+
k]+=dydp[i*npar+j]*dydp[i*npar+
k];
78 if(k!=j)alpha[k*npar+j]=alpha[j*npar+
k];
89 std::vector<std::vector<float>>
h(npar, std::vector<float>(npar+1,0));
95 h[i][j]=alpha[i*npar+j];
103 for(j=i+1;j<npar;j++){
110 for(k=0;k<=npar;k++){
119 h[j][k+1]-=h[i][k+1]*h[j][i]/h[i][i];
125 dp[i]=h[i][npar]/h[i][i];
143 std::vector<double>
alpha(npar*npar);
146 std::vector<int> ik(npar);
147 std::vector<int> jk(npar);
148 double aMax,
save, det;
151 for (i=0; i<npar*npar; i++){
157 for (k = 0; k < npar; k++){
159 for (i = k; i < npar; i++){
160 for (j = k; j < npar;j++){
164 if (fabs(alpha[i*npar+j]) > fabs(aMax)){
165 aMax = alpha[i*npar+j];
171 if (aMax == 0)
return(det);
176 for (j = 0;j < npar;j++){
177 save = alpha[k*npar+j];
178 alpha[k*npar+j] = alpha[i*npar+j];
179 alpha[i*npar+j] = -
save;
185 for (i = 0; i < npar; i++){
186 save = alpha[i*npar+
k];
187 alpha[i*npar+
k] = alpha[i*npar+j];
188 alpha[i*npar+j] = -
save;
192 for (i = 0; i < npar; i++){
193 if (i != k) alpha[i*npar+
k] = -alpha[i*npar+
k]/aMax;
195 #if defined WITH_OPENMP 199 for (i = 0; i < npar; i++){
200 for (j = 0; j < npar;j++){
201 if ((i != k)&&(j!= k))alpha[i*npar+j]=alpha[i*npar+j]+alpha[i*npar+
k]*alpha[k*npar+j];
204 for (j = 0; j < npar;j++){
205 if (j != k) alpha[k*npar+j] = alpha[k*npar+j]/aMax;
207 alpha[k*npar+
k] = 1/aMax;
212 for (k = npar-1; k >=0; k--){
215 for (i = 0; i < npar; i++){
216 save = alpha[i*npar+
k];
217 alpha[i*npar+
k] = -alpha[i*npar+j];
218 alpha[i*npar+j] =
save;
223 for (j = 0; j < npar;j++){
224 save = alpha[k*npar+j];
225 alpha[k*npar+j] = -alpha[i*npar+j];
226 alpha[i*npar+j] =
save;
231 for (i=0; i<npar*npar; i++){
246 std::vector<float> res(nData);
247 std::vector<float> dydp(nData*nParam);
248 std::vector<float>
beta(nParam);
249 std::vector<float>
alpha(nParam*nParam);
250 std::vector<std::vector<float>> alpsav(nParam,std::vector<float>(nParam));
252 fgauss(y, p, nParam, nData, res);
253 dgauss(p, nParam, nData, dydp);
255 for(i=0;i<nParam;i++){
256 for(j=0;j<nParam;j++){
257 alpsav[i][j]=alpha[i*nParam+j];
263 for(i=0;i<nParam;i++){
264 if(alpha[i*nParam+i]>=0.){
265 perr[i]=sqrt(alpha[i*nParam+i]);
267 perr[i]=alpha[i*nParam+i];
274 int MarqFitAlg::mrqdtfit(
float &lambda,
float p[],
float y[],
const int nParam,
const int nData,
float &chiSqr,
float &dchiSqr)
276 std::vector<float> plimmin(nParam,std::numeric_limits<float>::lowest());
278 return mrqdtfit(lambda, p, &plimmin[0], &plimmax[0], y, nParam, nData, chiSqr, dchiSqr);
281 int MarqFitAlg::mrqdtfit(
float &lambda,
float p[],
float plimmin[],
float plimmax[],
float y[],
const int nParam,
const int nData,
float &chiSqr,
float &dchiSqr)
284 float nu,
rho,lzmlh,amax,chiSq0;
286 std::vector<float> res(nData);
287 std::vector<float>
beta(nParam);
288 std::vector<float> dp(nParam);
289 std::vector<float> alpsav(nParam);
290 std::vector<float> psav(nParam);
291 std::vector<float> dydp(nData*nParam);
292 std::vector<float>
alpha(nParam*nParam);
294 bool haslimits =
false;
295 for(j=0;j<nParam;j++){
302 fgauss(y, p, nParam, nData, res);
304 dgauss(p, nParam, nData, dydp);
308 for(j = 0; j < nParam; j++){
309 if(alpha[j*nParam+j]>amax)amax=alpha[j*nParam+j];
313 for(j = 0; j < nParam; j++){
314 alpsav[j]=alpha[j*nParam+j];
315 alpha[j*nParam+j]=alpsav[j]+lambda;
323 for(j=0;j<nParam;j++){
327 fgauss(y, p, nParam, nData, res);
330 for(j=0;j<nParam;j++){
331 if (p[j]<=plimmin[j] || p[j]>=plimmax[j]) chiSqr*=10000;
336 for(j=0;j<nParam;j++){
337 lzmlh+=dp[j]*(lambda*dp[j]+beta[j]);
339 rho=2.*(chiSq0-chiSqr)/lzmlh;
341 for (j=0;j<nParam;j++)p[j]=psav[j];
345 for(j = 0; j < nParam; j++){
346 alpha[j*nParam+j]=alpsav[j]+lambda;
351 lambda=lambda*fmax(0.333333,1.-
pow(2.*rho-1.,3));
352 dchiSqr=chiSqr-chiSq0;
double beta(double KE, const simb::MCParticle *part)
void solve_matrix(const std::vector< float > &beta, const std::vector< float > &alpha, const int npar, std::vector< float > &dp)
int mrqdtfit(float &lambda, float p[], float y[], const int nParam, const int nData, float &chiSqr, float &dchiSqr)
int cal_perr(float p[], float y[], const int nParam, const int nData, float perr[])
void fgauss(const float yd[], const float p[], const int npar, const int ndat, std::vector< float > &res)
static int max(int a, int b)
float cal_xi2(const std::vector< float > &res, const int ndat)
void dgauss(const float p[], const int npar, const int ndat, std::vector< float > &dydp)
float invrt_matrix(std::vector< float > &alphaf, const int npar)
void setup_matrix(const std::vector< float > &res, const std::vector< float > &dydp, const int npar, const int ndat, std::vector< float > &beta, std::vector< float > &alpha)