Reputation: 23
I am trying to evaluate a duffing oscillator in MATLAB with multiple inputs, and I am getting an odd error I was hoping someone might be able to help me with.
Here is the code:
% file duffing.m
function dy=duffing(t,y,a,b,d,g,w)
dy=[y(2); -a*y(1)^3-b*y(1)-d*y(2)+g*cos(w*t)];
end
And the file that calls the duffing function:
t=0:0.01:100;
%duffing oscillator
y0=[2,0];
a=1;
b=-1;
d=0.2;
w=1;
g=0.1;
% duffing oscillator
[t,y]=ode45('duffing',t,y0,a,b,d,g,w);
When I run it, I get the following error:
Error using odearguments (line 92) DUFFING returns a vector of length 1, but the length of initial conditions vector is 2. The vector returned by DUFFING and the initial conditions vector must have the same number of elements.
But when I define the function duffing as
function dy=duffing(t,y)
a=1;
b=-1;
d=0.2;
w=1;
dy=[y(2); -a*y(1)^3-b*y(1)-d*y(2)+g*cos(w*t)];
end
and pass in
[t y]=ode45('duffing',t,y0);
with the same y0
as above, it runs fine and I can plot it.
What am I doing wrong?
Upvotes: 2
Views: 895
Reputation: 30579
The syntax for ode45
is:
function varargout = ode45(ode,tspan,y0,options,varargin)
The fourth argument, options
, is an options struct created with odeset
. The additional inputs need to be the fifth and later, and the function needs to be modified. The official way is to use a function handle or global variables, but here's how to do it with arguments to ode45
.
options = odeset('RelTol',1e-4);
[t,y]=ode45('duffing',t,y0,options,a,b,d,g,w);
Then you have to modify duffing
with a dummy argument to be compatible with the calling convention of odearguments.m (f(t,y,'',p1,p2...)
):
function dy=duffing(t,y,~,a,b,d,g,w)
dy=[y(2); -a*y(1)^3-b*y(1)-d*y(2)+g*cos(w*t)];
end
The official function handle solution looks something like this:
myDuffing = @(t,y) duffing(t,y,a,b,d,g,w);
Then call ode45
the same way as your second approach, but with myDuffing
(see David's solution for this method).
Upvotes: 1
Reputation: 8459
ode45
takes as input a function of two variables only. If you want to pass more inputs, you have to create a little anonymous function, like this:
a=1;
b=-1;
d=0.2;
w=1;
g=0.1;
% duffing oscillator
[t,y]=ode45(@(t,y) duffing(t,y,a,b,d,g,w),t,y0);
Upvotes: 1