sisi4s
Loading...
Searching...
No Matches
Interpolation.hpp
Go to the documentation of this file.
1#ifndef INTERPOLATION_DEFINED
2#define INTERPOLATION_DEFINED
3
5#include <iostream>
6#include <string>
7
8// TODO: unify interpolation routines
9
10namespace sisi4s {
11template <typename F = double>
12class Inter1D {
13public:
14 /*when you creat an instance of this class, you need to specify the size
15 of the data set you are interpolating on, and the corresponding x and y
16 */
17 Inter1D(const int size, F *x, F *y) {
18 N = size;
19 xv = new F[N];
20 yv = new F[N];
21 y2d = new F[N];
22 xv = x;
23 yv = y;
24 }
25
26 /*x and y are arrays of the same length, containing the x data and
27 the corresponding values of the function y. They two must be sorted
28 from min to max according to x.N is the length of the two arrays. y1d0 is
29 the 1st derivative of the function at the first point, and y1dn is the 1st
30 derivative of the function at the end of the data. User can specify them two
31 when the BoundaryCondition is set to "M" which stands for Manual, or it can
32 be set to "N" which stands for "Natural". This function returns an array
33 of the second derivatives at each x points, which can be used in
34 CubicSpline_getValue() function to inquire the value at certain point(s).
35 */
36 void cubicSpline(F y1d0 = 0.,
37 F y1dn = 0.,
38 const std::string boundaryCondition = "M") {
39 double u[N];
40 double qn(0.), un(0.), sig(0.), p(0.);
41 if (boundaryCondition == "N") {
42 LOG(1, "Interpolation::cubicSpline") << "Natural" << std::endl;
43 y2d[0] = 0.;
44 u[0] = 0.;
45 } else if (boundaryCondition == "M") {
46 LOG(1, "Interpolation::cubicSpline") << "Manual " << y1d0 << std::endl;
47 y2d[0] = -0.5; // does not really matter, T.B.C
48 u[0] =
49 (3. / (xv[1] - xv[0])) * (((yv[1] - yv[0])) / (xv[1] - xv[0]) - y1d0);
50 qn = 0.5;
51 un = (3. / (xv[N - 1] - xv[N - 2]))
52 * ((yv[N - 1] - yv[N - 2]) / (xv[N - 1] - xv[N - 2]) - y1dn);
53 }
54 for (int i(1); i < N - 1; i++) {
55 sig = (xv[i] - xv[i - 1]) / (xv[i + 1] - xv[i - 1]);
56 p = sig * y2d[i - 1] + 2.;
57 y2d[i] = (sig - 1.) / p;
58 u[i] = (6.
59 * ((yv[i + 1] - yv[i]) / (xv[i + 1] - xv[i])
60 - (yv[i] - yv[i - 1]) / (xv[i] - xv[i - 1]))
61 / (xv[i + 1] - xv[i - 1])
62 - sig * u[i - 1])
63 / p;
64 }
65 y2d[N - 1] = (un - qn * u[N - 2]) / (qn * y2d[N - 2] + 1.);
66 for (int t = N - 2; t >= 0; t--) y2d[t] = y2d[t] * y2d[t + 1] + u[t];
67 }
68 // The max(x) should not larger than max(xv).
69 F getValue(F xinterp) {
70 // LOG(1,"getValue") << "n= " << n << std::endl;
71 // int n=1;
72 double yinterp(0.);
73 double h, a, b;
74 int klow, khigh, k;
75 // y= new double[n];
76 // for (int i(0); i<n; ++i){
77 klow = 0;
78 khigh = N - 1;
79 while ((khigh - klow) > 1) {
80 k = (khigh + klow) / 2;
81 if (xv[k - 1] > xinterp) khigh = k;
82 else klow = k;
83 }
84 h = xv[khigh - 1] - xv[klow - 1];
85 if (abs(h) < 1e-12) {
86 LOG(1, "CubicSpline_getValue") << "Same x points in x data!"
87 << "STOP!" << std::endl;
88 exit(0);
89 }
90 a = (xv[khigh - 1] - xinterp) / h;
91 b = (xinterp - xv[klow - 1]) / h;
92 yinterp =
93 a * yv[klow - 1] + b * yv[khigh - 1]
94 + ((a * a * a - a) * y2d[klow - 1] + (b * b * b - b) * y2d[khigh - 1])
95 * (h * h) / 6.;
96 //}
97 return yinterp;
98 }
99 int N;
100 F *xv, *yv, *y2d;
101};
102} // namespace sisi4s
103
104#endif
#define LOG(...)
Definition Log.hpp:119
Definition Interpolation.hpp:12
F getValue(F xinterp)
Definition Interpolation.hpp:69
F * yv
Definition Interpolation.hpp:100
int N
Definition Interpolation.hpp:99
Inter1D(const int size, F *x, F *y)
Definition Interpolation.hpp:17
F * xv
Definition Interpolation.hpp:100
F * y2d
Definition Interpolation.hpp:100
void cubicSpline(F y1d0=0., F y1dn=0., const std::string boundaryCondition="M")
Definition Interpolation.hpp:36
Definition Algorithm.hpp:10
F abs(F const x)
Definition MathFunctions.hpp:29