1 #ifndef VTESTBED_CORE_RKF45_HH     2 #define VTESTBED_CORE_RKF45_HH     7 #include <vtestbed/base/blitz.hh>     8 #include <vtestbed/core/math.hh>    35             T _tolerance = T(1e-6);
    37             bool _verbose = 
false;
    65             template <
class Function, 
int N>
    66             inline blitz::TinyVector<T,N>
    67             solve(Function f, T t0, T t1, 
const blitz::TinyVector<T,N>& x0) {
    68                 typedef blitz::TinyVector<T,N> vec;
    74                 state st = state::normal_iteration;
    75                 const T tol = this->_tolerance;
    76                 const T h_min = this->_minstep;
    77                 const T h_max = this->_maxstep;
    83                         << std::setw(8) << 
"rkf45"    84                         << std::setw(10) << t0
    86                         << std::setw(10) << x0
    89                 while (st != state::end) {
   130                     const vec k_1 = h*f(t, x_i);
   145                         + (T(1932)/T(2197))*k_1
   146                         - (T(7200)/T(2197))*k_2
   147                         + (T(7296)/T(2197))*k_3
   152                         + (T(439)/T(216))*k_1
   154                         + (T(3680)/T(513))*k_3
   155                         - (T(845)/T(4104))*k_4
   162                         - (T(3544)/T(2565))*k_3
   163                         + (T(1859)/T(4104))*k_4
   178                         + (T(1408)/T(2565))*k_3
   179                         + (T(2197)/T(4101))*k_4
   195                         + (T(6656)/T(12825))*k_3
   196                         + (T(28561)/T(56430))*k_4
   199                     if (this->_verbose) {
   201                             << std::setw(8) << 
"rkf45"   202                             << std::setw(10) << t
   203                             << std::setw(10) << h
   204                             << std::setw(10) << x_ip1
   207                     if (st == state::last_iteration) {
   220                         const T diff = max(abs(x_ip1 - z_ip1));
   221                         const T s = std::pow((tol*h) / (T(2)*diff), T(1)/T(4));
   227                         h = blitz::clamp(s*h, h_min, h_max);
   228                         if (t + h + h_min > t1) {
   231                             st = state::last_iteration;
   242             template <
class Function, 
int N>
   243             inline blitz::TinyVector<T,N>
   244             operator()(Function f, T t0, T t1, 
const blitz::TinyVector<T,N>& x0) {
   245                 return this->solve<Function,N>(f, t0, t1, x0);
   249             min_step() const noexcept {
   250                 return this->_minstep;
   258                 this->_minstep = rhs;
   262             max_step() const noexcept {
   263                 return this->_maxstep;
   271                 this->_maxstep = rhs;
   275             tolerance() const noexcept {
   276                 return this->_tolerance;
   284                 this->_tolerance = rhs;
   288             verbose(
bool rhs) noexcept {
   289                 this->_verbose = rhs;
   293             verbose() const noexcept {
   294                 return this->_verbose;
   303 #endif // vim:filetype=cpp blitz::TinyVector< T, N > solve(Function f, T t0, T t1, const blitz::TinyVector< T, N > &x0)
Solve system of ordinary differential equations with right hand sides f.
 
blitz::TinyVector< T, N > operator()(Function f, T t0, T t1, const blitz::TinyVector< T, N > &x0)
Solve system of ordinary differential equations with right hand sides f.
 
Runge—Khutta—Fehlberg initial value problem solver.