def test_solver_comparison(self):
        """
        Test that all solvers return the same and correct solution.

        """

        # Convex functions.
        y = [1, 0, 0.1, 8, -6.5, 0.2, 0.004, 0.01]
        sol = [0.75, 0, 0, 7.75, -6.25, 0, 0, 0]
        w1, w2 = .8, .4
        f1 = functions.norm_l2(y=y, lambda_=w1 / 2.)  # Smooth.
        f2 = functions.norm_l1(lambda_=w2 / 2.)  # Non-smooth.

        # Solvers.
        L = w1  # Lipschitz continuous gradient.
        step = 1. / L
        lambda_ = 0.5
        params = {'step': step, 'lambda_': lambda_}
        slvs = []
        slvs.append(
            solvers.forward_backward(accel=acceleration.dummy(), step=step))
        slvs.append(solvers.douglas_rachford(**params))
        slvs.append(solvers.generalized_forward_backward(**params))

        # Compare solutions.
        params = {'rtol': 1e-14, 'verbosity': 'NONE', 'maxit': 1e4}
        niters = [2, 61, 26]
        for solver, niter in zip(slvs, niters):
            x0 = np.zeros(len(y))
            ret = solvers.solve([f1, f2], x0, solver, **params)
            nptest.assert_allclose(ret['sol'], sol)
            self.assertEqual(ret['niter'], niter)
            self.assertIs(ret['sol'], x0)  # The initial value was modified.
Beispiel #2
0
    def test_solver_comparison(self):
        """
        Test that all solvers return the same and correct solution.

        """

        # Convex functions.
        y = [1, 0, 0.1, 8, -6.5, 0.2, 0.004, 0.01]
        sol = [0.75, 0, 0, 7.75, -6.25, 0, 0, 0]
        w1, w2 = .8, .4
        f1 = functions.norm_l2(y=y, lambda_=w1 / 2.)  # Smooth.
        f2 = functions.norm_l1(lambda_=w2 / 2.)       # Non-smooth.

        # Solvers.
        L = w1  # Lipschitz continuous gradient.
        step = 1. / L
        lambda_ = 0.5
        params = {'step': step, 'lambda_': lambda_}
        slvs = []
        slvs.append(solvers.forward_backward(accel=acceleration.dummy(),
                                             step=step))
        slvs.append(solvers.douglas_rachford(**params))
        slvs.append(solvers.generalized_forward_backward(**params))

        # Compare solutions.
        params = {'rtol': 1e-14, 'verbosity': 'NONE', 'maxit': 1e4}
        niters = [2, 61, 26]
        for solver, niter in zip(slvs, niters):
            x0 = np.zeros(len(y))
            ret = solvers.solve([f1, f2], x0, solver, **params)
            nptest.assert_allclose(ret['sol'], sol)
            self.assertEqual(ret['niter'], niter)
            self.assertIs(ret['sol'], x0)  # The initial value was modified.
Beispiel #3
0
def optGFB(D, GK0, triangles, fxy, E, maxit, x1, step, tau1, tau2, tau3, flag):
    ####
    N = len(E)

    f2 = functions.func()
    f2._eval = lambda x: 0
    f2._prox = lambda x, T: np.clip(x, 0, 0.7)  #
    ###
    T1 = Nodeneighbor(triangles, N)
    g = lambda x: Ggradient(x, T1)
    f3 = functions.norm_l1(A=g, At=None, dim=1, y=np.zeros(N),
                           lambda_=tau2)  #['EVAL', 'PROX']
    ######
    yy2 = np.ravel(fxy)
    ####
    N_cov = np.zeros((2 * N, 2 * N))
    for j in np.arange(0, 2 * N, 2):
        N_cov[j, j] = 3
        N_cov[j + 1, j + 1] = 1
    gamma = GK0 @ N_cov @ GK0.T  #
    gamma += np.eye(gamma.shape[1]) * 1e-5
    gamma_inv = np.linalg.inv(gamma)
    f8 = functions.func(lambda_=tau1)
    f8._eval = lambda x: (yy2 - D @ x).T @ gamma_inv @ (yy2 - D @ x) * 1e+7
    f8._grad = lambda x: -D.T @ gamma_inv @ (yy2 - D @ x) * 1e+7
    #######
    #step = 0.08#0.5 /tau1# (np.linalg.norm(func(x0),2)**2/np.linalg.norm(x0,2)**2) #0.5/tau#2e3/scale
    solver2 = solvers.generalized_forward_backward(
        step=step * 0.2
    )  #generalized_forward_backward(step=step*0.1)#step*0.1)douglas_rachford
    # without f3 -->singular matrix
    ret2 = solvers.solve([f8, f3, f2], x1, solver2, rtol=1e-15, maxit=maxit)
    objective = np.array(ret2['objective'])
    sol = ret2['sol']

    import matplotlib.pyplot as plt

    if flag == 1:
        _ = plt.figure(figsize=(10, 4))
        _ = plt.subplot(121)
        _ = plt.plot(E, 'o', label='Original E')  #-np.ones(N)*0.1
        _ = plt.plot(ret2['sol'], 'xr', label='Reconstructed E')
        _ = plt.grid(True)
        _ = plt.title('Achieved reconstruction')
        _ = plt.legend(numpoints=1)
        _ = plt.xlabel('Signal dimension number')
        _ = plt.ylabel('Signal value')

        _ = plt.subplot(122)
        _ = plt.semilogy(objective[:, 0], '-.', label='l2-norm')  #
        _ = plt.semilogy(np.sum(objective, axis=1), label='Global objective')
        _ = plt.grid(True)
        _ = plt.title('Convergence')
        _ = plt.legend(numpoints=1)
        _ = plt.xlabel('Iteration number')
        _ = plt.ylabel('Objective function value')
        _ = plt.show()
    return sol
    def test_generalized_forward_backward(self):
        """
        Test the generalized forward-backward algorithm.

        """
        y = [4, 5, 6, 7]
        L = 4  # Gradient of the smooth function is Lipschitz continuous.
        solver = solvers.generalized_forward_backward(step=.9 / L, lambda_=.8)
        params = {'solver': solver, 'verbosity': 'NONE'}

        # Functions.
        f1 = functions.norm_l1(y=y, lambda_=.7)  # Non-smooth.
        f2 = functions.norm_l2(y=y, lambda_=L / 2.)  # Smooth.

        # Solve with 1 smooth and 1 non-smooth.
        ret = solvers.solve([f1, f2], np.zeros(len(y)), **params)
        nptest.assert_allclose(ret['sol'], y)
        self.assertEqual(ret['niter'], 25)

        # Solve with 1 smooth.
        ret = solvers.solve([f1], np.zeros(len(y)), **params)
        nptest.assert_allclose(ret['sol'], y)
        self.assertEqual(ret['niter'], 77)

        # Solve with 1 non-smooth.
        ret = solvers.solve([f2], np.zeros(len(y)), **params)
        nptest.assert_allclose(ret['sol'], y)
        self.assertEqual(ret['niter'], 18)

        # Solve with 1 smooth and 2 non-smooth.
        ret = solvers.solve([f1, f2, f2], np.zeros(len(y)), **params)
        nptest.assert_allclose(ret['sol'], y)
        self.assertEqual(ret['niter'], 26)

        # Solve with 2 smooth and 2 non-smooth.
        ret = solvers.solve([f2, f1, f2, f1], np.zeros(len(y)), **params)
        nptest.assert_allclose(ret['sol'], y)
        self.assertEqual(ret['niter'], 25)

        # Sanity checks
        x0 = np.zeros((4, ))
        solver.lambda_ = 2.
        self.assertRaises(ValueError, solver.pre, [f1, f2], x0)
        solver.lambda_ = -2.
        self.assertRaises(ValueError, solver.pre, [f1, f2], x0)
        f1 = functions.func()
        f2 = functions.func()
        f3 = functions.func()
        solver.lambda_ = 1.
        self.assertRaises(ValueError, solver.pre, [f1, f2, f3], x0)
Beispiel #5
0
    def test_generalized_forward_backward(self):
        """
        Test the generalized forward-backward algorithm.

        """
        y = [4, 5, 6, 7]
        L = 4  # Gradient of the smooth function is Lipschitz continuous.
        solver = solvers.generalized_forward_backward(step=.9 / L, lambda_=.8)
        params = {'solver': solver, 'verbosity': 'NONE'}

        # Functions.
        f1 = functions.norm_l1(y=y, lambda_=.7)    # Non-smooth.
        f2 = functions.norm_l2(y=y, lambda_=L / 2.)  # Smooth.

        # Solve with 1 smooth and 1 non-smooth.
        ret = solvers.solve([f1, f2], np.zeros(len(y)), **params)
        nptest.assert_allclose(ret['sol'], y)
        self.assertEqual(ret['niter'], 25)

        # Solve with 1 smooth.
        ret = solvers.solve([f1], np.zeros(len(y)), **params)
        nptest.assert_allclose(ret['sol'], y)
        self.assertEqual(ret['niter'], 77)

        # Solve with 1 non-smooth.
        ret = solvers.solve([f2], np.zeros(len(y)), **params)
        nptest.assert_allclose(ret['sol'], y)
        self.assertEqual(ret['niter'], 18)

        # Solve with 1 smooth and 2 non-smooth.
        ret = solvers.solve([f1, f2, f2], np.zeros(len(y)), **params)
        nptest.assert_allclose(ret['sol'], y)
        self.assertEqual(ret['niter'], 26)

        # Solve with 2 smooth and 2 non-smooth.
        ret = solvers.solve([f2, f1, f2, f1], np.zeros(len(y)), **params)
        nptest.assert_allclose(ret['sol'], y)
        self.assertEqual(ret['niter'], 25)

        # Sanity checks
        x0 = np.zeros((4,))
        solver.lambda_ = 2.
        self.assertRaises(ValueError, solver.pre, [f1, f2], x0)
        solver.lambda_ = -2.
        self.assertRaises(ValueError, solver.pre, [f1, f2], x0)
        f1 = functions.func()
        f2 = functions.func()
        f3 = functions.func()
        solver.lambda_ = 1.
        self.assertRaises(ValueError, solver.pre, [f1, f2, f3], x0)