This commit is contained in:
2026-03-23 20:54:41 +08:00
commit e13b3650e9
4596 changed files with 1015768 additions and 0 deletions

View File

@@ -0,0 +1,70 @@
/*
[auto_generated]
boost/numeric/odeint/integrate/detail/functors.hpp
[begin_description]
some functors for the iterator based integrate routines
[end_description]
Copyright 2009-2013 Karsten Ahnert
Copyright 2009-2013 Mario Mulansky
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or
copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_NUMERIC_ODEINT_INTEGRATE_DETAIL_FUNCTORS_HPP_INCLUDED
#define BOOST_NUMERIC_ODEINT_INTEGRATE_DETAIL_FUNCTORS_HPP_INCLUDED
#include <utility>
namespace boost {
namespace numeric {
namespace odeint {
namespace detail {
template< class Observer >
struct obs_caller {
size_t &m_n;
Observer m_obs;
obs_caller( size_t &m , Observer &obs ) : m_n(m) , m_obs( obs ) {}
template< class State , class Time >
void operator()( std::pair< const State & , const Time & > x )
{
typedef typename odeint::unwrap_reference< Observer >::type observer_type;
observer_type &obs = m_obs;
obs( x.first , x.second );
m_n++;
}
};
template< class Observer , class Time >
struct obs_caller_time {
Time &m_t;
Observer m_obs;
obs_caller_time( Time &t , Observer &obs ) : m_t(t) , m_obs( obs ) {}
template< class State >
void operator()( std::pair< const State & , const Time & > x )
{
typedef typename odeint::unwrap_reference< Observer >::type observer_type;
observer_type &obs = m_obs;
obs( x.first , x.second );
m_t = x.second;
}
};
} // namespace detail
} // namespace odeint
} // namespace numeric
} // namespace boost
#endif // BOOST_NUMERIC_ODEINT_INTEGRATE_DETAIL_FUNCTORS_HPP_INCLUDED

View File

@@ -0,0 +1,161 @@
/*
[auto_generated]
boost/numeric/odeint/integrate/detail/integrate_adaptive.hpp
[begin_description]
Default Integrate adaptive implementation.
[end_description]
Copyright 2011-2013 Karsten Ahnert
Copyright 2011-2015 Mario Mulansky
Copyright 2012 Christoph Koke
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or
copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_NUMERIC_ODEINT_INTEGRATE_DETAIL_INTEGRATE_ADAPTIVE_HPP_INCLUDED
#define BOOST_NUMERIC_ODEINT_INTEGRATE_DETAIL_INTEGRATE_ADAPTIVE_HPP_INCLUDED
#include <stdexcept>
#include <boost/throw_exception.hpp>
#include <boost/numeric/odeint/stepper/stepper_categories.hpp>
#include <boost/numeric/odeint/stepper/controlled_step_result.hpp>
#include <boost/numeric/odeint/integrate/max_step_checker.hpp>
#include <boost/numeric/odeint/integrate/detail/integrate_const.hpp>
#include <boost/numeric/odeint/util/bind.hpp>
#include <boost/numeric/odeint/util/unwrap_reference.hpp>
#include <boost/numeric/odeint/util/copy.hpp>
#include <boost/numeric/odeint/util/detail/less_with_sign.hpp>
#include <iostream>
namespace boost {
namespace numeric {
namespace odeint {
namespace detail {
// forward declaration
template< class Stepper , class System , class State , class Time , class Observer >
size_t integrate_const(
Stepper stepper , System system , State &start_state ,
Time start_time , Time end_time , Time dt ,
Observer observer , stepper_tag );
/*
* integrate_adaptive for simple stepper is basically an integrate_const + some last step
*/
template< class Stepper , class System , class State , class Time , class Observer >
size_t integrate_adaptive(
Stepper stepper , System system , State &start_state ,
Time start_time , Time end_time , Time dt ,
Observer observer , stepper_tag
)
{
size_t steps = detail::integrate_const( stepper , system , start_state , start_time ,
end_time , dt , observer , stepper_tag() );
typename odeint::unwrap_reference< Observer >::type &obs = observer;
typename odeint::unwrap_reference< Stepper >::type &st = stepper;
Time end = start_time + dt*steps;
if( less_with_sign( end , end_time , dt ) )
{ //make a last step to end exactly at end_time
st.do_step( system , start_state , end , end_time - end );
steps++;
obs( start_state , end_time );
}
return steps;
}
/*
* integrate adaptive for controlled stepper
*/
template< class Stepper , class System , class State , class Time , class Observer >
size_t integrate_adaptive(
Stepper stepper , System system , State &start_state ,
Time &start_time , Time end_time , Time &dt ,
Observer observer , controlled_stepper_tag
)
{
typename odeint::unwrap_reference< Observer >::type &obs = observer;
typename odeint::unwrap_reference< Stepper >::type &st = stepper;
failed_step_checker fail_checker; // to throw a runtime_error if step size adjustment fails
size_t count = 0;
while( less_with_sign( start_time , end_time , dt ) )
{
obs( start_state , start_time );
if( less_with_sign( end_time , static_cast<Time>(start_time + dt) , dt ) )
{
dt = end_time - start_time;
}
controlled_step_result res;
do
{
res = st.try_step( system , start_state , start_time , dt );
fail_checker(); // check number of failed steps
}
while( res == fail );
fail_checker.reset(); // if we reach here, the step was successful -> reset fail checker
++count;
}
obs( start_state , start_time );
return count;
}
/*
* integrate adaptive for dense output steppers
*
* step size control is used if the stepper supports it
*/
template< class Stepper , class System , class State , class Time , class Observer >
size_t integrate_adaptive(
Stepper stepper , System system , State &start_state ,
Time start_time , Time end_time , Time dt ,
Observer observer , dense_output_stepper_tag )
{
typename odeint::unwrap_reference< Observer >::type &obs = observer;
typename odeint::unwrap_reference< Stepper >::type &st = stepper;
size_t count = 0;
st.initialize( start_state , start_time , dt );
while( less_with_sign( st.current_time() , end_time , st.current_time_step() ) )
{
while( less_eq_with_sign( static_cast<Time>(st.current_time() + st.current_time_step()) ,
end_time ,
st.current_time_step() ) )
{ //make sure we don't go beyond the end_time
obs( st.current_state() , st.current_time() );
st.do_step( system );
++count;
}
// calculate time step to arrive exactly at end time
st.initialize( st.current_state() , st.current_time() , static_cast<Time>(end_time - st.current_time()) );
}
obs( st.current_state() , st.current_time() );
// overwrite start_state with the final point
boost::numeric::odeint::copy( st.current_state() , start_state );
return count;
}
} // namespace detail
} // namespace odeint
} // namespace numeric
} // namespace boost
#endif // BOOST_NUMERIC_ODEINT_INTEGRATE_DETAIL_INTEGRATE_ADAPTIVE_HPP_INCLUDED

View File

@@ -0,0 +1,167 @@
/*
[auto_generated]
boost/numeric/odeint/integrate/detail/integrate_const.hpp
[begin_description]
integrate const implementation
[end_description]
Copyright 2012-2015 Mario Mulansky
Copyright 2012 Christoph Koke
Copyright 2012 Karsten Ahnert
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or
copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_NUMERIC_ODEINT_INTEGRATE_DETAIL_INTEGRATE_CONST_HPP_INCLUDED
#define BOOST_NUMERIC_ODEINT_INTEGRATE_DETAIL_INTEGRATE_CONST_HPP_INCLUDED
#include <boost/numeric/odeint/util/unwrap_reference.hpp>
#include <boost/numeric/odeint/stepper/stepper_categories.hpp>
#include <boost/numeric/odeint/util/unit_helper.hpp>
#include <boost/numeric/odeint/integrate/detail/integrate_adaptive.hpp>
#include <boost/numeric/odeint/util/detail/less_with_sign.hpp>
namespace boost {
namespace numeric {
namespace odeint {
namespace detail {
// forward declaration
template< class Stepper , class System , class State , class Time , class Observer >
size_t integrate_adaptive(
Stepper stepper , System system , State &start_state ,
Time &start_time , Time end_time , Time &dt ,
Observer observer , controlled_stepper_tag
);
template< class Stepper , class System , class State , class Time , class Observer >
size_t integrate_const(
Stepper stepper , System system , State &start_state ,
Time start_time , Time end_time , Time dt ,
Observer observer , stepper_tag
)
{
typename odeint::unwrap_reference< Observer >::type &obs = observer;
typename odeint::unwrap_reference< Stepper >::type &st = stepper;
Time time = start_time;
int step = 0;
// cast time+dt explicitely in case of expression templates (e.g. multiprecision)
while( less_eq_with_sign( static_cast<Time>(time+dt) , end_time , dt ) )
{
obs( start_state , time );
st.do_step( system , start_state , time , dt );
// direct computation of the time avoids error propagation happening when using time += dt
// we need clumsy type analysis to get boost units working here
++step;
time = start_time + static_cast< typename unit_value_type<Time>::type >(step) * dt;
}
obs( start_state , time );
return step;
}
template< class Stepper , class System , class State , class Time , class Observer >
size_t integrate_const(
Stepper stepper , System system , State &start_state ,
Time start_time , Time end_time , Time dt ,
Observer observer , controlled_stepper_tag
)
{
typename odeint::unwrap_reference< Observer >::type &obs = observer;
Time time = start_time;
const Time time_step = dt;
int real_steps = 0;
int step = 0;
while( less_eq_with_sign( static_cast<Time>(time+time_step) , end_time , dt ) )
{
obs( start_state , time );
// integrate_adaptive_checked uses the given checker to throw if an overflow occurs
real_steps += detail::integrate_adaptive(stepper, system, start_state, time,
static_cast<Time>(time + time_step), dt,
null_observer(), controlled_stepper_tag());
// direct computation of the time avoids error propagation happening when using time += dt
// we need clumsy type analysis to get boost units working here
step++;
time = start_time + static_cast< typename unit_value_type<Time>::type >(step) * time_step;
}
obs( start_state , time );
return real_steps;
}
template< class Stepper , class System , class State , class Time , class Observer >
size_t integrate_const(
Stepper stepper , System system , State &start_state ,
Time start_time , Time end_time , Time dt ,
Observer observer , dense_output_stepper_tag
)
{
typename odeint::unwrap_reference< Observer >::type &obs = observer;
typename odeint::unwrap_reference< Stepper >::type &st = stepper;
Time time = start_time;
st.initialize( start_state , time , dt );
obs( start_state , time );
time += dt;
int obs_step( 1 );
int real_step( 0 );
while( less_eq_with_sign( static_cast<Time>(time+dt) , end_time , dt ) )
{
while( less_eq_with_sign( time , st.current_time() , dt ) )
{
st.calc_state( time , start_state );
obs( start_state , time );
++obs_step;
// direct computation of the time avoids error propagation happening when using time += dt
// we need clumsy type analysis to get boost units working here
time = start_time + static_cast< typename unit_value_type<Time>::type >(obs_step) * dt;
}
// we have not reached the end, do another real step
if( less_with_sign( static_cast<Time>(st.current_time()+st.current_time_step()) ,
end_time ,
st.current_time_step() ) )
{
while( less_eq_with_sign( st.current_time() , time , dt ) )
{
st.do_step( system );
++real_step;
}
}
else if( less_with_sign( st.current_time() , end_time , st.current_time_step() ) )
{ // do the last step ending exactly on the end point
st.initialize( st.current_state() , st.current_time() , end_time - st.current_time() );
st.do_step( system );
++real_step;
}
}
// last observation, if we are still in observation interval
// might happen due to finite precision problems when computing the the time
if( less_eq_with_sign( time , end_time , dt ) )
{
st.calc_state( time , start_state );
obs( start_state , time );
}
return real_step;
}
} } } }
#endif

View File

@@ -0,0 +1,161 @@
/*
[auto_generated]
boost/numeric/odeint/integrate/detail/integrate_n_steps.hpp
[begin_description]
integrate steps implementation
[end_description]
Copyright 2012-2015 Mario Mulansky
Copyright 2012 Christoph Koke
Copyright 2012 Karsten Ahnert
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or
copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_NUMERIC_ODEINT_INTEGRATE_DETAIL_INTEGRATE_N_STEPS_HPP_INCLUDED
#define BOOST_NUMERIC_ODEINT_INTEGRATE_DETAIL_INTEGRATE_N_STEPS_HPP_INCLUDED
#include <boost/numeric/odeint/util/unwrap_reference.hpp>
#include <boost/numeric/odeint/stepper/stepper_categories.hpp>
#include <boost/numeric/odeint/integrate/detail/integrate_adaptive.hpp>
#include <boost/numeric/odeint/util/unit_helper.hpp>
#include <boost/numeric/odeint/util/detail/less_with_sign.hpp>
namespace boost {
namespace numeric {
namespace odeint {
namespace detail {
// forward declaration
template< class Stepper , class System , class State , class Time , class Observer >
size_t integrate_adaptive_checked(
Stepper stepper , System system , State &start_state ,
Time &start_time , Time end_time , Time &dt ,
Observer observer, controlled_stepper_tag
);
/* basic version */
template< class Stepper , class System , class State , class Time , class Observer>
Time integrate_n_steps(
Stepper stepper , System system , State &start_state ,
Time start_time , Time dt , size_t num_of_steps ,
Observer observer , stepper_tag )
{
typename odeint::unwrap_reference< Observer >::type &obs = observer;
typename odeint::unwrap_reference< Stepper >::type &st = stepper;
Time time = start_time;
for( size_t step = 0; step < num_of_steps ; ++step )
{
obs( start_state , time );
st.do_step( system , start_state , time , dt );
// direct computation of the time avoids error propagation happening when using time += dt
// we need clumsy type analysis to get boost units working here
time = start_time + static_cast< typename unit_value_type<Time>::type >( step+1 ) * dt;
}
obs( start_state , time );
return time;
}
/* controlled version */
template< class Stepper , class System , class State , class Time , class Observer >
Time integrate_n_steps(
Stepper stepper , System system , State &start_state ,
Time start_time , Time dt , size_t num_of_steps ,
Observer observer , controlled_stepper_tag )
{
typename odeint::unwrap_reference< Observer >::type &obs = observer;
Time time = start_time;
Time time_step = dt;
for( size_t step = 0; step < num_of_steps ; ++step )
{
obs( start_state , time );
// integrate_adaptive_checked uses the given checker to throw if an overflow occurs
detail::integrate_adaptive(stepper, system, start_state, time, static_cast<Time>(time + time_step), dt,
null_observer(), controlled_stepper_tag());
// direct computation of the time avoids error propagation happening when using time += dt
// we need clumsy type analysis to get boost units working here
time = start_time + static_cast< typename unit_value_type<Time>::type >(step+1) * time_step;
}
obs( start_state , time );
return time;
}
/* dense output version */
template< class Stepper , class System , class State , class Time , class Observer >
Time integrate_n_steps(
Stepper stepper , System system , State &start_state ,
Time start_time , Time dt , size_t num_of_steps ,
Observer observer , dense_output_stepper_tag )
{
typename odeint::unwrap_reference< Observer >::type &obs = observer;
typename odeint::unwrap_reference< Stepper >::type &st = stepper;
Time time = start_time;
const Time end_time = start_time + static_cast< typename unit_value_type<Time>::type >(num_of_steps) * dt;
st.initialize( start_state , time , dt );
size_t step = 0;
while( step < num_of_steps )
{
while( less_with_sign( time , st.current_time() , st.current_time_step() ) )
{
st.calc_state( time , start_state );
obs( start_state , time );
++step;
// direct computation of the time avoids error propagation happening when using time += dt
// we need clumsy type analysis to get boost units working here
time = start_time + static_cast< typename unit_value_type<Time>::type >(step) * dt;
}
// we have not reached the end, do another real step
if( less_with_sign( static_cast<Time>(st.current_time()+st.current_time_step()) ,
end_time ,
st.current_time_step() ) )
{
st.do_step( system );
}
else if( less_with_sign( st.current_time() , end_time , st.current_time_step() ) )
{ // do the last step ending exactly on the end point
st.initialize( st.current_state() , st.current_time() , static_cast<Time>(end_time - st.current_time()) );
st.do_step( system );
}
}
// make sure we really end exactly where we should end
while( st.current_time() < end_time )
{
if( less_with_sign( end_time ,
static_cast<Time>(st.current_time()+st.current_time_step()) ,
st.current_time_step() ) )
st.initialize( st.current_state() , st.current_time() , static_cast<Time>(end_time - st.current_time()) );
st.do_step( system );
}
// observation at final point
obs( st.current_state() , end_time );
return time;
}
}
}
}
}
#endif /* BOOST_NUMERIC_ODEINT_INTEGRATE_DETAIL_INTEGRATE_N_STEPS_HPP_INCLUDED */

View File

@@ -0,0 +1,179 @@
/*
[auto_generated]
boost/numeric/odeint/integrate/detail/integrate_times.hpp
[begin_description]
Default integrate times implementation.
[end_description]
Copyright 2011-2015 Mario Mulansky
Copyright 2012 Karsten Ahnert
Copyright 2012 Christoph Koke
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or
copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_NUMERIC_ODEINT_INTEGRATE_DETAIL_INTEGRATE_TIMES_HPP_INCLUDED
#define BOOST_NUMERIC_ODEINT_INTEGRATE_DETAIL_INTEGRATE_TIMES_HPP_INCLUDED
#include <stdexcept>
#include <boost/config.hpp>
#include <boost/throw_exception.hpp>
#include <boost/numeric/odeint/util/unwrap_reference.hpp>
#include <boost/numeric/odeint/stepper/controlled_step_result.hpp>
#include <boost/numeric/odeint/util/detail/less_with_sign.hpp>
#include <boost/numeric/odeint/integrate/max_step_checker.hpp>
namespace boost {
namespace numeric {
namespace odeint {
namespace detail {
/*
* integrate_times for simple stepper
*/
template<class Stepper, class System, class State, class TimeIterator, class Time, class Observer>
size_t integrate_times(
Stepper stepper , System system , State &start_state ,
TimeIterator start_time , TimeIterator end_time , Time dt ,
Observer observer , stepper_tag
)
{
typedef typename odeint::unwrap_reference< Stepper >::type stepper_type;
typedef typename odeint::unwrap_reference< Observer >::type observer_type;
stepper_type &st = stepper;
observer_type &obs = observer;
typedef typename unit_value_type<Time>::type time_type;
size_t steps = 0;
Time current_dt = dt;
while( true )
{
Time current_time = *start_time++;
obs( start_state , current_time );
if( start_time == end_time )
break;
while( less_with_sign( current_time , static_cast<time_type>(*start_time) , current_dt ) )
{
current_dt = min_abs( dt , *start_time - current_time );
st.do_step( system , start_state , current_time , current_dt );
current_time += current_dt;
steps++;
}
}
return steps;
}
/*
* integrate_times for controlled stepper
*/
template< class Stepper , class System , class State , class TimeIterator , class Time , class Observer >
size_t integrate_times(
Stepper stepper , System system , State &start_state ,
TimeIterator start_time , TimeIterator end_time , Time dt ,
Observer observer , controlled_stepper_tag
)
{
typename odeint::unwrap_reference< Observer >::type &obs = observer;
typename odeint::unwrap_reference< Stepper >::type &st = stepper;
typedef typename unit_value_type<Time>::type time_type;
failed_step_checker fail_checker; // to throw a runtime_error if step size adjustment fails
size_t steps = 0;
while( true )
{
Time current_time = *start_time++;
obs( start_state , current_time );
if( start_time == end_time )
break;
while( less_with_sign( current_time , static_cast<time_type>(*start_time) , dt ) )
{
// adjust stepsize to end up exactly at the observation point
Time current_dt = min_abs( dt , *start_time - current_time );
if( st.try_step( system , start_state , current_time , current_dt ) == success )
{
++steps;
// successful step -> reset the fail counter, see #173
fail_checker.reset();
// continue with the original step size if dt was reduced due to observation
dt = max_abs( dt , current_dt );
}
else
{
fail_checker(); // check for possible overflow of failed steps in step size adjustment
dt = current_dt;
}
}
}
return steps;
}
/*
* integrate_times for dense output stepper
*/
template< class Stepper , class System , class State , class TimeIterator , class Time , class Observer >
size_t integrate_times(
Stepper stepper , System system , State &start_state ,
TimeIterator start_time , TimeIterator end_time , Time dt ,
Observer observer , dense_output_stepper_tag
)
{
typename odeint::unwrap_reference< Observer >::type &obs = observer;
typename odeint::unwrap_reference< Stepper >::type &st = stepper;
typedef typename unit_value_type<Time>::type time_type;
if( start_time == end_time )
return 0;
TimeIterator last_time_iterator = end_time;
--last_time_iterator;
Time last_time_point = static_cast<time_type>(*last_time_iterator);
st.initialize( start_state , *start_time , dt );
obs( start_state , *start_time++ );
size_t count = 0;
while( start_time != end_time )
{
while( ( start_time != end_time ) && less_eq_with_sign( static_cast<time_type>(*start_time) , st.current_time() , st.current_time_step() ) )
{
st.calc_state( *start_time , start_state );
obs( start_state , *start_time );
start_time++;
}
// we have not reached the end, do another real step
if( less_eq_with_sign( st.current_time() + st.current_time_step() ,
last_time_point ,
st.current_time_step() ) )
{
st.do_step( system );
++count;
}
else if( start_time != end_time )
{ // do the last step ending exactly on the end point
st.initialize( st.current_state() , st.current_time() , last_time_point - st.current_time() );
st.do_step( system );
++count;
}
}
return count;
}
} // namespace detail
} // namespace odeint
} // namespace numeric
} // namespace boost
#endif // BOOST_NUMERIC_ODEINT_INTEGRATE_DETAIL_INTEGRATE_ADAPTIVE_HPP_INCLUDED