Skip to content

Commit 062cd28

Browse files
authored
Move the DOE save after the algo the iteration (#185)
* Move the doe save after the algo the iteration * Add tests of saved doe files * Cleanup
1 parent 8b5f92f commit 062cd28

File tree

4 files changed

+46
-58
lines changed

4 files changed

+46
-58
lines changed

ego/src/egor.rs

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -333,22 +333,27 @@ mod tests {
333333
let _ = std::fs::remove_file(format!("{outdir}/{DOE_INITIAL_FILE}"));
334334
let _ = std::fs::remove_file(format!("{outdir}/{DOE_FILE}"));
335335
let xlimits = array![[0.0, 25.0]];
336-
let doe = Lhs::new(&xlimits).sample(10);
337-
let res = EgorBuilder::optimize(xsinx)
338-
.configure(|config| config.max_iters(15).doe(&doe).outdir(outdir).seed(42))
336+
let doe = array![[0.], [7.], [23.]];
337+
let _ = EgorBuilder::optimize(xsinx)
338+
.configure(|config| config.max_iters(2).doe(&doe).outdir(outdir).seed(42))
339339
.min_within(&xlimits)
340340
.run()
341341
.expect("Minimize failure");
342-
let expected = array![18.9];
343-
assert_abs_diff_eq!(expected, res.x_opt, epsilon = 1e-1);
342+
343+
let filepath = std::path::Path::new(&outdir).join(DOE_FILE);
344+
assert!(filepath.exists());
345+
let doe: Array2<f64> = read_npy(&filepath).expect("file read");
344346

345347
let res = EgorBuilder::optimize(xsinx)
346-
.configure(|config| config.max_iters(5).outdir(outdir).hot_start(true).seed(42))
348+
.configure(|config| config.max_iters(3).outdir(outdir).hot_start(true).seed(42))
347349
.min_within(&xlimits)
348350
.run()
349351
.expect("Egor should minimize xsinx");
350-
let _ = std::fs::remove_file(format!("target/test_egor_builder/{DOE_INITIAL_FILE}"));
351-
let _ = std::fs::remove_file(format!("target/test_egor_builder/{DOE_FILE}"));
352+
let doe2: Array2<f64> = read_npy(&filepath).expect("file read");
353+
assert_eq!(doe2.nrows(), doe.nrows() + 3);
354+
355+
let _ = std::fs::remove_file(format!("{outdir}/{DOE_INITIAL_FILE}"));
356+
let _ = std::fs::remove_file(format!("{outdir}/{DOE_FILE}"));
352357
let expected = array![18.9];
353358
assert_abs_diff_eq!(expected, res.x_opt, epsilon = 1e-1);
354359
}
@@ -390,17 +395,33 @@ mod tests {
390395

391396
#[test]
392397
#[serial]
393-
fn test_rosenbrock_2d_trego_egor_builder() {
398+
fn test_rosenbrock_2d_no_trego_egor_builder() {
399+
let outdir = "target/test_trego";
400+
let _ = std::fs::remove_file(format!("{outdir}/{DOE_INITIAL_FILE}"));
401+
let _ = std::fs::remove_file(format!("{outdir}/{DOE_FILE}"));
394402
let now = Instant::now();
395403
let xlimits = array![[-2., 2.], [-2., 2.]];
396-
let doe = Lhs::new(&xlimits)
404+
let init_doe = Lhs::new(&xlimits)
397405
.with_rng(Xoshiro256Plus::seed_from_u64(42))
398406
.sample(10);
407+
let max_iters = 20;
399408
let res = EgorBuilder::optimize(rosenb)
400-
.configure(|config| config.doe(&doe).max_iters(20).seed(42).trego(true))
409+
.configure(|config| {
410+
config
411+
.doe(&init_doe)
412+
.max_iters(max_iters)
413+
.outdir(outdir)
414+
.seed(42)
415+
.trego(false)
416+
})
401417
.min_within(&xlimits)
402418
.run()
403419
.expect("Minimize failure");
420+
let filepath = std::path::Path::new(&outdir).join(DOE_FILE);
421+
assert!(filepath.exists());
422+
let doe: Array2<f64> = read_npy(&filepath).expect("file read");
423+
assert_eq!(doe.nrows(), init_doe.nrows() + max_iters); // we get one point per iter
424+
404425
println!("Rosenbrock optim result = {res:?}");
405426
println!("Elapsed = {:?}", now.elapsed());
406427
let expected = array![1., 1.];

ego/src/solver/egor_impl.rs

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::gpmix::mixint::{as_continuous_limits, to_discrete_space};
33
use crate::utils::{compute_cstr_scales, find_best_result_index_from, update_data};
44
use crate::{find_best_result_index, optimizers::*, EgorConfig};
55
use crate::{types::*, EgorState};
6-
use crate::{EgorSolver, DEFAULT_CSTR_TOL, DOE_FILE, MAX_POINT_ADDITION_RETRY};
6+
use crate::{EgorSolver, DEFAULT_CSTR_TOL, MAX_POINT_ADDITION_RETRY};
77

88
use argmin::argmin_error_closure;
99
use argmin::core::{CostFunction, Problem, State};
@@ -18,7 +18,7 @@ use log::{debug, info, warn};
1818
use ndarray::{
1919
concatenate, s, Array, Array1, Array2, ArrayBase, ArrayView2, Axis, Data, Ix1, Ix2, Zip,
2020
};
21-
use ndarray_npy::write_npy;
21+
2222
use ndarray_stats::QuantileExt;
2323
use rand_xoshiro::Xoshiro256Plus;
2424
use rayon::prelude::*;
@@ -350,15 +350,6 @@ where
350350
.and(y_actual.rows())
351351
.for_each(|mut y, val| y.assign(&val));
352352

353-
let doe = concatenate![Axis(1), x_data, y_data];
354-
if self.config.outdir.is_some() {
355-
let path = self.config.outdir.as_ref().unwrap();
356-
std::fs::create_dir_all(path)?;
357-
let filepath = std::path::Path::new(path).join(DOE_FILE);
358-
info!("Save doe shape {:?} in {:?}", doe.shape(), filepath);
359-
write_npy(filepath, &doe).expect("Write current doe");
360-
}
361-
362353
let best_index = find_best_result_index_from(
363354
state.best_index.unwrap(),
364355
y_data.nrows() - add_count as usize,

ego/src/solver/egor_solver.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,16 @@ where
270270
self.ego_iteration(fobj, state)?
271271
};
272272
let (x_data, y_data) = res.0.data.clone().unwrap();
273+
274+
if self.config.outdir.is_some() {
275+
let doe = concatenate![Axis(1), x_data, y_data];
276+
let path = self.config.outdir.as_ref().unwrap();
277+
std::fs::create_dir_all(path)?;
278+
let filepath = std::path::Path::new(path).join(DOE_FILE);
279+
info!("Save doe shape {:?} in {:?}", doe.shape(), filepath);
280+
write_npy(filepath, &doe).expect("Write current doe");
281+
}
282+
273283
info!(
274284
"********* End iteration {}/{} in {:.3}s: Best fun(x)={} at x={}",
275285
res.0.get_iter() + 1,

ego/src/solver/trego.rs

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -170,40 +170,7 @@ impl<SB: SurrogateBuilder> EgorSolver<SB> {
170170
.collect();
171171
let cstr_refs: Vec<_> = cstrs.iter().map(|c| c.as_ref()).collect();
172172

173-
// Other way to constrain in trust-region with global l
174-
// let cstr_up = Box::new(
175-
// |x: &[f64], gradient: Option<&mut [f64]>, _params: &mut InfillObjData<f64>| -> f64 {
176-
// let f = |x: &Vec<f64>| -> f64 {
177-
// let x = Array1::from_shape_vec((x.len(),), x.to_vec()).unwrap();
178-
// let d = (&x - xbest).norm_l1();
179-
// d - local_bounds.1
180-
// };
181-
// if let Some(grad) = gradient {
182-
// grad[..].copy_from_slice(&x.to_vec().central_diff(&f));
183-
// }
184-
// f(&x.to_vec())
185-
// },
186-
// ) as Box<dyn crate::types::ObjFn<InfillObjData<f64>> + Sync>;
187-
188-
// let cstr_lo = Box::new(
189-
// |x: &[f64], gradient: Option<&mut [f64]>, _params: &mut InfillObjData<f64>| -> f64 {
190-
// let f = |x: &Vec<f64>| -> f64 {
191-
// let x = Array1::from_shape_vec((x.len(),), x.to_vec()).unwrap();
192-
// let d = (&x - xbest).norm_l1();
193-
// local_bounds.0 - d
194-
// };
195-
// if let Some(grad) = gradient {
196-
// grad[..].copy_from_slice(&x.to_vec().central_diff(&f));
197-
// }
198-
// f(&x.to_vec())
199-
// },
200-
// ) as Box<dyn crate::types::ObjFn<InfillObjData<f64>> + Sync>;
201-
202-
// let mut cons = cstr_refs.to_vec();
203-
// cons.push(&cstr_lo);
204-
// cons.push(&cstr_up);
205-
206-
let mut scale_cstr_ext = Array1::zeros(scale_cstr.len() + 2);
173+
let mut scale_cstr_ext = Array1::zeros(scale_cstr.len());
207174
scale_cstr_ext
208175
.slice_mut(s![..scale_cstr.len()])
209176
.assign(&scale_cstr);
@@ -212,6 +179,7 @@ impl<SB: SurrogateBuilder> EgorSolver<SB> {
212179
..*infill_data
213180
};
214181

182+
// Draw n_start initial points (multistart optim) in the local_area
215183
// local_area = intersection(trust_region, xlimits)
216184
let mut local_area = Array2::zeros((self.xlimits.nrows(), self.xlimits.ncols()));
217185
Zip::from(local_area.rows_mut())
@@ -224,8 +192,6 @@ impl<SB: SurrogateBuilder> EgorSolver<SB> {
224192
);
225193
row.assign(&aview1(&[lo, up]))
226194
});
227-
228-
// Draw n_start initial points (multistart optim)
229195
let rng = self.rng.clone();
230196
let lhs = Lhs::new(&local_area)
231197
.kind(egobox_doe::LhsKind::Maximin)

0 commit comments

Comments
 (0)