Mantid
Loading...
Searching...
No Matches
CalculateChiSquared.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
8
10
11using namespace Kernel;
12using namespace API;
13
14// Register the algorithm into the AlgorithmFactory
15DECLARE_ALGORITHM(CalculateChiSquared)
16
17
18const std::string CalculateChiSquared::name() const { return "CalculateChiSquared"; }
19
21int CalculateChiSquared::version() const { return 1; }
22
24const std::string CalculateChiSquared::summary() const {
25 return "Calculate chi squared for a function and a data set in a workspace.";
26}
27
28//----------------------------------------------------------------------------------------------
30void CalculateChiSquared::initConcrete() {
31 declareProperty("ChiSquared", 0.0, "Output value of chi squared.", Direction::Output);
32 declareProperty("ChiSquaredDividedByDOF", 0.0,
33 "Output value of chi squared divided by the "
34 "number of degrees of freedom (NofData "
35 "- nOfParams).",
37 declareProperty("ChiSquaredDividedByNData", 0.0,
38 "Output value of chi squared divided by the "
39 "number of data points).",
41 declareProperty("ChiSquaredWeighted", 0.0, "Output value of weighted chi squared.", Direction::Output);
42 declareProperty("ChiSquaredWeightedDividedByDOF", 0.0,
43 "Output value of weighted chi squared divided by the "
44 "number of degrees of freedom (NofData "
45 "- nOfParams).",
47 declareProperty("ChiSquaredWeightedDividedByNData", 0.0,
48 "Output value of weighted chi squared divided by the "
49 "number of data points).",
51 declareProperty("Weighted", false,
52 "Option to use the weighted chi squared "
53 "in error estimation. Default is false.");
54}
55
56//----------------------------------------------------------------------------------------------
58void CalculateChiSquared::execConcrete() {
59
60 // Function may need some preparation.
61 m_function->setUpForFit();
62
65 m_domainCreator->createDomain(domain, values);
66
67 // Do something with the function which may depend on workspace.
68 m_domainCreator->initFunction(m_function);
69
70 // Get the number of free fitting parameters
71 size_t nParams = 0;
72 for (size_t i = 0; i < m_function->nParams(); ++i) {
73 if (m_function->isActive(i))
74 nParams += 1;
75 }
76
77 // Calculate function values.
78 m_function->function(*domain, *values);
79
80 // Calculate the chi squared.
81 double chiSquared = 0.0;
82 double chiSquaredWeighted = 0.0;
83 double dof = 0.0;
84 calcChiSquared(*m_function, nParams, *domain, *values, chiSquared, chiSquaredWeighted, dof);
85 g_log.notice() << "Chi squared " << chiSquared << "\n"
86 << "Chi squared weighted " << chiSquaredWeighted << "\n";
87
88 // Store the result.
89 setProperty("ChiSquared", chiSquared);
90 setProperty("chiSquaredWeighted", chiSquaredWeighted);
91
92 // Divided by NParams
93 double nData = dof + static_cast<double>(nParams);
94 const double chiSquaredNData = chiSquared / nData;
95 const double chiSquaredWeightedNData = chiSquaredWeighted / nData;
96 g_log.notice() << "Chi squared / NData " << chiSquaredNData << "\n"
97 << "Chi squared weighed / NData " << chiSquaredWeightedNData << "\n"
98 << "NParams " << nParams << "\n";
99
100 // Store the result.
101 setProperty("ChiSquaredDividedByNData", chiSquaredNData);
102 setProperty("ChiSquaredWeightedDividedByNData", chiSquaredWeightedNData);
103
104 // Divided by the DOF
105 if (dof <= 0.0) {
106 dof = 1.0;
107 g_log.warning("DOF has a non-positive value, changing to 1.0");
108 }
109 const double chiSquaredDOF = chiSquared / dof;
110 const double chiSquaredWeightedDOF = chiSquaredWeighted / dof;
111 g_log.notice() << "Chi squared / DOF " << chiSquaredDOF << "\n"
112 << "Chi squared weighed / DOF " << chiSquaredWeightedDOF << "\n"
113 << "DOF " << dof << "\n";
114
115 // Store the result.
116 setProperty("ChiSquaredDividedByDOF", chiSquaredDOF);
117 setProperty("ChiSquaredWeightedDividedByDOF", chiSquaredWeightedDOF);
118}
119
120//----------------------------------------------------------------------------------------------
121
131void CalculateChiSquared::calcChiSquared(const API::IFunction &fun, size_t nParams, const API::FunctionDomain &domain,
132 API::FunctionValues &values, double &chiSquared, double &chiSquaredWeighted,
133 double &dof) {
134
135 // Calculate function values.
136 fun.function(domain, values);
137
138 // Calculate the chi squared.
139 chiSquared = 0.0;
140 chiSquaredWeighted = 0.0;
141 dof = -static_cast<double>(nParams);
142 for (size_t i = 0; i < values.size(); ++i) {
143 auto weight = values.getFitWeight(i);
144 if (weight > 0.0) {
145 double tmp = values.getFitData(i) - values.getCalculated(i);
146 chiSquared += tmp * tmp;
147 tmp *= weight;
148 chiSquaredWeighted += tmp * tmp;
149 dof += 1.0;
150 }
151 }
152 if (dof <= 0.0) {
153 dof = 1.0;
154 }
155}
156
157} // namespace Mantid::CurveFitting::Algorithms
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
gsl_vector * tmp
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
Definition: Algorithm.cpp:1913
Base class that represents the domain of a function.
A class to store values calculated by a function.
double getFitWeight(size_t i) const
Get a fitting weight.
double getFitData(size_t i) const
Get a fitting data value.
size_t size() const
Return the number of values.
double getCalculated(size_t i) const
Get i-th calculated value.
This is an interface to a fitting function - a semi-abstarct class.
Definition: IFunction.h:163
virtual void function(const FunctionDomain &domain, FunctionValues &values) const =0
Evaluates the function for all arguments in the domain.
Calculate chi squared for a function and a data set in a workspace.
static void calcChiSquared(const API::IFunction &fun, size_t nParams, const API::FunctionDomain &domain, API::FunctionValues &values, double &chiSquared, double &chiSquaredWeighted, double &dof)
Caclculate the chi squared, weighted chi squared and the number of degrees of freedom.
std::shared_ptr< API::IDomainCreator > m_domainCreator
Pointer to a domain creator.
std::shared_ptr< API::IFunction > m_function
Pointer to the fitting function.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void notice(const std::string &msg)
Logs at notice level.
Definition: Logger.cpp:95
void warning(const std::string &msg)
Logs at warning level.
Definition: Logger.cpp:86
std::shared_ptr< FunctionValues > FunctionValues_sptr
typedef for a shared pointer
Kernel::Logger g_log("ExperimentInfo")
static logger object
std::shared_ptr< FunctionDomain > FunctionDomain_sptr
typedef for a shared pointer
STL namespace.
@ Output
An output workspace.
Definition: Property.h:54