如果我有一个矩阵A
并且我想为x' * A * x
的多个值评估x
,我该如何对其进行矢量化?
(我可以做X' * A * X
并采取对角线,但这显然效率低下。)
答案 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(@times
和sum
合并为更简化,更高效的版本 -
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