Example #1
0
def test_procrustes_rotation_translation():
    # initial arrays
    array_a = np.array([[-7.3, 2.8], [-7.1, -0.2], [4.0, 1.4], [1.3, 0]])
    # rotation by 20 degree & reflection in the x-axis
    theta = 0.34907
    rotation = np.array([[np.cos(theta), -np.sin(theta)],
                         [np.sin(theta), np.cos(theta)]])
    reflection = np.array([[1, 0], [0, -1]])
    array_b = np.dot(array_a, np.dot(rotation, reflection))
    # procrustes without translation and scaling
    new_a, new_b, array_u, _ = orthogonal(array_a, array_b)
    assert_almost_equal(new_a, array_a, decimal=6)
    assert_almost_equal(new_b, array_b, decimal=6)
    assert_almost_equal(array_u, np.dot(rotation, reflection), decimal=6)
    assert_almost_equal(error(new_a, new_b, array_u), 0., decimal=6)
    # procrustes with translation
    new_a, new_b, array_u, _ = orthogonal(array_a, array_b, translate=True)
    assert_almost_equal(new_a, array_a - np.mean(array_a, axis=0), decimal=6)
    assert_almost_equal(new_b, array_b - np.mean(array_b, axis=0), decimal=6)
    assert_almost_equal(array_u, np.dot(rotation, reflection), decimal=6)
    assert_almost_equal(error(new_a, new_b, array_u), 0., decimal=6)
    # procrustes with translation and scaling
    new_a, new_b, array_u, _ = orthogonal(array_a,
                                          array_b,
                                          translate=True,
                                          scale=True)
    assert_almost_equal(array_u, np.dot(rotation, reflection), decimal=6)
    assert_almost_equal(error(new_a, new_b, array_u), 0., decimal=6)
Example #2
0
def test_procrustes_shifted():
    # square array
    array_a = np.array([[3.5, 0.1, 7.0], [0.5, 2.0, 1.0], [8.1, 0.3, 0.7]])
    expected_a = array_a - np.mean(array_a, axis=0)
    # constant shift
    array_b = array_a + 4.1
    new_a, new_b, array_u, _ = orthogonal(array_a, array_b, translate=True)
    #assert_almost_equal(new_b, array_b, decimal=6)
    assert_almost_equal(array_u, np.eye(3), decimal=6)
    assert_almost_equal(error(new_a, new_b, array_u), 0., decimal=6)
    # different shift along each axis
    array_b = array_a + np.array([0, 3.2, 5.0])
    new_a, new_b, array_u, _ = orthogonal(array_a, array_b, translate=True)
    # assert_almost_equal(new_b, array_b, decimal=6)
    assert_almost_equal(array_u, np.eye(3), decimal=6)
    assert_almost_equal(error(new_a, new_b, array_u), 0., decimal=6)
    # rectangular (2 by 3)
    array_a = np.array([[1, 2, 3], [7, 9, 5]])
    expected_a = array_a - np.array([4., 5.5, 4.])
    # constant shift
    array_b = array_a + 0.71
    new_a, new_b, array_u, _ = orthogonal(array_a, array_b, translate=True)
    #assert_almost_equal(new_b, array_b, decimal=6)
    assert_almost_equal(error(new_a, new_b, array_u), 0., decimal=6)
    # different shift along each axis
    array_b = array_a + np.array([0.3, 7.1, 4.2])
    new_a, new_b, array_u, _ = orthogonal(array_a, array_b, translate=True)
    # assert_almost_equal(new_b, array_b, decimal=6)
    assert_equal(array_u.shape, (3, 3))
    assert_almost_equal(error(new_a, new_b, array_u), 0., decimal=6)
Example #3
0
def test_procrustes_orthogonal_identical():
    # case of identical square arrays
    array_a = np.arange(9).reshape(3, 3)
    array_b = np.copy(array_a)
    new_a, new_b, array_u, _ = orthogonal(array_a, array_b)
    # check transformation array is identity
    assert_almost_equal(new_a, array_a, decimal=6)
    assert_almost_equal(new_b, array_b, decimal=6)
    assert_almost_equal(error(new_a, new_b, array_u), 0., decimal=6)
    # case of identical rectangular arrays (2 by 4)
    array_a = np.array([[1, 5, 6, 7], [1, 2, 9, 4]])
    array_b = np.copy(array_a)
    new_a, new_b, array_u, _ = orthogonal(array_a, array_b)
    assert_almost_equal(new_a, array_a, decimal=6)
    assert_almost_equal(new_b, array_b, decimal=6)
    assert_equal(array_u.shape, (4, 4))
    # assert_almost_equal(array_u, np.eye(4), decimal=6)
    assert_almost_equal(error(new_a, new_b, array_u), 0., decimal=6)
    # case of identical rectangular arrays (5 by 3)
    array_a = np.arange(15).reshape(5, 3)
    array_b = np.copy(array_a)
    new_a, new_b, array_u, _ = orthogonal(array_a, array_b)
    assert_almost_equal(new_a, array_a, decimal=6)
    assert_almost_equal(new_b, array_b, decimal=6)
    assert_equal(array_u.shape, (3, 3))
    assert_almost_equal(error(new_a, new_b, array_u), 0., decimal=6)
Example #4
0
def test_procrustes_reflection_square():
    # square array
    array_a = np.array([[2.0, 0.1], [0.5, 3.0]])
    # reflection through origin
    array_b = -array_a
    new_a, new_b, array_u, _ = orthogonal(array_a, array_b)
    assert_almost_equal(new_a, array_a, decimal=6)
    assert_almost_equal(new_b, array_b, decimal=6)
    assert_almost_equal(array_u, np.array([[-1, 0], [0, -1]]), decimal=6)
    assert_almost_equal(error(new_a, new_b, array_u), 0., decimal=6)
    # reflection in the x-axis
    array_b = np.array([[2.0, -0.1], [0.5, -3.0]])
    new_a, new_b, array_u, _ = orthogonal(array_a, array_b)
    assert_almost_equal(array_u, np.array([[1, 0], [0, -1]]), decimal=6)
    assert_almost_equal(error(new_a, new_b, array_u), 0., decimal=6)
    # reflection in the y-axis
    array_b = np.array([[-2.0, 0.1], [-0.5, 3.0]])
    new_a, new_b, array_u, _ = orthogonal(array_a, array_b)
    assert_almost_equal(array_u, np.array([[-1, 0], [0, 1]]), decimal=6)
    assert_almost_equal(error(new_a, new_b, array_u), 0., decimal=6)
    # reflection in the line y=x
    array_b = np.array([[0.1, 2.0], [3.0, 0.5]])
    new_a, new_b, array_u, _ = orthogonal(array_a, array_b)
    assert_almost_equal(array_u, np.array([[0, 1], [1, 0]]), decimal=6)
    assert_almost_equal(error(new_a, new_b, array_u), 0., decimal=6)
Example #5
0
def test_procrustes_shifted():
    r"""Test orthogonal Procrustes with shifted array."""
    # square array
    array_a = np.array([[3.5, 0.1, 7.0], [0.5, 2.0, 1.0], [8.1, 0.3, 0.7]])
    # expected_a = array_a - np.mean(array_a, axis=0)
    # constant shift
    array_b = array_a + 4.1
    res = orthogonal(array_a, array_b, translate=True)
    # assert_almost_equal(new_b, array_b, decimal=6)
    assert_almost_equal(res["array_u"], np.eye(3), decimal=6)
    assert_almost_equal(compute_error(res["new_a"], res["new_b"],
                                      res["array_u"]),
                        0.,
                        decimal=6)
    # different shift along each axis
    array_b = array_a + np.array([0, 3.2, 5.0])
    res = orthogonal(array_a, array_b, translate=True)
    # assert_almost_equal(new_b, array_b, decimal=6)
    assert_almost_equal(res["array_u"], np.eye(3), decimal=6)
    assert_almost_equal(compute_error(res["new_a"], res["new_b"],
                                      res["array_u"]),
                        0.,
                        decimal=6)
    # rectangular (2 by 3)
    array_a = np.array([[1, 2, 3], [7, 9, 5]])
    # expected_a = array_a - np.array([4., 5.5, 4.])
    # constant shift
    array_b = array_a + 0.71
    res = orthogonal(array_a, array_b, translate=True)
    # assert_almost_equal(new_b, array_b, decimal=6)
    assert_almost_equal(compute_error(res["new_a"], res["new_b"],
                                      res["array_u"]),
                        0.,
                        decimal=6)
    # different shift along each axis
    array_b = array_a + np.array([0.3, 7.1, 4.2])
    res = orthogonal(array_a, array_b, translate=True)
    # assert_almost_equal(new_b, array_b, decimal=6)
    assert_equal(res["array_u"].shape, (3, 3))
    assert_almost_equal(compute_error(res["new_a"], res["new_b"],
                                      res["array_u"]),
                        0.,
                        decimal=6)
Example #6
0
def test_procrustes_reflection_square(n):
    r"""Test orthogonal Procrustes with reflected squared array."""
    # square array
    array_a = np.random.uniform(-10.0, 10.0, (n, n))
    # reflection through diagonal plane
    array_b = -array_a
    res = orthogonal(array_a, array_b)
    assert_almost_equal(res.new_a, array_a, decimal=6)
    assert_almost_equal(res.new_b, array_b, decimal=6)
    assert_almost_equal(res.t, -np.eye(n), decimal=6)
    assert_almost_equal(res.error, 0., decimal=6)
    # General reflection through random hyperplane, see Wikipedia "Reflection (mathematics)"
    a = np.random.uniform(-10.0, 10.0, (n))
    a /= np.linalg.norm(a)
    rotation = np.eye(n) - 2.0 * np.outer(a, a) / np.linalg.norm(a)**2.0
    array_b = array_a.dot(rotation)
    res = orthogonal(array_a, array_b)
    assert_almost_equal(res.t, rotation, decimal=6)
    assert_almost_equal(res.error, 0., decimal=6)
    assert_almost_equal(array_a.dot(rotation), array_b, decimal=6)
    assert_equal(res.s, None)
Example #7
0
def test_procrustes_rotation_square_lapack_driver(n):
    r"""Test orthogonal Procrustes with squared array with non-default lapack_driver."""
    # square array
    array_a = np.random.uniform(-10.0, 10.0, (n, n))
    # rotation by 90 degree
    ortho_arr = ortho_group.rvs(n)
    array_b = array_a.dot(ortho_arr)
    res = orthogonal(array_a, array_b, lapack_driver="gesdd")
    assert_almost_equal(res.error, 0., decimal=6)
    assert_almost_equal(res.t.dot(res.t.T), np.eye(n), decimal=6)
    assert_almost_equal(res.t, ortho_arr)
    assert_equal(res.s, None)
Example #8
0
def test_procrustes_orthogonal_identical(m, n):
    r"""Test orthogonal Procrustes with identity matrix."""
    # case of identical square arrays
    array_a = np.random.uniform(-10.0, 10.0, (m, n))
    array_b = np.copy(array_a)
    res = orthogonal(array_a, array_b)
    assert_equal(res.s, None)
    assert_almost_equal(res.new_a, array_a, decimal=6)
    assert_almost_equal(res.new_b, array_b, decimal=6)
    assert_almost_equal(res.t.dot(res.t.T), np.eye(n), decimal=6)
    assert_almost_equal(res.error, 0., decimal=6)
    assert_almost_equal(array_a.dot(res.t), array_b)
Example #9
0
def test_procrustes_reflection_square():
    r"""Test orthogonal Procrustes with reflected squared array."""
    # square array
    array_a = np.array([[2.0, 0.1], [0.5, 3.0]])
    # reflection through origin
    array_b = -array_a
    res = orthogonal(array_a, array_b)
    assert_almost_equal(res["new_a"], array_a, decimal=6)
    assert_almost_equal(res["new_b"], array_b, decimal=6)
    assert_almost_equal(res["array_u"],
                        np.array([[-1, 0], [0, -1]]),
                        decimal=6)
    assert_almost_equal(compute_error(res["new_a"], res["new_b"],
                                      res["array_u"]),
                        0.,
                        decimal=6)
    # reflection in the x-axis
    array_b = np.array([[2.0, -0.1], [0.5, -3.0]])
    res = orthogonal(array_a, array_b)
    assert_almost_equal(res["array_u"], np.array([[1, 0], [0, -1]]), decimal=6)
    assert_almost_equal(compute_error(res["new_a"], res["new_b"],
                                      res["array_u"]),
                        0.,
                        decimal=6)
    # reflection in the y-axis
    array_b = np.array([[-2.0, 0.1], [-0.5, 3.0]])
    res = orthogonal(array_a, array_b)
    assert_almost_equal(res["array_u"], np.array([[-1, 0], [0, 1]]), decimal=6)
    assert_almost_equal(compute_error(res["new_a"], res["new_b"],
                                      res["array_u"]),
                        0.,
                        decimal=6)
    # reflection in the line y=x
    array_b = np.array([[0.1, 2.0], [3.0, 0.5]])
    res = orthogonal(array_a, array_b)
    assert_almost_equal(res["array_u"], np.array([[0, 1], [1, 0]]), decimal=6)
    assert_almost_equal(compute_error(res["new_a"], res["new_b"],
                                      res["array_u"]),
                        0.,
                        decimal=6)
Example #10
0
def test_procrustes_orthogonal_identical():
    r"""Test orthogonal Procrustes with identity matrix."""
    # case of identical square arrays
    array_a = np.arange(9).reshape(3, 3)
    array_b = np.copy(array_a)
    res = orthogonal(array_a, array_b)
    # check transformation array is identity
    assert_almost_equal(res["new_a"], array_a, decimal=6)
    assert_almost_equal(res["new_b"], array_b, decimal=6)
    assert_almost_equal(compute_error(res["new_a"], res["new_b"],
                                      res["array_u"]),
                        0.,
                        decimal=6)
    # case of identical rectangular arrays (2 by 4)
    array_a = np.array([[1, 5, 6, 7], [1, 2, 9, 4]])
    array_b = np.copy(array_a)
    res = orthogonal(array_a, array_b)
    assert_almost_equal(res["new_a"], array_a, decimal=6)
    assert_almost_equal(res["new_b"], array_b, decimal=6)
    assert_equal(res["array_u"].shape, (4, 4))
    # assert_almost_equal(array_u, np.eye(4), decimal=6)
    assert_almost_equal(compute_error(res["new_a"], res["new_b"],
                                      res["array_u"]),
                        0.,
                        decimal=6)
    # case of identical rectangular arrays (5 by 3)
    array_a = np.arange(15).reshape(5, 3)
    array_b = np.copy(array_a)
    res = orthogonal(array_a, array_b)
    assert_almost_equal(res["new_a"], array_a, decimal=6)
    assert_almost_equal(res["new_b"], array_b, decimal=6)
    assert_equal(res["array_u"].shape, (3, 3))
    assert_almost_equal(compute_error(res["new_a"], res["new_b"],
                                      res["array_u"]),
                        0.,
                        decimal=6)
Example #11
0
def test_rotation_translate_scale():
    # initial arrays
    array_a = np.array([[5.1, 0], [-1.1, 4.8], [3.9, 7.3], [9.1, 6.3]])
    # rotation by 68 degree & reflection in the Y=X
    theta = 1.18682
    rotation = np.array([[np.cos(theta), -np.sin(theta)],
                         [np.sin(theta), np.cos(theta)]])
    reflection = np.array([[0, 1], [1, 0]])
    array_b = np.dot(4 * array_a + 3.0, np.dot(rotation, reflection))
    # procrustes with translation and scaling
    new_a, new_b, array_u, _ = orthogonal(array_a,
                                          array_b,
                                          translate=True,
                                          scale=True)
    assert_almost_equal(array_u, np.dot(rotation, reflection), decimal=6)
    assert_almost_equal(error(new_a, new_b, array_u), 0., decimal=6)
Example #12
0
def test_procrustes_with_translation(m, n):
    r"""Test orthogonal Procrustes with translation."""
    array_a = np.random.uniform(-10.0, 10.0, (m, n))
    array_b = array_a + np.random.uniform(-10.0, 10.0, (n, ))
    res = orthogonal(array_a, array_b, translate=True)
    # Test that the new A and B are translation of the originals.
    assert_almost_equal(res.new_a,
                        array_a - np.mean(array_a, axis=0),
                        decimal=6)
    assert_almost_equal(res.new_b,
                        array_a - np.mean(array_a, axis=0),
                        decimal=6)
    # Test that optimal result is orthogonal, and error is zero
    assert_almost_equal(res.t.T.dot(res.t), np.eye(n), decimal=6)
    assert_almost_equal(res.error, 0., decimal=6)
    assert_almost_equal(res.new_a.dot(res.t), res.new_b, decimal=6)
    assert_equal(res.s, None)
Example #13
0
def test_procrustes_orthogonal_translate_scale2():
    # initial array
    array_a = np.array([[1, 4], [7, 9]])
    # define a transformation composed of rotation & reflection
    theta = np.pi / 2
    rot = np.array([[np.cos(theta), -np.sin(theta)],
                    [np.sin(theta), np.cos(theta)]])
    ref = np.array([[1, 0], [0, -1]])
    trans = np.dot(rot, ref)
    # define array_b by transforming array_a and padding with zero
    array_b = np.dot(array_a, trans)
    array_b = np.concatenate((array_b, np.zeros((2, 5))), axis=1)
    array_b = np.concatenate((array_b, np.zeros((5, 7))), axis=0)
    # compute procrustes transformation
    new_a, new_b, array_u, _ = orthogonal(array_a,
                                          array_b,
                                          translate=False,
                                          scale=False)
    assert_almost_equal(array_u, np.dot(rot, ref), decimal=6)
    assert_almost_equal(error(new_a, new_b, array_u), 0., decimal=6)
Example #14
0
def test_orthogonal_with_translate_and_scale(m, n):
    r"""Test orthogonal Procrustes with rotation, translation and scaling."""
    # initial arrays
    array_a = np.random.uniform(-10.0, 10.0, (m, n))
    # Generate reflection across random hyperplane
    a = np.random.uniform(-10.0, 10.0, (n))
    a /= np.linalg.norm(a)
    reflection = np.eye(n) - 2.0 * np.outer(a, a) / np.linalg.norm(a)**2.0
    rotation = ortho_group.rvs(n)
    # Translate and shift the rotated and reflected array_a.
    array_b = 4.0 * np.dot(array_a, rotation.dot(reflection)) + 3.0
    # Procrustes with translation and scaling
    res = orthogonal(array_a, array_b, translate=True, scale=True)
    untranslated_array_a = (array_a - np.mean(array_a, axis=0))
    assert_almost_equal(
        res.new_a, untranslated_array_a / np.linalg.norm(untranslated_array_a))
    assert_almost_equal(res.t.T.dot(res.t), np.eye(n), decimal=6)
    assert_almost_equal(res.error, 0., decimal=6)
    assert_almost_equal(res.new_a.dot(res.t), res.new_b, decimal=6)
    assert_equal(res.s, None)
Example #15
0
def test_orthogonal_translate_scale2():
    r"""Test orthogonal Procrustes with rotation, translation and scaling with a different array."""
    # initial array
    array_a = np.array([[1, 4], [7, 9]])
    # define a transformation composed of rotation & reflection
    theta = np.pi / 2
    rot = np.array([[np.cos(theta), -np.sin(theta)],
                    [np.sin(theta), np.cos(theta)]])
    ref = np.array([[1, 0], [0, -1]])
    trans = np.dot(rot, ref)
    # define array_b by transforming array_a and padding with zero
    array_b = np.dot(array_a, trans)
    array_b = np.concatenate((array_b, np.zeros((2, 5))), axis=1)
    array_b = np.concatenate((array_b, np.zeros((5, 7))), axis=0)
    # compute procrustes transformation
    res = orthogonal(array_a, array_b, translate=False, scale=False)
    assert_almost_equal(res["array_u"], np.dot(rot, ref), decimal=6)
    assert_almost_equal(compute_error(res["new_a"], res["new_b"],
                                      res["array_u"]),
                        0.,
                        decimal=6)
Example #16
0
def test_orthogonal_translate_scale_with_unpadding(m, n, ncols, nrows):
    r"""Test orthogonal Procrustes with rotation, translation and scaling with unpadding."""
    # initial array
    array_a = np.random.uniform(-10.0, 10.0, (m, n))
    # obtain random orthogonal matrix
    ortho = ortho_group.rvs(n)
    # define array_b by transforming array_a and padding with zero
    array_b = np.dot(array_a, ortho)
    # Pad array b with additional "ncols" columns and "nrows" rows.
    array_b = np.concatenate((array_b, np.zeros((m, ncols))), axis=1)
    array_b = np.concatenate((array_b, np.zeros((nrows, n + ncols))), axis=0)
    # compute procrustes transformation
    res = orthogonal(array_a,
                     array_b,
                     translate=False,
                     scale=False,
                     unpad_col=True,
                     unpad_row=True)
    assert_almost_equal(res.new_b, np.dot(array_a, ortho), decimal=6)
    assert_almost_equal(res.error, 0., decimal=6)
    assert_almost_equal(res.t.T.dot(res.t), np.eye(n), decimal=6)
    assert_almost_equal(res.new_a.dot(res.t), res.new_b, decimal=6)
    assert_equal(res.s, None)
Example #17
0
def test_procrustes_rotation_square():
    # square array
    array_a = np.arange(4).reshape(2, 2)
    # rotation by 90 degree
    array_b = np.array([[1, 0], [3, -2]])
    new_a, new_b, array_u, _ = orthogonal(array_a, array_b)
    assert_almost_equal(array_u, np.array([[0., -1.], [1., 0.]]), decimal=6)
    assert_almost_equal(error(new_a, new_b, array_u), 0., decimal=6)
    # rotation by 180 degree
    array_b = -array_a
    new_a, new_b, array_u, _ = orthogonal(array_a, array_b)
    assert_almost_equal(array_u, np.array([[-1., 0.], [0., -1.]]), decimal=6)
    assert_almost_equal(error(new_a, new_b, array_u), 0., decimal=6)
    # rotation by 270 degree
    array_b = np.array([[-1, 0], [-3, 2]])
    new_a, new_b, array_u, _ = orthogonal(array_a, array_b)
    assert_almost_equal(array_u, np.array([[0., 1.], [-1., 0.]]), decimal=6)
    assert_almost_equal(error(new_a, new_b, array_u), 0., decimal=6)
    # rotation by 45 degree
    rotation = 0.5 * np.sqrt(2) * np.array([[1, -1], [1, 1]])
    array_b = np.dot(array_a, rotation)
    new_a, new_b, array_u, _ = orthogonal(array_a, array_b)
    assert_almost_equal(array_u, rotation, decimal=6)
    assert_almost_equal(error(new_a, new_b, array_u), 0., decimal=6)
    # rotation by 30 degree
    theta = np.pi / 6
    rotation = np.array([[np.cos(theta), -np.sin(theta)],
                         [np.sin(theta), np.cos(theta)]])
    array_b = np.dot(array_a, rotation)
    new_a, new_b, array_u, _ = orthogonal(array_a, array_b)
    assert_almost_equal(array_u, rotation, decimal=6)
    assert_almost_equal(error(new_a, new_b, array_u), 0., decimal=6)
    # rotation by 72 degree
    theta = 1.25664
    rotation = np.array([[np.cos(theta), -np.sin(theta)],
                         [np.sin(theta), np.cos(theta)]])
    array_b = np.dot(array_a, rotation)
    new_a, new_b, array_u, _ = orthogonal(array_a, array_b)
    assert_almost_equal(array_u, rotation, decimal=6)
    assert_almost_equal(error(new_a, new_b, array_u), 0., decimal=6)
Example #18
0
def test_procrustes_rotation_square():
    r"""Test orthogonal Procrustes with squared array."""
    # square array
    array_a = np.arange(4).reshape(2, 2)
    # rotation by 90 degree
    array_b = np.array([[1, 0], [3, -2]])
    res = orthogonal(array_a, array_b)
    assert_almost_equal(res["array_u"],
                        np.array([[0., -1.], [1., 0.]]),
                        decimal=6)
    assert_almost_equal(compute_error(res["new_a"], res["new_b"],
                                      res["array_u"]),
                        0.,
                        decimal=6)
    # rotation by 180 degree
    array_b = -array_a
    res = orthogonal(array_a, array_b)
    assert_almost_equal(res["array_u"],
                        np.array([[-1., 0.], [0., -1.]]),
                        decimal=6)
    assert_almost_equal(compute_error(res["new_a"], res["new_b"],
                                      res["array_u"]),
                        0.,
                        decimal=6)
    # rotation by 270 degree
    array_b = np.array([[-1, 0], [-3, 2]])
    res = orthogonal(array_a, array_b)
    assert_almost_equal(res["array_u"],
                        np.array([[0., 1.], [-1., 0.]]),
                        decimal=6)
    assert_almost_equal(compute_error(res["new_a"], res["new_b"],
                                      res["array_u"]),
                        0.,
                        decimal=6)
    # rotation by 45 degree
    rotation = 0.5 * np.sqrt(2) * np.array([[1, -1], [1, 1]])
    array_b = np.dot(array_a, rotation)
    res = orthogonal(array_a, array_b)
    assert_almost_equal(res["array_u"], rotation, decimal=6)
    assert_almost_equal(compute_error(res["new_a"], res["new_b"],
                                      res["array_u"]),
                        0.,
                        decimal=6)
    # rotation by 30 degree
    theta = np.pi / 6
    rotation = np.array([[np.cos(theta), -np.sin(theta)],
                         [np.sin(theta), np.cos(theta)]])
    array_b = np.dot(array_a, rotation)
    res = orthogonal(array_a, array_b)
    assert_almost_equal(res["array_u"], rotation, decimal=6)
    assert_almost_equal(compute_error(res["new_a"], res["new_b"],
                                      res["array_u"]),
                        0.,
                        decimal=6)
    # rotation by 72 degree
    theta = 1.25664
    rotation = np.array([[np.cos(theta), -np.sin(theta)],
                         [np.sin(theta), np.cos(theta)]])
    array_b = np.dot(array_a, rotation)
    res = orthogonal(array_a, array_b)
    assert_almost_equal(res["array_u"], rotation, decimal=6)
    assert_almost_equal(compute_error(res["new_a"], res["new_b"],
                                      res["array_u"]),
                        0.,
                        decimal=6)