Call a function with multiple nonlinear eqns with ODE45

I created a function with multiple nonlinear equations, and inside that function i call on another function that uses a time parameter. In the script, I use ode45 to simulate the equations, but I get the following error:
Error using odearguments (line 95)
@(T,X)FNONLINEAR(TSPAN) returns a vector of length 1, but the length of initial conditions vector is 4. The vector returned by @(T,X)FNONLINEAR(TSPAN) and the initial conditions vector must have the same number of elements.
Error in ode45 (line 115)
odearguments(FcnHandlesUsed, solver_name, ode, tspan, y0, options, varargin);
I use the following code:
close all; clear; clc
tspan = [0 150];
x0 = [1;0;0;0];
[t,y] = ode45(@(t,x) fnonlinear(tspan),tspan,x0)
plot(t,y)
function DX = fnonlinear(t)
[ap,bp,am,bm,r,gamma] = problem_parameters(t);
thetah1 = bm/bp;
thetah2 = (am-ap)/bp;
u = @(t,x) thetah1*r+thetah2*x;
dx1 = @(t,x1) ap*x1+bp*u(t,x);
dx2 = @(t,x2) am*x2+bm*r;
dx3 = @(x1,x2) -gamma*(x1-x2)*r;
dx4 = @(x1,x2) -gamma*(x1-x2)*x1;
DX = @(t,x) [dx1(t,x);dx2(t,x);dx3(t,x);dx4(x1,x2)];
end
function [ap,bp,am,bm,r,gamma] = problem_parameters(t)
% problem parameters
bp = 2; am = -1; bm = 1; r = 0.5; gamma = 2;
% simulate a fault at 100 s
if t >= 100
ap = 2;
else
ap = 1; % fault causes reduced value of ap
end
end
Please let me know if i need to clarify anything.

 Réponse acceptée

There were a number of errors that I corrected.
This runs and produces what appears to be appropriate output:
tspan = [0 150];
x0 = [1;0;0;0];
[t,y] = ode45(@(t,x) fnonlinear(t,x),tspan,x0);
figure
plot(t,y)
grid
xlim([0 8]) % Optional
function DX = fnonlinear(t,x)
[ap,bp,am,bm,r,gamma] = problem_parameters(t);
thetah1 = bm/bp;
thetah2 = (am-ap)/bp;
u = @(x) thetah1*r+thetah2*x;
dx1 = ap*x(1)+bp*u(x(1));
dx2 = am*x(2)+bm*r;
dx3 = -gamma*(x(1)-x(2))*r;
dx4 = -gamma*(x(1)-x(2))*x(1);
DX = [dx1;dx2;dx3;dx4];
end
function [ap,bp,am,bm,r,gamma] = problem_parameters(t)
% problem parameters
bp = 2; am = -1; bm = 1; r = 0.5; gamma = 2;
% simulate a fault at 100 s
if t >= 100
ap = 2;
else
ap = 1; % fault causes reduced value of ap
end
end
.

6 commentaires

Thank you for you help
As always, my pleasure!
for some reason u is not changing when ap changes at 100 s, any thoughts?
Originally, ‘dx1’ was writtten:
dx1 = @(t,x1) ap*x1+bp*u(t,x);
I changed ‘u’ to be only a function of ‘x(1)’ (and guessing at that) since what was originally intended was not obvious to me.
Since ‘u’ is not a function of ’ap’, it will not change with respect to ‘ap’. If ‘u’ is a function of ‘ap’, it needs to be written as such.
so perhaps:
dx1 = ap*x(1)+bp*u(ap);
will do what you want.
Please let me know if that does what you want, or provide further clarification so I understand what needs to be changed so the code does what you want it to do.
What about
dx1 = ap*x(1)+bp*u(ap,x(1)) ?
Star Strider
Star Strider le 27 Mar 2021
Modifié(e) : Star Strider le 27 Mar 2021
If that does what you want, code it accordingly, and add another argument to ‘u’, and create ‘u’ as a function of both arguments.
Note that ‘u’ as originally written is only a function of ‘x’ (since ‘r’ already exists in the workspace, ‘u’ inherits that value and an explicit argument for it is not necessary), so passing ‘u’ an additional argument without changing its internal coding will likely not change its result.

Connectez-vous pour commenter.

Plus de réponses (0)

Produits

Version

R2020b

Community Treasure Hunt

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

Start Hunting!

Translated by