- do not use global
- do not use assignin
- read in datossinmodi.mat once at the beginning and pass the value in, rather than reading it every iteration
How to accelerate the ode45 solver?
34 次查看(过去 30 天)
显示 更早的评论
Hi, everyone, I'm working with this code (see below) but it takes hours to finish and thus, to show me the results, I want to know if there is a way that I can speed up this, because maybe I'll need to add it a greater tspan, I tried to adjust the step size (as you can see in the code) but I'm not sure it is working, is there anything wrong in here? This is just one of the five codes that I'll need to solve this way, this is the simplest (the other ones have more than 2 ODE to be solved) so I need it to be solve quicker, how can I do it?
Thanks
function [t,x]= cobellilee
global out1
tspan=[0:5:180];
x0=[80; 0];
options=odeset('InitialStep',5,'MaxStep',5)
[t,x]=ode45(@f,tspan,x0,options);
out1=[t,x]
assignin('base','out1',out1);
figure
subplot(2,1,1)
plot(t,x(:,1));
subplot(2,1,2)
plot(t,x(:,2));
function dxdt= f(t,x,uuno)
global tiempo
tiempo=t
assignin('base','tiempo',tiempo)
dxdt=[
(-4.9e-2-x(2))*x(1) + 4.42;
-9.1e-2*x(2) + 8.96*U1(t)
];
function [uuno]=U1(t)
global uu1 tiempo s1
uu1=importdata('datossinmodi.mat')
assignin('base','uu1',uu1)
s1=size(uu1,1)
assignin('base','s1',s1)
tiempo=t
assignin('base','tiempo',tiempo)
tiempo=round(tiempo)
if (s1>=tiempo)
if (tiempo==0)
uuno=0;
else
uuno=uu1(tiempo)
end
else
uuno=0;
end
Note: 'datossinmodi.mat' is a 288x1 vector that I need the code to read depending on time, is what I did fine? Thanks again!
0 个评论
回答(2 个)
Walter Roberson
2015-10-5
To speed up the routine:
2 个评论
Walter Roberson
2015-10-5
global and assignin are guaranteed to make the code slower, not faster. If you search the blogs for information on which kind of data references are faster or slower, global is the second worst.
[t,x]=ode45(@(t,y) f(t,y,uu1), tspan, x0, options);
Kelly Kearney
2015-10-5
If I understand your code correctly, the U1 function is simply interpolating the uu1 vector to the appropriate time, right? If so, you can eliminate all the loading and assigning, as Walter suggests:
uu1 = importdata('datossinmodi.mat');
ufun = @(t) interp1(1:length(uu1), uu1, t, 'nearest', 0);
f = @(t,x) [(-4.9e-2-x(2))*x(1) + 4.42; ...
-9.1e-2*x(2) + 8.96*ufun(t)];
tspan=[0:5:10];
x0=[80; 0];
options=odeset('InitialStep',5,'MaxStep',5)
[t,x]=ode45(f,tspan,x0,options);
Because it's a variable step solver, ode45 may still be slow for your set of equations if it has to reduce its step size a lot while solving. The MaxStep option only controls the largest possible step it takes, but not the smallest. If your solver code is still pretty slow after you've eliminated the unnecessary loads, try experimenting with other solvers.
6 个评论
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Ordinary Differential Equations 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!