Author: bugman Date: Tue Sep 8 16:40:16 2009 New Revision: 9476 URL: http://svn.gna.org/viewcvs/relax?rev=9476&view=rev Log: Created 3 unit tests of the maths_fns.rotation_matrix.quaternion_to_R() function. Modified: 1.3/test_suite/unit_tests/_maths_fns/test_rotation_matrix.py Modified: 1.3/test_suite/unit_tests/_maths_fns/test_rotation_matrix.py URL: http://svn.gna.org/viewcvs/relax/1.3/test_suite/unit_tests/_maths_fns/test_rotation_matrix.py?rev=9476&r1=9475&r2=9476&view=diff ============================================================================== --- 1.3/test_suite/unit_tests/_maths_fns/test_rotation_matrix.py (original) +++ 1.3/test_suite/unit_tests/_maths_fns/test_rotation_matrix.py Tue Sep 8 16:40:16 2009 @@ -21,8 +21,9 @@ ############################################################################### # Python module imports. -from math import pi -from numpy import float64, zeros +from math import acos, asin, pi, sqrt +from numpy import array, eye, float64, zeros +from numpy.linalg import norm from random import uniform from unittest import TestCase @@ -38,12 +39,56 @@ """Set up data used by the unit tests.""" - def test_R_euler_zyz_alpha_30(self): - """Test the rotation matrix from zyz Euler angle conversion using a beta angle of pi/4.""" - - # Generate the rotation matrix. - R = zeros((3, 3), float64) - R_euler_zyz(R, pi/6, 0.0, 0.0) + def test_quaternion_to_R_no_rot(self): + """Test the quaternion to rotation matrix conversion for a zero angle rotation.""" + + # Quaternion of zero angle. + quat = array([1, 0, 0, 0], float64) + + # The rotation matrix. + R = zeros((3, 3), float64) + quaternion_to_R(quat, R) + print("Rotation matrix:\n%s" % R) + + # The correct result. + R_true = eye(3) + + # Checks. + for i in range(3): + for j in range(3): + self.assertEqual(R[i, j], R_true[i, j]) + + + def test_quaternion_to_R_z_30(self): + """Test the quaternion to rotation matrix conversion for a 30 degree rotation about z.""" + + # Axis-angle values. + axis = array([0, 0, 1], float64) + angle = pi / 6 + + # First element. + w = cos(angle / 2) + + # Vector reduction (quaternion normalisation). + factor = sqrt(1 - w**2) + axis = axis * factor + + # Quaternion. + quat = zeros(4, float64) + quat[0] = w + quat[1:] = axis + print("Quat: %s" % quat) + print("Quat norm: %s" % norm(quat)) + + # Quaternion check. + w_check = cos(asin(sqrt(quat[1]**2 + quat[2]**2 + quat[3]**2))) + self.assertEqual(w, w_check) + self.assertEqual(norm(quat), 1) + + # Generate the rotation matrix. + R = zeros((3, 3), float64) + quaternion_to_R(quat, R) + print("Rotation matrix:\n%s" % R) # Axes. x_axis = array([1, 0, 0], float64) @@ -71,9 +116,9 @@ # Checks. for i in range(3): - self.assertEqual(x_new[i], x_real[i]) - self.assertEqual(y_new[i], y_real[i]) - self.assertEqual(z_new[i], z_real[i]) + self.assertAlmostEqual(x_new[i], x_real[i]) + self.assertAlmostEqual(y_new[i], y_real[i]) + self.assertAlmostEqual(z_new[i], z_real[i]) # Axes (do everything again, this time negative!). x_axis = array([-1, 0, 0], float64) @@ -101,17 +146,41 @@ # Checks. for i in range(3): - self.assertEqual(x_new[i], x_real[i]) - self.assertEqual(y_new[i], y_real[i]) - self.assertEqual(z_new[i], z_real[i]) - - - def test_R_euler_zyz_beta_45(self): - """Test the rotation matrix from zyz Euler angle conversion using a beta angle of pi/4.""" - - # Generate the rotation matrix. - R = zeros((3, 3), float64) - R_euler_zyz(R, 0.0, pi/4, 0.0) + self.assertAlmostEqual(x_new[i], x_real[i]) + self.assertAlmostEqual(y_new[i], y_real[i]) + self.assertAlmostEqual(z_new[i], z_real[i]) + + + def test_quaternion_to_R_180_complex(self): + """Test the quaternion to rotation matrix conversion for a 180 degree rotation about [1, 1, 1].""" + + # Axis-angle values. + axis = array([1, 1, 1], float64) / sqrt(3) + angle = 2 * pi / 3 + + # First element. + w = cos(angle / 2) + + # Vector reduction (quaternion normalisation). + factor = sqrt(1 - w**2) + axis = axis * factor + + # Quaternion. + quat = zeros(4, float64) + quat[0] = w + quat[1:] = axis + print("Quat: %s" % quat) + print("Quat norm: %s" % norm(quat)) + + # Quaternion check. + w_check = cos(asin(sqrt(quat[1]**2 + quat[2]**2 + quat[3]**2))) + self.assertAlmostEqual(w, w_check) + self.assertEqual(norm(quat), 1) + + # Generate the rotation matrix. + R = zeros((3, 3), float64) + quaternion_to_R(quat, R) + print("Rotation matrix:\n%s" % R) # Axes. x_axis = array([1, 0, 0], float64) @@ -119,29 +188,29 @@ z_axis = array([0, 0, 1], float64) # Rotated axis (real values). - x_real = array([cos(pi/4), 0, -sin(pi/4)], float64) - y_real = array([0, 1, 0], float64) - z_real = array([sin(pi/4), 0, cos(pi/4)], float64) - - # Rotation. - x_new = dot(R, x_axis) - y_new = dot(R, y_axis) - z_new = dot(R, z_axis) - - # Print out. - print("Rotated and true axes (beta = pi/4):") - print(("x rot: %s" % x_new)) - print(("x real: %s\n" % x_real)) - print(("y rot: %s" % y_new)) - print(("y real: %s\n" % y_real)) - print(("z rot: %s" % z_new)) - print(("z real: %s\n" % z_real)) - - # Checks. - for i in range(3): - self.assertEqual(x_new[i], x_real[i]) - self.assertEqual(y_new[i], y_real[i]) - self.assertEqual(z_new[i], z_real[i]) + x_real = array([0, 1, 0], float64) + y_real = array([0, 0, 1], float64) + z_real = array([1, 0, 0], float64) + + # Rotation. + x_new = dot(R, x_axis) + y_new = dot(R, y_axis) + z_new = dot(R, z_axis) + + # Print out. + print("Rotated and true axes (beta = pi/4):") + print(("x rot: %s" % x_new)) + print(("x real: %s\n" % x_real)) + print(("y rot: %s" % y_new)) + print(("y real: %s\n" % y_real)) + print(("z rot: %s" % z_new)) + print(("z real: %s\n" % z_real)) + + # Checks. + for i in range(3): + self.assertAlmostEqual(x_new[i], x_real[i]) + self.assertAlmostEqual(y_new[i], y_real[i]) + self.assertAlmostEqual(z_new[i], z_real[i]) # Axes (do everything again, this time negative!). x_axis = array([-1, 0, 0], float64) @@ -149,37 +218,37 @@ z_axis = array([0, 0, -1], float64) # Rotated axis (real values). - x_real = array([-cos(pi/4), 0, sin(pi/4)], float64) - y_real = array([0, -1, 0], float64) - z_real = array([-sin(pi/4), 0, -cos(pi/4)], float64) - - # Rotation. - x_new = dot(R, x_axis) - y_new = dot(R, y_axis) - z_new = dot(R, z_axis) - - # Print out. - print("Rotated and true axes (beta = pi/4):") - print(("x rot: %s" % x_new)) - print(("x real: %s\n" % x_real)) - print(("y rot: %s" % y_new)) - print(("y real: %s\n" % y_real)) - print(("z rot: %s" % z_new)) - print(("z real: %s\n" % z_real)) - - # Checks. - for i in range(3): - self.assertEqual(x_new[i], x_real[i]) - self.assertEqual(y_new[i], y_real[i]) - self.assertEqual(z_new[i], z_real[i]) - - - def test_R_euler_zyz_gamma_15(self): + x_real = array([0, -1, 0], float64) + y_real = array([0, 0, -1], float64) + z_real = array([-1, 0, 0], float64) + + # Rotation. + x_new = dot(R, x_axis) + y_new = dot(R, y_axis) + z_new = dot(R, z_axis) + + # Print out. + print("Rotated and true axes (beta = pi/4):") + print(("x rot: %s" % x_new)) + print(("x real: %s\n" % x_real)) + print(("y rot: %s" % y_new)) + print(("y real: %s\n" % y_real)) + print(("z rot: %s" % z_new)) + print(("z real: %s\n" % z_real)) + + # Checks. + for i in range(3): + self.assertAlmostEqual(x_new[i], x_real[i]) + self.assertAlmostEqual(y_new[i], y_real[i]) + self.assertAlmostEqual(z_new[i], z_real[i]) + + + def test_R_euler_zyz_alpha_30(self): """Test the rotation matrix from zyz Euler angle conversion using a beta angle of pi/4.""" # Generate the rotation matrix. R = zeros((3, 3), float64) - R_euler_zyz(R, 0.0, 0.0, pi/12) + R_euler_zyz(R, pi/6, 0.0, 0.0) # Axes. x_axis = array([1, 0, 0], float64) @@ -187,8 +256,8 @@ z_axis = array([0, 0, 1], float64) # Rotated axis (real values). - x_real = array([cos(pi/12), sin(pi/12), 0], float64) - y_real = array([-sin(pi/12), cos(pi/12), 0], float64) + x_real = array([cos(pi/6), sin(pi/6), 0], float64) + y_real = array([-sin(pi/6), cos(pi/6), 0], float64) z_real = array([0, 0, 1], float64) # Rotation. @@ -217,8 +286,8 @@ z_axis = array([0, 0, -1], float64) # Rotated axis (real values). - x_real = array([-cos(pi/12), -sin(pi/12), 0], float64) - y_real = array([sin(pi/12), -cos(pi/12), 0], float64) + x_real = array([-cos(pi/6), -sin(pi/6), 0], float64) + y_real = array([sin(pi/6), -cos(pi/6), 0], float64) z_real = array([0, 0, -1], float64) # Rotation. @@ -239,14 +308,15 @@ for i in range(3): self.assertEqual(x_new[i], x_real[i]) self.assertEqual(y_new[i], y_real[i]) - - - def test_R_euler_zyz_alpha_15_gamma_15(self): + self.assertEqual(z_new[i], z_real[i]) + + + def test_R_euler_zyz_beta_45(self): """Test the rotation matrix from zyz Euler angle conversion using a beta angle of pi/4.""" # Generate the rotation matrix. R = zeros((3, 3), float64) - R_euler_zyz(R, pi/12, 0.0, pi/12) + R_euler_zyz(R, 0.0, pi/4, 0.0) # Axes. x_axis = array([1, 0, 0], float64) @@ -254,9 +324,9 @@ z_axis = array([0, 0, 1], float64) # Rotated axis (real values). - x_real = array([cos(pi/6), sin(pi/6), 0], float64) - y_real = array([-sin(pi/6), cos(pi/6), 0], float64) - z_real = array([0, 0, 1], float64) + x_real = array([cos(pi/4), 0, -sin(pi/4)], float64) + y_real = array([0, 1, 0], float64) + z_real = array([sin(pi/4), 0, cos(pi/4)], float64) # Rotation. x_new = dot(R, x_axis) @@ -284,6 +354,141 @@ z_axis = array([0, 0, -1], float64) # Rotated axis (real values). + x_real = array([-cos(pi/4), 0, sin(pi/4)], float64) + y_real = array([0, -1, 0], float64) + z_real = array([-sin(pi/4), 0, -cos(pi/4)], float64) + + # Rotation. + x_new = dot(R, x_axis) + y_new = dot(R, y_axis) + z_new = dot(R, z_axis) + + # Print out. + print("Rotated and true axes (beta = pi/4):") + print(("x rot: %s" % x_new)) + print(("x real: %s\n" % x_real)) + print(("y rot: %s" % y_new)) + print(("y real: %s\n" % y_real)) + print(("z rot: %s" % z_new)) + print(("z real: %s\n" % z_real)) + + # Checks. + for i in range(3): + self.assertEqual(x_new[i], x_real[i]) + self.assertEqual(y_new[i], y_real[i]) + self.assertEqual(z_new[i], z_real[i]) + + + def test_R_euler_zyz_gamma_15(self): + """Test the rotation matrix from zyz Euler angle conversion using a beta angle of pi/4.""" + + # Generate the rotation matrix. + R = zeros((3, 3), float64) + R_euler_zyz(R, 0.0, 0.0, pi/12) + + # Axes. + x_axis = array([1, 0, 0], float64) + y_axis = array([0, 1, 0], float64) + z_axis = array([0, 0, 1], float64) + + # Rotated axis (real values). + x_real = array([cos(pi/12), sin(pi/12), 0], float64) + y_real = array([-sin(pi/12), cos(pi/12), 0], float64) + z_real = array([0, 0, 1], float64) + + # Rotation. + x_new = dot(R, x_axis) + y_new = dot(R, y_axis) + z_new = dot(R, z_axis) + + # Print out. + print("Rotated and true axes (beta = pi/4):") + print(("x rot: %s" % x_new)) + print(("x real: %s\n" % x_real)) + print(("y rot: %s" % y_new)) + print(("y real: %s\n" % y_real)) + print(("z rot: %s" % z_new)) + print(("z real: %s\n" % z_real)) + + # Checks. + for i in range(3): + self.assertEqual(x_new[i], x_real[i]) + self.assertEqual(y_new[i], y_real[i]) + self.assertEqual(z_new[i], z_real[i]) + + # Axes (do everything again, this time negative!). + x_axis = array([-1, 0, 0], float64) + y_axis = array([0, -1, 0], float64) + z_axis = array([0, 0, -1], float64) + + # Rotated axis (real values). + x_real = array([-cos(pi/12), -sin(pi/12), 0], float64) + y_real = array([sin(pi/12), -cos(pi/12), 0], float64) + z_real = array([0, 0, -1], float64) + + # Rotation. + x_new = dot(R, x_axis) + y_new = dot(R, y_axis) + z_new = dot(R, z_axis) + + # Print out. + print("Rotated and true axes (beta = pi/4):") + print(("x rot: %s" % x_new)) + print(("x real: %s\n" % x_real)) + print(("y rot: %s" % y_new)) + print(("y real: %s\n" % y_real)) + print(("z rot: %s" % z_new)) + print(("z real: %s\n" % z_real)) + + # Checks. + for i in range(3): + self.assertEqual(x_new[i], x_real[i]) + self.assertEqual(y_new[i], y_real[i]) + + + def test_R_euler_zyz_alpha_15_gamma_15(self): + """Test the rotation matrix from zyz Euler angle conversion using a beta angle of pi/4.""" + + # Generate the rotation matrix. + R = zeros((3, 3), float64) + R_euler_zyz(R, pi/12, 0.0, pi/12) + + # Axes. + x_axis = array([1, 0, 0], float64) + y_axis = array([0, 1, 0], float64) + z_axis = array([0, 0, 1], float64) + + # Rotated axis (real values). + x_real = array([cos(pi/6), sin(pi/6), 0], float64) + y_real = array([-sin(pi/6), cos(pi/6), 0], float64) + z_real = array([0, 0, 1], float64) + + # Rotation. + x_new = dot(R, x_axis) + y_new = dot(R, y_axis) + z_new = dot(R, z_axis) + + # Print out. + print("Rotated and true axes (beta = pi/4):") + print(("x rot: %s" % x_new)) + print(("x real: %s\n" % x_real)) + print(("y rot: %s" % y_new)) + print(("y real: %s\n" % y_real)) + print(("z rot: %s" % z_new)) + print(("z real: %s\n" % z_real)) + + # Checks. + for i in range(3): + self.assertEqual(x_new[i], x_real[i]) + self.assertEqual(y_new[i], y_real[i]) + self.assertEqual(z_new[i], z_real[i]) + + # Axes (do everything again, this time negative!). + x_axis = array([-1, 0, 0], float64) + y_axis = array([0, -1, 0], float64) + z_axis = array([0, 0, -1], float64) + + # Rotated axis (real values). x_real = array([-cos(pi/6), -sin(pi/6), 0], float64) y_real = array([sin(pi/6), -cos(pi/6), 0], float64) z_real = array([0, 0, -1], float64)