【发布时间】:2012-09-14 02:15:50
【问题描述】:
在我的程序中,我需要计算总和:
.
我用 C 和 z 的新值计算了这个总和 2500 次。
参数z 可能是一个向量。我写了简单的for循环和矢量化版本代码如下:
K = 200;
n_z = 40000;
C = ones(K,1); % an example, in real life the arey some coefficients (at next call will be new)
k = 0:K-1;
z = linspace(0, 2*pi, n_z); % at next call will be new
tic;
my_sum_for = zeros(1, K);
for i=1:n_z
my_sum_for(i) = C' * tan(k' * z(i));
end
toc; % Elapsed time is 1.820485 seconds.
tic;
my_sum = C' * tan(k' * z);
toc; % Elapsed time is 0.160924 seconds.
矢量化版本更快,但还不够。 是否可以改进矢量化版本?
在 Dominique Jacquel 的回答之后,我有了这个矢量化版本,它更快:
K = 200;
n_z = 40000;
C = ones(K,1)'; % an example, in real life they are some coefficients (at next call will be new)
k = (0:K-1)';
z = linspace(0, 2*pi, n_z); % at next call will be new
tic;
my_sum_for = zeros(1, K);
for i=1:n_z
my_sum_for(i) = C * tan(k * z(i));
end
toc; % Elapsed time is 1.521587 seconds.
tic;
my_sum = C * tan(k * z);
toc; % Elapsed time is 0.125468 seconds.
是否有可能进一步改进矢量化版本(bsxfun、arrayfun 之类的)? 250 秒的时间对我来说仍然很慢(占所有计算的 75%)。
【问题讨论】:
-
all(my_sum_for == my_sum) -> ans = 0...所以,您还没有检查过这个吗?在我看来,你做了一些不需要的奇怪转调.., -
我通过计算 norm(my_sum_for, my_sum) = 1.7861e-10 进行了检查。对我来说,相同代码的矢量化版本和循环版本会产生略有不同的结果,这对我来说并不新鲜。
-
C的实际内容真的只是一个吗?并且矩阵k*z中有一些重复的元素,您可能可以跳过计算tan的值,但考虑到K和n_Z的值,那里没有什么可保存的。 -
这是一个例子,C是一些系数的数组。最新版本的内存消耗最小。可能有更快的解决方案和更多的内存消耗?我的程序调用这个代码 2500 次,所以它是 250 秒。我希望我们可以更快地编写代码。
-
对这段代码的 2500 次调用之间有什么变化?这段代码是否总是使用
C和z的新值调用?如果没有,您可能会利用它来进一步优化。
标签: matlab vectorization