2
votes

I have a function as follows:

Function

My optimized matlab code is:

function gamma = calcGamma(H, d, delta, f)

s= size(H);
Nv = s(1);
Ne = s(2);
gamma = zeros(Ne,1);

for e =1:Ne

    hue = H(:,e);
    sdu=f./sqrt(d);

    mHUE = repmat(hue',Nv,1);
    mHVE = repmat(hue,1,Nv);
    mSDU = repmat(sdu',Nv,1);
    mSd = repmat(sdu,1,Nv);

   ss1 =  mHUE .* mHVE/delta(e) .* (mSDU-mSd).^2;
   gamma(e) = sum(ss1(:));
end

However, since Ne is very big, it takes quite a long time to calculate the function.

I see an similar question with a good solution, but I do not understand how it is derived.

enter image description here

Any solution to avoid the for-loop? Thanks

1
What are the typical sizes of H, d, gamma and f? And is the difference between gamma and gama intentional? - Bas Swinckels
the size of H is about 10,000*2,000, d and f is about 10,000*1,gamma is 2,000. the parameter of gamma should be delta, I am sorry about that. - xueliang liu

1 Answers

1
votes

I am not sure if this will be faster, but instead of your trick with repmat, you can use bsxfun. This trick is pretty similar to the array broadcasting that is standard in numpy and saves the creation of the large intermediate matrices like mHUE.

Another thing you should always do is to move everything out of the loop that does not depend on e. It seems to me that the calculation of sdu is totally constant, so do that once before the loop. And I guess that delta(e) is a scalar, so instead of dividing the big matrices by that, do it once afterwards:

s= size(H);
Nv = s(1);
Ne = s(2);
gamma = zeros(Ne,1);

sdu = f./sqrt(d);
M = bsxfun(@minus, sdu', sdu).^2;

for e =1:Ne
    hue = H(:,e);
    ss1 =  bsxfun(@times, hue', hue) .* M;
    gamma(e) = sum(ss1(:));
end
gamma = gamma ./ delta;

It might be possible to remove the for-loop, but it is doubtful that that will increase speed, since you have just a single loop and your calculation time is anyhow dominated by the multiplication of the big matrices. Moreover, removing the for-loop will just make your function very hard to understand, so just leave it as is.