Medusa  1.1
Coordinate Free Mehless Method implementation
RKExplicit_fwd.hpp
Go to the documentation of this file.
1 #ifndef MEDUSA_BITS_INTEGRATORS_RKEXPLICIT_FWD_HPP_
2 #define MEDUSA_BITS_INTEGRATORS_RKEXPLICIT_FWD_HPP_
3 
11 #include <medusa/Config.hpp>
12 #include <Eigen/Core>
14 #include "RKExplicit_fwd.hpp"
16 
17 namespace mm {
18 
19 template <typename Scalar, int num_steps>
20 class AdamsBashforth;
21 
31 template <typename Scalar, int num_stages>
32 class RKExplicit {
33  public:
34  typedef Scalar scalar_t;
35  enum { stages = num_stages };
36 
37  private:
38  Eigen::Matrix<scalar_t, stages, 1> alpha_;
39  Eigen::Matrix<scalar_t, stages, stages> beta_;
40  Eigen::Matrix<scalar_t, stages, 1> gamma_;
41 
42  public:
56  RKExplicit(const Eigen::Matrix<scalar_t, stages, 1>& alpha,
57  const Eigen::Matrix<scalar_t, stages, stages>& beta,
58  const Eigen::Matrix<scalar_t, stages, 1>& gamma)
59  : alpha_(alpha), beta_(beta), gamma_(gamma) {}
60 
64  template <typename func_t>
65  class Integrator {
69  int max_steps;
70  Eigen::VectorXd y0_;
71  const func_t& func_;
72 
73  public:
78  Integrator(const RKExplicit<scalar_t, num_stages>& method, const func_t& func, scalar_t t0,
79  scalar_t t_max, scalar_t dt, Eigen::VectorXd y0) :
80  method_(method), t0_(t0), dt_(dt), max_steps(iceil((t_max - t0) / dt)),
81  y0_(std::move(y0)), func_(func) {}
82 
87  class IterationStep : public std::iterator<
88  std::forward_iterator_tag, // iterator_category
89  IterationStep, // value_type
90  int, // difference_type
91  const IterationStep*, // pointer
92  IterationStep // reference
93  > {
96  Eigen::VectorXd y;
97  int cur_step;
98 
99  public:
103 
107 
111  t += integrator.dt_;
112  cur_step++;
113  return *this;
114  }
115 
122  IterationStep retval = *this;
123  ++(*this);
124  return retval;
125  }
126 
128  bool operator==(const IterationStep& other) const { return cur_step == other.cur_step; }
129 
131  bool operator!=(const IterationStep& other) const { return !(*this == other); }
132 
134  IterationStep& operator*() { return *this; }
135 
137  const IterationStep& operator*() const { return *this; }
138 
140  explicit operator bool() {
141  return cur_step <= integrator.max_steps;
142  }
143 
145  bool is_last() const {
146  return cur_step == integrator.max_steps;
147  }
148 
150  scalar_t time() const { return t; }
151 
153  Eigen::VectorXd value() const { return y; }
154 
156  scalar_t& time() { return t; }
157 
159  Eigen::VectorXd& value() { return y; }
160 
162  friend std::ostream& operator<<(std::ostream& os, const IterationStep& step) {
163  return os << "t = " << step.t << "; y = " << step.y;
164  }
165  };
166 
169 
171  iterator begin() { return IterationStep(*this); }
172 
174  const_iterator cbegin() { return IterationStep(*this); }
175 
178  iterator end() { return IterationStep(*this, 0); }
179 
181  const_iterator cend() { return IterationStep(*this, 0); }
182 
184  friend std::ostream& operator<<(std::ostream& os, const Integrator& integrator) {
185  return os << "Explicit RK integrator using " << integrator.method_ << " method from "
186  << "time " << integrator.t0_ << " with step " << integrator.dt_ << " for "
187  << integrator.max_steps << " steps.";
188  }
189  };
190 
191 
203  template <typename func_t>
204  Integrator<func_t> solve(const func_t& func, scalar_t t0, scalar_t t_max, scalar_t dt,
205  const Eigen::VectorXd& y0) const {
206  return Integrator<func_t>(*this, func, t0, t_max, dt, y0);
207  }
208 
209  private:
211  template <typename func_t>
212  Eigen::VectorXd step(const func_t& func, scalar_t t, const Eigen::VectorXd& y,
213  scalar_t dt) const {
214  Eigen::Matrix<scalar_t, Eigen::Dynamic, stages> k(y.size(), static_cast<int>(stages));
215  k.col(0) = func(t + alpha_(0) * dt, y);
216  for (int i = 1; i < stages; ++i) {
217  k.col(i) = func(t + alpha_(i) * dt,
218  y + dt * k.leftCols(i) * beta_.row(i).head(i).transpose());
219  }
220  return y + dt * k * gamma_;
221  }
222 
223  public:
225  template <typename scalar_t, int stages>
226  friend std::ostream& operator<<(std::ostream& os, const RKExplicit<scalar_t, stages>&);
227 
229  template <typename Scalar2, int num_steps2>
230  friend class AdamsBashforth;
231 };
232 
234 template <typename scalar_t, int num_stages>
235 std::ostream& operator<<(std::ostream& os, const RKExplicit<scalar_t, num_stages>& method) {
236  os << "RKExplicit with " << num_stages << " stages and "
237  << "alpha = " << method.alpha_ << ", "
238  << "beta = " << method.beta_ << ", "
239  << "gamma = " << method.gamma_;
240  return os;
241 }
242 
246 namespace integrators {
247 
256 namespace Explicit {
257 
259 template <class scalar_t = double>
260 RKExplicit<scalar_t, 4> RK4();
261 
263 template <class scalar_t = double>
264 RKExplicit<scalar_t, 4> RK38();
265 
267 template <class scalar_t = double>
268 RKExplicit<scalar_t, 1> Euler();
269 
271 template <class scalar_t = double>
272 RKExplicit<scalar_t, 2> Midpoint();
273 
275 template <class scalar_t = double>
276 RKExplicit<scalar_t, 3> RK3();
277 
279 template <class scalar_t = double>
280 RKExplicit<scalar_t, 6> Fehlberg5();
281 
283 namespace of_order_internal {
284 template <int order, class scalar_t>
285 struct _of_order_impl { static RKExplicit<scalar_t, order> of_order(); };
286 }
288 
292 template <int order, class scalar_t = double>
295 }
296 
297 } // namespace Explicit
298 } // namespace integrators
299 } // namespace mm
300 
301 #endif // MEDUSA_BITS_INTEGRATORS_RKEXPLICIT_FWD_HPP_
RKExplicit_fwd.hpp
mm
Root namespace for the whole library.
Definition: Gaussian.hpp:14
mm::integrators::Explicit::Midpoint
RKExplicit< scalar_t, 2 > Midpoint()
Explicit midpoint rule, 2nd order.
Definition: RKExplicit.hpp:55
mm::RKExplicit::Integrator::IterationStep::operator==
bool operator==(const IterationStep &other) const
Compare two steppers if they are on the same step.
Definition: RKExplicit_fwd.hpp:128
mm::RKExplicit
Class representing an explicit Runge-Kutta method.
Definition: RKExplicit_fwd.hpp:32
mm::RKExplicit::solve
Integrator< func_t > solve(const func_t &func, scalar_t t0, scalar_t t_max, scalar_t dt, const Eigen::VectorXd &y0) const
Returns a solver using this method.
Definition: RKExplicit_fwd.hpp:204
mm::RKExplicit::Integrator::Integrator
Integrator(const RKExplicit< scalar_t, num_stages > &method, const func_t &func, scalar_t t0, scalar_t t_max, scalar_t dt, Eigen::VectorXd y0)
Constructs stepper.
Definition: RKExplicit_fwd.hpp:78
mm::RKExplicit::Integrator::IterationStep
Class representing a step in the integration process.
Definition: RKExplicit_fwd.hpp:87
mm::RKExplicit::scalar_t
Scalar scalar_t
Floating point type used in the computations.
Definition: RKExplicit_fwd.hpp:34
mm::RKExplicit::Integrator::dt_
scalar_t dt_
Time step.
Definition: RKExplicit_fwd.hpp:68
mm::RKExplicit::Integrator::IterationStep::operator*
const IterationStep & operator*() const
const version of IterationStep::operator*
Definition: RKExplicit_fwd.hpp:137
mm::RKExplicit::Integrator::IterationStep::operator!=
bool operator!=(const IterationStep &other) const
Negation of IterationStep::operator==.
Definition: RKExplicit_fwd.hpp:131
mm::RKExplicit::Integrator::IterationStep::operator++
IterationStep operator++(int)
Advance the stepper for one time step, returning the old value.
Definition: RKExplicit_fwd.hpp:121
mm::integrators::Explicit::RK3
RKExplicit< scalar_t, 3 > RK3()
Kutta's third order method.
Definition: RKExplicit.hpp:66
mm::RKExplicit::Integrator::IterationStep::is_last
bool is_last() const
Returns true if integrator just completed its last step.
Definition: RKExplicit_fwd.hpp:145
mm::integrators::Explicit::of_order
static RKExplicit< scalar_t, order > of_order()
Returns Runge Kutta explicit method of requested order with given floating point type.
Definition: RKExplicit_fwd.hpp:293
mm::RKExplicit::Integrator::IterationStep::operator*
IterationStep & operator*()
Noop, used to conform to std::iterator requirements.
Definition: RKExplicit_fwd.hpp:134
mm::operator<<
std::ostream & operator<<(std::ostream &os, const Gaussian< S > &b)
Output basic information about given Gaussian RBF.
Definition: Gaussian.hpp:37
mm::RKExplicit::Integrator::const_iterator
IterationStep const_iterator
const iterator type
Definition: RKExplicit_fwd.hpp:168
numutils.hpp
mm::RKExplicit::Integrator::IterationStep::operator<<
friend std::ostream & operator<<(std::ostream &os, const IterationStep &step)
Output current state of the stepper.
Definition: RKExplicit_fwd.hpp:162
mm::RKExplicit::Integrator::func_
const func_t & func_
Function to integrate.
Definition: RKExplicit_fwd.hpp:71
mm::RKExplicit::Integrator::iterator
IterationStep iterator
iterator type
Definition: RKExplicit_fwd.hpp:167
mm::RKExplicit::Integrator::y0_
Eigen::VectorXd y0_
Initial value.
Definition: RKExplicit_fwd.hpp:70
mm::RKExplicit::gamma_
Eigen::Matrix< scalar_t, stages, 1 > gamma_
Bottom row of the tableau.
Definition: RKExplicit_fwd.hpp:40
mm::RKExplicit::Integrator::IterationStep::value
Eigen::VectorXd & value()
Read-write access to current value.
Definition: RKExplicit_fwd.hpp:159
mm::RKExplicit::Integrator::IterationStep::IterationStep
IterationStep(const Integrator &integrator)
Construct an iterator at the initial values of the equation.
Definition: RKExplicit_fwd.hpp:101
mm::RKExplicit::operator<<
friend std::ostream & operator<<(std::ostream &os, const RKExplicit< scalar_t, stages > &)
Output the method's tableau for debugging.
mm::integrators::Explicit::RK38
RKExplicit< scalar_t, 4 > RK38()
3/8 rule 4th order method
Definition: RKExplicit.hpp:30
Config.hpp
mm::RKExplicit::Integrator
Integrator class for RK methods.
Definition: RKExplicit_fwd.hpp:65
mm::iceil
int iceil(T x)
Ceils a floating point to an integer.
Definition: numutils.hpp:27
mm::RKExplicit::Integrator::IterationStep::cur_step
int cur_step
current step
Definition: RKExplicit_fwd.hpp:97
mm::RKExplicit::Integrator::operator<<
friend std::ostream & operator<<(std::ostream &os, const Integrator &integrator)
Output information about this integrator.
Definition: RKExplicit_fwd.hpp:184
mm::RKExplicit::Integrator::cend
const_iterator cend()
Same as Integrator::end()
Definition: RKExplicit_fwd.hpp:181
mm::RKExplicit::Integrator::cbegin
const_iterator cbegin()
Same as Integrator::begin()
Definition: RKExplicit_fwd.hpp:174
mm::RKExplicit::Integrator::end
iterator end()
Creates an invalid stepper at positioned past the last step, meant to be used for comparison it == en...
Definition: RKExplicit_fwd.hpp:178
mm::RKExplicit::Integrator::IterationStep::operator++
IterationStep & operator++()
Advance the stepper for one time step, returning the new value.
Definition: RKExplicit_fwd.hpp:109
assert.hpp
mm::RKExplicit::Integrator::IterationStep::IterationStep
IterationStep(const Integrator &integrator, int)
Construct an (invalid) iterator pointing past the last step.
Definition: RKExplicit_fwd.hpp:105
mm::RKExplicit::stages
@ stages
number of stages
Definition: RKExplicit_fwd.hpp:35
mm::RKExplicit::Integrator::begin
iterator begin()
Creates stepper at positioned at initial value.
Definition: RKExplicit_fwd.hpp:171
mm::RKExplicit::RKExplicit
RKExplicit(const Eigen::Matrix< scalar_t, stages, 1 > &alpha, const Eigen::Matrix< scalar_t, stages, stages > &beta, const Eigen::Matrix< scalar_t, stages, 1 > &gamma)
Construct a Runge-Kutta method with tableau .
Definition: RKExplicit_fwd.hpp:56
mm::RKExplicit::Integrator::IterationStep::time
scalar_t & time()
Read-write access to current time.
Definition: RKExplicit_fwd.hpp:156
mm::RKExplicit::Integrator::max_steps
int max_steps
Number of steps.
Definition: RKExplicit_fwd.hpp:69
mm::RKExplicit::step
Eigen::VectorXd step(const func_t &func, scalar_t t, const Eigen::VectorXd &y, scalar_t dt) const
Returns next value.
Definition: RKExplicit_fwd.hpp:212
mm::integrators::Explicit::RK4
RKExplicit< scalar_t, 4 > RK4()
Standard RK4 4th order method.
Definition: RKExplicit.hpp:16
mm::RKExplicit::alpha_
Eigen::Matrix< scalar_t, stages, 1 > alpha_
Left row of the tableau.
Definition: RKExplicit_fwd.hpp:38
mm::RKExplicit::Integrator::IterationStep::integrator
const Integrator & integrator
reference to underlying integrator
Definition: RKExplicit_fwd.hpp:94
mm::RKExplicit::Integrator::IterationStep::t
scalar_t t
current time
Definition: RKExplicit_fwd.hpp:95
mm::RKExplicit::Integrator::IterationStep::value
Eigen::VectorXd value() const
Get current value.
Definition: RKExplicit_fwd.hpp:153
mm::RKExplicit::Integrator::IterationStep::y
Eigen::VectorXd y
current value
Definition: RKExplicit_fwd.hpp:96
mm::RKExplicit::beta_
Eigen::Matrix< scalar_t, stages, stages > beta_
Central matrix of the tableau.
Definition: RKExplicit_fwd.hpp:39
mm::RKExplicit::Integrator::t0_
scalar_t t0_
Start time.
Definition: RKExplicit_fwd.hpp:67
mm::AdamsBashforth
Class representing an AdamsBashforth method, an explicit linear multistep method.
Definition: AdamsBashforth_fwd.hpp:29
mm::RKExplicit::Integrator::IterationStep::time
scalar_t time() const
Get current time.
Definition: RKExplicit_fwd.hpp:150
mm::integrators::Explicit::Fehlberg5
RKExplicit< scalar_t, 6 > Fehlberg5()
Fifth order method appearing in Fehlberg's method.
Definition: RKExplicit.hpp:79
mm::RKExplicit::Integrator::method_
const RKExplicit< scalar_t, num_stages > method_
Method used in this integrator.
Definition: RKExplicit_fwd.hpp:66
mm::integrators::Explicit::Euler
RKExplicit< scalar_t, 1 > Euler()
Explicit Euler's method, 1st order.
Definition: RKExplicit.hpp:44