scijit.integrate.odeint¶
- scijit.integrate.odeint(func, y0, t, args=(), Dfun=None, col_deriv=0, full_output=0, ml=None, mu=None, rtol=None, atol=None, tcrit=None, h0=0.0, hmax=0.0, hmin=0.0, ixpr=0, mxstep=0, mxhnil=0, mxordn=12, mxords=5, printmessg=0, tfirst=False, success_out=False)¶
Integrate a system of ODEs with LSODA over a time grid.
LSODA switches between Adams (non-stiff) and BDF (stiff) methods automatically. The result is time-major: row
iis the state att[i].- Parameters:
- func@njit function
The right-hand side,
f(y, t, *args), RETURNING a new 1-D float64 array ofneqderivatives. One parameter per entry ofargs. Undertfirst=Truethe order isf(t, y, *args). A plain@njitfunction.- y0float, sequence or ndarray
Initial state at
t[0]. A scalar becomes length 1. Rank >= 2 raisesValueError.- tsequence or ndarray
Times to report at, monotonic; repeated values are allowed.
t[0]is the initial time. Rank >= 2 raisesValueError. An emptytreturns a(0, neq)array.- argstuple, optional
Extra parameters, passed to the callback as separate arguments. An entry may be a float, an int, a bool or an array of any rank, and arrives with its own type and shape. Anything other than a tuple raises
ODEpackError("Extra arguments must be in a tuple."). A callback whose arity does not fit raisesTypeErrornaming both counts.- Dfun@njit function or None, optional
The Jacobian
d f / d y,j(y, t, *args), orj(t, y, *args)undertfirst=True.None(default) leaves LSODA to build one by finite differences, atneqextra right-hand-side evaluations per rebuild. A plain@njitfunction, asfuncis.Shape
(neq, neq)withjac[i, j] = d f_i / d y_j, or, withml/muset, the packed(ml + mu + 1, neq)form withjac[mu + i - j, j] = d f_i / d y_j.col_derivtransposes both. A wrong shape raisesRuntimeError.Measured on Robertson, 3 states,
rtol=1e-8 atol=1e-10:nfe502 without and 424 with,nje26 either way, values agreeing to 1.369777e-11. The 78 evaluations removed are exactly the26 * 3the finite-difference rebuilds cost.- col_derivint, optional
Non-zero means
Dfunreturns the transpose:(neq, neq)read asjac[j, i] = d f_i / d y_j, and withml/muthe packed array transposed to(neq, ml + mu + 1). Inert withDfun=None. Must be a compile-time constant inside@njit.- full_outputbool, optional
False(default) returnsy.Truereturns(y, infodict). Must be a compile-time constant inside@njit.- ml, muint or None, optional
Half-bandwidths of the Jacobian, counting the sub- and super-diagonals and excluding the main diagonal. Setting either selects LSODA’s banded Jacobian,
jt=5withDfun=Noneandjt=4with aDfun; the unset one becomes 0.None(default) on both keeps the full Jacobian. A negative value means the same asNone.Cost, on an 80-point heat equation by method of lines whose Jacobian is tridiagonal,
rtol=1e-6 atol=1e-9: LSODA rebuilds the Jacobian 6 times and a full finite-difference rebuild spendsneq = 80right-hand-side evaluations each, againstml + mu + 1 = 3for the banded one.nfe597 against 135.- rtol, atolfloat, sequence or None, optional
Relative and absolute tolerances.
None(the default) means 1.49012e-8,sqrt(finfo(float64).eps). Either may be a scalar or a vector of lengthneq; the four combinations map to LSODA’sitol1, 2, 3 and 4. A sequence of any other length raisesODEpackError, and rank >= 2 raisesODEpackError("Error converting relative tolerance.").- tcritfloat, sequence or None, optional
Critical times the integrator must not step past, in the order it will meet them. The first is in force from the first leg; the integrator advances to the next each time an output time passes the current one, and steps freely once the sequence is exhausted.
- h0float, optional
First step size.
0.0(default) lets LSODA choose.- hmax, hminfloat, optional
Step-size bounds.
0.0(default) means no bound.- ixprint, optional
Print a message on each method switch.
- mxstepint, optional
Maximum internal steps between two output times.
0(default) means LSODA’s internal 500.- mxhnilint, optional
Maximum “step size too small” messages.
0(default) means LSODA’s internal 10.- mxordn, mxordsint, optional
Maximum order for the Adams (12) and BDF (5) methods.
- printmessgint, optional
Non-zero asks for the success message as an
ODEintWarning. An abnormal exit warns whatever this is set to.- tfirstbool, optional
False(default) selects thef(y, t, *args)callback order.Trueselectsf(t, y, *args). Must be a compile-time constant inside@njit.- success_outbool, optional
Trueappends asuccessbool to the return.Falseis the default. Must be a compile-time constant inside@njit.
- Returns:
- yfloat64 ndarray, shape
(len(t), len(y0)) Solution at each requested time, time-major.
y[0]isy0. On an abnormal exit the rows up to and including the failing leg hold real values and the rest are0.0.- infodictInfoDict
Only with
full_output=True. The 13 keys reached as attributes:hu,imxer,leniw,lenrw,message,mused,nfe,nje,nqu,nst,tcur,tolsf,tsw. The nine vector fields have lengthlen(t) - 1, one entry per integration leg. Entries past a failure are0.0.tolsfis written by LSODA only on an “excess accuracy” exit, so on a successful run it reads0.0.- successbool
Only with
success_out=True.istate == 2.
- yfloat64 ndarray, shape
- Raises:
- TypeError
funcorDfunis not a plain@njitfunction (an integer or other non-@njitvalue); or its arity does not fitargs.- ODEpackError
argsis not a tuple, or a tolerance has the wrong length or rank.- RuntimeError
The right-hand side returned the wrong number of derivatives, or
Dfunreturned the wrong shape.- ValueError
y0orthas rank >= 2, ortis not monotonic.
- Warns:
- ODEintWarning
On every abnormal exit, and on a normal one under
printmessg.
See also
scipy.integrate.odeintThe scipy routine this mirrors.
Notes
success_outhas no scipy counterpart.ODEpackErrorderives straight fromException, where scipy raises its privatescipy.integrate._odepack.error, also derived fromException.On an abnormal exit the tail of
ypast the failing leg is0.0, and theinfodictvector entries past that leg are0.0; scipy leaves both uninitialized.tolsfreads0.0on a successful run, where scipy returns whatever the heap held.The right-hand side is called once before the run and the length of what it returns is checked, which is what scipy checks inside its callback on every call.
Dfun’s shape is checked the same way. A callback whose shape CHANGES mid-run is caught by scipy on the offending call and is not caught here.Dfun’s arity is checked before the run as well. scipy reaches a wrong arity only when LSODA calls the Jacobian, which on a non-stiff problem never happens.Two refusals arrive earlier from inside
@njitthan the check order scipy runs. AfuncorDfunthat is not a plain@njitfunction, and anargsentry that is neither a real number nor an array of them, are both settled when the call compiles, so a call carrying one of them and a non-monotonictreports the refusal where scipy reports theterror. Called from python, both follow scipy’s order.infodictis a namedtuple where scipy returns a dict, soinfo['nfe']is spelledinfo.nfe.ixpr=1prints LSODA’s method-switch messages on Fortran unit 6. scipy accepts the argument and prints nothing. Unit 6 is not reachable throughcontextlib.redirect_stdout, and concurrent solves underprangeinterleave on it, soixpr=0, the default, writes nothing.Prange-safe. The callback address, the
argspointer, the Jacobian address and thetfirstflag travel through Fortran module variables, and all slots are!$omp threadprivate, so each OS thread reads its own copy.Examples
>>> import numpy as np >>> from numba import njit >>> import scijit.integrate as si >>> @njit ... def rhs(y, t, k): # scipy's order, y first ... out = np.empty(2) # y'' = -k y ... out[0] = y[1] ... out[1] = -k * y[0] ... return out >>> @njit ... def run(): ... return si.odeint(rhs, np.array([1.0, 0.0]), ... np.array([0.0, 0.5, 1.0]), (4.0,)) >>> run() array([[ 1. , 0. ], [ 0.54030231, -1.68294195], [-0.4161468 , -1.81859487]])
full_output=Trueadds scipy’s diagnostics as a namedtuple, soinfo['nfe']is spelledinfo.nfe:>>> y, info = si.odeint(rhs, np.array([1.0, 0.0]), ... np.array([0.0, 0.5, 1.0]), (4.0,), ... full_output=True) >>> info.message 'Integration successful.'