Linear algebra examples
For the last part of this chapter we will work through two practical examples which use
some of the ideas discussed above.
Rotation matrices
Often we want to consider transformations that move and reorient coordinates but still
preserve their shape, i.e. the positions of the coordinates relative to one another. An
example of this, which will be discussed further in later chapters, is transformations on
complete molecular structures, in which case we are interested in the coordinate positions
of the atoms that make up the molecule. Although in some situations we may want to
move specific atoms to generate new molecular shapes, often we don’t want to distort the
precious (experimentally determined) data and merely wish to reposition the molecule.
There can be many reasons for moving a molecule’s coordinates, a few of which include:
creating a view to make a graphical representation; setting up a system for energy
calculations and dynamic simulations; superimposing structures to find where
conformations differ. Whatever the reason, a commonly required operation is rotation, a
kind of coordinate transformation that can be described by a rotation matrix.
The simplest rotations to consider are those that rotate about one of the three coordinate
axes. First, consider rotation by an angle A (specified in radians) about the z axis. The unit
vector along the z axis, (0, 0, 1) would not be affected by this rotation because it lies
exactly along the direction which we rotate around; effectively it gets transformed to itself.
For the same rotation, the unit vector along the x axis, (1, 0, 0), would naturally be altered
according to the sine and cosine of the angle; it moves away from a pure x direction to
gain a y component, specifically transformed to (cos A, sin A, 0).
10
Similarly, the unit
vector along the y axis, (0, 1, 0), moves to gain an x component and is transformed to
(−sin A, cos A, 0). Thus, combining the transformations for the individual axis vectors, the
rotation by an angle A about the z axis is given by the matrix:
Note that this indeed transforms things correctly, for example:
A rotation by an angle A about the x axis is similarly given by the matrix
And a rotation by an angle A about the y axis is given by the matrix
It turns out that all rotations, about any direction, can be composed of products of rotations
about the main axes, although this does not necessarily help. The formula for the rotation
about an arbitrary direction, n (a unit length axis of rotation), by an angle A is much more
complicated, and we won’t describe it in fine detail. It turns out that it is easiest to define it
by how it acts on an arbitrary vector w:
R
n,A
w = ( w
⋅ n) n + (cos A) ( w − ( w ⋅ n) n) + (sin A) n ∧ w
Here w
⋅ n is the sum of the element-wise product (also called the inner product or dot
product) of the two vectors, and n
∧ w is what is known as the cross-product.
11
The term
w − ( w
⋅ n)n can be thought of as representing the projection of the vector w along the axis
of rotation n. This component of the vector is not affected by the rotation, but the
remaining component is, hence the sine and cosine terms. Thinking in terms of two
vectors we can explicitly represent the calculations involved in generating the dot product
(a single number) and cross-product (another vector), although if you were doing this in
earnest you would use the dot() and cross() functions in NumPy:
vec1 = (x1, y1, z1)
vec2 = (x2, y2, z2)
dotProduct = x1*x2 + y1*y2 + z1*z2
crossProduct = (y1*z2-z1*y2, z1*x2-x1*z2, x1*y2-y1*x2)
Combining the expression for rotation about an arbitrary axis with the knowledge of
how to calculate dot and cross-products we can derive the following function to generate a
rotation matrix in Python. It takes an axis direction (specified as a vector, not necessarily
of unit length) and an angle (in radians) to define a rotation matrix that will perform the
required rotation operation, via matrix multiplication.
Note how the example makes use of the sin and cos trigonometric functions and the
square root function from the math module. We will not go through the mathematical
details, but you can see what the construction of the matrix involves: dividing the input
axis by its length to generate an axis vector of unit length; calculating variables for sine
and cosine of the angle, to avoid repeated calculation; and construction of the final
rotation matrix using the required expressions, involving the angle-derived variables and
axis coordinates.
import math
def getRotationMatrix(axis, angle):
vLen = math.sqrt( sum([xyz*xyz for xyz in axis]) )
x, y, z = [xyz/vLen for xyz in axis]
c = math.cos(angle)
d = 1-c
s = math.sin(angle)
R = [[c+d*x*x, d*x*y-s*z, d*x*z+s*y],
[d*y*x+s*z, c+d*y*y, d*y*z-s*x],
[d*z*x-s*y, d*z*y+s*x, c+d*z*z ]]
return R
Note that this does not use NumPy and what is returned is an ordinary Python list of
lists, but it can be converted using numpy.array(), if desired. For example, in the following
we get a NumPy array of the rotation matrix representing rotation by 60 degrees around
the axis (1, 1, 1) so that its transformation can be applied by matrix multiplication using
the dot() function:
import math
axis = (1, 1, 1)
angle = math.radians(60) # convert from degrees to radians
rotMatrix = numpy.array(getRotationMatrix(axis, angle))
vector1 = numpy.array([2, -1, -1]) # A test vector
vector2 = rotMatrix.dot(vector1) # [1, 1, -2]
The axis could be passed in as a NumPy vector rather than an ordinary Python vector;
the function works in either case.
Do'stlaringiz bilan baham: |