Background#

MADS is a derivative-free optimization method supported by a convergence analysis: under mild assumptions it generates a subsequence of iterates that converges to a point satisfying first-order (Clarke) optimality conditions, wherever it starts [Audet and Dennis, 2006]. Each iteration has two main steps, shown in Figure 1. The first is an optional search step, where any strategy may propose a finite number of trial points on the mesh (a design of experiments, a surrogate or model optimization, a global heuristic). The second is the mandatory poll step, a local exploration where poll directions spin around the incumbent solution on the discretized frame, and the blackbox is evaluated at the resulting poll points.

_images/mesh2.png

Figure 1 OMADS flow chart.#

When to use OMADS#

If the optimization problem is deterministic, this checklist helps you decide whether OMADS is a good choice from a computational-cost point of view.

  • If the problem has a known structure with explicit derivatives, a gradient-based method such as SQP should be used.

  • If the derivatives are unknown but can be reliably approximated and the design space has no differentiability issues, a gradient-based or model-based method such as NLPQLP is appropriate.

  • If the derivatives can be approximated but the design space has differentiability issues, a model-based derivative-free method such as COBYLA may be preferred.

  • If none of the above applies, that is, the functions are blackboxes (simulations or codes that cannot be differentiated), non-smooth, noisy or liable to fail, a blackbox method such as MADS is recommended. This is particularly so when evaluations are expensive, or when the problem has hidden or unrelaxable constraints, several objectives, or granular variables.

Note

OMADS 2610 is a Pythonic implementation of MADS with a progressive barrier, a granular mesh, ORTHO N+1 poll directions, a quadratic-model search and a density-guided sampling search.

Introduction#

In this section, we present the MADS algorithm. We begin with the definitions of the mesh and the frame from [Audet and Dennis, 2006, Audet and Hare, 2017].

Definition 1 (Mesh)

Let \(G \in \mathbb{R}^{n\times n}\) be an invertible matrix and let the columns of \(Z \in \mathbb{Z}^{n \times p}\) form a positive spanning set for \(\mathbb{R}^n\). Define \(D = GZ\). The mesh of coarseness \(\delta^{k} > 0\) generated by \(D\), centred at the incumbent solution \(x^{k} \in \mathbb{R}^n\), is

\[M^{k} := \{ x^{k} + \delta^{k} D y : y \in \mathbb{N}^{p} \} \subset \mathbb{R}^{n},\]

where \(\delta^{k}\) is called the mesh size parameter.

What distinguishes MADS from generalized pattern search (GPS) is a second parameter, the frame size \(\Delta^{k}\), which replaces \(\delta^{k}\) in the poll step. The frame size defines the region in which polling happens: the poll directions spin around the incumbent solution. At every iteration the two parameters satisfy \(0 < \delta^{k} \le \Delta^{k}\).

Definition 2 (Frame)

With \(G\), \(Z\) and \(D = GZ\) as above, select a mesh size parameter \(\delta^{k} > 0\) and let \(\Delta^{k}\) satisfy \(\delta^{k} \le \Delta^{k}\). The frame of extent \(\Delta^{k}\) generated by \(D\), centred at \(x^{k}\), is

\[F^{k} := \{ x \in M^{k} : \|x - x^{k}\|_{\infty} \le \Delta^{k} b \}, \qquad b = \max\{ \|d'\|_{\infty} : d' \in \mathbb{D} \},\]

and \(\Delta^{k}\) is called the frame size parameter.

In MADS, the poll set is built from mesh points inside the frame \(F^{k}\). Because the mesh size shrinks faster than the frame size (\(\delta^{k} = \min\{\Delta^{k}, (\Delta^{k})^2\}\)), the set of directions that can be chosen keeps growing, which allows an asymptotically dense set of poll directions; see Figure 2.

_images/mesh.png

Figure 2 Mesh and poll updates.#

Constraints are handled through the constraint violation function

\[h(x) = \sum_{j \in \mathcal{P}} \max\{c_j(x), 0\}^2,\]

computed over the relaxable constraints \(\mathcal{P}\) ("PB"). A point violating an unrelaxable constraint ("EB") is rejected outright (its violation is reported as \(h_{EB} = \sum_{j \in \mathcal{E}} \max\{c_j(x),0\}^2\) and it never enters the barrier as a candidate centre). A point is feasible when \(h(x) = 0\).

MADS algorithm#

This section explains each step of the MADS algorithm, shown in Algorithm 1, and how it is implemented in OMADS. The three public entry points run different subsets of it: mads.main runs the whole algorithm, poll.main runs the Update, Poll and Terminate procedures only, and search.main replaces the poll with the sampling search.

Success types

OMADS classifies every evaluated trial point \(t\) against the current frame centres (see Algorithm 2):

  • Full success: \(t\) is feasible and dominates (or equals) the feasible frame centre, or \(t\) is infeasible and dominates the infeasible frame centre.

  • Partial success: \(t\) is infeasible and only reduces the constraint violation \(h\) of the infeasible frame centre.

  • Unsuccessful: anything else.

Successful points enlarge the frame of their own barrier element along the successful step; an unsuccessful iteration refines the frame of the feasible frame centre.

Initialization step#

In this step, OMADS sets the initial frame size \(\Delta^{0}\), builds the mesh, adjusts the initial mesh size and sets the termination criteria before the study starts.

The class responsible for this is preprocess. It reads the input dictionaries and returns all the objects the main loop needs: the sampler (poll directions Dirs2n or search sampler EfficientExploration), the Options and Parameters objects, the post-processor, the adaptive barrier, the run state and statistics, the evaluator and the cache.

pre = preprocess(data=data, log=log, sampler_t=SAMPLER_TYPE.POLL)
(iteration, x0, poll_sampler, options, param, post, out, active_barrier,
 out_p, state, stats, bb_handle, hashtable, ms) = pre.initialize_from_dict()

The data dictionary holds four sub-dictionaries, evaluator, param, options and search. Every key is described in Configuration reference. The most important initial values are:

Quantity

Where it comes from

\(\Delta^{0}\)

options["psize_init"] for the orthogonal mesh (default 1.0); for the granular mesh, param["initial_frame_size"] or one tenth of each variable range.

\(D = GZ\)

Orthogonal Householder bases, scaled by (ub - lb) / scaling.

\(\tau\)

\(1/2\) for the orthogonal mesh; the granular mesh walks the mantissas \(1 \to 2 \to 5 \to 10\) (enlarge) and back (refine).

\(\epsilon_{\text{stop}}\)

options["tol"], applied to the frame size (poll) and the mesh size (search).

\(h^{0}_{\max}\)

param["h_max"] (default \(+\infty\)).

Update parameters#

Each iteration starts by choosing the frame centres from the adaptive barrier (Algorithm 2). The barrier keeps three sets: the non-dominated feasible points \(F^{k}\), the infeasible points \(U^{k}\) with \(h \le h^{k}_{\max}\) and its non-dominated subset \(I^{k}\). Each barrier element carries its own mesh, so frame sizes adapt per centre, which matters for multi-objective problems.

After the poll or search, update applies the success logic: on an unsuccessful iteration it refines the frame of the feasible centre and lowers \(h_{\max}\); on a partial success it lowers \(h_{\max}\) below the infeasible centre’s violation.

Listing 3 The update step (OMADS/_updates/_updates.py)#

The infeasible centre is chosen first when it is “far enough” from the feasible front (controlled by param["rho"] and options["use_dom_trigger"]); this is how the progressive barrier [Audet and Dennis, 2009] lets OMADS approach the feasible region from outside. For single-objective problems \(F^{k}\) holds the best feasible point only, so \(x^{k}_{F}\) is simply the incumbent. Dominance comparisons follow Jaszkiewicz and Lust [2018].

Search step#

The search step helps escape local minimizers, and every trial point is projected onto the mesh. In mads.main it comes in two flavours.

Model search runs first at every iteration and costs at most two evaluations (Algorithm 3). Right after a success, a speculative point repeats the last successful step. Then a quadratic model of the objective, and of each constraint when there are any, is fitted to cached points around the frame centre and minimized inside a trust region [Conn and Le Digabel, 2013]. When the model search succeeds, the poll and sampling search are skipped for that iteration.

The constraint margin pushes the model minimizer inside the predicted feasible region by twice the change of each constraint model over half a mesh step, so that projecting it on the mesh does not make it infeasible. The ratio test lets model steps travel further than the poll frame along long, flat valleys. The model search applies to single-objective problems only.

Sampling search runs after an unsuccessful poll, and keeps running while it succeeds (Algorithm 4). Its behaviour depends on search["type"] and search["s_method"]. With the classic samplers (LH, RS, HALTON, FULLFACTORIAL) it draws ns points in the whole box (or in a neighbourhood of the incumbent). With ACTIVE, OMADS chooses between strategies from the data it has gathered so far.

BiTPE (bi-population tree-structured Parzen estimation, from samplersLib) resamples from the density ratio between kernel density estimates of the good and the bad points, in the spirit of TPE and of trust-region Bayesian optimization [Eriksson et al., 2019]. Each model-based step proposes \(n_b\) points, set by search["batch"] (10 by default, capped by the remaining budget), plus three line probes. Readiness alone decides whether BiTPE runs; a low trust only widens its kernels, so one unlucky round cannot starve it of the data it needs to recover. When the installed samplersLib supports it, BiTPE works in a reduced space of \(n_{\text{eff}} = \max\{3, \lfloor 0.7n \rfloor\}\) dimensions for \(n > 3\). Any sampler failure falls back to Halton sampling of the trust region for that iteration.

With "type": "VNS" the search is a variable neighbourhood search that draws points around the incumbent from Gaussian, gamma, exponential, Poisson and binomial distributions.

See also

The search step can also be driven by surrogate models; see StatLML and RAF [Bayoumy, 2022, Bayoumy, 2022].

Poll step#

The MADS algorithm may select any poll direction such that \(x^{k}+\delta^{k}d\) lies inside the frame, \(\|\delta^{k}d\|_\infty \leq \Delta^{k}b\) for all \(d \in \mathbb{D}^{k}_{\Delta}\). Since \(\Delta^{k}>\delta^{k}\) whenever \(\delta^{k} < 1\), there is a lot of freedom in how the poll set is built.

Here is a glimpse of the MADS convergence properties and of what dense sets (richness) of poll directions mean. In MADS, any direction sampled in the limit of a refining sequence has a nonnegative Clarke generalized directional derivative. Moreover, the directions come from an ever-expanding set of options, because the mesh size parameter \(\delta^{k}\) goes to zero faster than the frame size parameter \(\Delta^{k}\).

MADS can produce an asymptotically dense set of poll directions using Householder matrices. First, the dense subset:

Definition 3 (Asymptotically dense subset)

The set \(V \subseteq \mathbb{R}^{n}\) is asymptotically dense if the normalized set \(\{v/\|v\| : v \in V\}\) is dense on the unit sphere \(S=\{w\in \mathbb{R}^{n} : \|w\| = 1\}\).

Then the Householder matrix:

Definition 4 (Householder matrix)

Let \(v \in \mathbb{R}^{n}\) be a normalized vector. The Householder matrix associated with \(v\) is \(H := I - 2vv^{T} \in \mathbb{R}^{n \times n}\), where \(I\) is the \(n \times n\) identity matrix.

Let \(v\) be a nonzero vector of \(\mathbb{R}^{n}\) and \(H\) its associated Householder matrix. Then for any nonzero \(\gamma\), \(\gamma\,[H \;\; -H]\) forms a maximal positive basis of \(\mathbb{R}^{n}\). Keeping only \(H\) and the negative sum of its (rounded) columns gives a minimal positive basis of \(n+1\) directions [Audet et al., 2014].

In OMADS, Algorithm 5 is implemented in the poll class Dirs2n: create_housholder builds the scaled, rounded direction matrix, _ortho_n_plus_1 builds the \(n+1\) set (options["direction_type"] = "ORTHO_N+1", real variables only) and create_poll_set turns the directions into candidate points.

Listing 4 Dirs2n.create_housholder (OMADS/_directions/_directions.py)#
Listing 5 Dirs2n._ortho_n_plus_1#
Listing 6 Dirs2n.create_poll_set#

Figure 3 shows the dense directions on the same frame size.

_images/poll_anim.gif

Figure 3 Poll set of dense directions.#

We recommend [Audet and Hare, 2017] for the proofs showing that the columns of the associated Householder matrices are asymptotically dense, given a dense set of directions on the unit sphere \(S\).

Mesh update#

OMADS has two meshes, selected with param["mesh_type"].

Orthogonal mesh (default). Omesh keeps one frame size per variable and applies \(\tau = 1/2\):

\[\begin{split}\Delta^{k+1}_i = \begin{cases} 2\,\Delta^{k}_i & \text{after a success,}\\ \Delta^{k}_i / 2 & \text{after a failure,} \end{cases} \qquad \delta^{k+1}_i = \min\{\Delta^{k+1}_i, (\Delta^{k+1}_i)^2\}.\end{split}\]

Granular mesh (GMESH). Gmesh implements the granular, anisotropic mesh of Audet et al. [2019]. Each frame size is \(\Delta_i = a_i \times 10^{b_i}\) with mantissa \(a_i \in \{1, 2, 5\}\), and may be a multiple of a granularity \(g_i\) (param["granularity"]). The update rules are given in Algorithm 6:

  • refinement (every options["refine_freq"] failures): \(a_i\) follows \(5 \to 2 \to 1 \to 5\,(b_i - 1)\), never below the minimum mesh size;

  • enlargement: \(a_i\) follows \(1 \to 2 \to 5 \to 1\,(b_i + 1)\), only for the coordinates where the successful step was large relative to the mesh, \(|d_i| / (\delta_i \rho_i) >\) options["anisotropy_factor"] (when options["anistropic_mesh"] is true), and never beyond the variable range.

Termination#

The algorithm stops when one of the following happens:

  • the evaluation budget options["budget"] is exhausted;

  • every component of the frame size (poll) or of the mesh size (search) falls below options["tol"];

  • the number of trial points that hit the bounds exceeds options["noutbound_hits_max"];

  • a feasible point is found during phase one (the run then continues in phase two).

The reason is written to OMADS.log in the post directory.