From 8a99c0f09bb94aba5b01d9dfa92d20367c06be26 Mon Sep 17 00:00:00 2001 From: Teytaud Date: Mon, 27 Nov 2023 13:02:05 +0100 Subject: [PATCH] Adaptation of Francois's PR for quasirandomization of sphere sampling (#1573) * Update sphere.py Added Riesz energy gradient descents: 3 options (blurred, blursum and noblur) plus methods to call with different conv and order parameters * black * fix_flaky * fix * fix * fix * fix * fix * fix * fix * fix * distinguish scipy optimizer without restart and with restart (#1575) * nor * nor * no_gomea * fixdetails * black * switch_to_101 * lessflaky * compare_new * compare_new * Update BibTeX entry of LSGO technical report (#1576) * new variants of scipy methods adapted to black-box optimization (#1574) * newdes * fix * fix * fix * fix * fix * fix_pos * newdes * fixblack * fix * more_para * po * fix * distinguish scipy optimizer without restart and with restart (#1575) * nor * nor * no_gomea * fixdetails * black * switch_to_101 * lessflaky * compare_new * compare_new --------- Co-authored-by: frclement <113344874+frclement@users.noreply.github.com> Co-authored-by: Iztok Fister Jr --- nevergrad/common/sphere.py | 228 +++++++++++++++++++- nevergrad/optimization/test_base.py | 4 +- nevergrad/optimization/test_optimizerlib.py | 1 + nevergrad/optimization/test_suggest.py | 2 +- 4 files changed, 229 insertions(+), 6 deletions(-) diff --git a/nevergrad/common/sphere.py b/nevergrad/common/sphere.py index ea42b8a15..934940659 100644 --- a/nevergrad/common/sphere.py +++ b/nevergrad/common/sphere.py @@ -20,6 +20,9 @@ # pylint: skip-file default_budget = 3000 # centiseconds +default_steps = 100 # nb of steps grad descent +default_order = 2 # Riesz energy order +default_stepsize = 10 # step size for grad descent methods = {} metrics = {} @@ -41,6 +44,12 @@ def convo(x, k): return scipy.ndimage.gaussian_filter(x, sigma=list(k) + [0.0] * (len(x.shape) - len(k))) +def convo_mult(x, k): # Convo for an array of different points + if k is None: + return x + return scipy.ndimage.gaussian_filter(x, sigma=[0] + list(k) + [0.0] * (len(x.shape) - len(k) - 1)) + + # Our well distributed point configurations. def pure_random(n, shape, conv=None): return normalize([np.random.randn(*shape) for i in range(n)]) @@ -146,6 +155,189 @@ def greedy_dispersion_with_mini_conv(n, shape, budget=default_budget): return greedy_dispersion(n, shape, budget=budget, conv=[2, 2]) +def Riesz_blurred_gradient( + n, shape, budget=default_budget, order=default_order, step_size=default_stepsize, conv=None +): + t = (n,) + tuple(shape) + x = np.random.randn(*t) + x = normalize(x) + t0 = time.time() + for steps in range(int(1e9 * budget)): + Temp = np.zeros(t) + Blurred = convo_mult(x, conv) + for i in range(n): + for j in range(n): + if j != i: + T = np.add(Blurred[i], -Blurred[j]) + Temp[i] = np.add(Temp[i], np.multiply(T, 1 / (np.sqrt(np.sum(T**2.0))) ** (order + 2))) + Temp[i] = np.multiply(Temp[i], step_size) + x = np.add(x, Temp) + x = normalize(x) + if time.time() > t0 + 0.01 * budget: + break + return x + + +def Riesz_blursum_gradient( + n, shape, budget=default_budget, order=default_order, step_size=default_stepsize, conv=None +): + t = (n,) + tuple(shape) + x = np.random.randn(*t) + x = normalize(x) + t0 = time.time() + for steps in range(int(1e9 * budget)): + Blurred = np.zeros(t) + for i in range(n): + for j in range(n): + if j != i: + T = np.add(x[i], -x[j]) + Blurred[i] = np.add( + np.multiply(T, 1 / (np.sqrt(np.sum(T**2.0))) ** (order + 2)), Blurred[i] + ) + Blurred = convo_mult(Blurred, conv) + x = np.add(x, Blurred) + x = normalize(x) + if time.time() > t0 + 0.01 * budget: + break + return x + + +def Riesz_noblur_gradient( + n, shape, budget=default_budget, order=default_order, step_size=default_stepsize, conv=None +): + t = (n,) + tuple(shape) + x = np.random.randn(*t) + x = normalize(x) + t0 = time.time() + for steps in range(int(1e9 * budget)): + Temp = np.zeros(t) + for i in range(n): + for j in range(n): + if j != i: + T = np.add(x[i], -x[j]) + Temp[i] = np.add(Temp[i], np.multiply(T, 1 / (np.sqrt(np.sum(T**2.0))) ** (order + 2))) + + x = np.add(x, Temp) + x = normalize(x) + if time.time() > t0 + 0.01 * budget: + break + return x + + +def Riesz_noblur_bigconv_loworder(n, shape, budget=default_budget): + return Riesz_noblur_gradient( + n, shape, default_steps, order=0.5, step_size=default_stepsize, conv=[24, 24] + ) + + +def Riesz_noblur_bigconv_midorder(n, shape, budget=default_budget): + return Riesz_noblur_gradient(n, shape, default_steps, order=1, step_size=default_stepsize, conv=[24, 24]) + + +def Riesz_noblur_bigconv_highorder(n, shape, budget=default_budget): + return Riesz_noblur_gradient(n, shape, default_steps, order=2, step_size=default_stepsize, conv=[24, 24]) + + +def Riesz_noblur_medconv_loworder(n, shape, budget=default_budget): + return Riesz_noblur_gradient(n, shape, default_steps, order=0.5, step_size=default_stepsize, conv=[8, 8]) + + +def Riesz_noblur_medconv_midorder(n, shape, budget=default_budget): + return Riesz_noblur_gradient(n, shape, default_steps, order=1, step_size=default_stepsize, conv=[8, 8]) + + +def Riesz_noblur_medconv_highorder(n, shape, budget=default_budget): + return Riesz_noblur_gradient(n, shape, default_steps, order=2, step_size=default_stepsize, conv=[8, 8]) + + +def Riesz_noblur_lowconv_loworder(n, shape, budget=default_budget): + return Riesz_noblur_gradient(n, shape, default_steps, order=0.5, step_size=default_stepsize, conv=[2, 2]) + + +def Riesz_noblur_lowconv_midorder(n, shape, budget=default_budget): + return Riesz_noblur_gradient(n, shape, default_steps, order=1, step_size=default_stepsize, conv=[2, 2]) + + +def Riesz_noblur_lowconv_highorder(n, shape, budget=default_budget): + return Riesz_noblur_gradient(n, shape, default_steps, order=2, step_size=default_stepsize, conv=[2, 2]) + + +def Riesz_blursum_bigconv_loworder(n, shape, budget=default_budget): + return Riesz_blursum_gradient( + n, shape, default_steps, order=0.5, step_size=default_stepsize, conv=[24, 24] + ) + + +def Riesz_blursum_bigconv_midorder(n, shape, budget=default_budget): + return Riesz_blursum_gradient(n, shape, default_steps, order=1, step_size=default_stepsize, conv=[24, 24]) + + +def Riesz_blursum_bigconv_highorder(n, shape, budget=default_budget): + return Riesz_blursum_gradient(n, shape, default_steps, order=2, step_size=default_stepsize, conv=[24, 24]) + + +def Riesz_blursum_medconv_loworder(n, shape, budget=default_budget): + return Riesz_blursum_gradient(n, shape, default_steps, order=0.5, step_size=default_stepsize, conv=[8, 8]) + + +def Riesz_blursum_medconv_midorder(n, shape, budget=default_budget): + return Riesz_blursum_gradient(n, shape, default_steps, order=1, step_size=default_stepsize, conv=[8, 8]) + + +def Riesz_blursum_medconv_highorder(n, shape, budget=default_budget): + return Riesz_blursum_gradient(n, shape, default_steps, order=2, step_size=default_stepsize, conv=[8, 8]) + + +def Riesz_blursum_lowconv_loworder(n, shape, budget=default_budget): + return Riesz_blursum_gradient(n, shape, default_steps, order=0.5, step_size=default_stepsize, conv=[2, 2]) + + +def Riesz_blursum_lowconv_midorder(n, shape, budget=default_budget): + return Riesz_blursum_gradient(n, shape, default_steps, order=1, step_size=default_stepsize, conv=[2, 2]) + + +def Riesz_blursum_lowconv_highorder(n, shape, budget=default_budget): + return Riesz_blursum_gradient(n, shape, default_steps, order=2, step_size=default_stepsize, conv=[2, 2]) + + +def Riesz_blurred_bigconv_loworder(n, shape, budget=default_budget): + return Riesz_blurred_gradient( + n, shape, default_steps, order=0.5, step_size=default_stepsize, conv=[24, 24] + ) + + +def Riesz_blurred_bigconv_midorder(n, shape, budget=default_budget): + return Riesz_blurred_gradient(n, shape, default_steps, order=1, step_size=default_stepsize, conv=[24, 24]) + + +def Riesz_blurred_bigconv_highorder(n, shape, budget=default_budget): + return Riesz_blurred_gradient(n, shape, default_steps, order=2, step_size=default_stepsize, conv=[24, 24]) + + +def Riesz_blurred_medconv_loworder(n, shape, budget=default_budget): + return Riesz_blurred_gradient(n, shape, default_steps, order=0.5, step_size=default_stepsize, conv=[8, 8]) + + +def Riesz_blurred_medconv_midorder(n, shape, budget=default_budget): + return Riesz_blurred_gradient(n, shape, default_steps, order=1, step_size=default_stepsize, conv=[8, 8]) + + +def Riesz_blurred_medconv_highorder(n, shape, budget=default_budget): + return Riesz_blurred_gradient(n, shape, default_steps, order=2, step_size=default_stepsize, conv=[8, 8]) + + +def Riesz_blurred_lowconv_loworder(n, shape, budget=default_budget): + return Riesz_blurred_gradient(n, shape, default_steps, order=0.5, step_size=default_stepsize, conv=[2, 2]) + + +def Riesz_blurred_lowconv_midorder(n, shape, budget=default_budget): + return Riesz_blurred_gradient(n, shape, default_steps, order=1, step_size=default_stepsize, conv=[2, 2]) + + +def Riesz_blurred_lowconv_highorder(n, shape, budget=default_budget): + return Riesz_blurred_gradient(n, shape, default_steps, order=2, step_size=default_stepsize, conv=[2, 2]) + + def block_symmetry(n, shape, num_blocks=None): x = [] if num_blocks is None: @@ -184,7 +376,7 @@ def big_block_symmetry(n, shape): def covering(n, shape, budget=default_budget, conv=None): - x = greedy_dispersion_with_conv(n, shape, budget / 2, conv) + x = greedy_dispersion(n, shape, budget / 2, conv) mindists = [] c = 0.01 previous_score = float("inf") @@ -503,6 +695,33 @@ def metric_pack_conv(x, budget=default_budget): "rs_rac", "rs_rac2", "rs_rac05", + "Riesz_blurred_bigconv_loworder", + "Riesz_blurred_bigconv_midorder", + "Riesz_blurred_bigconv_highorder", + "Riesz_blurred_medconv_loworder", + "Riesz_blurred_medconv_midorder", + "Riesz_blurred_medconv_highorder", + "Riesz_blurred_lowconv_loworder", + "Riesz_blurred_lowconv_midorder", + "Riesz_blurred_lowconv_highorder", + "Riesz_noblur_bigconv_loworder", + "Riesz_noblur_bigconv_midorder", + "Riesz_noblur_bigconv_highorder", + "Riesz_noblur_medconv_loworder", + "Riesz_noblur_medconv_midorder", + "Riesz_noblur_medconv_highorder", + "Riesz_noblur_lowconv_loworder", + "Riesz_noblur_lowconv_midorder", + "Riesz_noblur_lowconv_highorder", + "Riesz_blursum_bigconv_loworder", + "Riesz_blursum_bigconv_midorder", + "Riesz_blursum_bigconv_highorder", + "Riesz_blursum_medconv_loworder", + "Riesz_blursum_medconv_midorder", + "Riesz_blursum_medconv_highorder", + "Riesz_blursum_lowconv_loworder", + "Riesz_blursum_lowconv_midorder", + "Riesz_blursum_lowconv_highorder", ] list_metrics = [ "metric_half", @@ -527,13 +746,14 @@ def metric_pack_conv(x, budget=default_budget): def rs(n, shape, budget=default_budget, k="metric_half", ngtool=None): - t0 = time.time() bestm = float("inf") if ngtool is not None: opt = ng.optimizers.registry[ngtool]( ng.p.Array(shape=tuple([n] + list(shape))), budget=10000000000000 ) - while time.time() < t0 + 0.01 * budget: + t0 = time.time() + bestx = None + while time.time() < t0 + 0.01 * budget or bestx is None: if ngtool is None: x = pure_random(n, shape) else: @@ -824,6 +1044,8 @@ def bigcheck(): "covering", "covering_conv", "covering_mini_conv", + "Riesz_blurred_bigconv_highorder", + "Riesz_blursum_bigconv_highorder", ]: print("Starting to play with ", k) eval(f"{k}(n, shape)") diff --git a/nevergrad/optimization/test_base.py b/nevergrad/optimization/test_base.py index 71dcca33f..9d851175e 100644 --- a/nevergrad/optimization/test_base.py +++ b/nevergrad/optimization/test_base.py @@ -142,9 +142,9 @@ def test_optimize_and_dump(tmp_path: Path) -> None: def test_compare() -> None: - optimizer = optimizerlib.OnePlusOne(parametrization=2, budget=600, num_workers=6) + optimizer = optimizerlib.OnePlusOne(parametrization=2, budget=1200, num_workers=6) optimizerlib.addCompare(optimizer) - for _ in range(100): # TODO make faster test + for _ in range(200): # TODO make faster test x: tp.List[tp.Any] = [] for _ in range(6): x += [optimizer.ask()] diff --git a/nevergrad/optimization/test_optimizerlib.py b/nevergrad/optimization/test_optimizerlib.py index 501c98941..def52ca48 100644 --- a/nevergrad/optimization/test_optimizerlib.py +++ b/nevergrad/optimization/test_optimizerlib.py @@ -288,6 +288,7 @@ def test_optimizers_minimal(name: str) -> None: "NLOPT_GN_CRS2_LM", "ES", "RecMixES", + "MiniDE", "RecMutDE", "RecES", "VastLengler", diff --git a/nevergrad/optimization/test_suggest.py b/nevergrad/optimization/test_suggest.py index cfcbe5de0..4f500bf5d 100644 --- a/nevergrad/optimization/test_suggest.py +++ b/nevergrad/optimization/test_suggest.py @@ -97,7 +97,7 @@ def test_harder_suggest_optimizers(name: str) -> None: optimum = np.asarray([0] * 17 + [1] * 17 + [0] * 66) target = lambda x: min(3, np.sum((np.asarray(x, dtype=int) - optimum) ** 2)) suggestion = np.asarray([0] * 17 + [1] * 16 + [0] * 67) - suggestion_testing(name, instrum, suggestion, 1500, target, optimum) + suggestion_testing(name, instrum, suggestion, 1500 + (1000 if "Lengler" in name else 0), target, optimum) @skip_win_perf # type: ignore