From 0a170b8fd958af201e0849638f6503f1b08e5c82 Mon Sep 17 00:00:00 2001 From: Pierre-antoine Comby Date: Wed, 11 May 2022 22:48:40 +0200 Subject: [PATCH 1/8] switch from progressbar to tqdm. The progress bar can be provided externally for nested usage. --- modopt/opt/algorithms/base.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/modopt/opt/algorithms/base.py b/modopt/opt/algorithms/base.py index 85c36306..658d148c 100644 --- a/modopt/opt/algorithms/base.py +++ b/modopt/opt/algorithms/base.py @@ -4,7 +4,7 @@ from inspect import getmro import numpy as np -from progressbar import ProgressBar +from tqdm.auto import tqdm from modopt.base import backend from modopt.base.observable import MetricObserver, Observable @@ -268,10 +268,10 @@ def _iterations(self, max_iter, progbar=None): print(' - Converged!') break - if not isinstance(progbar, type(None)): - progbar.update(idx) + if progbar is not None: + progbar.update() - def _run_alg(self, max_iter): + def _run_alg(self, max_iter, progbar=None): """Run algorithm. Run the update step of a given algorithm up to the maximum number of @@ -287,11 +287,10 @@ def _run_alg(self, max_iter): progressbar.bar.ProgressBar """ - if self.progress: - with ProgressBar( - redirect_stdout=True, - max_value=max_iter, - ) as progbar: + if self.progress and progbar is None: + with tqdm(total=max_iter) as progbar: self._iterations(max_iter, progbar=progbar) + elif progbar is not None: + self._iterations(max_iter, progbar=progbar) else: self._iterations(max_iter) From 8cab7da070e74342d31b303991dc193494dd9df8 Mon Sep 17 00:00:00 2001 From: Pierre-antoine Comby Date: Wed, 11 May 2022 22:50:09 +0200 Subject: [PATCH 2/8] exposes the progress bar argument. --- modopt/opt/algorithms/forward_backward.py | 12 ++++++------ modopt/opt/algorithms/primal_dual.py | 8 +++++--- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/modopt/opt/algorithms/forward_backward.py b/modopt/opt/algorithms/forward_backward.py index e18f66c3..c798e3b8 100644 --- a/modopt/opt/algorithms/forward_backward.py +++ b/modopt/opt/algorithms/forward_backward.py @@ -467,7 +467,7 @@ def _update(self): or self._cost_func.get_cost(self._x_new) ) - def iterate(self, max_iter=150): + def iterate(self, max_iter=150, progbar=None): """Iterate. This method calls update until either the convergence criteria is met @@ -479,7 +479,7 @@ def iterate(self, max_iter=150): Maximum number of iterations (default is ``150``) """ - self._run_alg(max_iter) + self._run_alg(max_iter, progbar) # retrieve metrics results self.retrieve_outputs() @@ -750,7 +750,7 @@ def _update(self): if self._cost_func: self.converge = self._cost_func.get_cost(self._x_new) - def iterate(self, max_iter=150): + def iterate(self, max_iter=150, progbar=None): """Iterate. This method calls update until either convergence criteria is met or @@ -762,7 +762,7 @@ def iterate(self, max_iter=150): Maximum number of iterations (default is ``150``) """ - self._run_alg(max_iter) + self._run_alg(max_iter, progbar=progbar) # retrieve metrics results self.retrieve_outputs() @@ -995,7 +995,7 @@ def _update(self): or self._cost_func.get_cost(self._x_new) ) - def iterate(self, max_iter=150): + def iterate(self, max_iter=150, progbar=None): """Iterate. This method calls update until either convergence criteria is met or @@ -1007,7 +1007,7 @@ def iterate(self, max_iter=150): Maximum number of iterations (default is ``150``) """ - self._run_alg(max_iter) + self._run_alg(max_iter, progbar) # retrieve metrics results self.retrieve_outputs() diff --git a/modopt/opt/algorithms/primal_dual.py b/modopt/opt/algorithms/primal_dual.py index c8566969..7ab27f10 100644 --- a/modopt/opt/algorithms/primal_dual.py +++ b/modopt/opt/algorithms/primal_dual.py @@ -225,7 +225,7 @@ def _update(self): or self._cost_func.get_cost(self._x_new, self._y_new) ) - def iterate(self, max_iter=150, n_rewightings=1): + def iterate(self, max_iter=150, n_rewightings=1, progbar=None): """Iterate. This method calls update until either convergence criteria is met or @@ -239,12 +239,14 @@ def iterate(self, max_iter=150, n_rewightings=1): Number of reweightings to perform (default is ``1``) """ - self._run_alg(max_iter) + self._run_alg(max_iter, progbar) if not isinstance(self._reweight, type(None)): for _ in range(n_rewightings): self._reweight.reweight(self._linear.op(self._x_new)) - self._run_alg(max_iter) + if progbar is not None: + progbar.reset(total=max_iter) + self._run_alg(max_iter, progbar) # retrieve metrics results self.retrieve_outputs() From ff19d0a4aef45ff402df2fb5856749d067409d20 Mon Sep 17 00:00:00 2001 From: Pierre-antoine Comby Date: Wed, 11 May 2022 22:50:39 +0200 Subject: [PATCH 3/8] Child classes better have to implement these. (my linter was complaining) --- modopt/opt/algorithms/base.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modopt/opt/algorithms/base.py b/modopt/opt/algorithms/base.py index 658d148c..0c61c184 100644 --- a/modopt/opt/algorithms/base.py +++ b/modopt/opt/algorithms/base.py @@ -294,3 +294,9 @@ def _run_alg(self, max_iter, progbar=None): self._iterations(max_iter, progbar=progbar) else: self._iterations(max_iter) + + def _update(self): + raise NotImplementedError + + def get_notify_observers_kwargs(self): + raise NotImplementedError From 4c327af4ebbe3388dce899eeb1c75ec5cc9a7e46 Mon Sep 17 00:00:00 2001 From: Pierre-antoine Comby Date: Wed, 11 May 2022 22:55:02 +0200 Subject: [PATCH 4/8] update docs for progress bar using tqdm. --- modopt/opt/algorithms/base.py | 9 +++++---- modopt/opt/algorithms/forward_backward.py | 9 ++++++--- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/modopt/opt/algorithms/base.py b/modopt/opt/algorithms/base.py index 0c61c184..dde07ce1 100644 --- a/modopt/opt/algorithms/base.py +++ b/modopt/opt/algorithms/base.py @@ -240,9 +240,8 @@ def _iterations(self, max_iter, progbar=None): ---------- max_iter : int Maximum number of iterations - progbar : progressbar.bar.ProgressBar - Progress bar (default is ``None``) - + progbar: tqdm.tqdm + Progress bar handle (default is ``None``) """ for idx in range(max_iter): self.idx = idx @@ -281,10 +280,12 @@ def _run_alg(self, max_iter, progbar=None): ---------- max_iter : int Maximum number of iterations + progbar: tqdm.tqdm + Progress bar handle (default is ``None``) See Also -------- - progressbar.bar.ProgressBar + tqdm.tqdm """ if self.progress and progbar is None: diff --git a/modopt/opt/algorithms/forward_backward.py b/modopt/opt/algorithms/forward_backward.py index c798e3b8..bafd9e19 100644 --- a/modopt/opt/algorithms/forward_backward.py +++ b/modopt/opt/algorithms/forward_backward.py @@ -477,7 +477,8 @@ def iterate(self, max_iter=150, progbar=None): ---------- max_iter : int, optional Maximum number of iterations (default is ``150``) - + progbar: tqdm.tqdm + Progress bar handle (default is ``None``) """ self._run_alg(max_iter, progbar) @@ -760,7 +761,8 @@ def iterate(self, max_iter=150, progbar=None): ---------- max_iter : int, optional Maximum number of iterations (default is ``150``) - + progbar: tqdm.tqdm + Progress bar handle (default is ``None``) """ self._run_alg(max_iter, progbar=progbar) @@ -1005,7 +1007,8 @@ def iterate(self, max_iter=150, progbar=None): ---------- max_iter : int, optional Maximum number of iterations (default is ``150``) - + progbar: tqdm.tqdm + Progress bar handle (default is ``None``) """ self._run_alg(max_iter, progbar) From 45f345cdc9f90839c94e6c2f7ae018bb5e1c84cf Mon Sep 17 00:00:00 2001 From: Pierre-antoine Comby Date: Thu, 12 May 2022 00:27:12 +0200 Subject: [PATCH 5/8] fix WPS errors --- modopt/opt/algorithms/base.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/modopt/opt/algorithms/base.py b/modopt/opt/algorithms/base.py index dde07ce1..7e8bf504 100644 --- a/modopt/opt/algorithms/base.py +++ b/modopt/opt/algorithms/base.py @@ -289,8 +289,8 @@ def _run_alg(self, max_iter, progbar=None): """ if self.progress and progbar is None: - with tqdm(total=max_iter) as progbar: - self._iterations(max_iter, progbar=progbar) + with tqdm(total=max_iter) as pb: + self._iterations(max_iter, progbar=pb) elif progbar is not None: self._iterations(max_iter, progbar=progbar) else: @@ -300,4 +300,14 @@ def _update(self): raise NotImplementedError def get_notify_observers_kwargs(self): + """Notify observers. + + Return the mapping between the metrics call and the iterated + variables. + + Returns + ------- + notify_observers_kwargs : dict, + The mapping between the iterated variables + """ raise NotImplementedError From 544135becbfbf698ba881f827c7753c03327923b Mon Sep 17 00:00:00 2001 From: Pierre-antoine Comby Date: Thu, 12 May 2022 00:27:30 +0200 Subject: [PATCH 6/8] drop progressbar requirement, add tqdm. --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 63a404ba..1f44de13 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ importlib_metadata>=3.7.0 numpy>=1.19.5 scipy>=1.5.4 -progressbar2>=3.53.1 +tqdm>=4.64.0 From a882cfd2d4128fa273f429864e4e3fd1e9a2edbd Mon Sep 17 00:00:00 2001 From: Pierre-antoine Comby Date: Thu, 12 May 2022 22:51:11 +0200 Subject: [PATCH 7/8] [lint] disable warning for non implemented function. --- modopt/opt/algorithms/base.py | 13 ++++++------- modopt/opt/algorithms/primal_dual.py | 3 ++- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/modopt/opt/algorithms/base.py b/modopt/opt/algorithms/base.py index 7e8bf504..297c7f30 100644 --- a/modopt/opt/algorithms/base.py +++ b/modopt/opt/algorithms/base.py @@ -15,7 +15,7 @@ class SetUp(Observable): r"""Algorithm Set-Up. This class contains methods for checking the set-up of an optimisation - algotithm and produces warnings if they do not comply. + algorithm and produces warnings if they do not comply. Parameters ---------- @@ -38,7 +38,6 @@ class SetUp(Observable): -------- modopt.base.observable.Observable : parent class modopt.base.observable.MetricObserver : definition of metrics - """ def __init__( @@ -300,14 +299,14 @@ def _update(self): raise NotImplementedError def get_notify_observers_kwargs(self): - """Notify observers. + """Notify Observers. Return the mapping between the metrics call and the iterated variables. - Returns - ------- - notify_observers_kwargs : dict, - The mapping between the iterated variables + Raises + ------ + NotImplementedError + This method should be overriden by subclasses. """ raise NotImplementedError diff --git a/modopt/opt/algorithms/primal_dual.py b/modopt/opt/algorithms/primal_dual.py index 7ab27f10..f99b5522 100644 --- a/modopt/opt/algorithms/primal_dual.py +++ b/modopt/opt/algorithms/primal_dual.py @@ -237,7 +237,8 @@ def iterate(self, max_iter=150, n_rewightings=1, progbar=None): Maximum number of iterations (default is ``150``) n_rewightings : int, optional Number of reweightings to perform (default is ``1``) - + progbar: tqdm.tqdm + Progress bar handle (default is ``None``) """ self._run_alg(max_iter, progbar) From 378c510beb8df360e2fdbccec4045008e490f929 Mon Sep 17 00:00:00 2001 From: Pierre-antoine Comby Date: Thu, 9 Jun 2022 15:30:52 +0200 Subject: [PATCH 8/8] simplify progbar check and argument passthrough --- modopt/opt/algorithms/base.py | 4 ++-- modopt/opt/algorithms/forward_backward.py | 2 +- modopt/opt/algorithms/primal_dual.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modopt/opt/algorithms/base.py b/modopt/opt/algorithms/base.py index 297c7f30..b236013b 100644 --- a/modopt/opt/algorithms/base.py +++ b/modopt/opt/algorithms/base.py @@ -266,7 +266,7 @@ def _iterations(self, max_iter, progbar=None): print(' - Converged!') break - if progbar is not None: + if progbar: progbar.update() def _run_alg(self, max_iter, progbar=None): @@ -290,7 +290,7 @@ def _run_alg(self, max_iter, progbar=None): if self.progress and progbar is None: with tqdm(total=max_iter) as pb: self._iterations(max_iter, progbar=pb) - elif progbar is not None: + elif progbar: self._iterations(max_iter, progbar=progbar) else: self._iterations(max_iter) diff --git a/modopt/opt/algorithms/forward_backward.py b/modopt/opt/algorithms/forward_backward.py index bafd9e19..6923a6af 100644 --- a/modopt/opt/algorithms/forward_backward.py +++ b/modopt/opt/algorithms/forward_backward.py @@ -764,7 +764,7 @@ def iterate(self, max_iter=150, progbar=None): progbar: tqdm.tqdm Progress bar handle (default is ``None``) """ - self._run_alg(max_iter, progbar=progbar) + self._run_alg(max_iter, progbar) # retrieve metrics results self.retrieve_outputs() diff --git a/modopt/opt/algorithms/primal_dual.py b/modopt/opt/algorithms/primal_dual.py index f99b5522..d5bdd431 100644 --- a/modopt/opt/algorithms/primal_dual.py +++ b/modopt/opt/algorithms/primal_dual.py @@ -245,7 +245,7 @@ def iterate(self, max_iter=150, n_rewightings=1, progbar=None): if not isinstance(self._reweight, type(None)): for _ in range(n_rewightings): self._reweight.reweight(self._linear.op(self._x_new)) - if progbar is not None: + if progbar: progbar.reset(total=max_iter) self._run_alg(max_iter, progbar)