scijit.optimize.fsolve¶
- scijit.optimize.fsolve(func, x0, args=(), fprime=None, full_output=False, col_deriv=0, xtol=1.49012e-08, maxfev=0, band=None, epsfcn=None, factor=100.0, diag=None, mode=-1, validate=True, keep_shape=False)¶
Find the roots of a system of nonlinear equations.
Wraps MINPACK’s
hybrd, a modified Powell hybrid method, orhybrjwhen an analytic Jacobian is supplied.Callable from Python and from inside
@njit.- Parameters:
- funccallable
A plain
@njitf(x) -> residualsorf(x, args) -> residuals. The arity is detected, so the args form is used only when args is passed. The residual count must equalx0.size.- x0float or array_like
Initial guess. A scalar, list or tuple is accepted. Any rank is FLATTENED, so an
(n, m)guess is one system ofn*mvariables rather than a batch.- 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,).- fprimecallable or None, optional
None(default) uses a forward-difference Jacobian. A plain@njitjac(x) -> (n, n)selects the analytic path, with theiflagbranch and MINPACK’s column-major layout handled internally.- full_outputbool, optional
False(default) returns x alone.Truereturns the 4-tuple. Compile-time constant inside@njit: a literal, or left at its default.- col_derivint, optional
A statement about fprime.
0(default) readsjac(x)asJ[i, j] = dF_i/dx_j; a nonzero value reads it as already transposed. Ignored without fprime. A runtime variable is fine.- xtolfloat, optional
Relative error desired in the solution. Default 1.49012e-8.
- maxfevint, optional
Maximum callback evaluations.
0(default) means200*(n+1), or100*(n+1)with fprime.- bandtuple of int or None, optional
(ml, mu), the sub- and super-diagonal counts of a banded Jacobian.None(default) treats it as dense.- epsfcnfloat or None, optional
Forward-difference step.
None(default) resolves to machine epsilon.- 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.None(default) lets MINPACK derive them from the Jacobian column norms.- modeint, optional
Scaling mode.
1scales internally,2uses diag unchanged.-1(default) resolves to1when diag isNoneand2otherwise. A runtime variable is fine: it does not change the return type.- validatebool, optional
True(default) raises when the returned solution is degenerate, and probes whether the callback reads past the end of args.Falsereports the degenerate conditions through ier instead and skips the read probe. The check that the callback wrotefvec, and the residual-count and Jacobian-shape checks, are always on. Withfull_output=Falseavalidate=Falsefailure is invisible, so pair the two.- keep_shapebool, optional
False(default) returns x 1-D.Truereshapes it back to x0’s rank, which reads better for a field on a grid. Affects x only. Compile-time constant.
- Returns:
- xndarray
The solution, 1-D unless
keep_shape=True.- infodictInfoDict or InfoDictJ
Only with
full_output=True. Namedtuple with fieldsnfev,fjac,r,qtfandfvec, plusnjevafternfevon the fprime path, reached as attributes or by name. All butnfevare meaningful only whenier == 1.- ierint
MINPACK’s status:
0the arguments were rejected and the solver never ran, reachable only here since a bare call raises on it;1converged,2maxfev reached,3xtol too small,4and5not making progress.-1and-2are this package’s degenerate-solution codes, reachable only undervalidate=False:-1the residual is identically zero,-2the reported residual disagrees with a fresh evaluation at x.- mesgstr
The message matching ier.
- Raises:
- TypeError
If MINPACK reports
ier = 0, meaning it rejected the arguments and never ran, so x would come back as x0. Raised only on a bare call: withfull_output=Truethe status is returned asier = 0instead. Also if the residual count disagrees withx0.size, if fprime returns something other than an(n, n)array, or if diag has fewer entries than x0.- ValueError
If func or fprime is not a plain
@njitfunction; if an args entry is neither a real number nor an array of real numbers; if the callback never wrotefvec; or, undervalidate=True, if the returned solution is degenerate or the callback read past the end of args.
See also
scipy.optimize.fsolveThe scipy routine this mirrors.
scijit.optimize.rootThe same solvers behind a
methodargument.scijit.optimize.leastsqLeast squares rather than a square system.
Notes
infodict is a namedtuple rather than a dict.
info['nfev'],info.get('nfev'),info.keys(),info.values(),info.items()and'nfev' in infoall work, from Python and from inside@njit, and its field order is scipy’s key insertion order, so positional unpacking agrees too. Iterating it yields VALUES, where iterating a dict yields keys.nfevcounts every evaluation of func, including the ones this package makes before the solver runs: one to read the residual count off the callback, one to check that the callback writesfvec, and two more undervalidate=Truefor the read probe. scipy counts two of its own, sonfevis two higher than scipy’s on the forward-difference path atvalidate=Trueand equal to it on the other three. The evaluation fprime costs for its shape check is not counted, and scipy does not count its own either.Each args entry must be a real number or an array of real numbers. A mixed tuple is served:
(matrix, scale)reaches the callback as two separate parameters and returns[3., 3.]on the residualx - matrix.diagonal() * scale, which is what scipy returns on the same call. An entry of any other type raises, andargs=Noneis one: scipy reads it as the one-item tuple(None,)and callsf(x, None).Whether the callback reads past the end of args is recovered by probing it under
validate=True. An overrun larger than 8 slots still escapes that probe.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.
mode, validate and keep_shape have no scipy counterpart. Their defaults reproduce scipy: mode derives from diag exactly as scipy derives it, and keep_shape=False returns the flat x scipy returns.
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.fsolve.html
Examples
>>> import numpy as np >>> from numba import njit >>> from scijit.optimize import fsolve >>> @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 fsolve(f, np.array([0.0, 0.0])) >>> run() array([0.8411639, 0.1588361])
Parameters reach the callback through args, splatted as
func(x, *args):>>> @njit ... def fa(x, c): ... return np.array([x[0] ** 2 - c]) >>> @njit ... def run_args(): ... return fsolve(fa, np.array([1.0]), (2.0,)) >>> run_args() array([1.41421356])
With full_output, which must be a literal inside
@njit:>>> @njit ... def run_full(): ... return fsolve(f, np.array([0.0, 0.0]), full_output=True) >>> x, infodict, ier, mesg = run_full() >>> ier, infodict.nfev (1, 16) >>> mesg 'The solution converged.'