24#ifndef FPCURVE_HPP_INCLUDED
25#define FPCURVE_HPP_INCLUDED
27#include "fitpack_config.h"
30#include "fxArrays.hpp"
33#include "fitpack_curve_c.h"
45static_assert(
sizeof(fitpack_curve_c) ==
sizeof(fitpack_fitter_c),
46 "C descriptor layout mismatch: fitpack_curve_c vs fitpack_fitter_c");
107 if (
this != &other) {
199 return static_cast<fpFitter&
>(*this);
202 return static_cast<const fpFitter&
>(*this);
212 virtual void new_points(std::vector<double>&
x, std::vector<double>&
y,
double*
w =
nullptr) {
213 int32_t n =
static_cast<int32_t
>(
x.size());
221 virtual int32_t
new_fit(std::vector<double>&
x, std::vector<double>&
y,
double*
w =
nullptr,
double*
smoothing =
nullptr, int32_t*
order =
nullptr) {
222 int32_t n =
static_cast<int32_t
>(
x.size());
227 virtual int32_t
fit(
double*
smoothing =
nullptr, int32_t*
order =
nullptr,
bool* keep_knots =
nullptr) {
239 virtual double eval(
double x, int32_t& ierr) {
243 virtual double eval(
double x)
const {
250 virtual std::vector<double>
eval(std::vector<double>&
x, int32_t& ierr) {
251 int32_t n =
static_cast<int32_t
>(
x.size());
252 std::vector<double> result(n);
253 int32_t n_result = 0;
254 fitpack_curve_c_curve_eval_many(
as<fitpack_curve_c>(), n,
x.data(), &ierr, result.data(), &n_result, n);
255 result.resize(n_result);
263 virtual std::vector<double>
eval(std::vector<double>&
x) {
264 int32_t n =
static_cast<int32_t
>(
x.size());
265 std::vector<double> result(n);
266 int32_t n_result = 0;
267 fitpack_curve_c_curve_eval_many_pure(
as<fitpack_curve_c>(), n,
x.data(), result.data(), &n_result, n);
268 result.resize(n_result);
280 virtual void fourier_coefficients(std::vector<double>& alpha, std::vector<double>& a, std::vector<double>& b, int32_t* ierr =
nullptr) {
281 int32_t n =
static_cast<int32_t
>(alpha.size());
282 fitpack_curve_c_fourier_coefficients(
as<fitpack_curve_c>(), n, alpha.data(), a.data(), b.data(), ierr);
289 virtual std::vector<double>
zeros(int32_t max_size, int32_t* ierr =
nullptr) {
290 std::vector<double> result(max_size);
291 int32_t n_result = 0;
293 result.resize(n_result);
298 virtual double dfdx(
double x, int32_t
order, int32_t* ierr =
nullptr) {
305 virtual std::vector<double>
dfdx(std::vector<double>&
x, int32_t
order, int32_t* ierr =
nullptr) {
306 int32_t n =
static_cast<int32_t
>(
x.size());
307 std::vector<double> result(n);
308 int32_t n_result = 0;
310 result.resize(n_result);
318 virtual std::vector<double>
dfdx_all(
double x, int32_t& ierr, int32_t n_result) {
319 std::vector<double> result(n_result);
320 fitpack_curve_c_curve_all_derivatives(
as<fitpack_curve_c>(),
x, &ierr, result.data(), n_result);
328 virtual std::vector<double>
dfdx_all(
double x, int32_t n_result) {
329 std::vector<double> result(n_result);
342 virtual void insert_knot(std::vector<double>&
x, int32_t* ierr =
nullptr) {
343 int32_t n =
static_cast<int32_t
>(
x.size());
355 void comm_pack(std::vector<double>& buffer)
const override {
356 int32_t n =
static_cast<int32_t
>(buffer.size());
365 int32_t n =
static_cast<int32_t
>(buffer.size());
370 double mse()
const override {
382 int32_t n =
static_cast<int32_t
>(buffer.size());
391 int32_t n =
static_cast<int32_t
>(buffer.size());
409 double* raw =
nullptr;
410 int64_t extents[1] = {0};
412 const int64_t total = extents[0];
413 if (raw ==
nullptr || total <= 0)
return {};
414 const double* first =
reinterpret_cast<const double*
>(raw);
415 return std::vector<double>(first, first + total);
431 fxArray<double>
x()
const {
432 double* raw =
nullptr;
433 int64_t extents[1] = {0};
436 for (
int k = 0; k < 1; ++k) {
438 bounds[2 * k + 1] =
static_cast<FX_SIZE
>(extents[k]);
440 array_c descr = array_c_null;
441 array_c_from_ptr(&descr,
"x",
static_cast<void*
>(raw),
442 getCFITypeFlag<double>(),
443 static_cast<FX_SIZE
>(
sizeof(
double)),
444 static_cast<FX_RANK
>(1), bounds);
445 return fxArray<double>(descr);
454 double* raw =
nullptr;
455 int64_t extents[1] = {0};
457 const int64_t total = extents[0];
458 if (raw ==
nullptr || total <= 0)
return {};
459 const double* first =
reinterpret_cast<const double*
>(raw);
460 return std::vector<double>(first, first + total);
476 fxArray<double>
y()
const {
477 double* raw =
nullptr;
478 int64_t extents[1] = {0};
481 for (
int k = 0; k < 1; ++k) {
483 bounds[2 * k + 1] =
static_cast<FX_SIZE
>(extents[k]);
485 array_c descr = array_c_null;
486 array_c_from_ptr(&descr,
"y",
static_cast<void*
>(raw),
487 getCFITypeFlag<double>(),
488 static_cast<FX_SIZE
>(
sizeof(
double)),
489 static_cast<FX_RANK
>(1), bounds);
490 return fxArray<double>(descr);
499 double* raw =
nullptr;
500 int64_t extents[1] = {0};
502 const int64_t total = extents[0];
503 if (raw ==
nullptr || total <= 0)
return {};
504 const double* first =
reinterpret_cast<const double*
>(raw);
505 return std::vector<double>(first, first + total);
521 fxArray<double>
sp()
const {
522 double* raw =
nullptr;
523 int64_t extents[1] = {0};
526 for (
int k = 0; k < 1; ++k) {
528 bounds[2 * k + 1] =
static_cast<FX_SIZE
>(extents[k]);
530 array_c descr = array_c_null;
531 array_c_from_ptr(&descr,
"sp",
static_cast<void*
>(raw),
532 getCFITypeFlag<double>(),
533 static_cast<FX_SIZE
>(
sizeof(
double)),
534 static_cast<FX_RANK
>(1), bounds);
535 return fxArray<double>(descr);
544 double* raw =
nullptr;
545 int64_t extents[1] = {0};
547 const int64_t total = extents[0];
548 if (raw ==
nullptr || total <= 0)
return {};
549 const double* first =
reinterpret_cast<const double*
>(raw);
550 return std::vector<double>(first, first + total);
566 fxArray<double>
w()
const {
567 double* raw =
nullptr;
568 int64_t extents[1] = {0};
571 for (
int k = 0; k < 1; ++k) {
573 bounds[2 * k + 1] =
static_cast<FX_SIZE
>(extents[k]);
575 array_c descr = array_c_null;
576 array_c_from_ptr(&descr,
"w",
static_cast<void*
>(raw),
577 getCFITypeFlag<double>(),
578 static_cast<FX_SIZE
>(
sizeof(
double)),
579 static_cast<FX_RANK
>(1), bounds);
580 return fxArray<double>(descr);
593 double* raw =
nullptr;
594 int64_t extents[2] = {0, 0};
596 const int64_t total = extents[0] * extents[1];
597 if (raw ==
nullptr || total <= 0)
return {};
598 const double* first =
reinterpret_cast<const double*
>(raw);
599 return std::vector<double>(first, first + total);
607 double* raw =
nullptr;
608 int64_t extents[2] = {0, 0};
610 return { extents[0], extents[1] };
627 double* raw =
nullptr;
628 int64_t extents[2] = {0, 0};
631 for (
int k = 0; k < 2; ++k) {
633 bounds[2 * k + 1] =
static_cast<FX_SIZE
>(extents[k]);
635 array_c descr = array_c_null;
636 array_c_from_ptr(&descr,
"wrk_fou",
static_cast<void*
>(raw),
637 getCFITypeFlag<double>(),
638 static_cast<FX_SIZE
>(
sizeof(
double)),
639 static_cast<FX_RANK
>(2), bounds);
640 return fxArray<double>(descr);
649 double* raw =
nullptr;
650 int64_t extents[1] = {0};
652 const int64_t total = extents[0];
653 if (raw ==
nullptr || total <= 0)
return {};
654 const double* first =
reinterpret_cast<const double*
>(raw);
655 return std::vector<double>(first, first + total);
671 fxArray<double>
t()
const {
672 double* raw =
nullptr;
673 int64_t extents[1] = {0};
676 for (
int k = 0; k < 1; ++k) {
678 bounds[2 * k + 1] =
static_cast<FX_SIZE
>(extents[k]);
680 array_c descr = array_c_null;
681 array_c_from_ptr(&descr,
"t",
static_cast<void*
>(raw),
682 getCFITypeFlag<double>(),
683 static_cast<FX_SIZE
>(
sizeof(
double)),
684 static_cast<FX_RANK
>(1), bounds);
685 return fxArray<double>(descr);
696 const int32_t&
m()
const {
731 const int32_t&
bc()
const {
754 FP_FLAG
new_fit(
const std::vector<FP_REAL>&
x,
const std::vector<FP_REAL>&
y,
757 std::vector<FP_REAL> xw(
x), yw(
y);
762 FP_FLAG
new_fit(
const std::vector<FP_REAL>&
x,
const std::vector<FP_REAL>&
y,
763 const std::vector<FP_REAL>&
w, FP_REAL
smoothing = 1000.0)
765 std::vector<FP_REAL> xw(
x), yw(
y), ww(
w);
780 FP_REAL
eval(FP_REAL
x, FP_FLAG* ierr)
782 FP_FLAG ierr0 = FITPACK_OK;
783 const FP_REAL
y =
eval(
x, ierr0);
784 if (ierr) *ierr = ierr0;
789 std::vector<FP_REAL>
eval(
const std::vector<FP_REAL>&
x, FP_FLAG* ierr)
791 std::vector<FP_REAL> xw(
x);
792 FP_FLAG ierr0 = FITPACK_OK;
793 std::vector<FP_REAL>
y =
eval(xw, ierr0);
794 if (ierr) *ierr = ierr0;
802 std::vector<fpPoint<2>>
eval(FP_REAL xmin, FP_REAL xmax, FP_SIZE npts, FP_FLAG* ierr =
nullptr)
804 std::vector<FP_REAL>
x(
static_cast<std::size_t
>(npts > 0 ? npts : 0));
807 const FP_REAL dx = (xmax - xmin) / (npts - 1);
808 for (FP_SIZE i = 0; i < npts; ++i) x[static_cast<std::size_t>(i)] = xmin + i * dx;
810 else if (npts == 1)
x[0] = xmin;
812 FP_FLAG ierr0 = FITPACK_OK;
813 std::vector<FP_REAL>
y =
eval(
x, ierr0);
814 if (ierr) *ierr = ierr0;
816 std::vector<fpPoint<2>> xy(
x.size());
817 for (std::size_t i = 0; i <
x.size() && i <
y.size(); ++i) xy[i] = {
x[i],
y[i]};
826 std::vector<FP_REAL>
ddx(FP_REAL
x, FP_FLAG* ierr =
nullptr)
828 FP_FLAG ierr0 = FITPACK_OK;
830 if (ierr) *ierr = ierr0;
840 FP_FLAG
fourier(
const std::vector<FP_REAL>& alpha, std::vector<FP_REAL>& A, std::vector<FP_REAL>& B)
842 std::vector<FP_REAL> aw(alpha);
843 A.resize(alpha.size());
844 B.resize(alpha.size());
845 FP_FLAG ierr = FITPACK_OK;
virtual void fourier_coefficients(std::vector< double > &alpha, std::vector< double > &a, std::vector< double > &b, int32_t *ierr=nullptr)
fourier_coefficients
Definition fpCurve.hpp:280
void comm_pack(std::vector< double > &buffer) const override
comm_pack
Definition fpCurve.hpp:355
virtual int32_t least_squares(double *smoothing=nullptr, bool *reset_knots=nullptr)
Definition fpCurve.hpp:235
virtual double integral(double from, double to)
Definition fpCurve.hpp:273
FP_FLAG new_fit(const std::vector< FP_REAL > &x, const std::vector< FP_REAL > &y, const std::vector< FP_REAL > &w, FP_REAL smoothing=1000.0)
Fit a new curve through (x, y) with per-point weights w.
Definition fpCurve.hpp:762
virtual std::vector< double > dfdx_all(double x, int32_t &ierr, int32_t n_result)
dfdx_all
Definition fpCurve.hpp:318
virtual void new_points(std::vector< double > &x, std::vector< double > &y, double *w=nullptr)
new_points
Definition fpCurve.hpp:212
const char * cpp_type_name() const override
Return the fully-qualified C++ class name for this class. Owned by the C++ layer — does not round-tri...
Definition fpCurve.hpp:165
virtual int32_t fit(double *smoothing=nullptr, int32_t *order=nullptr, bool *keep_knots=nullptr)
Definition fpCurve.hpp:227
int32_t & knots()
Definition fpCurve.hpp:735
std::vector< double > t_vector() const
Deep copy of component 't' as a std::vector.
Definition fpCurve.hpp:648
virtual double eval(double x) const
Definition fpCurve.hpp:243
double mse() const override
Definition fpCurve.hpp:370
~fpCurve() override
Destructor - deallocates if owned.
Definition fpCurve.hpp:72
fpCurve & operator=(const fpCurve &other)
Copy assignment - deep copy.
Definition fpCurve.hpp:87
fxArray< double > x() const
Zero-copy fxArray view of component 'x'.
Definition fpCurve.hpp:431
FP_FLAG fit(FP_REAL smoothing)
Refit the current points with a new smoothing.
Definition fpCurve.hpp:772
void core_comm_expand(std::vector< double > &buffer) override
core_comm_expand
Definition fpCurve.hpp:390
static fpCurve make_view()
Construct an empty (non-owning) wrapper, for use as a view target.
Definition fpCurve.hpp:191
virtual double eval(double x, int32_t &ierr)
Definition fpCurve.hpp:239
const int32_t & order() const
Definition fpCurve.hpp:703
int32_t & bc()
Definition fpCurve.hpp:728
double & xright()
Definition fpCurve.hpp:714
std::vector< FP_REAL > eval(const std::vector< FP_REAL > &x, FP_FLAG *ierr)
Evaluate the curve at every x, reporting the status through ierr.
Definition fpCurve.hpp:789
std::vector< fpPoint< 2 > > eval(FP_REAL xmin, FP_REAL xmax, FP_SIZE npts, FP_FLAG *ierr=nullptr)
Evaluate the curve at npts points evenly spaced over [xmin, xmax].
Definition fpCurve.hpp:802
FP_FLAG new_fit(const std::vector< FP_REAL > &x, const std::vector< FP_REAL > &y, FP_REAL smoothing=1000.0)
Fit a new curve through (x, y).
Definition fpCurve.hpp:754
int32_t & nest()
Definition fpCurve.hpp:721
void comm_expand(std::vector< double > &buffer) override
comm_expand
Definition fpCurve.hpp:364
bool is_pointer() const override
Check if this is a non-owning pointer.
Definition fpCurve.hpp:150
int32_t & order()
Definition fpCurve.hpp:700
virtual std::vector< double > zeros(int32_t max_size, int32_t *ierr=nullptr)
zeros
Definition fpCurve.hpp:289
FP_REAL ddx(FP_REAL x, FP_SIZE order, FP_FLAG *ierr=nullptr)
Derivative of the given order at x.
Definition fpCurve.hpp:823
const int32_t & m() const
Definition fpCurve.hpp:696
FP_SIZE degree() const
Spline degree k of the current fit.
Definition fpCurve.hpp:751
std::vector< double > w_vector() const
Deep copy of component 'w' as a std::vector.
Definition fpCurve.hpp:543
fpCurve(fpCurve &&other) noexcept
Move constructor - transfer ownership.
Definition fpCurve.hpp:98
int32_t core_comm_size() const override
Definition fpCurve.hpp:374
virtual std::vector< double > dfdx(std::vector< double > &x, int32_t order, int32_t *ierr=nullptr)
dfdx
Definition fpCurve.hpp:305
virtual std::vector< double > eval(std::vector< double > &x, int32_t &ierr)
eval
Definition fpCurve.hpp:250
fitpack_curve_c & c_handle()
Get underlying C wrapper (for interop)
Definition fpCurve.hpp:172
virtual void insert_knot(std::vector< double > &x, int32_t *ierr=nullptr)
insert_knot
Definition fpCurve.hpp:342
double & xleft()
Definition fpCurve.hpp:707
virtual int32_t interpolate(int32_t *order=nullptr, bool *reset_knots=nullptr)
Definition fpCurve.hpp:231
fxArray< double > t() const
Zero-copy fxArray view of component 't'.
Definition fpCurve.hpp:671
fpCurve(const fpCurve &other)
Copy constructor - deep copy.
Definition fpCurve.hpp:79
const int32_t & bc() const
Definition fpCurve.hpp:731
FP_FLAG fourier(const std::vector< FP_REAL > &alpha, std::vector< FP_REAL > &A, std::vector< FP_REAL > &B)
Fourier coefficients A, B of the curve at the given angular frequencies.
Definition fpCurve.hpp:840
fpCurve & operator=(fpCurve &&other) noexcept
Move assignment - transfer ownership.
Definition fpCurve.hpp:106
FP_FLAG get_bc() const
Definition fpCurve.hpp:836
std::vector< double > y_vector() const
Deep copy of component 'y' as a std::vector.
Definition fpCurve.hpp:453
FP_FLAG interpolate(FP_SIZE order)
Interpolating fit of the given spline order.
Definition fpCurve.hpp:777
int32_t & m()
Definition fpCurve.hpp:693
virtual int32_t new_fit(std::vector< double > &x, std::vector< double > &y, double *w=nullptr, double *smoothing=nullptr, int32_t *order=nullptr)
new_fit
Definition fpCurve.hpp:221
FP_FLAG fit(FP_SIZE order)
Refit the current points with a new spline order.
Definition fpCurve.hpp:770
int32_t comm_size() const override
Definition fpCurve.hpp:348
std::array< int64_t, 2 > wrk_fou_shape() const
Extents of component 'wrk_fou', leading dimension first.
Definition fpCurve.hpp:606
fpCurve(fitpack_curve_c &c_wrapper, bool move=false)
Construct from existing C wrapper (takes ownership if move=true)
Definition fpCurve.hpp:117
FP_FLAG fit(FP_REAL smoothing, FP_SIZE order)
Refit the current points with a new smoothing and spline order.
Definition fpCurve.hpp:774
const fitpack_curve_c & c_handle() const
Get underlying C wrapper (const, for interop)
Definition fpCurve.hpp:179
const int32_t & nest() const
Definition fpCurve.hpp:724
std::vector< double > sp_vector() const
Deep copy of component 'sp' as a std::vector.
Definition fpCurve.hpp:498
virtual double dfdx(double x, int32_t order, int32_t *ierr=nullptr)
Definition fpCurve.hpp:298
virtual std::vector< double > eval(std::vector< double > &x)
eval
Definition fpCurve.hpp:263
const char * c_type_name() const override
Return the C wrapper struct name for this class (e.g. "fitpack_curve_c").
Definition fpCurve.hpp:157
void core_comm_pack(std::vector< double > &buffer) const override
core_comm_pack
Definition fpCurve.hpp:381
const double & xleft() const
Definition fpCurve.hpp:710
const int32_t & knots() const
Definition fpCurve.hpp:738
const fpFitter & as_parent() const
Definition fpCurve.hpp:201
fpFitter & as_parent()
Upcast to parent type (reference, no copy)
Definition fpCurve.hpp:198
bool is_allocated() const override
Check if object is allocated.
Definition fpCurve.hpp:143
fxArray< double > y() const
Zero-copy fxArray view of component 'y'.
Definition fpCurve.hpp:476
std::vector< FP_REAL > ddx(FP_REAL x, FP_FLAG *ierr=nullptr)
All derivatives (orders 0..k) at x.
Definition fpCurve.hpp:826
virtual std::vector< double > dfdx_all(double x, int32_t n_result)
dfdx_all
Definition fpCurve.hpp:328
fxArray< double > wrk_fou() const
Zero-copy fxArray view of component 'wrk_fou'.
Definition fpCurve.hpp:626
fpCurve()
Default constructor - allocates new fitpack_curve.
Definition fpCurve.hpp:65
fpCurve(NoAlloc tag)
Definition fpCurve.hpp:851
fxArray< double > w() const
Zero-copy fxArray view of component 'w'.
Definition fpCurve.hpp:566
std::vector< double > x_vector() const
Deep copy of component 'x' as a std::vector.
Definition fpCurve.hpp:408
std::vector< double > wrk_fou_vector() const
Deep copy of component 'wrk_fou' as a std::vector.
Definition fpCurve.hpp:592
const double & xright() const
Definition fpCurve.hpp:717
fxArray< double > sp() const
Zero-copy fxArray view of component 'sp'.
Definition fpCurve.hpp:521
FP_REAL eval(FP_REAL x, FP_FLAG *ierr)
Evaluate the curve at x, reporting the status through ierr.
Definition fpCurve.hpp:780
void destroy_base() override
Definition fpCurve.hpp:396
void set_bc(FP_FLAG value)
Spline behaviour outside the support (one of the OUTSIDE_* flags).
Definition fpCurve.hpp:835
virtual void insert_knot(double x, int32_t *ierr=nullptr)
Definition fpCurve.hpp:335
fpCurve(fitpack_curve_c &c_wrapper, ViewTag)
Non-owning view ctor: bit-copy the C handle, mark is_pointer=true. Used by parent classes' polymorphi...
Definition fpCurve.hpp:131
double & smoothing()
Definition fpFitter.hpp:317
fpFitter(NoAlloc)
Protected constructor for derived classes (does not allocate)
Definition fpFitter.hpp:354
T * as()
Definition fpFitter.hpp:360
Tag type for derived class constructors (no allocation)
Definition fpFitter.hpp:349
Tag type for non-owning view constructors of polymorphic concrete subtypes. Declared on roots and abs...
Definition fpFitter.hpp:103