2016-07-29 20 views

回答

0

編輯:

你可以很容易地解決非線性時變系統odeint。非線性時變系統下面的例子是從Applied Nonlinear Control by Slotine採取

enter image description here

注意,我們可以插入6sin(t)ode安全,因爲我們不是在每個時間步做什麼。如果你的系統有一個依賴於時間步長的控制器,如PID控制器,需要增量時間來計算導數,那麼在這種情況下,不要把它放在ode之內,因爲0123d被求解器多次調用。這是我解決系統的代碼。

#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

+0

嗨,有一個問題:在一個步求解器會調用該函數頌歌多次與不同的時間值。例如,RK4可以在一個步驟中通過時間t,t + dt/2,t + dt/2,t + dt。這可以通過將類改爲 'double GetTImeParameter(double t){return 6 * sin(t)} ode(const state_type&y,state_type&dy,double t){ dy [0] = y [1 ]。 dy [1] = GetTimeParameter(t)-0.1 * y [1]-pow(y [0],5); }' – headmyshoulder

+0

@headmyshoulder,你絕對是對的。我會更新答案以反映這個問題,當然也不需要'GetTImeParameter()'。 – CroCo

+0

@macropod,請參閱更新。 – CroCo

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; 
}; 
相關問題