【问题标题】:Iterating through matrix rows in Octave without using an index or for loop在 Octave 中遍历矩阵行而不使用索引或 for 循环
【发布时间】:2012-09-02 15:18:01
【问题描述】:

我试图通过删除我用来计算矩阵 X 每一行的公式的 for 循环来了解是否可以更有效地使用 Octave:

myscalar = 0
for i = 1:size(X, 1),
  myscalar += X(i, :) * y(i) % y is a vector of dimension size(X, 1)
  ...

公式比添加到标量更复杂。这里的问题实际上是如何在没有索引的情况下遍历 X 行,这样我就可以消除 for 循环。

【问题讨论】:

  • 我不明白你的代码应该做什么。在每个循环中,它只是将向量X(i,:) 乘以标量y(i)。你的 myscalar 实际上是一个向量。除非 X 只有一列,但为什么要设置它?你为什么要为乘法转置?另外,没有必要使用size (X, 1),Octave 已经有了rowscolumns 的功能。
  • 我的问题实际上是关于那个 for 循环,而不是任何代码。确实,转置很混乱,所以我要修复它,但是有没有办法删除索引和 for 循环?
  • 可能是的,但我不能告诉你怎么做,因为代码没有意义。 myscalar 应该是标量吗?乘法之和?矩阵?什么大小的?我不明白你想要什么。
  • 好的,我修复了 myscalar,但我不明白为什么专注于代码如此重要。这是一个普遍的问题,有没有办法在对每一行或每一列而不是每个元素应用公式时避免矩阵索引(在这种情况下矢量化更明显)?
  • 现在说得通了。我不明白myscalar 发生了什么,因为您之前只是覆盖它,而不是添加它(= 而不是+=)。

标签: octave vectorization


【解决方案1】:

是的,您可以为此使用broadcasting(您需要 3.6.0 或更高版本)。如果你知道 python,这也是一样的 (an explanation from python)。只需将矩阵乘以列。 Finnaly,cumsum 进行了加法,但我们只想要最后一行。

newx      = X .* y;
myscalars = cumsum (newx, 1) (end,:);

或者在一行中没有临时变量

myscalars = cumsum (X .* y, 1) (end,:);

如果大小合适,会自动执行广播。例如:

octave> a = [ 1 2 3
              1 2 3
              1 2 3];
octave> b = [ 1 0 2];
octave> a .* b'
warning: product: automatic broadcasting operation applied
ans =

   1   0   6
   1   0   6
   1   0   6

octave> a .* b
warning: product: automatic broadcasting operation applied
ans =

   1   2   3
   0   0   0
   2   4   6

警告的原因是它是一个新功能,可能会使用户感到困惑,并且在 Matlab 中不存在。您可以通过将warning ("off", "Octave:broadcast") 添加到您的.octaverc 文件来永久关闭它

对于使用旧版本 Octave 的任何人,都可以通过直接调用 bsxfun 来完成。

myscalars = cumsum (bsxfun (@times, X, y), 1) (end,:);

【讨论】:

  • 在 Octave 3.6 版本下是否可以做同样的事情,可能是(2.4)?
  • @Kaha 没有 2.4 版本(版本 2.0.16 之后是 2.9.14)。但只要实现bsxfun,也可以这样做。我已经编辑了我的答案以显示旧版本的替代方案。
猜你喜欢
  • 2022-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-27
相关资源
最近更新 更多