class_docstr: Accelerated proximal gradient descent
  
  For the minimization of objectives of the form
  
  .. math::
      f(w) + g(w),
  
  where :math:`f` has a smooth gradient and :math:`g` is prox-capable.
  Function :math:`f` corresponds to the ``model.loss`` method of the model
  (passed with ``set_model`` to the solver) and :math:`g` corresponds to
  the ``prox.value`` method of the prox (passed with the ``set_prox`` method).
  One iteration of :class:`AGD <tick.solver.AGD>` is as follows:
  
  .. math::
      w^{k} &\gets \mathrm{prox}_{\eta g} \big(z^k - \eta \nabla f(z^k)
      \big) \\
      t_{k+1} &\gets \frac{1 + \sqrt{1 + 4 t_k^2}}{2} \\
      z^{k+1} &\gets w^k + \frac{t_k - 1}{t_{k+1}} (w^k - w^{k-1})
  
  where :math:`\nabla f(w)` is the gradient of :math:`f` given by the
  ``model.grad`` method and :math:`\mathrm{prox}_{\eta g}` is given by the
  ``prox.call`` method. The step-size :math:`\eta` can be tuned with
  ``step``. The iterations stop whenever tolerance ``tol`` is achieved, or
  after ``max_iter`` iterations. The obtained solution :math:`w` is returned
  by the ``solve`` method, and is also stored in the ``solution`` attribute
  of the solver.
  
  Parameters
  ----------
  step : `float`, default=None
      Step-size parameter, the most important parameter of the solver.
      Whenever possible, this can be automatically tuned as
      ``step = 1 / model.get_lip_best()``. If ``linesearch=True``, this is
      the first step-size to be used in the linesearch (that should be taken
      as too large).
  
  tol : `float`, default=1e-10
      The tolerance of the solver (iterations stop when the stopping
      criterion is below it)
  
  max_iter : `int`, default=100
      Maximum number of iterations of the solver.
  
  linesearch : `bool`, default=True
      If `True`, use backtracking linesearch to tune the step automatically.
  
  verbose : `bool`, default=True
      If `True`, solver verboses history, otherwise nothing is displayed,
      but history is recorded anyway
  
  print_every : `int`, default=10
      Print history information every time the iteration number is a
      multiple of ``print_every``. Used only is ``verbose`` is True
  
  record_every : `int`, default=1
      Save history information every time the iteration number is a
      multiple of ``record_every``
  
  linesearch_step_increase : `float`, default=2.
      Factor of step increase when using linesearch
  
  linesearch_step_decrease : `float`, default=0.5
      Factor of step decrease when using linesearch
  
  Attributes
  ----------
  model : `Model`
      The model used by the solver, passed with the ``set_model`` method
  
  prox : `Prox`
      Proximal operator used by the solver, passed with the ``set_prox``
      method
  
  solution : `numpy.array`, shape=(n_coeffs,)
      Minimizer found by the solver
  
  history : `dict`-like
      A dict-type of object that contains history of the solver along
      iterations. It should be accessed using the ``get_history`` method
  
  time_start : `str`
      Start date of the call to ``solve()``
  
  time_elapsed : `float`
      Duration of the call to ``solve()``, in seconds
  
  time_end : `str`
      End date of the call to ``solve()``
  
  References
  ----------
  * A. Beck and M. Teboulle, A fast iterative shrinkage-thresholding
    algorithm for linear inverse problems,
    *SIAM journal on imaging sciences*, 2009
code: def _solve(self, x0: np.ndarray = None, step: float = None):
      (
          minimizer,
          prev_minimizer,
          y,
          grad_y,
          t,
          step,
          obj,
      ) = self._initialize_values(x0, step)
      for n_iter in range(self.max_iter):
          prev_t = t
          prev_minimizer[:] = minimizer
  
          # We will record on this iteration and we must be ready
          if self._should_record_iter(n_iter):
              prev_obj = self.objective(prev_minimizer)
  
          minimizer, y, t, step = self._gradient_step(
              minimizer, prev_minimizer, y, grad_y, t, prev_t, step
          )
          if step == 0:
              print("Step equals 0... at %i" % n_iter)
              break
  
          # Let's record metrics
          if self._should_record_iter(n_iter):
              rel_delta = relative_distance(minimizer, prev_minimizer)
              obj = self.objective(minimizer)
              rel_obj = abs(obj - prev_obj) / abs(prev_obj)
              converged = rel_obj < self.tol
              # If converged, we stop the loop and record the last step
              # in history
              self._handle_history(
                  n_iter + 1,
                  force=converged,
                  obj=obj,
                  x=minimizer.copy(),
                  rel_delta=rel_delta,
                  step=step,
                  rel_obj=rel_obj,
              )
              if converged:
                  break
  
      self._set("solution", minimizer)
      return minimizer
  
file_path: tick/tick/solver/agd.py
imports: import numpy
  from numpy.linalg import norm
  from .base import SolverFirstOrder
  from .base.utils import relative_distance
label_desc: Use image node_id 4 for calling the AGD obj's underlying member method code with example usage: obj._solve(x0, step) and returns: minimizer