Dynamic size differential equation system

조회 수: 19 (최근 30일)
Zsolt Fischer
Zsolt Fischer 2019년 4월 15일
답변: Steven Lord 2019년 4월 16일
I would like to create a system of N differential equations in a function and solve them with ode45. I tried to create them in a for loop:
function output = deqns(par)
alpha=par.alpha;
beta=par.beta;
n=par.n; % n = N/2 where N is the number of equations
ydot=zeros(2*n,1);
for k = 1:2*n
if k <= n
ydot(k) = alpha*(optV(par,y(k+n))-y(k))+beta*(y(mod(k+n,n)+1)-y(k));
else
ydot(k) = y(mod(k+n,n)+1)-y(k);
end
end
output = ydot;
end
The result should look like this, where the total number of equations is 2*n. (This is my original system)
When I try to solve this with ode45, i get a bunch of errors, because 'y' is not defined in the For loop. I tried to solve the problem but all I achived was some different errors.
[t, y] = ode45(@(t,y) deqns(par), [t0,tmax], init);
ERRORS:
Undefined function 'y' for input arguments of type 'double'.
Error in deqns (line 10)
ydot(k) = alpha*(optV(par,y(k+n))-y(k))+beta*(y(mod(k+n,n)+1)-y(k));
Error in asd>@(t,y)deqns(par)
Error in odearguments (line 90)
f0 = feval(ode,t0,y0,args{:}); % ODE15I sets args{1} to yp0.
Error in ode45 (line 115)
odearguments(FcnHandlesUsed, solver_name, ode, tspan, y0, options, varargin);
Error in asd (line 49)
[t, y] = ode45(@(t,y) deqns(par), [t0,tmax], init);
It is important that I need to avoid symbolic calculations (if possible). Any help is appreciated.

채택된 답변

Star Strider
Star Strider 2019년 4월 15일
I have absolutely no idea what you’re doing. Regardless, your ‘deqns’ function must have as two of its arguments your independent variable (here apprently ‘t’) and your dependent variable (here apparently ‘y’).
With those changes, you function runs without error, however you will probably want to change it so it runs much more efficiently.
Try this:
function output = deqns(t,y,par)
alpha=par.alpha;
beta=par.beta;
n=par.n; % n = N/2 where N is the number of equations
ydot=zeros(2*n,1);
for k = 1:2*n
if k <= n
ydot(k) = alpha*(optV(par,y(k+n))-y(k))+beta*(y(mod(k+n,n)+1)-y(k));
else
ydot(k) = y(mod(k+n,n)+1)-y(k);
end
end
output = ydot;
end
optV = @(b1,b2) 42; % Insert Correct Function
par.alpha = rand; % Assign Correct Value
par.beta = rand; % Assign Correct Value
par.n = 4; % Assign Correct Value
t0 = 0; % Assign Correct Value
tmax = 1; % Assign Correct Value
init = zeros(2*par.n,1); % Assign Correct Value
[t, y] = ode45(@(t,y) deqns(t,y,par), [t0,tmax], init);
figure
plot(t, y)
grid
Experiment to get the result you want.
  댓글 수: 2
Zsolt Fischer
Zsolt Fischer 2019년 4월 16일
Thank you, adding t and y as arguments solved the problem!
Star Strider
Star Strider 2019년 4월 16일
As always, my pleasure!

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Steven Lord
Steven Lord 2019년 4월 16일
There's no need for a loop here. Work on vectors.
function dvhdt = myodefun(t, vh, alpha, optV, beta)
% Compute N from the vh vector with which the ODE solver calls your function
N = numel(vh)/2;
% Unpack v and h into separate vectors
v = vh(1:N);
h = vh(N+1:end);
% Compute the updated dv/dt and dh/dt separately
% Use the computation for dh/dt to update dv/dt
dhdt = [diff(v); v(1)-v(N)];
dvdt = alpha*(optV - v)+beta*dhdt;
% Pack dv/dt and dh/dt together
dvhdt = [dvdt; dhdt];
end
You will need to pass alpha, optV, and beta into your ODE function as extra parameters.

카테고리

Help CenterFile Exchange에서 Programming에 대해 자세히 알아보기

제품


릴리스

R2018b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by