我想用boost :: odeint數值地整合一個非線性系統。系統具有外部生成的時變參數,我想將其納入我的程序中。這可能與odeint?在Matlab中,如果您要做類似的事情,則需要在值可用時插值。如何將查找表中的時變參數併入boost :: odeint,C++
非常感謝您的幫助!
我想用boost :: odeint數值地整合一個非線性系統。系統具有外部生成的時變參數,我想將其納入我的程序中。這可能與odeint?在Matlab中,如果您要做類似的事情,則需要在值可用時插值。如何將查找表中的時變參數併入boost :: odeint,C++
非常感謝您的幫助!
編輯:
你可以很容易地解決非線性時變系統odeint
。非線性時變系統下面的例子是從Applied Nonlinear Control by Slotine採取
注意,我們可以插入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;
}
結果是(即在上述書中提出了相同的結果)。
是的,這是可能的。但是您可能也需要插值。您可以通過系統功能與求解器進行交互。它可以是仿函數,它可以包含一個鏈接到的數據,例如
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;
};
嗨,有一個問題:在一個步求解器會調用該函數頌歌多次與不同的時間值。例如,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
@headmyshoulder,你絕對是對的。我會更新答案以反映這個問題,當然也不需要'GetTImeParameter()'。 – CroCo
@macropod,請參閱更新。 – CroCo