fitpack
Modern Fortran library for curve and surface fitting with splines
Loading...
Searching...
No Matches
fpPeriodicCurve.hpp
Go to the documentation of this file.
1/***************************************************************************************************
2! ____________________ ___ ________ __
3! / ____/ _/_ __/ __ \/ | / ____/ //_/
4! / /_ / / / / / /_/ / /| |/ / / ,<
5! / __/ _/ / / / / ____/ ___ / /___/ /| |
6! /_/ /___/ /_/ /_/ /_/ |_\____/_/ |_|
7!
8! A Curve Fitting Package
9!
10! fpPeriodicCurve.hpp (class fpPeriodicCurve)
11!> @brief Standalone C++ wrapper for fitpack_periodic_curve (no fortran-arrays dependency)
12!
13! @author Federico Perini
14! @date 2026-08-27
15!
16! References :
17! - C. De Boor, "On calculating with b-splines", J Approx Theory 6 (1972) 50-62
18! - M. G. Cox, "The numerical evaluation of b-splines", J Inst Maths Applics 10 (1972) 134-149
19! - P. Dierckx, "Curve and surface fitting with splines", Monographs on numerical analysis,
20! Oxford university press, 1993.
21!
22! **************************************************************************************************/
23
24#ifndef FPPERIODICCURVE_HPP_INCLUDED
25#define FPPERIODICCURVE_HPP_INCLUDED
26
27#include "fitpack_config.h"
28
29#if HAVE_FXARRAY
30#include "fxArrays.hpp"
31#endif
32
33#include "fitpack_periodic_curve_c.h"
34#include "fpCurve.hpp"
35#include <string>
36#include <vector>
37#include <cstdint>
38#include <memory>
39#include <stdexcept>
40#include <variant>
41#include <optional>
42
43static_assert(sizeof(fitpack_periodic_curve_c) == sizeof(fitpack_curve_c),
44 "C descriptor layout mismatch: fitpack_periodic_curve_c vs fitpack_curve_c");
45
54class fpPeriodicCurve : public fpCurve {
55public:
56 // ===========================================================================================
57 // Constructors and Destructor
58 // ===========================================================================================
59
64 fitpack_periodic_curve_c_allocate(as<fitpack_periodic_curve_c>(), nullptr);
65 }
66
70 ~fpPeriodicCurve() override {
71 fitpack_periodic_curve_c_destroy(as<fitpack_periodic_curve_c>(), nullptr);
72 }
73
78 *as<fitpack_periodic_curve_c>() = fitpack_periodic_curve_c_null;
79 fitpack_periodic_curve_c_copy(as<fitpack_periodic_curve_c>(), other.as<fitpack_periodic_curve_c>(), false, nullptr);
80 }
81
86 if (this != &other) {
87 fitpack_periodic_curve_c_destroy(as<fitpack_periodic_curve_c>(), nullptr);
88 fitpack_periodic_curve_c_copy(as<fitpack_periodic_curve_c>(), other.as<fitpack_periodic_curve_c>(), false, nullptr);
89 }
90 return *this;
91 }
92
97 *as<fitpack_periodic_curve_c>() = fitpack_periodic_curve_c_null;
98 fitpack_periodic_curve_c_move_alloc(as<fitpack_periodic_curve_c>(), other.as<fitpack_periodic_curve_c>(), nullptr);
99 }
100
105 if (this != &other) {
106 fitpack_periodic_curve_c_destroy(as<fitpack_periodic_curve_c>(), nullptr);
107 fitpack_periodic_curve_c_move_alloc(as<fitpack_periodic_curve_c>(), other.as<fitpack_periodic_curve_c>(), nullptr);
108 }
109 return *this;
110 }
111
115 explicit fpPeriodicCurve(fitpack_periodic_curve_c& c_wrapper, bool move = false) : fpCurve(NoAlloc{}) {
116 if (move) {
117 fitpack_periodic_curve_c_move_alloc(as<fitpack_periodic_curve_c>(), &c_wrapper, nullptr);
118 } else {
119 *as<fitpack_periodic_curve_c>() = fitpack_periodic_curve_c_null;
120 fitpack_periodic_curve_c_copy(as<fitpack_periodic_curve_c>(), &c_wrapper, false, nullptr);
121 }
122 }
123
129 explicit fpPeriodicCurve(fitpack_periodic_curve_c& c_wrapper, ViewTag) : fpCurve(NoAlloc{}) {
130 *as<fitpack_periodic_curve_c>() = c_wrapper;
131 as<fitpack_periodic_curve_c>()->is_pointer = true;
132 }
133
134 // ===========================================================================================
135 // Utility Methods
136 // ===========================================================================================
137
141 bool is_allocated() const override {
142 return as<fitpack_periodic_curve_c>()->cptr != nullptr;
143 }
144
148 bool is_pointer() const override {
149 return as<fitpack_periodic_curve_c>()->is_pointer;
150 }
151
155 const char* c_type_name() const override {
156 return fitpack_periodic_curve_c_c_type_name(*as<fitpack_periodic_curve_c>());
157 }
158
163 const char* cpp_type_name() const override {
164 return "fpPeriodicCurve";
165 }
166
170 fitpack_periodic_curve_c& c_handle() {
172 }
173
177 const fitpack_periodic_curve_c& c_handle() const {
179 }
180
190 return fpPeriodicCurve(NoAlloc{});
191 }
192
197 return static_cast<fpCurve&>(*this);
198 }
199 const fpCurve& as_parent() const {
200 return static_cast<const fpCurve&>(*this);
201 }
202
203 // ===========================================================================================
204 // Method Wrappers (standalone — no fxArray dependency)
205 // ===========================================================================================
206
210 void new_points(std::vector<double>& x, std::vector<double>& y, double* w = nullptr) override {
211 int32_t n = static_cast<int32_t>(x.size());
212 fitpack_periodic_curve_c_new_points(as<fitpack_periodic_curve_c>(), n, x.data(), y.data(), w);
213 }
214
215
219 int32_t new_fit(std::vector<double>& x, std::vector<double>& y, double* w = nullptr, double* smoothing = nullptr, int32_t* order = nullptr) override {
220 int32_t n = static_cast<int32_t>(x.size());
221 return fitpack_periodic_curve_c_new_fit(as<fitpack_periodic_curve_c>(), n, x.data(), y.data(), w, smoothing, order);
222 }
223
224
225 int32_t fit(double* smoothing = nullptr, int32_t* order = nullptr, bool* keep_knots = nullptr) override {
226 return fitpack_periodic_curve_c_fit(as<fitpack_periodic_curve_c>(), smoothing, order, keep_knots);
227 }
228
229 int32_t interpolate(int32_t* order = nullptr, bool* reset_knots = nullptr) override {
230 return fitpack_periodic_curve_c_interpolate(as<fitpack_periodic_curve_c>(), order, reset_knots);
231 }
232
233 int32_t least_squares(double* smoothing = nullptr, bool* reset_knots = nullptr) override {
234 return fitpack_periodic_curve_c_least_squares(as<fitpack_periodic_curve_c>(), smoothing, reset_knots);
235 }
236
237 double eval(double x, int32_t& ierr) override {
238 return fitpack_periodic_curve_c_curve_eval_one(as<fitpack_periodic_curve_c>(), x, &ierr);
239 }
240
241 double eval(double x) const override {
242 return fitpack_periodic_curve_c_curve_eval_one_noerr(as<fitpack_periodic_curve_c>(), x);
243 }
244
248 std::vector<double> eval(std::vector<double>& x, int32_t& ierr) override {
249 int32_t n = static_cast<int32_t>(x.size());
250 std::vector<double> result(n);
251 int32_t n_result = 0;
252 fitpack_periodic_curve_c_curve_eval_many(as<fitpack_periodic_curve_c>(), n, x.data(), &ierr, result.data(), &n_result, n);
253 result.resize(n_result);
254 return result;
255 }
256
257
261 std::vector<double> eval(std::vector<double>& x) override {
262 int32_t n = static_cast<int32_t>(x.size());
263 std::vector<double> result(n);
264 int32_t n_result = 0;
265 fitpack_periodic_curve_c_curve_eval_many_pure(as<fitpack_periodic_curve_c>(), n, x.data(), result.data(), &n_result, n);
266 result.resize(n_result);
267 return result;
268 }
269
270
271 double integral(double from, double to) override {
272 return fitpack_periodic_curve_c_integral(as<fitpack_periodic_curve_c>(), from, to);
273 }
274
278 void fourier_coefficients(std::vector<double>& alpha, std::vector<double>& a, std::vector<double>& b, int32_t* ierr = nullptr) override {
279 int32_t n = static_cast<int32_t>(alpha.size());
280 fitpack_periodic_curve_c_fourier_coefficients(as<fitpack_periodic_curve_c>(), n, alpha.data(), a.data(), b.data(), ierr);
281 }
282
283
287 std::vector<double> zeros(int32_t max_size, int32_t* ierr = nullptr) override {
288 std::vector<double> result(max_size);
289 int32_t n_result = 0;
290 fitpack_periodic_curve_c_zeros(as<fitpack_periodic_curve_c>(), ierr, result.data(), &n_result, max_size);
291 result.resize(n_result);
292 return result;
293 }
294
295
296 double dfdx(double x, int32_t order, int32_t* ierr = nullptr) override {
297 return fitpack_periodic_curve_c_curve_derivative(as<fitpack_periodic_curve_c>(), x, order, ierr);
298 }
299
303 std::vector<double> dfdx(std::vector<double>& x, int32_t order, int32_t* ierr = nullptr) override {
304 int32_t n = static_cast<int32_t>(x.size());
305 std::vector<double> result(n);
306 int32_t n_result = 0;
307 fitpack_periodic_curve_c_curve_derivatives(as<fitpack_periodic_curve_c>(), n, x.data(), order, ierr, result.data(), &n_result, n);
308 result.resize(n_result);
309 return result;
310 }
311
312
316 std::vector<double> dfdx_all(double x, int32_t& ierr, int32_t n_result) override {
317 std::vector<double> result(n_result);
318 fitpack_periodic_curve_c_curve_all_derivatives(as<fitpack_periodic_curve_c>(), x, &ierr, result.data(), n_result);
319 return result;
320 }
321
322
326 std::vector<double> dfdx_all(double x, int32_t n_result) override {
327 std::vector<double> result(n_result);
328 fitpack_periodic_curve_c_curve_all_derivatives_pure(as<fitpack_periodic_curve_c>(), x, result.data(), n_result);
329 return result;
330 }
331
332
333 void insert_knot(double x, int32_t* ierr = nullptr) override {
334 fitpack_periodic_curve_c_curve_insert_knot_one(as<fitpack_periodic_curve_c>(), x, ierr);
335 }
336
340 void insert_knot(std::vector<double>& x, int32_t* ierr = nullptr) override {
341 int32_t n = static_cast<int32_t>(x.size());
342 fitpack_periodic_curve_c_curve_insert_knot_many(as<fitpack_periodic_curve_c>(), n, x.data(), ierr);
343 }
344
345
346 int32_t comm_size() const override {
347 return fitpack_periodic_curve_c_comm_size(as<fitpack_periodic_curve_c>());
348 }
349
353 void comm_pack(std::vector<double>& buffer) const override {
354 int32_t n = static_cast<int32_t>(buffer.size());
355 fitpack_periodic_curve_c_comm_pack(as<fitpack_periodic_curve_c>(), n, buffer.data());
356 }
357
358
362 void comm_expand(std::vector<double>& buffer) override {
363 int32_t n = static_cast<int32_t>(buffer.size());
364 fitpack_periodic_curve_c_comm_expand(as<fitpack_periodic_curve_c>(), n, buffer.data());
365 }
366
367
368 double mse() const override {
369 return fitpack_periodic_curve_c_mse(as<fitpack_periodic_curve_c>());
370 }
371
372 int32_t core_comm_size() const override {
373 return fitpack_periodic_curve_c_core_comm_size(as<fitpack_periodic_curve_c>());
374 }
375
379 void core_comm_pack(std::vector<double>& buffer) const override {
380 int32_t n = static_cast<int32_t>(buffer.size());
381 fitpack_periodic_curve_c_core_comm_pack(as<fitpack_periodic_curve_c>(), n, buffer.data());
382 }
383
384
388 void core_comm_expand(std::vector<double>& buffer) override {
389 int32_t n = static_cast<int32_t>(buffer.size());
390 fitpack_periodic_curve_c_core_comm_expand(as<fitpack_periodic_curve_c>(), n, buffer.data());
391 }
392
393
394 void destroy_base() override {
395 fitpack_periodic_curve_c_destroy_base(as<fitpack_periodic_curve_c>());
396 }
397
398 // ===========================================================================================
399 // extra_methods/fpCurveInherit.hpp (hand-maintained)
400 //
401 // This class overrides the raw new_fit / fit / interpolate / eval, which hides the
402 // ergonomic overloads spliced into fpCurve. Re-expose them; the overrides above still win
403 // for their own signatures, and every ergonomic overload dispatches back through them.
404 // ===========================================================================================
405
406 using fpCurve::new_fit;
407 using fpCurve::fit;
409 using fpCurve::eval;
410
411protected:
412 explicit fpPeriodicCurve(NoAlloc tag) : fpCurve(tag) {}
413
414};
415
416#endif /* FPPERIODICCURVE_HPP_INCLUDED */
virtual int32_t fit(double *smoothing=nullptr, int32_t *order=nullptr, bool *keep_knots=nullptr)
Definition fpCurve.hpp:227
fxArray< double > x() const
Zero-copy fxArray view of component 'x'.
Definition fpCurve.hpp:431
virtual double eval(double x, int32_t &ierr)
Definition fpCurve.hpp:239
int32_t & order()
Definition fpCurve.hpp:700
virtual int32_t interpolate(int32_t *order=nullptr, bool *reset_knots=nullptr)
Definition fpCurve.hpp:231
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
fxArray< double > y() const
Zero-copy fxArray view of component 'y'.
Definition fpCurve.hpp:476
fpCurve()
Default constructor - allocates new fitpack_curve.
Definition fpCurve.hpp:65
fxArray< double > w() const
Zero-copy fxArray view of component 'w'.
Definition fpCurve.hpp:566
double & smoothing()
Definition fpFitter.hpp:317
T * as()
Definition fpFitter.hpp:360
std::vector< double > eval(std::vector< double > &x) override
eval
Definition fpPeriodicCurve.hpp:261
void new_points(std::vector< double > &x, std::vector< double > &y, double *w=nullptr) override
new_points
Definition fpPeriodicCurve.hpp:210
double eval(double x, int32_t &ierr) override
Definition fpPeriodicCurve.hpp:237
int32_t comm_size() const override
Definition fpPeriodicCurve.hpp:346
std::vector< double > dfdx_all(double x, int32_t &ierr, int32_t n_result) override
dfdx_all
Definition fpPeriodicCurve.hpp:316
void comm_expand(std::vector< double > &buffer) override
comm_expand
Definition fpPeriodicCurve.hpp:362
fpPeriodicCurve(fitpack_periodic_curve_c &c_wrapper, ViewTag)
Non-owning view ctor: bit-copy the C handle, mark is_pointer=true. Used by parent classes' polymorphi...
Definition fpPeriodicCurve.hpp:129
fpPeriodicCurve(const fpPeriodicCurve &other)
Copy constructor - deep copy.
Definition fpPeriodicCurve.hpp:77
fpPeriodicCurve(NoAlloc tag)
Definition fpPeriodicCurve.hpp:412
int32_t interpolate(int32_t *order=nullptr, bool *reset_knots=nullptr) override
Definition fpPeriodicCurve.hpp:229
void comm_pack(std::vector< double > &buffer) const override
comm_pack
Definition fpPeriodicCurve.hpp:353
void insert_knot(double x, int32_t *ierr=nullptr) override
Definition fpPeriodicCurve.hpp:333
int32_t least_squares(double *smoothing=nullptr, bool *reset_knots=nullptr) override
Definition fpPeriodicCurve.hpp:233
fpCurve & as_parent()
Upcast to parent type (reference, no copy)
Definition fpPeriodicCurve.hpp:196
fpPeriodicCurve & operator=(fpPeriodicCurve &&other) noexcept
Move assignment - transfer ownership.
Definition fpPeriodicCurve.hpp:104
bool is_allocated() const override
Check if object is allocated.
Definition fpPeriodicCurve.hpp:141
static fpPeriodicCurve make_view()
Construct an empty (non-owning) wrapper, for use as a view target.
Definition fpPeriodicCurve.hpp:189
const char * c_type_name() const override
Return the C wrapper struct name for this class (e.g. "fitpack_periodic_curve_c").
Definition fpPeriodicCurve.hpp:155
double dfdx(double x, int32_t order, int32_t *ierr=nullptr) override
Definition fpPeriodicCurve.hpp:296
~fpPeriodicCurve() override
Destructor - deallocates if owned.
Definition fpPeriodicCurve.hpp:70
const fitpack_periodic_curve_c & c_handle() const
Get underlying C wrapper (const, for interop)
Definition fpPeriodicCurve.hpp:177
bool is_pointer() const override
Check if this is a non-owning pointer.
Definition fpPeriodicCurve.hpp:148
double mse() const override
Definition fpPeriodicCurve.hpp:368
std::vector< double > zeros(int32_t max_size, int32_t *ierr=nullptr) override
zeros
Definition fpPeriodicCurve.hpp:287
int32_t new_fit(std::vector< double > &x, std::vector< double > &y, double *w=nullptr, double *smoothing=nullptr, int32_t *order=nullptr) override
new_fit
Definition fpPeriodicCurve.hpp:219
void fourier_coefficients(std::vector< double > &alpha, std::vector< double > &a, std::vector< double > &b, int32_t *ierr=nullptr) override
fourier_coefficients
Definition fpPeriodicCurve.hpp:278
fpPeriodicCurve(fpPeriodicCurve &&other) noexcept
Move constructor - transfer ownership.
Definition fpPeriodicCurve.hpp:96
std::vector< double > dfdx(std::vector< double > &x, int32_t order, int32_t *ierr=nullptr) override
dfdx
Definition fpPeriodicCurve.hpp:303
std::vector< double > dfdx_all(double x, int32_t n_result) override
dfdx_all
Definition fpPeriodicCurve.hpp:326
void core_comm_pack(std::vector< double > &buffer) const override
core_comm_pack
Definition fpPeriodicCurve.hpp:379
void insert_knot(std::vector< double > &x, int32_t *ierr=nullptr) override
insert_knot
Definition fpPeriodicCurve.hpp:340
double integral(double from, double to) override
Definition fpPeriodicCurve.hpp:271
void destroy_base() override
Definition fpPeriodicCurve.hpp:394
std::vector< double > eval(std::vector< double > &x, int32_t &ierr) override
eval
Definition fpPeriodicCurve.hpp:248
fpPeriodicCurve(fitpack_periodic_curve_c &c_wrapper, bool move=false)
Construct from existing C wrapper (takes ownership if move=true)
Definition fpPeriodicCurve.hpp:115
const fpCurve & as_parent() const
Definition fpPeriodicCurve.hpp:199
int32_t core_comm_size() const override
Definition fpPeriodicCurve.hpp:372
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 fpPeriodicCurve.hpp:163
fpPeriodicCurve()
Default constructor - allocates new fitpack_periodic_curve.
Definition fpPeriodicCurve.hpp:63
fitpack_periodic_curve_c & c_handle()
Get underlying C wrapper (for interop)
Definition fpPeriodicCurve.hpp:170
void core_comm_expand(std::vector< double > &buffer) override
core_comm_expand
Definition fpPeriodicCurve.hpp:388
double eval(double x) const override
Definition fpPeriodicCurve.hpp:241
fpPeriodicCurve & operator=(const fpPeriodicCurve &other)
Copy assignment - deep copy.
Definition fpPeriodicCurve.hpp:85
int32_t fit(double *smoothing=nullptr, int32_t *order=nullptr, bool *keep_knots=nullptr) override
Definition fpPeriodicCurve.hpp:225
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