ode45 function
3 views (last 30 days)
Show older comments
I have a damped, Duffing-type oscillator that I am try to drive with a randomly-varying forcing function fff, where fff is a one-dimensional array of amplitudes. Also t and fff have the same number of elements.
I defined a function as follows:
- * * * *
function s = duffing_arb(t,w,flag,a,b,c,d,fff) % s = zeros(2,1); s(1) = w(2); s(2) = a*w(2) + b*w(1) + c*(w(1))^3 -d*fff;
- * * * *
But I get the following error messages. Please help. Thank you.
??? In an assignment A(I) = B, the number of elements in B and I must be the same.
Error in ==> duffing_arb at 8 s(2) = a*w(2) + b*w(1) + c*(w(1))^3 -d*fff;
Error in ==> odearguments at 109 f0 = feval(ode,t0,y0,args{:}); % ODE15I sets args{1} to yp0.
Error in ==> ode45 at 173 [neq, tspan, ntspan, next, t0, tfinal, tdir, y0, f0, odeArgs, odeFcn, ...
Error in ==> beam_duffing3 at 92 [t,w] = ode45(@duffing_arb,t,w,[],[],a,b,c,d,fff);
0 Comments
Answers (2)
Matt Tearle
on 15 Mar 2011
I think the problem is with fff. When you say fff has the same number of elements as t, how many is that? The number of elements of t depends on the integration; ode45 is a variable timestep integrator, so how are you specifying what fff should be at each timestep (if that's indeed what you're trying to do)?
Anyway, the problem is that everything in the line
s(2) = a*w(2) + b*w(1) + c*(w(1))^3 -d*fff;
is a scalar, except fff, which is causing the problem.
EDIT to add
If fff is purely random at each time, you could just generate
fff = rand;
inside duffing_arb at each timestep. If, however, you need to have some pre-set array of t and fff values, you can do something like this to interpolate the current collocation point to the pre-made data:
function s = duffing_arb(t,w,flag,a,b,c,d,tvals,fff)
s = zeros(2,1);
f = interp1(tvals,fff,t,'cubic');
s(1) = w(2);
s(2) = a*w(2) + b*w(1) + c*(w(1))^3 -d*f;
Then, in your main script, set values for a through d, and the vectors t and fff, then:
duffman = @(x,y) duffing_arb(x,y,[],a,b,c,d,t,fff);
[tint,wint] = ode45(duffman,t,w);
Note that duffman is an anonymous function handle with all the parameters embedded, so you don't have to pass those separately when calling ode45. Also, because t is a whole vector of points, tint will be the same as t, even though ode45 will use a variable stepsize behind the scenes.
1 Comment
Jan
on 30 Jun 2011
@Matt Tearle: Using RAND as parameter in an ODE function will kill the integration scheme. The stepsize control of ODE45 is based on the smoothness of the function. In addition the single-step method ODE45 evaluates the function several times per step to approximate the intergral. If the function has random (maximum non-smooth) results, it is not an "ODE" and ODE45 is not a useful solver.
Ganesh
on 30 Jun 2011
I too have a similar problem with a sdof system.When i try the above solution by Matt,i get the following error: ??? Error using ==> od Too many input arguments. Error in ==> @(w,y)od(w,y,[],m,c,k,t,g)
where m,c,k,g are the parameters like a,b,c etc in Tom's code. Here's my function file: function xdot = od(t,x,g,m,c,k,tvals)
h=interp1(tvals,g,t,'cubic');
xdot=zeros(2,1);
xdot(1)=x(2); xdot(2)=-k/m*x(1)-(c/m)*x(2)+h/m;
Here g is a vector.
Can you please suggest a solution for this problem.
Thank you
1 Comment
Jan
on 30 Jun 2011
Please open a new thread for a new problem.
@(w,y)od(w,y,[],m,c,k,t,g) => 8 arguments
unction xdot = od(t,x,g,m,c,k,tvals) => 7 arguments
In addition the order of arguments seems to be confused.
See Also
Categories
Find more on Ordinary Differential Equations in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!