QMCPACK
CubicSplineCommon.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 // http://pathintegrals.info //
15 /////////////////////////////////////////////////////////////
16 
17 #ifndef CUBIC_SPLINE_COMMON_H
18 #define CUBIC_SPLINE_COMMON_H
19 
20 #include "Grid.h"
21 #include <iostream>
22 
23 
24 /// The CubicSplineCommon class is a third-order spline representation of a
25 /// function. It stores a pointer to a grid and the values of the
26 /// function and its second derivative at the points defined by the
27 /// grid.
29 {
30 private:
31  /// This flag records whether or not the stored second derivatives
32  /// are in sync with the function values. It is used to determine
33  /// whether the second derivatives need recomputation.
34  int UpToDate;
35  /// The function values on the grid points.
37  /// The second derivatives of the function
39 
40 public:
41  int NumParams;
42  std::shared_ptr<Grid> grid;
43  /// The values of the derivative of the represented function on the
44  /// boundary. If each value is greater that 1e30, we compute
45  /// boundary conditions assuming that the second derivative is zero at
46  /// that boundary.
48 
49  inline Array<double, 1>& Data();
50  /// Returns the interpolated value.
51  inline int size() { return grid->NumPoints; }
52  inline double operator()(double x);
53  /// Returns the interpolated first derivative.
54  inline double Deriv(double x);
55  /// Returns the interpolated second derivative.
56  inline double Deriv2(double x);
57  /// Returns the interpolated third derivative.
58  inline double Deriv3(double x);
59  /// Recompute the second derivatives from the function values
60  void Update();
61 
62  /// Initialize the cubic spline. See notes about start and end
63  /// deriv above.
64  inline void Init(std::shared_ptr<Grid>& NewGrid, Array<double, 1> NewYs, double startderiv, double endderiv)
65  {
66  StartDeriv = startderiv;
67  EndDeriv = endderiv;
68  if (NewGrid->NumPoints != NewYs.rows())
69  {
70  std::cerr << "Size mismatch in CubicSplineCommon.\n";
71  std::cerr << "Grid Points = " << NewGrid->NumPoints << std::endl;
72  std::cerr << "Y points = " << NewYs.rows() << std::endl;
73  exit(1);
74  }
75  grid = NewGrid;
76  NumParams = grid->NumPoints;
77  y.resize(grid->NumPoints);
78  d2y.resize(grid->NumPoints);
79  y = NewYs;
80  Update();
81  }
82 
83  /// Simplified form which assumes that the second derivative at both
84  /// boundaries are zero.
85  inline void Init(std::shared_ptr<Grid>& NewGrid, Array<double, 1> NewYs) { Init(NewGrid, NewYs, 5.0e30, 5.0e30); }
86 
87  /// Simplified constructor.
88  inline CubicSplineCommon(std::shared_ptr<Grid>& NewGrid, Array<double, 1> NewYs)
89  {
90  StartDeriv = EndDeriv = 5.0e30;
91  Init(NewGrid, NewYs, 5.0e30, 5.0e30);
92  }
93 
94  /// Full constructor.
95  inline CubicSplineCommon(std::shared_ptr<Grid>& NewGrid, Array<double, 1> NewYs, double startderiv, double endderiv)
96  {
97  Init(NewGrid, NewYs, startderiv, endderiv);
98  Update();
99  }
100 
101  /// Returns the value of the function at the ith grid point.
102  inline double operator()(int i) const { return (y(i)); }
103  /// Returns a reference to the value at the ith grid point.
104  inline double& operator()(int i)
105  {
106  UpToDate = 0;
107  return (y(i));
108  }
109 
110  /// Returns the value of the function at the ith grid point.
111  inline double Params(int i) const { return (y(i)); }
112  /// Returns a reference to the value at the ith grid point.
113  inline double& Params(int i) { return (y(i)); }
114  void Write(IOSectionClass& outSection)
115  {
116  outSection.WriteVar("StartDeriv", StartDeriv);
117  outSection.WriteVar("EndDeriv", EndDeriv);
118  outSection.WriteVar("y", y);
119 
120  outSection.NewSection("Grid");
121  grid->Write(outSection);
122  outSection.CloseSection();
123  }
124  void Read(IOSectionClass& inSection)
125  {
126  assert(inSection.ReadVar("StartDeriv", StartDeriv));
127  assert(inSection.ReadVar("EndDeriv", EndDeriv));
128  assert(inSection.ReadVar("y", y));
129  NumParams = y.size();
131  assert(inSection.OpenSection("Grid"));
132  grid = ReadGrid(inSection);
133  inSection.CloseSection();
134  Update();
135  }
136 
138 
139  /// Trivial constructor
141  {
142  UpToDate = 0;
143  NumParams = 0;
144  StartDeriv = 0;
145  EndDeriv = 0;
146  grid = NULL;
147  }
148 };
149 
150 
152 {
153  UpToDate = false;
154  return y;
155 }
156 
157 
158 inline double CubicSplineCommon::operator()(double x)
159 {
160  if (!UpToDate)
161  Update();
162 
163 
164  Grid& X = *grid;
165 #ifdef BZ_DEBUG
166  if (x > X.End)
167  {
168  if (x < (X.End * 1.000000001))
169  x = X.End;
170  else
171  {
172  std::cerr << "x outside grid in CubicSplineCommon.\n";
173  std::cerr << "x = " << x << " X.End = " << X.End << "\n";
174  abort();
175  }
176  }
177 #endif
178  int hi = X.ReverseMap(x) + 1;
179  int low = hi - 1;
180  if (low < 0)
181  {
182  low = 0;
183  hi = 1;
184  }
185  if (hi > (X.NumPoints - 1))
186  {
187  hi = (X.NumPoints - 1);
188  low = hi - 1;
189  }
190 
191  double h = X(hi) - X(low);
192  double hinv = 1.0 / h;
193  double a = (X(hi) - x) * hinv;
194  double b = (x - X(low)) * hinv;
195  double sixinv = 0.1666666666666666666;
196 
197  return (a * y(low) + b * y(hi) + ((a * a * a - a) * d2y(low) + (b * b * b - b) * d2y(hi)) * (h * h * sixinv));
198 }
199 
200 double CubicSplineCommon::Deriv(double x)
201 {
202  if (!UpToDate)
203  Update();
204 
205  Grid& X = *grid;
206  int hi = X.ReverseMap(x) + 1;
207  int low = hi - 1;
208  if (low < 0)
209  {
210  low = 0;
211  hi = 1;
212  }
213  if (hi > (X.NumPoints - 1))
214  {
215  hi = (X.NumPoints - 1);
216  low = hi - 1;
217  }
218 
219  double h = X(hi) - X(low);
220  double hinv = 1.0 / h;
221  double a = (X(hi) - x) * hinv;
222  double b = (x - X(low)) * hinv;
223  double sixinv = 0.1666666666666666666;
224 
225  return ((y(hi) - y(low)) * hinv + (h * sixinv) * ((3.0 * b * b - 1.0) * d2y(hi) - (3.0 * a * a - 1.0) * d2y(low)));
226 }
227 
228 inline double CubicSplineCommon::Deriv2(double x)
229 {
230  if (!UpToDate)
231  Update();
232  Grid& X = *grid;
233  int hi = X.ReverseMap(x) + 1;
234  int low = hi - 1;
235  if (low < 0)
236  {
237  low = 0;
238  hi = 1;
239  }
240  if (hi > (X.NumPoints - 1))
241  {
242  hi = (X.NumPoints - 1);
243  low = hi - 1;
244  }
245 
246 
247  double h = X(hi) - X(low);
248  double hinv = 1.0 / h;
249  double a = (X(hi) - x) * hinv;
250  double b = (x - X(low)) * hinv;
251  return (a * d2y(low) + b * d2y(hi));
252 }
253 
254 
255 inline double CubicSplineCommon::Deriv3(double x)
256 {
257  if (!UpToDate)
258  Update();
259  Grid& X = *grid;
260  int hi = X.ReverseMap(x) + 1;
261  int low = hi - 1;
262  if (low < 0)
263  {
264  low = 0;
265  hi = 1;
266  }
267  if (hi > (X.NumPoints - 1))
268  {
269  hi = (X.NumPoints - 1);
270  low = hi - 1;
271  }
272 
273  double h = X(hi) - X(low);
274 
275  return ((d2y(hi) - d2y(low)) / h);
276 }
277 
278 #endif
double Params(int i) const
Returns the value of the function at the ith grid point.
Array< double, 1 > d2y
The second derivatives of the function.
std::shared_ptr< Grid > ReadGrid(IOSectionClass &inSection)
Definition: Grid.h:633
void Write(IOSectionClass &outSection)
bool OpenSection(std::string name, int num=0)
Opens the num&#39;th section with the given name.
double StartDeriv
The values of the derivative of the represented function on the boundary.
double Deriv2(double x)
Returns the interpolated second derivative.
Parent class for all grids.
Definition: Grid.h:43
int UpToDate
This flag records whether or not the stored second derivatives are in sync with the function values...
std::shared_ptr< Grid > grid
int NumPoints
Number of points in the grid.
Definition: Grid.h:54
void Read(IOSectionClass &inSection)
void Init(std::shared_ptr< Grid > &NewGrid, Array< double, 1 > NewYs)
Simplified form which assumes that the second derivative at both boundaries are zero.
The CubicSplineCommon class is a third-order spline representation of a function. ...
bool WriteVar(std::string name, T val)
Writes a variable under the current section.
Definition: IO.h:184
void CloseSection()
Closes the current section.
void NewSection(std::string name)
Creates a new section of the same type as currentSection under currentSection.
Definition: IO.h:153
void resize(const std::array< SIZET, D > &dims)
Resize the container.
Definition: OhmmsArray.h:65
Array< double, 1 > y
The function values on the grid points.
void Update()
Recompute the second derivatives from the function values.
double & operator()(int i)
Returns a reference to the value at the ith grid point.
CubicSplineCommon(std::shared_ptr< Grid > &NewGrid, Array< double, 1 > NewYs, double startderiv, double endderiv)
Full constructor.
void Init(std::shared_ptr< Grid > &NewGrid, Array< double, 1 > NewYs, double startderiv, double endderiv)
Initialize the cubic spline.
size_t size() const
Definition: OhmmsArray.h:57
virtual int ReverseMap(double r)=0
Returns the index of the nearest point below r.
Array< double, 1 > & Data()
int size()
Returns the interpolated value.
CubicSplineCommon & operator=(const CubicSplineCommon &spline)
CubicSplineCommon(std::shared_ptr< Grid > &NewGrid, Array< double, 1 > NewYs)
Simplified constructor.
Wrapper class for IOTreeClass that gives a nearly identical interface as the OutputSectionClass.
Definition: IO.h:110
double operator()(double x)
double operator()(int i) const
Returns the value of the function at the ith grid point.
auto rows() const
Definition: Blitz.h:89
CubicSplineCommon()
Trivial constructor.
double Deriv(double x)
Returns the interpolated first derivative.
double End
Definition: Grid.h:51
bool ReadVar(std::string name, T &var)
Template function which reads a variable in the present section into the passed-by-reference T variab...
Definition: IO.h:168
double & Params(int i)
Returns a reference to the value at the ith grid point.
double Deriv3(double x)
Returns the interpolated third derivative.