fitpack
Modern Fortran library for curve and surface fitting with splines
Loading...
Searching...
No Matches
fpFitter.hpp
Go to the documentation of this file.
1/***************************************************************************************************
2! ____________________ ___ ________ __
3! / ____/ _/_ __/ __ \/ | / ____/ //_/
4! / /_ / / / / / /_/ / /| |/ / / ,<
5! / __/ _/ / / / / ____/ ___ / /___/ /| |
6! /_/ /___/ /_/ /_/ /_/ |_\____/_/ |_|
7!
8! A Curve Fitting Package
9!
10! fpFitter.hpp (class fpFitter)
11!> @brief Standalone C++ wrapper for fitpack_fitter (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 FPFITTER_HPP_INCLUDED
25#define FPFITTER_HPP_INCLUDED
26
27#include "fitpack_config.h"
28
29#if HAVE_FXARRAY
30#include "fxArrays.hpp"
31#endif
32
33#include "fitpack_fitter_c.h"
34#include <string>
35#include <vector>
36#include <cstdint>
37#include <memory>
38#include <stdexcept>
39#include <variant>
40#include <optional>
41
49class fpFitter {
50public:
51 // ===========================================================================================
52 // Abstract type - cannot be instantiated directly
53 // ===========================================================================================
54
55 virtual ~fpFitter() = default;
56
57 // ===========================================================================================
58 // Utility Methods
59 // ===========================================================================================
60
64 virtual bool is_allocated() const {
65 return as<fitpack_fitter_c>()->cptr != nullptr;
66 }
67
71 virtual bool is_pointer() const {
72 return as<fitpack_fitter_c>()->is_pointer;
73 }
74
78 const char* fortran_type_name() const {
79 const char* tag = as<fitpack_fitter_c>()->name_cptr;
80 return tag ? tag : fitpack_fitter_c_typename;
81 }
82
86 virtual const char* c_type_name() const {
87 return fitpack_fitter_c_c_type_name(*as<fitpack_fitter_c>());
88 }
89
94 virtual const char* cpp_type_name() const {
95 return "fpFitter";
96 }
97
103 struct ViewTag {};
104
108 fitpack_fitter_c& c_handle() {
109 return *as<fitpack_fitter_c>();
110 }
111
115 const fitpack_fitter_c& c_handle() const {
116 return *as<fitpack_fitter_c>();
117 }
118
119 // ===========================================================================================
120 // Method Wrappers (standalone — no fxArray dependency)
121 // ===========================================================================================
122
123 virtual double mse() const {
124 return fitpack_fitter_c_mse(as<fitpack_fitter_c>());
125 }
126
127 virtual int32_t core_comm_size() const {
128 return fitpack_fitter_c_core_comm_size(as<fitpack_fitter_c>());
129 }
130
134 virtual void core_comm_pack(std::vector<double>& buffer) const {
135 int32_t n = static_cast<int32_t>(buffer.size());
136 fitpack_fitter_c_core_comm_pack(as<fitpack_fitter_c>(), n, buffer.data());
137 }
138
139
143 virtual void core_comm_expand(std::vector<double>& buffer) {
144 int32_t n = static_cast<int32_t>(buffer.size());
145 fitpack_fitter_c_core_comm_expand(as<fitpack_fitter_c>(), n, buffer.data());
146 }
147
148
149 virtual void destroy_base() {
150 fitpack_fitter_c_destroy_base(as<fitpack_fitter_c>());
151 }
152
153 virtual int32_t comm_size() const = 0;
154
158 virtual void comm_pack(std::vector<double>& buffer) const = 0;
159
160
164 virtual void comm_expand(std::vector<double>& buffer) = 0;
165
166
167 // ===========================================================================================
168 // Component Array Accessors
169 // ===========================================================================================
170
175 std::vector<double> c_vector() const {
176 double* raw = nullptr;
177 int64_t extents[1] = {0};
178 fitpack_fitter_c_getcomp_c(as<fitpack_fitter_c>(), &raw, extents);
179 const int64_t total = extents[0];
180 if (raw == nullptr || total <= 0) return {};
181 const double* first = reinterpret_cast<const double*>(raw);
182 return std::vector<double>(first, first + total);
183 }
184
185#if HAVE_FXARRAY
198 fxArray<double> c() const {
199 double* raw = nullptr;
200 int64_t extents[1] = {0};
201 fitpack_fitter_c_getcomp_c(as<fitpack_fitter_c>(), &raw, extents);
202 FX_SIZE bounds[2]; // (lower, upper) per dimension, Fortran lbound 1
203 for (int k = 0; k < 1; ++k) {
204 bounds[2 * k] = 1;
205 bounds[2 * k + 1] = static_cast<FX_SIZE>(extents[k]);
206 }
207 array_c descr = array_c_null;
208 array_c_from_ptr(&descr, "c", static_cast<void*>(raw),
209 getCFITypeFlag<double>(),
210 static_cast<FX_SIZE>(sizeof(double)),
211 static_cast<FX_RANK>(1), bounds);
212 return fxArray<double>(descr);
213 }
214#endif // HAVE_FXARRAY
215
220 std::vector<double> wrk_vector() const {
221 double* raw = nullptr;
222 int64_t extents[1] = {0};
223 fitpack_fitter_c_getcomp_wrk(as<fitpack_fitter_c>(), &raw, extents);
224 const int64_t total = extents[0];
225 if (raw == nullptr || total <= 0) return {};
226 const double* first = reinterpret_cast<const double*>(raw);
227 return std::vector<double>(first, first + total);
228 }
229
230#if HAVE_FXARRAY
243 fxArray<double> wrk() const {
244 double* raw = nullptr;
245 int64_t extents[1] = {0};
246 fitpack_fitter_c_getcomp_wrk(as<fitpack_fitter_c>(), &raw, extents);
247 FX_SIZE bounds[2]; // (lower, upper) per dimension, Fortran lbound 1
248 for (int k = 0; k < 1; ++k) {
249 bounds[2 * k] = 1;
250 bounds[2 * k + 1] = static_cast<FX_SIZE>(extents[k]);
251 }
252 array_c descr = array_c_null;
253 array_c_from_ptr(&descr, "wrk", static_cast<void*>(raw),
254 getCFITypeFlag<double>(),
255 static_cast<FX_SIZE>(sizeof(double)),
256 static_cast<FX_RANK>(1), bounds);
257 return fxArray<double>(descr);
258 }
259#endif // HAVE_FXARRAY
260
265 std::vector<int32_t> iwrk_vector() const {
266 int32_t* raw = nullptr;
267 int64_t extents[1] = {0};
268 fitpack_fitter_c_getcomp_iwrk(as<fitpack_fitter_c>(), &raw, extents);
269 const int64_t total = extents[0];
270 if (raw == nullptr || total <= 0) return {};
271 const int32_t* first = reinterpret_cast<const int32_t*>(raw);
272 return std::vector<int32_t>(first, first + total);
273 }
274
275#if HAVE_FXARRAY
288 fxArray<int32_t> iwrk() const {
289 int32_t* raw = nullptr;
290 int64_t extents[1] = {0};
291 fitpack_fitter_c_getcomp_iwrk(as<fitpack_fitter_c>(), &raw, extents);
292 FX_SIZE bounds[2]; // (lower, upper) per dimension, Fortran lbound 1
293 for (int k = 0; k < 1; ++k) {
294 bounds[2 * k] = 1;
295 bounds[2 * k + 1] = static_cast<FX_SIZE>(extents[k]);
296 }
297 array_c descr = array_c_null;
298 array_c_from_ptr(&descr, "iwrk", static_cast<void*>(raw),
299 getCFITypeFlag<int32_t>(),
300 static_cast<FX_SIZE>(sizeof(int32_t)),
301 static_cast<FX_RANK>(1), bounds);
302 return fxArray<int32_t>(descr);
303 }
304#endif // HAVE_FXARRAY
305
306 // ===========================================================================================
307 // Scalar Property Accessors
308 // ===========================================================================================
309
310 int32_t& iopt() {
311 return *fitpack_fitter_c_ref_iopt(as<fitpack_fitter_c>());
312 }
313 const int32_t& iopt() const {
314 return *fitpack_fitter_c_ref_iopt(as<fitpack_fitter_c>());
315 }
316
317 double& smoothing() {
318 return *fitpack_fitter_c_ref_smoothing(as<fitpack_fitter_c>());
319 }
320 const double& smoothing() const {
321 return *fitpack_fitter_c_ref_smoothing(as<fitpack_fitter_c>());
322 }
323
324 double& fp() {
325 return *fitpack_fitter_c_ref_fp(as<fitpack_fitter_c>());
326 }
327 const double& fp() const {
328 return *fitpack_fitter_c_ref_fp(as<fitpack_fitter_c>());
329 }
330
331 int32_t& lwrk() {
332 return *fitpack_fitter_c_ref_lwrk(as<fitpack_fitter_c>());
333 }
334 const int32_t& lwrk() const {
335 return *fitpack_fitter_c_ref_lwrk(as<fitpack_fitter_c>());
336 }
337
338 int32_t& liwrk() {
339 return *fitpack_fitter_c_ref_liwrk(as<fitpack_fitter_c>());
340 }
341 const int32_t& liwrk() const {
342 return *fitpack_fitter_c_ref_liwrk(as<fitpack_fitter_c>());
343 }
344
345protected:
349 struct NoAlloc {};
350
354 explicit fpFitter(NoAlloc) {
355 // Do not allocate - derived class will allocate its own type
356 }
357
358 fitpack_fitter_c cobj = fitpack_fitter_c_null;
359
360 template<typename T> T* as() { return static_cast<T*>(static_cast<void*>(&cobj)); }
361 template<typename T> const T* as() const { return static_cast<const T*>(static_cast<const void*>(&cobj)); }
362
363};
364
365#endif /* FPFITTER_HPP_INCLUDED */
const double & fp() const
Definition fpFitter.hpp:327
fxArray< int32_t > iwrk() const
Zero-copy fxArray view of component 'iwrk'.
Definition fpFitter.hpp:288
const char * fortran_type_name() const
Return the dynamic Fortran type name of the underlying object.
Definition fpFitter.hpp:78
virtual const char * c_type_name() const
Return the C wrapper struct name for this class (e.g. "fitpack_fitter_c").
Definition fpFitter.hpp:86
virtual int32_t comm_size() const =0
double & fp()
Definition fpFitter.hpp:324
virtual void comm_expand(std::vector< double > &buffer)=0
comm_expand (deferred)
double & smoothing()
Definition fpFitter.hpp:317
virtual void core_comm_pack(std::vector< double > &buffer) const
core_comm_pack
Definition fpFitter.hpp:134
virtual double mse() const
Definition fpFitter.hpp:123
int32_t & liwrk()
Definition fpFitter.hpp:338
const T * as() const
Definition fpFitter.hpp:361
fxArray< double > c() const
Zero-copy fxArray view of component 'c'.
Definition fpFitter.hpp:198
fpFitter(NoAlloc)
Protected constructor for derived classes (does not allocate)
Definition fpFitter.hpp:354
virtual ~fpFitter()=default
fitpack_fitter_c cobj
Definition fpFitter.hpp:358
int32_t & iopt()
Definition fpFitter.hpp:310
const int32_t & liwrk() const
Definition fpFitter.hpp:341
virtual bool is_allocated() const
Check if object is allocated.
Definition fpFitter.hpp:64
T * as()
Definition fpFitter.hpp:360
std::vector< int32_t > iwrk_vector() const
Deep copy of component 'iwrk' as a std::vector.
Definition fpFitter.hpp:265
fitpack_fitter_c & c_handle()
Get underlying C wrapper (for interop)
Definition fpFitter.hpp:108
const int32_t & lwrk() const
Definition fpFitter.hpp:334
virtual void comm_pack(std::vector< double > &buffer) const =0
comm_pack (deferred)
const int32_t & iopt() const
Definition fpFitter.hpp:313
virtual void destroy_base()
Definition fpFitter.hpp:149
std::vector< double > wrk_vector() const
Deep copy of component 'wrk' as a std::vector.
Definition fpFitter.hpp:220
int32_t & lwrk()
Definition fpFitter.hpp:331
const fitpack_fitter_c & c_handle() const
Get underlying C wrapper (const, for interop)
Definition fpFitter.hpp:115
virtual void core_comm_expand(std::vector< double > &buffer)
core_comm_expand
Definition fpFitter.hpp:143
virtual const char * cpp_type_name() const
Return the fully-qualified C++ class name for this class. Owned by the C++ layer — does not round-tri...
Definition fpFitter.hpp:94
fxArray< double > wrk() const
Zero-copy fxArray view of component 'wrk'.
Definition fpFitter.hpp:243
const double & smoothing() const
Definition fpFitter.hpp:320
virtual bool is_pointer() const
Check if this is a non-owning pointer.
Definition fpFitter.hpp:71
virtual int32_t core_comm_size() const
Definition fpFitter.hpp:127
std::vector< double > c_vector() const
Deep copy of component 'c' as a std::vector.
Definition fpFitter.hpp:175
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