Theoretica
Scientific Computing
Loading...
Searching...
No Matches
ode.h
Go to the documentation of this file.
1
5
6#ifndef THEORETICA_ODE_H
7#define THEORETICA_ODE_H
8
9#include "../algebra/vec.h"
10
11
12namespace theoretica {
13
15 namespace ode {
16
17
22 template<typename Vector = vec<real>>
24
27
30
31
34
35
39 ode_solution_t(size_t steps, const Vector& x0, real t0) {
40
41 t.resize(steps);
42 x.resize(steps);
43
44 t[0] = t0;
45 x[0] = x0;
46 }
47
48
49#ifndef THEORETICA_NO_PRINT
50
52 inline std::string to_string(const std::string& separator = " ") const {
53
54 if (t.size() != x.size()) {
55 TH_MATH_ERROR("ode_solution_t::to_string", t.size(), MathError::InvalidArgument);
56 return "";
57 }
58
59 std::stringstream res;
60
61 for (unsigned int i = 0; i < t.size(); ++i) {
62
63 res << t[i] << separator;
64
65 for (unsigned int j = 0; j < x[i].size(); ++j) {
66
67 res << x[i][j];
68
69 if(j != x[i].size() - 1)
70 res << separator;
71 else
72 res << "\n";
73 }
74 }
75
76 return res.str();
77 }
78
79
81 inline operator std::string() {
82 return to_string();
83 }
84
85
88 inline friend std::ostream& operator<<(
89 std::ostream& out, const ode_solution_t<Vector>& obj) {
90 return out << obj.to_string();
91 }
92#endif
93
94 };
95
96
99
100
103
104
107
108
111
112
115
116
122 template<typename Vector>
123 using ode_function = std::function<Vector(real, const Vector&)>;
124
125
126 // Steppers
127 // (functions which compute one iteration of a method)
128
129
139 template<typename Vector, typename OdeFunction = ode_function<Vector>>
140 inline Vector step_euler(OdeFunction f, const Vector& x, real t, real h = 0.0001) {
141
142 return x + h * f(t, x);
143 }
144
145
155 template<typename Vector, typename OdeFunction = ode_function<Vector>>
156 inline Vector step_midpoint(OdeFunction f, const Vector& x, real t, real h = 0.0001) {
157
158 return x + h * f(t + h / 2.0, x + f(t, x) * h / 2.0);
159 }
160
161
171 template<typename Vector, typename OdeFunction = ode_function<Vector>>
172 inline Vector step_heun(OdeFunction f, const Vector& x, real t, real h = 0.001) {
173
174 const Vector k1 = f(t, x);
175
176 return x + (k1 + f(t + h, x + k1 * h)) * (h / 2.0);
177 }
178
179
190 template<typename Vector, typename OdeFunction = ode_function<Vector>>
191 inline Vector step_rk2(OdeFunction f, const Vector& x, real t, real h = 0.001) {
192
193 const Vector k1 = f(t, x);
194 const Vector k2 = f(t + (h / 2.0), x + k1 * (h / 2.0));
195
196 return x + k2 * h;
197 }
198
199
210 template<typename Vector, typename OdeFunction = ode_function<Vector>>
211 inline Vector step_rk4(OdeFunction f, const Vector& x, real t, real h = 0.01) {
212
213 const real half = h / 2.0;
214
215 const Vector k1 = f(t, x);
216 const Vector k2 = f(t + half, x + k1 * half);
217 const Vector k3 = f(t + half, x + k2 * half);
218 const Vector k4 = f(t + h, x + k3 * h);
219
220 return x + (k1 + k2 * 2.0 + k3 * 2.0 + k4) * (h / 6.0);
221 }
222
223
234 template<typename Vector, typename OdeFunction = ode_function<Vector>>
235 inline Vector step_k38(OdeFunction f, const Vector& x, real t, real h = 0.001) {
236
237 const Vector k1 = f(t, x);
238 const Vector k2 = f(t + (h / 3.0), x + k1 * (h / 3.0));
239 const Vector k3 = f(t + (h * 2.0 / 3.0), x + h * (-k1 / 3.0 + k2));
240 const Vector k4 = f(t + h, x + h * (k1 - k2 + k3));
241
242 return x + (k1 + 3.0 * k2 + 3.0 * k3 + k4) * (h / 8.0);
243 }
244
245
246 // Solvers
247 // (functions which solve numerically an ODE over an interval)
248
249
266 template <
267 typename Vector, typename OdeFunction = ode_function<Vector>,
268 typename StepFunction
269 >
272 OdeFunction f, const Vector& x0, real t0, real tf,
273 StepFunction step, real stepsize = 0.001) {
274
275 if (tf < t0) {
276 TH_MATH_ERROR("ode::solve_fixstep", tf, MathError::InvalidArgument);
277 ode_solution_t<Vector> err; err.t = Vector(nan());
278 return err;
279 }
280
281 const unsigned int steps = floor((tf - t0) / stepsize);
282 unsigned int total_steps = steps;
283 unsigned int i;
284
285 if (abs(t0 + steps * stepsize - tf) > MACH_EPSILON)
286 total_steps++;
287
288 // Initialize solution structure
290
291
292 // Iterate over each step of the numerical method
293 for (i = 1; i <= steps; ++i) {
294 solution.x[i] = step(f, solution.x[i - 1], solution.t[i - 1], stepsize);
295 solution.t[i] = solution.t[i - 1] + stepsize;
296 }
297
298
299 // Additional shorter step if the stepsize
300 // does not cover exactly the time interval
301 if (steps != total_steps) {
302 solution.x[i] = step(
303 f, solution.x[i - 1], solution.t[i - 1], tf - solution.t[i - 1]);
304 solution.t[i] = tf;
305 }
306
307 return solution;
308 }
309
310
322 template <
323 typename Vector, typename OdeFunction = ode_function<Vector>
324 >
331
332
344 template <
345 typename Vector, typename OdeFunction = ode_function<Vector>
346 >
353
354
366 template <
367 typename Vector, typename OdeFunction = ode_function<Vector>
368 >
375
376
389 template <
390 typename Vector, typename OdeFunction = ode_function<Vector>
391 >
398
399
412 template <
413 typename Vector, typename OdeFunction = ode_function<Vector>
414 >
421
422
434 template <
435 typename Vector, typename OdeFunction = ode_function<Vector>
436 >
443 }
444}
445
446#endif
A statically allocated N-dimensional vector with elements of the given type.
Definition vec.h:92
void resize(size_t n) const
Compatibility function to allow for allocation or resizing of dynamic vectors.
Definition vec.h:459
TH_CONSTEXPR unsigned int size() const
Returns the size of the vector (N)
Definition vec.h:449
#define TH_MATH_ERROR(F_NAME, VALUE, EXCEPTION)
TH_MATH_ERROR is a macro which throws exceptions or modifies errno (depending on which compilation op...
Definition error.h:219
Vector step_euler(OdeFunction f, const Vector &x, real t, real h=0.0001)
Compute one step of Euler's method for ordinary differential equations.
Definition ode.h:140
Vector step_k38(OdeFunction f, const Vector &x, real t, real h=0.001)
Compute one step of Kutta's 3/8 rule method for ordinary differential equations.
Definition ode.h:235
Vector step_rk2(OdeFunction f, const Vector &x, real t, real h=0.001)
Compute one step of the Runge-Kutta method of 2nd order for ordinary differential equations.
Definition ode.h:191
std::function< Vector(real, const Vector &)> ode_function
A function representing a system of differential equations, taking as input the time (independent var...
Definition ode.h:123
ode_solution_t< Vector > solve_midpoint(OdeFunction f, const Vector &x0, real t0, real tf, real stepsize=0.0001)
Integrate an ordinary differential equation over a certain domain with the given initial conditions u...
Definition ode.h:347
ode_solution_t< Vector > solve_k38(OdeFunction f, const Vector &x0, real t0, real tf, real stepsize=0.0001)
Integrate an ordinary differential equation over a certain domain with the given initial conditions u...
Definition ode.h:437
ode_solution_t< Vector > solve_rk4(OdeFunction f, const Vector &x0, real t0, real tf, real stepsize=0.01)
Integrate an ordinary differential equation over a certain domain with the given initial conditions u...
Definition ode.h:415
Vector step_midpoint(OdeFunction f, const Vector &x, real t, real h=0.0001)
Compute one step of the midpoint method for ordinary differential equations.
Definition ode.h:156
ode_solution_t< Vector > solve_fixstep(OdeFunction f, const Vector &x0, real t0, real tf, StepFunction step, real stepsize=0.001)
Integrate an ordinary differential equation using any numerical algorithm with a constant step size,...
Definition ode.h:271
Vector step_rk4(OdeFunction f, const Vector &x, real t, real h=0.01)
Compute one step of the Runge-Kutta method of 4th order for ordinary differential equations.
Definition ode.h:211
ode_solution_t< Vector > solve_heun(OdeFunction f, const Vector &x0, real t0, real tf, real stepsize=0.0001)
Integrate an ordinary differential equation over a certain domain with the given initial conditions u...
Definition ode.h:369
Vector step_heun(OdeFunction f, const Vector &x, real t, real h=0.001)
Compute one step of Heun's method for ordinary differential equations.
Definition ode.h:172
ode_solution_t< Vector > solve_rk2(OdeFunction f, const Vector &x0, real t0, real tf, real stepsize=0.0001)
Integrate an ordinary differential equation over a certain domain with the given initial conditions u...
Definition ode.h:392
ode_solution_t< Vector > solve_euler(OdeFunction f, const Vector &x0, real t0, real tf, real stepsize=0.0001)
Integrate an ordinary differential equation over a certain domain with the given initial conditions u...
Definition ode.h:325
Main namespace of the library which contains all functions and objects.
Definition algebra.h:27
double real
A real number, defined as a floating point type.
Definition constants.h:207
dual2 abs(dual2 x)
Compute the absolute value of a second order dual number.
Definition dual2_functions.h:242
Vector make_error()
Create a vector representing an error state, with all NaN values.
Definition algebra.h:103
TH_CONSTEXPR real nan()
Return a quiet NaN number in floating point representation.
Definition error.h:74
@ InvalidArgument
Invalid argument.
constexpr real MACH_EPSILON
Machine epsilon for the real type.
Definition constants.h:216
TH_CONSTEXPR int floor(real x)
Compute the floor of x, as the maximum integer number that is smaller than x.
Definition real_analysis.h:271
Data structure holding the numerical solution of a discretized ODE, where the vector represents the ...
Definition ode.h:23
friend std::ostream & operator<<(std::ostream &out, const ode_solution_t< Vector > &obj)
Stream the ODE solution in string representation to an output stream (std::ostream)
Definition ode.h:88
vec< real > t
A vector of the time values (independent variable).
Definition ode.h:26
ode_solution_t(size_t steps, const Vector &x0, real t0)
Prepare the structure for integration by specifying the number of total steps and the initial conditi...
Definition ode.h:39
ode_solution_t()
Default constructor.
Definition ode.h:33
std::string to_string(const std::string &separator=" ") const
Convert the ODE solution to string representation.
Definition ode.h:52
vec< Vector > x
A vector of the phase space values (solution).
Definition ode.h:29