假设我有一个N-by-K
矩阵A
,N-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循环!有没有一种加速这段代码的好方法?
答案 0 :(得分: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
答案 1 :(得分: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
答案 2 :(得分:0)
bxfun很慢...... 如下所示(我可能有错误的转置)
modA = A * (1./sum(A.^2,2)) * ones(1,k);
gamma = B' * modA;
x = B - A * gamma';