Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Egor ask-and-tell interface #116

Merged
merged 13 commits into from
Nov 30, 2023
1,388 changes: 759 additions & 629 deletions doc/Egor_Tutorial.ipynb

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions doe/src/lhs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,10 +271,10 @@ impl<F: Float, R: Rng + Clone> Lhs<F, R> {
lhs.mapv(F::cast)
}

fn _maximin_lhs(&self, ns: usize, centered: bool, n_iter: usize) -> Array2<F> {
fn _maximin_lhs(&self, ns: usize, centered: bool, max_iters: usize) -> Array2<F> {
let mut max_dist = F::zero();
let mut lhs = self._classic_lhs(ns);
for _ in 0..n_iter {
for _ in 0..max_iters {
if centered {
lhs = self._centered_lhs(ns);
} else {
Expand Down
13 changes: 8 additions & 5 deletions ego/examples/ackley.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,15 @@ fn ackley(x: &ArrayView2<f64>) -> Array2<f64> {
fn main() {
let xlimits = array![[-32.768, 32.768], [-32.768, 32.768], [-32.768, 32.768]];
let res = EgorBuilder::optimize(ackley)
.configure(|config| {
config
.regression_spec(RegressionSpec::CONSTANT)
.correlation_spec(CorrelationSpec::ABSOLUTEEXPONENTIAL)
.infill_strategy(InfillStrategy::WB2S)
.max_iters(200)
.target(5e-1)
})
.min_within(&xlimits)
.regression_spec(RegressionSpec::CONSTANT)
.correlation_spec(CorrelationSpec::ABSOLUTEEXPONENTIAL)
.infill_strategy(InfillStrategy::WB2S)
.n_iter(200)
.target(5e-1)
.run()
.expect("Minimize failure");
println!("Ackley minimum y = {} at x = {}", res.y_opt, res.x_opt);
Expand Down
50 changes: 50 additions & 0 deletions ego/examples/g24.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use egobox_doe::{Lhs, SamplingMethod};
use egobox_ego::EgorServiceBuilder;
use ndarray::{array, concatenate, Array2, ArrayBase, ArrayView2, Axis, Data, Ix1, Zip};

// Objective
fn g24(x: &ArrayBase<impl Data<Elem = f64>, Ix1>) -> f64 {
// Function G24: 1 global optimum y_opt = -5.5080 at x_opt =(2.3295, 3.1785)
-x[0] - x[1]
}

// Constraints < 0
fn g24_c1(x: &ArrayBase<impl Data<Elem = f64>, Ix1>) -> f64 {
-2.0 * x[0].powf(4.0) + 8.0 * x[0].powf(3.0) - 8.0 * x[0].powf(2.0) + x[1] - 2.0
}

fn g24_c2(x: &ArrayBase<impl Data<Elem = f64>, Ix1>) -> f64 {
-4.0 * x[0].powf(4.0) + 32.0 * x[0].powf(3.0) - 88.0 * x[0].powf(2.0) + 96.0 * x[0] + x[1]
- 36.0
}

fn f_g24(x: &ArrayView2<f64>) -> Array2<f64> {
let mut y = Array2::zeros((x.nrows(), 3));
Zip::from(y.rows_mut())
.and(x.rows())
.for_each(|mut yi, xi| {
yi.assign(&array![g24(&xi), g24_c1(&xi), g24_c2(&xi)]);
});
y
}

fn main() {
let xlimits = array![[0., 3.], [0., 4.]];
let mut doe = Lhs::new(&xlimits).sample(3);

// We use Egor optimizer as a service
let egor = EgorServiceBuilder::optimize()
.configure(|config| config.n_cstr(2).random_seed(42))
.min_within(&xlimits);

let mut y_doe = f_g24(&doe.view());
for _i in 0..10 {
// We tell function values and ask for next x location
let x_suggested = egor.suggest(&doe, &y_doe);

doe = concatenate![Axis(0), doe, x_suggested];
y_doe = f_g24(&doe.view());
}

println!("G24 optim x suggestion history = {doe:?}");
}
29 changes: 16 additions & 13 deletions ego/examples/mopta08.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ fn main() -> anyhow::Result<()> {
let dim = args.dim;
let outdir = args.outdir;
let n_doe = 2 * dim;
let n_iter = 2 * dim;
let max_iters = 2 * dim;
const N_CSTR: usize = 68;
let cstr_tol = Array1::from_elem(N_CSTR, 1e-4);
let kpls_dim = 3;
Expand All @@ -262,19 +262,22 @@ fn main() -> anyhow::Result<()> {
xlimits.column_mut(1).assign(&Array1::ones(dim));

let res = EgorBuilder::optimize(mopta_func(dim))
.configure(|config| {
config
.n_cstr(N_CSTR)
.cstr_tol(&cstr_tol)
.n_clusters(1)
.n_start(50)
.n_doe(n_doe)
.max_iters(max_iters)
.regression_spec(RegressionSpec::CONSTANT)
.correlation_spec(CorrelationSpec::SQUAREDEXPONENTIAL)
.infill_optimizer(InfillOptimizer::Slsqp)
.kpls_dim(kpls_dim)
.outdir(outdir)
.hot_start(true)
})
.min_within(&xlimits)
.n_cstr(N_CSTR)
.cstr_tol(&cstr_tol)
.n_clusters(1)
.n_start(50)
.n_doe(n_doe)
.n_iter(n_iter)
.regression_spec(RegressionSpec::CONSTANT)
.correlation_spec(CorrelationSpec::SQUAREDEXPONENTIAL)
.infill_optimizer(InfillOptimizer::Slsqp)
.kpls_dim(kpls_dim)
.outdir(outdir)
.hot_start(true)
.run()
.expect("Minimize failure");
println!(
Expand Down
3 changes: 1 addition & 2 deletions ego/examples/rosenbrock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,8 @@ fn rosenbrock(x: &ArrayView2<f64>) -> Array2<f64> {
fn main() {
let xlimits = array![[-2., 2.], [-2., 2.]];
let res = EgorBuilder::optimize(rosenbrock)
.configure(|config| config.max_iters(100).target(1e-2))
.min_within(&xlimits)
.n_iter(100)
.target(1e-2)
.run()
.expect("Minimize failure");
println!("Rosenbrock minimum y = {} at x = {}", res.y_opt, res.x_opt);
Expand Down
Loading