1 | // |
---|
2 | // C++ Implementation: PolynomialInterpolator1D |
---|
3 | // |
---|
4 | // Description: |
---|
5 | // |
---|
6 | // |
---|
7 | // Author: Takeshi Nakazato <takeshi.nakazato@nao.ac.jp>, (C) 2012 |
---|
8 | // |
---|
9 | // Copyright: See COPYING file that comes with this distribution |
---|
10 | // |
---|
11 | // |
---|
12 | #include <assert.h> |
---|
13 | #include <math.h> |
---|
14 | |
---|
15 | #include "PolynomialInterpolator1D.h" |
---|
16 | |
---|
17 | namespace asap { |
---|
18 | |
---|
19 | PolynomialInterpolator1D::PolynomialInterpolator1D() |
---|
20 | : Interpolator1D() |
---|
21 | {} |
---|
22 | |
---|
23 | PolynomialInterpolator1D::~PolynomialInterpolator1D() |
---|
24 | {} |
---|
25 | |
---|
26 | float PolynomialInterpolator1D::interpolate(double x) |
---|
27 | { |
---|
28 | assert(isready()); |
---|
29 | if (n_ == 1) |
---|
30 | return y_[0]; |
---|
31 | |
---|
32 | unsigned int i = locator_->locate(x); |
---|
33 | |
---|
34 | // do not perform extrapolation |
---|
35 | if (i == 0) { |
---|
36 | return y_[i]; |
---|
37 | } |
---|
38 | else if (i == n_) { |
---|
39 | return y_[i-1]; |
---|
40 | } |
---|
41 | |
---|
42 | // polynomial interpolation |
---|
43 | float y; |
---|
44 | if (order_ >= n_ - 1) { |
---|
45 | y = polint(x, i, 0, n_); |
---|
46 | } |
---|
47 | else { |
---|
48 | int j = i - 1 - order_ / 2; |
---|
49 | unsigned int m = n_ - 1 - order_; |
---|
50 | unsigned int k = (unsigned int)((j > 0) ? j : 0); |
---|
51 | k = ((k > m) ? m : k); |
---|
52 | y = polint(x, i, k, order_ + 1); |
---|
53 | } |
---|
54 | |
---|
55 | return y; |
---|
56 | } |
---|
57 | |
---|
58 | float PolynomialInterpolator1D::polint(double x, unsigned int loc, |
---|
59 | unsigned int left, unsigned int n) |
---|
60 | { |
---|
61 | int ns = loc - left; |
---|
62 | if (fabs(x - x_[loc]) >= fabs(x - x_[loc-1])) { |
---|
63 | ns--; |
---|
64 | } |
---|
65 | |
---|
66 | double *xa = &x_[left]; |
---|
67 | float *ya = &y_[left]; |
---|
68 | |
---|
69 | float y = ya[ns]; |
---|
70 | |
---|
71 | // c stores C11, C21, C31, ..., C[n-1]1 |
---|
72 | // d stores D11, D21, D31, ..., D[n-1]1 |
---|
73 | float *c = new float[n]; |
---|
74 | float *d = new float[n]; |
---|
75 | for (unsigned int i = 0; i < n; i++) { |
---|
76 | c[i] = ya[i]; |
---|
77 | d[i] = ya[i]; |
---|
78 | } |
---|
79 | |
---|
80 | for (unsigned int m = 1; m < n; m++) { |
---|
81 | for (unsigned int i = 0; i < n - m; i++) { |
---|
82 | double ho = xa[i] - x; |
---|
83 | double hp = xa[i+m] - x; |
---|
84 | float w = c[i+1] - d[i]; |
---|
85 | double denom = ho - hp; |
---|
86 | if (denom == 0.0) { |
---|
87 | delete[] c; |
---|
88 | delete[] d; |
---|
89 | assert(denom != 0.0); |
---|
90 | } |
---|
91 | denom = w / denom; |
---|
92 | |
---|
93 | d[i] = hp * denom; |
---|
94 | c[i] = ho * denom; |
---|
95 | } |
---|
96 | |
---|
97 | float dy; |
---|
98 | if (2 * ns < (int)(n - m)) { |
---|
99 | dy = c[ns]; |
---|
100 | } |
---|
101 | else { |
---|
102 | dy = d[ns-1]; |
---|
103 | ns--; |
---|
104 | } |
---|
105 | y += dy; |
---|
106 | } |
---|
107 | |
---|
108 | delete[] c; |
---|
109 | delete[] d; |
---|
110 | |
---|
111 | return y; |
---|
112 | } |
---|
113 | } |
---|