我正在尝试模拟一些粒子的运动。这个程序似乎很慢。我刚开始精益编程,所以我不知道问题到底在哪里,这让它很慢,我认为绘图需要很多时间。能给我一些建议吗?
function folks(N , T)
if nargin < 1
N = 50;
T = 100;
end
A=20;R=50;a=100;r=2;
x0=10*randn(3,N);
v0=0*randn(3,N);
clear c
% Initilazing plot
color = hsv(N);
xh=zeros(1,N);
f=2*max(max(x0));ff=f/1000000;
figure(2),clf
set(gcf,'doublebuffer','on')
hold on, grid on, axis([-1 1 -1 1 -.5 .5]*f)
for j = 1:N
xh(j) = line(x0(1,j),x0(2,j),x0(3,j),'color',color(j,:), ...
'marker','.','markersize',15);
end
title('t = 0','fontsize',18)
rotate3d;
view([1.8,-1.8,1])
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Solving the ode system
tol = 3e-14;
opts = odeset('reltol',tol,'abstol',tol);
X0=[x0(:);v0(:)];
dt=T/1000;
for tnext = dt:dt:10*T
tspan = [tnext-dt tnext];
[T1,X1] = ode45(@odefolk,tspan,X0,opts,r,R,a,A);
X0 = X1(end,:);
if max(abs(X0(1:3*N)))>f
f=1.1*f;
axis([-1 1 -1 1 -1 1]*f)
end
for j=0:N-1
set(xh(j+1),'xdata',X0(3*j+1),'ydata',X0(3*j+2),'zdata',X0(3*j+3))
end
title(sprintf('t = %3.0f %5.0e',tnext),'fontsize',18),
drawnow
end
我试着把数据保存在一个矩阵中,然后把每一件事都绘制在新的循环中,但这会让它慢得多。而且它与求解器ode45或系统odelfolk无关
function dx = fkt(~,x,r,R,a,A)
n = length(x); % n = 90 = 6 *N
M = n/6; % M= 15
dx = zeros(n,1);
for i = 1 : 3 : n/2
vx = 0 ; vy = 0 ; vz = 0;
for j = 1 : 3 : n/2
if (i~=j)
vx = x(i) - x(j) ;
vy = x(i+1) - x(j+1);
vz = x(i+2) - x(j+2);
% ex = expo (vx , vy , vz ,r , a);
%
% val = (ex(1) * R - ex(2) * A);
leng = sqrt(vx^ 2 +vy^ 2 + vz^ 2);
expo1 = exp(-1 * leng / r) / r;
expo2 = exp(-1 * leng / a) / a;
val = (expo1 * R - expo2 * A);
vx = vx * val;
vy = vy * val;
vz = vz * val;
end
end
vx = vx/M ;
vy = vy/M;
vz = vz/M;
dx(i) = x(i + 3 * M );
dx(i + 1) = x(i + 3 * M + 1);
dx(i + 2) = x(i + 3 * M + 2);
dx(i + 3 * M ) = vx;
dx(i + 3 * M + 1 ) = vy;
dx(i + 3 * M + 2 ) = vz;
end
end
要执行代码,最好使用Profiler:进行分析
https://es.mathworks.com/help/matlab/ref/profile.html
不管怎样,我认为有些事情你可以改变。首先,避免在每次迭代中绘制。做到底,或者画出每M个迭代。
其次,避免使用循环来定义图形。用矢量类型的输入数据绘制它。
第三,ode45可以为您进行迭代,并可以返回一个包含所有迭代的向量。使用它进行绘图。
一些提示:
- 使用
tic
和toc
来测量代码(行、函数等(的执行时间 - 预先分配数组,避免让它们在循环中增长
- 不要在循环中使用CCD_ 3。尝试使用低级命令,并通过引用现有行的句柄来更改现有行的值(例如
handle = line([0 1][2 3][4 5])
和set(handle,'XDATA',[4 7],'YDATA',[2 6],'ZDATA',[2 4])
( - MATLAB是一种解释语言,因此在大多数情况下,与编译程序相比,您的代码运行速度会较慢