def test_fat_rectangular_matrices_with_square_padding(self, nrow): r"""Test Symmetric Procrustes with random wide matrices.""" # Square padding is needed or else it returns an error. # Generate Random Rectangular Matrices ncol = np.random.randint(nrow + 1, nrow + 10) array_a, array_b = np.random.random((nrow, ncol)), np.random.random( (nrow, ncol)) with pytest.raises(ValueError): symmetric(array_a, array_b) _, desired_func = self._optimize(array_a, array_b, ncol) res = symmetric(array_a, array_b, pad_mode="square") # No uniqueness in solution, thus check that the optimal values are the same. assert np.abs(res["error"] - desired_func) < 1e-5
def test_not_full_rank_case(): # Define a random matrix and symmetric matrix array_a = np.array([[10, 83], [52, 58], [58, 44]]) sym_array = np.array([[0.38895636, 0.30523869], [0.30523869, 0.30856369]]) array_b = np.dot(array_a, sym_array) # compute procrustes transformation new_a, new_b, array_x, e_opt = symmetric(array_a, array_b) # check transformation is symmetric & error is zero assert_almost_equal(array_x, array_x.T, decimal=6) assert_almost_equal(e_opt, 0, decimal=6)
def test_not_full_rank_case(): r"""Test symmetric with not full rank case.""" # define a random matrix and symmetric matrix array_a = np.array([[10, 83], [52, 58], [58, 44]]) sym_array = np.array([[0.38895636, 0.30523869], [0.30523869, 0.30856369]]) array_b = np.dot(array_a, sym_array) # compute procrustes transformation & check results res = symmetric(array_a, array_b) assert_equal(res.s, None) assert_almost_equal(res.t, res.t.T, decimal=6) assert_almost_equal(res.error, 0.0, decimal=6)
def test_not_full_rank_case(): r"""Test symmetric with not full rank case.""" # Define a random matrix and symmetric matrix array_a = np.array([[10, 83], [52, 58], [58, 44]]) sym_array = np.array([[0.38895636, 0.30523869], [0.30523869, 0.30856369]]) array_b = np.dot(array_a, sym_array) # compute procrustes transformation res = symmetric(array_a, array_b) # check transformation is symmetric & error is zero assert_almost_equal(res["array_u"], res["array_u"].T, decimal=6) assert_almost_equal(res["error"], 0.0, decimal=6)
def test_fat_rectangular_matrices_with_square_padding_with_lapack_driver(nrow): r"""Test Symmetric Procrustes with random wide matrices and non-default lapack driver.""" # generate random rectangular matrices ncol = np.random.randint(nrow + 1, nrow + 10) array_a, array_b = np.random.random((nrow, ncol)), np.random.random( (nrow, ncol)) # minimize objective function to find transformation matrix _, desired_func = minimize_one_transformation(array_a, array_b, ncol) res = symmetric(array_a, array_b, pad=True, lapack_driver="gesdd") # check results (solution is not uniqueness) assert_almost_equal(np.abs(res.error - desired_func), 0.0, decimal=5) assert_equal(res.s, None)
def test_random_tall_rectangular_matrices(self, ncol): r"""Test Symmetric Procrustes with random tall matrices.""" # Generate Random Rectangular Matrices with small singular values nrow = np.random.randint(ncol, ncol + 10) array_a, array_b = np.random.random((nrow, ncol)), np.random.random( (nrow, ncol)) desired, desired_func = self._optimize(array_a, array_b, ncol) res = symmetric(array_a, array_b) assert np.abs(res["error"] - desired_func) < 1e-5 assert np.all(np.abs(res["array_u"] - desired) < 1e-3)
def test_random_tall_rectangular_matrices(ncol): r"""Test Symmetric Procrustes with random tall matrices.""" # generate random floats in [0.0, 1.0) interval nrow = np.random.randint(ncol, ncol + 10) array_a, array_b = np.random.random((nrow, ncol)), np.random.random( (nrow, ncol)) # minimize objective function to find transformation matrix desired, desired_func = minimize_one_transformation(array_a, array_b, ncol) # compute transformation & check results res = symmetric(array_a, array_b, unpad_col=True, unpad_row=True) assert_equal(res.s, None) assert_almost_equal(np.abs(res.error - desired_func), 0.0, decimal=5) assert_almost_equal(np.abs(res.t - desired), 0.0, decimal=3)
def test_having_zero_singular_case(): r"""Test symmetric that has zero singular values.""" # Define a matrix with not full singular values, e.g. 5 and 0 are singular values. sing_mat = np.array([[5., 0.], [0., 0.], [0., 0.], [0., 0.]]) array_a = ortho_group.rvs(4).dot(sing_mat).dot(ortho_group.rvs(2)) sym_array = np.array([[0.38895636, 0.30523869], [0.30523869, 0.30856369]]) array_b = np.dot(array_a, sym_array) # compute procrustes transformation res = symmetric(array_a, array_b) # check transformation is symmetric & error is zero assert_almost_equal(res["array_u"], res["array_u"].T, decimal=6) assert_almost_equal(res["error"], 0.0, decimal=6)
def test_symmetric_scaled_shifted_tranformed(): r"""Test symmetric with translation and scaling.""" # define an arbitrary array_a, translation matrix & symmetric matrix array_a = np.array([[5, 2, 8], [2, 2, 3], [1, 5, 6], [7, 3, 2]], dtype=float) shift = np.array([[9., 4., 3.], [9., 4., 3.], [9., 4., 3.], [9., 4., 3.]]) sym_array = np.dot(np.array([[1, 4, 9]]).T, np.array([[1, 4, 9]])) # define array_b by scaling, translating and transforming array_a array_b = 614.5 * array_a + shift array_b = np.dot(array_b, sym_array) # compute procrustes transformation res = symmetric(array_a, array_b, translate=True, scale=True) # check transformation is symmetric & error is zero assert_almost_equal(res["array_u"], res["array_u"].T, decimal=6) assert_almost_equal(res["error"], 0.0, decimal=6)
def test_symmetric_transformed(): r"""Test symmetric without translation and scaling.""" # define arbitrary array and symmetric transformation array_a = np.array([[1, 2, 4, 5], [5, 7, 3, 3], [1, 5, 1, 9], [1, 5, 2, 7], [5, 7, 9, 0]]) sym_array = np.dot(np.array([[1, 7, 4, 9]]).T, np.array([[1, 7, 4, 9]])) # define array_b by transforming array_a and padding with zero array_b = np.dot(array_a, sym_array) array_b = np.concatenate((array_b, np.zeros((5, 2))), axis=1) array_b = np.concatenate((array_b, np.zeros((8, 6))), axis=0) # compute procrustes transformation res = symmetric(array_a, array_b, translate=False, scale=False) # check transformation is symmetric & error is zero assert_almost_equal(res["array_u"], res["array_u"].T, decimal=6) assert_almost_equal(res["array_u"], sym_array, decimal=6) assert_almost_equal(res["error"], 0.0, decimal=6)
def test_having_zero_eigenvalues_case(m): r"""Test symmetric that has zero singular values.""" # define a singular matrix (i.e. some eigenvalues are hard zeros) numb_nonzero_eigs = int(np.random.randint(1, m - 1)) sing_mat = list(np.random.uniform(-10.0, 10.0, (numb_nonzero_eigs, ))) sing_mat += [0.] * (m - numb_nonzero_eigs) sing_mat = np.diag(sing_mat) array_a = ortho_group.rvs(m).dot(sing_mat).dot(ortho_group.rvs(m)) # generate random symmetric matrix & define matrix b rand_array = np.random.uniform(-1., 1., (m, m)) sym_array = (rand_array + rand_array.T) / 2.0 array_b = np.dot(array_a, sym_array) # compute procrustes transformation & check results res = symmetric(array_a, array_b) assert_equal(res.s, None) assert_almost_equal(res.t, res.t.T, decimal=6) assert_almost_equal(res.error, 0.0, decimal=6)
def test_symmetric_scaled_shifted_tranformed_4by3(): r"""Test symmetric by 4by3 array with translation and scaling.""" # define an arbitrary array_a, translation matrix & symmetric matrix array_a = np.array([[245.0, 122.4, 538.5], [122.5, 252.2, 352.2], [152.5, 515.2, 126.5], [357.5, 312.5, 225.5]]) shift = np.array([[19.3, 14.2, 13.1], [19.3, 14.2, 13.1], [19.3, 14.2, 13.1], [19.3, 14.2, 13.1]]) sym_array = np.dot( np.array([[111.4, 144.9, 249.6]]).T, np.array([[111.4, 144.9, 249.6]])) # define array_b by scaling, translating and transforming array_a array_b = 312.5 * array_a + shift array_b = np.dot(array_b, sym_array) # compute procrustes transformation res = symmetric(array_a, array_b, translate=True, scale=True) # check transformation is symmetric & error is zero assert_almost_equal(res["array_u"], res["array_u"].T, decimal=6) assert_almost_equal(res["error"], 0.0, decimal=6)
def test_symmetric_scaled_shifted_tranformed(): # define an arbitrary array_a, translation matrix & symmetric matrix array_a = np.array([[5, 2, 8], [2, 2, 3], [1, 5, 6], [7, 3, 2]], dtype=float) shift = np.array([[9., 4., 3.], [9., 4., 3.], [9., 4., 3.], [9., 4., 3.]]) sym_array = np.dot(np.array([[1, 4, 9]]).T, np.array([[1, 4, 9]])) # define array_b by scaling, translating and transforming array_a array_b = 614.5 * array_a + shift array_b = np.dot(array_b, sym_array) # compute procrustes transformation new_a, new_b, array_x, e_opt = symmetric(array_a, array_b, translate=True, scale=True) # check transformation is symmetric & error is zero assert_almost_equal(array_x, array_x.T, decimal=6) assert_almost_equal(e_opt, 0, decimal=6)
def test_symmetric_with_small_values(m, n): r"""Test symmetric by arrays with small values.""" # define an arbitrary array_a, translation matrix & symmetric matrix array_a = np.random.uniform(0.0, 1.0e-6, (m, n)) # Define shift to the rows of the matrices. This repeats a random matrix of size n, m times. shift = np.tile(np.random.uniform(-1.0e-6, 1.0e-6, (n, )), (m, 1)) # Random symmetric matrix. rand_array = np.random.uniform(-1.0, 1.0, (n, n)) sym_array = (rand_array + rand_array.T) / 2.0 # define array_b by scaling, translating and transforming array_a array_b = 6.61e-4 * array_a + shift array_b = np.dot(array_b, sym_array) # compute procrustes transformation res = symmetric(array_a, array_b, translate=True, scale=True) # check transformation is symmetric & error is zero assert_equal(res.s, None) assert_almost_equal(res.t, res.t.T, decimal=6) assert_almost_equal(res.error, 0.0, decimal=5)
def test_symmetric_with_unpadding(m, n, add_cols, add_rows): r"""Test symmetric without translation and scaling.""" # define arbitrary array and generate random symmetric transformation with rank 1. array_a = np.random.uniform(-10.0, 10.0, (m, n)) rand_array = np.random.uniform(-10., 10., (n, )) sym_array = np.outer(rand_array.T, rand_array) # define array_b by transforming array_a and padding with zero array_b = np.dot(array_a, sym_array) array_b = np.concatenate((array_b, np.zeros((m, add_cols))), axis=1) array_b = np.concatenate((array_b, np.zeros((add_rows, n + add_cols))), axis=0) # compute procrustes transformation res = symmetric(array_a, array_b, unpad_col=True, unpad_row=True) # check transformation is symmetric & error is zero assert_almost_equal(res.t, res.t.T, decimal=6) assert_almost_equal(res.error, 0.0, decimal=6) assert_equal(res.s, None) assert_almost_equal(res.new_a.dot(res.t), res.new_b, decimal=6)
def test_symmetric_transformed(): # define arbitrary array and symmetric transformation array_a = np.array([[1, 2, 4, 5], [5, 7, 3, 3], [1, 5, 1, 9], [1, 5, 2, 7], [5, 7, 9, 0]]) sym_array = np.dot(np.array([[1, 7, 4, 9]]).T, np.array([[1, 7, 4, 9]])) # define array_b by transforming array_a and padding with zero array_b = np.dot(array_a, sym_array) array_b = np.concatenate((array_b, np.zeros((5, 2))), axis=1) array_b = np.concatenate((array_b, np.zeros((8, 6))), axis=0) # compute procrustes transformation new_a, new_b, array_x, e_opt = symmetric(array_a, array_b, translate=False, scale=False) # check transformation is symmetric & error is zero assert_almost_equal(array_x, array_x.T, decimal=6) assert_almost_equal(array_x, sym_array, decimal=6) assert_almost_equal(e_opt, 0.0, decimal=6)
def test_symmetric_scaled_shifted_transformed(m, n): r"""Test symmetric with translation and scaling.""" # define an arbitrary array_a, translation matrix & symmetric matrix array_a = np.random.uniform(-10.0, 10.0, (m, n)) # Define shift to the rows of the matrices. This repeats a random matrix of size n, m times. shift = np.tile(np.random.uniform(-10.0, 10.0, (n, )), (m, 1)) # Generate random array with rank with which ever is the smallest. rand_array = np.random.uniform(-10., 10., (m, n)) sym_array = np.dot(rand_array.T, rand_array) # define array_b by scaling, translating and transforming array_a array_b = 614.5 * array_a + shift array_b = np.dot(array_b, sym_array) # compute procrustes transformation res = symmetric(array_a, array_b, translate=True, scale=True) # check transformation is symmetric & error is zero assert_almost_equal(res.t, res.t.T, decimal=6) assert_almost_equal(res.new_a.dot(res.t), res.new_b, decimal=6) assert_equal(res.s, None) assert_almost_equal(res.error, 0.0, decimal=6)
def test_symmetric(): r"""Test symmetric by arrays with small values.""" # define an arbitrary array_a, translation matrix & symmetric matrix array_a = np.array([[5.52e-5, 2.15e-5, 8.12e-5], [2.14e-5, 2.22e-5, 3.14e-5], [1.11e-5, 5.94e-5, 6.58e-5], [7.15e-5, 3.62e-5, 2.24e-5]]) shift = np.array([[9.42e-6, 4.32e-6, 3.22e-5], [9.42e-6, 4.32e-6, 3.22e-5], [9.42e-6, 4.32e-6, 3.22e-5], [9.42e-6, 4.32e-6, 3.22e-5]]) sym_array = np.dot( np.array([[5.2, 6.7, 3.5]]).T, np.array([[5.2, 6.7, 3.5]])) # define array_b by scaling, translating and transforming array_a array_b = 6.61e-4 * array_a + shift array_b = np.dot(array_b, sym_array) # compute procrustes transformation res = symmetric(array_a, array_b, translate=True, scale=True) # check transformation is symmetric & error is zero assert_almost_equal(res["array_u"], res["array_u"].T, decimal=6) assert_almost_equal(res["error"], 0.0, decimal=6)
def test_symmetric(): # define an arbitrary array_a, translation matrix & symmetric matrix array_a = np.array([[5.52e-5, 2.15e-5, 8.12e-5], [2.14e-5, 2.22e-5, 3.14e-5], [1.11e-5, 5.94e-5, 6.58e-5], [7.15e-5, 3.62e-5, 2.24e-5]]) shift = np.array([[9.42e-6, 4.32e-6, 3.22e-5], [9.42e-6, 4.32e-6, 3.22e-5], [9.42e-6, 4.32e-6, 3.22e-5], [9.42e-6, 4.32e-6, 3.22e-5]]) sym_array = np.dot( np.array([[5.2, 6.7, 3.5]]).T, np.array([[5.2, 6.7, 3.5]])) # define array_b by scaling, translating and transforming array_a array_b = 6.61e-4 * array_a + shift array_b = np.dot(array_b, sym_array) # compute procrustes transformation new_a, new_b, array_x, e_opt = symmetric(array_a, array_b, translate=True, scale=True) # check transformation is symmetric & error is zero assert_almost_equal(array_x, array_x.T, decimal=6) assert_almost_equal(e_opt, 0, decimal=6)