From 59fb50f8053d64ec9296fe4ab7d91daff7cadce7 Mon Sep 17 00:00:00 2001 From: kailunqiu Date: Tue, 16 Dec 2025 18:30:45 +0800 Subject: [PATCH 1/2] Fix stopping_criterion=None handling in convergence_plot --- .../benchmarking/process_benchmark_results.py | 4 +++- .../visualization/test_convergence_plot.py | 15 ++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/optimagic/benchmarking/process_benchmark_results.py b/src/optimagic/benchmarking/process_benchmark_results.py index df443f7b0..fe942f6c4 100644 --- a/src/optimagic/benchmarking/process_benchmark_results.py +++ b/src/optimagic/benchmarking/process_benchmark_results.py @@ -129,7 +129,9 @@ def _process_one_result( } # calculate at which iteration the problem has been solved - if stopping_criterion is not None: + if stopping_criterion is None: + is_converged = False + else: is_converged_x, x_idx = _check_convergence(params_dist_normalized, x_precision) is_converged_y, y_idx = _check_convergence(normalized_crit_hist, y_precision) diff --git a/tests/optimagic/visualization/test_convergence_plot.py b/tests/optimagic/visualization/test_convergence_plot.py index 931786e30..616595ca1 100644 --- a/tests/optimagic/visualization/test_convergence_plot.py +++ b/tests/optimagic/visualization/test_convergence_plot.py @@ -75,13 +75,14 @@ def test_convergence_plot_options(options, grid, benchmark_results, close_mpl_fi def test_convergence_plot_stopping_criterion_none(benchmark_results): problems, results = benchmark_results - with pytest.raises(UnboundLocalError): - convergence_plot( - problems=problems, - results=results, - problem_subset=["bard_good_start"], - stopping_criterion=None, - ) + fig = convergence_plot( + problems=problems, + results=results, + problem_subset=["bard_good_start"], + stopping_criterion=None, + ) + + assert fig is not None def test_check_only_allowed_subset_provided_none(): From e030be6f46b66809dc92b4ea70c8d152f6b5ddf3 Mon Sep 17 00:00:00 2001 From: kailunqiu Date: Sat, 20 Dec 2025 07:19:48 +0800 Subject: [PATCH 2/2] Following maintainer feedback on PR #659, clarify that stopping_criterion=None is not supported. --- .../benchmarking/process_benchmark_results.py | 4 +--- src/optimagic/visualization/convergence_plot.py | 7 ++++--- .../visualization/test_convergence_plot.py | 15 +++++++-------- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/optimagic/benchmarking/process_benchmark_results.py b/src/optimagic/benchmarking/process_benchmark_results.py index fe942f6c4..df443f7b0 100644 --- a/src/optimagic/benchmarking/process_benchmark_results.py +++ b/src/optimagic/benchmarking/process_benchmark_results.py @@ -129,9 +129,7 @@ def _process_one_result( } # calculate at which iteration the problem has been solved - if stopping_criterion is None: - is_converged = False - else: + if stopping_criterion is not None: is_converged_x, x_idx = _check_convergence(params_dist_normalized, x_precision) is_converged_y, y_idx = _check_convergence(normalized_crit_hist, y_precision) diff --git a/src/optimagic/visualization/convergence_plot.py b/src/optimagic/visualization/convergence_plot.py index 83ad6b4de..a59882579 100644 --- a/src/optimagic/visualization/convergence_plot.py +++ b/src/optimagic/visualization/convergence_plot.py @@ -72,7 +72,7 @@ def convergence_plot( runtime_measure: Literal[ "n_evaluations", "walltime", "n_batches" ] = "n_evaluations", - stopping_criterion: Literal["x", "y", "x_and_y", "x_or_y"] | None = "y", + stopping_criterion: Literal["x", "y", "x_and_y", "x_or_y"] = "y", x_precision: float = 1e-4, y_precision: float = 1e-4, combine_plots_in_grid: bool = True, @@ -118,8 +118,9 @@ def convergence_plot( the solution value. runtime_measure: This is the runtime until the desired convergence was reached by an algorithm. - stopping_criterion: Determines how convergence is determined from the two - precisions. If None, no convergence criterion is applied. + stopping_criterion: Determines how convergence is determined from the two precisions. + To effectively disable convergence, set `x_precision` and/or `y_precision` + to very small values (or 0). x_precision: how close an algorithm must have gotten to the true parameter values (as percent of the Euclidean distance between start and solution parameters) before the criterion for clipping and convergence is fulfilled. diff --git a/tests/optimagic/visualization/test_convergence_plot.py b/tests/optimagic/visualization/test_convergence_plot.py index 616595ca1..931786e30 100644 --- a/tests/optimagic/visualization/test_convergence_plot.py +++ b/tests/optimagic/visualization/test_convergence_plot.py @@ -75,14 +75,13 @@ def test_convergence_plot_options(options, grid, benchmark_results, close_mpl_fi def test_convergence_plot_stopping_criterion_none(benchmark_results): problems, results = benchmark_results - fig = convergence_plot( - problems=problems, - results=results, - problem_subset=["bard_good_start"], - stopping_criterion=None, - ) - - assert fig is not None + with pytest.raises(UnboundLocalError): + convergence_plot( + problems=problems, + results=results, + problem_subset=["bard_good_start"], + stopping_criterion=None, + ) def test_check_only_allowed_subset_provided_none():