Runge-Kutta Numerical Method Bad Approximation - matlab

I´m attempting to use the Runge-Kutta method to compare it to the lsode function. But it is performing rather poorly, every other method I used (forwards and backwards Euler, Heun) to compare to lsode do a way better job to the point they are almost indistinguishable from lsode.
This is what my code returns
https://i.stack.imgur.com/vJ6Yi.png
If anyone can point out a way to improve it or if I'm doing something wrong I´d appreciate it.
The following is what I use for the Runge-Kutta method
%Initial conditions
u(1) = 1;
v(1) = 2;
p(1) = -1/sqrt(3);
q(1) = 1/sqrt(3);
%Graf interval / step size
s0 = 0;
sf = 50;
h = 0.25;
n=(sf-s0)/h;
s(1) = s0;
%-----------------------------------------------------------------------%
for j = 2:n
i = j-1;
k1_u(j) = p(i);
k1_v(j) = q(i);
k1_p(j) = (-2*v(i)*p(i)*q(i)) / (u(i)*u(i) + v(i)*v(i) + 1);
k1_q(j) = (-2*u(i)*p(i)*q(i)) / (u(i)*u(i) + v(i)*v(i) + 1);
u1(j) = p(i) + (1/2)*k1_u(j)*h;
v1(j) = q(i) + (1/2)*k1_v(j)*h;
p1(j) = (-2*v(i)*p(i)*q(i)) / (u(i)*u(i) + v(i)*v(i) + 1) + (1/2)*k1_p(j)*h;
q1(j) = (-2*u(i)*p(i)*q(i)) / (u(i)*u(i) + v(i)*v(i) + 1) + (1/2)*k1_q(j)*h;
k2_u(j) = p1(j);
k2_v(j) = q1(j);
k2_p(j) = (-2*v1(j)*p1(j)*q1(j)) / (u1(j)*u1(j) + v1(j)*v1(j) + 1);
k2_q(j) = (-2*u1(j)*p1(j)*q1(j)) / (u1(j)*u1(j) + v1(j)*v1(j) + 1);
u2(j) = p(i) + (1/2)*k2_u(j)*h;
v2(j) = q(i) + (1/2)*k2_v(j)*h;
p2(j) = (-2*v(i)*p(i)*q(i)) / (u(i)*u(i) + v(i)*v(i) + 1) + (1/2)*k2_p(j)*h;
q2(j) = (-2*u(i)*p(i)*q(i)) / (u(i)*u(i) + v(i)*v(i) + 1) + (1/2)*k2_q(j)*h;
k3_u(j) = p2(j);
k3_v(j) = q2(j);
k3_p(j) = (-2*v2(j)*p2(j)*q2(j)) / (u2(j)*u2(j) + v2(j)*v2(j) + 1);
k3_q(j) = (-2*u2(j)*p2(j)*q2(j)) / (u2(j)*u2(j) + v2(j)*v2(j) + 1);
u3(j) = p(i) + k3_u(j)*h;
v3(j) = q(i) + k3_v(j)*h;
p3(j) = (-2*v(i)*p(i)*q(i)) / (u(i)*u(i) + v(i)*v(i) + 1) + k3_p(j)*h;
q3(j) = (-2*u(i)*p(i)*q(i)) / (u(i)*u(i) + v(i)*v(i) + 1) + k3_q(j)*h;
k4_u(j) = p3(j);
k4_v(j) = q3(j);
k4_p(j) = (-2*v3(j)*p3(j)*q3(j)) / (u3(j)*u3(j) + v3(j)*v3(j) + 1);
k4_q(j) = (-2*u3(j)*p3(j)*q3(j)) / (u3(j)*u3(j) + v3(j)*v3(j) + 1);
s(j) = s(j-1) + h;
u(j) = u(j-1) + (h/6)*(k1_u(j) + 2*k2_u(j) + 2*k3_u(j) + k4_u(j));
v(j) = v(j-1) + (h/6)*(k1_v(j) + 2*k2_v(j) + 2*k3_v(j) + k4_v(j));
p(j) = p(j-1) + (h/6)*(k1_p(j) + 2*k2_p(j) + 2*k3_p(j) + k4_p(j));
q(j) = q(j-1) + (h/6)*(k1_q(j) + 2*k2_q(j) + 2*k3_q(j) + k4_q(j));
endfor
subplot(2,3,1), plot(s,u);
hold on; plot(s,v); hold off;
title ("Runge-Kutta");
h = legend ("u(s)", "v(s)");
legend (h, "location", "northwestoutside");
set (h, "fontsize", 10);

You misunderstood something in the method. The intermediate values for p,q are computed the same way as the intermediate values for u,v, and both are "Euler steps" with the last computed slopes, not separate slope computations. For the first ones that is
u1(j) = u(i) + (1/2)*k1_u(j)*h;
v1(j) = v(i) + (1/2)*k1_v(j)*h;
p1(j) = p(i) + (1/2)*k1_p(j)*h;
q1(j) = q(i) + (1/2)*k1_q(j)*h;
The computation for the k2 values then is correct, the next midpoints need to be computed correctly via "Euler steps", etc.

Related

Matlab Numeric Solvers outputting: Warning: Unable to find explicit solution

I have 9 equations and 9 unknowns that I need to solve for, but when I set up the code and run it I get the following:
"Warning: Unable to find explicit solution. For options, see help.
In sym/solve (line 317)
In HW2_PartA (line 65)
ans =
Empty sym: 0-by-1"
I have tried using both the solve functions and the vpasolve functions and I receive the same message each time.
The code is:
clear all
clc
syms T0 nO2 nH2 nH nOH nH2O nO lO lH
t = T0/1000;
R = 8.314;
nF = 1;
nOX = 11/32;
P0 = 5.3e6; % Pa
Pstp = 101.3e3;%Pa
hfH2 = 0; %j/mol
hfO2 = 0; %j/mol
hfH2O = -241.82e3;% j/mol
hfO = 249.19e3; %j/mol
hfH = 218e3;%J/mol
hfOH = 39.46e3;%j/mol
oxygengas = [20.9111 10.721071 -2.020498 0.046449 9.245722 5.337651 237.6185 0.00];
hydrogengas = [43.4136 -4.2931 1.2724 -0.0969 -20.5339 -38.5152 162.0814 0.00];
hydrogen = [20.7860 0.0000 -0.0000 0.0000 0.0000 211.8020 139.8711 217.9990];
OHgas = [28.7470 4.7145 -0.8147 0.0547 -2.7478 26.4144 214.1166 38.9871];
water = [41.9643 8.6221 -1.4998 0.0981 -11.1576 -272.1797 219.7809 -241.8264];
%Enthalpy
hO2 = 1000*(oxygengas*t + oxygengas(2)*(t^2)/2 + oxygengas(3)*(t^3)/3 + oxygengas(4)*(t^4)/4 -
oxygengas(5)/t + oxygengas(6) - oxygengas(8));
hH2 = 1000*(hydrogengas(1)*t + hydrogengas(2)*(t^2)/2 + hydrogengas(3)*(t^3)/3 + hydrogengas(4)*
(t^4)/4 - hydrogengas(5)/t + hydrogengas(6) - hydrogengas(8));
hH = 1000*(hydrogen(1)*t + hydrogen(2)*(t^2)/2 + hydrogen(3)*(t^3)/3 + hydrogen(4)*(t^4)/4 -
hydrogen(5)/t + hydrogen(6) - hydrogen(8));
hOH = 1000*(OHgas(1)*t + OHgas(2)*(t^2)/2 + OHgas(3)*(t^3)/3 + OHgas(4)*(t^4)/4 - OHgas(5)/t +
OHgas(6) - OHgas(8));
hO = hH;
hH2O = 1000*(water(1)*t + water(2)*(t^2)/2 + water(3)*(t^3)/3 + water(4)*(t^4)/4 - water(5)/t +
water(6) - water(8));
%Entropy
sO2 = oxygengas(1)*log(t) + oxygengas(2)*t + oxygengas(3)*(t^2)/2 +oxygengas(4)*(t^3)/3 -
oxygengas(5)/(2*t^2) +oxygengas(7);
sH2 = hydrogengas(1)*log(t) + hydrogengas(2)*t + hydrogengas(3)*(t^2)/2 +hydrogengas(4)*(t^3)/3 -
hydrogengas(5)/(2*t^2) +hydrogengas(7);
sH = hydrogen(1)*log(t) + hydrogen(2)*t + hydrogen(3)*(t^2)/2 +hydrogen(4)*(t^3)/3 -
hydrogen(5)/(2*t^2) +hydrogen(7);
sOH = OHgas(1)*log(t) + OHgas(2)*t + OHgas(3)*(t^2)/2 +OHgas(4)*(t^3)/3 - OHgas(5)/(2*t^2) +OHgas(7);
sO = (5/2)*R*log(T0/298.15) + 161.003;
sH2O = water(1)*log(t) + water(2)*t + water(3)*(t^2)/2 +water(4)*(t^3)/3 - water(5)/(2*t^2)
+water(7);
%Mass continuity
eqn1 = 2*nO2 + nOH + nO +nH2O - 2*nOX == 0;
eqn2 = 2*nH2 + 2*nH2O + nOH + nH - 2*nF == 0;
%Minimizing Gibbs Free Energy
%Oxygen Gas
eqn3 = hO2 + hfO2 - T0*sO2 + R*T0*log(P0/Pstp) + R*T0*log(nO2/(nO2+nH2+nH+nOH+nO+nH2O)) + 2*lO ==0 ;
%Hydrogen Gas
eqn4 = hH2 + hfH2 - T0*sH2 + R*T0*log(P0/Pstp) + R*T0*log(nH2/(nO2+nH2+nH+nOH+nO+nH2O)) + 2*lH == 0;
%Hydrogen
eqn5 = hH + hfH - T0*sH + R*T0*log(P0/Pstp) + R*T0*log(nH/(nO2+nH2+nH+nOH+nO+nH2O)) + lH == 0;
%OH Gas
eqn6 = hOH + hfOH - T0*sOH + R*T0*log(P0/Pstp) + R*T0*log(nOH/(nO2+nH2+nH+nOH+nO+nH2O)) + lO + lH ==
0;
%Oxygen
eqn7 = hO + hfO - T0*sO + R*T0*log(P0/Pstp) + R*T0*log(nO/(nO2+nH2+nH+nOH+nO+nH2O)) + lO == 0;
%Water
eqn8 = hH2O + hfH2O - T0*sO2 + R*T0*log(P0/Pstp) + R*T0*log(nH2O/(nO2+nH2+nH+nOH+nO+nH2O)) + 2*lH +
lO == 0;
% Enthalpy Balance
eqn9 = nO2*hO2 + nH2*hH2 + nH*hH + nOH*hOH + nO*hO + nH2O*hH2O - nOX*hfO2 - nF*hfH2 + nO2*hfO2 +
nH2*hfH2 + nH*hfH + nOH*hfOH + nO*hfOH + nH2O*hfH2O == 0;
eqns = [eqn1,eqn2,eqn3,eqn4,eqn5, eqn6, eqn7, eqn8, eqn9];
sol = solve([eqn1,eqn2,eqn3,eqn4,eqn5,eqn6,eqn7,eqn8,eqn9], [T0 nO2 nH2 nH nOH nH2O nO lO lH]);
sol.T0

How can I vectorize this Nested for loop

I'm trying to vectorize the inner loop but I'm not being able to.
for i = 1:NTS
U(1) = 0;
V(1) = 0;
U(end)=1;
V(end)=1;
for j = 2:NAS-1
U(j) = (b(j) * U(j-1) + a(j) * UOld(j) + c(j) * UOld(j+1)) / gamma(j);
V(NAS-j+1) = (b(NAS-j+1) * VOld(NAS-j+1-1) + a(NAS-j+1) * VOld(NAS-j+1) + c(NAS-j+1) * V(NAS-j+1+1)) / gamma(NAS-j+1);
end
end
I've tried the following code but I get a wrong result, can someone please help me out if that?
U(2:NAS-1) = ((b(2:NAS-1) .* U(1:NAS-2) + a(2:NAS-1) .* UOld(2:NAS-1) + c(2:NAS-1) .* UOld(3:NAS)) ./ gamma(2:NAS-1));
V(NAS-1:-1:2) = ((b(NAS-1:-1:2) .* VOld(NAS-2:-1:1) + a(NAS-1:-1:2) .* VOld(NAS-1:-1:2) + c(NAS-1:-1:2) .* V(NAS:-1:3)) ./ gamma(NAS-1:-1:2));
this is the whole code as requested for the minimal verifiable thing. Thanks
clc
clear
NTS=1;
NAS=10;
U=rand(1,10)*100;
V=U;
UU=zeros(1,10);
VV=zeros(1,10);
Gamma=ones(1,100)*(1-10.05);
a=ones(1,10)*(1-0.05);
b=ones(1,10)*(1-0.15);
c=ones(1,10)*(1-0.35);
UOld=U;
VOld=V;
UU=U;
VV=V;
for i=1:NTS
UU(2:NAS-1) = ((b(2:NAS-1) .* UU(1:NAS-2) + a(2:NAS-1) .* UOld(2:NAS-1) + c(2:NAS-1) .* UOld(3:NAS)) ./ gamma(2:NAS-1));
VY(NAS-1:-1:2) = ((b(NAS-1:-1:2) .* VOld(NAS-2:-1:1) + a(NAS-1:-1:2) .* VOld(NAS-1:-1:2) + c(NAS-1:-1:2) .* VV(NAS:-1:3)) ./ gamma(NAS-1:-1:2));
for j = 2:NAS-1
U(j) = (b(j) * U(j-1) + a(j) * UOld(j) + c(j) * UOld(j+1)) / gamma(j);
V(NAS-j+1) = (b(NAS-j+1) * VOld(NAS-j+1-1) + a(NAS-j+1) * VOld(NAS-j+1) + c(NAS-j+1) * V(NAS-j+1+1)) / gamma(NAS-j+1);
end
display(sum(U(2:NAS-1)'-UU(2:NAS-1)'));
display(sum(V(2:NAS-1)'-VV(2:NAS-1)'));
end
display([U' UU']);
display([V' VV']);

Series of loops

Been having trouble simplifying this with into a series of loops? Not sure if to do nested / for or while loops. The variable Pnt could potentially be extended to an arbitrarily long number, but variables D and N are always from 1 to 6.
Pnt(7,:) = Pnt(1,:) +(-2*D(2)*N(2,:));
Pnt(8,:) = Pnt(1,:) + (-2*D(3)*N(3,:));
Pnt(9,:) = Pnt(1,:) + (-2*D(4)*N(4,:));
Pnt(10,:) = Pnt(1,:) + (-2*D(5)*N(5,:));
Pnt(11,:) = Pnt(1,:) + (-2*D(6)*N(6,:));
Pnt(12,:) = Pnt(2,:) + (-2*D(3)*N(3,:));
Pnt(13,:) = Pnt(2,:) + (-2*D(4)*N(4,:));
Pnt(14,:) = Pnt(2,:) + (-2*D(5)*N(5,:));
Pnt(15,:) = Pnt(2,:) + (-2*D(6)*N(6,:));
Pnt(16,:) = Pnt(2,:) + (-2*D(1)*N(1,:));
Pnt(17,:) = Pnt(3,:) + (-2*D(4)*N(4,:));
Pnt(18,:) = Pnt(3,:) + (-2*D(5)*N(5,:));
Pnt(19,:) = Pnt(3,:) + (-2*D(6)*N(6,:));
Pnt(20,:) = Pnt(3,:) + (-2*D(1)*N(1,:));
Pnt(21,:) = Pnt(3,:) + (-2*D(2)*N(2,:));
Pnt(22,:) = Pnt(4,:) + (-2*D(5)*N(5,:));
Pnt(23,:) = Pnt(4,:) + (-2*D(6)*N(6,:));
Pnt(24,:) = Pnt(4,:) + (-2*D(1)*N(1,:));
Pnt(25,:) = Pnt(4,:) + (-2*D(2)*N(2,:));
Pnt(26,:) = Pnt(4,:) + (-2*D(3)*N(3,:));
Pnt(27,:) = Pnt(5,:) + (-2*D(6)*N(6,:));
Pnt(28,:) = Pnt(5,:) + (-2*D(1)*N(1,:));
Pnt(29,:) = Pnt(5,:) + (-2*D(2)*N(2,:));
Pnt(30,:) = Pnt(5,:) + (-2*D(3)*N(3,:));
Pnt(31,:) = Pnt(5,:) + (-2*D(4)*N(4,:));
Pnt(32,:) = Pnt(6,:) + (-2*D(1)*N(1,:));
Pnt(33,:) = Pnt(6,:) + (-2*D(2)*N(2,:));
Pnt(34,:) = Pnt(6,:) + (-2*D(3)*N(3,:));
Pnt(35,:) = Pnt(6,:) + (-2*D(4)*N(4,:));
Pnt(36,:) = Pnt(6,:) + (-2*D(5)*N(5,:));
Here's a possible solution using 2 loops:
% Don't forget to pre-allocate memory for Pnt
p=7; q=1; r=1; %Initializing the variables to be used in the loop
while p<=36 % Since last row of Pnt to be calculated is 36th
for s=1:5 % Since each row of Pnt is used 5 times
r = mod(r,6); %Since maximum value for rows of D and N is 6
Pnt(p,:) = Pnt(q,:) + (-2*D(r+1)*N(r+1,:)); %Expression
p=p+1; r=r+1;
end
q=q+1; r=q;
end
bsxfun provides a handy way of performing element-wise operation on two arrays with implicit size-extension. The following is a way of implementing what you want in a more compact fashion using this funciton.
% compute the product of D and N beforehand for efficiency
DN = -2 * bsxfun(#times, N, (D(:)));
% compute new points in for-loop. 5 new points are generated
% in each iteration. Run longer for more points.
for ii=1:6
Pnt(1+ii*5+(1:5), :) = bsxfun(#plus, DN(mod(ii+(0:4), 6)+1, :), Pnt(mod(ii-1, 6)+1, :));
end

MATLAB: convert from euler (complex fourier) to sinus function (bn coefficients)

I have the following script
clc; clear all; close all;
syms x n
f = x;
L = 1;
subplot(2,1,1)
h = ezplot(f,[-L,L])
set(h, 'Color','r','LineWidth',1)
a0 = (1/L) * int(f * cos(0* pi*x/L),-L,L)
an = (1/L) * int(f * cos(n* pi*x/L),-L,L)
bn = (1/L)* int(f* sin(n* pi*x/L),-L,L)
fx = a0/2 + symsum((an* cos(n*pi*x/L) + bn* sin(n*pi*x/L)),n,1,5)
% for n =5, the answer: fx = (2*sin(pi*x))/pi - sin(2*pi*x)/pi +
%(2*sin(3*pi*x))/(3*pi) - sin(4*pi*x)/(2*pi) + (2*sin(5*pi*x))/(5*pi)
hold on
h = ezplot(fx,[-L,L])
grid on
%Solution with complex Fourier
c0 = (1/(2*L))*int(f*exp(-j*0*pi*x/L),-L,L)
cn = (1/(2*L))*int(f*exp(-j*n*pi*x/L),-L,L)
subplot(2,1,2)
h = ezplot(f,[-L,L])
set(h, 'Color','r','LineWidth',1)
fx_c = c0 + symsum(cn*exp(j*n*pi*x/L),n,-5,-1) + ...
symsum(cn*exp(j*n*pi*x/L),n,1,5) % n for complex -5,5
hold on
h = ezplot(fx_c,[-L,L])
grid on
My question: Since the answer of fx should be equal to fx_c (complex fourier). We can see from the figures produced by these 2 functions. They are same. But
fx =
(2*sin(pi*x))/pi - sin(2*pi*x)/pi + (2*sin(3*pi*x))/(3*pi) - sin(4*pi*x)/(2*pi) + (2*sin(5*pi*x))/(5*pi)
and
fx_c =
exp(-pi*x*i)*((pi*i - 1)/(2*pi^2) + (pi*i + 1)/(2*pi^2)) - exp(pi*x*i)*((pi*i - 1)/(2*pi^2) + (pi*i + 1)/(2*pi^2)) - exp(-pi*x*2*i)*((pi*2*i - 1)/(8*pi^2) + (pi*2*i + 1)/(8*pi^2)) + exp(pi*x*2*i)*((pi*2*i - 1)/(8*pi^2) + (pi*2*i + 1)/(8*pi^2)) + exp(-pi*x*3*i)*((pi*3*i - 1)/(18*pi^2) + (pi*3*i + 1)/(18*pi^2)) - exp(pi*x*3*i)*((pi*3*i - 1)/(18*pi^2) + (pi*3*i + 1)/(18*pi^2)) - exp(-pi*x*4*i)*((pi*4*i - 1)/(32*pi^2) + (pi*4*i + 1)/(32*pi^2)) + exp(pi*x*4*i)*((pi*4*i - 1)/(32*pi^2) + (pi*4*i + 1)/(32*pi^2)) + exp(-pi*x*5*i)*((pi*5*i - 1)/(50*pi^2) + (pi*5*i + 1)/(50*pi^2)) - exp(pi*x*5*i)*((pi*5*i - 1)/(50*pi^2) + (pi*5*i + 1)/(50*pi^2))
How to convert fx_c to be fx?
They are related by Euler's formula. You can check it with rewrite command:
>> rewrite(exp(1i*x), 'cos')
ans =
cos(x) + sin(x)*1i
Applying it to your function and simplifying a bit, you can get to the same expression:
>> expand(rewrite(fx_c, 'cos'), 'ArithmeticOnly', true)
ans =
(2*sin(pi*x))/pi - sin(2*pi*x)/pi + (2*sin(3*pi*x))/(3*pi) - sin(4*pi*x)/(2*pi) + (2*sin(5*pi*x))/(5*pi)
>> fx
fx =
(2*sin(pi*x))/pi - sin(2*pi*x)/pi + (2*sin(3*pi*x))/(3*pi) - sin(4*pi*x)/(2*pi) + (2*sin(5*pi*x))/(5*pi)

Porting Differential Equations from Matlab to Python 3.4 gives different results

I've been trying to port a set of differential equations from Matlab R2014b to python 3.4.
I've used both odeint and ode, with no satisfactory results. The expected results are the ones I get from Matlab where xi = xl and xj = xk with an offset of 180 in phase for each group, as you can see from the image below.
The code I'm running in Matlab is the following:
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;
However, when I moved the code to python I get an output like this.
In python I ran the ODE solver using the same time step as in Matlab and using solver 'dopri5', which is supposed to be equivalent to the one I'm using in Matlab, ode45. I use the same initial conditions in both cases. I've used both odeint and ode with similar results.
I just started programming in Python and it is my first implementation using Scipy and Numpy so maybe I'm misinterpreting something?
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]
The way that I'm calling the ODE is as follows:
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)
I hope I was clear enough.
Any suggestions?