ODE45 error: must return a column vector.

I am getting this error in my code. but in the MATLAB documentation there is an example ( Example 3) where the vectors are given as input but it works just fine. Why is that I get an error in my code?
Ca_ER = 10e-6;
c0 = 2e-6;
c1 = .185;
v1 = 6;
v2 = .11;
v3 = .09e6;
v4 = 1.2;
k3 = .1e-6;
a1 = 400e6;
a2 = 0.2e6;
a3 = 400e6;
a4 = 0.2e6;
a5 = 20e6;
b2 = .21;
d1 = 0.13e-6;
d2 = b2/a2;
d3 = 943.4e-9;
d4 = d1*d2/d3;
d5 = 82.34e-9;
IP= .5e-6;
Ca=.001e-6:.01e-6:1e-6;
num=Ca.*IP.*d2;
deno= (Ca.*IP+ IP*d2+d1*d2+Ca.*d3).*(Ca+d5);
p_open=( num./deno).^3; %this is the vector input
dc=@(t,c) (c1.*((v1.*p_open)+v2).*(Ca_ER-c))-((v3.*(c.^2))/(c.^2+(k3^2)));
[t,c]=ode45(dc,linspace(0, 100, 1000),.19e-6);
plot(t,c);

 Accepted Answer

For a start, try changing to column vectors. E.g.,
Ca = (.001e-6:.01e-6:1e-6)';

6 Comments

I did as you suggested but now i get the following error:
Error using odearguments (line 93)
@(T,C)(C1.*((V1.*P_OPEN)+V2).*(CA_ER-C))-((V3.*(C.^2))/(C.^2+(K3^2)))
returns a vector of length 100, but the length of initial conditions vector is 1. The vector returned by @(T,C)(C1.*((V1.*P_OPEN)+V2).*(CA_ER-C))-((V3.*(C.^2))/(C.^2+(K3^2))) and the initial conditions vector must have the same number of elements.
It is complaining that in this line, you only have a scalar for initial conditions, but your derivative function returns a vector.
[t,c]=ode45(dc,linspace(0, 100, 1000),.19e-6);
So you need to supply a vector initial condition in this line to get rid of the error.
Which begs the question, does your problem really involve a vector state (indicating that the initial condition is in error and needs to be a vector), or does your problem really involve only a scalar state (indicating that your derivative function is in error and needs to return a scalar)?
what I don't understand is that in the example provided in the link above they have used vector state with a scalar initial condition. So why is that their code does not get an error. This is what baffles me. Or am I missing something?
The myode function of Example 3 returns a scalar value for dydt. The vector stuff you see is just the inputs for the interpolation used to get the scalars. I.e., ode45 gets passed an anonymous function handle (that happens to use the vector stuff off to the side via myode) that takes a scalar input y and returns a scalar output ... it does not get passed the vector stuff directly.
Specifically, this is what is happening:
[T Y] = ode45(@(t,y) myode(t,y,ft,f,gt,g),Tspan,IC);
The @(t,y) creates an anonymous function handle with two inputs, t and y. In this case t and y are both scalars, and that is the only interface that ode45 knows about directly. That anonymous function calls another function, myode, with FIXED INPUTS ft, f, gt, and g which are all vectors. In essence, snapshots of ft, f, gt, and g are taken at the time this line is executed and embedded within the anonymous function handle itself (technically, shared data copies of ft, f, gt, and g are created and stored within the function handle). So each time this anonymous function gets called from within ode45, it ends up calling myode with t and y (passed directly in from ode45) but also uses these ft, f, gt, and g vectors at whatever state they happened to be in at the time of the anonymous function handle creation.
nashyshan
nashyshan on 6 Jun 2015
Edited: nashyshan on 6 Jun 2015
Okay! I will check and get back. Thank you so much for the valuable inputs.
We don't know what problem you are trying to solve. Are you trying to solve a scalar 1st order differential equation? A scalar higher order differential equation? A vector DE? Or what? Tell us what the DE or system of DE's is.

Sign in to comment.

More Answers (0)

Categories

Find more on Programming in Help Center and File Exchange

Tags

Community Treasure Hunt

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

Start Hunting!