source: trunk/src/PolynomialInterpolator1D.cpp @ 2731

Last change on this file since 2731 was 2730, checked in by Takeshi Nakazato, 11 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.