phys_581.assignment_2
=====================

.. py:module:: phys_581.assignment_2

.. autoapi-nested-parse::

   Assignment 2



Classes
-------

.. autoapisummary::

   phys_581.assignment_2.OdeResult


Functions
---------

.. autoapisummary::

   phys_581.assignment_2.solve_ivp_abm
   phys_581.assignment_2.solve_ivp_euler
   phys_581.assignment_2.solve_ivp_rk4
   phys_581.assignment_2.step_rk45


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

.. py:class:: OdeResult

   Bases: :py:obj:`scipy.optimize.OptimizeResult`


   Bunch object for storing results of solve_ivp* methods.


.. py:function:: solve_ivp_abm(fun, t_span, y0, Nt, ys=None, dys=None, dcp=None, save_memory=False, start_factor=2)

   Solve the specified IVP using a 5th order predictor-corrector method.

   This is the algorithm presented at the end of Section 23.10 of Hamming's book.  It
   is an average of the Milne and Adams-Bashforth cases.

   :param Nt: Number of steps.  The time-step will be ``np.diff(t_span)/Nt``.
   :type Nt: int
   :param ys: First four steps to get the process started.  If not provided, then these
              will be computed using :func:`solve_ivp_rk4`.
   :type ys: [y0, y1, y2, y3] or None
   :param dys: Derivatives at the corresponding previous steps.  Will be computed if not
               provided.
   :type dys: [dy0, dy1, dy2, dy3] or None
   :param dcp: Previous corrector-predictor difference (with a factor 161/170).
   :type dcp: array, None
   :param save_memory: If `True`, then only keep the last four steps.
   :type save_memory: bool

   :returns: * **res** (*OdeResult*) -- Bunch object.
             * The remaining arguments should match those of :py:func:`scipy.integrate.solve_ivp`.
             * Don't worry about optimizations like allowing `fun` to be `vectorized` etc.

   .. admonition:: Notes

      This method requires four initial values to get started.


.. py:function:: solve_ivp_euler(fun, t_span, y0, Nt)

   Solve the specified IVP using Euler's method.

   :param Nt: Number of steps.  The time-step will be ``(t_span[1] - t_span[0])/Nt``.
   :type Nt: int

   :returns: * **res** (*OdeResult*) -- Bunch object.
             * The remaining arguments should match those of :py:func:`scipy.integrate.solve_ivp`.
             * Don't worry about optimizations like allowing `fun` to be `vectorized` etc.


.. py:function:: solve_ivp_rk4(fun, t_span, y0, Nt)

   Solve the specified IVP using 4th order Runge-Kutta.

   :param Nt: Number of steps.  The time-step will be `(t_span[1] - t_span[0])/Nt`.
   :type Nt: int

   :returns: * **res** (*OdeResult*) -- Bunch object.
             * The remaining arguments should match those of :py:func:`scipy.integrate.solve_ivp`.
             * Don't worry about optimizations like allowing `fun` to be `vectorized` etc.


.. py:function:: step_rk45(fun, t, y, f, h)

   Take one step using the RK45 algorithm.

   :param fun: Right-hand side of the system.
   :type fun: callable
   :param t: Current time.
   :type t: float
   :param y: Current state.
   :type y: ndarray, shape (n,)
   :param f: Current value of the derivative, i.e., ``fun(x, y)``.
   :type f: ndarray, shape (n,)
   :param h: Step to use.
   :type h: float

   :returns: * **y_new** (*ndarray, shape (n,)*) -- Solution at `t + h` computed with a higher accuracy.
             * **f_new** (*ndarray, shape (n,)*) -- Derivative ``fun(t + h, y_new)``.

   .. rubric:: References

   E. Hairer, S. P. Norsett G. Wanner, "Solving Ordinary Differential Equations I:
   Nonstiff Problems", Sec. II.4.


