【问题标题】:Help in optimizing a for loop in matlab帮助优化matlab中的for循环
【发布时间】:2010-05-02 16:00:43
【问题描述】:

我有一个由 1 和 0 组成的 1 x N 双精度数组。我想将所有 1 映射到符号“-3”和“3”,并将所有 0 映射到符号“-1”和“1” .下面是我的代码。由于我的阵列约为 1 x 800 万,因此需要很长时间。如何加快速度?

[row,ll] = size(Data);
sym_zero = -1;
sym_one = -3;
for loop = 1 : row
    if Data(loop,1) == 0
        Data2(loop,1) = sym_zero;
                     if sym_zero == -1
                         sym_zero = 1;
                     else
                         sym_zero = -1;
                     end
    else
        Data2(loop,1) = sym_one;
                     if sym_one == -3
                         sym_zero = 3;
                     else
                         sym_zero = -3;
                     end
    end
end

【问题讨论】:

  • 从您的代码看来,您有一个 N × 1 数组。
  • 另外,MATLAB 问题编号 1234!
  • 预分配!检查我的答案:)

标签: optimization matlab


【解决方案1】:

这是一个非常重要的 MATLAB 优化技巧。

预分配!

通过简单的预分配,您的代码速度要快得多。只需添加

Data2 = zeros(size(Data));
for loop = 1: row 
...

在您的 for 循环之前。

在我的计算机上您的代码带有预分配终止于0.322s,并且您的原始代码仍在运行。我删除了我原来的解决方案,因为你的这个优化非常快:)。

此外,由于我们讨论的是 MATLAB,因此处理列向量会更快。

【讨论】:

    【解决方案2】:

    希望您能遵循这一点,并希望我正确理解了您的代码:

    nOnes = sum(Data);
    nZeroes = size(Data,2) - nOnes;
    
    Data2(find(Data)) = repmat([-3 3],1,nOnes/2)
    Data2(find(Data==0)) = repmat([-1 1],1,nZeroes/2)
    

    我会让你来处理奇怪的1s 和0s。

    【讨论】:

      【解决方案3】:

      所以,忽略负号,输出项 Data2[loop,1] = Data[loop,1]*2 + 1 的等式。那么为什么不首先使用简单的乘法来执行此操作 - 这应该很快,因为它可以被矢量化。然后创建一个原始数组长度为 1s 的一半,原始数组长度为 -1s 的一半的数组,在其上调用 randperm。然后乘以那个。一切都是矢量化的,应该会更快。

      【讨论】:

      • 你的想法不错,但我会在项目后期将符号模式增加到1个和3个以上。
      • @HH:只要有输入值到输出符号的简单映射,您就可以建立一个线性方程来产生结果(并且可以通过 MATLAB 有效地向量化),但是它听起来您已经通过使用预分配获得了足够的解决方案。
      【解决方案4】:
      [row,ll] = size(Data);
      sym_zero = -1;
      sym_one = -3;
      for loop = 1 : row
          if ( Data(loop,1) ) // is 1
              Data2(loop,1) = sym_one;
              sym_one = sym_one * -1; // flip the sign
          else
              Data2(loop,1) = sym_zero;
              sym_zero = sym_zero * -1; // flip the sign
          end
      end
      

      【讨论】:

      • 使用您的代码时,我没有看到性能上有显着差异。所以,它并没有真正起作用。
      猜你喜欢
      • 1970-01-01
      • 2021-07-17
      • 2020-10-19
      • 2011-05-14
      • 1970-01-01
      • 2022-11-18
      • 1970-01-01
      • 2021-05-31
      • 1970-01-01
      相关资源
      最近更新 更多