Skip to content

Commit d832b07

Browse files
authored
Use Logarithm of Expected Improvement (LogEi) as default infill strategy (#336)
* Use LogEI in examples * Use logEI as default infill criterion * Adjust infill criterion to old default in tests * Linting * Linting * Adjust infill criterion to old default in tests * Typo
1 parent 98228ae commit d832b07

File tree

8 files changed

+48
-15
lines changed

8 files changed

+48
-15
lines changed

crates/ego/examples/michalewicz.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ fn run_egor(dim: usize, outdir: &String, num: usize) -> Result<OptimResult<f64>>
6060
gp.regression_spec(RegressionSpec::CONSTANT)
6161
.correlation_spec(CorrelationSpec::ALL)
6262
})
63-
.infill_strategy(InfillStrategy::WB2)
63+
.infill_strategy(InfillStrategy::LogEI)
6464
.infill_optimizer(InfillOptimizer::Slsqp)
6565
.trego(true)
6666
// for dim=10

crates/ego/examples/rosenbrock.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ fn run_egor(dim: usize, outdir: &String, num: usize) -> Result<OptimResult<f64>>
4343
gp.regression_spec(RegressionSpec::CONSTANT)
4444
.correlation_spec(CorrelationSpec::ALL)
4545
})
46-
.infill_strategy(InfillStrategy::WB2)
46+
.infill_strategy(InfillStrategy::LogEI)
4747
.infill_optimizer(InfillOptimizer::Slsqp)
4848
.trego(true)
4949
.max_iters(max_iters)

crates/ego/src/egor.rs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,7 @@ mod tests {
612612
let res = EgorBuilder::optimize(xsinx)
613613
.configure(|config| {
614614
config
615+
.infill_strategy(InfillStrategy::WB2)
615616
.max_iters(n_iter)
616617
.seed(42)
617618
.hot_start(HotStartMode::Enabled)
@@ -628,6 +629,7 @@ mod tests {
628629
let res = EgorBuilder::optimize(xsinx)
629630
.configure(|config| {
630631
config
632+
.infill_strategy(InfillStrategy::WB2)
631633
.max_iters(n_iter)
632634
.seed(42)
633635
.hot_start(HotStartMode::Disabled)
@@ -644,6 +646,7 @@ mod tests {
644646
let res = EgorBuilder::optimize(xsinx)
645647
.configure(|config| {
646648
config
649+
.infill_strategy(InfillStrategy::WB2)
647650
.seed(42)
648651
.hot_start(HotStartMode::ExtendedIters(ext_iters))
649652
.outdir(outdir)
@@ -661,6 +664,7 @@ mod tests {
661664
let res = EgorBuilder::optimize(xsinx)
662665
.configure(|config| {
663666
config
667+
.infill_strategy(InfillStrategy::WB2)
664668
.seed(42)
665669
.hot_start(HotStartMode::ExtendedIters(ext_iters))
666670
.outdir(outdir)
@@ -699,7 +703,14 @@ mod tests {
699703
let xlimits = array![[0.0, 25.0]];
700704
let doe = array![[0.], [7.], [23.]];
701705
let _ = EgorBuilder::optimize(xsinx)
702-
.configure(|config| config.max_iters(2).doe(&doe).outdir(outdir).seed(42))
706+
.configure(|config| {
707+
config
708+
.infill_strategy(InfillStrategy::WB2)
709+
.max_iters(2)
710+
.doe(&doe)
711+
.outdir(outdir)
712+
.seed(42)
713+
})
703714
.min_within(&xlimits)
704715
.expect("Egor configured")
705716
.run()
@@ -709,15 +720,23 @@ mod tests {
709720
assert!(filepath.exists());
710721
let doe: Array2<f64> = read_npy(&filepath).expect("file read");
711722

723+
let n_iters = 3;
712724
let res = EgorBuilder::optimize(xsinx)
713-
.configure(|config| config.max_iters(3).outdir(outdir).warm_start(true).seed(42))
725+
.configure(|config| {
726+
config
727+
.infill_strategy(InfillStrategy::WB2)
728+
.max_iters(n_iters)
729+
.outdir(outdir)
730+
.warm_start(true)
731+
.seed(42)
732+
})
714733
.min_within(&xlimits)
715734
.expect("Egor configured")
716735
.run()
717736
.expect("Egor should minimize xsinx");
718737
let doe2: Array2<f64> = read_npy(&filepath).expect("file read");
719738

720-
assert!(doe2.nrows() >= doe.nrows() + 3);
739+
assert!(doe2.nrows() >= doe.nrows() + n_iters);
721740

722741
let _ = std::fs::remove_file(format!("{outdir}/{DOE_INITIAL_FILE}"));
723742
let _ = std::fs::remove_file(format!("{outdir}/{DOE_FILE}"));
@@ -778,6 +797,7 @@ mod tests {
778797
let res = EgorBuilder::optimize(rosenb)
779798
.configure(|config| {
780799
config
800+
.infill_strategy(InfillStrategy::WB2)
781801
.doe(&init_doe)
782802
.max_iters(max_iters)
783803
.outdir(outdir)
@@ -879,6 +899,7 @@ mod tests {
879899
let res = EgorBuilder::optimize(f_g24)
880900
.configure(|config| {
881901
config
902+
.infill_strategy(InfillStrategy::WB2)
882903
.n_cstr(2)
883904
.doe(&doe)
884905
.max_iters(20)

crates/ego/src/solver/egor_config.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ impl Default for ValidEgorConfig {
242242
q_optmod: 1,
243243
q_points: 1,
244244
gp: GpConfig::default(),
245-
infill_criterion: Box::new(WB2),
245+
infill_criterion: Box::new(LOG_EI),
246246
infill_optimizer: InfillOptimizer::Slsqp,
247247
target: f64::MIN,
248248
outdir: None,

python/egobox/egobox.pyi

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class Egor:
5757
5858
infill_strategy (InfillStrategy enum):
5959
Infill criteria to decide best next promising point.
60-
Can be either InfillStrategy.EI, InfillStrategy.WB2, InfillStrategy.WB2S orInfillStrategy.LOG_EI
60+
Can be either InfillStrategy.LOG_EI, InfillStrategy.EI, InfillStrategy.WB2, InfillStrategy.WB2S
6161
6262
infill_optimizer (InfillOptimizer enum):
6363
Internal optimizer used to optimize infill criteria.
@@ -120,7 +120,7 @@ class Egor:
120120
seed (int >= 0):
121121
Random generator seed to allow computation reproducibility.
122122
"""
123-
def __new__(cls, xspecs: typing.Any, gp_config: GpConfig = ..., n_cstr: builtins.int = 0, cstr_tol: typing.Optional[typing.Sequence[builtins.float]] = None, n_start: builtins.int = 20, n_doe: builtins.int = 0, doe: typing.Optional[numpy.typing.NDArray[numpy.float64]] = None, infill_strategy: InfillStrategy = InfillStrategy.WB2, cstr_infill: builtins.bool = False, cstr_strategy: ConstraintStrategy = ConstraintStrategy.MC, q_points: builtins.int = 1, q_infill_strategy: QInfillStrategy = QInfillStrategy.KB, infill_optimizer: InfillOptimizer = InfillOptimizer.COBYLA, trego: builtins.bool = False, coego_n_coop: builtins.int = 0, q_optmod: builtins.int = 1, target: builtins.float = -inf, outdir: typing.Optional[builtins.str] = None, warm_start: builtins.bool = False, hot_start: typing.Optional[builtins.int] = None, seed: typing.Optional[builtins.int] = None) -> Egor: ...
123+
def __new__(cls, xspecs: typing.Any, gp_config: GpConfig = ..., n_cstr: builtins.int = 0, cstr_tol: typing.Optional[typing.Sequence[builtins.float]] = None, n_start: builtins.int = 20, n_doe: builtins.int = 0, doe: typing.Optional[numpy.typing.NDArray[numpy.float64]] = None, infill_strategy: InfillStrategy = InfillStrategy.LOG_EI, cstr_infill: builtins.bool = False, cstr_strategy: ConstraintStrategy = ConstraintStrategy.MC, q_points: builtins.int = 1, q_infill_strategy: QInfillStrategy = QInfillStrategy.KB, infill_optimizer: InfillOptimizer = InfillOptimizer.COBYLA, trego: builtins.bool = False, coego_n_coop: builtins.int = 0, q_optmod: builtins.int = 1, target: builtins.float = -1.7976931348623157e+308, outdir: typing.Optional[builtins.str] = None, warm_start: builtins.bool = False, hot_start: typing.Optional[builtins.int] = None, seed: typing.Optional[builtins.int] = None) -> Egor: ...
124124
def minimize(self, fun: typing.Any, fcstrs: typing.Sequence[typing.Any] = [], max_iters: builtins.int = 20, run_info: typing.Optional[typing.Any] = None) -> OptimResult:
125125
r"""
126126
```ignore
@@ -854,11 +854,14 @@ def sampling(method: Sampling, xspecs: typing.Any, n_samples: builtins.int, seed
854854
Samples generation using given method
855855
856856
# Parameters
857-
method: LHS, FULL_FACTORIAL or RANDOM
857+
method: LHS, FULL_FACTORIAL, RANDOM,
858+
LHS_CLASSIC, LHS_CENTERED,
859+
LHS_MAXIMIN, LHS_CENTERED_MAXIMIN
858860
xspecs: list of XSpec
859861
n_samples: number of samples
860862
seed: random seed
861863
862864
# Returns
863865
ndarray of shape (n_samples, n_variables)
864866
"""
867+

python/egobox/tests/test_egor.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,13 @@ def test_xsinx_with_warmstart(self):
145145
os.remove("./test_dir/egor_doe.npy")
146146
xlimits = [[0.0, 25.0]]
147147
doe = egx.lhs(xlimits, 10)
148-
egor = egx.Egor(xlimits, doe=doe, seed=42, outdir="./test_dir")
148+
egor = egx.Egor(
149+
xlimits,
150+
doe=doe,
151+
infill_strategy=egx.InfillStrategy.WB2,
152+
seed=42,
153+
outdir="./test_dir",
154+
)
149155
res = egor.minimize(xsinx, max_iters=15)
150156
print(f"Optimization f={res.y_opt} at {res.x_opt}")
151157
self.assertAlmostEqual(-15.125, res.y_opt[0], delta=1e-3)
@@ -188,6 +194,7 @@ def test_g24(self):
188194
def test_g24_kpls(self):
189195
egor = egx.Egor(
190196
[[0.0, 3.0], [0.0, 4.0]],
197+
infill_strategy=egx.InfillStrategy.WB2,
191198
n_cstr=2,
192199
cstr_tol=np.array([5e-3, 5e-3]),
193200
gp_config=egx.GpConfig(
@@ -242,7 +249,7 @@ def test_constructor(self):
242249

243250
def test_egor_service(self):
244251
xlimits = [[0.0, 25.0]]
245-
egor = egx.Egor(xlimits, seed=42)
252+
egor = egx.Egor(xlimits, infill_strategy=egx.InfillStrategy.WB2, seed=42)
246253
x_doe = egx.lhs(xlimits, 3, seed=42)
247254
y_doe = xsinx(x_doe)
248255
for _ in range(10):
@@ -257,7 +264,9 @@ def test_egor_service(self):
257264
# the unconstrained minimum located in x=18.9
258265
def test_egor_with_fcstrs(self):
259266
fcstrs = [cstr_xsinx]
260-
egor = egx.Egor([[0.0, 25.0]], n_doe=5, seed=42)
267+
egor = egx.Egor(
268+
[[0.0, 25.0]], infill_strategy=egx.InfillStrategy.WB2, n_doe=5, seed=42
269+
)
261270
res = egor.minimize(xsinx, max_iters=20, fcstrs=fcstrs)
262271
print(f"Optimization f={res.y_opt} at {res.x_opt}")
263272
self.assertAlmostEqual(18, res.x_opt[0], delta=2e-3)

python/egobox/tests/test_mixintegor.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ def test_ord_enum(self):
5555
egx.XSpec(egx.XType.ENUM, xlimits=[2]),
5656
egx.XSpec(egx.XType.ORD, [0, 2, 3]),
5757
]
58-
egor = egx.Egor(xtypes, seed=42)
58+
egor = egx.Egor(xtypes, infill_strategy=egx.InfillStrategy.WB2, seed=42)
5959
res = egor.minimize(mixobj, max_iters=10)
6060
self.assertAlmostEqual(-14.25, res.y_opt[0])
6161
self.assertAlmostEqual(-5, res.x_opt[0])

python/src/egor.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ use std::cmp::Ordering;
6262
///
6363
/// infill_strategy (InfillStrategy enum):
6464
/// Infill criteria to decide best next promising point.
65-
/// Can be either InfillStrategy.EI, InfillStrategy.WB2, InfillStrategy.WB2S orInfillStrategy.LOG_EI
65+
/// Can be either InfillStrategy.LOG_EI, InfillStrategy.EI, InfillStrategy.WB2, InfillStrategy.WB2S
6666
///
6767
/// infill_optimizer (InfillOptimizer enum):
6868
/// Internal optimizer used to optimize infill criteria.
@@ -163,7 +163,7 @@ impl Egor {
163163
n_start = 20,
164164
n_doe = 0,
165165
doe = None,
166-
infill_strategy = InfillStrategy::Wb2,
166+
infill_strategy = InfillStrategy::LogEi,
167167
cstr_infill = false,
168168
cstr_strategy = ConstraintStrategy::Mc,
169169
q_points = 1,

0 commit comments

Comments
 (0)