libpspm
Spline Class Reference

#include <cubic_spline.h>

Collaboration diagram for Spline:
[legend]

Public Types

enum  Type { LINEAR, CUBIC, CONSTRAINED_CUBIC }
 
enum  Extr { ZERO, CONSTANT, QUADRATIC }
 

Public Member Functions

template<typename Container >
void set_points (const Container &x, const Container &y)
 
void solve_coeffs_linear ()
 
void solve_coeffs_cubic ()
 
void solve_coeffs_constrained_cubic ()
 
template<typename Container >
void constructAndReset (const Container &x, const Container &y)
 
Float extrapolate_left (double x) const
 
Float extrapolate_right (double x) const
 
Float eval (Float x) const
 
Float eval (Float x, int idx) const
 
void print ()
 

Public Attributes

int npoints
 
Type splineType = CUBIC
 
Extr extrapolate = CONSTANT
 

Protected Attributes

std::vector< Floatm_a
 
std::vector< Floatm_b
 
std::vector< Floatm_c
 
std::vector< Floatm_x
 
std::vector< Floatm_y
 

Detailed Description

Definition at line 121 of file cubic_spline.h.

Member Enumeration Documentation

◆ Extr

Enumerator
ZERO 
CONSTANT 
QUADRATIC 

Definition at line 127 of file cubic_spline.h.

◆ Type

Enumerator
LINEAR 
CUBIC 
CONSTRAINED_CUBIC 

Definition at line 125 of file cubic_spline.h.

Member Function Documentation

◆ constructAndReset()

template<typename Container >
void Spline::constructAndReset ( const Container &  x,
const Container &  y 
)
inline

Definition at line 246 of file cubic_spline.h.

246  { // construct should be able to take any containers, as the points will be copied to the Spline's own storage anyway
247  set_points(x,y);
248  }
void set_points(const Container &x, const Container &y)
Definition: cubic_spline.h:139
Here is the call graph for this function:

◆ eval() [1/2]

Float Spline::eval ( Float  x) const
inline

Definition at line 268 of file cubic_spline.h.

268  {
269  size_t n=m_x.size();
270 
271  if(x<m_x[0]) return extrapolate_left(x);
272  else if(x>=m_x[n-1]) return extrapolate_right(x);
273  else {
274  // find the closest point m_x[idx] < x
275 // std::vector<double>::const_iterator it;
276 // it=std::lower_bound(m_x.begin(),m_x.end(),x);
277 // int idx=std::max( int(it-m_x.begin())-1, 0);
278  int it = my_lower_bound(x, m_x.data(), m_x.size());
279  int idx=std::max(it-1,0); //std::max(it-1, 0);
280 // int it_ub = my_upper_bound(x, m_x.data(), m_x.size());
281 // int idx_ub=it_ub-1; //std::max(it_ub-1, 0);
282 // std::cout << "x: " << x << " " << idx << " " << idx_ub << endl;
283 
284  return eval(x,idx);
285  }
286  }
Float extrapolate_right(double x) const
Definition: cubic_spline.h:258
std::vector< Float > m_x
Definition: cubic_spline.h:135
Float extrapolate_left(double x) const
Definition: cubic_spline.h:250
int my_lower_bound(const T &val, const T *arr, const int arrlen)
Definition: cubic_spline.h:63
Float eval(Float x) const
Definition: cubic_spline.h:268
Here is the call graph for this function:
Here is the caller graph for this function:

◆ eval() [2/2]

Float Spline::eval ( Float  x,
int  idx 
) const
inline

Definition at line 288 of file cubic_spline.h.

288  {
289  double h=x-m_x[idx];
290  return ((m_a[idx]*h + m_b[idx])*h + m_c[idx])*h + m_y[idx];
291  }
std::vector< Float > m_x
Definition: cubic_spline.h:135
std::vector< Float > m_a
Definition: cubic_spline.h:134
std::vector< Float > m_y
Definition: cubic_spline.h:135
std::vector< Float > m_b
Definition: cubic_spline.h:134
std::vector< Float > m_c
Definition: cubic_spline.h:134

◆ extrapolate_left()

Float Spline::extrapolate_left ( double  x) const
inline

Definition at line 250 of file cubic_spline.h.

250  {
251  double h=x-m_x[0];
252  // extrapolation to the left
253  if (extrapolate == ZERO) return 0; // zero
254  else if (extrapolate == CONSTANT) return m_y[0]; // constant
255  else return ((m_b[0])*h + m_c[0])*h + m_y[0]; // quadratic
256  }
std::vector< Float > m_x
Definition: cubic_spline.h:135
Extr extrapolate
Definition: cubic_spline.h:128
std::vector< Float > m_y
Definition: cubic_spline.h:135
std::vector< Float > m_b
Definition: cubic_spline.h:134
std::vector< Float > m_c
Definition: cubic_spline.h:134
Here is the caller graph for this function:

◆ extrapolate_right()

Float Spline::extrapolate_right ( double  x) const
inline

Definition at line 258 of file cubic_spline.h.

258  {
259  size_t n=m_x.size();
260  double h=x-m_x[n-1];
261  // extrapolation to the right
262  if (extrapolate == ZERO) return 0; // zero
263  else if (extrapolate == CONSTANT) return m_y[n-1]; // constant
264  else return ((m_b[n-1])*h + m_c[n-1])*h + m_y[n-1]; // quadratic
265 
266  }
std::vector< Float > m_x
Definition: cubic_spline.h:135
Extr extrapolate
Definition: cubic_spline.h:128
std::vector< Float > m_y
Definition: cubic_spline.h:135
std::vector< Float > m_b
Definition: cubic_spline.h:134
std::vector< Float > m_c
Definition: cubic_spline.h:134
Here is the caller graph for this function:

◆ print()

void Spline::print ( )
inline

Definition at line 293 of file cubic_spline.h.

293  {
294  std::cout << "Spline: \n";
295  for (int i=0; i<npoints; ++i){
296  std::cout << std::right << std::setw(10) << std::setfill(' ') << m_x[i] << " "
297  << std::right << std::setw(10) << std::setfill(' ') << m_y[i] << " "
298  << std::right << std::setw(10) << std::setfill(' ') << m_a[i] << " "
299  << std::right << std::setw(10) << std::setfill(' ') << m_b[i] << " "
300  << std::right << std::setw(10) << std::setfill(' ') << m_c[i] << " "
301  << "\n";
302  }
303  std:: cout << std::endl;
304  }
int npoints
Definition: cubic_spline.h:123
std::vector< Float > m_x
Definition: cubic_spline.h:135
std::vector< Float > m_a
Definition: cubic_spline.h:134
std::vector< Float > m_y
Definition: cubic_spline.h:135
std::vector< Float > m_b
Definition: cubic_spline.h:134
std::vector< Float > m_c
Definition: cubic_spline.h:134

◆ set_points()

template<typename Container >
void Spline::set_points ( const Container &  x,
const Container &  y 
)
inline

Definition at line 139 of file cubic_spline.h.

139  { // construct should be able to take any containers, as the points will be copied to the Spline's own storage anyway
140  assert(x.size() == y.size());
141  m_x.assign(x.begin(), x.end());
142  m_y.assign(y.begin(), y.end());
143 
144  npoints = x.size();
145  m_a.resize(npoints);
146  m_b.resize(npoints);
147  m_c.resize(npoints);
148 
149  // Check that x is in increasing order
150  for(int i=0; i<npoints-1; i++) {
151  assert(m_x[i]<m_x[i+1]);
152  }
153 
154  if( splineType == CUBIC) { // cubic spline interpolation
156  }
157  else if (splineType == LINEAR) { // linear interpolation
159  }
160  else if (splineType == CONSTRAINED_CUBIC){
162  }
163 
164  }
void solve_coeffs_linear()
Definition: cubic_spline.h:167
int npoints
Definition: cubic_spline.h:123
std::vector< Float > m_x
Definition: cubic_spline.h:135
void solve_coeffs_constrained_cubic()
Definition: cubic_spline.h:219
void solve_coeffs_cubic()
Definition: cubic_spline.h:179
std::vector< Float > m_a
Definition: cubic_spline.h:134
std::vector< Float > m_y
Definition: cubic_spline.h:135
Type splineType
Definition: cubic_spline.h:126
std::vector< Float > m_b
Definition: cubic_spline.h:134
std::vector< Float > m_c
Definition: cubic_spline.h:134
Here is the call graph for this function:
Here is the caller graph for this function:

◆ solve_coeffs_constrained_cubic()

void Spline::solve_coeffs_constrained_cubic ( )
inline

Definition at line 219 of file cubic_spline.h.

219  {
220  int n = npoints;
221 
222  std::vector <double> m(n);
223  for (int i=1; i<n-1; ++i){
224  double fplus = (m_y[i+1]-m_y[i])/(m_x[i+1]-m_x[i]);
225  double fminus = (m_y[i]-m_y[i-1])/(m_x[i]-m_x[i-1]);
226  if (fplus*fminus < 0) m[i] = 0;
227  else m[i] = 2/(1/fplus + 1/fminus); // harmonic mean will tend towards smaller derivative
228  //else m[i] = (fplus+fminus)/2;
229  }
230  // Boundary conditions: zero curvature at x0 and xN-1
231  m[0] = 3*(m_y[1]-m_y[0])/(m_x[1]-m_x[0])/2 - m[1]/2;
232  m[n-1] = 3*(m_y[n-1]-m_y[n-2])/(m_x[n-1]-m_x[n-2])/2 - m[n-2]/2;
233 
234  for (int i=0; i<n-1; ++i){
235  m_c[i] = m[i];
236  double hi = m_x[i+1]-m_x[i];
237  m_b[i] = ( 3*(m_y[i+1]-m_y[i] - m[i]*hi) - hi*(m[i+1]-m[i]))/hi/hi;
238  m_a[i] = (-2*(m_y[i+1]-m_y[i] - m[i]*hi) + hi*(m[i+1]-m[i]))/hi/hi/hi;
239  }
240  m_b[n-1] = 0;
241  m_c[n-1] = m[n-1];
242  }
int npoints
Definition: cubic_spline.h:123
std::vector< Float > m_x
Definition: cubic_spline.h:135
std::vector< Float > m_a
Definition: cubic_spline.h:134
std::vector< Float > m_y
Definition: cubic_spline.h:135
std::vector< Float > m_b
Definition: cubic_spline.h:134
std::vector< Float > m_c
Definition: cubic_spline.h:134
Here is the caller graph for this function:

◆ solve_coeffs_cubic()

void Spline::solve_coeffs_cubic ( )
inline

Definition at line 179 of file cubic_spline.h.

179  {
180  int n = npoints;
181  // setting up the matrix and right hand side of the equation system
182  // for the parameters b[]
183  //band_matrix A(n,1,1);
184  std::vector <Float> l(n,0), m(n,0), u(n,0); // lower, middle, and upper diagonals of thr matrix. These hold coefficients of b{i-1}, b{i}, b{i+1} respectively
185  std::vector<double> rhs(n);
186  for(int i=1; i<n-1; i++) {
187  l[i] =1.0/3.0*(m_x[i]-m_x[i-1]);
188  m[i] =2.0/3.0*(m_x[i+1]-m_x[i-1]);
189  u[i] =1.0/3.0*(m_x[i+1]-m_x[i]);
190  rhs[i]=(m_y[i+1]-m_y[i])/(m_x[i+1]-m_x[i]) - (m_y[i]-m_y[i-1])/(m_x[i]-m_x[i-1]);
191  }
192  // boundary conditions, zero curvature b[0]=b[n-1]=0
193  m[0] = 2.0;
194  u[0] = 0.0;
195  rhs[0] = 0.0;
196  m[n-1] = 2.0;
197  l[n-1] = 0.0;
198  rhs[n-1] = 0.0;
199 
200  // solve the equation system to obtain the parameters b[]
201  thomas_solve(l.data(),m.data(),u.data(),rhs.data(),n);
202  m_b = rhs;
203 
204  // calculate parameters a[] and c[] based on b[]
205  for(int i=0; i<n-1; i++) {
206  m_a[i]=1.0/3.0*(m_b[i+1]-m_b[i])/(m_x[i+1]-m_x[i]);
207  m_c[i]=(m_y[i+1]-m_y[i])/(m_x[i+1]-m_x[i])
208  - 1.0/3.0*(2.0*m_b[i]+m_b[i+1])*(m_x[i+1]-m_x[i]);
209  }
210  // for the right boundary we define
211  // f_{n-1}(x) = b*(x-x_{n-1})^2 + c*(x-x_{n-1}) + y_{n-1}
212  double h=m_x[n-1]-m_x[n-2];
213  // m_b[n-1] is determined by the boundary condition (turns out to be 0; = 0 for 0 curvature at xn-1)
214  m_a[n-1] = 0.0;
215  m_c[n-1]=3.0*m_a[n-2]*h*h+2.0*m_b[n-2]*h+m_c[n-2]; // = f'_{n-2}(x_{n-1})
216  }
int npoints
Definition: cubic_spline.h:123
std::vector< Float > m_x
Definition: cubic_spline.h:135
std::vector< Float > m_a
Definition: cubic_spline.h:134
std::vector< Float > m_y
Definition: cubic_spline.h:135
void thomas_solve(double *a, double *b, double *c, double *d, int n)
Definition: cubic_spline.h:35
std::vector< Float > m_b
Definition: cubic_spline.h:134
std::vector< Float > m_c
Definition: cubic_spline.h:134
Here is the call graph for this function:
Here is the caller graph for this function:

◆ solve_coeffs_linear()

void Spline::solve_coeffs_linear ( )
inline

Definition at line 167 of file cubic_spline.h.

167  {
168  int n = npoints;
169  for(int i=0; i<n-1; i++) {
170  m_a[i]=0.0;
171  m_b[i]=0.0;
172  m_c[i]=(m_y[i+1]-m_y[i])/(m_x[i+1]-m_x[i]);
173  }
174  m_a[n-1] = m_b[n-1] = 0.0;
175  m_c[n-1] = m_c[n-2]; // fn-1 is same as fn-2 - same line extends right for extrapolation
176  }
int npoints
Definition: cubic_spline.h:123
std::vector< Float > m_x
Definition: cubic_spline.h:135
std::vector< Float > m_a
Definition: cubic_spline.h:134
std::vector< Float > m_y
Definition: cubic_spline.h:135
std::vector< Float > m_b
Definition: cubic_spline.h:134
std::vector< Float > m_c
Definition: cubic_spline.h:134
Here is the caller graph for this function:

Member Data Documentation

◆ extrapolate

Extr Spline::extrapolate = CONSTANT

Definition at line 128 of file cubic_spline.h.

◆ m_a

std::vector<Float> Spline::m_a
protected

Definition at line 134 of file cubic_spline.h.

◆ m_b

std::vector<Float> Spline::m_b
protected

Definition at line 134 of file cubic_spline.h.

◆ m_c

std::vector<Float> Spline::m_c
protected

Definition at line 134 of file cubic_spline.h.

◆ m_x

std::vector<Float> Spline::m_x
protected

Definition at line 135 of file cubic_spline.h.

◆ m_y

std::vector<Float> Spline::m_y
protected

Definition at line 135 of file cubic_spline.h.

◆ npoints

int Spline::npoints

Definition at line 123 of file cubic_spline.h.

◆ splineType

Type Spline::splineType = CUBIC

Definition at line 126 of file cubic_spline.h.


The documentation for this class was generated from the following file: