Asked by nah
on 20 Sep 2013

How to vectorize a for loop but with conditionals in it ?

[sizMat1 sizMat2] = size(matrixToMultiply);

cumulMatProduct = ones(sizMat1,1); %stores the cumulative Products of chosen Matrices. %gets updated at every iteration

for ix = 2:length(col1)

% Depending on if the value is either 0 or 1, pick a matrix; if (col1(ix) == 0 ) cumulProduct = simpleMatrix0 * cumulMatrixProduct; matrixToMultiply = matrix1;

elseif (col1(ix) == 1 ) matrixToMultiply = matrix2; end

anotherMatrixtoMultiply = diag( exp(constantMatrix) * col2(ix) ); % Another Matrix is created by multiplying a scalar %(picked from the same index ix of a different column col2 having same dimensions as col1)

cumulMatrixProduct = matrixToMultiply*anotherMatrixtoMultiply*cumulMatrixProduct;

end

Answer by Jan Simon
on 20 Sep 2013

Edited by Jan Simon
on 21 Sep 2013

I assume that the bottleneck of your code is: `exp(constantMatrix)`, because `exp()` is very expensive. So move this calculation out of the loops:

expConstantMatrix = exp(constantMatrix); for ix = 2:length(col1) ... anotherMatrixtoMultiply = diag( expConstantMatrix * col2(ix) );

Is this really wanted:

if (col1(ix) == 0 ) ... elseif (col1(ix) == 1 ) ... end

Or do you mean

if col1(ix) == 0 ... else ... end

This might be the same in a standard case, but it is prone to bugs to add an `elseif` without an `else`.

[EDITED] Some tests show that this is faster:

anotherVectortoMultiply = expConstantMatrix * col2(ix); cumulMatrixProduct = matrixToMultiply * bsxfun(@times, anotherVectortoMultiply, cumulMatrixProduct);

nah
on 24 Sep 2013

Opportunities for recent engineering grads.

## 5 Comments

## Azzi Abdelmalek (view profile)

Direct link to this comment:http://www.mathworks.com/matlabcentral/answers/87765#comment_170078

Is this a complete code?

## nah (view profile)

Direct link to this comment:http://www.mathworks.com/matlabcentral/answers/87765#comment_170084

Yes, almost. I could add:

## Jan Simon (view profile)

Direct link to this comment:http://www.mathworks.com/matlabcentral/answers/87765#comment_170092

@nah: Vectorizing is not trivial. Inserting a bug by a typo is as easy and suggesting a method is is much slower than the original version due to the need of huge temporary arrays. Therefore questions about improving the speed require testdata, e.g. created by rand() if this is meaningful, such that we can run and test our ideas before posting.

Should we add this:

## Jan Simon (view profile)

Direct link to this comment:http://www.mathworks.com/matlabcentral/answers/87765#comment_170097

@Readers: Is there a

fasterwas to calculateA * diag(x) * B? I cannot test ifA * bsxfun(@times, x, B)is faster than the BLAS librarie's DGEMM with the full matrix.## nah (view profile)

Direct link to this comment:http://www.mathworks.com/matlabcentral/answers/87765#comment_170408

Yes, the above test Data with rand should work. If needed, I can post my data as well (possibly by email or git )