【问题标题】:How to vectorize the evaluation of a quadratic form (x' * A * x)?如何向量化二次形式(x' * A * x)的评估?
【发布时间】:2015-02-17 18:12:25
【问题描述】:

如果我有一个矩阵 A,并且我想针对 x 的多个值评估 x' * A * x,我该如何对其进行向量化?

(我可以做X' * A * X 并取对角线,但这显然效率低下。)

【问题讨论】:

  • 每个x 都是一个列向量,对吧?

标签: matlab matrix vectorization


【解决方案1】:

一种思考方式是,您试图在X 中的向量和AX 中的向量之间获取一堆点积。 Matlab 有一个功能:

N = 10; % number of x's
M = 100; % length of x's
X = rand(M,N);
A = rand(M, M);

% way 1
way1 = diag(X' * A * X);

% way 2
way2 = dot(X, A*X)';

% compare
[way1 way2]

【讨论】:

  • 啊,好吧。我有点希望有一个更优雅的解决方案,可以让我将其保留为矩阵乘法,但似乎可能没有。无论如何谢谢!
  • 这不是真的低效吗?它计算的操作至少比需要的多 n**2 次。没有更好的办法吗?
  • @FarhoodET 你说的是方式 1 还是方式 2?
【解决方案2】:

这个怎么样?

sum((A*X).*X,1)

或者,如果您正在处理复杂的值,

sum((A*X).*conj(X),1)

检查:

>> A = rand(4,4);
>> X = rand(4,3);
>> sum((A*X).*X,1)
ans =
    5.4755    2.6205    3.4803
>> diag(X'*A*X)
ans =
    5.4755
    2.6205
    3.4803

【讨论】:

  • 等同于接受答案中的dot( X, A*X )
【解决方案3】:

这可能是一种方法,但不确定这是否比基于 direct matrix multiplication + diag 的方法更有效 -

%// Perform X'*A equivalent multiplication
mult1 = bsxfun(@times,permute(X,[1 3 2]),A)

%// Perform rest of the equivalent multiplication
mult2 = bsxfun(@times,mult1,permute(X,[3 1 2]))

%// Perform the summations required to reduce to desired output's size
out = sum(reshape(mult2,[],size(X,2)),1)

你可以重新安排一下乘法 -

mult1  = bsxfun(@times,permute(X,[1 3 2]),permute(X,[3 1 2]))
mult2 = bsxfun(@times,mult1,A)
out = sum(reshape(mult2,[],size(X,2)),1)

或者将结尾的bsxfun(@timessum 合并为更简化、可能更高效的版本-

mult1  = bsxfun(@times,permute(X,[1 3 2]),permute(X,[3 1 2]))
out = reshape(permute(mult1,[3 1 2]),size(X,2),[])*A(:)

或者进一步简化它,使其成为使用最少工具并且可能是最高效的单线器! -

out = reshape(bsxfun(@times,X.',permute(X,[2 3 1])),[],numel(A))*A(:)

【讨论】:

    猜你喜欢
    • 2012-01-17
    • 2016-12-04
    • 1970-01-01
    • 1970-01-01
    • 2021-03-15
    • 2011-11-08
    • 1970-01-01
    • 2015-08-30
    • 2021-09-13
    相关资源
    最近更新 更多