Niklas Rosencrantz
Niklas Rosencrantz

Reputation: 26647

How can I iterate using ode45?

I'm trying to write some matlab code. Why won't my new variable w get accepted so that my function can take another parameter? I want to iterate over the variable that is now 7.8 and use iteration instead.

 function dZ=sys(x,Z,w)
    c=@(z)4800 - 20.2090 + (17.3368)*z/1000+ (272.9057)*exp(-z*0.7528/1000); % c(z)
    c=c(2000);
    deg=w;

% Z(1):=z
% Z(2):=u
    dZ=zeros(2,1);    % a column vector
    dZ(1)=Z(2);
    dZ(2)=-(c/cosd(7.8))^2*(((-272.9057*0.7528/1000)*exp(-Z(1)*0.7528/1000)) + 17.3368/1000)/...
        (4800 - 20.2090 + (17.3368)*Z(1)/1000+ (272.9057)*exp(-Z(1)*0.7528/1000))^3;
    end

I get an error message when trying to use the new variable in my function that worked before.

Error using sys (line 4)
Not enough input arguments.

Error in odearguments (line 88)
f0 = feval(ode,t0,y0,args{:});   % ODE15I sets args{1} to yp0.

Error in ode45 (line 114)
[neq, tspan, ntspan, next, t0, tfinal, tdir, y0, f0, odeArgs, odeFcn, ...

Error in underwater (line 2)
[X,Z]=ode45(@sys,x,[2000 tand(7.8)], 7.8);

Upvotes: 0

Views: 445

Answers (2)

TallBrianL
TallBrianL

Reputation: 1252

The ODE solver is expecting a function of two variables. It is looking for a function in the form of:

y' = f(t, y)

So, if you are passing @sys to ode45, it must be a function of only two variables.

In the comments below you reference another question. They use the following call:

[t,N] = ode45(@(t,y) rateEquations(t,y,F), timeSpan, initialConditions)

Using @(t,y) makes a generic function which is a function of two variables. In this example the function rateEquations is called with a fixed F value. So ODE is in fact expecting a function of two variables. If you have a function of more than two variables you can recast it as a function of two variables by copying the technique used in the example you reference. Hope this helps!

Upvotes: 0

am304
am304

Reputation: 13876

I would write the function as follows (although w doesn't appear to be used):

function dZ=sys(t,Z,w)
    z = 2000;
    c = 4800 - 20.2090 + (17.3368)*z/1000+ (272.9057)*exp(-z*0.7528/1000);
    deg=w; % not used?

    dZ=zeros(2,1);    % a column vector
    dZ(1)=Z(2);
    dZ(2)=-(c/cosd(7.8))^2*(((-272.9057*0.7528/1000)*exp(-Z(1)*0.7528/1000)) + 17.3368/1000)/...
        (4800 - 20.2090 + (17.3368)*Z(1)/1000+ (272.9057)*exp(-Z(1)*0.7528/1000))^3;
end

and then call the ode solver as follows:

[T,Z_sol] = ode45(@(t,Z) sys(t,Z,w),x,[2000 tand(7.8)]);

where w and x are defined in your base or caller workspace.

Upvotes: 3

Related Questions