11 std::vector<float>& res)
13 #if defined WITH_OPENMP 16 for (
int i = 0; i < ndat; i++) {
18 for (
int j = 0; j < npar; j += 3) {
19 yf = yf + p[j] * std::exp(-0.5 * std::pow((
float(i) - p[j + 1]) / p[j + 2], 2));
26 void MarqFitAlg::dgauss(
const float p[],
const int npar,
const int ndat, std::vector<float>& dydp)
28 #if defined WITH_OPENMP 30 #ifdef __INTEL_COMPILER 34 for (
int i = 0; i < ndat; i++) {
35 for (
int j = 0; j < npar; j += 3) {
36 const float xmu = float(i) - p[j + 1];
37 const float xmu_sg = xmu / p[j + 2];
38 const float xmu_sg2 = xmu_sg * xmu_sg;
39 dydp[i * npar + j] = std::exp(-0.5 * xmu_sg2);
40 dydp[i * npar + j + 1] = p[j] * dydp[i * npar + j] * xmu_sg / p[j + 2];
41 dydp[i * npar + j + 2] = dydp[i * npar + j + 1] * xmu_sg;
52 for (i = 0; i < ndat; i++) {
53 xi2 += res[i] * res[i];
60 const std::vector<float>& dydp,
63 std::vector<float>& beta,
64 std::vector<float>& alpha)
69 #if defined WITH_OPENMP 71 #ifdef __INTEL_COMPILER 75 for (j = 0; j < npar; j++) {
77 for (i = 0; i < ndat; i++) {
78 beta[j] += res[i] * dydp[i * npar + j];
83 #if defined WITH_OPENMP 85 #ifdef __INTEL_COMPILER 89 for (j = 0; j < npar; j++) {
90 for (k = j; k < npar; k++) {
91 alpha[j * npar + k] = 0.0;
92 for (i = 0; i < ndat; i++) {
93 alpha[j * npar + k] += dydp[i * npar + j] * dydp[i * npar + k];
95 if (k != j) alpha[k * npar + j] = alpha[j * npar + k];
102 const std::vector<float>& alpha,
104 std::vector<float>& dp)
109 std::vector<std::vector<float>> h(npar, std::vector<float>(npar + 1, 0));
112 for (i = 0; i < npar; i++) {
113 h[i][npar] = beta[i];
114 for (j = 0; j < npar; j++) {
115 h[i][j] = alpha[i * npar + j];
120 for (i = 0; i < npar; i++) {
123 for (j = i + 1; j < npar; j++) {
124 if (h[j][i] > hmax) {
130 for (k = 0; k <= npar; k++) {
132 h[i][k] = h[imax][k];
136 for (j = 0; j < npar; j++) {
137 if (j == i)
continue;
138 for (k = i; k < npar; k++) {
139 h[j][k + 1] -= h[i][k + 1] * h[j][i] / h[i][i];
144 for (i = 0; i < npar; i++) {
145 dp[i] = h[i][npar] / h[i][i];
162 std::vector<double> alpha(npar * npar);
165 std::vector<int> ik(npar);
166 std::vector<int> jk(npar);
167 double aMax, save, det;
170 for (i = 0; i < npar * npar; i++) {
171 alpha[i] = alphaf[i];
176 for (k = 0; k < npar; k++) {
178 for (i = k; i < npar; i++) {
179 for (j = k; j < npar; j++) {
183 if (fabs(alpha[i * npar + j]) > fabs(aMax)) {
184 aMax = alpha[i * npar + j];
190 if (aMax == 0)
return (det);
195 for (j = 0; j < npar; j++) {
196 save = alpha[k * npar + j];
197 alpha[k * npar + j] = alpha[i * npar + j];
198 alpha[i * npar + j] = -save;
204 for (i = 0; i < npar; i++) {
205 save = alpha[i * npar + k];
206 alpha[i * npar + k] = alpha[i * npar + j];
207 alpha[i * npar + j] = -save;
211 for (i = 0; i < npar; i++) {
212 if (i != k) alpha[i * npar + k] = -alpha[i * npar + k] / aMax;
214 #if defined WITH_OPENMP 216 #ifdef __INTEL_COMPILER 220 for (i = 0; i < npar; i++) {
221 for (j = 0; j < npar; j++) {
222 if ((i != k) && (j != k))
223 alpha[i * npar + j] = alpha[i * npar + j] + alpha[i * npar + k] * alpha[k * npar + j];
226 for (j = 0; j < npar; j++) {
227 if (j != k) alpha[k * npar + j] = alpha[k * npar + j] / aMax;
229 alpha[k * npar + k] = 1 / aMax;
234 for (k = npar - 1; k >= 0; k--) {
237 for (i = 0; i < npar; i++) {
238 save = alpha[i * npar + k];
239 alpha[i * npar + k] = -alpha[i * npar + j];
240 alpha[i * npar + j] = save;
245 for (j = 0; j < npar; j++) {
246 save = alpha[k * npar + j];
247 alpha[k * npar + j] = -alpha[i * npar + j];
248 alpha[i * npar + j] = save;
253 for (i = 0; i < npar * npar; i++) {
254 alphaf[i] = alpha[i];
267 std::vector<float> res(nData);
268 std::vector<float> dydp(nData * nParam);
269 std::vector<float> beta(nParam);
270 std::vector<float> alpha(nParam * nParam);
271 std::vector<std::vector<float>> alpsav(nParam, std::vector<float>(nParam));
273 fgauss(y, p, nParam, nData, res);
274 dgauss(p, nParam, nData, dydp);
276 for (i = 0; i < nParam; i++) {
277 for (j = 0; j < nParam; j++) {
278 alpsav[i][j] = alpha[i * nParam + j];
283 if (det == 0)
return 1;
284 for (i = 0; i < nParam; i++) {
285 if (alpha[i * nParam + i] >= 0.) { perr[i] = sqrt(alpha[i * nParam + i]); }
287 perr[i] = alpha[i * nParam + i];
302 std::vector<float> plimmin(nParam, std::numeric_limits<float>::lowest());
303 std::vector<float> plimmax(nParam, std::numeric_limits<float>::max());
304 return mrqdtfit(lambda, p, &plimmin[0], &plimmax[0], y, nParam, nData, chiSqr, dchiSqr);
318 float nu, rho, lzmlh, amax, chiSq0;
320 std::vector<float> res(nData);
321 std::vector<float> beta(nParam);
322 std::vector<float> dp(nParam);
323 std::vector<float> alpsav(nParam);
324 std::vector<float> psav(nParam);
325 std::vector<float> dydp(nData * nParam);
326 std::vector<float> alpha(nParam * nParam);
328 bool haslimits =
false;
329 for (j = 0; j < nParam; j++) {
330 if (plimmin[j] > std::numeric_limits<float>::lowest() ||
331 plimmax[j] < std::numeric_limits<float>::max()) {
337 fgauss(y, p, nParam, nData, res);
339 dgauss(p, nParam, nData, dydp);
343 for (j = 0; j < nParam; j++) {
344 if (alpha[j * nParam + j] > amax) amax = alpha[j * nParam + j];
346 lambda = 0.001 * amax;
348 for (j = 0; j < nParam; j++) {
349 alpsav[j] = alpha[j * nParam + j];
350 alpha[j * nParam + j] = alpsav[j] + lambda;
358 for (j = 0; j < nParam; j++) {
362 fgauss(y, p, nParam, nData, res);
365 for (j = 0; j < nParam; j++) {
366 if (p[j] <= plimmin[j] || p[j] >= plimmax[j])
372 for (j = 0; j < nParam; j++) {
373 lzmlh += dp[j] * (lambda * dp[j] + beta[j]);
375 rho = 2. * (chiSq0 - chiSqr) / lzmlh;
377 for (j = 0; j < nParam; j++)
380 lambda = nu * lambda;
382 for (j = 0; j < nParam; j++) {
383 alpha[j * nParam + j] = alpsav[j] + lambda;
388 lambda = lambda * fmax(0.333333, 1. - pow(2. * rho - 1., 3));
389 dchiSqr = chiSqr - chiSq0;
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)
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)