在 matlab 中替代 diag(X'*C*X)

Alternative to diag(X'*C*X) in matlab

考虑一个 N x 1 向量 x 和一个 N x N 矩阵 C。我想评估

 s = x'*C*x;

在 matlab 中对向量 x 进行多次采样,例如将 x 的 M 个样本视为 N x M 矩阵 X;这可以使用

来完成
S = diag(X'*C*X);

但这是一个糟糕的解决方案,因为在此过程中分配了 M x M 矩阵,并且当 M>1e5 时会中断。是否有一些 matlab 功能可以建议替代方案?

一点 permute-ing and bsxfun-ing 就可以了。但是请注意,这需要一个大小为 N*N×M 的中间矩阵。如果 NM 小,这将是可行的(并且相当快)。否则你可能需要求助于使用循环。

T = reshape(bsxfun(@times, permute(conj(X), [1 3 2]), permute(X, [3 1 2])), [], M);
S = sum(bsxfun(@times, C(:), T), 1).';

示例:

M = 5;
N = 6;
C = rand(N,N) + 1j*rand(N,N);
X = rand(N,M) + 1j*rand(N,M);
T = reshape(bsxfun(@times, permute(conj(X), [1 3 2]), permute(X, [3 1 2])), [], M);
S = sum(bsxfun(@times, C(:), T), 1).';
S_check = diag(X'*C*X);
S./S_check % may not be exactly equal due to numerical accuracy

给予

>> S./S_check
ans =
  1.000000000000000 + 0.000000000000000i
  1.000000000000000 - 0.000000000000000i
  1.000000000000000 - 0.000000000000000i
  1.000000000000000 + 0.000000000000000i
  1.000000000000000 + 0.000000000000000i

执行右矩阵乘法C*X,然后执行元素乘积,这样就不会进行不需要的操作:

S = sum(X.*(C*X),1)';

如果你的矩阵是复值的,你还需要共轭:

S = sum(conj(X).*(C*X),1).';