我想重現使用Mathematica
與GSL創建的ODE求解器。什麼是使用GSL的ODE求解器的「MaxSteps」的等價物?
下面是使用NDSolve
Mathematica的代碼:
result[r_] := NDSolve[{
s'[t] == theta - (mu*s[t]) - ((betaA1*IA1[t] + betaA2*IA2[t] + betaB1*IB1[t] + betaB2*IB2[t]) +
(betaA1T*TA1[t] + betaA2T*TA2[t] + betaB1T*TB1[t] + betaB2T*TB2[t])) * s[t] -
((gammaA1*IA1[t] + gammaA2*IA2[t] + gammaB1*IB1[t] + gammaB2*IB2[t]) +
(gammaA1T*TA1[t] + gammaA2T*TA2[t] + gammaB1T*TB1[t] + gammaB2T*TB2[t])),
//... Some other equations
s[0] = sinit,IA1[0] = IA1init,IA2[0] = IA2init,
IB1[0] = IB1init,IB2[0] = IB2init,TA1[0] = TA1init,
TA2[0] = TA2init,TB1[0] = TB1init,TB2[0] = TB2init},
{s,IA1,IA2,IB1,IB2,TA1,TA2,TB1,TB2},{t,0,tmax},
MaxSteps->100000, StartingStepSize->0.1, Method->{"ExplicitRungeKutta"}];
嘗試使用GSL得到完全等效:
int run_simulation() {
gsl_odeiv_evolve* e = gsl_odeiv_evolve_alloc(nbins);
gsl_odeiv_control* c = gsl_odeiv_control_y_new(1e-17, 0);
gsl_odeiv_step* s = gsl_odeiv_step_alloc(gsl_odeiv_step_rkf45, nbins);
gsl_odeiv_system sys = {function, NULL, nbins, this };
while (_t < _tmax) { //convergence check here
int status = gsl_odeiv_evolve_apply(e, c, s, &sys, &_t, _tmax, &_h, y);
if (status != GSL_SUCCESS) { return status; }
}
return 0;
}
哪裏nbins
是給求解器和_h
方程式的數當前步長。
我沒有在這裏提供方程本身,但我發現限制步數的唯一方法(在Mathematica下使用MaxSteps->100000
完成),是調整gsl_odeiv_control_y_new
控制功能的第一個參數。這裏1e-17
給我東西大約140000步...
有沒有人知道一種方法來強制GSL的ODE解算器使用給定的最大步數?正如你可能理解的那樣,對我而言,能夠真正比較這兩種工具的結果對我來說很重要。
感謝您的幫助。
非常感謝。在進一步挖掘之後,我對你提到的有關'MaxSteps'的相同結論......關於你的其他觀點,這聽起來很有趣,我會嘗試這些可能性(我不知道'gsl_odeiv2_control_hadjust',我們也不能使用GSL中的固定步驟)。那謝謝啦!還有一個問題:函數來自哪裏?_ odeiv'2' _...函數來自哪裏?我沒有他們。我的GSL版本是否太舊了? –
yeap ..你需要更新gsl到1.15或1.16來獲得odeiv2 –
好的,再次感謝Vinicius。乾杯;) –