0
votes

I'm writing a piece of MATLAB code at the moment and for efficiency reasons I need to replace the for loop with matrix computation, which obviously MATLAB is really great for. But for the life of me I can't quite work it out. Any help would be appreciated.

So my code is:

for i = 1:N
    k1(i) = k1(i) + betas(i, :)*(xn-xn(i));
end

Where N is an integer, k1 and xn are column vectors size [N 1], and betas is a square matrix size [N N].

So that for N = 2,

k1(1) = k1(1) + beta11*(x1-x1) + beta12*(x2-x1)

k1(2) = k1(2) + beta21*(x1-x2) + beta22*(x2-x2)

Obviously some of the terms reduce to zero but I wrote them out for clarity's sake.

I have tried simple matrix multiplication but I can't work out what form the x matrix would have to be in. I have also tried using the following form:

xmat = repmat(xn, N, 1);
k1 = k1 + sum((betas.*(xmat - xmat.')), 2);

Which I am fairly convinced does the same thing but takes even longer (I have a sneaky suspicion that these functions just implement more for loops).

If you have any ideas let me know.

1
Every matrix operation uses loops. A matrix multiplication has 3 nested loops. Not sure why you think they don’t. Then there is the idea that loops in MATLAB are slow, so we want to defer them to compiled code. That was true 15 years ago. What is really slow is memory access, especially if matrices are larger than the cache. repmat creates a large matrix, and hence is expensive. You can actually do xn-xn.' directly, without repmat. Should be significantly faster. But you still create a large intermediate array that you don’t have in your loop code, so might still be slower. Not sure. - Cris Luengo

1 Answers

0
votes

Here is a vectorized version, that I think performs better than your version, because it doesn't create an intermediate [N x N] array.

k1 = k1 + betas * xn - sum(betas, 2) .* xn;