39 const Container<Number>&
X,
40 const Container<Number>& Y,
44 if (
X.size() != Y.size()) {
45 std::cerr <<
"Error in function " << __FUNCTION__
46 <<
": Vectors X (of size " <<
X.size()
47 <<
") and Y (of size " << Y.size()
48 <<
") are not the same size. Returning an empty array..." << std::endl;
62 Container<Number>
coeffs(n * (n - 1));
66#if defined(_OPENMP) && !defined(ALFI_DISABLE_OPENMP)
67#pragma omp parallel for
69 for (
SizeT i = 0; i < n - 1; ++i) {
74 Container<Number> P_i;
80 std::move(P_i.begin(), P_i.end(),
coeffs.begin() + (i * n));
93 const static auto binomials = [](
SizeT m) {
94 Container<Container<Number>> C(m + 1);
95 for (
SizeT i = 0; i <= m; ++i) {
97 C[i][0] = C[i][i] = 1;
98 for (
SizeT j = 1; j <= i / 2; ++j) {
99 C[i][j] = C[i][i-j] = C[i-1][j-1] + C[i-1][j];
105 const auto C = binomials(n - 1);
107#if defined(_OPENMP) && !defined(ALFI_DISABLE_OPENMP)
108#pragma omp parallel for
110 for (
SizeT i = 0; i < n - 1; ++i) {
112 for (
SizeT k = 1; k < n - 1; ++k) {
114 for (
SizeT j = 0; j < k; ++j) {
115 r += ((((k - j) & 1) == 0) ? 1 : -1) *
coeffs[i*n+j] * C[n-1-j][k-j];
130 template <
typename ContainerXType>
132 const Container<Number>& Y,
144 template <
typename ContainerXType>
146 const Container<Number>& Y,
151 if (
coeffs.empty() && !
X.empty()) {
152 std::cerr <<
"Error in function " << __FUNCTION__
153 <<
": failed to construct coefficients. Not changing the object..." << std::endl;
159 _X = std::forward<ContainerXType>(
X);
160 _coeffs = std::move(
coeffs);
167 if (_coeffs.empty()) {
169 }
else if (_coeffs.size() == 1) {
177 const SizeT n = _X.size();
179 Number result = _coeffs[
segment*n];
181 if (std::isnan(result)) {
182 switch (_evaluation_type) {
192 for (
SizeT i = 1; i < n; ++i) {
194 Number current = _coeffs[
segment*n+i];
195 if (std::isnan(current)) {
196 switch (_evaluation_type) {
213 Container<Number>
eval(
const Container<Number>& xx,
bool sorted =
true)
const {
214 Container<Number> result(xx.size());
216 for (
SizeT i = 0, i_x = 0; i < xx.size(); ++i) {
217 const Number x = xx[i];
218 while (i_x + 1 < _X.size() && x >= _X[i_x+1])
220 result[i] =
eval(x, i_x);
223 for (
SizeT i = 0; i < xx.size(); ++i) {
224 result[i] =
eval(xx[i]);
233 Container<Number>
operator()(
const Container<Number>& xx)
const {
238 return _polynomial_type;
242 return _optimization_type;
246 return _evaluation_type;
249 const Container<Number>&
X() const & {
252 Container<Number>&&
X() && {
253 return std::move(_X);
256 const Container<Number>&
coeffs() const & {
260 return std::move(_coeffs);
264 return {_X.size()*index, _X.size()*(index+1)};
271 Container<Number> _X = {};
272 Container<Number> _coeffs = {};
static Container< Number > compute_coeffs(const Container< Number > &X, const Container< Number > &Y, PolynomialType polynomial_type=PolynomialType::Default, OptimizationType optimization_type=OptimizationType::Default)
Definition polyeqv.h:38
PolynomialType polynomial_type() const
Definition polyeqv.h:237
Container< Number > eval(const Container< Number > &xx, bool sorted=true) const
Definition polyeqv.h:213
PolyEqvSpline & operator=(PolyEqvSpline &&other) noexcept=default
Container< Number > && coeffs() &&
Definition polyeqv.h:259
std::pair< SizeT, SizeT > segment(SizeT index) const
Definition polyeqv.h:263
PolyEqvSpline(ContainerXType &&X, const Container< Number > &Y, PolynomialType polynomial_type=PolynomialType::Default, OptimizationType optimization_type=OptimizationType::Default)
Definition polyeqv.h:131
PolyEqvSpline(const PolyEqvSpline &other)=default
PolyEqvSpline(PolyEqvSpline &&other) noexcept=default
Number eval(Number x) const
Definition polyeqv.h:163
void construct(ContainerXType &&X, const Container< Number > &Y, PolynomialType polynomial_type=PolynomialType::Default, OptimizationType optimization_type=OptimizationType::Default, EvaluationType evaluation_type=EvaluationType::Default)
Definition polyeqv.h:145
PolynomialType
Definition polyeqv.h:15
@ NEWTON
Definition polyeqv.h:18
@ LAGRANGE
Definition polyeqv.h:16
@ Default
Definition polyeqv.h:20
@ IMPROVED_LAGRANGE
Definition polyeqv.h:17
Number eval(Number x, SizeT segment) const
Definition polyeqv.h:166
EvaluationType
Definition polyeqv.h:30
@ Default
Definition polyeqv.h:35
@ NOT_IGNORE_NANS
Definition polyeqv.h:33
@ IGNORE_NANS
Definition polyeqv.h:32
@ IGNORE_NANS_AND_PREVIOUS
Definition polyeqv.h:31
PolyEqvSpline & operator=(const PolyEqvSpline &other)=default
const Container< Number > & X() const &
Definition polyeqv.h:249
Number operator()(Number x) const
Definition polyeqv.h:230
EvaluationType evaluation_type() const
Definition polyeqv.h:245
Container< Number > && X() &&
Definition polyeqv.h:252
OptimizationType optimization_type() const
Definition polyeqv.h:241
OptimizationType
Definition polyeqv.h:23
@ ACCURACY
Definition polyeqv.h:24
@ SPEED
Definition polyeqv.h:25
@ Default
Definition polyeqv.h:27
const Container< Number > & coeffs() const &
Definition polyeqv.h:256
Container< Number > operator()(const Container< Number > &xx) const
Definition polyeqv.h:233
Container< Number > newton(const Container< Number > &X, const Container< Number > &Y)
Definition poly.h:249
Container< Number > lagrange(const Container< Number > &X, const Container< Number > &Y)
Definition poly.h:36
Container< Number > imp_lagrange(const Container< Number > &X, const Container< Number > &Y)
Definition poly.h:126
Iterator first_leq_or_begin(Iterator begin, Iterator end, const T &value)
Definition misc.h:27
Container< Number > simple_spline(const Container< Number > &X, const Container< Number > &Y, SizeT degree)
Definition spline.h:10
ALFI_DEFAULT_NUMBER DefaultNumber
Definition config.h:17
ALFI_SIZE_TYPE SizeT
Definition config.h:22
ALFI_DEFAULT_CONTAINER< Number > DefaultContainer
Definition config.h:20