# Source code for naginterfaces.library.ode

# -*- coding: utf-8 -*-
r"""
Module Summary
--------------
Interfaces for the NAG Mark 28.7 ode Chapter.

ode - Ordinary Differential Equations

This module is concerned with the numerical solution of ordinary differential equations.
There are two main types of problem: those in which all boundary conditions are specified at one point (initial value problems), and those in which the boundary conditions are distributed between two or more points (boundary value problems and eigenvalue problems). Functions are available for initial value problems, two-point boundary value problems and Sturm--Liouville eigenvalue problems.

--------
naginterfaces.library.examples.ode :
This subpackage contains examples for the ode module.
See also the :ref:library_ode_ex subsection.

Functionality Index
-------------------

Differentiation of a function discretized on Chebyshev Gauss--Lobatto points: :meth:bvp_ps_lin_cgl_deriv

**Linear constant coefficient boundary value problem**

Chebyshev spectral integration method

Chebyshev coefficients generator for a function discretized on Chebyshev Gauss--Lobatto grid: :meth:bvp_ps_lin_coeffs

Chebyshev coefficients to function values on Chebyshev Gauss--Lobatto grid: :meth:bvp_ps_lin_cgl_vals

Chebyshev Gauss--Lobatto grid generator: :meth:bvp_ps_lin_cgl_grid

Chebyshev integration solver for linear constant coefficient boundary value problem: :meth:bvp_ps_lin_solve

Clenshaw--Curtis quadrature weights generator at Chebyshev Gauss--Lobatto points: :meth:bvp_ps_lin_quad_weights

Evaluation on uniform grid of function by Barycentric Lagrange interpolation: :meth:bvp_ps_lin_grid_vals

value of :math:k\ th Chebyshev polynomial: :meth:bvp_ps_lin_cheb_eval

**Second-order Sturm--Liouville problems**

regular/singular system, finite/infinite range

eigenvalue and eigenfunction: :meth:sl2_breaks_funs

eigenvalue only: :meth:sl2_breaks_vals

regular system, finite range, user-specified break-points

eigenvalue only: :meth:sl2_reg_finite

**System of first-order ordinary differential equations, initial value problems**

:math:{C}^1-interpolant: :meth:ivp_stiff_c1_interp

comprehensive integrator functions for stiff systems

continuation to call :meth:dae_dassl_gen: :meth:dae_dassl_cont

explicit ordinary differential equations

banded Jacobian: :meth:ivp_stiff_exp_bandjac

full Jacobian: :meth:ivp_stiff_exp_fulljac

sparse Jacobian: :meth:ivp_stiff_exp_sparjac

explicit ordinary differential equations (reverse communication)

full Jacobian: :meth:ivp_stiff_exp_revcom

implicit ordinary differential equations coupled with algebraic equations

banded Jacobian: :meth:ivp_stiff_imp_bandjac

banded Jacobian selector for DASSL integrator: :meth:dae_dassl_linalg

DASSL integrator: :meth:dae_dassl_gen

full Jacobian: :meth:ivp_stiff_imp_fulljac

integrator setup for DASSL: :meth:dae_dassl_setup

sparse Jacobian: :meth:ivp_stiff_imp_sparjac

implicit ordinary differential equations coupled with algebraic equations (reverse communication): :meth:ivp_stiff_imp_revcom

comprehensive integrator functions using Adams' method with root-finding option

diagnostic function: :meth:ivp_adams_diag

diagnostic function for root-finding: :meth:ivp_adams_rootdiag

direct communication: :meth:ivp_adams_roots

interpolant: :meth:ivp_adams_interp

reverse communication: :meth:ivp_adams_roots_revcom

setup function: :meth:ivp_adams_setup

comprehensive integrator functions using Runge--Kutta methods

diagnostic function: :meth:ivp_rkts_diag

diagnostic function for global error assessment: :meth:ivp_rkts_errass

interpolant, reverse communication: :meth:ivp_rk_interp_setup

interpolant and interpolation, direct communication: :meth:ivp_rkts_interp

interpolation, reverse communication: :meth:ivp_rk_interp_eval

over a range with intermediate output: :meth:ivp_rkts_range

over a step, direct communication: :meth:ivp_rkts_onestep

over a step, reverse communication: :meth:ivp_rk_step_revcomm

reset end of range: :meth:ivp_rkts_reset_tend

setup function: :meth:ivp_rkts_setup

compute weighted norm of local error estimate: :meth:ivp_stiff_errest

enquiry function for use with sparse Jacobian: :meth:ivp_stiff_sparjac_enq

integrator diagnostic function: :meth:ivp_stiff_integ_diag

integrator setup for backward differentiation formulae method for SPRINT integrator: :meth:ivp_stiff_bdf

integrator setup for Blend method for SPRINT integrator: :meth:ivp_stiff_blend

integrator setup for DASSL method for SPRINT integrator: :meth:ivp_stiff_dassl

linear algebra diagnostic function for sparse Jacobians: :meth:ivp_stiff_sparjac_diag

linear algebra setup for banded Jacobians: :meth:ivp_stiff_bandjac_setup

linear algebra setup for full Jacobians: :meth:ivp_stiff_fulljac_setup

linear algebra setup for sparse Jacobians: :meth:ivp_stiff_sparjac_setup

natural interpolant: :meth:ivp_stiff_interp

natural interpolant (for use by MONITR subfunction): :meth:ivp_stiff_nat_interp

setup function for continuation calls to integrator: :meth:ivp_stiff_contin

simple driver functions

Runge--Kutta--Merson method

until a function of the solution is zero: :meth:ivp_rkm_zero_simple

until a specified component attains a given value: :meth:ivp_rkm_val_simple

Runge--Kutta method

until (optionally) a function of the solution is zero, with optional intermediate output: :meth:ivp_rk_zero_simple

variable-order variable-step Adams' method

until (optionally) a function of the solution is zero, with optional intermediate output: :meth:ivp_adams_zero_simple

variable-order variable-step backward differentiation formulae method for stiff systems

until (optionally) a function of the solution is zero, with optional intermediate output: :meth:ivp_bdf_zero_simple

**System of ordinary differential equations, boundary value problems**

collocation and least squares

single :math:n\ th-order linear equation: :meth:bvp_coll_nth

system of first-order linear equations: :meth:bvp_coll_sys

system of :math:n\ th-order linear equations: :meth:bvp_coll_nth_comp

comprehensive functions using a collocation technique

continuation function: :meth:bvp_coll_nlin_contin

diagnostic function: :meth:bvp_coll_nlin_diag

general nonlinear problem solver (thread safe): :meth:bvp_coll_nlin_solve

interpolation function: :meth:bvp_coll_nlin_interp

setup function: :meth:bvp_coll_nlin_setup

finite difference technique with deferred correction

general linear problem: :meth:bvp_fd_lin_gen

general nonlinear problem, with continuation facility: :meth:bvp_fd_nonlin_gen

simple nonlinear problem: :meth:bvp_fd_nonlin_fixedbc

shooting and matching technique

boundary values to be determined: :meth:bvp_shoot_bval

general parameters to be determined: :meth:bvp_shoot_genpar

general parameters to be determined, allowing interior matching-point: :meth:bvp_shoot_genpar_intern

general parameters to be determined, subject to extra algebraic equations: :meth:bvp_shoot_genpar_algeq

**System of second-order ordinary differential equations**

Runge--Kutta--Nystrom method

diagnostic function: :meth:ivp_2nd_rkn_diag

integrator: :meth:ivp_2nd_rkn

interpolating solutions: :meth:ivp_2nd_rkn_interp

setup function: :meth:ivp_2nd_rkn_setup

For full information please refer to the NAG Library document

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02intro.html
"""

# NAG Copyright 2017-2022.

[docs]def bvp_shoot_genpar_intern(h, e, parerr, param, m1, aux, bcaux, raaux, prsol, data=None):
r"""
bvp_shoot_genpar_intern solves a two-point boundary value problem for a system of ordinary differential equations, using initial value techniques and Newton iteration; it generalizes :meth:bvp_shoot_bval to include the case where parameters other than boundary values are to be determined.

.. _d02ag-py2-py-doc:

For full information please refer to the NAG Library document for d02ag

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02agf.html

.. _d02ag-py2-py-parameters:

**Parameters**
**h** : float
:math:\mathrm{h} must be set to an estimate of the step size, :math:h, needed for integration.

**e** : float, array-like, shape :math:\left(n\right)
:math:\mathrm{e}[i-1] must be set to a small quantity to control the :math:i\ th solution component. The element :math:\mathrm{e}[i-1] is used:

(i) in the bound on the local error in the :math:i\ th component of the solution :math:y_i during integration,

(#) in the convergence test on the :math:i\ th component of the solution :math:y_i at the matching point in the Newton iteration.

The elements :math:\mathrm{e}[i-1] should not be chosen too small.

They should usually be several orders of magnitude larger than machine precision.

**parerr** : float, array-like, shape :math:\left(\textit{n1}\right)
:math:\mathrm{parerr}[i-1] must be set to a small quantity to control the :math:i\ th parameter component. The element :math:\mathrm{parerr}[i-1] is used:

(i) in the convergence test on the :math:i\ th parameter in the Newton iteration,

(#) in perturbing the :math:i\ th parameter when approximating the derivatives of the components of the solution with respect to the :math:i\ th parameter, for use in the Newton iteration.

The elements :math:\mathrm{parerr}[i-1] should not be chosen too small.

They should usually be several orders of magnitude larger than machine precision.

**param** : float, array-like, shape :math:\left(\textit{n1}\right)
:math:\mathrm{param}[\textit{i}-1] must be set to an estimate for the :math:\textit{i}\ th parameter, :math:p_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n1}.

**m1** : int
Determines whether or not the final solution is computed as well as the parameter values.

:math:\mathrm{m1} = 1

The final solution is not calculated;

:math:\mathrm{m1} > 1

The final values of the solution at interval (length of range)/:math:\left(\mathrm{m1}-1\right) are calculated and stored sequentially in the array :math:\mathrm{c} starting with the values of :math:y_i evaluated at the first end point (see :math:\mathrm{raaux}) stored in :math:\mathrm{c}[0,i-1].

**aux** : callable f = aux(n, y, x, param, data=None)
:math:\mathrm{aux} must evaluate the functions :math:f_i (i.e., the derivatives :math:y_i^{\prime }) for given values of its arguments, :math:x,y_1,\ldots,y_{\textit{n}}, :math:p_1,\ldots,p_{\textit{n}_1}\text{.}

**Parameters**
**n** : int
:math:\textit{n}, the total number of differential equations.

**y** : float, ndarray, shape :math:\left(\mathrm{n}\right)
:math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}, the value of the argument.

**x** : float
:math:x, the value of the argument.

**param** : float, ndarray, shape :math:\left(\textit{n1}\right)
:math:p_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}_1, the value of the parameters.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**f** : float, array-like, shape :math:\left(\mathrm{n}\right)
The value of :math:f_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}.

**bcaux** : callable (g0, g1) = bcaux(n, param, data=None)
:math:\mathrm{bcaux} must evaluate the values of :math:y_i at the end points of the range given the values of :math:p_1,\ldots,p_{\textit{n}_1}.

**Parameters**
**n** : int
:math:\textit{n}, the total number of differential equations.

**param** : float, ndarray, shape :math:\left(\textit{n1}\right)
:math:p_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}, the value of the parameters.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**g0** : float, array-like, shape :math:\left(\mathrm{n}\right)
The values :math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}, at the boundary point :math:x_0 (see :math:\mathrm{raaux}).

**g1** : float, array-like, shape :math:\left(\mathrm{n}\right)
The values :math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}, at the boundary point :math:x_1 (see :math:\mathrm{raaux}).

**raaux** : callable (x0, x1, r) = raaux(param, data=None)
:math:\mathrm{raaux} must evaluate the end points, :math:x_0 and :math:x_1, of the range and the matching point, :math:r, given the values :math:p_1,p_2,\ldots,p_{\textit{n}_1}.

**Parameters**
**param** : float, ndarray, shape :math:\left(\textit{n1}\right)
:math:p_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}_1, the value of the parameters.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**x0** : float
Must contain the left-hand end of the range, :math:x_0.

**x1** : float
Must contain the right-hand end of the range :math:x_1.

**r** : float
Must contain the matching point, :math:r.

**prsol** : callable prsol(param, res, err, data=None)
:math:\mathrm{prsol} is called at each iteration of the Newton method and can be used to print the current values of the parameters :math:p_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}_1, their errors, :math:e_i, and the sum of squares of the errors at the matching point, :math:r.

**Parameters**
**param** : float, ndarray, shape :math:\left(\textit{n1}\right)
:math:p_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}_1, the current value of the parameters.

**res** : float
The sum of squares of the errors in the arguments, :math:\sum_{{i = 1}}^{\textit{n}_1}e_i^2.

**err** : float, ndarray, shape :math:\left(\textit{n1}\right)
The errors in the parameters, :math:e_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}_1.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**data** : arbitrary, optional
User-communication data for callback functions.

**Returns**
**h** : float
The last step length used.

**param** : float, ndarray, shape :math:\left(\textit{n1}\right)
The corrected value for the :math:i\ th parameter, unless an error has occurred, when it contains the last calculated value of the parameter (possibly perturbed by :math:\mathrm{parerr}[i-1]\times \left(1+\left\lvert \mathrm{param}[i-1]\right\rvert \right) if the error occurred when calculating the approximate derivatives).

**c** : float, ndarray, shape :math:\left(\mathrm{m1}, n\right)
The solution when :math:\mathrm{m1} > 1 (see :math:\mathrm{m1}).

If :math:\mathrm{m1} = 1, the elements of :math:\mathrm{c} are not used.

.. _d02ag-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:\textit{n1} = \langle\mathit{\boldsymbol{value}}\rangle and :math:n = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\textit{n1}\leq n.

(errno :math:2)
No further progress can be made when stepping to obtain a Jacobian update for the current parameter values. Step length :math:\mathrm{h} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:3)
Currently the matching point :math:r does not lie in range :math:\left[x_0, x_1\right].

If :math:x_0, :math:x_1 or :math:r depend on the parameters then this may occur when care is not taken to avoid it.

:math:r = \langle\mathit{\boldsymbol{value}}\rangle, :math:x_0 = \langle\mathit{\boldsymbol{value}}\rangle and :math:x_1 = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:4)
No further progress can be made when stepping to a solution corresponding to the current parameter values.

Step length :math:\mathrm{h} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:5)
The Jacobian for parameter corrections is singular.

(errno :math:6)
The Newton method failed to converge while updating parameter values.

(errno :math:7)
The Newton method has not converged after :math:12 iterations while updating parameter values.

.. _d02ag-py2-py-notes:

**Notes**
No equivalent traditional C interface for this routine exists in the NAG Library.

bvp_shoot_genpar_intern solves a two-point boundary value problem by determining the unknown parameters :math:p_1,p_2,\ldots,p_{\textit{n}_1} of the problem.
These parameters may be, but need not be, boundary values (as they are in :meth:bvp_shoot_bval); they may include eigenvalue parameters in the coefficients of the differential equations, length of the range of integration, etc.
The notation and methods used are similar to those of :meth:bvp_shoot_bval and you are advised to study this first. (There the parameters :math:p_1,p_2,\ldots,p_{\textit{n}_1} correspond to the unknown boundary conditions.) It is assumed that we have a system of :math:\textit{n} first-order ordinary differential equations of the form

.. math::
\frac{{dy_i}}{{dx}} = f_i\left(x, y_1, y_2, \ldots, y_{\textit{n}}\right)\text{, }\quad i = 1,2,\ldots,\textit{n}\text{,}

and that derivatives :math:f_i are evaluated by :math:\mathrm{aux}.
The system, including the boundary conditions given by :math:\mathrm{bcaux}, and the range of integration and matching point, :math:r, given by :math:\mathrm{raaux}, involves the :math:\textit{n}_1 unknown parameters :math:p_1,p_2,\ldots,p_{\textit{n}_1} which are to be determined, and for which initial estimates must be supplied.
The number of unknown parameters :math:\textit{n}_1 must not exceed the number of equations :math:\textit{n}.
If :math:\textit{n}_1 < \textit{n}, we assume that :math:\left(\textit{n}-\textit{n}_1\right) equations of the system are not involved in the matching process.
These are usually referred to as 'driving equations'; they are independent of the parameters and of the solutions of the other :math:\textit{n}_1 equations.
In numbering the equations for :math:\mathrm{aux}, the driving equations must be put last.

The estimated values of the parameters are corrected by a form of Newton iteration.
The Newton correction on each iteration is calculated using a matrix whose :math:\left(i, j\right)\ th element depends on the derivative of the :math:i\ th component of the solution, :math:y_i, with respect to the :math:j\ th parameter, :math:p_j.
This matrix is calculated by a simple numerical differentiation technique which requires :math:\textit{n}_1 evaluations of the differential system.
"""
raise NotImplementedError

[docs]def ivp_rkm_val_simple(x, xend, y, tol, hmax, m, val, fcn, data=None):
r"""
ivp_rkm_val_simple integrates a system of first-order ordinary differential equations over an interval with suitable initial conditions, using a Runge--Kutta--Merson method, until a specified component attains a given value.

.. _d02bg-py2-py-doc:

For full information please refer to the NAG Library document for d02bg

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02bgf.html

.. _d02bg-py2-py-parameters:

**Parameters**
**x** : float
Must be set to the initial value of the independent variable :math:x.

**xend** : float
The final value of the independent variable :math:x.

If :math:\mathrm{xend} < \mathrm{x} on entry integration will proceed in the negative direction.

**y** : float, array-like, shape :math:\left(n\right)
The initial values of the solution :math:y_1,y_2,\ldots,y_{\textit{n}}.

**tol** : float
Must be set to a positive tolerance for controlling the error in the integration and in the determination of the position where :math:y_m = \alpha.

ivp_rkm_val_simple has been designed so that, for most problems, a reduction in :math:\mathrm{tol} leads to an approximately proportional reduction in the error in the solution obtained in the integration.

The relation between changes in :math:\mathrm{tol} and the error in the determination of the position where :math:y_m = \alpha is less clear, but for :math:\mathrm{tol} small enough the error should be approximately proportional to :math:\mathrm{tol}.

However, the actual relation between :math:\mathrm{tol} and the accuracy cannot be guaranteed.

You are strongly recommended to call ivp_rkm_val_simple with more than one value for :math:\mathrm{tol} and to compare the results obtained to estimate their accuracy.

In the absence of any prior knowledge you might compare results obtained by calling ivp_rkm_val_simple with :math:\mathrm{tol} = 10.0^{{-p}} and :math:\mathrm{tol} = 10.0^{{-p-1}} if :math:p correct decimal digits in the solution are required.

**hmax** : float
Controls how the sign of :math:y_m-\alpha is checked.

:math:\mathrm{hmax} = 0.0

:math:y_m-\alpha is checked at every internal integration step.

:math:\mathrm{hmax}\neq 0.0

The computed solution is checked for a change in sign of :math:y_m-\alpha at steps of not greater than :math:\left\lvert \mathrm{hmax}\right\rvert. This facility should be used if there is any chance of 'missing' the change in sign by checking too infrequently. For example, if two changes of sign of :math:y_m-\alpha are expected within a distance :math:h, say, of each other then a suitable value for :math:\mathrm{hmax} might be :math:\mathrm{hmax} = h/2. If only one change of sign in :math:y_m-\alpha is expected on the range :math:\mathrm{x} to :math:\mathrm{xend} then :math:\mathrm{hmax} = 0.0 is most appropriate.

**m** : int
The index :math:m of the component of the solution whose value is to be checked.

**val** : float
The value of :math:\alpha in the equation :math:y_m = \alpha to be solved for :math:\mathrm{x}.

**fcn** : callable f = fcn(x, y, data=None)
:math:\mathrm{fcn} must evaluate the functions :math:f_i (i.e., the derivatives :math:y_i^{\prime }) for given values of its arguments :math:x,y_1,\ldots,y_{\textit{n}}.

**Parameters**
**x** : float
:math:x, the value of the argument.

**y** : float, ndarray, shape :math:\left(n\right)
:math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}, the value of the argument.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**f** : float, array-like, shape :math:\left(n\right)
The value of :math:f_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}.

**data** : arbitrary, optional
User-communication data for callback functions.

**Returns**
**x** : float
The point where the component :math:y_m attains the value :math:\alpha unless an error has occurred, when it contains the value of :math:x at the error. In particular, if :math:y_m\neq \alpha anywhere on the range :math:x = \mathrm{x} to :math:x = \mathrm{xend}, it will contain :math:\mathrm{xend} on exit.

**y** : float, ndarray, shape :math:\left(n\right)
The computed values of the solution at a point near the solution :math:\mathrm{x}, unless an error has occurred when they contain the computed values at the final value of :math:\mathrm{x}.

**tol** : float
Normally unchanged. However if the range from :math:\mathrm{x} to the position where :math:y_m = \alpha (or to the final value of :math:\mathrm{x} if an error occurs) is so short that a small change in :math:\mathrm{tol} is unlikely to make any change in the computed solution then, on return, :math:\mathrm{tol} has its sign changed. To check results returned with :math:\mathrm{tol} < 0.0, ivp_rkm_val_simple should be called again with a positive value of :math:\mathrm{tol} whose magnitude is considerably smaller than that of the previous call.

.. _d02bg-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:\mathrm{m} = \langle\mathit{\boldsymbol{value}}\rangle and :math:n = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{m}\leq n.

(errno :math:1)
On entry, :math:\mathrm{m} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{m} > 0.

(errno :math:1)
On entry, :math:n = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:n > 0.

(errno :math:1)
On entry, :math:\mathrm{tol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{tol} > 0.0.

(errno :math:2)
The value of :math:\mathrm{tol}, :math:\langle\mathit{\boldsymbol{value}}\rangle, is too small for the function to make any further progress across the integration range. Current value of :math:\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:3)
The value of :math:\mathrm{tol}, :math:\langle\mathit{\boldsymbol{value}}\rangle, is too small for the function to take an initial step.

(errno :math:5)
An internal error has occurred in this function. Check the function call and any array sizes. If the call is correct then please contact NAG <https://www.nag.com>__ for assistance.

(errno :math:6)
A serious error occurred in a call to the internal integrator.

The error code internally was :math:\langle\mathit{\boldsymbol{value}}\rangle. Please contact NAG <https://www.nag.com>__.

(errno :math:7)
Unexpected internal error in call to interpolation routine.

The interpolation routine returned error flag :math:\langle\mathit{\boldsymbol{value}}\rangle.

**Warns**
**NagAlgorithmicWarning**
(errno :math:4)
No change in sign of the function :math:y_m-\alpha was detected in the integration range.

.. _d02bg-py2-py-notes:

**Notes**
No equivalent traditional C interface for this routine exists in the NAG Library.

ivp_rkm_val_simple advances the solution of a system of ordinary differential equations

.. math::
y_i^{\prime } = f_i\left(x, y_1, y_2, \ldots, y_{\textit{n}}\right)\text{, }\quad i = 1,2,\ldots,\textit{n}\text{,}

from :math:x = \mathrm{x} towards :math:x = \mathrm{xend} using a Merson form of the Runge--Kutta method.
The system is defined by :math:\mathrm{fcn}, which evaluates :math:f_i in terms of :math:x and :math:y_1,y_2,\ldots,y_{\textit{n}} (see :ref:Parameters <d02bg-py2-py-parameters>), and the values of :math:y_1,y_2,\ldots,y_{\textit{n}} must be given at :math:x = \mathrm{x}.

As the integration proceeds, a check is made on the specified component :math:y_m of the solution to determine an interval where it attains a given value :math:\alpha.
The position where this value is attained is then determined accurately by interpolation on the solution and its derivative.
It is assumed that the solution of :math:y_m = \alpha can be determined by searching for a change in sign in the function :math:y_m-\alpha.

The accuracy of the integration and, indirectly, of the determination of the position where :math:y_m = \alpha is controlled by the argument :math:\mathrm{tol}.

For a description of Runge--Kutta methods and their practical implementation see Hall and Watt (1976).

.. _d02bg-py2-py-references:

**References**
Hall, G and Watt, J M (ed.), 1976, Modern Numerical Methods for Ordinary Differential Equations, Clarendon Press, Oxford
"""
raise NotImplementedError

[docs]def ivp_rkm_zero_simple(x, xend, y, tol, irelab, hmax, fcn, g, data=None):
r"""
ivp_rkm_zero_simple integrates a system of first-order ordinary differential equations over an interval with suitable initial conditions, using a Runge--Kutta--Merson method, until a user-specified function of the solution is zero.

.. _d02bh-py2-py-doc:

For full information please refer to the NAG Library document for d02bh

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02bhf.html

.. _d02bh-py2-py-parameters:

**Parameters**
**x** : float
Must be set to the initial value of the independent variable :math:x.

**xend** : float
The final value of the independent variable :math:x.

If :math:\mathrm{xend} < \mathrm{x} on entry, integration proceeds in a negative direction.

**y** : float, array-like, shape :math:\left(n\right)
The initial values of the solution :math:y_1,y_2,\ldots,y_{\textit{n}}.

**tol** : float
Must be set to a **positive** tolerance for controlling the error in the integration and in the determination of the position where :math:g\left(x, y\right) = 0.0.

ivp_rkm_zero_simple has been designed so that, for most problems, a reduction in :math:\mathrm{tol} leads to an approximately proportional reduction in the error in the solution obtained in the integration.

The relation between changes in :math:\mathrm{tol} and the error in the determination of the position where :math:g\left(x, y\right) = 0.0 is less clear, but for :math:\mathrm{tol} small enough the error should be approximately proportional to :math:\mathrm{tol}.

However, the actual relation between :math:\mathrm{tol} and the accuracy cannot be guaranteed.

You are strongly recommended to call ivp_rkm_zero_simple with more than one value for :math:\mathrm{tol} and to compare the results obtained to estimate their accuracy.

In the absence of any prior knowledge you might compare results obtained by calling ivp_rkm_zero_simple with :math:\mathrm{tol} = 10.0^{{-p}} and :math:\mathrm{tol} = 10.0^{{-p-1}} if :math:p correct decimal digits in the solution are required.

**irelab** : int
Determines the type of error control. At each step in the numerical solution an estimate of the local error, :math:\textit{est}, is made. For the current step to be accepted the following condition must be satisfied:

:math:\mathrm{irelab} = 0

:math:\textit{est}\leq \mathrm{tol}\times \mathrm{max}\left\{1.0,\left\lvert y_1\right\rvert,\left\lvert y_2\right\rvert,\ldots,\left\lvert y_{\textit{n}}\right\rvert \right\};

:math:\mathrm{irelab} = 1

:math:\textit{est}\leq \mathrm{tol};

:math:\mathrm{irelab} = 2

:math:\textit{est}\leq \mathrm{tol}\times \mathrm{max}\left\{\epsilon,\left\lvert y_1\right\rvert,\left\lvert y_2\right\rvert,\ldots,\left\lvert y_{\textit{n}}\right\rvert \right\}, where :math:\epsilon is machine precision.

If the appropriate condition is not satisfied, the step size is reduced and the solution recomputed on the current step.

If you wish to measure the error in the computed solution in terms of the number of correct decimal places, set :math:\mathrm{irelab} = 1 on entry, whereas if the error requirement is in terms of the number of correct significant digits, set :math:\mathrm{irelab} = 2.

Where there is no preference in the choice of error test, :math:\mathrm{irelab} = 0 will result in a mixed error test.

It should be borne in mind that the computed solution will be used in evaluating :math:g\left(x, y\right).

**hmax** : float
If :math:\mathrm{hmax} = 0.0, no special action is taken.

If :math:\mathrm{hmax}\neq 0.0, a check is made for a change in sign of :math:g\left(x, y\right) at steps not greater than :math:\left\lvert \mathrm{hmax}\right\rvert.

This facility should be used if there is any chance of 'missing' the change in sign by checking too infrequently.

For example, if two changes of sign of :math:g\left(x, y\right) are expected within a distance :math:h, say, of each other, a suitable value for :math:\mathrm{hmax} might be :math:\mathrm{hmax} = h/2.

If only one change of sign in :math:g\left(x, y\right) is expected on the range :math:\mathrm{x} to :math:\mathrm{xend}, the choice :math:\mathrm{hmax} = 0.0 is most appropriate.

**fcn** : callable f = fcn(x, y, data=None)
:math:\mathrm{fcn} must evaluate the functions :math:f_i (i.e., the derivatives :math:y_i^{\prime }) for given values of its arguments :math:x,y_1,\ldots,y_{\textit{n}}.

**Parameters**
**x** : float
:math:x, the value of the argument.

**y** : float, ndarray, shape :math:\left(n\right)
:math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}, the value of the argument.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**f** : float, array-like, shape :math:\left(n\right)
The value of :math:f_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}.

**g** : callable retval = g(x, y, data=None)
:math:\mathrm{g} must evaluate the function :math:g\left(x, y\right) at a specified point.

**Parameters**
**x** : float
:math:x, the value of the independent variable.

**y** : float, ndarray, shape :math:\left(n\right)
The value of :math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**retval** : float
The value of :math:g\left(x, y\right) at the specified point.

**data** : arbitrary, optional
User-communication data for callback functions.

**Returns**
**x** : float
The point where :math:g\left(x, y\right) = 0.0 unless an error has occurred, when it contains the value of :math:x at the error. In particular, if :math:g\left(x, y\right)\neq 0.0 anywhere on the range :math:\mathrm{x} to :math:\mathrm{xend}, it will contain :math:\mathrm{xend} on exit.

**y** : float, ndarray, shape :math:\left(n\right)
The computed values of the solution at the final point :math:x = \mathrm{x}.

**tol** : float
Normally unchanged. However if the range from :math:x = \mathrm{x} to the position where :math:g\left(x, y\right) = 0.0 (or to the final value of :math:x if an error occurs) is so short that a small change in :math:\mathrm{tol} is unlikely to make any change in the computed solution, :math:\mathrm{tol} is returned with its sign changed. To check results returned with :math:\mathrm{tol} < 0.0, ivp_rkm_zero_simple should be called again with a positive value of :math:\mathrm{tol} whose magnitude is considerably smaller than that of the previous call.

.. _d02bh-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:\mathrm{irelab} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:0\leq \mathrm{irelab}\leq 2.

(errno :math:1)
On entry, :math:n = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:n > 0.

(errno :math:1)
On entry, :math:\mathrm{tol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{tol} > 0.0.

(errno :math:3)
The value of :math:\mathrm{tol}, :math:\langle\mathit{\boldsymbol{value}}\rangle, is too small for the function to take an initial step.

(errno :math:5)
An internal error has occurred in this function. Check the function call and any array sizes. If the call is correct then please contact NAG <https://www.nag.com>__ for assistance.

(errno :math:6)
A serious error occurred in a call to the internal integrator.

The error code internally was :math:\langle\mathit{\boldsymbol{value}}\rangle. Please contact NAG <https://www.nag.com>__.

(errno :math:7)
Unexpected internal error in call to interpolation routine.

The interpolation routine returned error flag :math:\langle\mathit{\boldsymbol{value}}\rangle.

**Warns**
**NagAlgorithmicWarning**
(errno :math:2)
The value of :math:\mathrm{tol}, :math:\langle\mathit{\boldsymbol{value}}\rangle, is too small for the function to make any further progress across the integration range. Current value of :math:x = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:4)
No change in sign of the function :math:g\left(x, y\right) was detected in the integration range.

.. _d02bh-py2-py-notes:

**Notes**
No equivalent traditional C interface for this routine exists in the NAG Library.

ivp_rkm_zero_simple advances the solution of a system of ordinary differential equations

.. math::
y_i^{\prime } = f_i\left(x, y_1, y_2, \ldots, y_{\textit{n}}\right)\text{, }\quad i = 1,2,\ldots,\textit{n}\text{,}

from :math:x = \mathrm{x} towards :math:x = \mathrm{xend} using a Merson form of the Runge--Kutta method.
The system is defined by :math:\mathrm{fcn}, which evaluates :math:f_i in terms of :math:x and :math:y_1,y_2,\ldots,y_{\textit{n}} (see :ref:Parameters <d02bh-py2-py-parameters>), and the values of :math:y_1,y_2,\ldots,y_{\textit{n}} must be given at :math:x = \mathrm{x}.

As the integration proceeds, a check is made on the function :math:g\left(x, y\right) specified by you, to determine an interval where it changes sign.
The position of this sign change is then determined accurately by interpolating for the solution and its derivative.
It is assumed that :math:g\left(x, y\right) is a continuous function of the variables, so that a solution of :math:g\left(x, y\right) = 0 can be determined by searching for a change in sign in :math:g\left(x, y\right).

The accuracy of the integration and, indirectly, of the determination of the position where :math:g\left(x, y\right) = 0, is controlled by :math:\mathrm{tol}.

For a description of Runge--Kutta methods and their practical implementation see Hall and Watt (1976).

.. _d02bh-py2-py-references:

**References**
Hall, G and Watt, J M (ed.), 1976, Modern Numerical Methods for Ordinary Differential Equations, Clarendon Press, Oxford
"""
raise NotImplementedError

[docs]def ivp_rk_zero_simple(x, xend, y, fcn, tol, relabs, output=None, g=None, data=None):
r"""
ivp_rk_zero_simple integrates a system of first-order ordinary differential equations over an interval with suitable initial conditions, using a fixed order Runge--Kutta method, until a user-specified function, if supplied, of the solution is zero, and returns the solution at points specified by you, if desired.

.. _d02bj-py2-py-doc:

For full information please refer to the NAG Library document for d02bj

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02bjf.html

.. _d02bj-py2-py-parameters:

**Parameters**
**x** : float
The initial value of the independent variable :math:x.

**xend** : float
The final value of the independent variable. If :math:\mathrm{xend} < \mathrm{x}, integration will proceed in the negative direction.

**y** : float, array-like, shape :math:\left(n\right)
The initial values of the solution :math:y_1,y_2,\ldots,y_{\textit{n}} at :math:x = \mathrm{x}.

**fcn** : callable f = fcn(x, y, data=None)
:math:\mathrm{fcn} must evaluate the functions :math:f_i (i.e., the derivatives :math:y_i^{\prime }) for given values of its arguments :math:x,y_1,\ldots,y_{\textit{n}}.

**Parameters**
**x** : float
:math:x, the value of the independent variable.

**y** : float, ndarray, shape :math:\left(n\right)
:math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}, the value of the variable.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**f** : float, array-like, shape :math:\left(n\right)
The value of :math:f_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}.

**tol** : float
A **positive** tolerance for controlling the error in the integration. Hence :math:\mathrm{tol} affects the determination of the position where :math:g\left(x, y\right) = 0, if :math:g is supplied.

ivp_rk_zero_simple has been designed so that, for most problems, a reduction in :math:\mathrm{tol} leads to an approximately proportional reduction in the error in the solution.

However, the actual relation between :math:\mathrm{tol} and the accuracy achieved cannot be guaranteed.

You are strongly recommended to call ivp_rk_zero_simple with more than one value for :math:\mathrm{tol} and to compare the results obtained to estimate their accuracy.

In the absence of any prior knowledge, you might compare the results obtained by calling ivp_rk_zero_simple with :math:\mathrm{relabs} = \texttt{'D'} and with each of :math:\mathrm{tol} = 10.0^{{-p}} and :math:\mathrm{tol} = 10.0^{{-p-1}} where :math:p correct significant digits are required in the solution, :math:y.

The accuracy of the value :math:x such that :math:g\left(x, y\right) = 0 is indirectly controlled by varying :math:\mathrm{tol}.

You should experiment to determine this accuracy.

**relabs** : str, length 1
The type of error control. At each step in the numerical solution an estimate of the local error, :math:\textit{est}, is made. For the current step to be accepted the following condition must be satisfied:

.. math::
\textit{est} = \mathrm{max}\left(e_i/ \left(\tau_r\times \mathrm{max}\left(\left\lvert y_i\right\rvert, \tau_a\right)\right)\right)\leq 1.0

where :math:\tau_r and :math:\tau_a are defined by

+-----------------------+--------------------+-------------------------------+
|:math:\mathrm{relabs}|:math:\tau_r      |:math:\tau_a                 |
+=======================+====================+===============================+
|'M'                    |:math:\mathrm{tol}|1.0                            |
+-----------------------+--------------------+-------------------------------+
|'A'                    |:math:\epsilon_r  |:math:\mathrm{tol}/\epsilon_r|
+-----------------------+--------------------+-------------------------------+
|'R'                    |:math:\mathrm{tol}|:math:\epsilon_a             |
+-----------------------+--------------------+-------------------------------+
|'D'                    |:math:\mathrm{tol}|:math:\epsilon_a             |
+-----------------------+--------------------+-------------------------------+

where :math:\epsilon_r and :math:\epsilon_a are small machine-dependent numbers and :math:e_i is an estimate of the local error at :math:y_i, computed internally. If the condition is not satisfied, the step size is reduced and the solution is recomputed on the current step. If you wish to measure the error in the computed solution in terms of the number of correct decimal places, :math:\mathrm{relabs} should be set to 'A' on entry, whereas if the error requirement is in terms of the number of correct significant digits, :math:\mathrm{relabs} should be set to 'R'. If you prefer a mixed error test, :math:\mathrm{relabs} should be set to 'M', otherwise if you have no preference, :math:\mathrm{relabs} should be set to the default 'D'. Note that in this case 'D' is taken to be 'R'.

**output** : None or callable xsol = output(xsol, y, data=None), optional
Note: if this argument is **None** then a NAG-supplied facility will be used.

:math:\mathrm{output} permits access to intermediate values of the computed solution (for example to print or plot them), at successive user-specified points.

It is initially called by ivp_rk_zero_simple with :math:\mathrm{xsol} = \mathrm{x} (the initial value of :math:x).

You must reset :math:\mathrm{xsol} to the next point (between the current :math:\mathrm{xsol} and :math:\mathrm{xend}) where :math:\mathrm{output} is to be called, and so on at each call to :math:\mathrm{output}.

If, after a call to :math:\mathrm{output}, the reset point :math:\mathrm{xsol} is beyond :math:\mathrm{xend}, ivp_rk_zero_simple will integrate to :math:\mathrm{xend} with no further calls to :math:\mathrm{output}; if a call to :math:\mathrm{output} is required at the point :math:\mathrm{xsol} = \mathrm{xend}, :math:\mathrm{xsol} must be given precisely the value :math:\mathrm{xend}.

**Parameters**
**xsol** : float
The output value of the independent variable :math:x.

**y** : float, ndarray, shape :math:\left(n\right)
The computed solution at the point :math:\mathrm{xsol}.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**xsol** : float
You must set :math:\mathrm{xsol} to the next value of :math:x at which :math:\mathrm{output} is to be called.

**g** : None or callable retval = g(x, y, data=None), optional
Note: if this argument is **None** then a NAG-supplied facility will be used.

:math:\mathrm{g} must evaluate the function :math:g\left(x, y\right) for specified values :math:x,y.

It specifies the function :math:g for which the first position :math:x where :math:g\left(x, y\right) = 0 is to be found.

**Parameters**
**x** : float
:math:x, the value of the independent variable.

**y** : float, ndarray, shape :math:\left(n\right)
:math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}, the value of the variable.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**retval** : float
The value of :math:g\left(x, y\right) at the specified point.

**data** : arbitrary, optional
User-communication data for callback functions.

**Returns**
**x** : float
If :math:g is supplied by you, it contains the point where :math:g\left(x, y\right) = 0, unless :math:g\left(x, y\right)\neq 0 anywhere on the range :math:\mathrm{x} to :math:\mathrm{xend}, in which case, :math:\mathrm{x} will contain :math:\mathrm{xend} (and the error indicator :math:\mathrm{errno} = 6 is set); if :math:g is not supplied by you it contains :math:\mathrm{xend}. However, if an error has occurred, it contains the value of :math:x at which the error occurred.

**y** : float, ndarray, shape :math:\left(n\right)
The computed values of the solution at the final point :math:x = \mathrm{x}.

.. _d02bj-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:n = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:n\geq 1.

(errno :math:1)
On entry, :math:\mathrm{x} = \mathrm{xend} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{x}\neq \mathrm{xend}.

(errno :math:1)
On entry, :math:\mathrm{tol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\langle\mathit{\boldsymbol{value}}\rangle\leq \mathrm{tol} < 0.01.

(errno :math:1)
On entry, :math:\mathrm{relabs} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{relabs} = \texttt{'M'}, :math:\texttt{'A'}, :math:\texttt{'R'} or :math:\texttt{'D'}.

(errno :math:2)
With the given value of :math:\mathrm{tol}, no further progress can be made across the integration range from the current point :math:x = \mathrm{x}.

The solution is returned at this point, :math:\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:3)
With the given value of :math:\mathrm{tol}, no initial progress can be made from the starting point of integration provided.

(errno :math:4)
On the first call to :math:\mathrm{output}, :math:\mathrm{xsol} was returned as :math:\langle\mathit{\boldsymbol{value}}\rangle, which is inconsistent with :math:\left(\mathrm{x}, \mathrm{xend}\right) --- :math:\left(\langle\mathit{\boldsymbol{value}}\rangle, \langle\mathit{\boldsymbol{value}}\rangle\right).

(errno :math:4)
On the first call to :math:\mathrm{output}, :math:\mathrm{xsol} remained unchanged.

(errno :math:5)
On a call to :math:\mathrm{output}, :math:\mathrm{xsol} was returned as :math:\langle\mathit{\boldsymbol{value}}\rangle, which is inconsistent with previous :math:\mathrm{xsol} and :math:\mathrm{xend} --- :math:\left(\langle\mathit{\boldsymbol{value}}\rangle, \langle\mathit{\boldsymbol{value}}\rangle\right).

(errno :math:5)
On a call to :math:\mathrm{output}, :math:\mathrm{xsol} remained unchanged.

(errno :math:6)
No change in sign of the function :math:g\left(x, y\right) was detected in the integration range.

(errno :math:7)
Unexpected internal error in call to zero-finding routine.

The zero-finding routine returned error flag :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:7)
Unexpected internal error in call to interpolation routine.

The interpolation routine returned error flag :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:8)
Unexpected internal error in call to step integrator.

The step integrator returned error flag :math:\langle\mathit{\boldsymbol{value}}\rangle.

.. _d02bj-py2-py-notes:

**Notes**
No equivalent traditional C interface for this routine exists in the NAG Library.

ivp_rk_zero_simple advances the solution of a system of ordinary differential equations

.. math::
y_i^{\prime } = f_i\left(x, y_1, y_2, \ldots, y_{\textit{n}}\right)\text{, }\quad i = 1,2,\ldots,\textit{n}\text{,}

from :math:x = \mathrm{x} to :math:x = \mathrm{xend} using a fixed order Runge--Kutta method.
The system is defined by :math:\mathrm{fcn}, which evaluates :math:f_i in terms of :math:x and :math:y = \left(y_1, y_2, \ldots, y_{\textit{n}}\right).
The initial values of :math:y = \left(y_1, y_2, \ldots, y_{\textit{n}}\right) must be given at :math:x = \mathrm{x}.

The solution is returned via the :math:\mathrm{output} supplied by you and at points specified by you, if desired: this solution is obtained by :math:C^1 interpolation on solution values produced by the method.
As the integration proceeds a check can be made on the user-specified function :math:g\left(x, y\right) to determine an interval where it changes sign.
The position of this sign change is then determined accurately by :math:C^1 interpolation to the solution.
It is assumed that :math:g\left(x, y\right) is a continuous function of the variables, so that a solution of :math:g\left(x, y\right) = 0 can be determined by searching for a change in sign in :math:g\left(x, y\right).
The accuracy of the integration, the interpolation and, indirectly, of the determination of the position where :math:g\left(x, y\right) = 0, is controlled by the arguments :math:\mathrm{tol} and :math:\mathrm{relabs}.

.. _d02bj-py2-py-references:

**References**
Shampine, L F, 1994, Numerical solution of ordinary differential equations, Chapman and Hall
"""
raise NotImplementedError

[docs]def ivp_adams_zero_simple(x, xend, y, fcn, tol, relabs, output=None, g=None, data=None):
r"""
ivp_adams_zero_simple integrates a system of first-order ordinary differential equations over a range with suitable initial conditions, using a variable-order, variable-step Adams' method until a user-specified function, if supplied, of the solution is zero, and returns the solution at points specified by you, if desired.

.. _d02cj-py2-py-doc:

For full information please refer to the NAG Library document for d02cj

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02cjf.html

.. _d02cj-py2-py-parameters:

**Parameters**
**x** : float
The initial value of the independent variable :math:x.

**xend** : float
The final value of the independent variable. If :math:\mathrm{xend} < \mathrm{x}, integration will proceed in the negative direction.

**y** : float, array-like, shape :math:\left(n\right)
The initial values of the solution :math:y_1,y_2,\ldots,y_{\textit{n}} at :math:x = \mathrm{x}.

**fcn** : callable f = fcn(x, y, data=None)
:math:\mathrm{fcn} must evaluate the functions :math:f_i (i.e., the derivatives :math:y_i^{\prime }) for given values of its arguments :math:x,y_1,\ldots,y_{\textit{n}}.

**Parameters**
**x** : float
:math:x, the value of the independent variable.

**y** : float, ndarray, shape :math:\left(n\right)
:math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}, the value of the variable.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**f** : float, array-like, shape :math:\left(n\right)
The value of :math:f_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}.

**tol** : float
A **positive** tolerance for controlling the error in the integration. Hence :math:\mathrm{tol} affects the determination of the position where :math:g\left(x, y\right) = 0.0, if :math:g is supplied.

ivp_adams_zero_simple has been designed so that, for most problems, a reduction in :math:\mathrm{tol} leads to an approximately proportional reduction in the error in the solution.

However, the actual relation between :math:\mathrm{tol} and the accuracy achieved cannot be guaranteed.

You are strongly recommended to call ivp_adams_zero_simple with more than one value for :math:\mathrm{tol} and to compare the results obtained to estimate their accuracy.

In the absence of any prior knowledge, you might compare the results obtained by calling ivp_adams_zero_simple with :math:\mathrm{tol} = 10.0^{{-p}} and :math:\mathrm{tol} = 10.0^{{-p-1}} where :math:p correct decimal digits are required in the solution.

**relabs** : str, length 1
The type of error control. At each step in the numerical solution an estimate of the local error, :math:\textit{est}, is made. For the current step to be accepted the following condition must be satisfied:

.. math::
\textit{est} = \sqrt{\sum_{{i = 1}}^{\textit{n}}{\left(e_i/\left(\tau_r\times \left\lvert y_i\right\rvert +\tau_a\right)\right)}^2}\leq 1.0

where :math:\tau_r and :math:\tau_a are defined by

+-----------------------+--------------------+--------------------+
|:math:\mathrm{relabs}|:math:\tau_r      |:math:\tau_a      |
+=======================+====================+====================+
|'M'                    |:math:\mathrm{tol}|:math:\mathrm{tol}|
+-----------------------+--------------------+--------------------+
|'A'                    |:math:0.0         |:math:\mathrm{tol}|
+-----------------------+--------------------+--------------------+
|'R'                    |:math:\mathrm{tol}|:math:\epsilon    |
+-----------------------+--------------------+--------------------+
|'D'                    |:math:\mathrm{tol}|:math:\mathrm{tol}|
+-----------------------+--------------------+--------------------+

where :math:\epsilon is a small machine-dependent number and :math:e_i is an estimate of the local error at :math:y_i, computed internally. If the appropriate condition is not satisfied, the step size is reduced and the solution is recomputed on the current step. If you wish to measure the error in the computed solution in terms of the number of correct decimal places, :math:\mathrm{relabs} should be set to 'A' on entry, whereas if the error requirement is in terms of the number of correct significant digits, :math:\mathrm{relabs} should be set to 'R'. If you prefer a mixed error test, :math:\mathrm{relabs} should be set to 'M', otherwise if you have no preference, :math:\mathrm{relabs} should be set to the default 'D'. Note that in this case 'D' is taken to be 'M'.

**output** : None or callable xsol = output(xsol, y, data=None), optional
Note: if this argument is **None** then a NAG-supplied facility will be used.

:math:\mathrm{output} permits access to intermediate values of the computed solution (for example to print or plot them), at successive user-specified points.

It is initially called by ivp_adams_zero_simple with :math:\mathrm{xsol} = \mathrm{x} (the initial value of :math:x).

You must reset :math:\mathrm{xsol} to the next point (between the current :math:\mathrm{xsol} and :math:\mathrm{xend}) where :math:\mathrm{output} is to be called, and so on at each call to :math:\mathrm{output}.

If, after a call to :math:\mathrm{output}, the reset point :math:\mathrm{xsol} is beyond :math:\mathrm{xend}, ivp_adams_zero_simple will integrate to :math:\mathrm{xend} with no further calls to :math:\mathrm{output}; if a call to :math:\mathrm{output} is required at the point :math:\mathrm{xsol} = \mathrm{xend}, :math:\mathrm{xsol} must be given precisely the value :math:\mathrm{xend}.

**Parameters**
**xsol** : float
The output value of the independent variable :math:x.

**y** : float, ndarray, shape :math:\left(n\right)
The computed solution at the point :math:\mathrm{xsol}.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**xsol** : float
You must set :math:\mathrm{xsol} to the next value of :math:x at which :math:\mathrm{output} is to be called.

**g** : None or callable retval = g(x, y, data=None), optional
Note: if this argument is **None** then a NAG-supplied facility will be used.

:math:\mathrm{g} must evaluate the function :math:g\left(x, y\right) for specified values :math:x,y.

It specifies the function :math:g for which the first position :math:x where :math:g\left(x, y\right) = 0 is to be found.

**Parameters**
**x** : float
:math:x, the value of the independent variable.

**y** : float, ndarray, shape :math:\left(n\right)
:math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}, the value of the variable.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**retval** : float
The value of :math:g\left(x, y\right) at the specified point.

**data** : arbitrary, optional
User-communication data for callback functions.

**Returns**
**x** : float
If :math:g is supplied by you, it contains the point where :math:g\left(x, y\right) = 0.0, unless :math:g\left(x, y\right)\neq 0.0 anywhere on the range :math:\mathrm{x} to :math:\mathrm{xend}, in which case, :math:\mathrm{x} will contain :math:\mathrm{xend}. If :math:g is not supplied by you it contains :math:\mathrm{xend}, unless an error has occurred, when it contains the value of :math:x at the error.

**y** : float, ndarray, shape :math:\left(n\right)
The computed values of the solution at the final point :math:x = \mathrm{x}.

.. _d02cj-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:\mathrm{relabs} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{relabs} = \texttt{'M'}, :math:\texttt{'A'}, :math:\texttt{'R'} or :math:\texttt{'D'}.

(errno :math:1)
On entry, :math:\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{xend} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{x}\neq \mathrm{xend}.

(errno :math:1)
On entry, :math:\mathrm{tol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{tol} > 0.0.

(errno :math:1)
On entry, :math:n = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:n\geq 1.

(errno :math:3)
No integration steps have been taken. Progress not possible with the input value of :math:\mathrm{tol} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:4)
On the first call to :math:\mathrm{output}, :math:\mathrm{xsol} was returned as :math:\langle\mathit{\boldsymbol{value}}\rangle, which is inconsistent with :math:\left(\mathrm{x}, \mathrm{xend}\right) --- :math:\left(\langle\mathit{\boldsymbol{value}}\rangle, \langle\mathit{\boldsymbol{value}}\rangle\right).

(errno :math:4)
On the first call to :math:\mathrm{output}, :math:\mathrm{xsol} remained unchanged.

(errno :math:5)
On a call to :math:\mathrm{output}, :math:\mathrm{xsol} remained unchanged.

:math:\mathrm{xsol} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:7)
Impossible error --- internal variable :math:\mathrm{IDID} = \langle\mathit{\boldsymbol{value}}\rangle.

**Warns**
**NagAlgorithmicWarning**
(errno :math:2)
Integration successful as far as :math:x = \langle\mathit{\boldsymbol{value}}\rangle, but further progress not possible with the input value of :math:\mathrm{tol} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:5)
On a call to :math:\mathrm{output}, :math:\mathrm{xsol} was returned as :math:\langle\mathit{\boldsymbol{value}}\rangle, which is inconsistent with previous :math:\mathrm{xsol} and :math:\mathrm{xend} --- :math:\left(\langle\mathit{\boldsymbol{value}}\rangle, \langle\mathit{\boldsymbol{value}}\rangle\right).

(errno :math:6)
No change in sign of the function :math:g\left(x, y\right) was detected in the integration range.

.. _d02cj-py2-py-notes:

**Notes**
In the NAG Library the traditional C interface for this routine uses a different algorithmic base. Please contact NAG if you have any questions about compatibility.

ivp_adams_zero_simple advances the solution of a system of ordinary differential equations

.. math::
y_i^{\prime } = f_i\left(x, y_1, y_2, \ldots, y_{\textit{n}}\right)\text{, }\quad i = 1,2,\ldots,\textit{n}\text{,}

from :math:x = \mathrm{x} to :math:x = \mathrm{xend} using a variable-order, variable-step Adams' method.
The system is defined by :math:\mathrm{fcn}, which evaluates :math:f_i in terms of :math:x and :math:y_1,y_2,\ldots,y_{\textit{n}}.
The initial values of :math:y_1,y_2,\ldots,y_{\textit{n}} must be given at :math:x = \mathrm{x}.

The solution is returned via :math:\mathrm{output} at points specified by you, if desired: this solution is obtained by :math:C^1 interpolation on solution values produced by the method.
As the integration proceeds a check can be made on the user-specified function :math:g\left(x, y\right) to determine an interval where it changes sign.
The position of this sign change is then determined accurately by :math:C^1 interpolation to the solution.
It is assumed that :math:g\left(x, y\right) is a continuous function of the variables, so that a solution of :math:g\left(x, y\right) = 0.0 can be determined by searching for a change in sign in :math:g\left(x, y\right).
The accuracy of the integration, the interpolation and, indirectly, of the determination of the position where :math:g\left(x, y\right) = 0.0, is controlled by the arguments :math:\mathrm{tol} and :math:\mathrm{relabs}.

For a description of Adams' methods and their practical implementation see Hall and Watt (1976).

.. _d02cj-py2-py-references:

**References**
Hall, G and Watt, J M (ed.), 1976, Modern Numerical Methods for Ordinary Differential Equations, Clarendon Press, Oxford
"""
raise NotImplementedError

[docs]def ivp_bdf_zero_simple(x, xend, y, fcn, tol, relabs, pederv=None, output=None, g=None, data=None, io_manager=None, spiked_sorder='C'):
r"""
ivp_bdf_zero_simple integrates a stiff system of first-order ordinary differential equations over an interval with suitable initial conditions, using a variable-order, variable-step method implementing the Backward Differentiation Formulae (BDF), until a user-specified function, if supplied, of the solution is zero, and returns the solution at points specified by you, if desired.

.. _d02ej-py2-py-doc:

For full information please refer to the NAG Library document for d02ej

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02ejf.html

.. _d02ej-py2-py-parameters:

**Parameters**
**x** : float
The initial value of the independent variable :math:x.

**xend** : float
The final value of the independent variable. If :math:\mathrm{xend} < \mathrm{x}, integration will proceed in the negative direction.

**y** : float, array-like, shape :math:\left(n\right)
The initial values of the solution :math:y_1,y_2,\ldots,y_{\textit{n}} at :math:x = \mathrm{x}.

**fcn** : callable f = fcn(x, y, data=None)
:math:\mathrm{fcn} must evaluate the functions :math:f_i (i.e., the derivatives :math:y_i^{\prime }) for given values of its arguments :math:x,y_1,\ldots,y_{\textit{n}}.

**Parameters**
**x** : float
:math:x, the value of the independent variable.

**y** : float, ndarray, shape :math:\left(n\right)
:math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}, the value of the variable.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**f** : float, array-like, shape :math:\left(n\right)
The value of :math:f_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}.

**tol** : float
Must be set to a **positive** tolerance for controlling the error in the integration. Hence :math:\mathrm{tol} affects the determination of the position where :math:g\left(x, y\right) = 0.0, if :math:\mathrm{g} is supplied.

ivp_bdf_zero_simple has been designed so that, for most problems, a reduction in :math:\mathrm{tol} leads to an approximately proportional reduction in the error in the solution.

However, the actual relation between :math:\mathrm{tol} and the accuracy achieved cannot be guaranteed.

You are strongly recommended to call ivp_bdf_zero_simple with more than one value for :math:\mathrm{tol} and to compare the results obtained to estimate their accuracy.

In the absence of any prior knowledge, you might compare the results obtained by calling ivp_bdf_zero_simple with :math:\mathrm{tol} = 10^{{-p}} and :math:\mathrm{tol} = 10^{{-p-1}} if :math:p correct decimal digits are required in the solution.

**relabs** : str, length 1
The type of error control. At each step in the numerical solution an estimate of the local error, :math:\textit{est}, is made. For the current step to be accepted the following condition must be satisfied:

.. math::
\textit{est} = \sqrt{\frac{1}{\textit{n}}\sum_{{i = 1}}^{\textit{n}}{\left(e_i/\left(\tau_r\times \left\lvert y_i\right\rvert +\tau_a\right)\right)}^2}\leq 1.0

where :math:\tau_r and :math:\tau_a are defined by

+-----------------------+--------------------+--------------------+
|:math:\mathrm{relabs}|:math:\tau_r      |:math:\tau_a      |
+=======================+====================+====================+
|'M'                    |:math:\mathrm{tol}|:math:\mathrm{tol}|
+-----------------------+--------------------+--------------------+
|'A'                    |0.0                 |:math:\mathrm{tol}|
+-----------------------+--------------------+--------------------+
|'R'                    |:math:\mathrm{tol}|:math:\epsilon    |
+-----------------------+--------------------+--------------------+
|'D'                    |:math:\mathrm{tol}|:math:\epsilon    |
+-----------------------+--------------------+--------------------+

where :math:\epsilon is a small machine-dependent number and :math:e_i is an estimate of the local error at :math:y_i, computed internally. If the appropriate condition is not satisfied, the step size is reduced and the solution is recomputed on the current step. If you wish to measure the error in the computed solution in terms of the number of correct decimal places, :math:\mathrm{relabs} should be set to 'A' on entry, whereas if the error requirement is in terms of the number of correct significant digits, :math:\mathrm{relabs} should be set to 'R'. If you prefer a mixed error test, :math:\mathrm{relabs} should be set to 'M', otherwise if you have no preference, :math:\mathrm{relabs} should be set to the default 'D'. Note that in this case 'D' is taken to be 'R'.

**pederv** : None or callable pw = pederv(x, y, data=None), optional
Note: if this argument is **None** then a NAG-supplied facility will be used.

:math:\mathrm{pederv} must evaluate the Jacobian of the system (that is, the partial derivatives :math:\frac{{\partial f_i}}{{\partial y_j}}) for given values of the variables :math:x,y_1,y_2,\ldots,y_{\textit{n}}.

**Parameters**
**x** : float
:math:x, the value of the independent variable.

**y** : float, ndarray, shape :math:\left(n\right)
:math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}, the value of the variable.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**pw** : float, array-like, shape :math:\left(n, n\right)
:math:\mathrm{pw}[\textit{i}-1,\textit{j}-1] must contain the value of :math:\frac{{\partial f_{\textit{i}}}}{{\partial y_{\textit{j}}}}, for :math:\textit{j} = 1,2,\ldots,\textit{n}, for :math:\textit{i} = 1,2,\ldots,\textit{n}.

**output** : None or callable xsol = output(xsol, y, data=None), optional
Note: if this argument is **None** then a NAG-supplied facility will be used.

:math:\mathrm{output} permits access to intermediate values of the computed solution (for example to print or plot them), at successive user-specified points.

It is initially called by ivp_bdf_zero_simple with :math:\mathrm{xsol} = \mathrm{x} (the initial value of :math:x).

You must reset :math:\mathrm{xsol} to the next point (between the current :math:\mathrm{xsol} and :math:\mathrm{xend}) where :math:\mathrm{output} is to be called, and so on at each call to :math:\mathrm{output}.

If, after a call to :math:\mathrm{output}, the reset point :math:\mathrm{xsol} is beyond :math:\mathrm{xend}, ivp_bdf_zero_simple will integrate to :math:\mathrm{xend} with no further calls to :math:\mathrm{output}; if a call to :math:\mathrm{output} is required at the point :math:\mathrm{xsol} = \mathrm{xend}, :math:\mathrm{xsol} must be given precisely the value :math:\mathrm{xend}.

**Parameters**
**xsol** : float
:math:x, the value of the independent variable.

**y** : float, ndarray, shape :math:\left(n\right)
The computed solution at the point :math:\mathrm{xsol}.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**xsol** : float
You must set :math:\mathrm{xsol} to the next value of :math:x at which :math:\mathrm{output} is to be called.

**g** : None or callable retval = g(x, y, data=None), optional
Note: if this argument is **None** then a NAG-supplied facility will be used.

:math:\mathrm{g} must evaluate the function :math:g\left(x, y\right) for specified values :math:x,y.

It specifies the function :math:g for which the first position :math:x where :math:g\left(x, y\right) = 0 is to be found.

**Parameters**
**x** : float
:math:x, the value of the independent variable.

**y** : float, ndarray, shape :math:\left(n\right)
:math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}, the value of the variable.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**retval** : float
The value of :math:g at the specified points.

**data** : arbitrary, optional
User-communication data for callback functions.

**io_manager** : FileObjManager, optional
Manager for I/O in this routine.

**spiked_sorder** : str, optional
If :math:\mathrm{pw} in :math:\mathrm{pederv} is spiked (i.e., has unit extent in all but one dimension, or has size :math:1), :math:\mathrm{spiked\_sorder} selects the storage order to associate with it in the NAG Engine:

spiked_sorder = :math:\texttt{'C'}
row-major storage will be used;

spiked_sorder = :math:\texttt{'F'}
column-major storage will be used.

**Returns**
**x** : float
If :math:\mathrm{g} is supplied by you, :math:\mathrm{x} contains the point where :math:g\left(x, y\right) = 0.0, unless :math:g\left(x, y\right)\neq 0.0 anywhere on the range :math:\mathrm{x} to :math:\mathrm{xend}, in which case, :math:\mathrm{x} will contain :math:\mathrm{xend}. If :math:\mathrm{g} is not supplied :math:\mathrm{x} contains :math:\mathrm{xend}, unless an error has occurred, when it contains the value of :math:x at the error.

**y** : float, ndarray, shape :math:\left(n\right)
The computed values of the solution at the final point :math:x = \mathrm{x}.

**tol** : float
Normally unchanged. However if the range :math:\mathrm{x} to :math:\mathrm{xend} is so short that a small change in :math:\mathrm{tol} is unlikely to make any change in the computed solution, then, on return, :math:\mathrm{tol} has its sign changed.

.. _d02ej-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:\mathrm{relabs} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{relabs} = \texttt{'M'}, :math:\texttt{'A'}, :math:\texttt{'R'} or :math:\texttt{'D'}.

(errno :math:1)
On entry, :math:\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{xend} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{x}\neq \mathrm{xend}.

(errno :math:1)
On entry, :math:\mathrm{tol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{tol} > 0.0.

(errno :math:1)
On entry, :math:n = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:n\geq 1.

(errno :math:3)
No integration steps have been taken. Progress not possible with the input value of :math:\mathrm{tol} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:4)
No integration steps have been taken. :math:\mathrm{xsol} has been set illegally.

(errno :math:7)
Integration successful as far as :math:x = \langle\mathit{\boldsymbol{value}}\rangle, but an internal error has occurred during rootfinding.

(errno :math:9)
Impossible error --- internal variable :math:\mathrm{IERR} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:9)
Impossible error --- internal variable :math:\mathrm{IREVCM} = \langle\mathit{\boldsymbol{value}}\rangle.

**Warns**
**NagAlgorithmicWarning**
(errno :math:2)
Integration successful as far as :math:x = \langle\mathit{\boldsymbol{value}}\rangle, but further progress not possible with the input value of :math:\mathrm{tol} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:5)
Integration successful as far as :math:x = \langle\mathit{\boldsymbol{value}}\rangle, but :math:\mathrm{xsol} has been reset illegally.

(errno :math:6)
No change in sign of the function :math:g\left(x, y\right) was detected in the integration range.

(errno :math:8)
Integration successful as far as :math:x = \langle\mathit{\boldsymbol{value}}\rangle, but an internal error has occurred during interpolation.

.. _d02ej-py2-py-notes:

**Notes**
In the NAG Library the traditional C interface for this routine uses a different algorithmic base. Please contact NAG if you have any questions about compatibility.

ivp_bdf_zero_simple advances the solution of a system of ordinary differential equations

.. math::
y_i^{\prime } = f_i\left(x, y_1, y_2, \ldots, y_{\textit{n}}\right)\text{, }\quad i = 1,2,\ldots,\textit{n}\text{,}

from :math:x = \mathrm{x} to :math:x = \mathrm{xend} using a variable-order, variable-step method implementing the BDF.
The system is defined by :math:\mathrm{fcn}, which evaluates :math:f_i in terms of :math:x and :math:y_1,y_2,\ldots,y_{\textit{n}} (see :ref:Parameters <d02ej-py2-py-parameters>).
The initial values of :math:y_1,y_2,\ldots,y_{\textit{n}} must be given at :math:x = \mathrm{x}.

The solution is returned via the :math:\mathrm{output} at points specified by you, if desired: this solution is obtained by :math:C^1 interpolation on solution values produced by the method.
As the integration proceeds a check can be made on the user-specified function :math:g\left(x, y\right) to determine an interval where it changes sign.
The position of this sign change is then determined accurately by :math:C^1 interpolation to the solution.
It is assumed that :math:g\left(x, y\right) is a continuous function of the variables, so that a solution of :math:g\left(x, y\right) = 0.0 can be determined by searching for a change in sign in :math:g\left(x, y\right).
The accuracy of the integration, the interpolation and, indirectly, of the determination of the position where :math:g\left(x, y\right) = 0.0, is controlled by the arguments :math:\mathrm{tol} and :math:\mathrm{relabs}.
The Jacobian of the system :math:y^{\prime } = f\left(x, y\right) may be supplied in :math:\mathrm{pederv}, if it is available.

For a description of BDF and their practical implementation see Hall and Watt (1976).

.. _d02ej-py2-py-references:

**References**
Hall, G and Watt, J M (ed.), 1976, Modern Numerical Methods for Ordinary Differential Equations, Clarendon Press, Oxford

--------
:meth:naginterfaces.library.examples.ode.ivp_bdf_zero_simple_ex.main
"""
raise NotImplementedError

[docs]def bvp_fd_nonlin_fixedbc(u, v, a, b, tol, fcn, x, np, itrace, comm, data=None, io_manager=None):
r"""
bvp_fd_nonlin_fixedbc solves a two-point boundary value problem with assigned boundary values for a system of ordinary differential equations, using a deferred correction technique and a Newton iteration.

.. _d02ga-py2-py-doc:

For full information please refer to the NAG Library document for d02ga

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02gaf.html

.. _d02ga-py2-py-parameters:

**Parameters**
**u** : float, array-like, shape :math:\left(n, 2\right)
:math:\mathrm{u}[\textit{i}-1,0] must be set to the known or estimated value of :math:y_{\textit{i}} at :math:a and :math:\mathrm{u}[\textit{i}-1,1] must be set to the known or estimated value of :math:y_{\textit{i}} at :math:b, for :math:\textit{i} = 1,2,\ldots,\textit{n}.

**v** : float, array-like, shape :math:\left(n, 2\right)
:math:\mathrm{v}[\textit{i}-1,\textit{j}-1] must be set to :math:0.0 if :math:\mathrm{u}[\textit{i}-1,\textit{j}-1] is a known value and to :math:1.0 if :math:\mathrm{u}[\textit{i}-1,\textit{j}-1] is an estimated value, for :math:\textit{j} = 1,2,\ldots,2, for :math:\textit{i} = 1,2,\ldots,\textit{n}.

**a** : float
:math:a, the left-hand boundary point.

**b** : float
:math:b, the right-hand boundary point.

**tol** : float
A positive absolute error tolerance. If

.. math::
a = x_1 < x_2 < \cdots < x_{\mathrm{np}} = b

is the final mesh, :math:z_j\left(x_i\right) is the :math:j\ th component of the approximate solution at :math:x_i, and :math:y_j\left(x\right) is the :math:j\ th component of the true solution of equation (1) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02gaf.html#eqn1>__ (see :ref:Notes <d02ga-py2-py-notes>) and the boundary conditions, then, except in extreme cases, it is expected that

.. math::
\left\lvert z_j\left(x_i\right)-y_j\left(x_i\right)\right\rvert \leq \mathrm{tol}\text{, }\quad i = 1,2,\ldots,\mathrm{np}\text{ and }j = 1,2,\ldots,\textit{n}\text{.}

**fcn** : callable f = fcn(n, x, y, data=None)
:math:\mathrm{fcn} must evaluate the functions :math:f_{\textit{i}} (i.e., the derivatives :math:y_{\textit{i}}^{\prime }), for :math:\textit{i} = 1,2,\ldots,\textit{n}, at a general point :math:x.

**Parameters**
**n** : int
:math:\textit{n}, the number of equations.

**x** : float
:math:x, the value of the argument.

**y** : float, ndarray, shape :math:\left(\mathrm{n}\right)
:math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}, the value of the argument.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**f** : float, array-like, shape :math:\left(\mathrm{n}\right)
The values of :math:f_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}.

**x** : float, array-like, shape :math:\left(\textit{mnp}\right)
If :math:\mathrm{np}\geq 4 (see :math:\mathrm{np}), the first :math:\mathrm{np} elements must define an initial mesh. Otherwise the elements of :math:\mathrm{x} need not be set.

**np** : int
Determines whether a default or user-supplied mesh is used.

:math:\mathrm{np} = 0

A default value of :math:4 for :math:\mathrm{np} and a corresponding equispaced mesh :math:\mathrm{x}[0],\mathrm{x}[1],\ldots,\mathrm{x}[\mathrm{np}-1] are used.

:math:\mathrm{np}\geq 4

You must define an initial mesh using the array :math:\mathrm{x} as described.

**itrace** : int
If :math:\mathrm{itrace} = 0 warning messages be suppressed, otherwise warning messages will be printed (see :ref:Exceptions <d02ga-py2-py-errors>).

**comm** : dict, communication object, modified in place
Communication structure.

On initial entry: need not be set.

**data** : arbitrary, optional
User-communication data for callback functions.

**io_manager** : FileObjManager, optional
Manager for I/O in this routine.

**Returns**
**x** : float, ndarray, shape :math:\left(\textit{mnp}\right)
:math:\mathrm{x}[0],\mathrm{x}[1],\ldots,\mathrm{x}[\mathrm{np}-1] define the final mesh (with the returned value of :math:\mathrm{np}) satisfying the relation (3) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02gaf.html#eqn3>__.

**y** : float, ndarray, shape :math:\left(n, \textit{mnp}\right)
The approximate solution :math:z_j\left(x_i\right) satisfying (2) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02gaf.html#eqn2>__, on the final mesh, that is

.. math::
\mathrm{y}[j-1,i-1] = z_j\left(x_i\right)\text{, }\quad i = 1,2,\ldots,\mathrm{np}\text{ and }j = 1,2,\ldots,\textit{n}\text{,}

where :math:\mathrm{np} is the number of points in the final mesh.

The remaining columns of :math:\mathrm{y} are not used.

**np** : int
The number of points in the final (returned) mesh.

.. _d02ga-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
The sequence :math:\mathrm{x} is not strictly increasing. For :math:i = \langle\mathit{\boldsymbol{value}}\rangle, :math:\mathrm{x}[i-1] = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{x}[i] = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry: :math:\mathrm{b} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{x}[\mathrm{np}-1] = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{a} = \mathrm{x}[0] < \mathrm{x}[1] < \cdots < \mathrm{x}[\mathrm{np}-1] = \mathrm{b}\text{, }\quad \mathrm{np}\geq 4.

(errno :math:1)
On entry: :math:\mathrm{a} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{x}[0] = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{a} = \mathrm{x}[0] < \mathrm{x}[1] < \cdots < \mathrm{x}[\mathrm{np}-1] = \mathrm{b}\text{, }\quad \mathrm{np}\geq 4.

(errno :math:1)
The sum of known left and right boundary values must equal the number of equations: the number of known left boundary values :math:\text{} = \langle\mathit{\boldsymbol{value}}\rangle, the number of known right boundary values :math:\text{} = \langle\mathit{\boldsymbol{value}}\rangle, the number of equations :math:\text{} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
The number of known right boundary values must be less than the number of equations: the number of known right boundary values :math:\text{} = \langle\mathit{\boldsymbol{value}}\rangle, the number of equations :math:\text{} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
The number of known left boundary values must be less than the number of equations: the number of known left boundary values :math:\text{} = \langle\mathit{\boldsymbol{value}}\rangle, the number of equations :math:\text{} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{a} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{b} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{b} > \mathrm{a}.

(errno :math:1)
On entry, :math:\textit{mnp} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\textit{mnp}\geq 32.

(errno :math:1)
On entry, :math:\mathrm{np} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\textit{mnp} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{np}\leq \textit{mnp}.

(errno :math:1)
On entry, :math:\mathrm{np} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{np} = 0 or :math:\mathrm{np}\geq 4.

(errno :math:1)
On entry, :math:\mathrm{tol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{tol} > 0.0.

(errno :math:1)
On entry, :math:n = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:n\geq 2.

(errno :math:2)
The Newton iteration has failed to converge.

This could be due to there being too few points in the initial mesh or to the initial approximate solution being too inaccurate. If this latter reason is suspected or you cannot make changes to prevent this error, you should use the routine with a continuation facility instead.

(errno :math:5)
A serious error occurred in a call to the internal integrator.

The error code internally was :math:\langle\mathit{\boldsymbol{value}}\rangle. Please contact NAG <https://www.nag.com>__.

**Warns**
**NagAlgorithmicWarning**
(errno :math:3)
Newton iteration has reached round-off level.

If desired accuracy has not been reached, :math:\mathrm{tol} is too small for this problem and this machine precision.

(errno :math:4)
A finer mesh is required for the accuracy requested; that is, :math:\textit{mnp} = \langle\mathit{\boldsymbol{value}}\rangle is not large enough.

.. _d02ga-py2-py-notes:

**Notes**
In the NAG Library the traditional C interface for this routine uses a different algorithmic base. Please contact NAG if you have any questions about compatibility.

bvp_fd_nonlin_fixedbc solves a two-point boundary value problem for a system of :math:\textit{n} differential equations in the interval [:math:a,b].
The system is written in the form:

.. math::
y_i^{\prime } = f_i\left(x, y_1, y_2, \ldots, y_{\textit{n}}\right)\text{, }\quad i = 1,2,\ldots,\textit{n}

and the derivatives :math:f_i are evaluated by :math:\mathrm{fcn}.
Initially, :math:\textit{n} boundary values of the variables :math:y_i must be specified, some at :math:a and some at :math:b.
You must supply estimates of the remaining :math:\textit{n} boundary values and all the boundary values are used in constructing an initial approximation to the solution.
This approximate solution is corrected by a finite difference technique with deferred correction allied with a Newton iteration to solve the finite difference equations.
The technique used is described fully in Pereyra (1979).
The Newton iteration requires a Jacobian matrix :math:\frac{{\partial f_i}}{{\partial y_j}} and this is calculated by numerical differentiation using an algorithm described in Curtis et al. (1974).

You supply an absolute error tolerance and may also supply an initial mesh for the construction of the finite difference equations (alternatively a default mesh is used).
The algorithm constructs a solution on a mesh defined by adding points to the initial mesh.
This solution is chosen so that the error is everywhere less than your tolerance and so that the error is approximately equidistributed on the final mesh.
The solution is returned on this final mesh.

If the solution is required at a few specific points then these should be included in the initial mesh.
If on the other hand the solution is required at several specific points then you should use the interpolation functions provided in submodule :mod:~naginterfaces.library.interp if these points do not themselves form a convenient mesh.

.. _d02ga-py2-py-references:

**References**
Curtis, A R, Powell, M J D and Reid, J K, 1974, On the estimation of sparse Jacobian matrices, J. Inst. Maths. Applics. (13), 117--119

Pereyra, V, 1979, PASVA3: An adaptive finite-difference Fortran program for first order nonlinear, ordinary boundary problems, Codes for Boundary Value Problems in Ordinary Differential Equations. Lecture Notes in Computer Science, (eds B Childs, M Scott, J W Daniel, E Denman and P Nelson) (76), Springer--Verlag
"""
raise NotImplementedError

[docs]def bvp_fd_lin_gen(a, b, tol, fcnf, fcng, c, d, gam, x, np, itrace, comm, data=None, io_manager=None, spiked_sorder='C'):
r"""
bvp_fd_lin_gen solves a general linear two-point boundary value problem for a system of ordinary differential equations, using a deferred correction technique.

.. _d02gb-py2-py-doc:

For full information please refer to the NAG Library document for d02gb

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02gbf.html

.. _d02gb-py2-py-parameters:

**Parameters**
**a** : float
:math:a, the left-hand boundary point.

**b** : float
:math:b, the right-hand boundary point.

**tol** : float
A positive absolute error tolerance. If

.. math::
a = x_1 < x_2 < \cdots < x_{\mathrm{np}} = b

is the final mesh, :math:z\left(x\right) is the approximate solution from bvp_fd_lin_gen and :math:y\left(x\right) is the true solution of equations (1) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02gbf.html#eqn1>__ and (2) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02gbf.html#eqn1>__ then, except in extreme cases, it is expected that

.. math::
\left\lVert z-y\right\rVert \leq \mathrm{tol}

where

.. math::
\left\lVert u\right\rVert = \mathrm{max}_{{1\leq i\leq n}}\mathrm{max}_{{1\leq j\leq \mathrm{np}}}\left\lvert u_i\left(x_j\right)\right\rvert \text{.}

**fcnf** : callable f = fcnf(n, x, data=None)
:math:\mathrm{fcnf} must evaluate the matrix :math:F\left(x\right) in (1) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02gbf.html#eqn1>__ at a general point :math:x.

**Parameters**
**n** : int
:math:\textit{n}, the number of equations.

**x** : float
:math:x, the value of the independent variable.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**f** : float, array-like, shape :math:\left(\mathrm{n}, \mathrm{n}\right)
:math:\mathrm{f}[\textit{j}-1,\textit{i}-1] must contain the :math:\left(\textit{i}, \textit{j}\right)\ th element of the matrix :math:F\left(x\right), for :math:\textit{j} = 1,2,\ldots,\textit{n}, for :math:\textit{i} = 1,2,\ldots,\textit{n}.

**fcng** : callable g = fcng(n, x, data=None)
:math:\mathrm{fcng} must evaluate the vector :math:g\left(x\right) in (1) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02gbf.html#eqn1>__ at a general point :math:x.

**Parameters**
**n** : int
:math:\textit{n}, the number of equations.

**x** : float
:math:x, the value of the independent variable.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**g** : float, array-like, shape :math:\left(\mathrm{n}\right)
The :math:\textit{i}\ th element of the vector :math:g\left(x\right), for :math:\textit{i} = 1,2,\ldots,\textit{n}.

**c** : float, array-like, shape :math:\left(n, n\right)
The arrays :math:\mathrm{c} and :math:\mathrm{d} must be set to the matrices :math:C and :math:D in (2) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02gbf.html#eqn2>__). :math:\mathrm{gam} must be set to the vector :math:\gamma in (2) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02gbf.html#eqn2>__.

**d** : float, array-like, shape :math:\left(n, n\right)
The arrays :math:\mathrm{c} and :math:\mathrm{d} must be set to the matrices :math:C and :math:D in (2) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02gbf.html#eqn2>__). :math:\mathrm{gam} must be set to the vector :math:\gamma in (2) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02gbf.html#eqn2>__.

**gam** : float, array-like, shape :math:\left(n\right)
The arrays :math:\mathrm{c} and :math:\mathrm{d} must be set to the matrices :math:C and :math:D in (2) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02gbf.html#eqn2>__). :math:\mathrm{gam} must be set to the vector :math:\gamma in (2) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02gbf.html#eqn2>__.

**x** : float, array-like, shape :math:\left(\textit{mnp}\right)
If :math:\mathrm{np}\geq 4 (see :math:\mathrm{np}), the first :math:\mathrm{np} elements must define an initial mesh. Otherwise the elements of :math:x need not be set.

**np** : int
Determines whether a default mesh or user-supplied mesh is used.

:math:\mathrm{np} = 0

A default value of :math:4 for :math:\mathrm{np} and a corresponding equispaced mesh :math:\mathrm{x}[0],\mathrm{x}[1],\ldots,\mathrm{x}[\mathrm{np}-1] are used.

:math:\mathrm{np}\geq 4

You must define an initial mesh :math:\mathrm{x} as in [equation] <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02gbf.html#eqnd02x-n>__.

**itrace** : int
If :math:\mathrm{itrace} = 0 warning messages be suppressed, otherwise warning messages will be printed (see :ref:Exceptions <d02gb-py2-py-errors>).

**comm** : dict, communication object, modified in place
Communication structure.

On initial entry: need not be set.

**data** : arbitrary, optional
User-communication data for callback functions.

**io_manager** : FileObjManager, optional
Manager for I/O in this routine.

**spiked_sorder** : str, optional
If :math:\mathrm{c} and :math:\mathrm{d} are spiked (i.e., have unit extent in all but one dimension, or have size :math:1), :math:\mathrm{spiked\_sorder} selects the storage order to associate with them in the NAG Engine:

spiked_sorder = :math:\texttt{'C'}
row-major storage will be used;

spiked_sorder = :math:\texttt{'F'}
column-major storage will be used.

Two-dimensional arrays returned from callback functions in this routine must then use the same storage order.

**Returns**
**c** : float, ndarray, shape :math:\left(n, n\right)
The rows of :math:\mathrm{c} and :math:\mathrm{d} and the components of :math:\mathrm{gam} are reordered so that the boundary conditions are in the order:

(i) conditions on :math:y\left(a\right) only;

(#) condition involving :math:y\left(a\right) and :math:y\left(b\right); and

(#) conditions on :math:y\left(b\right) only.

The function will be slightly more efficient if the arrays :math:\mathrm{c}, :math:\mathrm{d} and :math:\mathrm{gam} are ordered in this way before entry, and in this event they will be unchanged on exit.

Note that the problems (1) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02gbf.html#eqn1>__ and (2) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02gbf.html#eqn1>__ must be of boundary value type, that is neither :math:C nor :math:D may be identically zero.

Note also that the rank of the matrix :math:\left[C, D\right] must be :math:\textit{n} for the problem to be properly posed.

Any violation of these conditions will lead to an error exit.

**d** : float, ndarray, shape :math:\left(n, n\right)
The rows of :math:\mathrm{c} and :math:\mathrm{d} and the components of :math:\mathrm{gam} are reordered so that the boundary conditions are in the order:

(i) conditions on :math:y\left(a\right) only;

(#) condition involving :math:y\left(a\right) and :math:y\left(b\right); and

(#) conditions on :math:y\left(b\right) only.

The function will be slightly more efficient if the arrays :math:\mathrm{c}, :math:\mathrm{d} and :math:\mathrm{gam} are ordered in this way before entry, and in this event they will be unchanged on exit.

Note that the problems (1) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02gbf.html#eqn1>__ and (2) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02gbf.html#eqn1>__ must be of boundary value type, that is neither :math:C nor :math:D may be identically zero.

Note also that the rank of the matrix :math:\left[C, D\right] must be :math:\textit{n} for the problem to be properly posed.

Any violation of these conditions will lead to an error exit.

**gam** : float, ndarray, shape :math:\left(n\right)
The rows of :math:\mathrm{c} and :math:\mathrm{d} and the components of :math:\mathrm{gam} are reordered so that the boundary conditions are in the order:

(i) conditions on :math:y\left(a\right) only;

(#) condition involving :math:y\left(a\right) and :math:y\left(b\right); and

(#) conditions on :math:y\left(b\right) only.

The function will be slightly more efficient if the arrays :math:\mathrm{c}, :math:\mathrm{d} and :math:\mathrm{gam} are ordered in this way before entry, and in this event they will be unchanged on exit.

Note that the problems (1) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02gbf.html#eqn1>__ and (2) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02gbf.html#eqn1>__ must be of boundary value type, that is neither :math:C nor :math:D may be identically zero.

Note also that the rank of the matrix :math:\left[C, D\right] must be :math:\textit{n} for the problem to be properly posed.

Any violation of these conditions will lead to an error exit.

**x** : float, ndarray, shape :math:\left(\textit{mnp}\right)
:math:\mathrm{x}[0],\mathrm{x}[1],\ldots,\mathrm{x}[\mathrm{np}-1] define the final mesh (with the returned value of :math:\mathrm{np}) satisfying the relation [equation] <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02gbf.html#eqnd02x-n>__.

**y** : float, ndarray, shape :math:\left(n, \textit{mnp}\right)
The approximate solution :math:z\left(x\right) satisfying [equation] <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02gbf.html#eqnd02tol-g>__, on the final mesh, that is

.. math::
\mathrm{y}[j-1,i-1] = z_j\left(x_i\right)\text{, }\quad i = 1,2,\ldots,\mathrm{np}\text{ and }j = 1,2,\ldots,\textit{n}

where :math:\mathrm{np} is the number of points in the final mesh.

The remaining columns of :math:\mathrm{y} are not used.

**np** : int
The number of points in the final (returned) mesh.

.. _d02gb-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
The sequence :math:\mathrm{x} is not strictly increasing. For :math:i = \langle\mathit{\boldsymbol{value}}\rangle, :math:\mathrm{x}[i-1] = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{x}[i] = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry: :math:\mathrm{b} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{x}[\mathrm{np}-1] = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{a} = \mathrm{x}[0] < \mathrm{x}[1] < \cdots < \mathrm{x}[\mathrm{np}-1] = \mathrm{b}\text{, }\quad \mathrm{np}\geq 4.

(errno :math:1)
On entry: :math:\mathrm{a} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{x}[0] = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{a} = \mathrm{x}[0] < \mathrm{x}[1] < \cdots < \mathrm{x}[\mathrm{np}-1] = \mathrm{b}\text{, }\quad \mathrm{np}\geq 4.

(errno :math:1)
On entry, :math:\mathrm{a} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{b} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{b} > \mathrm{a}.

(errno :math:1)
On entry, :math:\textit{mnp} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\textit{mnp}\geq 32.

(errno :math:1)
On entry, :math:\mathrm{np} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\textit{mnp} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{np}\leq \textit{mnp}.

(errno :math:1)
On entry, :math:\mathrm{np} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{np} = 0 or :math:\mathrm{np}\geq 4.

(errno :math:1)
On entry, :math:\mathrm{tol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{tol} > 0.0.

(errno :math:1)
On entry, :math:n = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:n\geq 2.

(errno :math:2)
More than :math:\textit{n} columns of the :math:\textit{n} by :math:2\times n matrix :math:\left[C, D\right] are identically zero, i.e., the boundary conditions are rank deficient. The number of non-identically zero columns is :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:2)
Row :math:\langle\mathit{\boldsymbol{value}}\rangle of the array :math:\mathrm{c} and the corresponding row of array :math:\mathrm{d} are identically zero, i.e., the boundary conditions are rank deficient.

(errno :math:2)
:math:\mathrm{c} is identically zero; :math:\textit{n} conditions are set in :math:\mathrm{d}.

At least one condition must be on the left. :math:n = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:2)
:math:\mathrm{d} is identically zero; :math:\textit{n} conditions are set in :math:\mathrm{c}.

At least one condition must be on the right. :math:n = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:4)
A serious error occurred in a call to the internal integrator.

The error code internally was :math:\langle\mathit{\boldsymbol{value}}\rangle. Please contact NAG <https://www.nag.com>__.

(errno :math:5)
At least one row of the :math:\textit{n} by :math:2\times n matrix :math:\left[C, D\right] is a linear combination of the other rows determined up to a numerical tolerance, i.e., the boundary conditions are rank deficient. The index of first such row is :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:5)
At least one row of the :math:\textit{n} by :math:2\times n matrix :math:\left[C, D\right] is a linear combination of the other rows, i.e., the boundary conditions are rank deficient. The index of the first such row is :math:\langle\mathit{\boldsymbol{value}}\rangle.

**Warns**
**NagAlgorithmicWarning**
(errno :math:3)
Newton iteration has reached round-off level.

If desired accuracy has not been reached, :math:\mathrm{tol} is too small for this problem and this machine precision.

(errno :math:3)
The Newton iteration has failed to converge.

This could be due to there being too few points in the initial mesh or to the initial approximate solution being too inaccurate. If this latter reason is suspected or you cannot make changes to prevent this error, you should use the routine with a continuation facility instead.

(errno :math:3)
A finer mesh is required for the accuracy requested; that is, :math:\textit{mnp} is not large enough.

.. _d02gb-py2-py-notes:

**Notes**
In the NAG Library the traditional C interface for this routine uses a different algorithmic base. Please contact NAG if you have any questions about compatibility.

bvp_fd_lin_gen solves a linear two-point boundary value problem for a system of :math:\textit{n} ordinary differential equations in the interval [:math:a,b].
The system is written in the form

.. math::
y^{\prime } = F\left(x\right)y+g\left(x\right)

and the boundary conditions are written in the form

.. math::
Cy\left(a\right)+Dy\left(b\right) = \gamma \text{.}

Here :math:F\left(x\right), :math:C and :math:D are :math:\textit{n}\times \textit{n} matrices, and :math:g\left(x\right) and :math:\gamma are :math:\textit{n}-component vectors.
The approximate solution to (1) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02gbf.html#eqn1>__ and (2) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02gbf.html#eqn1>__ is found using a finite difference method with deferred correction.
The algorithm is a specialization of that used in function :meth:bvp_fd_nonlin_gen which solves a nonlinear version of (1) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02gbf.html#eqn1>__ and (2) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02gbf.html#eqn1>__.
The nonlinear version of the algorithm is described fully in Pereyra (1979).

You supply an absolute error tolerance and may also supply an initial mesh for the construction of the finite difference equations (alternatively a default mesh is used).
The algorithm constructs a solution on a mesh defined by adding points to the initial mesh.
This solution is chosen so that the error is everywhere less than your tolerance and so that the error is approximately equidistributed on the final mesh.
The solution is returned on this final mesh.

If the solution is required at a few specific points then these should be included in the initial mesh.
If, on the other hand, the solution is required at several specific points, then you should use the interpolation functions provided in submodule :mod:~naginterfaces.library.interp if these points do not themselves form a convenient mesh.

.. _d02gb-py2-py-references:

**References**
Pereyra, V, 1979, PASVA3: An adaptive finite-difference Fortran program for first order nonlinear, ordinary boundary problems, Codes for Boundary Value Problems in Ordinary Differential Equations. Lecture Notes in Computer Science, (eds B Childs, M Scott, J W Daniel, E Denman and P Nelson) (76), Springer--Verlag
"""
raise NotImplementedError

[docs]def bvp_shoot_bval(u, v, a, b, tol, fcn, m1, monlev, comm, data=None, io_manager=None):
r"""
bvp_shoot_bval solves a two-point boundary value problem for a system of ordinary differential equations, using a Runge--Kutta--Merson method and a Newton iteration in a shooting and matching technique.

.. _d02ha-py2-py-doc:

For full information please refer to the NAG Library document for d02ha

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02haf.html

.. _d02ha-py2-py-parameters:

**Parameters**
**u** : float, array-like, shape :math:\left(n, 2\right)
:math:\mathrm{u}[\textit{i}-1,0] must be set to the known or estimated value of :math:y_{\textit{i}} at :math:a and :math:\mathrm{u}[\textit{i}-1,1] must be set to the known or estimated value of :math:y_{\textit{i}} at :math:b, for :math:\textit{i} = 1,2,\ldots,\textit{n}.

**v** : float, array-like, shape :math:\left(n, 2\right)
:math:\mathrm{v}[\textit{i}-1,\textit{j}-1] must be set to :math:0.0 if :math:\mathrm{u}[\textit{i}-1,\textit{j}-1] is a known value and to :math:1.0 if :math:\mathrm{u}[\textit{i}-1,\textit{j}-1] is an estimated value, for :math:\textit{j} = 1,2,\ldots,2, for :math:\textit{i} = 1,2,\ldots,\textit{n}.

**a** : float
:math:a, the initial point of the interval of integration.

**b** : float
:math:b, the final point of the interval of integration.

**tol** : float
Must be set to a small quantity suitable for:

(a) testing the local error in :math:y_i during integration,

(#) testing for the convergence of :math:y_i at :math:b,

(#) calculating the perturbation in estimated boundary values for :math:y_i, which are used to obtain the approximate derivatives of the residuals for use in the Newton iteration.

You are advised to check your results by varying :math:\mathrm{tol}.

**fcn** : callable f = fcn(n, x, y, data=None)
:math:\mathrm{fcn} must evaluate the functions :math:f_{\textit{i}} (i.e., the derivatives :math:y_{\textit{i}}^{\prime }), for :math:\textit{i} = 1,2,\ldots,\textit{n}, at a general point :math:x.

**Parameters**
**n** : int
:math:\textit{n}, the number of equations.

**x** : float
:math:x, the value of the argument.

**y** : float, ndarray, shape :math:\left(\mathrm{n}\right)
:math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}, the value of the argument.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**f** : float, array-like, shape :math:\left(\mathrm{n}\right)
The values of :math:f_{\textit{i}}\left(x\right), for :math:\textit{i} = 1,2,\ldots,\textit{n}.

**m1** : int
A value which controls output.

:math:\mathrm{m1} = 1

The final solution is not evaluated.

:math:\mathrm{m1} > 1

The final values of :math:y_{\textit{i}} at interval :math:\left(b-a\right)/\left(\mathrm{m1}-1\right) are calculated and stored in the array :math:\mathrm{soln} by columns, starting with values :math:y_{\textit{i}} at :math:a stored in :math:\mathrm{soln}[\textit{i}-1,0], for :math:\textit{i} = 1,2,\ldots,\textit{n}.

**monlev** : int
Setting :math:\mathrm{monlev} = 0 disables monitoring of the pseudo-Newton iteration. Setting :math:\mathrm{monlev} = 1 enables this monitoring.

**comm** : dict, communication object, modified in place
Communication structure.

On initial entry: need not be set.

**data** : arbitrary, optional
User-communication data for callback functions.

**io_manager** : FileObjManager, optional
Manager for I/O in this routine.

**Returns**
**u** : float, ndarray, shape :math:\left(n, 2\right)
The known values unaltered, and corrected values of the estimates, unless an error has occurred. If an error has occurred, :math:\mathrm{u} contains the known values and the latest values of the estimates.

**soln** : float, ndarray, shape :math:\left(n, \mathrm{m1}\right)
The solution when :math:\mathrm{m1} > 1.

**w** : float, ndarray, shape :math:\left(n, 3\times n+17+\max\left(11,\mathrm{n}\right)\right)
If :math:\mathrm{errno} = 2, 3, 4 or 5, :math:\mathrm{w}[\textit{i}-1,0], for :math:\textit{i} = 1,2,\ldots,\textit{n}, contains the solution at the point where the integration fails and the point of failure is returned in :math:\mathrm{w}[0,1].

.. _d02ha-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:\mathrm{monlev} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{monlev} = 0 or :math:1.

(errno :math:1)
On entry, incorrect number of boundary values were flagged as known.

Number flagged as known: :math:\langle\mathit{\boldsymbol{value}}\rangle, but number should be :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry all left-hand boundary values were flagged as known.

(errno :math:1)
On entry no left-hand boundary values were flagged as known.

(errno :math:1)
On entry, :math:\mathrm{m1} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{m1}\geq 1.

(errno :math:1)
On entry, :math:\mathrm{tol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{tol} > 0.0.

(errno :math:1)
On entry, :math:n = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:n\geq 1.

(errno :math:2)
In the integration with initial or final parameters, the step size was reduced too far for the integration to proceed. Either this function is not a suitable method for solving the problem, or the initial choice of parameters is very poor.

(errno :math:3)
In the integration with initial or final parameters, a suitable initial step could not be found. Either this function is not suitable for solving the problem, or the initial choice of parameters is very poor.

(errno :math:4)
An initial step-length could be found for integration to proceed with the current parameters.

(errno :math:5)
The step-length required to calculate the Jacobian to sufficient accuracy is too small

(errno :math:6)
The Jacobian has an insignificant column. Make sure that the solution vector depends on all the parameters.

(errno :math:7)
An internal singular value decomposition has failed.

This error can be avoided by changing the initial parameter estimates.

(errno :math:8)
The Newton iteration has failed to converge.

This can indicate a poor initial choice of parameters or a very difficult problem.

Consider varying elements of the parameter convergence control if the residuals are small; otherwise vary initial parameter estimates.

(errno :math:10)
Internal error in calculating residual. Please contact NAG <https://www.nag.com>__.

(errno :math:11)
Internal error in calculating Jacobian. Please contact NAG <https://www.nag.com>__.

(errno :math:12)
Internal error in Newton method. Please contact NAG <https://www.nag.com>__.

.. _d02ha-py2-py-notes:

**Notes**
No equivalent traditional C interface for this routine exists in the NAG Library.

bvp_shoot_bval solves a two-point boundary value problem for a system of :math:\textit{n} ordinary differential equations in the range :math:a,b.
The system is written in the form:

.. math::
y_i^{\prime } = f_i\left(x, y_1, y_2, \ldots, y_{\textit{n}}\right)\text{, }\quad i = 1,2,\ldots,\textit{n}

and the derivatives :math:f_i are evaluated by :math:\mathrm{fcn}.
Initially, :math:\textit{n} boundary values of the variables :math:y_i must be specified, some at :math:a and some at :math:b.
You must supply estimates of the remaining :math:\textit{n} boundary values (called parameters below); the function corrects these by a form of Newton iteration.
It also calculates the complete solution on an equispaced mesh if required.

Starting from the known and estimated values of :math:y_i at :math:a, the function integrates the equations from :math:a to :math:b (using a Runge--Kutta--Merson method).
The differences between the values of :math:y_i at :math:b from integration and those specified initially should be zero for the true solution. (These differences are called residuals below.) The function uses a generalized Newton method to reduce the residuals to zero, by calculating corrections to the estimated boundary values.
This process is repeated iteratively until convergence is obtained, or until the function can no longer reduce the residuals.
See Hall and Watt (1976) for a simple discussion of shooting and matching techniques.

.. _d02ha-py2-py-references:

**References**
Hall, G and Watt, J M (ed.), 1976, Modern Numerical Methods for Ordinary Differential Equations, Clarendon Press, Oxford
"""
raise NotImplementedError

[docs]def bvp_shoot_genpar(p, pe, e, m1, monlev, fcn, bc, ebndry, comm, data=None, io_manager=None):
r"""
bvp_shoot_genpar solves a two-point boundary value problem for a system of ordinary differential equations, using initial value techniques and Newton iteration; it generalizes function :meth:bvp_shoot_bval to include the case where parameters other than boundary values are to be determined.

.. _d02hb-py2-py-doc:

For full information please refer to the NAG Library document for d02hb

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02hbf.html

.. _d02hb-py2-py-parameters:

**Parameters**
**p** : float, array-like, shape :math:\left(\textit{n1}\right)
An estimate for the :math:\textit{i}\ th argument, :math:p_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}_1.

**pe** : float, array-like, shape :math:\left(\textit{n1}\right)
The elements of :math:\mathrm{pe} must be given small positive values. The element :math:\mathrm{pe}[i-1] is used

(i) in the convergence test on the :math:i\ th argument in the Newton iteration, and

(#) in perturbing the :math:i\ th argument when approximating the derivatives of the components of the solution with respect to this argument for use in the Newton iteration.

The elements :math:\mathrm{pe}[i-1] should not be chosen too small.

They should usually be several orders of magnitude larger than machine precision.

**e** : float, array-like, shape :math:\left(n\right)
The elements of :math:\mathrm{e} must be given positive values. The element :math:\mathrm{e}[i-1] is used in the bound on the local error in the :math:i\ th component of the solution :math:y_i during integration.

The elements :math:\mathrm{e}[i-1] should not be chosen too small.

They should usually be several orders of magnitude larger than machine precision.

**m1** : int
A value which controls exit values.

:math:\mathrm{m1} = 1

The final solution is not calculated.

:math:\mathrm{m1} > 1

The final values of the solution at interval (length of range)/:math:\left(\mathrm{m1}-1\right) are calculated and stored sequentially in the array :math:\mathrm{soln} starting with the values of the solutions evaluated at the first end point (see :math:\mathrm{ebndry}) stored in the first column of :math:\mathrm{soln}.

**monlev** : int
Setting :math:\mathrm{monlev} = 0 disables monitoring of the pseudo-Newton iteration. Setting :math:\mathrm{monlev} = 1 enables this monitoring.

**fcn** : callable f = fcn(n, n1, x, y, p, data=None)
:math:\mathrm{fcn} must evaluate the functions :math:f_{\textit{i}} (i.e., the derivatives :math:y_{\textit{i}}^{\prime }), for :math:\textit{i} = 1,2,\ldots,\textit{n}, at a general point :math:x.

**Parameters**
**n** : int
:math:\textit{n}, the number of equations.

**n1** : int
:math:\textit{n}_1, the number of parameters.

**x** : float
:math:x, the value of the argument.

**y** : float, ndarray, shape :math:\left(\mathrm{n}\right)
:math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}, the value of the argument.

**p** : float, ndarray, shape :math:\left(\mathrm{n1}\right)
The current estimate of the argument :math:p_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}_1.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**f** : float, array-like, shape :math:\left(\mathrm{n}\right)
The value of :math:f_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}. The :math:f_i may depend upon the parameters :math:p_{\textit{j}}, for :math:\textit{j} = 1,2,\ldots,\textit{n}_1. If there are any driving equations (see :ref:Notes <d02hb-py2-py-notes>) then these must be numbered first in the ordering of the components of :math:\mathrm{f} in :math:\mathrm{fcn}.

**bc** : callable (g1, g2) = bc(n, n1, p, data=None)
:math:\mathrm{bc} must place in :math:\mathrm{g1} and :math:\mathrm{g2} the boundary conditions at :math:a and :math:b respectively (see :math:\mathrm{ebndry}).

**Parameters**
**n** : int
:math:\textit{n}, the number of equations.

**n1** : int
:math:\textit{n}_1, the number of parameters.

**p** : float, ndarray, shape :math:\left(\mathrm{n1}\right)
An estimate of the argument :math:p_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}_1.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**g1** : float, array-like, shape :math:\left(\mathrm{n}\right)
The value of :math:y_{\textit{i}}\left(a\right), (where this may be a known value or a function of the parameters :math:p_{\textit{j}}, for :math:\textit{j} = 1,2,\ldots,\textit{n}_1, for :math:\textit{i} = 1,2,\ldots,\textit{n}).

**g2** : float, array-like, shape :math:\left(\mathrm{n}\right)
The value of :math:y_{\textit{i}}\left(b\right), for :math:\textit{i} = 1,2,\ldots,\textit{n}, (where these may be known values or functions of the parameters :math:p_{\textit{j}}, for :math:\textit{j} = 1,2,\ldots,\textit{n}_1). If :math:\textit{n} > \textit{n}_1, so that there are some driving equations, the first :math:\textit{n}-\textit{n}_1 values of :math:\mathrm{g2} need not be set since they are never used.

**ebndry** : callable (a, b) = ebndry(n1, p, data=None)
:math:\mathrm{ebndry} must evaluate the boundary points :math:a and :math:b, each of which may depend on the arguments :math:p_1,p_2,\ldots,p_{\textit{n}_1}.

The integrations in the shooting method are always from :math:a to :math:b.

**Parameters**
**n1** : int
:math:\textit{n}_1, the number of parameters.

**p** : float, ndarray, shape :math:\left(\mathrm{n1}\right)
The current estimate of the :math:\textit{i}\ th argument, :math:p_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}_1.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**a** : float
:math:a, one of the boundary points.

**b** : float
The second boundary point, :math:b. Note that :math:\mathrm{b} > \mathrm{a} forces the direction of integration to be that of increasing :math:x. If :math:\mathrm{a} and :math:\mathrm{b} are interchanged the direction of integration is reversed.

**comm** : dict, communication object, modified in place
Communication structure.

On initial entry: need not be set.

**data** : arbitrary, optional
User-communication data for callback functions.

**io_manager** : FileObjManager, optional
Manager for I/O in this routine.

**Returns**
**p** : float, ndarray, shape :math:\left(\textit{n1}\right)
The corrected value for the :math:i\ th argument, unless an error has occurred, when it contains the last calculated value of the argument.

**soln** : float, ndarray, shape :math:\left(n, \mathrm{m1}\right)
The solution when :math:\mathrm{m1} > 1.

**w** : float, ndarray, shape :math:\left(n, 3\times n+14+\max\left(11,\mathrm{n}\right)\right)
With :math:\mathrm{errno} = 2, 3, 4 or 5 (see :ref:Exceptions <d02hb-py2-py-errors>), :math:\mathrm{w}[\textit{i}-1,0], for :math:\textit{i} = 1,2,\ldots,\textit{n}, contains the solution at the point :math:x when the error occurred. :math:\mathrm{w}[0,1] contains :math:x.

.. _d02hb-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:\mathrm{monlev} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{monlev} = 0 or :math:1.

(errno :math:1)
On entry a negative or zero local error tolerance has been set.

(errno :math:1)
On entry a negative or zero convergence test tolerance has been set.

(errno :math:1)
On entry, :math:\mathrm{m1} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{m1}\geq 1.

(errno :math:1)
On entry, :math:n = \langle\mathit{\boldsymbol{value}}\rangle and :math:\textit{n1} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:n\geq \textit{n1}.

(errno :math:1)
On entry, :math:\textit{n1} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\textit{n1}\geq 1.

(errno :math:2)
The step length for the integration became too short to proceed when calculating the residual.

(errno :math:2)
In the integration with initial or final parameters, the step size was reduced too far for the integration to proceed. Either this function is not a suitable method for solving the problem, or the initial choice of parameters is very poor.

(errno :math:3)
An initial step-length could be found for integration to proceed with the current parameters.

(errno :math:3)
In the integration with initial or final parameters, a suitable initial step could not be found. Either this function is not suitable for solving the problem, or the initial choice of parameters is very poor.

(errno :math:4)
The step-length required to calculate the Jacobian to sufficient accuracy is too small

(errno :math:5)
An initial step-length could be found for Jacobian calculation to proceed with the current parameters.

(errno :math:6)
The Jacobian has an insignificant column. Make sure that the solution vector depends on all the parameters.

(errno :math:7)
An internal singular value decomposition has failed.

This error can be avoided by changing the initial parameter estimates.

(errno :math:8)
The Newton iteration has failed to converge.

This can indicate a poor initial choice of parameters or a very difficult problem.

Consider varying elements of the parameter convergence control if the residuals are small; otherwise vary initial parameter estimates.

(errno :math:9)
Internal error in Newton method. Please contact NAG <https://www.nag.com>__.

(errno :math:10)
Internal error in calculating Jacobian. Please contact NAG <https://www.nag.com>__.

(errno :math:11)
Internal error in calculating residual. Please contact NAG <https://www.nag.com>__.

(errno :math:12)
Internal error in calculating residual. Please contact NAG <https://www.nag.com>__.

.. _d02hb-py2-py-notes:

**Notes**
No equivalent traditional C interface for this routine exists in the NAG Library.

bvp_shoot_genpar solves a two-point boundary value problem by determining the unknown parameters :math:p_1,p_2,\ldots,p_{\textit{n}_1} of the problem.
These parameters may be, but need not be, boundary values; they may include eigenvalue parameters in the coefficients of the differential equations, length of the range of integration, etc.
The notation and methods used are similar to those of :meth:bvp_shoot_bval and you are advised to study this first. (The parameters :math:p_1,p_2,\ldots,p_{\textit{n}_1} correspond precisely to the unknown boundary conditions in :meth:bvp_shoot_bval.) It is assumed that we have a system of :math:\textit{n} first-order ordinary differential equations of the form:

.. math::
\frac{{dy_i}}{{dx}} = f_i\left(x, y_1, y_2, \ldots, y_{\textit{n}}\right)\text{, }\quad i = 1,2,\ldots,\textit{n}\text{,}

and that the derivatives :math:f_i are evaluated by :math:\mathrm{fcn}.
The system, including the boundary conditions given by :math:\mathrm{bc} and the range of integration given by :math:\mathrm{ebndry}, involves the :math:\textit{n}_1 unknown parameters :math:p_1,p_2,\ldots,p_{\textit{n}_1} which are to be determined, and for which initial estimates must be supplied.
The number of unknown parameters :math:\textit{n}_1 must not exceed the number of equations :math:\textit{n}.
If :math:\textit{n}_1 < \textit{n}, we assume that :math:\left(\textit{n}-\textit{n}_1\right) equations of the system are not involved in the matching process.
These are usually referred to as 'driving equations'; they are independent of the parameters and of the solutions of the other :math:\textit{n}_1 equations.
In numbering the equations for :math:\mathrm{fcn}, the driving equations must be put **first**.

The estimated values of the parameters are corrected by a form of Newton iteration.
The Newton correction on each iteration is calculated using a Jacobian matrix whose :math:\left(i, j\right)\ th element depends on the derivative of the :math:i\ th component of the solution, :math:y_i, with respect to the :math:j\ th parameter, :math:p_j.
This matrix is calculated by a simple numerical differentiation technique which requires :math:\textit{n}_1 evaluations of the differential system.

If the argument :math:\mathrm{monlev} is set appropriately, the function automatically prints messages to inform you of the flow of the calculation.
These messages are discussed in detail in Further Comments <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02hbf.html#fcomments>__.

bvp_shoot_genpar is a simplified version of :meth:bvp_shoot_genpar_algeq which is described in detail in Gladwell (1979).

.. _d02hb-py2-py-references:

**References**
Gladwell, I, 1979, The development of the boundary value codes in the ordinary differential equations module of the NAG Library, Codes for Boundary Value Problems in Ordinary Differential Equations. Lecture Notes in Computer Science, (eds B Childs, M Scott, J W Daniel, E Denman and P Nelson) (76), Springer--Verlag
"""
raise NotImplementedError

[docs]def bvp_coll_nth(n, cf, bc, x0, x1, k1, kp, comm, data=None):
r"""
bvp_coll_nth solves a regular linear two-point boundary value problem for a single :math:n\ th-order ordinary differential equation by Chebyshev series using collocation and least squares.

.. _d02ja-py2-py-doc:

For full information please refer to the NAG Library document for d02ja

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02jaf.html

.. _d02ja-py2-py-parameters:

**Parameters**
**n** : int
:math:n, the order of the differential equation.

**cf** : callable retval = cf(j, x, data=None)
:math:\mathrm{cf} defines the differential equation (see :ref:Notes <d02ja-py2-py-notes>).

It must return the value of a function :math:f_j\left(x\right) at a given point :math:x, where, for :math:1\leq j\leq n+1, :math:f_j\left(x\right) is the coefficient of :math:y^{\left(j-1\right)}\left(x\right) in the equation, and :math:f_0\left(x\right) is the right-hand side.

**Parameters**
**j** : int
The index of the function :math:f_j to be evaluated.

**x** : float
The point at which :math:f_j is to be evaluated.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**retval** : float
The value of :math:f_j\left(x\right) at the given point :math:x.

**bc** : callable (j, rhs) = bc(i, data=None)
:math:\mathrm{bc} defines the boundary conditions, each of which has the form :math:y^{\left(k-1\right)}\left(x_1\right) = s_k or :math:y^{\left(k-1\right)}\left(x_0\right) = s_k.

The boundary conditions may be specified in any order.

**Parameters**
**i** : int
The index of the boundary condition to be defined.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**j** : int
Must be set to :math:{-k} if the boundary condition is :math:y^{\left(k-1\right)}\left(x_0\right) = s_k, and to :math:{+k} if it is :math:y^{\left(k-1\right)}\left(x_1\right) = s_k.

:math:\mathrm{j} must not be set to the same value :math:k for two different values of :math:\mathrm{i}.

**rhs** : float
Must be set to the value :math:s_k.

**x0** : float
The left- and right-hand boundaries, :math:x_0 and :math:x_1, respectively.

**x1** : float
The left- and right-hand boundaries, :math:x_0 and :math:x_1, respectively.

**k1** : int
The number of coefficients to be returned in the Chebyshev series representation of the solution (hence the degree of the polynomial approximation is :math:\mathrm{k1}-1).

**kp** : int
The number of collocation points to be used.

**comm** : dict, communication object, modified in place
Communication structure.

On initial entry: need not be set.

**data** : arbitrary, optional
User-communication data for callback functions.

**Returns**
**c** : float, ndarray, shape :math:\left(\mathrm{k1}\right)
The computed Chebyshev coefficients; that is, the computed solution is:

.. math::
{\sum^\prime}_{{i = 1}}^{\mathrm{k1}}\mathrm{c}[i-1]T_{{i-1}}\left(x\right)

where :math:T_i\left(x\right) is the :math:i\ th Chebyshev polynomial of the first kind, and :math:{\sum^\prime} denotes that the first coefficient, :math:\mathrm{c}[0], is halved.

.. _d02ja-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:\mathrm{kp} = \langle\mathit{\boldsymbol{value}}\rangle, :math:\mathrm{n} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{k1} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{kp}+\mathrm{n}\geq \mathrm{k1}.

(errno :math:1)
On entry, :math:\mathrm{k1} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{n} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{k1}\geq \mathrm{n}+1.

(errno :math:1)
On entry, :math:\mathrm{x1} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{x0} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{x1} > \mathrm{x0}.

(errno :math:1)
On entry, :math:\mathrm{n} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{n}\geq 1.

(errno :math:3)
Either the boundary conditions are not linearly independent, or the coefficient matrix is rank deficient. Increasing the number of collocation points may overcome this latter problem.

(errno :math:4)
Iterative refinement in the least squares solution has failed to converge. The coefficient matrix is too ill-conditioned.

.. _d02ja-py2-py-notes:

**Notes**
No equivalent traditional C interface for this routine exists in the NAG Library.

bvp_coll_nth calculates the solution of a regular two-point boundary value problem for a single :math:n\ th-order linear ordinary differential equation as a Chebyshev series in the interval :math:\left(x_0, x_1\right).
The differential equation

.. math::
f_{{n+1}}\left(x\right)y^{\left(n\right)}\left(x\right)+f_n\left(x\right)y^{\left(n-1\right)}\left(x\right)+ \cdots +f_1\left(x\right)y\left(x\right) = f_0\left(x\right)

is defined by :math:\mathrm{cf}, and the boundary conditions at the points :math:x_0 and :math:x_1 are defined by :math:\mathrm{bc}.

You specify the degree of Chebyshev series required, :math:\mathrm{k1}-1, and the number of collocation points, :math:\mathrm{kp}.
The function sets up a system of linear equations for the Chebyshev coefficients, one equation for each collocation point and one for each boundary condition.
The boundary conditions are solved exactly, and the remaining equations are then solved by a least squares method.
The result produced is a set of coefficients for a Chebyshev series solution of the differential equation on an interval normalized to :math:\left(-1, 1\right).

:meth:fit.dim1_cheb_eval2 <naginterfaces.library.fit.dim1_cheb_eval2> can be used to evaluate the solution at any point on the interval :math:\left(x_0, x_1\right). :meth:fit.dim1_cheb_deriv <naginterfaces.library.fit.dim1_cheb_deriv> followed by :meth:fit.dim1_cheb_eval2 <naginterfaces.library.fit.dim1_cheb_eval2> can be used to evaluate its derivatives.

.. _d02ja-py2-py-references:

**References**
Picken, S M, 1970, Algorithms for the solution of differential equations in Chebyshev-series by the selected points method, Report Math. 94, National Physical Laboratory
"""
raise NotImplementedError

[docs]def bvp_coll_sys(n, cf, bc, x0, x1, k1, kp, comm, data=None):
r"""
bvp_coll_sys solves a regular linear two-point boundary value problem for a system of ordinary differential equations by Chebyshev series using collocation and least squares.

.. _d02jb-py2-py-doc:

For full information please refer to the NAG Library document for d02jb

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02jbf.html

.. _d02jb-py2-py-parameters:

**Parameters**
**n** : int
:math:n, the order of the system of differential equations.

**cf** : callable retval = cf(i, j, x, data=None)
:math:\mathrm{cf} defines the system of differential equations (see :ref:Notes <d02jb-py2-py-notes>).

It must return the value of a coefficient function :math:a_{{i,j}}\left(x\right), of :math:A, at a given point :math:x, or of a right-hand side function :math:r_i\left(x\right) if :math:\mathrm{j} = 0.

**Parameters**
**i** : int
Indicate the function to be evaluated, namely :math:a_{{i,j}}\left(x\right) if :math:1\leq \mathrm{j}\leq n, or :math:r_i\left(x\right) if :math:\mathrm{j} = 0.

:math:1\leq \mathrm{i}\leq n, :math:0\leq \mathrm{j}\leq n.

**j** : int
Indicate the function to be evaluated, namely :math:a_{{i,j}}\left(x\right) if :math:1\leq \mathrm{j}\leq n, or :math:r_i\left(x\right) if :math:\mathrm{j} = 0.

:math:1\leq \mathrm{i}\leq n, :math:0\leq \mathrm{j}\leq n.

**x** : float
The point at which the function is to be evaluated.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**retval** : float
The value of a coefficient function :math:a_{{i,j}}\left(x\right), of :math:A, at a given point :math:x, or of a right-hand side function :math:r_i\left(x\right) if :math:\mathrm{j} = 0.

**bc** : callable (j, rhs) = bc(i, data=None)
:math:\mathrm{bc} defines the :math:n boundary conditions, which have the form :math:y_k\left(x_0\right) = s or :math:y_k\left(x_1\right) = s.

The boundary conditions may be specified in any order.

**Parameters**
**i** : int
The index of the boundary condition to be defined.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**j** : int
Must be set to :math:{-k} if the :math:i\ th boundary condition is :math:y_k\left(x_0\right) = s, or to :math:{+k} if it is :math:y_k\left(x_1\right) = s.

:math:\mathrm{j} must not be set to the same value :math:k for two different values of :math:\mathrm{i}.

**rhs** : float
The value :math:s.

**x0** : float
The left- and right-hand boundaries, :math:x_0 and :math:x_1, respectively.

**x1** : float
The left- and right-hand boundaries, :math:x_0 and :math:x_1, respectively.

**k1** : int
The number of coefficients to be returned in the Chebyshev series representation of the components of the solution (hence the degree of the polynomial approximation is :math:\mathrm{k1}-1).

**kp** : int
The number of collocation points to be used.

**comm** : dict, communication object, modified in place
Communication structure.

On initial entry: need not be set.

**data** : arbitrary, optional
User-communication data for callback functions.

**Returns**
**c** : float, ndarray, shape :math:\left(\mathrm{k1}, \mathrm{n}\right)
The computed Chebyshev coefficients of the :math:k\ th component of the solution, :math:y_k; that is, the computed solution is:

.. math::
y_k = {\sum^\prime}_{{i = 1}}^{\mathrm{k1}}\mathrm{c}[i-1,k-1]T_{{i-1}}\left(x\right)\text{, }\quad 1\leq k\leq n

where :math:T_i\left(x\right) is the :math:i\ th Chebyshev polynomial of the first kind, and :math:{\sum^\prime} denotes that the first coefficient, :math:\mathrm{c}[0,k-1], is halved.

.. _d02jb-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:\mathrm{kp} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{k1} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{kp}+1\geq \mathrm{k1}.

(errno :math:1)
On entry, :math:\mathrm{k1} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{k1}\geq 2.

(errno :math:1)
On entry, :math:\mathrm{x1} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{x0} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{x1} > \mathrm{x0}.

(errno :math:1)
On entry, :math:\mathrm{n} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{n}\geq 1.

(errno :math:3)
Either the boundary conditions are not linearly independent, or the coefficient matrix is rank deficient. Increasing the number of collocation points may overcome this latter problem.

(errno :math:4)
Iterative refinement in the least squares solution has failed to converge. The coefficient matrix is too ill-conditioned.

.. _d02jb-py2-py-notes:

**Notes**
No equivalent traditional C interface for this routine exists in the NAG Library.

bvp_coll_sys calculates the solution of a regular two-point boundary value problem for a regular linear :math:n\ th-order system of first-order ordinary differential equations as a Chebyshev series in the interval :math:\left(x_0, x_1\right).
The differential equation

.. math::
y^{\prime } = A\left(x\right)y+r\left(x\right)

is defined by :math:\mathrm{cf}, and the boundary conditions at the points :math:x_0 and :math:x_1 are defined by :math:\mathrm{bc}.

You specify the degree of Chebyshev series required, :math:\mathrm{k1}-1, and the number of collocation points, :math:\mathrm{kp}.
The function sets up a system of linear equations for the Chebyshev coefficients, :math:n equations for each collocation point and one for each boundary condition.
The boundary conditions are solved exactly, and the remaining equations are then solved by a least squares method.
The result produced is a set of coefficients for a Chebyshev series solution for each component of the solution of the system of differential equations on an interval normalized to :math:\left(-1, 1\right).

:meth:fit.dim1_cheb_eval2 <naginterfaces.library.fit.dim1_cheb_eval2> can be used to evaluate the components of the solution at any point on the interval :math:\left(x_0, x_1\right). :meth:fit.dim1_cheb_deriv <naginterfaces.library.fit.dim1_cheb_deriv> followed by :meth:fit.dim1_cheb_eval2 <naginterfaces.library.fit.dim1_cheb_eval2> can be used to evaluate their derivatives.

.. _d02jb-py2-py-references:

**References**
Picken, S M, 1970, Algorithms for the solution of differential equations in Chebyshev-series by the selected points method, Report Math. 94, National Physical Laboratory
"""
raise NotImplementedError

[docs]def sl2_reg_finite(xl, xr, coeffn, bcond, k, tol, elam, delam, monit=None, data=None):
r"""
sl2_reg_finite finds a specified eigenvalue of a regular second-order Sturm--Liouville system defined on a finite range, using a Pruefer transformation and a shooting method.

.. _d02ka-py2-py-doc:

For full information please refer to the NAG Library document for d02ka

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02kaf.html

.. _d02ka-py2-py-parameters:

**Parameters**
**xl** : float
The left- and right-hand end points :math:a and :math:b respectively, of the interval of definition of the problem.

**xr** : float
The left- and right-hand end points :math:a and :math:b respectively, of the interval of definition of the problem.

**coeffn** : callable (p, q, dqdl) = coeffn(x, elam, jint, data=None)
:math:\mathrm{coeffn} must compute the values of the coefficient functions :math:p\left(x\right) and :math:q\left(x;\lambda \right) for given values of :math:x and :math:\lambda. :ref:Notes <d02ka-py2-py-notes> states the conditions which :math:p and :math:q must satisfy.

**Parameters**
**x** : float
The current value of :math:x.

**elam** : float
The current trial value of the eigenvalue argument :math:\lambda.

**jint** : int
This argument is included for compatibility with the more complex function :meth:sl2_breaks_vals (which is called by sl2_reg_finite).

Need not be set.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**p** : float
The value of :math:p\left(x\right) for the current value of :math:x.

**q** : float
The value of :math:q\left(x;\lambda \right) for the current value of :math:x and the current trial value of :math:\lambda.

**dqdl** : float
The value of :math:\frac{{\partial q}}{{\partial \lambda }}\left(x;\lambda \right) for the current value of :math:x and the current trial value of :math:\lambda. However :math:\mathrm{dqdl} is only used in error estimation and, in the rare cases where it may be difficult to evaluate, an approximation (say to within :math:20\%) will suffice.

**bcond** : float, array-like, shape :math:\left(3, 2\right)
:math:\mathrm{bcond}[0,0] and :math:\mathrm{bcond}[1,0] must contain the numbers :math:a_1, :math:a_2 specifying the left-hand boundary condition in the form

.. math::
a_2y\left(a\right) = a_1p\left(a\right)y^{\prime }\left(a\right)

where :math:\left\lvert a_2\right\rvert +\left\lvert a_1p\left(a\right)\right\rvert \neq 0.

:math:\mathrm{bcond}[0,1] and :math:\mathrm{bcond}[1,1] must contain :math:b_1, :math:b_2 such that

.. math::
b_2y\left(b\right) = b_1p\left(b\right)y^{\prime }\left(b\right)

where :math:\left\lvert b_2\right\rvert +\left\lvert b_1p\left(b\right)\right\rvert \neq 0.

Note the occurrence of :math:p\left(a\right), :math:p\left(b\right) in these formulae.

**k** : int
:math:k, the index of the required eigenvalue when the eigenvalues are ordered

.. math::
\lambda_0 < \lambda_1 < \lambda_2 < \cdots < \lambda_k < \cdots \text{.}

**tol** : float
The tolerance argument which determines the accuracy of the computed eigenvalue. The error estimate held in :math:\mathrm{delam} on exit satisfies the mixed absolute/relative error test

.. math::
\mathrm{delam}\leq \mathrm{tol}\times \mathrm{max}\left(1.0, \left\lvert \mathrm{elam}\right\rvert \right)\text{,}

where :math:\mathrm{elam} is the final estimate of the eigenvalue. :math:\mathrm{delam} is usually somewhat smaller than the right-hand side of (1) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02kaf.html#eqn1>__ but not several orders of magnitude smaller.

**elam** : float
An initial estimate of the eigenvalue :math:\tilde{\lambda }.

**delam** : float
An indication of the scale of the problem in the :math:\lambda-direction. :math:\mathrm{delam} holds the initial 'search step' (positive or negative). Its value is not critical, but the first two trial evaluations are made at :math:\mathrm{elam} and :math:\mathrm{elam}+\mathrm{delam}, so the function will work most efficiently if the eigenvalue lies between these values. A reasonable choice (if a closer bound is not known) is about half the distance between adjacent eigenvalues in the neighbourhood of the one sought. In practice, there will often be a problem, similar to the one in hand but with known eigenvalues, which will help one to choose initial values for :math:\mathrm{elam} and :math:\mathrm{delam}.

If :math:\mathrm{delam} = 0.0 on entry, it is given the default value of :math:0.25\times \mathrm{max}\left(1.0, \left\lvert \mathrm{elam}\right\rvert \right).

**monit** : None or callable monit(nit, iflag, elam, finfo, data=None), optional
Note: if this argument is **None** then a NAG-supplied facility will be used.

:math:\mathrm{monit} is called by sl2_reg_finite at the end of each iteration for :math:\lambda and allows you to monitor the course of the computation by printing out the arguments.

**Parameters**
**nit** : int
15 minus the number of iterations used so far in the search for :math:\tilde{\lambda }. (Up to :math:15 iterations are permitted.)

**iflag** : int
Describes what phase the computation is in.

:math:\mathrm{iflag} < 0

An error occurred in the computation at this iteration; an error exit from sl2_reg_finite will follow.

:math:\mathrm{iflag} = 1

The function is trying to bracket the eigenvalue :math:\tilde{\lambda }.

:math:\mathrm{iflag} = 2

The function is converging to the eigenvalue :math:\tilde{\lambda } (having already bracketed it).

Normally, the iteration will terminate after a sequence of iterates with :math:\mathrm{iflag} = 2, but occasionally the bracket on :math:\tilde{\lambda } thus determined will not be sufficiently small and the iteration will be repeated with tighter accuracy control.

**elam** : float
The current trial value of :math:\tilde{\lambda }.

**finfo** : float, ndarray, shape :math:\left(15\right)
Information about the behaviour of the shooting method, and diagnostic information in the case of errors. It should not normally be printed in full if no error has occurred (that is, if :math:\mathrm{iflag}\geq 0), though the first few components may be of interest to you. In case of an error (:math:\mathrm{iflag} < 0) all the components of :math:\mathrm{finfo} should be printed.

The contents of :math:\mathrm{finfo} are as follows:

:math:\mathrm{finfo}[0]

The current value of the 'miss-distance' or 'residual' function :math:f\left(\lambda \right) on which the shooting method is based. :math:f\left(\tilde{\lambda }\right) = 0 in theory. This is set to zero if :math:\mathrm{iflag} < 0.

:math:\mathrm{finfo}[1]

An estimate of the quantity :math:\partial \lambda defined as follows. Consider the perturbation in the miss-distance :math:f\left(\lambda \right) that would result if the local error in the solution of the differential equation were always positive and equal to its maximum permitted value. Then :math:\partial \lambda is the perturbation in :math:\lambda that would have the same effect on :math:f\left(\lambda \right). Thus, at the zero of :math:f\left(\lambda \right),\left\lvert \partial \lambda \right\rvert is an approximate bound on the perturbation of the zero (that is the eigenvalue) caused by errors in numerical solution. If :math:\partial \lambda is very large then it is possible that there has been a programming error in :math:\mathrm{coeffn} such that :math:q is independent of :math:\lambda. If this is the case, an error exit with :math:\mathrm{errno} = 5 should follow. :math:\mathrm{finfo}[1] is set to zero if :math:\mathrm{iflag} < 0.

:math:\mathrm{finfo}[2]

The number of internal iterations, using the same value of :math:\lambda and tighter accuracy tolerances, needed to bring the accuracy (that is, the value of :math:\partial \lambda) to an acceptable value. Its value should normally be :math:1.0, and should almost never exceed :math:2.0.

:math:\mathrm{finfo}[3]

The number of calls to :math:\mathrm{coeffn} at this iteration.

:math:\mathrm{finfo}[4]

The number of successful steps taken by the internal differential equation solver at this iteration. A step is successful if it is used to advance the integration.

:math:\mathrm{finfo}[5]

The number of unsuccessful steps used by the internal integrator at this iteration.

:math:\mathrm{finfo}[6]

The number of successful steps at the maximum step size taken by the internal integrator at this iteration.

:math:\mathrm{finfo}[7]

Not used.

:math:\mathrm{finfo}[8] to :math:\mathrm{finfo}[14]

Set to zero, unless :math:\mathrm{iflag} < 0 in which case they hold the following values describing the point of failure:

:math:\mathrm{finfo}[8]

1 or :math:2 depending on whether integration was in a forward or backward direction at the time of failure.

:math:\mathrm{finfo}[9]

The value of the independent variable, :math:x, the point at which the error occurred.

:math:\mathrm{finfo}[10], :math:\mathrm{finfo}[11], :math:\mathrm{finfo}[12]

The current values of the Pruefer dependent variables :math:\beta, :math:\phi and :math:\rho respectively. See :ref:Notes for sl2_breaks_funs <d02ke-py2-py-notes> for a description of these variables.

:math:\mathrm{finfo}[13]

The local-error tolerance being used by the internal integrator at the point of failure.

:math:\mathrm{finfo}[14]

The last integration mesh point.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**data** : arbitrary, optional
User-communication data for callback functions.

**Returns**
**bcond** : float, ndarray, shape :math:\left(3, 2\right)
:math:\mathrm{bcond}[2,0] and :math:\mathrm{bcond}[2,1] hold values :math:\sigma_l,\sigma_r estimating the sensitivity of the computed eigenvalue to changes in the boundary conditions. These values should only be of interest if the boundary conditions are, in some sense, an approximation to some 'true' boundary conditions. For example, if the range [:math:\mathrm{xl}, :math:\mathrm{xr}] should really be :math:\left[0, \infty \right] but instead :math:\mathrm{xr} has been given a large value and the boundary conditions at infinity applied at :math:\mathrm{xr}, the sensitivity argument :math:\sigma_r may be of interest. Refer to Further Comments <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02kdf.html#fcomments5>__, for the actual meaning of :math:\sigma_r and :math:\sigma_l.

**elam** : float
The final computed estimate, whether or not an error occurred.

**delam** : float
If no exception or warning is raised, :math:\mathrm{delam} holds an estimate of the absolute error in the computed eigenvalue, that is :math:\left\lvert \tilde{\lambda }-\mathrm{elam}\right\rvert \simeq \mathrm{delam}, where :math:\tilde{\lambda } is the true eigenvalue.

If an exception is raised, :math:\mathrm{delam} may hold an estimate of the error, or its initial value, depending on the value of :math:\textit{errno}.

See :ref:Exceptions <d02ka-py2-py-errors> for further details.

.. _d02ka-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:\mathrm{tol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{tol} > 0.0.

(errno :math:1)
On entry, :math:\mathrm{k} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{k}\geq 0.

(errno :math:2)
The constraint on the left- or right-hand boundary condition has been violated.

(errno :math:3)
The function :math:p\left(x\right) became zero or changed sign in the interval :math:\left[a, b\right].

(errno :math:4)
After :math:15 iterations the eigenvalue had not been found to the required accuracy.

(errno :math:5)
The bracketing phase failed to bracket the eigenvalue within ten iterations. This may be due to an error in formulating the problem (for example, :math:q is independent of :math:\lambda), or by very poor initial estimates for the eigenvalue and search step.

(errno :math:6)
Too small a step size was required at the start of a sub-interval to obtain the desired accuracy.

(errno :math:7)
Too small a step size was required during solution in a sub-interval to obtain the desired accuracy.

(errno :math:9)
An internal error has occurred corresponding to a pole of the matching function. Try solving the problem again with a smaller tolerance.

**Warns**
**NagAlgorithmicWarning**
(errno :math:8)
The tolerance set is too small for the problem being solved and the machine precision being used. The local eigenvalue estimate returned is likely to be a very good approximation.

.. _d02ka-py2-py-notes:

**Notes**
No equivalent traditional C interface for this routine exists in the NAG Library.

sl2_reg_finite finds a specified eigenvalue :math:\tilde{\lambda } of a Sturm--Liouville system defined by a self-adjoint differential equation of the second-order

.. math::
\left(p\left(x\right)y^{\prime }\right)^{\prime }+q\left(x;\lambda \right)y = 0\text{, }\quad a < x < b\text{,}

together with boundary conditions of the form

.. math::
a_2y\left(a\right) = a_1p\left(a\right)y^{\prime }\left(a\right)

.. math::
b_2y\left(b\right) = b_1p\left(b\right)y^{\prime }\left(b\right)

at the two, finite, end points :math:a and :math:b.
The functions :math:p and :math:q, which are real-valued, are defined by :math:\mathrm{coeffn}.

For the theoretical basis of the numerical method to be valid, the following conditions should hold on the coefficient functions:

(a) :math:p\left(x\right) must be nonzero and must not change sign throughout the closed interval :math:\left[a, b\right];

(#) :math:\frac{{\partial q}}{{\partial \lambda }} must not change sign and must be nonzero throughout the open interval :math:\left(a, b\right) and for all relevant values of :math:\lambda, and must not be identically zero as :math:x varies, for any relevant value :math:\lambda; and,

(#) :math:p and :math:q should (as functions of :math:x) have continuous derivatives, preferably up to the fourth-order, on :math:\left[a, b\right]. The differential equation code used will integrate through mild discontinuities, but probably with severely reduced efficiency. Therefore, if :math:p and :math:q violate this condition, :meth:sl2_breaks_vals should be used.

The eigenvalue :math:\tilde{\lambda } is determined by a shooting method based on a Pruefer transformation of the differential equations.
Providing certain assumptions are met, the computed value of :math:\tilde{\lambda } will be correct to within a mixed absolute/relative error specified by :math:\mathrm{tol}. sl2_reg_finite is a driver function for the more complicated function :meth:sl2_breaks_vals whose specification provides more details of the techniques used.

A good account of the theory of Sturm--Liouville systems, with some description of Pruefer transformations, is given in Module X of Birkhoff and Rota (1962).
An introduction to the use of Pruefer transformations for the numerical solution of eigenvalue problems arising from physics and chemistry is given in Bailey (1966).

.. _d02ka-py2-py-references:

**References**
Bailey, P B, 1966, Sturm--Liouville eigenvalues via a phase function, SIAM J. Appl. Math. (14), 242--249

Birkhoff, G and Rota, G C, 1962, Ordinary Differential Equations, Ginn & Co., Boston and New York
"""
raise NotImplementedError

[docs]def sl2_breaks_vals(xpoint, coeffn, bdyval, k, tol, elam, delam, hmax, maxit=0, maxfun=0, monit=None, data=None):
r"""
sl2_breaks_vals finds a specified eigenvalue of a regular or singular second-order Sturm--Liouville system on a finite or infinite interval, using a Pruefer transformation and a shooting method.
Provision is made for discontinuities in the coefficient functions or their derivatives.

.. _d02kd-py2-py-doc:

For full information please refer to the NAG Library document for d02kd

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02kdf.html

.. _d02kd-py2-py-parameters:

**Parameters**
**xpoint** : float, array-like, shape :math:\left(m\right)
The points where the boundary conditions computed by :math:\mathrm{bdyval} are to be imposed, and also any break-points, i.e., :math:\mathrm{xpoint}[0] to :math:\mathrm{xpoint}[m-1] must contain values :math:x_1,\ldots,x_m such that

.. math::
x_1\leq x_2 < x_3 < \cdots < x_{{m-1}}\leq x_m

with the following meanings:

(a) :math:x_1 and :math:x_m are the left- and right-hand end points, :math:a and :math:b, of the domain of definition of the Sturm--Liouville system if these are finite. If either :math:a or :math:b is infinite, the corresponding value :math:x_1 or :math:x_m may be a more-or-less arbitrarily 'large' number of appropriate sign.

(#) :math:x_2 and :math:x_{{m-1}} are the Boundary Matching Points (BMPs), that is the points at which the left and right boundary conditions computed in :math:\mathrm{bdyval} are imposed.

If the left-hand end point is a regular point then you should set :math:x_2 = x_1 :math:\left(= a\right), while if it is a singular point you must set :math:x_2 > x_1.

Similarly :math:x_{{m-1}} = x_m (:math:\text{} = b) if the right-hand end point is regular, and :math:x_{{m-1}} < x_m if it is singular.

(#) The remaining :math:m-4 points :math:x_3,\ldots,x_{{m-2}}, if any, define 'break-points' which divide the interval :math:\left[x_2, x_{{m-1}}\right] into :math:m-3 sub-intervals

.. math::
i_1 = \left[x_2, x_3\right],\ldots,i_{{m-3}} = \left[x_{{m-2}}, x_{{m-1}}\right]\text{.}

Numerical integration of the differential equation is stopped and restarted at each break-point. In simple cases no break-points are needed. However, if :math:p\left(x\right) or :math:q\left(x;\lambda \right) are given by different formulae in different parts of the interval, integration is more efficient if the range is broken up by break-points in the appropriate way. Similarly points where any jumps occur in :math:p\left(x\right) or :math:q\left(x;\lambda \right), or in their derivatives up to the fifth-order, should appear as break-points.

Examples are given in Further Comments <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02kdf.html#fcomments>__. :math:\mathrm{xpoint} determines the position of the Shooting Matching Point (SMP), as explained in The Position of the Shooting Matching Point c <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02kdf.html#fcomments3>__.

**coeffn** : callable (p, q, dqdl) = coeffn(x, elam, jint, data=None)
:math:\mathrm{coeffn} must compute the values of the coefficient functions :math:p\left(x\right) and :math:q\left(x;\lambda \right) for given values of :math:x and :math:\lambda. :ref:Notes <d02kd-py2-py-notes> states the conditions which :math:p and :math:q must satisfy.

See Further Comments <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02kdf.html#fcomments4>__ for examples.

**Parameters**
**x** : float
The current value of :math:x.

**elam** : float
The current trial value of the eigenvalue argument :math:\lambda.

**jint** : int
The index :math:j of the sub-interval :math:i_j (see specification of :math:\mathrm{xpoint}) in which :math:x lies.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**p** : float
The value of :math:p\left(x\right) for the current value of :math:x.

**q** : float
The value of :math:q\left(x;\lambda \right) for the current value of :math:x and the current trial value of :math:\lambda.

**dqdl** : float
The value of :math:\frac{{\partial q}}{{\partial \lambda }}\left(x;\lambda \right) for the current value of :math:x and the current trial value of :math:\lambda. However :math:\mathrm{dqdl} is only used in error estimation and, in the rare cases where it may be difficult to evaluate, an approximation (say to within :math:20\%) will suffice.

**bdyval** : callable (yl, yr) = bdyval(xl, xr, elam, data=None)
:math:\mathrm{bdyval} must define the boundary conditions.

For each end point, :math:\mathrm{bdyval} must return (in :math:\mathrm{yl} or :math:\mathrm{yr}) values of :math:y\left(x\right) and :math:p\left(x\right)y^{\prime }\left(x\right) which are consistent with the boundary conditions at the end points; only the ratio of the values matters.

Here :math:x is a given point (:math:\mathrm{xl} or :math:\mathrm{xr}) equal to, or close to, the end point.

For a **regular** end point (:math:a, say), :math:x = a, a boundary condition of the form

.. math::
c_1y\left(a\right)+c_2y^{\prime }\left(a\right) = 0

can be handled by returning constant values in :math:\mathrm{yl}, e.g., :math:\mathrm{yl}[0] = c_2 and :math:\mathrm{yl}[1] = -c_1p\left(a\right).

For a **singular** end point however, :math:\mathrm{yl}[0] and :math:\mathrm{yl}[1] will in general be functions of :math:\mathrm{xl} and :math:\mathrm{elam}, and :math:\mathrm{yr}[0] and :math:\mathrm{yr}[1] functions of :math:\mathrm{xr} and :math:\mathrm{elam}, usually derived analytically from a power-series or asymptotic expansion.

Examples are given in Further Comments <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02kdf.html#fcomments5>__.

**Parameters**
**xl** : float
If :math:a is a regular end point of the system (so that :math:a = x_1 = x_2), :math:\mathrm{xl} contains :math:a. If :math:a is a singular point (so that :math:a\leq x_1 < x_2), :math:\mathrm{xl} contains a point :math:x such that :math:x_1 < x\leq x_2.

**xr** : float
If :math:b is a regular end point of the system (so that :math:x_{{m-1}} = x_m = b), :math:\mathrm{xr} contains :math:b. If :math:b is a singular point (so that :math:x_{{m-1}} < x_m\leq b), :math:\mathrm{xr} contains a point :math:x such that :math:x_{{m-1}}\leq x < x_m.

**elam** : float
The current trial value of :math:\lambda.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**yl** : float, array-like, shape :math:\left(3\right)
:math:\mathrm{yl}[0] and :math:\mathrm{yl}[1] should contain values of :math:y\left(x\right) and :math:p\left(x\right)y^{\prime }\left(x\right) respectively (not both zero) which are consistent with the boundary condition at the left-hand end point, given by :math:x = \mathrm{xl}. :math:\mathrm{yl}[2] should not be set.

**yr** : float, array-like, shape :math:\left(3\right)
:math:\mathrm{yr}[0] and :math:\mathrm{yr}[1] should contain values of :math:y\left(x\right) and :math:p\left(x\right)y^{\prime }\left(x\right) respectively (not both zero) which are consistent with the boundary condition at the right-hand end point, given by :math:x = \mathrm{xr}. :math:\mathrm{yr}[2] should not be set.

**k** : int
:math:k, the index of the required eigenvalue when the eigenvalues are ordered

.. math::
\lambda_0 < \lambda_1 < \lambda_2 < \cdots < \lambda_k < \cdots \text{.}

**tol** : float
The tolerance argument which determines the accuracy of the computed eigenvalue. The error estimate held in :math:\mathrm{delam} on exit satisfies the mixed absolute/relative error test

.. math::
\mathrm{delam}\leq \mathrm{tol}\times \mathrm{max}\left(1.0, \left\lvert \mathrm{elam}\right\rvert \right)\text{,}

where :math:\mathrm{elam} is the final estimate of the eigenvalue. :math:\mathrm{delam} is usually somewhat smaller than the right-hand side of (1) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02kdf.html#eqn1>__ but not several orders of magnitude smaller.

**elam** : float
An initial estimate of the eigenvalue :math:\tilde{\lambda }.

**delam** : float
An indication of the scale of the problem in the :math:\lambda-direction. :math:\mathrm{delam} holds the initial 'search step' (positive or negative). Its value is not critical, but the first two trial evaluations are made at :math:\mathrm{elam} and :math:\mathrm{elam}+\mathrm{delam}, so the function will work most efficiently if the eigenvalue lies between these values. A reasonable choice (if a closer bound is not known) is half the distance between adjacent eigenvalues in the neighbourhood of the one sought. In practice, there will often be a problem, similar to the one in hand but with known eigenvalues, which will help one to choose initial values for :math:\mathrm{elam} and :math:\mathrm{delam}.

If :math:\mathrm{delam} = 0.0 on entry, it is given the default value of :math:0.25\times \mathrm{max}\left(1.0, \left\lvert \mathrm{elam}\right\rvert \right).

**hmax** : float, array-like, shape :math:\left(2, m\right)
:math:\mathrm{hmax}[0,\textit{j}-1] should contain a maximum step size to be used by the differential equation code in the :math:\textit{j}\ th sub-interval :math:\textit{i}_{\textit{j}} (as described in the specification of argument :math:\mathrm{xpoint}), for :math:\textit{j} = 1,2,\ldots,m-3. If it is zero the function generates a maximum step size internally.

It is recommended that :math:\mathrm{hmax}[0,j-1] be set to zero unless the coefficient functions :math:p and :math:q have features (such as a narrow peak) within the :math:j\ th sub-interval that could be 'missed' if a long step were taken.

In such a case :math:\mathrm{hmax}[0,j-1] should be set to about half the distance over which the feature should be observed.

Too small a value will increase the computing time for the function.

See Further Comments <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02kdf.html#fcomments>__ for further suggestions.

The rest of the array is used as workspace.

**maxit** : int, optional
A bound on :math:n_r, the number of root-finding iterations allowed, that is the number of trial values of :math:\lambda that are used. If :math:\mathrm{maxit}\leq 0, no such bound is assumed. (See also :math:\mathrm{maxfun}.)

**maxfun** : int, optional
A bound on :math:n_f, the number of calls to :math:\mathrm{coeffn} made in any one root-finding iteration. If :math:\mathrm{maxfun}\leq 0, no such bound is assumed.

**monit** : None or callable monit(nit, iflag, elam, finfo, data=None), optional
Note: if this argument is **None** then a NAG-supplied facility will be used.

:math:\mathrm{monit} is called by sl2_breaks_vals at the end of each root-finding iteration and allows you to monitor the course of the computation by printing out the arguments.

**Parameters**
**nit** : int
The current value of the argument :math:\mathrm{maxit} of sl2_breaks_vals, this is decreased by one at each iteration.

**iflag** : int
Describes what phase the computation is in.

:math:\mathrm{iflag} < 0

An error occurred in the computation at this iteration; an error exit from sl2_breaks_vals with :math:\textit{errno} = -\mathrm{iflag} will follow.

:math:\mathrm{iflag} = 1

The function is trying to bracket the eigenvalue :math:\tilde{\lambda }.

:math:\mathrm{iflag} = 2

The function is converging to the eigenvalue :math:\tilde{\lambda } (having already bracketed it).

**elam** : float
The current trial value of :math:\lambda.

**finfo** : float, ndarray, shape :math:\left(15\right)
Information about the behaviour of the shooting method, and diagnostic information in the case of errors. It should not normally be printed in full if no error has occurred (that is, if :math:\mathrm{iflag} > 0), though the first few components may be of interest to you. In case of an error (:math:\mathrm{iflag} < 0) all the components of :math:\mathrm{finfo} should be printed.

The contents of :math:\mathrm{finfo} are as follows:

:math:\mathrm{finfo}[0]

The current value of the 'miss-distance' or 'residual' function :math:f\left(\lambda \right) on which the shooting method is based. (See Further Comments <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02kdf.html#fcomments2>__ for further information.) :math:\mathrm{finfo}[0] is set to zero if :math:\mathrm{iflag} < 0.

:math:\mathrm{finfo}[1]

An estimate of the quantity :math:\partial \lambda defined as follows. Consider the perturbation in the miss-distance :math:f\left(\lambda \right) that would result if the local error in the solution of the differential equation were always positive and equal to its maximum permitted value. Then :math:\partial \lambda is the perturbation in :math:\lambda that would have the same effect on :math:f\left(\lambda \right). Thus, at the zero of :math:f\left(\lambda \right),\left\lvert \partial \lambda \right\rvert is an approximate bound on the perturbation of the zero (that is the eigenvalue) caused by errors in numerical solution. If :math:\partial \lambda is very large then it is possible that there has been a programming error in :math:\mathrm{coeffn} such that :math:q is independent of :math:\lambda. If this is the case, an error exit with :math:\mathrm{errno} = 5 should follow. :math:\mathrm{finfo}[1] is set to zero if :math:\mathrm{iflag} < 0.

:math:\mathrm{finfo}[2]

The number of internal iterations, using the same value of :math:\lambda and tighter accuracy tolerances, needed to bring the accuracy (that is, the value of :math:\partial \lambda) to an acceptable value. Its value should normally be :math:1.0, and should almost never exceed :math:2.0.

:math:\mathrm{finfo}[3]

The number of calls to :math:\mathrm{coeffn} at this iteration.

:math:\mathrm{finfo}[4]

The number of successful steps taken by the internal differential equation solver at this iteration. A step is successful if it is used to advance the integration.

:math:\mathrm{finfo}[5]

The number of unsuccessful steps used by the internal integrator at this iteration.

:math:\mathrm{finfo}[6]

The number of successful steps at the maximum step size taken by the internal integrator at this iteration.

:math:\mathrm{finfo}[7]

Not used.

:math:\mathrm{finfo}[8] to :math:\mathrm{finfo}[14]

Set to zero, unless :math:\mathrm{iflag} < 0 in which case they hold the following values describing the point of failure:

:math:\mathrm{finfo}[8]

The index of the sub-interval where failure occurred, in the range :math:1 to :math:m-3. In case of an error in :math:\mathrm{bdyval}, it is set to :math:0 or :math:m-2 depending on whether the left or right boundary condition caused the error.

:math:\mathrm{finfo}[9]

The value of the independent variable, :math:x, the point at which the error occurred. In case of an error in :math:\mathrm{bdyval}, it is set to the value of :math:\mathrm{xl} or :math:\mathrm{xr} as appropriate (see the specification of :math:\mathrm{bdyval}).

:math:\mathrm{finfo}[10], :math:\mathrm{finfo}[11], :math:\mathrm{finfo}[12]

The current values of the Pruefer dependent variables :math:\beta, :math:\phi and :math:\rho respectively. These are set to zero in case of an error in :math:\mathrm{bdyval}. (See :meth:sl2_breaks_funs for a description of these variables.)

:math:\mathrm{finfo}[13]

The local-error tolerance being used by the internal integrator at the point of failure. This is set to zero in the case of an error in :math:\mathrm{bdyval}.

:math:\mathrm{finfo}[14]

The last integration mesh point. This is set to zero in the case of an error in :math:\mathrm{bdyval}.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**data** : arbitrary, optional
User-communication data for callback functions.

**Returns**
**elam** : float
The final computed estimate, whether or not an error occurred.

**delam** : float
If no exception or warning is raised, :math:\mathrm{delam} holds an estimate of the absolute error in the computed eigenvalue, that is :math:\left\lvert \tilde{\lambda }-\mathrm{elam}\right\rvert \simeq \mathrm{delam}. (In Further Comments <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02kdf.html#fcomments2>__ we discuss the assumptions under which this is true.) The true error is rarely more than twice, or less than a tenth, of the estimated error.

If an exception is raised, :math:\mathrm{delam} may hold an estimate of the error, or its initial value, depending on the value of :math:\textit{errno}.

See :ref:Exceptions <d02kd-py2-py-errors> for further details.

**hmax** : float, ndarray, shape :math:\left(2, m\right)
:math:\mathrm{hmax}[0,m-2] and :math:\mathrm{hmax}[0,m-1] contain the sensitivity coefficients :math:\sigma_l,\sigma_r, described in Further Comments <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02kdf.html#fcomments6>__. Other entries contain diagnostic output in the case of an error exit (see :ref:Exceptions <d02kd-py2-py-errors>).

**maxit** : int
Will have been decreased by the number of iterations actually performed, whether or not it was positive on entry.

.. _d02kd-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, the sequence of boundary and break points is not monotonic.

For :math:i = \langle\mathit{\boldsymbol{value}}\rangle, point :math:i-1 = \langle\mathit{\boldsymbol{value}}\rangle and point :math:i = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:m = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:m\geq 4.

(errno :math:1)
On entry, :math:\mathrm{tol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{tol} > 0.0.

(errno :math:1)
On entry, :math:\mathrm{k} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{k}\geq 0.

(errno :math:2)
The constraint on the specification of left- or right-hand boundary condition has been violated.

(errno :math:3)
The function :math:p\left(x\right) became zero or changed sign in the interval :math:\left[a, b\right].

(errno :math:6)
The last iteration was terminated because more than :math:\langle\mathit{\boldsymbol{value}}\rangle calls to evaluate :math:p, :math:q and its derivative were performed.

(errno :math:7)
Too small a step size was required at the start of a sub-interval to obtain the desired accuracy.

(errno :math:8)
Too small a step size was required during solution in a sub-interval to obtain the desired accuracy.

**Warns**
**NagAlgorithmicWarning**
(errno :math:4)
After :math:\langle\mathit{\boldsymbol{value}}\rangle iterations the eigenvalue had not been found to the required accuracy.

(errno :math:5)
The bracketing phase failed to bracket the eigenvalue within ten iterations. This may be due to an error in formulating the problem (for example, :math:q is independent of :math:\lambda), or by very poor initial estimates for the eigenvalue and search step.

(errno :math:9)
The tolerance set is too small for the problem being solved and the machine precision being used. The local eigenvalue estimate returned is likely to be a very good approximation.

(errno :math:10)
An internal error has occurred corresponding to a pole of the matching function. Try solving the problem again with a smaller tolerance.

.. _d02kd-py2-py-notes:

**Notes**
No equivalent traditional C interface for this routine exists in the NAG Library.

sl2_breaks_vals finds a specified eigenvalue :math:\tilde{\lambda } of a Sturm--Liouville system defined by a self-adjoint differential equation of the second-order

.. math::
\left(p\left(x\right)y^{\prime }\right)^{\prime }+q\left(x;\lambda \right)y = 0\text{, }\quad a < x < b\text{,}

together with appropriate boundary conditions at the two, finite or infinite, end points :math:a and :math:b.
The functions :math:p and :math:q, which are real-valued, are defined by :math:\mathrm{coeffn}.
The boundary conditions must be defined by :math:\mathrm{bdyval}, and, in the case of a singularity at :math:a or :math:b, take the form of an asymptotic formula for the solution near the relevant end point.

For the theoretical basis of the numerical method to be valid, the following conditions should hold on the coefficient functions:

(a) :math:p\left(x\right) must be nonzero and must not change sign throughout the interval :math:\left(a, b\right); and,

(#) :math:\frac{{\partial q}}{{\partial \lambda }} must not change sign throughout the interval :math:\left(a, b\right) for all relevant values of :math:\lambda, and must not be identically zero as :math:x varies, for any :math:\lambda.

Points of discontinuity in the functions :math:p and :math:q or their derivatives are allowed, and should be included as 'break-points' in the array :math:\mathrm{xpoint}.

The eigenvalue :math:\tilde{\lambda } is determined by a shooting method based on the Scaled Pruefer form of the differential equation as described in Pryce (1981), with certain modifications.
The Pruefer equations are integrated by a special internal function using Merson's Runge--Kutta formula with automatic control of local error.
Providing certain assumptions (see Timing <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02kdf.html#fcomments1>__) are met, the computed value of :math:\tilde{\lambda } will be correct to within a mixed absolute/relative error specified by :math:\mathrm{tol}.

A good account of the theory of Sturm--Liouville systems, with some description of Pruefer transformations, is given in Module X of Birkhoff and Rota (1962).
An introduction to the use of Pruefer transformations for the numerical solution of eigenvalue problems arising from physics and chemistry is given in Bailey (1966).

The scaled Pruefer method is described in a short note by Pryce and Hargrave (1977) and in some detail in the technical report by Pryce (1981).

.. _d02kd-py2-py-references:

**References**
Abramowitz, M and Stegun, I A, 1972, Handbook of Mathematical Functions, (3rd Edition), Dover Publications

Bailey, P B, 1966, Sturm--Liouville eigenvalues via a phase function, SIAM J. Appl. Math. (14), 242--249

Banks, D O and Kurowski, I, 1968, Computation of eigenvalues of singular Sturm--Liouville Systems, Math. Comput. (22), 304--310

Birkhoff, G and Rota, G C, 1962, Ordinary Differential Equations, Ginn & Co., Boston and New York

Pryce, J D, 1981, Two codes for Sturm--Liouville problems, Technical Report CS-81-01, Department of Computer Science, Bristol University

Pryce, J D and Hargrave, B A, 1977, The scaled Prüfer method for one-parameter and multi-parameter eigenvalue problems in ODEs, IMA Numerical Analysis Newsletter (1(3))
"""
raise NotImplementedError

[docs]def sl2_breaks_funs(xpoint, match, coeffn, bdyval, k, tol, elam, delam, hmax, report, maxit=0, maxfun=0, monit=None, data=None):
r"""
sl2_breaks_funs finds a specified eigenvalue of a regular or singular second-order Sturm--Liouville system on a finite or infinite interval, using a Pruefer transformation and a shooting method.
It also reports values of the eigenfunction and its derivatives.
Provision is made for discontinuities in the coefficient functions or their derivatives.

.. _d02ke-py2-py-doc:

For full information please refer to the NAG Library document for d02ke

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02kef.html

.. _d02ke-py2-py-parameters:

**Parameters**
**xpoint** : float, array-like, shape :math:\left(m\right)
The points where the boundary conditions computed by :math:\mathrm{bdyval} are to be imposed, and also any break-points, i.e., :math:\mathrm{xpoint}[0] to :math:\mathrm{xpoint}[m-1] must contain values :math:x_1,\ldots,x_m such that

.. math::
x_1\leq x_2 < x_3 < \cdots < x_{{m-1}}\leq x_m

with the following meanings:

(a) :math:x_1 and :math:x_m are the left- and right-hand end points, :math:a and :math:b, of the domain of definition of the Sturm--Liouville system if these are finite. If either :math:a or :math:b is infinite, the corresponding value :math:x_1 or :math:x_m may be a more-or-less arbitrarily 'large' number of appropriate sign.

(#) :math:x_2 and :math:x_{{m-1}} are the Boundary Matching Points (BMPs), that is the points at which the left and right boundary conditions computed in :math:\mathrm{bdyval} are imposed.

If the left-hand end point is a regular point then you should set :math:x_2 = x_1 :math:\left(= a\right), while if it is a singular point you must set :math:x_2 > x_1.

Similarly :math:x_{{m-1}} = x_m (:math:\text{} = b) if the right-hand end point is regular, and :math:x_{{m-1}} < x_m if it is singular.

(#) The remaining :math:m-4 points :math:x_3,\ldots,x_{{m-2}}, if any, define 'break-points' which divide the interval :math:\left[x_2, x_{{m-1}}\right] into :math:m-3 sub-intervals

.. math::
i_1 = \left[x_2, x_3\right],\ldots,i_{{m-3}} = \left[x_{{m-2}}, x_{{m-1}}\right]\text{.}

Numerical integration of the differential equation is stopped and restarted at each break-point. In simple cases no break-points are needed. However, if :math:p\left(x\right) or :math:q\left(x;\lambda \right) are given by different formulae in different parts of the interval, integration is more efficient if the range is broken up by break-points in the appropriate way. Similarly points where any jumps occur in :math:p\left(x\right) or :math:q\left(x;\lambda \right), or in their derivatives up to the fifth-order, should appear as break-points.

Examples are given in Further Comments <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02kef.html#fcomments>__. :math:\mathrm{xpoint} determines the position of the Shooting Matching Point (SMP), as explained in The Position of the Shooting Matching Point c <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02kef.html#fcomments3>__.

**match** : int
Must be set to the index of the 'break-point' to be used as the matching point (see The Position of the Shooting Matching Point c <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02kef.html#fcomments3>__). If :math:\mathrm{match} is set to a value outside the range :math:\left[2, {m-1}\right] then a default value is taken, corresponding to the break-point nearest the centre of the interval :math:\left[{\mathrm{xpoint}[1]}, {\mathrm{xpoint}[m-1]}\right].

**coeffn** : callable (p, q, dqdl) = coeffn(x, elam, jint, data=None)
:math:\mathrm{coeffn} must compute the values of the coefficient functions :math:p\left(x\right) and :math:q\left(x;\lambda \right) for given values of :math:x and :math:\lambda. :ref:Notes <d02ke-py2-py-notes> states the conditions which :math:p and :math:q must satisfy.

See Further Comments <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02kef.html#fcomments4>__ for examples.

**Parameters**
**x** : float
The current value of :math:x.

**elam** : float
The current trial value of the eigenvalue argument :math:\lambda.

**jint** : int
The index :math:j of the sub-interval :math:i_j (see specification of :math:\mathrm{xpoint}) in which :math:x lies.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**p** : float
The value of :math:p\left(x\right) for the current value of :math:x.

**q** : float
The value of :math:q\left(x;\lambda \right) for the current value of :math:x and the current trial value of :math:\lambda.

**dqdl** : float
The value of :math:\frac{{\partial q}}{{\partial \lambda }}\left(x;\lambda \right) for the current value of :math:x and the current trial value of :math:\lambda. However :math:\mathrm{dqdl} is only used in error estimation and, in the rare cases where it may be difficult to evaluate, an approximation (say to within :math:20\%) will suffice.

**bdyval** : callable (yl, yr) = bdyval(xl, xr, elam, data=None)
:math:\mathrm{bdyval} must define the boundary conditions.

For each end point, :math:\mathrm{bdyval} must return (in :math:\mathrm{yl} or :math:\mathrm{yr}) values of :math:y\left(x\right) and :math:p\left(x\right)y^{\prime }\left(x\right) which are consistent with the boundary conditions at the end points; only the ratio of the values matters.

Here :math:x is a given point (:math:\mathrm{xl} or :math:\mathrm{xr}) equal to, or close to, the end point.

For a **regular** end point (:math:a, say), :math:x = a, a boundary condition of the form

.. math::
c_1y\left(a\right)+c_2y^{\prime }\left(a\right) = 0

can be handled by returning constant values in :math:\mathrm{yl}, e.g., :math:\mathrm{yl}[0] = c_2 and :math:\mathrm{yl}[1] = -c_1p\left(a\right).

For a **singular** end point however, :math:\mathrm{yl}[0] and :math:\mathrm{yl}[1] will in general be functions of :math:\mathrm{xl} and :math:\mathrm{elam}, and :math:\mathrm{yr}[0] and :math:\mathrm{yr}[1] functions of :math:\mathrm{xr} and :math:\mathrm{elam}, usually derived analytically from a power-series or asymptotic expansion.

Examples are given in Further Comments <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02kef.html#fcomments5>__.

**Parameters**
**xl** : float
If :math:a is a regular end point of the system (so that :math:a = x_1 = x_2), :math:\mathrm{xl} contains :math:a. If :math:a is a singular point (so that :math:a\leq x_1 < x_2), :math:\mathrm{xl} contains a point :math:x such that :math:x_1 < x\leq x_2.

**xr** : float
If :math:b is a regular end point of the system (so that :math:x_{{m-1}} = x_m = b), :math:\mathrm{xr} contains :math:b. If :math:b is a singular point (so that :math:x_{{m-1}} < x_m\leq b), :math:\mathrm{xr} contains a point :math:x such that :math:x_{{m-1}}\leq x < x_m.

**elam** : float
The current trial value of :math:\lambda.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**yl** : float, array-like, shape :math:\left(3\right)
:math:\mathrm{yl}[0] and :math:\mathrm{yl}[1] should contain values of :math:y\left(x\right) and :math:p\left(x\right)y^{\prime }\left(x\right) respectively (not both zero) which are consistent with the boundary condition at the left-hand end point, given by :math:x = \mathrm{xl}. :math:\mathrm{yl}[2] should not be set.

**yr** : float, array-like, shape :math:\left(3\right)
:math:\mathrm{yr}[0] and :math:\mathrm{yr}[1] should contain values of :math:y\left(x\right) and :math:p\left(x\right)y^{\prime }\left(x\right) respectively (not both zero) which are consistent with the boundary condition at the right-hand end point, given by :math:x = \mathrm{xr}. :math:\mathrm{yr}[2] should not be set.

**k** : int
:math:k, the index of the required eigenvalue when the eigenvalues are ordered

.. math::
\lambda_0 < \lambda_1 < \lambda_2 < \cdots < \lambda_k < \cdots \text{.}

**tol** : float
The tolerance argument which determines the accuracy of the computed eigenvalue. The error estimate held in :math:\mathrm{delam} on exit satisfies the mixed absolute/relative error test

.. math::
\mathrm{delam}\leq \mathrm{tol}\times \mathrm{max}\left(1.0, \left\lvert \mathrm{elam}\right\rvert \right)\text{,}

where :math:\mathrm{elam} is the final estimate of the eigenvalue. :math:\mathrm{delam} is usually somewhat smaller than the right-hand side of (1) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02kef.html#eqn1>__ but not several orders of magnitude smaller.

**elam** : float
An initial estimate of the eigenvalue :math:\tilde{\lambda }.

**delam** : float
An indication of the scale of the problem in the :math:\lambda-direction. :math:\mathrm{delam} holds the initial 'search step' (positive or negative). Its value is not critical, but the first two trial evaluations are made at :math:\mathrm{elam} and :math:\mathrm{elam}+\mathrm{delam}, so the function will work most efficiently if the eigenvalue lies between these values. A reasonable choice (if a closer bound is not known) is half the distance between adjacent eigenvalues in the neighbourhood of the one sought. In practice, there will often be a problem, similar to the one in hand but with known eigenvalues, which will help one to choose initial values for :math:\mathrm{elam} and :math:\mathrm{delam}.

If :math:\mathrm{delam} = 0.0 on entry, it is given the default value of :math:0.25\times \mathrm{max}\left(1.0, \left\lvert \mathrm{elam}\right\rvert \right).

**hmax** : float, array-like, shape :math:\left(2, m\right)
:math:\mathrm{hmax}[0,\textit{j}-1] should contain a maximum step size to be used by the differential equation code in the :math:\textit{j}\ th sub-interval :math:\textit{i}_{\textit{j}} (as described in the specification of argument :math:\mathrm{xpoint}), for :math:\textit{j} = 1,2,\ldots,m-3. If it is zero the function generates a maximum step size internally.

It is recommended that :math:\mathrm{hmax}[0,j-1] be set to zero unless the coefficient functions :math:p and :math:q have features (such as a narrow peak) within the :math:j\ th sub-interval that could be 'missed' if a long step were taken.

In such a case :math:\mathrm{hmax}[0,j-1] should be set to about half the distance over which the feature should be observed.

Too small a value will increase the computing time for the function.

See Further Comments <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02kef.html#fcomments>__ for further suggestions.

The rest of the array is used as workspace.

**report** : callable report(x, v, jint, data=None)
:math:\mathrm{report} provides the means by which you may compute the eigenfunction :math:y\left(x\right) and its derivative at each integration mesh point :math:x. (See Further Comments <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02kef.html#fcomments>__ for an example.)

**Parameters**
**x** : float
The current value of the independent variable :math:x. See The Position of the Shooting Matching Point c <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02kef.html#fcomments3>__ for the order in which values of :math:x are supplied.

**v** : float, ndarray, shape :math:\left(3\right)
:math:\mathrm{v}[0], :math:\mathrm{v}[1], :math:\mathrm{v}[2] hold the current values of the Pruefer variables :math:\beta, :math:\phi, :math:\rho respectively.

**jint** : int
Indicates the sub-interval between break-points in which :math:\mathrm{x} lies exactly as for :math:\mathrm{coeffn}, **except** that at the extreme left-hand end point (when :math:x = \mathrm{xpoint}[1]) :math:\mathrm{jint} is set to :math:0 and at the extreme right-hand end point (when :math:x = x_r = \mathrm{xpoint}[m-1]) :math:\mathrm{jint} is set to :math:m-2.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**maxit** : int, optional
A bound on :math:n_r, the number of root-finding iterations allowed, that is the number of trial values of :math:\lambda that are used. If :math:\mathrm{maxit}\leq 0, no such bound is assumed. (See also :math:\mathrm{maxfun}.)

**maxfun** : int, optional
A bound on :math:n_f, the number of calls to :math:\mathrm{coeffn} made in any one root-finding iteration. If :math:\mathrm{maxfun}\leq 0, no such bound is assumed.

**monit** : None or callable monit(nit, iflag, elam, finfo, data=None), optional
Note: if this argument is **None** then a NAG-supplied facility will be used.

:math:\mathrm{monit} is called by sl2_breaks_funs at the end of each root-finding iteration and allows you to monitor the course of the computation by printing out the arguments.

**Parameters**
**nit** : int
The current value of the argument :math:\mathrm{maxit} of sl2_breaks_funs, this is decreased by one at each iteration.

**iflag** : int
Describes what phase the computation is in.

:math:\mathrm{iflag} < 0

An error occurred in the computation at this iteration; an error exit from sl2_breaks_funs with :math:\textit{errno} = -\mathrm{iflag} will follow.

:math:\mathrm{iflag} = 1

The function is trying to bracket the eigenvalue :math:\tilde{\lambda }.

:math:\mathrm{iflag} = 2

The function is converging to the eigenvalue :math:\tilde{\lambda } (having already bracketed it).

**elam** : float
The current trial value of :math:\lambda.

**finfo** : float, ndarray, shape :math:\left(15\right)
Information about the behaviour of the shooting method, and diagnostic information in the case of errors. It should not normally be printed in full if no error has occurred (that is, if :math:\mathrm{iflag} > 0), though the first few components may be of interest to you. In case of an error (:math:\mathrm{iflag} < 0) all the components of :math:\mathrm{finfo} should be printed.

The contents of :math:\mathrm{finfo} are as follows:

:math:\mathrm{finfo}[0]

The current value of the 'miss-distance' or 'residual' function :math:f\left(\lambda \right) on which the shooting method is based. (See Further Comments <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02kef.html#fcomments2>__ for further information.) :math:\mathrm{finfo}[0] is set to zero if :math:\mathrm{iflag} < 0.

:math:\mathrm{finfo}[1]

An estimate of the quantity :math:\partial \lambda defined as follows. Consider the perturbation in the miss-distance :math:f\left(\lambda \right) that would result if the local error in the solution of the differential equation were always positive and equal to its maximum permitted value. Then :math:\partial \lambda is the perturbation in :math:\lambda that would have the same effect on :math:f\left(\lambda \right). Thus, at the zero of :math:f\left(\lambda \right),\left\lvert \partial \lambda \right\rvert is an approximate bound on the perturbation of the zero (that is the eigenvalue) caused by errors in numerical solution. If :math:\partial \lambda is very large then it is possible that there has been a programming error in :math:\mathrm{coeffn} such that :math:q is independent of :math:\lambda. If this is the case, an error exit with :math:\mathrm{errno} = 5 should follow. :math:\mathrm{finfo}[1] is set to zero if :math:\mathrm{iflag} < 0.

:math:\mathrm{finfo}[2]

The number of internal iterations, using the same value of :math:\lambda and tighter accuracy tolerances, needed to bring the accuracy (that is, the value of :math:\partial \lambda) to an acceptable value. Its value should normally be :math:1.0, and should almost never exceed :math:2.0.

:math:\mathrm{finfo}[3]

The number of calls to :math:\mathrm{coeffn} at this iteration.

:math:\mathrm{finfo}[4]

The number of successful steps taken by the internal differential equation solver at this iteration. A step is successful if it is used to advance the integration.

:math:\mathrm{finfo}[5]

The number of unsuccessful steps used by the internal integrator at this iteration.

:math:\mathrm{finfo}[6]

The number of successful steps at the maximum step size taken by the internal integrator at this iteration.

:math:\mathrm{finfo}[7]

Not used.

:math:\mathrm{finfo}[8] to :math:\mathrm{finfo}[14]

Set to zero, unless :math:\mathrm{iflag} < 0 in which case they hold the following values describing the point of failure:

:math:\mathrm{finfo}[8]

The index of the sub-interval where failure occurred, in the range :math:1 to :math:m-3. In case of an error in :math:\mathrm{bdyval}, it is set to :math:0 or :math:m-2 depending on whether the left or right boundary condition caused the error.

:math:\mathrm{finfo}[9]

The value of the independent variable, :math:x, the point at which the error occurred. In case of an error in :math:\mathrm{bdyval}, it is set to the value of :math:\mathrm{xl} or :math:\mathrm{xr} as appropriate (see the specification of :math:\mathrm{bdyval}).

:math:\mathrm{finfo}[10], :math:\mathrm{finfo}[11], :math:\mathrm{finfo}[12]

The current values of the Pruefer dependent variables :math:\beta, :math:\phi and :math:\rho respectively. These are set to zero in case of an error in :math:\mathrm{bdyval}.

:math:\mathrm{finfo}[13]

The local-error tolerance being used by the internal integrator at the point of failure. This is set to zero in the case of an error in :math:\mathrm{bdyval}.

:math:\mathrm{finfo}[14]

The last integration mesh point. This is set to zero in the case of an error in :math:\mathrm{bdyval}.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**data** : arbitrary, optional
User-communication data for callback functions.

**Returns**
**match** : int
The index of the break-point actually used as the matching point.

**elam** : float
The final computed estimate, whether or not an error occurred.

**delam** : float
If no exception or warning is raised, :math:\mathrm{delam} holds an estimate of the absolute error in the computed eigenvalue, that is :math:\left\lvert \tilde{\lambda }-\mathrm{elam}\right\rvert \simeq \mathrm{delam}. (In Further Comments <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02kef.html#fcomments2>__ we discuss the assumptions under which this is true.) The true error is rarely more than twice, or less than a tenth, of the estimated error.

If an exception is raised, :math:\mathrm{delam} may hold an estimate of the error, or its initial value, depending on the value of :math:\textit{errno}.

See :ref:Exceptions <d02ke-py2-py-errors> for further details.

**hmax** : float, ndarray, shape :math:\left(2, m\right)
:math:\mathrm{hmax}[0,m-2] and :math:\mathrm{hmax}[0,m-1] contain the sensitivity coefficients :math:\sigma_l,\sigma_r, described in Further Comments <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02kef.html#fcomments6>__. Other entries contain diagnostic output in the case of an error exit (see :ref:Exceptions <d02ke-py2-py-errors>).

**maxit** : int
Will have been decreased by the number of iterations actually performed, whether or not it was positive on entry.

.. _d02ke-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:m = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:m\geq 4.

(errno :math:1)
On entry, :math:\mathrm{tol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{tol} > 0.0.

(errno :math:1)
On entry, :math:\mathrm{k} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{k}\geq 0.

(errno :math:2)
On entry, the sequence of boundary and break points is not monotonic.

For :math:i = \langle\mathit{\boldsymbol{value}}\rangle, point :math:i-1 = \langle\mathit{\boldsymbol{value}}\rangle and point :math:i = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:2)
The constraint on the specification of left- or right-hand boundary condition has been violated.

(errno :math:3)
The function :math:p\left(x\right) became zero or changed sign in the interval :math:\left[a, b\right].

(errno :math:4)
After :math:\langle\mathit{\boldsymbol{value}}\rangle iterations the eigenvalue had not been found to the required accuracy.

(errno :math:5)
The bracketing phase failed to bracket the eigenvalue within ten iterations. This may be due to an error in formulating the problem (for example, :math:q is independent of :math:\lambda), or by very poor initial estimates for the eigenvalue and search step.

(errno :math:6)
The last iteration was terminated because more than :math:\langle\mathit{\boldsymbol{value}}\rangle calls to evaluate :math:p, :math:q and its derivative were performed.

(errno :math:7)
Too small a step size was required at the start of a sub-interval to obtain the desired accuracy.

(errno :math:8)
Too small a step size was required during solution in a sub-interval to obtain the desired accuracy.

(errno :math:10)
An internal error has occurred corresponding to a pole of the matching function. Try solving the problem again with a smaller tolerance.

**Warns**
**NagAlgorithmicWarning**
(errno :math:9)
The tolerance set is too small for the problem being solved and the machine precision being used. The local eigenvalue estimate returned is likely to be a very good approximation.

.. _d02ke-py2-py-notes:

**Notes**
No equivalent traditional C interface for this routine exists in the NAG Library.

sl2_breaks_funs has essentially the same purpose as :meth:sl2_breaks_vals with minor modifications to enable values of the eigenfunction to be obtained after convergence to the eigenvalue has been achieved.

It first finds a specified eigenvalue :math:\tilde{\lambda } of a Sturm--Liouville system defined by a self-adjoint differential equation of the second-order

.. math::
\left(p\left(x\right)y^{\prime }\right)^{\prime }+q\left(x;\lambda \right)y = 0\text{, }\quad a < x < b\text{,}

together with appropriate boundary conditions at the two, finite or infinite, end points :math:a and :math:b.
The functions :math:p and :math:q, which are real-valued, are defined by :math:\mathrm{coeffn}.
The boundary conditions must be defined by :math:\mathrm{bdyval}, and, in the case of a singularity at :math:a or :math:b, take the form of an asymptotic formula for the solution near the relevant end point.

When the final estimate :math:\lambda = \tilde{\lambda } of the eigenvalue has been found, the function integrates the differential equation once more with that value of :math:\lambda, and with initial conditions chosen so that the integral

.. math::
S = \int_a^by\left(x\right)^2\frac{{\partial q}}{{\partial \lambda }}\left(x;\lambda \right){dx}

is approximately one.
When :math:q\left(x;\lambda \right) is of the form :math:\lambda w\left(x\right)+q\left(x\right), which is the most common case, :math:S represents the square of the norm of :math:y induced by the inner product

.. math::
\left\langle f, g\right\rangle = \int_a^bf\left(x\right)g\left(x\right)w\left(x\right){dx}\text{,}

with respect to which the eigenfunctions are mutually orthogonal.
This normalization of :math:y is only approximate, but experience shows that :math:S generally differs from unity by only one or two per cent.

During this final integration the :math:\mathrm{report} is called at each integration mesh point :math:x.
Sufficient information is returned to permit you to compute :math:y\left(x\right) and :math:y^{\prime }\left(x\right) for printing or plotting.
For reasons described in Further Comments <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02kef.html#fcomments2>__, sl2_breaks_funs passes across to :math:\mathrm{report}, not :math:y and :math:y^{\prime }, but the Pruefer variables :math:\beta, :math:\phi and :math:\rho on which the numerical method is based.
Their relationship to :math:y and :math:y^{\prime } is given by the equations

.. math::
p\left(x\right)y^{\prime } = \sqrt{\beta }\mathrm{exp}\left(\frac{\rho }{2}\right)\cos\left(\frac{\phi }{2}\right)\text{, }\quad y = \frac{1}{\sqrt{\beta }}\mathrm{exp}\left(\frac{\rho }{2}\right)\sin\left(\frac{\phi }{2}\right)\text{.}

For the theoretical basis of the numerical method to be valid, the following conditions should hold on the coefficient functions:

(a) :math:p\left(x\right) must be nonzero and must not change sign throughout the interval :math:\left(a, b\right); and,

(#) :math:\frac{{\partial q}}{{\partial \lambda }} must not change sign throughout the interval :math:\left(a, b\right) for all relevant values of :math:\lambda, and must not be identically zero as :math:x varies, for any :math:\lambda.

Points of discontinuity in the functions :math:p and :math:q or their derivatives are allowed, and should be included as 'break-points' in the array :math:\mathrm{xpoint}.

A good account of the theory of Sturm--Liouville systems, with some description of Pruefer transformations, is given in Module X of Birkhoff and Rota (1962).
An introduction to the use of Pruefer transformations for the numerical solution of eigenvalue problems arising from physics and chemistry is given in Bailey (1966).

The scaled Pruefer method is described in a short note by Pryce and Hargrave (1977) and in some detail in the technical report by Pryce (1981).

.. _d02ke-py2-py-references:

**References**
Abramowitz, M and Stegun, I A, 1972, Handbook of Mathematical Functions, (3rd Edition), Dover Publications

Bailey, P B, 1966, Sturm--Liouville eigenvalues via a phase function, SIAM J. Appl. Math. (14), 242--249

Banks, D O and Kurowski, I, 1968, Computation of eigenvalues of singular Sturm--Liouville Systems, Math. Comput. (22), 304--310

Birkhoff, G and Rota, G C, 1962, Ordinary Differential Equations, Ginn & Co., Boston and New York

Pryce, J D, 1981, Two codes for Sturm--Liouville problems, Technical Report CS-81-01, Department of Computer Science, Bristol University

Pryce, J D and Hargrave, B A, 1977, The scaled Prüfer method for one-parameter and multi-parameter eigenvalue problems in ODEs, IMA Numerical Analysis Newsletter (1(3))
"""
raise NotImplementedError

[docs]def ivp_2nd_rkn(fcn, t, tend, y, yp, ydp, comm, data=None):
r"""
ivp_2nd_rkn is a function for integrating a non-stiff system of second-order ordinary differential equations using Runge--Kutta--Nystrom techniques.

.. _d02la-py2-py-doc:

For full information please refer to the NAG Library document for d02la

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02laf.html

.. _d02la-py2-py-parameters:

**Parameters**
**fcn** : callable f = fcn(t, y, data=None)
:math:\mathrm{fcn} must evaluate the functions :math:f_i (that is the second derivatives :math:y_i^{{\prime \prime }}) for given values of its arguments :math:x, :math:y_1,y_2,\ldots,y_{\textit{neq}}.

**Parameters**
**t** : float
:math:x, the value of the argument.

**y** : float, ndarray, shape :math:\left(\textit{neq}\right)
:math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{neq}, the value of the argument.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**f** : float, array-like, shape :math:\left(\textit{neq}\right)
The value of :math:f_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{neq}.

**t** : float
The initial value of the independent variable :math:x.

**tend** : float
The end point of the range of integration. If :math:\mathrm{tend} < \mathrm{t} on initial entry, integration will proceed in the negative direction. :math:\mathrm{tend} may be reset, in the direction of integration, before any continuation call.

**y** : float, array-like, shape :math:\left(\textit{neq}\right)
The initial values of the solution :math:y_1,y_2,\ldots,y_{\textit{neq}}.

**yp** : float, array-like, shape :math:\left(\textit{neq}\right)
The initial values of the derivatives :math:y_1^{\prime },y_2^{\prime },\ldots,y_{\textit{neq}}^{\prime }.

**ydp** : float, array-like, shape :math:\left(\textit{neq}\right)
Must be unchanged from a previous call to ivp_2nd_rkn.

**comm** : dict, communication object, modified in place
Communication structure.

This argument must have been initialized by a prior call to :meth:ivp_2nd_rkn_setup.

**data** : arbitrary, optional
User-communication data for callback functions.

**Returns**
**t** : float
The value of the independent variable, which is usually :math:\mathrm{tend}, unless an error has occurred or the code is operating in one-step mode. If the integration is to be continued, possibly with a new value for :math:\mathrm{tend}, :math:\mathrm{t} must not be changed.

**y** : float, ndarray, shape :math:\left(\textit{neq}\right)
The computed values of the solution at the exit value of :math:\mathrm{t}. If the integration is to be continued, possibly with a new value for :math:\mathrm{tend}, these values must not be changed.

**yp** : float, ndarray, shape :math:\left(\textit{neq}\right)
The computed values of the derivatives at the exit value of :math:\mathrm{t}. If the integration is to be continued, possibly with a new value for :math:\mathrm{tend}, these values must not be changed.

**ydp** : float, ndarray, shape :math:\left(\textit{neq}\right)
The computed values of the second derivative at the exit value of :math:\mathrm{t}, unless illegal input is detected, in which case the elements of :math:\mathrm{ydp} may not have been initialized. If the integration is to be continued, possibly with a new value for :math:\mathrm{tend}, these values must not be changed.

.. _d02la-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:\textit{neq} = \langle\mathit{\boldsymbol{value}}\rangle, but in the previous call to the setup function :math:{\textit{neq}} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
The previous call to the setup function resulted in the error exit :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
The setup function :meth:ivp_2nd_rkn_setup has not been called.

(errno :math:1)
:math:\mathrm{tend} has been reset such that the direction of integration is reversed.

(errno :math:3)
To satisfy the accuracy requirements the step size, :math:\langle\mathit{\boldsymbol{value}}\rangle, at :math:\mathrm{t} = \langle\mathit{\boldsymbol{value}}\rangle, is too small for the machine precision.

(errno :math:4)
Two successive errors detected at the current value of :math:\mathrm{t} = \langle\mathit{\boldsymbol{value}}\rangle.

**Warns**
**NagAlgorithmicWarning**
(errno :math:1)
On entry, :math:\mathrm{t} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{tend} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{t}\neq \mathrm{tend}.

(errno :math:2)
The maximum number of steps, :math:\langle\mathit{\boldsymbol{value}}\rangle, has been attempted.

(errno :math:5)
Inefficiency detected in integrating exactly to values of :math:\mathrm{tend}.

.. _d02la-py2-py-notes:

**Notes**
No equivalent traditional C interface for this routine exists in the NAG Library.

Given the initial values :math:x,y_1,y_2,\ldots,y_{\textit{neq}},y_1^{\prime },y_2^{\prime },\ldots,y_{\textit{neq}}^{\prime } ivp_2nd_rkn integrates a non-stiff system of second-order differential equations of the type

.. math::
y_i^{{\prime \prime }} = f_i\left(x, y_1, y_2, \ldots, y_{\textit{neq}}\right)\text{, }\quad i = 1,2,\ldots,\textit{neq}\text{,}

from :math:x = \mathrm{t} to :math:x = \mathrm{tend} using a Runge--Kutta--Nystrom formula pair.
The system is defined by :math:\mathrm{fcn}, which evaluates :math:f_i in terms of :math:x and :math:y_1,y_2,\ldots,y_{\textit{neq}}, where :math:y_1,y_2,\ldots,y_{\textit{neq}} are supplied at :math:x.

There are two Runge--Kutta--Nystrom formula pairs implemented in this function.
The lower order method is intended if you have moderate accuracy requirements and may be used in conjunction with the interpolation function :meth:ivp_2nd_rkn_interp to produce solutions and derivatives at user-specified points.
The higher order method is intended if you have high accuracy requirements.

In one-step mode the function returns approximations to the solution, derivative and :math:f_i at each integration point.
In interval mode these values are returned at the end of the integration range.
You select the order of the method, the mode of operation, the error control and various optional inputs by a prior call to :meth:ivp_2nd_rkn_setup.

For a description of the Runge--Kutta--Nystrom formula pairs see Dormand et al. (1986a) and Dormand et al. (1986b) and for a description of their practical implementation see Brankin et al. (1989).

.. _d02la-py2-py-references:

**References**
Brankin, R W, Dormand, J R, Gladwell, I, Prince, P J and Seward, W L, 1989, Algorithm 670: A Runge--Kutta--Nystrom Code, ACM Trans. Math. Software (15), 31--40

Dormand, J R, El--Mikkawy, M E A and Prince, P J, 1986, Families of Runge--Kutta--Nystrom formulae, Mathematical Report TPMR 86-1, Teesside Polytechnic

Dormand, J R, El--Mikkawy, M E A and Prince, P J, 1986, High order embedded Runge--Kutta--Nystrom formulae, Mathematical Report TPMR 86-2, Teesside Polytechnic
"""
raise NotImplementedError

[docs]def ivp_2nd_rkn_setup(h, tol, thres, thresp, maxstp, start, onestp, high, comm):
r"""
ivp_2nd_rkn_setup is a setup function which must be called prior to the first call of the integrator :meth:ivp_2nd_rkn and may be called prior to any continuation call to :meth:ivp_2nd_rkn.

.. _d02lx-py2-py-doc:

For full information please refer to the NAG Library document for d02lx

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02lxf.html

.. _d02lx-py2-py-parameters:

**Parameters**
**h** : float
If :math:\mathrm{start} = \mathbf{True}, :math:\mathrm{h} may specify an initial step size to be attempted in :meth:ivp_2nd_rkn.

If :math:\mathrm{start} = \mathbf{False}, :math:\mathrm{h} may specify a step size to override the choice of next step attempted made internally to :meth:ivp_2nd_rkn.

The sign of :math:\mathrm{h} is not important, as the absolute value of :math:\mathrm{h} is chosen and the appropriate sign is selected by :meth:ivp_2nd_rkn.

If this option is not required then you must set :math:\mathrm{h} = 0.0.

**tol** : float
Must be set to a relative tolerance for controlling the error in the integration by :meth:ivp_2nd_rkn. :meth:ivp_2nd_rkn has been designed so that, for most problems, a reduction in :math:\mathrm{tol} leads to an approximately proportional reduction in the error in the solution. However the actual relation between :math:\mathrm{tol} and the accuracy of the solution cannot be guaranteed. You are strongly recommended to repeat the integration with a smaller value of :math:\mathrm{tol} and compare the results. See the description of :math:\mathrm{thres} and :math:\mathrm{thresp} for further details of how :math:\mathrm{tol} is used.

**thres** : float, array-like, shape :math:\left(\textit{neq}\right)
:math:\mathrm{thres} and :math:\mathrm{thresp} may be set to thresholds for use in the error control of :meth:ivp_2nd_rkn. At each step in the numerical integration estimates of the local errors :math:\mathrm{E1}\left(\textit{i}\right) and :math:\mathrm{E2}\left(\textit{i}\right) in the solution, :math:y_{\textit{i}}, and its derivative, :math:y_{\textit{i}}^{\prime }, respectively are computed, for :math:\textit{i} = 1,2,\ldots,\textit{neq}. For the step to be accepted conditions of the following type must be satisfied:

.. math::
\begin{array}{l}\mathrm{max}_{{1\leq i\leq \textit{neq}}} \left(\frac{{\mathrm{E1}\left(i\right)}}{{\mathrm{max}\left(\mathrm{thres}[i-1], \left\lvert y_i\right\rvert \right)}}\right) \leq \mathrm{tol}\text{,}\\\\\\\mathrm{max}_{{1\leq i\leq \textit{neq}}} \left(\frac{{\mathrm{E2}\left(i\right)}}{{\mathrm{max}\left(\mathrm{thresp}[i-1], \left\lvert y_i^{\prime }\right\rvert \right)}}\right) \leq \mathrm{tol}\text{.}\end{array}

If one or both of these is not satisfied then the step size is reduced and the solution is recomputed.

If :math:\mathrm{thres}[0]\leq 0.0 on entry, a value of :math:50.0\times \epsilon is used for :math:\mathrm{thres}[\textit{i}-1], for :math:\textit{i} = 1,2,\ldots,\textit{neq}, where :math:\epsilon is machine precision.

Similarly for :math:\mathrm{thresp}.

**thresp** : float, array-like, shape :math:\left(\textit{neq}\right)
:math:\mathrm{thresp} and :math:\mathrm{thresp} may be set to thresholds for use in the error control of :meth:ivp_2nd_rkn. At each step in the numerical integration estimates of the local errors :math:\mathrm{E1}\left(\textit{i}\right) and :math:\mathrm{E2}\left(\textit{i}\right) in the solution, :math:y_{\textit{i}}, and its derivative, :math:y_{\textit{i}}^{\prime }, respectively are computed, for :math:\textit{i} = 1,2,\ldots,\textit{neq}. For the step to be accepted conditions of the following type must be satisfied:

.. math::
\begin{array}{l}\mathrm{max}_{{1\leq i\leq \textit{neq}}} \left(\frac{{\mathrm{E1}\left(i\right)}}{{\mathrm{max}\left(\mathrm{thres}[i-1], \left\lvert y_i\right\rvert \right)}}\right) \leq \mathrm{tol}\text{,}\\\\\\\mathrm{max}_{{1\leq i\leq \textit{neq}}} \left(\frac{{\mathrm{E2}\left(i\right)}}{{\mathrm{max}\left(\mathrm{thresp}[i-1], \left\lvert y_i^{\prime }\right\rvert \right)}}\right) \leq \mathrm{tol}\text{.}\end{array}

If one or both of these is not satisfied then the step size is reduced and the solution is recomputed.

If :math:\mathrm{thres}[0]\leq 0.0 on entry, a value of :math:50.0\times \epsilon is used for :math:\mathrm{thres}[\textit{i}-1], for :math:\textit{i} = 1,2,\ldots,\textit{neq}, where :math:\epsilon is machine precision.

Similarly for :math:\mathrm{thresp}.

**maxstp** : int
A bound on the number of steps attempted in any one call of :meth:ivp_2nd_rkn.

If :math:\mathrm{maxstp}\leq 0 on entry, a value of :math:1000 is used.

**start** : bool
Specifies whether or not the call of :meth:ivp_2nd_rkn is for a new problem. :math:\mathrm{start} = \mathbf{True} indicates that a new problem is to be solved. :math:\mathrm{start} = \mathbf{False} indicates the call of ivp_2nd_rkn_setup is prior to a continuation call of :meth:ivp_2nd_rkn.

**onestp** : bool
The mode of operation for :meth:ivp_2nd_rkn.

:math:\mathrm{onestp} = \mathbf{True}

:meth:ivp_2nd_rkn will operate in one-step mode, that is it will return after each successful step.

:math:\mathrm{onestp} = \mathbf{False}

:meth:ivp_2nd_rkn will operate in interval mode, that is it will return at the end of the integration interval.

**high** : bool
If :math:\mathrm{high} = \mathbf{True}, a high-order method will be used, whereas if :math:\mathrm{high} = \mathbf{False}, a low-order method will be used. (See the specification of :meth:ivp_2nd_rkn for further details.)

**comm** : dict, communication object, modified in place
Communication structure.

On initial entry: need not be set.

**Returns**
**start** : bool
:math:\mathrm{start} = \mathbf{False}.

.. _d02lx-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:\mathrm{thresp}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle is not positive.

(errno :math:1)
On entry, :math:\mathrm{thres}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle is not positive.

(errno :math:2)
On entry, :math:\textit{neq} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\textit{neq}\geq 1.

(errno :math:2)
On entry, :math:\mathrm{high} = \mathbf{False} and :math:\textit{lrwork} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: if :math:\mathrm{high} = \mathbf{False} then :math:\textit{lrwork}\geq \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:2)
On entry, :math:\mathrm{high} = \mathbf{True} and :math:\textit{lrwork} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: if :math:\mathrm{high} = \mathbf{True} then :math:\textit{lrwork}\geq \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:3)
On entry, :math:\mathrm{tol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\langle\mathit{\boldsymbol{value}}\rangle < \mathrm{tol} < \langle\mathit{\boldsymbol{value}}\rangle.

.. _d02lx-py2-py-notes:

**Notes**
No equivalent traditional C interface for this routine exists in the NAG Library.

ivp_2nd_rkn_setup permits you to set optional inputs prior to any call of :meth:ivp_2nd_rkn.
It must be called before the first call of function :meth:ivp_2nd_rkn and it may be called before any continuation call of function :meth:ivp_2nd_rkn.
"""
raise NotImplementedError

[docs]def ivp_2nd_rkn_diag(neq, comm):
r"""
ivp_2nd_rkn_diag is a diagnostic function which may be called after a call of the integrator :meth:ivp_2nd_rkn.

.. _d02ly-py2-py-doc:

For full information please refer to the NAG Library document for d02ly

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02lyf.html

.. _d02ly-py2-py-parameters:

**Parameters**
**neq** : int
The number of second-order ordinary differential equations solved by :meth:ivp_2nd_rkn. It must be the same as the argument :math:\mathrm{neq} supplied to :meth:ivp_2nd_rkn_setup and :meth:ivp_2nd_rkn.

**comm** : dict, communication object
Communication structure.

This argument must have been initialized by a prior call to :meth:ivp_2nd_rkn_setup.

**Returns**
**hnext** : float
The next step size which :meth:ivp_2nd_rkn, if called, would attempt.

**hused** : float
The last successful step size used by :meth:ivp_2nd_rkn.

**hstart** : float
The initial step size used on the current integration problem by :meth:ivp_2nd_rkn.

**nsucc** : int
The number of steps attempted by :meth:ivp_2nd_rkn that have been successful since the start of the current problem.

**nfail** : int
The number of steps attempted by :meth:ivp_2nd_rkn that have failed since the start of the current problem.

**natt** : int
The number of steps attempted before the initial step was successful. Over a large number of problems the cost of an attempted step of this type is approximately half that of a normal attempted step.

**thres** : float, ndarray, shape :math:\left(\mathrm{neq}\right)
The :math:i\ th solution threshold value used in the error control strategy. (See :meth:ivp_2nd_rkn_setup.)

**thresp** : float, ndarray, shape :math:\left(\mathrm{neq}\right)
The :math:i\ th derivative threshold value used in the error control strategy. (See :meth:ivp_2nd_rkn_setup.)

.. _d02ly-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:\mathrm{neq} = \langle\mathit{\boldsymbol{value}}\rangle, but in the previous call to the setup function :math:{\textit{neq}} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
The integrator function :meth:ivp_2nd_rkn has not been called.

.. _d02ly-py2-py-notes:

**Notes**
No equivalent traditional C interface for this routine exists in the NAG Library.

ivp_2nd_rkn_diag permits you to extract information about the performance of :meth:ivp_2nd_rkn and the setting of some options.
It may be called only after a call of :meth:ivp_2nd_rkn.
"""
raise NotImplementedError

[docs]def ivp_2nd_rkn_interp(t, y, yp, nwant, twant, comm):
r"""
ivp_2nd_rkn_interp interpolates components of the solution of a non-stiff system of second-order differential equations from information provided by the integrator :meth:ivp_2nd_rkn, when the low-order method has been used.

.. _d02lz-py2-py-doc:

For full information please refer to the NAG Library document for d02lz

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02lzf.html

.. _d02lz-py2-py-parameters:

**Parameters**
**t** : float
:math:t, the current value at which the solution and its derivative have been computed (as returned in argument :math:\mathrm{t} on output from :meth:ivp_2nd_rkn).

**y** : float, array-like, shape :math:\left(\textit{neq}\right)
The :math:\textit{i}\ th component of the solution at :math:t, for :math:\textit{i} = 1,2,\ldots,\textit{neq}, as returned from :meth:ivp_2nd_rkn.

**yp** : float, array-like, shape :math:\left(\textit{neq}\right)
The :math:\textit{i}\ th component of the derivative at :math:t, for :math:\textit{i} = 1,2,\ldots,\textit{neq}, as returned from :meth:ivp_2nd_rkn.

**nwant** : int
The number of components of the solution and derivative whose values at :math:\mathrm{twant} are required. The first :math:\mathrm{nwant} components are evaluated.

**twant** : float
The point at which components of the solution and derivative are to be evaluated. :math:\mathrm{twant} should not normally be an extrapolation point, that is :math:\mathrm{twant} should satisfy

.. math::
\textit{told}\leq \mathrm{twant}\leq \mathrm{t}\text{,}

or if integration is proceeding in the negative direction

.. math::
\textit{told}\geq \mathrm{twant}\geq \mathrm{t}\text{,}

where told is the previous integration point which is held in an element of the array :math:\mathrm{comm}\ ['rwork'] and is, to within rounding, :math:\mathrm{t}-{\textit{hused}}. (:math:\textit{hused} is given by :meth:ivp_2nd_rkn_diag.) Extrapolation is permitted but not recommended, and :math:\mathrm{errno} = 2 is returned whenever extrapolation is attempted.

**comm** : dict, communication object, modified in place
Communication structure.

This argument must have been initialized by a prior call to :meth:ivp_2nd_rkn_setup.

**Returns**
**ywant** : float, ndarray, shape :math:\left(\mathrm{nwant}\right)
The calculated value of the :math:\textit{i}\ th component of the solution at :math:t = \mathrm{twant}, for :math:\textit{i} = 1,2,\ldots,\mathrm{nwant}.

**ypwant** : float, ndarray, shape :math:\left(\mathrm{nwant}\right)
The calculated value of the :math:\textit{i}\ th component of the derivative at :math:t = \mathrm{twant}, for :math:\textit{i} = 1,2,\ldots,\mathrm{nwant}.

.. _d02lz-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:\textit{neq} = \langle\mathit{\boldsymbol{value}}\rangle, but in a previous call to the setup function :math:{\textit{neq}} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
The integrator function :meth:ivp_2nd_rkn has not been called.

(errno :math:1)
No successful steps, interpolation impossible at :math:\mathrm{twant} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{nwant} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{nwant}\geq 1.

(errno :math:1)
On entry, :math:\mathrm{nwant} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\textit{neq} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{nwant}\leq \textit{neq}.

(errno :math:3)
Interpolation is not permitted on data from the high order formulas.

**Warns**
**NagAlgorithmicWarning**
(errno :math:2)
Extrapolation at :math:\mathrm{twant} = \langle\mathit{\boldsymbol{value}}\rangle.

.. _d02lz-py2-py-notes:

**Notes**
No equivalent traditional C interface for this routine exists in the NAG Library.

ivp_2nd_rkn_interp evaluates the first :math:\mathrm{nwant} (:math:\text{}\leq \textit{neq}) components of the solution of a non-stiff system of second-order ordinary differential equations at any point using a special Runge--Kutta--Nystrom formula (see Dormand and Prince (1986)) and information generated by :meth:ivp_2nd_rkn when the low-order method has been used.
This information must be presented unchanged to ivp_2nd_rkn_interp. ivp_2nd_rkn_interp should not normally be used to extrapolate outside the range of the values from :meth:ivp_2nd_rkn.

.. _d02lz-py2-py-references:

**References**
Dormand, J R and Prince, P J, 1986, Runge--Kutta--Nystrom triples, Mathematical Report TP-CS-86-05, Teesside Polytechnic
"""
raise NotImplementedError

[docs]def dae_dassl_cont(comm):
r"""
dae_dassl_cont is a setup function which must be called prior to a continuation call to :meth:dae_dassl_gen.

.. _d02mc-py2-py-doc:

For full information please refer to the NAG Library document for d02mc

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02mcf.html

.. _d02mc-py2-py-parameters:

**Parameters**
**comm** : dict, communication object, modified in place
Communication structure.

This argument must have been initialized by a prior call to :meth:dae_dassl_gen.

.. _d02mc-py2-py-notes:

**Notes**
dae_dassl_cont is provided to permit you to signal that the next call to :meth:dae_dassl_gen is a continuation call.
In particular, if :meth:dae_dassl_gen exits because the maximum number of integration steps has been exceeded, then a call to dae_dassl_cont resets the step counter allowing the integration to proceed.
"""
raise NotImplementedError

[docs]def ivp_stiff_dassl(neqmax, sdysav, maxord, con, tcrit, hmin, hmax, h0, maxstp, mxhnil, norm):
r"""
ivp_stiff_dassl is an integration method specific setup function which must be called prior to linear algebra setup functions and integrators from the SPRINT suite of functions, if the DASSL implementation of Backward Differentiation Formulae (BDF) is to be used.
Note that this method is also available, independent from the SPRINT suite, using :meth:dae_dassl_gen

.. _d02mv-py2-py-doc:

For full information please refer to the NAG Library document for d02mv

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02mvf.html

.. _d02mv-py2-py-parameters:

**Parameters**
**neqmax** : int
A bound on the maximum number of differential equations to be solved.

**sdysav** : int
The second dimension of the array :math:\textit{ysav} that will be supplied to the integrator, as declared in the (sub)program from which the integrator is called (e.g., see :meth:ivp_stiff_exp_fulljac).

**maxord** : int
The maximum order to be used for the BDF method. If :math:\mathrm{maxord} = 0 or :math:\mathrm{maxord} > 5, :math:\mathrm{maxord} = 5 is assumed.

**con** : float, array-like, shape :math:\left(3\right)
Values to be used to control step size choice during integration. If any :math:\mathrm{con}[i] = 0.0 on entry, it is replaced by its default value described below. In most cases this is the recommended setting.

:math:\mathrm{con}[0], :math:\mathrm{con}[1], and :math:\mathrm{con}[2] are factors used to bound step size changes.

If the current step size :math:h fails, the modulus of the next step size is bounded by :math:\mathrm{con}[0]\times \left\lvert h\right\rvert.

The default value of :math:\mathrm{con}[0] is :math:2.0.

Note that the new step size may be used with a method of different order to the failed step.

If the initial step size is :math:h, the modulus of the step size on the second step is bounded by :math:\mathrm{con}[2]\times \left\lvert h\right\rvert.

At any other stage in the integration, if the current step size is :math:h, the modulus of the next step size is bounded by :math:\mathrm{con}[1]\times \left\lvert h\right\rvert.

The default values are :math:10.0 for :math:\mathrm{con}[1] and :math:1000.0 for :math:\mathrm{con}[2].

**tcrit** : float
A point beyond which integration must not be attempted. The use of :math:\mathrm{tcrit} is described under the argument :math:\textit{itask} in the specification for the integrator (e.g., see :meth:ivp_stiff_exp_fulljac). A value, :math:0.0 say, must be specified even if :math:\textit{itask} subsequently specifies that :math:\mathrm{tcrit} will not be used.

**hmin** : float
The minimum absolute step size to be allowed. Set :math:\mathrm{hmin} = 0.0 if this option is not required.

**hmax** : float
The maximum absolute step size to be allowed. Set :math:\mathrm{hmax} = 0.0 if this option is not required.

**h0** : float
The step size to be attempted on the first step. Set :math:\mathrm{h0} = 0.0 if the initial step size is calculated internally.

**maxstp** : int
The maximum number of steps to be attempted during one call to the integrator after which it will return with :math:\mathrm{errno} = 2 (e.g., see :meth:ivp_stiff_exp_fulljac). Set :math:\mathrm{maxstp} = 0 if no limit is to be imposed.

**mxhnil** : int
The maximum number of warnings printed (if :math:{\textit{itrace}}\geq 0, e.g., see :meth:ivp_stiff_exp_fulljac) per problem when :math:t+h = t on a step (:math:h = \text{ current step size}). If :math:\mathrm{mxhnil}\leq 0, a default value of :math:10 is assumed.

**norm** : str, length 1
Indicates the type of norm to be used.

:math:\mathrm{norm} = \texttt{'M'}

Maximum norm.

:math:\mathrm{norm} = \texttt{'A'}

Averaged L2 norm.

:math:\mathrm{norm} = \texttt{'D'}

Is the same as 'A'.

If :math:\textit{vnorm} denotes the norm of the vector :math:v of length :math:n, for the averaged L2 norm

.. math::
\textit{vnorm}B = \sqrt{\frac{1}{n}\sum_{{i = 1}}^n\left(\frac{v_i}{w_i}\right)^2}\text{,}

while for the maximum norm

.. math::
\textit{vnorm} = \mathrm{max}_{{1\leq i\leq n}}\left\lvert \frac{v_i}{w_i}\right\rvert \text{.}

If you wish to weight the maximum norm or the L2 norm, :math:\textit{rtol} and :math:\textit{atol} should be scaled appropriately on input to the integrator (see under :math:\textit{itol} in the specification of the integrator for the formulation of the weight vector :math:w_i from :math:\textit{rtol} and :math:\textit{atol}, e.g., see :meth:ivp_stiff_exp_fulljac).

Only the first character to the actual argument :math:\mathrm{norm} is passed to ivp_stiff_dassl; hence it is permissible for the actual argument to be more descriptive, e.g., 'Maximum', 'Average L2' or 'Default' in a call to ivp_stiff_dassl.

**Returns**
**con** : float, ndarray, shape :math:\left(3\right)
The values actually to be used by the integration function.

**comm** : dict, communication object
Communication structure.

.. _d02mv-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
The sequence :math:\mathrm{con} is not strictly increasing: :math:\mathrm{con}[0] < \mathrm{con}[1] < \mathrm{con}[2] is required.

(errno :math:1)
On entry, :math:\mathrm{con}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{con}[\langle\mathit{\boldsymbol{value}}\rangle]\geq 1.0.

(errno :math:1)
On entry, :math:\mathrm{con}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{con}[\langle\mathit{\boldsymbol{value}}\rangle]\geq 0.0.

(errno :math:1)
On entry, :math:\mathrm{norm} was not valid: :math:\mathrm{norm} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{norm} = \texttt{'M'}, :math:\texttt{'A'} or :math:\texttt{'D'}.

(errno :math:1)
On entry, :math:\mathrm{neqmax} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{neqmax}\geq 1.

(errno :math:1)
On entry, :math:\mathrm{sdysav} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{maxord}+3 = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{sdysav}\geq \mathrm{maxord}+3.

(errno :math:1)
On entry, :math:\mathrm{maxord} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{maxord}\geq 0.

**Warns**
**NagAlgorithmicWarning**
(errno :math:1)
On entry, :math:\mathrm{maxord} > 5. :math:\mathrm{maxord} = 5 assumed.

.. _d02mv-py2-py-notes:

**Notes**
No equivalent traditional C interface for this routine exists in the NAG Library.

An integrator setup function must be called before the call to any linear algebra setup function or integrator from the SPRINT suite of functions in this sub-module.
This setup function, ivp_stiff_dassl, makes the choice of the DASSL integrator and permits you to define options appropriate to this choice. Alternative choices of integrator from this suite are the BDF method and the BLEND method which can be chosen by initial calls to :meth:ivp_stiff_bdf or :meth:ivp_stiff_blend respectively.
"""
raise NotImplementedError

[docs]def dae_dassl_setup(neq, maxord, jceval, hmax, h0, itol):
r"""
dae_dassl_setup is a setup function which must be called prior to the integrator :meth:dae_dassl_gen, if the DASSL implementation of Backward Differentiation Formulae (BDF) is to be used.

.. _d02mw-py2-py-doc:

For full information please refer to the NAG Library document for d02mw

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02mwf.html

.. _d02mw-py2-py-parameters:

**Parameters**
**neq** : int
The number of differential-algebraic equations to be solved.

**maxord** : int
The maximum order to be used for the BDF method. Orders up to 5th order are available; setting :math:\mathrm{maxord} > 5 means that the maximum order used will be :math:5.

**jceval** : str, length 1
Specifies the technique to be used to compute the Jacobian.

:math:\mathrm{jceval} = \texttt{'N'}

The Jacobian is to be evaluated numerically by the integrator.

:math:\mathrm{jceval} = \texttt{'A'}

You must supply a function to evaluate the Jacobian on a call to the integrator.

Only the first character of the actual paramater :math:\mathrm{jceval} is passed to dae_dassl_setup; hence it is permissible for the actual argument to be more descriptive, e.g., 'Numerical' or 'Analytical', on a call to dae_dassl_setup.

**hmax** : float
The maximum absolute step size to be allowed. Set :math:\mathrm{hmax} = 0.0 if this option is not required.

**h0** : float
The step size to be attempted on the first step. Set :math:\mathrm{h0} = 0.0 if the initial step size is calculated internally.

**itol** : int
A value to indicate the form of the local error test.

:math:\mathrm{itol} = 0

:math:\textit{rtol} and :math:\textit{atol} are single element vectors.

:math:\mathrm{itol} = 1

:math:\textit{rtol} and :math:\textit{atol} are vectors. This should be chosen if you want to apply different tolerances to each equation in the system.

See :meth:dae_dassl_gen.

Note: the tolerances must either both be single element vectors or both be vectors of length :math:\mathrm{neq}.

**Returns**
**comm** : dict, communication object
Communication structure.

.. _d02mw-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:\mathrm{neq} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{neq}\geq 1.

(errno :math:2)
On entry, :math:\mathrm{maxord} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{maxord}\geq 1.

(errno :math:3)
On entry, :math:\mathrm{jceval} has an illegal value: :math:\mathrm{jceval} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{jceval} = \texttt{'N'} or :math:\texttt{'A'}.

(errno :math:4)
On entry, :math:\mathrm{hmax} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{hmax}\geq 0.0.

(errno :math:6)
On entry, :math:\mathrm{itol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{itol} = 0 or :math:1.

.. _d02mw-py2-py-notes:

**Notes**
This integrator setup function must be called before the first call to the integrator :meth:dae_dassl_gen. This setup function dae_dassl_setup permits you to define options for the DASSL integrator, such as: whether the Jacobian is to be provided or is to be approximated numerically by the integrator; the initial and maximum step-sizes for the integration; whether relative and absolute tolerances are system wide or per system equation; and the maximum order of BDF method permitted.
"""
raise NotImplementedError

[docs]def ivp_stiff_interp(tsol, m, comm):
r"""
ivp_stiff_interp interpolates components of the solution of a system of first-order differential equations from information provided by those integrators in submodule ode using methods set up by calls to :meth:ivp_stiff_dassl, :meth:ivp_stiff_bdf or :meth:ivp_stiff_blend.

.. _d02mz-py2-py-doc:

For full information please refer to the NAG Library document for d02mz

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02mzf.html

.. _d02mz-py2-py-parameters:

**Parameters**
**tsol** : float
The point at which the first :math:\mathrm{m} components of the solution are to be evaluated. :math:\mathrm{tsol} should not normally be an extrapolation point. Extrapolation is permitted but not recommended.

**m** : int
The number of components of the solution whose values are required.

**comm** : dict, communication object
Communication structure.

This argument must have been initialized by a prior call to :meth:ivp_stiff_exp_fulljac, :meth:ivp_stiff_exp_bandjac, :meth:ivp_stiff_exp_sparjac, :meth:ivp_stiff_imp_fulljac, :meth:ivp_stiff_imp_bandjac, :meth:ivp_stiff_imp_sparjac, :meth:ivp_stiff_exp_revcom or :meth:ivp_stiff_imp_revcom.

**Returns**
**sol** : float, ndarray, shape :math:\left(\mathrm{m}\right)
The calculated value of the solution at :math:\mathrm{tsol}.

.. _d02mz-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:\textit{neq} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\textit{ldysav} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\textit{neq}\leq \textit{ldysav}.

(errno :math:1)
On entry, :math:\mathrm{m} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\textit{neq} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{m}\leq \textit{neq}.

(errno :math:1)
On entry, :math:\textit{neq} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\textit{neq}\geq 1.

(errno :math:1)
On entry, :math:\mathrm{m} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{m}\geq 1.

(errno :math:2)
Either the integrator function has not been called prior to the first call of this function or the array has become corrupted.

**Warns**
**NagAlgorithmicWarning**
(errno :math:3)
On entry, :math:\mathrm{tsol} is an extrapolation point.

.. _d02mz-py2-py-notes:

**Notes**
No equivalent traditional C interface for this routine exists in the NAG Library.

ivp_stiff_interp evaluates the first :math:\mathrm{m} components of the solution of a system of ordinary differential equations at any point using natural polynomial interpolation based on information generated by the integrator.
This information must be passed unchanged to ivp_stiff_interp. ivp_stiff_interp should not normally be used to extrapolate outside the range of values obtained from the above function.
"""
raise NotImplementedError

[docs]def ivp_stiff_exp_fulljac(t, tout, y, comm, rtol, atol, itol, fcn, itask, itrace, jac=None, monitr=None, data=None, io_manager=None, spiked_sorder='C'):
r"""
ivp_stiff_exp_fulljac is a direct communication function for integrating stiff systems of explicit ordinary differential equations when the Jacobian is a full matrix.

.. _d02nb-py2-py-doc:

For full information please refer to the NAG Library document for d02nb

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02nbf.html

.. _d02nb-py2-py-parameters:

**Parameters**
**t** : float
:math:t, the value of the independent variable. The input value of :math:\mathrm{t} is used only on the first call as the initial point of the integration.

**tout** : float
The next value of :math:t at which a computed solution is desired. For the initial :math:t, the input value of :math:\mathrm{tout} is used to determine the direction of integration. Integration is permitted in either direction (see also :math:\mathrm{itask}).

**y** : float, array-like, shape :math:\left(\textit{neq}\right)
The values of the dependent variables (solution). On the first call the first :math:\textit{neq} elements of :math:\mathrm{y} must contain the vector of initial values.

**comm** : dict, communication object, modified in place
Communication structure.

This argument must have been initialized by prior calls to :meth:ivp_stiff_fulljac_setup and one of :meth:ivp_stiff_bdf or :meth:ivp_stiff_blend.

**rtol** : float, array-like, shape :math:\left(:\right)
Note: the required length for this argument is determined as follows: if :math:\mathrm{itol}\text{ in } (1, 2): :math:1; otherwise: :math:\textit{neq}.

The relative local error tolerance.

**atol** : float, array-like, shape :math:\left(:\right)
Note: the required length for this argument is determined as follows: if :math:\mathrm{itol}\text{ in } (1, 3): :math:1; otherwise: :math:\textit{neq}.

The absolute local error tolerance.

**itol** : int
A value to indicate the form of the local error test. :math:\mathrm{itol} indicates to ivp_stiff_exp_fulljac whether to interpret either or both of :math:\mathrm{rtol} or :math:\mathrm{atol} as a vector or a scalar. The error test to be satisfied is :math:\left\lVert e_i/w_i\right\rVert < 1.0, where :math:w_i is defined as follows:

+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+
|:math:\mathrm{itol}|:math:\mathrm{rtol}|:math:\mathrm{atol}|:math:w_i                                                                     |
+=====================+=====================+=====================+================================================================================+
|1                    |scalar               |scalar               |:math:\mathrm{rtol}[0]\times \left\lvert y_i\right\rvert +\mathrm{atol}[0]    |
+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+
|2                    |scalar               |vector               |:math:\mathrm{rtol}[0]\times \left\lvert y_i\right\rvert +\mathrm{atol}[i-1]  |
+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+
|3                    |vector               |scalar               |:math:\mathrm{rtol}[i-1]\times \left\lvert y_i\right\rvert +\mathrm{atol}[0]  |
+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+
|4                    |vector               |vector               |:math:\mathrm{rtol}[i-1]\times \left\lvert y_i\right\rvert +\mathrm{atol}[i-1]|
+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+

:math:e_i is an estimate of the local error in :math:y_i, computed internally, and the choice of norm to be used is defined by a previous call to an integrator setup function.

**fcn** : callable (f, ires) = fcn(t, y, ires, data=None)
:math:\mathrm{fcn} must evaluate the derivative vector for the explicit ordinary differential equation system, defined by :math:y^{\prime } = g\left(t, y\right).

**Parameters**
**t** : float
:math:t, the current value of the independent variable.

**y** : float, ndarray, shape :math:\left(\textit{neq}\right)
The value of :math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{neq}.

**ires** : int
:math:\mathrm{ires} = 1.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**f** : float, array-like, shape :math:\left(\textit{neq}\right)
The value :math:y_{\textit{i}}^{\prime }, given by :math:y_{\textit{i}}^{\prime } = g_{\textit{i}}\left(t, y\right), for :math:\textit{i} = 1,2,\ldots,\textit{neq}.

**ires** : int
You may set :math:\mathrm{ires} as follows to indicate certain conditions in :math:\mathrm{fcn} to the integrator:

:math:\mathrm{ires} = 1

Indicates a normal return from :math:\mathrm{fcn}, that is :math:\mathrm{ires} has not been altered by you and integration continues.

:math:\mathrm{ires} = 2

Indicates to the integrator that control should be passed back immediately to the calling (sub)program with the error indicator set to :math:\mathrm{errno} = 11.

:math:\mathrm{ires} = 3

Indicates to the integrator that an error condition has occurred in the solution vector, its time derivative or in the value of :math:t. The integrator will use a smaller time step to try to avoid this condition. If this is not possible the integrator returns to the calling (sub)program with the error indicator set to :math:\mathrm{errno} = 7.

:math:\mathrm{ires} = 4

Indicates to the integrator to stop its current operation and to enter :math:\mathrm{monitr} immediately with argument :math:\mathrm{imon} = -2.

The task to be performed by the integrator.

:math:\mathrm{itask} = 1

Normal computation of output values of :math:y\left(t\right) at :math:t = \mathrm{tout} (by overshooting and interpolating).

:math:\mathrm{itask} = 2

Take one step only and return.

:math:\mathrm{itask} = 3

Stop at the first internal integration point at or beyond :math:t = \mathrm{tout} and return.

:math:\mathrm{itask} = 4

Normal computation of output values of :math:y\left(t\right) at :math:t = \mathrm{tout} but without overshooting :math:t = {\textit{tcrit}} (e.g., see :meth:ivp_stiff_dassl). :math:\textit{tcrit} must be specified as an option in one of the integrator setup functions before the first call to the integrator, or specified in the optional input function before a continuation call. :math:\textit{tcrit} may be equal to or beyond :math:\mathrm{tout}, but not before it, in the direction of integration.

:math:\mathrm{itask} = 5

Take one step only and return, without passing :math:\textit{tcrit} (e.g., see :meth:ivp_stiff_dassl). :math:\textit{tcrit} must be specified as under :math:\mathrm{itask} = 4.

**itrace** : int
The level of output that is printed by the integrator. :math:\mathrm{itrace} may take the value :math:-1, :math:0, :math:1, :math:2 or :math:3.

:math:\mathrm{itrace} < -1

:math:-1 is assumed and similarly if :math:\mathrm{itrace} > 3, :math:3 is assumed.

:math:\mathrm{itrace} = -1

No output is generated.

:math:\mathrm{itrace} = 0

Only warning messages are printed on the current error message unit (see :class:~naginterfaces.base.utils.FileObjManager).

:math:\mathrm{itrace} > 0

Warning messages are printed as above, and on the file object associated with the advisory I/O unit (see :class:~naginterfaces.base.utils.FileObjManager) output is generated which details Jacobian entries, the nonlinear iteration and the time integration. The advisory messages are given in greater detail the larger the value of :math:\mathrm{itrace}.

**jac** : None or callable p = jac(t, y, h, d, p, data=None), optional
Note: if this argument is **None** then a NAG-supplied facility will be used.

:math:\mathrm{jac} must evaluate the Jacobian of the system.

If this option is not required, the actual argument for :math:\mathrm{jac} must be **None**. You must indicate to the integrator whether this option is to be used by setting the argument :math:\textit{jceval} appropriately in a call to the full linear algebra setup function :meth:ivp_stiff_fulljac_setup.

First we must define the system of nonlinear equations which is solved internally by the integrator.

The time derivative, :math:y^{\prime }, generated internally, has the form

.. math::
y^{\prime } = \left(y-z\right)/\left(hd\right)\text{,}

where :math:h is the current step size and :math:d is an argument that depends on the integration method in use.

The vector :math:y is the current solution and the vector :math:z depends on information from previous time steps.

This means that :math:\frac{d}{{dy^{\prime }}}\left(\text{ }\right) = \left(hd\right)\frac{d}{{dy}}\left(\text{ }\right).

The system of nonlinear equations that is solved has the form

.. math::
y^{\prime }-g\left(t, y\right) = 0

but it is solved in the form

.. math::
r\left(t, y\right) = 0\text{,}

where :math:r is the function defined by

.. math::
r\left(t, y\right) = \left(hd\right)\left({\left(y-z\right)/\left(hd\right)-g\left(t, y\right)}\right)\text{.}

It is the Jacobian matrix :math:\frac{{\partial r}}{{\partial y}} that you must supply in :math:\mathrm{jac} as follows:

.. math::
\begin{array}{ll} \frac{{\partial r_i}}{{\partial y_j}} = 1-\left(hd\right) \frac{{\partial g_i}}{{\partial y_j}} \text{,} &\text{if }i = j\text{,}\\&\\ \frac{{\partial r_i}}{{\partial y_j}} = -\left(hd\right) \frac{{\partial g_i}}{{\partial y_j}} \text{,} &\text{otherwise.}\end{array}

**Parameters**
**t** : float
:math:t, the current value of the independent variable.

**y** : float, ndarray, shape :math:\left(\textit{neq}\right)
:math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{neq}, the current solution component.

**h** : float
The current step size.

**d** : float
The argument :math:d which depends on the integration method.

**p** : float, ndarray, shape :math:\left(\textit{neq}, \textit{neq}\right)
Is set to zero.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**p** : float, array-like, shape :math:\left(\textit{neq}, \textit{neq}\right)
:math:\mathrm{p}[\textit{i}-1,\textit{j}-1] must contain :math:\frac{{\partial r_{\textit{i}}}}{{\partial y_{\textit{j}}}}, for :math:\textit{j} = 1,2,\ldots,\textit{neq}, for :math:\textit{i} = 1,2,\ldots,\textit{neq}.

Only the nonzero elements of this array need be set, since it is preset to zero before the call to :math:\mathrm{jac}.

**monitr** : None or callable (hnext, y, imon, inln, hmin, hmax) = monitr(t, hlast, hnext, y, ydot, comm, r, acor, imon, hmin, hmax, nqu, data=None), optional
Note: if this argument is **None** then a NAG-supplied facility will be used.

:math:\mathrm{monitr} performs tasks requested by you.

If this option is not required, the actual argument for :math:\mathrm{monitr} must be **None**.

**Parameters**
**t** : float
The current value of the independent variable.

**hlast** : float
The last step size successfully used by the integrator.

**hnext** : float
The step size that the integrator proposes to take on the next step.

**y** : float, ndarray, shape :math:\left(\textit{neq}\right)
:math:y, the values of the dependent variables evaluated at :math:t.

**ydot** : float, ndarray, shape :math:\left(\textit{neq}\right)
The time derivatives :math:y^{\prime } of the vector :math:y.

**comm** : dict, communication object, modifiable in place
Communication structure.

This argument may be passed as argument :math:\textit{comm} in a call to :meth:ivp_stiff_nat_interp or :math:\textit{comm} in a call to :meth:ivp_stiff_c1_interp to enable you to carry out interpolation using either of those functions.

**r** : float, ndarray, shape :math:\left(\textit{neq}\right)
If :math:\mathrm{imon} = 0 and :math:\mathrm{inln} = 3, the first :math:\textit{neq} elements contain the residual vector, :math:y^{\prime }-g\left(t, y\right).

**acor** : float, ndarray, shape :math:\left(\textit{neq}, 2\right)
With :math:\mathrm{imon} = 1, :math:\mathrm{acor}[i-1,0] contains the weight used for the :math:i\ th equation when the norm is evaluated, and :math:\mathrm{acor}[i-1,1] contains the estimated local error for the :math:i\ th equation. The scaled local error at the end of a timestep may be obtained by calling :meth:ivp_stiff_errest.

**imon** : int
A flag indicating under what circumstances :math:\mathrm{monitr} was called:

:math:\mathrm{imon} = -2

Entry from the integrator after :math:\mathrm{ires} = 4 (set in :math:\mathrm{fcn}) caused an early termination (this facility could be used to locate discontinuities).

:math:\mathrm{imon} = -1

The current step failed repeatedly.

:math:\mathrm{imon} = 0

Entry after a call to the internal nonlinear equation solver (see :math:\mathrm{inln}).

:math:\mathrm{imon} = 1

The current step was successful.

**hmin** : float
The minimum step size to be taken on the next step.

**hmax** : float
The maximum step size to be taken on the next step.

**nqu** : int
The order of the integrator used on the last step. This is supplied to enable you to carry out interpolation using either of the functions :meth:ivp_stiff_nat_interp or :meth:ivp_stiff_c1_interp.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**hnext** : float
The next step size to be used. If this is different from the input value, :math:\mathrm{imon} must be set to :math:4.

**y** : float, array-like, shape :math:\left(\textit{neq}\right)
These values must not be changed unless :math:\mathrm{imon} is set to :math:2.

**imon** : int
May be reset to determine subsequent action in ivp_stiff_exp_fulljac.

:math:\mathrm{imon} = -2

Integration is to be halted. A return will be made from the integrator to the calling (sub)program with :math:\mathrm{errno} = 12.

:math:\mathrm{imon} = -1

Allow the integrator to continue with its own internal strategy. The integrator will try up to three restarts unless :math:\mathrm{imon} is set :math:\text{}\neq -1 on exit.

:math:\mathrm{imon} = 0

Return to the internal nonlinear equation solver, where the action taken is determined by the value of :math:\mathrm{inln} (see :math:\mathrm{inln}).

:math:\mathrm{imon} = 1

Normal exit to the integrator to continue integration.

:math:\mathrm{imon} = 2

Restart the integration at the current time point. The integrator will restart from order :math:1 when this option is used. The solution :math:\mathrm{y}, provided by :math:\mathrm{monitr}, will be used for the initial conditions.

:math:\mathrm{imon} = 3

Try to continue with the same step size and order as was to be used before the call to :math:\mathrm{monitr}. :math:\mathrm{hmin} and :math:\mathrm{hmax} may be altered if desired.

:math:\mathrm{imon} = 4

Continue the integration but using a new value of :math:\mathrm{hnext} and possibly new values of :math:\mathrm{hmin} and :math:\mathrm{hmax}.

**inln** : int
The action to be taken by the internal nonlinear equation solver when :math:\mathrm{monitr} is exited with :math:\mathrm{imon} = 0. By setting :math:\mathrm{inln} = 3 and returning to the integrator, the residual vector is evaluated and placed in the array :math:\mathrm{r}, and then :math:\mathrm{monitr} is called again. At present this is the only option available: :math:\mathrm{inln} must not be set to any other value.

**hmin** : float
The minimum step size to be used. If this is different from the input value, :math:\mathrm{imon} must be set to :math:3 or :math:4.

**hmax** : float
The maximum step size to be used. If this is different from the input value, :math:\mathrm{imon} must be set to :math:3 or :math:4. If :math:\mathrm{hmax} is set to zero, no limit is assumed.

**data** : arbitrary, optional
User-communication data for callback functions.

**io_manager** : FileObjManager, optional
Manager for I/O in this routine.

**spiked_sorder** : str, optional
If :math:\mathrm{p} in :math:\mathrm{jac} is spiked (i.e., has unit extent in all but one dimension, or has size :math:1), :math:\mathrm{spiked\_sorder} selects the storage order to associate with it in the NAG Engine:

spiked_sorder = :math:\texttt{'C'}
row-major storage will be used;

spiked_sorder = :math:\texttt{'F'}
column-major storage will be used.

**Returns**
**t** : float
The value at which the computed solution :math:y is returned (usually at :math:\mathrm{tout}).

**y** : float, ndarray, shape :math:\left(\textit{neq}\right)
The computed solution vector, evaluated at :math:\mathrm{t} (usually :math:\mathrm{t} = \mathrm{tout}).

**ydot** : float, ndarray, shape :math:\left(\textit{neq}\right)
The time derivatives :math:y^{\prime } of the vector :math:y at the last integration point.

.. _d02nb-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
Failure during internal time interpolation. :math:\mathrm{tout} and the current time are too close.

:math:\mathrm{itask} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle and the current time is :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{itask} = 4 or :math:5 and :math:\textit{tcrit} is before the current time in the direction of integration.

:math:\mathrm{itask} = \langle\mathit{\boldsymbol{value}}\rangle, :math:{\textit{tcrit}} = \langle\mathit{\boldsymbol{value}}\rangle and the current time is :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
:math:\mathrm{itask} = 3 and :math:\mathrm{tout} is more than an integration step behind the current time.

:math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle, current time minus step size: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
The initial stepsize, :math:\langle\mathit{\boldsymbol{value}}\rangle, is too small.

(errno :math:1)
On entry, :math:\mathrm{itask} = 4 or :math:5 and :math:\textit{tcrit} is before :math:\mathrm{tout} in the direction of integration.

:math:\mathrm{itask} = \langle\mathit{\boldsymbol{value}}\rangle, :math:{\textit{tcrit}} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{atol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{atol}\geq 0.0.

(errno :math:1)
On entry, :math:\mathrm{rtol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{rtol}\geq 0.0.

(errno :math:1)
Either the value of :math:\textit{sdysav} is not the same as the value supplied to the setup function or a communication array has become corrupted.

:math:\textit{sdysav} = \langle\mathit{\boldsymbol{value}}\rangle, :math:\textit{sdysav} (setup) :math:{} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, an illegal (negative) minimum stepsize was provided in a prior call to a setup function. :math:\mathrm{hmin} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{tout} is less than :math:\mathrm{t} with respect to the direction of integration given by the sign of :math:\textit{h0} in a prior call to a setup function.

:math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle, :math:\mathrm{t} = \langle\mathit{\boldsymbol{value}}\rangle and :math:{\textit{h0}} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, an illegal (negative) maximum number of steps was provided in a prior call to a setup function. :math:{\textit{maxstp}} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{itol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:1\leq \mathrm{itol}\leq 4.

(errno :math:1)
On entry, :math:\textit{neq} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\textit{ldysav} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\textit{neq}\leq \textit{ldysav}.

(errno :math:1)
On entry, :math:\textit{neq} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\textit{neq}\geq 1.

(errno :math:1)
Either the function was entered on a continuation call without a prior call of this function, or a communication array has become corrupted.

(errno :math:1)
On entry, :math:\mathrm{tout} is too close to :math:\mathrm{t} to start integration.

:math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{t} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{itask} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:1\leq \mathrm{itask}\leq 5.

(errno :math:1)
Either the integrator setup function has not been called prior to the first call of this function, or a communication array has become corrupted.

(errno :math:1)
On entry, an illegal (negative) maximum stepsize was provided in a prior call to a setup function. :math:\mathrm{hmax} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
Either the linear algebra setup function has not been called prior to the first call of this function, or a communication array has become corrupted.

(errno :math:1)
:math:\mathrm{monitr} set :math:\mathrm{inln} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{inln} = 3.

(errno :math:1)
:math:\mathrm{monitr} appears to have overwritten the solution vector.

Further integration will not be attempted.

(errno :math:2)
At time :math:\langle\mathit{\boldsymbol{value}}\rangle the maximum number of allowed steps on this call was taken before reaching the next output point :math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle.

Maximum number of steps :math:{} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:3)
Too much accuracy requested for precision of the machine at time :math:\langle\mathit{\boldsymbol{value}}\rangle.

The tolerances should be checked; the requested accuracy should be reduced by a factor of at least :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:7)
The derivative evaluation procedure set the error flag :math:\mathrm{ires} = 3 repeatedly despite attempts by the integrator to avoid this.

(errno :math:9)
A singular Jacobian has been encountered. You should check the problem formulation and Jacobian calculation.

(errno :math:10)
Workspace error occurred when trying to form the Jacobian matrix in calculating the initial values of the solution and its time derivative.

(errno :math:10)
Not enough integer store provided for sparse matrix solver.

Units of store needed: :math:\langle\mathit{\boldsymbol{value}}\rangle. Amount provided: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:10)
Larger integer workspace required.

Provided: :math:\langle\mathit{\boldsymbol{value}}\rangle; required: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:10)
Not enough real store provided for sparse matrix solver.

Units of store needed: :math:\langle\mathit{\boldsymbol{value}}\rangle. Amount provided: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:14)
On entry, too much accuracy requested for precision of the machine at the start of problem. The tolerances should be checked; the requested accuracy should be reduced by a factor of at least :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:15)
The linear algebra setup routine for full Jacobian was not called first.

**Warns**
**NagAlgorithmicWarning**
(errno :math:4)
There were repeated error-test failures on an attempted step, before completing the requested task, but the integration was successful as far as :math:\mathrm{t}. The problem may have a singularity, or the local error requirements may be inappropriate.

(errno :math:5)
There were repeated convergence-test failures on an attempted step, before completing the requested task, but the integration was successful as far as :math:\mathrm{t}. This may be caused by an inaccurate Jacobian matrix or one which is incorrectly computed.

(errno :math:6)
At time :math:\langle\mathit{\boldsymbol{value}}\rangle, error weight :math:\langle\mathit{\boldsymbol{value}}\rangle became zero. Check the values of :math:\mathrm{atol}, :math:\mathrm{rtol} and :math:\mathrm{itol} supplied.

(errno :math:6)
Weight number :math:i = \langle\mathit{\boldsymbol{value}}\rangle used in the local error test is too small. Check the values of :math:\mathrm{rtol} and :math:\mathrm{atol}.

:math:\mathrm{atol}[i-1] and :math:\mathrm{y}[i-1] may both be zero.

Weight :math:i = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:11)
:math:\mathrm{fcn} set :math:\mathrm{ires} = 2, which signals that the integration should terminate. :math:\mathrm{ires} = \langle\mathit{\boldsymbol{value}}\rangle at time :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:12)
A return was forced by setting :math:\mathrm{imon} = -2, but the integration was successful as far as :math:\mathrm{t}.

(errno :math:12)
:math:\mathrm{monitr} set :math:\mathrm{imon} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:-2\leq \mathrm{imon}\leq 4.

(errno :math:13)
The requested task has been completed, but it is estimated that a small change in :math:\mathrm{rtol} and :math:\mathrm{atol} is unlikely to produce any change in the computed solution. (This ONLY applies when you are NOT operating in one step mode; that is, when :math:\mathrm{itask} \neq 2 or :math:5.)

.. _d02nb-py2-py-notes:

**Notes**
No equivalent traditional C interface for this routine exists in the NAG Library.

ivp_stiff_exp_fulljac is a general purpose function for integrating the initial value problem for a stiff system of explicit ordinary differential equations,

.. math::
y^{\prime } = g\left(t, y\right)\text{.}

It is designed specifically for the case where the Jacobian :math:\frac{{\partial g}}{{\partial y}} is a full matrix.

Both interval and step oriented modes of operation are available and also modes designed to permit intermediate output within an interval oriented mode.

A typical calling program for ivp_stiff_exp_fulljac would involve calling the full matrix linear algebra setup function :meth:ivp_stiff_fulljac_setup, the Backward Differentiation Formula (BDF) integrator setup function :meth:ivp_stiff_bdf, and its diagnostic counterpart :meth:ivp_stiff_integ_diag as well as the call to ivp_stiff_exp_fulljac.
The linear algebra setup function :meth:ivp_stiff_fulljac_setup and one of the integrator setup functions, :meth:ivp_stiff_bdf or :meth:ivp_stiff_blend, must be called prior to the call of ivp_stiff_exp_fulljac.
The integrator diagnostic function :meth:ivp_stiff_integ_diag may be called after the call to ivp_stiff_exp_fulljac.
There is also a function, :meth:ivp_stiff_contin, designed to permit you to change step size on a continuation call to ivp_stiff_exp_fulljac without restarting the integration process.

--------
:meth:naginterfaces.library.examples.ode.ivp_stiff_exp_fulljac_ex.main
"""
raise NotImplementedError

[docs]def ivp_stiff_exp_bandjac(t, tout, y, comm, rtol, atol, itol, fcn, itask, itrace, jac=None, monitr=None, data=None, io_manager=None, spiked_sorder='C'):
r"""
ivp_stiff_exp_bandjac is a direct communication function for integrating stiff systems of explicit ordinary differential equations when the Jacobian is a banded matrix.

.. _d02nc-py2-py-doc:

For full information please refer to the NAG Library document for d02nc

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02ncf.html

.. _d02nc-py2-py-parameters:

**Parameters**
**t** : float
:math:t, the value of the independent variable. The input value of :math:\mathrm{t} is used only on the first call as the initial point of the integration.

**tout** : float
The next value of :math:t at which a computed solution is desired. For the initial :math:t, the input value of :math:\mathrm{tout} is used to determine the direction of integration. Integration is permitted in either direction (see also :math:\mathrm{itask}).

**y** : float, array-like, shape :math:\left(\textit{neq}\right)
The values of the dependent variables (solution). On the first call the first :math:\textit{neq} elements of :math:\mathrm{y} must contain the vector of initial values.

**comm** : dict, communication object, modified in place
Communication structure.

This argument must have been initialized by prior calls to :meth:ivp_stiff_bandjac_setup and one of :meth:ivp_stiff_bdf or :meth:ivp_stiff_blend.

**rtol** : float, array-like, shape :math:\left(:\right)
Note: the required length for this argument is determined as follows: if :math:\mathrm{itol}\text{ in } (1, 2): :math:1; otherwise: :math:\textit{neq}.

The relative local error tolerance.

**atol** : float, array-like, shape :math:\left(:\right)
Note: the required length for this argument is determined as follows: if :math:\mathrm{itol}\text{ in } (1, 3): :math:1; otherwise: :math:\textit{neq}.

The absolute local error tolerance.

**itol** : int
A value to indicate the form of the local error test. :math:\mathrm{itol} indicates to ivp_stiff_exp_bandjac whether to interpret either or both of :math:\mathrm{rtol} or :math:\mathrm{atol} as a vector or a scalar. The error test to be satisfied is :math:\left\lVert e_i/w_i\right\rVert < 1.0, where :math:w_i is defined as follows:

+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+
|:math:\mathrm{itol}|:math:\mathrm{rtol}|:math:\mathrm{atol}|:math:w_i                                                                     |
+=====================+=====================+=====================+================================================================================+
|1                    |scalar               |scalar               |:math:\mathrm{rtol}[0]\times \left\lvert y_i\right\rvert +\mathrm{atol}[0]    |
+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+
|2                    |scalar               |vector               |:math:\mathrm{rtol}[0]\times \left\lvert y_i\right\rvert +\mathrm{atol}[i-1]  |
+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+
|3                    |vector               |scalar               |:math:\mathrm{rtol}[i-1]\times \left\lvert y_i\right\rvert +\mathrm{atol}[0]  |
+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+
|4                    |vector               |vector               |:math:\mathrm{rtol}[i-1]\times \left\lvert y_i\right\rvert +\mathrm{atol}[i-1]|
+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+

:math:e_i is an estimate of the local error in :math:y_i, computed internally, and the choice of norm to be used is defined by a previous call to an integrator setup function.

**fcn** : callable (f, ires) = fcn(t, y, ires, data=None)
:math:\mathrm{fcn} must evaluate the derivative vector for the explicit ordinary differential equation system, defined by :math:y^{\prime } = g\left(t, y\right).

**Parameters**
**t** : float
:math:t, the current value of the independent variable.

**y** : float, ndarray, shape :math:\left(\textit{neq}\right)
The value of :math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{neq}.

**ires** : int
:math:\mathrm{ires} = 1.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**f** : float, array-like, shape :math:\left(\textit{neq}\right)
The value :math:y_{\textit{i}}^{\prime }, given by :math:y_{\textit{i}}^{\prime } = g_{\textit{i}}\left(t, y\right), for :math:\textit{i} = 1,2,\ldots,\textit{neq}.

**ires** : int
You may set :math:\mathrm{ires} as follows to indicate certain conditions in :math:\mathrm{fcn} to the integrator:

:math:\mathrm{ires} = 1

Indicates a normal return from :math:\mathrm{fcn}, that is :math:\mathrm{ires} has not been altered by you and integration continues.

:math:\mathrm{ires} = 2

Indicates to the integrator that control should be passed back immediately to the calling (sub)program with the error indicator set to :math:\mathrm{errno} = 11.

:math:\mathrm{ires} = 3

Indicates to the integrator that an error condition has occurred in the solution vector, its time derivative or in the value of :math:t. The integrator will use a smaller time step to try to avoid this condition. If this is not possible the integrator returns to the calling (sub)program with the error indicator set to :math:\mathrm{errno} = 7.

:math:\mathrm{ires} = 4

Indicates to the integrator to stop its current operation and to enter :math:\mathrm{monitr} immediately with argument :math:\mathrm{imon} = -2.

The task to be performed by the integrator.

:math:\mathrm{itask} = 1

Normal computation of output values of :math:y\left(t\right) at :math:t = \mathrm{tout} (by overshooting and interpolating).

:math:\mathrm{itask} = 2

Take one step only and return.

:math:\mathrm{itask} = 3

Stop at the first internal integration point at or beyond :math:t = \mathrm{tout} and return.

:math:\mathrm{itask} = 4

Normal computation of output values of :math:y\left(t\right) at :math:t = \mathrm{tout} but without overshooting :math:t = {\textit{tcrit}}. :math:\textit{tcrit} must be specified as an option in one of the integrator setup functions before the first call to the integrator, or specified in the optional input function before a continuation call. :math:\textit{tcrit} may be equal to or beyond :math:\mathrm{tout}, but not before it, in the direction of integration.

:math:\mathrm{itask} = 5

Take one step only and return, without passing :math:\textit{tcrit}. :math:\textit{tcrit} must be specified as under :math:\mathrm{itask} = 4.

**itrace** : int
The level of output that is printed by the integrator. :math:\mathrm{itrace} may take the value :math:-1, :math:0, :math:1, :math:2 or :math:3.

:math:\mathrm{itrace} < -1

:math:-1 is assumed and similarly if :math:\mathrm{itrace} > 3, :math:3 is assumed.

:math:\mathrm{itrace} = -1

No output is generated.

:math:\mathrm{itrace} = 0

Only warning messages are printed on the current error message unit (see :class:~naginterfaces.base.utils.FileObjManager).

:math:\mathrm{itrace} > 0

Warning messages are printed as above, and on the file object associated with the advisory I/O unit (see :class:~naginterfaces.base.utils.FileObjManager) output is generated which details Jacobian entries, the nonlinear iteration and the time integration. The advisory messages are given in greater detail the larger the value of :math:\mathrm{itrace}.

**jac** : None or callable p = jac(t, y, h, d, ml, mu, p, data=None), optional
Note: if this argument is **None** then a NAG-supplied facility will be used.

:math:\mathrm{jac} must evaluate the Jacobian of the system.

If this option is not required, the actual argument for :math:\mathrm{jac} must be **None**. You must indicate to the integrator whether this option is to be used by setting the argument :math:\textit{jceval} appropriately in a call to the banded linear algebra setup function :meth:ivp_stiff_bandjac_setup.

First we must define the system of nonlinear equations which is solved internally by the integrator.

The time derivative, :math:y^{\prime }, generated internally, has the form

.. math::
y^{\prime } = \left(y-z\right)/\left(hd\right)\text{,}

where :math:h is the current step size and :math:d is an argument that depends on the integration method in use.

The vector :math:y is the current solution and the vector :math:z depends on information from previous time steps.

This means that :math:\frac{d}{{dy^{\prime }}}\left(\text{ }\right) = \left(hd\right)\frac{d}{{dy}}\left(\text{ }\right).

The system of nonlinear equations that is solved has the form

.. math::
y^{\prime }-g\left(t, y\right) = 0

but it is solved in the form

.. math::
r\left(t, y\right) = 0\text{,}

where :math:r is the function defined by

.. math::
r\left(t, y\right) = \left(hd\right)\left({\left(y-z\right)/\left(hd\right)-g\left(t, y\right)}\right)\text{.}

It is the Jacobian matrix :math:\frac{{\partial r}}{{\partial y}} that you must supply in :math:\mathrm{jac} as follows:

.. math::
\begin{array}{ll} \frac{{\partial r_i}}{{\partial y_j}} = 1-\left(hd\right) \frac{{\partial g_i}}{{\partial y_j}} \text{,} &\text{if }i = j\text{,}\\&\\ \frac{{\partial r_i}}{{\partial y_j}} = -\left(hd\right) \frac{{\partial g_i}}{{\partial y_j}} \text{,} &\text{otherwise.}\end{array}

**Parameters**
**t** : float
:math:t, the current value of the independent variable.

**y** : float, ndarray, shape :math:\left(\textit{neq}\right)
:math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{neq}, the current solution component.

**h** : float
The current step size.

**d** : float
The argument :math:d which depends on the integration method.

**ml** : int
The number of subdiagonals and superdiagonals respectively in the band.

**mu** : int
The number of subdiagonals and superdiagonals respectively in the band.

**p** : float, ndarray, shape :math:\left(\mathrm{ml}+\mathrm{mu}+1, \textit{neq}\right)
Is set to zero.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**p** : float, array-like, shape :math:\left(\mathrm{ml}+\mathrm{mu}+1, \textit{neq}\right)
Elements of the Jacobian matrix :math:\frac{{\partial r}}{{\partial y}} stored as specified by the following pseudocode:

::

for i in range(1, neq+1):
j1 = max(i-ml, 1)
j2 = min(i+mu, neq)
for j in range(j1, j2+1):
k = min(ml+1-i, 0) + j
p[k-1, i-1] = J[i-1, j-1]

See also :meth:lapacklin.dgbtrf <naginterfaces.library.lapacklin.dgbtrf>.

Only nonzero elements of this array need be set, since it is preset to zero before the call to :math:\mathrm{jac}.

**monitr** : None or callable (hnext, y, imon, inln, hmin, hmax) = monitr(t, hlast, hnext, y, ydot, comm, r, acor, imon, hmin, hmax, nqu, data=None), optional
Note: if this argument is **None** then a NAG-supplied facility will be used.

:math:\mathrm{monitr} performs tasks requested by you.

If this option is not required, the actual argument for :math:\mathrm{monitr} must be **None**.

**Parameters**
**t** : float
The current value of the independent variable.

**hlast** : float
The last step size successfully used by the integrator.

**hnext** : float
The step size that the integrator proposes to take on the next step.

**y** : float, ndarray, shape :math:\left(\textit{neq}\right)
:math:y, the values of the dependent variables evaluated at :math:t.

**ydot** : float, ndarray, shape :math:\left(\textit{neq}\right)
The time derivatives :math:y^{\prime } of the vector :math:y.

**comm** : dict, communication object, modifiable in place
Communication structure.

This argument may be passed as argument :math:\textit{comm} in a call to :meth:ivp_stiff_nat_interp or :math:\textit{comm} in a call to :meth:ivp_stiff_c1_interp to enable you to carry out interpolation using either of those functions.

**r** : float, ndarray, shape :math:\left(\textit{neq}\right)
If :math:\mathrm{imon} = 0 and :math:\mathrm{inln} = 3, the first :math:\textit{neq} elements contain the residual vector, :math:y^{\prime }-g\left(t, y\right).

**acor** : float, ndarray, shape :math:\left(\textit{neq}, 2\right)
With :math:\mathrm{imon} = 1, :math:\mathrm{acor}[i-1,0] contains the weight used for the :math:i\ th equation when the norm is evaluated, and :math:\mathrm{acor}[i-1,1] contains the estimated local error for the :math:i\ th equation. The scaled local error at the end of a timestep may be obtained by calling :meth:ivp_stiff_errest.

**imon** : int
A flag indicating under what circumstances :math:\mathrm{monitr} was called:

:math:\mathrm{imon} = -2

Entry from the integrator after :math:\mathrm{ires} = 4 (set in :math:\mathrm{fcn}) caused an early termination (this facility could be used to locate discontinuities).

:math:\mathrm{imon} = -1

The current step failed repeatedly.

:math:\mathrm{imon} = 0

Entry after a call to the internal nonlinear equation solver (see :math:\mathrm{inln}).

:math:\mathrm{imon} = 1

The current step was successful.

**hmin** : float
The minimum step size to be taken on the next step.

**hmax** : float
The maximum step size to be taken on the next step.

**nqu** : int
The order of the integrator used on the last step. This is supplied to enable you to carry out interpolation using either of the functions :meth:ivp_stiff_nat_interp or :meth:ivp_stiff_c1_interp.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**hnext** : float
The next step size to be used. If this is different from the input value, :math:\mathrm{imon} must be set to :math:4.

**y** : float, array-like, shape :math:\left(\textit{neq}\right)
These values must not be changed unless :math:\mathrm{imon} is set to :math:2.

**imon** : int
May be reset to determine subsequent action in ivp_stiff_exp_bandjac.

:math:\mathrm{imon} = -2

Integration is to be halted. A return will be made from the integrator to the calling (sub)program with :math:\mathrm{errno} = 12.

:math:\mathrm{imon} = -1

Allow the integrator to continue with its own internal strategy. The integrator will try up to three restarts unless :math:\mathrm{imon} is set :math:\text{}\neq -1 on exit.

:math:\mathrm{imon} = 0

Return to the internal nonlinear equation solver, where the action taken is determined by the value of :math:\mathrm{inln} (see :math:\mathrm{inln}).

:math:\mathrm{imon} = 1

Normal exit to the integrator to continue integration.

:math:\mathrm{imon} = 2

Restart the integration at the current time point. The integrator will restart from order :math:1 when this option is used. The solution :math:\mathrm{y}, provided by :math:\mathrm{monitr}, will be used for the initial conditions.

:math:\mathrm{imon} = 3

Try to continue with the same step size and order as was to be used before the call to :math:\mathrm{monitr}. :math:\mathrm{hmin} and :math:\mathrm{hmax} may be altered if desired.

:math:\mathrm{imon} = 4

Continue the integration but using a new value of :math:\mathrm{hnext} and possibly new values of :math:\mathrm{hmin} and :math:\mathrm{hmax}.

**inln** : int
The action to be taken by the internal nonlinear equation solver when :math:\mathrm{monitr} is exited with :math:\mathrm{imon} = 0. By setting :math:\mathrm{inln} = 3 and returning to the integrator, the residual vector is evaluated and placed in the array :math:\mathrm{r}, and then :math:\mathrm{monitr} is called again. At present this is the only option available: :math:\mathrm{inln} must not be set to any other value.

**hmin** : float
The minimum step size to be used. If this is different from the input value, :math:\mathrm{imon} must be set to :math:3 or :math:4.

**hmax** : float
The maximum step size to be used. If this is different from the input value, :math:\mathrm{imon} must be set to :math:3 or :math:4. If :math:\mathrm{hmax} is set to zero, no limit is assumed.

**data** : arbitrary, optional
User-communication data for callback functions.

**io_manager** : FileObjManager, optional
Manager for I/O in this routine.

**spiked_sorder** : str, optional
If :math:\mathrm{p} in :math:\mathrm{jac} is spiked (i.e., has unit extent in all but one dimension, or has size :math:1), :math:\mathrm{spiked\_sorder} selects the storage order to associate with it in the NAG Engine:

spiked_sorder = :math:\texttt{'C'}
row-major storage will be used;

spiked_sorder = :math:\texttt{'F'}
column-major storage will be used.

**Returns**
**t** : float
The value at which the computed solution :math:y is returned (usually at :math:\mathrm{tout}).

**y** : float, ndarray, shape :math:\left(\textit{neq}\right)
The computed solution vector, evaluated at :math:\mathrm{t} (usually :math:\mathrm{t} = \mathrm{tout}).

**ydot** : float, ndarray, shape :math:\left(\textit{neq}\right)
The time derivatives :math:y^{\prime } of the vector :math:y at the last integration point.

.. _d02nc-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
:math:\mathrm{monitr} set :math:\mathrm{imon} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:-2\leq \mathrm{imon}\leq 4.

(errno :math:1)
Failure during internal time interpolation. :math:\mathrm{tout} and the current time are too close.

:math:\mathrm{itask} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle and the current time is :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{itask} = 4 or :math:5 and :math:\textit{tcrit} is before the current time in the direction of integration.

:math:\mathrm{itask} = \langle\mathit{\boldsymbol{value}}\rangle, :math:{\textit{tcrit}} = \langle\mathit{\boldsymbol{value}}\rangle and the current time is :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
:math:\mathrm{itask} = 3 and :math:\mathrm{tout} is more than an integration step behind the current time.

:math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle, current time minus step size: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
The initial stepsize, :math:\langle\mathit{\boldsymbol{value}}\rangle, is too small.

(errno :math:1)
On entry, :math:\mathrm{itask} = 4 or :math:5 and :math:\textit{tcrit} is before :math:\mathrm{tout} in the direction of integration.

:math:\mathrm{itask} = \langle\mathit{\boldsymbol{value}}\rangle, :math:{\textit{tcrit}} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{atol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{atol}\geq 0.0.

(errno :math:1)
On entry, :math:\mathrm{rtol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{rtol}\geq 0.0.

(errno :math:1)
Either the value of :math:\textit{sdysav} is not the same as the value supplied to the setup function or a communication array has become corrupted.

:math:\textit{sdysav} = \langle\mathit{\boldsymbol{value}}\rangle, :math:\textit{sdysav} (setup) :math:{} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, an illegal (negative) minimum stepsize was provided in a prior call to a setup function. :math:\mathrm{hmin} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{tout} is less than :math:\mathrm{t} with respect to the direction of integration given by the sign of :math:\textit{h0} in a prior call to a setup function.

:math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle, :math:\mathrm{t} = \langle\mathit{\boldsymbol{value}}\rangle and :math:{\textit{h0}} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, an illegal (negative) maximum number of steps was provided in a prior call to a setup function. :math:{\textit{maxstp}} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{itol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:1\leq \mathrm{itol}\leq 4.

(errno :math:1)
On entry, :math:\textit{neq} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\textit{ldysav} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\textit{neq}\leq \textit{ldysav}.

(errno :math:1)
On entry, :math:\textit{neq} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\textit{neq}\geq 1.

(errno :math:1)
Either the function was entered on a continuation call without a prior call of this function, or a communication array has become corrupted.

(errno :math:1)
On entry, :math:\mathrm{tout} is too close to :math:\mathrm{t} to start integration.

:math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{t} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{itask} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:1\leq \mathrm{itask}\leq 5.

(errno :math:1)
Either the integrator setup function has not been called prior to the first call of this function, or a communication array has become corrupted.

(errno :math:1)
On entry, an illegal (negative) maximum stepsize was provided in a prior call to a setup function. :math:\mathrm{hmax} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
Either the linear algebra setup function has not been called prior to the first call of this function, or a communication array has become corrupted.

(errno :math:1)
:math:\mathrm{monitr} set :math:\mathrm{inln} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{inln} = 3.

(errno :math:1)
:math:\mathrm{monitr} appears to have overwritten the solution vector.

Further integration will not be attempted.

(errno :math:2)
At time :math:\langle\mathit{\boldsymbol{value}}\rangle the maximum number of allowed steps on this call was taken before reaching the next output point :math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle.

Maximum number of steps :math:{} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:3)
Too much accuracy requested for precision of the machine at time :math:\langle\mathit{\boldsymbol{value}}\rangle.

The tolerances should be checked; the requested accuracy should be reduced by a factor of at least :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:7)
The derivative evaluation procedure set the error flag :math:\mathrm{ires} = 3 repeatedly despite attempts by the integrator to avoid this.

(errno :math:10)
Workspace error occurred when trying to form the Jacobian matrix in calculating the initial values of the solution and its time derivative.

(errno :math:10)
Not enough integer store provided for sparse matrix solver.

Units of store needed: :math:\langle\mathit{\boldsymbol{value}}\rangle. Amount provided: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:10)
Larger integer workspace required.

Provided: :math:\langle\mathit{\boldsymbol{value}}\rangle; required: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:10)
Not enough real store provided for sparse matrix solver.

Units of store needed: :math:\langle\mathit{\boldsymbol{value}}\rangle. Amount provided: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:14)
On entry, too much accuracy requested for precision of the machine at the start of problem. The tolerances should be checked; the requested accuracy should be reduced by a factor of at least :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:15)
The linear algebra setup routine for banded Jacobian was not called first.

**Warns**
**NagAlgorithmicWarning**
(errno :math:4)
There were repeated error-test failures on an attempted step, before completing the requested task, but the integration was successful as far as :math:\mathrm{t}. The problem may have a singularity, or the local error requirements may be inappropriate.

(errno :math:5)
There were repeated convergence-test failures on an attempted step, before completing the requested task, but the integration was successful as far as :math:\mathrm{t}. This may be caused by an inaccurate Jacobian matrix or one which is incorrectly computed.

(errno :math:6)
At time :math:\langle\mathit{\boldsymbol{value}}\rangle, error weight :math:\langle\mathit{\boldsymbol{value}}\rangle became zero. Check the values of :math:\mathrm{atol}, :math:\mathrm{rtol} and :math:\mathrm{itol} supplied.

(errno :math:6)
Weight number :math:i = \langle\mathit{\boldsymbol{value}}\rangle used in the local error test is too small. Check the values of :math:\mathrm{rtol} and :math:\mathrm{atol}.

:math:\mathrm{atol}[i-1] and :math:\mathrm{y}[i-1] may both be zero.

Weight :math:i = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:9)
A singular Jacobian has been encountered. You should check the problem formulation and Jacobian calculation.

(errno :math:11)
:math:\mathrm{fcn} set :math:\mathrm{ires} = 2, which signals that the integration should terminate. :math:\mathrm{ires} = \langle\mathit{\boldsymbol{value}}\rangle at time :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:12)
A return was forced by setting :math:\mathrm{imon} = -2, but the integration was successful as far as :math:\mathrm{t}.

(errno :math:13)
The requested task has been completed, but it is estimated that a small change in :math:\mathrm{rtol} and :math:\mathrm{atol} is unlikely to produce any change in the computed solution. (This ONLY applies when you are NOT operating in one step mode; that is, when :math:\mathrm{itask} \neq 2 or :math:5.)

.. _d02nc-py2-py-notes:

**Notes**
No equivalent traditional C interface for this routine exists in the NAG Library.

ivp_stiff_exp_bandjac is a general purpose function for integrating the initial value problem for a stiff system of explicit ordinary differential equations,

.. math::
y^{\prime } = g\left(t, y\right)\text{.}

It is designed specifically for the case where the Jacobian :math:\frac{{\partial g}}{{\partial y}} is a banded matrix.

Both interval and step oriented modes of operation are available and also modes designed to permit intermediate output within an interval oriented mode.

A typical calling program for ivp_stiff_exp_bandjac would involve calling the banded matrix linear algebra setup function :meth:ivp_stiff_bandjac_setup, the Backward Differentiation Formula (BDF) integrator setup function :meth:ivp_stiff_bdf, and its diagnostic counterpart :meth:ivp_stiff_integ_diag as well as the call to ivp_stiff_exp_bandjac.
The linear algebra setup function :meth:ivp_stiff_bandjac_setup and one of the integrator setup functions, :meth:ivp_stiff_bdf or :meth:ivp_stiff_blend, must be called prior to the call of ivp_stiff_exp_bandjac.
The integrator diagnostic function :meth:ivp_stiff_integ_diag may be called after the call to ivp_stiff_exp_bandjac.
There is also a function, :meth:ivp_stiff_contin, designed to permit you to change step size on a continuation call to ivp_stiff_exp_bandjac without restarting the integration process.
"""
raise NotImplementedError

[docs]def ivp_stiff_exp_sparjac(t, tout, y, comm, rtol, atol, itol, fcn, itask, itrace, jac=None, monitr=None, data=None, io_manager=None):
r"""
ivp_stiff_exp_sparjac is a direct communication function for integrating stiff systems of explicit ordinary differential equations when the Jacobian is a sparse matrix.

.. _d02nd-py2-py-doc:

For full information please refer to the NAG Library document for d02nd

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02ndf.html

.. _d02nd-py2-py-parameters:

**Parameters**
**t** : float
:math:t, the value of the independent variable. The input value of :math:\mathrm{t} is used only on the first call as the initial point of the integration.

**tout** : float
The next value of :math:t at which a computed solution is desired. For the initial :math:t, the input value of :math:\mathrm{tout} is used to determine the direction of integration. Integration is permitted in either direction (see also :math:\mathrm{itask}).

**y** : float, array-like, shape :math:\left(\textit{neq}\right)
The values of the dependent variables (solution). On the first call the first :math:\textit{neq} elements of :math:\mathrm{y} must contain the vector of initial values.

**comm** : dict, communication object, modified in place
Communication structure.

This argument must have been initialized by prior calls to :meth:ivp_stiff_sparjac_setup and one of :meth:ivp_stiff_bdf or :meth:ivp_stiff_blend.

**rtol** : float, array-like, shape :math:\left(:\right)
Note: the required length for this argument is determined as follows: if :math:\mathrm{itol}\text{ in } (1, 2): :math:1; otherwise: :math:\textit{neq}.

The relative local error tolerance.

**atol** : float, array-like, shape :math:\left(:\right)
Note: the required length for this argument is determined as follows: if :math:\mathrm{itol}\text{ in } (1, 3): :math:1; otherwise: :math:\textit{neq}.

The absolute local error tolerance.

**itol** : int
A value to indicate the form of the local error test. :math:\mathrm{itol} indicates to ivp_stiff_exp_sparjac whether to interpret either or both of :math:\mathrm{rtol} or :math:\mathrm{atol} as a vector or a scalar. The error test to be satisfied is :math:\left\lVert e_i/w_i\right\rVert < 1.0, where :math:w_i is defined as follows:

+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+
|:math:\mathrm{itol}|:math:\mathrm{rtol}|:math:\mathrm{atol}|:math:w_i                                                                     |
+=====================+=====================+=====================+================================================================================+
|1                    |scalar               |scalar               |:math:\mathrm{rtol}[0]\times \left\lvert y_i\right\rvert +\mathrm{atol}[0]    |
+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+
|2                    |scalar               |vector               |:math:\mathrm{rtol}[0]\times \left\lvert y_i\right\rvert +\mathrm{atol}[i-1]  |
+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+
|3                    |vector               |scalar               |:math:\mathrm{rtol}[i-1]\times \left\lvert y_i\right\rvert +\mathrm{atol}[0]  |
+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+
|4                    |vector               |vector               |:math:\mathrm{rtol}[i-1]\times \left\lvert y_i\right\rvert +\mathrm{atol}[i-1]|
+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+

:math:e_i is an estimate of the local error in :math:y_i, computed internally, and the choice of norm to be used is defined by a previous call to an integrator setup function.

**fcn** : callable (f, ires) = fcn(t, y, ires, data=None)
:math:\mathrm{fcn} must evaluate the derivative vector for the explicit ordinary differential equation system, defined by :math:y^{\prime } = g\left(t, y\right).

**Parameters**
**t** : float
:math:t, the current value of the independent variable.

**y** : float, ndarray, shape :math:\left(\textit{neq}\right)
The value of :math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{neq}.

**ires** : int
:math:\mathrm{ires} = 1.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**f** : float, array-like, shape :math:\left(\textit{neq}\right)
The value :math:y_{\textit{i}}^{\prime }, given by :math:y_{\textit{i}}^{\prime } = g_{\textit{i}}\left(t, y\right), for :math:\textit{i} = 1,2,\ldots,\textit{neq}.

**ires** : int
You may set :math:\mathrm{ires} as follows to indicate certain conditions in :math:\mathrm{fcn} to the integrator:

:math:\mathrm{ires} = 1

Indicates a normal return from :math:\mathrm{fcn}, that is :math:\mathrm{ires} has not been altered by you and integration continues.

:math:\mathrm{ires} = 2

Indicates to the integrator that control should be passed back immediately to the calling (sub)program with the error indicator set to :math:\mathrm{errno} = 11.

:math:\mathrm{ires} = 3

Indicates to the integrator that an error condition has occurred in the solution vector, its time derivative or in the value of :math:t. The integrator will use a smaller time step to try to avoid this condition. If this is not possible the integrator returns to the calling (sub)program with the error indicator set to :math:\mathrm{errno} = 7.

:math:\mathrm{ires} = 4

Indicates to the integrator to stop its current operation and to enter :math:\mathrm{monitr} immediately with argument :math:\mathrm{imon} = -2.

The task to be performed by the integrator.

:math:\mathrm{itask} = 1

Normal computation of output values of :math:y\left(t\right) at :math:t = \mathrm{tout} (by overshooting and interpolating).

:math:\mathrm{itask} = 2

Take one step only and return.

:math:\mathrm{itask} = 3

Stop at the first internal integration point at or beyond :math:t = \mathrm{tout} and return.

:math:\mathrm{itask} = 4

Normal computation of output values of :math:y\left(t\right) at :math:t = \mathrm{tout} but without overshooting :math:t = {\textit{tcrit}} (e.g., see :meth:ivp_stiff_dassl). :math:\textit{tcrit} must be specified as an option in one of the integrator setup functions before the first call to the integrator, or specified in the optional input function before a continuation call. :math:\textit{tcrit} may be equal to or beyond :math:\mathrm{tout}, but not before it, in the direction of integration.

:math:\mathrm{itask} = 5

Take one step only and return, without passing :math:\textit{tcrit} (e.g., see :meth:ivp_stiff_dassl). :math:\textit{tcrit} must be specified as under :math:\mathrm{itask} = 4.

**itrace** : int
The level of output that is printed by the integrator. :math:\mathrm{itrace} may take the value :math:-1, :math:0, :math:1, :math:2 or :math:3.

:math:\mathrm{itrace} < -1

:math:-1 is assumed and similarly if :math:\mathrm{itrace} > 3, :math:3 is assumed.

:math:\mathrm{itrace} = -1

No output is generated.

:math:\mathrm{itrace} = 0

Only warning messages are printed on the current error message unit (see :class:~naginterfaces.base.utils.FileObjManager).

:math:\mathrm{itrace} > 0

Warning messages are printed as above, and on the file object associated with the advisory I/O unit (see :class:~naginterfaces.base.utils.FileObjManager) output is generated which details Jacobian entries, the nonlinear iteration and the time integration. The advisory messages are given in greater detail the larger the value of :math:\mathrm{itrace}.

**jac** : None or callable pdj = jac(t, y, h, d, j, pdj, data=None), optional
Note: if this argument is **None** then a NAG-supplied facility will be used.

:math:\mathrm{jac} must evaluate the Jacobian of the system.

If this option is not required, the actual argument for :math:\mathrm{jac} must be **None**. You must indicate to the integrator whether this option is to be used by setting the argument :math:\textit{jceval} appropriately in a call to the sparse linear algebra setup function :meth:ivp_stiff_sparjac_setup.

First we must define the system of nonlinear equations which is solved internally by the integrator.

The time derivative, :math:y^{\prime }, generated internally, has the form

.. math::
y^{\prime } = \left(y-z\right)/\left(hd\right)\text{,}

where :math:h is the current step size and :math:d is an argument that depends on the integration method in use.

The vector :math:y is the current solution and the vector :math:z depends on information from previous time steps.

This means that :math:\frac{d}{{dy^{\prime }}}\left(\text{ }\right) = \left(hd\right)\frac{d}{{dy}}\left(\text{ }\right).

The system of nonlinear equations that is solved has the form

.. math::
y^{\prime }-g\left(t, y\right) = 0

but it is solved in the form

.. math::
r\left(t, y\right) = 0\text{,}

where :math:r is the function defined by

.. math::
r\left(t, y\right) = \left(hd\right)\left({\left(y-z\right)/\left(hd\right)-g\left(t, y\right)}\right)\text{.}

It is the Jacobian matrix :math:\frac{{\partial r}}{{\partial y}} that you must supply in :math:\mathrm{jac} as follows:

.. math::
\begin{array}{ll} \frac{{\partial r_i}}{{\partial y_j}} = 1-\left(hd\right) \frac{{\partial g_i}}{{\partial y_j}} \text{,} &\text{if }i = j\text{,}\\&\\ \frac{{\partial r_i}}{{\partial y_j}} = -\left(hd\right) \frac{{\partial g_i}}{{\partial y_j}} \text{,} &\text{otherwise.}\end{array}

**Parameters**
**t** : float
:math:t, the current value of the independent variable.

**y** : float, ndarray, shape :math:\left(\textit{neq}\right)
:math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{neq}, the current solution component.

**h** : float
The current step size.

**d** : float
The argument :math:d which depends on the integration method.

**j** : int
The column of the Jacobian that :math:\mathrm{jac} must return in the array :math:\mathrm{pdj}.

**pdj** : float, ndarray, shape :math:\left(\textit{neq}\right)
Is set to zero.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**pdj** : float, array-like, shape :math:\left(\textit{neq}\right)
:math:\mathrm{pdj}[i-1] should be set to the :math:\left(i, j\right)\ th element of the Jacobian, where :math:j is given by :math:\mathrm{j}. Only nonzero elements of this array need be set, since it is preset to zero before the call to :math:\mathrm{jac}.

**monitr** : None or callable (hnext, y, imon, inln, hmin, hmax) = monitr(t, hlast, hnext, y, ydot, comm, r, acor, imon, hmin, hmax, nqu, data=None), optional
Note: if this argument is **None** then a NAG-supplied facility will be used.

:math:\mathrm{monitr} performs tasks requested by you.

If this option is not required, the actual argument for :math:\mathrm{monitr} must be **None**.

**Parameters**
**t** : float
The current value of the independent variable.

**hlast** : float
The last step size successfully used by the integrator.

**hnext** : float
The step size that the integrator proposes to take on the next step.

**y** : float, ndarray, shape :math:\left(\textit{neq}\right)
:math:y, the values of the dependent variables evaluated at :math:t.

**ydot** : float, ndarray, shape :math:\left(\textit{neq}\right)
The time derivatives :math:y^{\prime } of the vector :math:y.

**comm** : dict, communication object, modifiable in place
Communication structure.

This argument may be passed as argument :math:\textit{comm} in a call to :meth:ivp_stiff_nat_interp or :math:\textit{comm} in a call to :meth:ivp_stiff_c1_interp to enable you to carry out interpolation using either of those functions.

**r** : float, ndarray, shape :math:\left(\textit{neq}\right)
If :math:\mathrm{imon} = 0 and :math:\mathrm{inln} = 3, the first :math:\textit{neq} elements contain the residual vector, :math:y^{\prime }-g\left(t, y\right).

**acor** : float, ndarray, shape :math:\left(\textit{neq}, 2\right)
With :math:\mathrm{imon} = 1, :math:\mathrm{acor}[i-1,0] contains the weight used for the :math:i\ th equation when the norm is evaluated, and :math:\mathrm{acor}[i-1,1] contains the estimated local error for the :math:i\ th equation. The scaled local error at the end of a timestep may be obtained by calling :meth:ivp_stiff_errest.

**imon** : int
A flag indicating under what circumstances :math:\mathrm{monitr} was called:

:math:\mathrm{imon} = -2

Entry from the integrator after :math:\mathrm{ires} = 4 (set in :math:\mathrm{fcn}) caused an early termination (this facility could be used to locate discontinuities).

:math:\mathrm{imon} = -1

The current step failed repeatedly.

:math:\mathrm{imon} = 0

Entry after a call to the internal nonlinear equation solver (see :math:\mathrm{inln}).

:math:\mathrm{imon} = 1

The current step was successful.

**hmin** : float
The minimum step size to be taken on the next step.

**hmax** : float
The maximum step size to be taken on the next step.

**nqu** : int
The order of the integrator used on the last step. This is supplied to enable you to carry out interpolation using either of the functions :meth:ivp_stiff_nat_interp or :meth:ivp_stiff_c1_interp.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**hnext** : float
The next step size to be used. If this is different from the input value, :math:\mathrm{imon} must be set to :math:4.

**y** : float, array-like, shape :math:\left(\textit{neq}\right)
These values must not be changed unless :math:\mathrm{imon} is set to :math:2.

**imon** : int
May be reset to determine subsequent action in ivp_stiff_exp_sparjac.

:math:\mathrm{imon} = -2

Integration is to be halted. A return will be made from the integrator to the calling (sub)program with :math:\mathrm{errno} = 12.

:math:\mathrm{imon} = -1

Allow the integrator to continue with its own internal strategy. The integrator will try up to three restarts unless :math:\mathrm{imon} is set :math:\text{}\neq -1 on exit.

:math:\mathrm{imon} = 0

Return to the internal nonlinear equation solver, where the action taken is determined by the value of :math:\mathrm{inln} (see :math:\mathrm{inln}).

:math:\mathrm{imon} = 1

Normal exit to the integrator to continue integration.

:math:\mathrm{imon} = 2

Restart the integration at the current time point. The integrator will restart from order :math:1 when this option is used. The solution :math:\mathrm{y}, provided by :math:\mathrm{monitr}, will be used for the initial conditions.

:math:\mathrm{imon} = 3

Try to continue with the same step size and order as was to be used before the call to :math:\mathrm{monitr}. :math:\mathrm{hmin} and :math:\mathrm{hmax} may be altered if desired.

:math:\mathrm{imon} = 4

Continue the integration but using a new value of :math:\mathrm{hnext} and possibly new values of :math:\mathrm{hmin} and :math:\mathrm{hmax}.

**inln** : int
The action to be taken by the internal nonlinear equation solver when :math:\mathrm{monitr} is exited with :math:\mathrm{imon} = 0. By setting :math:\mathrm{inln} = 3 and returning to the integrator, the residual vector is evaluated and placed in the array :math:\mathrm{r}, and then :math:\mathrm{monitr} is called again. At present this is the only option available: :math:\mathrm{inln} must not be set to any other value.

**hmin** : float
The minimum step size to be used. If this is different from the input value, :math:\mathrm{imon} must be set to :math:3 or :math:4.

**hmax** : float
The maximum step size to be used. If this is different from the input value, :math:\mathrm{imon} must be set to :math:3 or :math:4. If :math:\mathrm{hmax} is set to zero, no limit is assumed.

**data** : arbitrary, optional
User-communication data for callback functions.

**io_manager** : FileObjManager, optional
Manager for I/O in this routine.

**Returns**
**t** : float
The value at which the computed solution :math:y is returned (usually at :math:\mathrm{tout}).

**y** : float, ndarray, shape :math:\left(\textit{neq}\right)
The computed solution vector, evaluated at :math:\mathrm{t} (usually :math:\mathrm{t} = \mathrm{tout}).

**ydot** : float, ndarray, shape :math:\left(\textit{neq}\right)
The time derivatives :math:y^{\prime } of the vector :math:y at the last integration point.

.. _d02nd-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
:math:\mathrm{monitr} set :math:\mathrm{imon} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:-2\leq \mathrm{imon}\leq 4.

(errno :math:1)
Failure during internal time interpolation. :math:\mathrm{tout} and the current time are too close.

:math:\mathrm{itask} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle and the current time is :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{itask} = 4 or :math:5 and :math:\textit{tcrit} is before the current time in the direction of integration.

:math:\mathrm{itask} = \langle\mathit{\boldsymbol{value}}\rangle, :math:{\textit{tcrit}} = \langle\mathit{\boldsymbol{value}}\rangle and the current time is :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
:math:\mathrm{itask} = 3 and :math:\mathrm{tout} is more than an integration step behind the current time.

:math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle, current time minus step size: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
The initial stepsize, :math:\langle\mathit{\boldsymbol{value}}\rangle, is too small.

(errno :math:1)
On entry, :math:\mathrm{itask} = 4 or :math:5 and :math:\textit{tcrit} is before :math:\mathrm{tout} in the direction of integration.

:math:\mathrm{itask} = \langle\mathit{\boldsymbol{value}}\rangle, :math:{\textit{tcrit}} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{atol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{atol}\geq 0.0.

(errno :math:1)
On entry, :math:\mathrm{rtol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{rtol}\geq 0.0.

(errno :math:1)
Either the value of :math:\textit{sdysav} is not the same as the value supplied to the setup function or a communication array has become corrupted.

:math:\textit{sdysav} = \langle\mathit{\boldsymbol{value}}\rangle, :math:\textit{sdysav} (setup) :math:{} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, an illegal (negative) minimum stepsize was provided in a prior call to a setup function. :math:\mathrm{hmin} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{tout} is less than :math:\mathrm{t} with respect to the direction of integration given by the sign of :math:\textit{h0} in a prior call to a setup function.

:math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle, :math:\mathrm{t} = \langle\mathit{\boldsymbol{value}}\rangle and :math:{\textit{h0}} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, an illegal (negative) maximum number of steps was provided in a prior call to a setup function. :math:{\textit{maxstp}} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{itol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:1\leq \mathrm{itol}\leq 4.

(errno :math:1)
On entry, :math:\textit{neq} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\textit{ldysav} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\textit{neq}\leq \textit{ldysav}.

(errno :math:1)
On entry, :math:\textit{neq} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\textit{neq}\geq 1.

(errno :math:1)
Either the function was entered on a continuation call without a prior call of this function, or a communication array has become corrupted.

(errno :math:1)
On entry, :math:\mathrm{tout} is too close to :math:\mathrm{t} to start integration.

:math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{t} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{itask} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:1\leq \mathrm{itask}\leq 5.

(errno :math:1)
Either the integrator setup function has not been called prior to the first call of this function, or a communication array has become corrupted.

(errno :math:1)
On entry, an illegal (negative) maximum stepsize was provided in a prior call to a setup function. :math:\mathrm{hmax} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
Either the linear algebra setup function has not been called prior to the first call of this function, or a communication array has become corrupted.

(errno :math:1)
:math:\mathrm{monitr} set :math:\mathrm{inln} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{inln} = 3.

(errno :math:1)
:math:\mathrm{monitr} appears to have overwritten the solution vector.

Further integration will not be attempted.

(errno :math:2)
At time :math:\langle\mathit{\boldsymbol{value}}\rangle the maximum number of allowed steps on this call was taken before reaching the next output point :math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle.

Maximum number of steps :math:{} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:3)
Too much accuracy requested for precision of the machine at time :math:\langle\mathit{\boldsymbol{value}}\rangle.

The tolerances should be checked; the requested accuracy should be reduced by a factor of at least :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:7)
The derivative evaluation procedure set the error flag :math:\mathrm{ires} = 3 repeatedly despite attempts by the integrator to avoid this.

(errno :math:9)
A singular Jacobian has been encountered. You should check the problem formulation and Jacobian calculation.

(errno :math:10)
Workspace error occurred when trying to form the Jacobian matrix in calculating the initial values of the solution and its time derivative.

(errno :math:10)
Not enough integer store provided for sparse matrix solver.

Units of store needed: :math:\langle\mathit{\boldsymbol{value}}\rangle. Amount provided: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:10)
Larger integer workspace required.

Provided: :math:\langle\mathit{\boldsymbol{value}}\rangle; required: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:10)
Not enough real store provided for sparse matrix solver.

Units of store needed: :math:\langle\mathit{\boldsymbol{value}}\rangle. Amount provided: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:14)
On entry, too much accuracy requested for precision of the machine at the start of problem. The tolerances should be checked; the requested accuracy should be reduced by a factor of at least :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:15)
The linear algebra setup function for sparse Jacobian was not called first.

**Warns**
**NagAlgorithmicWarning**
(errno :math:4)
There were repeated error-test failures on an attempted step, before completing the requested task, but the integration was successful as far as :math:\mathrm{t}. The problem may have a singularity, or the local error requirements may be inappropriate.

(errno :math:5)
There were repeated convergence-test failures on an attempted step, before completing the requested task, but the integration was successful as far as :math:\mathrm{t}. This may be caused by an inaccurate Jacobian matrix or one which is incorrectly computed.

(errno :math:6)
At time :math:\langle\mathit{\boldsymbol{value}}\rangle, error weight :math:\langle\mathit{\boldsymbol{value}}\rangle became zero. Check the values of :math:\mathrm{atol}, :math:\mathrm{rtol} and :math:\mathrm{itol} supplied.

(errno :math:6)
Weight number :math:i = \langle\mathit{\boldsymbol{value}}\rangle used in the local error test is too small. Check the values of :math:\mathrm{rtol} and :math:\mathrm{atol}.

:math:\mathrm{atol}[i-1] and :math:\mathrm{y}[i-1] may both be zero.

Weight :math:i = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:11)
:math:\mathrm{fcn} set :math:\mathrm{ires} = 2, which signals that the integration should terminate. :math:\mathrm{ires} = \langle\mathit{\boldsymbol{value}}\rangle at time :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:12)
A return was forced by setting :math:\mathrm{imon} = -2, but the integration was successful as far as :math:\mathrm{t}.

(errno :math:13)
The requested task has been completed, but it is estimated that a small change in :math:\mathrm{rtol} and :math:\mathrm{atol} is unlikely to produce any change in the computed solution. (This ONLY applies when you are NOT operating in one step mode; that is, when :math:\mathrm{itask} \neq 2 or :math:5.)

.. _d02nd-py2-py-notes:

**Notes**
No equivalent traditional C interface for this routine exists in the NAG Library.

ivp_stiff_exp_sparjac is a general purpose function for integrating the initial value problem for a stiff system of explicit ordinary differential equations,

.. math::
y^{\prime } = g\left(t, y\right)\text{.}

It is designed specifically for the case where the Jacobian :math:\frac{{\partial g}}{{\partial y}} is a sparse matrix.

Both interval and step oriented modes of operation are available and also modes designed to permit intermediate output within an interval oriented mode.

A typical calling program for ivp_stiff_exp_sparjac would involve calling the sparse matrix linear algebra setup function :meth:ivp_stiff_sparjac_setup, the Backward Differentiation Formula (BDF) integrator setup function :meth:ivp_stiff_bdf, its diagnostic counterpart :meth:ivp_stiff_integ_diag, and the sparse linear algebra diagnostic function :meth:ivp_stiff_sparjac_diag as well as the call to ivp_stiff_exp_sparjac.
The linear algebra setup function :meth:ivp_stiff_sparjac_setup and one of the integrator setup functions, :meth:ivp_stiff_bdf or :meth:ivp_stiff_blend, must be called prior to the call of ivp_stiff_exp_sparjac.
Either or both of the integrator diagnostic function :meth:ivp_stiff_integ_diag, or the sparse matrix linear algebra diagnostic function :meth:ivp_stiff_sparjac_diag, may be called after the call to ivp_stiff_exp_sparjac.
There is also a function, :meth:ivp_stiff_contin, designed to permit you to change step size on a continuation call to ivp_stiff_exp_sparjac without restarting the integration process.
"""
raise NotImplementedError

[docs]def dae_dassl_gen(t, tout, y, ydot, rtol, atol, itask, res, comm, jac=None, data=None):
r"""
dae_dassl_gen is a function for integrating stiff systems of implicit ordinary differential equations coupled with algebraic equations.

.. _d02ne-py2-py-doc:

For full information please refer to the NAG Library document for d02ne

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02nef.html

.. _d02ne-py2-py-parameters:

**Parameters**
**t** : float
On initial entry: the initial value of the independent variable, :math:t.

**tout** : float
The next value of :math:t at which a computed solution is desired.

On initial entry: :math:\mathrm{tout} is used to determine the direction of integration. Integration is permitted in either direction (see also :math:\mathrm{itask}).

**y** : float, array-like, shape :math:\left(\textit{neq}\right)
On initial entry: the vector of initial values of the dependent variables :math:y.

**ydot** : float, array-like, shape :math:\left(\textit{neq}\right)
On initial entry: :math:\mathrm{ydot} must contain approximations to the time derivatives :math:y^{\prime } of the vector :math:y evaluated at the initial value of the independent variable.

**rtol** : float, array-like, shape :math:\left(:\right)
Note: the required length for this argument is determined as follows: if :math:\mathrm{comm}\ ['icom'][1]=1: :math:\textit{neq}; if :math:\mathrm{comm}\ ['icom'][1]=0: :math:1; otherwise: :math:0.

The relative local error tolerance.

**atol** : float, array-like, shape :math:\left(:\right)
Note: the required length for this argument is determined as follows: if :math:\mathrm{comm}\ ['icom'][1]=1: :math:\textit{neq}; if :math:\mathrm{comm}\ ['icom'][1]=0: :math:1; otherwise: :math:0.

The absolute local error tolerance.

On initial entry: need not be set.

**res** : callable (r, ires) = res(t, y, ydot, ires, data=None)
:math:\mathrm{res} must evaluate the residual

.. math::
R = F\left(t, y, y^{\prime }\right)\text{.}

**Parameters**
**t** : float
:math:t, the current value of the independent variable.

**y** : float, ndarray, shape :math:\left(\textit{neq}\right)
:math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{neq}, the current solution component.

**ydot** : float, ndarray, shape :math:\left(\textit{neq}\right)
The derivative of the solution at the current point :math:t.

**ires** : int
Is always equal to zero.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**r** : float, array-like, shape :math:\left(\textit{neq}\right)
:math:\mathrm{r}[\textit{i}-1] must contain the :math:\textit{i}\ th component of :math:R, for :math:\textit{i} = 1,2,\ldots,\textit{neq} where

.. math::
R = F\left(\mathrm{t}, \mathrm{y}, \mathrm{ydot}\right)\text{.}

**ires** : int
:math:\mathrm{ires} should normally be left unchanged. However, if an illegal value of :math:\mathrm{y} is encountered, :math:\mathrm{ires} should be set to :math:-1; dae_dassl_gen will then attempt to resolve the problem so that illegal values of :math:\mathrm{y} are not encountered. :math:\mathrm{ires} should be set to :math:-2 if you wish to return control to the calling function; this will cause dae_dassl_gen to exit with :math:\mathrm{errno} = 23.

**comm** : dict, communication object, modified in place
Communication structure.

This argument must have been initialized by a prior call to :meth:dae_dassl_setup.

**jac** : None or callable pd = jac(t, y, ydot, pd, cj, data=None), optional
Note: if this argument is **None** then a NAG-supplied facility will be used.

Evaluates the matrix of partial derivatives, :math:J, where

.. math::
J_{{ij}} = \frac{{\partial F_i}}{{\partial y_j}}+\mathrm{cj}\times \frac{{\partial F_i}}{{\partial y^{\prime }_j}}\text{, }\quad i,j = 1,2,\ldots,\textit{neq}\text{.}

If this option is not required, the actual argument for :math:\mathrm{jac} must be **None**. You must indicate to the integrator whether this option is to be used by setting the argument :math:\textit{jceval} appropriately in a call to the setup function :meth:dae_dassl_setup.

**Parameters**
**t** : float
:math:t, the current value of the independent variable.

**y** : float, ndarray, shape :math:\left(\textit{neq}\right)
:math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{neq}, the current solution component.

**ydot** : float, ndarray, shape :math:\left(\textit{neq}\right)
The derivative of the solution at the current point :math:t.

**pd** : float, ndarray, shape :math:\left(:\right)
:math:\mathrm{pd} is preset to zero before the call to :math:\mathrm{jac}.

**cj** : float
:math:\mathrm{cj} is a scalar constant which will be defined in dae_dassl_gen.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**pd** : float, array-like, shape :math:\left(:\right)
If the Jacobian is full then :math:\mathrm{pd}[\left(\textit{j}-1\right)\times \textit{neq}+\textit{i}-1] = J_{{\textit{i}\textit{j}}}, for :math:\textit{j} = 1,2,\ldots,\textit{neq}, for :math:\textit{i} = 1,2,\ldots,\textit{neq}; if the Jacobian is banded then :math:\mathrm{pd}[\left(j-1\right)\times \left(2{\textit{ml}}+{\textit{mu}}+1\right)+{\textit{ml}}+{\textit{mu}}+i-j] = J_{{ij}}, for :math:\mathrm{max}\left(1, {j-{\textit{mu}}}\right)\leq i\leq \mathrm{min}\left(n, {j+{\textit{ml}}}\right).

**data** : arbitrary, optional
User-communication data for callback functions.

**Returns**
**t** : float
On intermediate exit: :math:t, the current value of the independent variable.

On final exit: the value of the independent variable at which the computed solution :math:y is returned (usually at :math:\mathrm{tout}).

**y** : float, ndarray, shape :math:\left(\textit{neq}\right)
On intermediate exit: the computed solution vector, :math:y, evaluated at :math:t = T.

On final exit: the computed solution vector, evaluated at :math:t (usually :math:t = \mathrm{tout}).

**ydot** : float, ndarray, shape :math:\left(\textit{neq}\right)
The time derivatives :math:y^{\prime } of the vector :math:y at the last integration point.

**rtol** : float, ndarray, shape :math:\left(:\right)
:math:\mathrm{rtol} remains unchanged unless dae_dassl_gen exits with :math:\mathrm{errno} = 16 in which case the values may have been increased to values estimated to be appropriate for continuing the integration.

**atol** : float, ndarray, shape :math:\left(:\right)
:math:\mathrm{atol} remains unchanged unless dae_dassl_gen exits with :math:\mathrm{errno} = 16 in which case the values may have been increased to values estimated to be appropriate for continuing the integration.

The task performed by the integrator on successful completion or an indicator that a problem occurred during integration.

:math:\mathrm{itask} = 2

The integration to :math:\mathrm{tout} was successfully completed (:math:\mathrm{t} = \mathrm{tout}) by stepping exactly to :math:\mathrm{tout}.

:math:\mathrm{itask} = 3

The integration to :math:\mathrm{tout} was successfully completed (:math:\mathrm{t} = \mathrm{tout}) by stepping past :math:\mathrm{tout}. :math:\mathrm{y} and :math:\mathrm{ydot} are obtained by interpolation.

:math:\mathrm{itask} < 0

Different negative values of :math:\mathrm{itask} returned correspond to different failure exits. :math:\textit{errno} should always be checked in such cases and the corrective action taken where appropriate.

:math:\mathrm{itask} must remain **unchanged** between calls to dae_dassl_gen.

.. _d02ne-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:\textit{neq} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\textit{neq}\geq 1.

(errno :math:3)
On entry, :math:\mathrm{t} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{tout}\neq \mathrm{t}.

(errno :math:3)
:math:\mathrm{tout} is too close to :math:\mathrm{t} to start integration: :math:\mathrm{tout}-\mathrm{t} = \langle\mathit{\boldsymbol{value}}\rangle: :math:\textit{hmin} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:3)
:math:\mathrm{tout} is behind :math:\mathrm{t} in the direction of :math:h: :math:\mathrm{tout}-\mathrm{t} = \langle\mathit{\boldsymbol{value}}\rangle, :math:h = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:6)
Some element of :math:\mathrm{rtol} is less than zero.

(errno :math:7)
Some element of :math:\mathrm{atol} is less than zero.

(errno :math:8)
A previous call to this function returned with :math:\mathrm{itask} = \langle\mathit{\boldsymbol{value}}\rangle and no appropriate action was taken.

(errno :math:11)
Either the initialization function has not been called prior to the first call of this function or a communication array has become corrupted.

(errno :math:12)
Either the initialization function has not been called prior to the first call of this function or a communication array has become corrupted.

(errno :math:13)
:math:\mathrm{comm}\ ['com'] array is of insufficient length; length required :math:\text{} = \langle\mathit{\boldsymbol{value}}\rangle; actual length :math:\textit{lcom} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:14)
All elements of :math:\mathrm{rtol} and :math:\mathrm{atol} are zero.

(errno :math:15)
Maximum number of steps taken on this call before reaching :math:\mathrm{tout}: :math:\mathrm{t} = \langle\mathit{\boldsymbol{value}}\rangle, maximum number of steps :math:\text{} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:16)
Too much accuracy requested for precision of machine. :math:\mathrm{rtol} and :math:\mathrm{atol} were increased by scale factor :math:R. Try running again with these scaled tolerances. :math:\mathrm{t} = \langle\mathit{\boldsymbol{value}}\rangle, :math:R = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:17)
A solution component has become zero when a purely relative tolerance (zero absolute tolerance) was selected for that component. :math:\mathrm{t} = \langle\mathit{\boldsymbol{value}}\rangle, :math:\mathrm{y}[\textit{I}-1] = \langle\mathit{\boldsymbol{value}}\rangle for component :math:\textit{I} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:18)
The error test failed repeatedly with :math:\left\lvert h\right\rvert = \textit{hmin}. :math:\mathrm{t} = \langle\mathit{\boldsymbol{value}}\rangle. Stepsize :math:h = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:19)
The corrector repeatedly failed to converge with :math:\left\lvert h\right\rvert = \textit{hmin}. :math:\mathrm{t} = \langle\mathit{\boldsymbol{value}}\rangle. Stepsize :math:h = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:20)
The iteration matrix is singular. :math:\mathrm{t} = \langle\mathit{\boldsymbol{value}}\rangle. Stepsize :math:h = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:21)
The corrector could not converge and the error test failed repeatedly. :math:\mathrm{t} = \langle\mathit{\boldsymbol{value}}\rangle. Stepsize :math:h = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:22)
:math:\mathrm{ires} was set to :math:-1 during a call to :math:\mathrm{res} and could not be resolved. :math:\mathrm{t} = \langle\mathit{\boldsymbol{value}}\rangle. Stepsize :math:h = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:23)
:math:\mathrm{ires} was set to :math:-2 during a call to :math:\mathrm{res}. :math:\mathrm{t} = \langle\mathit{\boldsymbol{value}}\rangle. Stepsize :math:\text{} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:24)
The initial :math:\mathrm{ydot} could not be computed. :math:\mathrm{t} = \langle\mathit{\boldsymbol{value}}\rangle. Stepsize :math:h = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:25)
Repeated occurrences of input constraint violations have been detected. This could result in a potential infinite loop: :math:\mathrm{itask} = \langle\mathit{\boldsymbol{value}}\rangle. Current violation corresponds to exit with :math:\textit{errno} = \langle\mathit{\boldsymbol{value}}\rangle.

.. _d02ne-py2-py-notes:

**Notes**
dae_dassl_gen is a general purpose function for integrating the initial value problem for a stiff system of implicit ordinary differential equations with coupled algebraic equations written in the form

.. math::
F\left(t, y, y^{\prime }\right) = 0\text{.}

dae_dassl_gen uses the DASSL implementation of the Backward Differentiation Formulae (BDF) of orders one to five to solve a system of the above form for :math:y (:math:\mathrm{y}) and :math:y^{\prime } (:math:\mathrm{ydot}).
Values for :math:\mathrm{y} and :math:\mathrm{ydot} at the initial time must be given as input.
These values must be consistent, (i.e., if :math:\mathrm{t}, :math:\mathrm{y}, :math:\mathrm{ydot} are the given initial values, they must satisfy :math:F\left(\mathrm{t}, \mathrm{y}, \mathrm{ydot}\right) = 0).
The function solves the system from :math:t = \mathrm{t} to :math:t = \mathrm{tout}.

A typical calling progrm for dae_dassl_gen would involve calling the DASSL implementation of the BDF integrator setup function :meth:dae_dassl_setup and the banded matrix setup function :meth:dae_dassl_linalg (if required), and, if the integration needs to proceed, calls :meth:dae_dassl_cont before continuing the integration.
"""
raise NotImplementedError

[docs]def ivp_stiff_imp_fulljac(t, tout, y, ydot, comm, rtol, atol, itol, resid, lderiv, itask, itrace, jac=None, monitr=None, data=None, io_manager=None, spiked_sorder='C'):
r"""
ivp_stiff_imp_fulljac is a direct communication function for integrating stiff systems of implicit ordinary differential equations coupled with algebraic equations when the Jacobian is a full matrix.

.. _d02ng-py2-py-doc:

For full information please refer to the NAG Library document for d02ng

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02ngf.html

.. _d02ng-py2-py-parameters:

**Parameters**
**t** : float
:math:t, the value of the independent variable. The input value of :math:\mathrm{t} is used only on the first call as the initial point of the integration.

**tout** : float
The next value of :math:t at which a computed solution is desired. For the initial :math:t, the input value of :math:\mathrm{tout} is used to determine the direction of integration. Integration is permitted in either direction (see also :math:\mathrm{itask}).

**y** : float, array-like, shape :math:\left(\textit{neq}\right)
The values of the dependent variables (solution). On the first call the first :math:\textit{neq} elements of :math:\mathrm{y} must contain the vector of initial values.

**ydot** : float, array-like, shape :math:\left(\textit{neq}\right)
If :math:\mathrm{lderiv}[0] = \mathbf{True}, :math:\mathrm{ydot} must contain approximations to the time derivatives :math:y^{\prime } of the vector :math:y.

If :math:\mathrm{lderiv}[0] = \mathbf{False}, :math:\mathrm{ydot} need not be set on entry.

**comm** : dict, communication object, modified in place
Communication structure.

This argument must have been initialized by prior calls to :meth:ivp_stiff_fulljac_setup and one of :meth:ivp_stiff_dassl, :meth:ivp_stiff_bdf or :meth:ivp_stiff_blend.

**rtol** : float, array-like, shape :math:\left(:\right)
Note: the required length for this argument is determined as follows: if :math:\mathrm{itol}\text{ in } (1, 2): :math:1; otherwise: :math:\textit{neq}.

The relative local error tolerance.

**atol** : float, array-like, shape :math:\left(:\right)
Note: the required length for this argument is determined as follows: if :math:\mathrm{itol}\text{ in } (1, 3): :math:1; otherwise: :math:\textit{neq}.

The absolute local error tolerance.

**itol** : int
A value to indicate the form of the local error test. :math:\mathrm{itol} indicates to ivp_stiff_imp_fulljac whether to interpret either or both of :math:\mathrm{rtol} or :math:\mathrm{atol} as a vector or a scalar. The error test to be satisfied is :math:\left\lVert e_i/w_i\right\rVert < 1.0, where :math:w_i is defined as follows:

+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+
|:math:\mathrm{itol}|:math:\mathrm{rtol}|:math:\mathrm{atol}|:math:w_i                                                                     |
+=====================+=====================+=====================+================================================================================+
|1                    |scalar               |scalar               |:math:\mathrm{rtol}[0]\times \left\lvert y_i\right\rvert +\mathrm{atol}[0]    |
+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+
|2                    |scalar               |vector               |:math:\mathrm{rtol}[0]\times \left\lvert y_i\right\rvert +\mathrm{atol}[i-1]  |
+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+
|3                    |vector               |scalar               |:math:\mathrm{rtol}[i-1]\times \left\lvert y_i\right\rvert +\mathrm{atol}[0]  |
+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+
|4                    |vector               |vector               |:math:\mathrm{rtol}[i-1]\times \left\lvert y_i\right\rvert +\mathrm{atol}[i-1]|
+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+

:math:e_i is an estimate of the local error in :math:y_i, computed internally, and the choice of norm to be used is defined by a previous call to an integrator setup function.

**resid** : callable (r, ires) = resid(t, y, ydot, ires, data=None)
:math:\mathrm{resid} must evaluate the residual

.. math::
r = g\left(t, y\right)-A\left(t, y\right)y^{\prime }

in one case and

.. math::
r = -A\left(t, y\right)y^{\prime }

in another.

**Parameters**
**t** : float
:math:t, the current value of the independent variable.

**y** : float, ndarray, shape :math:\left(\textit{neq}\right)
The value of :math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{neq}.

**ydot** : float, ndarray, shape :math:\left(\textit{neq}\right)
The value of :math:y_{\textit{i}}^{\prime }, for :math:\textit{i} = 1,2,\ldots,\textit{neq}, at :math:t.

**ires** : int
The form of the residual that must be returned in array :math:\mathrm{r}.

:math:\mathrm{ires} = -1

The residual defined in equation (2) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02ngf.html#eqn2>__ must be returned.

:math:\mathrm{ires} = 1

The residual defined in equation (1) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02ngf.html#eqn1>__ must be returned.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**r** : float, array-like, shape :math:\left(\textit{neq}\right)
:math:\mathrm{r}[\textit{i}-1] must contain the :math:\textit{i}\ th component of :math:r, for :math:\textit{i} = 1,2,\ldots,\textit{neq}, where

.. math::
r = g\left(t, y\right)-A\left(t, y\right)y^{\prime }

or

.. math::
r = -A\left(t, y\right)y^{\prime }

and where the definition of :math:r is determined by the input value of :math:\mathrm{ires}.

**ires** : int
Should be unchanged unless one of the following actions is required of the integrator, in which case :math:\mathrm{ires} should be set accordingly.

:math:\mathrm{ires} = 2

Indicates to the integrator that control should be passed back immediately to the calling (sub)program with the error indicator set to :math:\mathrm{errno} = 11.

:math:\mathrm{ires} = 3

Indicates to the integrator that an error condition has occurred in the solution vector, its time derivative or in the value of :math:t. The integrator will use a smaller time step to try to avoid this condition. If this is not possible, the integrator returns to the calling (sub)program with the error indicator set to :math:\mathrm{errno} = 7.

:math:\mathrm{ires} = 4

Indicates to the integrator to stop its current operation and to enter :math:\mathrm{monitr} immediately with argument :math:\mathrm{imon} = -2.

**lderiv** : bool, array-like, shape :math:\left(2\right)
:math:\mathrm{lderiv}[0] must be set to :math:\mathbf{True} if you have supplied both an initial :math:y and an initial :math:y^{\prime }. :math:\mathrm{lderiv}[0] must be set to :math:\mathbf{False} if only the initial :math:y has been supplied.

:math:\mathrm{lderiv}[1] must be set to :math:\mathbf{True} if the integrator is to use a modified Newton method to evaluate the initial :math:y and :math:y^{\prime }.

Note that :math:y and :math:y^{\prime }, if supplied, are used as initial estimates.

This method involves taking a small step at the start of the integration, and if :math:\mathrm{itask} = 6 on entry, :math:\mathrm{t} and :math:\mathrm{tout} will be set to the result of taking this small step. :math:\mathrm{lderiv}[1] must be set to :math:\mathbf{False} if the integrator is to use functional iteration to evaluate the initial :math:y and :math:y^{\prime }, and if this fails a modified Newton method will then be attempted. :math:\mathrm{lderiv}[1] = \mathbf{True} is recommended if there are implicit equations or the initial :math:y and :math:y^{\prime } are zero.

The task to be performed by the integrator.

:math:\mathrm{itask} = 1

Normal computation of output values of :math:y\left(t\right) at :math:t = \mathrm{tout} (by overshooting and interpolating).

:math:\mathrm{itask} = 2

Take one step only and return.

:math:\mathrm{itask} = 3

Stop at the first internal integration point at or beyond :math:t = \mathrm{tout} and return.

:math:\mathrm{itask} = 4

Normal computation of output values of :math:y\left(t\right) at :math:t = \mathrm{tout} but without overshooting :math:t = {\textit{tcrit}}. :math:\textit{tcrit} must be specified as an option in one of the integrator setup functions before the first call to the integrator, or specified in the optional input function before a continuation call. :math:\textit{tcrit} may be equal to or beyond :math:\mathrm{tout}, but not before it, in the direction of integration.

:math:\mathrm{itask} = 5

Take one step only and return, without passing :math:\textit{tcrit}. :math:\textit{tcrit} must be specified as under :math:\mathrm{itask} = 4.

:math:\mathrm{itask} = 6

The integrator will solve for the initial values of :math:y and :math:y^{\prime } only and then return to the calling (sub)program without doing the integration. This option can be used to check the initial values of :math:y and :math:y^{\prime }. Functional iteration or a 'small' backward Euler method used in conjunction with a damped Newton iteration is used to calculate these values (see :math:\mathrm{lderiv}). Note that if a backward Euler step is used then the value of :math:t will have been advanced a short distance from the initial point.

**Note:** if ivp_stiff_imp_fulljac is recalled with a different value of :math:\mathrm{itask} (and :math:\mathrm{tout} altered), the initialization procedure is repeated, possibly leading to different initial conditions.

**itrace** : int
The level of output that is printed by the integrator. :math:\mathrm{itrace} may take the value :math:-1, :math:0, :math:1, :math:2 or :math:3.

:math:\mathrm{itrace} < -1

:math:-1 is assumed and similarly if :math:\mathrm{itrace} > 3, :math:3 is assumed.

:math:\mathrm{itrace} = -1

No output is generated.

:math:\mathrm{itrace} = 0

Only warning messages are printed on the current error message unit (see :class:~naginterfaces.base.utils.FileObjManager).

:math:\mathrm{itrace} > 0

Warning messages are printed as above, and on the file object associated with the advisory I/O unit (see :class:~naginterfaces.base.utils.FileObjManager) output is generated which details Jacobian entries, the nonlinear iteration and the time integration. The advisory messages are given in greater detail the larger the value of :math:\mathrm{itrace}.

**jac** : None or callable p = jac(t, y, ydot, h, d, p, data=None), optional
Note: if this argument is **None** then a NAG-supplied facility will be used.

:math:\mathrm{jac} must evaluate the Jacobian of the system.

If this option is not required, the actual argument for :math:\mathrm{jac} must be **None**. You must indicate to the integrator whether this option is to be used by setting the argument :math:\textit{jceval} appropriately in a call to the full linear algebra setup function :meth:ivp_stiff_fulljac_setup.

First we must define the system of nonlinear equations which is solved internally by the integrator.

The time derivative, :math:y^{\prime }, generated internally, has the form

.. math::
y^{\prime } = \left(y-z\right)/\left(hd\right)\text{,}

where :math:h is the current step size and :math:d is an argument that depends on the integration method in use.

The vector :math:y is the current solution and the vector :math:z depends on information from previous time steps.

This means that :math:\frac{d}{{dy^{\prime }}}\left(\text{ }\right) = \left(hd\right)\frac{d}{{dy}}\left(\text{ }\right).

The system of nonlinear equations that is solved has the form

.. math::
A\left(t, y\right)y^{\prime }-g\left(t, y\right) = 0

but it is solved in the form

.. math::
r\left(t, y\right) = 0\text{,}

where :math:r is the function defined by

.. math::
r\left(t, y\right) = \left(hd\right)\left({A\left(t, y\right)\left(y-z\right)/\left(hd\right)-g\left(t, y\right)}\right)\text{.}

It is the Jacobian matrix :math:\frac{{\partial r}}{{\partial y}} that you must supply in :math:\mathrm{jac} as follows:

.. math::
\frac{{\partial r_i}}{{\partial y_j}} = a_{{ij}}\left(t, y\right)+\left(hd\right)\frac{\partial }{{\partial y_j}}\left(\sum_{{k = 1}}^{\textit{neq}}a_{{ik}}\left(t, y\right)y_k^{\prime }-g_i\left(t, y\right)\right)\text{.}

Here :math:a_{{ij}} is the :math:ij\ th element of :math:A, i.e., the function (of :math:y and :math:t) multiplying :math:y_j^{\prime } in the :math:i\ th differential equation.

Also :math:y_k^{\prime } in the summation should be considered as a function of time so that the partial derivative affects only the :math:a_{{ik}} terms.

**Parameters**
**t** : float
:math:t, the current value of the independent variable.

**y** : float, ndarray, shape :math:\left(\textit{neq}\right)
:math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{neq}, the current solution component.

**ydot** : float, ndarray, shape :math:\left(\textit{neq}\right)
The derivative of the solution at the current point :math:t.

**h** : float
The current step size.

**d** : float
The argument :math:d which depends on the integration method.

**p** : float, ndarray, shape :math:\left(\textit{neq}, \textit{neq}\right)
Is set to zero.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**p** : float, array-like, shape :math:\left(\textit{neq}, \textit{neq}\right)
:math:\mathrm{p}[\textit{i}-1,\textit{j}-1] must contain :math:\frac{{\partial r_{\textit{i}}}}{{\partial y_{\textit{j}}}}, for :math:\textit{j} = 1,2,\ldots,\textit{neq}, for :math:\textit{i} = 1,2,\ldots,\textit{neq}.

Only the nonzero elements of this array need be set, since it is preset to zero before the call to :math:\mathrm{jac}.

**monitr** : None or callable (hnext, y, imon, inln, hmin, hmax) = monitr(t, hlast, hnext, y, ydot, comm, r, acor, imon, hmin, hmax, nqu, data=None), optional
Note: if this argument is **None** then a NAG-supplied facility will be used.

:math:\mathrm{monitr} performs tasks requested by you.

If this option is not required, the actual argument for :math:\mathrm{monitr} must be **None**.

**Parameters**
**t** : float
The current value of the independent variable.

**hlast** : float
The last step size successfully used by the integrator.

**hnext** : float
The step size that the integrator proposes to take on the next step.

**y** : float, ndarray, shape :math:\left(\textit{neq}\right)
:math:y, the values of the dependent variables evaluated at :math:t.

**ydot** : float, ndarray, shape :math:\left(\textit{neq}\right)
The time derivatives :math:y^{\prime } of the vector :math:y.

**comm** : dict, communication object, modifiable in place
Communication structure.

This argument may be passed as argument :math:\textit{comm} in a call to :meth:ivp_stiff_nat_interp or :math:\textit{comm} in a call to :meth:ivp_stiff_c1_interp to enable you to carry out interpolation using either of those functions.

**r** : float, ndarray, shape :math:\left(\textit{neq}\right)
If :math:\mathrm{imon} = 0 and :math:\mathrm{inln} = 3, the first :math:\textit{neq} elements contain the residual vector :math:A\left(t, y\right)y^{\prime }-g\left(t, y\right).

**acor** : float, ndarray, shape :math:\left(\textit{neq}, 2\right)
With :math:\mathrm{imon} = 1, :math:\mathrm{acor}[i-1,0] contains the weight used for the :math:i\ th equation when the norm is evaluated, and :math:\mathrm{acor}[i-1,1] contains the estimated local error for the :math:i\ th equation. The scaled local error at the end of a timestep may be obtained by calling :meth:ivp_stiff_errest.

**imon** : int
A flag indicating under what circumstances :math:\mathrm{monitr} was called:

:math:\mathrm{imon} = -2

Entry from the integrator after :math:\mathrm{ires} = 4 (set in :math:\mathrm{resid}) caused an early termination (this facility could be used to locate discontinuities).

:math:\mathrm{imon} = -1

The current step failed repeatedly.

:math:\mathrm{imon} = 0

Entry after a call to the internal nonlinear equation solver (see :math:\mathrm{inln}).

:math:\mathrm{imon} = 1

The current step was successful.

**hmin** : float
The minimum step size to be taken on the next step.

**hmax** : float
The maximum step size to be taken on the next step.

**nqu** : int
The order of the integrator used on the last step. This is supplied to enable you to carry out interpolation using either of the functions :meth:ivp_stiff_nat_interp or :meth:ivp_stiff_c1_interp.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**hnext** : float
The next step size to be used. If this is different from the input value, :math:\mathrm{imon} must be set to :math:4.

**y** : float, array-like, shape :math:\left(\textit{neq}\right)
These values must not be changed unless :math:\mathrm{imon} is set to :math:2.

**imon** : int
May be reset to determine subsequent action in ivp_stiff_imp_fulljac.

:math:\mathrm{imon} = -2

Integration is to be halted. A return will be made from the integrator to the calling (sub)program with :math:\mathrm{errno} = 12.

:math:\mathrm{imon} = -1

Allow the integrator to continue with its own internal strategy. The integrator will try up to three restarts unless :math:\mathrm{imon} \neq -1 on exit.

:math:\mathrm{imon} = 0

Return to the internal nonlinear equation solver, where the action taken is determined by the value of :math:\mathrm{inln} (see :math:\mathrm{inln}).

:math:\mathrm{imon} = 1

Normal exit to the integrator to continue integration.

:math:\mathrm{imon} = 2

Restart the integration at the current time point. The integrator will restart from order :math:1 when this option is used. The solution :math:\mathrm{y}, provided by :math:\mathrm{monitr}, will be used for the initial conditions.

:math:\mathrm{imon} = 3

Try to continue with the same step size and order as was to be used before the call to :math:\mathrm{monitr}. :math:\mathrm{hmin} and :math:\mathrm{hmax} may be altered if desired.

:math:\mathrm{imon} = 4

Continue the integration but using a new value of :math:\mathrm{hnext} and possibly new values of :math:\mathrm{hmin} and :math:\mathrm{hmax}.

**inln** : int
The action to be taken by the internal nonlinear equation solver when :math:\mathrm{monitr} is exited with :math:\mathrm{imon} = 0. By setting :math:\mathrm{inln} = 3 and returning to the integrator, the residual vector is evaluated and placed in the array :math:\mathrm{r}, and then :math:\mathrm{monitr} is called again. At present this is the only option available: :math:\mathrm{inln} must not be set to any other value.

**hmin** : float
The minimum step size to be used. If this is different from the input value, :math:\mathrm{imon} must be set to :math:3 or :math:4.

**hmax** : float
The maximum step size to be used. If this is different from the input value, :math:\mathrm{imon} must be set to :math:3 or :math:4. If :math:\mathrm{hmax} is set to zero, no limit is assumed.

**data** : arbitrary, optional
User-communication data for callback functions.

**io_manager** : FileObjManager, optional
Manager for I/O in this routine.

**spiked_sorder** : str, optional
If :math:\mathrm{p} in :math:\mathrm{jac} is spiked (i.e., has unit extent in all but one dimension, or has size :math:1), :math:\mathrm{spiked\_sorder} selects the storage order to associate with it in the NAG Engine:

spiked_sorder = :math:\texttt{'C'}
row-major storage will be used;

spiked_sorder = :math:\texttt{'F'}
column-major storage will be used.

**Returns**
**t** : float
The value at which the computed solution :math:y is returned (usually at :math:\mathrm{tout}).

**tout** : float
Normally unchanged. However, when :math:\mathrm{itask} = 6, :math:\mathrm{tout} contains the value of :math:\mathrm{t} at which initial values have been computed without performing any integration. See descriptions of :math:\mathrm{itask} and :math:\mathrm{lderiv}.

**y** : float, ndarray, shape :math:\left(\textit{neq}\right)
The computed solution vector, evaluated at :math:\mathrm{t} (usually :math:\mathrm{t} = \mathrm{tout}).

**ydot** : float, ndarray, shape :math:\left(\textit{neq}\right)
The time derivatives :math:y^{\prime } of the vector :math:y at the last integration point.

**lderiv** : bool, ndarray, shape :math:\left(2\right)
:math:\mathrm{lderiv}[0] is normally unchanged. However if :math:\mathrm{itask} = 6 and internal initialization was successful then :math:\mathrm{lderiv}[0] = \mathbf{True}.

:math:\mathrm{lderiv}[1] = \mathbf{True}, if implicit equations were detected.

Otherwise :math:\mathrm{lderiv}[1] = \mathbf{False}.

.. _d02ng-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:\mathrm{ires} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\frac{{dy}}{{dt}} = 0.0 for all elements.

Check the evaluation of the residual for this value of :math:\mathrm{ires}.

(errno :math:1)
:math:\mathrm{ires} was set to an illegal value during initialization.

:math:\mathrm{ires} = \langle\mathit{\boldsymbol{value}}\rangle at time :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
:math:\mathrm{monitr} set :math:\mathrm{imon} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:-2\leq \mathrm{imon}\leq 4.

(errno :math:1)
Failure during internal time interpolation. :math:\mathrm{tout} and the current time are too close.

:math:\mathrm{itask} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle and the current time is :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{itask} = 4 or :math:5 and :math:\textit{tcrit} is before the current time in the direction of integration.

:math:\mathrm{itask} = \langle\mathit{\boldsymbol{value}}\rangle, :math:{\textit{tcrit}} = \langle\mathit{\boldsymbol{value}}\rangle and the current time is :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
:math:\mathrm{itask} = 3 and :math:\mathrm{tout} is more than an integration step behind the current time.

:math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle, current time minus step size: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
The initial stepsize, :math:\langle\mathit{\boldsymbol{value}}\rangle, is too small.

(errno :math:1)
Weight number :math:i = \langle\mathit{\boldsymbol{value}}\rangle used in the local error test is too small. Check the values of :math:\mathrm{rtol} and :math:\mathrm{atol}.

:math:\mathrm{atol}[i-1] and :math:\mathrm{y}[i-1] may both be zero.

Weight :math:i = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{itask} = 4 or :math:5 and :math:\textit{tcrit} is before :math:\mathrm{tout} in the direction of integration.

:math:\mathrm{itask} = \langle\mathit{\boldsymbol{value}}\rangle, :math:{\textit{tcrit}} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{atol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{atol}\geq 0.0.

(errno :math:1)
On entry, :math:\mathrm{rtol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{rtol}\geq 0.0.

(errno :math:1)
Either the value of :math:\textit{sdysav} is not the same as the value supplied to the setup function or a communication array has become corrupted.

:math:\textit{sdysav} = \langle\mathit{\boldsymbol{value}}\rangle, :math:\textit{sdysav} (setup) :math:{} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, an illegal (negative) minimum stepsize was provided in a prior call to a setup function. :math:\mathrm{hmin} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{tout} is less than :math:\mathrm{t} with respect to the direction of integration given by the sign of :math:\textit{h0} in a prior call to a setup function.

:math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle, :math:\mathrm{t} = \langle\mathit{\boldsymbol{value}}\rangle and :math:{\textit{h0}} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, an illegal (negative) maximum number of steps was provided in a prior call to a setup function. :math:{\textit{maxstp}} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{itol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:1\leq \mathrm{itol}\leq 4.

(errno :math:1)
On entry, :math:\textit{neq} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\textit{ldysav} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\textit{neq}\leq \textit{ldysav}.

(errno :math:1)
On entry, :math:\textit{neq} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\textit{neq}\geq 1.

(errno :math:1)
Either the function was entered on a continuation call without a prior call of this function, or a communication array has become corrupted.

(errno :math:1)
On entry, :math:\mathrm{tout} is too close to :math:\mathrm{t} to start integration.

:math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{t} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{itask} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:1\leq \mathrm{itask}\leq 5.

(errno :math:1)
Either the integrator setup function has not been called prior to the first call of this function, or a communication array has become corrupted.

(errno :math:1)
On entry, an illegal (negative) maximum stepsize was provided in a prior call to a setup function. :math:\mathrm{hmax} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
Either the linear algebra setup function has not been called prior to the first call of this function, or a communication array has become corrupted.

(errno :math:1)
:math:\mathrm{monitr} set :math:\mathrm{inln} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{inln} = 3.

(errno :math:1)
:math:\mathrm{monitr} appears to have overwritten the solution vector.

Further integration will not be attempted.

(errno :math:2)
At time :math:\langle\mathit{\boldsymbol{value}}\rangle the maximum number of allowed steps on this call was taken before reaching the next output point :math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle.

Maximum number of steps :math:{} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:3)
Too much accuracy requested for precision of the machine at time :math:\langle\mathit{\boldsymbol{value}}\rangle.

The tolerances should be checked; the requested accuracy should be reduced by a factor of at least :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:4)
There were repeated error-test failures on an attempted step, before completing the requested task, but the integration was successful as far as :math:\mathrm{t}. The problem may have a singularity, or the local error requirements may be inappropriate.

(errno :math:5)
There were repeated convergence-test failures on an attempted step, before completing the requested task, but the integration was successful as far as :math:\mathrm{t}. This may be caused by an inaccurate Jacobian matrix or one which is incorrectly computed.

(errno :math:6)
At time :math:\langle\mathit{\boldsymbol{value}}\rangle, error weight :math:\langle\mathit{\boldsymbol{value}}\rangle became zero. Check the values of :math:\mathrm{atol}, :math:\mathrm{rtol} and :math:\mathrm{itol} supplied.

(errno :math:7)
:math:\mathrm{resid} set :math:\mathrm{ires} = 3, which signals that an error condition has occurred in the solution vector, its time derivative or in the value of :math:t. It was not possible to remove this condition.

:math:\mathrm{ires} = \langle\mathit{\boldsymbol{value}}\rangle at :math:t = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:8)
Attempt was made to reduce the step size to a value less than the minimum step size during the calculation of initial values.

Minimum stepsize: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:8)
The user problem has one or more inconsistencies between the :math:\mathrm{ires} = 1 and :math:\mathrm{ires} = -1 parts. Integration will not be attempted.

(errno :math:8)
The residual function returned an error when calculating the initial values of the solution and its time derivative.

(errno :math:8)
Workspace error occurred when trying to form the Jacobian matrix in calculating the initial values of the solution and its time derivative.

(errno :math:9)
A singular Jacobian has been encountered. You should check the problem formulation and Jacobian calculation.

(errno :math:10)
Not enough real store provided for sparse matrix solver.

Units of store needed: :math:\langle\mathit{\boldsymbol{value}}\rangle. Amount provided: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:10)
Not enough integer store provided for sparse matrix solver.

Units of store needed: :math:\langle\mathit{\boldsymbol{value}}\rangle. Amount provided: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:10)
Larger integer workspace required.

Provided: :math:\langle\mathit{\boldsymbol{value}}\rangle; required: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:10)
Not enough integer store provided for internal storage pointers.

Units of store needed: :math:\langle\mathit{\boldsymbol{value}}\rangle. Amount provided: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:14)
On entry, too much accuracy requested for precision of the machine at the start of problem. The tolerances should be checked; the requested accuracy should be reduced by a factor of at least :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:15)
Either the full matrix linear algebra setup function was not called first or a communication array has become corrupted.

**Warns**
**NagAlgorithmicWarning**
(errno :math:8)
Nonlinear solver failed to converge using a damped Newton method to solve for initial values.

Damping factor: :math:\langle\mathit{\boldsymbol{value}}\rangle; convergence rate: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:11)
:math:\mathrm{resid} set :math:\mathrm{ires} = 2, which signals that the integration should terminate. :math:\mathrm{ires} = \langle\mathit{\boldsymbol{value}}\rangle at time :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:12)
A return was forced by setting :math:\mathrm{imon} = -2, but the integration was successful as far as :math:\mathrm{t}.

(errno :math:13)
The requested task has been completed, but it is estimated that a small change in :math:\mathrm{rtol} and :math:\mathrm{atol} is unlikely to produce any change in the computed solution. (This ONLY applies when you are NOT operating in one step mode; that is, when :math:\mathrm{itask} \neq 2 or :math:5.)

.. _d02ng-py2-py-notes:

**Notes**
No equivalent traditional C interface for this routine exists in the NAG Library.

ivp_stiff_imp_fulljac is a general purpose function for integrating the initial value problem for a stiff system of implicit ordinary differential equations coupled with algebraic equations, written in the form

.. math::
A\left(t, y\right)y^{\prime } = g\left(t, y\right)\text{.}

It is designed specifically for the case where the resulting Jacobian is a full matrix (see the description of :math:\mathrm{jac}).

Both interval and step oriented modes of operation are available and also modes designed to permit intermediate output within an interval oriented mode.

A typical calling program for ivp_stiff_imp_fulljac would involve calling the full matrix linear algebra setup function :meth:ivp_stiff_fulljac_setup, the Backward Differentiation Formula (BDF) integrator setup function :meth:ivp_stiff_bdf, and its diagnostic counterpart :meth:ivp_stiff_integ_diag as well as the call to ivp_stiff_imp_fulljac.
The linear algebra setup function :meth:ivp_stiff_fulljac_setup and one of the integrator setup functions, :meth:ivp_stiff_dassl, :meth:ivp_stiff_bdf or :meth:ivp_stiff_blend, must be called prior to the call of ivp_stiff_imp_fulljac.
The integrator diagnostic function :meth:ivp_stiff_integ_diag may be called after the call to ivp_stiff_imp_fulljac.
There is also a function, :meth:ivp_stiff_contin, designed to permit you to change step size on a continuation call to ivp_stiff_imp_fulljac without restarting the integration process.
"""
raise NotImplementedError

[docs]def ivp_stiff_imp_bandjac(t, tout, y, ydot, comm, rtol, atol, itol, resid, lderiv, itask, itrace, jac=None, monitr=None, data=None, io_manager=None, spiked_sorder='C'):
r"""
ivp_stiff_imp_bandjac is a direct communication function for integrating stiff systems of implicit ordinary differential equations coupled with algebraic equations when the Jacobian is a banded matrix.

.. _d02nh-py2-py-doc:

For full information please refer to the NAG Library document for d02nh

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02nhf.html

.. _d02nh-py2-py-parameters:

**Parameters**
**t** : float
:math:t, the value of the independent variable. The input value of :math:\mathrm{t} is used only on the first call as the initial point of the integration.

**tout** : float
The next value of :math:t at which a computed solution is desired. For the initial :math:t, the input value of :math:\mathrm{tout} is used to determine the direction of integration. Integration is permitted in either direction (see also :math:\mathrm{itask}).

**y** : float, array-like, shape :math:\left(\textit{neq}\right)
The values of the dependent variables (solution). On the first call the first :math:\textit{neq} elements of :math:\mathrm{y} must contain the vector of initial values.

**ydot** : float, array-like, shape :math:\left(\textit{neq}\right)
If :math:\mathrm{lderiv}[0] = \mathbf{True}, :math:\mathrm{ydot} must contain approximations to the time derivatives :math:y^{\prime } of the vector :math:y.

If :math:\mathrm{lderiv}[0] = \mathbf{False}, :math:\mathrm{ydot} need not be set on entry.

**comm** : dict, communication object, modified in place
Communication structure.

This argument must have been initialized by prior calls to :meth:ivp_stiff_bandjac_setup and one of :meth:ivp_stiff_dassl, :meth:ivp_stiff_bdf or :meth:ivp_stiff_blend.

**rtol** : float, array-like, shape :math:\left(:\right)
Note: the required length for this argument is determined as follows: if :math:\mathrm{itol}\text{ in } (1, 2): :math:1; otherwise: :math:\textit{neq}.

The relative local error tolerance.

**atol** : float, array-like, shape :math:\left(:\right)
Note: the required length for this argument is determined as follows: if :math:\mathrm{itol}\text{ in } (1, 3): :math:1; otherwise: :math:\textit{neq}.

The absolute local error tolerance.

**itol** : int
A value to indicate the form of the local error test. :math:\mathrm{itol} indicates to ivp_stiff_imp_bandjac whether to interpret either or both of :math:\mathrm{rtol} or :math:\mathrm{atol} as a vector or a scalar. The error test to be satisfied is :math:\left\lVert e_i/w_i\right\rVert < 1.0, where :math:w_i is defined as follows:

+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+
|:math:\mathrm{itol}|:math:\mathrm{rtol}|:math:\mathrm{atol}|:math:w_i                                                                     |
+=====================+=====================+=====================+================================================================================+
|1                    |scalar               |scalar               |:math:\mathrm{rtol}[0]\times \left\lvert y_i\right\rvert +\mathrm{atol}[0]    |
+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+
|2                    |scalar               |vector               |:math:\mathrm{rtol}[0]\times \left\lvert y_i\right\rvert +\mathrm{atol}[i-1]  |
+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+
|3                    |vector               |scalar               |:math:\mathrm{rtol}[i-1]\times \left\lvert y_i\right\rvert +\mathrm{atol}[0]  |
+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+
|4                    |vector               |vector               |:math:\mathrm{rtol}[i-1]\times \left\lvert y_i\right\rvert +\mathrm{atol}[i-1]|
+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+

:math:e_i is an estimate of the local error in :math:y_i, computed internally, and the choice of norm to be used is defined by a previous call to an integrator setup function.

**resid** : callable (r, ires) = resid(t, y, ydot, ires, data=None)
:math:\mathrm{resid} must evaluate the residual

.. math::
r = g\left(t, y\right)-A\left(t, y\right)y^{\prime }

in one case and

.. math::
r = -A\left(t, y\right)y^{\prime }

in another.

**Parameters**
**t** : float
:math:t, the current value of the independent variable.

**y** : float, ndarray, shape :math:\left(\textit{neq}\right)
The value of :math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{neq}.

**ydot** : float, ndarray, shape :math:\left(\textit{neq}\right)
The value of :math:y_{\textit{i}}^{\prime }, for :math:\textit{i} = 1,2,\ldots,\textit{neq}, at :math:t.

**ires** : int
The form of the residual that must be returned in array :math:\mathrm{r}.

:math:\mathrm{ires} = -1

The residual defined in equation (2) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02nhf.html#eqn2>__ must be returned.

:math:\mathrm{ires} = 1

The residual defined in equation (1) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02nhf.html#eqn1>__ must be returned.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**r** : float, array-like, shape :math:\left(\textit{neq}\right)
:math:\mathrm{r}[\textit{i}-1] must contain the :math:\textit{i}\ th component of :math:r, for :math:\textit{i} = 1,2,\ldots,\textit{neq}, where

.. math::
r = g\left(t, y\right)-A\left(t, y\right)y^{\prime }

or

.. math::
r = -A\left(t, y\right)y^{\prime }

and where the definition of :math:r is determined by the input value of :math:\mathrm{ires}.

**ires** : int
Should be unchanged unless one of the following actions is required of the integrator, in which case :math:\mathrm{ires} should be set accordingly.

:math:\mathrm{ires} = 2

Indicates to the integrator that control should be passed back immediately to the calling (sub)program with the error indicator set to :math:\mathrm{errno} = 11.

:math:\mathrm{ires} = 3

Indicates to the integrator that an error condition has occurred in the solution vector, its time derivative or in the value of :math:t. The integrator will use a smaller time step to try to avoid this condition. If this is not possible, the integrator returns to the calling (sub)program with the error indicator set to :math:\mathrm{errno} = 7.

:math:\mathrm{ires} = 4

Indicates to the integrator to stop its current operation and to enter :math:\mathrm{monitr} immediately with argument :math:\mathrm{imon} = -2.

**lderiv** : bool, array-like, shape :math:\left(2\right)
:math:\mathrm{lderiv}[0] must be set to :math:\mathbf{True} if you have supplied both an initial :math:y and an initial :math:y^{\prime }. :math:\mathrm{lderiv}[0] must be set to :math:\mathbf{False} if only the initial :math:y has been supplied.

:math:\mathrm{lderiv}[1] must be set to :math:\mathbf{True} if the integrator is to use a modified Newton method to evaluate the initial :math:y and :math:y^{\prime }.

Note that :math:y and :math:y^{\prime }, if supplied, are used as initial estimates.

This method involves taking a small step at the start of the integration, and if :math:\mathrm{itask} = 6 on entry, :math:\mathrm{t} and :math:\mathrm{tout} will be set to the result of taking this small step. :math:\mathrm{lderiv}[1] must be set to :math:\mathbf{False} if the integrator is to use functional iteration to evaluate the initial :math:y and :math:y^{\prime }, and if this fails a modified Newton method will then be attempted. :math:\mathrm{lderiv}[1] = \mathbf{True} is recommended if there are implicit equations or the initial :math:y and :math:y^{\prime } are zero.

The task to be performed by the integrator.

:math:\mathrm{itask} = 1

Normal computation of output values of :math:y\left(t\right) at :math:t = \mathrm{tout} (by overshooting and interpolating).

:math:\mathrm{itask} = 2

Take one step only and return.

:math:\mathrm{itask} = 3

Stop at the first internal integration point at or beyond :math:t = \mathrm{tout} and return.

:math:\mathrm{itask} = 4

Normal computation of output values of :math:y\left(t\right) at :math:t = \mathrm{tout} but without overshooting :math:t = {\textit{tcrit}}. :math:\textit{tcrit} must be specified as an option in one of the integrator setup functions before the first call to the integrator, or specified in the optional input function before a continuation call. :math:\textit{tcrit} may be equal to or beyond :math:\mathrm{tout}, but not before it, in the direction of integration.

:math:\mathrm{itask} = 5

Take one step only and return, without passing :math:\textit{tcrit}. :math:\textit{tcrit} must be specified as under :math:\mathrm{itask} = 4.

:math:\mathrm{itask} = 6

The integrator will solve for the initial values of :math:y and :math:y^{\prime } only and then return to the calling (sub)program without doing the integration. This option can be used to check the initial values of :math:y and :math:y^{\prime }. Functional iteration or a 'small' backward Euler method used in conjunction with a damped Newton iteration is used to calculate these values (see :math:\mathrm{lderiv}). Note that if a backward Euler step is used then the value of :math:t will have been advanced a short distance from the initial point.

**Note:** if ivp_stiff_imp_bandjac is recalled with a different value of :math:\mathrm{itask} (and :math:\mathrm{tout} altered), the initialization procedure is repeated, possibly leading to different initial conditions.

**itrace** : int
The level of output that is printed by the integrator. :math:\mathrm{itrace} may take the value :math:-1, :math:0, :math:1, :math:2 or :math:3.

:math:\mathrm{itrace} < -1

:math:-1 is assumed and similarly if :math:\mathrm{itrace} > 3, :math:3 is assumed.

:math:\mathrm{itrace} = -1

No output is generated.

:math:\mathrm{itrace} = 0

Only warning messages are printed on the current error message unit (see :class:~naginterfaces.base.utils.FileObjManager).

:math:\mathrm{itrace} > 0

Warning messages are printed as above, and on the file object associated with the advisory I/O unit (see :class:~naginterfaces.base.utils.FileObjManager) output is generated which details Jacobian entries, the nonlinear iteration and the time integration. The advisory messages are given in greater detail the larger the value of :math:\mathrm{itrace}.

**jac** : None or callable p = jac(t, y, ydot, h, d, ml, mu, p, data=None), optional
Note: if this argument is **None** then a NAG-supplied facility will be used.

:math:\mathrm{jac} must evaluate the Jacobian of the system.

If this option is not required, the actual argument for :math:\mathrm{jac} must be **None**. You must indicate to the integrator whether this option is to be used by setting the argument :math:\textit{jceval} appropriately in a call to the banded linear algebra setup function :meth:ivp_stiff_bandjac_setup.

First we must define the system of nonlinear equations which is solved internally by the integrator.

The time derivative, :math:y^{\prime }, generated internally, has the form

.. math::
y^{\prime } = \left(y-z\right)/\left(hd\right)\text{,}

where :math:h is the current step size and :math:d is an argument that depends on the integration method in use.

The vector :math:y is the current solution and the vector :math:z depends on information from previous time steps.

This means that :math:\frac{d}{{dy^{\prime }}}\left(\text{ }\right) = \left(hd\right)\frac{d}{{dy}}\left(\text{ }\right).

The system of nonlinear equations that is solved has the form

.. math::
A\left(t, y\right)y^{\prime }-g\left(t, y\right) = 0

but it is solved in the form

.. math::
r\left(t, y\right) = 0\text{,}

where :math:r is the function defined by

.. math::
r\left(t, y\right) = \left(hd\right)\left({A\left(t, y\right)\left(y-z\right)/\left(hd\right)-g\left(t, y\right)}\right)\text{.}

It is the Jacobian matrix :math:\frac{{\partial r}}{{\partial y}} that you must supply in :math:\mathrm{jac} as follows:

.. math::
\frac{{\partial r_i}}{{\partial y_j}} = a_{{ij}}\left(t, y\right)+\left(hd\right)\frac{\partial }{{\partial y_j}}\left(\sum_{{k = 1}}^{\textit{neq}}a_{{ik}}\left(t, y\right)y_k^{\prime }-g_i\left(t, y\right)\right)\text{.}

**Parameters**
**t** : float
:math:t, the current value of the independent variable.

**y** : float, ndarray, shape :math:\left(\textit{neq}\right)
:math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{neq}, the current solution component.

**ydot** : float, ndarray, shape :math:\left(\textit{neq}\right)
The derivative of the solution at the current point :math:t.

**h** : float
The current step size.

**d** : float
The argument :math:d which depends on the integration method.

**ml** : int
The number of subdiagonals and superdiagonals respectively in the band.

**mu** : int
The number of subdiagonals and superdiagonals respectively in the band.

**p** : float, ndarray, shape :math:\left(\mathrm{ml}+\mathrm{mu}+1, \textit{neq}\right)
Is set to zero.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**p** : float, array-like, shape :math:\left(\mathrm{ml}+\mathrm{mu}+1, \textit{neq}\right)
Elements of the Jacobian matrix :math:\frac{{\partial r}}{{\partial y}} stored as specified by the following pseudocode:

::

for i in range(1, neq+1):
j1 = max(i-ml, 1)
j2 = min(i+mu, neq)
for j in range(j1, j2+1):
k = min(ml+1-i, 0) + j
p[k-1, i-1] = J[i-1, j-1]

See also :meth:lapacklin.dgbtrf <naginterfaces.library.lapacklin.dgbtrf>.

Only nonzero elements of this array need be set, since it is preset to zero before the call to :math:\mathrm{jac}.

**monitr** : None or callable (hnext, y, imon, inln, hmin, hmax) = monitr(t, hlast, hnext, y, ydot, comm, r, acor, imon, hmin, hmax, nqu, data=None), optional
Note: if this argument is **None** then a NAG-supplied facility will be used.

:math:\mathrm{monitr} performs tasks requested by you.

If this option is not required, the actual argument for :math:\mathrm{monitr} must be **None**.

**Parameters**
**t** : float
The current value of the independent variable.

**hlast** : float
The last step size successfully used by the integrator.

**hnext** : float
The step size that the integrator proposes to take on the next step.

**y** : float, ndarray, shape :math:\left(\textit{neq}\right)
:math:y, the values of the dependent variables evaluated at :math:t.

**ydot** : float, ndarray, shape :math:\left(\textit{neq}\right)
The time derivatives :math:y^{\prime } of the vector :math:y.

**comm** : dict, communication object, modifiable in place
Communication structure.

This argument may be passed as argument :math:\textit{comm} in a call to :meth:ivp_stiff_nat_interp or :math:\textit{comm} in a call to :meth:ivp_stiff_c1_interp to enable you to carry out interpolation using either of those functions.

**r** : float, ndarray, shape :math:\left(\textit{neq}\right)
If :math:\mathrm{imon} = 0 and :math:\mathrm{inln} = 3, the first :math:\textit{neq} elements contain the residual vector :math:A\left(t, y\right)y^{\prime }-g\left(t, y\right).

**acor** : float, ndarray, shape :math:\left(\textit{neq}, 2\right)
With :math:\mathrm{imon} = 1, :math:\mathrm{acor}[i-1,0] contains the weight used for the :math:i\ th equation when the norm is evaluated, and :math:\mathrm{acor}[i-1,1] contains the estimated local error for the :math:i\ th equation. The scaled local error at the end of a timestep may be obtained by calling :meth:ivp_stiff_errest.

**imon** : int
A flag indicating under what circumstances :math:\mathrm{monitr} was called:

:math:\mathrm{imon} = -2

Entry from the integrator after :math:\mathrm{ires} = 4 (set in :math:\mathrm{resid}) caused an early termination (this facility could be used to locate discontinuities).

:math:\mathrm{imon} = -1

The current step failed repeatedly.

:math:\mathrm{imon} = 0

Entry after a call to the internal nonlinear equation solver (see :math:\mathrm{inln}).

:math:\mathrm{imon} = 1

The current step was successful.

**hmin** : float
The minimum step size to be taken on the next step.

**hmax** : float
The maximum step size to be taken on the next step.

**nqu** : int
The order of the integrator used on the last step. This is supplied to enable you to carry out interpolation using either of the functions :meth:ivp_stiff_nat_interp or :meth:ivp_stiff_c1_interp.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**hnext** : float
The next step size to be used. If this is different from the input value, :math:\mathrm{imon} must be set to :math:4.

**y** : float, array-like, shape :math:\left(\textit{neq}\right)
These values must not be changed unless :math:\mathrm{imon} is set to :math:2.

**imon** : int
May be reset to determine subsequent action in ivp_stiff_imp_bandjac.

:math:\mathrm{imon} = -2

Integration is to be halted. A return will be made from the integrator to the calling (sub)program with :math:\mathrm{errno} = 12.

:math:\mathrm{imon} = -1

Allow the integrator to continue with its own internal strategy. The integrator will try up to three restarts unless :math:\mathrm{imon} \neq -1 on exit.

:math:\mathrm{imon} = 0

Return to the internal nonlinear equation solver, where the action taken is determined by the value of :math:\mathrm{inln} (see :math:\mathrm{inln}).

:math:\mathrm{imon} = 1

Normal exit to the integrator to continue integration.

:math:\mathrm{imon} = 2

Restart the integration at the current time point. The integrator will restart from order :math:1 when this option is used. The solution :math:\mathrm{y}, provided by :math:\mathrm{monitr}, will be used for the initial conditions.

:math:\mathrm{imon} = 3

Try to continue with the same step size and order as was to be used before the call to :math:\mathrm{monitr}. :math:\mathrm{hmin} and :math:\mathrm{hmax} may be altered if desired.

:math:\mathrm{imon} = 4

Continue the integration but using a new value of :math:\mathrm{hnext} and possibly new values of :math:\mathrm{hmin} and :math:\mathrm{hmax}.

**inln** : int
The action to be taken by the internal nonlinear equation solver when :math:\mathrm{monitr} is exited with :math:\mathrm{imon} = 0. By setting :math:\mathrm{inln} = 3 and returning to the integrator, the residual vector is evaluated and placed in the array :math:\mathrm{r}, and then :math:\mathrm{monitr} is called again. At present this is the only option available: :math:\mathrm{inln} must not be set to any other value.

**hmin** : float
The minimum step size to be used. If this is different from the input value, :math:\mathrm{imon} must be set to :math:3 or :math:4.

**hmax** : float
The maximum step size to be used. If this is different from the input value, :math:\mathrm{imon} must be set to :math:3 or :math:4. If :math:\mathrm{hmax} is set to zero, no limit is assumed.

**data** : arbitrary, optional
User-communication data for callback functions.

**io_manager** : FileObjManager, optional
Manager for I/O in this routine.

**spiked_sorder** : str, optional
If :math:\mathrm{p} in :math:\mathrm{jac} is spiked (i.e., has unit extent in all but one dimension, or has size :math:1), :math:\mathrm{spiked\_sorder} selects the storage order to associate with it in the NAG Engine:

spiked_sorder = :math:\texttt{'C'}
row-major storage will be used;

spiked_sorder = :math:\texttt{'F'}
column-major storage will be used.

**Returns**
**t** : float
The value at which the computed solution :math:y is returned (usually at :math:\mathrm{tout}).

**tout** : float
Normally unchanged. However, when :math:\mathrm{itask} = 6, :math:\mathrm{tout} contains the value of :math:\mathrm{t} at which initial values have been computed without performing any integration. See descriptions of :math:\mathrm{itask} and :math:\mathrm{lderiv}.

**y** : float, ndarray, shape :math:\left(\textit{neq}\right)
The computed solution vector, evaluated at :math:\mathrm{t} (usually :math:\mathrm{t} = \mathrm{tout}).

**ydot** : float, ndarray, shape :math:\left(\textit{neq}\right)
The time derivatives :math:y^{\prime } of the vector :math:y at the last integration point.

**lderiv** : bool, ndarray, shape :math:\left(2\right)
:math:\mathrm{lderiv}[0] is normally unchanged. However if :math:\mathrm{itask} = 6 and internal initialization was successful then :math:\mathrm{lderiv}[0] = \mathbf{True}.

:math:\mathrm{lderiv}[1] = \mathbf{True}, if implicit equations were detected.

Otherwise :math:\mathrm{lderiv}[1] = \mathbf{False}.

.. _d02nh-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:\mathrm{ires} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\frac{{dy}}{{dt}} = 0.0 for all elements.

Check the evaluation of the residual for this value of :math:\mathrm{ires}.

(errno :math:1)
:math:\mathrm{ires} was set to an illegal value during initialization.

:math:\mathrm{ires} = \langle\mathit{\boldsymbol{value}}\rangle at time :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
:math:\mathrm{monitr} set :math:\mathrm{imon} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:-2\leq \mathrm{imon}\leq 4.

(errno :math:1)
Failure during internal time interpolation. :math:\mathrm{tout} and the current time are too close.

:math:\mathrm{itask} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle and the current time is :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{itask} = 4 or :math:5 and :math:\textit{tcrit} is before the current time in the direction of integration.

:math:\mathrm{itask} = \langle\mathit{\boldsymbol{value}}\rangle, :math:{\textit{tcrit}} = \langle\mathit{\boldsymbol{value}}\rangle and the current time is :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
:math:\mathrm{itask} = 3 and :math:\mathrm{tout} is more than an integration step behind the current time.

:math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle, current time minus step size: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
The initial stepsize, :math:\langle\mathit{\boldsymbol{value}}\rangle, is too small.

(errno :math:1)
Weight number :math:i = \langle\mathit{\boldsymbol{value}}\rangle used in the local error test is too small. Check the values of :math:\mathrm{rtol} and :math:\mathrm{atol}.

:math:\mathrm{atol}[i-1] and :math:\mathrm{y}[i-1] may both be zero.

Weight :math:i = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{itask} = 4 or :math:5 and :math:\textit{tcrit} is before :math:\mathrm{tout} in the direction of integration.

:math:\mathrm{itask} = \langle\mathit{\boldsymbol{value}}\rangle, :math:{\textit{tcrit}} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{atol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{atol}\geq 0.0.

(errno :math:1)
On entry, :math:\mathrm{rtol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{rtol}\geq 0.0.

(errno :math:1)
Either the value of :math:\textit{sdysav} is not the same as the value supplied to the setup function or a communication array has become corrupted.

:math:\textit{sdysav} = \langle\mathit{\boldsymbol{value}}\rangle, :math:\textit{sdysav} (setup) :math:{} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, an illegal (negative) minimum stepsize was provided in a prior call to a setup function. :math:\mathrm{hmin} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{tout} is less than :math:\mathrm{t} with respect to the direction of integration given by the sign of :math:\textit{h0} in a prior call to a setup function.

:math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle, :math:\mathrm{t} = \langle\mathit{\boldsymbol{value}}\rangle and :math:{\textit{h0}} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, an illegal (negative) maximum number of steps was provided in a prior call to a setup function. :math:{\textit{maxstp}} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{itol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:1\leq \mathrm{itol}\leq 4.

(errno :math:1)
On entry, :math:\textit{neq} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\textit{ldysav} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\textit{neq}\leq \textit{ldysav}.

(errno :math:1)
On entry, :math:\textit{neq} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\textit{neq}\geq 1.

(errno :math:1)
Either the function was entered on a continuation call without a prior call of this function, or a communication array has become corrupted.

(errno :math:1)
On entry, :math:\mathrm{tout} is too close to :math:\mathrm{t} to start integration.

:math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{t} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{itask} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:1\leq \mathrm{itask}\leq 5.

(errno :math:1)
On entry, an illegal (negative) maximum stepsize was provided in a prior call to a setup function. :math:\mathrm{hmax} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
Either the linear algebra setup function has not been called prior to the first call of this function, or a communication array has become corrupted.

(errno :math:1)
:math:\mathrm{monitr} set :math:\mathrm{inln} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{inln} = 3.

(errno :math:1)
:math:\mathrm{monitr} appears to have overwritten the solution vector.

Further integration will not be attempted.

(errno :math:2)
At time :math:\langle\mathit{\boldsymbol{value}}\rangle the maximum number of allowed steps on this call was taken before reaching the next output point :math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle.

Maximum number of steps :math:{} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:7)
:math:\mathrm{resid} set :math:\mathrm{ires} = 3, which signals that an error condition has occurred in the solution vector, its time derivative or in the value of :math:t. It was not possible to remove this condition.

:math:\mathrm{ires} = \langle\mathit{\boldsymbol{value}}\rangle at :math:t = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:8)
Attempt was made to reduce the step size to a value less than the minimum step size during the calculation of initial values.

Minimum stepsize: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:8)
The residual function returned an error when calculating the initial values of the solution and its time derivative.

(errno :math:8)
Workspace error occurred when trying to form the Jacobian matrix in calculating the initial values of the solution and its time derivative.

(errno :math:9)
A singular Jacobian has been encountered. You should check the problem formulation and Jacobian calculation.

(errno :math:10)
Not enough real store provided for sparse matrix solver.

Units of store needed: :math:\langle\mathit{\boldsymbol{value}}\rangle. Amount provided: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:10)
Not enough integer store provided for sparse matrix solver.

Units of store needed: :math:\langle\mathit{\boldsymbol{value}}\rangle. Amount provided: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:10)
Larger integer workspace required.

Provided: :math:\langle\mathit{\boldsymbol{value}}\rangle; required: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:10)
Not enough integer store provided for internal storage pointers.

Units of store needed: :math:\langle\mathit{\boldsymbol{value}}\rangle. Amount provided: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:14)
On entry, too much accuracy requested for precision of the machine at the start of problem. The tolerances should be checked; the requested accuracy should be reduced by a factor of at least :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:15)
Either the banded matrix linear algebra setup function was not called first or a communication array has become corrupted.

**Warns**
**NagAlgorithmicWarning**
(errno :math:3)
Too much accuracy requested for precision of the machine at time :math:\langle\mathit{\boldsymbol{value}}\rangle.

The tolerances should be checked; the requested accuracy should be reduced by a factor of at least :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:4)
There were repeated error-test failures on an attempted step, before completing the requested task, but the integration was successful as far as :math:\mathrm{t}. The problem may have a singularity, or the local error requirements may be inappropriate.

(errno :math:5)
There were repeated convergence-test failures on an attempted step, before completing the requested task, but the integration was successful as far as :math:\mathrm{t}. This may be caused by an inaccurate Jacobian matrix or one which is incorrectly computed.

(errno :math:6)
At time :math:\langle\mathit{\boldsymbol{value}}\rangle, error weight :math:\langle\mathit{\boldsymbol{value}}\rangle became zero. Check the values of :math:\mathrm{atol}, :math:\mathrm{rtol} and :math:\mathrm{itol} supplied.

(errno :math:8)
Nonlinear solver failed to converge using a damped Newton method to solve for initial values.

Damping factor: :math:\langle\mathit{\boldsymbol{value}}\rangle; convergence rate: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:8)
The user problem has one or more inconsistencies between the :math:\mathrm{ires} = 1 and :math:\mathrm{ires} = -1 parts. Integration will not be attempted.

(errno :math:11)
:math:\mathrm{resid} set :math:\mathrm{ires} = 2, which signals that the integration should terminate. :math:\mathrm{ires} = \langle\mathit{\boldsymbol{value}}\rangle at time :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:12)
A return was forced by setting :math:\mathrm{imon} = -2, but the integration was successful as far as :math:\mathrm{t}.

(errno :math:13)
The requested task has been completed, but it is estimated that a small change in :math:\mathrm{rtol} and :math:\mathrm{atol} is unlikely to produce any change in the computed solution. (This ONLY applies when you are NOT operating in one step mode; that is, when :math:\mathrm{itask} \neq 2 or :math:5.)

.. _d02nh-py2-py-notes:

**Notes**
No equivalent traditional C interface for this routine exists in the NAG Library.

ivp_stiff_imp_bandjac is a general purpose function for integrating the initial value problem for a stiff system of implicit ordinary differential equations coupled with algebraic equations, written in the form

.. math::
A\left(t, y\right)y^{\prime } = g\left(t, y\right)\text{.}

It is designed specifically for the case where the resulting Jacobian is a banded matrix (see the description of :math:\mathrm{jac}).

Both interval and step oriented modes of operation are available and also modes designed to permit intermediate output within an interval oriented mode.

A typical calling program for ivp_stiff_imp_bandjac would involve calling the banded matrix linear algebra setup function :meth:ivp_stiff_bandjac_setup, the Backward Differentiation Formula (BDF) integrator setup function :meth:ivp_stiff_bdf, and its diagnostic counterpart :meth:ivp_stiff_integ_diag as well as the call to ivp_stiff_imp_bandjac.
The linear algebra setup function :meth:ivp_stiff_bandjac_setup and one of the integrator setup functions, :meth:ivp_stiff_dassl, :meth:ivp_stiff_bdf or :meth:ivp_stiff_blend, must be called prior to the call of ivp_stiff_imp_bandjac.
The integrator diagnostic function :meth:ivp_stiff_integ_diag may be called after the call to ivp_stiff_imp_bandjac.
There is also a function, :meth:ivp_stiff_contin, designed to permit you to change step size on a continuation call to ivp_stiff_imp_bandjac without restarting the integration process.
"""
raise NotImplementedError

[docs]def ivp_stiff_imp_sparjac(t, tout, y, ydot, comm, rtol, atol, itol, resid, lderiv, itask, itrace, jac=None, monitr=None, data=None, io_manager=None):
r"""
ivp_stiff_imp_sparjac is a direct communication function for integrating stiff systems of implicit ordinary differential equations coupled with algebraic equations when the Jacobian is a sparse matrix.

.. _d02nj-py2-py-doc:

For full information please refer to the NAG Library document for d02nj

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02njf.html

.. _d02nj-py2-py-parameters:

**Parameters**
**t** : float
:math:t, the value of the independent variable. The input value of :math:\mathrm{t} is used only on the first call as the initial point of the integration.

**tout** : float
The next value of :math:t at which a computed solution is desired. For the initial :math:t, the input value of :math:\mathrm{tout} is used to determine the direction of integration. Integration is permitted in either direction (see also :math:\mathrm{itask}).

**y** : float, array-like, shape :math:\left(\textit{neq}\right)
The values of the dependent variables (solution). On the first call the first :math:\textit{neq} elements of :math:\mathrm{y} must contain the vector of initial values.

**ydot** : float, array-like, shape :math:\left(\textit{neq}\right)
If :math:\mathrm{lderiv}[0] = \mathbf{True}, :math:\mathrm{ydot} must contain approximations to the time derivatives :math:y^{\prime } of the vector :math:y.

If :math:\mathrm{lderiv}[0] = \mathbf{False}, :math:\mathrm{ydot} need not be set on entry.

**comm** : dict, communication object, modified in place
Communication structure.

This argument must have been initialized by prior calls to :meth:ivp_stiff_sparjac_setup and one of :meth:ivp_stiff_dassl, :meth:ivp_stiff_bdf or :meth:ivp_stiff_blend.

**rtol** : float, array-like, shape :math:\left(:\right)
Note: the required length for this argument is determined as follows: if :math:\mathrm{itol}\text{ in } (1, 2): :math:1; otherwise: :math:\textit{neq}.

The relative local error tolerance.

**atol** : float, array-like, shape :math:\left(:\right)
Note: the required length for this argument is determined as follows: if :math:\mathrm{itol}\text{ in } (1, 3): :math:1; otherwise: :math:\textit{neq}.

The absolute local error tolerance.

**itol** : int
A value to indicate the form of the local error test. :math:\mathrm{itol} indicates to ivp_stiff_imp_sparjac whether to interpret either or both of :math:\mathrm{rtol} or :math:\mathrm{atol} as a vector or a scalar. The error test to be satisfied is :math:\left\lVert e_i/w_i\right\rVert < 1.0, where :math:w_i is defined as follows:

+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+
|:math:\mathrm{itol}|:math:\mathrm{rtol}|:math:\mathrm{atol}|:math:w_i                                                                     |
+=====================+=====================+=====================+================================================================================+
|1                    |scalar               |scalar               |:math:\mathrm{rtol}[0]\times \left\lvert y_i\right\rvert +\mathrm{atol}[0]    |
+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+
|2                    |scalar               |vector               |:math:\mathrm{rtol}[0]\times \left\lvert y_i\right\rvert +\mathrm{atol}[i-1]  |
+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+
|3                    |vector               |scalar               |:math:\mathrm{rtol}[i-1]\times \left\lvert y_i\right\rvert +\mathrm{atol}[0]  |
+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+
|4                    |vector               |vector               |:math:\mathrm{rtol}[i-1]\times \left\lvert y_i\right\rvert +\mathrm{atol}[i-1]|
+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+

:math:e_i is an estimate of the local error in :math:y_i, computed internally, and the choice of norm to be used is defined by a previous call to an integrator setup function.

**resid** : callable (r, ires) = resid(t, y, ydot, ires, data=None)
:math:\mathrm{resid} must evaluate the residual

.. math::
r = g\left(t, y\right)-A\left(t, y\right)y^{\prime }

in one case and

.. math::
r = -A\left(t, y\right)y^{\prime }

in another.

**Parameters**
**t** : float
:math:t, the current value of the independent variable.

**y** : float, ndarray, shape :math:\left(\textit{neq}\right)
The value of :math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{neq}.

**ydot** : float, ndarray, shape :math:\left(\textit{neq}\right)
The value of :math:y_{\textit{i}}^{\prime }, for :math:\textit{i} = 1,2,\ldots,\textit{neq}, at :math:t.

**ires** : int
The form of the residual that must be returned in array :math:\mathrm{r}.

:math:\mathrm{ires} = -1

The residual defined in equation (2) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02njf.html#eqn2>__ must be returned.

:math:\mathrm{ires} = 1

The residual defined in equation (1) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02njf.html#eqn1>__ must be returned.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**r** : float, array-like, shape :math:\left(\textit{neq}\right)
:math:\mathrm{r}[\textit{i}-1] must contain the :math:\textit{i}\ th component of :math:r, for :math:\textit{i} = 1,2,\ldots,\textit{neq}, where

.. math::
r = g\left(t, y\right)-A\left(t, y\right)y^{\prime }

or

.. math::
r = -A\left(t, y\right)y^{\prime }

and where the definition of :math:r is determined by the input value of :math:\mathrm{ires}.

**ires** : int
Should be unchanged unless one of the following actions is required of the integrator, in which case :math:\mathrm{ires} should be set accordingly.

:math:\mathrm{ires} = 2

Indicates to the integrator that control should be passed back immediately to the calling (sub)program with the error indicator set to :math:\mathrm{errno} = 11.

:math:\mathrm{ires} = 3

Indicates to the integrator that an error condition has occurred in the solution vector, its time derivative or in the value of :math:t. The integrator will use a smaller time step to try to avoid this condition. If this is not possible, the integrator returns to the calling (sub)program with the error indicator set to :math:\mathrm{errno} = 7.

:math:\mathrm{ires} = 4

Indicates to the integrator to stop its current operation and to enter :math:\mathrm{monitr} immediately with argument :math:\mathrm{imon} = -2.

**lderiv** : bool, array-like, shape :math:\left(2\right)
:math:\mathrm{lderiv}[0] must be set to :math:\mathbf{True} if you have supplied both an initial :math:y and an initial :math:y^{\prime }. :math:\mathrm{lderiv}[0] must be set to :math:\mathbf{False} if only the initial :math:y has been supplied.

:math:\mathrm{lderiv}[1] must be set to :math:\mathbf{True} if the integrator is to use a modified Newton method to evaluate the initial :math:y and :math:y^{\prime }.

Note that :math:y and :math:y^{\prime }, if supplied, are used as initial estimates.

This method involves taking a small step at the start of the integration, and if :math:\mathrm{itask} = 6 on entry, :math:\mathrm{t} and :math:\mathrm{tout} will be set to the result of taking this small step. :math:\mathrm{lderiv}[1] must be set to :math:\mathbf{False} if the integrator is to use functional iteration to evaluate the initial :math:y and :math:y^{\prime }, and if this fails a modified Newton method will then be attempted. :math:\mathrm{lderiv}[1] = \mathbf{True} is recommended if there are implicit equations or the initial :math:y and :math:y^{\prime } are zero.

The task to be performed by the integrator.

:math:\mathrm{itask} = 1

Normal computation of output values of :math:y\left(t\right) at :math:t = \mathrm{tout} (by overshooting and interpolating).

:math:\mathrm{itask} = 2

Take one step only and return.

:math:\mathrm{itask} = 3

Stop at the first internal integration point at or beyond :math:t = \mathrm{tout} and return.

:math:\mathrm{itask} = 4

Normal computation of output values of :math:y\left(t\right) at :math:t = \mathrm{tout} but without overshooting :math:t = {\textit{tcrit}}. :math:\textit{tcrit} must be specified as an option in one of the integrator setup functions before the first call to the integrator, or specified in the optional input function before a continuation call. :math:\textit{tcrit} may be equal to or beyond :math:\mathrm{tout}, but not before it, in the direction of integration.

:math:\mathrm{itask} = 5

Take one step only and return, without passing :math:\textit{tcrit}. :math:\textit{tcrit} must be specified as under :math:\mathrm{itask} = 4.

:math:\mathrm{itask} = 6

The integrator will solve for the initial values of :math:y and :math:y^{\prime } only and then return to the calling (sub)program without doing the integration. This option can be used to check the initial values of :math:y and :math:y^{\prime }. Functional iteration or a 'small' backward Euler method used in conjunction with a damped Newton iteration is used to calculate these values (see :math:\mathrm{lderiv}). Note that if a backward Euler step is used then the value of :math:t will have been advanced a short distance from the initial point.

**Note:** if ivp_stiff_imp_sparjac is recalled with a different value of :math:\mathrm{itask} (and :math:\mathrm{tout} altered), the initialization procedure is repeated, possibly leading to different initial conditions.

**itrace** : int
The level of output that is printed by the integrator. :math:\mathrm{itrace} may take the value :math:-1, :math:0, :math:1, :math:2 or :math:3.

:math:\mathrm{itrace} < -1

:math:-1 is assumed and similarly if :math:\mathrm{itrace} > 3, :math:3 is assumed.

:math:\mathrm{itrace} = -1

No output is generated.

:math:\mathrm{itrace} = 0

Only warning messages are printed on the current error message unit (see :class:~naginterfaces.base.utils.FileObjManager).

:math:\mathrm{itrace} > 0

Warning messages are printed as above, and on the file object associated with the advisory I/O unit (see :class:~naginterfaces.base.utils.FileObjManager) output is generated which details Jacobian entries, the nonlinear iteration and the time integration. The advisory messages are given in greater detail the larger the value of :math:\mathrm{itrace}.

**jac** : None or callable pdj = jac(t, y, ydot, h, d, j, pdj, data=None), optional
Note: if this argument is **None** then a NAG-supplied facility will be used.

:math:\mathrm{jac} must evaluate the Jacobian of the system.

If this option is not required, the actual argument for :math:\mathrm{jac} must be **None**. You must indicate to the integrator whether this option is to be used by setting the argument :math:\textit{jceval} appropriately in a call to the sparse linear algebra setup function :meth:ivp_stiff_sparjac_setup.

First we must define the system of nonlinear equations which is solved internally by the integrator.

The time derivative, :math:y^{\prime }, generated internally, has the form

.. math::
y^{\prime } = \left(y-z\right)/\left(hd\right)\text{,}

where :math:h is the current step size and :math:d is an argument that depends on the integration method in use.

The vector :math:y is the current solution and the vector :math:z depends on information from previous time steps.

This means that :math:\frac{d}{{dy^{\prime }}}\left(\text{ }\right) = \left(hd\right)\frac{d}{{dy}}\left(\text{ }\right).

The system of nonlinear equations that is solved has the form

.. math::
A\left(t, y\right)y^{\prime }-g\left(t, y\right) = 0

but it is solved in the form

.. math::
r\left(t, y\right) = 0\text{,}

where :math:r is the function defined by

.. math::
r\left(t, y\right) = \left(hd\right)\left({A\left(t, y\right)\left(y-z\right)/\left(hd\right)-g\left(t, y\right)}\right)\text{.}

It is the Jacobian matrix :math:\frac{{\partial r}}{{\partial y}} that you must supply in :math:\mathrm{jac} as follows:

.. math::
\frac{{\partial r_i}}{{\partial y_j}} = a_{{ij}}\left(t, y\right)+\left(hd\right)\frac{\partial }{{\partial y_j}}\left(\sum_{{k = 1}}^{\textit{neq}}a_{{ik}}\left(t, y\right)y_k^{\prime }-g_i\left(t, y\right)\right)\text{.}

**Parameters**
**t** : float
:math:t, the current value of the independent variable.

**y** : float, ndarray, shape :math:\left(\textit{neq}\right)
:math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{neq}, the current solution component.

**ydot** : float, ndarray, shape :math:\left(\textit{neq}\right)
The derivative of the solution at the current point :math:t.

**h** : float
The current step size.

**d** : float
The argument :math:d which depends on the integration method.

**j** : int
The column of the Jacobian that :math:\mathrm{jac} must return in the array :math:\mathrm{pdj}.

**pdj** : float, ndarray, shape :math:\left(\textit{neq}\right)
Is set to zero.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**pdj** : float, array-like, shape :math:\left(\textit{neq}\right)
:math:\mathrm{pdj}[i-1] should be set to the :math:\left(i, j\right)\ th element of the Jacobian, where :math:j is given by :math:\mathrm{j}. Only nonzero elements of this array need be set, since it is preset to zero before the call to :math:\mathrm{jac}.

**monitr** : None or callable (hnext, y, imon, inln, hmin, hmax) = monitr(t, hlast, hnext, y, ydot, comm, r, acor, imon, hmin, hmax, nqu, data=None), optional
Note: if this argument is **None** then a NAG-supplied facility will be used.

:math:\mathrm{monitr} performs tasks requested by you.

If this option is not required, the actual argument for :math:\mathrm{monitr} must be **None**.

**Parameters**
**t** : float
The current value of the independent variable.

**hlast** : float
The last step size successfully used by the integrator.

**hnext** : float
The step size that the integrator proposes to take on the next step.

**y** : float, ndarray, shape :math:\left(\textit{neq}\right)
:math:y, the values of the dependent variables evaluated at :math:t.

**ydot** : float, ndarray, shape :math:\left(\textit{neq}\right)
The time derivatives :math:y^{\prime } of the vector :math:y.

**comm** : dict, communication object, modifiable in place
Communication structure.

This argument may be passed as argument :math:\textit{comm} in a call to :meth:ivp_stiff_nat_interp or :math:\textit{comm} in a call to :meth:ivp_stiff_c1_interp to enable you to carry out interpolation using either of those functions.

**r** : float, ndarray, shape :math:\left(\textit{neq}\right)
If :math:\mathrm{imon} = 0 and :math:\mathrm{inln} = 3, the first :math:\textit{neq} elements contain the residual vector :math:A\left(t, y\right)y^{\prime }-g\left(t, y\right).

**acor** : float, ndarray, shape :math:\left(\textit{neq}, 2\right)
With :math:\mathrm{imon} = 1, :math:\mathrm{acor}[i-1,0] contains the weight used for the :math:i\ th equation when the norm is evaluated, and :math:\mathrm{acor}[i-1,1] contains the estimated local error for the :math:i\ th equation. The scaled local error at the end of a timestep may be obtained by calling :meth:ivp_stiff_errest.

**imon** : int
A flag indicating under what circumstances :math:\mathrm{monitr} was called:

:math:\mathrm{imon} = -2

Entry from the integrator after :math:\mathrm{ires} = 4 (set in :math:\mathrm{resid}) caused an early termination (this facility could be used to locate discontinuities).

:math:\mathrm{imon} = -1

The current step failed repeatedly.

:math:\mathrm{imon} = 0

Entry after a call to the internal nonlinear equation solver (see :math:\mathrm{inln}).

:math:\mathrm{imon} = 1

The current step was successful.

**hmin** : float
The minimum step size to be taken on the next step.

**hmax** : float
The maximum step size to be taken on the next step.

**nqu** : int
The order of the integrator used on the last step. This is supplied to enable you to carry out interpolation using either of the functions :meth:ivp_stiff_nat_interp or :meth:ivp_stiff_c1_interp.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**hnext** : float
The next step size to be used. If this is different from the input value, :math:\mathrm{imon} must be set to :math:4.

**y** : float, array-like, shape :math:\left(\textit{neq}\right)
These values must not be changed unless :math:\mathrm{imon} is set to :math:2.

**imon** : int
May be reset to determine subsequent action in ivp_stiff_imp_sparjac.

:math:\mathrm{imon} = -2

Integration is to be halted. A return will be made from the integrator to the calling (sub)program with :math:\mathrm{errno} = 12.

:math:\mathrm{imon} = -1

Allow the integrator to continue with its own internal strategy. The integrator will try up to three restarts unless :math:\mathrm{imon} \neq -1 on exit.

:math:\mathrm{imon} = 0

Return to the internal nonlinear equation solver, where the action taken is determined by the value of :math:\mathrm{inln} (see :math:\mathrm{inln}).

:math:\mathrm{imon} = 1

Normal exit to the integrator to continue integration.

:math:\mathrm{imon} = 2

Restart the integration at the current time point. The integrator will restart from order :math:1 when this option is used. The solution :math:\mathrm{y}, provided by :math:\mathrm{monitr}, will be used for the initial conditions.

:math:\mathrm{imon} = 3

Try to continue with the same step size and order as was to be used before the call to :math:\mathrm{monitr}. :math:\mathrm{hmin} and :math:\mathrm{hmax} may be altered if desired.

:math:\mathrm{imon} = 4

Continue the integration but using a new value of :math:\mathrm{hnext} and possibly new values of :math:\mathrm{hmin} and :math:\mathrm{hmax}.

**inln** : int
The action to be taken by the internal nonlinear equation solver when :math:\mathrm{monitr} is exited with :math:\mathrm{imon} = 0. By setting :math:\mathrm{inln} = 3 and returning to the integrator, the residual vector is evaluated and placed in the array :math:\mathrm{r}, and then :math:\mathrm{monitr} is called again. At present this is the only option available: :math:\mathrm{inln} must not be set to any other value.

**hmin** : float
The minimum step size to be used. If this is different from the input value, :math:\mathrm{imon} must be set to :math:3 or :math:4.

**hmax** : float
The maximum step size to be used. If this is different from the input value, :math:\mathrm{imon} must be set to :math:3 or :math:4. If :math:\mathrm{hmax} is set to zero, no limit is assumed.

**data** : arbitrary, optional
User-communication data for callback functions.

**io_manager** : FileObjManager, optional
Manager for I/O in this routine.

**Returns**
**t** : float
The value at which the computed solution :math:y is returned (usually at :math:\mathrm{tout}).

**tout** : float
Normally unchanged. However, when :math:\mathrm{itask} = 6, :math:\mathrm{tout} contains the value of :math:\mathrm{t} at which initial values have been computed without performing any integration. See descriptions of :math:\mathrm{itask} and :math:\mathrm{lderiv}.

**y** : float, ndarray, shape :math:\left(\textit{neq}\right)
The computed solution vector, evaluated at :math:\mathrm{t} (usually :math:\mathrm{t} = \mathrm{tout}).

**ydot** : float, ndarray, shape :math:\left(\textit{neq}\right)
The time derivatives :math:y^{\prime } of the vector :math:y at the last integration point.

**lderiv** : bool, ndarray, shape :math:\left(2\right)
:math:\mathrm{lderiv}[0] is normally unchanged. However if :math:\mathrm{itask} = 6 and internal initialization was successful then :math:\mathrm{lderiv}[0] = \mathbf{True}.

:math:\mathrm{lderiv}[1] = \mathbf{True}, if implicit equations were detected.

Otherwise :math:\mathrm{lderiv}[1] = \mathbf{False}.

.. _d02nj-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:\mathrm{ires} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\frac{{dy}}{{dt}} = 0.0 for all elements.

Check the evaluation of the residual for this value of :math:\mathrm{ires}.

(errno :math:1)
:math:\mathrm{ires} was set to an illegal value during initialization.

:math:\mathrm{ires} = \langle\mathit{\boldsymbol{value}}\rangle at time :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
:math:\mathrm{monitr} set :math:\mathrm{imon} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:-2\leq \mathrm{imon}\leq 4.

(errno :math:1)
Failure during internal time interpolation. :math:\mathrm{tout} and the current time are too close.

:math:\mathrm{itask} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle and the current time is :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{itask} = 4 or :math:5 and :math:\textit{tcrit} is before the current time in the direction of integration.

:math:\mathrm{itask} = \langle\mathit{\boldsymbol{value}}\rangle, :math:{\textit{tcrit}} = \langle\mathit{\boldsymbol{value}}\rangle and the current time is :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
:math:\mathrm{itask} = 3 and :math:\mathrm{tout} is more than an integration step behind the current time.

:math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle, current time minus step size: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
The initial stepsize, :math:h = \langle\mathit{\boldsymbol{value}}\rangle, is too small.

(errno :math:1)
Weight number :math:i = \langle\mathit{\boldsymbol{value}}\rangle used in the local error test is too small. Check the values of :math:\mathrm{rtol} and :math:\mathrm{atol}.

:math:\mathrm{atol}[i-1] and :math:\mathrm{y}[i-1] may both be zero.

Weight :math:i = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{itask} = 4 or :math:5 and :math:\textit{tcrit} is before :math:\mathrm{tout} in the direction of integration.

:math:\mathrm{itask} = \langle\mathit{\boldsymbol{value}}\rangle, :math:{\textit{tcrit}} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{atol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{atol}\geq 0.0.

(errno :math:1)
On entry, :math:\mathrm{rtol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{rtol}\geq 0.0.

(errno :math:1)
Either the value of :math:\textit{sdysav} is not the same as the value supplied to the setup function or a communication array has become corrupted.

:math:\textit{sdysav} = \langle\mathit{\boldsymbol{value}}\rangle, :math:\textit{sdysav} (setup) :math:{} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, an illegal (negative) minimum stepsize was provided in a prior call to a setup function. :math:{\textit{hmin}} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{tout} is less than :math:\mathrm{t} with respect to the direction of integration given by the sign of :math:\textit{h0} in a prior call to a setup function.

:math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle, :math:\mathrm{t} = \langle\mathit{\boldsymbol{value}}\rangle and :math:{\textit{h0}} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, an illegal (negative) maximum number of steps was provided in a prior call to a setup function. :math:{\textit{maxstp}} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{itol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:1\leq \mathrm{itol}\leq 4.

(errno :math:1)
On entry, :math:\textit{neq} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\textit{ldysav} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\textit{neq}\leq \textit{ldysav}.

(errno :math:1)
On entry, :math:\textit{neq} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\textit{neq}\geq 1.

(errno :math:1)
Either the function was entered on a continuation call without a prior call of this function, or a communication array has become corrupted.

(errno :math:1)
On entry, :math:\mathrm{tout} is too close to :math:\mathrm{t} to start integration.

:math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{t} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{itask} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:1\leq \mathrm{itask}\leq 5.

(errno :math:1)
Either the integrator setup function has not been called prior to the first call of this function, or a communication array has become corrupted.

(errno :math:1)
On entry, an illegal (negative) maximum stepsize was provided in a prior call to a setup function. :math:{\textit{hmax}} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
Either the linear algebra setup function has not been called prior to the first call of this function, or a communication array has become corrupted.

(errno :math:1)
:math:\mathrm{monitr} set :math:\mathrm{inln} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{inln} = 3.

(errno :math:1)
:math:\mathrm{monitr} appears to have overwritten the solution vector.

Further integration will not be attempted.

(errno :math:2)
At time :math:\langle\mathit{\boldsymbol{value}}\rangle the maximum number of allowed steps on this call was taken before reaching the next output point :math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle.

Maximum number of steps :math:{} = \langle\mathit{\boldsymbol{value}}\rangle.

See :meth:ivp_stiff_dassl for details of :math:\textit{maxstp}.

(errno :math:7)
:math:\mathrm{resid} set :math:\mathrm{ires} = 3, which signals that an error condition has occurred in the solution vector, its time derivative or in the value of :math:t. It was not possible to remove this condition.

:math:\mathrm{ires} = \langle\mathit{\boldsymbol{value}}\rangle at :math:t = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:8)
Attempt was made to reduce the step size to a value less than the minimum step size during the calculation of initial values.

Minimum stepsize: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:8)
The residual function returned an error when calculating the initial values of the solution and its time derivative.

(errno :math:8)
Workspace error occurred when trying to form the Jacobian matrix in calculating the initial values of the solution and its time derivative.

(errno :math:9)
A singular Jacobian has been encountered. You should check the problem formulation and Jacobian calculation.

(errno :math:10)
Not enough real store provided for sparse matrix solver.

Units of store needed: :math:\langle\mathit{\boldsymbol{value}}\rangle. Amount provided: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:10)
Larger integer workspace required.

Provided: :math:\langle\mathit{\boldsymbol{value}}\rangle; required: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:10)
Not enough integer store provided for internal storage pointers.

Units of store needed: :math:\langle\mathit{\boldsymbol{value}}\rangle. Amount provided: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:14)
On entry, too much accuracy requested for precision of the machine at the start of problem. The tolerances should be checked; the requested accuracy should be reduced by a factor of at least :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:15)
Either the sparse matrix linear algebra setup function was not called first or a communication array has become corrupted.

**Warns**
**NagAlgorithmicWarning**
(errno :math:3)
Too much accuracy requested for precision of the machine at time :math:\langle\mathit{\boldsymbol{value}}\rangle.

The tolerances should be checked; the requested accuracy should be reduced by a factor of at least :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:4)
There were repeated error-test failures on an attempted step, before completing the requested task, but the integration was successful as far as :math:\mathrm{t}. The problem may have a singularity, or the local error requirements may be inappropriate.

(errno :math:5)
There were repeated convergence-test failures on an attempted step, before completing the requested task, but the integration was successful as far as :math:\mathrm{t}. This may be caused by an inaccurate Jacobian matrix or one which is incorrectly computed.

(errno :math:6)
At time :math:\langle\mathit{\boldsymbol{value}}\rangle, error weight :math:\langle\mathit{\boldsymbol{value}}\rangle became zero. Check the values of :math:\mathrm{atol}, :math:\mathrm{rtol} and :math:\mathrm{itol} supplied.

(errno :math:8)
Nonlinear solver failed to converge using a damped Newton method to solve for initial values.

Damping factor: :math:\langle\mathit{\boldsymbol{value}}\rangle; convergence rate: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:8)
The user problem has one or more inconsistencies between the :math:\mathrm{ires} = 1 and :math:\mathrm{ires} = -1 parts. Integration will not be attempted.

(errno :math:10)
Not enough integer store provided for sparse matrix solver.

Units of store needed: :math:\langle\mathit{\boldsymbol{value}}\rangle. Amount provided: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:11)
:math:\mathrm{resid} set :math:\mathrm{ires} = 2, which signals that the integration should terminate. :math:\mathrm{ires} = \langle\mathit{\boldsymbol{value}}\rangle at time :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:12)
A return was forced by setting :math:\mathrm{imon} = -2, but the integration was successful as far as :math:\mathrm{t}.

(errno :math:13)
The requested task has been completed, but it is estimated that a small change in :math:\mathrm{rtol} and :math:\mathrm{atol} is unlikely to produce any change in the computed solution. (This ONLY applies when you are NOT operating in one step mode; that is, when :math:\mathrm{itask} \neq 2 or :math:5.)

.. _d02nj-py2-py-notes:

**Notes**
No equivalent traditional C interface for this routine exists in the NAG Library.

ivp_stiff_imp_sparjac is a general purpose function for integrating the initial value problem for a stiff system of implicit ordinary differential equations coupled with algebraic equations, written in the form

.. math::
A\left(t, y\right)y^{\prime } = g\left(t, y\right)\text{.}

It is designed specifically for the case where the resulting Jacobian is a sparse matrix (see the description of :math:\mathrm{jac}).

Both interval and step oriented modes of operation are available and also modes designed to permit intermediate output within an interval oriented mode.

A typical calling program for ivp_stiff_imp_sparjac would involve calling the sparse matrix linear algebra setup function :meth:ivp_stiff_sparjac_setup, the Backward Differentiation Formula (BDF) integrator setup function :meth:ivp_stiff_bdf, its diagnostic counterpart :meth:ivp_stiff_integ_diag, and the sparse matrix linear algebra diagnostic function :meth:ivp_stiff_sparjac_diag as well as the call to ivp_stiff_imp_sparjac.
The linear algebra setup function :meth:ivp_stiff_sparjac_setup and one of the integrator setup functions, :meth:ivp_stiff_dassl, :meth:ivp_stiff_bdf or :meth:ivp_stiff_blend, must be called prior to the call of ivp_stiff_imp_sparjac. Either or both of the integrator diagnostic function :meth:ivp_stiff_integ_diag, or the sparse matrix linear algebra diagnostic function :meth:ivp_stiff_sparjac_diag, may be called after the call to ivp_stiff_imp_sparjac. There is also a function, :meth:ivp_stiff_contin, designed to permit you to change step size on a continuation call to ivp_stiff_imp_sparjac without restarting the integration process.
"""
raise NotImplementedError

[docs]def ivp_stiff_exp_revcom(t, tout, y, ydot, comm, rtol, atol, itol, wkjac, imon, inln, ires, irevcm, itask, itrace, io_manager=None):
r"""
ivp_stiff_exp_revcom is a reverse communication function for integrating stiff systems of explicit ordinary differential equations.

.. _d02nm-py2-py-doc:

For full information please refer to the NAG Library document for d02nm

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02nmf.html

.. _d02nm-py2-py-parameters:

**Parameters**
**t** : float
On initial entry: :math:t, the value of the independent variable. The input value of :math:\mathrm{t} is used only on the first call as the initial point of the integration.

**tout** : float
On initial entry: the next value of :math:t at which a computed solution is desired. For the initial :math:t, the input value of :math:\mathrm{tout} is used to determine the direction of integration. Integration is permitted in either direction (see also :math:\mathrm{itask}).

**y** : float, ndarray, shape :math:\left(\textit{neq}\right), modified in place
On initial entry: the values of the dependent variables (solution). On the first call the first :math:\textit{neq} elements of :math:y must contain the vector of initial values.

On final exit: the computed solution vector evaluated at :math:\mathrm{t} (usually :math:t = \mathrm{tout}).

**ydot** : float, ndarray, shape :math:\left(\textit{neq}\right), modified in place
On intermediate entry: must be set to the derivatives as defined under the description of :math:\mathrm{irevcm}.

On final exit: the time derivatives :math:y^{\prime } of the vector :math:y at the last integration point.

**comm** : dict, communication object, modified in place
Communication structure.

This argument must have been initialized by prior calls to one of :meth:ivp_stiff_fulljac_setup, :meth:ivp_stiff_bandjac_setup or :meth:ivp_stiff_sparjac_setup and one of :meth:ivp_stiff_dassl, :meth:ivp_stiff_bdf or :meth:ivp_stiff_blend.

**rtol** : float, array-like, shape :math:\left(:\right)
Note: the required length for this argument is determined as follows: if :math:\mathrm{itol}\text{ in } (1, 2): :math:1; otherwise: :math:\textit{neq}.

On initial entry: the relative local error tolerance.

**atol** : float, array-like, shape :math:\left(:\right)
Note: the required length for this argument is determined as follows: if :math:\mathrm{itol}\text{ in } (1, 3): :math:1; otherwise: :math:\textit{neq}.

On initial entry: the absolute local error tolerance.

**itol** : int
On initial entry: a value to indicate the form of the local error test. :math:\mathrm{itol} indicates to ivp_stiff_exp_revcom whether to interpret either or both of :math:\mathrm{rtol} or :math:\mathrm{atol} as a vector or a scalar. The error test to be satisfied is :math:\left\lVert e_i/w_i\right\rVert < 1.0, where :math:w_i is defined as follows:

+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+
|:math:\mathrm{itol}|:math:\mathrm{rtol}|:math:\mathrm{atol}|:math:w_i                                                                     |
+=====================+=====================+=====================+================================================================================+
|1                    |scalar               |scalar               |:math:\mathrm{rtol}[0]\times \left\lvert y_i\right\rvert +\mathrm{atol}[0]    |
+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+
|2                    |scalar               |vector               |:math:\mathrm{rtol}[0]\times \left\lvert y_i\right\rvert +\mathrm{atol}[i-1]  |
+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+
|3                    |vector               |scalar               |:math:\mathrm{rtol}[i-1]\times \left\lvert y_i\right\rvert +\mathrm{atol}[0]  |
+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+
|4                    |vector               |vector               |:math:\mathrm{rtol}[i-1]\times \left\lvert y_i\right\rvert +\mathrm{atol}[i-1]|
+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+

:math:e_i is an estimate of the local error in :math:y_i, computed internally, and the choice of norm to be used is defined by a previous call to an integrator setup function.

**wkjac** : float, ndarray, shape :math:\left(\textit{nwkjac}\right), modified in place
On intermediate entry: elements of the Jacobian as defined under the description of :math:\mathrm{irevcm}. If a numerical Jacobian was requested then :math:\mathrm{wkjac} is used for workspace.

On intermediate exit: the Jacobian is overwritten.

**imon** : int
On intermediate entry: may be reset to determine subsequent action in ivp_stiff_exp_revcom.

:math:\mathrm{imon} = -2

Integration is to be halted. A return will be made from ivp_stiff_exp_revcom to the calling (sub)program with :math:\mathrm{errno} = 12.

:math:\mathrm{imon} = -1

Allow ivp_stiff_exp_revcom to continue with its own internal strategy. The integrator will try up to three restarts unless :math:\mathrm{imon}\neq -1.

:math:\mathrm{imon} = 0

Return to the internal nonlinear equation solver, where the action taken is determined by the value of :math:\mathrm{inln}.

:math:\mathrm{imon} = 1

Normal exit to ivp_stiff_exp_revcom to continue integration.

:math:\mathrm{imon} = 2

Restart the integration at the current time point. The integrator will restart from order :math:1 when this option is used. The solution :math:\mathrm{y}, provided by the :math:\mathrm{monitr} operation (see :ref:Notes <d02nm-py2-py-notes>), will be used for the initial conditions.

:math:\mathrm{imon} = 3

Try to continue with the same step size and order as was to be used before entering the :math:\mathrm{monitr} operation (see :ref:Notes <d02nm-py2-py-notes>). :math:\mathrm{hmin} and :math:\mathrm{hmax} may be altered if desired.

:math:\mathrm{imon} = 4

Continue the integration but using a new value of :math:\mathrm{hnext} and possibly new values of :math:\mathrm{hmin} and :math:\mathrm{hmax}.

**inln** : int
On intermediate entry: with :math:\mathrm{imon} = 0 and :math:\mathrm{irevcm} = 9, :math:\mathrm{inln} specifies the action to be taken by the internal nonlinear equation solver. By setting :math:\mathrm{inln} = 3 and returning to ivp_stiff_exp_revcom, the residual vector is evaluated and placed in :math:\mathrm{comm}\ ['rwork'][50+2\times \textit{neq}+\textit{i}-1], for :math:\textit{i} = 1,2,\ldots,\textit{neq} and then the :math:\mathrm{monitr} operation (see :ref:Notes <d02nm-py2-py-notes>) is invoked again. At present this is the only option available: :math:\mathrm{inln} must not be set to any other value.

**ires** : int
On intermediate entry: should be unchanged unless one of the following actions is required of ivp_stiff_exp_revcom in which case :math:\mathrm{ires} should be set accordingly.

:math:\mathrm{ires} = 2

Indicates to ivp_stiff_exp_revcom that control should be passed back immediately to the calling (sub)program with the error indicator set to :math:\mathrm{errno} = 11.

:math:\mathrm{ires} = 3

Indicates to ivp_stiff_exp_revcom that an error condition has occurred in the solution vector, its time derivative or in the value of :math:t. The integrator will use a smaller time step to try to avoid this condition. If this is not possible ivp_stiff_exp_revcom returns to the calling (sub)program with the error indicator set to :math:\mathrm{errno} = 7.

:math:\mathrm{ires} = 4

Indicates to ivp_stiff_exp_revcom to stop its current operation and to enter the :math:\mathrm{monitr} operation (see :ref:Notes <d02nm-py2-py-notes>) immediately.

**irevcm** : int
On initial entry: must contain :math:0.

On intermediate entry: should remain unchanged.

On initial entry: the task to be performed by the integrator.

:math:\mathrm{itask} = 1

Normal computation of output values of :math:y\left(t\right) at :math:t = \mathrm{tout} (by overshooting and interpolating).

:math:\mathrm{itask} = 2

Take one step only and return.

:math:\mathrm{itask} = 3

Stop at the first internal integration point at or beyond :math:t = \mathrm{tout} and return.

:math:\mathrm{itask} = 4

Normal computation of output values of :math:y\left(t\right) at :math:t = \mathrm{tout} but without overshooting :math:t = {\textit{tcrit}}. :math:\textit{tcrit} must be specified as an option in one of the integrator setup functions before the first call to the integrator, or specified in the optional input function before a continuation call. :math:\textit{tcrit} (e.g., see :meth:ivp_stiff_bdf) may be equal to or beyond :math:\mathrm{tout}, but not before it in the direction of integration.

:math:\mathrm{itask} = 5

Take one step only and return, without passing :math:\textit{tcrit} (e.g., see :meth:ivp_stiff_bdf). :math:\textit{tcrit} must be specified under :math:\mathrm{itask} = 4.

**itrace** : int
On initial entry: the level of output that is printed by the integrator. :math:\mathrm{itrace} may take the value :math:-1, :math:0, :math:1, :math:2 or :math:3.

:math:\mathrm{itrace} < -1

:math:-1 is assumed and similarly if :math:\mathrm{itrace} > 3, :math:3 is assumed.

:math:\mathrm{itrace} = -1

No output is generated.

:math:\mathrm{itrace} = 0

Only warning messages are printed on the current error message unit (see :class:~naginterfaces.base.utils.FileObjManager).

:math:\mathrm{itrace} > 0

Warning messages are printed as above, and on the file object associated with the advisory I/O unit (see :class:~naginterfaces.base.utils.FileObjManager) output is generated which details Jacobian entries, the nonlinear iteration and the time integration. The advisory messages are given in greater detail the larger the value of :math:\mathrm{itrace}.

**io_manager** : FileObjManager, optional
Manager for I/O in this routine.

**Returns**
**t** : float
On final exit: the value at which the computed solution :math:y is returned (usually at :math:\mathrm{tout}).

**imon** : int
On intermediate exit: used to pass information between ivp_stiff_exp_revcom and the MONITR operation (see :ref:Notes <d02nm-py2-py-notes>). With :math:\mathrm{irevcm} = 9, :math:\mathrm{imon} contains a flag indicating under what circumstances the return from ivp_stiff_exp_revcom occurred:

:math:\mathrm{imon} = -2

Exit from ivp_stiff_exp_revcom after :math:\mathrm{ires} = 4 caused an early termination (this facility could be used to locate discontinuities).

:math:\mathrm{imon} = -1

The current step failed repeatedly.

:math:\mathrm{imon} = 0

Exit from ivp_stiff_exp_revcom after a call to the internal nonlinear equation solver.

:math:\mathrm{imon} = 1

The current step was successful.

**inln** : int
On intermediate exit: contains a flag indicating the action to be taken, if any, by the internal nonlinear equation solver.

**ires** : int
On intermediate exit: with :math:\mathrm{irevcm} = 1, :math:2, :math:3, :math:4 or :math:5, :math:\mathrm{ires} contains the value :math:1.

**irevcm** : int
On intermediate exit: indicates what action you must take before re-entering. The possible exit values of :math:\mathrm{irevcm} are :math:1, :math:3, :math:4, :math:5, :math:8, :math:9 or :math:10, which should be interpreted as follows:

:math:\mathrm{irevcm} = 1, :math:3, :math:4 or :math:5

Indicates that an FCN operation (see :ref:Notes <d02nm-py2-py-notes>) is required: :math:y^{\prime } = g\left(t, y\right) must be supplied, where :math:\mathrm{y}[\textit{i}-1] is located in :math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{neq}.

For :math:\mathrm{irevcm} = 1 or :math:3, :math:y_{\textit{i}}^{\prime } should be placed in location :math:\mathrm{comm}\ ['rwork'][50+2\times \textit{neq}+\textit{i}-1], for :math:\textit{i} = 1,2,\ldots,\textit{neq}.

For :math:\mathrm{irevcm} = 4, :math:y_{\textit{i}}^{\prime } should be placed in location :math:\mathrm{comm}\ ['rwork'][50+\textit{neq}+\textit{i}-1], for :math:\textit{i} = 1,2,\ldots,\textit{neq}.

For :math:\mathrm{irevcm} = 5, :math:y_{\textit{i}}^{\prime } should be placed in location :math:\mathrm{ydot}[\textit{i}-1], for :math:\textit{i} = 1,2,\ldots,\textit{neq}.

:math:\mathrm{irevcm} = 8

Indicates that a JAC operation (see :ref:Notes <d02nm-py2-py-notes>) is required: the Jacobian matrix must be supplied.

If full matrix linear algebra is being used, the :math:\left(i, j\right)\ th element of the Jacobian must be stored in :math:\mathrm{wkjac}[\left(j-1\right)\times \textit{neq}+i-1].

If banded matrix linear algebra is being used then the :math:\left(i, j\right)\ th element of the Jacobian must be stored in :math:\mathrm{wkjac}[\left(i-1\right)\times m_B+k-1], where :math:m_B = m_L+m_U+1 and :math:k = \mathrm{min}\left({m_L-i+1}, 0\right)+j; here :math:m_L and :math:m_U are the number of subdiagonals and superdiagonals, respectively, in the band.

If sparse matrix linear algebra is being used then :meth:ivp_stiff_sparjac_enq must be called to determine which column of the Jacobian is required and where it should be stored.

:math:\mathrm{irevcm} = 9

Indicates that a MONITR operation (see :ref:Notes <d02nm-py2-py-notes>) can be performed.

:math:\mathrm{irevcm} = 10

Indicates that the current step was not successful, due to error test failure or convergence test failure. The only information supplied to you on this return is the current value of the independent variable :math:t, located in :math:\mathrm{comm}\ ['rwork'][18]. No values must be changed before re-entering ivp_stiff_exp_revcom; this facility enables you to determine the number of unsuccessful steps.

On final exit: :math:\mathrm{irevcm} = 0 indicated the user-specified task has been completed or an error has been encountered (see the descriptions for :math:\mathrm{itask} and :math:\textit{errno}).

.. _d02nm-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On re-entry, :math:\mathrm{imon} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:-2\leq \mathrm{imon}\leq 4.

(errno :math:1)
Failure during internal time interpolation. :math:\mathrm{tout} and the current time are too close.

:math:\mathrm{itask} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle and the current time is :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{itask} = 4 or :math:5 and :math:\textit{tcrit} is before the current time in the direction of integration.

:math:\mathrm{itask} = \langle\mathit{\boldsymbol{value}}\rangle, :math:{\textit{tcrit}} = \langle\mathit{\boldsymbol{value}}\rangle and the current time is :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
:math:\mathrm{itask} = 3 and :math:\mathrm{tout} is more than an integration step behind the current time.

:math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle, current time minus step size: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
The initial stepsize, :math:\langle\mathit{\boldsymbol{value}}\rangle, is too small.

(errno :math:1)
Weight number :math:i = \langle\mathit{\boldsymbol{value}}\rangle used in the local error test is too small. Check the values of :math:\mathrm{rtol} and :math:\mathrm{atol}.

:math:\mathrm{atol}[i-1] and :math:\mathrm{y}[i-1] may both be zero.

Weight :math:i = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{itask} = 4 or :math:5 and :math:\textit{tcrit} is before :math:\mathrm{tout} in the direction of integration.

:math:\mathrm{itask} = \langle\mathit{\boldsymbol{value}}\rangle, :math:{\textit{tcrit}} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{atol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{atol}\geq 0.0.

(errno :math:1)
On entry, :math:\mathrm{rtol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{rtol}\geq 0.0.

(errno :math:1)
Either the value of :math:\textit{nwkjac} is not the same as the value supplied to the setup function or a communication array has become corrupted.

:math:\textit{nwkjac} = \langle\mathit{\boldsymbol{value}}\rangle, :math:\textit{nwkjac} (setup) :math:{} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
Either the value of :math:\textit{sdysav} is not the same as the value supplied to the setup function or a communication array has become corrupted.

:math:\textit{sdysav} = \langle\mathit{\boldsymbol{value}}\rangle, :math:\textit{sdysav} (setup) :math:{} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, an illegal (negative) minimum stepsize was provided in a prior call to a setup function. :math:{\textit{hmin}} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{tout} is less than :math:\mathrm{t} with respect to the direction of integration given by the sign of :math:\textit{h0} in a prior call to a setup function.

:math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle, :math:\mathrm{t} = \langle\mathit{\boldsymbol{value}}\rangle and :math:{\textit{h0}} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, an illegal (negative) maximum number of steps was provided in a prior call to a setup function. :math:{\textit{maxstp}} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{itol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:1\leq \mathrm{itol}\leq 4.

(errno :math:1)
On entry, :math:\textit{neq} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\textit{ldysav} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\textit{neq}\leq \textit{ldysav}.

(errno :math:1)
On entry, :math:\textit{neq} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\textit{neq}\geq 1.

(errno :math:1)
Either the function was entered on a continuation call without a prior call of this function, or a communication array has become corrupted.

(errno :math:1)
On entry, :math:\mathrm{tout} is too close to :math:\mathrm{t} to start integration.

:math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{t} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{itask} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:1\leq \mathrm{itask}\leq 5.

(errno :math:1)
Either the integrator setup function has not been called prior to the first call of this function, or a communication array has become corrupted.

(errno :math:1)
On entry, an illegal (negative) maximum stepsize was provided in a prior call to a setup function. :math:{\textit{hmax}} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
Either the linear algebra setup function has not been called prior to the first call of this function, or a communication array has become corrupted.

(errno :math:1)
On re-entry, :math:\mathrm{inln} \neq 3 for the case :math:\mathrm{irevcm} = 9 and :math:\mathrm{imon} = 0.

:math:\mathrm{inln} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{irevcm} is invalid: :math:\mathrm{irevcm} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On re-entry, the solution vector appears to have been overwritten.

Further integration will not be attempted.

(errno :math:2)
At time :math:\langle\mathit{\boldsymbol{value}}\rangle the maximum number of allowed steps on this call was taken before reaching the next output point :math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle.

Maximum number of steps :math:{} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:7)
The derivative evaluation procedure set the error flag :math:\mathrm{ires} = 3 repeatedly despite attempts by the integrator to avoid this.

(errno :math:9)
A singular Jacobian has been encountered. You should check the problem formulation and Jacobian calculation.

(errno :math:10)
Workspace error occurred when trying to form the Jacobian matrix in calculating the initial values of the solution and its time derivative.

(errno :math:10)
Not enough integer store provided for sparse matrix solver.

Units of store needed: :math:\langle\mathit{\boldsymbol{value}}\rangle. Amount provided: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:10)
Larger integer workspace required.

Provided: :math:\langle\mathit{\boldsymbol{value}}\rangle; required: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:10)
Not enough real store provided for sparse matrix solver.

Units of store needed: :math:\langle\mathit{\boldsymbol{value}}\rangle. Amount provided: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:14)
On entry, too much accuracy requested for precision of the machine at the start of problem. The tolerances should be checked; the requested accuracy should be reduced by a factor of at least :math:\langle\mathit{\boldsymbol{value}}\rangle.

**Warns**
**NagAlgorithmicWarning**
(errno :math:3)
Too much accuracy requested for precision of the machine at time :math:\langle\mathit{\boldsymbol{value}}\rangle.

The tolerances should be checked; the requested accuracy should be reduced by a factor of at least :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:4)
There were repeated error-test failures on an attempted step, before completing the requested task, but the integration was successful as far as :math:\mathrm{t}. The problem may have a singularity, or the local error requirements may be inappropriate.

(errno :math:5)
There were repeated convergence-test failures on an attempted step, before completing the requested task, but the integration was successful as far as :math:\mathrm{t}. This may be caused by an inaccurate Jacobian matrix or one which is incorrectly computed.

(errno :math:6)
At time :math:\langle\mathit{\boldsymbol{value}}\rangle, error weight :math:\langle\mathit{\boldsymbol{value}}\rangle became zero. Check the values of :math:\mathrm{atol}, :math:\mathrm{rtol} and :math:\mathrm{itol} supplied.

(errno :math:11)
On re-entry, :math:\mathrm{ires} = 2, which signals that the integration should terminate. :math:\mathrm{ires} = \langle\mathit{\boldsymbol{value}}\rangle at time :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:12)
A return was forced by setting :math:\mathrm{imon} = -2, but the integration was successful as far as :math:\mathrm{t}.

(errno :math:13)
The requested task has been completed, but it is estimated that a small change in :math:\mathrm{rtol} and :math:\mathrm{atol} is unlikely to produce any change in the computed solution. (This ONLY applies when you are NOT operating in one step mode; that is, when :math:\mathrm{itask} \neq 2 or :math:5.)

.. _d02nm-py2-py-notes:

**Notes**
No equivalent traditional C interface for this routine exists in the NAG Library.

ivp_stiff_exp_revcom is a general purpose function for integrating the initial value problem for a stiff system of explicit ordinary differential equations,

.. math::
y^{\prime } = g\left(t, y\right)\text{.}

An outline of a typical calling program is

call the linear algebra setup routine

call the integrator setup routine

set :math:\mathrm{irevcm} = 0

start looping

call ivp_stiff_exp_revcom

if :math:\mathrm{irevcm} = 8 then

supply the Jacobian matrix

else if :math:\mathrm{irevcm} = 9 then

perform monitoring tasks requested by the user

else if :math:\mathrm{irevcm} = 1 or :math:3\leq \mathrm{irevcm}\leq 5 then

evaluate the derivative

else if :math:\mathrm{irevcm} = 10 then

indicates an unsuccessful step

else

stop looping

post processing; optional linear algebra diagnostic call (sparse case only), optional integrator diagnostic call

There are three major operations that may be required of the calling function on an intermediate return (:math:\mathrm{irevcm}\neq 0) from ivp_stiff_exp_revcom; these are denoted (i), (ii) and (iii).

The following sections describe in greater detail exactly what is required of each of these operations.

(i) **Supply the Jacobian matrix**

You need only provide this facility if the argument :math:{\textit{jceval}} = \texttt{'A'} (or :math:{\textit{jceval}} = \texttt{'F'} if using sparse matrix linear algebra) in a call to the linear algebra setup function (see :math:\textit{jceval} in :meth:ivp_stiff_fulljac_setup).
If the Jacobian matrix is to be evaluated numerically by the integrator, then the remainder of section (i) can be ignored.

We must define the system of nonlinear equations which is solved internally by the integrator.
The time derivative, :math:y^{\prime }, has the form

.. math::
y^{\prime } = \left(y-z\right)/\left(hd\right)\text{,}

where :math:h is the current step size and :math:d is an argument that depends on the integration method in use.
The vector :math:y is the current solution and the vector :math:z depends on information from previous time steps.
This means that :math:\frac{d}{{dy^{\prime }}}\left(\text{ }\right) = \left(hd\right)\frac{d}{{dy}}\left(\text{ }\right).

The system of nonlinear equations that is solved has the form

.. math::
y^{\prime }-g\left(t, y\right) = 0

but is solved in the form

.. math::
r\left(t, y\right) = 0\text{,}

where the function :math:r is defined by

.. math::
r\left(t, y\right) = \left(hd\right)\left({\left(y-z\right)/\left(hd\right)-g\left(t, y\right)}\right)\text{.}

It is the Jacobian matrix :math:\frac{{\partial r}}{{\partial y}} that you must supply as follows:

.. math::
\begin{array}{ccc}&\frac{{\partial r_i}}{{\partial y_j}} = 1-\left(hd\right)\frac{{\partial g_i}}{{\partial y_j}}&\text{if }i = j\text{,}\\&\\&\\&\frac{{\partial r_i}}{{\partial y_j}} = -\left(hd\right)\frac{{\partial g_i}}{{\partial y_j}}&\text{otherwise,}\end{array}

where :math:t, :math:h and :math:d are located in :math:\mathrm{comm}\ ['rwork'][18], :math:\mathrm{comm}\ ['rwork'][15] and :math:\mathrm{comm}\ ['rwork'][19] respectively and the array :math:\mathrm{y} contains the current values of the dependent variables.
Only the nonzero elements of the Jacobian need be set, since the locations where it is to be stored are preset to zero.

**In this document this operation is referred to as JAC.**

(#) **Perform tasks requested by you**

This operation is essentially a monitoring function and additionally provides the opportunity of changing the current values of :math:\mathrm{y}, HNEXT (the step size that the integrator proposes to take on the next step), HMIN (the minimum step size to be taken on the next step), and HMAX (the maximum step size to be taken on the next step).
The scaled local error at the end of a timestep may be obtained by calling :meth:ivp_stiff_errest.

The following gives details of the location within the array :math:\mathrm{comm}\ ['rwork'] of variables that may be of interest to you:

+----------------------+---------------------------------------------------------------+------------------------------------+
|Variable              |Specification                                                  |Location                            |
+======================+===============================================================+====================================+
|:math:\mathrm{tcurr}|the current value of the independent variable                  |:math:\mathrm{comm}\ ['rwork'][18]|
+----------------------+---------------------------------------------------------------+------------------------------------+
|:math:\mathrm{hlast}|last step size successfully used by the integrator             |:math:\mathrm{comm}\ ['rwork'][14]|
+----------------------+---------------------------------------------------------------+------------------------------------+
|:math:\mathrm{hnext}|step size that the integrator proposes to take on the next step|:math:\mathrm{comm}\ ['rwork'][15]|
+----------------------+---------------------------------------------------------------+------------------------------------+
|:math:\mathrm{hmin} |minimum step size to be taken on the next step                 |:math:\mathrm{comm}\ ['rwork'][16]|
+----------------------+---------------------------------------------------------------+------------------------------------+
|:math:\mathrm{hmax} |maximum step size to be taken on the next step                 |:math:\mathrm{comm}\ ['rwork'][17]|
+----------------------+---------------------------------------------------------------+------------------------------------+
|:math:\mathrm{nqu}  |the order of the integrator used on the last step              |:math:\mathrm{comm}\ ['rwork'][9] |
+----------------------+---------------------------------------------------------------+------------------------------------+

You are advised to consult the description of :math:\textit{monitr} in :meth:ivp_stiff_exp_fulljac for details on what optional input can be made.

If :math:\mathrm{y} is changed, then :math:\mathrm{imon} must be set to :math:2 before return to ivp_stiff_exp_revcom.
If either of the values of HMIN or HMAX are changed, then :math:\mathrm{imon} must be set :math:\text{}\geq 3 before return to ivp_stiff_exp_revcom.
If HNEXT is changed, then :math:\mathrm{imon} must be set to :math:4 before return to ivp_stiff_exp_revcom.

In addition you can force ivp_stiff_exp_revcom to evaluate the residual vector

.. math::
y^{\prime }-g\left(t, y\right)

by setting :math:\mathrm{imon} = 0 and :math:\mathrm{inln} = 3 and then returning to ivp_stiff_exp_revcom; on return to this monitoring operation the residual vector will be stored in :math:\mathrm{comm}\ ['rwork'][50+2\times \textit{neq}+\textit{i}-1], for :math:\textit{i} = 1,2,\ldots,\textit{neq}.

**In this document this operation is referred to as MONITR.**

(#) **Evaluate the derivative**

This operation must evaluate the derivative vector for the explicit ordinary differential equation system defined by

.. math::
y^{\prime } = g\left(t, y\right)\text{,}

where :math:t is located in :math:\mathrm{comm}\ ['rwork'][18].

**In this document this operation is referred to as FCN.**
"""
raise NotImplementedError

[docs]def ivp_stiff_imp_revcom(t, tout, y, ydot, comm, rtol, atol, itol, wkjac, imon, inln, ires, irevcm, lderiv, itask, itrace, io_manager=None):
r"""
ivp_stiff_imp_revcom is a reverse communication function for integrating stiff systems of implicit ordinary differential equations coupled with algebraic equations.

.. _d02nn-py2-py-doc:

For full information please refer to the NAG Library document for d02nn

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02nnf.html

.. _d02nn-py2-py-parameters:

**Parameters**
**t** : float
On initial entry: :math:t, the value of the independent variable. The input value of :math:\mathrm{t} is used only on the first call as the initial point of the integration.

**tout** : float
On initial entry: the next value of :math:t at which a computed solution is desired. For the initial :math:t, the input value of :math:\mathrm{tout} is used to determine the direction of integration. Integration is permitted in either direction (see also :math:\mathrm{itask}).

**y** : float, ndarray, shape :math:\left(\textit{neq}\right), modified in place
On initial entry: the values of the dependent variables (solution). On the first call the first :math:\textit{neq} elements of :math:y must contain the vector of initial values.

On final exit: the computed solution vector evaluated at :math:\mathrm{t} (usually :math:t = \mathrm{tout}).

**ydot** : float, ndarray, shape :math:\left(\textit{neq}\right), modified in place
On initial entry: if :math:\mathrm{lderiv}[0] = \mathbf{True}, :math:\mathrm{ydot} must contain approximations to the time derivatives :math:y^{\prime } of the vector :math:y. If :math:\mathrm{lderiv}[0] = \mathbf{False}, :math:\mathrm{ydot} need not be set on entry.

On final exit: contains the time derivatives :math:y^{\prime } of the vector :math:y at the last integration point.

**comm** : dict, communication object, modified in place
Communication structure.

This argument must have been initialized by prior calls to one of :meth:ivp_stiff_fulljac_setup, :meth:ivp_stiff_bandjac_setup or :meth:ivp_stiff_sparjac_setup and one of :meth:ivp_stiff_dassl, :meth:ivp_stiff_bdf or :meth:ivp_stiff_blend.

**rtol** : float, array-like, shape :math:\left(:\right)
Note: the required length for this argument is determined as follows: if :math:\mathrm{itol}\text{ in } (1, 2): :math:1; otherwise: :math:\textit{neq}.

On initial entry: the relative local error tolerance.

**atol** : float, array-like, shape :math:\left(:\right)
Note: the required length for this argument is determined as follows: if :math:\mathrm{itol}\text{ in } (1, 3): :math:1; otherwise: :math:\textit{neq}.

On initial entry: the absolute local error tolerance.

**itol** : int
On initial entry: a value to indicate the form of the local error test. :math:\mathrm{itol} indicates to ivp_stiff_imp_revcom whether to interpret either or both of :math:\mathrm{rtol} or :math:\mathrm{atol} as a vector or a scalar. The error test to be satisfied is :math:\left\lVert e_i/w_i\right\rVert < 1.0, where :math:w_i is defined as follows:

+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+
|:math:\mathrm{itol}|:math:\mathrm{rtol}|:math:\mathrm{atol}|:math:w_i                                                                     |
+=====================+=====================+=====================+================================================================================+
|1                    |scalar               |scalar               |:math:\mathrm{rtol}[0]\times \left\lvert y_i\right\rvert +\mathrm{atol}[0]    |
+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+
|2                    |scalar               |vector               |:math:\mathrm{rtol}[0]\times \left\lvert y_i\right\rvert +\mathrm{atol}[i-1]  |
+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+
|3                    |vector               |scalar               |:math:\mathrm{rtol}[i-1]\times \left\lvert y_i\right\rvert +\mathrm{atol}[0]  |
+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+
|4                    |vector               |vector               |:math:\mathrm{rtol}[i-1]\times \left\lvert y_i\right\rvert +\mathrm{atol}[i-1]|
+---------------------+---------------------+---------------------+--------------------------------------------------------------------------------+

:math:e_i is an estimate of the local error in :math:y_i, computed internally, and the choice of norm to be used is defined by a previous call to an integrator setup function.

**wkjac** : float, ndarray, shape :math:\left(\textit{nwkjac}\right), modified in place
On intermediate entry: elements of the Jacobian as defined under the description of :math:\mathrm{irevcm}. If a numerical Jacobian was requested then :math:\mathrm{wkjac} is used for workspace.

On intermediate exit: the Jacobian is overwritten.

**imon** : int
On intermediate entry: may be reset to determine subsequent action in ivp_stiff_imp_revcom.

:math:\mathrm{imon} = -2

Integration is to be halted. A return will be made from ivp_stiff_imp_revcom to the calling (sub)program with :math:\mathrm{errno} = 12.

:math:\mathrm{imon} = -1

Allow ivp_stiff_imp_revcom to continue with its own internal strategy. The integrator will try up to three restarts unless :math:\mathrm{imon}\neq -1.

:math:\mathrm{imon} = 0

Return to the internal nonlinear equation solver, where the action taken is determined by the value of :math:\mathrm{inln}.

:math:\mathrm{imon} = 1

Normal exit to ivp_stiff_imp_revcom to continue integration.

:math:\mathrm{imon} = 2

Restart the integration at the current time point. The integrator will restart from order :math:1 when this option is used. The internal initialization module solves for new values of :math:y and :math:y^{\prime } by using the values supplied in :math:\mathrm{y} and :math:\mathrm{ydot} by the :math:\mathrm{monitr} operation (see :ref:Notes <d02nn-py2-py-notes>) as initial estimates.

:math:\mathrm{imon} = 3

Try to continue with the same step size and order as was to be used before entering the :math:\mathrm{monitr} operation (see :ref:Notes <d02nn-py2-py-notes>). :math:\mathrm{hmin} and :math:\mathrm{hmax} may be altered if desired.

:math:\mathrm{imon} = 4

Continue the integration but using a new value of :math:\mathrm{hnext} and possibly new values of :math:\mathrm{hmin} and :math:\mathrm{hmax}.

**inln** : int
On intermediate entry: with :math:\mathrm{imon} = 0 and :math:\mathrm{irevcm} = 9, :math:\mathrm{inln} specifies the action to be taken by the internal nonlinear equation solver. By setting :math:\mathrm{inln} = 3 and returning to ivp_stiff_imp_revcom, the residual vector is evaluated and placed in :math:\mathrm{comm}\ ['rwork'][50+2\times \textit{neq}+\textit{i}-1], for :math:\textit{i} = 1,2,\ldots,\textit{neq} and then the :math:\mathrm{monitr} operation (see :ref:Notes <d02nn-py2-py-notes>) is invoked again. At present this is the only option available: :math:\mathrm{inln} must not be set to any other value.

**ires** : int
On intermediate entry: should be unchanged unless one of the following actions is required of ivp_stiff_imp_revcom in which case :math:\mathrm{ires} should be set accordingly.

:math:\mathrm{ires} = 2

Indicates to ivp_stiff_imp_revcom that control should be passed back immediately to the calling (sub)program with the error indicator set to :math:\mathrm{errno} = 11.

:math:\mathrm{ires} = 3

Indicates to ivp_stiff_imp_revcom that an error condition has occurred in the solution vector, its time derivative or in the value of :math:t. The integrator will use a smaller time step to try to avoid this condition. If this is not possible ivp_stiff_imp_revcom returns to the calling (sub)program with the error indicator set to :math:\mathrm{errno} = 7.

:math:\mathrm{ires} = 4

Indicates to ivp_stiff_imp_revcom to stop its current operation and to enter the :math:\mathrm{monitr} operation (see :ref:Notes <d02nn-py2-py-notes>) immediately.

**irevcm** : int
On initial entry: must contain :math:0.

On intermediate entry: should remain unchanged.

**lderiv** : bool, ndarray, shape :math:\left(2\right), modified in place
On initial entry: :math:\mathrm{lderiv}[0] must be set to :math:\mathbf{True} if you have supplied both an initial :math:y and an initial :math:y^{\prime }. :math:\mathrm{lderiv}[0] must be set to :math:\mathbf{False} if only the initial :math:y has been supplied.

:math:\mathrm{lderiv}[1] must be set to :math:\mathbf{True} if the integrator is to use a modified Newton method to evaluate the initial :math:y and :math:y^{\prime }.

Note that :math:y and :math:y^{\prime }, if supplied, are used as initial estimates.

This method involves taking a small step at the start of the integration, and if :math:\mathrm{itask} = 6 on entry, :math:\mathrm{t} and :math:\mathrm{tout} will be set to the result of taking this small step. :math:\mathrm{lderiv}[1] must be set to :math:\mathbf{False} if the integrator is to use functional iteration to evaluate the initial :math:y and :math:y^{\prime }, and if this fails a modified Newton method will then be attempted. :math:\mathrm{lderiv}[1] = \mathbf{True} is recommended if there are implicit equations or the initial :math:y and :math:y^{\prime } are zero.

On final exit: :math:\mathrm{lderiv}[0] is normally unchanged. However if :math:\mathrm{itask} = 6 and internal initialization was successful then :math:\mathrm{lderiv}[0] = \mathbf{True}.

:math:\mathrm{lderiv}[1] = \mathbf{True}, if implicit equations were detected.

Otherwise :math:\mathrm{lderiv}[1] = \mathbf{False}.

On initial entry: the task to be performed by the integrator.

:math:\mathrm{itask} = 1

Normal computation of output values of :math:y\left(t\right) at :math:t = \mathrm{tout} (by overshooting and interpolating).

:math:\mathrm{itask} = 2

Take one step only and return.

:math:\mathrm{itask} = 3

Stop at the first internal integration point at or beyond :math:t = \mathrm{tout} and return.

:math:\mathrm{itask} = 4

Normal computation of output values of :math:y\left(t\right) at :math:t = \mathrm{tout} but without overshooting :math:t = {\textit{tcrit}}. :math:\textit{tcrit} must be specified as an option in one of the integrator setup functions before the first call to the integrator, or specified in the optional input function before a continuation call. :math:\textit{tcrit} (e.g., see :meth:ivp_stiff_bdf) may be equal to or beyond :math:\mathrm{tout}, but not before it in the direction of integration.

:math:\mathrm{itask} = 5

Take one step only and return, without passing :math:\textit{tcrit} (e.g., see :meth:ivp_stiff_bdf). :math:\textit{tcrit} must be specified under :math:\mathrm{itask} = 4.

:math:\mathrm{itask} = 6

The integrator will solve for the initial values of :math:y and :math:y^{\prime } only and then return to the calling (sub)program without doing the integration. This option can be used to check the initial values of :math:y and :math:y^{\prime }. Functional iteration or a 'small' backward Euler method used in conjunction with a damped Newton iteration is used to calculate these values (see :math:\mathrm{lderiv}). Note that if a backward Euler step is used then the value of :math:t will have been advanced a short distance from the initial point.

**Note:** if ivp_stiff_imp_revcom is recalled with a different value of :math:\mathrm{itask} (and :math:\mathrm{tout} altered) then the initialization procedure is repeated, possibly leading to different initial conditions.

**itrace** : int
On initial entry: the level of output that is printed by the integrator. :math:\mathrm{itrace} may take the value :math:-1, :math:0, :math:1, :math:2 or :math:3.

:math:\mathrm{itrace} < -1

:math:-1 is assumed and similarly if :math:\mathrm{itrace} > 3, :math:3 is assumed.

:math:\mathrm{itrace} = -1

No output is generated.

:math:\mathrm{itrace} = 0

Only warning messages are printed on the current error message unit (see :class:~naginterfaces.base.utils.FileObjManager).

:math:\mathrm{itrace} > 0

Warning messages are printed as above, and on the file object associated with the advisory I/O unit (see :class:~naginterfaces.base.utils.FileObjManager) output is generated which details Jacobian entries, the nonlinear iteration and the time integration. The advisory messages are given in greater detail the larger the value of :math:\mathrm{itrace}.

**io_manager** : FileObjManager, optional
Manager for I/O in this routine.

**Returns**
**t** : float
On final exit: the value at which the computed solution :math:y is returned (usually at :math:\mathrm{tout}).

**tout** : float
Is unaltered unless :math:\mathrm{itask} = 6 and :math:\mathrm{lderiv}[1] = \mathbf{True} on entry (see also :math:\mathrm{itask} and :math:\mathrm{lderiv}) in which case :math:\mathrm{tout} will be set to the result of taking a small step at the start of the integration.

**imon** : int
On intermediate exit: used to pass information between ivp_stiff_imp_revcom and the :math:\mathrm{monitr} operation (see :ref:Notes <d02nn-py2-py-notes>). With :math:\mathrm{irevcm} = 9, :math:\mathrm{imon} contains a flag indicating under what circumstances the return from ivp_stiff_imp_revcom occurred:

:math:\mathrm{imon} = -2

Exit from ivp_stiff_imp_revcom after :math:\mathrm{ires} = 4 (set in the :math:\mathrm{resid} operation (see :ref:Notes <d02nn-py2-py-notes>) caused an early termination (this facility could be used to locate discontinuities).

:math:\mathrm{imon} = -1

The current step failed repeatedly.

:math:\mathrm{imon} = 0

Exit from ivp_stiff_imp_revcom after a call to the internal nonlinear equation solver.

:math:\mathrm{imon} = 1

The current step was successful.

**inln** : int
On intermediate exit: contains a flag indicating the action to be taken, if any, by the internal nonlinear equation solver.

**ires** : int
On intermediate exit: with :math:\mathrm{irevcm} = 1, :math:2, :math:3, :math:4, :math:5, :math:6, :math:7 or :math:11, :math:\mathrm{ires} specifies the form of the residual to be returned by the :math:\mathrm{resid} operation (see :ref:Notes <d02nn-py2-py-notes>).

If :math:\mathrm{ires} = 1, :math:-r = g\left(t, y\right)-A\left(t, y\right)y^{\prime } must be returned.

If :math:\mathrm{ires} = -1, :math:-\hat{r} = -A\left(t, y\right)y^{\prime } must be returned.

**irevcm** : int
On intermediate exit: indicates what action you must take before re-entering ivp_stiff_imp_revcom. The possible exit values of :math:\mathrm{irevcm} are :math:1, :math:2, :math:3, :math:4, :math:5, :math:6, :math:7, :math:8, :math:9, :math:10 or :math:11 which should be interpreted as follows:

:math:\mathrm{irevcm} = 1, :math:2, :math:3, :math:4, :math:5, :math:6, :math:7 or :math:11

Indicates that a :math:\mathrm{resid} operation (see :ref:Notes <d02nn-py2-py-notes>) is required: you must supply the residual of the system. For each of these values of :math:\mathrm{irevcm}, :math:y_{\textit{i}} is located in :math:\mathrm{y}[\textit{i}-1], for :math:\textit{i} = 1,2,\ldots,\textit{neq}.

For :math:\mathrm{irevcm} = 1, :math:3, :math:6 or :math:11, :math:y_{\textit{i}}^{\prime } is located in :math:\mathrm{ydot}[\textit{i}-1] and :math:r_{\textit{i}} should be stored in :math:\mathrm{comm}\ ['rwork'][50+2\times \textit{neq}+\textit{i}-1], for :math:\textit{i} = 1,2,\ldots,\textit{neq}.

For :math:\mathrm{irevcm} = 2, :math:y_{\textit{i}}^{\prime } is located in :math:\mathrm{comm}\ ['rwork'][50+\textit{neq}+\textit{i}-1] and :math:r_{\textit{i}} should be stored in :math:\mathrm{comm}\ ['rwork'][50+2\times \textit{neq}+\textit{i}-1], for :math:\textit{i} = 1,2,\ldots,\textit{neq}.

For :math:\mathrm{irevcm} = 4 or :math:7, :math:y_{\textit{i}}^{\prime } is located in :math:\mathrm{ydot}[\textit{i}-1] and :math:r_{\textit{i}} should be stored in :math:\mathrm{comm}\ ['rwork'][50+\textit{neq}+\textit{i}-1], for :math:\textit{i} = 1,2,\ldots,\textit{neq}.

For :math:\mathrm{irevcm} = 5, :math:y_{\textit{i}}^{\prime } is located in :math:\mathrm{comm}\ ['rwork'][50+2\times \textit{neq}+\textit{i}-1] and :math:r_{\textit{i}} should be stored in :math:\mathrm{ydot}[\textit{i}-1], for :math:\textit{i} = 1,2,\ldots,\textit{neq}.

:math:\mathrm{irevcm} = 8

Indicates that a :math:\mathrm{jac} operation (see :ref:Notes <d02nn-py2-py-notes>) is required: you must supply the Jacobian matrix.

If full matrix linear algebra is being used, the :math:\left(i, j\right)\ th element of the Jacobian must be stored in :math:\mathrm{wkjac}[\left(j-1\right)\times \textit{neq}+i-1].

If banded matrix linear algebra is being used, the :math:\left(i, j\right)\ th element of the Jacobian must be stored in :math:\mathrm{wkjac}[\left(i-1\right)\times m_B+k-1], where :math:m_B = m_L+m_U+1 and :math:k = \mathrm{min}\left({m_L-i+1}, 0\right)+j; here :math:m_L and :math:m_U are the number of subdiagonals and superdiagonals, respectively, in the band.

If sparse matrix linear algebra is being used, :meth:ivp_stiff_sparjac_enq must be called to determine which column of the Jacobian is required and where it should be stored.

:math:\mathrm{irevcm} = 9

Indicates that a :math:\mathrm{monitr} operation (see :ref:Notes <d02nn-py2-py-notes>) can be performed.

:math:\mathrm{irevcm} = 10

Indicates that the current step was not successful, due to error test failure or convergence test failure. The only information supplied to you on this return is the current value of the variable :math:t, located in :math:\mathrm{comm}\ ['rwork'][18]. No values must be changed before re-entering ivp_stiff_imp_revcom; this facility enables you to determine the number of unsuccessful steps.

On final exit: :math:\mathrm{irevcm} = 0 indicating that the user-specified task has been completed or an error has been encountered (see the descriptions for :math:\mathrm{itask} and :math:\textit{errno}).

.. _d02nn-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:\mathrm{ires} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\frac{{dy}}{{dt}} = 0.0 for all elements.

Check the evaluation of the residual for this value of :math:\mathrm{ires}.

(errno :math:1)
On re-entry, :math:\mathrm{ires} has been set to an illegal value during initialization.

:math:\mathrm{ires} = \langle\mathit{\boldsymbol{value}}\rangle at time :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On re-entry, :math:\mathrm{imon} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:-2\leq \mathrm{imon}\leq 4.

(errno :math:1)
Failure during internal time interpolation. :math:\mathrm{tout} and the current time are too close.

:math:\mathrm{itask} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle and the current time is :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{itask} = 4 or :math:5 and :math:\textit{tcrit} is before the current time in the direction of integration.

:math:\mathrm{itask} = \langle\mathit{\boldsymbol{value}}\rangle, :math:{\textit{tcrit}} = \langle\mathit{\boldsymbol{value}}\rangle and the current time is :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
:math:\mathrm{itask} = 3 and :math:\mathrm{tout} is more than an integration step behind the current time.

:math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle, current time minus step size: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
The initial stepsize, :math:h = \langle\mathit{\boldsymbol{value}}\rangle, is too small.

(errno :math:1)
Weight number :math:i = \langle\mathit{\boldsymbol{value}}\rangle used in the local error test is too small. Check the values of :math:\mathrm{rtol} and :math:\mathrm{atol}.

:math:\mathrm{atol}[i-1] and :math:\mathrm{y}[i-1] may both be zero.

Weight :math:i = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{itask} = 4 or :math:5 and :math:\textit{tcrit} is before :math:\mathrm{tout} in the direction of integration.

:math:\mathrm{itask} = \langle\mathit{\boldsymbol{value}}\rangle, :math:{\textit{tcrit}} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{atol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{atol}\geq 0.0.

(errno :math:1)
On entry, :math:\mathrm{rtol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{rtol}\geq 0.0.

(errno :math:1)
Either the value of :math:\textit{nwkjac} is not the same as the value supplied to the setup function or a communication array has become corrupted.

:math:\textit{nwkjac} = \langle\mathit{\boldsymbol{value}}\rangle, :math:\textit{nwkjac} (setup) :math:{} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
Either the value of :math:\textit{sdysav} is not the same as the value supplied to the setup function or a communication array has become corrupted.

:math:\textit{sdysav} = \langle\mathit{\boldsymbol{value}}\rangle, :math:\textit{sdysav} (setup) :math:{} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, an illegal (negative) minimum stepsize was provided in a prior call to a setup function. :math:{\textit{hmin}} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{tout} is less than :math:\mathrm{t} with respect to the direction of integration given by the sign of :math:\textit{h0} in a prior call to a setup function.

:math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle, :math:\mathrm{t} = \langle\mathit{\boldsymbol{value}}\rangle and :math:{\textit{h0}} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, an illegal (negative) maximum number of steps was provided in a prior call to a setup function. :math:{\textit{maxstp}} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{itol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:1\leq \mathrm{itol}\leq 4.

(errno :math:1)
On entry, :math:\textit{neq} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\textit{ldysav} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\textit{neq}\leq \textit{ldysav}.

(errno :math:1)
On entry, :math:\textit{neq} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\textit{neq}\geq 1.

(errno :math:1)
Either the function was entered on a continuation call without a prior call of this function, or a communication array has become corrupted.

(errno :math:1)
On entry, :math:\mathrm{tout} is too close to :math:\mathrm{t} to start integration.

:math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{t} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{itask} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:1\leq \mathrm{itask}\leq 5.

(errno :math:1)
Either the integrator setup function has not been called prior to the first call of this function, or a communication array has become corrupted.

(errno :math:1)
On entry, an illegal (negative) maximum stepsize was provided in a prior call to a setup function. :math:{\textit{hmax}} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
Either the linear algebra setup function has not been called prior to the first call of this function, or a communication array has become corrupted.

(errno :math:1)
On re-entry, :math:\mathrm{inln} = \langle\mathit{\boldsymbol{value}}\rangle for the case :math:\mathrm{irevcm} = 9 and :math:\mathrm{imon} = 0.

Constraint: :math:\mathrm{inln} = 3.

(errno :math:1)
On entry, :math:\mathrm{irevcm} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:0\leq \mathrm{irevcm}\leq 11.

(errno :math:1)
On re-entry, the solution vector appears to have been overwritten.

Further integration will not be attempted.

(errno :math:2)
At time :math:\langle\mathit{\boldsymbol{value}}\rangle the maximum number of allowed steps on this call was taken before reaching the next output point :math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle.

Maximum number of steps :math:{} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:7)
On re-entry, :math:\mathrm{ires} = 3 which signals that an error condition has occurred in the solution vector, its time derivative or in the value of :math:t. It was not possible to remove this condition.

:math:\mathrm{ires} = \langle\mathit{\boldsymbol{value}}\rangle at :math:t = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:8)
Attempt was made to reduce the step size to a value less than the minimum step size during the calculation of initial values.

Minimum stepsize: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:8)
The user problem has one or more inconsistencies between the :math:\mathrm{ires} = 1 and :math:\mathrm{ires} = -1 parts. Integration will not be attempted.

(errno :math:8)
The residual function returned an error when calculating the initial values of the solution and its time derivative.

(errno :math:8)
Workspace error occurred when trying to form the Jacobian matrix in calculating the initial values of the solution and its time derivative.

(errno :math:9)
A singular Jacobian has been encountered. You should check the problem formulation and Jacobian calculation.

(errno :math:10)
Workspace error occurred when trying to form the Jacobian matrix in calculating the initial values of the solution and its time derivative.

(errno :math:10)
Not enough integer store provided for sparse matrix solver.

Units of store needed: :math:\langle\mathit{\boldsymbol{value}}\rangle. Amount provided: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:10)
Larger integer workspace required.

Provided: :math:\langle\mathit{\boldsymbol{value}}\rangle; required: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:10)
Not enough real store provided for sparse matrix solver.

Units of store needed: :math:\langle\mathit{\boldsymbol{value}}\rangle. Amount provided: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:14)
On entry, too much accuracy requested for precision of the machine at the start of problem. The tolerances should be checked; the requested accuracy should be reduced by a factor of at least :math:\langle\mathit{\boldsymbol{value}}\rangle.

**Warns**
**NagAlgorithmicWarning**
(errno :math:3)
Too much accuracy requested for precision of the machine at time :math:\langle\mathit{\boldsymbol{value}}\rangle.

The tolerances should be checked; the requested accuracy should be reduced by a factor of at least :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:4)
There were repeated error-test failures on an attempted step, before completing the requested task, but the integration was successful as far as :math:\mathrm{t}. The problem may have a singularity, or the local error requirements may be inappropriate.

(errno :math:5)
Nonlinear solver failed to converge using a damped Newton method to solve for initial values.

Damping factor: :math:\langle\mathit{\boldsymbol{value}}\rangle; convergence rate: :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:6)
At time :math:\langle\mathit{\boldsymbol{value}}\rangle, error weight :math:\langle\mathit{\boldsymbol{value}}\rangle became zero. Check the values of :math:\mathrm{atol}, :math:\mathrm{rtol} and :math:\mathrm{itol} supplied.

(errno :math:11)
On re-entry, :math:\mathrm{ires} = 2, which signals that the integration should terminate. :math:\mathrm{ires} = \langle\mathit{\boldsymbol{value}}\rangle at time :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:12)
A return was forced by setting :math:\mathrm{imon} = -2, but the integration was successful as far as :math:\mathrm{t}.

(errno :math:13)
The requested task has been completed, but it is estimated that a small change in :math:\mathrm{rtol} and :math:\mathrm{atol} is unlikely to produce any change in the computed solution. (This ONLY applies when you are NOT operating in one step mode; that is, when :math:\mathrm{itask} \neq 2 or :math:5.)

.. _d02nn-py2-py-notes:

**Notes**
No equivalent traditional C interface for this routine exists in the NAG Library.

ivp_stiff_imp_revcom is a general purpose function for integrating the initial value problem for a stiff system of implicit ordinary differential equations coupled with algebraic equations, written in the form

.. math::
A\left(t, y\right)y^{\prime } = g\left(t, y\right)\text{.}

An outline of a typical calling program is

call the linear algebra setup routine

call the integrator setup routine

set :math:\mathrm{irevcm} = 0

start looping

call ivp_stiff_imp_revcom

if :math:\mathrm{irevcm} = 8 then

supply the Jacobian matrix

else if :math:\mathrm{irevcm} = 9 then

perform monitoring tasks requested by the user

else if :math:\mathrm{irevcm} = 10 then

indicates an unsuccessful step

else if :math:\mathrm{irevcm} > 0 then

evaluate the residual

else

stop looping

post processing; optional linear algebra diagnostic call (sparse case only), optional integrator diagnostic call

There are three major operations that may be required of the calling function on an intermediate return (:math:\mathrm{irevcm}\neq 0) from ivp_stiff_imp_revcom; these are denoted (i), (ii) and (iii).

The following sections describe in greater detail exactly what is required of each of these operations.

(i) **Supply the Jacobian matrix**

You need only provide this facility if the argument :math:{\textit{jceval}} = \texttt{'A'} (or :math:{\textit{jceval}} = \texttt{'F'} if using sparse matrix linear algebra) in a call to the linear algebra setup function (see :math:\textit{jceval} in :meth:ivp_stiff_sparjac_setup).
If the Jacobian matrix is to be evaluated numerically by the integrator, then the remainder of section (i) can be ignored.

We must define the system of nonlinear equations which is solved internally by the integrator.
The time derivative, :math:y^{\prime }, has the form

.. math::
y^{\prime } = \left(y-z\right)/\left(hd\right)\text{,}

where :math:h is the current step size and :math:d is an argument that depends on the integration method in use.
The vector :math:y is the current solution and the vector :math:z depends on information from previous time steps.
This means that :math:\frac{d}{{dy^{\prime }}}\left(\text{ }\right) = \left(hd\right)\frac{d}{{dy}}\left(\text{ }\right).

The system of nonlinear equations that is solved has the form

.. math::
A\left(t, y\right)y^{\prime }-g\left(t, y\right) = 0

but is solved in the form

.. math::
f\left(t, y\right) = 0\text{,}

where :math:f is the function defined by

.. math::
f\left(t, y\right) = \left(hd\right)\left({A\left(t, y\right)\left(y-z\right)/\left(hd\right)-g\left(t, y\right)}\right)\text{.}

It is the Jacobian matrix :math:\frac{{\partial r}}{{\partial y}} that you must supply as follows:

.. math::
\frac{{\partial f_i}}{{\partial y_j}} = a_{{ij}}\left(t, y\right)+hd\frac{\partial }{{\partial y_j}}\left(\sum_{{k = 1}}^{\textit{neq}}a_{{ik}}\left(t, y\right){y^{\prime }}_k-g_i\left(t, y\right)\right)\text{,}

where :math:t, :math:h and :math:d are located in :math:\mathrm{comm}\ ['rwork'][18], :math:\mathrm{comm}\ ['rwork'][15] and :math:\mathrm{comm}\ ['rwork'][19] respectively and the arrays :math:\mathrm{y} and :math:\mathrm{ydot} contain the current solution and time derivatives respectively.
Only the nonzero elements of the Jacobian need be set, since the locations where it is to be stored are preset to zero.

**In this document this operation is referred to as JAC.**

(#) **Perform tasks requested by you**

This operation is essentially a monitoring function and additionally provides the opportunity of changing the current values of :math:\mathrm{y}, :math:\mathrm{ydot}, :math:\mathrm{hnext} (the step size that the integrator proposes to take on the next step), :math:\mathrm{hmin} (the minimum step size to be taken on the next step), and :math:\mathrm{hmax} (the maximum step size to be taken on the next step). The scaled local error at the end of a time step may be obtained by calling :meth:ivp_stiff_errest.

The following gives details of the location within the array :math:\mathrm{comm}\ ['rwork'] of variables that may be of interest to you:

+----------------------+---------------------------------------------------------------+------------------------------------+
|Variable              |Specification                                                  |Location                            |
+======================+===============================================================+====================================+
|:math:\mathrm{tcurr}|the current value of the independent variable                  |:math:\mathrm{comm}\ ['rwork'][18]|
+----------------------+---------------------------------------------------------------+------------------------------------+
|:math:\mathrm{hlast}|last step size successfully used by the integrator             |:math:\mathrm{comm}\ ['rwork'][14]|
+----------------------+---------------------------------------------------------------+------------------------------------+
|:math:\mathrm{hnext}|step size that the integrator proposes to take on the next step|:math:\mathrm{comm}\ ['rwork'][15]|
+----------------------+---------------------------------------------------------------+------------------------------------+
|:math:\mathrm{hmin} |minimum step size to be taken on the next step                 |:math:\mathrm{comm}\ ['rwork'][16]|
+----------------------+---------------------------------------------------------------+------------------------------------+
|:math:\mathrm{hmax} |maximum step size to be taken on the next step                 |:math:\mathrm{comm}\ ['rwork'][17]|
+----------------------+---------------------------------------------------------------+------------------------------------+
|:math:\mathrm{nqu}  |the order of the integrator used on the last step              |:math:\mathrm{comm}\ ['rwork'][9] |
+----------------------+---------------------------------------------------------------+------------------------------------+

You are advised to consult the description of :math:\textit{monitr} in :meth:ivp_stiff_imp_fulljac for details on what optional input can be made.

If either :math:\mathrm{y} or :math:\mathrm{ydot} are changed, then :math:\mathrm{imon} must be set to :math:2 before return to ivp_stiff_imp_revcom.
If either of the values :math:\mathrm{hmin} or :math:\mathrm{hmax} are changed, then :math:\mathrm{imon} must be set :math:\text{}\geq 3 before return to ivp_stiff_imp_revcom.
If :math:\mathrm{hnext} is changed, then :math:\mathrm{imon} must be set to :math:4 before return to ivp_stiff_imp_revcom.

In addition you can force ivp_stiff_imp_revcom to evaluate the residual vector

.. math::
A\left(t, y\right)y^{\prime }-g\left(t, y\right)

by setting :math:\mathrm{imon} = 0 and :math:\mathrm{inln} = 3 and then returning to ivp_stiff_imp_revcom; on return to this monitoring operation the residual vector will be stored in :math:\mathrm{comm}\ ['rwork'][50+2\times \textit{neq}+\textit{i}-1], for :math:\textit{i} = 1,2,\ldots,\textit{neq}.

**In this document this operation is referred to as MONITR.**

(#) **Evaluate the residual**

This operation must evaluate the residual

.. math::
-r = g\left(t, y\right)-A\left(t, y\right)y^{\prime }

in one case and the reduced residual

.. math::
-\hat{r} = -A\left(t, y\right)y^{\prime }

in another, where :math:t is located in :math:\mathrm{comm}\ ['rwork'][18].
The form of the residual that is returned is determined by the value of :math:\mathrm{ires} returned by ivp_stiff_imp_revcom.
If :math:\mathrm{ires} = -1, then the residual defined by equation (2) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02nnf.html#eqn2>__ above must be returned; if :math:\mathrm{ires} = 1, then the residual returned by equation (1) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02nnf.html#eqn1>__ above must be returned.

**In this document this operation is referred to as RESID.**
"""
raise NotImplementedError

[docs]def dae_dassl_linalg(neq, ml, mu, comm):
r"""
dae_dassl_linalg is a setup function which you must call prior to :meth:dae_dassl_gen and after a call to :meth:dae_dassl_setup, if the Jacobian is to be considered as having a banded structure.

.. _d02np-py2-py-doc:

For full information please refer to the NAG Library document for d02np

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02npf.html

.. _d02np-py2-py-parameters:

**Parameters**
**neq** : int
The number of differential-algebraic equations to be solved.

**ml** : int
:math:m_L, the number of subdiagonals in the band.

**mu** : int
:math:m_U, the number of superdiagonals in the band.

**comm** : dict, communication object, modified in place
Communication structure.

This argument must have been initialized by a prior call to :meth:dae_dassl_setup.

.. _d02np-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:\mathrm{neq} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{neq}\geq 1.

(errno :math:2)
On entry, :math:\mathrm{ml} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{ml}\geq 0.

(errno :math:2)
On entry, :math:\mathrm{ml} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{neq} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{ml}\leq \mathrm{neq}-1.

(errno :math:3)
On entry, :math:\mathrm{mu} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{mu}\geq 0.

(errno :math:3)
On entry, :math:\mathrm{mu} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{neq} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{mu}\leq \mathrm{neq}-1.

(errno :math:4)
Either the initialization function has not been called prior to the first call of this function or the communication array has become corrupted.

(errno :math:5)
On entry, :math:\textit{licom} is too small: :math:\textit{licom} = \langle\mathit{\boldsymbol{value}}\rangle.

.. _d02np-py2-py-notes:

**Notes**
A call to dae_dassl_linalg specifies that the Jacobian to be used is banded in structure.
If dae_dassl_linalg is not called before a call to :meth:dae_dassl_gen then the Jacobian is assumed to be full.
"""
raise NotImplementedError

[docs]def ivp_stiff_sparjac_enq(comm):
r"""
ivp_stiff_sparjac_enq is an enquiry function for communicating with :meth:ivp_stiff_exp_revcom or :meth:ivp_stiff_imp_revcom when supplying columns of a sparse Jacobian matrix.

.. _d02nr-py2-py-doc:

For full information please refer to the NAG Library document for d02nr

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02nrf.html

.. _d02nr-py2-py-parameters:

**Parameters**
**comm** : dict, communication object
Communication structure.

This argument must have been initialized by a prior call to :meth:ivp_stiff_exp_revcom or :meth:ivp_stiff_imp_revcom.

**Returns**
**j** : int
The index :math:j of the column of the Jacobian which is required.

**iplace** : int
Indicates which locations in the array :math:\textit{rwork} to fill with the :math:j\ th column.

If :math:\mathrm{iplace} = 1, the :math:\left(i, j\right)\ th element of the Jacobian must be placed in :math:{\textit{rwork}}[50+2\times {\textit{ldysav}}+i-1], otherwise the :math:\left(i, j\right)\ th element must be placed in :math:{\textit{rwork}}[50+{\textit{ldysav}}+i-1].

If :math:{\textit{jceval}} = \texttt{'F'}, in the previous call to :meth:ivp_stiff_sparjac_setup, :math:\mathrm{iplace} = 2 always, hence the :math:j\ th column of the Jacobian must be placed in :math:{\textit{rwork}}[50+{\textit{ldysav}}+\textit{i}-1], for :math:\textit{i} = 1,2,\ldots,{\textit{neq}}.

:math:\textit{rwork}, :math:\textit{neq} and :math:\textit{ldysav} are arguments of :meth:ivp_stiff_exp_revcom and :meth:ivp_stiff_imp_revcom.

.. _d02nr-py2-py-notes:

**Notes**
No equivalent traditional C interface for this routine exists in the NAG Library.

ivp_stiff_sparjac_enq is required when :meth:ivp_stiff_exp_revcom or :meth:ivp_stiff_imp_revcom is being used with sparse matrix linear algebra.
After an exit from :meth:ivp_stiff_exp_revcom or :meth:ivp_stiff_imp_revcom with :math:{\textit{irevcm}} = 8, ivp_stiff_sparjac_enq must be called to determine which column of the Jacobian is required and where it is to be placed in the array :math:\textit{rwork} (an argument of :meth:ivp_stiff_exp_revcom or :meth:ivp_stiff_imp_revcom).
"""
raise NotImplementedError

[docs]def ivp_stiff_fulljac_setup(neq, neqmax, jceval, nwkjac, comm):
r"""
ivp_stiff_fulljac_setup is a setup function which must be called prior to an integrator in submodule ode, if full matrix linear algebra is required.

.. _d02ns-py2-py-doc:

For full information please refer to the NAG Library document for d02ns

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02nsf.html

.. _d02ns-py2-py-parameters:

**Parameters**
**neq** : int
The number of differential equations.

**neqmax** : int
A bound on the maximum number of differential equations to be solved during the integration.

**jceval** : str, length 1
Specifies the technique to be used to compute the Jacobian.

:math:\mathrm{jceval} = \texttt{'N'}

The Jacobian is to be evaluated numerically by the integrator. If this option is used, the actual argument corresponding to :math:\textit{jac} in the call to :meth:ivp_stiff_exp_fulljac or :meth:ivp_stiff_imp_fulljac must be specified as **None**.

:math:\mathrm{jceval} = \texttt{'A'}

You must supply a (sub)program to evaluate the Jacobian on a call to the integrator.

:math:\mathrm{jceval} = \texttt{'D'}

The default choice is to be made. In this case 'D' is interpreted as 'N'.

Only the first character of the actual argument :math:\mathrm{jceval} is passed to ivp_stiff_fulljac_setup; hence it is permissible for the actual argument to be more descriptive 'Numerical', 'Analytical' or 'Default' on a call to ivp_stiff_fulljac_setup.

**nwkjac** : int
The size of the workspace array :math:\textit{wkjac}, which you are supplying to the integrator, as declared in the (sub)program from which ivp_stiff_fulljac_setup is called.

**comm** : dict, communication object, modified in place
Communication structure.

This argument must have been initialized by a prior call to :meth:ivp_stiff_bdf or :meth:ivp_stiff_blend.

.. _d02ns-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:\mathrm{jceval} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{jceval} = \texttt{'A'}, :math:\texttt{'N'} or :math:\texttt{'D'}.

(errno :math:1)
On entry, :math:\mathrm{nwkjac} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{neqmax} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{nwkjac}\geq \left(\mathrm{neqmax}+1\right)\times \mathrm{neqmax}.

(errno :math:1)
On entry, :math:\mathrm{neq} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{neqmax} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{neq}\leq \mathrm{neqmax}.

(errno :math:1)
On entry, :math:\mathrm{neqmax} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{neqmax}\geq 1.

(errno :math:1)
On entry, :math:\mathrm{neq} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{neq}\geq 1.

.. _d02ns-py2-py-notes:

**Notes**
No equivalent traditional C interface for this routine exists in the NAG Library.

ivp_stiff_fulljac_setup defines the linear algebra to be used as full matrix linear algebra, permits you to specify the method for calculating the Jacobian and checks the validity of certain input values.

--------
:meth:naginterfaces.library.examples.ode.ivp_stiff_exp_fulljac_ex.main
"""
raise NotImplementedError

[docs]def ivp_stiff_bandjac_setup(neq, neqmax, jceval, ml, mu, nwkjac, njcpvt, comm):
r"""
ivp_stiff_bandjac_setup is a setup function which you must call prior to an integrator in submodule ode, if banded matrix linear algebra is required.

.. _d02nt-py2-py-doc:

For full information please refer to the NAG Library document for d02nt

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02ntf.html

.. _d02nt-py2-py-parameters:

**Parameters**
**neq** : int
The number of differential equations.

**neqmax** : int
A bound on the maximum number of differential equations to be solved during the integration.

**jceval** : str, length 1
Specifies the technique to be used to compute the Jacobian as follows:

:math:\mathrm{jceval} = \texttt{'N'}

The Jacobian is to be evaluated numerically by the integrator. If this option is used, the actual argument corresponding to :math:\textit{jac} in the call to :meth:ivp_stiff_exp_bandjac or :meth:ivp_stiff_imp_bandjac must be specified as **None**.

:math:\mathrm{jceval} = \texttt{'A'}

You must supply a (sub)program to evaluate the Jacobian on a call to the integrator.

:math:\mathrm{jceval} = \texttt{'D'}

The default choice is to be made. In this case 'D' is interpreted as 'N'.

Only the first character of the actual argument :math:\mathrm{jceval} is passed to ivp_stiff_bandjac_setup; hence it is permissible for the actual argument to be more descriptive, e.g., 'Numerical', 'Analytical' or 'Default', on a call to ivp_stiff_bandjac_setup.

**ml** : int
:math:m_L, the number of subdiagonals in the band.

**mu** : int
:math:m_U, the number of superdiagonals in the band.

**nwkjac** : int
The size of the workspace array :math:\textit{wkjac}, which you are supplying to the integrator, as declared in the (sub)program from which ivp_stiff_bandjac_setup is called.

**njcpvt** : int
The size of the workspace array :math:\textit{jacpvt}, which you are supplying to the integrator, as declared in the (sub)program from which ivp_stiff_bandjac_setup is called.

**comm** : dict, communication object, modified in place
Communication structure.

This argument must have been initialized by a prior call to :meth:ivp_stiff_bdf or :meth:ivp_stiff_blend.

.. _d02nt-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:\mathrm{jceval} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{jceval} = \texttt{'A'}, :math:\texttt{'N'} or :math:\texttt{'D'}.

(errno :math:1)
On entry, :math:\mathrm{mu} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{neq} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{mu}\leq \mathrm{neq}-1.

(errno :math:1)
On entry, :math:\mathrm{mu} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{mu}\geq 0.

(errno :math:1)
On entry, :math:\mathrm{ml} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{neq} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{ml}\leq \mathrm{neq}-1.

(errno :math:1)
On entry, :math:\mathrm{ml} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{ml}\geq 0.

(errno :math:1)
On entry, :math:\mathrm{nwkjac} = \langle\mathit{\boldsymbol{value}}\rangle, :math:\mathrm{ml} = \langle\mathit{\boldsymbol{value}}\rangle, :math:\mathrm{mu} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{neqmax} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{nwkjac}\geq \left(2\times \mathrm{ml}+\mathrm{mu}+1\right)\times \mathrm{neqmax}.

(errno :math:1)
On entry, :math:\mathrm{njcpvt} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{neqmax} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{njcpvt}\geq \mathrm{neqmax}.

(errno :math:1)
On entry, :math:\mathrm{neq} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{neqmax} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{neq}\leq \mathrm{neqmax}.

(errno :math:1)
On entry, :math:\mathrm{neqmax} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{neqmax}\geq 1.

(errno :math:1)
On entry, :math:\mathrm{neq} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{neq}\geq 1.

.. _d02nt-py2-py-notes:

**Notes**
No equivalent traditional C interface for this routine exists in the NAG Library.

ivp_stiff_bandjac_setup defines the linear algebra to be used as banded matrix linear algebra, permits you to specify the method for calculating the Jacobian and checks the validity of certain input values.
"""
raise NotImplementedError

[docs]def ivp_stiff_sparjac_setup(neq, neqmax, jceval, nwkjac, ia, ja, comm, njcpvt, sens, u, eta, lblock, isplit=73):
r"""
ivp_stiff_sparjac_setup is a setup function which must be called prior to an integrator in submodule ode, if sparse matrix linear algebra is required.

.. _d02nu-py2-py-doc:

For full information please refer to the NAG Library document for d02nu

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02nuf.html

.. _d02nu-py2-py-parameters:

**Parameters**
**neq** : int
The number of differential equations.

**neqmax** : int
A bound on the maximum number of differential equations to be solved during the integration.

**jceval** : str, length 1
Specifies the technique to be used to compute the Jacobian.

:math:\mathrm{jceval} = \texttt{'N'}

The sparsity structure and the value of the Jacobian are to be determined numerically by the integrator.

:math:\mathrm{jceval} = \texttt{'S'}

The sparsity structure of the Jacobian is supplied in the arrays :math:\mathrm{ia} and :math:\mathrm{ja} but its value is to be determined numerically. This is the recommended mode of operation unless it is a simple matter to supply the Jacobian.

:math:\mathrm{jceval} = \texttt{'A'}

The Jacobian will be evaluated by calls to :math:\textit{jac}. The sparsity structure will be estimated by calls to :math:\textit{jac}; that is, no explicit sparsity structure need be supplied in the arrays :math:\mathrm{ia} and :math:\mathrm{ja}.

:math:\mathrm{jceval} = \texttt{'F'}

The sparsity structure of the Jacobian is supplied in :math:\mathrm{ia} and :math:\mathrm{ja}, and its value will be determined by calls to :math:\textit{jac}. This is the recommended mode of operation if the :math:\textit{jac} is simple to form.

:math:\mathrm{jceval} = \texttt{'D'}

The default choice is to be made. In this case 'D' is interpreted as 'S'.

If the sparsity structure is supplied in arrays :math:\mathrm{ia} and :math:\mathrm{ja}, any evidence from the numerical or analytical formation of the Jacobian that this structure is not correct, is ignored.

Only the first character of the actual argument :math:\mathrm{jceval} is passed to ivp_stiff_sparjac_setup; hence it is permissible for the actual argument to be more descriptive, e.g., 'Numerical', 'Structural', 'Analytical', 'Full information' or 'Default' in a call to ivp_stiff_sparjac_setup.

If the option :math:\mathrm{jceval} = \texttt{'N'}, :math:\texttt{'S'} or :math:\texttt{'D'} is used then the actual argument corresponding to :math:\textit{jac} in the call to :meth:ivp_stiff_exp_sparjac or :meth:ivp_stiff_imp_sparjac must be specified as **None**.

If integration is to be performed by reverse communication (:meth:ivp_stiff_exp_revcom or :meth:ivp_stiff_imp_revcom) then :math:\mathrm{jceval} should be set to either 'N' or 'A'.

In this case :math:\mathrm{ia} and :math:\mathrm{ja} are not used and their lengths may be set to :math:1.

**nwkjac** : int
The size of the array :math:\textit{wkjac}, which you are supplying to the integrator, as declared in the (sub)program from which ivp_stiff_sparjac_setup is called.

Suggested value: :math:\mathrm{nwkjac} = 4\times \mathrm{neqmax} if :math:\mathrm{jceval} = \texttt{'N'} or :math:\texttt{'A'}. If :math:\mathrm{nwkjac} is less than this estimate, a message is printed on the file object associated with the advisory I/O unit (see :class:~naginterfaces.base.utils.FileObjManager), and execution continues.

**ia** : int, array-like, shape :math:\left(\textit{nia}\right)
If :math:\mathrm{jceval} = \texttt{'S'}, :math:\texttt{'F'} or :math:\texttt{'D'}, :math:\mathrm{ia} must contain details of the sparsity pattern to be used for the Jacobian. See :math:\mathrm{ja}.

:math:\mathrm{ia} is not used if :math:\mathrm{jceval} = \texttt{'N'} or :math:\texttt{'A'}.

**ja** : int, array-like, shape :math:\left(\textit{nja}\right)
If :math:\mathrm{jceval} = \texttt{'S'}, :math:\texttt{'F'} or :math:\texttt{'D'}, :math:\mathrm{ja} must contain details of the sparsity pattern to be used for the Jacobian. :math:\mathrm{ja} contains the row indices where nonzero elements occur, reading in column-wise order, and :math:\mathrm{ia} contains the starting locations in :math:\mathrm{ja} of the descriptions of columns :math:1,2,\ldots,\mathrm{neq} in that order, with :math:\mathrm{ia}[0] = 1. Thus for each column index :math:j = 1,2,\ldots,\mathrm{neq}, the values of the row index :math:i in column :math:j where a nonzero element may occur are given by

.. math::
i = \mathrm{ja}[k]

where :math:\mathrm{ia}[j-1]\leq k < \mathrm{ia}[j].

Thus the total number of nonzeros, :math:\textit{nelement}, must be :math:\mathrm{ia}[\mathrm{neq}]-1.

For example, for the following matrix

.. math::
\begin{pmatrix}x&0&x&0&0\\0&x&x&x&0\\x&x&x&0&0\\x&0&0&x&x\\0&0&0&x&x\end{pmatrix}

where :math:x represents nonzero elements (13 in all) the arrays :math:\mathrm{ia} and :math:\mathrm{ja} should be

.. math::
\begin{array}{cccccccccccccc}\mathrm{ia}[k-1]&1&4&6&9&12&14&&&&&&&\\\mathrm{ja}[k-1]&1&3&4&2& 3& 1&2&3&2&4&5&4&5\end{array}

:math:\mathrm{ja} is not used if :math:\mathrm{jceval} = \texttt{'N'} or :math:\texttt{'A'}.

**comm** : dict, communication object, modified in place
Communication structure.

This argument must have been initialized by a prior call to :meth:ivp_stiff_bdf or :meth:ivp_stiff_blend.

**njcpvt** : int
The length of the array :math:\mathrm{comm}\ ['jacpvt'], which you are supplying to the integrator, as dimensioned in the sub(program) from which ivp_stiff_sparjac_setup is called.

Suggested value: :math:\mathrm{njcpvt} = 20\times \mathrm{neqmax} if :math:\mathrm{jceval} = \texttt{'N'} or :math:\texttt{'A'}. If :math:\mathrm{njcpvt} is less than this estimate, a message is printed on the file object associated with the advisory I/O unit (see :class:~naginterfaces.base.utils.FileObjManager), and execution continues.

**sens** : float
A threshold argument used to determine whether or not a matrix element is zero; when :math:\mathrm{sens} is set to :math:0.0 on entry, the function will use :math:\mathrm{sens} = 100.0\times \text{machine precision}. Otherwise the absolute value of :math:\mathrm{sens} is used.

**u** : float
Should have a value between :math:0.0 and :math:0.9999. Otherwise a default value of :math:0.1 is used. When the sparsity pattern has been evaluated, the first Jacobian computed is decomposed with :math:\mathrm{u} governing the choice of pivots; subsequent Jacobian decompositions use the same pattern of decomposition until the sparsity pattern is re-evaluated. When searching a row for a pivot, any element is excluded from the search which is less than :math:\mathrm{u} times the largest of those elements in the row available as pivots. Thus decreasing :math:\mathrm{u} biases the algorithm towards maintaining sparsity at the expense of numerical stability.

**eta** : float
A relative pivot threshold, below which on subsequent decompositions (as described under :math:\mathrm{u}), an internal error is provoked.

:math:\mathrm{eta} > 1.0

No check on pivot size is made.

:math:\mathrm{eta}\leq 0.0

The default value :math:\mathrm{eta} = 1.0e-4 is used.

**lblock** : bool
Indicates if preordering is used before decomposition.

If :math:\mathrm{lblock} = \mathbf{True}, on entry, the Jacobian matrix is preordered to block lower triangular form before a decomposition is performed (this is the recommended mode).

If you know the structure of the Jacobian to be irreducible, that is not permutable to block lower triangular form, you should set :math:\mathrm{lblock} = \mathbf{False}.

For example, a Jacobian arising from using the method of lines for parabolic partial differential equations would normally be irreducible. (See the specification of :meth:ivp_stiff_sparjac_diag for optional output concerning :math:\mathrm{lblock}.)

**isplit** : int, optional
This argument is used for splitting the integer workspace :math:\mathrm{comm}\ ['jacpvt'] to effect an efficient decomposition. It must satisfy :math:1\leq \mathrm{isplit}\leq 99. If :math:\mathrm{isplit} lies outside this range on entry, a default value of :math:73 is used. An appropriate value for :math:\mathrm{isplit} for subsequent runs on similar problems is available via the optional output :meth:ivp_stiff_sparjac_diag.

.. _d02nu-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:\mathrm{nwkjac} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{ia}[\mathrm{neq}]-1+2\times \mathrm{neq} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{nwkjac}\geq \mathrm{ia}[\mathrm{neq}]-1+2\times \mathrm{neq}.

(errno :math:1)
On entry, :math:\mathrm{ja} defines duplicate elements in row :math:\langle\mathit{\boldsymbol{value}}\rangle and column :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:i = \langle\mathit{\boldsymbol{value}}\rangle, :math:\mathrm{ja}[i] = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{neq} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:1\leq \mathrm{ja}[i]\leq \mathrm{neq} for all :math:i.

(errno :math:1)
On entry, :math:i = \langle\mathit{\boldsymbol{value}}\rangle, :math:\mathrm{ia}[i] = \langle\mathit{\boldsymbol{value}}\rangle, :math:i-1 = \langle\mathit{\boldsymbol{value}}\rangle, :math:\mathrm{ia}[i-1] = \langle\mathit{\boldsymbol{value}}\rangle, :math:\mathrm{neq} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{ia}[\langle\mathit{\boldsymbol{value}}\rangle]-\mathrm{ia}[\langle\mathit{\boldsymbol{value}}\rangle]\leq \mathrm{neq}.

(errno :math:1)
On entry, :math:\mathrm{ia}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{ia}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{ia}[\langle\mathit{\boldsymbol{value}}\rangle]\geq \mathrm{ia}[\langle\mathit{\boldsymbol{value}}\rangle].

(errno :math:1)
On entry, :math:\mathrm{ia}[0] = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{ia}[0] = 1.

(errno :math:1)
On entry, :math:\mathrm{njcpvt} = \langle\mathit{\boldsymbol{value}}\rangle and :math:3\times \left(\mathrm{ia}[\mathrm{neq}]-1\right)+14\times \mathrm{neq}+1 = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{njcpvt}\geq 3\times \left(\mathrm{ia}[\mathrm{neq}]-1\right)+14\times \mathrm{neq}+1.

(errno :math:1)
On entry, :math:\textit{nja} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{ia}[\mathrm{neq}]-1 = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\textit{nja}\geq \mathrm{ia}[\mathrm{neq}]-1.

(errno :math:1)
On entry, :math:\mathrm{ia}[\mathrm{neq}]-1 = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{neq} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{ia}[\mathrm{neq}]-1\geq \mathrm{neq}.

(errno :math:1)
On entry, :math:\textit{nia} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{neq}+1 = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\textit{nia}\geq \mathrm{neq}+1.

(errno :math:1)
On entry, :math:\mathrm{jceval} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{jceval} = \texttt{'A'}, :math:\texttt{'N'}, :math:\texttt{'S'}, :math:\texttt{'F'} or :math:\texttt{'D'}.

(errno :math:1)
On entry, :math:\mathrm{neq} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{neqmax} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{neq}\leq \mathrm{neqmax}.

(errno :math:1)
On entry, :math:\mathrm{neqmax} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{neqmax}\geq 1.

(errno :math:1)
On entry, :math:\mathrm{neq} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{neq}\geq 1.

.. _d02nu-py2-py-notes:

**Notes**
No equivalent traditional C interface for this routine exists in the NAG Library.

ivp_stiff_sparjac_setup defines the linear algebra to be used as sparse matrix linear algebra, permits you to specify the method for calculating the Jacobian and its structure, and checks the validity of certain input values.
"""
raise NotImplementedError

[docs]def ivp_stiff_bdf(neqmax, sdysav, maxord, method, petzld, con, tcrit, hmin, hmax, h0, maxstp, mxhnil, norm):
r"""
ivp_stiff_bdf is a setup function which must be called prior to linear algebra setup functions and integrators from the SPRINT suite of functions, if Backward Differentiation Formulae (BDF) are to be used.

.. _d02nv-py2-py-doc:

For full information please refer to the NAG Library document for d02nv

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02nvf.html

.. _d02nv-py2-py-parameters:

**Parameters**
**neqmax** : int
A bound on the maximum number of differential equations to be solved.

**sdysav** : int
The second dimension of the array :math:\textit{ysav} that will be supplied to the integrator, as declared in the (sub)program from which the integrator is called.

**maxord** : int
The maximum order to be used for the BDF method.

**method** : str, length 1
Specifies the method to be used to solve the system of nonlinear equations arising on each step of the BDF code.

:math:\mathrm{method} = \texttt{'N'}

A modified Newton iteration is used.

:math:\mathrm{method} = \texttt{'F'}

Functional iteration is used.

:math:\mathrm{method} = \texttt{'D'}

A modified Newton iteration is used.

**Note:** a linear algebra setup function must be called even when using functional iteration, since if difficulty is encountered a switch is made to a modified Newton method.

Only the first character of the actual argument :math:\mathrm{method} is passed to ivp_stiff_bdf; hence it is permissible for the actual argument to be more descriptive e.g., 'Newton', 'Functional iteration' or 'Default' in a call to ivp_stiff_bdf.

**petzld** : bool
Specifies whether the Petzold local error test is to be used. If :math:\mathrm{petzld} is set to :math:\mathbf{True} on entry, the Petzold local error test is used, otherwise a conventional test is used. The Petzold test results in extra overhead cost but is more stable and reliable for differential/algebraic equations.

**con** : float, array-like, shape :math:\left(6\right)
Values to be used to control step size choice during integration. If any :math:\mathrm{con}[i-1] = 0.0 on entry, it is replaced by its default value described below. In most cases this is the recommended setting.

:math:\mathrm{con}[0], :math:\mathrm{con}[1], and :math:\mathrm{con}[2] are factors used to bound step size changes.

If the current step size :math:h fails, the modulus of the next step size is bounded by :math:\mathrm{con}[0]\times \left\lvert h\right\rvert.

The default value of :math:\mathrm{con}[0] is :math:2.0.

Note that the new step size may be used with a method of different order to the failed step.

If the initial step size is :math:h, the modulus of the step size on the second step is bounded by :math:\mathrm{con}[2]\times \left\lvert h\right\rvert.

At any other stage in the integration, if the current step size is :math:h, the modulus of the next step size is bounded by :math:\mathrm{con}[1]\times \left\lvert h\right\rvert.

The default values are :math:10.0 for :math:\mathrm{con}[1] and :math:1000.0 for :math:\mathrm{con}[2].

:math:\mathrm{con}[3], :math:\mathrm{con}[4] and :math:\mathrm{con}[5] are 'tuning' constants used in determining the next order and step size.

They are used to scale the error estimates used in determining whether to keep the same order of the BDF method, decrease the order or increase the order respectively.

The larger the value of :math:\mathrm{con}[\textit{i}-1], for :math:\textit{i} = 4,5,\ldots,6, the less likely the choice of the corresponding order.

The default values are: :math:\mathrm{con}[3] = 1.2, :math:\mathrm{con}[4] = 1.3, :math:\mathrm{con}[5] = 1.4.

**tcrit** : float
A point beyond which integration must not be attempted. The use of :math:\mathrm{tcrit} is described under the argument :math:\textit{itask} in the specification for the integrator (e.g., see :meth:ivp_stiff_exp_fulljac). A value, :math:0.0 say, must be specified even if :math:\textit{itask} subsequently specifies that :math:\mathrm{tcrit} will not be used.

**hmin** : float
The minimum absolute step size to be allowed. Set :math:\mathrm{hmin} = 0.0 if this option is not required.

**hmax** : float
The maximum absolute step size to be allowed. Set :math:\mathrm{hmax} = 0.0 if this option is not required.

**h0** : float
The step size to be attempted on the first step. Set :math:\mathrm{h0} = 0.0 if the initial step size is calculated internally.

**maxstp** : int
The maximum number of steps to be attempted during one call to the integrator after which it will return with :math:\mathrm{errno} = 2. Set :math:\mathrm{maxstp} = 0 if no limit is to be imposed.

**mxhnil** : int
The maximum number of warnings printed (if :math:{\textit{itrace}}\geq 0) per problem when :math:t+h = t on a step (:math:h = {} current step size). If :math:\mathrm{mxhnil}\leq 0, a default value of :math:10 is assumed.

**norm** : str, length 1
Indicates the type of norm to be used.

:math:\mathrm{norm} = \texttt{'M'}

Maximum norm.

:math:\mathrm{norm} = \texttt{'A'}

Averaged L2 norm.

:math:\mathrm{norm} = \texttt{'D'}

Is the same as :math:\mathrm{norm} = \texttt{'A'}.

If :math:\textit{vnorm} denotes the norm of the vector :math:v of length :math:n, for the averaged L2 norm

.. math::
\textit{vnorm} = \sqrt{\frac{1}{n}\sum_{{i = 1}}^n\left(v_i/w_i\right)^2}\text{,}

while for the maximum norm

.. math::
\textit{vnorm} = \mathrm{max}_i\left\lvert v_i/w_i\right\rvert \text{.}

If you wish to weight the maximum norm or the L2 norm, :math:\textit{rtol} and :math:\textit{atol} should be scaled appropriately on input to the integrator (see under :math:\textit{itol} in the specification of the integrator for the formulation of the weight vector :math:w_i from :math:\textit{rtol} and :math:\textit{atol}, e.g., see :meth:ivp_stiff_exp_fulljac).

Only the first character to the actual argument :math:\mathrm{norm} is passed to ivp_stiff_bdf; hence it is permissible for the actual argument to be more descriptive e.g., 'Maximum', 'Average L2' or 'Default' in a call to ivp_stiff_bdf.

**Returns**
**con** : float, ndarray, shape :math:\left(6\right)
The values actually used by ivp_stiff_bdf.

**comm** : dict, communication object
Communication structure.

.. _d02nv-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:\mathrm{con}[1] = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{con}[2] = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{con}[1]\leq \mathrm{con}[2].

(errno :math:1)
On entry, :math:\mathrm{con}[0] = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{con}[1] = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{con}[0]\leq \mathrm{con}[1].

(errno :math:1)
On entry, :math:\mathrm{con}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle was less than :math:1.0.

(errno :math:1)
On entry, :math:\mathrm{con}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle was less than :math:0.0.

(errno :math:1)
On entry, :math:\mathrm{method} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{maxord} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{maxord}\leq \langle\mathit{\boldsymbol{value}}\rangle, the maximum allowed order for the method define by :math:\mathrm{method}.

(errno :math:1)
On entry, :math:\mathrm{maxord} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{maxord}\geq 1.

(errno :math:1)
On entry, :math:\mathrm{sdysav} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{maxord} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{sdysav} > \mathrm{maxord}.

(errno :math:1)
On entry, :math:\mathrm{norm} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{norm} = \texttt{'M'}, :math:\texttt{'A'} or :math:\texttt{'D'}.

(errno :math:1)
On entry, :math:\mathrm{neqmax} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{neqmax}\geq 1.

(errno :math:1)
On entry, :math:\mathrm{method} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{method} = \texttt{'N'}, :math:\texttt{'F'} or :math:\texttt{'D'}.

.. _d02nv-py2-py-notes:

**Notes**
No equivalent traditional C interface for this routine exists in the NAG Library.

An integrator setup function must be called before the call to any linear algebra setup function or integrator from the SPRINT suite of functions in this sub-module.
This setup function, ivp_stiff_bdf, makes the choice of the BDF integrator and permits you to define options appropriate to this choice.
Alternative choices of integrator from this suite are the BLEND method and the DASSL implementation of the BDF method which can be chosen by initial calls to :meth:ivp_stiff_blend or :meth:ivp_stiff_dassl respectively.

--------
:meth:naginterfaces.library.examples.ode.ivp_stiff_exp_fulljac_ex.main
"""
raise NotImplementedError

[docs]def ivp_stiff_blend(neqmax, sdysav, maxord, con, tcrit, hmin, hmax, h0, maxstp, mxhnil, norm):
r"""
ivp_stiff_blend is a setup function which must be called prior to linear algebra setup functions and integrators from the SPRINT suite of functions, if the BLEND formulae are to be used.

.. _d02nw-py2-py-doc:

For full information please refer to the NAG Library document for d02nw

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02nwf.html

.. _d02nw-py2-py-parameters:

**Parameters**
**neqmax** : int
A bound on the maximum number of differential equations to be solved.

**sdysav** : int
The second dimension of the array :math:\textit{ysav} that will be supplied to the integrator, as declared in the (sub)program from which the integrator is called (e.g., see :meth:ivp_stiff_exp_fulljac).

**maxord** : int
The maximum order to be used for the BLEND method.

**con** : float, array-like, shape :math:\left(6\right)
Values to be used to control step size choice during integration. If any :math:\mathrm{con}[i-1] = 0.0 on entry, it is replaced by its default value described below. In most cases this is the recommended setting.

:math:\mathrm{con}[0], :math:\mathrm{con}[1], and :math:\mathrm{con}[2] are factors used to bound step size changes.

If the current step size :math:h fails, the modulus of the next step size is bounded by :math:\mathrm{con}[0]\times \left\lvert h\right\rvert.

The default value of :math:\mathrm{con}[0] is :math:2.0.

Note that the new step size may be used with a method of different order to the failed step.

If the initial step size is :math:h, the modulus of the step size on the second step is bounded by :math:\mathrm{con}[2]\times \left\lvert h\right\rvert.

At any other stage in the integration, if the current step size is :math:h, the modulus of the next step size is bounded by :math:\mathrm{con}[1]\times \left\lvert h\right\rvert.

The default values are :math:10.0 for :math:\mathrm{con}[1] and :math:1000.0 for :math:\mathrm{con}[2].

:math:\mathrm{con}[3], :math:\mathrm{con}[4] and :math:\mathrm{con}[5] are 'tuning' constants used in determining the next order and step size.

They are used to scale the error estimates used in determining whether to keep the same order of the BLEND method, decrease the order or increase the order respectively.

The larger the value of :math:\mathrm{con}[\textit{i}-1], for :math:\textit{i} = 4,5,\ldots,6, the less likely the choice of the corresponding order.

The default values are: :math:\mathrm{con}[3] = 1.2, :math:\mathrm{con}[4] = 1.3, :math:\mathrm{con}[5] = 1.4.

**tcrit** : float
A point beyond which integration must not be attempted. The use of :math:\mathrm{tcrit} is described under the argument :math:\textit{itask} in the specification for the integrator (e.g., see :meth:ivp_stiff_exp_fulljac). A value, :math:0.0 say, must be specified even if :math:\textit{itask} subsequently specifies that :math:\mathrm{tcrit} will not be used.

**hmin** : float
The minimum absolute step size to be allowed. Set :math:\mathrm{hmin} = 0.0 if this option is not required.

**hmax** : float
The maximum absolute step size to be allowed. Set :math:\mathrm{hmax} = 0.0 if this option is not required.

**h0** : float
The step size to be attempted on the first step. Set :math:\mathrm{h0} = 0.0 if the initial step size is calculated internally.

**maxstp** : int
The maximum number of steps to be attempted during one call to the integrator after which it will return with :math:\mathrm{errno} = 2. Set :math:\mathrm{maxstp} = 0 if no limit is to be imposed.

**mxhnil** : int
The maximum number of warnings printed (if :math:{\textit{itrace}}\geq 0, e.g., see :meth:ivp_stiff_exp_fulljac) per problem when :math:t+h = t on a step (:math:h = \text{ current step size}). If :math:\mathrm{mxhnil}\leq 0, a default value of :math:10 is assumed.

**norm** : str, length 1
Indicates the type of norm to be used.

:math:\mathrm{norm} = \texttt{'M'}

Maximum norm.

:math:\mathrm{norm} = \texttt{'A'}

Averaged L2 norm.

:math:\mathrm{norm} = \texttt{'D'}

Is the same as 'A'.

If :math:\textit{vnorm} denotes the norm of the vector :math:v of length :math:n, for the averaged L2 norm

.. math::
\textit{vnorm} = \sqrt{\frac{1}{n}\sum_{{i = 1}}^n\left(v_i/w_i\right)^2}\text{,}

while for the maximum norm

.. math::
\textit{vnorm} = \mathrm{max}_i\left\lvert v_i/w_i\right\rvert \text{.}

If you wish to weight the maximum norm or the L2 norm, :math:\textit{rtol} and :math:\textit{atol} should be scaled appropriately on input to the integrator (see under :math:\textit{itol} in the specification of the integrator for the formulation of the weight vector :math:w_i from :math:\textit{rtol} and :math:\textit{atol}, e.g., :meth:ivp_stiff_exp_fulljac).

Only the first character of the actual argument :math:\mathrm{norm} is passed to ivp_stiff_blend; hence it is permissible for the actual argument to be more descriptive e.g., 'Maximum', 'Average L2' or 'Default' in a call to ivp_stiff_blend.

**Returns**
**con** : float, ndarray, shape :math:\left(6\right)
The values actually used by ivp_stiff_blend.

**comm** : dict, communication object
Communication structure.

.. _d02nw-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:\mathrm{con}[1] = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{con}[2] = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{con}[1]\leq \mathrm{con}[2].

(errno :math:1)
On entry, :math:\mathrm{maxord} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{sdysav} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{sdysav}\geq \mathrm{maxord}+3.

(errno :math:1)
On entry, :math:\mathrm{maxord} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:0 < \mathrm{maxord}\leq 11.

(errno :math:1)
On entry, :math:\mathrm{con}[0] = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{con}[1] = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{con}[0]\leq \mathrm{con}[1].

(errno :math:1)
On entry, :math:\mathrm{con}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle was less than :math:1.0.

(errno :math:1)
On entry, :math:\mathrm{con}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle was less than :math:0.0.

(errno :math:1)
On entry, :math:\mathrm{norm} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{norm} = \texttt{'M'}, :math:\texttt{'A'} or :math:\texttt{'D'}.

(errno :math:1)
On entry, :math:\mathrm{neqmax} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{neqmax}\geq 1.

.. _d02nw-py2-py-notes:

**Notes**
No equivalent traditional C interface for this routine exists in the NAG Library.

An integrator setup function must be called before the call to any linear algebra setup function or integrator from the SPRINT suite of functions in this sub-module.
This setup function, ivp_stiff_blend, makes the choice of the BLEND integrator and permits you to define options appropriate to this choice.
Alternative choices of integrator from this suite are the BDF method and the DASSL implementation of the BDF method which can be chosen by initial calls to :meth:ivp_stiff_bdf or :meth:ivp_stiff_dassl respectively.
"""
raise NotImplementedError

[docs]def ivp_stiff_sparjac_diag(icall, lblock, comm):
r"""
ivp_stiff_sparjac_diag is an optional output function which you may call, on exit from an integrator in submodule ode, if sparse matrix linear algebra has been selected.

.. _d02nx-py2-py-doc:

For full information please refer to the NAG Library document for d02nx

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02nxf.html

.. _d02nx-py2-py-parameters:

**Parameters**
**icall** : int
Indicates whether or not all output arguments have been set during the call to the integrator. If so, that is, if the integrator returned with the function exits successfully or :math:\mathrm{errno} = 12, then :math:\mathrm{icall} must be set to :math:0. Otherwise :math:\mathrm{icall} must be set to :math:1, indicating that integration did not take place due to lack of space in arrays :math:\textit{wkjac} and :math:\textit{jacpvt}, and only :math:\mathrm{liwreq}, :math:\mathrm{liwusd}, :math:\mathrm{lrwreq}, :math:\mathrm{lrwusd} have been set.

**lblock** : bool
The value used for the argument :math:\mathrm{lblock} when calling :meth:ivp_stiff_sparjac_setup.

**comm** : dict, communication object
Communication structure.

This argument must have been initialized by a prior call to :meth:ivp_stiff_exp_sparjac, :meth:ivp_stiff_imp_sparjac or :meth:ivp_stiff_imp_revcom.

**Returns**
**liwreq** : int
The length of the int workspace :math:\textit{jacpvt} reserved for the sparse matrix functions.

**liwusd** : int
The length of the int workspace :math:\textit{jacpvt} actually used by the sparse matrix functions.

**lrwreq** : int
The length of the float workspace :math:\textit{wkjac} reserved for the sparse matrix functions.

**lrwusd** : int
The length of the float workspace :math:\textit{wkjac} actually used by the sparse matrix functions.

**nlu** : int
The number of :math:LU decompositions done during the integration.

**nnz** : int
The number of nonzeros in the Jacobian.

**ngp** : int
The number of :math:\textit{fcn} or :math:\textit{resid} calls needed to form the Jacobian.

**isplit** : int
An appropriate value for the argument :math:\mathrm{isplit} when calling :meth:ivp_stiff_sparjac_setup for subsequent runs of similar problems.

**igrow** : int
An estimate of the growth of the elements encountered during the last :math:LU decomposition performed. If the actual estimate exceeds the largest possible integer value for the machine being used (see :meth:machine.integer_max <naginterfaces.library.machine.integer_max>) :math:\mathrm{igrow} is set to the value returned by :meth:machine.integer_max <naginterfaces.library.machine.integer_max>.

**nblock** : int
If :math:\mathrm{lblock} = \mathbf{True}, :math:\mathrm{nblock} contains the number of diagonal blocks in the Jacobian matrix permuted to block lower triangular form. If :math:\mathrm{nblock} = 1 then on subsequent runs of a similar problem :math:\mathrm{lblock} should be set to :math:\mathbf{False} in the call to :meth:ivp_stiff_sparjac_setup.

If :math:\mathrm{lblock} = \mathbf{False}, :math:\mathrm{nblock} = 1.

.. _d02nx-py2-py-notes:

**Notes**
No equivalent traditional C interface for this routine exists in the NAG Library.

ivp_stiff_sparjac_diag permits you to examine the various outputs from the sparse linear algebra functions called by the integrator.
"""
raise NotImplementedError

[docs]def ivp_stiff_integ_diag(neq, neqmax, comm):
r"""
ivp_stiff_integ_diag is a diagnostic function which you may call either after any user-specified exit or after a mid-integration error exit from any of those integrators in submodule ode that use methods set up by calls to :meth:ivp_stiff_dassl, :meth:ivp_stiff_bdf or :meth:ivp_stiff_blend.

.. _d02ny-py2-py-doc:

For full information please refer to the NAG Library document for d02ny

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02nyf.html

.. _d02ny-py2-py-parameters:

**Parameters**
**neq** : int
The value used for the argument :math:\mathrm{neq} when calling the integrator.

**neqmax** : int
The value used for the argument :math:\mathrm{neqmax} when calling the integrator.

**comm** : dict, communication object
Communication structure.

This argument must have been initialized by a prior call to :meth:ivp_stiff_exp_fulljac, :meth:ivp_stiff_exp_bandjac, :meth:ivp_stiff_exp_sparjac, :meth:ivp_stiff_imp_fulljac, :meth:ivp_stiff_imp_bandjac, :meth:ivp_stiff_imp_sparjac, :meth:ivp_stiff_exp_revcom or :meth:ivp_stiff_imp_revcom.

**Returns**
**hu** : float
The last successful step size.

**h** : float
The proposed next step size for continuing the integration.

**tcur** : float
:math:t, the value of the independent variable which the integrator has actually reached. :math:\mathrm{tcur} will always be at least as far as the output value of the argument :math:t in the direction of integration, but may be further (if overshooting and interpolation at :math:\textit{tout} was specified, e.g., see :meth:ivp_stiff_exp_fulljac).

**tolsf** : float
A tolerance scale factor, :math:\mathrm{tolsf}\geq 1.0, which is computed when a request for too much accuracy is detected by the integrator (indicated by a return with :math:\mathrm{errno} = 3 or 14). If :math:\textit{itol} is left unaltered but :math:\textit{rtol} and :math:\textit{atol} are uniformly scaled up by a factor of :math:\mathrm{tolsf} the next call to the integrator is deemed likely to succeed.

**nst** : int
The number of steps taken in the integration so far.

**nre** : int
The number of function or residual evaluations (:math:\textit{fcn} (e.g., see :meth:ivp_stiff_exp_fulljac) or :math:\textit{resid} (e.g., see :meth:ivp_stiff_imp_fulljac) calls) used in the integration so far.

**nje** : int
The number of Jacobian evaluations used in the integration so far. This equals the number of matrix :math:LU decompositions.

**nqu** : int
The order of the method last used (successfully) in the integration.

**nq** : int
The proposed order of the method for continuing the integration.

**niter** : int
The number of iterations performed in the integration so far by the nonlinear equation solver.

**imxer** : int
The index of the component of largest magnitude in the weighted local error vector :math:\left(e_{\textit{i}}/w_{\textit{i}}\right), for :math:\textit{i} = 1,2,\ldots,\mathrm{neq}.

**algequ** : bool, ndarray, shape :math:\left(\mathrm{neq}\right)
:math:\mathrm{algequ}[\textit{i}-1] = \mathbf{True} if the :math:\textit{i}\ th equation integrated was detected to be algebraic, otherwise :math:\mathrm{algequ}[\textit{i}-1] = \mathbf{False}. Note that when the integrators for explicit equations are being used, then :math:\mathrm{algequ}[\textit{i}-1] = \mathbf{False}, for :math:\textit{i} = 1,2,\ldots,\mathrm{neq}.

.. _d02ny-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:\mathrm{neq} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{neqmax} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{neq}\leq \mathrm{neqmax}.

(errno :math:1)
On entry, :math:\mathrm{neqmax} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{neqmax}\geq 1.

(errno :math:1)
On entry, :math:\mathrm{neq} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{neq}\geq 1.

.. _d02ny-py2-py-notes:

**Notes**
No equivalent traditional C interface for this routine exists in the NAG Library.

ivp_stiff_integ_diag permits you to inspect statistics produced by any integrator in this sub-module that has been set up a call to one of :meth:ivp_stiff_dassl, :meth:ivp_stiff_bdf or :meth:ivp_stiff_blend.
These statistics concern the integration only.
"""
raise NotImplementedError

[docs]def ivp_stiff_contin(neqmax, tcrit, h, hmin, hmax, maxstp, mxhnil, comm):
r"""
ivp_stiff_contin is a setup function which must be called, if optional inputs need resetting, prior to a continuation call to any of those integrators in submodule ode that use methods set up by calls to :meth:ivp_stiff_dassl, :meth:ivp_stiff_bdf or :meth:ivp_stiff_blend.

.. _d02nz-py2-py-doc:

For full information please refer to the NAG Library document for d02nz

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02nzf.html

.. _d02nz-py2-py-parameters:

**Parameters**
**neqmax** : int
The value used for the argument :math:\mathrm{neqmax} when calling the integrator.

**tcrit** : float
A point beyond which integration must not be attempted. The use of :math:\mathrm{tcrit} is described under the argument :math:\textit{itask} in the specification for the integrator (e.g., see :meth:ivp_stiff_exp_fulljac). A value, :math:0.0 say, must be specified even if :math:\textit{itask} subsequently specifies that :math:\mathrm{tcrit} will not be used.

**h** : float
The next step size to be attempted. Set :math:\mathrm{h} = 0.0 if the current value of :math:\mathrm{h} is not to be changed.

**hmin** : float
The minimum absolute step size to be allowed. Set :math:\mathrm{hmin} = 0.0 if this option is not required. Set :math:\mathrm{hmin} < 0.0 if the current value of :math:\mathrm{hmin} is not to be changed.

**hmax** : float
The maximum absolute step size to be allowed. Set :math:\mathrm{hmax} = 0.0 if this option is not required. Set :math:\mathrm{hmax} < 0.0 if the current value of :math:\mathrm{hmax} is not to be changed.

**maxstp** : int
The maximum number of steps to be attempted during one call to the integrator after which it will return with :math:\mathrm{errno} = 2 (see :meth:ivp_stiff_exp_bandjac). Set :math:\mathrm{maxstp} = 0 if this option is not required. Set :math:\mathrm{maxstp} < 0 if the current value of :math:\mathrm{maxstp} is not to be changed.

**mxhnil** : int
The maximum number of warnings printed (if :math:{\textit{itrace}}\geq 0, e.g., see :meth:ivp_stiff_exp_fulljac) per problem when :math:t+h = t on a step (:math:h = \text{ current step size}). If :math:\mathrm{mxhnil}\leq 0, a default value of :math:10 is assumed.

**comm** : dict, communication object, modified in place
Communication structure.

This argument must have been initialized by a prior call to :meth:ivp_stiff_dassl, :meth:ivp_stiff_bdf or :meth:ivp_stiff_blend.

.. _d02nz-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:\mathrm{neqmax} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{neqmax}\geq 1.

.. _d02nz-py2-py-notes:

**Notes**
No equivalent traditional C interface for this routine exists in the NAG Library.

ivp_stiff_contin is provided to permit you to reset many of the arguments which control the integration 'on the fly', that is in conjunction with the interrupt facility permitted through the argument :math:\textit{itask} of the integrator (e.g., see :meth:ivp_stiff_exp_fulljac).
In addition to a number of arguments which you can set initially through one of the integrator setup functions, the step size to be attempted on the next step may be changed.
"""
raise NotImplementedError

[docs]def ivp_rkts_range(f, twant, ygot, ymax, comm, data=None):
r"""
ivp_rkts_range solves an initial value problem for a first-order system of ordinary differential equations using Runge--Kutta methods.

.. _d02pe-py2-py-doc:

For full information please refer to the NAG Library document for d02pe

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02pef.html

.. _d02pe-py2-py-parameters:

**Parameters**
**f** : callable yp = f(t, y, data=None)
:math:\mathrm{f} must evaluate the functions :math:f_i (that is the first derivatives :math:y_i^{\prime }) for given values of the arguments :math:t, :math:y_i.

**Parameters**
**t** : float
:math:t, the current value of the independent variable.

**y** : float, ndarray, shape :math:\left(n\right)
The current values of the dependent variables, :math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**yp** : float, array-like, shape :math:\left(n\right)
The values of :math:f_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}.

**twant** : float
:math:t, the next value of the independent variable where a solution is desired.

**ygot** : float, array-like, shape :math:\left(n\right)
On the first call to ivp_rkts_range, :math:\mathrm{ygot} need not be set. On all subsequent calls :math:\mathrm{ygot} must remain unchanged.

**ymax** : float, array-like, shape :math:\left(n\right)
On the first call to ivp_rkts_range, :math:\mathrm{ymax} need not be set. On all subsequent calls :math:\mathrm{ymax} must remain unchanged.

**comm** : dict, communication object, modified in place
Communication structure.

This argument must have been initialized by a prior call to :meth:ivp_rkts_setup.

**data** : arbitrary, optional
User-communication data for callback functions.

**Returns**
**tgot** : float
:math:t, the value of the independent variable at which a solution has been computed. On successful exit with no exception or warning is raised, :math:\mathrm{tgot} will equal :math:\mathrm{twant}. On exit with :math:\mathrm{errno} > 1, a solution has still been computed at the value of :math:\mathrm{tgot} but in general :math:\mathrm{tgot} will not equal :math:\mathrm{twant}.

**ygot** : float, ndarray, shape :math:\left(n\right)
An approximation to the true solution at the value of :math:\mathrm{tgot}. At each step of the integration to :math:\mathrm{tgot}, the local error has been controlled as specified in :meth:ivp_rkts_setup. The local error has still been controlled even when :math:\mathrm{tgot}\neq \mathrm{twant}, that is after a return with :math:\mathrm{errno} > 1.

**ypgot** : float, ndarray, shape :math:\left(n\right)
An approximation to the first derivative of the true solution at :math:\mathrm{tgot}.

**ymax** : float, ndarray, shape :math:\left(n\right)
:math:\mathrm{ymax}[i-1] contains the largest value of :math:\left\lvert y_i\right\rvert computed at any step in the integration so far.

.. _d02pe-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, a previous call to the setup function has not been made or the communication arrays have become corrupted.

(errno :math:1)
On entry, :math:n = \langle\mathit{\boldsymbol{value}}\rangle, but the value passed to the setup function was :math:{\textit{n}} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, the communication arrays have become corrupted, or a catastrophic error has already been detected elsewhere. You cannot continue integrating the problem.

(errno :math:1)
:math:\mathrm{twant} is too close to the last value of :math:\mathrm{tgot} (:math:\textit{tstart} on setup).

When using the method of order :math:8 at setup, these must differ by at least :math:\langle\mathit{\boldsymbol{value}}\rangle. Their absolute difference is :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
:math:\mathrm{twant} lies beyond :math:\textit{tend} (setup) in the direction of integration.

:math:\mathrm{twant} = \langle\mathit{\boldsymbol{value}}\rangle and :math:{\textit{tend}} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
:math:\mathrm{twant} lies beyond :math:\textit{tend} (setup) in the direction of integration, but is very close to :math:\textit{tend}.

You may have intended :math:\mathrm{twant} = {\textit{tend}}.

:math:\left\lvert \mathrm{twant}-{\textit{tend}}\right\rvert = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
:math:\mathrm{twant} does not lie in the direction of integration. :math:\mathrm{twant} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
:math:\textit{tend} (setup) had already been reached in a previous call.

To start a new problem, you will need to call the setup function.

(errno :math:1)
You cannot call this function after it has returned an error.

You must call the setup function to start another problem.

(errno :math:1)
You cannot call this function when you have specified, in the setup function, that the step integrator will be used.

**Warns**
**NagAlgorithmicWarning**
(errno :math:2)
This function is being used inefficiently because the step size has been reduced drastically many times to obtain answers at many points. Using the order :math:4 and :math:5 pair method at setup is more appropriate here. You can continue integrating this problem.

(errno :math:3)
Approximately :math:\langle\mathit{\boldsymbol{value}}\rangle function evaluations have been used to compute the solution since the integration started or since this message was last printed. However, you can continue integrating the problem.

(errno :math:4)
Approximately :math:\langle\mathit{\boldsymbol{value}}\rangle function evaluations have been used to compute the solution since the integration started or since this message was last printed. Your problem has been diagnosed as stiff. If the situation persists, it will cost roughly :math:\langle\mathit{\boldsymbol{value}}\rangle times as much to reach :math:\textit{tend} (setup) as it has cost to reach the current time. You should probably call functions intended for stiff problems. However, you can continue integrating the problem.

(errno :math:4)
Your problem has been diagnosed as stiff. If the situation persists, it will cost roughly :math:\langle\mathit{\boldsymbol{value}}\rangle times as much to reach :math:\textit{tend} (setup) as it has cost to reach the current time. You should probably call functions intended for stiff problems. However, you can continue integrating the problem.

(errno :math:5)
In order to satisfy your error requirements the solver has to use a step size of :math:\langle\mathit{\boldsymbol{value}}\rangle at the current time, :math:\langle\mathit{\boldsymbol{value}}\rangle. This step size is too small for the machine precision, and is smaller than :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:6)
The global error assessment algorithm failed at start of integration.

The integration is being terminated.

(errno :math:6)
The global error assessment may not be reliable for times beyond :math:\langle\mathit{\boldsymbol{value}}\rangle.

The integration is being terminated.

.. _d02pe-py2-py-notes:

**Notes**
ivp_rkts_range and its associated functions (:meth:ivp_rkts_setup, :meth:ivp_rkts_diag and :meth:ivp_rkts_errass) solve an initial value problem for a first-order system of ordinary differential equations.
The functions, based on Runge--Kutta methods and derived from RKSUITE (see Brankin et al. (1991)), integrate

.. math::
y^{\prime } = f\left(t, y\right)\quad \text{ given }\quad y\left(t_0\right) = y_0

where :math:y is the vector of :math:\textit{n} solution components and :math:t is the independent variable.

ivp_rkts_range is designed for the usual task, namely to compute an approximate solution at a sequence of points.
You must first call :meth:ivp_rkts_setup to specify the problem and how it is to be solved.
Thereafter you call ivp_rkts_range repeatedly with successive values of :math:\mathrm{twant}, the points at which you require the solution, in the range from :math:\textit{tstart} to :math:\textit{tend} (as specified in :meth:ivp_rkts_setup).
In this manner ivp_rkts_range returns the point at which it has computed a solution :math:\mathrm{tgot} (usually :math:\mathrm{twant}), the solution there (:math:\mathrm{ygot}) and its derivative (:math:\mathrm{ypgot}).
If ivp_rkts_range encounters some difficulty in taking a step toward :math:\mathrm{twant}, then it returns the point of difficulty (:math:\mathrm{tgot}) and the solution and derivative computed there (:math:\mathrm{ygot} and :math:\mathrm{ypgot}, respectively).

In the call to :meth:ivp_rkts_setup you can specify either the first step size for ivp_rkts_range to attempt or that it computes automatically an appropriate value.
Thereafter ivp_rkts_range estimates an appropriate step size for its next step.
This value and other details of the integration can be obtained after any call to ivp_rkts_range by a call to :meth:ivp_rkts_diag.
The local error is controlled at every step as specified in :meth:ivp_rkts_setup.
If you wish to assess the true error, you must set :math:\textit{method} to a positive value in the call to :meth:ivp_rkts_setup.
This assessment can be obtained after any call to ivp_rkts_range by a call to :meth:ivp_rkts_errass.

For more complicated tasks, you are referred to functions :meth:ivp_rkts_onestep, :meth:ivp_rkts_interp and :meth:ivp_rkts_reset_tend, all of which are used by ivp_rkts_range.

.. _d02pe-py2-py-references:

**References**
Brankin, R W, Gladwell, I and Shampine, L F, 1991, RKSUITE: A suite of Runge--Kutta codes for the initial value problems for ODEs, SoftReport 91-S1, Southern Methodist University
"""
raise NotImplementedError

[docs]def ivp_rkts_onestep(f, n, comm, data=None):
r"""
ivp_rkts_onestep is a one-step function for solving an initial value problem for a first-order system of ordinary differential equations using Runge--Kutta methods.

.. _d02pf-py2-py-doc:

For full information please refer to the NAG Library document for d02pf

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02pff.html

.. _d02pf-py2-py-parameters:

**Parameters**
**f** : callable yp = f(t, y, data=None)
:math:\mathrm{f} must evaluate the functions :math:f_i (that is the first derivatives :math:y_i^{\prime }) for given values of the arguments :math:t, :math:y_i.

**Parameters**
**t** : float
:math:t, the current value of the independent variable.

**y** : float, ndarray, shape :math:\left(n\right)
The current values of the dependent variables, :math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**yp** : float, array-like, shape :math:\left(n\right)
The values of :math:f_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}.

**n** : int
:math:n, the number of ordinary differential equations in the system to be solved.

**comm** : dict, communication object, modified in place
Communication structure.

This argument must have been initialized by a prior call to :meth:ivp_rkts_setup.

**data** : arbitrary, optional
User-communication data for callback functions.

**Returns**
**tnow** : float
:math:t, the value of the independent variable at which a solution has been computed.

**ynow** : float, ndarray, shape :math:\left(\mathrm{n}\right)
An approximation to the solution at :math:\mathrm{tnow}. The local error of the step to :math:\mathrm{tnow} was no greater than permitted by the specified tolerances (see :meth:ivp_rkts_setup).

**ypnow** : float, ndarray, shape :math:\left(\mathrm{n}\right)
An approximation to the first derivative of the solution at :math:\mathrm{tnow}.

.. _d02pf-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
:math:\textit{tend}, as specified in the setup function, has already been reached. To start a new problem, you will need to call the setup function. To continue integration beyond :math:\textit{tend} then :meth:ivp_rkts_reset_tend must first be called to reset :math:\textit{tend} to a new end value.

(errno :math:1)
A call to this function cannot be made after it has returned an error.

The setup function must be called to start another problem.

(errno :math:1)
On entry, a previous call to the setup function has not been made or the communication arrays have become corrupted.

(errno :math:1)
On entry, :math:\mathrm{n} = \langle\mathit{\boldsymbol{value}}\rangle, but the value passed to the setup function was :math:{\textit{n}} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, the communication arrays have become corrupted, or a catastrophic error has already been detected elsewhere. You cannot continue integrating the problem.

**Warns**
**NagAlgorithmicWarning**
(errno :math:2)
More than :math:100 output points have been obtained by integrating to :math:\textit{tend} (as specified in the setup function). They have been so clustered that it would probably be (much) more efficient to use the interpolation function (if :math:\left\lvert {\textit{method}}\right\rvert = 3, switch to :math:\left\lvert {\textit{method}}\right\rvert = 2 at setup). However, you can continue integrating the problem.

(errno :math:3)
Approximately :math:\langle\mathit{\boldsymbol{value}}\rangle function evaluations have been used to compute the solution since the integration started or since this message was last printed. However, you can continue integrating the problem.

(errno :math:4)
Approximately :math:\langle\mathit{\boldsymbol{value}}\rangle function evaluations have been used to compute the solution since the integration started or since this message was last printed. Your problem has been diagnosed as stiff. If the situation persists, it will cost roughly :math:\langle\mathit{\boldsymbol{value}}\rangle times as much to reach :math:\textit{tend} (setup) as it has cost to reach the current time. You should probably call functions intended for stiff problems. However, you can continue integrating the problem.

(errno :math:4)
Your problem has been diagnosed as stiff. If the situation persists, it will cost roughly :math:\langle\mathit{\boldsymbol{value}}\rangle times as much to reach :math:\textit{tend} (setup) as it has cost to reach the current time. You should probably call functions intended for stiff problems. However, you can continue integrating the problem.

(errno :math:5)
In order to satisfy your error requirements the solver has to use a step size of :math:\langle\mathit{\boldsymbol{value}}\rangle at the current time, :math:\langle\mathit{\boldsymbol{value}}\rangle. This step size is too small for the machine precision, and is smaller than :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:6)
The global error assessment may not be reliable for times beyond :math:\langle\mathit{\boldsymbol{value}}\rangle.

The integration is being terminated.

(errno :math:6)
The global error assessment algorithm failed at start of integration.

The integration is being terminated.

.. _d02pf-py2-py-notes:

**Notes**
ivp_rkts_onestep and its associated functions (:meth:ivp_rkts_setup, :meth:ivp_rkts_reset_tend, :meth:ivp_rkts_interp, :meth:ivp_rkts_diag and :meth:ivp_rkts_errass) solve an initial value problem for a first-order system of ordinary differential equations.
The functions, based on Runge--Kutta methods and derived from RKSUITE (see Brankin et al. (1991)), integrate

.. math::
y^{\prime } = f\left(t, y\right)\quad \text{ given }\quad y\left(t_0\right) = y_0

where :math:y is the vector of :math:\textit{n} solution components and :math:t is the independent variable.

ivp_rkts_onestep is designed to be used in complicated tasks when solving systems of ordinary differential equations.
You must first call :meth:ivp_rkts_setup to specify the problem and how it is to be solved.
Thereafter you (repeatedly) call ivp_rkts_onestep to take one integration step at a time from :math:\textit{tstart} in the direction of :math:\textit{tend} (as specified in :meth:ivp_rkts_setup).
In this manner ivp_rkts_onestep returns an approximation to the solution :math:\mathrm{ynow} and its derivative :math:\mathrm{ypnow} at successive points :math:\mathrm{tnow}.
If ivp_rkts_onestep encounters some difficulty in taking a step, the integration is not advanced and the function returns with the same values of :math:\mathrm{tnow}, :math:\mathrm{ynow} and :math:\mathrm{ypnow} as returned on the previous successful step. ivp_rkts_onestep tries to advance the integration as far as possible subject to passing the test on the local error and not going past :math:\textit{tend}.

In the call to :meth:ivp_rkts_setup you can specify either the first step size for ivp_rkts_onestep to attempt or that it computes automatically an appropriate value.
Thereafter ivp_rkts_onestep estimates an appropriate step size for its next step.
This value and other details of the integration can be obtained after any call to ivp_rkts_onestep by a call to :meth:ivp_rkts_diag.
The local error is controlled at every step as specified in :meth:ivp_rkts_setup.
If you wish to assess the true error, you must set :math:\textit{method} to a positive value in the call to :meth:ivp_rkts_setup.
This assessment can be obtained after any call to ivp_rkts_onestep by a call to :meth:ivp_rkts_errass.

If you want answers at specific points there are two ways to proceed:

(i) The more efficient way is to step past the point where a solution is desired, and then call :meth:ivp_rkts_interp to get an answer there. Within the span of the current step, you can get all the answers you want at very little cost by repeated calls to :meth:ivp_rkts_interp. This is very valuable when you want to find where something happens, e.g., where a particular solution component vanishes. You cannot proceed in this way with :math:{\textit{method}} = 3 or :math:-3.

(#) The other way to get an answer at a specific point is to set :math:\textit{tend} to this value and integrate to :math:\textit{tend}. ivp_rkts_onestep will not step past :math:\textit{tend}, so when a step would carry it past, it will reduce the step size so as to produce an answer at :math:\textit{tend} exactly. After getting an answer there (:math:\mathrm{tnow} = {\textit{tend}}), you can reset :math:\textit{tend} to the next point where you want an answer, and repeat. :math:\textit{tend} could be reset by a call to :meth:ivp_rkts_setup, but you should not do this. You should use :meth:ivp_rkts_reset_tend instead because it is both easier to use and much more efficient. This way of getting answers at specific points can be used with any of the available methods, but it is the only way with :math:{\textit{method}} = 3 or :math:-3. It can be inefficient. Should this be the case, the code will bring the matter to your attention.

.. _d02pf-py2-py-references:

**References**
Brankin, R W, Gladwell, I and Shampine, L F, 1991, RKSUITE: A suite of Runge--Kutta codes for the initial value problems for ODEs, SoftReport 91-S1, Southern Methodist University
"""
raise NotImplementedError

[docs]def ivp_rk_step_revcomm(irevcm, yp, comm):
r"""
ivp_rk_step_revcomm is a reverse communication one-step function for solving an initial value problem for a first-order system of ordinary differential equations using Runge--Kutta methods.
The direct communication version of this function is :meth:ivp_rkts_onestep.
See Direct and Reverse Communication Routines <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/h/howtounl.html#revcommroutines>__ for the difference between forward and reverse communication.

.. _d02pg-py2-py-doc:

For full information please refer to the NAG Library document for d02pg

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02pgf.html

.. _d02pg-py2-py-parameters:

**Parameters**
**irevcm** : int
On initial entry :math:\mathrm{irevcm} must be set to zero, otherwise should be unchanged from the previous call.

**yp** : float, array-like, shape :math:\left(n\right)
On initial entry: :math:\mathrm{yp} need not be set.

On intermediate entry: :math:\mathrm{yp} must contain the value of the derivatives :math:y^{\prime } = f\left(t, y\right) where :math:t is supplied in :math:\mathrm{t} and :math:y is supplied in the array :math:\mathrm{y}.

**comm** : dict, communication object, modified in place
Communication structure.

This argument must have been initialized by a prior call to :meth:ivp_rkts_setup.

**Returns**
**irevcm** : int
On intermediate exit :math:\mathrm{irevcm} returns a value :math:\text{} > 0 to indicate that a function evaluation is required prior to re-entry.

On final exit returns :math:-1 or :math:-2 denoting success or failure, respectively.

**t** : float
On intermediate exit: :math:\mathrm{t} contains the value of the independent variable :math:t at which the derivatives :math:y^{\prime } are to be evaluated.

On final exit: the value of :math:t at which a solution has been computed following a successful step.

**y** : float, ndarray, shape :math:\left(n\right)
On intermediate exit: :math:\mathrm{y} contains the value of the solution :math:y at which the derivatives :math:y^{\prime } are to be evaluated.

On final exit: the approximation to the solution computed following a successful step.

.. _d02pg-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
:math:\textit{tend}, as specified in the setup function, has already been reached. To start a new problem, you will need to call the setup function. To continue integration beyond :math:\textit{tend} then :meth:ivp_rkts_reset_tend must first be called to reset :math:\textit{tend} to a new end value.

(errno :math:1)
A call to this function cannot be made after it has returned an error.

The setup function must be called to start another problem.

(errno :math:1)
On entry, a previous call to the setup function has not been made or the communication arrays have become corrupted.

(errno :math:1)
:math:\mathrm{irevcm} < 0 on entry.

(errno :math:1)
On entry, :math:n = \langle\mathit{\boldsymbol{value}}\rangle, but the value passed to the setup function was :math:{\textit{n}} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, the communication arrays have become corrupted, or a catastrophic error has already been detected elsewhere. You cannot continue integrating the problem.

**Warns**
**NagAlgorithmicWarning**
(errno :math:2)
More than :math:100 output points have been obtained by integrating to :math:\textit{tend} (as specified in the setup function). They have been so clustered that it would probably be (much) more efficient to use the interpolation function. However, you can continue integrating the problem.

(errno :math:3)
Approximately :math:\langle\mathit{\boldsymbol{value}}\rangle function evaluations have been used to compute the solution since the integration started or since this message was last printed. However, you can continue integrating the problem.

(errno :math:4)
Approximately :math:\langle\mathit{\boldsymbol{value}}\rangle function evaluations have been used to compute the solution since the integration started or since this message was last printed. Your problem has been diagnosed as stiff. If the situation persists, it will cost roughly :math:\langle\mathit{\boldsymbol{value}}\rangle times as much to reach :math:\textit{tend} (setup) as it has cost to reach the current time. You should probably call functions intended for stiff problems. However, you can continue integrating the problem.

(errno :math:4)
Your problem has been diagnosed as stiff. If the situation persists, it will cost roughly :math:\langle\mathit{\boldsymbol{value}}\rangle times as much to reach :math:\textit{tend} (setup) as it has cost to reach the current time. You should probably call functions intended for stiff problems. However, you can continue integrating the problem.

(errno :math:5)
In order to satisfy your error requirements the solver has to use a step size of :math:\langle\mathit{\boldsymbol{value}}\rangle at the current time, :math:\langle\mathit{\boldsymbol{value}}\rangle. This step size is too small for the machine precision, and is smaller than :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:6)
The global error assessment may not be reliable for times beyond :math:\langle\mathit{\boldsymbol{value}}\rangle.

The integration is being terminated.

(errno :math:6)
The global error assessment algorithm failed at start of integration.

The integration is being terminated.

.. _d02pg-py2-py-notes:

**Notes**
ivp_rk_step_revcomm and its associated functions (:meth:ivp_rk_interp_setup, :meth:ivp_rk_interp_eval, :meth:ivp_rkts_setup, :meth:ivp_rkts_reset_tend, :meth:ivp_rkts_diag and :meth:ivp_rkts_errass) solve an initial value problem for a first-order system of ordinary differential equations.
The functions, based on Runge--Kutta methods and derived from RKSUITE (see Brankin et al. (1991)), integrate

.. math::
y^{\prime } = f\left(t, y\right)\quad \text{ given }\quad y\left(t_0\right) = y_0

where :math:y is the vector of :math:\textit{n} solution components and :math:t is the independent variable.

ivp_rk_step_revcomm is designed to be used in complicated tasks when solving systems of ordinary differential equations.
You must first call :meth:ivp_rkts_setup to specify the problem and how it is to be solved.
Thereafter you (repeatedly) call ivp_rk_step_revcomm in reverse communication loops to take one integration step at a time from :math:\textit{tstart} in the direction of :math:\textit{tend} (as specified in :meth:ivp_rkts_setup).
In this manner ivp_rk_step_revcomm returns an approximation to the solution :math:\mathrm{y} and its derivative :math:\mathrm{yp} at successive points :math:\mathrm{t}.
If ivp_rk_step_revcomm encounters some difficulty in taking a step, the integration is not advanced and the function returns with the same values of :math:\mathrm{t}, :math:\mathrm{y} and :math:\mathrm{yp} as returned on the previous successful step. ivp_rk_step_revcomm tries to advance the integration as far as possible subject to passing the test on the local error and not going past :math:\textit{tend}.

In the call to :meth:ivp_rkts_setup you can specify either the first step size for ivp_rk_step_revcomm to attempt or it computes automatically an appropriate value.
Thereafter ivp_rk_step_revcomm estimates an appropriate step size for its next step.
This value and other details of the integration can be obtained after a completed step by ivp_rk_step_revcomm by a call to :meth:ivp_rkts_diag.
The local error is controlled at every step as specified in :meth:ivp_rkts_setup.
If you wish to assess the true error, you must set :math:\textit{method} to a positive value in the call to :meth:ivp_rkts_setup.
This assessment can be obtained after any call to ivp_rk_step_revcomm by a call to :meth:ivp_rkts_errass.

If you want answers at specific points there are two ways to proceed:

(i) The more efficient way is to step past the point where a solution is desired, and then call :meth:ivp_rk_interp_setup and :meth:ivp_rk_interp_eval to get an answer there. Within the span of the current step, you can get all the answers you want at very little cost by repeated calls to :meth:ivp_rk_interp_eval. This is very valuable when you want to find where something happens, e.g., where a particular solution component vanishes.

(#) Alternatively, set :math:\textit{tend} to the desired value and integrate to :math:\textit{tend}. ivp_rk_step_revcomm will not step past :math:\textit{tend}, so when a step would carry it past, it will reduce the step size so as to produce an answer at :math:\textit{tend} exactly. After getting an answer there (:math:\mathrm{t} = {\textit{tend}}), you can reset :math:\textit{tend} to the next point where you want an answer, and repeat. :math:\textit{tend} could be reset by a call to :meth:ivp_rkts_setup, but you should not do this. You should use :meth:ivp_rkts_reset_tend instead because it is both easier to use and much more efficient. This way of getting answers at specific points can be used with any of the available methods, but it can be inefficient. Should this be the case, the code will bring the matter to your attention.

.. _d02pg-py2-py-references:

**References**
Brankin, R W, Gladwell, I and Shampine, L F, 1991, RKSUITE: A suite of Runge--Kutta codes for the initial value problems for ODEs, SoftReport 91-S1, Southern Methodist University
"""
raise NotImplementedError

[docs]def ivp_rk_interp_setup(irevcm, nwant, yp, comm):
r"""
ivp_rk_interp_setup is a reverse communication function that computes the interpolant for evaluation by :meth:ivp_rk_interp_eval anywhere on an integration step taken by :meth:ivp_rk_step_revcomm.
The direct communication version of the ivp_rk_interp_setup and :meth:ivp_rk_interp_eval pair is :meth:ivp_rkts_interp.
A significant difference in functionality between the forward and reverse communication versions is that ivp_rk_interp_setup and :meth:ivp_rk_interp_eval can interpolate for the high-order Runge--Kutta method.

.. _d02ph-py2-py-doc:

For full information please refer to the NAG Library document for d02ph

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02phf.html

.. _d02ph-py2-py-parameters:

**Parameters**
**irevcm** : int
On initial entry: :math:\mathrm{irevcm} must be set to zero to indicate that the interpolant for a new step is being taken.

On intermediate entry: :math:\mathrm{irevcm} should remain unchanged.

**nwant** : int
The number of components of the solution to be computed. The first :math:\mathrm{nwant} components are evaluated.

**yp** : float, array-like, shape :math:\left(n\right)
On initial entry: need not be set.

On intermediate entry: :math:\mathrm{yp} must contain the values of the derivatives :math:y_i^{\prime } for the given values of the parameters :math:t, :math:y_i.

**comm** : dict, communication object, modified in place
Communication structure.

This argument must have been initialized by a prior call to :meth:ivp_rkts_setup.

**Returns**
**irevcm** : int
On intermediate exit: :math:\mathrm{irevcm} returns a value :math:1 to indicate that a function evaluation is required prior to re-entry; the value of the derivatives must be returned in :math:\mathrm{yp} where the value of :math:t is supplied in :math:\mathrm{t} and the values :math:y\left(t\right) are supplied in the array :math:\mathrm{y}.

On final exit:

:math:\mathrm{irevcm} = -1

Successful exit; :math:\mathrm{comm}\ ['rwsav'] and :math:\mathrm{comm}\ ['wcomm'] contain details of the interpolant.

:math:\mathrm{irevcm} = -2

Error exit; :math:\textit{errno} should be interrogated to determine the nature of the error.

**t** : float
On intermediate exit: :math:\mathrm{t} contains the value of the independent variable :math:t at which the derivatives :math:y^{\prime } are to be evaluated.

On final exit: contains no useful information.

**y** : float, ndarray, shape :math:\left(n\right)
On intermediate exit: :math:\mathrm{y} contains the value of the solution :math:y at which the derivatives :math:y^{\prime } are to be evaluated.

On final exit: contains no useful information.

.. _d02ph-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
You cannot call this function after the integrator has returned an error.

(errno :math:1)
You cannot call this function before you have called the step integrator.

(errno :math:1)
You cannot call this function after the range integrator has been called.

(errno :math:1)
On entry, :math:n = \langle\mathit{\boldsymbol{value}}\rangle, but the value passed to the setup function was :math:{\textit{n}} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{nwant} = \langle\mathit{\boldsymbol{value}}\rangle and :math:n = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:1\leq \mathrm{nwant}\leq n.

(errno :math:1)
On entry, a previous call to the setup function has not been made or the communication arrays have become corrupted, or a catastrophic error has already been detected elsewhere.

You cannot continue integrating the problem.

.. _d02ph-py2-py-notes:

**Notes**
ivp_rk_interp_setup and its associated functions (:meth:ivp_rk_step_revcomm, :meth:ivp_rk_interp_eval, :meth:ivp_rkts_setup, :meth:ivp_rkts_reset_tend, :meth:ivp_rkts_diag and :meth:ivp_rkts_errass) solve the initial value problem for a first-order system of ordinary differential equations.
The functions, based on Runge--Kutta methods and derived from RKSUITE (see Brankin et al. (1991)), integrate

.. math::
y^{\prime } = f\left(t, y\right)\quad \text{ given }\quad y\left(t_0\right) = y_0

where :math:y is the vector of :math:\textit{n} solution components and :math:t is the independent variable.

:meth:ivp_rk_step_revcomm computes the solution at the end of an integration step.
Using the information computed on that step ivp_rk_interp_setup computes the interpolant which can be evaluated at any point on that step by :meth:ivp_rk_interp_eval.
If :math:{\textit{method}} = 1 or :math:-1 then there is enough information available from the stages of the last step to provide an interpolant of sufficient order of accuracy; no further derivative evaluations will, therefore, be requested.
If :math:{\textit{method}} = 2 or :math:-2 then the interpolant is an order :math:8 continuous Runge--Kutta process that requires a further :math:3 stages of derivative evaluations that will be requested in turn before a final exit.
If :math:{\textit{method}} = 3 or :math:-3 was specified in the call to setup function :meth:ivp_rkts_setup then the interpolant is a continuous Runge--Kutta process requiring a further :math:7 stages of derivative evaluations that will be requested in turn.

.. _d02ph-py2-py-references:

**References**
Brankin, R W, Gladwell, I and Shampine, L F, 1991, RKSUITE: A suite of Runge--Kutta codes for the initial value problems for ODEs, SoftReport 91-S1, Southern Methodist University
"""
raise NotImplementedError

[docs]def ivp_rk_interp_eval(icheck, n, nwant, t, ideriv, comm):
r"""
ivp_rk_interp_eval evaluates the interpolant calculated by :meth:ivp_rk_interp_setup, following an integration step performed by :meth:ivp_rk_step_revcomm to solve an initial value problem.

.. _d02pj-py2-py-doc:

For full information please refer to the NAG Library document for d02pj

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02pjf.html

.. _d02pj-py2-py-parameters:

**Parameters**
**icheck** : int
Indicates whether consistency checks on input arguments should be performed

:math:\mathrm{icheck} \neq 1

Don't perform checks on input arguments.

:math:\mathrm{icheck} = 1

Perform consistency checks on input arguments.

It is recommended to use :math:\mathrm{icheck} = 1 on the first call following a call to :meth:ivp_rk_interp_setup and to set :math:\mathrm{icheck} \neq 1 on subsequent calls within the last step to avoid the overhead of argument checking.

**n** : int
:math:n, the dimension of the system of ODEs being integrated.

**nwant** : int
Only the first :math:\mathrm{nwant} system components to be computed. This should be the same value as passed to :meth:ivp_rk_interp_setup when computing the interpolant.

**t** : float
:math:t, the value of the independent variable where a solution is desired. Although any value of :math:t can be supplied, accurate solutions can only be obtained for values in the range of the last time-step taken by :meth:ivp_rk_step_revcomm.

**ideriv** : int
:math:\mathrm{ideriv} = 0

Compute approximations to the first :math:\mathrm{nwant} components of the solution :math:y\left(t\right).

:math:\mathrm{ideriv} = 1

Compute approximations to the first :math:\mathrm{nwant} components of the first derivatives of the solution :math:y^{\prime }\left(t\right).

**comm** : dict, communication object, modified in place
Communication structure.

This argument must have been initialized by a prior call to :meth:ivp_rkts_setup.

**Returns**
**sol** : float, ndarray, shape :math:\left(\mathrm{nwant}\right)
:math:\mathrm{ideriv} = 0

The first :math:\mathrm{nwant} components of the solution :math:y\left(t\right).

:math:\mathrm{ideriv} = 1

The first :math:\mathrm{nwant} components of the first derivatives of the solution :math:y^{\prime }\left(t\right).

.. _d02pj-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
The previous call to the interpolation setup function returned an error.

(errno :math:1)
You cannot call this function before you have called the interpolation setup.

(errno :math:1)
On entry, :math:\mathrm{n} = \langle\mathit{\boldsymbol{value}}\rangle, but the value passed to the setup routine was :math:\mathrm{n} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{ideriv} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{ideriv} = 0 or :math:1.

(errno :math:1)
On entry, :math:\mathrm{nwant} = \langle\mathit{\boldsymbol{value}}\rangle, but on interpolation setup :math:\mathrm{nwant} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{nwant} must be unchanged from setup.

(errno :math:1)
On entry, :math:\textit{lwcomm} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{nwant} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: for :math:{\textit{method}} = -3 or :math:3, :math:\textit{lwcomm}\geq 8\times \mathrm{nwant}.

(errno :math:1)
On entry, :math:\textit{lwcomm} = \langle\mathit{\boldsymbol{value}}\rangle, :math:\mathrm{n} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{nwant} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: for :math:{\textit{method}} = -2 or :math:2, :math:\textit{lwcomm}\geq \mathrm{n}+\mathrm{max}\left(\mathrm{n}, {5\times \mathrm{nwant}}\right).

(errno :math:1)
On entry, :math:\textit{lwcomm} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: for :math:{\textit{method}} = -1 or :math:1, :math:\textit{lwcomm}\geq 1.

(errno :math:1)
On entry, a previous call to the setup function has not been made or the communication arrays have become corrupted, or a catastrophic error has already been detected elsewhere.

You cannot continue integrating the problem.

.. _d02pj-py2-py-notes:

**Notes**
When integrating using the reverse communication Runge--Kutta integrator :meth:ivp_rk_step_revcomm, the solution or its derivatives can be obtained inexpensively between steps by interpolation. :meth:ivp_rk_interp_setup is called after a step by :meth:ivp_rk_step_revcomm from a previous value of :math:t (:math:= t_{{k-1}}) to its current value, :math:t = t_k (i.e., a :math:k\ th successful time-step has been taken). ivp_rk_interp_eval can then be called to evaluate interpolated approximations of the function or its derivatives at any value of :math:t in the interval :math:\left(t_{{k-1}}, t_k\right).

.. _d02pj-py2-py-references:

**References**
Brankin, R W, Gladwell, I and Shampine, L F, 1991, RKSUITE: A suite of Runge--Kutta codes for the initial value problems for ODEs, SoftReport 91-S1, Southern Methodist University
"""
raise NotImplementedError

[docs]def ivp_rkts_setup(tstart, tend, yinit, tol, thresh, method, hstart=0.0):
r"""
ivp_rkts_setup is a setup function which must be called prior to the first call of either of the integration functions :meth:ivp_rkts_range, :meth:ivp_rkts_onestep and :meth:ivp_rk_step_revcomm.

.. _d02pq-py2-py-doc:

For full information please refer to the NAG Library document for d02pq

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02pqf.html

.. _d02pq-py2-py-parameters:

**Parameters**
**tstart** : float
The initial value of the independent variable, :math:t_0.

**tend** : float
The final value of the independent variable, :math:t_f, at which the solution is required. :math:\mathrm{tstart} and :math:\mathrm{tend} together determine the direction of integration.

**yinit** : float, array-like, shape :math:\left(n\right)
:math:y_0, the initial values of the solution, :math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,n.

**tol** : float
A relative error tolerance. The actual tolerance used is :math:\mathrm{max}\left({10\times \text{machine precision}}, \mathrm{min}\left(\mathrm{tol}, 0.01\right)\right); that is, the minimum tolerance is set at :math:10 times machine precision and the maximum tolerance is set at :math:0.01.

**thresh** : float, array-like, shape :math:\left(n\right)
A vector of thresholds. For the :math:i\ th component, the actual threshold used is :math:\mathrm{max}\left(\sqrt{\textbf{safe range}}, \mathrm{thresh}[i-1]\right), where :math:\textbf{safe range} is the value returned by :meth:machine.real_safe <naginterfaces.library.machine.real_safe>.

**method** : int
The Runge--Kutta method to be used.

:math:\mathrm{method} = 1 or :math:-1

A :math:2{}\left(3\right) pair is used.

:math:\mathrm{method} = 2 or :math:-2

A :math:4{}\left(5\right) pair is used.

:math:\mathrm{method} = 3 or :math:-3

A :math:7{}\left(8\right) pair is used.

**hstart** : float, optional
A value for the size of the first step in the integration to be attempted. The absolute value of :math:\mathrm{hstart} is used with the direction being determined by :math:\mathrm{tstart} and :math:\mathrm{tend}. The actual first step taken by the integrator may be different to :math:\mathrm{hstart} if the underlying algorithm determines that :math:\mathrm{hstart} is unsuitable. If :math:\mathrm{hstart} = 0.0 then the size of the first step is computed automatically.

**Returns**
**comm** : dict, communication object
Communication structure.

.. _d02pq-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:n = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:n\geq 1.

(errno :math:1)
On entry, :math:\mathrm{tstart} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{tstart}\neq \mathrm{tend}.

(errno :math:1)
On entry, :math:\mathrm{tstart} is too close to :math:\mathrm{tend}.

:math:\left\lvert \mathrm{tstart}-\mathrm{tend}\right\rvert = \langle\mathit{\boldsymbol{value}}\rangle, but this quantity should be at least :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{method} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{method} = -3, :math:-2, :math:-1, :math:1, :math:2 or :math:3.

(errno :math:1)
On entry, too much workspace required.

Workspace provided was :math:\langle\mathit{\boldsymbol{value}}\rangle, workspace required is :math:\langle\mathit{\boldsymbol{value}}\rangle.

.. _d02pq-py2-py-notes:

**Notes**
ivp_rkts_setup and its associated functions (:meth:ivp_rkts_range, :meth:ivp_rkts_onestep, :meth:ivp_rk_step_revcomm, :meth:ivp_rk_interp_setup, :meth:ivp_rk_interp_eval, :meth:ivp_rkts_reset_tend, :meth:ivp_rkts_interp, :meth:ivp_rkts_diag and :meth:ivp_rkts_errass) solve the initial value problem for a first-order system of ordinary differential equations.
The functions, based on Runge--Kutta methods and derived from RKSUITE (see Brankin et al. (1991)), integrate

.. math::
y^{\prime } = f\left(t, y\right)\quad \text{ given }\quad y\left(t_0\right) = y_0

where :math:y is the vector of :math:n solution components and :math:t is the independent variable.

The integration proceeds by steps from the initial point :math:t_0 towards the final point :math:t_f.
An approximate solution :math:y is computed at each step.
For each component :math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,n, the error made in the step, i.e., the local error, is estimated.
The step size is chosen automatically so that the integration will proceed efficiently while keeping this local error estimate smaller than a tolerance that you specify by means of arguments :math:\mathrm{tol} and :math:\mathrm{thresh}.

:meth:ivp_rkts_range can be used to solve the 'usual task', namely integrating the system of differential equations to obtain answers at points you specify. :meth:ivp_rkts_onestep is used for more 'complicated' tasks where :math:f\left(t, y\right) can readily be coded within a function argument and high-order interpolation is not required. :meth:ivp_rk_step_revcomm is used for the most 'complicated' tasks where :math:f\left(t, y\right) is best evaluated outside the integrator or where high-order interpolation is required.

You should consider carefully how you want the local error to be controlled.
Essentially the code uses relative local error control, with :math:\mathrm{tol} being the desired relative accuracy.
For reliable computation, the code must work with approximate solutions that have some correct digits, so there is an upper bound on the value used for :math:\mathrm{tol}.
It is impossible to compute a numerical solution that is more accurate than the correctly rounded value of the true solution, so you are not allowed to specify :math:\mathrm{tol} too small for the precision you are using.
The magnitude of the local error in :math:y_i on any step will not be greater than :math:\mathrm{tol}\times \mathrm{max}\left(\mu_i, {\mathrm{thresh}[i-1]}\right) where :math:\mu_i is an average magnitude of :math:y_i over the step.
If :math:\mathrm{thresh}[i-1] is smaller than the current value of :math:\mu_i, this is a relative error test and :math:\mathrm{tol} indicates how many significant digits you want in :math:y_i.
If :math:\mathrm{thresh}[i-1] is larger than the current value of :math:\mu_i, this is an absolute error test with tolerance :math:\mathrm{tol}\times \mathrm{thresh}[i-1].
Relative error control is the recommended mode of operation, but pure relative error control, :math:\mathrm{thresh}[i-1] = 0.0, is not permitted.
See Further Comments <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02pqf.html#fcomments>__ for further information about error control.

:meth:ivp_rkts_range, :meth:ivp_rkts_onestep and :meth:ivp_rk_step_revcomm control local error rather than the true (global) error, the difference between the numerical and true solution.
Control of the local error controls the true error indirectly.
Roughly speaking, the code produces a solution that satisfies the differential equation with a discrepancy bounded in magnitude by the error tolerance.
What this implies about how close the numerical solution is to the true solution depends on the stability of the problem.
Most practical problems are at least moderately stable, and the true error is then comparable to the error tolerance.
To judge the accuracy of the numerical solution, you could reduce :math:\mathrm{tol} substantially, e.g., use :math:0.1\times \mathrm{tol}, and solve the problem again.
This will usually result in a rather more accurate solution, and the true error of the first integration can be estimated by comparison.
Alternatively, a global error assessment can be computed automatically using the argument :math:\mathrm{method}. Because indirect control of the true error by controlling the local error is generally satisfactory and because both ways of assessing true errors cost twice, or more, the cost of the integration itself, such assessments are used mostly for spot checks, selecting appropriate tolerances for local error control, and exploratory computations.

:meth:ivp_rkts_range, :meth:ivp_rkts_onestep and :meth:ivp_rk_step_revcomm each implement three Runge--Kutta formula pairs, and you must select one for the integration.
The best choice for :math:\mathrm{method} depends on the problem.
The order of accuracy is :math:3, :math:5 and :math:8 respectively.
As a rule, the smaller :math:\mathrm{tol} is, the larger you should take the order of the :math:\mathrm{method}.
If the components :math:\mathrm{thresh} are small enough that you are effectively specifying relative error control, experience suggests

+-----------------------+----------------------------------+
|:math:\mathrm{tol}   |efficient :math:\mathrm{method} |
+=======================+==================================+
|:math:10^{-2}-10^{-4}|order :math:2 and :math:3 pair|
+-----------------------+----------------------------------+
|:math:10^{-3}-10^{-6}|order :math:4 and :math:5 pair|
+-----------------------+----------------------------------+
|:math:10^{-5}-{}     |order :math:7 and :math:8 pair|
+-----------------------+----------------------------------+

The overlap in the ranges of tolerances appropriate for a given :math:\mathrm{method} merely reflects the dependence of efficiency on the problem being solved.
Making :math:\mathrm{tol} smaller will normally make the integration more expensive.
However, in the range of tolerances appropriate to a :math:\mathrm{method}, the increase in cost is modest.
There are situations for which one :math:\mathrm{method}, or even this kind of code, is a poor choice.
You should not specify a very small value for :math:\mathrm{thresh}[i-1], when the :math:i\ th solution component might vanish.
In particular, you should not do this when :math:y_i = 0.0.
If you do, the code will have to work hard with any value for :math:\mathrm{method} to compute significant digits, but the lowest order method is a particularly poor choice in this situation.
All three methods are inefficient when the problem is 'stiff'.
If it is only mildly stiff, you can solve it with acceptable efficiency with the order :math:2 and :math:3 pair, but if it is moderately or very stiff, a code designed specifically for such problems will be much more efficient.
The higher the order the more smoothness is required of the solution in order for the method to be efficient.

When assessment of the true (global) error is requested, this error assessment is updated at each step.
Its value can be obtained at any time by a call to :meth:ivp_rkts_errass.
The code monitors the computation of the global error assessment and reports any doubts it has about the reliability of the results.
The assessment scheme requires some smoothness of :math:f\left(t, y\right), and it can be deceived if :math:f is insufficiently smooth.
At very crude tolerances the numerical solution can become so inaccurate that it is impossible to continue assessing the accuracy reliably.
At very stringent tolerances the effects of finite precision arithmetic can make it impossible to assess the accuracy reliably.
The cost of this is roughly twice the cost of the integration itself with the 5th and 8th order methods, and three times with the 3rd order method.

The first step of the integration is critical because it sets the scale of the problem.
The integrator will find a starting step size automatically if you set the argument :math:\mathrm{hstart} to :math:0.0.
Automatic selection of the first step is so effective that you should normally use it.
Nevertheless, you might want to specify a trial value for the first step to be certain that the code recognizes the scale on which phenomena occur near the initial point.
Also, automatic computation of the first step size involves some cost, so supplying a good value for this step size will result in a less expensive start.
If you are confident that you have a good value, provide it via the argument :math:\mathrm{hstart}.

.. _d02pq-py2-py-references:

**References**
Brankin, R W, Gladwell, I and Shampine, L F, 1991, RKSUITE: A suite of Runge--Kutta codes for the initial value problems for ODEs, SoftReport 91-S1, Southern Methodist University
"""
raise NotImplementedError

[docs]def ivp_rkts_reset_tend(tendnu, comm):
r"""
ivp_rkts_reset_tend resets the end point in an integration performed by :meth:ivp_rkts_onestep and :meth:ivp_rk_step_revcomm.

.. _d02pr-py2-py-doc:

For full information please refer to the NAG Library document for d02pr

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02prf.html

.. _d02pr-py2-py-parameters:

**Parameters**
**tendnu** : float
The new value for :math:t_f.

**comm** : dict, communication object, modified in place
Communication structure.

This argument must have been initialized by a prior call to :meth:ivp_rkts_setup.

.. _d02pr-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
You cannot call this function before you have called the setup function.

(errno :math:1)
You cannot call this function after the integrator has returned an error.

(errno :math:1)
You cannot call this function before you have called the step integrator.

(errno :math:1)
You cannot call this function when the range integrator has been used.

(errno :math:1)
On entry, a previous call to the setup function has not been made or the communication arrays have become corrupted, or a catastrophic error has already been detected elsewhere. You cannot continue integrating the problem.

(errno :math:1)
On entry, :math:\mathrm{tendnu} is not beyond :math:\textit{tnow} (step integrator) in the direction of integration.

The direction is positive, :math:\mathrm{tendnu} = \langle\mathit{\boldsymbol{value}}\rangle and :math:{\textit{tnow}} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{tendnu} is not beyond :math:\textit{tnow} (step integrator) in the direction of integration.

The direction is negative, :math:\mathrm{tendnu} = \langle\mathit{\boldsymbol{value}}\rangle and :math:{\textit{tnow}} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{tendnu} is too close to :math:\textit{tnow} (step integrator). Their difference is :math:\langle\mathit{\boldsymbol{value}}\rangle, but this quantity must be at least :math:\langle\mathit{\boldsymbol{value}}\rangle.

.. _d02pr-py2-py-notes:

**Notes**
ivp_rkts_reset_tend and its associated functions (:meth:ivp_rkts_setup, :meth:ivp_rkts_onestep, :meth:ivp_rk_step_revcomm, :meth:ivp_rk_interp_setup, :meth:ivp_rk_interp_eval, :meth:ivp_rkts_interp, :meth:ivp_rkts_diag and :meth:ivp_rkts_errass) solve the initial value problem for a first-order system of ordinary differential equations.
The functions, based on Runge--Kutta methods and derived from RKSUITE (see Brankin et al. (1991)), integrate

.. math::
y^{\prime } = f\left(t, y\right)\quad \text{ given }\quad y\left(t_0\right) = y_0

where :math:y is the vector of :math:n solution components and :math:t is the independent variable.

ivp_rkts_reset_tend is used to reset the final value of the independent variable, :math:t_f, when the integration is already underway.
It can be used to extend or reduce the range of integration.
The new value must be beyond the current value of the independent variable (as returned in :math:\textit{tnow} by :meth:ivp_rkts_onestep or :meth:ivp_rk_step_revcomm) in the current direction of integration.
It is much more efficient to use ivp_rkts_reset_tend for this purpose than to use :meth:ivp_rkts_setup which involves the overhead of a complete restart of the integration.

If you want to change the direction of integration then you must restart by a call to :meth:ivp_rkts_setup.

.. _d02pr-py2-py-references:

**References**
Brankin, R W, Gladwell, I and Shampine, L F, 1991, RKSUITE: A suite of Runge--Kutta codes for the initial value problems for ODEs, SoftReport 91-S1, Southern Methodist University
"""
raise NotImplementedError

[docs]def ivp_rkts_interp(n, twant, ideriv, nwant, f, comm, data=None):
r"""
ivp_rkts_interp computes the solution of a system of ordinary differential equations using interpolation anywhere on an integration step taken by :meth:ivp_rkts_onestep.

.. _d02ps-py2-py-doc:

For full information please refer to the NAG Library document for d02ps

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02psf.html

.. _d02ps-py2-py-parameters:

**Parameters**
**n** : int
:math:n, the number of ordinary differential equations in the system to be solved by the integration function.

**twant** : float
:math:t, the value of the independent variable where a solution is desired.

**ideriv** : int
Determines whether the solution and/or its first derivative are to be computed

:math:\mathrm{ideriv} = 0

compute approximate solution.

:math:\mathrm{ideriv} = 1

compute approximate first derivative.

:math:\mathrm{ideriv} = 2

compute approximate solution and first derivative.

**nwant** : int
The number of components of the solution to be computed. The first :math:\mathrm{nwant} components are evaluated.

**f** : callable yp = f(t, y, data=None)
:math:\mathrm{f} must evaluate the functions :math:f_i (that is the first derivatives :math:y_i^{\prime }) for given values of the arguments :math:t,y_i.

It must be the same procedure as supplied to :meth:ivp_rkts_onestep.

**Parameters**
**t** : float
:math:t, the current value of the independent variable.

**y** : float, ndarray, shape :math:\left(n\right)
The current values of the dependent variables, :math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**yp** : float, array-like, shape :math:\left(n\right)
The values of :math:f_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}.

**comm** : dict, communication object, modified in place
Communication structure.

This argument must have been initialized by a prior call to :meth:ivp_rkts_setup.

**data** : arbitrary, optional
User-communication data for callback functions.

**Returns**
**ywant** : float, ndarray, shape :math:\left(\mathrm{nwant}\right)
An approximation to the first :math:\mathrm{nwant} components of the solution at :math:\mathrm{twant} if :math:\mathrm{ideriv} = 0 or :math:2. Otherwise :math:\mathrm{ywant} is not defined.

**ypwant** : float, ndarray, shape :math:\left(\mathrm{nwant}\right)
An approximation to the first :math:\mathrm{nwant} components of the first derivative at :math:\mathrm{twant} if :math:\mathrm{ideriv} = 1 or :math:2. Otherwise :math:\mathrm{ypwant} is not defined.

.. _d02ps-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
You cannot call this function after the integrator has returned an error.

(errno :math:1)
You cannot call this function before you have called the step integrator.

(errno :math:1)
You cannot call this function when you have specified, in the setup function, that the range integrator will be used.

(errno :math:1)
:math:{\textit{method}} = -3 or :math:3 in setup, but interpolation is not available for this method. Either use :math:{\textit{method}} = -2 or :math:2 in setup or use reset function to force the integrator to step to particular points.

(errno :math:1)
On entry, :math:\mathrm{n} = \langle\mathit{\boldsymbol{value}}\rangle, but the value passed to the setup function was :math:{\textit{n}} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{ideriv} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{ideriv} = 0, :math:1 or :math:2.

(errno :math:1)
On entry, :math:\mathrm{nwant} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{n} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:1\leq \mathrm{nwant}\leq \mathrm{n}.

(errno :math:1)
On entry, a previous call to the setup function has not been made or the communication arrays have become corrupted, or a catastrophic error has already been detected elsewhere.

You cannot continue integrating the problem.

.. _d02ps-py2-py-notes:

**Notes**
ivp_rkts_interp and its associated functions (:meth:ivp_rkts_setup, :meth:ivp_rkts_onestep, :meth:ivp_rkts_reset_tend, :meth:ivp_rkts_diag and :meth:ivp_rkts_errass) solve the initial value problem for a first-order system of ordinary differential equations.
The functions, based on Runge--Kutta methods and derived from RKSUITE (see Brankin et al. (1991)), integrate

.. math::
y^{\prime } = f\left(t, y\right)\quad \text{ given }\quad y\left(t_0\right) = y_0

where :math:y is the vector of :math:\textit{n} solution components and :math:t is the independent variable.

:meth:ivp_rkts_onestep computes the solution at the end of an integration step.
Using the information computed on that step ivp_rkts_interp computes the solution by interpolation at any point on that step.
It cannot be used if :math:{\textit{method}} = 3 or :math:-3 was specified in the call to setup function :meth:ivp_rkts_setup.

.. _d02ps-py2-py-references:

**References**
Brankin, R W, Gladwell, I and Shampine, L F, 1991, RKSUITE: A suite of Runge--Kutta codes for the initial value problems for ODEs, SoftReport 91-S1, Southern Methodist University
"""
raise NotImplementedError

[docs]def ivp_rkts_diag(comm):
r"""
ivp_rkts_diag provides details about an integration performed by either :meth:ivp_rkts_range, :meth:ivp_rkts_onestep or :meth:ivp_rk_step_revcomm.

.. _d02pt-py2-py-doc:

For full information please refer to the NAG Library document for d02pt

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02ptf.html

.. _d02pt-py2-py-parameters:

**Parameters**
**comm** : dict, communication object, modified in place
Communication structure.

This argument must have been initialized by prior calls to :meth:ivp_rkts_setup and one of :meth:ivp_rkts_range, :meth:ivp_rkts_onestep or :meth:ivp_rk_step_revcomm.

**Returns**
**fevals** : int
The total number of evaluations of :math:f used in the integration so far; this includes evaluations of :math:f required for the secondary integration necessary if :meth:ivp_rkts_setup had previously been called with :math:{\textit{method}} > 0.

**stepcost** : int
The cost in terms of number of evaluations of :math:f of a typical step with the method being used for the integration. The method is specified by the argument :math:\textit{method} in a prior call to :meth:ivp_rkts_setup.

**waste** : float
The number of attempted steps that failed to meet the local error requirement divided by the total number of steps attempted so far in the integration. A 'large' fraction indicates that the integrator is having trouble with the problem being solved. This can happen when the problem is 'stiff' and also when the solution has discontinuities in a low-order derivative.

**stepsok** : int
The number of accepted steps.

**hnext** : float
The step size the integrator will attempt to use for the next step.

.. _d02pt-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
You cannot call this function before you have called the integrator.

(errno :math:1)
You have already made one call to this function after the integrator could not achieve specified accuracy.

You cannot call this function again.

(errno :math:1)
On entry, a previous call to the setup function has not been made or the communication arrays have become corrupted, or a catastrophic error has already been detected elsewhere.

You cannot continue integrating the problem.

.. _d02pt-py2-py-notes:

**Notes**
ivp_rkts_diag and its associated functions (:meth:ivp_rkts_range, :meth:ivp_rkts_onestep, :meth:ivp_rk_step_revcomm, :meth:ivp_rk_interp_setup, :meth:ivp_rk_interp_eval, :meth:ivp_rkts_setup, :meth:ivp_rkts_reset_tend, :meth:ivp_rkts_interp and :meth:ivp_rkts_errass) solve the initial value problem for a first-order system of ordinary differential equations.
The functions, based on Runge--Kutta methods and derived from RKSUITE (see Brankin et al. (1991)), integrate

.. math::
y^{\prime } = f\left(t, y\right)\quad \text{ given }\quad y\left(t_0\right) = y_0

where :math:y is the vector of :math:n solution components and :math:t is the independent variable.

After a call to :meth:ivp_rkts_range, :meth:ivp_rkts_onestep or :meth:ivp_rk_step_revcomm, ivp_rkts_diag can be called to obtain information about the cost of the integration and the size of the next step.

.. _d02pt-py2-py-references:

**References**
Brankin, R W, Gladwell, I and Shampine, L F, 1991, RKSUITE: A suite of Runge--Kutta codes for the initial value problems for ODEs, SoftReport 91-S1, Southern Methodist University
"""
raise NotImplementedError

[docs]def ivp_rkts_errass(n, comm):
r"""
ivp_rkts_errass provides details about global error assessment computed during an integration with either :meth:ivp_rkts_range, :meth:ivp_rkts_onestep or :meth:ivp_rk_step_revcomm.

.. _d02pu-py2-py-doc:

For full information please refer to the NAG Library document for d02pu

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02puf.html

.. _d02pu-py2-py-parameters:

**Parameters**
**n** : int
:math:n, the number of ordinary differential equations in the system to be solved by the integration function.

**comm** : dict, communication object, modified in place
Communication structure.

This argument must have been initialized by a prior call to :meth:ivp_rkts_setup.

**Returns**
**rmserr** : float, ndarray, shape :math:\left(\mathrm{n}\right)
:math:\mathrm{rmserr}[\textit{i}-1] approximates the RMS average of the true error of the numerical solution for the :math:\textit{i}\ th solution component, for :math:\textit{i} = 1,2,\ldots,\textit{n}. The average is taken over all steps from the beginning of the integration to the current integration point.

**errmax** : float
The maximum weighted approximate true error taken over all solution components and all steps.

**terrmx** : float
The first value of the independent variable where an approximate true error attains the maximum value, :math:\mathrm{errmax}.

.. _d02pu-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:\mathrm{n} = \langle\mathit{\boldsymbol{value}}\rangle, but the value passed to the setup function was :math:{\textit{n}} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
No error assessment is available since the integrator has not actually taken any successful steps.

(errno :math:1)
No error assessment is available since you did not ask for it in your call to the setup function.

(errno :math:1)
You cannot call this function before you have called the integrator.

(errno :math:1)
You have already made one call to this function after the integrator could not achieve specified accuracy.

You cannot call this function again.

(errno :math:1)
On entry, a previous call to the setup function has not been made or the communication arrays have become corrupted, or a catastrophic error has already been detected elsewhere.

You cannot continue integrating the problem.

.. _d02pu-py2-py-notes:

**Notes**
ivp_rkts_errass and its associated functions (:meth:ivp_rkts_range, :meth:ivp_rkts_onestep, :meth:ivp_rk_step_revcomm, :meth:ivp_rk_interp_setup, :meth:ivp_rk_interp_eval, :meth:ivp_rkts_setup, :meth:ivp_rkts_reset_tend, :meth:ivp_rkts_interp and :meth:ivp_rkts_diag) solve the initial value problem for a first-order system of ordinary differential equations.
The functions, based on Runge--Kutta methods and derived from RKSUITE (see Brankin et al. (1991)), integrate

.. math::
y^{\prime } = f\left(t, y\right)\quad \text{ given }\quad y\left(t_0\right) = y_0

where :math:y is the vector of :math:\textit{n} solution components and :math:t is the independent variable.

After a call to :meth:ivp_rkts_range, :meth:ivp_rkts_onestep or :meth:ivp_rk_step_revcomm, ivp_rkts_errass can be called for information about error assessment, if this assessment was specified in the setup function :meth:ivp_rkts_setup.
A more accurate 'true' solution :math:\hat{y} is computed in a secondary integration.
The error is measured as specified in :meth:ivp_rkts_setup for local error control.
At each step in the primary integration, an average magnitude :math:\mu_i of component :math:y_i is computed, and the error in the component is

.. math::
\frac{{\left\lvert y_i-\hat{y}_i\right\rvert }}{{\mathrm{max}\left(\mu_i,{\textit{thresh}}[i-1]\right)}}\text{.}

It is difficult to estimate reliably the true error at a single point.
For this reason the RMS (root-mean-square) average of the estimated global error in each solution component is computed.
This average is taken over all steps from the beginning of the integration through to the current integration point.
If all has gone well, the average errors reported will be comparable to :math:\textit{tol} (see :meth:ivp_rkts_setup).
The maximum error seen in any component in the integration so far and the point where the maximum error first occurred are also reported.

.. _d02pu-py2-py-references:

**References**
Brankin, R W, Gladwell, I and Shampine, L F, 1991, RKSUITE: A suite of Runge--Kutta codes for the initial value problems for ODEs, SoftReport 91-S1, Southern Methodist University
"""
raise NotImplementedError

[docs]def ivp_adams_roots(fcn, t, y, tout, neqg, comm, g=None, data=None):
r"""
ivp_adams_roots is a function for integrating a non-stiff system of first-order ordinary differential equations using a variable-order variable-step Adams' method.
A root-finding facility is provided.

.. _d02qf-py2-py-doc:

For full information please refer to the NAG Library document for d02qf

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02qff.html

.. _d02qf-py2-py-parameters:

**Parameters**
**fcn** : callable f = fcn(x, y, data=None)
:math:\mathrm{fcn} must evaluate the functions :math:f_i (that is the first derivatives :math:y_i^{\prime }) for given values of its arguments :math:x, :math:y_1,y_2,\ldots,y_{\textit{neqf}}.

**Parameters**
**x** : float
The current value of the argument :math:x.

**y** : float, ndarray, shape :math:\left(\textit{neqf}\right)
:math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{neqf}, the current value of the argument.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**f** : float, array-like, shape :math:\left(\textit{neqf}\right)
The value of :math:f_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{neqf}.

**t** : float
After a call to :meth:ivp_adams_setup with :math:{\textit{statef}} = \texttt{'S'} (i.e., an initial entry), :math:\mathrm{t} must be set to the initial value of the independent variable :math:x.

**y** : float, array-like, shape :math:\left(\textit{neqf}\right)
The initial values of the solution :math:y_1,y_2,\ldots,y_{\textit{neqf}}.

**tout** : float
The next value of :math:x at which a computed solution is required. For the initial :math:\mathrm{t}, the input value of :math:\mathrm{tout} is used to determine the direction of integration. Integration is permitted in either direction. If :math:\mathrm{tout} = \mathrm{t} on exit, :math:\mathrm{tout} must be reset beyond :math:\mathrm{t} **in the direction of integration**, before any continuation call.

**neqg** : int
The number of event functions which you are defining for root-finding. If root-finding is not required the value for :math:\mathrm{neqg} must be :math:\text{}\leq 0. Otherwise it must be the same argument :math:\mathrm{neqg} used in the prior call to :meth:ivp_adams_setup.

**comm** : dict, communication object, modified in place
Communication structure.

This argument must have been initialized by a prior call to :meth:ivp_adams_setup.

**g** : None or callable retval = g(x, y, yp, k, data=None), optional
Note: if this argument is **None** then a NAG-supplied facility will be used.

:math:\mathrm{g} must evaluate a given component of :math:g\left(x, y, {y^{\prime }}\right) at a specified point.

If root-finding is not required the actual argument for :math:\mathrm{g} must be **None**.

**Parameters**
**x** : float
The current value of the independent variable.

**y** : float, ndarray, shape :math:\left(\textit{neqf}\right)
The current values of the dependent variables.

**yp** : float, ndarray, shape :math:\left(\textit{neqf}\right)
The current values of the derivatives of the dependent variables.

**k** : int
The component of :math:g which must be evaluated.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**retval** : float
The value of the component of :math:g\left(x, y, {y^{\prime }}\right) at the specified point.

**data** : arbitrary, optional
User-communication data for callback functions.

**Returns**
**t** : float
The value of :math:x at which :math:y has been computed. This may be an intermediate output point, a root, :math:\mathrm{tout} or a point at which an error has occurred. If the integration is to be continued, possibly with a new value for :math:\mathrm{tout}, :math:\mathrm{t} must not be changed.

**y** : float, ndarray, shape :math:\left(\textit{neqf}\right)
The computed values of the solution at the exit value of :math:\mathrm{t}. If the integration is to be continued, possibly with a new value for :math:\mathrm{tout}, these values must not be changed.

**root** : bool
If root-finding was required (:math:\mathrm{neqg} > 0 on entry), :math:\mathrm{root} specifies whether or not the output value of the argument :math:\mathrm{t} is a root of one of the event functions. If :math:\mathrm{root} = \mathbf{False}, no root was detected, whereas :math:\mathrm{root} = \mathbf{True} indicates a root and you should make a call to :meth:ivp_adams_rootdiag for further information.

If root-finding was not required (:math:\mathrm{neqg} = 0 on entry), then on exit :math:\mathrm{root} = \mathbf{False}.

.. _d02qf-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
The value of :math:\mathrm{tout}, :math:\langle\mathit{\boldsymbol{value}}\rangle, indicates a change in the integration direction. This is not permitted on a continuation call.

(errno :math:1)
The value of :math:\mathrm{t} has been changed from :math:\langle\mathit{\boldsymbol{value}}\rangle to :math:\langle\mathit{\boldsymbol{value}}\rangle.

This is not permitted on a continuation call.

(errno :math:1)
On entry, :math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle but :math:{\textit{crit}} = \mathbf{True} in :meth:ivp_adams_setup.

Integration cannot be attempted beyond :math:{\textit{tcrit}} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{tout} = \mathrm{t} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{neqg} = \langle\mathit{\boldsymbol{value}}\rangle and :math:{\textit{neqg}} = 0 in :meth:ivp_adams_setup.

Constraint: if :math:\mathrm{neqg}\leq 0 then :math:\mathrm{neqg} = {\textit{neqg}} in :meth:ivp_adams_setup.

(errno :math:1)
On entry, :math:\mathrm{neqg} = \langle\mathit{\boldsymbol{value}}\rangle and :math:{\textit{neqg}} = 0 in :meth:ivp_adams_setup.

Constraint: if :math:\mathrm{neqg} > 0 then :math:{\textit{neqg}} > 0 in :meth:ivp_adams_setup.

(errno :math:1)
On entry, :math:\mathrm{neqg} = \langle\mathit{\boldsymbol{value}}\rangle and :math:{\textit{neqg}} = \langle\mathit{\boldsymbol{value}}\rangle in :meth:ivp_adams_setup.

Constraint: if :math:\mathrm{neqg}\leq 0 then :math:{\textit{neqg}}\leq 0 in :meth:ivp_adams_setup.

(errno :math:1)
On entry, :math:\textit{neqf} = \langle\mathit{\boldsymbol{value}}\rangle and :math:{\textit{neqf}} = \langle\mathit{\boldsymbol{value}}\rangle in :meth:ivp_adams_setup.

Constraint: :math:\textit{neqf} = {\textit{neqf}} in :meth:ivp_adams_setup.

(errno :math:1)
The call to setup function :meth:ivp_adams_setup produced an error.

(errno :math:1)
The setup function :meth:ivp_adams_setup has not been called.

(errno :math:3)
The error tolerances are too stringent.

(errno :math:7)
Two successive errors detected at the current value of :math:\mathrm{t}, :math:\langle\mathit{\boldsymbol{value}}\rangle.

**Warns**
**NagAlgorithmicWarning**
(errno :math:2)
The maximum number of steps has been attempted.

If integration is to be continued then the function may be called again and a further :math:\textit{maxstp} in :meth:ivp_adams_setup steps will be attempted.

(errno :math:4)
Error weight :math:i has become zero during the integration.

:math:{\textit{atol}}[i] = 0.0 in :meth:ivp_adams_setup but :math:\mathrm{y}[i] is now :math:0.0. Integration successful as far as :math:\mathrm{t}.

(errno :math:5)
The problem appears to be stiff.

(errno :math:6)
A change in sign of an event function has been detected but the root-finding process appears to have converged to a singular point of :math:\mathrm{t} rather than a root. Integration may be continued by calling the function again.

.. _d02qf-py2-py-notes:

**Notes**
In the NAG Library the traditional C interface for this routine uses a different algorithmic base. Please contact NAG if you have any questions about compatibility.

Given the initial values :math:x,y_1,y_2,\ldots,y_{\textit{neqf}} ivp_adams_roots integrates a non-stiff system of first-order differential equations of the type

.. math::
y_i^{\prime } = f_i\left(x, y_1, y_2, \ldots, y_{\textit{neqf}}\right)\text{, }\quad i = 1,2,\ldots,\textit{neqf}\text{,}

from :math:x = \mathrm{t} to :math:x = \mathrm{tout} using a variable-order variable-step Adams' method.
The system is defined by :math:\mathrm{fcn}, which evaluates :math:f_i in terms of :math:x and :math:y_1,y_2,\ldots,y_{\textit{neqf}}, and :math:y_1,y_2,\ldots,y_{\textit{neqf}} are supplied at :math:x = \mathrm{t}.
The function is capable of finding roots (values of :math:x) of prescribed event functions of the form

.. math::
g_j\left(x, y, {y^{\prime }}\right) = 0\text{, }\quad j = 1,2,\ldots,{\textit{neqg}}\text{.}

(See :meth:ivp_adams_setup for the specification of :math:\textit{neqg}.)

Each :math:g_j is considered to be independent of the others so that roots are sought of each :math:g_j individually.
The root reported by the function will be the first root encountered by any :math:g_j.
Two techniques for determining the presence of a root in an integration step are available: the sophisticated method described in Watts (1985) and a simplified method whereby sign changes in each :math:g_j are looked for at the ends of each integration step.
The event functions are defined by :math:\mathrm{g} supplied by you which evaluates :math:g_j in terms of :math:x,y_1,\ldots,y_{\textit{neqf}} and :math:y_1^{\prime },\ldots,y_{\textit{neqf}}^{\prime }.
In one-step mode the function returns an approximation to the solution at each integration point.
In interval mode this value is returned at the end of the integration range.
If a root is detected this approximation is given at the root.
You select the mode of operation, the error control, the root-finding technique and various optional inputs by a prior call to the setup function :meth:ivp_adams_setup.

For a description of the practical implementation of an Adams' formula see Shampine and Gordon (1975) and Shampine and Watts (1979).

.. _d02qf-py2-py-references:

**References**
Shampine, L F and Gordon, M K, 1975, Computer Solution of Ordinary Differential Equations -- The Initial Value Problem, W H Freeman & Co., San Francisco

Shampine, L F and Watts, H A, 1979, DEPAC -- design of a user oriented package of ODE solvers, Report SAND79-2374, Sandia National Laboratory

Watts, H A, 1985, RDEAM -- An Adams ODE code with root solving capability, Report SAND85-1595, Sandia National Laboratory
"""
raise NotImplementedError

[docs]def ivp_adams_roots_revcom(t, y, tout, neqg, irevcm, grvcm, kgrvcm, comm):
r"""
ivp_adams_roots_revcom is a reverse communication function for integrating a non-stiff system of first-order ordinary differential equations using a variable-order variable-step Adams' method.
A root-finding facility is provided.

.. _d02qg-py2-py-doc:

For full information please refer to the NAG Library document for d02qg

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02qgf.html

.. _d02qg-py2-py-parameters:

**Parameters**
**t** : float
On initial entry: that is after a call to :meth:ivp_adams_setup with :math:{\textit{statef}} = \texttt{'S'}, :math:\mathrm{t} must be set to the initial value of the independent variable :math:x.

**y** : float, ndarray, shape :math:\left(\textit{neqf}\right), modified in place
On initial entry: the initial values of the solution :math:y_1,y_2,\ldots,y_{\textit{neqf}}.

On final exit: the computed values of the solution at the exit value of :math:\mathrm{t}. If the integration is to be continued, possibly with a new value for :math:\mathrm{tout}, these values must not be changed.

**tout** : float
On initial entry: the next value of :math:x at which a computed solution is required. For the initial :math:\mathrm{t}, the input value of :math:\mathrm{tout} is used to determine the direction of integration. Integration is permitted in either direction. If :math:\mathrm{tout} = \mathrm{t} on exit, :math:\mathrm{tout} must be reset beyond :math:\mathrm{t} **in the direction of integration**, before any continuation call.

**neqg** : int
On initial entry: the number of event functions which you are defining for root-finding. If root-finding is not required the value for :math:\mathrm{neqg} must be :math:\text{}\leq 0. Otherwise it must be the same value as the argument :math:\mathrm{neqg} used in the prior call to :meth:ivp_adams_setup.

**irevcm** : int
On initial entry: must have the value :math:0.

**grvcm** : float
On initial entry: need not be set.

On intermediate entry: with :math:\mathrm{irevcm} = 9, :math:10, :math:11 or :math:12, :math:\mathrm{grvcm} must contain the value of :math:g_k\left(x, y, {y^{\prime }}\right), where :math:k is given by :math:\mathrm{kgrvcm}.

**kgrvcm** : int
On intermediate entry: with :math:\mathrm{irevcm} = 9, :math:10, :math:11 or :math:12, :math:\mathrm{kgrvcm} must remain unchanged from a previous call to ivp_adams_roots_revcom.

**comm** : dict, communication object, modified in place
Communication structure.

This argument must have been initialized by a prior call to :meth:ivp_adams_setup.

**Returns**
**t** : float
On final exit: the value of :math:x at which :math:y has been computed. This may be an intermediate output point, a root, :math:\mathrm{tout} or a point at which an error has occurred. If the integration is to be continued, possibly with a new value for :math:\mathrm{tout}, :math:\mathrm{t} must not be changed.

**root** : bool
On final exit: if root-finding was required (:math:\mathrm{neqg} > 0 on entry), :math:\mathrm{root} specifies whether or not the output value of the argument :math:\mathrm{t} is a root of one of the event functions. If :math:\mathrm{root} = \mathbf{False}, no root was detected, whereas :math:\mathrm{root} = \mathbf{True} indicates a root and you should make a call to :meth:ivp_adams_rootdiag for further information.

If root-finding was not required (:math:\mathrm{neqg} = 0 on entry), :math:\mathrm{root} = \mathbf{False}.

**irevcm** : int
On intermediate exit: specifies what action you must take before re-entering ivp_adams_roots_revcom **with** :math:\mathrm{irevcm} **unchanged**.

:math:\mathrm{irevcm} = 1, :math:2, :math:3, :math:4, :math:5, :math:6 or :math:7

Indicates that you must supply :math:y^{\prime } = f\left(x, y\right), where :math:x is given by :math:\mathrm{trvcm} and :math:y_{\textit{i}} is returned in :math:\mathrm{y}[\textit{i}-1], for :math:\textit{i} = 1,2,\ldots,\textit{neqf} when :math:\mathrm{yrvcm} = 0 and :math:\mathrm{comm}\ ['rwork'][\mathrm{yrvcm}+\textit{i}-2], for :math:\textit{i} = 1,2,\ldots,\textit{neqf} when :math:\mathrm{yrvcm}\neq 0. :math:y_{\textit{i}}^{\prime } should be placed in location :math:\mathrm{comm}\ ['rwork'][\mathrm{yprvcm}+\textit{i}-2], for :math:\textit{i} = 1,2,\ldots,\textit{neqf}.

:math:\mathrm{irevcm} = 8

Indicates that the current step was not successful due to error test failure. The only information supplied to you on this return is the current value of the independent variable :math:\mathrm{t}, as given by :math:\mathrm{trvcm}. No values must be changed before re-entering ivp_adams_roots_revcom. This facility enables you to determine the number of unsuccessful steps.

:math:\mathrm{irevcm} = 9, :math:10, :math:11 or :math:12

Indicates that you must supply :math:g_k\left(x, y, {y^{\prime }}\right), where :math:k is given by :math:\mathrm{kgrvcm}, :math:x is given by :math:\mathrm{trvcm}, :math:y_i is given by :math:\mathrm{y}[i-1] and :math:y_i^{\prime } is given by :math:\mathrm{comm}\ ['rwork'][\mathrm{yprvcm}-1+i-1]. The result :math:g_k should be placed in the variable :math:\mathrm{grvcm}.

On final exit: has the value :math:0, which indicates that an output point or root has been reached or an error has occurred (see :math:\textit{errno}).

**trvcm** : float
On intermediate exit: the current value of the independent variable.

**yrvcm** : int
On intermediate exit: with :math:\mathrm{irevcm} = 1, :math:2, :math:3, :math:4, :math:5, :math:6, :math:7, :math:9, :math:10, :math:11 or :math:12, :math:\mathrm{yrvcm} specifies the locations of the dependent variables :math:y for use in evaluating the differential system or the event functions.

:math:\mathrm{yrvcm} = 0

:math:y_{\textit{i}} is given by :math:\mathrm{y}[\textit{i}], for :math:\textit{i} = 1,2,\ldots,\textit{neqf}.

:math:\mathrm{yrvcm}\neq 0

:math:y_{\textit{i}} is given by :math:\mathrm{comm}\ ['rwork'][\mathrm{yrvcm}+\textit{i}-2], for :math:\textit{i} = 1,2,\ldots,\textit{neqf}.

**yprvcm** : int
On intermediate exit: with :math:\mathrm{irevcm} = 1, :math:2, :math:3, :math:4, :math:5, :math:6 or :math:7, :math:\mathrm{yprvcm} specifies the positions in :math:\mathrm{comm}\ ['rwork'] at which you should place the derivatives :math:y^{\prime }. :math:y_{\textit{i}}^{\prime } should be placed in location :math:\mathrm{comm}\ ['rwork'][\mathrm{yprvcm}+\textit{i}-2], for :math:\textit{i} = 1,2,\ldots,\textit{neqf}.

With :math:\mathrm{irevcm} = 9, :math:10, :math:11 or :math:12, :math:\mathrm{yprvcm} specifies the locations of the derivatives :math:y^{\prime } for use in evaluating the event functions. :math:y_{\textit{i}}^{\prime } is given by :math:\mathrm{comm}\ ['rwork'][\mathrm{yprvcm}+\textit{i}-2], for :math:\textit{i} = 1,2,\ldots,\textit{neqf}.

**kgrvcm** : int
On intermediate exit: with :math:\mathrm{irevcm} = 9, :math:10, :math:11 or :math:12, :math:\mathrm{kgrvcm} specifies which event function :math:g_k\left(x, y, {y^{\prime }}\right) you must evaluate.

.. _d02qg-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:\mathrm{irevcm} had an illegal value, :math:\langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
The value of :math:\mathrm{tout}, :math:\langle\mathit{\boldsymbol{value}}\rangle, indicates a change in the integration direction. This is not permitted on a continuation call.

(errno :math:1)
The value of :math:\mathrm{t} has been changed from :math:\langle\mathit{\boldsymbol{value}}\rangle to :math:\langle\mathit{\boldsymbol{value}}\rangle.

This is not permitted on a continuation call.

(errno :math:1)
On entry, :math:\mathrm{tout} = \langle\mathit{\boldsymbol{value}}\rangle but :math:{\textit{crit}} = \mathbf{True} in :meth:ivp_adams_setup.

Integration cannot be attempted beyond :math:{\textit{tcrit}} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{tout} = \mathrm{t} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{neqg} = \langle\mathit{\boldsymbol{value}}\rangle and :math:{\textit{neqg}} = 0 in :meth:ivp_adams_setup.

Constraint: if :math:\mathrm{neqg}\leq 0 then :math:\mathrm{neqg} = {\textit{neqg}} in :meth:ivp_adams_setup.

(errno :math:1)
On entry, :math:\mathrm{neqg} = \langle\mathit{\boldsymbol{value}}\rangle and :math:{\textit{neqg}} = 0 in :meth:ivp_adams_setup.

Constraint: if :math:\mathrm{neqg} > 0 then :math:{\textit{neqg}} > 0 in :meth:ivp_adams_setup.

(errno :math:1)
On entry, :math:\mathrm{neqg} = \langle\mathit{\boldsymbol{value}}\rangle and :math:{\textit{neqg}} = \langle\mathit{\boldsymbol{value}}\rangle in :meth:ivp_adams_setup.

Constraint: if :math:\mathrm{neqg}\leq 0 then :math:{\textit{neqg}}\leq 0 in :meth:ivp_adams_setup.

(errno :math:1)
On entry, :math:\textit{neqf} = \langle\mathit{\boldsymbol{value}}\rangle and :math:{\textit{neqf}} = \langle\mathit{\boldsymbol{value}}\rangle in :meth:ivp_adams_setup.

Constraint: :math:\textit{neqf} = {\textit{neqf}} in :meth:ivp_adams_setup.

(errno :math:1)
The call to setup function :meth:ivp_adams_setup produced an error.

(errno :math:1)
The setup function :meth:ivp_adams_setup has not been called.

(errno :math:3)
The error tolerances are too stringent.

(errno :math:7)
Two successive errors detected at the current value of :math:\mathrm{t}, :math:\langle\mathit{\boldsymbol{value}}\rangle.

**Warns**
**NagAlgorithmicWarning**
(errno :math:2)
The maximum number of steps has been attempted.

If integration is to be continued then the function may be called again and a further :math:\textit{maxstp} in :meth:ivp_adams_setup steps will be attempted.

(errno :math:4)
Error weight :math:i has become zero during the integration.

:math:{\textit{atol}}[i] = 0.0 in :meth:ivp_adams_setup but :math:\mathrm{y}[i] is now :math:0.0. Integration successful as far as :math:\mathrm{t}.

(errno :math:5)
The problem appears to be stiff.

(errno :math:6)
A change in sign of an event function has been detected but the root-finding process appears to have converged to a singular point of :math:\mathrm{t} rather than a root. Integration may be continued by calling the function again.

.. _d02qg-py2-py-notes:

**Notes**
No equivalent traditional C interface for this routine exists in the NAG Library.

Given the initial values :math:x,y_1,y_2,\ldots,y_{\textit{neqf}} ivp_adams_roots_revcom integrates a non-stiff system of first-order differential equations of the type

.. math::
y_i^{\prime } = f_i\left(x, y_1, y_2, \ldots, y_{\textit{neqf}}\right)\text{, }\quad i = 1,2,\ldots,\textit{neqf}\text{,}

from :math:x = \mathrm{t} to :math:x = \mathrm{tout} using a variable-order variable-step Adams' method.
You define the system by reverse communication, evaluating :math:f_i in terms of :math:x and :math:y_1,y_2,\ldots,y_{\textit{neqf}}, and :math:y_1,y_2,\ldots,y_{\textit{neqf}} are supplied at :math:x = \mathrm{t} by ivp_adams_roots_revcom.
The function is capable of finding roots (values of :math:x) of prescribed event functions of the form

.. math::
g_j\left(x, y, {y^{\prime }}\right) = 0\text{, }\quad j = 1,2,\ldots,\mathrm{neqg}\text{.}

Each :math:g_j is considered to be independent of the others so that roots are sought of each :math:g_j individually.
The root reported by the function will be the first root encountered by any :math:g_j.
Two techniques for determining the presence of a root in an integration step are available: the sophisticated method described in Watts (1985) and a simplified method whereby sign changes in each :math:g_j are looked for at the ends of each integration step.
You also define each :math:g_j by reverse communication.
In one-step mode the function returns an approximation to the solution at each integration point.
In interval mode this value is returned at the end of the integration range.
If a root is detected this approximation is given at the root.
You select the mode of operation, the error control, the root-finding technique and various optional inputs by a prior call to the setup function :meth:ivp_adams_setup.

For a description of the practical implementation of an Adams' formula see Shampine and Gordon (1975).

.. _d02qg-py2-py-references:

**References**
Shampine, L F and Gordon, M K, 1975, Computer Solution of Ordinary Differential Equations -- The Initial Value Problem, W H Freeman & Co., San Francisco

Shampine, L F and Watts, H A, 1979, DEPAC -- design of a user oriented package of ODE solvers, Report SAND79-2374, Sandia National Laboratory

Watts, H A, 1985, RDEAM -- An Adams ODE code with root solving capability, Report SAND85-1595, Sandia National Laboratory
"""
raise NotImplementedError

[docs]def ivp_adams_setup(statef, neqf, vectol, atol, rtol, onestp, crit, tcrit, hmax, maxstp, neqg, alterg, sophst, comm):
r"""
ivp_adams_setup is a setup function which must be called prior to the first call of either of the integrators :meth:ivp_adams_roots and :meth:ivp_adams_roots_revcom and may be called prior to any continuation call to these functions.

.. _d02qw-py2-py-doc:

For full information please refer to the NAG Library document for d02qw

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02qwf.html

.. _d02qw-py2-py-parameters:

**Parameters**
**statef** : str, length 1
Specifies whether the integration function (:meth:ivp_adams_roots or :meth:ivp_adams_roots_revcom) is to start a new system of ordinary differential equations, restart a system or continue with a system.

:math:\mathrm{statef} = \texttt{'S'}

Start integration with a new differential system.

:math:\mathrm{statef} = \texttt{'R'}

Restart integration with the current differential system.

:math:\mathrm{statef} = \texttt{'C'}

Continue integration with the current differential system.

**neqf** : int
The number of ordinary differential equations to be solved by the integration function. :math:\mathrm{neqf} must remain unchanged on subsequent calls to ivp_adams_setup with :math:\mathrm{statef} = \texttt{'C'} or :math:\texttt{'R'}.

**vectol** : bool
Specifies whether vector or scalar error control is to be employed for the local error test in the integration.

If :math:\mathrm{vectol} = \mathbf{True}, vector error control will be used and you must specify values of :math:\mathrm{rtol}[\textit{i}-1] and :math:\mathrm{atol}[\textit{i}-1], for :math:\textit{i} = 1,2,\ldots,\mathrm{neqf}.

Otherwise scalar error control will be used and you must specify values of just :math:\mathrm{rtol}[0] and :math:\mathrm{atol}[0].

The error test to be satisfied is of the form

.. math::
\sqrt{\sum_{{i = 1}}^{\mathrm{neqf}}\left(\frac{e_i}{w_i}\right)^2}\leq 1.0\text{.}

where :math:w_i is defined as follows:

+-----------------------+--------------------------------------------------------------------------------+
|:math:\mathrm{vectol}|:math:w_i                                                                     |
+=======================+================================================================================+
|:math:\mathbf{True}  |:math:\mathrm{rtol}[i-1]\times \left\lvert y_i\right\rvert +\mathrm{atol}[i-1]|
+-----------------------+--------------------------------------------------------------------------------+
|:math:\mathbf{False} |:math:\mathrm{rtol}[0]\times \left\lvert y_i\right\rvert +\mathrm{atol}[0]    |
+-----------------------+--------------------------------------------------------------------------------+

and :math:e_i is an estimate of the local error in :math:y_i, computed internally. :math:\mathrm{vectol} must remain unchanged on subsequent calls to ivp_adams_setup with :math:\mathrm{statef} = \texttt{'C'} or :math:\texttt{'R'}.

**atol** : float, array-like, shape :math:\left(\textit{latol}\right)
The absolute local error tolerance (see :math:\mathrm{vectol}).

**rtol** : float, array-like, shape :math:\left(\textit{lrtol}\right)
The relative local error tolerance (see :math:\mathrm{vectol}).

**onestp** : bool
The mode of operation of the integration function. If :math:\mathrm{onestp} = \mathbf{True}, the integration function will operate in one-step mode, that is it will return after each successful step. Otherwise the integration function will operate in interval mode, that is it will return at the end of the integration interval.

**crit** : bool
Specifies whether or not there is a value for the independent variable beyond which integration is not to be attempted. Setting :math:\mathrm{crit} = \mathbf{True} indicates that there is such a point, whereas :math:\mathrm{crit} = \mathbf{False} indicates that there is no such restriction.

**tcrit** : float
With :math:\mathrm{crit} = \mathbf{True}, :math:\mathrm{tcrit} must be set to a value of the independent variable beyond which integration is not to be attempted. Otherwise :math:\mathrm{tcrit} is not referenced.

**hmax** : float
If :math:\mathrm{hmax}\neq 0.0, a bound on the absolute step size during the integration is taken to be :math:\left\lvert \mathrm{hmax}\right\rvert.

If :math:\mathrm{hmax} = 0.0, no bound is assumed on the step size during the integration.

A bound may be required if there are features of the solution on very short ranges of integration which may be missed.

You should try :math:\mathrm{hmax} = 0.0 first.

**Note:** this argument only affects the step size if the option :math:\mathrm{crit} = \mathbf{True} is being used.

**maxstp** : int
A bound on the number of attempted steps in any one call to the integration function. If :math:\mathrm{maxstp}\leq 0 on entry, a value of :math:1000 is used.

**neqg** : int
Specifies whether or not root-finding is required in :meth:ivp_adams_roots or :meth:ivp_adams_roots_revcom.

:math:\mathrm{neqg}\leq 0

**No** root-finding is attempted.

:math:\mathrm{neqg} > 0

Root-finding is required and :math:\mathrm{neqg} event functions will be specified for the integration function.

**alterg** : bool
Specifies whether or not the event functions have been redefined. :math:\mathrm{alterg} need not be set if :math:\mathrm{statef} = \texttt{'S'}. On subsequent calls to ivp_adams_setup, if :math:\mathrm{neqg} has been set positive, :math:\mathrm{alterg} = \mathbf{False} specifies that the event functions remain unchanged, whereas :math:\mathrm{alterg} = \mathbf{True} specifies that the event functions have changed. Because of the expense in reinitializing the root searching procedure, :math:\mathrm{alterg} should be set to :math:\mathbf{True} only if the event functions really have been altered. :math:\mathrm{alterg} need not be set if the root-finding option is not used.

**sophst** : bool
The type of search technique to be used in the root-finding. If :math:\mathrm{sophst} = \mathbf{True} then a sophisticated and reliable but expensive technique will be used, whereas for :math:\mathrm{sophst} = \mathbf{False} a simple but less reliable technique will be used. If :math:\mathrm{neqg}\leq 0, :math:\mathrm{sophst} is not referenced.

**comm** : dict, communication object, modified in place
Communication structure.

On initial entry: need not be set.

**Returns**
**statef** : str, length 1
Is set to 'C', except that if an error is detected, :math:\mathrm{statef} is unchanged.

**alterg** : bool
Is set to :math:\mathbf{False}.

.. _d02qw-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:\mathrm{statef} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{statef} = \texttt{'S'}, :math:\texttt{'R'} or :math:\texttt{'C'}.

(errno :math:1)
On entry, for :math:i = \langle\mathit{\boldsymbol{value}}\rangle, :math:\mathrm{atol}[i] = 0.0, :math:\mathrm{rtol}[i] = \langle\mathit{\boldsymbol{value}}\rangle and :math:4\times \textit{eps} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: if :math:\mathrm{atol}[i] = 0.0 then :math:\mathrm{rtol}[i]\geq 4\times \textit{eps} for all :math:i.

(errno :math:1)
On entry, :math:\mathrm{rtol}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{rtol}[i]\geq 0.0 for all :math:i.

(errno :math:1)
On entry, :math:\mathrm{atol}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{atol}[i]\geq 0.0 for all :math:i.

(errno :math:1)
On entry, :math:\mathrm{statef} = \texttt{'R'} or :math:\texttt{'C'}, :math:\mathrm{alterg} = \mathbf{False} and :math:\mathrm{neqg} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: if :math:\mathrm{statef} = \texttt{'R'} or :math:\texttt{'C'} and :math:\mathrm{alterg} = \mathbf{False} then :math:\mathrm{neqg} must retain its value from the prior call with :math:\mathrm{statef} = \texttt{'S'}.

(errno :math:1)
On entry, :math:\mathrm{statef} = \texttt{'R'} or :math:\texttt{'C'} and :math:\mathrm{vectol} = \mathbf{False}.

Constraint: if :math:\mathrm{statef} = \texttt{'R'} or :math:\texttt{'C'} then :math:\mathrm{vectol} must retain its value from the prior call with :math:\mathrm{statef} = \texttt{'S'}.

(errno :math:1)
On entry, :math:\mathrm{statef} = \texttt{'R'} or :math:\texttt{'C'} and :math:\mathrm{vectol} = \mathbf{True}.

Constraint: if :math:\mathrm{statef} = \texttt{'R'} or :math:\texttt{'C'} then :math:\mathrm{vectol} must retain its value from the prior call with :math:\mathrm{statef} = \texttt{'S'}.

(errno :math:1)
On entry, :math:\mathrm{statef} = \texttt{'R'} or :math:\texttt{'C'} and :math:\mathrm{neqf} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: if :math:\mathrm{statef} = \texttt{'R'} or :math:\texttt{'C'} then :math:\mathrm{neqf} must retain its value, :math:\langle\mathit{\boldsymbol{value}}\rangle, from the prior call with :math:\mathrm{statef} = \texttt{'S'}.

(errno :math:1)
On entry, :math:\textit{latol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\textit{latol}\geq 1.

(errno :math:1)
On entry, :math:\textit{lrtol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\textit{lrtol}\geq 1.

(errno :math:1)
On entry, :math:\mathrm{vectol} = \mathbf{True}, :math:\textit{latol} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{neqf} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: if :math:\mathrm{vectol} = \mathbf{True} then :math:\textit{latol}\geq \mathrm{neqf}.

(errno :math:1)
On entry, :math:\mathrm{vectol} = \mathbf{True}, :math:\textit{lrtol} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{neqf} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: if :math:\mathrm{vectol} = \mathbf{True} then :math:\textit{lrtol}\geq \mathrm{neqf}.

(errno :math:1)
On entry, :math:\mathrm{neqf} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{neqf}\geq 1.

.. _d02qw-py2-py-notes:

**Notes**
In the NAG Library the traditional C interface for this routine uses a different algorithmic base. Please contact NAG if you have any questions about compatibility.

ivp_adams_setup permits initialization of the integration method and setting of optional inputs prior to any call of :meth:ivp_adams_roots or :meth:ivp_adams_roots_revcom. It must be called before the first call of either of the functions :meth:ivp_adams_roots or :meth:ivp_adams_roots_revcom and it may be called before any continuation call of either of the functions :meth:ivp_adams_roots or :meth:ivp_adams_roots_revcom.
"""
raise NotImplementedError

r"""
ivp_adams_diag is a diagnostic function which may be called after a call to either of the integration functions :meth:ivp_adams_roots and :meth:ivp_adams_roots_revcom.

.. _d02qx-py2-py-doc:

For full information please refer to the NAG Library document for d02qx

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02qxf.html

.. _d02qx-py2-py-parameters:

**Parameters**
**neqf** : int
The number of first-order ordinary differential equations solved by the integration function. It must be the same argument :math:\mathrm{neqf} supplied to the setup function :meth:ivp_adams_setup and the integration functions :meth:ivp_adams_roots or :meth:ivp_adams_roots_revcom.

**comm** : dict, communication object
Communication structure.

This argument must have been initialized by prior calls to :meth:ivp_adams_setup and one of :meth:ivp_adams_roots or :meth:ivp_adams_roots_revcom.

**Returns**
**yp** : float, ndarray, shape :math:\left(\mathrm{neqf}\right)
The approximate derivative of the solution component :math:y_i, as supplied in :math:y_i on output from the integration function at the output value of :math:\textit{t}. These values are obtained by the evaluation of :math:y^{\prime } = f\left(x, y\right) except when the output value of the argument :math:\textit{t} in the call to the integration function is :math:\textit{tout} and :math:\mathrm{tcurr}\neq {\textit{tout}}, in which case they are obtained by interpolation.

**tcurr** : float
The value of the independent variable which the integrator has actually reached. :math:\mathrm{tcurr} will always be at least as far as the output value of the argument :math:\textit{t} (from the integration function) in the direction of integration, but may be further.

**hlast** : float
The last successful step size used by the integrator.

**hnext** : float
The next step size which the integration function would attempt.

**odlast** : int
The order of the method last used (successfully) by the integration function.

**odnext** : int
The order of the method which the integration function would attempt on the next step.

**nsucc** : int
The number of steps attempted by the integration function that have been successful since the start of the current problem.

**nfail** : int
The number of steps attempted by the integration function that have failed since the start of the current problem.

**tolfac** : float
A tolerance scale factor, :math:\mathrm{tolfac}\geq 1.0, returned when the integration function exits with :math:\mathrm{errno} = 3. If :math:\textit{rtol} and :math:\textit{atol} are uniformly scaled up by a factor of :math:\mathrm{tolfac} and :meth:ivp_adams_setup is called, the next call to the integration function is deemed likely to succeed.

If the integration function returned with :math:\mathrm{errno} = 4, :math:\mathrm{badcmp} specifies the index of the component which forced the error exit. Otherwise :math:\mathrm{badcmp} is :math:0.

.. _d02qx-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:\mathrm{neqf} = \langle\mathit{\boldsymbol{value}}\rangle and :math:{\textit{neqf}} = \langle\mathit{\boldsymbol{value}}\rangle in :meth:ivp_adams_setup.

Constraint: :math:\mathrm{neqf} = {\textit{neqf}} in :meth:ivp_adams_setup.

(errno :math:1)
Neither of the appropriate two integrator functions has been called.

.. _d02qx-py2-py-notes:

**Notes**
No equivalent traditional C interface for this routine exists in the NAG Library.

ivp_adams_diag permits you to extract information about the performance of :meth:ivp_adams_roots or :meth:ivp_adams_roots_revcom.
It may only be called after a call to :meth:ivp_adams_roots or :meth:ivp_adams_roots_revcom.
"""
raise NotImplementedError

r"""
ivp_adams_rootdiag is a diagnostic function which may be called after a call to the integrator functions :meth:ivp_adams_roots or :meth:ivp_adams_roots_revcom.

.. _d02qy-py2-py-doc:

For full information please refer to the NAG Library document for d02qy

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02qyf.html

.. _d02qy-py2-py-parameters:

**Parameters**
**neqg** : int
The number of event functions defined for the integration function. It must be the same argument :math:\mathrm{neqg} supplied to the setup function :meth:ivp_adams_setup and to the integration function (:meth:ivp_adams_roots or :meth:ivp_adams_roots_revcom).

**comm** : dict, communication object
Communication structure.

This argument must have been initialized by prior calls to :meth:ivp_adams_setup and one of :meth:ivp_adams_roots or :meth:ivp_adams_roots_revcom.

**Returns**
**index** : int
The index :math:k of the event equation :math:g_k\left(x, y, {y^{\prime }}\right) = 0 for which the root has been detected.

**itype** : int
Information about the root detected for the event equation defined by :math:\mathrm{index}. The possible values of :math:\mathrm{itype} with their interpretations are as follows:

:math:\mathrm{itype} = 1

A simple root, or lack of distinguishing information available.

:math:\mathrm{itype} = 2

A root of even multiplicity is believed to have been detected, that is no change in sign of the event function was found.

:math:\mathrm{itype} = 3

A high-order root of odd multiplicity.

:math:\mathrm{itype} = 4

A possible root, but due to high multiplicity or a clustering of roots accurate evaluation of the event function was prohibited by round-off error and/or cancellation.

In general, the accuracy of the root is less reliable for values of :math:\mathrm{itype} > 1.

**events** : int, ndarray, shape :math:\left(\mathrm{neqg}\right)
Information about the :math:k\ th event function on a very small interval containing the root, :math:\textit{t} (see :meth:ivp_adams_roots and :meth:ivp_adams_roots_revcom), as output from the integration function. All roots lying in this interval are considered indistinguishable numerically and, therefore, should be regarded as defining a root at :math:\textit{t}. The possible values of :math:\mathrm{events}[k-1] with their interpretations are as follows:

:math:\mathrm{events}[k-1] = 0

The :math:k\ th event function did not have a root.

:math:\mathrm{events}[k-1] = -1

The :math:k\ th event function changed sign from positive to negative about a root, in the direction of integration.

:math:\mathrm{events}[k-1] = 1

The :math:k\ th event function changed sign from negative to positive about a root, in the direction of integration.

:math:\mathrm{events}[k-1] = 2

A root was identified, but no change in sign was observed.

**resids** : float, ndarray, shape :math:\left(\mathrm{neqg}\right)
The value of the :math:k\ th event function computed at the root, :math:\textit{t} (see :meth:ivp_adams_roots and :meth:ivp_adams_roots_revcom).

.. _d02qy-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:\mathrm{neqg} = \langle\mathit{\boldsymbol{value}}\rangle and :math:{\textit{neqg}} = \langle\mathit{\boldsymbol{value}}\rangle in :meth:ivp_adams_setup.

Constraint: :math:\mathrm{neqg} = {\textit{neqg}} in :meth:ivp_adams_setup.

(errno :math:1)
The integrator did not end at an event.

(errno :math:1)
Neither of the appropriate two integrator functions has been called.

.. _d02qy-py2-py-notes:

**Notes**
In the NAG Library the traditional C interface for this routine uses a different algorithmic base. Please contact NAG if you have any questions about compatibility.

ivp_adams_rootdiag should be called only after a call to :meth:ivp_adams_roots or :meth:ivp_adams_roots_revcom results in the output value :math:{\textit{root}} = \mathbf{True}, indicating that a root has been detected. ivp_adams_rootdiag permits you to examine information about the root detected, such as the indices of the event equations for which there is a root, the type of root (odd or even) and the residuals of the event equations.
"""
raise NotImplementedError

[docs]def ivp_adams_interp(neqf, twant, nwant, comm):
r"""
ivp_adams_interp interpolates components of the solution of a non-stiff system of first-order differential equations from information provided by the integrator functions :meth:ivp_adams_roots or :meth:ivp_adams_roots_revcom.

.. _d02qz-py2-py-doc:

For full information please refer to the NAG Library document for d02qz

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02qzf.html

.. _d02qz-py2-py-parameters:

**Parameters**
**neqf** : int
The number of first-order ordinary differential equations being solved by the integration function. It must contain the same value as the argument :math:\mathrm{neqf} in a prior call to the setup function :meth:ivp_adams_setup.

**twant** : float
The point at which components of the solution and derivative are to be evaluated. :math:\mathrm{twant} should not normally be an extrapolation point, that is :math:\mathrm{twant} should satisfy

:math:\textit{told}\leq \mathrm{twant}\leq \mathrm{T},

or if integration is proceeding in the negative direction

:math:\textit{told}\geq \mathrm{twant}\geq \mathrm{T},

where :math:\textit{told} is the previous integration point and is, to within rounding, :math:\textit{tcurr} -- :math:\textit{hlast} (see :meth:ivp_adams_diag). Extrapolation is permitted but not recommended and :math:\mathrm{errno} = 2 is returned whenever extrapolation is attempted.

**nwant** : int
The number of components of the solution and derivative whose values at :math:\mathrm{twant} are required. The first :math:\mathrm{nwant} components are evaluated.

**comm** : dict, communication object, modified in place
Communication structure.

This argument must have been initialized by prior calls to :meth:ivp_adams_setup and one of :meth:ivp_adams_roots or :meth:ivp_adams_roots_revcom.

**Returns**
**ywant** : float, ndarray, shape :math:\left(\mathrm{nwant}\right)
The calculated value of the :math:\textit{i}\ th component of the solution at :math:\mathrm{twant}, for :math:\textit{i} = 1,2,\ldots,\mathrm{nwant}.

**ypwant** : float, ndarray, shape :math:\left(\mathrm{nwant}\right)
The calculated value of the :math:\textit{i}\ th component of the derivative at :math:\mathrm{twant}, for :math:\textit{i} = 1,2,\ldots,\mathrm{nwant}.

.. _d02qz-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry, :math:\mathrm{nwant} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{nwant}\geq 1.

(errno :math:1)
On entry, :math:\mathrm{nwant} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{neqf} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{nwant}\leq \mathrm{neqf}.

(errno :math:1)
On entry, :math:\mathrm{neqf} = \langle\mathit{\boldsymbol{value}}\rangle and :math:{\textit{neqf}} = \langle\mathit{\boldsymbol{value}}\rangle in :meth:ivp_adams_setup.

Constraint: :math:\mathrm{neqf} = {\textit{neqf}} in :meth:ivp_adams_setup.

(errno :math:1)
Neither of the appropriate two integrator functions has been called.

**Warns**
**NagAlgorithmicWarning**
(errno :math:1)
No successful steps had been taken, so interpolation is impossible at :math:\mathrm{twant} = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:2)
Extrapolation performed at :math:\mathrm{twant} = \langle\mathit{\boldsymbol{value}}\rangle.

.. _d02qz-py2-py-notes:

**Notes**
In the NAG Library the traditional C interface for this routine uses a different algorithmic base. Please contact NAG if you have any questions about compatibility.

ivp_adams_interp evaluates the first :math:\mathrm{nwant} components of the solution of a non-stiff system of first-order ordinary differential equations at any point using the method of Watts and Shampine (1986) and information generated by :meth:ivp_adams_roots or :meth:ivp_adams_roots_revcom. ivp_adams_interp should not normally be used to extrapolate outside the current range of the values produced by the integration function.

.. _d02qz-py2-py-references:

**References**
Watts, H A and Shampine, L F, 1986, Smoother interpolants for Adams codes, SIAM J. Sci. Statist. Comput. (7), 334--345
"""
raise NotImplementedError

[docs]def bvp_fd_nonlin_gen(np, numbeg, nummix, tol, init, x, y, fcn, g, ijac, deleps, itrace, comm, jacobf=None, jacobg=None, jaceps=None, jacgep=None, data=None, io_manager=None, spiked_sorder='C'):
r"""
bvp_fd_nonlin_gen solves a two-point boundary value problem with general boundary conditions for a system of ordinary differential equations, using a deferred correction technique and Newton iteration.

.. _d02ra-py2-py-doc:

For full information please refer to the NAG Library document for d02ra

https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02raf.html

.. _d02ra-py2-py-parameters:

**Parameters**
**np** : int
Must be set to the number of points to be used in the initial mesh.

**numbeg** : int
The number of left-hand boundary conditions (that is the number involving :math:y\left(a\right) only).

**nummix** : int
The number of coupled boundary conditions (that is the number involving both :math:y\left(a\right) and :math:y\left(b\right)).

**tol** : float
A positive absolute error tolerance. If

.. math::
a = x_1 < x_2 < \cdots < x_{\mathrm{np}} = b

is the final mesh, :math:z_j\left(x_i\right) is the :math:j\ th component of the approximate solution at :math:x_i, and :math:y_j\left(x\right) is the :math:j\ th component of the true solution of (1) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02raf.html#eqn1>__ and (2) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02raf.html#eqn1>__, then, except in extreme circumstances, it is expected that

.. math::
\left\lvert z_j\left(x_i\right)-y_j\left(x_i\right)\right\rvert \leq \mathrm{tol}\text{, }\quad i = 1,2,\ldots,\mathrm{np}\text{ and }j = 1,2,\ldots,n\text{.}

**init** : int
Indicates whether you wish to supply an initial mesh and approximate solution (:math:\mathrm{init} = 1) or whether default values are to be used, (:math:\mathrm{init} = 0).

**x** : float, array-like, shape :math:\left(\textit{mnp}\right)
You must set :math:\mathrm{x}[0] = a and :math:\mathrm{x}[\mathrm{np}-1] = b. If :math:\mathrm{init} = 0 on entry a default equispaced mesh will be used, otherwise you must specify a mesh by setting :math:\mathrm{x}[\textit{i}-1] = x_{\textit{i}}, for :math:\textit{i} = 2,3,\ldots,\mathrm{np}-1.

**y** : float, array-like, shape :math:\left(n, \textit{mnp}\right)
If :math:\mathrm{init} = 0, :math:\mathrm{y} need not be set.

If :math:\mathrm{init} = 1, the array :math:\mathrm{y} must contain an initial approximation to the solution such that :math:\mathrm{y}[j-1,i-1] contains an approximation to

.. math::
y_j\left(x_i\right)\text{, }\quad i = 1,2,\ldots,\mathrm{np}\text{ and }j = 1,2,\ldots,n\text{.}

**fcn** : callable f = fcn(x, eps, y, data=None)
:math:\mathrm{fcn} must evaluate the functions :math:f_i (i.e., the derivatives :math:y_i^{\prime }) at a general point :math:x for a given value of :math:\epsilon, the continuation parameter (see :ref:Notes <d02ra-py2-py-notes>).

**Parameters**
**x** : float
:math:x, the value of the independent variable.

**eps** : float
:math:\epsilon, the value of the continuation parameter. This is :math:1 if continuation is not being used.

**y** : float, ndarray, shape :math:\left(n\right)
:math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}, the values of the dependent variables at :math:x.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**f** : float, array-like, shape :math:\left(n\right)
The values of the derivatives :math:f_{\textit{i}} evaluated at :math:x given :math:\epsilon, for :math:\textit{i} = 1,2,\ldots,\textit{n}.

**g** : callable bc = g(eps, ya, yb, data=None)
:math:\mathrm{g} must evaluate the boundary conditions in equation (3) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02raf.html#eqn3>__ and place them in the array :math:\mathrm{bc}.

**Parameters**
**eps** : float
:math:\epsilon, the value of the continuation parameter. This is :math:1 if continuation is not being used.

**ya** : float, ndarray, shape :math:\left(n\right)
The value :math:y_{\textit{i}}\left(a\right), for :math:\textit{i} = 1,2,\ldots,n.

**yb** : float, ndarray, shape :math:\left(n\right)
The value :math:y_{\textit{i}}\left(b\right), for :math:\textit{i} = 1,2,\ldots,n.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**bc** : float, array-like, shape :math:\left(n\right)
The values :math:g_{\textit{i}}\left({y\left(a\right)}, {y\left(b\right)}, \epsilon \right), for :math:\textit{i} = 1,2,\ldots,n. These must be ordered as follows:

(i) first, the conditions involving only :math:y\left(a\right) (see :math:\mathrm{numbeg});

(#) next, the :math:\mathrm{nummix} coupled conditions involving both :math:y\left(a\right) and :math:y\left(b\right) (see :math:\mathrm{nummix}); and,

(#) finally, the conditions involving only :math:y\left(b\right) (:math:n-\mathrm{numbeg}-\mathrm{nummix}).

**ijac** : int
Indicates whether or not you are supplying Jacobian evaluation functions.

:math:\mathrm{ijac}\neq 0

You must supply :math:\mathrm{jacobf} and :math:\mathrm{jacobg} and also, when continuation is used, :math:\mathrm{jaceps} and :math:\mathrm{jacgep}.

:math:\mathrm{ijac} = 0

Numerical differentiation is used to calculate the Jacobian and **None** may be used for the respective callbacks.

**deleps** : float
Must be given a value which specifies whether continuation is required. If :math:\mathrm{deleps}\leq 0.0 or :math:\mathrm{deleps}\geq 1.0 then it is assumed that continuation is not required. If :math:0.0 < \mathrm{deleps} < 1.0 then it is assumed that continuation is required unless :math:\mathrm{deleps} < \sqrt{\text{machine precision}} when an error exit is taken. :math:\mathrm{deleps} is used as the increment :math:\epsilon_2-\epsilon_1 (see (4) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02raf.html#eqn4>__) and the choice :math:\mathrm{deleps} = 0.1 is recommended.

**itrace** : int
If :math:\mathrm{itrace} = 0 warning messages be suppressed, otherwise warning messages will be printed (see :ref:Exceptions <d02ra-py2-py-errors>).

**comm** : dict, communication object, modified in place
Communication structure.

On initial entry: need not be set.

**jacobf** : None or callable f = jacobf(x, eps, y, data=None), optional
Note: if this argument is **None** then a NAG-supplied facility will be used.

:math:\mathrm{jacobf} evaluates the Jacobian :math:\left(\frac{{\partial f_{\textit{i}}}}{{\partial y_{\textit{j}}}}\right), for :math:\textit{j} = 1,2,\ldots,n, for :math:\textit{i} = 1,2,\ldots,n, given :math:x and :math:y_{\textit{j}}, for :math:\textit{j} = 1,2,\ldots,n.

If :math:\mathrm{ijac} = 0, numerical differentiation is used to calculate the Jacobian.

**Parameters**
**x** : float
:math:x, the value of the independent variable.

**eps** : float
:math:\epsilon, the value of the continuation parameter. This is :math:1 if continuation is not being used.

**y** : float, ndarray, shape :math:\left(n\right)
:math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,\textit{n}, the values of the dependent variables at :math:x.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**f** : float, array-like, shape :math:\left(n, n\right)
:math:\mathrm{f}[\textit{j}-1,\textit{i}-1] must be set to the value of :math:\frac{{\partial f_{\textit{i}}}}{{\partial y_{\textit{j}}}}, evaluated at the point :math:\left(x, y\right), for :math:\textit{j} = 1,2,\ldots,n, for :math:\textit{i} = 1,2,\ldots,n.

**jacobg** : None or callable (aj, bj) = jacobg(eps, ya, yb, data=None), optional
Note: if this argument is **None** then a NAG-supplied facility will be used.

:math:\mathrm{jacobg} evaluates the Jacobians :math:\left(\frac{{\partial g_i}}{{\partial y_j\left(a\right)}}\right) and :math:\left(\frac{{\partial g_i}}{{\partial y_j\left(b\right)}}\right).

The ordering of the rows of :math:\mathrm{aj} and :math:\mathrm{bj} must correspond to the ordering of the boundary conditions described in the specification of :math:\mathrm{g}.

If :math:\mathrm{ijac} = 0, numerical differentiation is used to calculate the Jacobian.

**Parameters**
**eps** : float
:math:\epsilon, the value of the continuation parameter. This is :math:1 if continuation is not being used.

**ya** : float, ndarray, shape :math:\left(n\right)
The value :math:y_{\textit{i}}\left(a\right), for :math:\textit{i} = 1,2,\ldots,n.

**yb** : float, ndarray, shape :math:\left(n\right)
The value :math:y_{\textit{i}}\left(b\right), for :math:\textit{i} = 1,2,\ldots,n.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**aj** : float, array-like, shape :math:\left(n, n\right)
:math:\mathrm{aj}[\textit{i}-1,\textit{j}-1] must be set to the value :math:\frac{{\partial g_{\textit{i}}}}{{\partial y_{\textit{j}}\left(a\right)}}, for :math:\textit{j} = 1,2,\ldots,n, for :math:\textit{i} = 1,2,\ldots,n.

**bj** : float, array-like, shape :math:\left(n, n\right)
:math:\mathrm{bj}[\textit{i}-1,\textit{j}-1] must be set to the value :math:\frac{{\partial g_{\textit{i}}}}{{\partial y_{\textit{j}}\left(b\right)}}, for :math:\textit{j} = 1,2,\ldots,n, for :math:\textit{i} = 1,2,\ldots,n.

**jaceps** : None or callable f = jaceps(x, eps, y, data=None), optional
Note: if this argument is **None** then a NAG-supplied facility will be used.

:math:\mathrm{jaceps} evaluates the derivative :math:\frac{{\partial f_i}}{{\partial \epsilon }} given :math:x and :math:y if continuation is being used.

**Parameters**
**x** : float
:math:x, the value of the independent variable.

**eps** : float
:math:\epsilon, the value of the continuation parameter.

**y** : float, ndarray, shape :math:\left(n\right)
The solution values :math:y_{\textit{i}}, for :math:\textit{i} = 1,2,\ldots,n, at the point :math:x.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**f** : float, array-like, shape :math:\left(n\right)
:math:\mathrm{f}[\textit{i}-1] must contain the value :math:\frac{{\partial f_{\textit{i}}}}{{\partial \epsilon }} at the point :math:\left(x, y\right), for :math:\textit{i} = 1,2,\ldots,n.

**jacgep** : None or callable bcep = jacgep(eps, ya, yb, data=None), optional
Note: if this argument is **None** then a NAG-supplied facility will be used.

:math:\mathrm{jacgep} evaluates the derivatives :math:\frac{{\partial g_i}}{{\partial \epsilon }} if continuation is being used.

**Parameters**
**eps** : float
:math:\epsilon, the value of the continuation parameter.

**ya** : float, ndarray, shape :math:\left(n\right)
The value of :math:y_{\textit{i}}\left(a\right), for :math:\textit{i} = 1,2,\ldots,n.

**yb** : float, ndarray, shape :math:\left(n\right)
The value of :math:y_{\textit{i}}\left(b\right), for :math:\textit{i} = 1,2,\ldots,n.

**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.

**Returns**
**bcep** : float, array-like, shape :math:\left(n\right)
:math:\mathrm{bcep}[\textit{i}-1] must contain the value of :math:\frac{{\partial g_{\textit{i}}}}{{\partial \epsilon }}, for :math:\textit{i} = 1,2,\ldots,n.

**data** : arbitrary, optional
User-communication data for callback functions.

**io_manager** : FileObjManager, optional
Manager for I/O in this routine.

**spiked_sorder** : str, optional
If :math:\mathrm{y} is spiked (i.e., has unit extent in all but one dimension, or has size :math:1), :math:\mathrm{spiked\_sorder} selects the storage order to associate with it in the NAG Engine:

spiked_sorder = :math:\texttt{'C'}
row-major storage will be used;

spiked_sorder = :math:\texttt{'F'}
column-major storage will be used.

Two-dimensional arrays returned from callback functions in this routine must then use the same storage order.

**Returns**
**np** : int
The number of points in the final mesh.

**x** : float, ndarray, shape :math:\left(\textit{mnp}\right)
:math:\mathrm{x}[0],\mathrm{x}[1],\ldots,\mathrm{x}[\mathrm{np}-1] define the final mesh (with the returned value of :math:\mathrm{np}) and :math:\mathrm{x}[0] = a and :math:\mathrm{x}[\mathrm{np}-1] = b.

**y** : float, ndarray, shape :math:\left(n, \textit{mnp}\right)
The approximate solution :math:z_j\left(x_i\right) satisfying (5) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02raf.html#eqn5>__ on the final mesh, that is

.. math::
\mathrm{y}[j-1,i-1] = z_j\left(x_i\right)\text{, }\quad i = 1,2,\ldots,\mathrm{np}\text{ and }j = 1,2,\ldots,n\text{,}

where :math:\mathrm{np} is the number of points in the final mesh. If an error has occurred then :math:\mathrm{y} contains the latest approximation to the solution. The remaining columns of :math:\mathrm{y} are not used.

**abt** : float, ndarray, shape :math:\left(n\right)
:math:\mathrm{abt}[\textit{i}-1], for :math:\textit{i} = 1,2,\ldots,n, holds the largest estimated error (in magnitude) of the :math:i\ th component of the solution over all mesh points.

**deleps** : float
An overestimate of the increment :math:\epsilon_p-\epsilon_{{p-1}} (in fact the value of the increment which would have been tried if the restriction :math:\epsilon_p = 1 had not been imposed). If continuation was not requested then :math:\mathrm{deleps} = 0.0.

If continuation is not requested then :math:\mathrm{jaceps} and :math:\mathrm{jacgep} may each be replaced by **None**.

.. _d02ra-py2-py-errors:

**Raises**
**NagValueError**
(errno :math:1)
On entry the mesh points are not in strictly ascending order.

For :math:i = \langle\mathit{\boldsymbol{value}}\rangle, mesh point :math:i = \langle\mathit{\boldsymbol{value}}\rangle, but mesh point :math:i+1 = \langle\mathit{\boldsymbol{value}}\rangle.

(errno :math:1)
On entry, :math:\mathrm{numbeg} = \langle\mathit{\boldsymbol{value}}\rangle, :math:\mathrm{nummix} = \langle\mathit{\boldsymbol{value}}\rangle and :math:n = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{numbeg}+\mathrm{nummix}\leq n.

(errno :math:1)
On entry, :math:\mathrm{nummix} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{nummix}\geq 0.

(errno :math:1)
On entry, :math:\mathrm{numbeg} = \langle\mathit{\boldsymbol{value}}\rangle and :math:n = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{numbeg} < n.

(errno :math:1)
On entry, :math:\mathrm{numbeg} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{numbeg}\geq 0.

(errno :math:1)
On entry, :math:\mathrm{x}[0] = \langle\mathit{\boldsymbol{value}}\rangle and :math:\mathrm{x}[\mathrm{np}-1] = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{x}[0] < \mathrm{x}[\mathrm{np}-1].

(errno :math:1)
On entry, :math:\textit{mnp} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\textit{mnp}\geq 32.

(errno :math:1)
On entry, :math:\mathrm{np} = \langle\mathit{\boldsymbol{value}}\rangle and :math:\textit{mnp} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{np}\leq \textit{mnp}.

(errno :math:1)
On entry, :math:\mathrm{np} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{np}\geq 4.

(errno :math:1)
On entry, :math:\mathrm{tol} = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:\mathrm{tol} > 0.0.

(errno :math:1)
On entry, :math:n = \langle\mathit{\boldsymbol{value}}\rangle.

Constraint: :math:n\geq 1.

(errno :math:2)
A finer mesh is required for the accuracy requested; that is, :math:\textit{mnp} = \langle\mathit{\boldsymbol{value}}\rangle is not large enough.

(errno :math:3)
The Newton iteration has failed to converge.

This could be due to there being too few points in the initial mesh or to the initial approximate solution being too inaccurate.

If this latter reason is suspected or you cannot make changes to prevent this error, you should use the function with a continuation facility instead.

(errno :math:5)
The Jacobian for the boundary conditions is singular.

This may occur due to faulty coding of the Jacobian or, in some circumstances, to a zero initial choice of approximate solution.

(errno :math:6)
There is no dependence on the continuation parameter when continuation is being used. This can be due to faulty coding of derivatives with respect to the continuation parameter or to a zero initial choice of approximate solution.

(errno :math:7)
The continuation step is required to be less than machine precision for continuation to proceed. It is likely that either the problem has no solution for some value of the continuation parameter near the current value or that the problem is so difficult that even with continuation it is unlikely to be solved using this function. In the latter case using more mesh points initially may help.

(errno :math:8)
A serious error occurred in a call to the internal integrator.

The error code internally was :math:\langle\mathit{\boldsymbol{value}}\rangle.

Please contact NAG <https://www.nag.com>__.

(errno :math:9)
A continuation error occurred, but continuation is not being used.

Please contact NAG <https://www.nag.com>__.

**Warns**
**NagAlgorithmicWarning**
(errno :math:4)
Newton iteration has reached round-off level.

If desired accuracy has not been reached, :math:\mathrm{tol} is too small for this problem and this machine precision.

.. _d02ra-py2-py-notes:

**Notes**
In the NAG Library the traditional C interface for this routine uses a different algorithmic base. Please contact NAG if you have any questions about compatibility.

bvp_fd_nonlin_gen solves a two-point boundary value problem for a system of :math:n ordinary differential equations in the interval :math:\left[a, b\right] with :math:b > a.
The system is written in the form

.. math::
y_i^{\prime } = f_i\left(x, y_1, y_2, \ldots, y_n\right)\text{, }\quad i = 1,2,\ldots,n

and the derivatives :math:f_i are evaluated by :math:\mathrm{fcn}.
With the differential equations (1) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02raf.html#eqn1>__ must be given a system of :math:n (nonlinear) boundary conditions

.. math::
g_i\left({y\left(a\right)}, {y\left(b\right)}\right) = 0\text{, }\quad i = 1,2,\ldots,n\text{,}

where

.. math::
y\left(x\right) = \left[{y_1\left(x\right)}, {y_2\left(x\right)}, \ldots, {y_n\left(x\right)}\right]^\mathrm{T}\text{.}

The functions :math:g_i are evaluated by :math:\mathrm{g}.
The solution is computed using a finite difference technique with deferred correction allied to a Newton iteration to solve the finite difference equations.
The technique used is described fully in Pereyra (1979).

You must supply an absolute error tolerance and may also supply an initial mesh for the finite difference equations and an initial approximate solution (alternatively a default mesh and approximation are used).
The approximate solution is corrected using Newton iteration and deferred correction.
Then, additional points are added to the mesh and the solution is recomputed with the aim of making the error everywhere less than your tolerance and of approximately equidistributing the error on the final mesh.
The solution is returned on this final mesh.

If the solution is required at a few specific points then these should be included in the initial mesh.
If, on the other hand, the solution is required at several specific points then you should use the interpolation functions provided in submodule :mod:~naginterfaces.library.interp if these points do not themselves form a convenient mesh.

The Newton iteration requires Jacobian matrices

.. math::
\left(\frac{{\partial f_i}}{{\partial y_j}}\right),\left(\frac{{\partial g_i}}{{\partial y_j\left(a\right)}}\right)\quad \text{ and }\quad \left(\frac{{\partial g_i}}{{\partial y_j\left(b\right)}}\right)\text{.}

These may be supplied through :math:\mathrm{jacobf} for :math:\left(\frac{{\partial f_i}}{{\partial y_j}}\right) and :math:\mathrm{jacobg} for the others.
Alternatively the Jacobians may be calculated by numerical differentiation using the algorithm described in Curtis et al. (1974).

For problems of the type (1) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02raf.html#eqn1>__ and (2) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02raf.html#eqn1>__ for which it is difficult to determine an initial approximation from which the Newton iteration will converge, a continuation facility is provided.
You must set up a family of problems

.. math::
y^{\prime } = f\left(x, y, \epsilon \right)\text{, }\quad g\left({y\left(a\right)}, {y\left(b\right)}, \epsilon \right) = 0\text{,}

where :math:f = \left[f_1, f_2, \ldots, f_n\right]^\mathrm{T} etc., and where :math:\epsilon is a continuation parameter.
The choice :math:\epsilon = 0 must give a problem (3) <https://www.nag.com/numeric/nl/nagdoc_28.7/flhtml/d02/d02raf.html#eqn3>__ which is easy to solve and :math:\epsilon = 1 must define the problem whose solution is actually required.
The function solves a sequence of problems with :math:\epsilon values

.. math::
0 = \epsilon_1 < \epsilon_2 < \cdots < \epsilon_p = 1\text{.}

The number :math:p and the values :math:\epsilon_i are chosen by the function so that each problem can be solved using the solution of its predecessor as a starting approximation.
Jacobians :math:\frac{{\partial f}}{{\partial \epsilon }} and :math:\frac{{\partial g}}{{\partial \epsilon }} are required and they may be supplied by you via :math:\mathrm{jaceps} and :math:\mathrm{jacgep} respectively or may be computed by numerical differentiation.

.. _d02ra-py2-py-references:

**References**
Curtis, A R, Powell, M J D and Reid, J K, 1974, On the estimation of sparse Jacobian matrices, J. Inst. Maths. Applics. (13), 117--119

Pereyra, V, 1979, PASVA3: An adaptive finite-difference Fortran program for first order nonlinear, ordinary boundary problems, Codes for Boundary Value Problems in Ordinary Differential Equations. Lecture Notes in Computer Science, (eds B Childs, M Scott, J W Daniel, E Denman and P Nelson) (76), Springer--Verlag
"""
raise NotImplementedError

[docs]def bvp_shoot_genpar_algeq(p, n, n1, pe, pf, dp, swp, icount, brkpts, bc, fcn, ymax, monlev, comm, e=None, eqn=None, constr=None, monit=None, prsol=None, data=None, io_manager=None):
r"""
bvp_shoot_genpar_algeq solves a two-point boundary value problem for a system of first-order ordinary