annotate DEPENDENCIES/generic/include/boost/numeric/odeint/stepper/extrapolation_stepper.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents f46d142149f5
children
rev   line source
Chris@102 1 /*
Chris@102 2 [auto_generated]
Chris@102 3 boost/numeric/odeint/stepper/extrapolation_stepper.hpp
Chris@102 4
Chris@102 5 [begin_description]
Chris@102 6 extrapolation stepper
Chris@102 7 [end_description]
Chris@102 8
Chris@102 9 Copyright 2009-2015 Mario Mulansky
Chris@102 10
Chris@102 11 Distributed under the Boost Software License, Version 1.0.
Chris@102 12 (See accompanying file LICENSE_1_0.txt or
Chris@102 13 copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@102 14 */
Chris@102 15
Chris@102 16 #ifndef BOOST_NUMERIC_ODEINT_STEPPER_EXTRAPOLATION_STEPPER_HPP_INCLUDED
Chris@102 17 #define BOOST_NUMERIC_ODEINT_STEPPER_EXTRAPOLATION_STEPPER_HPP_INCLUDED
Chris@102 18
Chris@102 19 #include <iostream>
Chris@102 20
Chris@102 21 #include <algorithm>
Chris@102 22
Chris@102 23 #include <boost/config.hpp> // for min/max guidelines
Chris@102 24 #include <boost/static_assert.hpp>
Chris@102 25
Chris@102 26 #include <boost/numeric/odeint/util/bind.hpp>
Chris@102 27 #include <boost/numeric/odeint/util/unwrap_reference.hpp>
Chris@102 28
Chris@102 29 #include <boost/numeric/odeint/stepper/base/explicit_error_stepper_base.hpp>
Chris@102 30 #include <boost/numeric/odeint/stepper/modified_midpoint.hpp>
Chris@102 31 #include <boost/numeric/odeint/stepper/controlled_step_result.hpp>
Chris@102 32 #include <boost/numeric/odeint/algebra/range_algebra.hpp>
Chris@102 33 #include <boost/numeric/odeint/algebra/default_operations.hpp>
Chris@102 34 #include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp>
Chris@102 35 #include <boost/numeric/odeint/algebra/operations_dispatcher.hpp>
Chris@102 36
Chris@102 37 #include <boost/numeric/odeint/util/state_wrapper.hpp>
Chris@102 38 #include <boost/numeric/odeint/util/is_resizeable.hpp>
Chris@102 39 #include <boost/numeric/odeint/util/resizer.hpp>
Chris@102 40 #include <boost/numeric/odeint/util/unit_helper.hpp>
Chris@102 41 #include <boost/numeric/odeint/util/detail/less_with_sign.hpp>
Chris@102 42
Chris@102 43 namespace boost
Chris@102 44 {
Chris@102 45 namespace numeric
Chris@102 46 {
Chris@102 47 namespace odeint
Chris@102 48 {
Chris@102 49
Chris@102 50 template < unsigned short Order, class State, class Value = double,
Chris@102 51 class Deriv = State, class Time = Value,
Chris@102 52 class Algebra = typename algebra_dispatcher< State >::algebra_type,
Chris@102 53 class Operations =
Chris@102 54 typename operations_dispatcher< State >::operations_type,
Chris@102 55 class Resizer = initially_resizer >
Chris@102 56 #ifndef DOXYGEN_SKIP
Chris@102 57 class extrapolation_stepper
Chris@102 58 : public explicit_error_stepper_base<
Chris@102 59 extrapolation_stepper< Order, State, Value, Deriv, Time, Algebra,
Chris@102 60 Operations, Resizer >,
Chris@102 61 Order, Order, Order - 2, State, Value, Deriv, Time, Algebra,
Chris@102 62 Operations, Resizer >
Chris@102 63 #else
Chris@102 64 class extrapolation_stepper : public explicit_error_stepper_base
Chris@102 65 #endif
Chris@102 66 {
Chris@102 67
Chris@102 68 private:
Chris@102 69 // check for Order being odd
Chris@102 70 BOOST_STATIC_ASSERT_MSG(
Chris@102 71 ( ( Order % 2 ) == 0 ) && ( Order > 2 ),
Chris@102 72 "extrapolation_stepper requires even Order larger than 2" );
Chris@102 73
Chris@102 74 public:
Chris@102 75 #ifndef DOXYGEN_SKIP
Chris@102 76 typedef explicit_error_stepper_base<
Chris@102 77 extrapolation_stepper< Order, State, Value, Deriv, Time, Algebra,
Chris@102 78 Operations, Resizer >,
Chris@102 79 Order, Order, Order - 2, State, Value, Deriv, Time, Algebra, Operations,
Chris@102 80 Resizer > stepper_base_type;
Chris@102 81 #else
Chris@102 82 typedef explicit_error_stepper_base< extrapolation_stepper< ... >, ... >
Chris@102 83 stepper_base_type;
Chris@102 84 #endif
Chris@102 85
Chris@102 86 typedef typename stepper_base_type::state_type state_type;
Chris@102 87 typedef typename stepper_base_type::value_type value_type;
Chris@102 88 typedef typename stepper_base_type::deriv_type deriv_type;
Chris@102 89 typedef typename stepper_base_type::time_type time_type;
Chris@102 90 typedef typename stepper_base_type::algebra_type algebra_type;
Chris@102 91 typedef typename stepper_base_type::operations_type operations_type;
Chris@102 92 typedef typename stepper_base_type::resizer_type resizer_type;
Chris@102 93
Chris@102 94 #ifndef DOXYGEN_SKIP
Chris@102 95 typedef typename stepper_base_type::stepper_type stepper_type;
Chris@102 96 typedef typename stepper_base_type::wrapped_state_type wrapped_state_type;
Chris@102 97 typedef typename stepper_base_type::wrapped_deriv_type wrapped_deriv_type;
Chris@102 98
Chris@102 99 typedef std::vector< value_type > value_vector;
Chris@102 100 typedef std::vector< value_vector > value_matrix;
Chris@102 101 typedef std::vector< size_t > int_vector;
Chris@102 102 typedef std::vector< wrapped_state_type > state_table_type;
Chris@102 103 typedef modified_midpoint< state_type, value_type, deriv_type, time_type,
Chris@102 104 algebra_type, operations_type,
Chris@102 105 resizer_type > midpoint_stepper_type;
Chris@102 106
Chris@102 107 #endif // DOXYGEN_SKIP
Chris@102 108
Chris@102 109 typedef unsigned short order_type;
Chris@102 110 static const order_type order_value = stepper_base_type::order_value;
Chris@102 111 static const order_type stepper_order_value =
Chris@102 112 stepper_base_type::stepper_order_value;
Chris@102 113 static const order_type error_order_value =
Chris@102 114 stepper_base_type::error_order_value;
Chris@102 115
Chris@102 116 const static size_t m_k_max = ( order_value - 2 ) / 2;
Chris@102 117
Chris@102 118 extrapolation_stepper( const algebra_type &algebra = algebra_type() )
Chris@102 119 : stepper_base_type( algebra ), m_interval_sequence( m_k_max + 1 ),
Chris@102 120 m_coeff( m_k_max + 1 ), m_table( m_k_max )
Chris@102 121 {
Chris@102 122 for ( unsigned short i = 0; i < m_k_max + 1; i++ )
Chris@102 123 {
Chris@102 124 m_interval_sequence[i] = 2 * ( i + 1 );
Chris@102 125 m_coeff[i].resize( i );
Chris@102 126 for ( size_t k = 0; k < i; ++k )
Chris@102 127 {
Chris@102 128 const value_type r =
Chris@102 129 static_cast< value_type >( m_interval_sequence[i] ) /
Chris@102 130 static_cast< value_type >( m_interval_sequence[k] );
Chris@102 131 m_coeff[i][k] =
Chris@102 132 static_cast< value_type >( 1 ) /
Chris@102 133 ( r * r - static_cast< value_type >(
Chris@102 134 1 ) ); // coefficients for extrapolation
Chris@102 135 }
Chris@102 136 }
Chris@102 137 }
Chris@102 138
Chris@102 139 template < class System, class StateIn, class DerivIn, class StateOut,
Chris@102 140 class Err >
Chris@102 141 void do_step_impl( System system, const StateIn &in, const DerivIn &dxdt,
Chris@102 142 time_type t, StateOut &out, time_type dt, Err &xerr )
Chris@102 143 {
Chris@102 144 // std::cout << "dt: " << dt << std::endl;
Chris@102 145 // normal step
Chris@102 146 do_step_impl( system, in, dxdt, t, out, dt );
Chris@102 147
Chris@102 148 static const value_type val1( 1.0 );
Chris@102 149 // additionally, perform the error calculation
Chris@102 150 stepper_base_type::m_algebra.for_each3(
Chris@102 151 xerr, out, m_table[0].m_v,
Chris@102 152 typename operations_type::template scale_sum2<
Chris@102 153 value_type, value_type >( val1, -val1 ) );
Chris@102 154 }
Chris@102 155
Chris@102 156 template < class System, class StateInOut, class DerivIn, class Err >
Chris@102 157 void do_step_impl_io( System system, StateInOut &inout, const DerivIn &dxdt,
Chris@102 158 time_type t, time_type dt, Err &xerr )
Chris@102 159 {
Chris@102 160 // normal step
Chris@102 161 do_step_impl_io( system, inout, dxdt, t, dt );
Chris@102 162
Chris@102 163 static const value_type val1( 1.0 );
Chris@102 164 // additionally, perform the error calculation
Chris@102 165 stepper_base_type::m_algebra.for_each3(
Chris@102 166 xerr, inout, m_table[0].m_v,
Chris@102 167 typename operations_type::template scale_sum2<
Chris@102 168 value_type, value_type >( val1, -val1 ) );
Chris@102 169 }
Chris@102 170
Chris@102 171 template < class System, class StateIn, class DerivIn, class StateOut >
Chris@102 172 void do_step_impl( System system, const StateIn &in, const DerivIn &dxdt,
Chris@102 173 time_type t, StateOut &out, time_type dt )
Chris@102 174 {
Chris@102 175 m_resizer.adjust_size(
Chris@102 176 in, detail::bind( &stepper_type::template resize_impl< StateIn >,
Chris@102 177 detail::ref( *this ), detail::_1 ) );
Chris@102 178 size_t k = 0;
Chris@102 179 m_midpoint.set_steps( m_interval_sequence[k] );
Chris@102 180 m_midpoint.do_step( system, in, dxdt, t, out, dt );
Chris@102 181 for ( k = 1; k <= m_k_max; ++k )
Chris@102 182 {
Chris@102 183 m_midpoint.set_steps( m_interval_sequence[k] );
Chris@102 184 m_midpoint.do_step( system, in, dxdt, t, m_table[k - 1].m_v, dt );
Chris@102 185 extrapolate( k, m_table, m_coeff, out );
Chris@102 186 }
Chris@102 187 }
Chris@102 188
Chris@102 189 template < class System, class StateInOut, class DerivIn >
Chris@102 190 void do_step_impl_io( System system, StateInOut &inout, const DerivIn &dxdt,
Chris@102 191 time_type t, time_type dt )
Chris@102 192 {
Chris@102 193 // special care for inout
Chris@102 194 m_xout_resizer.adjust_size(
Chris@102 195 inout,
Chris@102 196 detail::bind( &stepper_type::template resize_m_xout< StateInOut >,
Chris@102 197 detail::ref( *this ), detail::_1 ) );
Chris@102 198 do_step_impl( system, inout, dxdt, t, m_xout.m_v, dt );
Chris@102 199 boost::numeric::odeint::copy( m_xout.m_v, inout );
Chris@102 200 }
Chris@102 201
Chris@102 202 template < class System, class StateInOut, class DerivIn >
Chris@102 203 void do_step_dxdt_impl( System system, StateInOut &x, const DerivIn &dxdt,
Chris@102 204 time_type t, time_type dt )
Chris@102 205 {
Chris@102 206 do_step_impl_io( system , x , dxdt , t , dt );
Chris@102 207 }
Chris@102 208
Chris@102 209 template < class System, class StateIn, class DerivIn, class StateOut >
Chris@102 210 void do_step_dxdt_impl( System system, const StateIn &in,
Chris@102 211 const DerivIn &dxdt, time_type t, StateOut &out,
Chris@102 212 time_type dt )
Chris@102 213 {
Chris@102 214 do_step_impl( system , in , dxdt , t , out , dt );
Chris@102 215 }
Chris@102 216
Chris@102 217
Chris@102 218 template < class StateIn > void adjust_size( const StateIn &x )
Chris@102 219 {
Chris@102 220 resize_impl( x );
Chris@102 221 m_midpoint.adjust_size( x );
Chris@102 222 }
Chris@102 223
Chris@102 224 private:
Chris@102 225 template < class StateIn > bool resize_impl( const StateIn &x )
Chris@102 226 {
Chris@102 227 bool resized( false );
Chris@102 228 for ( size_t i = 0; i < m_k_max; ++i )
Chris@102 229 resized |= adjust_size_by_resizeability(
Chris@102 230 m_table[i], x, typename is_resizeable< state_type >::type() );
Chris@102 231 return resized;
Chris@102 232 }
Chris@102 233
Chris@102 234 template < class StateIn > bool resize_m_xout( const StateIn &x )
Chris@102 235 {
Chris@102 236 return adjust_size_by_resizeability(
Chris@102 237 m_xout, x, typename is_resizeable< state_type >::type() );
Chris@102 238 }
Chris@102 239
Chris@102 240 template < class StateInOut >
Chris@102 241 void extrapolate( size_t k, state_table_type &table,
Chris@102 242 const value_matrix &coeff, StateInOut &xest )
Chris@102 243 /* polynomial extrapolation, see http://www.nr.com/webnotes/nr3web21.pdf
Chris@102 244 uses the obtained intermediate results to extrapolate to dt->0
Chris@102 245 */
Chris@102 246 {
Chris@102 247 static const value_type val1 = static_cast< value_type >( 1.0 );
Chris@102 248
Chris@102 249 for ( int j = k - 1; j > 0; --j )
Chris@102 250 {
Chris@102 251 stepper_base_type::m_algebra.for_each3(
Chris@102 252 table[j - 1].m_v, table[j].m_v, table[j - 1].m_v,
Chris@102 253 typename operations_type::template scale_sum2<
Chris@102 254 value_type, value_type >( val1 + coeff[k][j],
Chris@102 255 -coeff[k][j] ) );
Chris@102 256 }
Chris@102 257 stepper_base_type::m_algebra.for_each3(
Chris@102 258 xest, table[0].m_v, xest,
Chris@102 259 typename operations_type::template scale_sum2<
Chris@102 260 value_type, value_type >( val1 + coeff[k][0], -coeff[k][0] ) );
Chris@102 261 }
Chris@102 262
Chris@102 263 private:
Chris@102 264 midpoint_stepper_type m_midpoint;
Chris@102 265
Chris@102 266 resizer_type m_resizer;
Chris@102 267 resizer_type m_xout_resizer;
Chris@102 268
Chris@102 269 int_vector m_interval_sequence; // stores the successive interval counts
Chris@102 270 value_matrix m_coeff;
Chris@102 271
Chris@102 272 wrapped_state_type m_xout;
Chris@102 273 state_table_type m_table; // sequence of states for extrapolation
Chris@102 274 };
Chris@102 275
Chris@102 276 /******** DOXYGEN *******/
Chris@102 277
Chris@102 278 /**
Chris@102 279 * \class extrapolation_stepper
Chris@102 280 * \brief Extrapolation stepper with configurable order, and error estimation.
Chris@102 281 *
Chris@102 282 * The extrapolation stepper is a stepper with error estimation and configurable
Chris@102 283 * order. The order is given as template parameter and needs to be an _odd_
Chris@102 284 * number. The stepper is based on several executions of the modified midpoint
Chris@102 285 * method and a Richardson extrapolation. This is essentially the same technique
Chris@102 286 * as for bulirsch_stoer, but without the variable order.
Chris@102 287 *
Chris@102 288 * \note The Order parameter has to be an even number greater 2.
Chris@102 289 */
Chris@102 290 }
Chris@102 291 }
Chris@102 292 }
Chris@102 293 #endif