如何提高这个Matlab代码的运行速度?

如何提高这个Matlab代码的运行速度?,matlab,Matlab,我正在尝试模拟一些粒子的运动。这个程序看起来很慢。 我刚开始精益编程,所以我不知道到底是哪里的问题,使它变慢,我认为绘图是需要很多时间。 有谁能建议我如何改进它吗 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 =

我正在尝试模拟一些粒子的运动。这个程序看起来很慢。 我刚开始精益编程,所以我不知道到底是哪里的问题,使它变慢,我认为绘图是需要很多时间。 有谁能建议我如何改进它吗

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

要执行代码,最好使用探查器对其进行分析:

不管怎样,我发现有些事情你可以改变。首先,避免在每次迭代中绘制。最后做一次,或者每M次画一次

其次,避免使用循环来定义图形。用矢量型输入数据绘制它


第三,ode45可以为您执行迭代,并可以返回一个包含所有迭代的向量。用它来绘图

要执行代码,最好使用探查器进行分析:

不管怎样,我发现有些事情你可以改变。首先,避免在每次迭代中绘制。最后做一次,或者每M次画一次

其次,避免使用循环来定义图形。用矢量型输入数据绘制它

第三,ode45可以为您执行迭代,并可以返回一个包含所有迭代的向量。用它来绘图

一些提示:
  • 使用
    tic
    toc
    测量代码的执行时间(行、函数等)
  • 预先分配数组并避免让它们在循环中增长
  • 不要在循环中使用
    plot
    。尝试使用低级命令并通过引用现有行的句柄(例如
    handle=line([01][23][45])
    然后
    set(句柄、'XDATA'、[47]、'YDATA'、[26]、'ZDATA'、[24])来更改现有行的值。
  • MATLAB是一种解释语言,因此与编译程序相比,您的代码在大多数情况下运行较慢
一些提示:
  • 使用
    tic
    toc
    测量代码的执行时间(行、函数等)
  • 预先分配数组并避免让它们在循环中增长
  • 不要在循环中使用
    plot
    。尝试使用低级命令并通过引用现有行的句柄(例如
    handle=line([01][23][45])
    然后
    set(句柄、'XDATA'、[47]、'YDATA'、[26]、'ZDATA'、[24])来更改现有行的值。
  • MATLAB是一种解释语言,因此与编译程序相比,您的代码在大多数情况下运行较慢

这非常有用,似乎odefolk
花费了太多时间。正如我之前提到的,我刚开始学习编程,所以请你解释一下如何在不使用循环的情况下绘图。以及如何使用ode45获得所有迭代(我只需要每次迭代中ode45结果的最后一行)@Sergio我认为MATLAB文档很好地解释了这一点。在该URL上运行示例以了解其工作原理。如果你有更多的麻烦,我会帮助你。这是非常有用的,似乎odefolk
花费了太多的时间。正如我之前提到的,我刚开始学习编程,所以请你解释一下如何在不使用循环的情况下绘图。以及如何使用ode45获得所有迭代(我只需要每次迭代中ode45结果的最后一行)@Sergio我认为MATLAB文档很好地解释了这一点。在该URL上运行示例以了解其工作原理。如果你有更多的麻烦,我会帮助你。我已将odefolk添加到问题中。我已将odefolk添加到问题中,而不是使用
tic
toc
我更喜欢使用内置分析器。我使用tic&toc比较两个不同的代码与相同的函数odefolk,它们大致相同。你能给我更多的细节,如何避免使用循环,如果我存储一个数据,所以我需要的大小矩阵(1000,90),你能参考一些例子或参考@Lemonbonbon不是使用
tic
toc
我更喜欢使用内置的探查器。我使用tic和toc来比较两个不同的代码与相同的函数,因为它们大致相同。你能给我更多的细节,如何避免使用循环,如果我存储一个数据,所以我需要的大小矩阵(1000,90),你能参考一些例子或参考@柠檬软糖
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