Skip to content

1.0.0

Choose a tag to compare

@relf relf released this 12 Oct 11:55
· 46 commits to master since this release

This release brings two things:

  • A stable Python API: the names deprecated in 0.38.0 are removed, and Gpx / SparseGpx
    thetas, variances and likelihoods become properties. Most code that runs without
    DeprecationWarning on 0.38 keeps working, see Breaking changes for the exceptions.
  • Experimental multi-objective optimization, in Rust Egor and in Python with the new Belfegor
    optimizer. Mono-objective optimization is unchanged, and the Rust API changes are additive.

Rust crates: egobox-ego 0.42.0, egobox-moe 0.36.2, egobox-gp 0.37.1 (egobox-doe 0.35.2 and
egobox-gpx 0.6.0 unchanged).

Breaking changes (Python)

The names deprecated in 0.38.0 are removed. A removed keyword argument raises TypeError, a removed
attribute or method raises AttributeError, and a removed dict key raises ValueError.

Removed Use instead
Egor(n_start=...) Egor(infill_n_start=...)
GpConfig(n_start=...), GpConfig.n_start, gp_config={"n_start": ...} theta_n_start
GpConfig(max_eval=...), GpConfig.max_eval, gp_config={"max_eval": ...} theta_max_eval
GpMix / Gpx.builder(n_start=..., max_eval=...) theta_n_start=..., theta_max_eval=...
SparseGpMix / SparseGpx.builder(n_start=...) theta_n_start=...
SparseGpMix / SparseGpx.builder(nz=..., z=...) n_inducing=..., inducing=...
Egor.get_result(x_doe, y_doe) Egor.best_result(x_doe, y_doe)
Egor.get_result_index(y_doe) Egor.best_index(y_doe)
Egor(doe=...) Egor(x_doe=..., y_doe=...)
Egor(cstr_tol=[...]) per-spec tolerance: Egor(cstr_specs=[CstrSpec.leq(0.0, tol=...)]), minimize(fcstr_specs=[...])
CstrSpec.btw(lower, upper), {"btw": (lower, upper)} CstrSpec.between(lower, upper), {"between": (lower, upper)}
QEiConfig(optmod=...), QEiConfig.optmod, qei_config={"optmod": ...} optim_every
TregoConfig(n_gl_steps=...), TregoConfig.n_gl_steps, trego={"n_gl_steps": ...} n_global_local_steps
TregoConfig(d=...), TregoConfig.d, trego={"d": ...} radius_bounds
sampling(method, xspecs, n_samples, seed) (positional) sampling(xspecs, n_samples, method=..., seed=...)

Other changes:

  • Gpx.thetas, Gpx.variances and Gpx.likelihoods (and the same on SparseGpx) are read-only properties:
    write gpx.thetas instead of gpx.thetas().
  • Egor loses its 4th positional parameter cstr_tol. Positional arguments after n_cstr (cstr_specs,
    infill_n_start, ...) move up one slot. Calls with keyword arguments are not affected.
  • Defaults that were None only to detect the deprecated names now show their value: for example
    infill_n_start=20, GpConfig(theta_n_start=10, theta_max_eval=50), QEiConfig(optim_every=1),
    TregoConfig(n_global_local_steps=(1, 4), radius_bounds=(1e-6, 1.0)) and
    sampling(..., method=Sampling.LHS). Passing None explicitly is no longer accepted for these parameters.

Multi-objective Egor (Rust, #476–#481)

  • API: EgorConfig::n_obj() and configure_moo(MooConfig). The objective function returns
    [obj_1, ..., obj_n_obj, cstr_1, ...]. Egor::run_pareto() returns a ParetoResult (Pareto set/front,
    compromise point, DOE) and run() returns the compromise point.

  • Strategies (MooConfig::strategy()):

    Strategy Infill criterion Default
    ParEgo scalarized objectives, single surrogate (Knowles 2006) beyond 3 objectives
    Eim Expected Improvement Matrix, Euclidean/maximin/hypervolume aggregation (Zhan 2017)
    Ehvi Expected Hypervolume Improvement in closed form, up to 8 objectives (Emmerich 2006) 2 or 3 objectives
    QEhvi batch EHVI under the joint posterior, batches of at most 4 points (Daulton 2020)
  • Hypervolume-based stop: MooConfig::hv_stop(tol, n_iters).

  • Supported with several objectives:

    • constraints, function constraints and cstr_specs;
    • mixed-integer variables;
    • batches;
    • warm/hot start;
    • ask-and-tell (EgorServiceBuilder);
    • failsafe imputation (not with ParEGO).

    TREGO, CoEGO and target are not supported.

  • Helpers: find_pareto_front_indices() and find_compromise_index() give the front and the compromise
    point of given data. GaussianProcess::predict_covariance() and GpSurrogateExt::predict_covariance()
    give the posterior covariance between points.

Python Belfegor (#482)

belfegor = egx.Belfegor(xspecs, n_obj=2, moo_config=egx.MooConfig(strategy=egx.MooStrategy.QEHVI, batch=3))
res = belfegor.minimize(fun, max_iters=20)
res.x_pareto, res.y_pareto, res.x_opt, res.y_opt  # Pareto front and compromise point
  • Options:
    • the Egor ones that apply to several objectives;
    • n_obj;
    • moo_config (MooConfig: strategy, batch size, EIM aggregation, hv_stop, ParEGO options).
  • Methods: suggest() (ask-and-tell), pareto_result() / pareto_indices() (front of given data).
  • Examples: zdt1.py, and belfegor_pymoo.py on pymoo test problems with quality metrics and plots.

Other changes

  • EgorState::param / cost hold the first evaluated point of the iteration and its value, instead of the
    first proposed point and its prediction (#476).
  • Fix the probability of feasibility gradient (cstr_infill) with a non-zero constraint tolerance (#477).