Ejemplo n.º 1
0
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)
Ejemplo n.º 2
0
    def _reconstruct(self, observation, out):
        observation = self.observation_space.element(observation)
        out[:] = self.x0
        gradient = Gradient(self.op.domain)
        L = [self.op, gradient]
        f = ZeroFunctional(self.op.domain)
        l2_norm = 0.5 * L2NormSquared(self.op.range).translated(observation)
        l12_norm = self.lam * GroupL1Norm(gradient.range)
        g = [l2_norm, l12_norm]
        op_norm = power_method_opnorm(self.op, maxiter=20)
        gradient_norm = power_method_opnorm(gradient, maxiter=20)
        sigma_ray_trafo = 45.0 / op_norm**2
        sigma_gradient = 45.0 / gradient_norm**2
        sigma = [sigma_ray_trafo, sigma_gradient]
        h = ZeroFunctional(self.op.domain)
        forward_backward_pd(out,
                            f,
                            g,
                            L,
                            h,
                            self.tau,
                            sigma,
                            self.niter,
                            callback=self.callback)

        return out
Ejemplo n.º 3
0
def test_forward_backward_basic():
    """Test for the forward-backward solver by minimizing ||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(x) = g(x) = 0, h(x) = ||x||_2^2 and L is the
    zero-operator.
    """

    space = odl.rn(10)

    lin_ops = [odl.ZeroOperator(space)]
    g = [odl.solvers.ZeroFunctional(space)]
    f = odl.solvers.ZeroFunctional(space)
    h = odl.solvers.L2NormSquared(space)

    x = noise_element(space)
    x_global_min = space.zero()

    forward_backward_pd(x, f, g, lin_ops, h, tau=0.5,
                        sigma=[1.0], niter=10)

    assert all_almost_equal(x, x_global_min, places=HIGH_ACCURACY)
Ejemplo n.º 4
0
def test_forward_backward_with_li_and_h():
    """Test for the forward-backward solver with infimal convolution.

    The test is done by minimizing the functional ``(g @ l)(x) + h(x)``, where

        ``(g @ l)(x) = inf_y { g(y) + l(x-y) }``,

    g is the indicator function on [-3, -1], and l(x) = h(x) = 1/2||x||_2^2.
    The optimal solution to this problem is given by x = -0.5.
    """

    # 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)
    h = 0.5 * odl.solvers.L2NormSquared(space)
    l = [0.5 * odl.solvers.L2NormSquared(space)]

    # Creating an element not to far away from -0.5, in order to converge in
    # a few number of iterations.
    x = space.element(10)

    forward_backward_pd(x, f, g, lin_ops, h, tau=0.5,
                        sigma=[1.0], niter=20, l=l)

    expected_result = -0.5
    assert almost_equal(x[0], expected_result, places=LOW_ACCURACY)
Ejemplo n.º 5
0
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)
Ejemplo n.º 6
0
def test_forward_backward_with_li_and_h():
    """Test for the forward-backward solver with infimal convolution.

    The test is done by minimizing the functional ``(g @ l)(x) + h(x)``, where

        ``(g @ l)(x) = inf_y { g(y) + l(x-y) }``,

    g is the indicator function on [-3, -1], and l(x) = h(x) = 1/2||x||_2^2.
    The optimal solution to this problem is given by x = -0.5.
    """

    # 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)
    h = 0.5 * odl.solvers.L2NormSquared(space)
    l = [0.5 * odl.solvers.L2NormSquared(space)]

    # Creating an element not to far away from -0.5, in order to converge in
    # a few number of iterations.
    x = space.element(10)

    forward_backward_pd(x,
                        f,
                        g,
                        lin_ops,
                        h,
                        tau=0.5,
                        sigma=[1.0],
                        niter=20,
                        l=l)

    expected_result = -0.5
    assert almost_equal(x[0], expected_result, places=LOW_ACCURACY)
Ejemplo n.º 7
0
def test_forward_backward_basic():
    """Test for the forward-backward solver by minimizing ||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(x) = g(x) = 0, h(x) = ||x||_2^2 and L is the
    zero-operator.
    """

    space = odl.rn(10)

    lin_ops = [odl.ZeroOperator(space)]
    g = [odl.solvers.ZeroFunctional(space)]
    f = odl.solvers.ZeroFunctional(space)
    h = odl.solvers.L2NormSquared(space)

    x = noise_element(space)
    x_global_min = space.zero()

    forward_backward_pd(x, f, g, lin_ops, h, tau=0.5, sigma=[1.0], niter=10)

    assert all_almost_equal(x, x_global_min, places=HIGH_ACCURACY)
Ejemplo n.º 8
0
def test_forward_backward_input_handling():
    """Test to see that input is handled correctly."""

    space1 = odl.uniform_discr(0, 1, 10)

    lin_ops = [odl.ZeroOperator(space1), odl.ZeroOperator(space1)]
    g = [odl.solvers.ZeroFunctional(space1),
         odl.solvers.ZeroFunctional(space1)]
    f = odl.solvers.ZeroFunctional(space1)
    h = odl.solvers.ZeroFunctional(space1)

    # Check that the algorithm runs. With the above operators, the algorithm
    # returns the input.
    x0 = noise_element(space1)
    x = x0.copy()
    niter = 3

    forward_backward_pd(x, f, g, lin_ops, h, tau=1.0,
                        sigma=[1.0, 1.0], niter=niter)

    assert x == x0

    # Testing that sizes needs to agree:
    # Too few sigma_i:s
    with pytest.raises(ValueError):
        forward_backward_pd(x, f, g, lin_ops, h, tau=1.0,
                            sigma=[1.0], niter=niter)

    # Too many operators
    g_too_many = [odl.solvers.ZeroFunctional(space1),
                  odl.solvers.ZeroFunctional(space1),
                  odl.solvers.ZeroFunctional(space1)]
    with pytest.raises(ValueError):
        forward_backward_pd(x, f, g_too_many, lin_ops, h,
                            tau=1.0, sigma=[1.0, 1.0], niter=niter)

    # Test for correct space
    space2 = odl.uniform_discr(1, 2, 10)
    x = noise_element(space2)
    with pytest.raises(ValueError):
        forward_backward_pd(x, f, g, lin_ops, h, tau=1.0,
                            sigma=[1.0, 1.0], niter=niter)
Ejemplo n.º 9
0
def test_forward_backward_input_handling():
    """Test to see that input is handled correctly."""

    space1 = odl.uniform_discr(0, 1, 10)

    lin_ops = [odl.ZeroOperator(space1), odl.ZeroOperator(space1)]
    g = [
        odl.solvers.ZeroFunctional(space1),
        odl.solvers.ZeroFunctional(space1)
    ]
    f = odl.solvers.ZeroFunctional(space1)
    h = odl.solvers.ZeroFunctional(space1)

    # Check that the algorithm runs. With the above operators, the algorithm
    # returns the input.
    x0 = noise_element(space1)
    x = x0.copy()
    niter = 3

    forward_backward_pd(x,
                        f,
                        g,
                        lin_ops,
                        h,
                        tau=1.0,
                        sigma=[1.0, 1.0],
                        niter=niter)

    assert x == x0

    # Testing that sizes needs to agree:
    # Too few sigma_i:s
    with pytest.raises(ValueError):
        forward_backward_pd(x,
                            f,
                            g,
                            lin_ops,
                            h,
                            tau=1.0,
                            sigma=[1.0],
                            niter=niter)

    # Too many operators
    g_too_many = [
        odl.solvers.ZeroFunctional(space1),
        odl.solvers.ZeroFunctional(space1),
        odl.solvers.ZeroFunctional(space1)
    ]
    with pytest.raises(ValueError):
        forward_backward_pd(x,
                            f,
                            g_too_many,
                            lin_ops,
                            h,
                            tau=1.0,
                            sigma=[1.0, 1.0],
                            niter=niter)

    # Test for correct space
    space2 = odl.uniform_discr(1, 2, 10)
    x = noise_element(space2)
    with pytest.raises(ValueError):
        forward_backward_pd(x,
                            f,
                            g,
                            lin_ops,
                            h,
                            tau=1.0,
                            sigma=[1.0, 1.0],
                            niter=niter)