xueliang liu
xueliang liu

Reputation: 556

Avoiding for-loops in Matlab

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

Upvotes: 2

Views: 179

Answers (1)

Bas Swinckels
Bas Swinckels

Reputation: 18488

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.

Upvotes: 1

Related Questions