如何对二次形式的评估进行矢量化(x' * A * x)?

时间:2015-02-17 18:12:25

标签: matlab matrix vectorization

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

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

3 个答案:

答案 0 :(得分:8)

考虑它的一种方法是,你试图在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]

答案 1 :(得分: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(:)

答案 2 :(得分:3)

这个怎么样?

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