scijit.optimize.root¶
- scijit.optimize.root(fun, x0, args=(), method='hybr', jac=None, tol=None, callback=None, options=None, col_deriv=0, xtol=1.49012e-08, ftol=1.49012e-08, gtol=0.0, maxfev=0, maxiter=0, band=None, eps=None, factor=100.0, diag=None, m=-1, validate=True)¶
Find a root of a vector function.
Dispatches over MINPACK’s two drivers: a modified Powell hybrid method, and Levenberg-Marquardt for a non-square system.
Callable from Python and from inside
@njit.- Parameters:
- funcallable
A plain
@njitf(x, *args) -> residuals.- x0float or array_like
Initial guess. A scalar, list or tuple is accepted. Any rank is FLATTENED.
- argstuple, optional
Extra parameters, passed to the callback as
f(x, *args), one per entry. Entries may be scalars or arrays and need not share a type. A non-tuple args is coerced to the ONE argument(args,).- method{‘hybr’, ‘lm’}, optional
'hybr'(default) modified Powell hybrid,'lm'Levenberg-Marquardt. Matched case-insensitively and NOT stripped, so'hybr 'raises. Must be a compile-time constant inside@njit: it selects the return type.- jaccallable, bool or None, optional
None(default) uses a forward-difference Jacobian. A plain@njitjac(x, *args)selects the analytic path. Any other value is read for its truth value: a truthy one means fun returns the pair(residuals, jacobian)and a falsy one means the same asNone, so1and0behave asTrueandFalse. An integer other than0or1is refused. A non-callable jac must be written out inside@njit, not held in a variable.- tolfloat or None, optional
Convenience tolerance.
None(default) leaves the per-method defaults. A value setsxtolon BOTH methods, and loses to an explicitoptions['xtol'].- callbackcallable, optional
Accepted and ignored, with a
RuntimeWarning. Neither method reads it.- optionsdict or None, optional
Solver options. Recognised keys are
col_deriv,xtol,maxfev,band,eps,factor,diagfor'hybr';col_deriv,ftol,xtol,gtol,maxiter,eps,factor,diagfor'lm'. A key the method does not read draws anOptimizeWarningand is ignored, and every key is also reachable as the argument of the same name.Inside
@njita dict whose values are all of ONE type carries only the keys of that kind, so a dict of numbers cannot holdband’s tuple ordiag’s array and raises when it names either. A dict holding values of two different types carries every key:{'xtol': 1e-10, 'band': (0, 0)}and{'xtol': 1e-10, 'diag': d}both work. An empty dict literal is not typeable by numba;Noneis the empty case.- col_derivint, optional
A statement about jac.
0(default) reads the Jacobian asJ[i, j] = dF_i/dx_j; a nonzero value reads it as already transposed, which on'lm'means the shape(n, m)rather than(m, n). Ignored without jac. A runtime variable is fine.- xtol, ftol, gtolfloat, optional
Tolerances.
ftol/gtolare read by'lm'only.- maxfevint, optional
'hybr'evaluation budget.0(default) means200*(n+1), or100*(n+1)withjac.- maxiterint, optional
'lm'evaluation budget.- bandtuple of int or None, optional
(ml, mu)for a banded Jacobian.'hybr'only.- epsfloat or None, optional
Forward-difference step.
None(default) resolves to machine epsilon on'hybr'and to0.0on'lm'. MINPACK derives the step assqrt(max(eps_given, eps_machine)), so the two spellings produce an identical step and identical evaluation counts.- factorfloat, optional
Initial step bound, in
(0.1, 100). Default 100.- diagsequence or None, optional
Per-variable scale factors, all positive. An array, list or tuple. The first
x0.sizeentries are used and any others ignored.- mint, optional
Residual count,
'lm'only.-1(default) reads it from the callback. A value skips that call.- validatebool, optional
True(default) raises when the returned solution is degenerate;Falsereports it asstatus = -1or-2instead. The check that the callback wrote anything at all is always on.
- Returns:
- resultRootHybr, RootHybrJ, RootLm or RootLmJ
A namedtuple whose fields depend on method and on whether jac was given, reached as attributes:
x,success,status,method,fun,fjac,qtf,nfev,message, plusron'hybr',ipvtandcov_xon'lm', andnjevwheneverjacis given.fun,fjac,qtfandrare only meaningful whensuccess.
- Raises:
- TypeError
If the residual count disagrees with
x0.sizeon'hybr', if jac returns an array of the wrong shape, or if diag has fewer entries than x0.- ValueError
If method is neither
'hybr'nor'lm'; if fun is not a plain@njitfunction; if an args entry is neither a real number nor an array of real numbers; if an options dict inside@njitnamesbandordiagand its value type cannot carry one; or, undervalidate=True, if the returned solution is degenerate.
See also
scipy.optimize.rootThe scipy routine this mirrors.
scijit.optimize.fsolve'hybr'alone, returning thefsolveshape.scijit.optimize.leastsq'lm'alone, returning theleastsqshape.scijit.optimize.root_scalarOne equation in one variable.
Notes
scipy dispatches
rootover ten methods. This one implementshybrandlm, calling the MINPACK drivers directly. The remaining eight (broyden1,broyden2,anderson,linearmixing,diagbroyden,excitingmixing,krylov,df-sane) are pure Python in scipy and are planned, not unavailable in principle.The result is a namedtuple rather than an
OptimizeResult.res['x'],res.get('x'),res.keys(),res.values(),res.items()and'x' in resall work, from Python and from inside@njit, and its field order is scipy’s key insertion order, which differs between the two methods as it does in scipy, so positional unpacking agrees too. Iterating it yields VALUES, where iterating a dict yields keys, and it is not an instance ofscipy.optimize.OptimizeResult.method, and whether jac is
None, must be compile-time constants inside@njit: both change the return type.callback draws a
RuntimeWarningand is ignored, and an unrecognised options key draws anOptimizeWarningand is ignored. Both are scipy’s class and scipy’s text on these two methods.cov_xon'lm'isNonein the two cases scipy returnsNone: an status outside{1, 2, 3, 4}, or a singular triangular factor.nfevcounts the evaluations this package makes before the solver runs as well as MINPACK’s own: one to check that the callback writes the residual, one on'hybr'to read the residual count, and two more on'hybr'without jac undervalidate=Truefor the read probe. On'hybr'it is therefore two higher than scipy’s without jac and equal to scipy’s with one. On'lm'the evaluation that reads the residual length is not counted, as scipy does not count its own, and nor is the one jac costs for its shape check.args=Noneraises. scipy reads it as the one-item tuple(None,)and callsf(x, None), andNoneis not a real number.A diag with fewer entries than x0 raises before the solver runs. scipy reads past the end of the array instead, and what MINPACK then does depends on the values that happen to follow it. A non-positive entry reaches MINPACK, which reports
status = 0.validate has no scipy counterpart; its default reports a degenerate solution that scipy would return silently.
Safe to call from a
numba.prangeloop. MINPACK reaches the callback through a Fortran module variable, which carries!$omp threadprivateand so resolves to one slot per thread.https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.root.html
Examples
>>> import numpy as np >>> from numba import njit >>> from scijit.optimize import root >>> @njit ... def f(x): ... return np.array([x[0] + 0.5 * (x[0] - x[1]) ** 3 - 1.0, ... 0.5 * (x[1] - x[0]) ** 3 + x[1]]) >>> @njit ... def run(): ... return root(f, np.array([0.0, 0.0])) >>> res = run() >>> res.x array([0.8411639, 0.1588361]) >>> res.success True