这是我的代码,我想改进它。
这是正确的,但我想减少这段代码的时间!
我该怎么办?!
我的代码:
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
答案 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 );
现在看一下x
和y
的结果形状,大小和值。它们允许您在一步中对x
和y
执行操作“ - 最简单的示例:x+y
现在为您提供所有可能的x
和{{对的总和1}}值。
但是在您的代码中,您希望将向量(例如y
)添加到-Xn
和x
值。由于y
和x
现在是矩阵,因此它们已经占据了前两个维度中的空间,因此这是一个问题。我们可以通过多种方式解决此问题 - 例如,使用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
是必要的,因为bsxfun
和x
形状不完全相同:Xn
需要“平铺”或“广播”到维度2和3中。
然后,您继续以这种方式修改代码,注意您的维度(例如,每当您执行Xn
时,您应该始终明确地告诉它要汇总的维度 )。最后,您最终会得到sum
与原始Et
和x
相同的大小和形状,并且您希望在尺寸2和3中执行最小操作,其中y
和x
值各不相同:
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 ];
:
#Q = [ 9,5,4 ; 10,1,7 ; 4,6,10 ];
: