我有以下情况:
Y(i) - m x 1 vecotr , i = 1,...,N
A(i) - m x m symmetric matrix , i = 1,...,N
H(i,j) = 0.5*(Y(i)-Y(j))'( A(i)^-1+A(j)^-1)(Y(i)-Y(j)) |i,j = 1,...,N
目前我分别计算A(i)的倒数,H计算两个'for'循环:
for i= 1:N
A_inv(:,:,i) = inv(A(:,:,i));
end
H= zeros(N,N);
for j=1:N
for i=(j+1):N
x = Y(:,1,j)-Y(:,1,i);
H(j,i) = 0.5*(x'*(A_inv(:,:,i)+A_inv(:,:,j))*x);
H(i,j) = H(j,i);
end
end
我还没有找到优化代码的方法,我在论坛中看到的答案是针对A是常量而不依赖于索引的情况。 有更有效的计算方法吗?
答案 0 :(得分:0)
我不知道涉及的是什么尺寸,但是下面的方法几乎总是更快更准确,因为它不需要矩阵求逆(这应该总是尽量避免):
clearvars
% Build sample inputs
N = 100;
m = 500;
Y = randn(m, 1, N);
for i = N:-1:1
t = randn(m);
A(:,:,i) = t' * t;
end
% original method
tic
for i= 1:N
A_inv(:,:,i) = inv(A(:,:,i));
end
H= zeros(N,N);
for j=1:N
for i=(j+1):N
x = Y(:,1,j)-Y(:,1,i);
H(j,i) = 0.5*(x'*(A_inv(:,:,i)+A_inv(:,:,j))*x);
H(i,j) = H(j,i);
end
end
toc
H_old = H;
clear A_inv H x
% proposed method
tic
for i = N:-1:1
Ai_invY = A(:,:,i) \ Y(:,:);
H(i,:) = Y(:,i)' * Ai_invY(:,i) ... % Yi' * Ai_inv * Yi
- 2 * Y(:,i)' * Ai_invY ... % - Yi' * Ai_inv * Yj - Yj' * Ai_inv * Yi
+ sum(Y(:,:) .* Ai_invY, 1); % + Yj' * Ai_inv * Yj
end
H = (H + H')/2;
toc
% check difference
plot(H_old(:) - H(:))
在我的笔记本电脑中,原始方法的时间为10.3秒,建议的时间为0.44秒。