循环的替代品

时间:2014-12-24 18:23:49

标签: matlab network-programming

这是我的代码,我想改进它。

这是正确的,但我想减少这段代码的时间!

我该怎么办?!

我的代码:

D  = [ 0 9 1 ; 0 9 8 ];
f   =D(:, 3);
s  = D(:, 1);
a   = D(:, 2);
t   = 0 : 0.01 : 10;
x    = t.';
i   = 0 : 0.01 : 10;
y    = i.';
E= 1.0000e+025;

for x=0 : 1: 10
    for y =0 :1 :10
        h   = sqrt( (x - s).^2 +(y-a).^2 );
        Ex1 = (q.*(x-Xn)) ./ r.^3  ;
        r  = sum(Ex1);
        Ey1 = (q.*(y-Yn)) ./ r.^3  ;
        r2 = sum(Ey1);
        Et  = sqrt( r^2 + r2^2 );    

        end 
    end 
end

2 个答案:

答案 0 :(得分:2)

你几乎总能摆脱Matlab中的for循环,直接使用数字数组“一次性”(意味着循环仍然发生,但它们在底层二进制文件中实现了高度优化的方式)。此过程称为“向量化”,并且有一个tutorial on it on the MathWorks website以及一百个Google搜索结果的结尾。对您而言,两个主要工具将是meshgrid(或ndgrid,无论您喜欢哪种方式)和bsxfun。在你的特定情况下,我将从

开始
[ x, y] = ndgrid( 0:0.01:10, 0:0.01:10 );

现在看一下xy的结果形状,大小和值。它们允许您在一步中对xy执行操作“ - 最简单的示例:x+y现在为您提供所有可能的x和{{对的总和1}}值。

但是在您的代码中,您希望将向量(例如y)添加到-Xnx值。由于yx现在是矩阵,因此它们已经占据了前两个维度中的空间,因此这是一个问题。我们可以通过多种方式解决此问题 - 例如,使用y将向量Xn投影到第三维中。或者,如果我们将Xn = permute(Xn(:), [3 2 1])x转换为更高维度(2和3),它可能会更清晰。所以让我们修改它:

y

现在可以在不改变其形状的情况下减去列矢量[ ~, x, y] = ndgrid( 1, 0:0.01:10, 0:0.01:10 ); 。这是这样做的:

Xn

bsxfun( @minus, x, Xn ) % instead of x-Xn 是必要的,因为bsxfunx形状不完全相同:Xn需要“平铺”或“广播”到维度2和3中。

然后,您继续以这种方式修改代码,注意您的维度(例如,每当您执行Xn时,您应该始终明确地告诉它要汇总的维度 )。最后,您最终会得到sum与原始Etx相同的大小和形状,并且您希望在尺寸2和3中执行最小操作,其中yx值各不相同:

y

答案 1 :(得分:0)

在您的算法for循环中占用大部分时间。如果可以避免循环,那么您将获得极佳的时间性能。正如 @jez 所提到的,在您的情况下,您可以使用meshgrid()bsxfun()函数的组合,而不是使用for循环,这可以替代gradient() {1}}想到了。

试试这个:

tic

Q      = [ 0,5,7 ; 2.5,0,7; 2.5,10,7 ; 7.5,0,7 ; 7.5,10,7 ; 10,5,7 ]; 
% // Q      = [ 9,5,4 ; 10,1,7 ; 4,6,10 ];  % // You can write any Q matrix you want
Xn     = Q(:, 1);
Yn     = Q(:, 2);
q      = Q(:, 3);
len    = length(Xn);
x      = meshgrid([0 : .01 : 10]'); % // Enter your x vector to meshgrid() as an argument
% // [~, y] = meshgrid([0 : .01 : 10]'); % // Enter your y vector to meshgrid() as an argument
[U, y] = meshgrid([0 : .01 : 10]'); % // U refer to unnecessary variable. You should do it like that because tilde sign isn' t defined in your MATLAB version..
X      = meshgrid( x, zeros(len, 1) );      
Y      = meshgrid( y, zeros(1, len) );
xDif   = bsxfun(@minus, X, Xn);
yDif   = bsxfun(@minus, Y, Yn);
r      = sqrt( xDif.^2 + yDif.^2 );
Ex1    = ( bsxfun(@times, xDif, q) ) ./ ( r.^3 );
Ey1    = ( bsxfun(@times, yDif, q) ) ./ ( r.^3 );
Ex     = sum(Ex1, 1);
Ey     = sum(Ey1, 1);
Et     = sqrt(Ex.^2 + Ey.^2);
Emin   = min(Et);
indMin = find(Et==Emin);
Xmin   = X(1, indMin);
Ymin   = Y(1, indMin);

toc

使用此代码,我的电脑时间增长 17.582351 - 1.740135 = 15.8422 seconds


代码的执行样本:

Q = [ 0,5,7 ; 2.5,0,7; 2.5,10,7 ; 7.5,0,7 ; 7.5,10,7 ; 10,5,7 ]; enter image description here

Q = [ 9,5,4 ; 10,1,7 ; 4,6,10 ]; enter image description here