def test_matvec_adjoint(fn): # Square cases sparse_mat = _sparse_matrix(fn) dense_mat = _dense_matrix(fn) op_sparse = MatVecOperator(sparse_mat, fn, fn) op_dense = MatVecOperator(dense_mat, fn, fn) # Just test if it runs, nothing interesting to test here op_sparse.adjoint op_dense.adjoint # Rectangular case rect_mat = 2 * np.eye(2, 3) r2, r3 = Rn(2), Rn(3) c2 = Cn(2) op = MatVecOperator(rect_mat, r3, r2) op_adj = op.adjoint assert op_adj.domain == op.range assert op_adj.range == op.domain assert np.array_equal(op_adj.matrix, op.matrix.conj().T) assert np.array_equal(op_adj.adjoint.matrix, op.matrix) # The operator Rn -> Cn has no adjoint op_noadj = MatVecOperator(rect_mat, r3, c2) with pytest.raises(NotImplementedError): op_noadj.adjoint
def test_matvec_call(fn): # Square cases sparse_mat = _sparse_matrix(fn) dense_mat = _dense_matrix(fn) xarr, x = example_vectors(fn) op_sparse = MatVecOperator(sparse_mat, fn, fn) op_dense = MatVecOperator(dense_mat, fn, fn) yarr_sparse = sparse_mat.dot(xarr) yarr_dense = dense_mat.dot(xarr) # Out-of-place y = op_sparse(x) assert all_almost_equal(y, yarr_sparse) y = op_dense(x) assert all_almost_equal(y, yarr_dense) # In-place y = fn.element() op_sparse(x, out=y) assert all_almost_equal(y, yarr_sparse) y = fn.element() op_dense(x, out=y) assert all_almost_equal(y, yarr_dense) # Rectangular case rect_mat = 2 * np.eye(2, 3) r2, r3 = Rn(2), Rn(3) op = MatVecOperator(rect_mat, r3, r2) xarr = np.arange(3, dtype=float) x = r3.element(xarr) yarr = rect_mat.dot(xarr) # Out-of-place y = op(x) assert all_almost_equal(y, yarr) # In-place y = r2.element() op(x, out=y) assert all_almost_equal(y, yarr)
def test_matrix_representation(): # Verify that the matrix representation function returns the correct matrix n = 3 A = np.random.rand(n, n) Aop = MatVecOperator(A) the_matrix = matrix_representation(Aop) assert almost_equal(np.sum(np.abs(A - the_matrix)), 1e-6)
def test_matvec_simple_properties(): # Matrix - always ndarray in for dense input, scipy.sparse.spmatrix else rect_mat = 2 * np.eye(2, 3) r2 = Rn(2) r3 = Rn(3) op = MatVecOperator(rect_mat, r3, r2) assert isinstance(op.matrix, np.ndarray) op = MatVecOperator(np.asmatrix(rect_mat), r3, r2) assert isinstance(op.matrix, np.ndarray) op = MatVecOperator(rect_mat.tolist(), r3, r2) assert isinstance(op.matrix, np.ndarray) assert not op.matrix_issparse sparse_mat = _sparse_matrix(Rn(5)) op = MatVecOperator(sparse_mat, Rn(5), Rn(5)) assert isinstance(op.matrix, sp.sparse.spmatrix) assert op.matrix_issparse
def test_matrix_representation_product_to_product_two(): # Verify that the matrix representation function returns the correct matrix n = 3 rn = odl.Rn(n) A = np.random.rand(n, n) Aop = MatVecOperator(A) B = np.random.rand(n, n) Bop = MatVecOperator(B) ran_and_dom = ProductSpace(rn, 2) AB_matrix = np.vstack([np.hstack([A, np.zeros((n, n))]), np.hstack([np.zeros((n, n)), B])]) ABop = ProductSpaceOperator([[Aop, 0], [0, Bop]], ran_and_dom, ran_and_dom) the_matrix = matrix_representation(ABop) assert almost_equal(np.sum(np.abs(AB_matrix - the_matrix)), 1e-6)
def test_matrix_representation_lin_space_to_product(): # Verify that the matrix representation function returns the correct matrix n = 3 rn = odl.Rn(n) A = np.random.rand(n, n) Aop = MatVecOperator(A) m = 2 rm = odl.Rn(m) B = np.random.rand(m, n) Bop = MatVecOperator(B) dom = ProductSpace(rn, 1) ran = ProductSpace(rn, rm) AB_matrix = np.vstack([A, B]) ABop = ProductSpaceOperator([[Aop], [Bop]], dom, ran) the_matrix = matrix_representation(ABop) assert almost_equal(np.sum(np.abs(AB_matrix - the_matrix)), 1e-6)
def test_matvec_init(fn): # Square matrices, sparse and dense sparse_mat = _sparse_matrix(fn) dense_mat = _dense_matrix(fn) MatVecOperator(sparse_mat, fn, fn) MatVecOperator(dense_mat, fn, fn) # Test defaults op_float = MatVecOperator([[1.0, 2], [-1, 0.5]]) assert isinstance(op_float.domain, Fn) assert op_float.domain.is_rn assert isinstance(op_float.range, Fn) assert op_float.domain.is_rn op_complex = MatVecOperator([[1.0, 2 + 1j], [-1 - 1j, 0.5]]) assert isinstance(op_complex.domain, Fn) assert op_complex.domain.is_cn assert isinstance(op_complex.range, Fn) assert op_complex.domain.is_cn op_int = MatVecOperator([[1, 2], [-1, 0]]) assert isinstance(op_int.domain, Fn) assert op_int.domain.dtype == int assert isinstance(op_int.range, Fn) assert op_int.domain.dtype == int # Rectangular rect_mat = 2 * np.eye(2, 3) r2 = Rn(2) r3 = Rn(3) MatVecOperator(rect_mat, r3, r2) with pytest.raises(ValueError): MatVecOperator(rect_mat, r2, r2) with pytest.raises(ValueError): MatVecOperator(rect_mat, r3, r3) with pytest.raises(ValueError): MatVecOperator(rect_mat, r2, r3) # Rn to Cn okay MatVecOperator(rect_mat, r3, Cn(2)) # Cn to Rn not okay (no safe cast) with pytest.raises(TypeError): MatVecOperator(rect_mat, Cn(3), r2) # Complex matrix between real spaces not okay rect_complex_mat = rect_mat + 1j with pytest.raises(TypeError): MatVecOperator(rect_complex_mat, r3, r2) # Init with array-like structure (including numpy.matrix) MatVecOperator(rect_mat.tolist(), r3, r2) MatVecOperator(np.asmatrix(rect_mat), r3, r2)