31#include <boost/math/distributions/students_t.hpp>
36bool greaterIsLess(
double x1,
double x2) {
return x1 > x2; }
39using namespace Kernel;
40using API::MatrixWorkspace;
52 :
API::
IDomainCreator(fit,
std::vector<
std::string>(1, workspacePropertyName), domainType), m_workspaceIndex(-1),
55 throw std::runtime_error(
"Cannot create FitMW: no workspace given");
71 throw std::invalid_argument(
"InputWorkspace must be a MatrixWorkspace.");
93 auto mustBePositive = std::make_shared<BoundedValidator<int>>();
94 mustBePositive->setLower(0);
96 "The Workspace Index to fit in the input workspace");
98 "A value of x in, or on the low x boundary of, the first bin to "
100 "the fit (default lowest value of x)");
102 "A value in, or on the high x boundary of, the last bin the fitting "
104 "(default the highest value of x)");
116 throw std::runtime_error(
"Workspace contains no data.");
124 Mantid::MantidVec::const_iterator from;
125 Mantid::MantidVec::const_iterator to;
127 bool isXAscending =
X.front() <
X.back();
135 throw std::invalid_argument(
"Both StartX and EndX must be given to set fitting interval.");
136 }
else if (isXAscending) {
140 from = std::lower_bound(
X.begin(),
X.end(),
m_startX);
141 to = std::upper_bound(from,
X.end(),
m_endX);
146 from = std::lower_bound(
X.begin(),
X.end(),
m_startX, greaterIsLess);
147 to = std::upper_bound(from,
X.end(),
m_endX, greaterIsLess);
153 if (to - from == 0) {
154 throw std::invalid_argument(
"StartX and EndX values do not capture a range "
155 "within the workspace interval.");
163 return std::make_pair(std::distance(
X.begin(), from), std::distance(
X.begin(), to));
171 size_t startIndex, endIndex;
173 return endIndex - startIndex;
183 throw std::runtime_error(
"Cannot initialize empty function.");
198 size_t nxvalues(nyvalues);
207 auto tAxis = std::make_unique<API::TextAxis>(nhistograms);
208 ws->replaceAxis(1, std::move(tAxis));
214 for (
size_t i = 0; i < nhistograms; i++) {
231 if (domain && values) {
245 const std::string &baseName,
API::IFunction_sptr function, std::shared_ptr<API::FunctionDomain> domain,
246 std::shared_ptr<API::FunctionValues> values,
const std::string &outputWorkspacePropertyName) {
248 throw std::logic_error(
"FunctionValues expected");
252 std::list<API::IFunction_sptr> functionsToDisplay(1, function);
258 const size_t nhistograms = functionsToDisplay.size() + 2;
259 const size_t nyvalues = values->size();
268 auto iend = functionsToDisplay.end();
270 for (
auto it = functionsToDisplay.begin(); it != iend; ++it) {
272 textAxis->
setLabel(wsIndex, (*it)->name());
274 if (it == functionsToDisplay.begin())
281 const auto &Ycal = ws->y(1);
282 auto &Diff = ws->mutableY(2);
283 const size_t nData = values->size();
284 for (
size_t i = 0; i < nData; ++i) {
285 if (values->getFitWeight(i) != 0.0) {
286 Diff[i] = values->getFitData(i) - Ycal[i];
292 if (!outputWorkspacePropertyName.empty()) {
294 "Name of the output Workspace holding resulting simulated spectrum");
301 if (!std::dynamic_pointer_cast<Mantid::API::IEventWorkspace>(
m_matrixWorkspace)) {
303 ws->setDistribution(
true);
321 const auto compositeFn = std::dynamic_pointer_cast<API::CompositeFunction>(function);
325 const size_t nlocals = compositeFn->nFunctions();
326 for (
size_t i = 0; i < nlocals; ++i) {
327 auto localFunction = compositeFn->getFunction(i);
328 auto localComposite = std::dynamic_pointer_cast<API::CompositeFunction>(localFunction);
332 functionList.insert(functionList.end(), localFunction);
352 std::shared_ptr<Functions::Convolution> convolution = std::dynamic_pointer_cast<Functions::Convolution>(function);
354 const auto compositeFn = std::dynamic_pointer_cast<API::CompositeFunction>(convolution->getFunction(1));
356 functionList.insert(functionList.end(), convolution);
358 auto resolution = convolution->getFunction(0);
359 const size_t nlocals = compositeFn->nFunctions();
360 for (
size_t i = 0; i < nlocals; ++i) {
361 auto localFunction = compositeFn->getFunction(i);
362 std::shared_ptr<Functions::Convolution> localConvolution = std::make_shared<Functions::Convolution>();
363 localConvolution->addFunction(resolution);
364 localConvolution->addFunction(localFunction);
365 functionList.insert(functionList.end(), localConvolution);
380 std::shared_ptr<API::MatrixWorkspace> &ws,
const size_t wsIndex,
381 const std::shared_ptr<API::FunctionDomain> &domain,
382 const std::shared_ptr<API::FunctionValues> &resultValues)
const {
383 const size_t nData = resultValues->size();
384 resultValues->zeroCalculated();
390 double prob = std::erf(
sigma / sqrt(2));
392 double alpha = (1 + prob) / 2;
395 function->function(*domain, *resultValues);
397 size_t nParams = function->nParams();
400 auto covar = function->getCovarianceMatrix();
401 bool hasErrors =
false;
403 for (
size_t j = 0; j < nParams; ++j) {
404 if (function->getError(j) != 0.0) {
411 if (covar || hasErrors) {
415 function->functionDeriv(*domain, J);
417 function->calNumericalDeriv(*domain, J);
426 std::vector<double> E(nData);
427 for (
size_t k = 0; k < nData; ++k) {
429 for (
size_t i = 0; i < nParams; ++i) {
432 for (
size_t j = i + 1; j < nParams; ++j) {
433 s += J.
get(k, i) * C[i][j] * J.
get(k, j) * 2;
439 size_t dof = nData - nParams;
440 auto &yValues = ws->mutableY(wsIndex);
441 auto &eValues = ws->mutableE(wsIndex);
444 boost::math::students_t dist(
static_cast<double>(dof));
445 T = boost::math::quantile(dist, alpha);
447 for (
size_t i = 0; i < nData; i++) {
448 yValues[i] = resultValues->getCalculated(i);
449 eValues[i] = T * std::sqrt(E[i]);
454 auto &yValues = ws->mutableY(wsIndex);
455 auto &eValues = ws->mutableE(wsIndex);
456 for (
size_t i = 0; i < nData; i++) {
457 yValues[i] = resultValues->getCalculated(i);
459 for (
size_t j = 0; j < nParams; ++j) {
460 double d = J.
get(i, j) * function->getError(j);
463 eValues[i] = std::sqrt(err);
468 auto &yValues = ws->mutableY(wsIndex);
469 for (
size_t i = 0; i < nData; i++) {
470 yValues[i] = resultValues->getCalculated(i);
std::map< DeltaEMode::Type, std::string > index
An base class for domain creators for use in Fit.
DomainType
Type of domain to create.
bool m_convolutionCompositeMembers
Perform convolution of output composite components.
bool m_outputCompositeMembers
Output separate composite function values.
std::vector< std::string > m_workspacePropertyNames
Property names for workspaces to get the data from.
Kernel::IPropertyManager * m_manager
Pointer to a property manager.
void declareProperty(Kernel::Property *prop, const std::string &doc)
Declare a property to the algorithm.
This is an interface to a fitting function - a semi-abstarct class.
Represents the Jacobian in IFitFunction::functionDeriv.
virtual double get(size_t iY, size_t iP)=0
Get the value to a Jacobian matrix element.
Class to represent a text axis of a workspace.
void setLabel(const std::size_t &index, const std::string &lbl)
Set the label at the given index.
A property class for workspaces.
void declareDatasetProperties(const std::string &suffix="", bool addProp=true) override
Declare properties that specify the dataset within the workspace to fit to.
std::string m_endXPropertyName
Store endX property name.
void appendCompositeFunctionMembers(std::list< API::IFunction_sptr > &functionList, const API::IFunction_sptr &function) const
std::string m_startXPropertyName
Store startX property name.
std::weak_ptr< API::FunctionDomain1D > m_domain
Store the created domain and values.
std::shared_ptr< API::MatrixWorkspace > createEmptyResultWS(const size_t nhistograms, const size_t nyvalues)
Creates the blank output workspace of the correct size.
std::pair< size_t, size_t > getXInterval() const
Calculate size and starting iterator in the X array.
std::shared_ptr< API::MatrixWorkspace > m_matrixWorkspace
The input MareixWorkspace.
std::weak_ptr< API::FunctionValues > m_values
IMWDomainCreator(Kernel::IPropertyManager *fit, const std::string &workspacePropertyName, DomainType domainType=Simple)
Constructor.
virtual void setParameters() const
Set all parameters.
void setInitialValues(API::IFunction &function)
Set initial values for parameters with default values.
void addFunctionValuesToWS(const API::IFunction_sptr &function, std::shared_ptr< API::MatrixWorkspace > &ws, const size_t wsIndex, const std::shared_ptr< API::FunctionDomain > &domain, const std::shared_ptr< API::FunctionValues > &resultValues) const
Add the calculated function values to the workspace.
size_t m_workspaceIndex
The workspace index.
std::string m_workspacePropertyName
Store workspace property name.
std::shared_ptr< API::Workspace > createOutputWorkspace(const std::string &baseName, API::IFunction_sptr function, std::shared_ptr< API::FunctionDomain > domain, std::shared_ptr< API::FunctionValues > values, const std::string &outputWorkspacePropertyName) override
Create an output workspace.
std::string m_workspaceIndexPropertyName
Store workspace index property name.
void appendConvolvedCompositeFunctionMembers(std::list< API::IFunction_sptr > &functionList, const API::IFunction_sptr &function) const
If the fit function is Convolution and flag m_convolutionCompositeMembers is set and Convolution's se...
void initFunction(API::IFunction_sptr function) override
Initialize the function.
size_t getDomainSize() const override
Return the size of the domain to be created.
Interface to PropertyManager.
virtual void setPropertyValue(const std::string &name, const std::string &value)=0
Sets property value from a string.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
virtual bool existsProperty(const std::string &name) const =0
Checks whether the named property is already in the list of managed property.
virtual TypedValue getProperty(const std::string &name) const =0
Get the value of a property.
The concrete, templated class for properties.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
std::shared_ptr< IFunction > IFunction_sptr
shared pointer to the function base class
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
void MANTID_CURVEFITTING_DLL estimate(API::IFunction &function, const API::FunctionDomain1D &domain, const API::FunctionValues &values)
ParameterEstimator estimates parameter values of some fitting functions from fitting data.
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
@ Output
An output workspace.