pdfo.pdfo#
- pdfo.pdfo(fun, x0, args=(), method=None, bounds=None, constraints=(), options=None)[source]#
Powell’s Derivative-Free Optimization solvers.
PDFO is an interface to call Powell’s derivatives-free optimization solvers: UOBYQA, NEWUOA, BOBYQA, LINCOA, and COBYLA. They are designed to minimize a scalar function of several variables subject to (possibly) bound constraints, linear constraints, and nonlinear constraints.
Attention
This function does not accept any ‘solver’ options. If you want to specify which solver to use, please use the method argument.
- Parameters:
- funcallable
Objective function to be minimized.
fun(x, *args) -> float
where
x
is an array with shape (n,) and args is a tuple.- x0array_like, shape (n,)
Initial guess.
- argstuple, optional
Extra arguments of the objective function. For example,
pdfo(fun, x0, args, ...)
is equivalent to
pdfo(lambda x: fun(x, *args), x0, ...)
- method{‘uobyqa’, ‘newuoa’, ‘bobyqa’, ‘lincoa’, ‘cobyla’}, optional
Name of the Powell method that will be used. By default, ‘uobyqa’ is selected if the problem is unconstrained with
2 <= n <= 8
, ‘newuoa’ is selected if the problem is unconstrained withn = 1
orn >= 9
, ‘bobyqa’ is selected if the problem is bound-constrained, ‘lincoa’ is selected if the problem is linearly constrained, and ‘cobyla’ is selected otherwise.- bounds{
scipy.optimize.Bounds
, array_like, shape (n, 2)}, optional Bound constraints of the problem. It can be one of the cases below.
An instance of
scipy.optimize.Bounds
.An array with shape (n, 2). The bound constraints for
x[i]
arebounds[i, 0] <= x[i] <= bounds[i, 1]
. Setbounds[i, 0]
to \(-\infty\) if there is no lower bound, and setbounds[i, 1]
to \(\infty\) if there is no upper bound.
- constraints{dict,
scipy.optimize.LinearConstraint
,scipy.optimize.NonlinearConstraint
, list}, optional Constraints of the problem. It can be one of the cases below.
A dictionary with fields:
- type{‘eq’, ‘ineq’}
Whether the constraint is
fun(x) = 0
orfun(x) >= 0
.- funcallable
Constraint function.
An instance of
scipy.optimize.LinearConstraint
.An instance of
scipy.optimize.NonlinearConstraint
.A list, each of whose elements are described in 1, 2, and 3.
- optionsdict, optional
The options passed to the solver. Accepted options are:
- radius_initfloat, optional
Initial value of the trust-region radius. Typically, it should be in the order of one tenth of the greatest expected change to the variables.
- radius_finalfloat, optional
Final value of the trust-region radius. It must be smaller than or equal to
options['radius_init']
and should indicate the accuracy required in the final values of the variables.- maxfevint, optional
Maximum number of function evaluations.
- ftargetfloat, optional
Target value of the objective function. The optimization procedure is terminated when the objective function value of a nearly feasible point is less than or equal to this target.
- nptint, optional
Number of interpolation points for NEWUOA, BOBYQA, and LINCOA.
- quiet: bool, optional
Whether to suppress the output messages.
- scalebool, optional
Whether to scale the problem according to the bound constraints.
- eliminate_lin_eqbool, optional
Whether to eliminate linear equality constraints.
- honour_x0bool, optional
Whether to honour the initial guess. It is only used by BOBYQA.
- classicalbool, optional
Whether to use the classical version of Powell’s methods. It is highly discouraged in production.
- debugbool, optional
Whether to perform debugging checks. It is highly discouraged in production.
- chkfunvalbool, optional
Whether to check the value of the objective and constraint functions at the solution. This is only done in the debug mode, and requires one extra function evaluation. It is highly discouraged in production.
- Returns:
- res
scipy.optimize.OptimizeResult
Result of the optimization procedure, with the following fields:
- messagestr
Description of the exit status specified in the
status
field (i.e., the cause of the termination of the solver).- successbool
Whether the optimization procedure terminated successfully.
- statusint
Termination status of the optimization procedure.
- funfloat
Objective function value at the solution point.
- x
numpy.ndarray
, shape (n,) Solution point.
- nfevint
Number of function evaluations.
- fun_history
numpy.ndarray
, shape (nfev,) History of the objective function values.
- methodstr
Name of the Powell method used.
For constrained problems, the following fields are also returned:
- maxcvfloat
Maximum constraint violation at the solution point.
- maxcv_history
numpy.ndarray
, shape (nfev,) History of the maximum constraint violation.
For linearly and nonlinearly constrained problems, the following field is also returned:
- constraints{
numpy.ndarray
, list} The values of the constraints at the solution point. If a single constraint is passed, i.e., if the constraints argument is either a dict, a
scipy.optimize.LinearConstraint
, or ascipy.optimize.NonlinearConstraint
, then the returned value is anumpy.ndarray
, which is the value of the constraint atx
. Otherwise, it is a list ofnumpy.ndarray
, each element being the value of a constraint atx
.
This function attempts to detect the infeasibility of constraints (however, if no such infeasibility is detected, it does not mean that the problem is feasible). If the optimization procedure terminated because some constraints are infeasible (i.e., when the exit status is -4), the following fields may also be returned:
- infeasible_bounds
numpy.ndarray
Indices of the bounds that are infeasible.
- infeasible_linear_constraints
numpy.ndarray
Indices of the linear constraints that are infeasible.
- infeasible_nonlinear_constraints
numpy.ndarray
Indices of the nonlinear constraints that are infeasible.
Finally, if warnings are raised during the optimization procedure, the following field is also returned:
- warningslist
A list of the warnings raised during the optimization procedure.
A description of the termination statuses is given below.
Exit status
Description
0
The lower bound on the trust-region radius is reached.
1
The target value of the objective function is reached.
2
A trust-region step has failed to reduce the quadratic model.
3
The maximum number of function evaluations is reached.
4
Much cancellation occurred in a denominator.
7
Rounding errors are becoming damaging.
8
Rounding errors are damaging the solution point.
9
A denominator has become zero.
13
All variables are fixed by the bounds.
14
A linear feasibility problem has been received and solved.
15
A linear feasibility problem has been received but failed.
-1
NaN is encountered in the solution point.
-2
NaN is encountered in the objective/constraint function value. This is possible only in the classical mode.
-3
NaN is encountered in the model parameter.
-4
The problem is infeasible.
- res
References
[1]T. M. Ragonneau and Z. Zhang. PDFO: a cross-platform package for Powell’s derivative-free optimization solvers. arXiv:2302.13246 [math.OC], 2023.
Examples
The following example shows how to solve a simple optimization problem using
pdfo
. In practice, the problem considered below should be solved with a derivative-based method as it is a smooth problem for which the derivatives are known. We solve it here usingpdfo
only as an illustration.We consider the 2-dimensional problem
\[\begin{split}\min_{x, y \in \R} \quad x^2 + y^2 \quad \text{s.t.} \quad \left\{ \begin{array}{l} 0 \le x \le 2,\\ 1 / 2 \le y \le 3,\\ 0 \le x + y \le 1,\\ x^2 - y \le 0. \end{array} \right.\end{split}\]We solve this problem using
pdfo
starting from the initial guess \((x_0, y_0) = (0, 1)\) with at most 200 function evaluations.>>> import numpy as np >>> from pdfo import pdfo >>> from scipy.optimize import Bounds, LinearConstraint, NonlinearConstraint >>> >>> # Build the constraints. >>> bounds = Bounds([0, 0.5], [2, 3]) >>> linear_constraints = LinearConstraint([1, 1], 0, 1) >>> nonlinear_constraints = NonlinearConstraint(lambda x: x[0]**2 - x[1], -np.inf, 0) >>> constraints = [linear_constraints, nonlinear_constraints] >>> >>> # Solve the problem. >>> options = {'maxfev': 200} >>> res = pdfo(lambda x: x[0]**2 + x[1]**2, [0, 1], bounds=bounds, constraints=constraints, options=options) >>> res.x array([0. , 0.5])