Using matrix structure to speed up Matlab

Suppose I have a matrix N-by-K A, N-by-Pmatrix B. I want to do the following calculations to get the final matrix N-by-P X.

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

Where

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

In MATLAB, I have my code like

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

which are very inefficient because they use three for loops! Is there a way to speed up this code?

+4
source share
3 answers

Use bsxfunto divide and multiply matrices for loops:

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

And here is the test script

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)

which returns

ans =
     1
ans =
     1
+4
source

, - ; , 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
+4

bxfun is slow ... How about something like the following (I may have the wrong transpose)

modA = A * (1./sum(A.^2,2)) * ones(1,k);
gamma = B' * modA;
x = B - A * gamma';
0
source

All Articles