Ode solver varying parameters

29 views (last 30 days)
Hello,
I have a three differnetial equations with 8 parameters in total of which 1 parameter p7 actually changes with time (p7=a*b^y*c^z - given for representative purpose, but i have a similar equation for that). How do i solve this with ode45? When i tried i got the following error: Unable to perform assignment because the left and right sides have a different number of elements. This is because the p7 has several values wheras other parametrs have only 1. Can someone help me how to solve ode with changing parameters.
CODE:
dx = zeros(3,1);
p7=a*b^y*c^z;
dx(1)=((p1.*((x(2)/(x(2)+p2)).*(x(3)/(x(3)+p3)))).*x(1));
dx(2)=((-((1/p4).*(p1.*((x(2)/(x(2)+p2)).*(x(3)/(x(3)+p3)))))+p5).*x(1));
dx(3)=(((-((1/p6).*(p1.*((x(2)/(x(2)+p2)).*(x(3)/(x(3)+p3)))))+p5).*x(1))+(p7.*(p8-x(3))));

Accepted Answer

Walter Roberson
Walter Roberson on 1 Aug 2019
You do not assign multiple values to p7. Instead, each time that p7 needs to change values in a discontinuous way, you need to terminate the ode45, and then restart it from where you left off except with the new p7 value.
If the p7 changes happen at known times, then the way to do this is to call ode45 with tspan reflecting the interval in which p7 is to remain constant. For example,
p7times = [0, 1, 2.5, 5, 5.2, 10];
p7vals = [pi/9, 0.3, exp(-1), sqrt(2), -3]; %one fewer
num_interval = length(p7vals);
x0 = [0 0 0];
t = cell(num_interval,1);
x = cell(num_interval, 1);
for idx = 1 : num_interval
p7 = p7vals(idx);
[t{idx},x{idx}] = ode45(@(t,x) try_eqns(t, x, p7), p7times(idx:idx+1), x0);
x0 = x{idx}(end,:);
end
If discontinuous changes to your p7 depend upon the results of the ode, then you should instead use ode event functions to detect the situation and terminate the integration and then resume with the new p7. There is a useful example of this: see ballode
  4 Comments
Nivedhitha S
Nivedhitha S on 2 Aug 2019
Thanks Mr.Walter.
To get clear, on what basis are the variable this_t and this_x assigned? Why not have the equations getting solved only fotr the given t spans? I got about 12937 values for these variables. I am not able to follow the actual mechanism which this is done. It would be great if you could help me out.
Thanks a lot.
Walter Roberson
Walter Roberson on 2 Aug 2019
At each ode45 call you are passing a vector of two times. When you pass a vector of length 2 then ode45 returns for a series of times according to whatever it feels like internally, and the number of times returned for can vary depending upon integration tolerances (so two calls for slightly different time ranges are not necessarily going to return the same number of outputs.)
When you pass ode45 a vector of 3 or more times then it returns only for those times, except as needed for terminal events.
Either way, ode45 will evaluate wherever it wants, and the question is just which times it reports back about. It is *not* the case that it only evaluates the function at the given times: it has to evaluate at intermediate times to meet tolerances.
If you wanted then you can pass in [t1, (t1+t2)/2, t2] to reduce the number of times it reports back to 3,but you still end up having to extract the (end) output.
You cannot just pass in list of p7 times because you are changing p7 abruptly and ode45 requires that the function be differentiable

Sign in to comment.

More Answers (1)

J Chen
J Chen on 31 Jul 2019
You put the derivative calculation in a file such as fcn.m,
function dx = fcn(t,x)
dx = zeros(3,1);
p7 = t; %p7=a*b^y*c^z;
p1 = 1; p2 = 2; p3 = 3; p4 = 4; p5 = 5; p6 = 6; p8 = 8;
dx(1) = ((p1.*((x(2)/(x(2)+p2)).*(x(3)/(x(3)+p3)))).*x(1));
dx(2) = ((-((1/p4).*(p1.*((x(2)/(x(2)+p2)).*(x(3)/(x(3)+p3)))))+p5).*x(1));
dx(3) = (((-((1/p6).*(p1.*((x(2)/(x(2)+p2)).*(x(3)/(x(3)+p3)))))+p5).*x(1))+(p7.*(p8-x(3))));
and call the solver in the command line
[t,x] = ode45('fcn',[0 1],[0 0 0]');
You can set p1 to p8 in the fcn.m file.
  1 Comment
Nivedhitha S
Nivedhitha S on 1 Aug 2019
Sorry i guess you mistook my question. My derivatibve functions are already within a function file:
%solving differential equations
function[dx]=try_eqns(t,x)
p1= p1; % values of parameters wil be given here:
p2= p2;
p3= p3;
p4= p4;
p5= p5;
p6= p6;
p8= p8;
p7=a*y^b*z^c;
% not a function of t or x, y and z are some input variables, a,b,c are parameter values.
% this parameter changes at every time point accoding to changes in inputs
dx = zeros(3,1);
dx(1) = ((p1.*((x(2)/(x(2)+p2)).*(x(3)/(x(3)+p3)))).*x(1));
dx(2) = ((-((1/p4).*(p1.*((x(2)/(x(2)+p2)).*(x(3)/(x(3)+p3)))))+p5).*x(1));
dx(3) = (((-((1/p6).*(p1.*((x(2)/(x(2)+p2)).*(x(3)/(x(3)+p3)))))+p5).*x(1))+(p7.*(p8-x(3))));
end
My question was: since p7 changes at every time point (say every 30 second), i'm unable to apply that here. i tried trying for loop, symbolic solving, etc., the solver is considering only the 1st value of parameter 7 and solving the equations. Please help. I want assistance with using ode for changing parameters

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!