def test_element_setitem_single(): H = odl.ProductSpace(odl.rn(1), odl.rn(2)) x1 = H[0].element([0]) x2 = H[1].element([1, 2]) x = H.element([x1, x2]) x1_1 = H[0].element([1]) x[-2] = x1_1 assert x[-2] is x1_1 x2_1 = H[1].element([3, 4]) x[-1] = x2_1 assert x[-1] is x2_1 x1_2 = H[0].element([5]) x[0] = x1_2 x2_2 = H[1].element([3, 4]) x[1] = x2_2 assert x[1] is x2_2 with pytest.raises(IndexError): x[-3] = x2 x[2] = x1
def test_fixed_disp_init(): """Verify that the init method and checks work properly.""" space = odl.uniform_discr(0, 1, 5) disp_field = space.tangent_bundle.element( disp_field_factory(space.ndim)) # Valid input print(LinDeformFixedDisp(disp_field)) print(LinDeformFixedDisp(disp_field, templ_space=space)) # Non-valid input with pytest.raises(TypeError): # displacement not ProductSpaceElement LinDeformFixedDisp(space.one()) with pytest.raises(TypeError): # templ_space not DiscreteLp LinDeformFixedDisp(disp_field, space.tangent_bundle) with pytest.raises(TypeError): # templ_space not a power space bad_pspace = odl.ProductSpace(space, odl.rn(3)) LinDeformFixedDisp(disp_field, bad_pspace) with pytest.raises(TypeError): # templ_space not based on DiscreteLp bad_pspace = odl.ProductSpace(odl.rn(2), 1) LinDeformFixedDisp(disp_field, bad_pspace) with pytest.raises(TypeError): # wrong dtype on templ_space wrong_dtype = odl.ProductSpace(space.astype(complex), 1) LinDeformFixedDisp(disp_field, wrong_dtype) with pytest.raises(ValueError): # vector field spaces don't match bad_space = odl.uniform_discr(0, 1, 10) LinDeformFixedDisp(disp_field, bad_space)
def test_ufuncs(): # Cannot use fixture due to bug in pytest H = odl.ProductSpace(odl.rn(1), odl.rn(2)) # one arg x = H.element([[-1], [-2, -3]]) z = x.ufunc.absolute() assert all_almost_equal(z, [[1], [2, 3]]) # one arg with out x = H.element([[-1], [-2, -3]]) y = H.element() z = x.ufunc.absolute(out=y) assert y is z assert all_almost_equal(z, [[1], [2, 3]]) # Two args x = H.element([[1], [2, 3]]) y = H.element([[4], [5, 6]]) w = H.element() z = x.ufunc.add(y) assert all_almost_equal(z, [[5], [7, 9]]) # Two args with out x = H.element([[1], [2, 3]]) y = H.element([[4], [5, 6]]) w = H.element() z = x.ufunc.add(y, out=w) assert w is z assert all_almost_equal(z, [[5], [7, 9]])
def test_element_setitem_fancy(): """Test assignment of pspace parts with lists.""" pspace = odl.ProductSpace(odl.rn(1), odl.rn(2), odl.rn(3)) x0 = pspace[0].element([0]) x1 = pspace[1].element([1, 2]) x2 = pspace[2].element([3, 4, 5]) x = pspace.element([x0, x1, x2]) old_x0 = x[0] old_x2 = x[2] # Check that values are set, but identity is preserved new_x0 = pspace[0].element([6]) new_x2 = pspace[2].element([7, 8, 9]) x[[0, 2]] = pspace[[0, 2]].element([new_x0, new_x2]) assert x[[0, 2]][0] is old_x0 assert x[[0, 2]][0] == new_x0 assert x[[0, 2]][1] is old_x2 assert x[[0, 2]][1] == new_x2 # Set values with sequences of scalars x[[0, 2]] = [-1, -2] assert x[[0, 2]][0] is old_x0 assert all_equal(x[[0, 2]][0], [-1]) assert x[[0, 2]][1] is old_x2 assert all_equal(x[[0, 2]][1], [-2, -2, -2])
def test_init(exponent): # Validate that the different init patterns work and do not crash. space = odl.FunctionSpace(odl.IntervalProd(0, 1)) part = odl.uniform_partition_fromintv(space.domain, 10) rn = odl.rn(10, exponent=exponent) odl.DiscreteLp(space, part, rn, exponent=exponent) odl.DiscreteLp(space, part, rn, exponent=exponent, interp='linear') # Normal discretization of unit interval with complex complex_space = odl.FunctionSpace(odl.IntervalProd(0, 1), field=odl.ComplexNumbers()) cn = odl.cn(10, exponent=exponent) odl.DiscreteLp(complex_space, part, cn, exponent=exponent) space = odl.FunctionSpace(odl.IntervalProd([0, 0], [1, 1])) part = odl.uniform_partition_fromintv(space.domain, (10, 10)) rn = odl.rn(100, exponent=exponent) odl.DiscreteLp(space, part, rn, exponent=exponent, interp=['nearest', 'linear']) # Real space should not work with complex with pytest.raises(ValueError): odl.DiscreteLp(space, part, cn) # Complex space should not work with reals with pytest.raises(ValueError): odl.DiscreteLp(complex_space, part, rn) # Wrong size of underlying space rn_wrong_size = odl.rn(20) with pytest.raises(ValueError): odl.DiscreteLp(space, part, rn_wrong_size)
def test_element_setitem_single(): """Test assignment of pspace parts with single indices.""" pspace = odl.ProductSpace(odl.rn(1), odl.rn(2)) x0 = pspace[0].element([0]) x1 = pspace[1].element([1, 2]) x = pspace.element([x0, x1]) old_x0 = x[0] old_x1 = x[1] # Check that values are set, but identity is preserved new_x0 = pspace[0].element([1]) x[-2] = new_x0 assert x[-2] == new_x0 assert x[-2] is old_x0 new_x1 = pspace[1].element([3, 4]) x[-1] = new_x1 assert x[-1] == new_x1 assert x[-1] is old_x1 # Set values with scalars x[1] = -1 assert all_equal(x[1], [-1, -1]) assert x[1] is old_x1 # Check that out-of-bounds indices raise IndexError with pytest.raises(IndexError): x[-3] = x1 with pytest.raises(IndexError): x[2] = x0
def test_reductions(): H = odl.ProductSpace(odl.rn(1), odl.rn(2)) x = H.element([[1], [2, 3]]) assert x.ufunc.sum() == 6.0 assert x.ufunc.prod() == 6.0 assert x.ufunc.min() == 1.0 assert x.ufunc.max() == 3.0
def test_custom_funcs(): # Checking the standard 1-norm and standard inner product, just to # see that the functions are handled correctly. r2 = odl.rn(2) r2x = r2.element([1, -1]) r2y = r2.element([-2, 3]) # inner = -5, dist = 5, norms = (sqrt(2), sqrt(13)) r3 = odl.rn(3) r3x = r3.element([3, 4, 4]) r3y = r3.element([1, -2, 1]) # inner = -1, dist = 7, norms = (sqrt(41), sqrt(6)) pspace_2 = odl.ProductSpace(r2, r3, exponent=2.0) x = pspace_2.element((r2x, r3x)) y = pspace_2.element((r2y, r3y)) pspace_custom = odl.ProductSpace(r2, r3, inner=custom_inner) xc = pspace_custom.element((r2x, r3x)) yc = pspace_custom.element((r2y, r3y)) assert almost_equal(x.inner(y), xc.inner(yc)) pspace_1 = odl.ProductSpace(r2, r3, exponent=1.0) x = pspace_1.element((r2x, r3x)) y = pspace_1.element((r2y, r3y)) pspace_custom = odl.ProductSpace(r2, r3, norm=custom_norm) xc = pspace_custom.element((r2x, r3x)) assert almost_equal(x.norm(), xc.norm()) pspace_custom = odl.ProductSpace(r2, r3, dist=custom_dist) xc = pspace_custom.element((r2x, r3x)) yc = pspace_custom.element((r2y, r3y)) assert almost_equal(x.dist(y), xc.dist(yc)) with pytest.raises(TypeError): odl.ProductSpace(r2, r3, a=1) # extra keyword argument with pytest.raises(ValueError): odl.ProductSpace(r2, r3, norm=custom_norm, inner=custom_inner) with pytest.raises(ValueError): odl.ProductSpace(r2, r3, dist=custom_dist, inner=custom_inner) with pytest.raises(ValueError): odl.ProductSpace(r2, r3, norm=custom_norm, dist=custom_dist) with pytest.raises(ValueError): odl.ProductSpace(r2, r3, norm=custom_norm, exponent=1.0) with pytest.raises(ValueError): odl.ProductSpace(r2, r3, norm=custom_norm, weight=2.0) with pytest.raises(ValueError): odl.ProductSpace(r2, r3, dist=custom_dist, weight=2.0) with pytest.raises(ValueError): odl.ProductSpace(r2, r3, inner=custom_inner, weight=2.0)
def __init__(self, matrix, domain=None, range=None): dom = (odl.rn(matrix.shape[1]) if domain is None else domain) ran = (odl.rn(matrix.shape[0]) if range is None else range) super().__init__(dom, ran) self.matrix = matrix
def test_getitem_fancy(): r1 = odl.rn(1) r2 = odl.rn(2) r3 = odl.rn(3) H = odl.ProductSpace(r1, r2, r3) assert H[[0, 2]] == odl.ProductSpace(r1, r3) assert H[[0, 2]][0] is r1 assert H[[0, 2]][1] is r3
def test_getitem_slice(): r1 = odl.rn(1) r2 = odl.rn(2) r3 = odl.rn(3) H = odl.ProductSpace(r1, r2, r3) assert H[:2] == odl.ProductSpace(r1, r2) assert H[:2][0] is r1 assert H[:2][1] is r2 assert H[3:] == odl.ProductSpace(field=r1.field)
def test_element_getitem_fancy(): H = odl.ProductSpace(odl.rn(1), odl.rn(2), odl.rn(3)) x1 = H[0].element([0]) x2 = H[1].element([1, 2]) x3 = H[2].element([3, 4, 5]) x = H.element([x1, x2, x3]) assert x[[0, 2]].space == H[[0, 2]] assert x[[0, 2]][0] is x1 assert x[[0, 2]][1] is x3
def test_element_getitem_slice(): H = odl.ProductSpace(odl.rn(1), odl.rn(2), odl.rn(3)) x0 = H[0].element([0]) x1 = H[1].element([1, 2]) x2 = H[2].element([3, 4, 5]) x = H.element([x0, x1, x2]) assert x[:2].space == H[:2] assert x[:2][0] is x0 assert x[:2][1] is x1
def test_getitem_single(): r1 = odl.rn(1) r2 = odl.rn(2) H = odl.ProductSpace(r1, r2) assert H[-2] is r1 assert H[-1] is r2 assert H[0] is r1 assert H[1] is r2 with pytest.raises(IndexError): H[-3] H[2]
def test_mixed_space(): """Verify that a mixed productspace is handled properly.""" r2_1 = odl.rn(2, dtype='float64') r2_2 = odl.rn(2, dtype='float32') pspace = odl.ProductSpace(r2_1, r2_2) assert not pspace.is_power_space assert pspace.spaces[0] is r2_1 assert pspace.spaces[1] is r2_2 # dtype not well defined for this space with pytest.raises(AttributeError): pspace.dtype
def test_element_setitem_slice(): H = odl.ProductSpace(odl.rn(1), odl.rn(2), odl.rn(3)) x1 = H[0].element([0]) x2 = H[1].element([1, 2]) x3 = H[2].element([3, 4, 5]) x = H.element([x1, x2, x3]) x1_new = H[0].element([6]) x2_new = H[1].element([7, 8]) x[:2] = H[:2].element([x1_new, x2_new]) assert x[:2][0] is x1_new assert x[:2][1] is x2_new
def test_element_setitem_fancy(): H = odl.ProductSpace(odl.rn(1), odl.rn(2), odl.rn(3)) x1 = H[0].element([0]) x2 = H[1].element([1, 2]) x3 = H[2].element([3, 4, 5]) x = H.element([x1, x2, x3]) x1_new = H[0].element([6]) x3_new = H[2].element([7, 8, 9]) x[[0, 2]] = H[[0, 2]].element([x1_new, x3_new]) assert x[[0, 2]][0] is x1_new assert x[[0, 2]][1] is x3_new
def test_element_getitem_single(): H = odl.ProductSpace(odl.rn(1), odl.rn(2)) x1 = H[0].element([0]) x2 = H[1].element([1, 2]) x = H.element([x1, x2]) assert x[-2] is x1 assert x[-1] is x2 assert x[0] is x1 assert x[1] is x2 with pytest.raises(IndexError): x[-3] x[2]
def test_element_equals(): H = odl.ProductSpace(odl.rn(1), odl.rn(2)) x = H.element([[0], [1, 2]]) assert x != 0 # test == not always true assert x == x x_2 = H.element([[0], [1, 2]]) assert x == x_2 x_3 = H.element([[3], [1, 2]]) assert x != x_3 x_4 = H.element([[0], [1, 3]]) assert x != x_4
def test_nonlinear_functional(): r3 = odl.rn(3) x = r3.element([1, 2, 3]) op = SumSquaredFunctional(r3) assert almost_equal(op(x), np.sum(x**2))
def test_functional(): r3 = odl.rn(3) x = r3.element([1, 2, 3]) op = SumFunctional(r3) assert op(x) == 6
def test_arithmetic(): """Test that all standard arithmetic works.""" space = odl.rn(3) # Create elements needed for later functional = odl.solvers.L2Norm(space).translated([1, 2, 3]) functional2 = odl.solvers.L2NormSquared(space) operator = odl.IdentityOperator(space) - space.element([4, 5, 6]) x = noise_element(functional.domain) y = noise_element(functional.domain) scalar = np.pi # Simple tests here, more in depth comes later assert functional(x) == functional(x) assert functional(x) != functional2(x) assert (scalar * functional)(x) == scalar * functional(x) assert (scalar * (scalar * functional))(x) == scalar**2 * functional(x) assert (functional * scalar)(x) == functional(scalar * x) assert ((functional * scalar) * scalar)(x) == functional(scalar**2 * x) assert (functional + functional2)(x) == functional(x) + functional2(x) assert (functional - functional2)(x) == functional(x) - functional2(x) assert (functional * operator)(x) == functional(operator(x)) assert all_almost_equal((y * functional)(x), y * functional(x)) assert all_almost_equal((y * (y * functional))(x), (y * y) * functional(x)) assert all_almost_equal((functional * y)(x), functional(y * x)) assert all_almost_equal(((functional * y) * y)(x), functional((y * y) * x))
def test_primal_dual_with_li(): """Test for the forward-backward solver with infimal convolution. The test is done by minimizing the functional ``(g @ l)(x)``, where ``(g @ l)(x) = inf_y { g(y) + l(x - y) }``, g is the indicator function on [-3, -1], and l(x) = 1/2||x||_2^2. The optimal solution to this problem is given by x in [-3, -1]. """ # Parameter values for the box constraint upper_lim = -1 lower_lim = -3 space = odl.rn(1) lin_ops = [odl.IdentityOperator(space)] g = [odl.solvers.IndicatorBox(space, lower=lower_lim, upper=upper_lim)] f = odl.solvers.ZeroFunctional(space) l = [odl.solvers.L2NormSquared(space)] # Centering around a point further away from [-3,-1]. x = space.element(10) douglas_rachford_pd(x, f, g, lin_ops, tau=0.5, sigma=[1.0], niter=20, l=l) assert lower_lim - 10 ** -LOW_ACCURACY <= float(x) assert float(x) <= upper_lim + 10 ** -LOW_ACCURACY
def test_power_method_opnorm_exceptions(): # Test the exceptions space = odl.rn(2) op = odl.IdentityOperator(space) with pytest.raises(ValueError): # Too small number of iterates power_method_opnorm(op, maxiter=0) with pytest.raises(ValueError): # Negative number of iterates power_method_opnorm(op, maxiter=-5) with pytest.raises(ValueError): # Input vector is zero power_method_opnorm(op, maxiter=2, xstart=space.zero()) with pytest.raises(ValueError): # Input vector in the nullspace op = odl.MatrixOperator([[0., 1.], [0., 0.]]) power_method_opnorm(op, maxiter=2, xstart=op.domain.one()) with pytest.raises(ValueError): # Uneven number of iterates for non square operator op = odl.MatrixOperator([[1., 2., 3.], [4., 5., 6.]]) power_method_opnorm(op, maxiter=1, xstart=op.domain.one())
def test_functional_scale(): r3 = odl.rn(3) Aop = SumFunctional(r3) x = r3.element([1, 2, 3]) y = 1 # Test a range of scalars (scalar multiplication could implement # optimizations for (-1, 0, 1). scalars = [-1.432, -1, 0, 1, 3.14] for scale in scalars: C = OperatorRightScalarMult(Aop, scale) assert C.is_linear assert C.adjoint.is_linear assert C(x) == scale * np.sum(x) assert all_almost_equal(C.adjoint(y), scale * y * np.ones(3)) assert all_almost_equal(C.adjoint.adjoint(x), C(x)) # Using operator overloading assert (scale * Aop)(x) == scale * np.sum(x) assert (Aop * scale)(x) == scale * np.sum(x) assert all_almost_equal((scale * Aop).adjoint(y), scale * y * np.ones(3)) assert all_almost_equal((Aop * scale).adjoint(y), scale * y * np.ones(3))
def test_element_1d(exponent): discr = odl.uniform_discr(0, 1, 3, impl='numpy', exponent=exponent) weight = 1.0 if exponent == float('inf') else discr.cell_volume dspace = odl.rn(3, exponent=exponent, weighting=weight) elem = discr.element() assert isinstance(elem, odl.DiscreteLpElement) assert elem.ntuple in dspace
def test_metric(): H = odl.rn(2) v11 = H.element([1, 2]) v12 = H.element([5, 3]) v21 = H.element([1, 2]) v22 = H.element([8, 9]) # 1-norm HxH = odl.ProductSpace(H, H, exponent=1.0) w1 = HxH.element([v11, v12]) w2 = HxH.element([v21, v22]) assert almost_equal(HxH.dist(w1, w2), H.dist(v11, v21) + H.dist(v12, v22)) # 2-norm HxH = odl.ProductSpace(H, H, exponent=2.0) w1 = HxH.element([v11, v12]) w2 = HxH.element([v21, v22]) assert almost_equal( HxH.dist(w1, w2), (H.dist(v11, v21) ** 2 + H.dist(v12, v22) ** 2) ** (1 / 2.0)) # inf norm HxH = odl.ProductSpace(H, H, exponent=float('inf')) w1 = HxH.element([v11, v12]) w2 = HxH.element([v21, v22]) assert almost_equal( HxH.dist(w1, w2), max(H.dist(v11, v21), H.dist(v12, v22)))
def test_pnorm(exponent): for fn in (odl.rn(3, exponent=exponent), odl.cn(3, exponent=exponent)): xarr, x = noise_elements(fn) correct_norm = np.linalg.norm(xarr, ord=exponent) assert almost_equal(fn.norm(x), correct_norm) assert almost_equal(x.norm(), correct_norm)
def test_getitem_single(): r1 = odl.rn(1) r2 = odl.rn(2) H = odl.ProductSpace(r1, r2) assert H[-2] is r1 assert H[-1] is r2 assert H[0] is r1 assert H[1] is r2 with pytest.raises(IndexError): H[-3] H[2] assert H[(1, )] == r2 with pytest.raises(IndexError): H[0, 1]
def test_element_getitem_multi(): """Test element access with multiple indices.""" pspace = odl.ProductSpace(odl.rn(1), odl.rn(2)) pspace2 = odl.ProductSpace(pspace, 3) pspace3 = odl.ProductSpace(pspace2, 2) z = pspace3.element([[[[1], [2, 3]], [[4], [5, 6]], [[7], [8, 9]]], [[[10], [12, 13]], [[14], [15, 16]], [[17], [18, 19]]]]) assert pspace3.shape == (2, 3, 2) assert z[0, 0, 0, 0] == 1 assert all_equal(z[0, 0, 1], [2, 3]) assert all_equal(z[0, 0], [[1], [2, 3]]) assert all_equal(z[0, 1:], [[[4], [5, 6]], [[7], [8, 9]]]) assert all_equal(z[0, 1:, 1], [[5, 6], [8, 9]]) assert all_equal(z[0, 1:, :, 0], [[[4], [5]], [[7], [8]]])
def test_gradient_init(): """Check initialization of ``Gradient``.""" space = odl.uniform_discr([0, 0], [1, 1], (4, 5)) vspace = space ** 2 op = Gradient(space) assert repr(op) != '' op = Gradient(range=vspace) assert repr(op) != '' op = Gradient(space, range=space.astype('float32') ** 2) assert repr(op) != '' op = Gradient(space, method='central') assert repr(op) != '' op = Gradient(space, pad_const=1) assert repr(op) != '' op = Gradient(space, pad_mode='order1') assert repr(op) != '' with pytest.raises(TypeError): Gradient(odl.rn(1)) with pytest.raises(TypeError): Gradient(space, range=space) with pytest.raises(ValueError): Gradient(space, range=space ** 3)
def test_divergence_init(): """Check initialization of ``Divergence``.""" space = odl.uniform_discr([0, 0], [1, 1], (4, 5)) vspace = space ** 2 op = Divergence(vspace) assert repr(op) != '' op = Divergence(range=space) assert repr(op) != '' op = Divergence(vspace, range=space.astype('float32')) assert repr(op) != '' op = Divergence(vspace, method='central') assert repr(op) != '' op = Divergence(vspace, pad_const=1) assert repr(op) != '' op = Divergence(vspace, pad_mode='order1') assert repr(op) != '' with pytest.raises(TypeError): Divergence(odl.rn(1) ** 2) with pytest.raises(TypeError): Divergence(vspace, range=vspace) with pytest.raises(ValueError): Divergence(space ** 3, range=space)
def space(request, tspace_impl): name = request.param.strip() if name == 'r10': return odl.rn(10, impl=tspace_impl) elif name == 'uniform_discr': return odl.uniform_discr(0, 1, 7, impl=tspace_impl)
def test_operators(arithmetic_op): # Test of the operators `+`, `-`, etc work as expected by numpy space = odl.rn(3) pspace = odl.ProductSpace(space, 2) # Interactions with scalars for scalar in [-31.2, -1, 0, 1, 2.13]: # Left op x_arr, x = noise_elements(pspace) if scalar == 0 and arithmetic_op in [operator.truediv, operator.itruediv]: # Check for correct zero division behaviour with pytest.raises(ZeroDivisionError): y = arithmetic_op(x, scalar) else: y_arr = arithmetic_op(x_arr, scalar) y = arithmetic_op(x, scalar) assert all_almost_equal([x, y], [x_arr, y_arr]) # Right op x_arr, x = noise_elements(pspace) y_arr = arithmetic_op(scalar, x_arr) y = arithmetic_op(scalar, x) assert all_almost_equal([x, y], [x_arr, y_arr]) # Verify that the statement z=op(x, y) gives equivalent results to NumPy x_arr, x = noise_elements(space, 1) y_arr, y = noise_elements(pspace, 1) # non-aliased left if arithmetic_op in [operator.iadd, operator.isub, operator.itruediv, operator.imul]: # Check for correct error since in-place op is not possible here with pytest.raises(TypeError): z = arithmetic_op(x, y) else: z_arr = arithmetic_op(x_arr, y_arr) z = arithmetic_op(x, y) assert all_almost_equal([x, y, z], [x_arr, y_arr, z_arr]) # non-aliased right z_arr = arithmetic_op(y_arr, x_arr) z = arithmetic_op(y, x) assert all_almost_equal([x, y, z], [x_arr, y_arr, z_arr]) # aliased operation z_arr = arithmetic_op(y_arr, y_arr) z = arithmetic_op(y, y) assert all_almost_equal([x, y, z], [x_arr, y_arr, z_arr])
def test_primal_dual_l1(): """Verify that the correct value is returned for l1 dist optimization. Solves the optimization problem min_x ||x - data_1||_1 + 0.5 ||x - data_2||_1 which has optimum value data_1. """ # Define the space space = odl.rn(5) # Operator L = [odl.IdentityOperator(space)] # Data data_1 = odl.util.testutils.noise_element(space) data_2 = odl.util.testutils.noise_element(space) # Proximals f = odl.solvers.L1Norm(space).translated(data_1) g = [0.5 * odl.solvers.L1Norm(space).translated(data_2)] # Solve with f term dominating x = space.zero() douglas_rachford_pd(x, f, g, L, tau=3.0, sigma=[1.0], niter=10) assert all_almost_equal(x, data_1, places=2)
def test_metric(): H = odl.rn(2) v11 = H.element([1, 2]) v12 = H.element([5, 3]) v21 = H.element([1, 2]) v22 = H.element([8, 9]) # 1-norm HxH = odl.ProductSpace(H, H, exponent=1.0) w1 = HxH.element([v11, v12]) w2 = HxH.element([v21, v22]) assert (HxH.dist(w1, w2) == pytest.approx(H.dist(v11, v21) + H.dist(v12, v22))) # 2-norm HxH = odl.ProductSpace(H, H, exponent=2.0) w1 = HxH.element([v11, v12]) w2 = HxH.element([v21, v22]) assert (HxH.dist(w1, w2) == pytest.approx( (H.dist(v11, v21)**2 + H.dist(v12, v22)**2)**0.5)) # inf norm HxH = odl.ProductSpace(H, H, exponent=float('inf')) w1 = HxH.element([v11, v12]) w2 = HxH.element([v21, v22]) assert (HxH.dist(w1, w2) == pytest.approx( max(H.dist(v11, v21), H.dist(v12, v22))))
def test_gradient(space, method, padding): """Discretized spatial gradient operator.""" places = 2 if space.dtype == np.float32 else 4 with pytest.raises(TypeError): Gradient(odl.rn(1), method=method) if isinstance(padding, tuple): pad_mode, pad_const = padding else: pad_mode, pad_const = padding, 0 # DiscreteLp Vector dom_vec = noise_element(space) dom_vec_arr = dom_vec.asarray() # gradient grad = Gradient(space, method=method, pad_mode=pad_mode, pad_const=pad_const) grad_vec = grad(dom_vec) assert len(grad_vec) == space.ndim # computation of gradient components with helper function for axis, dx in enumerate(space.cell_sides): diff = finite_diff(dom_vec_arr, axis=axis, dx=dx, method=method, pad_mode=pad_mode, pad_const=pad_const) assert all_almost_equal(grad_vec[axis].asarray(), diff) # Test adjoint operator derivative = grad.derivative() ran_vec = noise_element(derivative.range) deriv_grad_vec = derivative(dom_vec) adj_grad_vec = derivative.adjoint(ran_vec) lhs = ran_vec.inner(deriv_grad_vec) rhs = dom_vec.inner(adj_grad_vec) # Check not to use trivial data assert lhs != 0 assert rhs != 0 assert almost_equal(lhs, rhs, places=places) # Higher-dimensional arrays lin_size = 3 for ndim in [1, 3, 6]: space = odl.uniform_discr([0.] * ndim, [1.] * ndim, [lin_size] * ndim) dom_vec = odl.phantom.cuboid(space, [0.2] * ndim, [0.8] * ndim) grad = Gradient(space, method=method, pad_mode=pad_mode, pad_const=pad_const) grad(dom_vec)
def test_nonlinear_functional(): r3 = odl.rn(3) x = r3.element([1, 2, 3]) op = SumSquaredFunctional(r3) assert almost_equal(op(x), np.sum(x ** 2))
def test_nearest_interpolation_1d_variants(): intv = odl.IntervalProd(0, 1) part = odl.uniform_partition_fromintv(intv, 5, nodes_on_bdry=False) # Coordinate vectors are: # [0.1, 0.3, 0.5, 0.7, 0.9] space = odl.FunctionSpace(intv) dspace = odl.rn(part.size) # 'left' variant interp_op = NearestInterpolation(space, part, dspace, variant='left') function = interp_op([0, 1, 2, 3, 4]) # Testing two midpoints and the extreme values pts = np.array([0.4, 0.8, 0.0, 1.0]) true_arr = [1, 3, 0, 4] assert all_equal(function(pts), true_arr) # 'right' variant interp_op = NearestInterpolation(space, part, dspace, variant='right') function = interp_op([0, 1, 2, 3, 4]) # Testing two midpoints and the extreme values pts = np.array([0.4, 0.8, 0.0, 1.0]) true_arr = [2, 4, 0, 4] assert all_equal(function(pts), true_arr)
def __init__(self, q): assert all(qi.space == q[0].space for qi in q[1:]) super(KrylovSpaceEmbedding, self).__init__(domain=odl.rn(len(q)), range=q[0].space, linear=True) self.q = q
def test_discretizedspace_init(): """Test initialization and basic properties of DiscretizedSpace.""" # Real space part = odl.uniform_partition([0, 0], [1, 1], (2, 4)) tspace = odl.rn(part.shape) discr = DiscretizedSpace(part, tspace) assert discr.tspace == tspace assert discr.partition == part assert discr.exponent == tspace.exponent assert discr.axis_labels == ('$x$', '$y$') assert discr.is_real # Complex space tspace_c = odl.cn(part.shape) discr = DiscretizedSpace(part, tspace_c) assert discr.is_complex # Make sure repr shows something assert repr(discr) != '' # Error scenarios part_1d = odl.uniform_partition(0, 1, 2) with pytest.raises(ValueError): DiscretizedSpace(part_1d, tspace) # wrong dimensionality part_diffshp = odl.uniform_partition([0, 0], [1, 1], (3, 4)) with pytest.raises(ValueError): DiscretizedSpace(part_diffshp, tspace) # shape mismatch
def test_weighted_proximal_L1_norm_close(space): """Test for the weighted proximal of the L1 norm near zero""" # Set the space. space = odl.rn(5) # Define the functional on the space. func = odl.solvers.L1Norm(space) # Set the stepsize. sigma = [0.1, 0.2, 0.5, 1.0, 2.0] # Set the starting point. x = 0.5 * space.one() # Calculate the proximal point in-place and out-of-place p_ip = space.element() func.proximal(sigma)(x, out=p_ip) p_oop = func.proximal(sigma)(x) # Both should contain the same vector now. assert all_almost_equal(p_ip, p_oop) # Check if this equals the expected result. expected_result = [0.4, 0.3, 0.0, 0.0, 0.0] assert all_almost_equal(expected_result, p_ip)
def test_matrix_op_call(matrix): """Validate result from calls to matrix operators against Numpy.""" dense_matrix = matrix sparse_matrix = scipy.sparse.coo_matrix(dense_matrix) # Default 1d case dmat_op = MatrixOperator(dense_matrix) smat_op = MatrixOperator(sparse_matrix) xarr, x = noise_elements(dmat_op.domain) true_result = dense_matrix.dot(xarr) assert all_almost_equal(dmat_op(x), true_result) assert all_almost_equal(smat_op(x), true_result) out = dmat_op.range.element() dmat_op(x, out=out) assert all_almost_equal(out, true_result) smat_op(x, out=out) assert all_almost_equal(out, true_result) # Multi-dimensional case domain = odl.rn((2, 2, 4)) mat_op = MatrixOperator(dense_matrix, domain, axis=2) xarr, x = noise_elements(mat_op.domain) true_result = np.moveaxis(np.tensordot(dense_matrix, xarr, (1, 2)), 0, 2) assert all_almost_equal(mat_op(x), true_result) out = mat_op.range.element() mat_op(x, out=out) assert all_almost_equal(out, true_result)
def test_collocation_interpolation_identity(): """Check if collocation is left-inverse to interpolation.""" # Interpolation followed by collocation on the same grid should be # the identity rect = odl.IntervalProd([0, 0], [1, 1]) part = odl.uniform_partition_fromintv(rect, [4, 2]) space = odl.FunctionSpace(rect) tspace = odl.rn(part.shape) coll_op = PointCollocation(space, part, tspace) interp_ops = [ NearestInterpolation(space, part, tspace, variant='left'), NearestInterpolation(space, part, tspace, variant='right'), LinearInterpolation(space, part, tspace), PerAxisInterpolation(space, part, tspace, schemes=['linear', 'nearest']) ] values = np.arange(1, 9, dtype='float64').reshape(tspace.shape) for interp_op in interp_ops: ident_values = coll_op(interp_op(values)) assert all_almost_equal(ident_values, values)
def test_forward_backward_with_lin_ops(): """Test for the forward-backward solver with linear operatros. The test is done by minimizing ||x - b||_2^2 + ||alpha * x||_2^2. The general problem is of the form ``min_x f(x) + sum_i g_i(L_i x) + h(x)`` and here we take f = 0, g = ||.||_2^2, L = alpha * IndentityOperator, and h = ||. - b||_2^2. """ space = odl.rn(10) alpha = 0.1 b = noise_element(space) lin_ops = [alpha * odl.IdentityOperator(space)] g = [odl.solvers.L2NormSquared(space)] f = odl.solvers.ZeroFunctional(space) # Gradient of two-norm square h = odl.solvers.L2NormSquared(space).translated(b) x = noise_element(space) # Explicit solution: x_hat = (I^T * I + (alpha*I)^T * (alpha*I))^-1 * (I*b) x_global_min = b / (1 + alpha**2) forward_backward_pd(x, f, g, lin_ops, h, tau=0.5, sigma=[1.0], niter=20) assert all_almost_equal(x, x_global_min, places=LOW_ACCURACY)
def test_nearest_interpolation_2d_float(): """Test nearest neighbor interpolation in 2d.""" rect = odl.IntervalProd([0, 0], [1, 1]) part = odl.uniform_partition_fromintv(rect, [4, 2], nodes_on_bdry=False) # Coordinate vectors are: # [0.125, 0.375, 0.625, 0.875], [0.25, 0.75] fspace = odl.FunctionSpace(rect) tspace = odl.rn(part.shape) interp_op = NearestInterpolation(fspace, part, tspace) function = interp_op(np.reshape([0, 1, 2, 3, 4, 5, 6, 7], part.shape)) # Evaluate at single point val = function([0.3, 0.6]) # closest to index (1, 1) -> 3 assert val == 3.0 # Input array, with and without output array pts = np.array([[0.3, 0.6], [1.0, 1.0]]) true_arr = [3, 7] assert all_equal(function(pts.T), true_arr) out = np.empty(2, dtype='float64') function(pts.T, out=out) assert all_equal(out, true_arr) # Input meshgrid, with and without output array mg = sparse_meshgrid([0.3, 1.0], [0.4, 1.0]) # Indices: (1, 3) x (0, 1) true_mg = [[2, 3], [6, 7]] assert all_equal(function(mg), true_mg) out = np.empty((2, 2), dtype='float64') function(mg, out=out) assert all_equal(out, true_mg) assert repr(interp_op) != ''
def _test_getslice(slice): # Validate get against python list behaviour r6 = odl.rn(6) y = [0, 1, 2, 3, 4, 5] x = r6.element(y) assert all_equal(x[slice].data, y[slice])
def test_primal_dual_with_li(): """Test for the forward-backward solver with infimal convolution. The test is done by minimizing the functional ``(g @ l)(x)``, where ``(g @ l)(x) = inf_y { g(y) + l(x - y) }``, g is the indicator function on [-3, -1], and l(x) = 1/2||x||_2^2. The optimal solution to this problem is given by x in [-3, -1]. """ # Parameter values for the box constraint upper_lim = -1 lower_lim = -3 space = odl.rn(1) lin_ops = [odl.IdentityOperator(space)] g = [odl.solvers.IndicatorBox(space, lower=lower_lim, upper=upper_lim)] f = odl.solvers.ZeroFunctional(space) l = [odl.solvers.L2NormSquared(space)] # Centering around a point further away from [-3,-1]. x = space.element(10) douglas_rachford_pd(x, f, g, lin_ops, tau=0.5, sigma=[1.0], niter=20, l=l) assert lower_lim - 10**-LOW_ACCURACY <= float(x) assert float(x) <= upper_lim + 10**-LOW_ACCURACY
def test_collocation_interpolation_identity(): # Check if interpolation followed by collocation on the same grid # is the identity rect = odl.IntervalProd([0, 0], [1, 1]) part = odl.uniform_partition_fromintv(rect, [4, 2]) space = odl.FunctionSpace(rect) dspace = odl.rn(part.size) coll_op_c = PointCollocation(space, part, dspace, order='C') coll_op_f = PointCollocation(space, part, dspace, order='F') interp_ops_c = [ NearestInterpolation(space, part, dspace, variant='left', order='C'), NearestInterpolation(space, part, dspace, variant='right', order='C'), LinearInterpolation(space, part, dspace, order='C'), PerAxisInterpolation(space, part, dspace, order='C', schemes=['linear', 'nearest'])] interp_ops_f = [ NearestInterpolation(space, part, dspace, variant='left', order='F'), NearestInterpolation(space, part, dspace, variant='right', order='F'), LinearInterpolation(space, part, dspace, order='F'), PerAxisInterpolation(space, part, dspace, order='F', schemes=['linear', 'nearest'])] values = np.arange(1, 9, dtype='float64') for interp_op_c in interp_ops_c: ident_values = coll_op_c(interp_op_c(values)) assert all_almost_equal(ident_values, values) for interp_op_f in interp_ops_f: ident_values = coll_op_f(interp_op_f(values)) assert all_almost_equal(ident_values, values)
def test_nonlinear_functional(): r3 = odl.rn(3) x = r3.element([1, 2, 3]) op = SumSquaredFunctional(r3) assert op(x) == pytest.approx(np.sum(x ** 2))
def test_nearest_interpolation_2d_float(): rect = odl.IntervalProd([0, 0], [1, 1]) part = odl.uniform_partition_fromintv(rect, [4, 2], nodes_on_bdry=False) # Coordinate vectors are: # [0.125, 0.375, 0.625, 0.875], [0.25, 0.75] space = odl.FunctionSpace(rect) dspace = odl.rn(part.size) interp_op = NearestInterpolation(space, part, dspace) function = interp_op([0, 1, 2, 3, 4, 5, 6, 7]) # Evaluate at single point val = function([0.3, 0.6]) # closest to index (1, 1) -> 3 assert val == 3.0 # Input array, with and without output array pts = np.array([[0.3, 0.6], [1.0, 1.0]]) true_arr = [3, 7] assert all_equal(function(pts.T), true_arr) out = np.empty(2, dtype='float64') function(pts.T, out=out) assert all_equal(out, true_arr) # Input meshgrid, with and without output array mg = sparse_meshgrid([0.3, 1.0], [0.4, 1.0]) # Indices: (1, 3) x (0, 1) true_mg = [[2, 3], [6, 7]] assert all_equal(function(mg), true_mg) out = np.empty((2, 2), dtype='float64') function(mg, out=out) assert all_equal(out, true_mg)
def test_primal_dual_no_operator(): """Verify that the correct value is returned when there is no operator. Solves the optimization problem min_x ||x - data_1||_1 which has optimum value data_1. """ # Define the space space = odl.rn(5) # Operator L = [] # Data data_1 = odl.util.testutils.noise_element(space) # Proximals f = odl.solvers.L1Norm(space).translated(data_1) g = [] # Solve with f term dominating x = space.zero() douglas_rachford_pd(x, f, g, L, tau=3.0, sigma=[], niter=10) assert all_almost_equal(x, data_1, ndigits=2)