SplineInterpolatorEinspline.h
Go to the documentation of this file.
1 #ifndef _utl_SplineInterpolatorEinspline_h_
2 #define _utl_SplineInterpolatorEinspline_h_
3 
4 #include <iostream>
5 
6 #include <boost/array.hpp>
7 #include <boost/multi_array.hpp>
8 
9 #include <utl/AugerException.h>
10 
11 /* fix annoying compiler warnings
12  * because of useless macro constants
13  * set by both einspline and CLHEP */
14 #undef PACKAGE
15 #undef PACKAGE_BUGREPORT
16 #undef PACKAGE_STRING
17 #undef PACKAGE_NAME
18 #undef PACKAGE_TARNAME
19 #undef PACKAGE_VERSION
20 #undef VERSION
21 #include <einspline/bspline_base.h>
22 #include <einspline/bspline_structs.h>
23 #include <einspline/bspline_create.h>
24 #include <einspline/bspline_eval_std_d.h>
25 
26 #include <einspline/multi_bspline_structs.h>
27 #include <einspline/multi_bspline_create.h>
28 #include <einspline/multi_bspline_eval_d.h>
29 #undef PACKAGE
30 #undef PACKAGE_BUGREPORT
31 #undef PACKAGE_STRING
32 #undef PACKAGE_NAME
33 #undef PACKAGE_TARNAME
34 #undef PACKAGE_VERSION
35 #undef VERSION
36 
37 #include <vector>
38 
39 
40 namespace utl {
41 
42  namespace Spline {
43 
53  enum Type {
54  eNatural = NATURAL, /* minimize total curvature */
55  ePeriodic = PERIODIC, /* for a polar coordinate */
56  eFirstDerivative = DERIV1, /* set 1st derivatives at endpoints */
57  eSecondDerivative = DERIV2, /* set 2nd derivatives at endpoints */
58  };
59 
60 
61  class BoundaryCondition : public BCtype_d {
62  public:
64  const double vLeft = 0,
65  const double vRight = 0)
66  {
67  lCode = static_cast<const bc_code>(type);
68  lVal = vLeft;
69  rCode = static_cast<const bc_code>(type);
70  rVal = vRight;
71  }
72  };
73 
74 
76  public:
78 
79  Interpolator1D(const Interpolator1D& other) { *this = other; }
80 
81  Interpolator1D(const double xStart,
82  const double xStop, /* inclusive! */
83  const std::vector<double>& fValue,
84  const BoundaryCondition& bcX = BoundaryCondition())
85  {
86  Ugrid grid;
87  grid.start = xStart;
88  grid.end = xStop;
89  grid.num = fValue.size();
90  fDataPtr = create_UBspline_1d_d(grid, bcX, const_cast<double*>(&fValue[0]));
91  }
92 
93  ~Interpolator1D() { destroy_Bspline(fDataPtr); }
94 
96  operator=(const Interpolator1D& other)
97  {
98  if (this != &other) {
99  if (fDataPtr)
100  destroy_Bspline(fDataPtr);
101  fDataPtr = new UBspline_1d_d;
102  *fDataPtr = *other.fDataPtr;
103  const int n = fDataPtr->x_grid.num + (fDataPtr->xBC.lCode == PERIODIC ? 3 : 2);
104  fDataPtr->coefs = new double[n];
105  for (int i = 0; i < n; ++i)
106  fDataPtr->coefs[i] = other.fDataPtr->coefs[i];
107  }
108  return *this;
109  }
110 
111  double
112  operator()(const double x)
113  const
114  {
115  if (!fDataPtr)
116  throw utl::InvalidConfigurationException("no data for spline interpolator");
117  if (x < fDataPtr->x_grid.start || x > fDataPtr->x_grid.end)
118  throw utl::OutOfBoundException("argument is outside of interpolation range");
119 
120  double result;
121  eval_UBspline_1d_d(fDataPtr, x, &result);
122  return result;
123  }
124 
125  double
126  GetStart()
127  const
128  {
129  if (!fDataPtr)
130  throw utl::InvalidConfigurationException("no data for spline interpolator");
131  return fDataPtr->x_grid.start;
132  }
133 
134  double
135  GetStop()
136  const
137  {
138  if (!fDataPtr)
139  throw utl::InvalidConfigurationException("no data for spline interpolator");
140  return fDataPtr->x_grid.end;
141  }
142 
143  protected:
144  UBspline_1d_d* fDataPtr = nullptr;
145  };
146 
147 
149  public:
151 
152  Interpolator2D(const Interpolator2D& other) { *this = other; }
153 
154  Interpolator2D(const double xStart,
155  const double xStop,
156  const double yStart,
157  const double yStop,
158  const boost::multi_array<double,2>& values,
159  const BoundaryCondition bcX = BoundaryCondition(),
160  const BoundaryCondition bcY = BoundaryCondition())
161  {
162  Ugrid grid[2];
163  grid[0].num = values.shape()[0];
164  grid[0].start = xStart;
165  grid[0].end = xStop;
166  grid[1].num = values.shape()[1];
167  grid[1].start = yStart;
168  grid[1].end = yStop;
169  fDataPtr = create_UBspline_2d_d(grid[0], grid[1], bcX, bcY, const_cast<double*>(values.data()));
170  }
171 
172  ~Interpolator2D() { destroy_Bspline(fDataPtr); }
173 
175  operator=(const Interpolator2D& other)
176  {
177  if (this != &other) {
178  if (fDataPtr)
179  destroy_Bspline(fDataPtr);
180  fDataPtr = new UBspline_2d_d;
181  *fDataPtr = *other.fDataPtr;
182  const int n =
183  (fDataPtr->x_grid.num + (fDataPtr->xBC.lCode == PERIODIC ? 3 : 2)) *
184  (fDataPtr->y_grid.num + (fDataPtr->yBC.lCode == PERIODIC ? 3 : 2));
185  fDataPtr->coefs = new double[n];
186  for (int i = 0; i < n; ++i)
187  fDataPtr->coefs[i] = other.fDataPtr->coefs[i];
188  }
189  return *this;
190  }
191 
192  double
193  operator()(const double x, const double y)
194  const
195  {
196  if (!fDataPtr)
197  throw utl::InvalidConfigurationException("no data for spline interpolator");
198  if (x < fDataPtr->x_grid.start || x > fDataPtr->x_grid.end)
199  throw utl::OutOfBoundException("x argument is outside of interpolation range");
200  if (y < fDataPtr->y_grid.start || y > fDataPtr->y_grid.end)
201  throw utl::OutOfBoundException("y argument is outside of interpolation range");
202 
203  double result;
204  eval_UBspline_2d_d(fDataPtr, x, y, &result);
205  return result;
206  }
207 
208  double
209  GetStart(const unsigned char dimension)
210  const
211  {
212  if (!fDataPtr)
213  throw utl::InvalidConfigurationException("no data for spline interpolator");
214  switch (dimension) {
215  case 0:
216  return fDataPtr->x_grid.start;
217  case 1:
218  return fDataPtr->y_grid.start;
219  default:
220  throw utl::DoesNotComputeException("dimension is too large");
221  }
222  return 0;
223  }
224 
225  double
226  GetStop(const unsigned char dimension)
227  const
228  {
229  if (!fDataPtr)
230  throw utl::InvalidConfigurationException("no data for spline interpolator");
231  switch (dimension) {
232  case 0:
233  return fDataPtr->x_grid.end;
234  case 1:
235  return fDataPtr->y_grid.end;
236  default:
237  throw utl::DoesNotComputeException("dimension is too large");
238  }
239  return 0;
240  }
241 
242  protected:
243  UBspline_2d_d* fDataPtr = nullptr;
244  };
245 
246 
248  public:
250 
251  Interpolator3D(const Interpolator3D& other) { *this = other; }
252 
253  Interpolator3D(const double xStart,
254  const double xStop, /* inclusive! */
255  const double yStart,
256  const double yStop, /* inclusive! */
257  const double zStart,
258  const double zStop, /* inclusive! */
259  const boost::multi_array<double,3>& values,
260  const BoundaryCondition bcX = BoundaryCondition(),
261  const BoundaryCondition bcY = BoundaryCondition(),
262  const BoundaryCondition bcZ = BoundaryCondition())
263  {
264  Ugrid grid[3];
265  grid[0].num = values.shape()[0];
266  grid[0].start = xStart;
267  grid[0].end = xStop;
268  grid[1].num = values.shape()[1];
269  grid[1].start = yStart;
270  grid[1].end = yStop;
271  grid[2].num = values.shape()[2];
272  grid[2].start = zStart;
273  grid[2].end = zStop;
274 
275  fDataPtr = create_UBspline_3d_d(grid[0], grid[1], grid[2], bcX, bcY, bcZ, const_cast<double*>(values.data()));
276  }
277 
278  ~Interpolator3D() { destroy_Bspline(fDataPtr); }
279 
281  operator=(const Interpolator3D& other)
282  {
283  if (this != &other) {
284  if (fDataPtr)
285  destroy_Bspline(fDataPtr);
286  fDataPtr = new UBspline_3d_d;
287  *fDataPtr = *other.fDataPtr;
288  const int n =
289  (fDataPtr->x_grid.num + (fDataPtr->xBC.lCode == PERIODIC ? 3 : 2)) *
290  (fDataPtr->y_grid.num + (fDataPtr->yBC.lCode == PERIODIC ? 3 : 2)) *
291  (fDataPtr->z_grid.num + (fDataPtr->zBC.lCode == PERIODIC ? 3 : 2));
292  fDataPtr->coefs = new double[n];
293  for (int i = 0; i < n; ++i)
294  fDataPtr->coefs[i] = other.fDataPtr->coefs[i];
295  }
296  return *this;
297  }
298 
299  double
300  operator()(const double x, const double y, const double z)
301  const
302  {
303  if (!fDataPtr)
304  throw utl::InvalidConfigurationException("no data for spline interpolator");
305  if (x < fDataPtr->x_grid.start || x > fDataPtr->x_grid.end)
306  throw utl::OutOfBoundException("x argument is outside of interpolation range");
307  if (y < fDataPtr->y_grid.start || y > fDataPtr->y_grid.end)
308  throw utl::OutOfBoundException("y argument is outside of interpolation range");
309  if (z < fDataPtr->z_grid.start || z > fDataPtr->z_grid.end)
310  throw utl::OutOfBoundException("z argument is outside of interpolation range");
311 
312  double result;
313  eval_UBspline_3d_d(fDataPtr, x, y, z, &result);
314  return result;
315  }
316 
317  double
318  GetStart(const unsigned char dimension)
319  const
320  {
321  if (!fDataPtr)
322  throw utl::InvalidConfigurationException("no data for spline interpolator");
323  switch (dimension) {
324  case 0:
325  return fDataPtr->x_grid.start;
326  case 1:
327  return fDataPtr->y_grid.start;
328  case 2:
329  return fDataPtr->z_grid.start;
330  default:
331  throw utl::DoesNotComputeException("dimension is too large");
332  }
333  return 0;
334  }
335 
336  double
337  GetStop(const unsigned char dimension)
338  const
339  {
340  if (!fDataPtr)
341  throw utl::InvalidConfigurationException("no data for spline interpolator");
342  switch (dimension) {
343  case 0:
344  return fDataPtr->x_grid.end;
345  case 1:
346  return fDataPtr->y_grid.end;
347  case 2:
348  return fDataPtr->z_grid.end;
349  default:
350  throw utl::DoesNotComputeException("dimension is too large");
351  }
352  return 0;
353  }
354 
355  protected:
356  UBspline_3d_d* fDataPtr = nullptr;
357  };
358 
359 
361  public:
363 
364  VectorInterpolator1D(const VectorInterpolator1D& other) { *this = other; }
365 
366  VectorInterpolator1D(const double xStart,
367  const double xStop, /* inclusive! */
368  const boost::multi_array<double,2>& fValue, // first index is function vector index!
369  const BoundaryCondition& bcX = BoundaryCondition())
370  {
371  Ugrid grid;
372  grid.start = xStart;
373  grid.end = xStop;
374  grid.num = fValue.shape()[1];
375 
376  fDataPtr = create_multi_UBspline_1d_d(grid, bcX, fValue.shape()[0]);
377  for (size_t i = 0; i < fValue.shape()[0]; ++i)
378  set_multi_UBspline_1d_d(fDataPtr, i, const_cast<double*>(fValue.data() + i*grid.num));
379  }
380 
381  ~VectorInterpolator1D() { destroy_Bspline(fDataPtr); }
382 
385  {
386  if (this != &other) {
387  if (fDataPtr)
388  destroy_Bspline(fDataPtr);
389  fDataPtr = new multi_UBspline_1d_d;
390  *fDataPtr = *other.fDataPtr;
391  const int n = fDataPtr->num_splines *
392  (fDataPtr->x_grid.num + (fDataPtr->xBC.lCode == PERIODIC ? 3 : 2));
393  fDataPtr->coefs = new double[n];
394  for (int i = 0; i < n; ++i)
395  fDataPtr->coefs[i] = other.fDataPtr->coefs[i];
396  }
397  return *this;
398  }
399 
400  void
401  operator()(std::vector<double>& result, const double x)
402  const
403  {
404  if (!fDataPtr)
405  throw utl::InvalidConfigurationException("no data for spline interpolator");
406  if (x < fDataPtr->x_grid.start || x > fDataPtr->x_grid.end)
407  throw utl::OutOfBoundException("argument is outside of interpolation range");
408  if (result.size() != size_t(fDataPtr->num_splines))
409  result.resize(fDataPtr->num_splines);
410  eval_multi_UBspline_1d_d(fDataPtr, x, &result[0]);
411  }
412 
413  double
414  GetStart()
415  const
416  {
417  if (!fDataPtr)
418  throw utl::InvalidConfigurationException("no data for spline interpolator");
419  return fDataPtr->x_grid.start;
420  }
421 
422  double
423  GetStop()
424  const
425  {
426  if (!fDataPtr)
427  throw utl::InvalidConfigurationException("no data for spline interpolator");
428  return fDataPtr->x_grid.end;
429  }
430 
431  protected:
432  multi_UBspline_1d_d* fDataPtr = nullptr;
433  };
434 
435 
437  public:
439 
440  VectorInterpolator2D(const VectorInterpolator2D& other) { *this = other; }
441 
442  VectorInterpolator2D(const double xStart,
443  const double xStop, /* inclusive! */
444  const double yStart,
445  const double yStop, /* inclusive! */
446  const boost::multi_array<double,3>& fValue, // first index is function vector index!
447  const BoundaryCondition& bcX = BoundaryCondition(),
448  const BoundaryCondition& bcY = BoundaryCondition())
449  {
450  Ugrid grid[2];
451  grid[0].start = xStart;
452  grid[0].end = xStop;
453  grid[0].num = fValue.shape()[1];
454  grid[1].start = yStart;
455  grid[1].end = yStop;
456  grid[1].num = fValue.shape()[2];
457 
458  fDataPtr = create_multi_UBspline_2d_d(grid[0], grid[1], bcX, bcY, fValue.shape()[0]);
459  for (size_t i = 0; i < fValue.shape()[0]; ++i)
460  set_multi_UBspline_2d_d(fDataPtr, i, const_cast<double*>(fValue.data() + i*grid[0].num*grid[1].num));
461  }
462 
463  ~VectorInterpolator2D() { destroy_Bspline(fDataPtr); }
464 
467  {
468  if (this != &other) {
469  if (fDataPtr)
470  destroy_Bspline(fDataPtr);
471  fDataPtr = new multi_UBspline_2d_d;
472  *fDataPtr = *other.fDataPtr;
473  const int n = fDataPtr->num_splines *
474  (fDataPtr->x_grid.num + (fDataPtr->xBC.lCode == PERIODIC ? 3 : 2)) *
475  (fDataPtr->y_grid.num + (fDataPtr->yBC.lCode == PERIODIC ? 3 : 2));
476  fDataPtr->coefs = new double[n];
477  for (int i = 0; i < n; ++i)
478  fDataPtr->coefs[i] = other.fDataPtr->coefs[i];
479  }
480  return *this;
481  }
482 
483  void
484  operator()(std::vector<double>& result, const double x, const double y)
485  const
486  {
487  if (!fDataPtr)
488  throw utl::InvalidConfigurationException("no data for spline interpolator");
489  if (x < fDataPtr->x_grid.start || x > fDataPtr->x_grid.end)
490  throw utl::OutOfBoundException("x argument is outside of interpolation range");
491  if (y < fDataPtr->y_grid.start || y > fDataPtr->y_grid.end)
492  throw utl::OutOfBoundException("y argument is outside of interpolation range");
493  if (result.size() != size_t(fDataPtr->num_splines))
494  result.resize(fDataPtr->num_splines);
495  eval_multi_UBspline_2d_d(fDataPtr, x, y, &result[0]);
496  }
497 
498  double
499  GetStart(const unsigned char dimension)
500  const
501  {
502  if (!fDataPtr)
503  throw utl::InvalidConfigurationException("no data for spline interpolator");
504  switch (dimension) {
505  case 0:
506  return fDataPtr->x_grid.start;
507  case 1:
508  return fDataPtr->y_grid.start;
509  default:
510  throw utl::DoesNotComputeException("dimension is too large");
511  }
512  return 0;
513  }
514 
515  double
516  GetStop(const unsigned char dimension)
517  const
518  {
519  if (!fDataPtr)
520  throw utl::InvalidConfigurationException("no data for spline interpolator");
521  switch (dimension) {
522  case 0:
523  return fDataPtr->x_grid.end;
524  case 1:
525  return fDataPtr->y_grid.end;
526  default:
527  throw utl::DoesNotComputeException("dimension is too large");
528  }
529  return 0;
530  }
531 
532  protected:
533  multi_UBspline_2d_d* fDataPtr = nullptr;
534  };
535 
536 
538  public:
540 
541  VectorInterpolator3D(const VectorInterpolator3D& other) { *this = other; }
542 
543  VectorInterpolator3D(const double xStart,
544  const double xStop, /* inclusive! */
545  const double yStart,
546  const double yStop, /* inclusive! */
547  const double zStart,
548  const double zStop, /* inclusive! */
549  const boost::multi_array<double,4>& fValue, // first index is function vector index!
550  const BoundaryCondition& bcX = BoundaryCondition(),
551  const BoundaryCondition& bcY = BoundaryCondition(),
552  const BoundaryCondition& bcZ = BoundaryCondition())
553  {
554  Ugrid grid[3];
555  grid[0].start = xStart;
556  grid[0].end = xStop;
557  grid[0].num = fValue.shape()[1];
558  grid[1].start = yStart;
559  grid[1].end = yStop;
560  grid[1].num = fValue.shape()[2];
561  grid[2].start = zStart;
562  grid[2].end = zStop;
563  grid[2].num = fValue.shape()[3];
564 
565  fDataPtr = create_multi_UBspline_3d_d(grid[0], grid[1], grid[2], bcX, bcY, bcZ, fValue.shape()[0]);
566  for (size_t i = 0; i < fValue.shape()[0]; ++i)
567  set_multi_UBspline_3d_d(fDataPtr, i, const_cast<double*>(fValue.data() + i*grid[0].num*grid[1].num*grid[2].num));
568  }
569 
570  ~VectorInterpolator3D() { destroy_Bspline(fDataPtr); }
571 
574  {
575  if (this != &other) {
576  if (fDataPtr)
577  destroy_Bspline(fDataPtr);
578  fDataPtr = new multi_UBspline_3d_d;
579  *fDataPtr = *other.fDataPtr;
580  const int n = fDataPtr->num_splines *
581  (fDataPtr->x_grid.num + (fDataPtr->xBC.lCode == PERIODIC ? 3 : 2)) *
582  (fDataPtr->y_grid.num + (fDataPtr->yBC.lCode == PERIODIC ? 3 : 2)) *
583  (fDataPtr->z_grid.num + (fDataPtr->zBC.lCode == PERIODIC ? 3 : 2));
584  fDataPtr->coefs = new double[n];
585  for (int i = 0; i < n; ++i)
586  fDataPtr->coefs[i] = other.fDataPtr->coefs[i];
587  }
588  return *this;
589  }
590 
591  void
592  operator()(std::vector<double>& result, const double x, const double y, const double z)
593  const
594  {
595  if (!fDataPtr)
596  throw utl::InvalidConfigurationException("no data for spline interpolator");
597  if (x < fDataPtr->x_grid.start || x > fDataPtr->x_grid.end)
598  throw utl::OutOfBoundException("x argument is outside of interpolation range");
599  if (y < fDataPtr->y_grid.start || y > fDataPtr->y_grid.end)
600  throw utl::OutOfBoundException("y argument is outside of interpolation range");
601  if (z < fDataPtr->z_grid.start || z > fDataPtr->z_grid.end)
602  throw utl::OutOfBoundException("z argument is outside of interpolation range");
603  if (result.size() != size_t(fDataPtr->num_splines))
604  result.resize(fDataPtr->num_splines);
605  eval_multi_UBspline_3d_d(fDataPtr, x, y, z, &result[0]);
606  }
607 
608  double
609  GetStart(const unsigned char dimension)
610  const
611  {
612  if (!fDataPtr)
613  throw utl::InvalidConfigurationException("no data for spline interpolator");
614  switch (dimension) {
615  case 0:
616  return fDataPtr->x_grid.start;
617  case 1:
618  return fDataPtr->y_grid.start;
619  case 2:
620  return fDataPtr->z_grid.start;
621  default:
622  throw utl::DoesNotComputeException("dimension is too large");
623  }
624  return 0;
625  }
626 
627  double
628  GetStop(const unsigned char dimension)
629  const
630  {
631  if (!fDataPtr)
632  throw utl::InvalidConfigurationException("no data for spline interpolator");
633  switch (dimension) {
634  case 0:
635  return fDataPtr->x_grid.end;
636  case 1:
637  return fDataPtr->y_grid.end;
638  case 2:
639  return fDataPtr->z_grid.end;
640  default:
641  throw utl::DoesNotComputeException("dimension is too large");
642  }
643  return 0;
644  }
645 
646  protected:
647  multi_UBspline_3d_d* fDataPtr = nullptr;
648  };
649 
650  }
651 
652 }
653 
654 
655 #endif
Interpolator3D(const Interpolator3D &other)
double GetStart(const unsigned char dimension) const
VectorInterpolator2D & operator=(const VectorInterpolator2D &other)
Base class for exceptions arising because configuration data are not valid.
VectorInterpolator1D & operator=(const VectorInterpolator1D &other)
Interpolator2D(const Interpolator2D &other)
double GetStart(const unsigned char dimension) const
VectorInterpolator2D(const VectorInterpolator2D &other)
VectorInterpolator1D(const VectorInterpolator1D &other)
double GetStop(const unsigned char dimension) const
Exception for reporting variable out of valid range.
VectorInterpolator2D(const double xStart, const double xStop, const double yStart, const double yStop, const boost::multi_array< double, 3 > &fValue, const BoundaryCondition &bcX=BoundaryCondition(), const BoundaryCondition &bcY=BoundaryCondition())
VectorInterpolator3D & operator=(const VectorInterpolator3D &other)
Interpolator2D & operator=(const Interpolator2D &other)
void operator()(std::vector< double > &result, const double x, const double y, const double z) const
BoundaryCondition(const Type type=eNatural, const double vLeft=0, const double vRight=0)
const Data result[]
double GetStart(const unsigned char dimension) const
double operator()(const double x, const double y, const double z) const
Interpolator1D(const double xStart, const double xStop, const std::vector< double > &fValue, const BoundaryCondition &bcX=BoundaryCondition())
double GetStop(const unsigned char dimension) const
Base class for inconsistency/illogicality exceptions.
void operator()(std::vector< double > &result, const double x, const double y) const
Interpolator1D & operator=(const Interpolator1D &other)
Interpolator1D(const Interpolator1D &other)
Interpolator3D(const double xStart, const double xStop, const double yStart, const double yStop, const double zStart, const double zStop, const boost::multi_array< double, 3 > &values, const BoundaryCondition bcX=BoundaryCondition(), const BoundaryCondition bcY=BoundaryCondition(), const BoundaryCondition bcZ=BoundaryCondition())
double GetStart(const unsigned char dimension) const
void operator()(std::vector< double > &result, const double x) const
VectorInterpolator3D(const VectorInterpolator3D &other)
VectorInterpolator1D(const double xStart, const double xStop, const boost::multi_array< double, 2 > &fValue, const BoundaryCondition &bcX=BoundaryCondition())
double GetStop(const unsigned char dimension) const
double GetStop(const unsigned char dimension) const
VectorInterpolator3D(const double xStart, const double xStop, const double yStart, const double yStop, const double zStart, const double zStop, const boost::multi_array< double, 4 > &fValue, const BoundaryCondition &bcX=BoundaryCondition(), const BoundaryCondition &bcY=BoundaryCondition(), const BoundaryCondition &bcZ=BoundaryCondition())
Interpolator2D(const double xStart, const double xStop, const double yStart, const double yStop, const boost::multi_array< double, 2 > &values, const BoundaryCondition bcX=BoundaryCondition(), const BoundaryCondition bcY=BoundaryCondition())
double operator()(const double x) const
Interpolator3D & operator=(const Interpolator3D &other)
double operator()(const double x, const double y) const

, generated on Tue Sep 26 2023.