QMCPACK
RungeKutta.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 RUNGE_KUTTA_H
18 #define RUNGE_KUTTA_H
19 
20 #include "Grid.h"
21 
22 inline double mag(double x) { return (std::abs(x)); }
23 
24 inline double mag(const Vec2& x) { return (std::abs(x[0]) + std::abs(x[1])); }
25 
26 inline double mag(const Vec3& x) { return (std::abs(x[0]) + std::abs(x[1]) + std::abs(x[2])); }
27 
28 template<class IntegrandClass, class T>
30 {
31 private:
32  IntegrandClass& Integrand;
33 
34  // Separate functions are just a little faster...
35  inline void IntegrateForw(const Grid& grid, int startPoint, int endPoint, Array<T, 1>& result, bool scale = true)
36  {
37  T k1, k2, k3, k4;
38  T y, yplus;
39  double h, x;
40 
41  const static double OneSixth = 1.0 / 6.0;
42  const static double OneThird = 1.0 / 3.0;
43 
44  for (int i = startPoint; i < endPoint; i++)
45  {
46  x = grid(i);
47  h = grid(i + 1) - x;
48  y = result(i);
49  k1 = h * Integrand(x, y);
50  yplus = y + 0.5 * k1;
51  k2 = h * Integrand(x + 0.5 * h, yplus);
52  yplus = y + 0.5 * k2;
53  k3 = h * Integrand(x + 0.5 * h, yplus);
54  yplus = y + k3;
55  k4 = h * Integrand(x + h, yplus);
56  result(i + 1) = y + (OneSixth * (k1 + k4) + OneThird * (k2 + k3));
57  if (scale && mag(result(i + 1)) > 1.0e10)
58  for (int j = startPoint; j <= endPoint; j++)
59  result(j) *= 1.0e-10;
60  }
61  }
62 
63  inline void IntegrateRev(const Grid& grid, int startPoint, int endPoint, Array<T, 1>& result, bool scale = true)
64  {
65  T k1, k2, k3, k4;
66  T y, yplus;
67  double h, x;
68 
69  const static double OneSixth = 1.0 / 6.0;
70  const static double OneThird = 1.0 / 3.0;
71 
72  for (int i = startPoint; i > endPoint; i--)
73  {
74  x = grid(i);
75  h = grid(i - 1) - x;
76  y = result(i);
77  k1 = h * Integrand(x, y);
78  yplus = y + 0.5 * k1;
79  k2 = h * Integrand(x + 0.5 * h, yplus);
80  yplus = y + 0.5 * k2;
81  k3 = h * Integrand(x + 0.5 * h, yplus);
82  yplus = y + k3;
83  k4 = h * Integrand(x + h, yplus);
84  result(i - 1) = y + (OneSixth * (k1 + k4) + OneThird * (k2 + k3));
85  if (scale && mag(result(i - 1)) > 1.0e10)
86  for (int j = startPoint; j >= endPoint; j--)
87  result(j) *= 1.0e-10;
88  }
89  }
90 
91 
92 public:
93  inline void Integrate(const Grid& grid, int startPoint, int endPoint, Array<T, 1>& result, bool scale = true)
94  {
95  if (endPoint > startPoint)
96  IntegrateForw(grid, startPoint, endPoint, result, scale);
97  else
98  IntegrateRev(grid, startPoint, endPoint, result, scale);
99  }
100 
101  RungeKutta(IntegrandClass& integrand) : Integrand(integrand)
102  {
103  // Do nothing
104  }
105 };
106 
107 
108 template<class IntegrandClass>
110 {
111 private:
112  IntegrandClass& Integrand;
113 
114  // Separate functions are just a little faster...
115  inline void IntegrateForw(const Grid& grid, int startPoint, int endPoint, Array<double, 2>& result)
116  {
117  int numVars = result.cols();
118  Array<double, 1> k1(numVars), k2(numVars), k3(numVars), k4(numVars);
119  Array<double, 1> y(numVars), yplus(numVars);
120  double h, x;
121 
122  const static double OneSixth = 1.0 / 6.0;
123  const static double OneThird = 1.0 / 3.0;
124 
125  for (int i = startPoint; i < endPoint; i++)
126  {
127  x = grid(i);
128  h = grid(i + 1) - x;
129  y = result(i, Range::all());
130  k1 = h * Integrand(x, y);
131  yplus = y + 0.5 * k1;
132  k2 = h * Integrand(x + 0.5 * h, yplus);
133  yplus = y + 0.5 * k2;
134  k3 = h * Integrand(x + 0.5 * h, yplus);
135  yplus = y + k3;
136  k4 = h * Integrand(x + h, yplus);
137  result(i + 1, Range::all()) = y + (OneSixth * (k1 + k4) + OneThird * (k2 + k3));
138  }
139  }
140 
141  inline void IntegrateRev(const Grid& grid, int startPoint, int endPoint, Array<double, 2>& result)
142  {
143  int numVars = result.cols();
144  Array<double, 1> k1(numVars), k2(numVars), k3(numVars), k4(numVars);
145  Array<double, 1> y(numVars), yplus(numVars);
146  double h, x;
147 
148  const static double OneSixth = 1.0 / 6.0;
149  const static double OneThird = 1.0 / 3.0;
150 
151  for (int i = startPoint; i > endPoint; i--)
152  {
153  x = grid(i);
154  h = grid(i - 1) - x;
155  y = result(i, Range::all());
156  k1 = h * Integrand(x, y);
157  yplus = y + 0.5 * k1;
158  k2 = h * Integrand(x + 0.5 * h, yplus);
159  yplus = y + 0.5 * k2;
160  k3 = h * Integrand(x + 0.5 * h, yplus);
161  yplus = y + k3;
162  k4 = h * Integrand(x + h, yplus);
163  result(i - 1)/*, Range::all())*/ = y + (OneSixth * (k1 + k4) + OneThird * (k2 + k3));
164  }
165  }
166 
167 
168 public:
169  inline void Integrate(const Grid& grid, int startPoint, int endPoint, Array<double, 2>& result)
170  {
171  if (endPoint > startPoint)
172  IntegrateForw(grid, startPoint, endPoint, result);
173  else
174  IntegrateRev(grid, startPoint, endPoint, result);
175  }
176 
177  RungeKutta2(IntegrandClass& integrand) : Integrand(integrand)
178  {
179  // Do nothing
180  }
181 };
182 
183 
184 #endif
RungeKutta(IntegrandClass &integrand)
Definition: RungeKutta.h:101
MakeReturn< UnaryNode< FnFabs, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t abs(const Vector< T1, C1 > &l)
Parent class for all grids.
Definition: Grid.h:43
void IntegrateForw(const Grid &grid, int startPoint, int endPoint, Array< T, 1 > &result, bool scale=true)
Definition: RungeKutta.h:35
void IntegrateForw(const Grid &grid, int startPoint, int endPoint, Array< double, 2 > &result)
Definition: RungeKutta.h:115
RungeKutta2(IntegrandClass &integrand)
Definition: RungeKutta.h:177
IntegrandClass & Integrand
Definition: RungeKutta.h:32
void IntegrateRev(const Grid &grid, int startPoint, int endPoint, Array< double, 2 > &result)
Definition: RungeKutta.h:141
static auto all()
Definition: Blitz.h:176
auto cols() const
Definition: Blitz.h:90
void Integrate(const Grid &grid, int startPoint, int endPoint, Array< T, 1 > &result, bool scale=true)
Definition: RungeKutta.h:93
IntegrandClass & Integrand
Definition: RungeKutta.h:112
double mag(double x)
Definition: RungeKutta.h:22
void IntegrateRev(const Grid &grid, int startPoint, int endPoint, Array< T, 1 > &result, bool scale=true)
Definition: RungeKutta.h:63
void Integrate(const Grid &grid, int startPoint, int endPoint, Array< double, 2 > &result)
Definition: RungeKutta.h:169