4

假设我有一个N-by-K矩阵AN-by-P矩阵B。我想做以下计算来得到我的最终N-by-P矩阵X

X(n,p) = B(n,p) - dot(gamma(p,:),A(n,:))

在哪里

gamma(p,k) = dot(A(:,k),B(:,p))/sum( A(:,k).^2 )

在 MATLAB 中,我的代码如下

for p = 1:P
    for n = 1:N
        for k = 1:K
            gamma(p,k) = dot(A(:,k),B(:,p))/sum(A(:,k).^2);
        end
        x(n,p) = B(n,p) - dot(gamma(p,:),A(n,:));
    end
end

这是非常低效的,因为它使用三个 for 循环!有没有加快这段代码的好方法?

4

3 回答 3

4

在我看来,您可以将伽马计算提升到循环之外;至少,我在伽玛计算中看不到对 N 的任何依赖。

所以是这样的:

for p = 1:P
    for k = 1:K
        gamma(p,k) = dot(A(:,k),B(:,p))/sum(A(:,k).^2);
    end
end
for p = 1:P
    for n = 1:N
        x(n,p) = B(n,p) - dot(gamma(p,:),A(n,:));
    end
end

我对您的代码(或 matlab)不够熟悉,无法真正知道您是否可以合并两个循环,但如果可以的话:

for p = 1:P
    for k = 1:K
        gamma(p,k) = dot(A(:,k),B(:,p))/sum(A(:,k).^2);
    end
    for n = 1:N
        x(n,p) = B(n,p) - dot(gamma(p,:),A(n,:));
    end
end
于 2013-10-21T21:28:48.603 回答
4

用于bsxfun循环的除法和矩阵乘法:

gamma = bsxfun(@rdivide, B.'*A, sum(A.^2));
x = B - A*gamma.';

这是一个测试脚本

N = 3;
K = 4;
P = 5;

A = rand(N, K);
B = rand(N, P);

for p = 1:P
    for n = 1:N
        for k = 1:K
            gamma(p,k) = dot(A(:,k),B(:,p))/sum(A(:,k).^2);
        end
        x(n,p) = B(n,p) - dot(gamma(p,:),A(n,:));
    end
end

gamma2 = bsxfun(@rdivide, B.'*A, sum(A.^2));
X2 = B - A*gamma2.';

isequal(x, X2)
isequal(gamma, gamma2)

返回

ans =
     1
ans =
     1
于 2013-10-21T21:30:25.833 回答
0

bxfun 很慢......像下面这样的东西怎么样(我可能有一个转置错误)

modA = A * (1./sum(A.^2,2)) * ones(1,k);
gamma = B' * modA;
x = B - A * gamma';
于 2014-05-24T22:27:08.263 回答