matlab - 有比这更好的矢量化技术吗?

标签 matlab vector matrix vectorization

我正在尝试查看是否有其他方法可以更有效地编写此代码示例。这里,y 是一个 1xM 矩阵(比如 1x1000),z 是一个 NxM 矩阵(比如 5x1000)。

mean(ones(N,1)*y.^3 .* z,2)

这段代码工作正常,但我担心如果 N 增加很多,ones(N,1)*y.^3 可能会变得太浪费并使一切变慢。

想法?

最佳答案

对于这么小的矩阵来说并没有那么糟糕。很多时候,您可以通过使用 bsxfun 来解决此类问题。这里的矩阵太小了,无法真正获得任何东西。

>> N = 5;M =1000;
>> y = rand(1,M);
>> z = rand(N,M);
>> mean(ones(N,1)*y.^3 .* z,2)
ans =
      0.12412
      0.11669
      0.12102
      0.11976
      0.12196

>> mean(bsxfun(@times,y.^3,z),2)
ans =
      0.12412
      0.11669
      0.12102
      0.11976
      0.12196

>> z*y.'.^3/M
ans =
      0.12412
      0.11669
      0.12102
      0.11976
      0.12196

如您所见,所有三个解决方案都返回相同的结果。所有都同样有效。

现在我将比较所需的时间。

>> timeit(@() mean(ones(N,1)*y.^3 .* z,2))
ans =
   0.00023018

>> timeit(@() mean(bsxfun(@times,y.^3,z),2))
ans =
   0.00026829

>> timeit(@() z*y.'.^3/M)
ans =
   0.00016594

正如我所说,您不会有太多收获。事实上,bsxfun 根本没有增益,甚至还慢了一点。但是,如果您将表达式重新写成我提出的第三种形式,您会有所收获。不多,但有点。

编辑:如果 N 很大,那么时间会稍微改变。

>> N = 2000;M = 1000;
>> y = rand(1,M);
>> z = rand(N,M);
>> timeit(@() mean(ones(N,1)*y.^3 .* z,2))
ans =
     0.034664

>> timeit(@() mean(bsxfun(@times,y.^3,z),2))
ans =
     0.012234

>> timeit(@() z*y.'.^3/M)
ans =
    0.0017674

不同之处在于第一个解决方案显式创建了一个扩展的 y.^3 矩阵。这是低效的。

bsxfun 解决方案更好,因为它从不显式地形成扩展 y.^3 矩阵。但它仍然形成一个 N × M 的乘积矩阵。所以这个解决方案仍然必须抓取并填充一大块内存。

您应该明白为什么矩阵向量乘法在所有情况下都是最好的。从来没有形成过大矩阵。由于 * 只是一个点积(因此是乘积之和),因此它必须更有效率。然后我在事后除以 M 以创建所需的均值。

比上一个小改进...

>> timeit(@() z*(y.*y.*y).'/M)
ans =
    0.0015793

略高于 power op。

timeit ?这来自 File Exchange,这是一个非常有用的实用程序,由 Steve Eddins 编写,用于计时代码片段。

关于matlab - 有比这更好的矢量化技术吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12186178/

相关文章:

python - matlab 类似于 python 中的结构

C++变量数据被覆盖

c++ - C++ 中的矩阵和 vector 模板类

r - 在 R 中传递大型矩阵的替代方法

javascript - 检查我的矩阵是否是幻方 javascript

c - mexGetData() 输出零

matlab - 如何使用 repmat 将 1d 向量 reshape 为 3d 矩阵?

c++ - 如何使C++函数返回char数组所有排列的 vector

matlab - 如何获取单选按钮的选定值?

c++ - 初始化结构中结构的 vector