将微分方程从Matlab移植到Python 3.4会得到不同的结果

时间:2015-03-11 19:39:17

标签: matlab python-3.x scipy differential-equations

我一直试图将一组微分方程从Matlab R2014b移植到python 3.4。

我同时使用了odeint和ode,没有令人满意的结果。预期的结果是我从Matlab获得的结果,其中xi = xl和xj = xk,每组的相位偏移为180,如下图所示。 enter image description here

我在Matlab中运行的代码如下:

function Fv = cpg(t, ini_i);  

freq = 2;
%fixed parameters
alpha = 5;
beta = 50;
miu = 1;
b = 1;

%initial conditions 
xi     = ini_i(1);
yi     = ini_i(2);
xj     = ini_i(3);
yj     = ini_i(4);
xk     = ini_i(5);
yk     = ini_i(6);
xl     = ini_i(7);
yl     = ini_i(8);

ri = sqrt(xi^2 + yi^2);
rj = sqrt(xj^2 + yj^2);
rk = sqrt(xk^2 + yk^2);
rl = sqrt(xl^2 + yl^2);

%frequency for all oscillators
w_swing = 1;
w_stance = freq*w_swing;

%Coupling matrix, that determines a walking gate for
%a quadruped robot. 
k = [ 0, -1, -1,  1;
     -1,  0,  1, -1;
     -1,  1,  0, -1;
      1, -1, -1,  0];

%Hopf oscillator 1
omegai = w_stance/(exp(-b*yi)+1) + w_swing/(exp(b*yi)+1);
xi_dot = alpha*(miu - ri^2)*xi - omegai*yi;
yi_dot = beta*(miu - ri^2)*yi + omegai*xi + k(1,2)*yj + k(1,3)*yk + k(1,4)*yl;

%Hopf oscillator 2
omegaj = w_stance/(exp(-b*yj)+1) + w_swing/(exp(b*yj)+1);
xj_dot = alpha*(miu - rj^2)*xj - omegaj*yj;
yj_dot = beta*(miu - rj^2)*yj + omegaj*xj + k(2,1)*yi + k(2,3)*yk + k(2,4)*yl;

%Hopf oscillator 3
omegak = w_stance/(exp(-b*yk)+1) + w_swing/(exp(b*yj)+1);
xk_dot = alpha*(miu - rk^2)*xk - omegak*yk;
yk_dot = beta *(miu - rk^2)*yk + omegak*xk + k(3,4)*yl + k(3,2)*yj + k(3,1)*yi;

%Hopf oscillator 4
omegal = w_stance/(exp(-b*yl)+1) + w_swing/(exp(b*yl)+1);
xl_dot = alpha*(miu - rl^2)*xl - omegal*yl;
yl_dot = beta *(miu - rl^2)*yl + omegal*xl + k(4,3)*yk + k(4,2)*yj + k(4,1)*yi; 

%Outputs
Fv(1,1) = xi_dot;
Fv(2,1) = yi_dot;
Fv(3,1) = xj_dot;
Fv(4,1) = yj_dot;
Fv(5,1) = xk_dot;
Fv(6,1) = yk_dot;
Fv(7,1) = xl_dot;
Fv(8,1) = yl_dot;

然而,当我将代码移动到python时,我得到了这样的输出。 enter image description here 在python中,我使用与Matlab相同的时间步长运行ODE求解器,并使用求解器'dopri5',它应该等同于我在Matlab中使用的那个,ode45。我在两种情况下使用相同的初始条件。我已经使用了odeint和ode两种类似的结果。 我刚开始用Python编程,这是我第一次使用Scipy和Numpy实现,所以也许我误解了一些东西?

def cpg(t, ini, k, freq):
    alpha = 5
    beta = 50
    miu = 1
    b = 1
    assert freq == 2

    'Initial conditions'
    xi = ini[0] 
    yi = ini[1]
    xj = ini[2]
    yj = ini[3]
    xk = ini[4]
    yk = ini[5]
    xl = ini[6]
    yl = ini[7]

    ri = sqrt(xi**2 + yi**2)
    rj = sqrt(xj**2 + yj**2)
    rk = sqrt(xk**2 + yk**2)
    rl = sqrt(xl**2 + yl**2)

    'Frequencies for each oscillator'
    w_swing = 1
    w_stance = freq * w_swing

    'First Oscillator'
    omegai = w_stance/(exp(-b*yi)+1) + w_swing/(exp(b*yi)+1)
    xi_dot = alpha*(miu - ri**2)*xi - omegai*yi
    yi_dot =  beta*(miu - ri**2)*yi + omegai*xi + k[1]*yj + k[2]*yk + k[3]*yl

    'Second Oscillator'
    omegaj = w_stance/(exp(-b*yj)+1) + w_swing/(exp(b*yj)+1)
    xj_dot = alpha*(miu - rj**2)*xj - omegaj*yj
    yj_dot =  beta*(miu - rj**2)*yj + omegaj*xj + k[4]*yi + k[6]*yk + k[7]*yl

    'Third Oscillator'
    omegak = w_stance/(exp(-b*yk)+1) + w_swing/(exp(b*yk)+1)
    xk_dot = alpha*(miu - rk**2)*xk - omegak*yk
    yk_dot =  beta*(miu - rk**2)*yk + omegak*xk + k[8]*yi + k[9]*yj + k[11]*yl

    'Fourth Oscillator'
    omegal = w_stance/(exp(-b*yl)+1) + w_swing/(exp(b*yl)+1)
    xl_dot = alpha*(miu - rl**2)*xl - omegal*yl
    yl_dot =  beta*(miu - rl**2)*yl + omegal*xl + k[12]*yi + k[13]*yj + k[14]*yk

    return [xi_dot, yi_dot, xj_dot, yj_dot, xk_dot, yk_dot, xl_dot, yl_dot]

我打电话给ODE的方式如下:

X0 = [1,-1, 0,-1, 1,1, 0,1] 
r = ode(cpg).set_integrator('dopri5')
r.set_initial_value(X0).set_f_params(k_trot, 2)

t1 = 30.
dt = .012
while r.successful() and r.t < (t1-dt):
    r.integrate(r.t+dt)

我希望我足够清楚。 有什么建议吗?

0 个答案:

没有答案