fitpack
Modern Fortran library for curve and surface fitting with splines
Loading...
Searching...
No Matches
fpConvexCurve.hpp
Go to the documentation of this file.
1/***************************************************************************************************
2! ____________________ ___ ________ __
3! / ____/ _/_ __/ __ \/ | / ____/ //_/
4! / /_ / / / / / /_/ / /| |/ / / ,<
5! / __/ _/ / / / / ____/ ___ / /___/ /| |
6! /_/ /___/ /_/ /_/ /_/ |_\____/_/ |_|
7!
8! A Curve Fitting Package
9!
10! fpConvexCurve.hpp (class fpConvexCurve)
11!> @brief Standalone C++ wrapper for fitpack_convex_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 FPCONVEXCURVE_HPP_INCLUDED
25#define FPCONVEXCURVE_HPP_INCLUDED
26
27#include "fitpack_config.h"
28
29#if HAVE_FXARRAY
30#include "fxArrays.hpp"
31#endif
32
33#include "fitpack_convex_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_convex_curve_c) == sizeof(fitpack_curve_c),
44 "C descriptor layout mismatch: fitpack_convex_curve_c vs fitpack_curve_c");
45
54class fpConvexCurve : public fpCurve {
55public:
56 // ===========================================================================================
57 // Constructors and Destructor
58 // ===========================================================================================
59
64 fitpack_convex_curve_c_allocate(as<fitpack_convex_curve_c>(), nullptr);
65 }
66
70 ~fpConvexCurve() override {
71 fitpack_convex_curve_c_destroy(as<fitpack_convex_curve_c>(), nullptr);
72 }
73
78 *as<fitpack_convex_curve_c>() = fitpack_convex_curve_c_null;
79 fitpack_convex_curve_c_copy(as<fitpack_convex_curve_c>(), other.as<fitpack_convex_curve_c>(), false, nullptr);
80 }
81
86 if (this != &other) {
87 fitpack_convex_curve_c_destroy(as<fitpack_convex_curve_c>(), nullptr);
88 fitpack_convex_curve_c_copy(as<fitpack_convex_curve_c>(), other.as<fitpack_convex_curve_c>(), false, nullptr);
89 }
90 return *this;
91 }
92
96 fpConvexCurve(fpConvexCurve&& other) noexcept : fpCurve(NoAlloc{}) {
97 *as<fitpack_convex_curve_c>() = fitpack_convex_curve_c_null;
98 fitpack_convex_curve_c_move_alloc(as<fitpack_convex_curve_c>(), other.as<fitpack_convex_curve_c>(), nullptr);
99 }
100
105 if (this != &other) {
106 fitpack_convex_curve_c_destroy(as<fitpack_convex_curve_c>(), nullptr);
107 fitpack_convex_curve_c_move_alloc(as<fitpack_convex_curve_c>(), other.as<fitpack_convex_curve_c>(), nullptr);
108 }
109 return *this;
110 }
111
115 explicit fpConvexCurve(fitpack_convex_curve_c& c_wrapper, bool move = false) : fpCurve(NoAlloc{}) {
116 if (move) {
117 fitpack_convex_curve_c_move_alloc(as<fitpack_convex_curve_c>(), &c_wrapper, nullptr);
118 } else {
119 *as<fitpack_convex_curve_c>() = fitpack_convex_curve_c_null;
120 fitpack_convex_curve_c_copy(as<fitpack_convex_curve_c>(), &c_wrapper, false, nullptr);
121 }
122 }
123
129 explicit fpConvexCurve(fitpack_convex_curve_c& c_wrapper, ViewTag) : fpCurve(NoAlloc{}) {
130 *as<fitpack_convex_curve_c>() = c_wrapper;
131 as<fitpack_convex_curve_c>()->is_pointer = true;
132 }
133
134 // ===========================================================================================
135 // Utility Methods
136 // ===========================================================================================
137
141 bool is_allocated() const override {
142 return as<fitpack_convex_curve_c>()->cptr != nullptr;
143 }
144
148 bool is_pointer() const override {
149 return as<fitpack_convex_curve_c>()->is_pointer;
150 }
151
155 const char* c_type_name() const override {
156 return fitpack_convex_curve_c_c_type_name(*as<fitpack_convex_curve_c>());
157 }
158
163 const char* cpp_type_name() const override {
164 return "fpConvexCurve";
165 }
166
170 fitpack_convex_curve_c& c_handle() {
172 }
173
177 const fitpack_convex_curve_c& c_handle() const {
179 }
180
190 return fpConvexCurve(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_convex_curve_c_new_points(as<fitpack_convex_curve_c>(), n, x.data(), y.data(), w);
213 }
214
215
216 int32_t fit(double* smoothing = nullptr, int32_t* order = nullptr, bool* keep_knots = nullptr) override {
217 return fitpack_convex_curve_c_fit(as<fitpack_convex_curve_c>(), smoothing, order, keep_knots);
218 }
219
220 int32_t least_squares(double* smoothing = nullptr, bool* reset_knots = nullptr) override {
221 return fitpack_convex_curve_c_least_squares(as<fitpack_convex_curve_c>(), smoothing, reset_knots);
222 }
223
227 virtual int32_t set_convexity(std::vector<double>& v) {
228 int32_t n = static_cast<int32_t>(v.size());
229 return fitpack_convex_curve_c_set_convexity(as<fitpack_convex_curve_c>(), n, v.data());
230 }
231
232
233 int32_t comm_size() const override {
234 return fitpack_convex_curve_c_comm_size(as<fitpack_convex_curve_c>());
235 }
236
240 void comm_pack(std::vector<double>& buffer) const override {
241 int32_t n = static_cast<int32_t>(buffer.size());
242 fitpack_convex_curve_c_comm_pack(as<fitpack_convex_curve_c>(), n, buffer.data());
243 }
244
245
249 void comm_expand(std::vector<double>& buffer) override {
250 int32_t n = static_cast<int32_t>(buffer.size());
251 fitpack_convex_curve_c_comm_expand(as<fitpack_convex_curve_c>(), n, buffer.data());
252 }
253
254
255 double mse() const override {
256 return fitpack_convex_curve_c_mse(as<fitpack_convex_curve_c>());
257 }
258
259 int32_t core_comm_size() const override {
260 return fitpack_convex_curve_c_core_comm_size(as<fitpack_convex_curve_c>());
261 }
262
266 void core_comm_pack(std::vector<double>& buffer) const override {
267 int32_t n = static_cast<int32_t>(buffer.size());
268 fitpack_convex_curve_c_core_comm_pack(as<fitpack_convex_curve_c>(), n, buffer.data());
269 }
270
271
275 void core_comm_expand(std::vector<double>& buffer) override {
276 int32_t n = static_cast<int32_t>(buffer.size());
277 fitpack_convex_curve_c_core_comm_expand(as<fitpack_convex_curve_c>(), n, buffer.data());
278 }
279
280
281 void destroy_base() override {
282 fitpack_convex_curve_c_destroy_base(as<fitpack_convex_curve_c>());
283 }
284
285 // ===========================================================================================
286 // Component Array Accessors
287 // ===========================================================================================
288
293 std::vector<double> v_vector() const {
294 double* raw = nullptr;
295 int64_t extents[1] = {0};
296 fitpack_convex_curve_c_getcomp_v(as<fitpack_convex_curve_c>(), &raw, extents);
297 const int64_t total = extents[0];
298 if (raw == nullptr || total <= 0) return {};
299 const double* first = reinterpret_cast<const double*>(raw);
300 return std::vector<double>(first, first + total);
301 }
302
303#if HAVE_FXARRAY
316 fxArray<double> v() const {
317 double* raw = nullptr;
318 int64_t extents[1] = {0};
319 fitpack_convex_curve_c_getcomp_v(as<fitpack_convex_curve_c>(), &raw, extents);
320 FX_SIZE bounds[2]; // (lower, upper) per dimension, Fortran lbound 1
321 for (int k = 0; k < 1; ++k) {
322 bounds[2 * k] = 1;
323 bounds[2 * k + 1] = static_cast<FX_SIZE>(extents[k]);
324 }
325 array_c descr = array_c_null;
326 array_c_from_ptr(&descr, "v", static_cast<void*>(raw),
327 getCFITypeFlag<double>(),
328 static_cast<FX_SIZE>(sizeof(double)),
329 static_cast<FX_RANK>(1), bounds);
330 return fxArray<double>(descr);
331 }
332#endif // HAVE_FXARRAY
333
338 std::vector<double> sx_vector() const {
339 double* raw = nullptr;
340 int64_t extents[1] = {0};
341 fitpack_convex_curve_c_getcomp_sx(as<fitpack_convex_curve_c>(), &raw, extents);
342 const int64_t total = extents[0];
343 if (raw == nullptr || total <= 0) return {};
344 const double* first = reinterpret_cast<const double*>(raw);
345 return std::vector<double>(first, first + total);
346 }
347
348#if HAVE_FXARRAY
361 fxArray<double> sx() const {
362 double* raw = nullptr;
363 int64_t extents[1] = {0};
364 fitpack_convex_curve_c_getcomp_sx(as<fitpack_convex_curve_c>(), &raw, extents);
365 FX_SIZE bounds[2]; // (lower, upper) per dimension, Fortran lbound 1
366 for (int k = 0; k < 1; ++k) {
367 bounds[2 * k] = 1;
368 bounds[2 * k + 1] = static_cast<FX_SIZE>(extents[k]);
369 }
370 array_c descr = array_c_null;
371 array_c_from_ptr(&descr, "sx", static_cast<void*>(raw),
372 getCFITypeFlag<double>(),
373 static_cast<FX_SIZE>(sizeof(double)),
374 static_cast<FX_RANK>(1), bounds);
375 return fxArray<double>(descr);
376 }
377#endif // HAVE_FXARRAY
378
379 // ===========================================================================================
380 // Scalar Property Accessors
381 // ===========================================================================================
382
383 int32_t& maxtr() {
384 return *fitpack_convex_curve_c_ref_maxtr(as<fitpack_convex_curve_c>());
385 }
386 const int32_t& maxtr() const {
387 return *fitpack_convex_curve_c_ref_maxtr(as<fitpack_convex_curve_c>());
388 }
389
390 int32_t& maxbin() {
391 return *fitpack_convex_curve_c_ref_maxbin(as<fitpack_convex_curve_c>());
392 }
393 const int32_t& maxbin() const {
394 return *fitpack_convex_curve_c_ref_maxbin(as<fitpack_convex_curve_c>());
395 }
396
397protected:
398 explicit fpConvexCurve(NoAlloc tag) : fpCurve(tag) {}
399
400};
401
402#endif /* FPCONVEXCURVE_HPP_INCLUDED */
fpConvexCurve(const fpConvexCurve &other)
Copy constructor - deep copy.
Definition fpConvexCurve.hpp:77
void destroy_base() override
Definition fpConvexCurve.hpp:281
void core_comm_pack(std::vector< double > &buffer) const override
core_comm_pack
Definition fpConvexCurve.hpp:266
void comm_expand(std::vector< double > &buffer) override
comm_expand
Definition fpConvexCurve.hpp:249
fpConvexCurve()
Default constructor - allocates new fitpack_convex_curve.
Definition fpConvexCurve.hpp:63
void core_comm_expand(std::vector< double > &buffer) override
core_comm_expand
Definition fpConvexCurve.hpp:275
fpConvexCurve(fitpack_convex_curve_c &c_wrapper, ViewTag)
Non-owning view ctor: bit-copy the C handle, mark is_pointer=true. Used by parent classes' polymorphi...
Definition fpConvexCurve.hpp:129
std::vector< double > sx_vector() const
Deep copy of component 'sx' as a std::vector.
Definition fpConvexCurve.hpp:338
const int32_t & maxtr() const
Definition fpConvexCurve.hpp:386
static fpConvexCurve make_view()
Construct an empty (non-owning) wrapper, for use as a view target.
Definition fpConvexCurve.hpp:189
const int32_t & maxbin() const
Definition fpConvexCurve.hpp:393
fpConvexCurve(NoAlloc tag)
Definition fpConvexCurve.hpp:398
void comm_pack(std::vector< double > &buffer) const override
comm_pack
Definition fpConvexCurve.hpp:240
fpConvexCurve(fitpack_convex_curve_c &c_wrapper, bool move=false)
Construct from existing C wrapper (takes ownership if move=true)
Definition fpConvexCurve.hpp:115
const char * c_type_name() const override
Return the C wrapper struct name for this class (e.g. "fitpack_convex_curve_c").
Definition fpConvexCurve.hpp:155
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 fpConvexCurve.hpp:163
virtual int32_t set_convexity(std::vector< double > &v)
set_convexity
Definition fpConvexCurve.hpp:227
fxArray< double > sx() const
Zero-copy fxArray view of component 'sx'.
Definition fpConvexCurve.hpp:361
fitpack_convex_curve_c & c_handle()
Get underlying C wrapper (for interop)
Definition fpConvexCurve.hpp:170
fxArray< double > v() const
Zero-copy fxArray view of component 'v'.
Definition fpConvexCurve.hpp:316
const fitpack_convex_curve_c & c_handle() const
Get underlying C wrapper (const, for interop)
Definition fpConvexCurve.hpp:177
int32_t core_comm_size() const override
Definition fpConvexCurve.hpp:259
int32_t fit(double *smoothing=nullptr, int32_t *order=nullptr, bool *keep_knots=nullptr) override
Definition fpConvexCurve.hpp:216
bool is_allocated() const override
Check if object is allocated.
Definition fpConvexCurve.hpp:141
int32_t & maxtr()
Definition fpConvexCurve.hpp:383
int32_t least_squares(double *smoothing=nullptr, bool *reset_knots=nullptr) override
Definition fpConvexCurve.hpp:220
void new_points(std::vector< double > &x, std::vector< double > &y, double *w=nullptr) override
new_points
Definition fpConvexCurve.hpp:210
fpConvexCurve(fpConvexCurve &&other) noexcept
Move constructor - transfer ownership.
Definition fpConvexCurve.hpp:96
fpConvexCurve & operator=(const fpConvexCurve &other)
Copy assignment - deep copy.
Definition fpConvexCurve.hpp:85
fpConvexCurve & operator=(fpConvexCurve &&other) noexcept
Move assignment - transfer ownership.
Definition fpConvexCurve.hpp:104
std::vector< double > v_vector() const
Deep copy of component 'v' as a std::vector.
Definition fpConvexCurve.hpp:293
int32_t & maxbin()
Definition fpConvexCurve.hpp:390
~fpConvexCurve() override
Destructor - deallocates if owned.
Definition fpConvexCurve.hpp:70
fpCurve & as_parent()
Upcast to parent type (reference, no copy)
Definition fpConvexCurve.hpp:196
double mse() const override
Definition fpConvexCurve.hpp:255
int32_t comm_size() const override
Definition fpConvexCurve.hpp:233
bool is_pointer() const override
Check if this is a non-owning pointer.
Definition fpConvexCurve.hpp:148
const fpCurve & as_parent() const
Definition fpConvexCurve.hpp:199
fxArray< double > x() const
Zero-copy fxArray view of component 'x'.
Definition fpCurve.hpp:431
int32_t & order()
Definition fpCurve.hpp:700
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
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