matlab中二次型的快速计算

时间:2016-04-13 08:00:47

标签: performance matlab quadratic

我有以下情况:

    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是常量而不依赖于索引的情况。 有更有效的计算方法吗?

1 个答案:

答案 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秒。