QMCPACK
CubicSpline.h
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////////////////////
2 // This file is distributed under the University of Illinois/NCSA Open Source License.
3 // See LICENSE file in top directory for details.
4 //
5 // Copyright (c) 2016 Jeongnim Kim and QMCPACK developers.
6 //
7 // File developed by: Paul R. C. Kent, kentpr@ornl.gov, Oak Ridge National Laboratory
8 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
9 //
10 // File created by: Paul R. C. Kent, kentpr@ornl.gov, Oak Ridge National Laboratory
11 //////////////////////////////////////////////////////////////////////////////////////
12 
13 
14 #ifndef CUB_SPLINE_H
15 #define CUB_SPLINE_H
16 
17 #include "GeneralGrid.h"
18 #include <iostream>
19 #include <cstdlib>
20 
21 
22 /// The CubSpline class is a third-order spline representation of a
23 /// function. It stores a pointer to a grid and the values of the
24 /// function and its second derivative at the points defined by the
25 /// grid.
26 class CubSpline
27 {
28 private:
29  /// This flag records whether or not the stored second derivatives
30  /// are in sync with the function values. It is used to determine
31  /// whether the second derivatives need recomputation.
32  bool UpToDate;
33  /// The function values on the grid points.
34  std::vector<double> y;
35  /// The second derivatives of the function
36  std::vector<double> d2y;
37 
38  /// The values of the derivative of the represented function on the
39  /// boundary. If each value is greater that 1e30, we compute
40  /// boundary conditions assuming that the second derivative is zero at
41  /// that boundary.
43 
44 public:
47 
48  /// Returns the interpolated value.
49  inline int size() { return grid.NumPoints(); }
50  inline double operator()(double x);
51  /// Returns the interpolated first derivative.
52  inline double Deriv(double x);
53  /// Returns the interpolated second derivative.
54  inline double Deriv2(double x);
55  /// Returns the interpolated third derivative.
56  inline double Deriv3(double x);
57  /// Recompute the second derivatives from the function values
58  void Update();
59  inline std::vector<double>& Data() { return y; }
60 
61  /// Initialize the cubic spline. See notes about start and end
62  /// deriv above.
63  inline void Init(SimpleGrid& newGrid, std::vector<double> yvals, double startderiv, double endderiv)
64  {
65  StartDeriv = startderiv;
66  EndDeriv = endderiv;
67  if (newGrid.NumPoints() != yvals.size())
68  {
69  std::cerr << "Size mismatch in CubSpline.\n";
70  std::cerr << "Grid Points = " << newGrid.NumPoints() << std::endl;
71  std::cerr << "Y points = " << yvals.size() << std::endl;
72  abort();
73  }
74  grid = newGrid;
75  y.resize(grid.NumPoints());
76  d2y.resize(grid.NumPoints());
77  y = yvals;
78  Update();
79  Initialized = true;
80  }
81 
82  /// Simplified form which assumes that the second derivative at both
83  /// boundaries are zero.
84  inline void Init(SimpleGrid& newGrid, std::vector<double>& yvals)
85  {
86  Init(newGrid, yvals, 5.0e30, 5.0e30);
87  Update();
88  }
89 
90  /// Simplified constructor.
91  inline CubSpline(SimpleGrid& newGrid, std::vector<double>& yvals)
92  {
93  StartDeriv = EndDeriv = 5.0e30;
94  Init(newGrid, yvals, 5.0e30, 5.0e30);
95  Update();
96  }
97 
98  /// Full constructor.
99  inline CubSpline(SimpleGrid& newGrid, std::vector<double>& yvals, double startderiv, double endderiv)
100  {
101  Init(newGrid, yvals, startderiv, endderiv);
102  Update();
103  }
104 
105  /// Returns the value of the function at the ith grid point.
106  inline double operator()(int i) const { return (y[i]); }
107  /// Returns a reference to the value at the ith grid point.
108  inline double& operator()(int i)
109  {
110  UpToDate = false;
111  return (y[i]);
112  }
113 
114  /// Trivial constructor
116  {
117  UpToDate = false;
118  Initialized = false;
119  }
120 };
121 
122 inline double CubSpline::operator()(double x)
123 {
124  if (!UpToDate)
125  Update();
126 
127  SimpleGrid& X = grid;
128 #ifdef DEBUG
129  if (x > X.End())
130  {
131  if (x < (X.End() * 1.000000001))
132  x = X.End();
133  else
134  {
135  std::cerr << "x outside grid in CubSpline.\n";
136  std::cerr << "x = " << x << " X.End = " << X.End() << "\n";
137  abort();
138  }
139  }
140 #endif
141  int hi = X.ReverseMap(x) + 1;
142  int low = hi - 1;
143  if (low < 0)
144  {
145  low = 0;
146  hi = 1;
147  }
148  if (hi > (X.NumPoints() - 1))
149  {
150  hi = (X.NumPoints() - 1);
151  low = hi - 1;
152  }
153 
154  double h = X[hi] - X[low];
155  double hinv = 1.0 / h;
156  double a = (X[hi] - x) * hinv;
157  double b = (x - X[low]) * hinv;
158  double sixinv = 0.1666666666666666666;
159 
160  return (a * y[low] + b * y[hi] + ((a * a * a - a) * d2y[low] + (b * b * b - b) * d2y[hi]) * (h * h * sixinv));
161 }
162 
163 double CubSpline::Deriv(double x)
164 {
165  if (!UpToDate)
166  Update();
167 
168  SimpleGrid& X = grid;
169  int hi = X.ReverseMap(x) + 1;
170  int low = hi - 1;
171  if (low < 0)
172  {
173  low = 0;
174  hi = 1;
175  }
176  if (hi > (X.NumPoints() - 1))
177  {
178  hi = (X.NumPoints() - 1);
179  low = hi - 1;
180  }
181 
182  double h = X[hi] - X[low];
183  double hinv = 1.0 / h;
184  double a = (X[hi] - x) * hinv;
185  double b = (x - X[low]) * hinv;
186  double sixinv = 0.1666666666666666666;
187 
188  return ((y[hi] - y[low]) * hinv + (h * sixinv) * ((3.0 * b * b - 1.0) * d2y[hi] - (3.0 * a * a - 1.0) * d2y[low]));
189 }
190 
191 inline double CubSpline::Deriv2(double x)
192 {
193  if (!UpToDate)
194  Update();
195  SimpleGrid& X = grid;
196  int hi = X.ReverseMap(x) + 1;
197  int low = hi - 1;
198  if (low < 0)
199  {
200  low = 0;
201  hi = 1;
202  }
203  if (hi > (X.NumPoints() - 1))
204  {
205  hi = (X.NumPoints() - 1);
206  low = hi - 1;
207  }
208 
209 
210  double h = X[hi] - X[low];
211  double hinv = 1.0 / h;
212  double a = (X[hi] - x) * hinv;
213  double b = (x - X[low]) * hinv;
214  return (a * d2y[low] + b * d2y[hi]);
215 }
216 
217 
218 inline double CubSpline::Deriv3(double x)
219 {
220  if (!UpToDate)
221  Update();
222  SimpleGrid& X = grid;
223  int hi = X.ReverseMap(x) + 1;
224  int low = hi - 1;
225  if (low < 0)
226  {
227  low = 0;
228  hi = 1;
229  }
230  if (hi > (X.NumPoints() - 1))
231  {
232  hi = (X.NumPoints() - 1);
233  low = hi - 1;
234  }
235 
236  double h = X[hi] - X[low];
237 
238  return ((d2y[hi] - d2y[low]) / h);
239 }
240 
241 
242 #endif
double & operator()(int i)
Returns a reference to the value at the ith grid point.
Definition: CubicSpline.h:108
The CubSpline class is a third-order spline representation of a function.
Definition: CubicSpline.h:26
double End()
Definition: GeneralGrid.h:62
double EndDeriv
Definition: CubicSpline.h:42
bool Initialized
Definition: CubicSpline.h:46
SimpleGrid grid
Definition: CubicSpline.h:45
std::vector< double > & Data()
Definition: CubicSpline.h:59
double Deriv2(double x)
Returns the interpolated second derivative.
Definition: CubicSpline.h:191
int size()
Returns the interpolated value.
Definition: CubicSpline.h:49
CubSpline()
Trivial constructor.
Definition: CubicSpline.h:115
bool UpToDate
This flag records whether or not the stored second derivatives are in sync with the function values...
Definition: CubicSpline.h:32
void Init(SimpleGrid &newGrid, std::vector< double > &yvals)
Simplified form which assumes that the second derivative at both boundaries are zero.
Definition: CubicSpline.h:84
int NumPoints()
Definition: GeneralGrid.h:26
double StartDeriv
The values of the derivative of the represented function on the boundary.
Definition: CubicSpline.h:42
double Deriv3(double x)
Returns the interpolated third derivative.
Definition: CubicSpline.h:218
double operator()(double x)
Definition: CubicSpline.h:122
void Update()
Recompute the second derivatives from the function values.
CubSpline(SimpleGrid &newGrid, std::vector< double > &yvals)
Simplified constructor.
Definition: CubicSpline.h:91
std::vector< double > d2y
The second derivatives of the function.
Definition: CubicSpline.h:36
int ReverseMap(double r)
Returns the index of the nearest point below r.
Definition: GeneralGrid.h:33
void Init(SimpleGrid &newGrid, std::vector< double > yvals, double startderiv, double endderiv)
Initialize the cubic spline.
Definition: CubicSpline.h:63
std::vector< double > y
The function values on the grid points.
Definition: CubicSpline.h:34
CubSpline(SimpleGrid &newGrid, std::vector< double > &yvals, double startderiv, double endderiv)
Full constructor.
Definition: CubicSpline.h:99
double Deriv(double x)
Returns the interpolated first derivative.
Definition: CubicSpline.h:163
double operator()(int i) const
Returns the value of the function at the ith grid point.
Definition: CubicSpline.h:106