fitpack
Modern Fortran library for curve and surface fitting with splines
Loading...
Searching...
No Matches
fpParametricSurface.hpp
Go to the documentation of this file.
1/***************************************************************************************************
2! ____________________ ___ ________ __
3! / ____/ _/_ __/ __ \/ | / ____/ //_/
4! / /_ / / / / / /_/ / /| |/ / / ,<
5! / __/ _/ / / / / ____/ ___ / /___/ /| |
6! /_/ /___/ /_/ /_/ /_/ |_\____/_/ |_|
7!
8! A Curve Fitting Package
9!
10! fpParametricSurface.hpp (class fpParametricSurface)
11!> @brief Standalone C++ wrapper for fitpack_parametric_surface (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 FPPARAMETRICSURFACE_HPP_INCLUDED
25#define FPPARAMETRICSURFACE_HPP_INCLUDED
26
27#include "fitpack_config.h"
28
29#if HAVE_FXARRAY
30#include "fxArrays.hpp"
31#endif
32
33#include "fitpack_parametric_surface_c.h"
34#include "fpFitter.hpp"
35#include <string>
36#include <vector>
37#include <cstdint>
38#include <memory>
39#include <stdexcept>
40#include <variant>
41#include <optional>
42#include <array>
43
44static_assert(sizeof(fitpack_parametric_surface_c) == sizeof(fitpack_fitter_c),
45 "C descriptor layout mismatch: fitpack_parametric_surface_c vs fitpack_fitter_c");
46
56public:
57 // ===========================================================================================
58 // Constructors and Destructor
59 // ===========================================================================================
60
65 fitpack_parametric_surface_c_allocate(as<fitpack_parametric_surface_c>(), nullptr);
66 }
67
72 fitpack_parametric_surface_c_destroy(as<fitpack_parametric_surface_c>(), nullptr);
73 }
74
79 *as<fitpack_parametric_surface_c>() = fitpack_parametric_surface_c_null;
80 fitpack_parametric_surface_c_copy(as<fitpack_parametric_surface_c>(), other.as<fitpack_parametric_surface_c>(), false, nullptr);
81 }
82
87 if (this != &other) {
88 fitpack_parametric_surface_c_destroy(as<fitpack_parametric_surface_c>(), nullptr);
89 fitpack_parametric_surface_c_copy(as<fitpack_parametric_surface_c>(), other.as<fitpack_parametric_surface_c>(), false, nullptr);
90 }
91 return *this;
92 }
93
98 *as<fitpack_parametric_surface_c>() = fitpack_parametric_surface_c_null;
99 fitpack_parametric_surface_c_move_alloc(as<fitpack_parametric_surface_c>(), other.as<fitpack_parametric_surface_c>(), nullptr);
100 }
101
106 if (this != &other) {
107 fitpack_parametric_surface_c_destroy(as<fitpack_parametric_surface_c>(), nullptr);
108 fitpack_parametric_surface_c_move_alloc(as<fitpack_parametric_surface_c>(), other.as<fitpack_parametric_surface_c>(), nullptr);
109 }
110 return *this;
111 }
112
116 explicit fpParametricSurface(fitpack_parametric_surface_c& c_wrapper, bool move = false) : fpFitter(NoAlloc{}) {
117 if (move) {
118 fitpack_parametric_surface_c_move_alloc(as<fitpack_parametric_surface_c>(), &c_wrapper, nullptr);
119 } else {
120 *as<fitpack_parametric_surface_c>() = fitpack_parametric_surface_c_null;
121 fitpack_parametric_surface_c_copy(as<fitpack_parametric_surface_c>(), &c_wrapper, false, nullptr);
122 }
123 }
124
130 explicit fpParametricSurface(fitpack_parametric_surface_c& c_wrapper, ViewTag) : fpFitter(NoAlloc{}) {
132 as<fitpack_parametric_surface_c>()->is_pointer = true;
133 }
134
135 // ===========================================================================================
136 // Utility Methods
137 // ===========================================================================================
138
142 bool is_allocated() const override {
143 return as<fitpack_parametric_surface_c>()->cptr != nullptr;
144 }
145
149 bool is_pointer() const override {
150 return as<fitpack_parametric_surface_c>()->is_pointer;
151 }
152
156 const char* c_type_name() const override {
157 return fitpack_parametric_surface_c_c_type_name(*as<fitpack_parametric_surface_c>());
158 }
159
164 const char* cpp_type_name() const override {
165 return "fpParametricSurface";
166 }
167
171 fitpack_parametric_surface_c& c_handle() {
173 }
174
178 const fitpack_parametric_surface_c& c_handle() const {
180 }
181
193
198 return static_cast<fpFitter&>(*this);
199 }
200 const fpFitter& as_parent() const {
201 return static_cast<const fpFitter&>(*this);
202 }
203
204 // ===========================================================================================
205 // Method Wrappers (standalone — no fxArray dependency)
206 // ===========================================================================================
207
211 virtual int32_t fit(int32_t n, double* smoothing = nullptr, bool* periodic = nullptr, bool* keep_knots = nullptr) {
212 return fitpack_parametric_surface_c_fit(as<fitpack_parametric_surface_c>(), smoothing, n, periodic, keep_knots);
213 }
214
215
216 virtual int32_t interpolate(bool* reset_knots = nullptr) {
217 return fitpack_parametric_surface_c_interpolate(as<fitpack_parametric_surface_c>(), reset_knots);
218 }
219
223 virtual int32_t least_squares(int32_t n, double* u_knots = nullptr, double* v_knots = nullptr, double* smoothing = nullptr, bool* reset_knots = nullptr) {
224 return fitpack_parametric_surface_c_least_squares(as<fitpack_parametric_surface_c>(), n, u_knots, v_knots, smoothing, reset_knots);
225 }
226
227
231 virtual std::vector<double> eval(double u, double v, int32_t n_result, int32_t* ierr = nullptr) {
232 std::vector<double> result(n_result);
233 fitpack_parametric_surface_c_surf_eval_one(as<fitpack_parametric_surface_c>(), u, v, ierr, result.data(), n_result);
234 return result;
235 }
236
237
241 virtual std::vector<double> eval(std::vector<double>& u, std::vector<double>& v, int32_t n_result, int32_t* ierr = nullptr) {
242 int32_t n = static_cast<int32_t>(u.size());
243 std::vector<double> result(n_result);
244 fitpack_parametric_surface_c_surf_eval_grid(as<fitpack_parametric_surface_c>(), n, u.data(), v.data(), ierr, result.data(), n_result);
245 return result;
246 }
247
248
249 int32_t comm_size() const override {
250 return fitpack_parametric_surface_c_comm_size(as<fitpack_parametric_surface_c>());
251 }
252
256 void comm_pack(std::vector<double>& buffer) const override {
257 int32_t n = static_cast<int32_t>(buffer.size());
258 fitpack_parametric_surface_c_comm_pack(as<fitpack_parametric_surface_c>(), n, buffer.data());
259 }
260
261
265 void comm_expand(std::vector<double>& buffer) override {
266 int32_t n = static_cast<int32_t>(buffer.size());
267 fitpack_parametric_surface_c_comm_expand(as<fitpack_parametric_surface_c>(), n, buffer.data());
268 }
269
270
271 double mse() const override {
272 return fitpack_parametric_surface_c_mse(as<fitpack_parametric_surface_c>());
273 }
274
275 int32_t core_comm_size() const override {
276 return fitpack_parametric_surface_c_core_comm_size(as<fitpack_parametric_surface_c>());
277 }
278
282 void core_comm_pack(std::vector<double>& buffer) const override {
283 int32_t n = static_cast<int32_t>(buffer.size());
284 fitpack_parametric_surface_c_core_comm_pack(as<fitpack_parametric_surface_c>(), n, buffer.data());
285 }
286
287
291 void core_comm_expand(std::vector<double>& buffer) override {
292 int32_t n = static_cast<int32_t>(buffer.size());
293 fitpack_parametric_surface_c_core_comm_expand(as<fitpack_parametric_surface_c>(), n, buffer.data());
294 }
295
296
297 void destroy_base() override {
298 fitpack_parametric_surface_c_destroy_base(as<fitpack_parametric_surface_c>());
299 }
300
301 // ===========================================================================================
302 // Component Array Accessors
303 // ===========================================================================================
304
309 std::vector<double> u_vector() const {
310 double* raw = nullptr;
311 int64_t extents[1] = {0};
312 fitpack_parametric_surface_c_getcomp_u(as<fitpack_parametric_surface_c>(), &raw, extents);
313 const int64_t total = extents[0];
314 if (raw == nullptr || total <= 0) return {};
315 const double* first = reinterpret_cast<const double*>(raw);
316 return std::vector<double>(first, first + total);
317 }
318
319#if HAVE_FXARRAY
332 fxArray<double> u() const {
333 double* raw = nullptr;
334 int64_t extents[1] = {0};
335 fitpack_parametric_surface_c_getcomp_u(as<fitpack_parametric_surface_c>(), &raw, extents);
336 FX_SIZE bounds[2]; // (lower, upper) per dimension, Fortran lbound 1
337 for (int k = 0; k < 1; ++k) {
338 bounds[2 * k] = 1;
339 bounds[2 * k + 1] = static_cast<FX_SIZE>(extents[k]);
340 }
341 array_c descr = array_c_null;
342 array_c_from_ptr(&descr, "u", static_cast<void*>(raw),
343 getCFITypeFlag<double>(),
344 static_cast<FX_SIZE>(sizeof(double)),
345 static_cast<FX_RANK>(1), bounds);
346 return fxArray<double>(descr);
347 }
348#endif // HAVE_FXARRAY
349
354 std::vector<double> v_vector() const {
355 double* raw = nullptr;
356 int64_t extents[1] = {0};
357 fitpack_parametric_surface_c_getcomp_v(as<fitpack_parametric_surface_c>(), &raw, extents);
358 const int64_t total = extents[0];
359 if (raw == nullptr || total <= 0) return {};
360 const double* first = reinterpret_cast<const double*>(raw);
361 return std::vector<double>(first, first + total);
362 }
363
364#if HAVE_FXARRAY
377 fxArray<double> v() const {
378 double* raw = nullptr;
379 int64_t extents[1] = {0};
380 fitpack_parametric_surface_c_getcomp_v(as<fitpack_parametric_surface_c>(), &raw, extents);
381 FX_SIZE bounds[2]; // (lower, upper) per dimension, Fortran lbound 1
382 for (int k = 0; k < 1; ++k) {
383 bounds[2 * k] = 1;
384 bounds[2 * k + 1] = static_cast<FX_SIZE>(extents[k]);
385 }
386 array_c descr = array_c_null;
387 array_c_from_ptr(&descr, "v", static_cast<void*>(raw),
388 getCFITypeFlag<double>(),
389 static_cast<FX_SIZE>(sizeof(double)),
390 static_cast<FX_RANK>(1), bounds);
391 return fxArray<double>(descr);
392 }
393#endif // HAVE_FXARRAY
394
403 std::vector<double> z_vector() const {
404 double* raw = nullptr;
405 int64_t extents[3] = {0, 0, 0};
406 fitpack_parametric_surface_c_getcomp_z(as<fitpack_parametric_surface_c>(), &raw, extents);
407 const int64_t total = extents[0] * extents[1] * extents[2];
408 if (raw == nullptr || total <= 0) return {};
409 const double* first = reinterpret_cast<const double*>(raw);
410 return std::vector<double>(first, first + total);
411 }
412
417 std::array<int64_t, 3> z_shape() const {
418 double* raw = nullptr;
419 int64_t extents[3] = {0, 0, 0};
420 fitpack_parametric_surface_c_getcomp_z(as<fitpack_parametric_surface_c>(), &raw, extents);
421 return { extents[0], extents[1], extents[2] };
422 }
423
424#if HAVE_FXARRAY
437 fxArray<double> z() const {
438 double* raw = nullptr;
439 int64_t extents[3] = {0, 0, 0};
440 fitpack_parametric_surface_c_getcomp_z(as<fitpack_parametric_surface_c>(), &raw, extents);
441 FX_SIZE bounds[6]; // (lower, upper) per dimension, Fortran lbound 1
442 for (int k = 0; k < 3; ++k) {
443 bounds[2 * k] = 1;
444 bounds[2 * k + 1] = static_cast<FX_SIZE>(extents[k]);
445 }
446 array_c descr = array_c_null;
447 array_c_from_ptr(&descr, "z", static_cast<void*>(raw),
448 getCFITypeFlag<double>(),
449 static_cast<FX_SIZE>(sizeof(double)),
450 static_cast<FX_RANK>(3), bounds);
451 return fxArray<double>(descr);
452 }
453#endif // HAVE_FXARRAY
454
463 std::vector<double> t_vector() const {
464 double* raw = nullptr;
465 int64_t extents[2] = {0, 0};
466 fitpack_parametric_surface_c_getcomp_t(as<fitpack_parametric_surface_c>(), &raw, extents);
467 const int64_t total = extents[0] * extents[1];
468 if (raw == nullptr || total <= 0) return {};
469 const double* first = reinterpret_cast<const double*>(raw);
470 return std::vector<double>(first, first + total);
471 }
472
477 std::array<int64_t, 2> t_shape() const {
478 double* raw = nullptr;
479 int64_t extents[2] = {0, 0};
480 fitpack_parametric_surface_c_getcomp_t(as<fitpack_parametric_surface_c>(), &raw, extents);
481 return { extents[0], extents[1] };
482 }
483
484#if HAVE_FXARRAY
497 fxArray<double> t() const {
498 double* raw = nullptr;
499 int64_t extents[2] = {0, 0};
500 fitpack_parametric_surface_c_getcomp_t(as<fitpack_parametric_surface_c>(), &raw, extents);
501 FX_SIZE bounds[4]; // (lower, upper) per dimension, Fortran lbound 1
502 for (int k = 0; k < 2; ++k) {
503 bounds[2 * k] = 1;
504 bounds[2 * k + 1] = static_cast<FX_SIZE>(extents[k]);
505 }
506 array_c descr = array_c_null;
507 array_c_from_ptr(&descr, "t", static_cast<void*>(raw),
508 getCFITypeFlag<double>(),
509 static_cast<FX_SIZE>(sizeof(double)),
510 static_cast<FX_RANK>(2), bounds);
511 return fxArray<double>(descr);
512 }
513#endif // HAVE_FXARRAY
514
515 // ===========================================================================================
516 // Scalar Property Accessors
517 // ===========================================================================================
518
519 int32_t& idim() {
520 return *fitpack_parametric_surface_c_ref_idim(as<fitpack_parametric_surface_c>());
521 }
522 const int32_t& idim() const {
523 return *fitpack_parametric_surface_c_ref_idim(as<fitpack_parametric_surface_c>());
524 }
525
526 int32_t& nmax() {
527 return *fitpack_parametric_surface_c_ref_nmax(as<fitpack_parametric_surface_c>());
528 }
529 const int32_t& nmax() const {
530 return *fitpack_parametric_surface_c_ref_nmax(as<fitpack_parametric_surface_c>());
531 }
532
533protected:
534 explicit fpParametricSurface(NoAlloc tag) : fpFitter(tag) {}
535
536};
537
538#endif /* FPPARAMETRICSURFACE_HPP_INCLUDED */
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
int32_t & idim()
Definition fpParametricSurface.hpp:519
bool is_allocated() const override
Check if object is allocated.
Definition fpParametricSurface.hpp:142
fxArray< double > v() const
Zero-copy fxArray view of component 'v'.
Definition fpParametricSurface.hpp:377
std::array< int64_t, 3 > z_shape() const
Extents of component 'z', leading dimension first.
Definition fpParametricSurface.hpp:417
std::array< int64_t, 2 > t_shape() const
Extents of component 't', leading dimension first.
Definition fpParametricSurface.hpp:477
std::vector< double > u_vector() const
Deep copy of component 'u' as a std::vector.
Definition fpParametricSurface.hpp:309
const int32_t & nmax() const
Definition fpParametricSurface.hpp:529
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 fpParametricSurface.hpp:164
virtual int32_t interpolate(bool *reset_knots=nullptr)
Definition fpParametricSurface.hpp:216
std::vector< double > z_vector() const
Deep copy of component 'z' as a std::vector.
Definition fpParametricSurface.hpp:403
std::vector< double > t_vector() const
Deep copy of component 't' as a std::vector.
Definition fpParametricSurface.hpp:463
void core_comm_pack(std::vector< double > &buffer) const override
core_comm_pack
Definition fpParametricSurface.hpp:282
fitpack_parametric_surface_c & c_handle()
Get underlying C wrapper (for interop)
Definition fpParametricSurface.hpp:171
fxArray< double > z() const
Zero-copy fxArray view of component 'z'.
Definition fpParametricSurface.hpp:437
void comm_pack(std::vector< double > &buffer) const override
comm_pack
Definition fpParametricSurface.hpp:256
virtual int32_t fit(int32_t n, double *smoothing=nullptr, bool *periodic=nullptr, bool *keep_knots=nullptr)
fit
Definition fpParametricSurface.hpp:211
const char * c_type_name() const override
Return the C wrapper struct name for this class (e.g. "fitpack_parametric_surface_c").
Definition fpParametricSurface.hpp:156
fpParametricSurface(fitpack_parametric_surface_c &c_wrapper, ViewTag)
Non-owning view ctor: bit-copy the C handle, mark is_pointer=true. Used by parent classes' polymorphi...
Definition fpParametricSurface.hpp:130
fpParametricSurface & operator=(fpParametricSurface &&other) noexcept
Move assignment - transfer ownership.
Definition fpParametricSurface.hpp:105
double mse() const override
Definition fpParametricSurface.hpp:271
int32_t core_comm_size() const override
Definition fpParametricSurface.hpp:275
bool is_pointer() const override
Check if this is a non-owning pointer.
Definition fpParametricSurface.hpp:149
virtual std::vector< double > eval(std::vector< double > &u, std::vector< double > &v, int32_t n_result, int32_t *ierr=nullptr)
eval
Definition fpParametricSurface.hpp:241
virtual std::vector< double > eval(double u, double v, int32_t n_result, int32_t *ierr=nullptr)
eval
Definition fpParametricSurface.hpp:231
void destroy_base() override
Definition fpParametricSurface.hpp:297
int32_t & nmax()
Definition fpParametricSurface.hpp:526
const fitpack_parametric_surface_c & c_handle() const
Get underlying C wrapper (const, for interop)
Definition fpParametricSurface.hpp:178
void comm_expand(std::vector< double > &buffer) override
comm_expand
Definition fpParametricSurface.hpp:265
virtual int32_t least_squares(int32_t n, double *u_knots=nullptr, double *v_knots=nullptr, double *smoothing=nullptr, bool *reset_knots=nullptr)
least_squares
Definition fpParametricSurface.hpp:223
const int32_t & idim() const
Definition fpParametricSurface.hpp:522
fpParametricSurface & operator=(const fpParametricSurface &other)
Copy assignment - deep copy.
Definition fpParametricSurface.hpp:86
fpParametricSurface(fpParametricSurface &&other) noexcept
Move constructor - transfer ownership.
Definition fpParametricSurface.hpp:97
const fpFitter & as_parent() const
Definition fpParametricSurface.hpp:200
fxArray< double > u() const
Zero-copy fxArray view of component 'u'.
Definition fpParametricSurface.hpp:332
void core_comm_expand(std::vector< double > &buffer) override
core_comm_expand
Definition fpParametricSurface.hpp:291
fpFitter & as_parent()
Upcast to parent type (reference, no copy)
Definition fpParametricSurface.hpp:197
int32_t comm_size() const override
Definition fpParametricSurface.hpp:249
fxArray< double > t() const
Zero-copy fxArray view of component 't'.
Definition fpParametricSurface.hpp:497
std::vector< double > v_vector() const
Deep copy of component 'v' as a std::vector.
Definition fpParametricSurface.hpp:354
fpParametricSurface(NoAlloc tag)
Definition fpParametricSurface.hpp:534
fpParametricSurface(fitpack_parametric_surface_c &c_wrapper, bool move=false)
Construct from existing C wrapper (takes ownership if move=true)
Definition fpParametricSurface.hpp:116
fpParametricSurface()
Default constructor - allocates new fitpack_parametric_surface.
Definition fpParametricSurface.hpp:64
fpParametricSurface(const fpParametricSurface &other)
Copy constructor - deep copy.
Definition fpParametricSurface.hpp:78
static fpParametricSurface make_view()
Construct an empty (non-owning) wrapper, for use as a view target.
Definition fpParametricSurface.hpp:190
~fpParametricSurface() override
Destructor - deallocates if owned.
Definition fpParametricSurface.hpp:71
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