def test_proximal_translation(): """Test for the proximal of a translation: prox[F(. - g)]""" # Image space space = odl.uniform_discr(0, 1, 10) # Element in the image space where the proximal operator is evaluated translation = example_element(space) # Factory function returning the proximal operators lam = float(np.random.randn(1)) prox_factory = odls.proximal_l2_squared(space, lam=lam) # Initialize proximal operators step_size = float(np.random.rand(1)) # Non-negative step size prox = odls.proximal_translation(prox_factory, translation)(step_size) # Create an element in the space, in which to evaluate the proximals x = example_element(space) # Explicit computation: expected_result = ((x + 2 * step_size * lam * translation) / (1 + 2 * step_size * lam)) assert all_almost_equal(prox(x), expected_result, places=PLACES)
def test_inner(fn): xd = example_element(fn) yd = example_element(fn) correct_inner = np.vdot(yd, xd) assert almost_equal(fn.inner(xd, yd), correct_inner) assert almost_equal(xd.inner(yd), correct_inner)
def test_proximal_defintion(proximal_and_function): """Test the defintion of the proximal: prox[f](x) = argmin_y {f(y) + 1/2 ||x-y||^2} Hence we expect for all x in the domain of the proximal x* = prox[f](x) f(x*) + 1/2 ||x*-y||^2 < f(y) + 1/2 ||x-y||^2 """ proximal, function = proximal_and_function assert proximal.domain == proximal.range x = example_element(proximal.domain) * 10 f_x = proximal_objective(function, x, x) prox_x = proximal(x) f_prox_x = proximal_objective(function, x, prox_x) assert f_prox_x <= f_x for i in range(100): y = example_element(proximal.domain) f_y = proximal_objective(function, x, y) assert f_prox_x <= f_y
def test_proximal_quadratic_perturbation_linear_and_quadratic(): """Test for the proximal of quadratic perturbation with both terms""" # Image space space = odl.uniform_discr(0, 1, 10) # The parameter for the quadratic perturbation a = float(np.random.rand(1)) # This needs to be non-negative u = example_element(space) lam = float(np.random.randn(1)) # Factory function returning the proximal operators prox_factory = odls.proximal_l2_squared(space, lam=lam) # Initialize proximal operators step_size = float(np.random.rand(1)) # Non-negative step size prox = odls.proximal_quadratic_perturbation(prox_factory, a, u)(step_size) # Create an element in the space, in which to evaluate the proximals x = example_element(space) # Explicit computation: expected_result = (x - step_size * u) / (2 * step_size * (lam + a) + 1) assert all_almost_equal(prox(x), expected_result, places=PLACES)
def test_assign(fn): x = example_element(fn) y = example_element(fn) y.assign(x) assert y == x assert y is not x # test alignment x *= 2 assert y != x
def test_transpose(fn): x = example_element(fn) y = example_element(fn) # Assert linear operator assert isinstance(x.T, odl.Operator) assert x.T.is_linear # Check result assert almost_equal(x.T(y), x.inner(y)) assert all_almost_equal(x.T.adjoint(1.0), x) # x.T.T returns self assert x.T.T == x
def test_setitem_index_error(fn): x = example_element(fn) with pytest.raises(IndexError): x[-fn.size - 1] = 0 with pytest.raises(IndexError): x[fn.size] = 0
def test_member_copy(fn): x = example_element(fn) y = x.copy() assert x == y assert y is not x # test not aliased x *= 2 assert x != y
def test_copy(fn): import copy x = example_element(fn) y = copy.copy(x) assert x == y assert y is not x z = copy.deepcopy(x) assert x == z assert z is not x
def test_proximal_arg_scaling_zero(): """Test for the proximal of scaling: prox[F(. * a)] when a = 0""" # Image space space = odl.uniform_discr(0, 1, 10) # Factory function returning the proximal operators prox_factory = odls.proximal_l1(space, lam=1) # Initialize proximal operators scaling_param = 0.0 step_size = float(np.random.rand(1)) # Non-negative step size prox = odls.proximal_arg_scaling(prox_factory, scaling_param)(step_size) # Create an element in the space, in which to evaluate the proximals x = example_element(space) # Check that the scaling with zero returns proximal facotry for the # proximal_zero, which ersults in the identity operator assert all_almost_equal(prox(x), x, places=PLACES)
def test_proximal_arg_scaling(): """Test for the proximal of scaling: prox[F(. * a)]""" # Image space space = odl.uniform_discr(0, 1, 10) # Factory function returning the proximal operators lam = float(np.random.randn(1)) prox_factory = odls.proximal_l2_squared(space, lam=lam) # Initialize proximal operators step_size = float(np.random.rand(1)) # Non-negative step size scaling_param = float(np.random.randn(1)) prox = odls.proximal_arg_scaling(prox_factory, scaling_param)(step_size) # Create an element in the space, in which to evaluate the proximals x = example_element(space) # Explicit computation: expected_result = x / (2 * step_size * lam * scaling_param ** 2 + 1) assert all_almost_equal(prox(x), expected_result, places=PLACES)
def test_python_copy(fn): import copy x = example_element(fn) y = copy.copy(x) assert x == y assert y is not x # test not aliased x *= 2 assert x != y z = copy.deepcopy(x) assert x == z assert z is not x # test not aliased x *= 2 assert x != z
def _pos_vector(fn): """Create an vector with positive real entries as weight in `fn`.""" return np.abs(example_element(fn)) + 0.1
def proximal_and_function(request, stepsize, offset): """Return a proximal factory and the corresponding function.""" name = request.param.strip() space = odl.uniform_discr(0, 1, 2) if offset: g = example_element(space) else: g = None if name == 'l1': @make_offset(g, stepsize=stepsize, convex_conjugate=False) def l1_norm(x): return np.abs(x).inner(x.space.one()) prox = proximal_l1(space, g=g) return prox(stepsize), l1_norm if name == 'l1_dual': @make_offset(g, stepsize=stepsize, convex_conjugate=True) def l1_norm_dual(x): return 0.0 if np.max(np.abs(x)) <= 1.0 else np.Infinity prox = proximal_cconj_l1(space, g=g) return prox(stepsize), l1_norm_dual elif name == 'l2': @make_offset(g, stepsize=stepsize, convex_conjugate=False) def l2_norm(x): return x.norm() prox = proximal_l2(space, g=g) return prox(stepsize), l2_norm elif name == 'l2_dual': @make_offset(g, stepsize=stepsize, convex_conjugate=True) def l2_norm_dual(x): # numerical margin return 0.0 if x.norm() < 1.00001 else np.Infinity prox = proximal_cconj_l2(space, g=g) return prox(stepsize), l2_norm_dual elif name == 'l2^2': @make_offset(g, stepsize=stepsize, convex_conjugate=False) def l2_norm_squared(x): return x.norm() ** 2 prox = proximal_l2_squared(space, g=g) return prox(stepsize), l2_norm_squared elif name == 'l2^2_dual': @make_offset(g, stepsize=stepsize, convex_conjugate=True) def l2_norm_squared_dual(x): return (1.0 / 4.0) * x.norm() ** 2 prox = proximal_cconj_l2_squared(space, g=g) return prox(stepsize), l2_norm_squared_dual else: assert False
def test_setitem(fn): x = example_element(fn) for index in [0, 1, 2, -1, -2, -3]: x[index] = index assert almost_equal(x[index], index)
def proximal_and_function(request, stepsize, offset): """Return a proximal factory and the corresponding function.""" name = request.param.strip() space = odl.uniform_discr(0, 1, 2) if offset: g = example_element(space) else: g = None if name == 'l1': @make_offset(g, stepsize=stepsize, convex_conjugate=False) def l1_norm(x): return np.abs(x).inner(x.space.one()) prox = proximal_l1(space, g=g) return prox(stepsize), l1_norm if name == 'l1_dual': @make_offset(g, stepsize=stepsize, convex_conjugate=True) def l1_norm_dual(x): return 0.0 if np.max(np.abs(x)) <= 1.0 else np.Infinity prox = proximal_cconj_l1(space, g=g) return prox(stepsize), l1_norm_dual elif name == 'l2': @make_offset(g, stepsize=stepsize, convex_conjugate=False) def l2_norm(x): return x.norm() prox = proximal_l2(space, g=g) return prox(stepsize), l2_norm elif name == 'l2_dual': @make_offset(g, stepsize=stepsize, convex_conjugate=True) def l2_norm_dual(x): # numerical margin return 0.0 if x.norm() < 1.00001 else np.Infinity prox = proximal_cconj_l2(space, g=g) return prox(stepsize), l2_norm_dual elif name == 'l2^2': @make_offset(g, stepsize=stepsize, convex_conjugate=False) def l2_norm_squared(x): return x.norm()**2 prox = proximal_l2_squared(space, g=g) return prox(stepsize), l2_norm_squared elif name == 'l2^2_dual': @make_offset(g, stepsize=stepsize, convex_conjugate=True) def l2_norm_squared_dual(x): return (1.0 / 4.0) * x.norm()**2 prox = proximal_cconj_l2_squared(space, g=g) return prox(stepsize), l2_norm_squared_dual else: assert False