scijit.optimize.brute¶
- scijit.optimize.brute(func, ranges, args=(), Ns=20, full_output=0, finish=<function fmin>, disp=False, workers=1, xtol=0.0001, ftol=0.0001)¶
Brute-force grid search over a full Cartesian grid.
Evaluates
funcon a full Cartesian grid and returns the best point, optionally polished by a local minimiser. No randomness is involved: the same call gives the same answer every time.Callback style A –
funcis a plain@njitfunc(x, *args) -> float64.- Parameters:
- funccallable
A plain
@njitf(x, *args) -> float.- ranges(N, 2) array_like
One
(min, max)pair per dimension.sliceobjects are not accepted; see Notes.- argstuple or ndarray, optional
Extra parameters. A tuple is unpacked into separate arguments after x, so
args=(a, b)callsfunc(x, a, b). Its elements may be of any type a compiled call accepts, arrays and strings included. Default(), which callsfunc(x). An ndarray or a list arrives as ONE argument instead,func(x, args). See Notes.- Nsint, optional
Points per axis. Default 20.
- full_outputbool, optional
False(default) returnsx0alone.Truereturns(x0, fval, grid, Jout). Compile-time constant inside@njit.- finishcallable or None, optional
The minimiser that polishes the best grid point.
Noneskips it;fmin()(default) runs Nelder-Mead. Any other minimiser raises. Resolved when the call compiles, so it is a name at the call site rather than a variable. See Notes.- dispbool, optional
Reaches the finish minimiser, which then prints its own summary, and turns on a
RuntimeWarningfor a polish that reports a non-zero status. DefaultFalse.- workersint, optional
1(default) evaluates the grid in order on one thread. Any other value evaluates it in aprange;-1selects all cores. The result is BIT-IDENTICAL either way: the grid points are independent and nothing is reduced across them.The VALUE does not cap the thread count; numba’s own
NUMBA_NUM_THREADSornumba.set_num_threads(k)does. Compile-time literal, becauseprangeneedsparallel=Trueat compile time. A map-like callable in workers is not accepted; see Notes.Worth it only when the grid is large enough to cover the fixed cost of entering a parallel region: a few hundred microseconds. A 20x20 grid of a cheap objective is slower in parallel.
- xtol, ftolfloat, optional
Passed to the
finishminimiser. Both default to1e-4. See Notes.
- Returns:
- x0ndarray, shape (N,)
Minimizer – the best grid point, or the polished point.
- fvalfloat
funcatx0. Withfull_output.- gridndarray, shape (M, N)
Every grid point, C order. With
full_output. Reshape to(N,) + (Ns,)*Nwithgrid.T.reshape((N,) + (Ns,)*N); see Notes.- Joutndarray, shape (M,)
funcat every grid point. Withfull_output. Reshape withJout.reshape((Ns,)*N).
- Raises:
- ValueError
An empty ranges, ranges that is not
(N, 2), more than 40 variables,Ns < 1, a grid of more than2**31points, a finish that is neitherNonenorfmin(), or a non-integer workers. ranges, finish and workers raise from Python; inside@njitfinish raises the sameValueErrorwhile workers and full_output raiseTypingErrorcarrying the same message, since both are read when the call compiles.
See also
scipy.optimize.bruteThe scipy routine this mirrors.
scijit.optimize.differential_evolutionStochastic, no grid.
scijit.optimize.basinhoppingRandom restarts around a local minimizer.
scijit.optimize.fminThe polish step
finish=fminruns.
Notes
finish takes two spellings,
Noneand the minimiser itself, from Python and from inside@njit. A minimiser other thanfmin()raises, and so does one chosen at RUN TIME, since the name is read when the call compiles.UNAVAILABLE:
sliceobjects in ranges, which take(min, max)pairs instead.UNAVAILABLE: a
gridwhose ndim followsN. It and Jout are flat in C order, since a compiled function cannot return an array whose ndim depends on a runtime value.UNAVAILABLE: a map-like callable in workers. It is an int literal, and any other value raises.
Ns < 1and a grid above2**31points raise before the grid is built. scipy builds a zero-point grid and fails later insideargmin, with numpy’s message.DELIBERATELY DIFFERENT:
N == 1withfinish=Nonereturns a length-1 array where scipy returns a float. A numba function has one return type andNis a runtime value. With a polish scipy also returns an array, so the two agree there.xtol and ftol reach the finish minimiser and both default to
1e-4.args is unpacked into the objective’s argument list,
func(x, *args).DELIBERATELY DIFFERENT: an ndarray or a list args reaches func as ONE argument,
func(x, args). scipy unpacks those two element by element. The arity of a compiled call is fixed when it compiles, so a sequence whose length is known only at run time cannot be unpacked:func(x, *args)on an ndarray inside@njitis aTypingError. An objective written to the unpacked shape refuses the ndarray rather than reading it wrongly.https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.brute.html
Examples
>>> import numpy as np >>> from numba import njit >>> from scijit.optimize import brute >>> @njit ... def q(x): ... return (x[0] - 1.5) ** 2 + (x[1] + 0.5) ** 2 >>> ranges = np.array([[-3.0, 3.0], [-3.0, 3.0]]) >>> @njit ... def run(): ... return brute(q, ranges) >>> np.round(run(), 4) array([ 1.5, -0.5])