Dot product of 3x3 rotation matrix and column vector?

Hi all,

I was wondering if there is a simple way of doing the following. I have a 3x3 rotation matrix and a column vector and need to find the dot product. Going by the notation used on the wikipedia page for this operation http://en.wikipedia.org/wiki/Dot_product#Rotation , this amounts to forming each of the three elements of the output matrix by multiplying each row of the rotation matrix by the transpose of the column vector (am I correct in this?). First problem: it gives the matrix dimensions mismatch error when I try to do:  MatrixOP/O out = row(0,Rotation_Matrix).vector^t when the rotation matrix is 3x3 and the transposed column vector should give a 3 element row vector, why is this? Second problem is that using this approach I would perform this three times, multiplying the rows 0,1,2 of the rotation matrix by the row vector to get three scalars and then construct my output column vector from these three elements. This seems a bit long-winded, especially as I need to repeat this whole process for three individual column vectors.

As an aside, apologies for asking about the maths rather than the programming, but if I have these three column vectors, representing vectors in three dimensions and want to find the individual dot product of each vector with the rotation matrix, is this the same as constructing a 3x3 matrix of the three vectors, where each column is from the vector and then performing the dot product calculation with the rotation matrix?

I hope that was clear enough but I'll try and explain more thoroughly if not. If anyone has access to Journal of Applied Crystallography and wants to know specifically what I am doing, see this paper http://scripts.iucr.org/cgi-bin/paper?cg5056 , (surface X-ray diffraction) I am rotating the 3 reciprocal lattice vectors of a crystal by a rotation matrix in order to orient the crystal relative to a surface using a known (hkl) reflection.

Best, Tom
UPDATE: I have realised that the dimension mismatch error came from wrong syntax in the row operation, it should have read row(Rotation_matrix,0) instead of the other way round. This works and returns a scalar so I am looking to reduce the number of steps in doing this. Any help would be welcome.
Thomas.Dane wrote:
As an aside, apologies for asking about the maths rather than the programming, but if I have these three column vectors, representing vectors in three dimensions and want to find the individual dot product of each vector with the rotation matrix, is this the same as constructing a 3x3 matrix of the three vectors, where each column is from the vector and then performing the dot product calculation with the rotation matrix?


Each vector of your reciprocal lattice is a 3x1 column. The rotation operation is a 3x3 matrix. The order of the math is (3x3) .dot. (3x1) = (3x1). This says, each column vector (reciprocal lattice vector) operated on by the rotation matrix gives a new column vector (reciprocal lattice vector).

When you have a set of N column vectors (reciprocal lattice vectors), you can generate a (3xN) matrix. Then, (3x3) .dot. (3xN) = (3xN). Each column in the (3xN) matrix is the new reciprocal lattice vector of its corresponding column in the original matrix.

See this link for an example ... http://en.wikipedia.org/wiki/Matrix_multiplication

Hope this answers what you are asking.

--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAHuntsville
jjweimer wrote:
When you have a set of N column vectors (reciprocal lattice vectors), you can generate a (3xN) matrix. Then, (3x3) .dot. (3xN) = (3xN). Each column in the (3xN) matrix is the new reciprocal lattice vector of its corresponding column in the original matrix.


This is true of matrix multiplication but not the dot product. The dot product of two matrices with the same dimensions is a scalar, a single number. In Igor, where "reciprocal" and "rotation_matrix" are both (3x3) doing MatrixOP/O Reciprocal_rotated = Rotation_matrix.reciprocal returns a wave with one point. Using the " x " operator instead of "." will return as you say above, however, the paper explicitly says A*'= R.A* where A* is a column vector. Whilst Igor will give a dimension mismatch error if you try and get the dot product of matrices with different dimensions the wiki page I posted above explains how it is possible, specifically:

Quote:
When an orthonormal basis that the vector a is represented in terms of is rotated, a's matrix in the new basis is obtained through multiplying a by a rotation matrix R. This matrix multiplication is just a compact representation of a sequence of dot products.


I have done this sequentially in Igor in the following way:
MatrixOP/O temp1 = row(Rotation_Matrix,0).rec_vect_a^t
MatrixOP/O temp2 = row(Rotation_Matrix,1).rec_vect_a^t
MatrixOP/O temp3 = row(Rotation_Matrix,2).rec_vect_a^t
Concatenate/O/NP=0 {temp1,temp2,temp3}, rec_vect_aR


But was wondering if there is a more elegant way as I repeat the above code 3 times.
I think this gets you there - I am not sure if it is more elegant, but it is definitely harder to follow.

Make/D/O/N = (3) ones = 1
MatrixOp/O rec_vect_aR =  (DiagRC(rec_vect_a,3,3) x Rotation_Matrix)^t x ones
Thomas.Dane wrote:
This is true of matrix multiplication but not the dot product. ..


Oh, I see. Somehow my memory was that rotation operations were simple matrix multiplications of the column vector containing the coordinates of the end points of the vector from zero. I must be thinking of a special case.
Quote:
When an orthonormal basis that the vector a is represented in terms of is rotated, a's matrix in the new basis is obtained through multiplying a by a rotation matrix R. This matrix multiplication is just a compact representation of a sequence of dot products.

I have done this sequentially in Igor in the following way:
MatrixOP/O temp1 = row(Rotation_Matrix,0).rec_vect_a^t
MatrixOP/O temp2 = row(Rotation_Matrix,1).rec_vect_a^t
MatrixOP/O temp3 = row(Rotation_Matrix,2).rec_vect_a^t
Concatenate/O/NP=0 {temp1,temp2,temp3}, rec_vect_aR


But was wondering if there is a more elegant way as I repeat the above code 3 times.


I have not read the paper in question so restricting myself to your code quoted here, I think you got the correct response earlier, i.e., the code that you wrote above is essentially matrix multiplication, which is also the standard way of handling rotation. Here is an example:

Make/o/n=3 rec_vect_a={1,2,3}
make/o/n=(3,3) Rotation_Matrix=enoise(1)  // just for illustration; not real rotation mat!
MatrixOP/O temp1 = row(Rotation_Matrix,0).rec_vect_a^t
MatrixOP/O temp2 = row(Rotation_Matrix,1).rec_vect_a^t
MatrixOP/O temp3 = row(Rotation_Matrix,2).rec_vect_a^t
Concatenate/O/NP=0 {temp1,temp2,temp3}, rec_vect_aR
MatrixOP/O aa=sum(abs((Rotation_Matrix x rec_vect_a)-rec_vect_aR))
print aa[0]


As you can see, in SP there is no difference between your method and matrix multiplication.

AG