Apply function on several matrices without for loop
Afficher commentaires plus anciens
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 commentaires
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
le 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
le 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
le 9 Oct 2017
Réponses (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,[]).';
Catégories
En savoir plus sur Creating and Concatenating Matrices dans Centre d'aide et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!