-
Notifications
You must be signed in to change notification settings - Fork 122
/
CompositeFunction.h
310 lines (280 loc) · 12.3 KB
/
CompositeFunction.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
#ifndef MANTID_API_COMPOSITEFUNCTION_H_
#define MANTID_API_COMPOSITEFUNCTION_H_
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidAPI/IFunction.h"
#include "MantidAPI/Jacobian.h"
#include <map>
namespace Mantid {
namespace API {
/** A composite function is a function containing other functions. It combines
values
calculated by the member function using an operation. The default operation
is summation (+).
Composite functions do not have their own parameters, they use parameters of
the member functions.
Functions are added to a composite functions with addFunction method and can
be retrieved with
getFinction(i) method. Function indices are defined by the order they are
added. Parameter names
are formed from the member function's index and its parameter name:
f[index].[name]. For example,
name "f0.Sigma" would be given to the "Sigma" parameter of a Gaussian added
first to the composite
function. If a member function is a composite function itself the same
principle applies: 'f[index].'
is prepended to a name, e.g. "f0.f1.Sigma".
The default implementation expects its member to use the same type of
FunctionDomain. The domain
passed to the function(...) method is used to evaluate all member functions.
@author Roman Tolchenov, Tessella Support Services plc
@date 20/10/2009
Copyright © 2009 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
National Laboratory & European Spallation Source
This file is part of Mantid.
Mantid is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
Mantid is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
File change history is stored at: <https://github.com/mantidproject/mantid>.
Code Documentation is available at: <http://doxygen.mantidproject.org>
*/
class MANTID_API_DLL CompositeFunction : public virtual IFunction {
public:
/// Default constructor
CompositeFunction();
/* Overriden methods */
/// Returns the function's name
std::string name() const override { return "CompositeFunction"; }
/// Writes itself into a string
std::string asString() const override;
/// Sets the workspace for each member function
void setWorkspace(boost::shared_ptr<const Workspace> ws) override;
/// Set matrix workspace
void
setMatrixWorkspace(boost::shared_ptr<const API::MatrixWorkspace> workspace,
size_t wi, double startX, double endX) override;
/// Function you want to fit to.
void function(const FunctionDomain &domain,
FunctionValues &values) const override;
/// Derivatives of function with respect to active parameters
void functionDeriv(const FunctionDomain &domain, Jacobian &jacobian) override;
/// Set i-th parameter
void setParameter(size_t, const double &value,
bool explicitlySet = true) override;
/// Set i-th parameter description
void setParameterDescription(size_t, const std::string &description) override;
/// Get i-th parameter
double getParameter(size_t i) const override;
/// Set parameter by name.
void setParameter(const std::string &name, const double &value,
bool explicitlySet = true) override;
/// Set description of parameter by name.
void setParameterDescription(const std::string &name,
const std::string &description) override;
/// Get parameter by name.
double getParameter(const std::string &name) const override;
/// Total number of parameters
size_t nParams() const override;
/// Returns the index of parameter name
size_t parameterIndex(const std::string &name) const override;
/// Returns the name of parameter i
std::string parameterName(size_t i) const override;
/// Returns the description of parameter i
std::string parameterDescription(size_t i) const override;
/// Checks if a parameter has been set explicitly
bool isExplicitlySet(size_t i) const override;
/// Get the fitting error for a parameter
double getError(size_t i) const override;
/// Set the fitting error for a parameter
void setError(size_t i, double err) override;
/// Value of i-th active parameter. Override this method to make fitted
/// parameters different from the declared
double activeParameter(size_t i) const override;
/// Set new value of i-th active parameter. Override this method to make
/// fitted parameters different from the declared
void setActiveParameter(size_t i, double value) override;
/// Update parameters after a fitting iteration
void updateActive(const double *in);
/// Returns the name of active parameter i
std::string nameOfActive(size_t i) const override;
/// Returns the name of active parameter i
std::string descriptionOfActive(size_t i) const override;
/// Return parameter index from a parameter reference.
size_t getParameterIndex(const ParameterReference &ref) const override;
/// Get the containing function
IFunction_sptr getContainingFunction(const ParameterReference &ref) const;
/// Apply the ties
void applyTies() override;
/// Remove all ties
void clearTies() override;
// Unhide base class function: removeTie(string). Avoids Intel compiler
// warning
using IFunction::removeTie;
/// Removes i-th parameter's tie
bool removeTie(size_t i) override;
/// Get the tie of i-th parameter
ParameterTie *getTie(size_t i) const override;
/// Get constraint of i-th parameter
IConstraint *getConstraint(size_t i) const override;
/// Prepare function for a fit
void setUpForFit() override;
/// Remove a constraint
void removeConstraint(const std::string &parName) override;
/// Get number of domains required by this function
size_t getNumberDomains() const override;
/// Split this function (if needed) into a list of independent functions.
std::vector<boost::shared_ptr<IFunction>>
createEquivalentFunctions() const override;
/* CompositeFunction own methods */
/// Add a function at the back of the internal function list
virtual size_t addFunction(IFunction_sptr f);
/// Returns the pointer to i-th function
IFunction_sptr getFunction(std::size_t i) const;
/// Number of functions
std::size_t nFunctions() const { return m_functions.size(); }
/// Remove a function
void removeFunction(size_t i);
/// Replace a function
void replaceFunction(size_t i, IFunction_sptr f);
/// Replace a function
void replaceFunctionPtr(const IFunction_sptr f_old, IFunction_sptr f_new);
/// Get the function index
std::size_t functionIndex(std::size_t i) const;
/// Returns the index of parameter i as it declared in its function
size_t parameterLocalIndex(size_t i, bool recursive = false) const;
/// Returns the name of parameter i as it declared in its function
std::string parameterLocalName(size_t i, bool recursive = false) const;
/// Check the function.
void checkFunction();
/// Remove all member functions
void clear();
/// Returns the number of attributes associated with the function
virtual size_t nLocalAttributes() const { return 0; }
/// Returns a list of attribute names
virtual std::vector<std::string> getLocalAttributeNames() const {
return std::vector<std::string>();
}
/// Return a value of attribute attName
virtual Attribute getLocalAttribute(size_t i,
const std::string &attName) const {
(void)i;
throw std::invalid_argument("Attribute " + attName +
" not found in function " + this->name());
}
/// Set a value to attribute attName
virtual void setLocalAttribute(size_t i, const std::string &attName,
const Attribute &) {
(void)i;
throw std::invalid_argument("Attribute " + attName +
" not found in function " + this->name());
}
/// Check if attribute attName exists
virtual bool hasLocalAttribute(const std::string &) const { return false; }
template <typename T>
void setLocalAttributeValue(size_t i, const std::string &attName,
const T &value) {
setLocalAttribute(i, attName, Attribute(value));
}
void setLocalAttributeValue(size_t i, const std::string &attName,
const char *value) {
setLocalAttribute(i, attName, Attribute(std::string(value)));
}
protected:
/// Function initialization. Declare function parameters in this method.
void init() override;
/// Declare a new parameter
void declareParameter(const std::string &name, double initValue = 0,
const std::string &description = "") override;
/// Change status of parameter
void setParameterStatus(size_t i, ParameterStatus status) override;
/// Get status of parameter
ParameterStatus getParameterStatus(size_t i) const override;
size_t paramOffset(size_t i) const { return m_paramOffsets[i]; }
private:
/// Extract function index and parameter name from a variable name
static void parseName(const std::string &varName, size_t &index,
std::string &name);
/// Pointers to the included funtions
std::vector<IFunction_sptr> m_functions;
/// Individual function parameter offsets (function index in m_functions)
/// e.g. m_functions[i]->parameter(m_paramOffsets[i]+1) gives second declared
/// parameter of i-th function
std::vector<size_t> m_paramOffsets;
/// Keeps the function index for each declared parameter (parameter declared
/// index)
std::vector<size_t> m_IFunction;
/// Total number of parameters
size_t m_nParams;
/// Function counter to be used in nextConstraint
mutable size_t m_iConstraintFunction;
};
/// shared pointer to the composite function base class
typedef boost::shared_ptr<CompositeFunction> CompositeFunction_sptr;
/// shared pointer to the composite function base class (const version)
typedef boost::shared_ptr<const CompositeFunction> CompositeFunction_const_sptr;
/** A Jacobian for individual functions
*/
class PartialJacobian : public Jacobian {
Jacobian *m_J; ///< pointer to the overall Jacobian
size_t m_iY0; ///< fitting data index offset in the overall Jacobian for a
/// particular function
size_t m_iP0; ///< parameter index offset in the overall Jacobian for a
/// particular function
public:
/** Constructor
* @param J :: A pointer to the overall Jacobian
* @param iP0 :: The parameter index (declared) offset for a particular
* function
*/
PartialJacobian(Jacobian *J, size_t iP0)
: m_J(J), m_iY0(0), m_iP0(iP0) //,m_iaP0(iap0)
{}
/** Constructor
* @param J :: A pointer to the overall Jacobian
* @param iY0 :: The data index offset for a particular function
* @param iP0 :: The parameter index offset for a particular function
*/
PartialJacobian(Jacobian *J, size_t iY0, size_t iP0)
: m_J(J), m_iY0(iY0), m_iP0(iP0) {}
/**
* Overridden Jacobian::set(...).
* @param iY :: The index of the data point
* @param iP :: The parameter index of an individual function.
* @param value :: The derivative value
*/
void set(size_t iY, size_t iP, double value) override {
m_J->set(m_iY0 + iY, m_iP0 + iP, value);
}
/**
* Overridden Jacobian::get(...).
* @param iY :: The index of the data point
* @param iP :: The parameter index of an individual function.
*/
double get(size_t iY, size_t iP) override {
return m_J->get(m_iY0 + iY, m_iP0 + iP);
}
/** Zero all matrix elements.
*/
void zero() override {
throw Kernel::Exception::NotImplementedError(
"zero() is not implemented for PartialJacobian");
}
/** Add number to all iY (data) Jacobian elements for a given iP (parameter)
* @param value :: Value to add
* @param iP :: The index of an active parameter.
*/
void addNumberToColumn(const double &value, const size_t &iP) override {
m_J->addNumberToColumn(value, m_iP0 + iP);
}
};
} // namespace API
} // namespace Mantid
#endif /*MANTID_API_COMPOSITEFUNCTION_H_*/