source: trunk/src/PolynomialInterpolator1D.cpp@ 2730

Last change on this file since 2730 was 2730, checked in by Takeshi Nakazato, 12 years ago

New Development: No

JIRA Issue: Yes CAS-4770

Ready for Test: Yes

Interface Changes: No

What Interface Changed: Please list interface changes

Test Programs: List test programs

Put in Release Notes: Yes/No

Module(s): Module Names change impacts.

Description: Describe your changes here...

Rewrite implementations for locator and interpolator.
Documentation (doxygen format) is added to header files.


File size: 2.3 KB
Line 
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#include <iostream>
15using namespace std;
16
17#include <casa/Exceptions/Error.h>
18
19#include "PolynomialInterpolator1D.h"
20
21namespace asap {
22
23PolynomialInterpolator1D::PolynomialInterpolator1D()
24 : Interpolator1D()
25{}
26
27PolynomialInterpolator1D::~PolynomialInterpolator1D()
28{}
29
30float PolynomialInterpolator1D::interpolate(double x)
31{
32 assert(isready());
33 if (n_ == 1)
34 return y_[0];
35
36 unsigned int i = locator_->locate(x);
37
38 // do not perform extrapolation
39 if (i == 0) {
40 return y_[i];
41 }
42 else if (i == n_) {
43 return y_[i-1];
44 }
45
46 // polynomial interpolation
47 float y;
48 if (order_ >= n_ - 1) {
49 // use full region
50 y = dopoly(x, 0, n_);
51 }
52 else {
53 // use partial region
54 int j = i - 1 - order_ / 2;
55 unsigned int m = n_ - 1 - order_;
56 unsigned int k = (unsigned int)((j > 0) ? j : 0);
57 k = ((k > m) ? m : k);
58 y = dopoly(x, k, order_ + 1);
59 }
60
61 return y;
62}
63
64float PolynomialInterpolator1D::dopoly(double x, unsigned int left,
65 unsigned int n)
66{
67 double *xa = &x_[left];
68 float *ya = &y_[left];
69
70 // storage for C and D in Neville's algorithm
71 float *c = new float[n];
72 float *d = new float[n];
73 for (unsigned int i = 0; i < n; i++) {
74 c[i] = ya[i];
75 d[i] = ya[i];
76 }
77
78 // Neville's algorithm
79 float y = c[0];
80 for (unsigned int m = 1; m < n; m++) {
81 // Evaluate Cm1, Cm2, Cm3, ... Cm[n-m] and Dm1, Dm2, Dm3, ... Dm[n-m].
82 // Those are stored to c[0], c[1], ..., c[n-m-1] and d[0], d[1], ...,
83 // d[n-m-1].
84 for (unsigned int i = 0; i < n - m; i++) {
85 float cd = c[i+1] - d[i];
86 double dx = xa[i] - xa[i+m];
87 try {
88 cd /= dx;
89 }
90 catch (...) {
91 delete[] c;
92 delete[] d;
93 throw casa::AipsError("x_ has duplicate elements");
94 }
95 c[i] = (xa[i] - x) * cd;
96 d[i] = (xa[i+m] - x) * cd;
97 }
98
99 // In each step, c[0] holds Cm1 which is a correction between
100 // P12...m and P12...[m+1]. Thus, the following repeated update
101 // corresponds to the route P1 -> P12 -> P123 ->...-> P123...n.
102 y += c[0];
103 }
104
105 delete[] c;
106 delete[] d;
107
108 return y;
109}
110}
Note: See TracBrowser for help on using the repository browser.