-
Notifications
You must be signed in to change notification settings - Fork 122
/
Polynomial.cpp
137 lines (117 loc) · 4.07 KB
/
Polynomial.cpp
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
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
// NScD Oak Ridge National Laboratory, European Spallation Source,
// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
// SPDX - License - Identifier: GPL - 3.0 +
#include "MantidCurveFitting/Functions/Polynomial.h"
#include "MantidAPI/FunctionFactory.h"
using namespace Mantid::Kernel;
using namespace Mantid::API;
using namespace std;
namespace Mantid {
namespace CurveFitting {
namespace Functions {
using namespace CurveFitting;
DECLARE_FUNCTION(Polynomial)
//----------------------------------------------------------------------------------------------
/** Constructor
*/
Polynomial::Polynomial() : m_n(0) { declareParameter("A0"); }
//----------------------------------------------------------------------------------------------
/** Function to calcualte polynomial
*/
void Polynomial::function1D(double *out, const double *xValues,
const size_t nData) const {
// 1. Use a vector for all coefficient
vector<double> coeff(m_n + 1, 0.0);
for (int i = 0; i < m_n + 1; ++i)
coeff[i] = getParameter(i);
// 2. Calculate
for (size_t i = 0; i < nData; ++i) {
double x = xValues[i];
double temp = coeff[0];
double nx = x;
for (int j = 1; j <= m_n; ++j) {
temp += coeff[j] * nx;
nx *= x;
}
out[i] = temp;
}
}
//----------------------------------------------------------------------------------------------
/** Function to calculate derivative analytically
*/
void Polynomial::functionDeriv1D(API::Jacobian *out, const double *xValues,
const size_t nData) {
for (size_t i = 0; i < nData; i++) {
double x = xValues[i];
double nx = 1;
for (int j = 0; j <= m_n; ++j) {
out->set(i, j, nx);
nx *= x;
}
}
}
//----------------------------------------------------------------------------------------------
/** Get Attribute names
* @return A list of attribute names (identical to Polynomial)
*/
std::vector<std::string> Polynomial::getAttributeNames() const { return {"n"}; }
//----------------------------------------------------------------------------------------------
/** Get Attribute
* @param attName :: Attribute name. If it is not "n" exception is thrown.
* @return a value of attribute attName
* (identical to Polynomial)
*/
API::IFunction::Attribute
Polynomial::getAttribute(const std::string &attName) const {
if (attName == "n") {
return Attribute(m_n);
}
throw std::invalid_argument("Polynomial: Unknown attribute " + attName);
}
//----------------------------------------------------------------------------------------------
/** Set Attribute
* @param attName :: The attribute name. If it is not "n" exception is thrown.
* @param att :: An int attribute containing the new value. The value cannot be
* negative.
* (identical to Polynomial)
*/
void Polynomial::setAttribute(const std::string &attName,
const API::IFunction::Attribute &att) {
if (attName == "n") {
// set the polynomial order
auto newN = att.asInt();
if (newN < 0) {
throw std::invalid_argument(
"Polynomial: polynomial order cannot be negative.");
}
// Save old values
std::vector<double> oldValues(std::min(m_n, newN) + 1);
for (size_t i = 0; i < oldValues.size(); ++i) {
oldValues[i] = getParameter(i);
}
if (m_n >= 0) {
clearAllParameters();
}
m_n = att.asInt();
for (int i = 0; i <= m_n; ++i) {
std::string parName = "A" + std::to_string(i);
declareParameter(parName);
}
// Reset old values to new parameters
for (size_t i = 0; i < oldValues.size(); ++i) {
setParameter(i, oldValues[i]);
}
}
}
//----------------------------------------------------------------------------------------------
/** Check if attribute attName exists
*/
bool Polynomial::hasAttribute(const std::string &attName) const {
return attName == "n";
}
} // namespace Functions
} // namespace CurveFitting
} // namespace Mantid