【问题标题】:Do controlled error steppers in boost odeint support complex data types?boost odeint 中的受控错误步进器是否支持复杂的数据类型?
【发布时间】:2020-02-06 17:19:15
【问题描述】:

我在使用受控错误步进器和复杂状态类型的 odeint 库时遇到了问题。示例中的代码带有复杂的斯图尔特兰道方程,我对其进行了修改,使其包含一个自适应积分器。代码现在看起来像这样:

#include <iostream>
#include <complex>
#include <boost/array.hpp>

#include <boost/numeric/odeint.hpp>

using namespace std;
using namespace boost::numeric::odeint;

//[ stuart_landau_system_function
typedef complex< double > state_type;

struct stuart_landau
{
    double m_eta;
    double m_alpha;

    stuart_landau( double eta = 1.0 , double alpha = 1.0 )
    : m_eta( eta ) , m_alpha( alpha ) { }

    void operator()( const state_type &x , state_type &dxdt , double t ) const
    {
        const complex< double > I( 0.0 , 1.0 );
        dxdt = ( 1.0 + m_eta * I ) * x - ( 1.0 + m_alpha * I ) * norm( x ) * x;
    }
};
//]


struct streaming_observer
{
    std::ostream& m_out;

    streaming_observer( std::ostream &out ) : m_out( out ) { }

    template< class State >
    void operator()( const State &x , double t ) const
    {
        m_out.precision(10);
        m_out << t;
        m_out << "\t" << x.real() << "\t" << x.imag() ;
        m_out << "\n";
    }
};


int main( int argc , char **argv )
{
    //[ stuart_landau_integration
    state_type x = complex< double >( 1.0 , 0.0 );

    bulirsch_stoer< state_type > stepper( 1E-12 , 1E-12 , 1 , 1 );

    const double dt = 0.1;

    //]
    integrate_adaptive( stepper , stuart_landau( 2.0 , 1.0 ) , x , 0.0 , 10.0 , dt , streaming_observer( cout ) );

    return 0;
}

但是,如果我将步进器的定义更改为

bulirsch_stoer< state_type, complex< double > > stepper( 1E-12 , 1E-12 , 1 , 1 );

编译失败。 我的问题是:受控错误步进器不支持复杂数据类型吗?如果是这样,是否有一种方法可以规避出现的问题。或者,是否可以为复杂数据类型定义自己的向量代数?

【问题讨论】:

    标签: c++ boost odeint


    【解决方案1】:

    odeint 库确实支持复杂的数据类型,包括受控步进器。

    例如,要在 4 阶/5 阶 Dormand-Prince 方法的情况下获得受控步进器,您可以这样做:

    runge_kutta_dopri5< state_type > stepper;
    auto c_stepper = make_controlled(1.E-12, 1.E-12, stepper); 
    integrate_adaptive(c_stepper, stuart_landau( 2.0 , 1.0 ) , x , 0.0 , 10.0 , dt , streaming_observer( cout ) );
    

    state_type 的类型定义为

    typedef complex< double > state_type;
    

    但是,在 odeint 中实现的 Bulirsch-Stoer algorithm 本质上已经是一个受控步进器。因此,在这种情况下,不可能应用make_controlled 或其他策略来创建受控步进器。 odeint 库中没有这样的模板,因为它没有意义。

    您发布的第一个代码已经集成了 ODE,具有复杂的值和受控的步进器。目前尚不清楚您通过将步进器更改为来达到什么目的

    bulirsch_stoer< complex<double>, complex<double> > stepper( 1E-12 , 1E-12 , 1 , 1 );
    

    【讨论】:

    • 感谢您的回答和帮助!是的,代码的第一个版本运行,即使 bulirsch_stoer 实际上不应该使用复数。接下来,我想添加对多精度复数的支持。你能想出一种方法来包含这种类型的数据吗?我尝试了 boost mpc,但没有成功。
    • 讨论了多精度在 odeint 中的使用,例如,here,但我不知道多精度 复数 数。我认为它有效,但我没有尝试过。
    • 对不起,但我做不到,我已经累了:(我开了一个新的stackoverflow.com/questions/58306832/…
    猜你喜欢
    • 1970-01-01
    • 2020-08-02
    • 1970-01-01
    • 2019-07-24
    • 2014-03-21
    • 2012-06-23
    • 2013-07-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多