NumeRe v1.1.4
NumeRe: Framework für Numerische Rechnungen
fitcontroller.cpp
Go to the documentation of this file.
1/*****************************************************************************
2 NumeRe: Framework fuer Numerische Rechnungen
3 Copyright (C) 2016 Erik Haenel et al.
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17******************************************************************************/
18
19#include "fitcontroller.hpp"
20#include "../../kernel.hpp"
21
28
29using namespace std;
30
31
36{
37 nIterations = 0;
38 dChiSqr = 0.0;
39 sExpr = "";
40
41 xvar = 0;
42 yvar = 0;
43 zvar = 0;
44}
45
46
55{
56 _fitParser = _parser;
57 mu::varmap_type mVars = _parser->GetVar();
58 xvar = mVars["x"];
59 yvar = mVars["y"];
60 zvar = mVars["z"];
61}
62
63
68{
69 _fitParser = 0;
70 xvar = 0;
71 yvar = 0;
72 zvar = 0;
73}
74
75
76// Bei NaN Ergebnisse auf double MAX gesetzt. Kann ggf. Schwierigkeiten bei Fitfunktionen mit Minima nahe NaN machen...
87int Fitcontroller::fitfunction(const gsl_vector* params, void* data, gsl_vector* fvals)
88{
89 FitData* _fData = static_cast<FitData*>(data);
90 unsigned int i = 0;
91
92 for (auto iter = mParams.begin(); iter != mParams.end(); ++iter)
93 {
94 *(iter->second) = gsl_vector_get(params, i);
95 i++;
96 }
97
98 if (_fData->vx.size() && _fData->vy.size() && !_fData->vz.size()) // xy-Fit
99 {
100 for (unsigned int n = 0; n < _fData->vx.size(); n++)
101 {
102 if (isnan(_fData->vy[n]) || isinf(_fData->vy[n]) || isnan(_fData->vy_w[n]) || !_fData->vy_w[n])
103 {
104 gsl_vector_set(fvals, n , 0.0);
105 continue;
106 }
107
108 *xvar = _fData->vx[n];
109 gsl_vector_set(fvals, n, (_fitParser->Eval().real() - _fData->vy[n])/_fData->vy_w[n]); // Residuen (y-y0)/sigma
110
111 }
112
113 removeNANVals(fvals, _fData->vx.size());
114 }
115 else if (_fData->vx.size() && _fData->vy.size() && _fData->vz.size()) // xyz-Fit
116 {
117 for (unsigned int n = 0; n < _fData->vx.size(); n++)
118 {
119 *xvar = _fData->vx[n];
120
121 for (unsigned int m = 0; m < _fData->vy.size(); m++)
122 {
123 if (isnan(_fData->vz[n][m]) || isinf(_fData->vz[n][m]) || isnan(_fData->vz_w[n][m]) || !_fData->vz_w[n][m])
124 {
125 gsl_vector_set(fvals, n , 0.0);
126 continue;
127 }
128
129 *yvar = _fData->vy[m];
130 gsl_vector_set(fvals, m+n*(_fData->vy.size()), (_fitParser->Eval().real() - _fData->vz[n][m])/_fData->vz_w[n][m]);
131
132 }
133 }
134
135 removeNANVals(fvals, _fData->vx.size()*_fData->vy.size());
136 }
137
138 return GSL_SUCCESS;
139}
140
141
152int Fitcontroller::fitjacobian(const gsl_vector* params, void* data, gsl_matrix* Jac)
153{
154 FitData* _fData = static_cast<FitData*>(data);
155 unsigned int i = 0;
156 const double dEps = _fData->dPrecision*1.0e-1;
157 FitMatrix vFuncRes;
158 FitMatrix vDiffRes;
159
160 for (auto iter = mParams.begin(); iter != mParams.end(); ++iter)
161 {
162 *(iter->second) = gsl_vector_get(params, i);
163 i++;
164 }
165
166 if (_fData->vx.size() && _fData->vy.size() && !_fData->vz.size()) // xy-Fit
167 {
168 vFuncRes = FitMatrix(_fData->vx.size(),vector<double>(1,0.0));
169 vDiffRes = FitMatrix(_fData->vx.size(),vector<double>(1,0.0));
170
171 for (unsigned int n = 0; n < _fData->vx.size(); n++)
172 {
173 *xvar = _fData->vx[n];
174 vFuncRes[n][0] = _fitParser->Eval().real();
175 }
176 }
177 else if (_fData->vx.size() && _fData->vy.size() && _fData->vz.size()) // xyz-Fit
178 {
179 vFuncRes = FitMatrix(_fData->vz.size(),vector<double>(_fData->vz[0].size(),0.0));
180 vDiffRes = FitMatrix(_fData->vz.size(),vector<double>(_fData->vz[0].size(),0.0));
181
182 for (unsigned int n = 0; n < _fData->vx.size(); n++)
183 {
184 *xvar = _fData->vx[n];
185
186 for (unsigned int m = 0; m < _fData->vy.size(); m++)
187 {
188 *yvar = _fData->vy[m];
189 vFuncRes[n][m] = _fitParser->Eval().real();
190
191 }
192 }
193 }
194
195 i = 0;
196
197 for (auto iter = mParams.begin(); iter != mParams.end(); ++iter)
198 {
199 *(iter->second) = gsl_vector_get(params, i) + dEps;
200
201 if (_fData->vx.size() && _fData->vy.size() && !_fData->vz.size()) // xy-Fit
202 {
203 for (unsigned int n = 0; n < _fData->vx.size(); n++)
204 {
205 *xvar = _fData->vx[n];
206 vDiffRes[n][0] = _fitParser->Eval().real();
207 }
208
209 for (unsigned int n = 0; n < _fData->vx.size(); n++)
210 {
211 if (isnan(_fData->vy[n]) || isinf(_fData->vy[n]))
212 {
213 gsl_matrix_set(Jac, n, i, 0.0);
214 continue;
215 }
216
217 gsl_matrix_set(Jac, n, i, (vDiffRes[n][0]-vFuncRes[n][0])/(dEps*_fData->vy_w[n]));
218 }
219 }
220 else if (_fData->vx.size() && _fData->vy.size() && _fData->vz.size()) // xyz-Fit
221 {
222 for (unsigned int n = 0; n < _fData->vx.size(); n++)
223 {
224 *xvar = _fData->vx[n];
225
226 for (unsigned int m = 0; m < _fData->vy.size(); m++)
227 {
228 *yvar = _fData->vy[m];
229 vDiffRes[n][m] = _fitParser->Eval().real();
230 }
231 }
232
233 for (unsigned int n = 0; n < _fData->vx.size(); n++)
234 {
235 for (unsigned int m = 0; m < _fData->vy.size(); m++)
236 {
237 if (isnan(_fData->vz[n][m]) || isinf(_fData->vz[n][m]))
238 {
239 gsl_matrix_set(Jac, m+n*(_fData->vy.size()), i, 0.0);
240 continue;
241 }
242
243 gsl_matrix_set(Jac, m+n*(_fData->vy.size()), i, (vDiffRes[n][m]-vFuncRes[n][m])/(dEps*_fData->vz_w[n][m]));
244 }
245 }
246 }
247
248 *(iter->second) = gsl_vector_get(params, i);
249 i++;
250 }
251
252 if (_fData->vx.size() && _fData->vy.size() && !_fData->vz.size())
253 removeNANVals(Jac, _fData->vx.size(), mParams.size());
254 else if (_fData->vx.size() && _fData->vy.size() && _fData->vz.size())
255 removeNANVals(Jac, _fData->vx.size() * _fData->vy.size(), mParams.size());
256
257 return GSL_SUCCESS;
258}
259
260
272int Fitcontroller::fitfuncjac(const gsl_vector* params, void* data, gsl_vector* fvals, gsl_matrix* Jac)
273{
274 fitfunction(params, data, fvals);
275 fitjacobian(params, data, Jac);
276 return GSL_SUCCESS;
277}
278
279
290int Fitcontroller::fitfunctionrestricted(const gsl_vector* params, void* data, gsl_vector* fvals)
291{
292 FitData* _fData = static_cast<FitData*>(data);
293 unsigned int i = 0;
294 int nVals = 0;
295 value_type* v = 0;
296
297 for (auto iter = mParams.begin(); iter != mParams.end(); ++iter)
298 {
299 *(iter->second) = gsl_vector_get(params, i);
300 i++;
301 }
302
303 if (_fData->vx.size() && _fData->vy.size() && !_fData->vz.size()) // xy-Fit
304 {
305 for (unsigned int n = 0; n < _fData->vx.size(); n++)
306 {
307 if (isnan(_fData->vy[n]) || isinf(_fData->vy[n]) || isnan(_fData->vy_w[n]) || !_fData->vy_w[n])
308 {
309 gsl_vector_set(fvals, n , 0.0);
310 continue;
311 }
312
313 *xvar = _fData->vx[n];
314 v = _fitParser->Eval(nVals);
315 gsl_vector_set(fvals, n, (evalRestrictions(v, nVals) - _fData->vy[n])/_fData->vy_w[n]); // Residuen (y-y0)/sigma
316
317 }
318
319 removeNANVals(fvals, _fData->vx.size());
320 }
321 else if (_fData->vx.size() && _fData->vy.size() && _fData->vz.size()) // xyz-Fit
322 {
323 for (unsigned int n = 0; n < _fData->vx.size(); n++)
324 {
325 *xvar = _fData->vx[n];
326
327 for (unsigned int m = 0; m < _fData->vy.size(); m++)
328 {
329 if (isnan(_fData->vz[n][m]) || isinf(_fData->vz[n][m]) || isnan(_fData->vz_w[n][m]) || !_fData->vz_w[n][m])
330 {
331 gsl_vector_set(fvals, n , 0.0);
332 continue;
333 }
334
335 *yvar = _fData->vy[m];
336 v = _fitParser->Eval(nVals);
337 gsl_vector_set(fvals, m+n*(_fData->vy.size()), (evalRestrictions(v, nVals) - _fData->vz[n][m])/_fData->vz_w[n][m]);
338
339 }
340 }
341
342 removeNANVals(fvals, _fData->vx.size()*_fData->vy.size());
343 }
344
345 return GSL_SUCCESS;
346}
347
348
359int Fitcontroller::fitjacobianrestricted(const gsl_vector* params, void* data, gsl_matrix* Jac)
360{
361 FitData* _fData = static_cast<FitData*>(data);
362 unsigned int i = 0;
363 const double dEps = _fData->dPrecision*1.0e-1;
364 FitMatrix vFuncRes;
365 FitMatrix vDiffRes;
366 value_type* v = 0;
367 int nVals = 0;
368
369 for (auto iter = mParams.begin(); iter != mParams.end(); ++iter)
370 {
371 *(iter->second) = gsl_vector_get(params, i);
372 i++;
373 }
374
375 if (_fData->vx.size() && _fData->vy.size() && !_fData->vz.size()) // xy-Fit
376 {
377 vFuncRes = FitMatrix(_fData->vx.size(),vector<double>(1,0.0));
378 vDiffRes = FitMatrix(_fData->vx.size(),vector<double>(1,0.0));
379
380 for (unsigned int n = 0; n < _fData->vx.size(); n++)
381 {
382 *xvar = _fData->vx[n];
383 v = _fitParser->Eval(nVals);
384 vFuncRes[n][0] = evalRestrictions(v, nVals);
385 }
386 }
387 else if (_fData->vx.size() && _fData->vy.size() && _fData->vz.size()) // xyz-Fit
388 {
389 vFuncRes = FitMatrix(_fData->vz.size(),vector<double>(_fData->vz[0].size(),0.0));
390 vDiffRes = FitMatrix(_fData->vz.size(),vector<double>(_fData->vz[0].size(),0.0));
391
392 for (unsigned int n = 0; n < _fData->vx.size(); n++)
393 {
394 *xvar = _fData->vx[n];
395
396 for (unsigned int m = 0; m < _fData->vy.size(); m++)
397 {
398 *yvar = _fData->vy[m];
399 v = _fitParser->Eval(nVals);
400 vFuncRes[n][m] = evalRestrictions(v, nVals);
401
402 }
403 }
404 }
405
406 i = 0;
407
408 for (auto iter = mParams.begin(); iter != mParams.end(); ++iter)
409 {
410 *(iter->second) = gsl_vector_get(params, i) + dEps;
411
412 if (_fData->vx.size() && _fData->vy.size() && !_fData->vz.size()) // xy-Fit
413 {
414 for (unsigned int n = 0; n < _fData->vx.size(); n++)
415 {
416 *xvar = _fData->vx[n];
417 v = _fitParser->Eval(nVals);
418 vDiffRes[n][0] = evalRestrictions(v, nVals);
419 }
420
421 for (unsigned int n = 0; n < _fData->vx.size(); n++)
422 {
423 if (isnan(_fData->vy[n]) || isinf(_fData->vy[n]))
424 {
425 gsl_matrix_set(Jac, n, i, 0.0);
426 continue;
427 }
428
429 gsl_matrix_set(Jac, n, i, (vDiffRes[n][0]-vFuncRes[n][0])/(dEps*_fData->vy_w[n]));
430 }
431 }
432 else if (_fData->vx.size() && _fData->vy.size() && _fData->vz.size()) // xyz-Fit
433 {
434 for (unsigned int n = 0; n < _fData->vx.size(); n++)
435 {
436 *xvar = _fData->vx[n];
437
438 for (unsigned int m = 0; m < _fData->vy.size(); m++)
439 {
440 *yvar = _fData->vy[m];
441 v = _fitParser->Eval(nVals);
442 vDiffRes[n][m] = evalRestrictions(v, nVals);
443 }
444 }
445
446 for (unsigned int n = 0; n < _fData->vx.size(); n++)
447 {
448 for (unsigned int m = 0; m < _fData->vy.size(); m++)
449 {
450 if (isnan(_fData->vz[n][m]) || isinf(_fData->vz[n][m]))
451 {
452 gsl_matrix_set(Jac, m+n*(_fData->vy.size()), i, 0.0);
453 continue;
454 }
455
456 gsl_matrix_set(Jac, m+n*(_fData->vy.size()), i, (vDiffRes[n][m]-vFuncRes[n][m])/(dEps*_fData->vz_w[n][m]));
457 }
458 }
459 }
460
461 *(iter->second) = gsl_vector_get(params, i);
462 i++;
463 }
464
465 if (_fData->vx.size() && _fData->vy.size() && !_fData->vz.size())
466 removeNANVals(Jac, _fData->vx.size(), mParams.size());
467 else if (_fData->vx.size() && _fData->vy.size() && _fData->vz.size())
468 removeNANVals(Jac, _fData->vx.size() * _fData->vy.size(), mParams.size());
469
470 return GSL_SUCCESS;
471}
472
473
486int Fitcontroller::fitfuncjacrestricted(const gsl_vector* params, void* data, gsl_vector* fvals, gsl_matrix* Jac)
487{
488 fitfunctionrestricted(params, data, fvals);
489 fitjacobianrestricted(params, data, Jac);
490 return GSL_SUCCESS;
491}
492
493
503{
504 if (nVals == 1)
505 return v[0].real();
506 else
507 {
508 for (int i = 1; i < nVals; i++)
509 {
510 if (!v[i].real())
511 return NAN;
512 }
513
514 return v[0].real();
515 }
516
517 return NAN;
518}
519
520
530void Fitcontroller::removeNANVals(gsl_vector* fvals, unsigned int nSize)
531{
532 double dMax = NAN;
533
534 for (unsigned int i = 0; i < nSize; i++)
535 {
536 if (!isnan(gsl_vector_get(fvals, i)) && !isinf(gsl_vector_get(fvals, i)))
537 {
538 if (isnan(dMax))
539 dMax = fabs(gsl_vector_get(fvals, i));
540 else if (dMax < fabs(gsl_vector_get(fvals, i)))
541 dMax = fabs(gsl_vector_get(fvals, i));
542 }
543 }
544
545 if (isnan(dMax))
546 dMax = 1.0e120;
547
548 dMax *= 100.0;
549
550 for (unsigned int i = 0; i < nSize; i++)
551 {
552 if (isnan(gsl_vector_get(fvals, i)) || isinf(gsl_vector_get(fvals, i)))
553 gsl_vector_set(fvals, i, dMax);
554 }
555}
556
557
568void Fitcontroller::removeNANVals(gsl_matrix* Jac, unsigned int nLines, unsigned int nCols)
569{
570 double dMax = NAN;
571
572 for (unsigned int i = 0; i < nLines; i++)
573 {
574 for (unsigned int j = 0; j < nCols; j++)
575 {
576 if (!isnan(gsl_matrix_get(Jac, i, j)) && !isinf(gsl_matrix_get(Jac, i, j)))
577 {
578 if (isnan(dMax))
579 dMax = fabs(gsl_matrix_get(Jac, i, j));
580 else if (dMax < fabs(gsl_matrix_get(Jac, i, j)))
581 dMax = fabs(gsl_matrix_get(Jac, i, j));
582 }
583 }
584 }
585
586 if (isnan(dMax))
587 dMax = 1.0e120;
588
589 dMax *= 100.0;
590
591 for (unsigned int i = 0; i < nLines; i++)
592 {
593 for (unsigned int j = 0; j < nCols; j++)
594 {
595 if (isnan(gsl_matrix_get(Jac, i, j)) || isinf(gsl_matrix_get(Jac, i, j)))
596 gsl_matrix_set(Jac, i, j, dMax);
597 }
598 }
599}
600
601
615bool Fitcontroller::fitctrl(const string& __sExpr, const string& __sRestrictions, FitData& _fData, double __dPrecision, int nMaxIterations)
616{
617 dChiSqr = 0.0;
618 nIterations = 0;
619 sExpr = "";
620
621 int nStatus = 0;
622 int nRetry = 0;
623 unsigned int nPoints = (_fData.vz.size()) ? _fData.vx.size()*_fData.vy.size() : _fData.vx.size();
624
625 // Validation
626 if (_fData.vz.size() && _fData.vx.size() && _fData.vy.size())
627 {
628 if (_fData.vz.size() != _fData.vx.size()
629 || _fData.vz[0].size() != _fData.vy.size()
630 || _fData.vz.size() != _fData.vz_w.size()
631 || _fData.vz[0].size() != _fData.vz_w[0].size())
632 return false;
633 }
634 else if (_fData.vx.size() && _fData.vy.size())
635 {
636 if (_fData.vx.size() != _fData.vy.size() || _fData.vy.size() != _fData.vy_w.size())
637 return false;
638 }
639 else
640 return false;
641
642 // Validate the algorithm parameters
643 if (!isnan(__dPrecision) && !isinf(__dPrecision))
644 _fData.dPrecision = fabs(__dPrecision);
645 else
646 _fData.dPrecision = 1e-4;
647
648 if (nMaxIterations <= 1)
649 nMaxIterations = 500;
650
651 if (__sRestrictions.length())
652 _fitParser->SetExpr(__sExpr+","+__sRestrictions);
653 else
654 _fitParser->SetExpr(__sExpr);
655
656 _fitParser->Eval();
657 sExpr = __sExpr;
658
659 // Adapt the fit weights
660 if (_fData.vy_w.size())
661 {
662 for (size_t i = 0; i < _fData.vy_w.size(); i++)
663 _fData.vy_w[i] += 1.0;
664 }
665
666 if (_fData.vz_w.size())
667 {
668 for (size_t i = 0; i < _fData.vz_w.size(); i++)
669 {
670 for (size_t j = 0; j < _fData.vz_w[i].size(); j++)
671 _fData.vz_w[i][j] += 1.0;
672 }
673 }
674
675 // gsl_vector seems to be better in the interaction
676 // with GSL than std::vector
677 gsl_vector* params = gsl_vector_alloc(mParams.size());
678 size_t n = 0;
679
680 // Copy the parameter values
681 for (auto iter = mParams.begin(); iter != mParams.end(); ++iter)
682 {
683 gsl_vector_set(params, n, (*iter->second).real());
684 n++;
685 }
686
687 // Prepare the GSL fitting module
688 const gsl_multifit_fdfsolver_type* solver_type = gsl_multifit_fdfsolver_lmsder;
689 gsl_multifit_fdfsolver* solver = gsl_multifit_fdfsolver_alloc(solver_type, nPoints, mParams.size());
690 gsl_multifit_function_fdf func;
691
692 // Assign the correct functions to the
693 // multifit function structure
694 if (__sRestrictions.length())
695 {
699 }
700 else
701 {
702 func.f = fitfunction;
703 func.df = fitjacobian;
704 func.fdf = fitfuncjac;
705 }
706
707 func.n = nPoints;
708 func.p = mParams.size();
709 func.params = &_fData;
710
711 gsl_multifit_fdfsolver_set(solver, &func, params);
712
713 // Main fit iterator
714 do
715 {
716 // Iterate the fit solver
717 if (gsl_multifit_fdfsolver_iterate(solver))
718 {
719 // Failure in this iteration
720 if (!nIterations && !nRetry) //Algorithmus kommt mit den Startparametern nicht klar (und nur mit diesen)
721 {
722 for (size_t j = 0; j < mParams.size(); j++)
723 {
724 if (!gsl_vector_get(params, j)) // 0 durch 1 ersetzen und nochmal probieren
725 gsl_vector_set(params, j, 1.0);
726 }
727
728 // Reset the solver
729 gsl_multifit_fdfsolver_free(solver);
730 solver = gsl_multifit_fdfsolver_alloc(solver_type, nPoints, mParams.size());
731 gsl_multifit_fdfsolver_set(solver, &func, params);
732 nRetry = 1;
733 nStatus = GSL_CONTINUE;
734 continue;
735 }
736 else if (!nIterations && nRetry == 1)
737 {
738 nRetry++;
739 nStatus = GSL_CONTINUE;
740 continue;
741 }
742 else
743 break;
744 }
745
746 // Test, whether the required precision is already
747 // in the desired range
748 nStatus = gsl_multifit_test_delta(solver->dx, solver->x, _fData.dPrecision, _fData.dPrecision);
749 nIterations++;
750
751 // Cancel the algorithm if required by the user
753 {
754 gsl_multifit_fdfsolver_free(solver);
756 }
757 }
758 while (nStatus == GSL_CONTINUE && nIterations < nMaxIterations);
759
760 // Get the covariance matrix
761 gsl_matrix* mCovar = gsl_matrix_alloc(mParams.size(), mParams.size());
762 gsl_multifit_covar(solver->J, 0.0, mCovar);
763 vCovarianceMatrix = FitMatrix(mParams.size(), vector<double>(mParams.size(), 0.0));
764
765 for (size_t i = 0; i < mParams.size(); i++)
766 {
767 for (size_t j = 0; j < mParams.size(); j++)
768 vCovarianceMatrix[i][j] = gsl_matrix_get(mCovar, i, j);
769 }
770
771 gsl_matrix_free(mCovar);
772
773 n = 0;
774 // Get the parameter from the solver
775 for (auto iter = mParams.begin(); iter != mParams.end(); ++iter)
776 {
777 *(iter->second) = gsl_vector_get(solver->x, n);
778 n++;
779 }
780
781 // Get the Chi^2
782 dChiSqr = gsl_blas_dnrm2(solver->f);
783 dChiSqr *= dChiSqr;
784
785 // Free the memory needed by the solver
786 gsl_multifit_fdfsolver_free(solver);
787 gsl_vector_free(params);
788
789 // Examine the restrictions
790 if (__sRestrictions.length())
791 {
792 int nVals = 0;
793 value_type* v = _fitParser->Eval(nVals);
794
795 if (isnan(evalRestrictions(v, nVals)))
796 return false;
797 }
798
799 return true;
800}
801
802
817bool Fitcontroller::fit(FitVector& vx, FitVector& vy, FitVector& vy_w, const string& __sExpr, const string& __sRestrictions, mu::varmap_type& mParamsMap, double __dPrecision, int nMaxIterations)
818{
819 mParams = mParamsMap;
820 FitData _fData;
821 _fData.vx = vx;
822 _fData.vy = vy;
823 _fData.vy_w = vy_w;
824
825 return fitctrl(__sExpr, __sRestrictions, _fData, __dPrecision, nMaxIterations);
826}
827
828
844bool Fitcontroller::fit(FitVector& vx, FitVector& vy, FitMatrix& vz, FitMatrix& vz_w, const string& __sExpr, const string& __sRestrictions, mu::varmap_type& mParamsMap, double __dPrecision, int nMaxIterations)
845{
846 mParams = mParamsMap;
847 FitData _fData;
848 _fData.vx = vx;
849 _fData.vy = vy;
850 _fData.vz = vz;
851 _fData.vz_w = vz_w;
852
853 return fitctrl(__sExpr, __sRestrictions, _fData, __dPrecision, nMaxIterations);
854}
855
856
866{
867 if (!sExpr.length())
868 return "";
869
870 sExpr += " ";
871
872 for (auto iter = mParams.begin(); iter != mParams.end(); ++iter)
873 {
874 for (unsigned int i = 0; i < sExpr.length(); i++)
875 {
876 if (sExpr.substr(i, (iter->first).length()) == iter->first)
877 {
878 if ((!i && checkDelimiter(" "+sExpr.substr(i, (iter->first).length()+1)))
879 || (i && checkDelimiter(sExpr.substr(i-1, (iter->first).length()+2))))
880 {
881 sExpr.replace(i, (iter->first).length(), toString(*(iter->second), 5));
882 i += toString(*(iter->second), 5).length();
883 }
884 }
885 }
886 }
887
888 for (size_t i = 0; i < sExpr.length()-1; i++)
889 {
890 if (sExpr.find_first_not_of(' ', i+1) == string::npos)
891 break;
892
893 if (sExpr[i] == '+' && sExpr[sExpr.find_first_not_of(' ', i+1)] == '-')
894 sExpr.erase(i,1);
895
896 if (sExpr[i] == '-' && sExpr[sExpr.find_first_not_of(' ', i+1)] == '+')
897 sExpr.erase(sExpr.find_first_not_of(' ', i+1), 1);
898
899 if (sExpr[i] == '-' && sExpr[sExpr.find_first_not_of(' ', i+1)] == '-')
900 {
901 sExpr[i] = '+';
902 sExpr.erase(sExpr.find_first_not_of(' ', i+1), 1);
903 }
904 }
905
907 return sExpr;
908}
909
910
919{
920 return vCovarianceMatrix;
921}
922
923
This class contains the internal fit logic and the interface to the GSL fitting module.
static mu::value_type * xvar
bool fit(FitVector &vx, FitVector &vy, const std::string &__sExpr, const std::string &__sRestrictions, mu::varmap_type &mParamsMap, double __dPrecision=1e-4, int nMaxIterations=500)
Calculate an unweighted 1D-fit.
static int fitfunctionrestricted(const gsl_vector *params, void *data, gsl_vector *fvals)
Fit function respecting additional restrictions.
static mu::value_type * yvar
static mu::value_type * zvar
static mu::Parser * _fitParser
static double evalRestrictions(const mu::value_type *v, int nVals)
Evaluate additional restrictions.
static mu::varmap_type mParams
FitMatrix vCovarianceMatrix
FitMatrix getCovarianceMatrix() const
Returns the covariance matrix of the performed fit.
static void removeNANVals(gsl_vector *fvals, unsigned int nSize)
Replace NaNs with some very large value to avoid converging towards NaNs.
static int fitfuncjac(const gsl_vector *params, void *data, gsl_vector *fvals, gsl_matrix *Jac)
Combination of fit function and the corresponding jacobian.
static int fitjacobian(const gsl_vector *params, void *data, gsl_matrix *Jac)
Create the jacobian matrix without using restrictions.
static int fitfunction(const gsl_vector *params, void *data, gsl_vector *fvals)
Fit function for the usual case without any restrictions.
std::string sExpr
static int fitjacobianrestricted(const gsl_vector *params, void *data, gsl_matrix *Jac)
Jacobian matrix respecting additional restrictions.
static int nDimensions
~Fitcontroller()
Destructor.
bool fitctrl(const std::string &__sExpr, const std::string &__sRestrictions, FitData &_fData, double __dPrecision, int nMaxIterations)
This is the central fitting function using the data passed from the interface functions.
Fitcontroller()
Default constructor.
static int fitfuncjacrestricted(const gsl_vector *params, void *data, gsl_vector *fvals, gsl_matrix *Jac)
Combination of fit function and the corresponding jacobian respecting additional restrictions.
std::string getFitFunction()
Returns the fit function, where each parameter is replaced with its value converted to a string.
static bool GetAsyncCancelState()
This function is used by the kernel to get informed, when the user pressed ESC or used other means of...
Definition: kernel.cpp:3703
Common exception class for all exceptions thrown in NumeRe.
Definition: error.hpp:32
@ PROCESS_ABORTED_BY_USER
Definition: error.hpp:202
static size_t invalid_position
Definition: error.hpp:235
void SetExpr(StringView a_sExpr)
Set the expression. Triggers first time calculation thus the creation of the bytecode and scanning of...
value_type Eval()
Single-value wrapper around the vectorized overload of this member function.
const varmap_type & GetVar() const
Return a map containing the used variables only.
Mathematical expressions parser.
Definition: muParser.h:51
std::vector< std::vector< double > > FitMatrix
Typedef for readability.
std::vector< double > FitVector
Typedef for readability.
MUP_BASETYPE value_type
The numeric datatype used by the parser.
Definition: muParserDef.h:251
bool isnan(const value_type &v)
Definition: muParserDef.h:379
std::vector< double > real(const std::vector< value_type > &vVec)
bool isinf(const value_type &v)
Definition: muParserDef.h:374
std::map< string_type, value_type * > varmap_type
Type used for storing variables.
Definition: muParserDef.h:273
Resample_Real(* func)(Resample_Real t)
Definition: resampler.cpp:372
void StripSpaces(std::string &)
Removes leading and trailing white spaces and tabulator characters.
Defines the datapoints, which shall be fitted.
FitMatrix vz_w
FitVector vy
double dPrecision
FitMatrix vz
FitVector vx
FitVector vy_w
std::string toString(int)
Converts an integer to a string without the Settings bloat.
bool checkDelimiter(const string &sString, bool stringdelim)
Checks, whether the first and the last character in the passed string is a delimiter character.
Definition: tools.cpp:1982