fitpack
Modern Fortran library for curve and surface fitting with splines
Loading...
Searching...
No Matches
fpGridSphere.hpp
Go to the documentation of this file.
1/***************************************************************************************************
2! ____________________ ___ ________ __
3! / ____/ _/_ __/ __ \/ | / ____/ //_/
4! / /_ / / / / / /_/ / /| |/ / / ,<
5! / __/ _/ / / / / ____/ ___ / /___/ /| |
6! /_/ /___/ /_/ /_/ /_/ |_\____/_/ |_|
7!
8! A Curve Fitting Package
9!
10! fpGridSphere.hpp (class fpGridSphere)
11!> @brief Standalone C++ wrapper for fitpack_grid_sphere (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 FPGRIDSPHERE_HPP_INCLUDED
25#define FPGRIDSPHERE_HPP_INCLUDED
26
27#include "fitpack_config.h"
28
29#if HAVE_FXARRAY
30#include "fxArrays.hpp"
31#endif
32
33#include "fitpack_grid_sphere_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_grid_sphere_c) == sizeof(fitpack_fitter_c),
45 "C descriptor layout mismatch: fitpack_grid_sphere_c vs fitpack_fitter_c");
46
55class fpGridSphere : public fpFitter {
56public:
57 // ===========================================================================================
58 // Constructors and Destructor
59 // ===========================================================================================
60
65 fitpack_grid_sphere_c_allocate(as<fitpack_grid_sphere_c>(), nullptr);
66 }
67
71 ~fpGridSphere() override {
72 fitpack_grid_sphere_c_destroy(as<fitpack_grid_sphere_c>(), nullptr);
73 }
74
79 *as<fitpack_grid_sphere_c>() = fitpack_grid_sphere_c_null;
80 fitpack_grid_sphere_c_copy(as<fitpack_grid_sphere_c>(), other.as<fitpack_grid_sphere_c>(), false, nullptr);
81 }
82
87 if (this != &other) {
88 fitpack_grid_sphere_c_destroy(as<fitpack_grid_sphere_c>(), nullptr);
89 fitpack_grid_sphere_c_copy(as<fitpack_grid_sphere_c>(), other.as<fitpack_grid_sphere_c>(), false, nullptr);
90 }
91 return *this;
92 }
93
97 fpGridSphere(fpGridSphere&& other) noexcept : fpFitter(NoAlloc{}) {
98 *as<fitpack_grid_sphere_c>() = fitpack_grid_sphere_c_null;
99 fitpack_grid_sphere_c_move_alloc(as<fitpack_grid_sphere_c>(), other.as<fitpack_grid_sphere_c>(), nullptr);
100 }
101
106 if (this != &other) {
107 fitpack_grid_sphere_c_destroy(as<fitpack_grid_sphere_c>(), nullptr);
108 fitpack_grid_sphere_c_move_alloc(as<fitpack_grid_sphere_c>(), other.as<fitpack_grid_sphere_c>(), nullptr);
109 }
110 return *this;
111 }
112
116 explicit fpGridSphere(fitpack_grid_sphere_c& c_wrapper, bool move = false) : fpFitter(NoAlloc{}) {
117 if (move) {
118 fitpack_grid_sphere_c_move_alloc(as<fitpack_grid_sphere_c>(), &c_wrapper, nullptr);
119 } else {
120 *as<fitpack_grid_sphere_c>() = fitpack_grid_sphere_c_null;
121 fitpack_grid_sphere_c_copy(as<fitpack_grid_sphere_c>(), &c_wrapper, false, nullptr);
122 }
123 }
124
130 explicit fpGridSphere(fitpack_grid_sphere_c& c_wrapper, ViewTag) : fpFitter(NoAlloc{}) {
131 *as<fitpack_grid_sphere_c>() = c_wrapper;
132 as<fitpack_grid_sphere_c>()->is_pointer = true;
133 }
134
135 // ===========================================================================================
136 // Utility Methods
137 // ===========================================================================================
138
142 bool is_allocated() const override {
143 return as<fitpack_grid_sphere_c>()->cptr != nullptr;
144 }
145
149 bool is_pointer() const override {
150 return as<fitpack_grid_sphere_c>()->is_pointer;
151 }
152
156 const char* c_type_name() const override {
157 return fitpack_grid_sphere_c_c_type_name(*as<fitpack_grid_sphere_c>());
158 }
159
164 const char* cpp_type_name() const override {
165 return "fpGridSphere";
166 }
167
171 fitpack_grid_sphere_c& c_handle() {
173 }
174
178 const fitpack_grid_sphere_c& c_handle() const {
180 }
181
191 return fpGridSphere(NoAlloc{});
192 }
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 void new_points(std::vector<double>& u, std::vector<double>& v, int32_t z_n1, int32_t z_n2, std::vector<double>& z) {
212 int32_t n = static_cast<int32_t>(u.size());
213 fitpack_grid_sphere_c_new_points(as<fitpack_grid_sphere_c>(), n, u.data(), v.data(), z_n1, z_n2, z.data());
214 }
215
216
220 virtual int32_t new_fit(std::vector<double>& u, std::vector<double>& v, int32_t z_n1, int32_t z_n2, std::vector<double>& z, double* smoothing = nullptr) {
221 int32_t n = static_cast<int32_t>(u.size());
222 return fitpack_grid_sphere_c_new_fit(as<fitpack_grid_sphere_c>(), n, u.data(), v.data(), z_n1, z_n2, z.data(), smoothing);
223 }
224
225
226 virtual void BC_north_pole(double* z0 = nullptr, bool* exact = nullptr, bool* differentiable = nullptr, bool* zero_grad = nullptr) {
227 fitpack_grid_sphere_c_BC_north_pole(as<fitpack_grid_sphere_c>(), z0, exact, differentiable, zero_grad);
228 }
229
230 virtual void BC_south_pole(double* z0 = nullptr, bool* exact = nullptr, bool* differentiable = nullptr, bool* zero_grad = nullptr) {
231 fitpack_grid_sphere_c_BC_south_pole(as<fitpack_grid_sphere_c>(), z0, exact, differentiable, zero_grad);
232 }
233
234 virtual int32_t fit(double* smoothing = nullptr, bool* keep_knots = nullptr) {
235 return fitpack_grid_sphere_c_fit(as<fitpack_grid_sphere_c>(), smoothing, keep_knots);
236 }
237
238 virtual int32_t least_squares(double* smoothing = nullptr, bool* reset_knots = nullptr) {
239 return fitpack_grid_sphere_c_least_squares(as<fitpack_grid_sphere_c>(), smoothing, reset_knots);
240 }
241
242 virtual int32_t interpolate(bool* reset_knots = nullptr) {
243 return fitpack_grid_sphere_c_interpolate(as<fitpack_grid_sphere_c>(), reset_knots);
244 }
245
246 virtual double eval(double u, double v, int32_t* ierr = nullptr) {
247 return fitpack_grid_sphere_c_gridded_eval_one(as<fitpack_grid_sphere_c>(), u, v, ierr);
248 }
249
253 virtual std::vector<double> eval(std::vector<double>& u, std::vector<double>& v, int32_t* ierr = nullptr) {
254 int32_t n = static_cast<int32_t>(u.size());
255 std::vector<double> result(n * n);
256 int32_t n_result = 0;
257 fitpack_grid_sphere_c_gridded_eval_many(as<fitpack_grid_sphere_c>(), n, u.data(), v.data(), ierr, result.data(), &n_result, n * n);
258 result.resize(n_result);
259 return result;
260 }
261
262
263 int32_t comm_size() const override {
264 return fitpack_grid_sphere_c_comm_size(as<fitpack_grid_sphere_c>());
265 }
266
270 void comm_pack(std::vector<double>& buffer) const override {
271 int32_t n = static_cast<int32_t>(buffer.size());
272 fitpack_grid_sphere_c_comm_pack(as<fitpack_grid_sphere_c>(), n, buffer.data());
273 }
274
275
279 void comm_expand(std::vector<double>& buffer) override {
280 int32_t n = static_cast<int32_t>(buffer.size());
281 fitpack_grid_sphere_c_comm_expand(as<fitpack_grid_sphere_c>(), n, buffer.data());
282 }
283
284
285 virtual void write(const char* filename) {
286 fitpack_grid_sphere_c_write(as<fitpack_grid_sphere_c>(), filename);
287 }
288
289 double mse() const override {
290 return fitpack_grid_sphere_c_mse(as<fitpack_grid_sphere_c>());
291 }
292
293 int32_t core_comm_size() const override {
294 return fitpack_grid_sphere_c_core_comm_size(as<fitpack_grid_sphere_c>());
295 }
296
300 void core_comm_pack(std::vector<double>& buffer) const override {
301 int32_t n = static_cast<int32_t>(buffer.size());
302 fitpack_grid_sphere_c_core_comm_pack(as<fitpack_grid_sphere_c>(), n, buffer.data());
303 }
304
305
309 void core_comm_expand(std::vector<double>& buffer) override {
310 int32_t n = static_cast<int32_t>(buffer.size());
311 fitpack_grid_sphere_c_core_comm_expand(as<fitpack_grid_sphere_c>(), n, buffer.data());
312 }
313
314
315 void destroy_base() override {
316 fitpack_grid_sphere_c_destroy_base(as<fitpack_grid_sphere_c>());
317 }
318
319 // ===========================================================================================
320 // Component Array Accessors
321 // ===========================================================================================
322
327 std::vector<double> u_vector() const {
328 double* raw = nullptr;
329 int64_t extents[1] = {0};
330 fitpack_grid_sphere_c_getcomp_u(as<fitpack_grid_sphere_c>(), &raw, extents);
331 const int64_t total = extents[0];
332 if (raw == nullptr || total <= 0) return {};
333 const double* first = reinterpret_cast<const double*>(raw);
334 return std::vector<double>(first, first + total);
335 }
336
337#if HAVE_FXARRAY
350 fxArray<double> u() const {
351 double* raw = nullptr;
352 int64_t extents[1] = {0};
353 fitpack_grid_sphere_c_getcomp_u(as<fitpack_grid_sphere_c>(), &raw, extents);
354 FX_SIZE bounds[2]; // (lower, upper) per dimension, Fortran lbound 1
355 for (int k = 0; k < 1; ++k) {
356 bounds[2 * k] = 1;
357 bounds[2 * k + 1] = static_cast<FX_SIZE>(extents[k]);
358 }
359 array_c descr = array_c_null;
360 array_c_from_ptr(&descr, "u", static_cast<void*>(raw),
361 getCFITypeFlag<double>(),
362 static_cast<FX_SIZE>(sizeof(double)),
363 static_cast<FX_RANK>(1), bounds);
364 return fxArray<double>(descr);
365 }
366#endif // HAVE_FXARRAY
367
372 std::vector<double> v_vector() const {
373 double* raw = nullptr;
374 int64_t extents[1] = {0};
375 fitpack_grid_sphere_c_getcomp_v(as<fitpack_grid_sphere_c>(), &raw, extents);
376 const int64_t total = extents[0];
377 if (raw == nullptr || total <= 0) return {};
378 const double* first = reinterpret_cast<const double*>(raw);
379 return std::vector<double>(first, first + total);
380 }
381
382#if HAVE_FXARRAY
395 fxArray<double> v() const {
396 double* raw = nullptr;
397 int64_t extents[1] = {0};
398 fitpack_grid_sphere_c_getcomp_v(as<fitpack_grid_sphere_c>(), &raw, extents);
399 FX_SIZE bounds[2]; // (lower, upper) per dimension, Fortran lbound 1
400 for (int k = 0; k < 1; ++k) {
401 bounds[2 * k] = 1;
402 bounds[2 * k + 1] = static_cast<FX_SIZE>(extents[k]);
403 }
404 array_c descr = array_c_null;
405 array_c_from_ptr(&descr, "v", static_cast<void*>(raw),
406 getCFITypeFlag<double>(),
407 static_cast<FX_SIZE>(sizeof(double)),
408 static_cast<FX_RANK>(1), bounds);
409 return fxArray<double>(descr);
410 }
411#endif // HAVE_FXARRAY
412
421 std::vector<double> z_vector() const {
422 double* raw = nullptr;
423 int64_t extents[2] = {0, 0};
424 fitpack_grid_sphere_c_getcomp_z(as<fitpack_grid_sphere_c>(), &raw, extents);
425 const int64_t total = extents[0] * extents[1];
426 if (raw == nullptr || total <= 0) return {};
427 const double* first = reinterpret_cast<const double*>(raw);
428 return std::vector<double>(first, first + total);
429 }
430
435 std::array<int64_t, 2> z_shape() const {
436 double* raw = nullptr;
437 int64_t extents[2] = {0, 0};
438 fitpack_grid_sphere_c_getcomp_z(as<fitpack_grid_sphere_c>(), &raw, extents);
439 return { extents[0], extents[1] };
440 }
441
442#if HAVE_FXARRAY
455 fxArray<double> z() const {
456 double* raw = nullptr;
457 int64_t extents[2] = {0, 0};
458 fitpack_grid_sphere_c_getcomp_z(as<fitpack_grid_sphere_c>(), &raw, extents);
459 FX_SIZE bounds[4]; // (lower, upper) per dimension, Fortran lbound 1
460 for (int k = 0; k < 2; ++k) {
461 bounds[2 * k] = 1;
462 bounds[2 * k + 1] = static_cast<FX_SIZE>(extents[k]);
463 }
464 array_c descr = array_c_null;
465 array_c_from_ptr(&descr, "z", static_cast<void*>(raw),
466 getCFITypeFlag<double>(),
467 static_cast<FX_SIZE>(sizeof(double)),
468 static_cast<FX_RANK>(2), bounds);
469 return fxArray<double>(descr);
470 }
471#endif // HAVE_FXARRAY
472
481 std::vector<double> t_vector() const {
482 double* raw = nullptr;
483 int64_t extents[2] = {0, 0};
484 fitpack_grid_sphere_c_getcomp_t(as<fitpack_grid_sphere_c>(), &raw, extents);
485 const int64_t total = extents[0] * extents[1];
486 if (raw == nullptr || total <= 0) return {};
487 const double* first = reinterpret_cast<const double*>(raw);
488 return std::vector<double>(first, first + total);
489 }
490
495 std::array<int64_t, 2> t_shape() const {
496 double* raw = nullptr;
497 int64_t extents[2] = {0, 0};
498 fitpack_grid_sphere_c_getcomp_t(as<fitpack_grid_sphere_c>(), &raw, extents);
499 return { extents[0], extents[1] };
500 }
501
502#if HAVE_FXARRAY
515 fxArray<double> t() const {
516 double* raw = nullptr;
517 int64_t extents[2] = {0, 0};
518 fitpack_grid_sphere_c_getcomp_t(as<fitpack_grid_sphere_c>(), &raw, extents);
519 FX_SIZE bounds[4]; // (lower, upper) per dimension, Fortran lbound 1
520 for (int k = 0; k < 2; ++k) {
521 bounds[2 * k] = 1;
522 bounds[2 * k + 1] = static_cast<FX_SIZE>(extents[k]);
523 }
524 array_c descr = array_c_null;
525 array_c_from_ptr(&descr, "t", static_cast<void*>(raw),
526 getCFITypeFlag<double>(),
527 static_cast<FX_SIZE>(sizeof(double)),
528 static_cast<FX_RANK>(2), bounds);
529 return fxArray<double>(descr);
530 }
531#endif // HAVE_FXARRAY
532
533 // ===========================================================================================
534 // Scalar Property Accessors
535 // ===========================================================================================
536
537 int32_t& nmax() {
538 return *fitpack_grid_sphere_c_ref_nmax(as<fitpack_grid_sphere_c>());
539 }
540 const int32_t& nmax() const {
541 return *fitpack_grid_sphere_c_ref_nmax(as<fitpack_grid_sphere_c>());
542 }
543
544protected:
545 explicit fpGridSphere(NoAlloc tag) : fpFitter(tag) {}
546
547};
548
549#endif /* FPGRIDSPHERE_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
fxArray< double > v() const
Zero-copy fxArray view of component 'v'.
Definition fpGridSphere.hpp:395
fpGridSphere(const fpGridSphere &other)
Copy constructor - deep copy.
Definition fpGridSphere.hpp:78
std::vector< double > t_vector() const
Deep copy of component 't' as a std::vector.
Definition fpGridSphere.hpp:481
virtual void new_points(std::vector< double > &u, std::vector< double > &v, int32_t z_n1, int32_t z_n2, std::vector< double > &z)
new_points
Definition fpGridSphere.hpp:211
fpGridSphere(fitpack_grid_sphere_c &c_wrapper, bool move=false)
Construct from existing C wrapper (takes ownership if move=true)
Definition fpGridSphere.hpp:116
fpGridSphere & operator=(fpGridSphere &&other) noexcept
Move assignment - transfer ownership.
Definition fpGridSphere.hpp:105
std::vector< double > u_vector() const
Deep copy of component 'u' as a std::vector.
Definition fpGridSphere.hpp:327
void core_comm_pack(std::vector< double > &buffer) const override
core_comm_pack
Definition fpGridSphere.hpp:300
virtual void BC_south_pole(double *z0=nullptr, bool *exact=nullptr, bool *differentiable=nullptr, bool *zero_grad=nullptr)
Definition fpGridSphere.hpp:230
const int32_t & nmax() const
Definition fpGridSphere.hpp:540
void core_comm_expand(std::vector< double > &buffer) override
core_comm_expand
Definition fpGridSphere.hpp:309
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 fpGridSphere.hpp:164
int32_t comm_size() const override
Definition fpGridSphere.hpp:263
virtual double eval(double u, double v, int32_t *ierr=nullptr)
Definition fpGridSphere.hpp:246
bool is_allocated() const override
Check if object is allocated.
Definition fpGridSphere.hpp:142
virtual std::vector< double > eval(std::vector< double > &u, std::vector< double > &v, int32_t *ierr=nullptr)
eval
Definition fpGridSphere.hpp:253
fpGridSphere()
Default constructor - allocates new fitpack_grid_sphere.
Definition fpGridSphere.hpp:64
virtual void BC_north_pole(double *z0=nullptr, bool *exact=nullptr, bool *differentiable=nullptr, bool *zero_grad=nullptr)
Definition fpGridSphere.hpp:226
const fpFitter & as_parent() const
Definition fpGridSphere.hpp:200
virtual int32_t fit(double *smoothing=nullptr, bool *keep_knots=nullptr)
Definition fpGridSphere.hpp:234
const fitpack_grid_sphere_c & c_handle() const
Get underlying C wrapper (const, for interop)
Definition fpGridSphere.hpp:178
void destroy_base() override
Definition fpGridSphere.hpp:315
fitpack_grid_sphere_c & c_handle()
Get underlying C wrapper (for interop)
Definition fpGridSphere.hpp:171
fpGridSphere(NoAlloc tag)
Definition fpGridSphere.hpp:545
fpGridSphere(fitpack_grid_sphere_c &c_wrapper, ViewTag)
Non-owning view ctor: bit-copy the C handle, mark is_pointer=true. Used by parent classes' polymorphi...
Definition fpGridSphere.hpp:130
virtual int32_t least_squares(double *smoothing=nullptr, bool *reset_knots=nullptr)
Definition fpGridSphere.hpp:238
int32_t & nmax()
Definition fpGridSphere.hpp:537
bool is_pointer() const override
Check if this is a non-owning pointer.
Definition fpGridSphere.hpp:149
void comm_expand(std::vector< double > &buffer) override
comm_expand
Definition fpGridSphere.hpp:279
const char * c_type_name() const override
Return the C wrapper struct name for this class (e.g. "fitpack_grid_sphere_c").
Definition fpGridSphere.hpp:156
virtual int32_t new_fit(std::vector< double > &u, std::vector< double > &v, int32_t z_n1, int32_t z_n2, std::vector< double > &z, double *smoothing=nullptr)
new_fit
Definition fpGridSphere.hpp:220
std::array< int64_t, 2 > t_shape() const
Extents of component 't', leading dimension first.
Definition fpGridSphere.hpp:495
static fpGridSphere make_view()
Construct an empty (non-owning) wrapper, for use as a view target.
Definition fpGridSphere.hpp:190
virtual int32_t interpolate(bool *reset_knots=nullptr)
Definition fpGridSphere.hpp:242
~fpGridSphere() override
Destructor - deallocates if owned.
Definition fpGridSphere.hpp:71
int32_t core_comm_size() const override
Definition fpGridSphere.hpp:293
void comm_pack(std::vector< double > &buffer) const override
comm_pack
Definition fpGridSphere.hpp:270
fxArray< double > t() const
Zero-copy fxArray view of component 't'.
Definition fpGridSphere.hpp:515
fpGridSphere & operator=(const fpGridSphere &other)
Copy assignment - deep copy.
Definition fpGridSphere.hpp:86
fpFitter & as_parent()
Upcast to parent type (reference, no copy)
Definition fpGridSphere.hpp:197
fxArray< double > z() const
Zero-copy fxArray view of component 'z'.
Definition fpGridSphere.hpp:455
std::vector< double > v_vector() const
Deep copy of component 'v' as a std::vector.
Definition fpGridSphere.hpp:372
std::vector< double > z_vector() const
Deep copy of component 'z' as a std::vector.
Definition fpGridSphere.hpp:421
fpGridSphere(fpGridSphere &&other) noexcept
Move constructor - transfer ownership.
Definition fpGridSphere.hpp:97
fxArray< double > u() const
Zero-copy fxArray view of component 'u'.
Definition fpGridSphere.hpp:350
double mse() const override
Definition fpGridSphere.hpp:289
std::array< int64_t, 2 > z_shape() const
Extents of component 'z', leading dimension first.
Definition fpGridSphere.hpp:435
virtual void write(const char *filename)
Definition fpGridSphere.hpp:285
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