无法通过math.js使Lotka-Volterra方程振荡稳定

时间:2017-11-23 22:58:53

标签: javascript differential-equations math.js

我试图用JavaScript实现一个简单的Lotka-Volterra系统,但是从我在学术论文和幻灯片中看到的结果得到了不同的结果。这是我的等式:

sim2.eval("dxdt(x, y) = (2 * x) - (x * y)");
sim2.eval("dydt(x, y) = (-0.25 * y) + (x * y)");

使用系数a = 2,b = 1,c = 0.25和d = 1.但是,我的结果如下:

enter image description here

当我预期稳定的振荡时,如PDF slides所示:

enter image description here

可能是ndsolve的实现会导致这种情况吗?或者由于浮点运算导致JavaScript出现机器错误?

2 个答案:

答案 0 :(得分:1)

无视,错误只是使用了太大的评估步骤(dt = 0.1,至少必须为0.01)。所使用的数值方法对于这个问题是已知的。

答案 1 :(得分:0)

出于严肃的目的使用更高阶的方法,最小的是固定步骤经典Runge-Kutta。然后你也可以使用tfinal=300,它在多个时期都是稳定的,我试过dt=0.05没有问题。但是,您将在图表中看到步长,因为它明显是分段线性的。步长的一半function odesolveRK4(f, x0, dt, tmax) { var n = f.size()[0]; // Number of variables var x = x0.clone(),xh=[]; // Current values of variables var dxdt = [], k1=[], k2=[], k3=[], k4=[]; // Temporary variable to hold time-derivatives var result = []; // Contains entire solution var nsteps = math.divide(tmax, dt); // Number of time steps dt2 = math.divide(dt,2); dt6 = math.divide(dt,6); for(var i=0; i<nsteps; i++) { // compute the 4 stages if the classical order-4 Runge-Kutta method k1 = f.map(function(fj) {return fj.apply(null, x.toArray()); } ); xh = math.add(x, math.multiply(k1, dt2)); k2 = f.map(function(fj) {return fj.apply(null, xh.toArray()); } ); xh = math.add(x, math.multiply(k2, dt2)); k3 = f.map(function(fj) {return fj.apply(null, xh.toArray()); } ); xh = math.add(x, math.multiply(k3, dt)); k4 = f.map(function(fj) {return fj.apply(null, xh.toArray()); } ); x = math.add(x, math.multiply(math.add(math.add(k1,k4), math.multiply(math.add(k2,k3),2)), dt6)) if( 0==i%50) console.log("%3d %o %o",i,dt,x.toString()); result.push(x.clone()); } return math.matrix(result); } math.import({odesolveRK4:odesolveRK4}); 会大大减少。

{{1}}