source: trunk/src/CubicSplineInterpolator1D.cpp @ 2727

Last change on this file since 2727 was 2727, checked in by Takeshi Nakazato, 11 years ago

New Development: No

JIRA Issue: Yes CAS-4770, CAS-4774

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...

Updated STApplyCal to be able to specify interpolation method.
The method can be specified in time and frequency axes independently.
Possible options are nearest, linear (default), (natural) cubic spline,
and polynomial with arbitrary order.

File size: 2.1 KB
Line 
1//
2// C++ Implementation: CubicSplineInterpolator1D
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
14#include <iostream>
15using namespace std;
16
17#include "CubicSplineInterpolator1D.h"
18
19namespace asap {
20
21CubicSplineInterpolator1D::CubicSplineInterpolator1D()
22  : Interpolator1D(),
23    y2_(0),
24    ny2_(0),
25    reusable_(false)
26{}
27
28CubicSplineInterpolator1D::~CubicSplineInterpolator1D()
29{
30  if (y2_)
31    delete[] y2_;
32}
33
34void CubicSplineInterpolator1D::setY(float *y, unsigned int n)
35{
36  Interpolator1D::setY(y, n);
37  reusable_ = false;
38}
39
40float CubicSplineInterpolator1D::interpolate(double x)
41{
42  assert(isready());
43  if (n_ == 1)
44    return y_[0];
45
46  unsigned int i = locator_->locate(x);
47
48  // do not perform extrapolation
49  if (i == 0) {
50    return y_[i];
51  }
52  else if (i == n_) {
53    return y_[i-1];
54  }
55
56  // determine second derivative of each point
57  if (!reusable_) {
58    spline();
59    reusable_ = true;
60  }
61
62  // cubic spline interpolation
63  float y = splint(x, i);
64  return y;
65}
66
67void CubicSplineInterpolator1D::spline()
68{
69  if (n_ > ny2_) {
70    if (y2_)
71      delete[] y2_;
72    y2_ = new float[n_];
73    ny2_ = n_;
74  }
75
76  float *u = new float[ny2_-1];
77  y2_[0] = 0.0;
78  u[0] = 0.0;
79
80  for (unsigned int i = 1; i < ny2_ - 1; i++) {
81    double sig = (x_[i] - x_[i-1]) / (x_[i+1] - x_[i-1]);
82    double p = sig * y2_[i-1] + 2.0;
83    y2_[i] = (sig - 1.0) / p;
84    u[i] = (y_[i+1] - y_[i]) / (x_[i+1] - x_[i])
85      - (y_[i] - y_[i-1]) / (x_[i] - x_[i-1]);
86    u[i] = (6.0 * u[i] / (x_[i+1] - x_[i-1]) - sig * u[i-1]) / p;
87  }
88
89  y2_[ny2_-1] = 0.0;
90
91  for (int k = ny2_ - 2; k >= 0; k--)
92    y2_[k] = y2_[k] * y2_[k+1] + u[k];
93
94  delete[] u;
95}
96
97float CubicSplineInterpolator1D::splint(double x, unsigned int i)
98{
99  unsigned int j = i - 1;
100  double h = x_[i] - x_[j];
101  double a = (x_[i] - x) / h;
102  double b = (x - x_[j]) / h;
103  float y = a * y_[j] + b * y_[i] +
104    ((a * a * a - a) * y2_[j] + (b * b * b - b) * y2_[i]) * (h * h) / 6.0;
105  return y;
106}
107
108}
Note: See TracBrowser for help on using the repository browser.