133 double upperLimit)
const {
134 const double DBL_EPS = std::numeric_limits<double>::epsilon();
135 size_t nParams = peakFunction.
nParams();
137 std::vector<double> parameterErrors(nParams);
138 bool hasErrors =
false;
139 for (
size_t i = 0; i < nParams; ++i) {
140 parameterErrors[i] = peakFunction.
getError(i);
141 if (parameterErrors[i] > DBL_EPS)
148 std::vector<double> gradients(nParams);
149 auto peakFunctionClone = std::dynamic_pointer_cast<IPeakFunction>(peakFunction.
clone());
150 for (
size_t i = 0; i < nParams; i++) {
152 double parameterError = parameterErrors[i];
153 if (parameterError > DBL_EPS) {
154 double step(parameterError / 2.0);
156 peakFunctionClone->setParameter(i, parameterValue + step);
157 std::shared_ptr<const IPeakFunction> functionPlus(
158 std::const_pointer_cast<const IPeakFunction>(peakFunctionClone));
159 auto resultPlus =
integrate(*functionPlus, lowerLimit, upperLimit);
161 peakFunctionClone->setParameter(i, parameterValue - step);
162 auto functionMinus(std::const_pointer_cast<const IPeakFunction>(peakFunctionClone));
163 auto resultMinus =
integrate(*functionMinus, lowerLimit, upperLimit);
165 peakFunctionClone->setParameter(i, parameterValue);
166 gradients[i] = (resultPlus.result - resultMinus.result) / parameterError;
172 for (
size_t i = 0; i < nParams; i++)
173 error += pow(gradients[i] * parameterErrors[i], 2);