Skip to content

Commit 954d4f3

Browse files
committed
Add API for constraint handling strategy
1 parent 7fcd22f commit 954d4f3

File tree

8 files changed

+58
-3
lines changed

8 files changed

+58
-3
lines changed

crates/ego/src/solver/egor_config.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use ndarray::Array2;
1010
use serde::{Deserialize, Serialize};
1111

1212
/// A structure to handle TREGO method parameterization
13-
#[derive(Clone, Serialize, Deserialize, Debug)]
13+
#[derive(Clone, Debug, Serialize, Deserialize)]
1414
pub(crate) struct TregoConfig {
1515
pub(crate) activated: bool,
1616
pub(crate) n_local_steps: u64,
@@ -90,6 +90,8 @@ pub struct EgorConfig {
9090
pub(crate) seed: Option<u64>,
9191
/// Trego parameterization
9292
pub(crate) trego: TregoConfig,
93+
/// Constraints criterion
94+
pub(crate) cstr_strategy: ConstraintStrategy,
9395
}
9496

9597
impl Default for EgorConfig {
@@ -117,6 +119,7 @@ impl Default for EgorConfig {
117119
xtypes: vec![],
118120
seed: None,
119121
trego: TregoConfig::default(),
122+
cstr_strategy: ConstraintStrategy::MeanValue,
120123
}
121124
}
122125
}
@@ -294,6 +297,12 @@ impl EgorConfig {
294297
self
295298
}
296299

300+
/// Sets the infill strategy
301+
pub fn cstr_strategy(mut self, cstr_strategy: ConstraintStrategy) -> Self {
302+
self.cstr_strategy = cstr_strategy;
303+
self
304+
}
305+
297306
/// Check whether we are in a discrete optimization context
298307
pub fn discrete(&self) -> bool {
299308
crate::utils::discrete(&self.xtypes)

crates/ego/src/solver/solver_computations.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,11 @@ where
144144
params: &mut InfillObjData<f64>|
145145
-> f64 {
146146
let scale_cstr = params.scale_cstr.as_ref().expect("constraint scaling")[i];
147-
// Self::mean_cstr(&*cstr_models[i], x, gradient, scale_cstr)
148-
Self::upper_trust_bound_cstr(&*cstr_models[i], x, gradient, scale_cstr)
147+
if self.config.cstr_strategy == ConstraintStrategy::MeanValue {
148+
Self::mean_cstr(&*cstr_models[i], x, gradient, scale_cstr)
149+
} else {
150+
Self::upper_trust_bound_cstr(&*cstr_models[i], x, gradient, scale_cstr)
151+
}
149152
};
150153
#[cfg(feature = "nlopt")]
151154
{

crates/ego/src/types.rs

+9
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,15 @@ pub enum InfillStrategy {
3232
WB2S,
3333
}
3434

35+
/// Constraint criterion used to select next promising point
36+
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
37+
pub enum ConstraintStrategy {
38+
/// Use the mean value
39+
MeanValue,
40+
/// Use the upper bound (ie mean + 3*sigma)
41+
UpperTrustedBound,
42+
}
43+
3544
/// Optimizer used to optimize the infill criteria
3645
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
3746
pub enum InfillOptimizer {

python/egobox/egobox.pyi

+8
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ class Egor:
7070
infill_strategy (InfillStrategy enum)
7171
Infill criteria to decide best next promising point.
7272
Can be either InfillStrategy.EI, InfillStrategy.WB2 or InfillStrategy.WB2S.
73+
74+
cstr_strategy (ConstraintStrategy enum)
75+
Constraint management either use the mean value or upper bound
76+
Can be either ConstraintStrategy.MV (default) or ConstraintStrategy.UTB.
7377
7478
q_points (int > 0):
7579
Number of points to be evaluated to allow parallel evaluation of the function under optimization.
@@ -660,6 +664,10 @@ class InfillStrategy(Enum):
660664
Wb2 = auto()
661665
Wb2s = auto()
662666

667+
class ConstraintStrategy(Enum):
668+
Mv = auto()
669+
Utb = auto()
670+
663671
class ParInfillStrategy(Enum):
664672
Kb = auto()
665673
Kblb = auto()

python/egobox/tests/test_egor.py

+1
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ def test_g24(self):
150150
seed=42,
151151
n_optmod=2,
152152
n_doe=n_doe,
153+
cstr_strategy=egx.ConstraintStrategy.UTB,
153154
)
154155
start = time.process_time()
155156
res = egor.minimize(g24, max_iters=max_iters)

python/src/egor.rs

+17
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ pub(crate) fn to_specs(py: Python, xlimits: Vec<Vec<f64>>) -> PyResult<PyObject>
103103
/// Infill criteria to decide best next promising point.
104104
/// Can be either InfillStrategy.EI, InfillStrategy.WB2 or InfillStrategy.WB2S.
105105
///
106+
/// cstr_strategy (ConstraintStrategy enum)
107+
/// Constraint management either use the mean value or upper bound
108+
/// Can be either ConstraintStrategy.MeanValue or ConstraintStrategy.UpperTrustedBound.
109+
///
106110
/// q_points (int > 0):
107111
/// Number of points to be evaluated to allow parallel evaluation of the function under optimization.
108112
///
@@ -170,6 +174,7 @@ pub(crate) struct Egor {
170174
pub regression_spec: RegressionSpec,
171175
pub correlation_spec: CorrelationSpec,
172176
pub infill_strategy: InfillStrategy,
177+
pub cstr_strategy: ConstraintStrategy,
173178
pub q_points: usize,
174179
pub par_infill_strategy: ParInfillStrategy,
175180
pub infill_optimizer: InfillOptimizer,
@@ -209,6 +214,7 @@ impl Egor {
209214
regr_spec = RegressionSpec::CONSTANT,
210215
corr_spec = CorrelationSpec::SQUARED_EXPONENTIAL,
211216
infill_strategy = InfillStrategy::Wb2,
217+
cstr_strategy = ConstraintStrategy::Mv,
212218
q_points = 1,
213219
par_infill_strategy = ParInfillStrategy::Kb,
214220
infill_optimizer = InfillOptimizer::Cobyla,
@@ -234,6 +240,7 @@ impl Egor {
234240
regr_spec: u8,
235241
corr_spec: u8,
236242
infill_strategy: InfillStrategy,
243+
cstr_strategy: ConstraintStrategy,
237244
q_points: usize,
238245
par_infill_strategy: ParInfillStrategy,
239246
infill_optimizer: InfillOptimizer,
@@ -265,6 +272,7 @@ impl Egor {
265272
regression_spec: RegressionSpec(regr_spec),
266273
correlation_spec: CorrelationSpec(corr_spec),
267274
infill_strategy,
275+
cstr_strategy,
268276
q_points,
269277
par_infill_strategy,
270278
infill_optimizer,
@@ -461,6 +469,13 @@ impl Egor {
461469
}
462470
}
463471

472+
fn cstr_strategy(&self) -> egobox_ego::ConstraintStrategy {
473+
match self.cstr_strategy {
474+
ConstraintStrategy::Mv => egobox_ego::ConstraintStrategy::MeanValue,
475+
ConstraintStrategy::Utb => egobox_ego::ConstraintStrategy::UpperTrustedBound,
476+
}
477+
}
478+
464479
fn qei_strategy(&self) -> egobox_ego::QEiStrategy {
465480
match self.par_infill_strategy {
466481
ParInfillStrategy::Kb => egobox_ego::QEiStrategy::KrigingBeliever,
@@ -519,6 +534,7 @@ impl Egor {
519534
doe: Option<&Array2<f64>>,
520535
) -> egobox_ego::EgorConfig {
521536
let infill_strategy = self.infill_strategy();
537+
let cstr_strategy = self.cstr_strategy();
522538
let qei_strategy = self.qei_strategy();
523539
let infill_optimizer = self.infill_optimizer();
524540

@@ -536,6 +552,7 @@ impl Egor {
536552
egobox_moe::CorrelationSpec::from_bits(self.correlation_spec.0).unwrap(),
537553
)
538554
.infill_strategy(infill_strategy)
555+
.cstr_strategy(cstr_strategy)
539556
.q_points(self.q_points)
540557
.qei_strategy(qei_strategy)
541558
.infill_optimizer(infill_optimizer)

python/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ fn egobox(_py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> {
3535
m.add_class::<RegressionSpec>()?;
3636
m.add_class::<CorrelationSpec>()?;
3737
m.add_class::<InfillStrategy>()?;
38+
m.add_class::<ConstraintStrategy>()?;
3839
m.add_class::<ParInfillStrategy>()?;
3940
m.add_class::<InfillOptimizer>()?;
4041
m.add_class::<XType>()?;

python/src/types.rs

+7
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,13 @@ pub(crate) enum InfillStrategy {
5656
Wb2s = 3,
5757
}
5858

59+
#[pyclass(eq, eq_int, rename_all = "UPPERCASE")]
60+
#[derive(Debug, Clone, Copy, PartialEq)]
61+
pub(crate) enum ConstraintStrategy {
62+
Mv = 1,
63+
Utb = 2,
64+
}
65+
5966
#[pyclass(eq, eq_int, rename_all = "UPPERCASE")]
6067
#[derive(Debug, Clone, Copy, PartialEq)]
6168
pub(crate) enum ParInfillStrategy {

0 commit comments

Comments
 (0)