scijit.optimize.bisect¶
- scijit.optimize.bisect(f, a, b, args=(), xtol=2e-12, rtol=8.881784197001252e-16, maxiter=100, full_output=False, disp=True)¶
Bisection root-finder.
Callback style A:
fis a plain@njitfunction taking one float and returning one float. No@cfunc, no.address, and with anargstuple beside it:@njit def f(x): return x * x - 2.0 root = bisect(f, 0.0, 2.0) root, res = bisect(f, 0.0, 2.0, full_output=True)
- Parameters:
- f@njit function
f(x) -> float Continuous function whose root is wanted.
- a, bfloat
Bracket endpoints.
f(a)andf(b)must not have the same sign; if they do,ValueErroris raised. Either endpoint being an exact root returns immediately withiterations = 0.- argstuple, optional
Extra arguments for f, unpacked into every call as
f(x, *args). A non-tuple is taken as a single extra argument. Default().- xtolfloat, optional
Absolute tolerance on the bracket width. Default 2e-12. Must be positive;
ValueErrorotherwise.- rtolfloat, optional
Relative tolerance; convergence when
|dm| < xtol + rtol * |x|. Default4 * eps= 8.88e-16, which is also its floor. A smaller value raisesValueError.- maxiterint, optional
Iteration cap. Default 100. Negative raises
ValueError.- full_outputbool, optional
False(default) returns the root alone.Truereturns(x, RootResults). Inside@njitit must be a compile-time constant; see Notes.- dispbool, optional
True(default) raisesRuntimeErrorwhen the iteration limit is reached.Falsereturnsconverged=Falseinstead, with root set to the left endpoint of the surviving bracket.
- f@njit function
- Returns:
- xfloat
The estimated root, when
full_outputis False.- (x, res)tuple of (float, RootResults)
When
full_outputis True. res fields are reached by attribute, by index or by unpacking.- rootfloat
Best estimate of the root.
- iterationsint
Iterations used.
- function_callsint
Evaluations of f. Counts every one, including the ones a solver discards.
- convergedbool
True if a tolerance test was met before maxiter. Only ever False under
disp=False.- flagstr
'converged', or'convergence error'.- methodstr
The method that produced the result, by name.
- Raises:
- ValueError
If
f(a)andf(b)have the same sign, so the interval is not known to bracket a root; if a or b is infinite and the sign test passes; iffreturns NaN at any iterate; ifxtol <= 0; if rtol is below4 * eps; or ifmaxiter < 0.- RuntimeError
If maxiter is reached, unless
disp=False.- numba.core.errors.TypingError
From inside
@njit, if full_output is a runtime variable.
See also
scipy.optimize.bisectThe scipy routine this mirrors.
scijit.optimize.brentqFaster on a well-behaved function; the usual choice.
scijit.optimize.root_scalarThe bracketing methods behind a
methodargument.
Notes
full_output selects the RETURN SHAPE, and a compiled function has one return type per signature, so inside
@njitthe flag has to be readable when the call compiles. A literal, an omitted default and a module-level constant all are; a variable is not, and raises TypingError naming the constraint. From Python a runtime value is fine.The result is a namedtuple, where scipy’s is a
dictsubclass. See RootResults.iterationsis 0 when a or b is an exact root. scipy’s C returns before assigning that field and reports an indeterminate value read from uninitialised memory.An infinite a or b that passes the sign test raises
ValueError. scipy has no such check and runs to maxiter: measured on scipy 1.18,bisect(f, 0.0, inf)onx * x - 2reportsRuntimeError: Failed to converge after 100 iterations. An infinite endpoint that fails the sign test, is an exact root, or at which f returns NaN reaches the same outcome here as in scipy.Bisection uses only the SIGN of f, so no derivative or curvature estimate can mislead it, and the bracket halves every step: at most
log2((b - a) / xtol)iterations. It is the slowest of the bracketing methods; preferbrentq()unless f is badly behaved.Pure
@njit, no state and no callback slot, so it is safe to call from anumba.prangeloop.https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.bisect.html
Examples
>>> from numba import njit >>> from scijit.optimize import bisect >>> @njit ... def f(x): ... return x * x - 2.0 >>> @njit ... def run(): ... return bisect(f, 0.0, 2.0) >>> round(run(), 10) 1.4142135624 >>> @njit ... def run_full(): ... return bisect(f, 0.0, 2.0, full_output=True) >>> x, res = run_full() >>> round(x, 10), res.converged, res.method (1.4142135624, True, 'bisect')