【问题标题】:Matlab variable size arraysMatlab 可变大小数组
【发布时间】:2018-07-29 18:54:54
【问题描述】:

我对 Matlab 很陌生,对数组的使用感到完全不知所措。以下 C++ 代码在 Matlab 中最有效的实现是什么?

A = std::vector<double>();

for (int i = 0; i < 100; i++) {
  if (complicatedBoolFunction(i)) {
    A.push_back(i);
  }
}

编辑:效率是指使用尽可能少的资源来增长数组 A - 即避免将其复制粘贴到临时内存中

【问题讨论】:

    标签: arrays matlab


    【解决方案1】:

    此类 C++ 代码的最有效实现是

    i = 0:99;
    A = i(complicatedBoolFunction(i));
    

    无论如何,您都可以通过连接来增长一个数组,这通常是(或曾经)不推荐的,如下所示

    A = [];
    
    for i = 0:99
      if (complicatedBoolFunction(i))
        A = [A i];
      end
    end
    

    much more efficiently 像这样:

    A = [];
    
    for i = 0:99
      if (complicatedBoolFunction(i))
        A(end + 1) = i;
      end
    end
    

    【讨论】:

    • 感谢您的回复,马尔科。最后两个建议效果很好。第一个建议,用一个简单的例子 i = 0:99; A = i(mod(i, 2)) 失败,下标索引必须是正整数或逻辑数
    • 因为mod(i, 2)的返回是一个double值的数组。试试mod(i, 2) == 0
    • 增加数组的第二种形式要高效得多,因为第一种形式会在每次迭代时复制数组。请参阅此处:stackoverflow.com/q/48351041/7328782(比较问题和答案中的图表)。
    【解决方案2】:

    你可以通过两种方式做到这一点

    1. 预分配最大尺寸,并删除未使用的元素。这样做的好处是在经常满足条件的情况下预分配内存...

      A = NaN(100,1)
      for ii = 0:99
          if rand > 0.5    % some condition
              A(ii+1) = ii; % some value
          end
      end
      A(isnan(A)) = []; % remove unused elements
      
    2. 附加到数组。如果不太可能追加,这可以避免使 A 太大...

      A = []; % empty array
      for ii = 0:99
          if rand > 0.5 % some condition
              A(end+1, 1) = ii; % some value. Equivalent to 'A = [A; ii];'
          end
      end
      

    一种更好、更类似于 Matlab 的方法是将条件函数向量化。这样可以避免循环分配问题...

    ii = 0:99;
    A = ii(rand(100, 1) > 0.5);
    

    您可以使用任何您喜欢的布尔函数作为索引数组,只要它返回的逻辑数组的元素数量与您要索引的数组(此处为ii)或元素的整数索引相同即可选择。

    【讨论】:

    • 我喜欢第三种,Matlab-esque 方式,它并不总是很实用,但它似乎是最有效的方式 - 没有循环
    • @user2305193:MATLAB 中的循环不再慢,我注意到有时代码在向量化循环后会变慢!例如,请参见此处:stackoverflow.com/a/48220174/7328782
    • 同意@Cris,不是必然慢,尽管对于这个例子来说,如果布尔函数调用可以被向量化,显然会更整洁。虽然较新的 JIT 编译器在循环方面相当不错,但矢量化代码仍然可以为某些操作带来不错的性能改进。
    • 我同意。并且通常(如在本例中)矢量化代码也更易于阅读。但是一些向量化优化真的很难破译! :)
    • @CrisLuengo 我知道循环在 Matlab 中并不是很慢,我不能同意更多,使用循环更实用,尤其是迭代增加变量/将值推送到向量以提高可读性并且能够在运行中更快地对其进行修改。但是 Matlab 似乎是为“布尔方式”而设计的,如果它不能比“传统”循环更快(或至少同样快)处理这些循环,那将是令人惊讶的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-24
    • 2016-09-17
    • 2017-06-16
    • 1970-01-01
    • 1970-01-01
    • 2015-10-24
    相关资源
    最近更新 更多