2
votes

I have a KxLxM matrix A which is an image with a feature vector, length M, for each pixel location. I have also have a feature vector v, length M. At each pixel location of image A i want to calculate the correlation of the pixel's feature vector with my feature vector v.

I've already done this using a loop, but loops are slow in matlab. Does anyone have a suggestion of how to vectorize this?

function test()
A = rand(4,5,3);
v = [1 2 3];
c = somecorr(A, v);
size(c)

function c = somecorr(a,v)
c = a(:,:,1).*0;
for y = 1:size(a,1)
    for x = 1:size(a,2)
        c(y,x) = corr2(squeeze(a(y,x,1:length(v)))',v);
    end
end

>>test()
ans =

 4     5
1
I think it used to be the case that loops in matlab were slow. But nowadays due to the power of Just In Time compilation it is no longer necessarily true. linksietschie

1 Answers

2
votes

You could try this and see, if its faster:

function c = somecorr2(a,v)

    as = reshape(a,size(a,1)*size(a,2),size(a,3));
    cs = corr(as',v');
    c = reshape(cs,size(a,1),size(a,2));
    size(c)

I only did some small tests, but it seems to be more than 100x faster. At least for my test cases.

If you do not have the 'corr' function you can use this on, inspired by this [answer]( What is a fast way to compute column by column correlation in matlab):

function C = manualCorr(A,B)
    An=bsxfun(@minus,A,mean(A,1)); %%% zero-mean
    Bn=bsxfun(@minus,B,mean(B,1)); %%% zero-mean
    An=bsxfun(@times,An,1./sqrt(sum(An.^2,1))); %% L2-normalization
    Bn=bsxfun(@times,Bn,1./sqrt(sum(Bn.^2,1))); %% L2-normalization
    C=sum(An.*repmat(Bn,1,size(An,2)),1); %% correlation

For a 100x100x3 matrix I get the following runtimes:

Your version: 1.643065 seconds. mine with 'corr': 0.007191 seconds. mine with 'manualCorr': 0.006206 seconds.

I was using Matlab R2012a.