QMCPACK
test_one_dim_cubic_spline.cpp
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) 2019 Jeongnim Kim and QMCPACK developers.
6 //
7 // File developed by: Mark Dewing, mdewing@anl.gov, Argonne National Laboratory
8 //
9 // File created by: Mark Dewing, mdewing@anl.gov, Argonne National Laboratory
10 //////////////////////////////////////////////////////////////////////////////////////
11 
12 #include "catch.hpp"
14 
15 #include <stdio.h>
16 #include <string>
17 
18 using std::string;
19 
20 namespace qmcplusplus
21 {
22 // Generated from gen_cubic_spline.py
23 TEST_CASE("spline_function_1", "[numerics]")
24 {
25  const int n = 3;
26  double x[n] = {0.0, 1.0, 2.0};
27  double y[n] = {1.0, 2.0, 1.5};
28  double y2[n];
29 
30  CubicSplineSolve(x, y, n, 1e+33, 1e+33, y2);
31 
32  CHECK(y2[0] == Approx(0));
33  CHECK(y2[1] == Approx(-2.25));
34  CHECK(y2[2] == Approx(0));
35 }
36 
37 
38 // Generated from gen_cubic_spline.py
39 TEST_CASE("spline_function_2", "[numerics]")
40 {
41  const int n = 3;
42  double x[n] = {0.0, 1.0, 2.0};
43  double y[n] = {1.0, 2.0, 1.5};
44  double y2[n];
45 
46  CubicSplineSolve(x, y, n, 1e+33, 1.0, y2);
47 
48  CHECK(y2[0] == Approx(0));
49  CHECK(y2[1] == Approx(-3.85714));
50  CHECK(y2[2] == Approx(6.42857));
51 }
52 
53 
54 // Generated from gen_cubic_spline.py
55 TEST_CASE("spline_function_3", "[numerics]")
56 {
57  const int n = 3;
58  double x[n] = {0.0, 1.0, 2.0};
59  double y[n] = {1.0, 2.0, 1.5};
60  double y2[n];
61 
62  CubicSplineSolve(x, y, n, 1.0, 2.0, y2);
63 
64  CHECK(y2[0] == Approx(2.75));
65  CHECK(y2[1] == Approx(-5.5));
66  CHECK(y2[2] == Approx(10.25));
67 }
68 
69 
70 // Generated from gen_cubic_spline.py
71 TEST_CASE("spline_function_4", "[numerics]")
72 {
73  const int n = 4;
74  double x[n] = {0.0, 1.2, 2.4, 3.0};
75  double y[n] = {1.0, 2.0, 1.5, 1.8};
76  double y2[n];
77 
78  CubicSplineSolve(x, y, n, 1e+33, 1e+33, y2);
79 
80  CHECK(y2[0] == Approx(0));
81  CHECK(y2[1] == Approx(-2.12121));
82  CHECK(y2[2] == Approx(2.23485));
83  CHECK(y2[3] == Approx(0));
84 }
85 
86 
87 // Generated from gen_cubic_spline.py
88 TEST_CASE("spline_function_5", "[numerics]")
89 {
90  const int n = 4;
91  double x[n] = {0.0, 1.2, 2.4, 3.0};
92  double y[n] = {1.0, 2.0, 1.5, 1.8};
93  double y2[n];
94 
95  CubicSplineSolve(x, y, n, 0.0, 1.0, y2);
96 
97  CHECK(y2[0] == Approx(3.60507));
98  CHECK(y2[1] == Approx(-3.04348));
99  CHECK(y2[2] == Approx(2.31884));
100  CHECK(y2[3] == Approx(1.34058));
101 }
102 
103 
104 // Structure for holding value, first and second derivatives
105 struct D2U
106 {
107  D2U(double val_, double du_, double d2u_) : val(val_), du(du_), d2u(d2u_) {}
108  double val;
109  double du;
110  double d2u;
111 };
112 
113 
114 // Generated from gen_cubic_spline.py
115 TEST_CASE("one_dim_cubic_spline_1", "[numerics]")
116 {
117  const int n = 3;
118  std::vector<double> yvals = {1.0, 2.0, 1.5};
119 
120  auto grid = std::make_unique<LinearGrid<double>>();
121  grid->set(0.0, 2.0, n);
122 
123  OneDimCubicSpline<double> cubic_spline(std::move(grid), yvals);
124 
125  int imin = 0;
126  int imax = 3 - 1;
127 
128  double yp0 = 1.0;
129  double ypn = 2.0;
130 
131  cubic_spline.spline(imin, yp0, imax, ypn);
132 
133  std::vector<double> check_xvals = {0.0, 0.39999999998, 0.79999999996, 1.19999999994, 1.59999999992, 1.9999999999};
134  std::vector<double> check_yvals;
135  std::vector<D2U> check_yvals_d2u;
136 
137  for (int i = 0; i < check_xvals.size(); i++)
138  {
139  double r = check_xvals[i];
140  double val = cubic_spline.splint(r);
141  check_yvals.push_back(val);
142 
143  double du, d2u;
144  double val2 = cubic_spline.splint(r, du, d2u);
145  check_yvals_d2u.push_back(D2U(val2, du, d2u));
146 
147  //std::cout << i << " r = " << r << " val = " << val << " " << check_yvals[i] << std::endl;
148  }
149 
150  CHECK(check_yvals[0] == Approx(1));
151  CHECK(check_yvals[1] == Approx(1.532));
152  CHECK(check_yvals[2] == Approx(1.976));
153  CHECK(check_yvals[3] == Approx(1.836));
154  CHECK(check_yvals[4] == Approx(1.352));
155  CHECK(check_yvals[5] == Approx(1.5));
156 
157  CHECK(check_yvals_d2u[0].val == Approx(1));
158  CHECK(check_yvals_d2u[0].du == Approx(1));
159  CHECK(check_yvals_d2u[0].d2u == Approx(2.75));
160  CHECK(check_yvals_d2u[1].val == Approx(1.532));
161  CHECK(check_yvals_d2u[1].du == Approx(1.44));
162  CHECK(check_yvals_d2u[1].d2u == Approx(-0.55));
163  CHECK(check_yvals_d2u[2].val == Approx(1.976));
164  CHECK(check_yvals_d2u[2].du == Approx(0.56));
165  CHECK(check_yvals_d2u[2].d2u == Approx(-3.85));
166  CHECK(check_yvals_d2u[3].val == Approx(1.836));
167  CHECK(check_yvals_d2u[3].du == Approx(-1.16));
168  CHECK(check_yvals_d2u[3].d2u == Approx(-2.35));
169  CHECK(check_yvals_d2u[4].val == Approx(1.352));
170  CHECK(check_yvals_d2u[4].du == Approx(-0.84));
171  CHECK(check_yvals_d2u[4].d2u == Approx(3.95));
172  CHECK(check_yvals_d2u[5].val == Approx(1.5));
173  CHECK(check_yvals_d2u[5].du == Approx(2));
174  CHECK(check_yvals_d2u[5].d2u == Approx(10.25));
175 }
176 
177 } // namespace qmcplusplus
void CubicSplineSolve(T const *x, T const *y, int n, T yp0, T ypn, T *y2)
Solve for second derivatives for cubic splines.
Definition: SplineSolvers.h:33
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
TEST_CASE("complex_helper", "[type_traits]")
value_type splint(point_type r) const override
void spline(int imin, value_type yp1, int imax, value_type ypn) override
Evaluate the 2nd derivative on the grid points.
CHECK(log_values[0]==ComplexApprox(std::complex< double >{ 5.603777579195571, -6.1586603331188225 }))
D2U(double val_, double du_, double d2u_)