4

我需要对表格进行大量评估

X(:,i)' * A * X(:,i)   i = 1...n

其中 X(:,i) 是一个向量,A 是一个对称矩阵。从表面上看,我可以循环执行此操作

for i=1:n
    z(i) = X(:,i)' * A * X(:,i)
end

这很慢,或者将其矢量化为

z = diag(X' * A * X)

当 X 有很多列时,这会不可接受地浪费 RAM。目前我正在妥协

Y = A * X
for i=1:n
    z(i) = Y(:,i)' * X(:,i)
end

这更快/更轻,但似乎仍然不能令人满意。

我希望可能有一些 matlab/scilab 习语或技巧来更有效地实现这一结果?

4

3 回答 3

3

尝试这个:

z = dot(X, A*X)

我这里没有要测试的 Matlab,但它适用于 Octave,所以我希望 Matlab 具有类似的 dot()功能。

在 Octave 的帮助下:

  -- Function File:  dot (X, Y, DIM)
     Computes the dot product of two vectors. If X and Y are matrices,
     calculate the dot-product along the first non-singleton dimension.
     If the optional argument DIM is given, calculate the dot-product
     along this dimension.
于 2010-04-02T20:23:57.940 回答
3

在 MATLAB 中试试这个:

z = sum(X.*(A*X));

这给出了相当于Federico使用函数DOT的建议的结果,但运行速度应该稍快一些。这是因为DOT函数在内部计算结果的方式与我上面使用SUM函数的方式相同。但是,对于处理复数的情况, DOT还具有额外的输入参数检查和额外的计算,这是您可能不想要或不需要的额外开销。

关于计算效率的说明:

尽管这两种方法运行速度之间的时间差异很小,但如果您要多次执行该操作它将开始累加。为了测试相对速度,我创建了两个 100×100 的随机值矩阵,并在多次运行中对这两种方法进行计时,以获得平均执行时间:

    METHOD        AVERAGE EXECUTION TIME
--------------------------------------------
Z = sum(X.*Y);        0.0002595 sec
Z = dot(X,Y);         0.0003627 sec

因此,对于大约 10,000 个元素的矩阵,使用SUM代替DOT可以将该操作的执行时间减少约 28%。矩阵越大,这两种方法之间的差异就越小。

总而言之,如果这种计算代表了代码运行速度的重大瓶颈,我会使用SUM的解决方案。否则,任何一种解决方案都应该没问题。

于 2010-04-02T20:24:23.403 回答
1

为了完整起见,gnovice 在 Scilab 中的回答是

z = sum(X .* Y, 1)'
于 2010-04-02T22:52:25.100 回答