使用boost :: odeint与本征::矩阵状态向量 [英] Using Boost::odeint with Eigen::Matrix as state vector
问题描述
我想利用的 ODE集成升压能力利用本征3 作为 Matrix类我状态向量,但我遇到了问题深入升压,我不知道如何解决。
的什么,我试图做一个小例子:
的#include<艾根/酷睿>
#包括LT&;升压/数字/ odeint /步进/ runge_kutta_dopri5.hpp>
#包括LT&;&iostream的GT;使用本征空间;
使用空间boost ::数字:: odeint;模板<为size_t N'GT;
采用矢量=矩阵和LT;双,N,1取代;typedef的矢量< 3>州;诠释主(){ 状态X0;
X0<< 1.,2,3 .;
国家XOUT = X0; runge_kutta_dopri5<州与GT;步进; //如果我删除这些行,一切都正常编译
stepper.do_step([](常量状态x,国家dxdt,常量双T) - GT;无效{
dxdt = X;
},X0,0.0,XOUT 0.01); 性病::法院LT&;< XOUT<<的std :: ENDL;
}
如果我COMENT了调用 stepper.do_step
一切编译和运行得很好,但当然没有做什么有趣的事。如果我不这样做,升压呕吐编译过我的终端的错误,第一个是
在文件从/usr/include/boost/mpl/aux_/begin_end_impl.hpp:20:0包括,
从/usr/include/boost/mpl/begin_end.hpp:18,
从/usr/include/boost/mpl/is_sequence.hpp:19,
从/usr/include/boost/fusion/support/detail/is_mpl_sequence.hpp:12,
从/usr/include/boost/fusion/support/tag_of.hpp:13,
从/usr/include/boost/fusion/support/is_sequence.hpp:11,
从/usr/include/boost/fusion/sequence/intrinsic_fwd.hpp:12,
从/usr/include/boost/fusion/sequence/intrinsic/front.hpp:10,
从/usr/include/boost/fusion/include/front.hpp:10,
从/usr/include/boost/numeric/odeint/util/is_resizeable.hpp:26,
从/usr/include/boost/numeric/odeint/util/state_wrapper.hpp:25,
从/usr/include/boost/numeric/odeint/stepper/base/explicit_error_stepper_fsal_base.hpp:27,
从/usr/include/boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp:24,
从/home/tlycken/exjobb/$c$c/alpha-orbit-follower/test/algebra/algebra-tests.cpp:2:
/usr/include/boost/mpl/eval_if.hpp:在结构提升实例:: MPL :: eval_if_c<真,提振:: range_const_iterator<本征::矩阵和LT;双,3,1> >中的boost :: range_mutable_iterator<常量征::矩阵和LT;双,3,1> > >':
/usr/include/boost/range/iterator.hpp:63:63:从结构的boost :: range_iterator&LT必需的; 3,1&GT双; const的本征::矩阵和LT; >'
/usr/include/boost/range/begin.hpp:112:61:通过模板&LT替代需要;类T>类型名的boost :: range_iterator<常量T> ::类型boost :: range_adl_barrier ::开始(常量T&安培;)与T =本征::矩阵和LT;双,3,1>]
/usr/include/boost/numeric/odeint/algebra/range_algebra.hpp:52:45:从静态无效升压所需::数字:: odeint :: range_algebra :: for_each3(S1和放大器,S2放大器,S3放;,欧普)与S1 =本征::矩阵和LT;双,3,1取代; S2 =常数本征::矩阵和LT;双,3,1取代; S3 =常数本征::矩阵和LT;双,3,1取代; OP =的boost ::数字:: odeint :: default_operations :: scale_sum2<双层,双>]
/usr/include/boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp:128:9:从'无效升压所需::数字:: odeint :: runge_kutta_dopri5<状态,价值,DERIV,时间,代数,运营,调整器> :: do_step_impl(系统,常量StateIn和放大器;,常量DerivIn&放;,提高::数字:: odeint :: runge_kutta_dopri5<状态,价值,DERIV,时间,代数,运营,调整器> :: time_type,StateOut和放大器;,DerivOut和放大器;,提振::数字:: odeint :: runge_kutta_dopri5<状态,价值,DERIV,时间,代数,运营,调整器> :: time_type)与系统主=():: __ lambda0; StateIn =本征::矩阵和LT;双,3,1取代; DerivIn =本征::矩阵和LT;双,3,1取代; StateOut =本征::矩阵和LT;双,3,1取代; DerivOut =本征::矩阵和LT;双,3,1取代;状态=本征::矩阵和LT;双,3,1取代;值=双; DERIV =本征::矩阵和LT;双,3,1取代;时间=双;代数=提高::数字:: odeint :: range_algebra;操作=提高::数字:: odeint :: default_operations;调整器=提高::数字:: odeint :: initially_resizer;提高::数字:: odeint :: runge_kutta_dopri5<状态,价值,DERIV,时间,代数,运营,调整器> :: time_type =双重]'
/usr/include/boost/numeric/odeint/stepper/base/explicit_error_stepper_fsal_base.hpp:167:9:从'typename的提升需要:: disable_if<提高:: is_same< StateInOut,时间&gt ;,无效> ::类型boost ::数字:: odeint :: explicit_error_stepper_fsal_base<步进,秩序,StepperOrder,ErrorOrder,国家,价值,DERIV,时间,代数,运营,调整器> :: do_step(系统,常量StateIn&放;,提高::数字:: odeint :: explicit_error_stepper_fsal_base&LT ;步进,秩序,StepperOrder,ErrorOrder,国家,价值,DERIV,时间,代数,运营,调整器> :: time_type,StateOut和放大器;,提高::数字:: odeint :: explicit_error_stepper_fsal_base<步进,秩序,StepperOrder,ErrorOrder,国家,价值,DERIV,时间,代数,运营,调整器> :: time_type)与系统主=():: __ lambda0; StateIn =本征::矩阵和LT;双,3,1取代; StateOut =本征::矩阵和LT;双,3,1取代;步进=的boost ::数字:: odeint :: runge_kutta_dopri5<本征::矩阵和LT;双,3,1>取代;短期无符号整型令= 5U;短期无符号整型StepperOrder = 5U;短期无符号整型ErrorOrder = 4U;状态=本征::矩阵和LT;双,3,1取代;值=双; DERIV =本征::矩阵和LT;双,3,1取代;时间=双;代数=提高::数字:: odeint :: range_algebra;操作=提高::数字:: odeint :: default_operations;调整器=提高::数字:: odeint :: initially_resizer;类型名的boost :: disable_if<提高:: is_same< StateInOut,时间&gt ;,无效> ::类型=无效;提高::数字:: odeint :: explicit_error_stepper_fsal_base<步进,秩序,StepperOrder,ErrorOrder,国家,价值,DERIV,时间,代数,运营,调整器> :: time_type =双重]'
/home/tlycken/exjobb/$c$c/alpha-orbit-follower/test/algebra/algebra-tests.cpp:21:137:从这里需要
/usr/include/boost/mpl/eval_if.hpp:60:31:错误:没有键入'助推名为'类型':: MPL :: eval_if_c<真,提振:: range_const_iterator<本征::矩阵和LT;双,3 ,1> >中的boost :: range_mutable_iterator<常量征::矩阵和LT;双,3,1> > > :: {F_又名结构的boost :: range_const_iterator<本征::矩阵和LT;双,3,1> >}'
的typedef typename的˚F_ :: type类型;
我试图钻进去的Boost头文件出错位置,但我没有足够的理解发生了什么事情才能够解决我的code的。由于odeint库文档<一个href=\"http://www.boost.org/doc/libs/1_55_0/libs/numeric/odeint/doc/html/boost_numeric_odeint/getting_started/overview.html\"相对=nofollow>明确
odeint的主要重点是提供一种方法实现的数值方法,其中所述算法是完全独立于用于重新present的状态x的数据结构
块引用>我相信这应该不是太难得到工作,即使odeint不支持原生的本征
解决方案您只需要通过
更换步进的定义runge_kutta_dopri5&LT;状态,双状态,双,vector_space_algebra&GT;步进;
本征应开箱与
vector_space_algebra
,但你需要手动指定它们。在接下来的版本odeint我们有一个机制,用于自动检测代数。顺便说一句。悠逸的ODE的定义是不正确的,你需要的derivatve参考
stepper.do_step([](常量状态和放大器; X,状态和放大器; dxdt,常量双T) - GT;无效{
dxdt = X;
},X0,0.0,XOUT 0.01);I'm trying to utilize the ODE integration capabilities of Boost using the Matrix class from Eigen 3 as my state vector, but I'm running into problems deep into Boost that I don't understand how to address.
A minimal example of what I'm trying to do:
#include <Eigen/Core> #include <boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp> #include <iostream> using namespace Eigen; using namespace boost::numeric::odeint; template<size_t N> using vector = Matrix<double, N, 1>; typedef vector<3> state; int main() { state X0; X0 << 1., 2., 3.; state xout = X0; runge_kutta_dopri5<state> stepper; // If I remove these lines, everything compiles fine stepper.do_step([](const state x, state dxdt, const double t) -> void { dxdt = x; }, X0, 0.0, xout, 0.01); std::cout << xout << std::endl; }
If I coment out the call to
stepper.do_step
everything compiles and runs just fine, but of course doesn't do anything interesting. If I don't, Boost vomits compile errors over my terminal, the first of which isIn file included from /usr/include/boost/mpl/aux_/begin_end_impl.hpp:20:0, from /usr/include/boost/mpl/begin_end.hpp:18, from /usr/include/boost/mpl/is_sequence.hpp:19, from /usr/include/boost/fusion/support/detail/is_mpl_sequence.hpp:12, from /usr/include/boost/fusion/support/tag_of.hpp:13, from /usr/include/boost/fusion/support/is_sequence.hpp:11, from /usr/include/boost/fusion/sequence/intrinsic_fwd.hpp:12, from /usr/include/boost/fusion/sequence/intrinsic/front.hpp:10, from /usr/include/boost/fusion/include/front.hpp:10, from /usr/include/boost/numeric/odeint/util/is_resizeable.hpp:26, from /usr/include/boost/numeric/odeint/util/state_wrapper.hpp:25, from /usr/include/boost/numeric/odeint/stepper/base/explicit_error_stepper_fsal_base.hpp:27, from /usr/include/boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp:24, from /home/tlycken/exjobb/Code/alpha-orbit-follower/test/algebra/algebra-tests.cpp:2: /usr/include/boost/mpl/eval_if.hpp: In instantiation of ‘struct boost::mpl::eval_if_c<true, boost::range_const_iterator<Eigen::Matrix<double, 3, 1> >, boost::range_mutable_iterator<const Eigen::Matrix<double, 3, 1> > >’: /usr/include/boost/range/iterator.hpp:63:63: required from ‘struct boost::range_iterator<const Eigen::Matrix<double, 3, 1> >’ /usr/include/boost/range/begin.hpp:112:61: required by substitution of ‘template<class T> typename boost::range_iterator<const T>::type boost::range_adl_barrier::begin(const T&) [with T = Eigen::Matrix<double, 3, 1>]’ /usr/include/boost/numeric/odeint/algebra/range_algebra.hpp:52:45: required from ‘static void boost::numeric::odeint::range_algebra::for_each3(S1&, S2&, S3&, Op) [with S1 = Eigen::Matrix<double, 3, 1>; S2 = const Eigen::Matrix<double, 3, 1>; S3 = const Eigen::Matrix<double, 3, 1>; Op = boost::numeric::odeint::default_operations::scale_sum2<double, double>]’ /usr/include/boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp:128:9: required from ‘void boost::numeric::odeint::runge_kutta_dopri5<State, Value, Deriv, Time, Algebra, Operations, Resizer>::do_step_impl(System, const StateIn&, const DerivIn&, boost::numeric::odeint::runge_kutta_dopri5<State, Value, Deriv, Time, Algebra, Operations, Resizer>::time_type, StateOut&, DerivOut&, boost::numeric::odeint::runge_kutta_dopri5<State, Value, Deriv, Time, Algebra, Operations, Resizer>::time_type) [with System = main()::__lambda0; StateIn = Eigen::Matrix<double, 3, 1>; DerivIn = Eigen::Matrix<double, 3, 1>; StateOut = Eigen::Matrix<double, 3, 1>; DerivOut = Eigen::Matrix<double, 3, 1>; State = Eigen::Matrix<double, 3, 1>; Value = double; Deriv = Eigen::Matrix<double, 3, 1>; Time = double; Algebra = boost::numeric::odeint::range_algebra; Operations = boost::numeric::odeint::default_operations; Resizer = boost::numeric::odeint::initially_resizer; boost::numeric::odeint::runge_kutta_dopri5<State, Value, Deriv, Time, Algebra, Operations, Resizer>::time_type = double]’ /usr/include/boost/numeric/odeint/stepper/base/explicit_error_stepper_fsal_base.hpp:167:9: required from ‘typename boost::disable_if<boost::is_same<StateInOut, Time>, void>::type boost::numeric::odeint::explicit_error_stepper_fsal_base<Stepper, Order, StepperOrder, ErrorOrder, State, Value, Deriv, Time, Algebra, Operations, Resizer>::do_step(System, const StateIn&, boost::numeric::odeint::explicit_error_stepper_fsal_base<Stepper, Order, StepperOrder, ErrorOrder, State, Value, Deriv, Time, Algebra, Operations, Resizer>::time_type, StateOut&, boost::numeric::odeint::explicit_error_stepper_fsal_base<Stepper, Order, StepperOrder, ErrorOrder, State, Value, Deriv, Time, Algebra, Operations, Resizer>::time_type) [with System = main()::__lambda0; StateIn = Eigen::Matrix<double, 3, 1>; StateOut = Eigen::Matrix<double, 3, 1>; Stepper = boost::numeric::odeint::runge_kutta_dopri5<Eigen::Matrix<double, 3, 1> >; short unsigned int Order = 5u; short unsigned int StepperOrder = 5u; short unsigned int ErrorOrder = 4u; State = Eigen::Matrix<double, 3, 1>; Value = double; Deriv = Eigen::Matrix<double, 3, 1>; Time = double; Algebra = boost::numeric::odeint::range_algebra; Operations = boost::numeric::odeint::default_operations; Resizer = boost::numeric::odeint::initially_resizer; typename boost::disable_if<boost::is_same<StateInOut, Time>, void>::type = void; boost::numeric::odeint::explicit_error_stepper_fsal_base<Stepper, Order, StepperOrder, ErrorOrder, State, Value, Deriv, Time, Algebra, Operations, Resizer>::time_type = double]’ /home/tlycken/exjobb/Code/alpha-orbit-follower/test/algebra/algebra-tests.cpp:21:137: required from here /usr/include/boost/mpl/eval_if.hpp:60:31: error: no type named ‘type’ in ‘boost::mpl::eval_if_c<true, boost::range_const_iterator<Eigen::Matrix<double, 3, 1> >, boost::range_mutable_iterator<const Eigen::Matrix<double, 3, 1> > >::f_ {aka struct boost::range_const_iterator<Eigen::Matrix<double, 3, 1> >}’ typedef typename f_::type type;
I tried to dig into the Boost header where the error occurs, but I didn't understand enough of what's going on to be able to fix my code. Since the odeint library documentation clearly states
The main focus of odeint is to provide numerical methods implemented in a way where the algorithm is completely independent on the data structure used to represent the state x.
I believe this shouldn't be too hard to get working even if odeint doesn't support Eigen natively.
解决方案You only need to replace the definition of the stepper by
runge_kutta_dopri5<state,double,state,double,vector_space_algebra> stepper;
Eigen should work out of the Box with the
vector_space_algebra
but you need to specify them manually. In the next odeint version we have a mechanism for automatically detecting the algebra.Btw. youe definition of the ODE is not correct, you need a reference for the derivatve
stepper.do_step([](const state &x, state &dxdt, const double t) -> void { dxdt = x; }, X0, 0.0, xout, 0.01);
这篇关于使用boost :: odeint与本征::矩阵状态向量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!