CompositeFunction.h 12.4 KB
Newer Older
1
2
3
4
5
6
#ifndef MANTID_API_COMPOSITEFUNCTION_H_
#define MANTID_API_COMPOSITEFUNCTION_H_

//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
7
#include "MantidAPI/IFunction.h"
8
#include "MantidAPI/Jacobian.h"
9
10

#include <map>
11

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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].'
30
31
    is prepended to a name, e.g. "f0.f1.Sigma".

32
33
    The default implementation expects its member to use the same type of
   FunctionDomain. The domain
34
    passed to the function(...) method is used to evaluate all member functions.
35
36
37
38

    @author Roman Tolchenov, Tessella Support Services plc
    @date 20/10/2009

39
40
    Copyright &copy; 2009 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
   National Laboratory & European Spallation Source
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

    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/>.

57
    File change history is stored at: <https://github.com/mantidproject/mantid>.
58
59
    Code Documentation is available at: <http://doxygen.mantidproject.org>
*/
60
class MANTID_API_DLL CompositeFunction : public virtual IFunction {
61
62
public:
  /// Default constructor
63
  CompositeFunction();
64

65
  /* Overriden methods */
66

67
  /// Returns the function's name
68
  std::string name() const override { return "CompositeFunction"; }
69
  /// Writes itself into a string
Roman Tolchenov's avatar
Roman Tolchenov committed
70
71
  std::string
  asString(const std::string &parentLocalAttributesStr = "") const override;
72
  /// Sets the workspace for each member function
73
  void setWorkspace(boost::shared_ptr<const Workspace> ws) override;
74
  /// Set matrix workspace
75
76
  void
  setMatrixWorkspace(boost::shared_ptr<const API::MatrixWorkspace> workspace,
77
                     size_t wi, double startX, double endX) override;
78

79
  /// Function you want to fit to.
80
81
  void function(const FunctionDomain &domain,
                FunctionValues &values) const override;
82
  /// Derivatives of function with respect to active parameters
83
  void functionDeriv(const FunctionDomain &domain, Jacobian &jacobian) override;
84

85
  /// Set i-th parameter
86
87
  void setParameter(size_t, const double &value,
                    bool explicitlySet = true) override;
88
  /// Set i-th parameter description
89
  void setParameterDescription(size_t, const std::string &description) override;
90
  /// Get i-th parameter
91
  double getParameter(size_t i) const override;
92
  /// Set parameter by name.
93
  void setParameter(const std::string &name, const double &value,
94
                    bool explicitlySet = true) override;
95
  /// Set description of parameter by name.
96
  void setParameterDescription(const std::string &name,
97
                               const std::string &description) override;
98
  /// Get parameter by name.
99
  double getParameter(const std::string &name) const override;
100
  /// Total number of parameters
101
  size_t nParams() const override;
102
  /// Returns the index of parameter name
103
  size_t parameterIndex(const std::string &name) const override;
104
  /// Returns the name of parameter i
105
  std::string parameterName(size_t i) const override;
106
  /// Returns the description of parameter i
107
  std::string parameterDescription(size_t i) const override;
108
  /// Checks if a parameter has been set explicitly
109
  bool isExplicitlySet(size_t i) const override;
110
  /// Get the fitting error for a parameter
111
  double getError(size_t i) const override;
112
  /// Set the fitting error for a parameter
113
  void setError(size_t i, double err) override;
114

115
116
  /// Value of i-th active parameter. Override this method to make fitted
  /// parameters different from the declared
117
  double activeParameter(size_t i) const override;
118
119
  /// Set new value of i-th active parameter. Override this method to make
  /// fitted parameters different from the declared
120
  void setActiveParameter(size_t i, double value) override;
121
  /// Update parameters after a fitting iteration
122
  void updateActive(const double *in);
123
  /// Returns the name of active parameter i
124
  std::string nameOfActive(size_t i) const override;
125
  /// Returns the name of active parameter i
126
  std::string descriptionOfActive(size_t i) const override;
127

128
  /// Return parameter index from a parameter reference.
129
  size_t getParameterIndex(const ParameterReference &ref) const override;
130
  /// Get the containing function
131
  IFunction_sptr getContainingFunction(const ParameterReference &ref) const;
132

133
  /// Apply the ties
134
  void applyTies() override;
135
  /// Remove all ties
136
  void clearTies() override;
137
138
  // Unhide base class function: removeTie(string). Avoids Intel compiler
  // warning
139
  using IFunction::removeTie;
140
  /// Removes i-th parameter's tie
141
  bool removeTie(size_t i) override;
142
  /// Get the tie of i-th parameter
143
  ParameterTie *getTie(size_t i) const override;
144

145
  /// Get constraint of i-th parameter
146
  IConstraint *getConstraint(size_t i) const override;
147
  /// Prepare function for a fit
148
  void setUpForFit() override;
149
  /// Remove a constraint
150
  void removeConstraint(const std::string &parName) override;
151
152
153
154
155
  /// 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;
156

157
  /* CompositeFunction own methods */
158

159
  /// Add a function at the back of the internal function list
160
  virtual size_t addFunction(IFunction_sptr f);
161
  /// Returns the pointer to i-th function
162
  IFunction_sptr getFunction(std::size_t i) const;
163
  /// Number of functions
164
  std::size_t nFunctions() const { return m_functions.size(); }
165
  /// Remove a function
166
  void removeFunction(size_t i);
167
  /// Replace a function
168
  void replaceFunction(size_t i, IFunction_sptr f);
169
  /// Replace a function
170
  void replaceFunctionPtr(const IFunction_sptr f_old, IFunction_sptr f_new);
171
  /// Get the function index
172
  std::size_t functionIndex(std::size_t i) const;
173
  /// Returns the index of parameter i as it declared in its function
174
  size_t parameterLocalIndex(size_t i, bool recursive = false) const;
175
  /// Returns the name of parameter i as it declared in its function
176
  std::string parameterLocalName(size_t i, bool recursive = false) const;
177
178
  /// Check the function.
  void checkFunction();
179
180
  /// Remove all member functions
  void clear();
181

182
  /// Returns the number of attributes associated with the function
183
  virtual size_t nLocalAttributes() const { return 0; }
184
  /// Returns a list of attribute names
185
186
187
  virtual std::vector<std::string> getLocalAttributeNames() const {
    return std::vector<std::string>();
  }
188
  /// Return a value of attribute attName
189
190
  virtual Attribute getLocalAttribute(size_t i,
                                      const std::string &attName) const {
191
    (void)i;
192
193
    throw std::invalid_argument("Attribute " + attName +
                                " not found in function " + this->name());
194
195
  }
  /// Set a value to attribute attName
196
197
  virtual void setLocalAttribute(size_t i, const std::string &attName,
                                 const Attribute &) {
198
    (void)i;
199
200
    throw std::invalid_argument("Attribute " + attName +
                                " not found in function " + this->name());
201
202
  }
  /// Check if attribute attName exists
203
204
205
206
207
208
209
210
211
212
  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)));
  }
213

214
215
protected:
  /// Function initialization. Declare function parameters in this method.
216
  void init() override;
217
  /// Declare a new parameter
218
219
  void declareParameter(const std::string &name, double initValue = 0,
                        const std::string &description = "") override;
220
221
222
223
  /// Change status of parameter
  void setParameterStatus(size_t i, ParameterStatus status) override;
  /// Get status of parameter
  ParameterStatus getParameterStatus(size_t i) const override;
224

225
  size_t paramOffset(size_t i) const { return m_paramOffsets[i]; }
226

227
private:
228
  /// Extract function index and parameter name from a variable name
229
230
  static void parseName(const std::string &varName, size_t &index,
                        std::string &name);
231
232

  /// Pointers to the included funtions
233
  std::vector<IFunction_sptr> m_functions;
234
  /// Individual function parameter offsets (function index in m_functions)
235
236
  /// e.g. m_functions[i]->parameter(m_paramOffsets[i]+1) gives second declared
  /// parameter of i-th function
237
  std::vector<size_t> m_paramOffsets;
238
239
  /// Keeps the function index for each declared parameter  (parameter declared
  /// index)
240
  std::vector<size_t> m_IFunction;
241
  /// Total number of parameters
242
  size_t m_nParams;
243
  /// Function counter to be used in nextConstraint
244
  mutable size_t m_iConstraintFunction;
245
246
};

247
/// shared pointer to the composite function base class
248
typedef boost::shared_ptr<CompositeFunction> CompositeFunction_sptr;
249
/// shared pointer to the composite function base class (const version)
250
251
typedef boost::shared_ptr<const CompositeFunction> CompositeFunction_const_sptr;

252
253
/** A Jacobian for individual functions
 */
254
255
256
257
258
259
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
260
261
262
public:
  /** Constructor
   * @param J :: A pointer to the overall Jacobian
263
264
   * @param iP0 :: The parameter index (declared) offset for a particular
   * function
265
   */
266
267
  PartialJacobian(Jacobian *J, size_t iP0)
      : m_J(J), m_iY0(0), m_iP0(iP0) //,m_iaP0(iap0)
268
269
270
271
272
273
  {}
  /** 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
   */
274
275
  PartialJacobian(Jacobian *J, size_t iY0, size_t iP0)
      : m_J(J), m_iY0(iY0), m_iP0(iP0) {}
276
277
278
279
280
281
  /**
   * 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
   */
282
  void set(size_t iY, size_t iP, double value) override {
283
    m_J->set(m_iY0 + iY, m_iP0 + iP, value);
284
285
286
287
288
289
  }
  /**
   * Overridden Jacobian::get(...).
   * @param iY :: The index of the data point
   * @param iP :: The parameter index of an individual function.
   */
290
291
292
  double get(size_t iY, size_t iP) override {
    return m_J->get(m_iY0 + iY, m_iP0 + iP);
  }
293
294
295
  /** Zero all matrix elements.
  */
  void zero() override {
296
297
    throw Kernel::Exception::NotImplementedError(
        "zero() is not implemented for PartialJacobian");
298
  }
299
300
301
302
  /**  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.
   */
303
  void addNumberToColumn(const double &value, const size_t &iP) override {
304
    m_J->addNumberToColumn(value, m_iP0 + iP);
305
  }
306
307
308
309
310
311
};

} // namespace API
} // namespace Mantid

#endif /*MANTID_API_COMPOSITEFUNCTION_H_*/