# -*- coding: utf-8 -*-
r"""
Module Summary
--------------
Interfaces for the NAG Mark 30.2 `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.
See Also
--------
``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://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02intro.html
"""
# NAG Copyright 2017-2024.
[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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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
See Also
--------
: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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02gbf.html#eqn1>`__ and `(2) <https://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02gbf.html#eqn2>`__). :math:`\mathrm{gam}` must be set to the vector :math:`\gamma` in `(2) <https://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02gbf.html#eqn2>`__). :math:`\mathrm{gam}` must be set to the vector :math:`\gamma` in `(2) <https://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02gbf.html#eqn2>`__). :math:`\mathrm{gam}` must be set to the vector :math:`\gamma` in `(2) <https://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02gbf.html#eqn1>`__ and `(2) <https://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02gbf.html#eqn1>`__ and `(2) <https://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02gbf.html#eqn1>`__ and `(2) <https://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02gbf.html#eqn1>`__ and `(2) <https://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02gbf.html#eqn1>`__ and `(2) <https://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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`.
**itask** : int
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.
See Also
--------
: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://support.nag.com/numeric/nl/nagdoc_30.2/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`.
**itask** : int
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://support.nag.com/numeric/nl/nagdoc_30.2/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`.
**itask** : int
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://support.nag.com/numeric/nl/nagdoc_30.2/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.
**itask** : int
`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.
**itask** : int
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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02ngf.html#eqn2>`__ must be returned.
:math:`\mathrm{ires} = 1`
The residual defined in equation `(1) <https://support.nag.com/numeric/nl/nagdoc_30.2/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.
**itask** : int
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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02nhf.html#eqn2>`__ must be returned.
:math:`\mathrm{ires} = 1`
The residual defined in equation `(1) <https://support.nag.com/numeric/nl/nagdoc_30.2/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.
**itask** : int
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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02njf.html#eqn2>`__ must be returned.
:math:`\mathrm{ires} = 1`
The residual defined in equation `(1) <https://support.nag.com/numeric/nl/nagdoc_30.2/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.
**itask** : int
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://support.nag.com/numeric/nl/nagdoc_30.2/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.
**itask** : int
`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://support.nag.com/numeric/nl/nagdoc_30.2/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}`.
**itask** : int
`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://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02nnf.html#eqn2>`__ above must be returned; if :math:`\mathrm{ires} = 1`, then the residual returned by equation `(1) <https://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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.
See Also
--------
: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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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.
See Also
--------
: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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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
[docs]def ivp_adams_diag(neqf, comm):
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://support.nag.com/numeric/nl/nagdoc_30.2/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.
**badcmp** : int
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
[docs]def ivp_adams_rootdiag(neqg, comm):
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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02raf.html#eqn1>`__ and `(2) <https://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02raf.html#eqn1>`__ and `(2) <https://support.nag.com/numeric/nl/nagdoc_30.2/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://support.nag.com/numeric/nl/nagdoc_30.2/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 differential equations with boundary conditions, combined with additional algebraic equations.
It uses initial value techniques and a modified Newton iteration in a shooting and matching method.
.. _d02sa-py2-py-doc:
For full information please refer to the NAG Library document for d02sa
https://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02saf.html
.. _d02sa-py2-py-parameters:
**Parameters**
**p** : float, array-like, shape :math:`\left(m\right)`
:math:`\mathrm{p}[\textit{i}]` must be set to an estimate of the :math:`\textit{i}`\ th argument, :math:`p_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,m`.
**n** : int
:math:`n`, the total number of differential equations.
**n1** : int
:math:`n_1`, the number of differential equations active in the matching process. The active equations must be placed last in the numbering in :math:`\mathrm{fcn}` and :math:`\mathrm{bc}`. The **first** :math:`\mathrm{n}-\mathrm{n1}` equations are used as the driving equations.
**pe** : float, array-like, shape :math:`\left(m\right)`
:math:`\mathrm{pe}[\textit{i}-1]`, for :math:`\textit{i} = 1,2,\ldots,m`, must be set to a positive value for use in the convergence test in the :math:`i`\ th argument :math:`p_i`. See the description of :math:`\mathrm{pf}` for further details.
**pf** : float, array-like, shape :math:`\left(m\right)`
:math:`\mathrm{pf}[\textit{i}-1]`, for :math:`\textit{i} = 1,2,\ldots,m`, should be set to a 'floor' value in the convergence test on the :math:`i`\ th argument :math:`p_i`. If :math:`\mathrm{pf}[i-1]\leq 0.0` on entry then it is set to the small positive value :math:`\sqrt{\epsilon }` (where :math:`\epsilon` may in most cases be considered to be machine precision); otherwise it is used unchanged.
The Newton iteration is presumed to have converged if a full Newton step is taken (:math:`\mathrm{istate} = 1` in the specification of :math:`\mathrm{monit}`), the singular values of the Jacobian are not being significantly perturbed (also see :math:`\mathrm{monit}`) and if the Newton correction :math:`C_i` satisfies
.. math::
\left\lvert C_i\right\rvert \leq \mathrm{pe}[i-1]\times \mathrm{max}\left(\left\lvert p_i\right\rvert, \mathrm{pf}[i-1]\right)\text{, }\quad i = 1,2,\ldots,m\text{,}
where :math:`p_i` is the current value of the :math:`i`\ th argument.
The values :math:`\mathrm{pf}[i-1]` are also used in determining the Newton iterates as discussed in :ref:`Notes <d02sa-py2-py-notes>`, see equation `(6) <https://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02saf.html#eqn6>`__.
**dp** : float, array-like, shape :math:`\left(m\right)`
A value to be used in perturbing the argument :math:`p_i` in the numerical differentiation to estimate the Jacobian used in Newton's method. If :math:`\mathrm{dp}[i] = 0.0` on entry, an estimate is made internally by setting
.. math::
\mathrm{dp}[i] = \sqrt{\epsilon }\times \mathrm{max}\left(\mathrm{pf}[i], \left\lvert p_i\right\rvert \right)\text{,}
where :math:`p_i` is the initial value of the argument supplied by you and :math:`\epsilon` may in most cases be considered to be machine precision. The estimate of the Jacobian, :math:`J`, is made using forward differences, that is for each :math:`\textit{i}`, for :math:`\textit{i} = 1,2,\ldots,m`, :math:`p_{\textit{i}}` is perturbed to :math:`p_{\textit{i}}+\mathrm{dp}[\textit{i}]` and the :math:`\textit{i}`\ th column of :math:`J` is estimated as
.. math::
\left(r\left(p_{\textit{i}}+\mathrm{dp}[\textit{i}]\right)-r\left(p_{\textit{i}}\right)\right)/\mathrm{dp}[\textit{i}]
where the other components of :math:`p` are unchanged (see `(3) <https://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02saf.html#eqn3>`__ for the notation used). If this fails to produce a Jacobian with significant columns, backward differences are tried by perturbing :math:`p_{\textit{i}}` to :math:`p_{\textit{i}}-\mathrm{dp}[\textit{i}]` and if this also fails then central differences are used with :math:`p_{\textit{i}}` perturbed to :math:`p_{\textit{i}}+10.0\times \mathrm{dp}[\textit{i}]`. If this also fails then the calculation of the Jacobian is abandoned. If the Jacobian has not previously been calculated then an error exit is taken. If an earlier estimate of the Jacobian is available then the current argument set, :math:`p_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,m`, is abandoned in favour of the last argument set from which useful progress was made and the singular values of the Jacobian used at the point are modified before proceeding with the Newton iteration. You are recommended to use the default value :math:`\mathrm{dp}[i] = 0.0` unless you have prior knowledge of a better choice. If any of the perturbations described are likely to lead to an unfortunate set of argument values then you should use :math:`\mathrm{constr}` to prevent such perturbations (all changes of arguments are checked by a call to :math:`\mathrm{constr}`).
**swp** : float, array-like, shape :math:`\left(\textit{npoint}, 6\right)`
:math:`\mathrm{swp}[i-1,0]` must contain an estimate for an initial step size for integration across the :math:`i`\ th sub-interval :math:`\left[\mathrm{x}[\textit{i}-1], \mathrm{x}[\textit{i}]\right]`, for :math:`\textit{i} = 1,2,\ldots,\textit{npoint}-1`, (see :math:`\mathrm{brkpts}`). :math:`\mathrm{swp}[i-1,0]` should have the same sign as :math:`\mathrm{x}[i]-\mathrm{x}[i-1]` if it is nonzero. If :math:`\mathrm{swp}[i-1,0] = 0.0`, on entry, a default value for the initial step size is calculated internally. This is the recommended mode of entry.
:math:`\mathrm{swp}[i-1,2]` must contain a lower bound for the modulus of the step size on the :math:`\textit{i}`\ th sub-interval :math:`\left[\mathrm{x}[ \textit{i} -1], \mathrm{x}[ \textit{i} + 1 -1]\right]`, for :math:`\textit{i} = 1,2,\ldots,\textit{npoint}-1`.
If :math:`\mathrm{swp}[i-1,2] = 0.0` on entry, a very small default value is used.
By setting :math:`\mathrm{swp}[i-1,2] > 0.0` but smaller than the expected step sizes (assuming you have some insight into the likely step sizes) expensive integrations with arguments :math:`p` far from the solution can be avoided.
:math:`\mathrm{swp}[\textit{i}-1,1]` must contain an upper bound on the modulus of the step size to be used in the integration on :math:`\left[\mathrm{x}[ \textit{i} -1], \mathrm{x}[ \textit{i} + 1 -1]\right]`, for :math:`\textit{i} = 1,2,\ldots,\textit{npoint}-1`.
If :math:`\mathrm{swp}[i-1,1] = 0.0` on entry no bound is assumed.
This is the recommended mode of entry unless the solution is expected to have important features which might be 'missed' in the integration if the step size were permitted to be chosen freely.
**icount** : int
An upper bound on the number of Newton iterations. If :math:`\mathrm{icount} = 0` on entry, no check on the number of iterations is made (this is the recommended mode of entry).
**brkpts** : callable x = brkpts(npoint, p, data=None)
:math:`\mathrm{brkpts}` must specify the break-points :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,\mathrm{npoint}`, which may depend on the arguments :math:`p_{\textit{j}}`, for :math:`\textit{j} = 1,2,\ldots,m`.
**Parameters**
**npoint** : int
:math:`2` plus the number of break-points in :math:`\left(a, b\right)`.
**p** : float, ndarray, shape :math:`\left(m\right)`
The current estimate of the :math:`\textit{i}`\ th argument, for :math:`\textit{i} = 1,2,\ldots,m`.
**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.
**Returns**
**x** : float, array-like, shape :math:`\left(\mathrm{npoint}\right)`
The :math:`\textit{i}`\ th break-point, for :math:`\textit{i} = 1,2,\ldots,\mathrm{npoint}`. The sequence :math:`\left(\mathrm{x}[i]\right)` must be strictly monotonic, that is either
.. math::
a = \mathrm{x}[0] < \mathrm{x}[1] < \cdots < \mathrm{x}[\mathrm{npoint}-1] = b
or
.. math::
a = \mathrm{x}[0] > \mathrm{x}[1] > \cdots > \mathrm{x}[\mathrm{npoint}-1] = b\text{.}
**bc** : callable (g1, g2) = bc(p, n, 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.
**Parameters**
**p** : float, ndarray, shape :math:`\left(m\right)`
An estimate of the :math:`\textit{i}`\ th argument, :math:`p_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,m`.
**n** : int
:math:`n`, the number of differential equations.
**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)`, for :math:`\textit{i} = 1,2,\ldots,n`, (where this may be a known value or a function of the parameters :math:`p_{\textit{j}}`, for :math:`\textit{j} = 1,2,\ldots,m`).
**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,n`, (where these may be known values or functions of the parameters :math:`p_{\textit{j}}`, for :math:`\textit{j} = 1,2,\ldots,m`). If :math:`n > n_1`, so that there are some driving equations, the first :math:`n-n_1` values of :math:`\mathrm{g2}` need not be set since they are never used.
**fcn** : callable f = fcn(x, y, p, i, 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,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.
**p** : float, ndarray, shape :math:`\left(m\right)`
The current estimate of the :math:`\textit{i}`\ th argument :math:`p_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,m`.
**i** : int
Specifies the sub-interval :math:`\left[x_i, x_{{i+1}}\right]` on which the derivatives are to be evaluated.
**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.
**Returns**
**f** : float, array-like, shape :math:`\left(n\right)`
The derivative of :math:`y_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`, evaluated at :math:`x`. :math:`\mathrm{f}[i]` may depend upon the parameters :math:`p_{\textit{j}}`, for :math:`\textit{j} = 1,2,\ldots,m`. If there are any driving equations (see :ref:`Notes <d02sa-py2-py-notes>`) then these must be numbered first in the ordering of the components of :math:`\mathrm{f}`.
**ymax** : float
A non-negative value which is used as a bound on all values :math:`\left\lVert y\left(x\right)\right\rVert_\infty` where :math:`y\left(x\right)` is the solution at any point :math:`x` between :math:`\mathrm{x}[0]` and :math:`\mathrm{x}[\textit{npoint}-1]` for the current arguments :math:`p_1,p_2,\ldots,p_m`. If this bound is exceeded the integration is terminated and the current arguments are rejected. Such a rejection will result in an error exit if it prevents the initial residual or Jacobian, or the final solution, being calculated. If :math:`\mathrm{ymax} = 0` on entry, no bound on the solution :math:`y` is used; that is the integrations proceed without any checking on the size of :math:`\left\lVert y\right\rVert_\infty`.
**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.
**e** : None or float, array-like, shape :math:`\left(\mathrm{n}\right)`, optional
Note: if this argument is **None** then a default value will be used, determined as follows: :math:`10^{-5}`.
Values for use in controlling the local error in the integration of the differential equations. If :math:`\textit{err}_{\textit{i}}` is an estimate of the local error in :math:`y_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`,
.. math::
\left\lvert \textit{err}_i\right\rvert \leq \mathrm{e}[i-1]\times \mathrm{max}\left\{\sqrt{\epsilon }, \left\lvert y_i\right\rvert \right\}\text{,}
where :math:`\epsilon` may in most cases be considered to be machine precision.
**eqn** : None or callable e = eqn(q, p, data=None), optional
Note: if this argument is **None** then a NAG-supplied facility will be used.
:math:`\mathrm{eqn}` is used to describe the additional algebraic equations to be solved in the determination of the parameters, :math:`p_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,m`.
If there are no additional algebraic equations (i.e., :math:`m = n_1`) then :math:`\mathrm{eqn}` is never called and may be **None**.
**Parameters**
**q** : int
The number of algebraic equations, :math:`m-n_1`.
**p** : float, ndarray, shape :math:`\left(m\right)`
The current estimate of the :math:`\textit{i}`\ th argument :math:`p_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,m`.
**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.
**Returns**
**e** : float, array-like, shape :math:`\left(\mathrm{q}\right)`
The vector of residuals, :math:`r_2\left(p\right)`, that is the amount by which the current estimates of the arguments fail to satisfy the algebraic equations.
**constr** : None or callable retval = constr(p, data=None), optional
Note: if this argument is **None** then a NAG-supplied facility will be used.
:math:`\mathrm{constr}` is used to prevent the pseudo-Newton iteration running into difficulty. :math:`\mathrm{constr}` should return the value :math:`\mathbf{True}` if the constraints are satisfied by the parameters :math:`p_1,p_2,\ldots,p_m`.
Otherwise :math:`\mathrm{constr}` should return the value :math:`\mathbf{False}`. If **None** is supplied the function will act as if :math:`\mathrm{constr}` returns the value :math:`\mathbf{True}` at all times, and in the first instance this is recommended as the actual argument.
**Parameters**
**p** : float, ndarray, shape :math:`\left(m\right)`
An estimate of the :math:`\textit{i}`\ th argument, :math:`p_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,m`.
**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.
**Returns**
**retval** : bool
Must be :math:`\mathbf{True}` if the constraints are satisfied by the parameters :math:`\mathrm{p}`.
**monit** : None or callable monit(istate, iflag, ifail1, p, f, pnorm, pnorm1, eps, d, data=None), optional
Note: if this argument is **None** then a NAG-supplied facility will be used.
:math:`\mathrm{monit}` enables you to monitor the values of various quantities during the calculation. If :math:`\mathrm{monlev} = 0` on entry no monitoring is performed and this argument is never referenced. Otherwise, if :math:`\mathrm{monlev} = 1` on entry, you may supply **None**, to use NAG-defined default monitoring, or you may supply your own custom monitoring function. The function is called by ``bvp_shoot_genpar_algeq`` after every calculation of the norm :math:`\left\lVert \mathrm{d}^{-1}\tilde{J}^+r\right\rVert_2` which determines the strategy of the Newton method, every time there is an internal error exit leading to a change of strategy, and before an error exit when calculating the initial Jacobian.
**Parameters**
**istate** : int
The state of the Newton iteration.
:math:`\mathrm{istate} = 0`
The calculation of the residual, Jacobian and :math:`\left\lVert \mathrm{d}^{-1}\tilde{J}^+r\right\rVert_2` are taking place.
:math:`\mathrm{istate} = 1` to :math:`5`
During the Newton iteration a factor of :math:`2^{\left(-\mathrm{istate}+1\right)}` of the Newton step is being used to try to reduce the norm.
:math:`\mathrm{istate} = 6`
The current Newton step has been rejected and the Jacobian is being re-calculated.
:math:`\mathrm{istate} = -6` to :math:`-1`
An internal error exit has caused the rejection of the current set of argument values, :math:`p`. :math:`{-\mathrm{istate}}` is the value which :math:`\mathrm{istate}` would have taken if the error had not occurred.
:math:`\mathrm{istate} = -7`
An internal error exit has occurred when calculating the initial Jacobian.
**iflag** : int
Whether or not the Jacobian being used has been calculated at the beginning of the current iteration. If the Jacobian has been updated then :math:`\mathrm{iflag} = 1`; otherwise :math:`\mathrm{iflag} = 2`. The Jacobian is only calculated when convergence to the current argument values has been slow.
**ifail1** : int
If :math:`-6\leq \mathrm{istate}\leq -1`, :math:`\mathrm{ifail1}` specifies the :math:`\textit{errno}` error number that would be produced were control returned to you. :math:`\mathrm{ifail1}` is unspecified for values of :math:`\mathrm{istate}` outside this range.
**p** : float, ndarray, shape :math:`\left(m\right)`
The current estimate of the :math:`\textit{i}`\ th argument :math:`p_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,m`.
**f** : float, ndarray, shape :math:`\left(m\right)`
:math:`r`, the residual corresponding to the current argument values, provided :math:`1\leq \mathrm{istate}\leq 5` or :math:`\mathrm{istate} = -7`. :math:`\mathrm{f}` is unspecified for other values of :math:`\mathrm{istate}`.
**pnorm** : float
A quantity against which all reductions in norm are currently measured.
**pnorm1** : float
:math:`p`, the norm of the current arguments. It is set for :math:`1\leq \mathrm{istate}\leq 5` and is undefined for other values of :math:`\mathrm{istate}`.
**eps** : float
Gives some indication of the convergence rate. It is the current singular value modification factor (see Gay (1976)). It is zero initially and whenever convergence is proceeding steadily. :math:`\mathrm{eps}` is :math:`\epsilon^{{3/8}}` or greater (where :math:`\epsilon` may in most cases be considered machine precision) when the singular values of :math:`J` are approximately zero or when convergence is not being achieved. The larger the value of :math:`\mathrm{eps}` the worse the convergence rate. When :math:`\mathrm{eps}` becomes too large the Newton iteration is terminated.
**d** : float, ndarray, shape :math:`\left(m\right)`
:math:`J`, the singular values of the current modified Jacobian matrix. If :math:`\mathrm{d}[m-1]` is small relative to :math:`\mathrm{d}[0]` for a number of Jacobians corresponding to different argument values then the computed results should be viewed with suspicion. It could be that the matching equations do not depend significantly on some argument (which could be due to a programming error in :math:`\mathrm{fcn}`, :math:`\mathrm{bc}`, :math:`\mathrm{brkpts}` or :math:`\mathrm{eqn}`). Alternatively, the system of differential equations may be very ill-conditioned when viewed as an initial value problem, in which case ``bvp_shoot_genpar_algeq`` is unsuitable. This may also be indicated by some singular values being very large. These values of :math:`\mathrm{d}[\textit{i}-1]`, for :math:`\textit{i} = 1,2,\ldots,m`, should not be changed.
**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.
**prsol** : None or callable z = prsol(z, y, data=None), optional
Note: if this argument is **None** then a NAG-supplied facility will be used.
:math:`\mathrm{prsol}` can be used to obtain values of the solution :math:`y` at a selected point :math:`z` by integration across the final range :math:`\left[\mathrm{x}[0], \mathrm{x}[ \mathrm{npoint} -1]\right]`.
If no output is required **None** can be used as the actual argument.
**Parameters**
**z** : float
Contains :math:`x_1` on the first call. On subsequent calls :math:`\mathrm{z}` contains its previous output value.
**y** : float, ndarray, shape :math:`\left(n\right)`
The solution value :math:`y_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n`, at :math:`z`.
**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.
**Returns**
**z** : float
The next point at which output is required. The new point must be nearer :math:`\mathrm{x}[\mathrm{npoint}-1]` than the old.
If :math:`\mathrm{z}` is set to a point outside :math:`\left[\mathrm{x}[0], \mathrm{x}[ \mathrm{npoint} -1]\right]` the process stops and control returns from ``bvp_shoot_genpar_algeq`` to the (sub)program from which ``bvp_shoot_genpar_algeq`` is called.
Otherwise the next call to :math:`\mathrm{prsol}` is made by ``bvp_shoot_genpar_algeq`` at the point :math:`\mathrm{z}`, with solution values :math:`y_1,y_2,\ldots,y_n` at :math:`\mathrm{z}` contained in :math:`\mathrm{y}`.
If :math:`\mathrm{z}` is set to :math:`\mathrm{x}[\mathrm{npoint}-1]` exactly, the final call to :math:`\mathrm{prsol}` is made with :math:`y_1,y_2,\ldots,y_n` as values of the solution at :math:`\mathrm{x}[\mathrm{npoint}-1]` produced by the integration.
In general the solution values obtained at :math:`\mathrm{x}[\mathrm{npoint}-1]` from :math:`\mathrm{prsol}` will differ from the values obtained at this point by a call to :math:`\mathrm{bc}`.
The difference between the two solutions is the residual :math:`r`.
You are reminded that the points :math:`\mathrm{x}[0],\mathrm{x}[1],\ldots,\mathrm{x}[\mathrm{npoint}-1]` are available in the locations :math:`\mathrm{swp}[0,3],\mathrm{swp}[1,3],\ldots,\mathrm{swp}[\mathrm{npoint}-1,3]` at all times.
**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(m\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.
**pf** : float, ndarray, shape :math:`\left(m\right)`
The values actually used.
**dp** : float, ndarray, shape :math:`\left(m\right)`
The values actually used.
**swp** : float, ndarray, shape :math:`\left(\textit{npoint}, 6\right)`
:math:`\mathrm{swp}[\textit{i}-1,0]` contains the initial step size used on the last integration on :math:`\left[\mathrm{x}[ \textit{i} -1], \mathrm{x}[ \textit{i} + 1 -1]\right]`, for :math:`\textit{i} = 1,2,\ldots,\textit{npoint}-1`, (excluding integrations during the calculation of the Jacobian).
:math:`\mathrm{swp}[\textit{i}-1,1]`, for :math:`\textit{i} = 1,2,\ldots,\textit{npoint}-1`, is usually unchanged.
If the maximum step size :math:`\mathrm{swp}[i-1,1]` is so small or the length of the range :math:`\left[\mathrm{x}[ i -1], \mathrm{x}[ i + 1 -1]\right]` is so short that on the last integration the step size was not controlled in the main by the size of the error tolerances :math:`\mathrm{e}[i-1]` but by these other factors, :math:`\mathrm{swp}[\textit{npoint}-1,1]` is set to the floating-point value of :math:`i` if the problem last occurred in :math:`\left[\mathrm{x}[ i -1], \mathrm{x}[ i + 1 -1]\right]`.
Any results obtained when this value is returned as nonzero should be viewed with caution.
:math:`\mathrm{swp}[\textit{i}-1,2]`, for :math:`\textit{i} = 1,2,\ldots,\textit{npoint}-1`, are unchanged.
If an error exit with :math:`\mathrm{errno}` = 4, 5 or 6 (see :ref:`Exceptions <d02sa-py2-py-errors>`) occurs on the integration made from :math:`\mathrm{x}[i-1]` to :math:`\mathrm{x}[i]` the floating-point value of :math:`i` is returned in :math:`\mathrm{swp}[\textit{npoint}-1,0]`.
The actual point :math:`x \in \left[\mathrm{x}[ i -1], \mathrm{x}[ i + 1 -1]\right]` where the error occurred is returned in :math:`\mathrm{swp}[0,4]` (see also the specification of :math:`\mathrm{w}`).
The floating-point value of :math:`\textit{npoint}` is returned in :math:`\mathrm{swp}[\textit{npoint}-1,0]` if the error exit is caused by a call to :math:`\mathrm{bc}`.
If an error exit occurs when estimating the Jacobian matrix (:math:`\mathrm{errno}` = 7, 8, 9, 10, 11 or 12, see :ref:`Exceptions <d02sa-py2-py-errors>`) and if argument :math:`p_i` was the cause of the failure then on exit :math:`\mathrm{swp}[\textit{npoint}-1,0]` contains the floating-point value of :math:`i`.
:math:`\mathrm{swp}[\textit{i}-1,3]` contains the point :math:`\mathrm{x}[\textit{i}-1]`, for :math:`\textit{i} = 1,2,\ldots,\textit{npoint}`, used at the solution :math:`p` or at the final values of :math:`p` if an error occurred.
:math:`\mathrm{swp}` is also partly used as workspace.
**w** : float, ndarray, shape :math:`\left(\max\left(\mathrm{n},m\right), 3\times m+12+\max\left(11,m\right)\right)`
In the case of an error exit of the type where the point of failure is returned in :math:`\mathrm{swp}[0,4]`, the solution at this point of failure is returned in :math:`\mathrm{w}[\textit{i}-1,0]`, for :math:`\textit{i} = 1,2,\ldots,n`.
Otherwise :math:`\mathrm{w}` is used for workspace.
.. _d02sa-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, an element of the parameter convergence control array is zero or negative.
(`errno` :math:`1`)
On entry an element of the local error control array is zero or negative.
(`errno` :math:`1`)
On entry, :math:`\mathrm{ymax} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{ymax}\geq 0.0`.
(`errno` :math:`1`)
On entry, :math:`\textit{npoint} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\textit{npoint}\geq 2`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{icount} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{icount}\geq 0`.
(`errno` :math:`1`)
On entry, :math:`m = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{n1} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`m\geq \mathrm{n1}`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{n} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{n1} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{n}\geq \mathrm{n1}`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{n1} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{n1}\geq 1`.
(`errno` :math:`2`)
The constraints have been violated by the initial parameters.
(`errno` :math:`3`)
The sequence of break-points is not strictly monotonic in their initial specification.
(`errno` :math:`4`)
In the integration from first to last break-point with initial or final parameters, the step size was reduced too far for the integration to proceed. Consider reversing the order of break-points or relaxing the local error control. If this error exit still results, either this function is not a suitable method for solving the problem, or the initial choice of parameters is very poor.
(`errno` :math:`5`)
In the integration from first to last break-point with initial or final parameters, a suitable initial step could not be found on one of the intervals. Consider reversing the order of break-points or relaxing the local error control. If this error exit still results, either this function is not suitable for solving the problem, or the initial choice of parameters is very poor.
(`errno` :math:`6`)
During integration the solution exceeded :math:`\mathrm{ymax}` in magnitude, where, on entry, :math:`\mathrm{ymax} = \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`7`)
On calculating the initial approximation to the Jacobian, the constraints were violated.
(`errno` :math:`8`)
On perturbing the parameters when calculating the initial approximation to the Jacobian, the monotonicity condition on break-points is violated.
(`errno` :math:`9`)
An initial step-length could be found for integration to proceed with the current parameters.
(`errno` :math:`10`)
The step-length required to calculate the Jacobian to sufficient accuracy is too small.
(`errno` :math:`11`)
On calculating the initial approximation to the Jacobian, the solution to the system of differential equations exceeded :math:`\mathrm{ymax}` in magnitude, where, on entry, :math:`\mathrm{ymax} = \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`12`)
The Jacobian has an insignificant column. Make sure that the solution vector depends on all the parameters.
(`errno` :math:`13`)
An internal singular value decomposition has failed. This error can be avoided by changing the initial parameter estimates.
(`errno` :math:`14`)
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:`15`)
The number of iterations permitted by :math:`\mathrm{icount}` has been exceeded where this was set to a positive value on entry. :math:`\mathrm{icount} = \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`16`)
Internal error in calculating Jacobian. Please contact `NAG <https://www.nag.com>`__.
(`errno` :math:`17`)
Internal error in calculating residual. Please contact `NAG <https://www.nag.com>`__.
(`errno` :math:`18`)
Internal error in integration. Please contact `NAG <https://www.nag.com>`__.
(`errno` :math:`19`)
Internal error in Newton method. Please contact `NAG <https://www.nag.com>`__.
.. _d02sa-py2-py-notes:
**Notes**
`No equivalent traditional C interface for this routine exists in the NAG Library.`
``bvp_shoot_genpar_algeq`` solves a two-point boundary value problem for a system of :math:`n` first-order ordinary differential equations with separated boundary conditions by determining certain unknown arguments :math:`p_1,p_2,\ldots,p_m`. (There may also be additional algebraic equations to be solved in the determination of the arguments and, if so, these equations are defined by :math:`\mathrm{eqn}`.) The arguments may be, but need not be, boundary values; they may include eigenvalues, arguments in the coefficients of the differential equations, coefficients in series expansions or asymptotic expansions for boundary values, the length of the range of definition of the system of differential equations, etc.
It is assumed that we have a system of :math:`n` differential equations of the form
.. math::
y^{\prime } = f\left(x, y, p\right)\text{,}
where :math:`p = {\left(p_1, p_2, \ldots, p_m\right)}^\mathrm{T}` is the vector of arguments, and that the derivative :math:`f` is evaluated by :math:`\mathrm{fcn}`.
Also, :math:`n_1` of the equations are assumed to depend on :math:`p`.
For :math:`n_1 < n` the :math:`n-n_1` equations of the system are not involved in the matching process.
These are the driving equations; they should be independent of :math:`p` and of the solution of the other :math:`n_1` equations.
In numbering the equations in :math:`\mathrm{fcn}` and :math:`\mathrm{bc}` the driving equations must be put **first** (as they naturally occur in most applications).
The range of definition [:math:`a,b`] of the differential equations is defined by :math:`\mathrm{brkpts}` and may depend on the arguments :math:`p_1,p_2,\ldots,p_m` (that is, on :math:`p`). :math:`\mathrm{brkpts}` must define the points :math:`x_1,x_2,\ldots,x_{\textit{npoint}}`, :math:`\textit{npoint}\geq 2`, which must satisfy
.. math::
a = x_1 < x_2 < \cdots < x_{\textit{npoint}} = b
(or a similar relationship with all the inequalities reversed).
If :math:`\textit{npoint} > 2` the points :math:`x_1,x_2,\ldots,x_{\textit{npoint}}` can be used to break up the range of definition.
Integration is restarted at each of these points.
This means that the differential equations `(1) <https://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02saf.html#eqn1>`__ can be defined differently in each sub-interval :math:`\left[x_{\textit{i}}, x_{{\textit{i}+1}}\right]`, for :math:`\textit{i} = 1,2,\ldots,\textit{npoint}-1`.
Also, since initial and maximum integration step sizes can be supplied on each sub-interval (via the array :math:`\mathrm{swp}`), you can indicate parts of the range :math:`\left[a, b\right]` where the solution :math:`y\left(x\right)` may be difficult to obtain accurately and can take appropriate action.
The boundary conditions may also depend on the arguments and are applied at :math:`a = x_1` and :math:`b = x_{\textit{npoint}}`.
They are defined (in :math:`\mathrm{bc}`) in the form
.. math::
y\left(a\right) = g_1\left(p\right), > y\left(b\right) = g_2\left(p\right)\text{.}
The boundary value problem is solved by determining the unknown arguments :math:`p` by a shooting and matching technique.
The differential equations are always integrated from :math:`a` to :math:`b` with initial values :math:`y\left(a\right) = g_1\left(p\right)`.
The solution vector thus obtained at :math:`x = b` is subtracted from the vector :math:`g_2\left(p\right)` to give the :math:`n_1` residuals :math:`r_1\left(p\right)`, ignoring the first :math:`n-n_1`, driving equations.
Because the direction of integration is always from :math:`a` to :math:`b`, it is unnecessary, in :math:`\mathrm{bc}`, to supply values for the first :math:`n-n_1` boundary values at :math:`b`, that is the first :math:`n-n_1` components of :math:`g_2` in `(3) <https://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02saf.html#eqn3>`__.
For :math:`n_1 < m` then :math:`r_1\left(p\right)`.
Together with the :math:`m-n_1` equations defined by :math:`\mathrm{eqn}`,
.. math::
r_2\left(p\right) = 0\text{,}
these give a vector of residuals :math:`r`, which at the solution, :math:`p`, must satisfy
.. math::
\begin{pmatrix}r_1\left(p\right)\\r_2\left(p\right)\end{pmatrix} = 0\text{.}
These equations are solved by a pseudo-Newton iteration which uses a modified singular value decomposition of :math:`J = \frac{{\partial r}}{{\partial p}}` when solving the linear equations which arise.
The Jacobian :math:`J` used in Newton's method is obtained by numerical differentiation.
The arguments at each Newton iteration are accepted only if the norm :math:`\left\lVert D^{-1}\tilde{J}^+r\right\rVert_2` is much reduced from its previous value.
Here :math:`\tilde{J}^+` is the pseudo-inverse, calculated from the singular value decomposition, of a modified version of the Jacobian :math:`J` (:math:`J^+` is actually the inverse of the Jacobian in well-conditioned cases). :math:`D` is a diagonal matrix with
.. math::
d_{{ii}} = \mathrm{max}\left({\left\lvert p_i\right\rvert }, {\mathrm{pf}[i]}\right)
where :math:`\mathrm{pf}` is an array of floor values.
See Deuflhard (1974) for further details of the variants of Newton's method used, Gay (1976) for the modification of the singular value decomposition and Gladwell (1979) for an overview of the method used.
Two facilities are provided to prevent the pseudo-Newton iteration running into difficulty.
First, you are permitted to specify constraints on the values of the arguments :math:`p` via a :math:`\mathrm{constr}`.
These constraints are only used to prevent the Newton iteration using values for :math:`p` which would violate them; that is, they are not used to determine the values of :math:`p`.
Secondly, you are permitted to specify a maximum value :math:`y_{\mathrm{max}}` for :math:`\left\lVert y\left(x\right)\right\rVert_\infty` at all points in the range :math:`\left[a, b\right]`.
It is intended that this facility be used to prevent machine 'overflow' in the integrations of equation `(1) <https://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02saf.html#eqn1>`__ due to poor choices of the arguments :math:`p` which might arise during the Newton iteration.
When using this facility, it is presumed that you have an estimate of the likely size of :math:`\left\lVert y\left(x\right)\right\rVert_\infty` at all points :math:`x \in \left[a, b\right]`. :math:`y_{\mathrm{max}}` should then be chosen rather larger (say by a factor of :math:`10`) than this estimate.
You are strongly advised to set :math:`\mathrm{monlev}` to monitor the progress of the pseudo-Newton iteration.
You can output the solution of the problem :math:`y\left(x\right)` by supplying a suitable :math:`\mathrm{prsol}`.
``bvp_shoot_genpar_algeq`` is designed to try all possible options before admitting failure and returning to you.
Provided the function can start the Newton iteration from the initial point :math:`p` it will exhaust all the options available to it (though you can override this by specifying a maximum number of iterations to be taken).
The fact that all its options have been exhausted is the only error exit from the iteration.
Other error exits are possible, however, whilst setting up the Newton iteration and when computing the final solution.
If you require more background information about the solution of boundary value problems by shooting methods you are recommended to read the appropriate modules of Hall and Watt (1976), and for a detailed description of ``bvp_shoot_genpar_algeq`` Gladwell (1979) is recommended.
.. _d02sa-py2-py-references:
**References**
Deuflhard, P, 1974, `A modified Newton method for the solution of ill-conditioned systems of nonlinear equations with application to multiple shooting`, Numer. Math. (22), 289--315
Gay, D, 1976, `On modifying singular values to solve possibly singular systems of nonlinear equations`, Working Paper 125, Computer Research Centre, National Bureau for Economics and Management Science, Cambridge, MA
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
Hall, G and Watt, J M (ed.), 1976, `Modern Numerical Methods for Ordinary Differential Equations`, Clarendon Press, Oxford
"""
raise NotImplementedError
[docs]def bvp_coll_nth_comp(m, l, x0, x1, k1, kp, coeff, bdyc, data=None, spiked_sorder='C'):
r"""
``bvp_coll_nth_comp`` solves a system of linear ordinary differential equations by least squares fitting of a series of Chebyshev polynomials using collocation.
.. _d02tg-py2-py-doc:
For full information please refer to the NAG Library document for d02tg
https://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02tgf.html
.. _d02tg-py2-py-parameters:
**Parameters**
**m** : int, array-like, shape :math:`\left(n\right)`
:math:`\mathrm{m}[\textit{i}]` must be set to the highest order derivative occurring in the :math:`\textit{i}`\ th equation, for :math:`\textit{i} = 1,2,\ldots,n`.
**l** : int, array-like, shape :math:`\left(n\right)`
:math:`\mathrm{l}[\textit{i}]` must be set to the number of boundary conditions associated with the :math:`\textit{i}`\ th equation, for :math:`\textit{i} = 1,2,\ldots,n`.
**x0** : float
The left-hand boundary, :math:`x_0`.
**x1** : float
The right-hand boundary, :math:`x_1`.
**k1** : int
The number of coefficients, :math:`k_1`, 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, :math:`k_p`.
**coeff** : callable (a, rhs) = coeff(x, i, a, rhs, data=None)
:math:`\mathrm{coeff}` defines the system of differential equations (see :ref:`Notes <d02tg-py2-py-notes>`).
It must evaluate the coefficient functions :math:`f_{{kj}}^i\left(x\right)` and the right-hand side function :math:`r^i\left(x\right)` of the :math:`i`\ th equation at a given point.
Only nonzero entries of the array :math:`\mathrm{a}` and :math:`\mathrm{rhs}` need be specifically assigned, since all elements are set to zero by ``bvp_coll_nth_comp`` before calling :math:`\mathrm{coeff}`.
**Parameters**
**x** : float
:math:`x`, the point at which the functions must be evaluated.
**i** : int
The equation for which the coefficients and right-hand side are to be evaluated.
**a** : float, ndarray, shape :math:`\left(\textit{ia}, \textit{ia1}\right)`
All elements of :math:`\mathrm{a}` are set to zero.
**rhs** : float
Is set to zero.
**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.
**Returns**
**a** : float, array-like, shape :math:`\left(\textit{ia}, \textit{ia1}\right)`
:math:`\mathrm{a}[k-1,j-1]` must contain the value :math:`f_{{kj}}^i\left(x\right)`, for :math:`1\leq k\leq n`, :math:`1\leq j\leq m_i+1`.
**rhs** : float
It must contain the value :math:`r^i\left(x\right)`.
**bdyc** : callable (x, a, rhs) = bdyc(i, j, a, rhs, data=None)
:math:`\mathrm{bdyc}` defines the boundary conditions (see :ref:`Notes <d02tg-py2-py-notes>`).
It must evaluate the coefficient functions :math:`f_{{kj}}^{{ij}}` and right-hand side function :math:`r^{{ij}}` in the :math:`j`\ th boundary condition associated with the :math:`i`\ th equation, at the point :math:`x^{{ij}}` at which the boundary condition is applied.
Only nonzero entries of the array :math:`\mathrm{a}` and :math:`\mathrm{rhs}` need be specifically assigned, since all elements are set to zero by ``bvp_coll_nth_comp`` before calling :math:`\mathrm{bdyc}`.
**Parameters**
**i** : int
The differential equation with which the condition is associated.
**j** : int
The boundary condition for which the coefficients and right-hand side are to be evaluated.
**a** : float, ndarray, shape :math:`\left(\textit{ia}, \textit{ia1}\right)`
All elements of :math:`\mathrm{a}` are set to zero.
**rhs** : float
Is set to zero.
**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.
**Returns**
**x** : float
:math:`x^{{ij}}`, the value at which the boundary condition is applied.
**a** : float, array-like, shape :math:`\left(\textit{ia}, \textit{ia1}\right)`
The value :math:`f_{{kj}}^{{ij}}\left(x^{{ij}}\right)`, for :math:`1\leq k\leq n`, :math:`1\leq j\leq m_i+1`.
**rhs** : float
The value :math:`r^{{ij}}\left(x^{{ij}}\right)`.
**data** : arbitrary, optional
User-communication data for callback functions.
**spiked_sorder** : str, optional
If :math:`\mathrm{a}` in :math:`\mathrm{bdyc}` or :math:`\mathrm{a}` in :math:`\mathrm{coeff}` 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.
**Returns**
**c** : float, ndarray, shape :math:`\left(\mathrm{k1}, n\right)`
The :math:`k`\ th column of :math:`\mathrm{c}` contains 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}}^{k_1}\mathrm{c}[i-1,k-1]T_{{i-1}}\left(x\right)\text{, }\quad 1\leq k\leq n\text{,}
where :math:`T_i\left(x\right)` is the Chebyshev polynomial of the first kind and :math:`{\sum^\prime}` denotes that the first coefficient, :math:`\mathrm{c}[0,k-1]`, is halved.
.. _d02tg-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` and :math:`\mathrm{max}\left(\mathrm{m}[i-1]\right) = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{k1}\geq 1+\mathrm{max}\left(\mathrm{m}[i-1]\right)`.
(`errno` :math:`1`)
On entry, one of the equations is of order less than :math:`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, a negative number of boundary conditions was set for one of the system equations.
(`errno` :math:`1`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`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.
.. _d02tg-py2-py-notes:
**Notes**
`No equivalent traditional C interface for this routine exists in the NAG Library.`
``bvp_coll_nth_comp`` calculates an approximate solution of a linear or linearized system of ordinary differential equations as a Chebyshev series.
Suppose there are :math:`n` differential equations for :math:`n` variables :math:`y_1,y_2,\ldots,y_n`, over the range :math:`\left(x_0, x_1\right)`.
Let the :math:`i`\ th equation be
.. math::
\sum_{{j = 1}}^{{m_i+1}}\sum_{{k = 1}}^nf_{{kj}}^i\left(x\right)y_k^{\left(j-1\right)}\left(x\right) = r^i\left(x\right)
where :math:`y_k^{\left(j\right)}\left(x\right) = \frac{{d^jy_k\left(x\right)}}{{dx^j}}`. :math:`\mathrm{coeff}` evaluates the coefficients :math:`f_{{kj}}^i\left(x\right)` and the right-hand side :math:`r^i\left(x\right)` for each :math:`i`, :math:`1\leq i\leq n`, at any point :math:`x`.
The boundary conditions may be applied either at the end points or at intermediate points; they are written in the same form as the differential equations, and specified by :math:`\mathrm{bdyc}`.
For example the :math:`j`\ th boundary condition out of those associated with the :math:`i`\ th differential equation takes the form
.. math::
\sum_{{j = 1}}^{{l_i+1}}\sum_{{k = 1}}^nf_{{kj}}^{{ij}}\left(x^{{ij}}\right)y_k^{\left(j-1\right)}\left(x^{{ij}}\right) = r^{{ij}}\left(x^{{ij}}\right)\text{,}
where :math:`x^{{ij}}` lies between :math:`x_0` and :math:`x_1`.
It is assumed in this function that certain of the boundary conditions are associated with each differential equation.
This is for your convenience; the grouping does not affect the results.
The degree of the polynomial solution must be the same for all variables.
You specify the degree required, :math:`k_1-1`, and the number of collocation points, :math:`k_p`, in the range.
The function sets up a system of linear equations for the Chebyshev coefficients, with :math:`n` equations for each collocation point and one for each boundary condition.
The collocation points are chosen at the extrema of a shifted Chebyshev polynomial of degree :math:`k_p-1`.
The boundary conditions are satisfied exactly, and the remaining equations are solved by a least squares method.
The result produced is a set of Chebyshev coefficients for the :math:`n` functions :math:`y_1,y_2,\ldots,y_n`, with the range 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 range :math:`\left[x_0, x_1\right]`. :meth:`fit.dim1_cheb_deriv <naginterfaces.library.fit.dim1_cheb_deriv>` and :meth:`fit.dim1_cheb_integ <naginterfaces.library.fit.dim1_cheb_integ>` may be used to obtain Chebyshev series representations of derivatives and integrals (respectively) of the components of the solution.
.. _d02tg-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_nlin_solve(ffun, fjac, gafun, gbfun, gajac, gbjac, guess, comm, data=None, spiked_sorder='C'):
r"""
``bvp_coll_nlin_solve`` solves a general two-point boundary value problem for a nonlinear mixed order system of ordinary differential equations.
.. _d02tl-py2-py-doc:
For full information please refer to the NAG Library document for d02tl
https://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02tlf.html
.. _d02tl-py2-py-parameters:
**Parameters**
**ffun** : callable f = ffun(x, y, m, data=None)
:math:`\mathrm{ffun}` must evaluate the functions :math:`f_i` for given values :math:`x,z\left(y\left(x\right)\right)`.
**Parameters**
**x** : float
:math:`x`, the independent variable.
**y** : float, ndarray, shape :math:`\left(\textit{neq}, :\right)`
:math:`\mathrm{y}[\textit{i}-1,\textit{j}]` contains :math:`y_{\textit{i}}^{\left(\textit{j}\right)}\left(x\right)`, for :math:`\textit{j} = 0,1,\ldots,\mathrm{m}[\textit{i}-1]-1`, for :math:`\textit{i} = 1,2,\ldots,\textit{neq}`.
**Note:** :math:`y_i^{\left(0\right)}\left(x\right) = y_i\left(x\right)`.
**m** : int, ndarray, shape :math:`\left(\textit{neq}\right)`
:math:`\mathrm{m}[\textit{i}-1]` contains :math:`m_{\textit{i}}`, the order of the :math:`\textit{i}`\ th differential equation, for :math:`\textit{i} = 1,2,\ldots,\textit{neq}`.
**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.
**Returns**
**f** : float, array-like, shape :math:`\left(\textit{neq}\right)`
:math:`\mathrm{f}[\textit{i}-1]` must contain :math:`f_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,\textit{neq}`.
**fjac** : callable dfdy = fjac(x, y, m, dfdy, data=None)
:math:`\mathrm{fjac}` must evaluate the partial derivatives of :math:`f_i` with respect to the elements of
:math:`z\left(y\left(x\right)\right) = \left({y_1\left(x\right)}, {y_1^1\left(x\right)}, \ldots, {y_1^{\left(m_1-1\right)}\left(x\right)}, {y_2\left(x\right)}, \ldots, {y_n^{\left(m_n-1\right)}\left(x\right)}\right)`.
**Parameters**
**x** : float
:math:`x`, the independent variable.
**y** : float, ndarray, shape :math:`\left(\textit{neq}, :\right)`
:math:`\mathrm{y}[\textit{i}-1,\textit{j}]` contains :math:`y_{\textit{i}}^{\left(\textit{j}\right)}\left(x\right)`, for :math:`\textit{j} = 0,1,\ldots,\mathrm{m}[\textit{i}-1]-1`, for :math:`\textit{i} = 1,2,\ldots,\textit{neq}`.
**Note:** :math:`y_i^{\left(0\right)}\left(x\right) = y_i\left(x\right)`.
**m** : int, ndarray, shape :math:`\left(\textit{neq}\right)`
:math:`\mathrm{m}[\textit{i}-1]` contains :math:`m_{\textit{i}}`, the order of the :math:`\textit{i}`\ th differential equation, for :math:`\textit{i} = 1,2,\ldots,\textit{neq}`.
**dfdy** : float, ndarray, shape :math:`\left(\textit{neq}, \textit{neq}, :\right)`
Set to zero.
**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.
**Returns**
**dfdy** : float, array-like, shape :math:`\left(\textit{neq}, \textit{neq}, :\right)`
:math:`\mathrm{dfdy}[\textit{i}-1,\textit{j}-1,\textit{k}]` must contain the partial derivative of :math:`f_{\textit{i}}` with respect to :math:`y_{\textit{j}}^{\left(\textit{k}\right)}`, for :math:`\textit{k} = 0,1,\ldots,\mathrm{m}[\textit{j}-1]-1`, for :math:`\textit{j} = 1,2,\ldots,\textit{neq}`, for :math:`\textit{i} = 1,2,\ldots,\textit{neq}`. Only nonzero partial derivatives need be set.
**gafun** : callable ga = gafun(ya, m, nlbc, data=None)
:math:`\mathrm{gafun}` must evaluate the boundary conditions at the left-hand end of the range, that is functions :math:`g_i\left(z\left(y\left(a\right)\right)\right)` for given values of :math:`z\left(y\left(a\right)\right)`.
**Parameters**
**ya** : float, ndarray, shape :math:`\left(\textit{neq}, :\right)`
:math:`\mathrm{ya}[\textit{i}-1,\textit{j}]` contains :math:`y_{\textit{i}}^{\left(\textit{j}\right)}\left(a\right)`, for :math:`\textit{j} = 0,1,\ldots,\mathrm{m}[\textit{i}-1]-1`, for :math:`\textit{i} = 1,2,\ldots,\textit{neq}`.
**Note:** :math:`y_i^{\left(0\right)}\left(a\right) = y_i\left(a\right)`.
**m** : int, ndarray, shape :math:`\left(\textit{neq}\right)`
:math:`\mathrm{m}[\textit{i}-1]` contains :math:`m_{\textit{i}}`, the order of the :math:`\textit{i}`\ th differential equation, for :math:`\textit{i} = 1,2,\ldots,\textit{neq}`.
**nlbc** : int
The number of boundary conditions at :math:`a`.
**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.
**Returns**
**ga** : float, array-like, shape :math:`\left(\mathrm{nlbc}\right)`
:math:`\mathrm{ga}[\textit{i}-1]` must contain :math:`g_{\textit{i}}\left(z\left(y\left(a\right)\right)\right)`, for :math:`\textit{i} = 1,2,\ldots,\mathrm{nlbc}`.
**gbfun** : callable gb = gbfun(yb, m, nrbc, data=None)
:math:`\mathrm{gbfun}` must evaluate the boundary conditions at the right-hand end of the range, that is functions :math:`\bar{g}_i\left(z\left(y\left(b\right)\right)\right)` for given values of :math:`z\left(y\left(b\right)\right)`.
**Parameters**
**yb** : float, ndarray, shape :math:`\left(\textit{neq}, :\right)`
:math:`\mathrm{yb}[\textit{i}-1,\textit{j}]` contains :math:`y_{\textit{i}}^{\left(\textit{j}\right)}\left(b\right)`, for :math:`\textit{j} = 0,1,\ldots,\mathrm{m}[\textit{i}-1]-1`, for :math:`\textit{i} = 1,2,\ldots,\textit{neq}`.
**Note:** :math:`y_i^{\left(0\right)}\left(b\right) = y_i\left(b\right)`.
**m** : int, ndarray, shape :math:`\left(\textit{neq}\right)`
:math:`\mathrm{m}[\textit{i}-1]` contains :math:`m_{\textit{i}}`, the order of the :math:`\textit{i}`\ th differential equation, for :math:`\textit{i} = 1,2,\ldots,\textit{neq}`.
**nrbc** : int
The number of boundary conditions at :math:`b`.
**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.
**Returns**
**gb** : float, array-like, shape :math:`\left(\mathrm{nrbc}\right)`
:math:`\mathrm{gb}[\textit{i}-1]` must contain :math:`\bar{g}_{\textit{i}}\left(z\left(y\left(b\right)\right)\right)`, for :math:`\textit{i} = 1,2,\ldots,\mathrm{nrbc}`.
**gajac** : callable dgady = gajac(ya, m, dgady, data=None)
:math:`\mathrm{gajac}` must evaluate the partial derivatives of :math:`g_i\left(z\left(y\left(a\right)\right)\right)` with respect to the elements of :math:`z\left(y\left(a\right)\right) = \left({y_1\left(a\right)}, {y_1^1\left(a\right)}, \ldots, {y_1^{\left(m_1-1\right)}\left(a\right)}, {y_2\left(a\right)}, \ldots, {y_n^{\left(m_n-1\right)}\left(a\right)}\right)`.
**Parameters**
**ya** : float, ndarray, shape :math:`\left(\textit{neq}, :\right)`
:math:`\mathrm{ya}[\textit{i}-1,\textit{j}]` contains :math:`y_{\textit{i}}^{\left(\textit{j}\right)}\left(a\right)`, for :math:`\textit{j} = 0,1,\ldots,\mathrm{m}[\textit{i}-1]-1`, for :math:`\textit{i} = 1,2,\ldots,\textit{neq}`.
**Note:** :math:`y_i^{\left(0\right)}\left(a\right) = y_i\left(a\right)`.
**m** : int, ndarray, shape :math:`\left(\textit{neq}\right)`
:math:`\mathrm{m}[\textit{i}-1]` contains :math:`m_{\textit{i}}`, the order of the :math:`\textit{i}`\ th differential equation, for :math:`\textit{i} = 1,2,\ldots,\textit{neq}`.
**dgady** : float, ndarray, shape :math:`\left(\textit{nlbc}, \textit{neq}, :\right)`
Set to zero.
**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.
**Returns**
**dgady** : float, array-like, shape :math:`\left(\textit{nlbc}, \textit{neq}, :\right)`
:math:`\mathrm{dgady}[\textit{i}-1,\textit{j}-1,\textit{k}]` must contain the partial derivative of :math:`g_{\textit{i}}\left(z\left(y\left(a\right)\right)\right)` with respect to :math:`y_{\textit{j}}^{\left(\textit{k}\right)}\left(a\right)`, for :math:`\textit{k} = 0,1,\ldots,\mathrm{m}[\textit{j}-1]-1`, for :math:`\textit{j} = 1,2,\ldots,\textit{neq}`, for :math:`\textit{i} = 1,2,\ldots,\mathrm{nlbc}`. Only nonzero partial derivatives need be set.
**gbjac** : callable dgbdy = gbjac(yb, m, dgbdy, data=None)
:math:`\mathrm{gbjac}` must evaluate the partial derivatives of :math:`\bar{g}_i\left(z\left(y\left(b\right)\right)\right)` with respect to the elements of :math:`z\left(y\left(b\right)\right) = \left({y_1\left(b\right)}, {y_1^1\left(b\right)}, \ldots, {y_1^{\left(m_1-1\right)}\left(b\right)}, {y_2\left(b\right)}, \ldots, {y_n^{\left(m_n-1\right)}\left(b\right)}\right)`.
**Parameters**
**yb** : float, ndarray, shape :math:`\left(\textit{neq}, :\right)`
:math:`\mathrm{yb}[\textit{i}-1,\textit{j}]` contains :math:`y_{\textit{i}}^{\left(\textit{j}\right)}\left(b\right)`, for :math:`\textit{j} = 0,1,\ldots,\mathrm{m}[\textit{i}-1]-1`, for :math:`\textit{i} = 1,2,\ldots,\textit{neq}`.
**Note:** :math:`y_i^{\left(0\right)}\left(b\right) = y_i\left(b\right)`.
**m** : int, ndarray, shape :math:`\left(\textit{neq}\right)`
:math:`\mathrm{m}[\textit{i}-1]` contains :math:`m_{\textit{i}}`, the order of the :math:`\textit{i}`\ th differential equation, for :math:`\textit{i} = 1,2,\ldots,\textit{neq}`.
**dgbdy** : float, ndarray, shape :math:`\left(\textit{nrbc}, \textit{neq}, :\right)`
Set to zero.
**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.
**Returns**
**dgbdy** : float, array-like, shape :math:`\left(\textit{nrbc}, \textit{neq}, :\right)`
:math:`\mathrm{dgbdy}[\textit{i}-1,\textit{j}-1,\textit{k}]` must contain the partial derivative of :math:`\bar{g}_{\textit{i}}\left(z\left(y\left(b\right)\right)\right)` with respect to :math:`y_{\textit{j}}^{\left(\textit{k}\right)}\left(b\right)`, for :math:`\textit{k} = 0,1,\ldots,\mathrm{m}[\textit{j}-1]-1`, for :math:`\textit{j} = 1,2,\ldots,\textit{neq}`, for :math:`\textit{i} = 1,2,\ldots,\mathrm{nrbc}`. Only nonzero partial derivatives need be set.
**guess** : callable (y, dym) = guess(x, m, mmax, data=None)
:math:`\mathrm{guess}` must return initial approximations for the solution components :math:`y_{\textit{i}}^{\left(\textit{j}\right)}` and the derivatives :math:`y_{\textit{i}}^{\left(m_{\textit{i}}\right)}`, for :math:`\textit{j} = 0,1,\ldots,\mathrm{m}[\textit{i}-1]-1`, for :math:`\textit{i} = 1,2,\ldots,\textit{neq}`.
Try to compute each derivative :math:`y_i^{\left(m_i\right)}` such that it corresponds to your approximations to :math:`y_i^{\left(\textit{j}\right)}`, for :math:`\textit{j} = 0,1,\ldots,\mathrm{m}[i-1]-1`.
You should **not** call :math:`\mathrm{ffun}` to compute :math:`y_i^{\left(m_i\right)}`.
If ``bvp_coll_nlin_solve`` is being used in conjunction with :meth:`bvp_coll_nlin_contin` as part of a continuation process, :math:`\mathrm{guess}` is not called by ``bvp_coll_nlin_solve`` after the call to :meth:`bvp_coll_nlin_contin`.
**Parameters**
**x** : float
:math:`x`, the independent variable; :math:`x \in \left[a, b\right]`.
**m** : int, ndarray, shape :math:`\left(\textit{neq}\right)`
:math:`\mathrm{m}[\textit{i}-1]` contains :math:`m_{\textit{i}}`, the order of the :math:`\textit{i}`\ th differential equation, for :math:`\textit{i} = 1,2,\ldots,\textit{neq}`.
**mmax** : int
:math:`\mathrm{max}\left(\mathrm{m}[i]\right)`.
**data** : arbitrary, optional, modifiable in place
User-communication data for callback functions.
**Returns**
**y** : float, array-like, shape :math:`\left(\textit{neq}, \textit{mmax}\right)`
:math:`\mathrm{y}[\textit{i}-1,\textit{j}]` must contain :math:`y_{\textit{i}}^{\left(\textit{j}\right)}\left(x\right)`, for :math:`\textit{j} = 0,1,\ldots,\mathrm{m}[\textit{i}-1]-1`, for :math:`\textit{i} = 1,2,\ldots,\textit{neq}`.
**Note:** :math:`y_i^{\left(0\right)}\left(x\right) = y_i\left(x\right)`.
**dym** : float, array-like, shape :math:`\left(\textit{neq}\right)`
:math:`\mathrm{dym}[\textit{i}-1]` must contain :math:`y_{\textit{i}}^{\left(m_{\textit{i}}\right)}\left(x\right)`, for :math:`\textit{i} = 1,2,\ldots,\textit{neq}`.
**comm** : dict, communication object, modified in place
Communication structure.
This argument must have been initialized by a prior call to :meth:`bvp_coll_nlin_setup`.
**data** : arbitrary, optional
User-communication data for callback functions.
**spiked_sorder** : str, optional
If :math:`\mathrm{dfdy}` in :math:`\mathrm{fjac}`, :math:`\mathrm{dgady}` in :math:`\mathrm{gajac}` or :math:`\mathrm{y}` in :math:`\mathrm{guess}` 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.
.. _d02tl-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
Either the setup function has not been called or the communication arrays have become corrupted. No solution will be computed.
(`errno` :math:`2`)
Numerical singularity has been detected in the Jacobian used in the Newton iteration.
No results have been generated. Check the coding of the functions for calculating the Jacobians of system and boundary conditions.
(`errno` :math:`3`)
All Newton iterations that have been attempted have failed to converge.
No results have been generated. Check the coding of the functions for calculating the Jacobians of system and boundary conditions.
Try to provide a better initial solution approximation.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`4`)
A Newton iteration has failed to converge. The computation has not succeeded but results have been returned for an intermediate mesh on which convergence was achieved.
These results should be treated with extreme caution.
(`errno` :math:`5`)
The expected number of sub-intervals required to continue the computation exceeds the maximum specified: :math:`\langle\mathit{\boldsymbol{value}}\rangle`.
Results have been generated which may be useful.
Try increasing this number or relaxing the error requirements.
.. _d02tl-py2-py-notes:
**Notes**
``bvp_coll_nlin_solve`` and its associated functions (:meth:`bvp_coll_nlin_setup`, :meth:`bvp_coll_nlin_contin`, :meth:`bvp_coll_nlin_interp` and :meth:`bvp_coll_nlin_diag`) solve the two-point boundary value problem for a nonlinear mixed order system of ordinary differential equations
.. math::
\begin{array}{rcl} y_1^{\left(m_1\right)} \left(x\right) & = & f_1 \left(x, y_1, y_1^{\left(1\right)}, \ldots, y_1^{\left(m_1-1\right)}, y_2, \ldots, y_n^{\left(m_n-1\right)}\right) \\ y_2^{\left(m_2\right)} \left(x\right) & = & f_2 \left(x, y_1, y_1^{\left(1\right)}, \ldots, y_1^{\left(m_1-1\right)}, y_2, \ldots, y_n^{\left(m_n-1\right)}\right) \\& \vdots &\\ y_n^{\left(m_n\right)} \left(x\right) & = & f_n \left(x, y_1, y_1^{\left(1\right)}, \ldots, y_1^{\left(m_1-1\right)}, y_2, \ldots, y_n^{\left(m_n-1\right)}\right) \end{array}
over an interval :math:`\left[a, b\right]` subject to :math:`p` (:math:`\text{} > 0`) nonlinear boundary conditions at :math:`a` and :math:`q` (:math:`\text{} > 0`) nonlinear boundary conditions at :math:`b`, where :math:`p+q = \sum_{{i = 1}}^nm_i`.
Note that :math:`y_i^{\left(m\right)}\left(x\right)` is the :math:`m`\ th derivative of the :math:`i`\ th solution component.
Hence :math:`y_i^{\left(0\right)}\left(x\right) = y_i\left(x\right)`.
The left boundary conditions at :math:`a` are defined as
.. math::
g_i\left(z\left(y\left(a\right)\right)\right) = 0\text{, }\quad i = 1,2,\ldots,p\text{,}
and the right boundary conditions at :math:`b` as
.. math::
\bar{g}_j\left(z\left(y\left(b\right)\right)\right) = 0\text{, }\quad j = 1,2,\ldots,q\text{,}
where :math:`y = \left(y_1, y_2, \ldots, y_n\right)` and
.. math::
z\left(y\left(x\right)\right) = \left({y_1\left(x\right)}, {y_1^{\left(1\right)}\left(x\right)}, \ldots, {y_1^{\left(m_1-1\right)}\left(x\right)}, {y_2\left(x\right)}, \ldots, {y_n^{\left(m_n-1\right)}\left(x\right)}\right)\text{.}
First, :meth:`bvp_coll_nlin_setup` must be called to specify the initial mesh, error requirements and other details.
Note that the error requirements apply only to the solution components :math:`y_1,y_2,\ldots,y_n` and that no error control is applied to derivatives of solution components. (If error control is required on derivatives then the system must be reduced in order by introducing the derivatives whose error is to be controlled as new variables.
See `Further Comments <https://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02tvf.html#fcomments>`__.) Then, ``bvp_coll_nlin_solve`` can be used to solve the boundary value problem.
After successful computation, :meth:`bvp_coll_nlin_diag` can be used to ascertain details about the final mesh and other details of the solution procedure, and :meth:`bvp_coll_nlin_interp` can be used to compute the approximate solution anywhere on the interval :math:`\left[a, b\right]`.
A description of the numerical technique used in ``bvp_coll_nlin_solve`` is given in :ref:`Notes for bvp_coll_nlin_setup <d02tv-py2-py-notes>`.
``bvp_coll_nlin_solve`` can also be used in the solution of a series of problems, for example in performing continuation, when the mesh used to compute the solution of one problem is to be used as the initial mesh for the solution of the next related problem. :meth:`bvp_coll_nlin_contin` should be used in between calls to ``bvp_coll_nlin_solve`` in this context.
See `Further Comments <https://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02tvf.html#fcomments>`__ for details of how to solve boundary value problems of a more general nature.
The functions are based on modified versions of the codes COLSYS and COLNEW (see Ascher `et al.` (1979) and Ascher and Bader (1987)).
A comprehensive treatment of the numerical solution of boundary value problems can be found in Ascher `et al.` (1988) and Keller (1992).
.. _d02tl-py2-py-references:
**References**
Ascher, U M and Bader, G, 1987, `A new basis implementation for a mixed order boundary value ODE solver`, SIAM J. Sci. Stat. Comput. (8), 483--500
Ascher, U M, Christiansen, J and Russell, R D, 1979, `A collocation solver for mixed order systems of boundary value problems`, Math. Comput. (33), 659--679
Ascher, U M, Mattheij, R M M and Russell, R D, 1988, `Numerical Solution of Boundary Value Problems for Ordinary Differential Equations`, Prentice--Hall
Keller, H B, 1992, `Numerical Methods for Two-point Boundary-value Problems`, Dover, New York
"""
raise NotImplementedError
[docs]def bvp_coll_nlin_setup(m, nlbc, nrbc, ncol, tols, nmesh, mesh, ipmesh):
r"""
``bvp_coll_nlin_setup`` is a setup function which must be called prior to the first call of the nonlinear two-point boundary value solver :meth:`bvp_coll_nlin_solve`.
.. _d02tv-py2-py-doc:
For full information please refer to the NAG Library document for d02tv
https://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02tvf.html
.. _d02tv-py2-py-parameters:
**Parameters**
**m** : int, array-like, shape :math:`\left(\textit{neq}\right)`
:math:`\mathrm{m}[\textit{i}-1]` must contain :math:`m_i`, the order of the :math:`\textit{i}`\ th differential equation, for :math:`\textit{i} = 1,2,\ldots,n`.
**nlbc** : int
:math:`p`, the number of left boundary conditions defined at the left-hand end, :math:`a` (:math:`\text{} = \mathrm{mesh}[0]`).
**nrbc** : int
:math:`q`, the number of right boundary conditions defined at the right-hand end, :math:`b` (:math:`\text{} = \mathrm{mesh}[\mathrm{nmesh}-1]`).
**ncol** : int
The number of collocation points to be used in each mesh sub-interval.
**tols** : float, array-like, shape :math:`\left(\textit{neq}\right)`
:math:`\mathrm{tols}[i-1]` must contain the error requirement for the :math:`i`\ th solution component.
**nmesh** : int
The number of points to be used in the initial mesh of the solution process.
**mesh** : float, array-like, shape :math:`\left(\textit{mxmesh}\right)`
The positions of the initial :math:`\mathrm{nmesh}` mesh points. The remaining elements of :math:`\mathrm{mesh}` need not be set. You should try to place the mesh points in areas where you expect the solution to vary most rapidly. In the absence of any other information the points should be equally distributed on :math:`\left[a, b\right]`.
:math:`\mathrm{mesh}[0]` must contain the left boundary point, :math:`a`, and :math:`\mathrm{mesh}[\mathrm{nmesh}-1]` must contain the right boundary point, :math:`b`.
**ipmesh** : int, array-like, shape :math:`\left(\textit{mxmesh}\right)`
:math:`\mathrm{ipmesh}[\textit{i}-1]` specifies whether or not the initial mesh point defined in :math:`\mathrm{mesh}[\textit{i}-1]`, for :math:`\textit{i} = 1,2,\ldots,\mathrm{nmesh}`, should be a fixed point in all meshes computed during the solution process. The remaining elements of :math:`\mathrm{ipmesh}` need not be set.
:math:`\mathrm{ipmesh}[i-1] = 1`
Indicates that :math:`\mathrm{mesh}[i-1]` should be a fixed point in all meshes.
:math:`\mathrm{ipmesh}[i-1] = 2`
Indicates that :math:`\mathrm{mesh}[i-1]` is not a fixed point.
**Returns**
**comm** : dict, communication object
Communication structure.
.. _d02tv-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{ipmesh}[i] \neq 1` or :math:`2` for some :math:`i`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{ipmesh}[0]` or :math:`\mathrm{ipmesh}[\mathrm{nmesh}-1]` does not equal :math:`1`.
(`errno` :math:`1`)
On entry, the elements of :math:`\mathrm{mesh}` are not strictly increasing.
(`errno` :math:`1`)
On entry, :math:`\mathrm{nlbc} = \langle\mathit{\boldsymbol{value}}\rangle`, :math:`\mathrm{nrbc} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{sum}\left(\mathrm{m}[i]\right) = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{nlbc}+\mathrm{nrbc} = \mathrm{sum}\left(\mathrm{m}[i]\right)`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{nlbc} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{nrbc} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{nlbc}\geq 1` and :math:`\mathrm{nrbc}\geq 1`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{ncol} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{max}\left(\mathrm{m}[i]\right) = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{max}\left(\mathrm{m}[\textit{i}]\right)\leq \mathrm{ncol}\leq 7`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{tols}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{tols}[i-1] > \langle\mathit{\boldsymbol{value}}\rangle` for all :math:`i`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{m}[\langle\mathit{\boldsymbol{value}}\rangle] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`1\leq \mathrm{m}[i-1]\leq 4` for all :math:`i`.
(`errno` :math:`1`)
On entry, :math:`\textit{mxmesh} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{nmesh} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\textit{mxmesh}\geq 2\times \mathrm{nmesh}-1`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{nmesh} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{nmesh}\geq 6`.
(`errno` :math:`1`)
On entry, :math:`\textit{neq} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\textit{neq}\geq 1`.
.. _d02tv-py2-py-notes:
**Notes**
``bvp_coll_nlin_setup`` and its associated functions (:meth:`bvp_coll_nlin_solve`, :meth:`bvp_coll_nlin_contin`, :meth:`bvp_coll_nlin_interp` and :meth:`bvp_coll_nlin_diag`) solve the two-point boundary value problem for a nonlinear system of ordinary differential equations
.. math::
\begin{array}{rcl} y_1^{\left(m_1\right)} \left(x\right) & = & f_1 \left(x, y_1, y_1^{\left(1\right)}, \ldots, y_1^{\left(m_1-1\right)}, y_2, \ldots, y_n^{\left(m_n-1\right)}\right) \\ y_2^{\left(m_2\right)} \left(x\right) & = & f_2 \left(x, y_1, y_1^{\left(1\right)}, \ldots, y_1^{\left(m_1-1\right)}, y_2, \ldots, y_n^{\left(m_n-1\right)}\right) \\& \vdots &\\ y_n^{\left(m_n\right)} \left(x\right) & = & f_n \left(x, y_1, y_1^{\left(1\right)}, \ldots, y_1^{\left(m_1-1\right)}, y_2, \ldots, y_n^{\left(m_n-1\right)}\right) \end{array}
over an interval :math:`\left[a, b\right]` subject to :math:`p` (:math:`\text{} > 0`) nonlinear boundary conditions at :math:`a` and :math:`q` (:math:`\text{} > 0`) nonlinear boundary conditions at :math:`b`, where :math:`p+q = \sum_{{i = 1}}^nm_i`.
Note that :math:`y_i^{\left(m\right)}\left(x\right)` is the :math:`m`\ th derivative of the :math:`i`\ th solution component.
Hence :math:`y_i^{\left(0\right)}\left(x\right) = y_i\left(x\right)`.
The left boundary conditions at :math:`a` are defined as
.. math::
g_i\left(z\left(y\left(a\right)\right)\right) = 0\text{, }\quad i = 1,2,\ldots,p\text{,}
and the right boundary conditions at :math:`b` as
.. math::
\bar{g}_j\left(z\left(y\left(b\right)\right)\right) = 0\text{, }\quad j = 1,2,\ldots,q\text{,}
where :math:`y = \left(y_1, y_2, \ldots, y_n\right)` and
.. math::
z\left(y\left(x\right)\right) = \left({y_1\left(x\right)}, {y_1^{\left(1\right)}\left(x\right)}, \ldots, {y_1^{\left(m_1-1\right)}\left(x\right)}, {y_2\left(x\right)}, \ldots, {y_n^{\left(m_n-1\right)}\left(x\right)}\right)\text{.}
See `Further Comments <https://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02tvf.html#fcomments>`__ for information on how boundary value problems of a more general nature can be treated.
``bvp_coll_nlin_setup`` is used to specify an initial mesh, error requirements and other details. :meth:`bvp_coll_nlin_solve` is then used to solve the boundary value problem.
The solution function :meth:`bvp_coll_nlin_solve` proceeds as follows.
A modified Newton method is applied to the equations
.. math::
y_i^{\left(m_i\right)}\left(x\right)-f_i\left(x, {z\left(y\left(x\right)\right)}\right) = 0\text{, }\quad i = 1,\ldots,n
and the boundary conditions.
To solve these equations numerically the components :math:`y_i` are approximated by piecewise polynomials :math:`v_{{ij}}` using a monomial basis on the :math:`j`\ th mesh sub-interval.
The coefficients of the polynomials :math:`v_{{ij}}` form the unknowns to be computed.
Collocation is applied at Gaussian points
.. math::
v_{{ij}}^{\left(m_i\right)}\left(x_{{jk}}\right)-f_i\left(x_{{jk}}, {z\left(v\left(x_{{jk}}\right)\right)}\right) = 0\text{, }\quad i = 1,2,\ldots,n\text{,}
where :math:`x_{{jk}}` is the :math:`k`\ th collocation point in the :math:`j`\ th mesh sub-interval.
Continuity at the mesh points is imposed, that is
.. math::
v_{{ij}}\left(x_{{j+1}}\right)-v_{{i,j+1}}\left(x_{{j+1}}\right) = 0\text{, }\quad i = 1,2,\ldots,n\text{,}
where :math:`x_{{j+1}}` is the right-hand end of the :math:`j`\ th mesh sub-interval.
The linearized collocation equations and boundary conditions, together with the continuity conditions, form a system of linear algebraic equations, an almost block diagonal system which is solved using special linear solvers.
To start the modified Newton process, an approximation to the solution on the initial mesh must be supplied via the procedure argument :math:`\textit{guess}` of :meth:`bvp_coll_nlin_solve`.
The solver attempts to satisfy the conditions
.. math::
\frac{{\left\lVert y_i-v_i\right\rVert }}{\left(1.0+\left\lVert v_i\right\rVert \right)}\leq \mathrm{tols}[i-1]\text{, }\quad i = 1,2,\ldots,n\text{,}
where :math:`v_i` is the approximate solution for the :math:`i`\ th solution component and :math:`\mathrm{tols}` is supplied by you.
The mesh is refined by trying to equidistribute the estimated error in the computed solution over all mesh sub-intervals, and an extrapolation-like test (doubling the number of mesh sub-intervals) is used to check for `(1) <https://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02tvf.html#eqn1>`__.
The functions are based on modified versions of the codes COLSYS and COLNEW (see Ascher `et al.` (1979) and Ascher and Bader (1987)).
A comprehensive treatment of the numerical solution of boundary value problems can be found in Ascher `et al.` (1988) and Keller (1992).
.. _d02tv-py2-py-references:
**References**
Ascher, U M and Bader, G, 1987, `A new basis implementation for a mixed order boundary value ODE solver`, SIAM J. Sci. Stat. Comput. (8), 483--500
Ascher, U M, Christiansen, J and Russell, R D, 1979, `A collocation solver for mixed order systems of boundary value problems`, Math. Comput. (33), 659--679
Ascher, U M, Mattheij, R M M and Russell, R D, 1988, `Numerical Solution of Boundary Value Problems for Ordinary Differential Equations`, Prentice--Hall
Gill, P E, Murray, W and Wright, M H, 1981, `Practical Optimization`, Academic Press
Keller, H B, 1992, `Numerical Methods for Two-point Boundary-value Problems`, Dover, New York
Schwartz, I B, 1983, `Estimating regions of existence of unstable periodic orbits using computer-based techniques`, SIAM J. Sci. Statist. Comput. (20(1)), 106--120
"""
raise NotImplementedError
[docs]def bvp_coll_nlin_contin(nmesh, mesh, ipmesh, comm):
r"""
``bvp_coll_nlin_contin`` allows a solution to a nonlinear two-point boundary value problem computed by :meth:`bvp_coll_nlin_solve` to be used as an initial approximation in the solution of a related nonlinear two-point boundary value problem in a continuation call to :meth:`bvp_coll_nlin_solve`.
.. _d02tx-py2-py-doc:
For full information please refer to the NAG Library document for d02tx
https://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02txf.html
.. _d02tx-py2-py-parameters:
**Parameters**
**nmesh** : int
The number of points to be used in the new initial mesh. It is strongly recommended that if this function is called that the suggested value (see below) for :math:`\mathrm{nmesh}` is used. In this case the arrays :math:`\textit{mesh}` and :math:`\textit{ipmesh}` returned by :meth:`bvp_coll_nlin_diag` can be passed to this function without any modification.
`Suggested value`: :math:`\left(n^*+1\right)/2`, where :math:`n^*` is the number of mesh points used in the previous mesh as returned in the argument :math:`\mathrm{nmesh}` of :meth:`bvp_coll_nlin_diag`.
**mesh** : float, array-like, shape :math:`\left(\textit{mxmesh}\right)`
The :math:`\mathrm{nmesh}` points to be used in the new initial mesh as specified by :math:`\mathrm{ipmesh}`.
`Suggested value`: the argument :math:`\mathrm{mesh}` returned from a call to :meth:`bvp_coll_nlin_diag`.
**ipmesh** : int, array-like, shape :math:`\left(\textit{mxmesh}\right)`
Specifies the points in :math:`\mathrm{mesh}` to be used as the new initial mesh. Let :math:`\left\{i_j:j = 1,2,\ldots,\mathrm{nmesh}\right\}` be the set of array indices of :math:`\mathrm{ipmesh}` such that :math:`\mathrm{ipmesh}[i_j-1] = 1` or :math:`2` and :math:`1 = i_1 < i_2 < \cdots < i_{\mathrm{nmesh}}`. Then :math:`\mathrm{mesh}[i_j-1]` will be included in the new initial mesh.
If :math:`\mathrm{ipmesh}[i_j-1] = 1`, :math:`\mathrm{mesh}[i_j-1]` will be a fixed point in the new initial mesh.
If :math:`\mathrm{ipmesh}[k-1] = 3` for any :math:`k`, :math:`\mathrm{mesh}[k-1]` will not be included in the new mesh.
`Suggested value`: the argument :math:`\mathrm{ipmesh}` returned in a call to :meth:`bvp_coll_nlin_diag`.
**comm** : dict, communication object, modified in place
Communication structure.
This argument must have been initialized by a prior call to :meth:`bvp_coll_nlin_setup`.
.. _d02tx-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
The entries in :math:`\mathrm{mesh}` are not strictly increasing.
(`errno` :math:`1`)
The last point of the new mesh does not coincide with the right hand end of the range previously specified.
Last point of the new mesh: :math:`\langle\mathit{\boldsymbol{value}}\rangle`; right-hand end of the range: :math:`\langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`1`)
You have set the element of :math:`\mathrm{ipmesh}` corresponding to the last element of :math:`\mathrm{mesh}` to be included in the new mesh as :math:`\langle\mathit{\boldsymbol{value}}\rangle`, which is not :math:`1`.
(`errno` :math:`1`)
Expected :math:`\langle\mathit{\boldsymbol{value}}\rangle` elements of :math:`\mathrm{ipmesh}` to be :math:`1` or :math:`2`, but :math:`\langle\mathit{\boldsymbol{value}}\rangle` such elements found.
(`errno` :math:`1`)
An element of :math:`\mathrm{ipmesh}` was set to :math:`-1` before :math:`\mathrm{nmesh}` elements containing :math:`1` or :math:`2` were detected.
(`errno` :math:`1`)
:math:`\mathrm{ipmesh}[i] \neq -1`, :math:`1`, :math:`2` or :math:`3` for some :math:`i`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{ipmesh}[0] = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{ipmesh}[0] = 1`.
(`errno` :math:`1`)
The first element of array :math:`\mathrm{mesh}` does not coincide with the left-hand end of the range previously specified.
First element of :math:`\mathrm{mesh}`: :math:`\langle\mathit{\boldsymbol{value}}\rangle`; left-hand of the range: :math:`\langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{nmesh} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\textit{mxmesh} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{nmesh}\leq \left(\textit{mxmesh}+1\right)/2`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{nmesh} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{nmesh}\geq 6`.
(`errno` :math:`1`)
On entry, :math:`\textit{mxmesh} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`{\textit{mxmesh}} = \langle\mathit{\boldsymbol{value}}\rangle` in :meth:`bvp_coll_nlin_setup`.
Constraint: :math:`\textit{mxmesh} = {\textit{mxmesh}}` in :meth:`bvp_coll_nlin_setup`.
(`errno` :math:`1`)
The solver function did not produce any results suitable for remeshing.
(`errno` :math:`1`)
The solver function does not appear to have been called.
.. _d02tx-py2-py-notes:
**Notes**
``bvp_coll_nlin_contin`` and its associated functions (:meth:`bvp_coll_nlin_solve`, :meth:`bvp_coll_nlin_setup`, :meth:`bvp_coll_nlin_interp` and :meth:`bvp_coll_nlin_diag`) solve the two-point boundary value problem for a nonlinear system of ordinary differential equations
.. math::
\begin{array}{rcl} y_1^{\left(m_1\right)} \left(x\right) & = & f_1 \left(x, y_1, y_1^{\left(1\right)}, \ldots, y_1^{\left(m_1-1\right)}, y_2, \ldots, y_n^{\left(m_n-1\right)}\right) \\ y_2^{\left(m_2\right)} \left(x\right) & = & f_2 \left(x, y_1, y_1^{\left(1\right)}, \ldots, y_1^{\left(m_1-1\right)}, y_2, \ldots, y_n^{\left(m_n-1\right)}\right) \\& \vdots &\\ y_n^{\left(m_n\right)} \left(x\right) & = & f_n \left(x, y_1, y_1^{\left(1\right)}, \ldots, y_1^{\left(m_1-1\right)}, y_2, \ldots, y_n^{\left(m_n-1\right)}\right) \end{array}
over an interval :math:`\left[a, b\right]` subject to :math:`p` (:math:`\text{} > 0`) nonlinear boundary conditions at :math:`a` and :math:`q` (:math:`\text{} > 0`) nonlinear boundary conditions at :math:`b`, where :math:`p+q = \sum_{{i = 1}}^nm_i`.
Note that :math:`y_i^{\left(m\right)}\left(x\right)` is the :math:`m`\ th derivative of the :math:`i`\ th solution component.
Hence :math:`y_i^{\left(0\right)}\left(x\right) = y_i\left(x\right)`.
The left boundary conditions at :math:`a` are defined as
.. math::
g_i\left(z\left(y\left(a\right)\right)\right) = 0\text{, }\quad i = 1,2,\ldots,p\text{,}
and the right boundary conditions at :math:`b` as
.. math::
\bar{g}_j\left(z\left(y\left(b\right)\right)\right) = 0\text{, }\quad j = 1,2,\ldots,q\text{,}
where :math:`y = \left(y_1, y_2, \ldots, y_n\right)` and
.. math::
z\left(y\left(x\right)\right) = \left({y_1\left(x\right)}, {y_1^{\left(1\right)}\left(x\right)}, \ldots, {y_1^{\left(m_1-1\right)}\left(x\right)}, {y_2\left(x\right)}, \ldots, {y_n^{\left(m_n-1\right)}\left(x\right)}\right)\text{.}
First, :meth:`bvp_coll_nlin_setup` must be called to specify the initial mesh, error requirements and other details.
Then, :meth:`bvp_coll_nlin_solve` can be used to solve the boundary value problem.
After successful computation, :meth:`bvp_coll_nlin_diag` can be used to ascertain details about the final mesh. :meth:`bvp_coll_nlin_interp` can be used to compute the approximate solution anywhere on the interval :math:`\left[a, b\right]` using interpolation.
If the boundary value problem being solved is one of a sequence of related problems, for example as part of some continuation process, then ``bvp_coll_nlin_contin`` should be used between calls to :meth:`bvp_coll_nlin_solve`.
This avoids the overhead of a complete initialization when the setup function :meth:`bvp_coll_nlin_setup` is used. ``bvp_coll_nlin_contin`` allows the solution values computed in the previous call to :meth:`bvp_coll_nlin_solve` to be used as an initial approximation for the solution in the next call to :meth:`bvp_coll_nlin_solve`.
You must specify the new initial mesh.
The previous mesh can be obtained by a call to :meth:`bvp_coll_nlin_diag`.
It may be used unchanged as the new mesh, in which case any fixed points in the previous mesh remain as fixed points in the new mesh.
Fixed and other points may be added or subtracted from the mesh by manipulation of the contents of the array argument :math:`\mathrm{ipmesh}`.
Initial values for the solution components on the new mesh are computed by interpolation on the values for the solution components on the previous mesh.
The functions are based on modified versions of the codes COLSYS and COLNEW (see Ascher `et al.` (1979) and Ascher and Bader (1987)).
A comprehensive treatment of the numerical solution of boundary value problems can be found in Ascher `et al.` (1988) and Keller (1992).
.. _d02tx-py2-py-references:
**References**
Ascher, U M and Bader, G, 1987, `A new basis implementation for a mixed order boundary value ODE solver`, SIAM J. Sci. Stat. Comput. (8), 483--500
Ascher, U M, Christiansen, J and Russell, R D, 1979, `A collocation solver for mixed order systems of boundary value problems`, Math. Comput. (33), 659--679
Ascher, U M, Mattheij, R M M and Russell, R D, 1988, `Numerical Solution of Boundary Value Problems for Ordinary Differential Equations`, Prentice--Hall
Keller, H B, 1992, `Numerical Methods for Two-point Boundary-value Problems`, Dover, New York
"""
raise NotImplementedError
[docs]def bvp_coll_nlin_interp(x, neq, mmax, comm):
r"""
``bvp_coll_nlin_interp`` interpolates on the solution of a general two-point boundary value problem computed by :meth:`bvp_coll_nlin_solve`.
.. _d02ty-py2-py-doc:
For full information please refer to the NAG Library document for d02ty
https://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02tyf.html
.. _d02ty-py2-py-parameters:
**Parameters**
**x** : float
:math:`x`, the independent variable.
**neq** : int
The number of differential equations.
**mmax** : int
The maximal order of the differential equations, :math:`\mathrm{max}\left(m_{\textit{i}}\right)`, for :math:`\textit{i} = 1,2,\ldots,\mathrm{neq}`.
**comm** : dict, communication object, modified in place
Communication structure.
This argument must have been initialized by a prior call to :meth:`bvp_coll_nlin_setup`.
**Returns**
**y** : float, ndarray, shape :math:`\left(\mathrm{neq}, \mathrm{mmax}\right)`
:math:`\mathrm{y}[\textit{i}-1,\textit{j}]` contains an approximation to :math:`y_{\textit{i}}^{\left(\textit{j}\right)}\left(x\right)`, for :math:`\textit{j} = 0,1,\ldots,m_{\textit{i}}-1`, for :math:`\textit{i} = 1,2,\ldots,\mathrm{neq}`. The remaining elements of :math:`\mathrm{y}` (where :math:`m_i < \mathrm{mmax}`) are initialized to :math:`0.0`.
.. _d02ty-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}\leq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{x}\geq \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{mmax} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{max}\left({\textit{m}}[i]\right) = \langle\mathit{\boldsymbol{value}}\rangle` in :meth:`bvp_coll_nlin_setup`.
Constraint: :math:`\mathrm{mmax} = \mathrm{max}\left({\textit{m}}[i]\right)` in :meth:`bvp_coll_nlin_setup`.
(`errno` :math:`1`)
The solver function did not produce any results suitable for interpolation.
(`errno` :math:`1`)
The solver function does not appear to have been called.
(`errno` :math:`1`)
On entry, :math:`\mathrm{neq} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`{\textit{neq}} = \langle\mathit{\boldsymbol{value}}\rangle` in :meth:`bvp_coll_nlin_setup`.
Constraint: :math:`\mathrm{neq} = {\textit{neq}}` in :meth:`bvp_coll_nlin_setup`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`2`)
The solver function did not satisfy the error requirements.
Interpolated values should be treated with caution.
(`errno` :math:`2`)
The solver function did not converge to a suitable solution.
A converged intermediate solution has been used.
Interpolated values should be treated with caution.
.. _d02ty-py2-py-notes:
**Notes**
``bvp_coll_nlin_interp`` and its associated functions (:meth:`bvp_coll_nlin_setup`, :meth:`bvp_coll_nlin_solve`, :meth:`bvp_coll_nlin_contin` and :meth:`bvp_coll_nlin_diag`) solve the two-point boundary value problem for a nonlinear mixed order system of ordinary differential equations
.. math::
\begin{array}{rcl} y_1^{\left(m_1\right)} \left(x\right) & = & f_1 \left(x, y_1, y_1^{\left(1\right)}, \ldots, y_1^{\left(m_1-1\right)}, y_2, \ldots, y_n^{\left(m_n-1\right)}\right) \\ y_2^{\left(m_2\right)} \left(x\right) & = & f_2 \left(x, y_1, y_1^{\left(1\right)}, \ldots, y_1^{\left(m_1-1\right)}, y_2, \ldots, y_n^{\left(m_n-1\right)}\right) \\& \vdots &\\ y_n^{\left(m_n\right)} \left(x\right) & = & f_n \left(x, y_1, y_1^{\left(1\right)}, \ldots, y_1^{\left(m_1-1\right)}, y_2, \ldots, y_n^{\left(m_n-1\right)}\right) \end{array}
over an interval :math:`\left[a, b\right]` subject to :math:`p` (:math:`\text{} > 0`) nonlinear boundary conditions at :math:`a` and :math:`q` (:math:`\text{} > 0`) nonlinear boundary conditions at :math:`b`, where :math:`p+q = \sum_{{i = 1}}^nm_i`.
Note that :math:`y_i^{\left(m\right)}\left(x\right)` is the :math:`m`\ th derivative of the :math:`i`\ th solution component.
Hence :math:`y_i^{\left(0\right)}\left(x\right) = y_i\left(x\right)`.
The left boundary conditions at :math:`a` are defined as
.. math::
g_i\left(z\left(y\left(a\right)\right)\right) = 0\text{, }\quad i = 1,2,\ldots,p\text{,}
and the right boundary conditions at :math:`b` as
.. math::
\bar{g}_j\left(z\left(y\left(b\right)\right)\right) = 0\text{, }\quad j = 1,2,\ldots,q\text{,}
where :math:`y = \left(y_1, y_2, \ldots, y_n\right)` and
.. math::
z\left(y\left(x\right)\right) = \left({y_1\left(x\right)}, {y_1^{\left(1\right)}\left(x\right)}, \ldots, {y_1^{\left(m_1-1\right)}\left(x\right)}, {y_2\left(x\right)}, \ldots, {y_n^{\left(m_n-1\right)}\left(x\right)}\right)\text{.}
First, :meth:`bvp_coll_nlin_setup` must be called to specify the initial mesh, error requirements and other details.
Then, :meth:`bvp_coll_nlin_solve` can be used to solve the boundary value problem.
After successful computation, :meth:`bvp_coll_nlin_diag` can be used to ascertain details about the final mesh and other details of the solution procedure, and ``bvp_coll_nlin_interp`` can be used to compute the approximate solution anywhere on the interval :math:`\left[a, b\right]` using interpolation.
The functions are based on modified versions of the codes COLSYS and COLNEW (see Ascher `et al.` (1979) and Ascher and Bader (1987)).
A comprehensive treatment of the numerical solution of boundary value problems can be found in Ascher `et al.` (1988) and Keller (1992).
.. _d02ty-py2-py-references:
**References**
Ascher, U M and Bader, G, 1987, `A new basis implementation for a mixed order boundary value ODE solver`, SIAM J. Sci. Stat. Comput. (8), 483--500
Ascher, U M, Christiansen, J and Russell, R D, 1979, `A collocation solver for mixed order systems of boundary value problems`, Math. Comput. (33), 659--679
Ascher, U M, Mattheij, R M M and Russell, R D, 1988, `Numerical Solution of Boundary Value Problems for Ordinary Differential Equations`, Prentice--Hall
Grossman, C, 1992, `Enclosures of the solution of the Thomas--Fermi equation by monotone discretization`, J. Comput. Phys. (98), 26--32
Keller, H B, 1992, `Numerical Methods for Two-point Boundary-value Problems`, Dover, New York
"""
raise NotImplementedError
[docs]def bvp_coll_nlin_diag(mxmesh, comm):
r"""
``bvp_coll_nlin_diag`` returns information about the solution of a general two-point boundary value problem computed by :meth:`bvp_coll_nlin_solve`.
.. _d02tz-py2-py-doc:
For full information please refer to the NAG Library document for d02tz
https://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02tzf.html
.. _d02tz-py2-py-parameters:
**Parameters**
**mxmesh** : int
The maximum number of points allowed in the mesh.
**comm** : dict, communication object
Communication structure.
This argument must have been initialized by a prior call to :meth:`bvp_coll_nlin_setup`.
**Returns**
**nmesh** : int
The number of points in the mesh last used by :meth:`bvp_coll_nlin_solve`.
**mesh** : float, ndarray, shape :math:`\left(\mathrm{mxmesh}\right)`
:math:`\mathrm{mesh}[\textit{i}-1]` contains the :math:`\textit{i}`\ th point of the mesh last used by :meth:`bvp_coll_nlin_solve`, for :math:`\textit{i} = 1,2,\ldots,\mathrm{nmesh}`. :math:`\mathrm{mesh}[0]` will contain :math:`a` and :math:`\mathrm{mesh}[\mathrm{nmesh}-1]` will contain :math:`b`. The remaining elements of :math:`\mathrm{mesh}` are not initialized.
**ipmesh** : int, ndarray, shape :math:`\left(\mathrm{mxmesh}\right)`
:math:`\mathrm{ipmesh}[\textit{i}-1]` specifies the nature of the point :math:`\mathrm{mesh}[\textit{i}-1]`, for :math:`\textit{i} = 1,2,\ldots,\mathrm{nmesh}`, in the final mesh computed by :meth:`bvp_coll_nlin_solve`.
:math:`\mathrm{ipmesh}[i-1] = 1`
Indicates that the :math:`i`\ th point is a fixed point and was used by the solver before an extrapolation-like error test.
:math:`\mathrm{ipmesh}[i-1] = 2`
Indicates that the :math:`i`\ th point was used by the solver before an extrapolation-like error test.
:math:`\mathrm{ipmesh}[i-1] = 3`
Indicates that the :math:`i`\ th point was used by the solver only as part of an extrapolation-like error test.
The remaining elements of :math:`\mathrm{ipmesh}` are initialized to :math:`-1`.
See `Further Comments <https://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02tzf.html#fcomments>`__ for advice on how these values may be used in conjunction with a continuation process.
**ermx** : float
An estimate of the maximum error in the solution computed by :meth:`bvp_coll_nlin_solve`, that is
.. math::
\mathrm{ermx} = \mathrm{max}\left(\frac{{\left\lVert y_i-v_i\right\rVert }}{\left(1.0+\left\lVert v_i\right\rVert \right)}\right)
where :math:`v_i` is the approximate solution for the :math:`i`\ th solution component. If :meth:`bvp_coll_nlin_solve` returned successfully with no exception or warning is raised, :math:`\mathrm{ermx}` will be less than :math:`{\textit{tols}}[\mathrm{ijermx}-1]` in :meth:`bvp_coll_nlin_setup` where :math:`\textit{tols}` contains the error requirements as specified in :ref:`Notes for bvp_coll_nlin_setup <d02tv-py2-py-notes>` and :ref:`Parameters for bvp_coll_nlin_setup <d02tv-py2-py-parameters>`.
If :meth:`bvp_coll_nlin_solve` returned with :math:`\mathrm{errno}` = 5, :math:`\mathrm{ermx}` will be greater than :math:`{\textit{tols}}[\mathrm{ijermx}-1]` in :meth:`bvp_coll_nlin_setup`.
If :meth:`bvp_coll_nlin_solve` returned any other value for :math:`\textit{errno}` then an error estimate is not available and :math:`\mathrm{ermx}` is initialized to :math:`0.0`.
**iermx** : int
Indicates the mesh sub-interval where the value of :math:`\mathrm{ermx}` has been computed, that is :math:`\left[\mathrm{mesh}[ \mathrm{iermx} -1], {\mathrm{mesh}[ \mathrm{iermx} + 1 -1]}\right]`.
If an estimate of the error is not available then :math:`\mathrm{iermx}` is initialized to :math:`0`.
**ijermx** : int
Indicates the component :math:`i` (:math:`\text{} = \mathrm{ijermx}`) of the solution for which :math:`\mathrm{ermx}` has been computed, that is the approximation of :math:`y_i` on :math:`\left[{\mathrm{mesh}[\mathrm{iermx}-1]}, {\mathrm{mesh}[\mathrm{iermx}]}\right]` is estimated to have the largest error of all components :math:`y_i` over mesh sub-intervals defined by :math:`\mathrm{mesh}`.
If an estimate of the error is not available then :math:`\mathrm{ijermx}` is initialized to :math:`0`.
.. _d02tz-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
The solver function did not produce any results suitable for interpolation.
(`errno` :math:`1`)
The solver function does not appear to have been called.
(`errno` :math:`1`)
On entry, :math:`\mathrm{mxmesh} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`{\textit{mxmesh}} = \langle\mathit{\boldsymbol{value}}\rangle` in :meth:`bvp_coll_nlin_setup`.
Constraint: :math:`\mathrm{mxmesh} = {\textit{mxmesh}}` in :meth:`bvp_coll_nlin_setup`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`2`)
The solver function did not satisfy the error requirements.
Information has been supplied on the last mesh used.
(`errno` :math:`2`)
The solver function did not converge to a suitable solution.
A converged intermediate solution has been used.
Error estimate information is not available.
.. _d02tz-py2-py-notes:
**Notes**
``bvp_coll_nlin_diag`` and its associated functions (:meth:`bvp_coll_nlin_setup`, :meth:`bvp_coll_nlin_solve`, :meth:`bvp_coll_nlin_contin` and :meth:`bvp_coll_nlin_interp`) solve the two-point boundary value problem for a nonlinear mixed order system of ordinary differential equations
.. math::
\begin{array}{rcl} y_1^{\left(m_1\right)} \left(x\right) & = & f_1 \left(x, y_1, y_1^{\left(1\right)}, \ldots, y_1^{\left(m_1-1\right)}, y_2, \ldots, y_n^{\left(m_n-1\right)}\right) \\ y_2^{\left(m_2\right)} \left(x\right) & = & f_2 \left(x, y_1, y_1^{\left(1\right)}, \ldots, y_1^{\left(m_1-1\right)}, y_2, \ldots, y_n^{\left(m_n-1\right)}\right) \\& \vdots &\\ y_n^{\left(m_n\right)} \left(x\right) & = & f_n \left(x, y_1, y_1^{\left(1\right)}, \ldots, y_1^{\left(m_1-1\right)}, y_2, \ldots, y_n^{\left(m_n-1\right)}\right) \end{array}
over an interval :math:`\left[a, b\right]` subject to :math:`p` (:math:`\text{} > 0`) nonlinear boundary conditions at :math:`a` and :math:`q` (:math:`\text{} > 0`) nonlinear boundary conditions at :math:`b`, where :math:`p+q = \sum_{{i = 1}}^nm_i`.
Note that :math:`y_i^{\left(m\right)}\left(x\right)` is the :math:`m`\ th derivative of the :math:`i`\ th solution component.
Hence :math:`y_i^{\left(0\right)}\left(x\right) = y_i\left(x\right)`.
The left boundary conditions at :math:`a` are defined as
.. math::
g_i\left(z\left(y\left(a\right)\right)\right) = 0\text{, }\quad i = 1,2,\ldots,p\text{,}
and the right boundary conditions at :math:`b` as
.. math::
\bar{g}_j\left(z\left(y\left(b\right)\right)\right) = 0\text{, }\quad j = 1,2,\ldots,q\text{,}
where :math:`y = \left(y_1, y_2, \ldots, y_n\right)` and
.. math::
z\left(y\left(x\right)\right) = \left({y_1\left(x\right)}, {y_1^{\left(1\right)}\left(x\right)}, \ldots, {y_1^{\left(m_1-1\right)}\left(x\right)}, {y_2\left(x\right)}, \ldots, {y_n^{\left(m_n-1\right)}\left(x\right)}\right)\text{.}
First, :meth:`bvp_coll_nlin_setup` must be called to specify the initial mesh, error requirements and other details.
Then, :meth:`bvp_coll_nlin_solve` can be used to solve the boundary value problem.
After successful computation, ``bvp_coll_nlin_diag`` can be used to ascertain details about the final mesh. :meth:`bvp_coll_nlin_interp` can be used to compute the approximate solution anywhere on the interval :math:`\left[a, b\right]` using interpolation.
The functions are based on modified versions of the codes COLSYS and COLNEW (see Ascher `et al.` (1979) and Ascher and Bader (1987)).
A comprehensive treatment of the numerical solution of boundary value problems can be found in Ascher `et al.` (1988) and Keller (1992).
.. _d02tz-py2-py-references:
**References**
Ascher, U M and Bader, G, 1987, `A new basis implementation for a mixed order boundary value ODE solver`, SIAM J. Sci. Stat. Comput. (8), 483--500
Ascher, U M, Christiansen, J and Russell, R D, 1979, `A collocation solver for mixed order systems of boundary value problems`, Math. Comput. (33), 659--679
Ascher, U M, Mattheij, R M M and Russell, R D, 1988, `Numerical Solution of Boundary Value Problems for Ordinary Differential Equations`, Prentice--Hall
Cole, J D, 1968, `Perturbation Methods in Applied Mathematics`, Blaisdell, Waltham, Mass.
Keller, H B, 1992, `Numerical Methods for Two-point Boundary-value Problems`, Dover, New York
"""
raise NotImplementedError
[docs]def bvp_ps_lin_coeffs(f):
r"""
``bvp_ps_lin_coeffs`` obtains the Chebyshev coefficients of a function discretized on Chebyshev Gauss--Lobatto points.
The set of discretization points on which the function is evaluated is usually obtained by a previous call to :meth:`bvp_ps_lin_cgl_grid`.
.. _d02ua-py2-py-doc:
For full information please refer to the NAG Library document for d02ua
https://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02uaf.html
.. _d02ua-py2-py-parameters:
**Parameters**
**f** : float, array-like, shape :math:`\left(n+1\right)`
The function values :math:`f\left(x_{\textit{r}}\right)`, for :math:`\textit{r} = 1,2,\ldots,n+1`.
**Returns**
**c** : float, ndarray, shape :math:`\left(n+1\right)`
The Chebyshev coefficients, :math:`c_{\textit{j}}`, for :math:`\textit{j} = 1,2,\ldots,n+1`.
.. _d02ua-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n > 1`.
(`errno` :math:`1`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\textit{n}` is even.
.. _d02ua-py2-py-notes:
**Notes**
``bvp_ps_lin_coeffs`` computes the coefficients :math:`c_{\textit{j}}`, for :math:`\textit{j} = 1,2,\ldots,n+1`, of the interpolating Chebyshev series
.. math::
\frac{1}{2}c_1T_0\left(\bar{x}\right)+c_2T_1\left(\bar{x}\right)+c_3T_2\left(\bar{x}\right)+ \cdots +c_{{n+1}}T_n\left(\bar{x}\right)\text{,}
which interpolates the function :math:`f\left(x\right)` evaluated at the Chebyshev Gauss--Lobatto points
.. math::
\bar{x}_r = -\cos\left(\left(r-1\right)\pi /n\right)\text{, }\quad r = 1,2,\ldots,n+1\text{.}
Here :math:`T_j\left(\bar{x}\right)` denotes the Chebyshev polynomial of the first kind of degree :math:`j` with argument :math:`\bar{x}` defined on :math:`\left[-1, 1\right]`.
In terms of your original variable, :math:`x` say, the input values at which the function values are to be provided are
.. math::
x_r = -\frac{1}{2}\left(b-a\right)\cos\left(\pi \left(r-1\right)/n\right)+\frac{1}{2}\left(b+a\right)\text{, }\quad r = 1,2,\ldots,n+1\text{, }
where :math:`b` and :math:`a` are respectively the upper and lower ends of the range of :math:`x` over which the function is required.
.. _d02ua-py2-py-references:
**References**
Canuto, C, 1988, `Spectral Methods in Fluid Dynamics`, 502, Springer
Canuto, C, Hussaini, M Y, Quarteroni, A and Zang, T A, 2006, `Spectral Methods: Fundamentals in Single Domains`, Springer
Trefethen, L N, 2000, `Spectral Methods in MATLAB`, SIAM
"""
raise NotImplementedError
[docs]def bvp_ps_lin_cgl_vals(a, b, q, c):
r"""
``bvp_ps_lin_cgl_vals`` evaluates a function, or one of its lower order derivatives, from its Chebyshev series representation at Chebyshev Gauss--Lobatto points on :math:`\left[a, b\right]`.
The coefficients of the Chebyshev series representation required are usually derived from those returned by :meth:`bvp_ps_lin_coeffs` or :meth:`bvp_ps_lin_solve`.
.. _d02ub-py2-py-doc:
For full information please refer to the NAG Library document for d02ub
https://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02ubf.html
.. _d02ub-py2-py-parameters:
**Parameters**
**a** : float
:math:`a`, the lower bound of domain :math:`\left[a, b\right]`.
**b** : float
:math:`b`, the upper bound of domain :math:`\left[a, b\right]`.
**q** : int
The order, :math:`q`, of the derivative to evaluate.
**c** : float, array-like, shape :math:`\left(n+1\right)`
The Chebyshev coefficients, :math:`c_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n+1`.
**Returns**
**f** : float, ndarray, shape :math:`\left(n+1\right)`
The derivatives :math:`S^{\left(q\right)}x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n+1`, of the Chebyshev series, :math:`S`.
.. _d02ub-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n > 0`.
(`errno` :math:`1`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\textit{n}` is even.
(`errno` :math:`2`)
On entry, :math:`\mathrm{a} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{b} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{a} < \mathrm{b}`.
(`errno` :math:`3`)
On entry, :math:`\mathrm{q} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`0\leq \mathrm{q}\leq 4`.
.. _d02ub-py2-py-notes:
**Notes**
``bvp_ps_lin_cgl_vals`` evaluates the Chebyshev series
.. math::
S\left(\bar{x}\right) = \frac{1}{2}c_1T_0\left(\bar{x}\right)+c_2T_1\left(\bar{x}\right)+c_3T_2\left(\bar{x}\right)+ \cdots +c_{{n+1}}T_n\left(\bar{x}\right)\text{,}
or its derivative (up to fourth order) at the Chebyshev Gauss--Lobatto points on :math:`\left[a, b\right]`.
Here :math:`T_j\left(\bar{x}\right)` denotes the Chebyshev polynomial of the first kind of degree :math:`j` with argument :math:`\bar{x}` defined on :math:`\left[-1, 1\right]`.
In terms of your original variable, :math:`x` say, the input values at which the function values are to be provided are
.. math::
x_r = -\frac{1}{2}\left(b-a\right)\cos\left(\pi \left(r-1\right)/n\right)+\frac{1}{2}\left(b+a\right)\text{, }\quad r = 1,2,\ldots,n+1\text{, }
where :math:`b` and :math:`a` are respectively the upper and lower ends of the range of :math:`x` over which the function is required.
The calculation is implemented by a forward one-dimensional discrete Fast Fourier Transform (DFT).
.. _d02ub-py2-py-references:
**References**
Canuto, C, 1988, `Spectral Methods in Fluid Dynamics`, 502, Springer
Canuto, C, Hussaini, M Y, Quarteroni, A and Zang, T A, 2006, `Spectral Methods: Fundamentals in Single Domains`, Springer
Trefethen, L N, 2000, `Spectral Methods in MATLAB`, SIAM
"""
raise NotImplementedError
[docs]def bvp_ps_lin_cgl_grid(n, a, b):
r"""
``bvp_ps_lin_cgl_grid`` returns the Chebyshev Gauss--Lobatto grid points on :math:`\left[a, b\right]`.
.. _d02uc-py2-py-doc:
For full information please refer to the NAG Library document for d02uc
https://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02ucf.html
.. _d02uc-py2-py-parameters:
**Parameters**
**n** : int
:math:`n`, where the number of grid points is :math:`n+1`. This is also the largest order of Chebyshev polynomial in the Chebyshev series to be computed.
**a** : float
:math:`a`, the lower bound of domain :math:`\left[a, b\right]`.
**b** : float
:math:`b`, the upper bound of domain :math:`\left[a, b\right]`.
**Returns**
**x** : float, ndarray, shape :math:`\left(\mathrm{n}+1\right)`
The Chebyshev Gauss--Lobatto grid points, :math:`x_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,n+1`, on :math:`\left[a, b\right]`.
.. _d02uc-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{n} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{n} > 0`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{n} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{n}` is even.
(`errno` :math:`2`)
On entry, :math:`\mathrm{a} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{b} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{a} < \mathrm{b}`.
.. _d02uc-py2-py-notes:
**Notes**
``bvp_ps_lin_cgl_grid`` returns the Chebyshev Gauss--Lobatto grid points on :math:`\left[a, b\right]`.
The Chebyshev Gauss--Lobatto points on :math:`\left[-1, 1\right]` are computed as :math:`t_{\textit{i}} = -\cos\left(\frac{{\left(\textit{i}-1\right)\pi }}{n}\right)`, for :math:`\textit{i} = 1,2,\ldots,n+1`.
The Chebyshev Gauss--Lobatto points on an arbitrary domain :math:`\left[a, b\right]` are:
.. math::
x_i = \frac{{b-a}}{2}t_i+\frac{{a+b}}{2}\text{, }\quad i = 1,2,\ldots,n+1\text{.}
.. _d02uc-py2-py-references:
**References**
Trefethen, L N, 2000, `Spectral Methods in MATLAB`, SIAM
"""
raise NotImplementedError
[docs]def bvp_ps_lin_cgl_deriv(f):
r"""
``bvp_ps_lin_cgl_deriv`` differentiates a function discretized on Chebyshev Gauss--Lobatto points.
The grid points on which the function values are to be provided are normally returned by a previous call to :meth:`bvp_ps_lin_cgl_grid`.
.. _d02ud-py2-py-doc:
For full information please refer to the NAG Library document for d02ud
https://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02udf.html
.. _d02ud-py2-py-parameters:
**Parameters**
**f** : float, array-like, shape :math:`\left(n+1\right)`
The function values :math:`f\left(x_{\textit{i}}\right)`, for :math:`\textit{i} = 1,2,\ldots,n+1`
**Returns**
**fd** : float, ndarray, shape :math:`\left(n+1\right)`
The approximations to the derivatives of the function evaluated at the Chebyshev Gauss--Lobatto points. For functions defined on :math:`\left[a, b\right]`, the returned derivative values (corresponding to the domain :math:`\left[-1, 1\right]`) must be multiplied by the factor :math:`2/\left(b-a\right)` to obtain the correct values on :math:`\left[a, b\right]`.
.. _d02ud-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n > 0`.
(`errno` :math:`1`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\textit{n}` is even.
.. _d02ud-py2-py-notes:
**Notes**
``bvp_ps_lin_cgl_deriv`` differentiates a function discretized on Chebyshev Gauss--Lobatto points on :math:`\left[-1, 1\right]`.
The polynomial interpolation on Chebyshev points is equivalent to trigonometric interpolation on equally spaced points.
Hence the differentiation on the Chebyshev points can be implemented by the Fast Fourier transform (FFT).
Given the function values :math:`f\left(x_i\right)` on Chebyshev Gauss--Lobatto points :math:`x_{\textit{i}} = -\cos\left(\left(\textit{i}-1\right)\pi /n\right)`, for :math:`\textit{i} = 1,2,\ldots,n+1`, :math:`f` is differentiated with respect to :math:`x` by means of forward and backward FFTs on the function values :math:`f\left(x_i\right)`. ``bvp_ps_lin_cgl_deriv`` returns the computed derivative values :math:`f^{\prime }\left(x_{\textit{i}}\right)`, for :math:`\textit{i} = 1,2,\ldots,n+1`.
The derivatives are computed with respect to the standard Chebyshev Gauss--Lobatto points on :math:`\left[-1, 1\right]`; for derivatives of a function on :math:`\left[a, b\right]` the returned values have to be scaled by a factor :math:`2/\left(b-a\right)`.
.. _d02ud-py2-py-references:
**References**
Canuto, C, Hussaini, M Y, Quarteroni, A and Zang, T A, 2006, `Spectral Methods: Fundamentals in Single Domains`, Springer
Greengard, L, 1991, `Spectral integration and two-point boundary value problems`, SIAM J. Numer. Anal. (28(4)), 1071--80
Trefethen, L N, 2000, `Spectral Methods in MATLAB`, SIAM
"""
raise NotImplementedError
[docs]def bvp_ps_lin_solve(a, b, c, bmat, y, bvec, f):
r"""
``bvp_ps_lin_solve`` finds the solution of a linear constant coefficient boundary value problem by using the Chebyshev integration formulation on a Chebyshev Gauss--Lobatto grid.
.. _d02ue-py2-py-doc:
For full information please refer to the NAG Library document for d02ue
https://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02uef.html
.. _d02ue-py2-py-parameters:
**Parameters**
**a** : float
:math:`a`, the lower bound of domain :math:`\left[a, b\right]`.
**b** : float
:math:`b`, the upper bound of domain :math:`\left[a, b\right]`.
**c** : float, array-like, shape :math:`\left(n+1\right)`
The Chebyshev coefficients :math:`c_j`, :math:`j = 0,1,\ldots,n`, for the right-hand side of the boundary value problem. Usually these are obtained by a previous call of :meth:`bvp_ps_lin_coeffs`.
**bmat** : float, array-like, shape :math:`\left(m, m+1\right)`
:math:`\mathrm{bmat}[\textit{i}-1,{\textit{j}+1}-1]` must contain the coefficients :math:`B_{{\textit{i},\textit{j}+1}}`, for :math:`\textit{j} = 0,1,\ldots,m`, for :math:`\textit{i} = 1,2,\ldots,m`, in the problem formulation of :ref:`Notes <d02ue-py2-py-notes>`.
**y** : float, array-like, shape :math:`\left(m\right)`
The points, :math:`y_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,m`, where the boundary conditions are discretized.
**bvec** : float, array-like, shape :math:`\left(m\right)`
The values, :math:`\beta_{\textit{i}}`, for :math:`\textit{i} = 1,2,\ldots,m`, in the formulation of the boundary conditions given in :ref:`Notes <d02ue-py2-py-notes>`.
**f** : float, array-like, shape :math:`\left(m+1\right)`
The coefficients, :math:`f_{\textit{j}}`, for :math:`\textit{j} = 1,2,\ldots,m+1`, in the formulation of the linear boundary value problem given in :ref:`Notes <d02ue-py2-py-notes>`. The highest order term, :math:`\mathrm{f}[{m+1}-1]`, needs to be nonzero to have a well posed problem.
**Returns**
**bmat** : float, ndarray, shape :math:`\left(m, m+1\right)`
The coefficients have been scaled to form an equivalent problem defined on the domain :math:`\left[-1, 1\right]`.
**f** : float, ndarray, shape :math:`\left(m+1\right)`
The coefficients have been scaled to form an equivalent problem defined on the domain :math:`\left[-1, 1\right]`.
**uc** : float, ndarray, shape :math:`\left(n+1, m+1\right)`
The Chebyshev coefficients in the Chebyshev series representations of the solution and derivatives of the solution to the boundary value problem. The :math:`n+1` elements :math:`\mathrm{uc}[0:{n+1},0]` contain the coefficients representing the solution :math:`U\left(x_{\textit{i}}\right)`, for :math:`\textit{i} = 0,1,\ldots,n`. :math:`\mathrm{uc}[0:{n+1},\textit{j}]` contains the coefficients representing the :math:`\textit{j}`\ th derivative of :math:`U`, for :math:`\textit{j} = 1,2,\ldots,m`.
**resid** : float
The maximum residual resulting from substituting the solution vectors returned in :math:`\mathrm{uc}` into the equations representing the linear boundary value problem and associated boundary conditions.
.. _d02ue-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n\geq 8`.
(`errno` :math:`1`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\textit{n}` is even.
(`errno` :math:`2`)
On entry, :math:`\mathrm{a} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{b} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{a} < \mathrm{b}`.
(`errno` :math:`3`)
On entry, :math:`\mathrm{f}[m] = 0.0`.
(`errno` :math:`6`)
On entry, :math:`m = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`1\leq m\leq 4`.
(`errno` :math:`7`)
Internal error while unpacking matrix during iterative refinement.
Please contact `NAG <https://www.nag.com>`__.
(`errno` :math:`8`)
Singular matrix encountered during iterative refinement.
Please check that your system is well posed.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`9`)
During iterative refinement, the maximum number of iterations was reached.
:math:`\text{Number of iterations} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\text{residual achieved} = \langle\mathit{\boldsymbol{value}}\rangle`.
(`errno` :math:`10`)
During iterative refinement, convergence was achieved, but the residual is more than :math:`100\times \text{machine precision}`. :math:`\text{Residual achieved on convergence} = \langle\mathit{\boldsymbol{value}}\rangle`.
.. _d02ue-py2-py-notes:
**Notes**
``bvp_ps_lin_solve`` solves the constant linear coefficient ordinary differential problem
.. math::
\sum_{0}^{m}{f_{{j+1}}}\frac{{d^ju}}{{dx^j}} = f\left(x\right)\text{, }\quad x \in \left[a, b\right]
subject to a set of :math:`m` linear constraints at points :math:`y_{\textit{i}} \in \left[a, b\right]`, for :math:`\textit{i} = 1,2,\ldots,m`:
.. math::
\sum_{0}^{m}{B_{{i,j+1}}}\left(\frac{{d^ju}}{{dx}^j}\right)_{\left(x = y_i\right)} = \beta_i\text{,}
where :math:`1\leq m\leq 4`, :math:`B` is an :math:`m\times \left(m+1\right)` matrix of constant coefficients and :math:`\beta_i` are constants.
The points :math:`y_i` are usually either :math:`a` or :math:`b`.
The function :math:`f\left(x\right)` is supplied as an array of Chebyshev coefficients :math:`c_j`, :math:`j = 0,1,\ldots,n` for the function discretized on :math:`n+1` Chebyshev Gauss--Lobatto points (as returned by :meth:`bvp_ps_lin_cgl_grid`); the coefficients are normally obtained by a previous call to :meth:`bvp_ps_lin_coeffs`.
The solution and its derivatives (up to order :math:`m`) are returned, in the form of their Chebyshev series representation, as arrays of Chebyshev coefficients; subsequent calls to :meth:`bvp_ps_lin_cgl_vals` will return the corresponding function and derivative values at the Chebyshev Gauss--Lobatto discretization points on :math:`\left[a, b\right]`.
Function and derivative values can be obtained on any uniform grid over the same range :math:`\left[a, b\right]` by calling the interpolation function :meth:`bvp_ps_lin_grid_vals`.
.. _d02ue-py2-py-references:
**References**
Clenshaw, C W, 1957, `The numerical solution of linear differential equations in Chebyshev series`, Proc. Camb. Phil. Soc. (53), 134--149
Coutsias, E A, Hagstrom, T and Torres, D, 1996, `An efficient spectral method for ordinary differential equations with rational function coefficients`, Mathematics of Computation (65(214)), 611--635
Greengard, L, 1991, `Spectral integration and two-point boundary value problems`, SIAM J. Numer. Anal. (28(4)), 1071--80
Lundbladh, A, Hennigson, D S and Johannson, A V, 1992, `An efficient spectral integration method for the solution of the Navier--Stokes equations`, Technical report FFA--TN, 1992--28, Aeronautical Research Institute of Sweden
Muite, B K, 2010, `A numerical comparison of Chebyshev methods for solving fourth-order semilinear initial boundary value problems`, Journal of Computational and Applied Mathematics (234(2)), 317--342
"""
raise NotImplementedError
[docs]def bvp_ps_lin_grid_vals(nip, x, f):
r"""
``bvp_ps_lin_grid_vals`` interpolates from a set of function values on a supplied grid onto a set of values for a uniform grid on the same range.
The interpolation is performed using barycentric Lagrange interpolation. ``bvp_ps_lin_grid_vals`` is primarily a utility function to map a set of function values specified on a Chebyshev Gauss--Lobatto grid onto a uniform grid.
.. _d02uw-py2-py-doc:
For full information please refer to the NAG Library document for d02uw
https://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02uwf.html
.. _d02uw-py2-py-parameters:
**Parameters**
**nip** : int
The number, :math:`m`, of grid points in the uniform mesh :math:`\hat{x}` onto which function values are interpolated. If :math:`\mathrm{nip} = 1` then on successful exit from ``bvp_ps_lin_grid_vals``, :math:`\mathrm{fip}[0]` will contain the value :math:`f\left(x_n\right)`.
**x** : float, array-like, shape :math:`\left(n+1\right)`
The grid points, :math:`x_{\textit{i}}`, for :math:`\textit{i} = 0,1,\ldots,n`, at which the function is specified.
Usually this should be the array of Chebyshev Gauss--Lobatto points returned in :meth:`bvp_ps_lin_cgl_grid`.
**f** : float, array-like, shape :math:`\left(n+1\right)`
The function values, :math:`f\left(x_{\textit{i}}\right)`, for :math:`\textit{i} = 0,1,\ldots,n`.
**Returns**
**xip** : float, ndarray, shape :math:`\left(\mathrm{nip}\right)`
The evenly-spaced grid points, :math:`\hat{x}_{\textit{j}}`, for :math:`\textit{j} = 1,2,\ldots,m`.
**fip** : float, ndarray, shape :math:`\left(\mathrm{nip}\right)`
The set of interpolated values :math:`\hat{f}\left(\hat{x}_{\textit{j}}\right)`, for :math:`\textit{j} = 1,2,\ldots,m`. Here :math:`\hat{f}\left(\hat{x}_{\textit{j}}\right)≈f\left(x = \hat{x}_{\textit{j}}\right)`.
.. _d02uw-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`n > 0`.
(`errno` :math:`1`)
On entry, :math:`n = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\textit{n}` is even.
(`errno` :math:`2`)
On entry, :math:`\mathrm{nip} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{nip} > 0`.
.. _d02uw-py2-py-notes:
**Notes**
``bvp_ps_lin_grid_vals`` interpolates from a set of :math:`n+1` function values, :math:`f\left(x_{\textit{i}}\right)`, on a supplied grid, :math:`x_{\textit{i}}`, for :math:`\textit{i} = 0,1,\ldots,n`, onto a set of :math:`m` values, :math:`\hat{f}\left(\hat{x}_{\textit{j}}\right)`, on a uniform grid, :math:`\hat{x}_{\textit{j}}`, for :math:`\textit{j} = 1,2,\ldots,m`.
The image :math:`\hat{x}` has the same range as :math:`x`, so that :math:`\hat{x}_{\textit{j}} = x_{\textit{min}}+\left(\left(\textit{j}-1\right)/\left(m-1\right)\right)\times \left(x_{\textit{max}}-x_{\textit{min}}\right)`, for :math:`\textit{j} = 1,2,\ldots,m`.
The interpolation is performed using barycentric Lagrange interpolation as described in Berrut and Trefethen (2004).
``bvp_ps_lin_grid_vals`` is primarily a utility function to map a set of function values specified on a Chebyshev Gauss--Lobatto grid computed by :meth:`bvp_ps_lin_cgl_grid` onto an evenly-spaced grid with the same range as the original grid.
.. _d02uw-py2-py-references:
**References**
Berrut, J P and Trefethen, L N, 2004, `Barycentric lagrange interpolation`, SIAM Rev. (46(3)), 501--517
"""
raise NotImplementedError
[docs]def bvp_ps_lin_quad_weights(n):
r"""
``bvp_ps_lin_quad_weights`` obtains the weights for Clenshaw--Curtis quadrature at Chebyshev points.
This allows for fast approximations of integrals for functions specified on Chebyshev Gauss--Lobatto points on :math:`\left[-1, 1\right]`.
.. _d02uy-py2-py-doc:
For full information please refer to the NAG Library document for d02uy
https://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02uyf.html
.. _d02uy-py2-py-parameters:
**Parameters**
**n** : int
:math:`n`, where the number of grid points is :math:`n+1`.
**Returns**
**w** : float, ndarray, shape :math:`\left(\mathrm{n}+1\right)`
The Clenshaw--Curtis quadrature weights, :math:`w_{\textit{i}}`, for :math:`\textit{i} = 0,1,\ldots,n`.
.. _d02uy-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{n} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{n} > 0`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{n} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{n}` is even.
.. _d02uy-py2-py-notes:
**Notes**
``bvp_ps_lin_quad_weights`` obtains the weights for Clenshaw--Curtis quadrature at Chebyshev points.
Given the (Clenshaw--Curtis) weights :math:`w_{\textit{i}}`, for :math:`\textit{i} = 0,1,\ldots,n`, and function values :math:`f_{\textit{i}} = f\left(t_{\textit{i}}\right)` (where :math:`t_{\textit{i}} = -\cos\left(\textit{i}\times \pi /n\right)`, for :math:`\textit{i} = 0,1,\ldots,n`, are the Chebyshev Gauss--Lobatto points), then :math:`\int_{-1}^1f\left(x\right)dx≈\sum_{0}^{n}{w_i}f_i`.
For a function discretized on a Chebyshev Gauss--Lobatto grid on :math:`\left[a, b\right]` the resultant summation must be multiplied by the factor :math:`\left(b-a\right)/2`.
.. _d02uy-py2-py-references:
**References**
Trefethen, L N, 2000, `Spectral Methods in MATLAB`, SIAM
"""
raise NotImplementedError
[docs]def bvp_ps_lin_cheb_eval(k, x):
r"""
``bvp_ps_lin_cheb_eval`` returns the value of the :math:`k`\ th Chebyshev polynomial evaluated at a point :math:`x \in \left[-1, 1\right]`. ``bvp_ps_lin_cheb_eval`` is primarily a utility function for use by the Chebyshev boundary value problem solvers.
.. _d02uz-py2-py-doc:
For full information please refer to the NAG Library document for d02uz
https://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02uzf.html
.. _d02uz-py2-py-parameters:
**Parameters**
**k** : int
The order of the Chebyshev polynomial.
**x** : float
The point at which to evaluate the polynomial.
**Returns**
**t** : float
The value, :math:`T`, of the Chebyshev polynomial order :math:`k` evaluated at :math:`x`.
.. _d02uz-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\mathrm{k} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{k}\geq 0`.
(`errno` :math:`2`)
On entry, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`{-1.0}\leq \mathrm{x}\leq 1.0`.
.. _d02uz-py2-py-notes:
**Notes**
``bvp_ps_lin_cheb_eval`` returns the value, :math:`T`, of the :math:`k`\ th Chebyshev polynomial evaluated at a point :math:`x \in \left[-1, 1\right]`; that is, :math:`T = \cos\left(k\times \arccos\left(x\right)\right)`.
.. _d02uz-py2-py-references:
**References**
Trefethen, L N, 2000, `Spectral Methods in MATLAB`, SIAM
"""
raise NotImplementedError
[docs]def ivp_stiff_nat_interp(xsol, m, comm, neq, x, nqu, hu, h):
r"""
``ivp_stiff_nat_interp`` interpolates components of the solution of a system of first-order ordinary differential equations from information provided by the integrators in submodule ``ode``.
.. _d02xj-py2-py-doc:
For full information please refer to the NAG Library document for d02xj
https://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02xjf.html
.. _d02xj-py2-py-parameters:
**Parameters**
**xsol** : float
The point at which the first :math:`m` components of the solution are to be evaluated. :math:`\mathrm{xsol}` should not be an extrapolation point, that is :math:`\mathrm{xsol}` should satisfy :math:`\left(\mathrm{xsol}-\mathrm{x}\right)\times \mathrm{hu}\leq 0.0`. Extrapolation is permitted but not recommended.
**m** : int
:math:`m`, the number of components of the solution whose values at :math:`\mathrm{xsol}` are required. The first :math:`\mathrm{m}` components are evaluated.
**comm** : dict, communication object
Communication structure populated by a previous call to the integrator.
**neq** : int
The value used for the argument :math:`\mathrm{neq}` when calling the integrator.
**x** : float
The latest value at which the solution has been computed, as provided in the argument :math:`\textit{tcur}` on return from the optional output :meth:`ivp_stiff_integ_diag`.
**nqu** : int
The order of the method used up to the latest value at which the solution has been computed, as provided in the argument :math:`\textit{nqu}` on return from the optional output :meth:`ivp_stiff_integ_diag`.
**hu** : float
The last successful step used, that is the step used in the integration to get to :math:`\mathrm{x}`, as provided in the argument :math:`\textit{hu}` on return from the optional output :meth:`ivp_stiff_integ_diag`.
**h** : float
The next step size to be attempted in the integration, as provided in the argument :math:`\textit{h}` on return from the optional output :meth:`ivp_stiff_integ_diag`.
**Returns**
**sol** : float, ndarray, shape :math:`\left(\mathrm{m}\right)`
The calculated value of the :math:`\textit{i}`\ th component of the solution at :math:`\mathrm{xsol}`, for :math:`\textit{i} = 1,2,\ldots,m`.
.. _d02xj-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
On entry, :math:`\textit{sdysav} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{nqu} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\textit{sdysav}\geq \mathrm{nqu}+1`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{nqu} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{nqu}\geq 1`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{neq} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\textit{ldysav} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{neq}\leq \textit{ldysav}`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{m} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{neq} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{m}\leq \mathrm{neq}`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{neq} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{neq}\geq 1`.
(`errno` :math:`1`)
On entry, :math:`\textit{ldysav} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\textit{ldysav}\geq 1`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{m} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{m}\geq 1`.
(`errno` :math:`2`)
On entry, :math:`\mathrm{hu} = 0.0`.
(`errno` :math:`2`)
On entry, :math:`\mathrm{h} = 0.0`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`3`)
On entry, :math:`\mathrm{xsol} = \langle\mathit{\boldsymbol{value}}\rangle`, :math:`\mathrm{x} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{h} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{xsol}` should not be an extrapolation point.
.. _d02xj-py2-py-notes:
**Notes**
`No equivalent traditional C interface for this routine exists in the NAG Library.`
``ivp_stiff_nat_interp`` evaluates the first :math:`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_nat_interp``. ``ivp_stiff_nat_interp`` should not normally be used to extrapolate outside the range of values obtained from the above functions.
"""
raise NotImplementedError
[docs]def ivp_stiff_c1_interp(xsol, m, comm, acor, x, nqu, hu, h):
r"""
``ivp_stiff_c1_interp`` interpolates components of the solution of a system of first-order ordinary differential equations from information provided by the integrators in submodule ``ode``.
It provides :math:`C^1` interpolation suitable for general use.
.. _d02xk-py2-py-doc:
For full information please refer to the NAG Library document for d02xk
https://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02xkf.html
.. _d02xk-py2-py-parameters:
**Parameters**
**xsol** : float
The point at which the first :math:`m` components of the solution are to be evaluated. :math:`\mathrm{xsol}` should not be an extrapolation point, that is :math:`\mathrm{xsol}` should satisfy :math:`\left(\mathrm{xsol}-\mathrm{x}\right)\times \mathrm{hu}\leq 0.0`. Extrapolation is permitted but not recommended.
**m** : int
The number of components of the solution whose values at :math:`\mathrm{xsol}` are required. The first :math:`m` components are evaluated.
**comm** : dict, communication object
Communication structure populated by a previous call to the integrator.
**acor** : float, array-like, shape :math:`\left(\textit{neq}\right)`
The value returned in position :math:`\left(\textit{ldysav}+50+\textit{i}\right)`, for :math:`\textit{i} = 1,2,\ldots,\textit{neq}`, of the argument :math:`\textit{rwork}` returned by the integrator. If one of the direct communication D02N functions is being employed and ``ivp_stiff_c1_interp`` is to be used in :math:`\textit{monitr}`, :math:`{\textit{acor}}[\textit{i}-1]` must contain the value given in position :math:`\left(\textit{i}, 2\right)` of the :math:`\textit{monitr}` argument :math:`\textit{acor}`, for :math:`\textit{i} = 1,2,\ldots,\textit{neq}` (e.g., see :meth:`ivp_stiff_exp_fulljac`).
**x** : float
The latest value at which the solution has been computed, as provided in the argument :math:`\textit{tcur}` on return from the optional output :meth:`ivp_stiff_integ_diag`.
**nqu** : int
The order of the method used up to the latest value at which the solution has been computed, as provided in the argument :math:`\textit{nqu}` on return from the optional output :meth:`ivp_stiff_integ_diag`.
**hu** : float
The last successful step used, that is the step used in the integration to get to :math:`\mathrm{x}`, as provided in the argument :math:`\textit{hu}` on return from the optional output :meth:`ivp_stiff_integ_diag`.
**h** : float
The next step size to be attempted in the integration, as provided in the argument :math:`\textit{h}` on return from the optional output :meth:`ivp_stiff_integ_diag`.
**Returns**
**sol** : float, ndarray, shape :math:`\left(\mathrm{m}\right)`
The calculated value of the :math:`\textit{i}`\ th component of the solution at :math:`\mathrm{xsol}`, for :math:`\textit{i} = 1,2,\ldots,m`.
.. _d02xk-py2-py-errors:
**Raises**
**NagValueError**
(`errno` :math:`1`)
The Petzold error test was selected.
(`errno` :math:`1`)
The BDF integration method is not being used.
(`errno` :math:`1`)
On entry, :math:`\textit{sdysav} = \langle\mathit{\boldsymbol{value}}\rangle` and :math:`\mathrm{nqu} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\textit{sdysav}\geq \mathrm{nqu}+1`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{nqu} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{nqu}\geq 1`.
(`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:`\textit{ldysav} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\textit{ldysav}\geq 1`.
(`errno` :math:`1`)
On entry, :math:`\mathrm{m} = \langle\mathit{\boldsymbol{value}}\rangle`.
Constraint: :math:`\mathrm{m}\geq 1`.
(`errno` :math:`2`)
On entry, :math:`\mathrm{hu} = 0.0`.
(`errno` :math:`2`)
On entry, :math:`\mathrm{h} = 0.0`.
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`3`)
Extrapolation has been performed.
.. _d02xk-py2-py-notes:
**Notes**
`No equivalent traditional C interface for this routine exists in the NAG Library.`
``ivp_stiff_c1_interp`` evaluates the first :math:`m` components of the solution of a system of ordinary differential equations at any point using :math:`C^1` polynomial interpolation based on information generated by the integrator.
This information must be passed unchanged to ``ivp_stiff_c1_interp``. ``ivp_stiff_c1_interp`` should not normally be used to extrapolate outside the range of values obtained from the above functions.
It may be used with the D02N functions only when the BDF integration method is being employed (setup function :meth:`ivp_stiff_bdf`), provided the Petzold error test was not selected.
"""
raise NotImplementedError
[docs]def ivp_stiff_errest(v, w, comm):
r"""
``ivp_stiff_errest`` calculates the weighted norm of the local error estimate from inside a :math:`\textit{monitr}` called from an integrator in submodule ``ode`` (e.g., see :meth:`ivp_stiff_exp_fulljac`).
.. _d02za-py2-py-doc:
For full information please refer to the NAG Library document for d02za
https://support.nag.com/numeric/nl/nagdoc_30.2/flhtml/d02/d02zaf.html
.. _d02za-py2-py-parameters:
**Parameters**
**v** : float, array-like, shape :math:`\left(\textit{neq}\right)`
The vector, the weighted norm of which is to be evaluated by ``ivp_stiff_errest``. :math:`\mathrm{v}` is calculated internally by the integrator being used.
**w** : float, array-like, shape :math:`\left(\textit{neq}\right)`
The weights, calculated internally by the integrator, to be used in the norm evaluation.
**comm** : dict, communication object
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`.
**Returns**
**errnrm** : float
:math:`\left\lVert v\right\rVert`, the norm of the scaled local error estimate.
.. _d02za-py2-py-errors:
**Warns**
**NagAlgorithmicWarning**
(`errno` :math:`1`)
The value of the norm would either overflow or is close to overflowing.
.. _d02za-py2-py-notes:
**Notes**
`No equivalent traditional C interface for this routine exists in the NAG Library.`
``ivp_stiff_errest`` is for use with the direct communication integrators :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` and :meth:`ivp_stiff_imp_sparjac` and the reverse communication integrators :meth:`ivp_stiff_exp_revcom` and :meth:`ivp_stiff_imp_revcom`.
It must be used only inside :math:`\textit{monitr}` (if this option is selected) for the direct communication functions or on the equivalent return for the reverse communication functions.
It may be used to evaluate the norm of the scaled local error estimate, :math:`\left\lVert v\right\rVert`, where the weights used are contained in :math:`w` and the norm used is as defined by an earlier call to the integrator setup function (:meth:`ivp_stiff_dassl`, :meth:`ivp_stiff_bdf` or :meth:`ivp_stiff_blend`).
Its use is described under the description of :math:`\textit{monitr}` in the specifications for the direct communication integrators mentioned above.
"""
raise NotImplementedError