# 3D array of rotation matrices multiplied on 2D array of vectors

13 views (last 30 days)
Morten Nissov on 21 Apr 2021
Commented: Morten Nissov on 22 Apr 2021
As the title says I have two matrices, rotmats and acc. For this example suppose that acc is a vector of {n} frame accelerations of size 100x3, so 100 3-vectors of acceleraetions.
For each 3-vector I have a corresponding quaterion quat which I need to apply to transform the acceleration from {n} to {b} frame. taking rotmat(quat, 'point') returns a 3x3x100 array of rotation matrices from {b} to {n}, I couldn't find a way to elementwise transpose the pages, but using rotmat(quat ,'frame') happens to return a 3x3x100 array of rotation matrices, each of which are the transpose of the corresponding matrix produced by rotmat(quat, 'point').
So, with this in mind, I would like to rotate acc according to these quaternions. I figured as easy way to do this would be
rotmats = rotmat(quat, 'frame');
acc_b = rotmats * acc_n;
but this returns an error. Using pagemtimes doens't seem to be an option either as only one of the arrays has "pages".
In short: I am trying to take two arrays like
A = rand(3,3,10);
B = rand(10,3);
and compute a multiplication equivalent to
C = nan(size(B)); % result container
for i=1:size(A,3)
C(i,:) = (A(:,:,i) * B(i,:)')';
end
but I would like to avoid for-loops for speed.
edit: forgot a transpose
##### 2 CommentsShowHide 1 older comment
Morten Nissov on 21 Apr 2021
Yeah sorry I realized as well I had made a typo. I tried to edit the last code to reflect this.

Matt J on 21 Apr 2021
Edited: Matt J on 21 Apr 2021
C=pagemtimes(A, reshape(B.',3,1,[]) );
C=reshape(C,3,[]).';

James Tursa on 21 Apr 2021
Edited: James Tursa on 21 Apr 2021
To answer your side question of how to transpose 2D pages of an array, you can use the permute function to swap the first two dimensions. E.g., to transpose the first 2D slices of a 3D array:
A_transpose = permute(A,[2 1 3]);
To use the quaternions directly with the vectors without converting to rotation matrices first, you can use the quatrotate() function from the Aerospace Toolbox. E.g., assuming your quaternions are in an Mx4 matrix and your acceleration vectors are in an Mx3 matrix:
a_b = quatrotate(Q,a_n);
If that does the opposite of what you want because your quaternion convention is left chain instead of right chain, then you can conjugate the quaternions first:
a_b = quatrotate(quatconj(Q),a_n);
If you don't have the Aerospace Toolbox, you can write manual code for this, an example of which you can find here:
You might also be interested in this post about the 'frame' and 'point' conventions:
Morten Nissov on 22 Apr 2021
Okay I see this can very quickly become confusing. To make it even more confusing I'm not even using the robotics nor aerospace toolbox, but instead the sensor fusion variant. As far as I can see it follows the same conventions of the aerospace set.