Apply function on several matrices without for loop

Hi all,
I have hundred 3x3 rotation matrices stored in a 100x9 matrix. I would like to compute the corresponding rotation vectors using the Rodrigues convention. The desired output would be a 100x3 matrix.
Currently, I have written a function with a for loop that reads the 9 parameters of each rotation matrix line by line and fills in the corresponding rotation vector line by line.
function [rot_vectors] = rotationMatricesToVectors(rot_matrices)
nb_rotations = size(rot_matrices,1);
rot_vectors = zeros(nb_rotations,3);
for i = 1:nb_rotations
R = [...
rot_matrices(i,1) rot_matrices(i,2) rot_matrices(i,3);
rot_matrices(i,4) rot_matrices(i,5) rot_matrices(i,6);
rot_matrices(i,7) rot_matrices(i,8) rot_matrices(i,9)];
rot_vectors(i,:) = rotationMatrixToVector(R);
end
end
I was wondering if there is a more elegant way to write this function, in particular to avoid the for loop.
Thank you!
Guillaume

4 Comments

Slightly better:
Rstack=reshape(rot_matrices.',3,3,[]);
for i = 1:nb_rotations
rot_vectors(i,:) = rotationMatrixToVector(Rstack(:,:,i));
end
However, for further optimization, you need to show us what rotationMatrixToVector() is doing.
@Matt, you're missing a final transpose/permute due to the unconventional linear indexing used. Either:
Rstack = permute(reshape(rot_matrices.',3,3,[]), [2 1 3]);
or
rot_vectors(i,:) = rotationMatrixToVector(Rstack(:,:,i).');
@Guillaume, matlab indexing is such that indices go down column first. It would be better if you respected that convention and thus stored your matrices in the order
[(i,1) (i,4) (i,7)
(i,2) (i,5) (i,8)
(i,3) (i,6) (i,9)]
This would significantly speed up the processing. At the moment, your code (or Matt's) does a lot of transposing. That's a slow operation as matlab needs to completely rewrite a new matrix. Storing your rotation matrices as above and actually storing them as a 9x100 would mean that only reshape operations are needed. These are near instantaneous.
-- Another Guillaume --
@Guillaume2,
Good point, although I don't think the transposition should matter, ultimately. The rotation axes are the same both for a rotation matrix R and its transpose.
Hi Matt, Guillaume,
Thanks for the comments! As you suggested, I am going to change the indexing (column by column instead of row by row).
rotationMatrixToVector is actually a built-in function:
https://fr.mathworks.com/help/vision/ref/rotationmatrixtovector.html

Sign in to comment.

Answers (1)

I doubt this will be faster than a for loop, but it does get rid of it.
function [rot_vectors] = rotationMatricesToVectors(rot_matrices)
nb_rotations = size(rot_matrices,1);
Rstack=reshape(rot_matrices.',3,3,[]);
K=kron(speye(nb_rotations),ones(3));
K(K>0)=Rstack(:);
[v,~]=eigs(K,1);
rot_vectors=reshape(v,3,[]).';

Categories

Asked:

on 9 Oct 2017

Commented:

on 9 Oct 2017

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!