Apply function on several matrices without for loop
Show older comments
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.
Guillaume
on 9 Oct 2017
@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 --
Matt J
on 9 Oct 2017
@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.
Guillaume
on 9 Oct 2017
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
Find more on Creating and Concatenating Matrices in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!