310 bool isDerivDefined =
true;
311 gsl_matrix *M =
nullptr;
315 const double xValuesTest = 0;
323 isDerivDefined =
false;
329 const int maxInterations =
getProperty(
"MaxIterations");
335 const size_t numberOfSpectra = localworkspace->getNumberHistograms();
337 if (histNumber >=
static_cast<int>(numberOfSpectra)) {
338 g_log.
warning(
"Invalid Workspace index given, using first Workspace");
343 Mantid::HistogramData::HistogramX
const &XValues = localworkspace->x(histNumber);
344 Mantid::HistogramData::HistogramY
const &YValues = localworkspace->y(histNumber);
345 Mantid::HistogramData::HistogramE
const &YErrors = localworkspace->e(histNumber);
352 startX = XValues.front();
357 endX = XValues.back();
366 if (startX < XValues.front()) {
367 g_log.
warning(
"StartX out of range! Set to start of frame.");
368 startX = XValues.front();
372 for (m_minX = 0; XValues[m_minX + 1] < startX; ++m_minX) {
377 if (endX >= XValues.back() || endX < startX) {
378 g_log.
warning(
"EndX out of range! Set to end of frame");
379 endX = XValues.back();
380 m_maxX =
static_cast<int>(YValues.size());
382 for (m_maxX = m_minX; XValues[m_maxX] < endX; ++m_maxX) {
395 l_data.
n = m_maxX - m_minX;
398 throw std::runtime_error(
"The data set is empty.");
400 if (l_data.
n < l_data.
p) {
401 g_log.
error(
"Number of data points less than number of parameters to be fitted.");
402 throw std::runtime_error(
"Number of data points less than number of parameters to be fitted.");
404 l_data.
X =
new double[l_data.
n];
411 const bool isHistogram = localworkspace->isHistogramData();
412 for (
unsigned int i = 0; i < l_data.
n; ++i) {
414 l_data.
X[i] = 0.5 * (XValues[m_minX + i] + XValues[m_minX + i + 1]);
416 l_data.
X[i] = XValues[m_minX + i];
419 l_data.
Y = &YValues[m_minX];
422 for (
unsigned int i = 0; i < l_data.
n; ++i) {
423 if (YErrors[m_minX + i] <= 0.0) {
426 l_data.
sigmaData[i] = YErrors[m_minX + i];
442 for (
size_t i = 0; i <
nParams(); i++) {
446 for (
size_t i = 0; i <
nParams(); i++) {
452 gsl_vector *initFuncArg;
453 initFuncArg = gsl_vector_alloc(l_data.
p);
455 for (
size_t i = 0, j = 0; i <
nParams(); i++) {
462 gsl_multimin_function gslSimplexContainer;
463 gslSimplexContainer.n = l_data.
p;
465 gslSimplexContainer.params = &l_data;
469 gsl_multifit_function_fdf f;
479 const gsl_multifit_fdfsolver_type *T = gsl_multifit_fdfsolver_lmsder;
480 gsl_multifit_fdfsolver *s =
nullptr;
481 if (isDerivDefined) {
482 s = gsl_multifit_fdfsolver_alloc(T, l_data.
n, l_data.
p);
483 gsl_multifit_fdfsolver_set(s, &f, initFuncArg);
488 const gsl_multimin_fminimizer_type *simplexType = gsl_multimin_fminimizer_nmsimplex;
489 gsl_multimin_fminimizer *simplexMinimizer =
nullptr;
490 gsl_vector *simplexStepSize =
nullptr;
491 if (!isDerivDefined) {
492 simplexMinimizer = gsl_multimin_fminimizer_alloc(simplexType, l_data.
p);
493 simplexStepSize = gsl_vector_alloc(l_data.
p);
494 gsl_vector_set_all(simplexStepSize,
496 gsl_multimin_fminimizer_set(simplexMinimizer, &gslSimplexContainer, initFuncArg, simplexStepSize);
503 double finalCostFuncVal;
504 auto dof =
static_cast<double>(l_data.
n - l_data.
p);
508 Progress prog(
this, 0.0, 1.0, maxInterations);
509 if (isDerivDefined) {
513 status = gsl_multifit_fdfsolver_iterate(s);
518 status = gsl_multifit_test_delta(s->dx, s->x, 1e-4, 1e-4);
520 }
while (status == GSL_CONTINUE && iter < maxInterations);
522 double chi = gsl_blas_dnrm2(s->f);
523 finalCostFuncVal = chi * chi / dof;
526 for (
size_t i = 0, j = 0; i <
nParams(); i++)
532 status = gsl_multimin_fminimizer_iterate(simplexMinimizer);
537 double size = gsl_multimin_fminimizer_size(simplexMinimizer);
538 status = gsl_multimin_test_size(size, 1e-2);
540 }
while (status == GSL_CONTINUE && iter < maxInterations);
542 finalCostFuncVal = simplexMinimizer->fval / dof;
554 std::string reportOfFit = gsl_strerror(status);
557 <<
"Status = " << reportOfFit <<
"\n"
558 <<
"Chi^2/DoF = " << finalCostFuncVal <<
"\n";
565 setProperty(
"OutputChi2overDoF", finalCostFuncVal);
570 if (!output.empty()) {
573 gsl_matrix *covar(
nullptr);
574 std::vector<double> standardDeviations;
575 std::vector<double> sdExtended;
576 if (isDerivDefined) {
577 covar = gsl_matrix_alloc(l_data.
p, l_data.
p);
578#if GSL_MAJOR_VERSION < 2
579 gsl_multifit_covar(s->J, 0.0, covar);
581 gsl_matrix *J = gsl_matrix_alloc(l_data.
n, l_data.
p);
582 gsl_multifit_fdfsolver_jac(s, J);
583 gsl_multifit_covar(J, 0.0, covar);
588 for (
size_t i = 0; i <
nParams(); i++) {
589 sdExtended.emplace_back(1.0);
591 sdExtended[i] = sqrt(gsl_matrix_get(covar, iPNotFixed, iPNotFixed));
596 for (
size_t i = 0; i <
nParams(); i++)
598 standardDeviations.emplace_back(sdExtended[i]);
602 "The name of the TableWorkspace in which to store the final "
603 "covariance matrix");
604 setPropertyValue(
"OutputNormalisedCovarianceMatrix", output +
"_NormalisedCovarianceMatrix");
608 m_covariance->addColumn(
"str",
"Name");
609 std::vector<std::string> paramThatAreFitted;
610 for (
size_t i = 0; i <
nParams(); i++) {
617 for (
size_t i = 0; i < l_data.
p; i++) {
620 row << paramThatAreFitted[i];
621 for (
size_t j = 0; j < l_data.
p; j++) {
625 row << 100.0 * gsl_matrix_get(covar, i, j) /
626 sqrt(gsl_matrix_get(covar, i, i) * gsl_matrix_get(covar, j, j));
631 setProperty(
"OutputNormalisedCovarianceMatrix", m_covariance);
636 "The name of the TableWorkspace in which to store the "
637 "final fit parameters");
639 "Name of the output Workspace holding resulting simlated spectrum");
647 m_result->addColumn(
"str",
"Name");
648 m_result->addColumn(
"double",
"Value");
650 m_result->addColumn(
"double",
"Error");
652 firstRow <<
"Chi^2/DoF" << finalCostFuncVal;
654 for (
size_t i = 0; i <
nParams(); i++) {
657 if (isDerivDefined && l_data.
active[i]) {
659 row << sdExtended[i];
667 Mantid::HistogramData::HistogramX
const &inputX = inputWorkspace->x(iSpec);
668 Mantid::HistogramData::HistogramY
const &inputY = inputWorkspace->y(iSpec);
670 int histN = isHistogram ? 1 : 0;
674 ws->getAxis(0)->unit() = inputWorkspace->getAxis(0)->unit();
676 for (
int i = 0; i < 3; i++)
677 ws->mutableX(i).assign(inputX.begin() + m_minX, inputX.begin() + m_maxX + histN);
679 ws->mutableY(0).assign(inputY.begin() + m_minX, inputY.begin() + m_maxX);
681 auto &
Y = ws->mutableY(1);
682 auto &E = ws->mutableY(2);
684 auto lOut =
new double[l_data.
n];
692 for (
unsigned int i = 0; i < l_data.
n; i++) {
694 E[i] = l_data.
Y[i] -
Y[i];
699 setProperty(
"OutputWorkspace", std::dynamic_pointer_cast<MatrixWorkspace>(ws));
702 gsl_matrix_free(covar);
708 gsl_multifit_fdfsolver_free(s);
710 gsl_vector_free(simplexStepSize);
711 gsl_multimin_fminimizer_free(simplexMinimizer);
718 gsl_vector_free(initFuncArg);