Mantid
Loading...
Searching...
No Matches
EigenJacobian.h
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2010 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 +
7#pragma once
8
10#include "MantidAPI/Jacobian.h"
12
13#include <stdexcept>
14#include <vector>
15
16namespace Mantid {
17namespace CurveFitting {
27 std::vector<int> m_index;
28
29public:
33 EigenJacobian(const API::IFunction &fun, const size_t ny) {
34 m_index.resize(fun.nParams(), -1);
35 size_t np = 0; // number of active parameters
36 for (size_t i = 0; i < fun.nParams(); ++i) {
37 m_index[i] = static_cast<int>(np);
38 if (fun.isActive(i)) {
39 ++np;
40 }
41 }
42 m_J.resize(ny, np);
43 }
44
45 EigenMatrix &matrix() { return m_J; }
46
48 map_type &getJ() { return m_J.mutator(); }
49
55 void addNumberToColumn(const double &value, const size_t &iActiveP) override {
56 if (iActiveP < m_J.size2()) {
57 // add penalty to first and last point and every 10th point in between
58 m_J.mutator().data()[iActiveP * m_J.size1()] += value;
59 m_J.mutator().data()[(iActiveP + 1) * m_J.size1() - 1] += value;
60 for (size_t iY = 9; iY < m_J.size1() - 1; iY += 10)
61 m_J.mutator().data()[iActiveP * m_J.size1() + iY] += value;
62 } else {
63 throw std::runtime_error("Try to add number to column of Jacobian matrix "
64 "which does not exist.");
65 }
66 }
68 void set(size_t iY, size_t iP, double value) override {
69 int j = m_index[iP];
70 if (j >= 0)
71 m_J.set(iY, j, value);
72 }
74 double get(size_t iY, size_t iP) override {
75 int j = m_index[iP];
76 if (j >= 0)
77 return m_J.get(iY, j);
78 return 0.0;
79 }
81 void zero() override { m_J.zero(); }
82};
83
85template <class T> class JacobianImpl1 : public API::Jacobian {
86public:
88 T *m_J;
90 std::vector<int> m_index;
91
93 void setJ(T *J) { m_J = J; }
94
100 void addNumberToColumn(const double &value, const size_t &iActiveP) override {
101 if (iActiveP < m_J->size2()) {
102 // add penalty to first and last point and every 10th point in between
103 m_J->mutator().data()[iActiveP * m_J->size1()] += value;
104 m_J->mutator().data()[(iActiveP + 1) * m_J->size1() - 1] += value;
105 for (size_t iY = 9; iY < m_J->size1() - 1; iY += 10)
106 m_J->mutator().data()[iActiveP * m_J->size1() + iY] += value;
107 } else {
108 throw std::runtime_error("Try to add number to column of Jacobian matrix "
109 "which does not exist.");
110 }
111 }
113 void set(size_t iY, size_t iP, double value) override {
114 if (iP >= m_index.size()) {
115 // Functions are allowed to change their number of active
116 // fitting parameters during the fit (example: the crystal field
117 // functions). When it happens after an iteration is finished there is a
118 // special exception that signals the minimizer to re-initialize itself.
119 // But it can happen during a numeric derivative calculation: a field
120 // parameter is incremented, a new peak may appear and it may have a free
121 // fitting parameter, so the number of parameters change. You cannot throw
122 // and re-initialize the minimizer at this point because the same will
123 // happen again. If you ignore these "virtual" extra parameters by the
124 // time the derivative calculations finish the number of parameters will
125 // return to the original value. Note that the get(...) method doesn't
126 // skip any extra indices because if there are any it is an error.
127 return;
128 }
129 int j = m_index[iP];
130 if (j >= 0)
131 m_J->mutator().data()[j * m_J->size1() + iY] = value;
132 }
134 double get(size_t iY, size_t iP) override {
135 int j = m_index[iP];
136 if (j >= 0)
137 return m_J->inspector().data()[j * m_J->size1() + iY];
138 return 0.0;
139 }
141 void zero() override { m_J->zero(); }
142};
143
144} // namespace CurveFitting
145} // namespace Mantid
double value
The value of the point.
Definition: FitMW.cpp:51
This is an interface to a fitting function - a semi-abstarct class.
Definition: IFunction.h:163
virtual size_t nParams() const =0
Total number of parameters.
bool isActive(size_t i) const
Check if an active parameter i is actually active.
Definition: IFunction.cpp:160
Represents the Jacobian in IFitFunction::functionDeriv.
Definition: Jacobian.h:22
Two implementations of Jacobian.
Definition: EigenJacobian.h:23
map_type & getJ()
Get the map to the jacobian.
Definition: EigenJacobian.h:48
void zero() override
overwrite base method
Definition: EigenJacobian.h:81
EigenJacobian(const API::IFunction &fun, const size_t ny)
Constructor.
Definition: EigenJacobian.h:33
double get(size_t iY, size_t iP) override
overwrite base method
Definition: EigenJacobian.h:74
std::vector< int > m_index
Maps declared indeces to active. For fixed (tied) parameters holds -1.
Definition: EigenJacobian.h:27
void addNumberToColumn(const double &value, const size_t &iActiveP) override
overwrite base method
Definition: EigenJacobian.h:55
EigenMatrix m_J
The internal jacobian matrix.
Definition: EigenJacobian.h:25
void set(size_t iY, size_t iP, double value) override
overwrite base method
Definition: EigenJacobian.h:68
A wrapper around Eigen::Matrix.
Definition: EigenMatrix.h:33
void set(size_t i, size_t j, double value)
Set an element.
double get(size_t i, size_t j) const
Get an element.
size_t size1() const
First size of the matrix.
map_type & mutator()
Get the map to Eigen matrix.
Definition: EigenMatrix.h:56
void zero()
Set all elements to zero.
size_t size2() const
Second size of the matrix.
void resize(const size_t nx, const size_t ny)
Resize the matrix.
The implementation of Jacobian.
Definition: EigenJacobian.h:85
T * m_J
The internal jacobian matrix.
Definition: EigenJacobian.h:88
double get(size_t iY, size_t iP) override
overwrite base method
void set(size_t iY, size_t iP, double value) override
overwrite base method
void addNumberToColumn(const double &value, const size_t &iActiveP) override
overwrite base method
void setJ(T *J)
Set the pointer to the jacobian.
Definition: EigenJacobian.h:93
void zero() override
overwrite base method
std::vector< int > m_index
Maps declared indices to active. For fixed (tied) parameters holds -1.
Definition: EigenJacobian.h:90
Eigen::Map< Eigen::MatrixXd, 0, dynamic_stride > map_type
Helper class which provides the Collimation Length for SANS instruments.