def test_operator_sum(dom_eq_ran): """Check operator sum against NumPy reference.""" if dom_eq_ran: mat1 = np.random.rand(3, 3) mat2 = np.random.rand(3, 3) else: mat1 = np.random.rand(4, 3) mat2 = np.random.rand(4, 3) op1 = MultiplyAndSquareOp(mat1) op2 = MultiplyAndSquareOp(mat2) xarr, x = noise_elements(op1.domain) # Explicit instantiation sum_op = OperatorSum(op1, op2) assert not sum_op.is_linear check_call(sum_op, x, mult_sq_np(mat1, xarr) + mult_sq_np(mat2, xarr)) # Using operator overloading check_call(op1 + op2, x, mult_sq_np(mat1, xarr) + mult_sq_np(mat2, xarr)) # Verify that unmatched operator domains fail op_wrong_dom = MultiplyAndSquareOp(mat1[:, :-1]) with pytest.raises(OpTypeError): OperatorSum(op1, op_wrong_dom) # Verify that unmatched operator ranges fail op_wrong_ran = MultiplyAndSquareOp(mat1[:-1, :]) with pytest.raises(OpTypeError): OperatorSum(op1, op_wrong_ran)
def test_nonlinear_addition(): # Test operator addition A = np.random.rand(4, 3) B = np.random.rand(4, 3) x = np.random.rand(3) Aop = MultiplyAndSquareOp(A) Bop = MultiplyAndSquareOp(B) xvec = Aop.domain.element(x) # Explicit instantiation C = OperatorSum(Aop, Bop) assert not C.is_linear assert all_almost_equal(C(xvec), mult_sq_np(A, x) + mult_sq_np(B, x)) # Using operator overloading assert all_almost_equal((Aop + Bop)(xvec), mult_sq_np(A, x) + mult_sq_np(B, x)) # Verify that unmatched operators domains fail C = np.random.rand(4, 4) Cop = MultiplyAndSquareOp(C) with pytest.raises(TypeError): C = OperatorSum(Aop, Cop)
def test_linear_addition(): A = np.random.rand(4, 3) B = np.random.rand(4, 3) x = np.random.rand(3) y = np.random.rand(4) Aop = MatVecOperator(A) Bop = MatVecOperator(B) xvec = Aop.domain.element(x) yvec = Aop.range.element(y) # Explicit instantiation C = OperatorSum(Aop, Bop) assert C.is_linear assert C.adjoint.is_linear assert all_almost_equal(C(xvec), np.dot(A, x) + np.dot(B, x)) assert all_almost_equal(C.adjoint(yvec), np.dot(A.T, y) + np.dot(B.T, y)) # Using operator overloading assert all_almost_equal((Aop + Bop)(xvec), np.dot(A, x) + np.dot(B, x)) assert all_almost_equal((Aop + Bop).adjoint(yvec), np.dot(A.T, y) + np.dot(B.T, y))
def test_linear_operator_addition(dom_eq_ran): """Check call and adjoint of a sum of linear operators.""" if dom_eq_ran: mat1 = np.random.rand(3, 3) mat2 = np.random.rand(3, 3) else: mat1 = np.random.rand(4, 3) mat2 = np.random.rand(4, 3) op1 = MatrixOperator(mat1) op2 = MatrixOperator(mat2) xarr, x = noise_elements(op1.domain) yarr, y = noise_elements(op1.range) # Explicit instantiation sum_op = OperatorSum(op1, op2) assert sum_op.is_linear assert sum_op.adjoint.is_linear check_call(sum_op, x, np.dot(mat1, xarr) + np.dot(mat2, xarr)) check_call(sum_op.adjoint, y, np.dot(mat1.T, yarr) + np.dot(mat2.T, yarr)) # Using operator overloading check_call(op1 + op2, x, np.dot(mat1, xarr) + np.dot(mat2, xarr)) check_call((op1 + op2).adjoint, y, np.dot(mat1.T, yarr) + np.dot(mat2.T, yarr))
def test_functional_addition(): r3 = odl.Rn(3) Aop = SumFunctional(r3) Bop = SumFunctional(r3) x = r3.element([1, 2, 3]) y = 1 # Explicit instantiation C = OperatorSum(Aop, Bop) assert C.is_linear assert C.adjoint.is_linear assert C(x) == 2 * np.sum(x) # Test adjoint assert all_almost_equal(C.adjoint(y), y * 2 * np.ones(3)) assert all_almost_equal(C.adjoint.adjoint(x), C(x)) # Using operator overloading assert (Aop + Bop)(x) == 2 * np.sum(x) assert all_almost_equal((Aop + Bop).adjoint(y), y * 2 * np.ones(3))