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 +
9
11
12using namespace Kernel;
13using namespace API;
14
15// Register the algorithm into the AlgorithmFactory
16DECLARE_ALGORITHM(CalculateChiSquared)
17
18
19const std::string CalculateChiSquared::name() const { return "CalculateChiSquared"; }
20
22int CalculateChiSquared::version() const { return 1; }
23
25const std::string CalculateChiSquared::summary() const {
26 return "Calculate chi squared for a function and a data set in a workspace.";
27}
28
29//----------------------------------------------------------------------------------------------
31void CalculateChiSquared::initConcrete() {
32 declareProperty("ChiSquared", 0.0, "Output value of chi squared.", Direction::Output);
33 declareProperty("ChiSquaredDividedByDOF", 0.0,
34 "Output value of chi squared divided by the "
35 "number of degrees of freedom (NofData "
36 "- nOfParams).",
38 declareProperty("ChiSquaredDividedByNData", 0.0,
39 "Output value of chi squared divided by the "
40 "number of data points).",
42 declareProperty("ChiSquaredWeighted", 0.0, "Output value of weighted chi squared.", Direction::Output);
43 declareProperty("ChiSquaredWeightedDividedByDOF", 0.0,
44 "Output value of weighted chi squared divided by the "
45 "number of degrees of freedom (NofData "
46 "- nOfParams).",
48 declareProperty("ChiSquaredWeightedDividedByNData", 0.0,
49 "Output value of weighted chi squared divided by the "
50 "number of data points).",
52 declareProperty("Weighted", false,
53 "Option to use the weighted chi squared "
54 "in error estimation. Default is false.");
55}
56
57//----------------------------------------------------------------------------------------------
59void CalculateChiSquared::execConcrete() {
60
61 // Function may need some preparation.
62 m_function->setUpForFit();
63
66 m_domainCreator->createDomain(domain, values);
67
68 // Do something with the function which may depend on workspace.
69 m_domainCreator->initFunction(m_function);
70
71 // Get the number of free fitting parameters
72 size_t nParams = 0;
73 for (size_t i = 0; i < m_function->nParams(); ++i) {
74 if (m_function->isActive(i))
75 nParams += 1;
76 }
77
78 // Calculate function values.
79 m_function->function(*domain, *values);
80
81 // Calculate the chi squared.
82 double chiSquared = 0.0;
83 double chiSquaredWeighted = 0.0;
84 double dof = 0.0;
85 calcChiSquared(*m_function, nParams, *domain, *values, chiSquared, chiSquaredWeighted, dof);
86 g_log.notice() << "Chi squared " << chiSquared << "\n"
87 << "Chi squared weighted " << chiSquaredWeighted << "\n";
88
89 // Store the result.
90 setProperty("ChiSquared", chiSquared);
91 setProperty("chiSquaredWeighted", chiSquaredWeighted);
92
93 // Divided by NParams
94 double nData = dof + static_cast<double>(nParams);
95 const double chiSquaredNData = chiSquared / nData;
96 const double chiSquaredWeightedNData = chiSquaredWeighted / nData;
97 g_log.notice() << "Chi squared / NData " << chiSquaredNData << "\n"
98 << "Chi squared weighed / NData " << chiSquaredWeightedNData << "\n"
99 << "NParams " << nParams << "\n";
100
101 // Store the result.
102 setProperty("ChiSquaredDividedByNData", chiSquaredNData);
103 setProperty("ChiSquaredWeightedDividedByNData", chiSquaredWeightedNData);
104
105 // Divided by the DOF
106 if (dof <= 0.0) {
107 dof = 1.0;
108 g_log.warning("DOF has a non-positive value, changing to 1.0");
109 }
110 const double chiSquaredDOF = chiSquared / dof;
111 const double chiSquaredWeightedDOF = chiSquaredWeighted / dof;
112 g_log.notice() << "Chi squared / DOF " << chiSquaredDOF << "\n"
113 << "Chi squared weighed / DOF " << chiSquaredWeightedDOF << "\n"
114 << "DOF " << dof << "\n";
115
116 // Store the result.
117 setProperty("ChiSquaredDividedByDOF", chiSquaredDOF);
118 setProperty("ChiSquaredWeightedDividedByDOF", chiSquaredWeightedDOF);
119}
120
121//----------------------------------------------------------------------------------------------
122
132void CalculateChiSquared::calcChiSquared(const API::IFunction &fun, size_t nParams, const API::FunctionDomain &domain,
133 API::FunctionValues &values, double &chiSquared, double &chiSquaredWeighted,
134 double &dof) {
135
136 // Calculate function values.
137 fun.function(domain, values);
138
139 // Calculate the chi squared.
140 chiSquared = 0.0;
141 chiSquaredWeighted = 0.0;
142 dof = -static_cast<double>(nParams);
143 for (size_t i = 0; i < values.size(); ++i) {
144 auto weight = values.getFitWeight(i);
145 if (weight > 0.0) {
146 double tmp = values.getFitData(i) - values.getCalculated(i);
147 chiSquared += tmp * tmp;
148 tmp *= weight;
149 chiSquaredWeighted += tmp * tmp;
150 dof += 1.0;
151 }
152 }
153 if (dof <= 0.0) {
154 dof = 1.0;
155 }
156}
157
158} // namespace Mantid::CurveFitting::Algorithms
std::string name
Definition Run.cpp:60
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:547
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.
Kernel::Logger & g_log
Definition Algorithm.h:426
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:167
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:126
void warning(const std::string &msg)
Logs at warning level.
Definition Logger.cpp:117
std::shared_ptr< FunctionValues > FunctionValues_sptr
typedef for a shared pointer
std::shared_ptr< FunctionDomain > FunctionDomain_sptr
typedef for a shared pointer
STL namespace.
@ Output
An output workspace.
Definition Property.h:55