使用boost :: odeint与本征::矩阵状态向量 [英] Using Boost::odeint with Eigen::Matrix as state vector

查看:821
本文介绍了使用boost :: odeint与本征::矩阵状态向量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想利用的 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 is

In 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆