gpe.imports
===========

.. py:module:: gpe.imports

.. autoapi-nested-parse::

   Common imports to simplify notebooks.

   Usage::

       from gpe.imports import *



Classes
-------

.. autoapisummary::

   gpe.imports.MinimizeState
   gpe.imports.MPLGrid


Functions
---------

.. autoapisummary::

   gpe.imports.evolve_to
   gpe.imports.evolve
   gpe.imports.evolves


Module Contents
---------------

.. py:class:: MinimizeState(state, real=False, fix_N=True, **kw)

   Bases: :py:obj:`Minimize`


   Minimizer for states with the pytimeode.interfaces.IStateForABMEvolver
   interface.


   .. py:attribute:: state


   .. py:attribute:: fix_N
      :value: True



   .. py:attribute:: real
      :value: False



   .. py:attribute:: _active_inds


   .. py:property:: x

      Get current state.  Must allow setting and unsetting.


   .. py:property:: _x_dtype


   .. py:method:: init()

      Overload this to initialize your state if needed.



   .. py:method:: unpack(x, state=None)

      Unpack `x` into `state` including factors of `x_scale`

      Note: Do not scale or otherwise mutate `x`.



   .. py:method:: pack(state)

      This is not symmetric with `unpack` as it does not scale
      the solution by any factors.  (This is because we unpack both
      states and Hpsi which have different scalings.).



   .. py:method:: f_df(x)

      Return the objective function and it's derivative  as a function of
      the unpacked state `x`.



   .. py:method:: g_dg(x)

      Return the objective function minimizing the residual norm.

      INCOMPLETE.



   .. py:method:: minimize(psi_tol=1e-08, E_tol=1e-12, callback=None, _debug=False, **kw)

      Return the state with minimized energy.

      If `x_tol < sqrt(eps)`, then we use the canned L-BFGS-B algorithm from
      scipy as the is very robust.  If we need higher precision on `x`, then
      we use a custom L-BFGS algorithm with a modified stopping criterion.

      :param f_tol: Relative stopping tolerance for the energy.
      :type f_tol: float
      :param x_tol: Relative stopping tolerance for the wavefunction.
      :type x_tol: float
      :param polish: If `True`, then build an approximation to the hessian during the
                     minimization phase so that this can be used with Broyden's method to
                     polish the solution to high accuracy after the energy is minimized.
                     This allows us to ensure that the wavefunction is also converged to
                     high accuracy.  (Since the energy is quadratic about the minimum, it
                     is common for the energy to be converged to machine precision eps
                     even though the state is only converged to about sqrt(eps)).

                     Currently does not actually polish the solution - only stores the data in
                     `self.broyden_data`.  See `use_scipy` below.
      :type polish: bool
      :param broyden_alpha: Initial inverse Jacobian approximation is `alpha` times the
                            identity.  If `None`, then this will be estimated by performing a
                            line search in the descent direction.
      :type broyden_alpha: None, float
      :param broyden_opts: Arguments to pass through to `mmfutils.solve.broyden.DyadicSum()`.
      :type broyden_opts: dict()
      :param use_scipy: If `True`, then use the scipy solvers, otherwise, if `x_tol < sqrt(eps)`,
                        then use our custom solver that performs Broyden iterations after.  The issue
                        here is that the minimizer might bail out prematurely because of the `f_tol`
                        criterion before reaching the desired `x_tol` because the minimum is
                        quadratic.  Since we have information about the hessian, we can in principle
                        continue to refine the solution with Broyden iterations to minimize the norm
                        of the residual.

                        This is the idea of the polish option, but one can "trick" scipy into doing
                        this by setting `f_tol=np.nan`.  This will always invalidate the criterion
                        (even `f_tol=0` can fail sometimes when the energy is very flat) and force
                        scipy to continue until `x_tol` is met or the method fails.  Always check
                        your answer if you do this!
      :type use_scipy: bool
      :param _debug: If `True` then return `(x, f, df, locals())`.
      :type _debug: bool

      :returns: * **x** (*array*) -- Solution
                * **f, df** (*functions*) -- Objective function and its gradient in the packed representation.
                * *Developer notes*
                * 1. Do not mutate `state0`.  Use `state` as a working copy if a -- true state is needed.
                * 2. Be careful which version of `state` or `state0` you use as the -- argument to `get_Hy` and `get_energy` since this determines the
                  non-linear portions.  In general one should use `state`, but
                  if one implements a minimization on the norm of `Hy` then for
                  the derivative one must be careful.



.. py:function:: evolve_to(state, t, Evolver=EvolverABM, dt_t_scale=0.1, callback=None, plot_steps=100)

   Evolve state to time t.

   :param callback: If provided, then call callback(state) every plot_steps steps.
   :type callback: None, function
   :param plot_steps: Steps to take between plots.
   :type plot_steps: int


.. py:function:: evolve(state=None, history=None, Evolver=EvolverABM, t_max=np.inf, dt_t_scale=0.1, steps=100, display=True)

   Iterator that runs an evolver.

   :param state: State to evolve.
   :type state: IState
   :param history: List of states.  If provided, then use the last state to
                   start.  This is mutated.
   :type history: [State]
   :param Evolver: Evolver to use.
   :type Evolver: IEvolver
   :param t_max: Maximum time to evolve to.  (Default - evolve until
                 interrupted.)
   :type t_max: float
   :param dt_t_scale: Size of time-step in units of state.t_scale.
   :type dt_t_scale: float
   :param steps: Steps to evolve between yielded states.
   :type steps: int
   :param display: If True, then display the current figure (using plt.gcf()).
   :type display: bool
   :param Example:
   :param for y in evolve(s): plt.clf()
                              y.plot()


.. py:function:: evolves(states=None, histories=None, Evolver=EvolverABM, t_max=np.inf, dt_t_scale=0.1, steps=100, fig=None, display=True)

   Iterator that runs an evolver like evolve() but with multiple states.

   :param states: List of states to evolve.  The first of these is used as the
                  reference state for units such as t_scale etc.
   :type states: IState
   :param histories: List of histories: each is a list of states.  If provided, then
                     use the last states to start.  These lists are mutated.
   :type histories: [[State]]
   :param Evolver: Evolver to use.
   :type Evolver: IEvolver
   :param t_max: Maximum time to evolve to.  (Default - evolve until
                 interrupted.)
   :type t_max: float
   :param dt_t_scale: Size of time-step in units of state.t_scale.
   :type dt_t_scale: float
   :param steps: Steps to evolve between yielded states.
   :type steps: int
   :param display: If True, then display the current figure (using fig or plt.gcf()).
   :type display: bool


.. py:class:: MPLGrid(fig=None, subplot_spec=None, ax=None, direction='down', right=False, scale=True, space=None, share=False, size=1, **kw)

   Object for stacking plots.

   After initializing the object, call next() to get the next axis.  By
   default axes will stack vertically.

   .. attribute:: down

      If True, then stack elements vertically growing down.  Otherwise stack
      elements horizontally growing right.

      :type: bool

   .. attribute:: ratios

      List of relative size of each entry.

      :type: [float]

   .. attribute:: axes

      List of axes of nested grid objects.

      :type: [Axes, MPLGrid]

   .. attribute:: direction

      Direction of growth.

      :type: ['down', 'right']

   .. attribute:: right

      Specify if y axis labels should be on the right or left.

      :type: bool

   .. attribute:: scale

      If False, then when a parent MPLGrid is being adjusted, the ratio for
      this grid component will be the sum of the ratios rather than the
      specified parent ratio.  If True, then all the components will be
      scaled to fit into the parents ratio.

      :type: bool

   .. attribute:: share

      If `True`, then axes in the growth direction are shared, and tick labels
      etc. are suppressed except for the final one.

      :type: bool

   .. attribute:: space

      Space (hspace or wspace) between grids.  If this is None, then the space
      is set of zero if the axes are shared and 0.1 otherwise.

      :type: float, None

   .. attribute:: size

      Default size for new elements.

      :type: float


   .. py:attribute:: fig
      :value: None



   .. py:attribute:: subplot_spec
      :value: None



   .. py:attribute:: shape
      :value: [0, 0]



   .. py:attribute:: kw


   .. py:attribute:: right
      :value: False



   .. py:attribute:: share
      :value: False



   .. py:attribute:: direction
      :value: 'down'



   .. py:attribute:: _ratios
      :value: []



   .. py:attribute:: axes
      :value: []



   .. py:attribute:: space
      :value: None



   .. py:attribute:: scale
      :value: True



   .. py:attribute:: size
      :value: 1



   .. py:method:: __getitem__(key)


   .. py:method:: adjust()

      Adjust the positions of all the axes.



   .. py:method:: __repr__()


   .. py:property:: ratios

      Return the size ratios for the various axes.

      If the sub-axis is an MPLGrid instance with scale == False, then the
      ratio is the sum of the sub-grid's ratios.


   .. py:property:: _gridspec


   .. py:method:: next(size=None)

      Return the next axis.



   .. py:method:: empty(size=None)

      Return the next axis but hide it so it acts as a space.



   .. py:method:: grid(size=None, **kw)

      Insert a sub-grid and return it.



   .. py:method:: rescale(tight=None, scalex=True, scaley=True, force=False)


