Search code examples
pythonnumpyrotational-matrices

How to test if a matrix is a rotation matrix?


I have a task to check if a matrix is a rotation matrix, I write code as follow:

import numpy as np    

def isRotationMatrix(R):
    # some code here
    # return True or False

R = np.array([
    [0, 0, 1],
    [1, 0, 0],
    [0, 1, 0],
])
print(isRotationMatrix(R))  # Should be True
R = np.array([
    [-1, 0, 0],
    [0, 1, 0],
    [0, 0, 1],
])
print(isRotationMatrix(R))  # Should be False

I don't know how to implement the function isRotationMatrix.


My naive implement, it only works for a 3x3 matrix:

def isRotationMatrix(R_3x3):
    should_be_norm_one = np.allclose(np.linalg.norm(R_3x3, axis=0), np.ones(shape=3))
    x = R_3x3[:, 0].ravel()
    y = R_3x3[:, 1].ravel()
    z = R_3x3[:, 2].ravel()
    should_be_perpendicular = \
        np.allclose(np.cross(x, y), z) \
        and np.allclose(np.cross(y, z), x) \
        and np.allclose(np.cross(z, x), y)
    return should_be_perpendicular and should_be_norm_one

Solution

  • A rotation matrix is a orthonormal matrix and its determinant should be 1.
    My implement:

    import numpy as np
    
    
    def isRotationMatrix(R):
        # square matrix test
        if R.ndim != 2 or R.shape[0] != R.shape[1]:
            return False
        should_be_identity = np.allclose(R.dot(R.T), np.identity(R.shape[0], np.float))
        should_be_one = np.allclose(np.linalg.det(R), 1)
        return should_be_identity and should_be_one
    
    
    if __name__ == '__main__':
        R = np.array([
            [0, 0, 1],
            [1, 0, 0],
            [0, 1, 0],
        ])
        print(isRotationMatrix(R))  # True
        R = np.array([
            [-1, 0, 0],
            [0, 1, 0],
            [0, 0, 1],
        ])
        print(isRotationMatrix(R))  # True
        print(isRotationMatrix(np.zeros((3, 2))))  # False