1#include <NDEVR/Angle.h>
2#include <NDEVR/Buffer.h>
3#include <NDEVR/Vertex.h>
4#include <NDEVR/BandMatrix.h>
5#include <NDEVR/SplineBoundaryType.h>
12 template<
class t_po
int_type>
42 ,
fltp08 right_value = 0.0)
51 for (
uint04 i = 0; i <
Y.size(); i++)
58 ,
bool make_monotonic =
false
62 ,
fltp08 right_value = 0.0)
79 lib_assert(x.
size() >= 4,
"not-a-knot with 3 points has multiple solutions");
85 for (
uint04 i = 0; i < n - 1; i++)
95 for (
uint04 i = 0; i < n - 1; i++)
118 for (
uint04 i = 1; i < n - 1; i++)
120 A(i, i - 1) = 1.0 / 3.0 * (x[i] - x[i - 1]);
121 A(i, i) = 2.0 / 3.0 * (x[i + 1] - x[i - 1]);
122 A(i, i + 1) = 1.0 / 3.0 * (x[i + 1] - x[i]);
123 rhs[i] = (y[i + 1] - y[i]) / (x[i + 1] - x[i]) - (y[i] - y[i - 1]) / (x[i] - x[i - 1]);
137 A(0, 0) = 2.0 * (x[1] - x[0]);
138 A(0, 1) = 1.0 * (x[1] - x[0]);
139 rhs[0] = 3.0 * ((y[1] - y[0]) / (x[1] - x[0]) -
m_left_value);
145 A(0, 0) = -(x[2] - x[1]);
146 A(0, 1) = x[2] - x[0];
147 A(0, 2) = -(x[1] - x[0]);
157 A(n - 1, n - 1) = 2.0;
158 A(n - 1, n - 2) = 0.0;
166 A(n - 1, n - 1) = 2.0 * (x[n - 1] - x[n - 2]);
167 A(n - 1, n - 2) = 1.0 * (x[n - 1] - x[n - 2]);
168 rhs[n - 1] = 3.0 * (
m_right_value - (y[n - 1] - y[n - 2]) / (x[n - 1] - x[n - 2]));
174 A(n - 1, n - 3) = -(x[n - 1] - x[n - 2]);
175 A(n - 1, n - 2) = x[n - 1] - x[n - 3];
176 A(n - 1, n - 1) = -(x[n - 2] - x[n - 3]);
185 m_c =
A.luSolve(rhs);
190 for (
uint04 i = 0; i < n - 1; i++)
192 m_d[i] = 1.0 / 3.0 * (
m_c[i + 1] -
m_c[i]) / (x[i + 1] - x[i]);
193 m_b[i] = (y[i + 1] - y[i]) / (x[i + 1] - x[i])
194 - 1.0 / 3.0 * (2.0 *
m_c[i] +
m_c[i + 1]) * (x[i + 1] - x[i]);
198 fltp08 h = x[n - 1] - x[n - 2];
201 m_b[n - 1] = 3.0 *
m_d[n - 2] * h * h + 2.0 *
m_c[n - 2] * h +
m_b[n - 2];
215 for (
uint04 i = 1; i < n - 1; i++)
219 m_b[i] = -h / (hl * (hl + h)) *
m_y[i - 1] + (h - hl) / (hl * h) *
m_y[i]
220 + hl / (h * (hl + h)) *
m_y[i + 1];
238 + h0 * h0 / (h1 * h1) * (
m_b[1] +
m_b[2] - 2.0 * (
m_y[2] -
m_y[1]) / h1);
260 m_b[n - 1] = -
m_b[n - 2] + 2.0 * (
m_y[n - 1] -
m_y[n - 2]) / h1 + h1 * h1 / (h0 * h0)
261 * (
m_b[n - 3] +
m_b[n - 2] - 2.0 * (
m_y[n - 2] -
m_y[n - 3]) / h0);
263 m_c[n - 1] = (
m_b[n - 2] + 2.0 *
m_b[n - 1]) / h1 - 3.0 * (
m_y[n - 1] -
m_y[n - 2]) / (h1 * h1);
289 bool modified =
false;
293 for (
uint04 i = 0; i < n; i++)
306 for (
uint04 i = 0; i < n - 1; i++)
309 for (
uint01 n = 0; n < t_point_type::NumberOfDimensions(); n++)
312 if (avg == 0.0 && (
m_b[i][n] != 0.0 ||
m_b[i + 1][n] != 0.0)) {
317 else if ((
m_b[i][n] >= 0.0 &&
m_b[i + 1][n] >= 0.0 && avg > 0.0) ||
318 (
m_b[i][n] <= 0.0 &&
m_b[i + 1][n] <= 0.0 && avg < 0.0))
327 m_b[i][n] *= (3.0 / r);
328 m_b[i + 1][n] *= (3.0 / r);
360 t_point_type interpol;
366 else if (x >
m_x[n - 1])
369 interpol = (
m_c[n - 1] * h +
m_b[n - 1]) * h +
m_y[n - 1];
374 interpol = ((
m_d[idx] * h +
m_c[idx]) * h +
m_b[idx]) * h +
m_y[idx];
386 t_point_type interpol;
393 interpol = 2.0 *
m_c0 * h +
m_b[0];
396 interpol = 2.0 *
m_c0;
403 else if (x >
m_x[n - 1])
409 interpol = 2.0 *
m_c[n - 1] * h +
m_b[n - 1];
412 interpol = 2.0 *
m_c[n - 1];
425 interpol = (3.0 *
m_d[idx] * h + 2.0 *
m_c[idx]) * h +
m_b[idx];
428 interpol = 6.0 *
m_d[idx] * h + 2.0 *
m_c[idx];
431 interpol = 6.0 *
m_d[idx];
448 if (ignore_extrapolation ==
false)
460 for (
uint04 i = 0; i < n - 1; i++)
467 if ((-eps <= root[j]) && (root[j] <
m_x[i + 1] -
m_x[i]))
469 t_point_type new_root =
m_x[i] + root[j];
470 if (x.
size() > 0 && x.
last() + eps > new_root)
483 if (!ignore_extrapolation)
489 x.
add(
m_x[n - 1] + root[j]);
500 return 2.2204460492503131e-16;
533 , t_point_type b, t_point_type c
534 ,
int newton_iter = 0)
539 const t_point_type p = 0.5 * b / c;
540 const t_point_type q = a / c;
541 const t_point_type discr = p * p - q;
543 const t_point_type discr_err = (6.0 * (p * p) + 3.0 *
abs(q) +
abs(discr)) * eps;
546 if (
abs(discr) <= discr_err)
552 else if (discr < 0.0) {
558 for (
uint01 n = 0; n < t_point_type::NumberOfDimensions(); n++)
560 x[0][n] = -p[n] -
sqrt(discr[n]);
561 x[1][n] = -p[n] +
sqrt(discr[n]);
568 for (
int k = 0; k < newton_iter; k++)
570 t_point_type f = (c * x[i] + b) * x[i] + a;
571 t_point_type f1 = 2.0 * c * x[i] + b;
589 , t_point_type b, t_point_type c
590 , t_point_type d,
int newton_iter)
const
604 const t_point_type p = -(1.0 / 3.0) * b + (1.0 / 9.0) * (c * c);
605 const t_point_type r = 2.0 * (c * c) - 9.0 * b;
606 const t_point_type q = -0.5 * a - (1.0 / 54.0) * (c * r);
607 const t_point_type discr = p * p * p - q * q;
609 t_point_type p_err = eps * ((3.0 / 3.0) *
abs(b)
610 + (4.0 / 9.0) * (c * c)
612 t_point_type r_err = eps * (6.0 * (c * c)
615 t_point_type q_err = 0.5 *
abs(a) * eps
616 + (1.0 / 54.0) *
abs(c) * (r_err +
abs(r) * 3.0 * eps)
618 t_point_type discr_err = (p * p) * (3.0 * p_err
619 +
abs(p) * 2.0 * eps)
620 +
abs(q) * (2.0 * q_err
626 if (
abs(discr) <= discr_err)
642 else if (discr > Vertex < 3, fltp08>(0))
646 for (
uint01 n = 0; n < t_point_type::NumberOfDimensions(); n++)
648 fltp08 ac = (1.0 / 3.0) * acos(q[n] / (p[n] *
sqrt(p[n])));
650 z[0][n] = sq *
cos(ac);
651 z[1][n] = sq *
cos(ac - 2.0 * PI<fltp08>() / 3.0);
652 z[2][n] = sq *
cos(ac - 4.0 * PI<fltp08>() / 3.0);
655 else if (discr < 0.0)
659 for (
uint01 n = 0; n < t_point_type::NumberOfDimensions(); n++)
661 fltp08 sgnq = (q[n] >= 0 ? 1 : -1);
663 fltp08 C = sgnq * pow(basis, 1.0 / 3.0);
664 z[0][n] =
C + p[n] /
C;
670 z[i] -= (1.0 / 3.0) * c;
672 for (
int k = 0; k < newton_iter; k++)
674 t_point_type f = ((z[i] + c) * z[i] + b) * z[i] + a;
675 t_point_type f1 = (3.0 * z[i] + 2.0 * c) * z[i] + b;
685 lib_assert(z.
size() > 0,
"cubic should always have at least one root");
686 t_point_type xmin =
abs(z[0]);
690 if (xmin >
abs(z[i]))
721 for (
uint04 i = 0; i < n - 1; i++)
725 m_c[i] = (3.0 * (
m_y[i + 1] -
m_y[i]) / h - (2.0 *
m_b[i] +
m_b[i + 1])) / h;
727 m_d[i] = ((
m_b[i + 1] -
m_b[i]) / (3.0 * h) - 2.0 / 3.0 *
m_c[i]) / h;
#define lib_assert(expression, message)
Definition LibAssert.h:61
Band Matrix solver.
Definition BandMatrix.hpp:12
The equivelent of std::vector but with a bit more control. The basic array unit of the library.
Definition Buffer.hpp:56
void add(t_type &&object)
Adds object to the end of the buffer.
Definition Buffer.hpp:186
constexpr t_index_type size() const
Definition Buffer.hpp:823
decltype(auto) last()
Definition Buffer.hpp:588
decltype(auto) end()
Definition Buffer.hpp:507
void setSize(t_index_type new_size)
Definition Buffer.hpp:803
decltype(auto) begin()
Definition Buffer.hpp:402
void resize(t_index_type new_size)
Definition Buffer.hpp:812
A spline is a function used to interpolate or smooth data. Splines are a series of polynomials joined...
Definition Spline.hpp:14
Spline(const Buffer< t_point_type > &Y, SplineType type=SplineType::e_cspline, SplineBoundaryType left=SplineBoundaryType::e_second_deriv, fltp08 left_value=0.0, SplineBoundaryType right=SplineBoundaryType::e_second_deriv, fltp08 right_value=0.0)
Definition Spline.hpp:37
static fltp08 getEPS()
Definition Spline.hpp:498
SplineBoundaryType m_right
Definition Spline.hpp:27
fltp08 m_left_value
Definition Spline.hpp:28
Buffer< t_point_type > solveCubic(t_point_type a, t_point_type b, t_point_type c, t_point_type d, int newton_iter) const
Definition Spline.hpp:588
Buffer< t_point_type > m_c
Definition Spline.hpp:22
t_point_type deriv(uint04 order, fltp08 x) const
Definition Spline.hpp:379
fltp08 m_right_value
Definition Spline.hpp:29
void setCoeffsFromB()
Definition Spline.hpp:710
SplineType m_type
Definition Spline.hpp:25
t_point_type operator()(fltp08 x) const
Definition Spline.hpp:349
static Buffer< t_point_type > solveQuadratic(t_point_type a, t_point_type b, t_point_type c, int newton_iter=0)
Definition Spline.hpp:532
bool makeMonotonic()
Definition Spline.hpp:284
void setPoints(const Buffer< fltp08 > &x, const Buffer< t_point_type > &y, SplineType type)
Definition Spline.hpp:74
Spline(const Buffer< fltp08 > &X, const Buffer< t_point_type > &Y, SplineType type=SplineType::e_cspline, bool make_monotonic=false, SplineBoundaryType left=SplineBoundaryType::e_second_deriv, fltp08 left_value=0.0, SplineBoundaryType right=SplineBoundaryType::e_second_deriv, fltp08 right_value=0.0)
Definition Spline.hpp:55
SplineBoundaryType m_left
Definition Spline.hpp:26
Buffer< t_point_type > m_d
Definition Spline.hpp:23
void setBoundary(SplineBoundaryType left, fltp08 left_value, SplineBoundaryType right, fltp08 right_value)
Definition Spline.hpp:701
Spline()
Definition Spline.hpp:34
Buffer< t_point_type > m_y
Definition Spline.hpp:17
uint04 find_closest(fltp08 x) const
Definition Spline.hpp:343
Buffer< t_point_type > solve(t_point_type y, bool ignore_extrapolation) const
Definition Spline.hpp:441
bool m_made_monotonic
Definition Spline.hpp:30
Buffer< t_point_type > m_b
Definition Spline.hpp:21
static Buffer< t_point_type > solveLinear(t_point_type a, t_point_type b)
Definition Spline.hpp:504
t_point_type m_c0
Definition Spline.hpp:24
Buffer< fltp08 > m_x
Definition Spline.hpp:16
constexpr t_type getMax(const t_type &left, const t_type &right)
Finds the max of the given arguments using the > operator The only requirement is that t_type have > ...
Definition BaseFunctions.hpp:94
SplineType
Definition SplineEnums.h:7
uint8_t uint01
-Defines an alias representing a 1 byte, unsigned integer -Can represent exact integer values 0 throu...
Definition BaseValues.hpp:80
std::enable_if<!ObjectInfo< t_type >::Float, fltp08 >::type cos(const Angle< t_type > &angle)
Performs optimized cosine operation on the given angle using pre-computed lookup table for optimal sp...
Definition AngleFunctions.h:124
uint32_t uint04
-Defines an alias representing a 4 byte, unsigned integer -Can represent exact integer values 0 throu...
Definition BaseValues.hpp:96
t_type sqrt(const t_type &value)
Definition VectorFunctions.hpp:1225
constexpr t_to cast(const Angle< t_from > &value)
Definition Angle.h:375
constexpr Angle< t_angle_type > abs(const Angle< t_angle_type > &value)
Changes an input with a negative sign, to a positive sign.
Definition AngleFunctions.h:645
@ A
Definition BaseValues.hpp:168
@ Y
Definition BaseValues.hpp:169
@ X
Definition BaseValues.hpp:167
@ C
Definition BaseValues.hpp:172
double fltp08
Defines an alias representing an 8 byte floating-point number.
Definition BaseValues.hpp:149
SplineBoundaryType
Definition SplineEnums.h:15
constexpr t_type getMin(const t_type &left, const t_type &right)
Finds the minimum of the given arguments based on the < operator Author: Tyler Parke Date: 2017-11-05...
Definition BaseFunctions.hpp:56