diff --git a/src/solver/parameters.py b/src/solver/parameters.py index 7fd921d0e24686f703da303caf8f4511c4ee45a6..b77276c051c454f3dac2670b54889db93e950cb8 100755 --- a/src/solver/parameters.py +++ b/src/solver/parameters.py @@ -34,7 +34,8 @@ class SlopeParameters(object): dual_scaling: DualScalingOptions = DualScalingOptions.EXACT - eval_gap: bool = True + eval_gap: bool = True + eval_gap_it: int = 1 lipchitz_constant: float = None lipchitz_update: EnumLipchitzOptions = EnumLipchitzOptions.EXACT diff --git a/src/solver/slope.py b/src/solver/slope.py index ada599c2161584414d0ddfe8e0dba7867292db01..dd055d188497cf10d7d13f5331c2cbdb1b7cee06 100755 --- a/src/solver/slope.py +++ b/src/solver/slope.py @@ -3,8 +3,8 @@ import time import numpy as np -from src.parameters import SlopeParameters, EnumLipchitzOptions, DualScalingOptions -from src.prox import prox_owl +from src.solver.parameters import SlopeParameters, EnumLipchitzOptions, DualScalingOptions +from src.solver.prox import prox_owl def primal_func(vecy, Ax, x, lbd, vec_gammas) -> float: @@ -182,7 +182,7 @@ def slope_gp(vecy, matA, lbd, vecgamma, algParameters=SlopeParameters()): gap = best_costfunc - if (it % 20 == 0) or algParameters.eval_gap: + if algParameters.eval_gap and (it % algParameters.eval_gap_it == 0): # -- Evaluating dual function (if needed) # if algParameters.eval_gap: index_sort_neg_grad = np.argsort(np.abs(neg_grad))[::-1] diff --git a/tests/test_generalized_screening.py b/tests/test_generalized_screening.py deleted file mode 100644 index c497b0822a3108e491709a77c43c5429d690dc74..0000000000000000000000000000000000000000 --- a/tests/test_generalized_screening.py +++ /dev/null @@ -1,58 +0,0 @@ -# -*- coding: utf-8 -*- -import unittest -import numpy as np - -from src.dictionaries import generate_dic -from src.solver.slope import primal_func, dual_func, slope_gp -from src.solver.parameters import SlopeParameters -from src.screening.singletest import GapSphereSingleTest -from src.screening.gap_ptest import GAP_Ptest -import src.utils as utils - -class TestSolver(unittest.TestCase): - - def test_gp_cost_decrease(self): - """ Run a non accelerated proximal gradient algorithm - assess that the cost function decreaes - """ - - # 1. Create problem - m = 20 - n = 50 - matA = generate_dic("gaussian", m, n, True) - vecy = np.random.randn(m) - vec_gammas = np.linspace(.5, 1, n)[::-1] - - # 2. Compute lambda_max - lbd_max = utils.get_lambda_max(vecy, matA, vec_gammas) - lbd = .6 * lbd_max - - # 3. Eval solution of slope problem - algParameters = SlopeParameters() - algParameters.gap_stopping = 1e-12 - algParameters.max_it = 100000 - algParameters.accelerated = False - out = slope_gp(vecy, matA, .5*lbd_max, vec_gammas, algParameters) - - vecu = vecy - matA @ out["sol"] - beta_dual = np.sort(np.abs(matA.T @ vecu))[::-1] - beta_dual = np.cumsum(beta_dual) / np.cumsum(lbd * vec_gammas) - vecu /= np.max(beta_dual) - Atu = matA.T @ vecu - - pval = primal_func(vecy, matA @ out["sol"], out["sol"], lbd, vec_gammas) - dval = dual_func(vecy, np.linalg.norm(vecy, 2)**2, vecu) - gap = np.abs(pval - dval) - - # 4. Start screening test - test1 = GapSphereSingleTest() - test2 = GAP_Ptest(np.cumsum(vec_gammas)) - - out1 = test1.apply_test(Atu, gap, lbd, vec_gammas) - out2 = test2.apply_test(Atu, gap, lbd, vec_gammas) - - # 1e-15 due to machine precision error - self.assertTrue( (out2 >= out1).all() ) - -if __name__ == '__main__': - unittest.main() \ No newline at end of file diff --git a/tests/test_solver.py b/tests/test_solver.py index 1bea217c14dbfcdd538f612fd0724a84fe1a3c33..6cfdba4815545be1f8fb69a3b549ac730aae110f 100644 --- a/tests/test_solver.py +++ b/tests/test_solver.py @@ -38,5 +38,53 @@ class TestSolver(unittest.TestCase): # 1e-15 due to machine precision error self.assertTrue( (vec_diff <= 1e-14).all() ) + + def test_no_gap_evluation(self): + # 1. Create problem + m = 20 + n = 50 + matA = generate_dic("gaussian", m, n, True) + vecy = np.random.randn(m) + vec_gammas = np.linspace(0, 1, n)[::-1] + + # 2. Compute lambda_max + lbd_max = utils.get_lambda_max(vecy, matA, vec_gammas) + + # 3. Eval solution of slope problem + algParameters = SlopeParameters() + algParameters.max_it = 1000 + algParameters.accelerated = False + algParameters.eval_gap = False + out = slope_gp(vecy, matA, .5 * lbd_max, vec_gammas, algParameters) + + best_cost = np.min(out["cost_function"]) + gap = out["gap"] + self.assertTrue(np.abs(best_cost - gap) <= 1e-10) + + + def test_gap_tend_to_zero(self): + # 1. Create problem + m = 20 + n = 50 + matA = generate_dic("gaussian", m, n, True) + vecy = np.random.randn(m) + vec_gammas = np.linspace(0, 1, n)[::-1] + + # 2. Compute lambda_max + lbd_max = utils.get_lambda_max(vecy, matA, vec_gammas) + + # 3. Eval solution of slope problem + algParameters = SlopeParameters() + algParameters.max_it = 1e6 + algParameters.accelerated = False + algParameters.eval_gap = True + algParameters.gap_stopping = 1e-8 + out = slope_gp(vecy, matA, .5 * lbd_max, vec_gammas, algParameters) + + gap = out["gap"] + + self.assertTrue(gap <= 1e-8) + + if __name__ == '__main__': unittest.main() \ No newline at end of file