【问题标题】:omitting the for loops in matlab省略matlab中的for循环
【发布时间】:2014-06-29 09:55:14
【问题描述】:

我将计算以下等式,其中有四个不同的变量。有没有可能的方法来省略计算这个方程的 for 循环?

 Z = p1 * sqrt(q1^2 + q2^2 * p2^2)

其中的变量是:

p=[(1,1) (1,2) (1,3) (1,4)
   (2,1) (2,2) (2,3) (2,4)
   (3,1) (3,2) (3,3) (3,4)
   (4,1) (4,2) (4,3) (4,4)];

其中第一个数字是 p1,第二个数字是 p2(例如,在 (1,2) 中,p1=1,p2=2)。 和:

q=[(5,5) (5,6) (5,7) (5,8)
   (6,5) (6,6) (6,7) (6,8)
   (7,5) (7,6) (7,7) (7,8)
   (8,5) (8,6) (8,7) (8,8)]

第一个数字是 q1,第二个数字是 q2。

如何在没有 for 循环的情况下为它们中的每一个计算 Z?

【问题讨论】:

  • 我没有看到任何 for 循环。你到底想要什么?
  • @Daniel 我没有在这里编写 for 循环,我想计算每个 p1、p2、q1 和 q2 的 Z。实际上对于这四个变量的每个组合,我都会有一个 Z。
  • @user3482383 查看基于bsxfun here 的新解决方案,该解决方案显示出一些运行时性能的承诺。

标签: arrays matlab for-loop vectorization


【解决方案1】:

要计算四个变量的每个组合而不使用for 循环,请使用ndgrid

[pp1 pp2 qq1 qq2] = ndgrid(p1,p2,q1,q2);
Z = pp1 .* sqrt(qq1.^2 + qq2.^2 + pp2.^2);

对于您的示例,这会产生大小为 16 x 16 x 16 x 16 的结果 ZZ 的第一个索引是指p1,第二是 p2,第三是 q1,第四是q2.

顺便说一句,在您的代码中,您需要将 length 替换为 numel;就目前而言,您不会从每个矩阵中获取所有元素。


问题编辑后: 计算p1q1的每个组合p2的索引与p1的索引相同,q2的索引与q2的索引相同q1:

[ii jj] = ndgrid(1:numel(p1), 1:numel(q1));
Z = pp1(ii) .* sqrt(qq1(jj).^2 + qq2(jj).^2 + pp2(ii).^2);

在您的情况下,Z 的大小为 16 x 16。

【讨论】:

  • 我所做的编辑怎么样?对于这种情况,我该如何改变你的想法?
  • 我尝试使用 ndgrid 代替 for 循环,但计算时间更多的是使用 for 循环的时间!
【解决方案2】:

我假设你的嵌套循环看起来像这样 -

Z = zeros(length(p1),length(p2),length(q1),length(q2));
for i=1:length(p1)
    for j=1:length(p2)
        for m = 1:length(q1)
            for n = 1:length(q2)
                Z(i,j,m,n) = p1(i) * sqrt(q1(m)^2 + q2(n)^2 * p2(j)^2);
            end
        end
    end
end

注意:numelsize 将是比 length 更好的参数,但在您修改问题之前,请在此处保留代码中使用的 length

现在,在p1q1p2q2 中,您有网格数据和许多相同的值,可用于代码优化和向量化。这是bsxfun 的矢量化解决方案 -

impvals = bsxfun(@times,p1(:,1)',sqrt(q1(:,1).^2+(p2(1)*q2(1))^2)); %//'
Z = repmat(permute(impvals,[2 3 1 4]),[1 4 1 4]);

我用你给定的4x4 数据为这四个二维数组中的每一个运行了100000 次(为了更好的运行时测量),这就是运行时 -

Elapsed time (with for-loops) is 5.684010 seconds.
Elapsed time (with bsxfun) is 4.441675 seconds.

【讨论】:

  • 在您看来,如果这些嵌套循环是用 C++ 编写的,那会是什么时候呢?
  • @user3482383 运行时是什么?我认为计算机必须是回答这个问题的更好人选。为什么不编写一个 C++ 程序并在您的计算机上进行测试呢?
  • 我对 C++ 不熟悉,所以我问你在不同编程语言中使用for loops 的经验
  • @user3482383 我也没有多少。此外,这必须是一个单独的问题,因为这是 MATLAB 特定的。
猜你喜欢
  • 2012-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多