如何将查找表中的时变参数合并到boost :: odeint,c ++中

时间:2016-07-29 15:25:52

标签: c++ boost odeint

我正在尝试使用boost :: odeint在数值上集成非线性系统。系统具有外部生成的时变参数,我想将其合并到我的程序中。这可能与odeint有关吗?在Matlab中,如果你要做类似的事情,你需要在值可用时插值。

提前感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

是的,这是可能的。但您可能还需要插值。您可以通过系统功能与解算器进行交互。它可以是仿函数,它可以包含数据的链接,例如

struct ode
{
    void operator()( const state_type& x , state_type& dxdt , double t ) const
    {
         // get the the parameter from time_varying_parameters
    }
    std::vector<double> time_varying_parameters;
};

答案 1 :(得分:0)

编辑:

您可以使用odeint轻松解决非线性时变系统问题。以下非线性时变系统示例取自Applied Nonlinear Control by Slotine

enter image description here

请注意,我们可以安全地在6sin(t)内插入ode,因为我们在每个时间步都没有做任何事情。如果你的系统有一个控制器,它依赖于像PID控制器那样需要增量时间来计算导数的时间步长,那么在这种情况下,不要将它放在ode内,因为ode()被多次调用由颂歌解决者。这是我解决系统的代码。

#include <iostream>
#include <boost/math/constants/constants.hpp>
#include <boost/numeric/odeint.hpp>
#include <fstream>

std::ofstream data("data.txt");

using namespace boost::numeric::odeint;

typedef std::vector< double > state_type;

class System
{
public:
    System(const double& deltaT);
    void updateODE();
    void updateSystem();
private:
    double t, dt;
    runge_kutta_dopri5 < state_type > stepper;
    state_type y;
    void ode(const state_type &y, state_type &dy, double t);

};

System::System(const double& deltaT) : dt(deltaT), t(0.0), y(2)
{
    /*
       x = y[0]
      dx = y[1] = dy[0]
     ddx        = dy[1] = ode equation
     */

    // initial values
    y[0] = 2.0;  //  x1 
    y[1] = 0.0;  //  x2
}

void System::updateODE()
{
    // store data for plotting  
    data << t << " " << y[0] << std::endl;

    //=========================================================================
    using namespace std::placeholders;
    stepper.do_step(std::bind(&System::ode, this, _1, _2, _3), y, t, dt);
    t += dt;
}

void System::updateSystem()
{
    // you can utitilize this function in case you have a controller and 
    // you need to update the controller at a fixed step size. 

}

void System::ode(const state_type &y, state_type &dy, double t)
{
    //#####################( ODE Equation )################################
    dy[0] = y[1];
    dy[1] = 6.0*sin(t) - 0.1*y[1] - pow(y[0],5);
}

int main(int argc, char **argv)
{
    const double dt(0.001); 
    System sys(dt);

    for (double t(0.0); t <= 50.0; t += dt){
        // update time-varying parameters of the system 
        //sys.updateSystem();
        // solve the ODE one step forward. 
        sys.updateODE();
    }

    return 0;
}

结果是(即上述书中给出的结果相同)。

enter image description here