scijit.optimize.fmin_cobyla¶
- scijit.optimize.fmin_cobyla(func, x0, cons, args=(), consargs=None, rhobeg=1.0, rhoend=0.0001, maxfun=1000, disp=None, catol=0.0002, *, callback=None, m_nlcon=-1, Aineq=None, bineq=None, Aeq=None, beq=None, lower=None, upper=None, full_output=False)¶
Minimize a function subject to nonlinear inequality constraints.
COBYLA builds a linear model of the objective and of every constraint from values alone, and minimizes it inside a trust region. No derivatives are required.
Callable from Python and from inside
@njit.- Parameters:
- funccallable
A plain
@njitf(x, *args) -> value.- x0array_like
Initial guess. Any rank is flattened.
- conscallable or sequence of callables
Constraint functions, feasible where the result is
>= 0. Either one plain@njitc(x, *consargs)returning all of them at once, or a list or tuple of such functions returning a scalar or an array each. A tuple is the spelling that types inside@njit.- argstuple or ndarray, optional
Extra parameters for func, packed into one flat float64 buffer.
- consargstuple, ndarray or None, optional
Extra parameters for cons.
None(default) reuses args.- rhobegfloat, optional
Initial trust-region radius. Default 1.0.
- rhoendfloat, optional
Final trust-region radius. Default 1e-4.
- maxfunint, optional
Maximum objective evaluations. Default 1000.
- dispint or None, optional
0,1,2,3orNone; anything else is aValueError. Truthy printsCOBYLA failed to find a solution:and the message when the solve fails. The solver’s own per-iteration stream is not reproduced.- catolfloat or None, optional
Constraint-violation tolerance, reaching the solver as PRIMA’s
ctol. It governs which point the solver returns, and it decidessuccess: a solve leavingmaxcv > catolreportssuccess=False. Raising it trades feasibility for objective value. Default 2e-4.Noneresolves tosqrt(eps), 1.49e-08, which is whatminimize(method='COBYLA')uses. A negative ornanvalue raises aUserWarningand the solver runs onsqrt(eps), whilesuccessand message still read the value as given, so ananmakes the violation test pass whatevermaxcvis.- callbackNone, optional
Accepted only as
None. See Notes. Keyword-only, as is every parameter after it, so ten is the largest number of positional arguments.- m_nlconint, optional
Number of nonlinear constraints.
-1(default) reads it from cons by evaluating the constraints once at x0.- Aineq, bineq, Aeq, beq, lower, upperndarray or None, optional
Linear constraints
Aineq @ x <= bineqandAeq @ x == beq, and simple bounds, all taken by PRIMA natively.None(default) for each leaves it unset.- full_outputbool, optional
False(default) returns x alone.Truereturns aCobylaResult. Compile-time constant inside@njit: it selects the return type.
- Returns:
- xndarray
The minimizer.
- resultCobylaResult
Only with
full_output=True. Namedtuple with fieldsx,fun,maxcv,message,nfev,statusandsuccess.statusis PRIMA’s own exit code:0the trust-region radius reached its lower bound,1the target value was achieved,2a trust-region step failed to reduce the model,3maxfun was exhausted,7damaging rounding errors, and negative codes for NaN or infinity in x, in the objective, or in the models.successisTruewhenmaxcv <= catolandstatusis0or1.nfevcounts the one probe evaluation this routine makes before the solve as well as the solver’s own calls.
- Raises:
- TypeError
If cons is omitted, or is neither callable nor a sequence of callables.
- ValueError
If func is not a plain
@njitfunction; if disp is outside{0, 1, 2, 3, None}; or if callback is notNone. The compiled entry point raises the same text as aTypingErrorwherever the argument’s type settles the refusal.
See also
scipy.optimize.fmin_cobylaThe scipy routine this mirrors.
scijit.optimize.fmin_slsqpConstrained, gradient-based.
scijit.optimize.minimizeReaches PRIMA’s unconstrained and bounded solvers by name.
Notes
The returned point is not scipy’s. scipy 1.16 replaced Powell’s COBYLA with pyprima, a Python translation of the same algorithm, while this wraps PRIMA itself. Measured on
min x0**2 + x1**2subject tox0 >= 1from(3, 3):|dx|1.18e-04 and|df|1.38e-08, with PRIMA the nearer of the two to the true optimum,f - 1being 6.8e-14 against scipy’s 1.4e-08.catol moves the answer, so it is worth setting deliberately. On the problem above, the 2e-4 default returns
fun = 0.999900005atmaxcv = 5.0e-05;catol=Nonereturns1.000000002atmaxcv = 0;catol=1e-2returns0.999003146atmaxcv = 5.0e-04;catol=1returns0.910296579atmaxcv = 5.0e-02.args and consargs each pack into one flat float64 buffer, so they carry numbers rather than arbitrary objects.
scipy calls callback once per iteration, with either
callback(xk)orcallback(intermediate_result). Neither is served here: PRIMA’scobylatakes acallback_fcnandsrc/prima/wrappers.f90passes none, so the Fortran has no slot for one to arrive through.disp prints the failure line and not the solver’s own per-iteration stream, which PRIMA emits from Fortran.
Aineq, bineq, Aeq, beq, lower and upper have no scipy counterpart; scipy’s COBYLA can express linear constraints and bounds only by folding them into cons. A scipy-shaped call leaves all six unset and behaves as scipy does. full_output has no scipy counterpart either: scipy returns x alone and discards fun, maxcv, nfev, status, message and success, which is what the
Falsedefault reproduces.Safe to call from a
numba.prangeloop. PRIMA 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.fmin_cobyla.html
Examples
Minimize
x0**2 + x1**2subject tox0 >= 1:>>> import numpy as np >>> from numba import njit >>> from scijit.optimize import fmin_cobyla >>> @njit ... def obj(x): ... return x[0] ** 2 + x[1] ** 2 >>> @njit ... def cons(x): ... return np.array([x[0] - 1.0]) >>> @njit ... def run(): ... return fmin_cobyla(obj, np.array([3.0, 3.0]), cons) >>> np.round(run(), 4) array([1., 0.])
With full_output, which must be a literal inside
@njit:>>> @njit ... def run_full(): ... return fmin_cobyla(obj, np.array([3.0, 3.0]), cons, ... full_output=True) >>> res = run_full() >>> round(res.fun, 9), res.status, res.success (0.999900005, 0, True) >>> round(res.maxcv, 9), res.nfev (5e-05, 37)
A tuple of one-constraint functions, which is scipy’s own spelling:
>>> @njit ... def c_lo(x): ... return x[0] - 1.0 >>> @njit ... def c_hi(x): ... return 5.0 - x[1] >>> @njit ... def run_pair(): ... return fmin_cobyla(obj, np.array([3.0, 3.0]), (c_lo, c_hi)) >>> np.round(run_pair(), 4) array([1., 0.])