diff --git a/benches/samplers.rs b/benches/samplers.rs index 79da8a6..4cb2e7f 100644 --- a/benches/samplers.rs +++ b/benches/samplers.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main}; use optimizer::parameter::{FloatParam, Parameter}; -use optimizer::sampler::grid::GridSearchSampler; +use optimizer::sampler::grid::GridSampler; use optimizer::sampler::random::RandomSampler; use optimizer::sampler::tpe::TpeSampler; use optimizer::sampler::{CompletedTrial, Sampler}; @@ -97,7 +97,7 @@ fn bench_grid_sample(c: &mut Criterion) { |b, _| { b.iter(|| { // Fresh sampler each iteration since grid tracks used points - let sampler = GridSearchSampler::builder() + let sampler = GridSampler::builder() .n_points_per_param(grid_points) .build(); sampler.sample(&dist, 0, &history) diff --git a/examples/sampler_comparison.rs b/examples/sampler_comparison.rs index 9e484e2..f1c1b7a 100644 --- a/examples/sampler_comparison.rs +++ b/examples/sampler_comparison.rs @@ -65,7 +65,7 @@ fn main() { // Evaluates evenly spaced grid points. Each parameter gets its own grid that // is sampled in order, so n_points_per_param must be >= n_trials. println!("\n3. Grid sampler (exhaustive):"); - let grid = GridSearchSampler::builder() + let grid = GridSampler::builder() .n_points_per_param(n_trials) // one grid point per trial per parameter .build(); let grid_best = run_study(Study::minimize(grid), n_trials); diff --git a/src/lib.rs b/src/lib.rs index 1424b33..808012d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -54,11 +54,11 @@ //! |---------|-----------|----------|--------------| //! | [`RandomSampler`](sampler::RandomSampler) | Uniform random | Baselines, high-dimensional | — | //! | [`TpeSampler`](sampler::TpeSampler) | Tree-Parzen Estimator | General-purpose Bayesian | — | -//! | [`GridSearchSampler`](sampler::GridSearchSampler) | Exhaustive grid | Small, discrete spaces | — | +//! | [`GridSearchSampler`](sampler::GridSampler) | Exhaustive grid | Small, discrete spaces | — | //! | [`SobolSampler`](sampler::SobolSampler) | Sobol quasi-random sequence | Space-filling, low dimensions | `sobol` | //! | [`CmaEsSampler`](sampler::CmaEsSampler) | CMA-ES | Continuous, moderate dimensions | `cma-es` | //! | [`GpSampler`](sampler::GpSampler) | Gaussian Process + EI | Expensive objectives, few trials | `gp` | -//! | [`DifferentialEvolutionSampler`](sampler::DifferentialEvolutionSampler) | Differential Evolution | Non-convex, population-based | — | +//! | [`DESampler`](sampler::DESampler) | Differential Evolution | Non-convex, population-based | — | //! | [`BohbSampler`](sampler::BohbSampler) | BOHB (TPE + `HyperBand`) | Budget-aware early stopping | — | //! //! ## Multi-objective samplers @@ -168,9 +168,8 @@ pub mod prelude { #[cfg(feature = "sobol")] pub use crate::sampler::SobolSampler; pub use crate::sampler::{ - BohbSampler, CompletedTrial, Decomposition, DifferentialEvolutionSampler, - DifferentialEvolutionStrategy, GridSearchSampler, MoeadSampler, MotpeSampler, Nsga2Sampler, - Nsga3Sampler, RandomSampler, TpeSampler, + BohbSampler, CompletedTrial, DESampler, DEStrategy, Decomposition, GridSampler, + MoeadSampler, MotpeSampler, Nsga2Sampler, Nsga3Sampler, RandomSampler, TpeSampler, }; #[cfg(feature = "journal")] pub use crate::storage::JournalStorage; diff --git a/src/sampler/de.rs b/src/sampler/de.rs index 7641084..bd6be26 100644 --- a/src/sampler/de.rs +++ b/src/sampler/de.rs @@ -10,7 +10,7 @@ //! //! Each generation, for every population member *xᵢ*: //! 1. **Mutation** — create a mutant vector *v* from other population -//! members using the selected [`DifferentialEvolutionStrategy`]: +//! members using the selected [`DEStrategy`]: //! - `Rand1`: `v = x_r1 + F * (x_r2 - x_r3)` //! - `Best1`: `v = x_best + F * (x_r1 - x_r2)` //! - `CurrentToBest1`: `v = x_i + F * (x_best - x_i) + F * (x_r1 - x_r2)` @@ -40,20 +40,20 @@ //! | `population_size` | `max(10n, 15)` | Candidates per generation | //! | `mutation_factor` (F) | 0.8 | Differential amplification — higher = more exploration | //! | `crossover_rate` (CR) | 0.9 | Probability of taking a dimension from the mutant | -//! | `strategy` | `Rand1` | Mutation strategy (see [`DifferentialEvolutionStrategy`]) | +//! | `strategy` | `Rand1` | Mutation strategy (see [`DEStrategy`]) | //! | `seed` | random | RNG seed for reproducibility | //! //! # Examples //! //! ``` -//! use optimizer::sampler::de::{DifferentialEvolutionSampler, DifferentialEvolutionStrategy}; +//! use optimizer::sampler::de::{DESampler, DEStrategy}; //! use optimizer::{Direction, Study}; //! //! // Minimize with DE using the Best1 strategy for faster convergence -//! let sampler = DifferentialEvolutionSampler::builder() +//! let sampler = DESampler::builder() //! .mutation_factor(0.7) //! .crossover_rate(0.9) -//! .strategy(DifferentialEvolutionStrategy::Best1) +//! .strategy(DEStrategy::Best1) //! .population_size(20) //! .seed(42) //! .build(); @@ -74,7 +74,7 @@ use crate::sampler::{CompletedTrial, Sampler}; /// /// Controls how mutant vectors are created from the current population. #[derive(Clone, Copy, Debug, Default)] -pub enum DifferentialEvolutionStrategy { +pub enum DEStrategy { /// DE/rand/1: `v = x_r1 + F * (x_r2 - x_r3)` /// /// The most robust strategy. Uses three random population members. @@ -99,46 +99,36 @@ pub enum DifferentialEvolutionStrategy { /// # Examples /// /// ``` -/// use optimizer::sampler::de::DifferentialEvolutionSampler; +/// use optimizer::sampler::de::DESampler; /// use optimizer::{Direction, Study}; /// /// // Default configuration -/// let study: Study = -/// Study::with_sampler(Direction::Minimize, DifferentialEvolutionSampler::new()); +/// let study: Study = Study::with_sampler(Direction::Minimize, DESampler::new()); /// /// // With seed for reproducibility -/// let study: Study = Study::with_sampler( -/// Direction::Minimize, -/// DifferentialEvolutionSampler::with_seed(42), -/// ); +/// let study: Study = Study::with_sampler(Direction::Minimize, DESampler::with_seed(42)); /// /// // Custom configuration via builder -/// use optimizer::sampler::de::DifferentialEvolutionStrategy; -/// let sampler = DifferentialEvolutionSampler::builder() +/// use optimizer::sampler::de::DEStrategy; +/// let sampler = DESampler::builder() /// .mutation_factor(0.8) /// .crossover_rate(0.9) -/// .strategy(DifferentialEvolutionStrategy::Best1) +/// .strategy(DEStrategy::Best1) /// .population_size(30) /// .seed(42) /// .build(); /// let study: Study = Study::with_sampler(Direction::Minimize, sampler); /// ``` -pub struct DifferentialEvolutionSampler { +pub struct DESampler { state: Mutex, } -impl DifferentialEvolutionSampler { +impl DESampler { /// Creates a new DE sampler with default settings and a random seed. #[must_use] pub fn new() -> Self { Self { - state: Mutex::new(State::new( - None, - 0.8, - 0.9, - DifferentialEvolutionStrategy::Rand1, - None, - )), + state: Mutex::new(State::new(None, 0.8, 0.9, DEStrategy::Rand1, None)), } } @@ -146,30 +136,24 @@ impl DifferentialEvolutionSampler { #[must_use] pub fn with_seed(seed: u64) -> Self { Self { - state: Mutex::new(State::new( - None, - 0.8, - 0.9, - DifferentialEvolutionStrategy::Rand1, - Some(seed), - )), + state: Mutex::new(State::new(None, 0.8, 0.9, DEStrategy::Rand1, Some(seed))), } } - /// Creates a builder for configuring a `DifferentialEvolutionSampler`. + /// Creates a builder for configuring a `DESampler`. #[must_use] - pub fn builder() -> DifferentialEvolutionSamplerBuilder { - DifferentialEvolutionSamplerBuilder::new() + pub fn builder() -> DESamplerBuilder { + DESamplerBuilder::new() } } -impl Default for DifferentialEvolutionSampler { +impl Default for DESampler { fn default() -> Self { Self::new() } } -/// Builder for configuring a [`DifferentialEvolutionSampler`]. +/// Builder for configuring a [`DESampler`]. /// /// All options have sensible defaults: /// - `population_size`: `max(10 * n_dims, 15)` (auto-computed from parameter count) @@ -181,34 +165,32 @@ impl Default for DifferentialEvolutionSampler { /// # Examples /// /// ``` -/// use optimizer::sampler::de::{ -/// DifferentialEvolutionSamplerBuilder, DifferentialEvolutionStrategy, -/// }; +/// use optimizer::sampler::de::{DESamplerBuilder, DEStrategy}; /// -/// let sampler = DifferentialEvolutionSamplerBuilder::new() +/// let sampler = DESamplerBuilder::new() /// .mutation_factor(0.5) /// .crossover_rate(0.7) -/// .strategy(DifferentialEvolutionStrategy::CurrentToBest1) +/// .strategy(DEStrategy::CurrentToBest1) /// .population_size(20) /// .seed(42) /// .build(); /// ``` #[derive(Debug, Clone)] -pub struct DifferentialEvolutionSamplerBuilder { +pub struct DESamplerBuilder { population_size: Option, mutation_factor: f64, crossover_rate: f64, - strategy: DifferentialEvolutionStrategy, + strategy: DEStrategy, seed: Option, } -impl Default for DifferentialEvolutionSamplerBuilder { +impl Default for DESamplerBuilder { fn default() -> Self { Self::new() } } -impl DifferentialEvolutionSamplerBuilder { +impl DESamplerBuilder { /// Creates a new builder with default settings. #[must_use] pub fn new() -> Self { @@ -216,7 +198,7 @@ impl DifferentialEvolutionSamplerBuilder { population_size: None, mutation_factor: 0.8, crossover_rate: 0.9, - strategy: DifferentialEvolutionStrategy::Rand1, + strategy: DEStrategy::Rand1, seed: None, } } @@ -261,9 +243,9 @@ impl DifferentialEvolutionSamplerBuilder { /// Sets the mutation strategy. /// - /// Default: [`DifferentialEvolutionStrategy::Rand1`]. + /// Default: [`DEStrategy::Rand1`]. #[must_use] - pub fn strategy(mut self, strategy: DifferentialEvolutionStrategy) -> Self { + pub fn strategy(mut self, strategy: DEStrategy) -> Self { self.strategy = strategy; self } @@ -275,10 +257,10 @@ impl DifferentialEvolutionSamplerBuilder { self } - /// Builds the configured [`DifferentialEvolutionSampler`]. + /// Builds the configured [`DESampler`]. #[must_use] - pub fn build(self) -> DifferentialEvolutionSampler { - DifferentialEvolutionSampler { + pub fn build(self) -> DESampler { + DESampler { state: Mutex::new(State::new( self.population_size, self.mutation_factor, @@ -345,7 +327,7 @@ struct State { /// Crossover rate (CR). crossover_rate: f64, /// Mutation strategy. - strategy: DifferentialEvolutionStrategy, + strategy: DEStrategy, /// Current phase. phase: Phase, /// Discovered dimension info (populated during discovery). @@ -383,7 +365,7 @@ impl State { user_population_size: Option, mutation_factor: f64, crossover_rate: f64, - strategy: DifferentialEvolutionStrategy, + strategy: DEStrategy, seed: Option, ) -> Self { let rng = seed.map_or_else(fastrand::Rng::new, fastrand::Rng::with_seed); @@ -601,21 +583,21 @@ fn create_mutant_with_rng(state: &mut State, target_idx: usize, n_continuous: us let pop_size = state.population_size; match state.strategy { - DifferentialEvolutionStrategy::Rand1 => { + DEStrategy::Rand1 => { let indices = select_random_indices(&mut state.rng, pop_size, 3, &[target_idx]); let (r1, r2, r3) = (indices[0], indices[1], indices[2]); (0..n_continuous) .map(|j| pop[r1][j] + f * (pop[r2][j] - pop[r3][j])) .collect() } - DifferentialEvolutionStrategy::Best1 => { + DEStrategy::Best1 => { let indices = select_random_indices(&mut state.rng, pop_size, 2, &[target_idx]); let (r1, r2) = (indices[0], indices[1]); (0..n_continuous) .map(|j| pop[best_idx][j] + f * (pop[r1][j] - pop[r2][j])) .collect() } - DifferentialEvolutionStrategy::CurrentToBest1 => { + DEStrategy::CurrentToBest1 => { let indices = select_random_indices(&mut state.rng, pop_size, 2, &[target_idx]); let (r1, r2) = (indices[0], indices[1]); (0..n_continuous) @@ -693,7 +675,7 @@ fn generate_initial_population(state: &mut State) -> Vec { // Sampler trait implementation // --------------------------------------------------------------------------- -impl Sampler for DifferentialEvolutionSampler { +impl Sampler for DESampler { #[allow(clippy::cast_precision_loss)] fn sample( &self, @@ -968,7 +950,7 @@ mod tests { #[test] fn test_de_sampler_basic_float() { - let sampler = DifferentialEvolutionSampler::with_seed(42); + let sampler = DESampler::with_seed(42); let dist = Distribution::Float(FloatDistribution { low: -5.0, high: 5.0, @@ -1000,7 +982,7 @@ mod tests { }); let sample_values = |seed: u64| { - let sampler = DifferentialEvolutionSampler::with_seed(seed); + let sampler = DESampler::with_seed(seed); (0..20) .map(|i| sampler.sample(&dist, i, &[])) .collect::>() @@ -1016,22 +998,16 @@ mod tests { #[test] fn test_de_strategy_default() { - assert!(matches!( - DifferentialEvolutionStrategy::default(), - DifferentialEvolutionStrategy::Rand1 - )); + assert!(matches!(DEStrategy::default(), DEStrategy::Rand1)); } #[test] fn test_builder_defaults() { - let builder = DifferentialEvolutionSamplerBuilder::new(); + let builder = DESamplerBuilder::new(); assert!(builder.population_size.is_none()); assert!((builder.mutation_factor - 0.8).abs() < f64::EPSILON); assert!((builder.crossover_rate - 0.9).abs() < f64::EPSILON); - assert!(matches!( - builder.strategy, - DifferentialEvolutionStrategy::Rand1 - )); + assert!(matches!(builder.strategy, DEStrategy::Rand1)); assert!(builder.seed.is_none()); } } diff --git a/src/sampler/grid.rs b/src/sampler/grid.rs index c3ce2b7..b991f35 100644 --- a/src/sampler/grid.rs +++ b/src/sampler/grid.rs @@ -1,6 +1,6 @@ //! Grid search sampler — exhaustive evaluation of discretized parameter spaces. //! -//! [`GridSearchSampler`] divides each parameter range into a fixed number of +//! [`GridSampler`] divides each parameter range into a fixed number of //! evenly spaced points (or uses the explicit step size when defined) and //! evaluates them sequentially. This guarantees complete coverage of the //! search grid at the cost of scaling exponentially with the number of @@ -29,9 +29,9 @@ //! //! ``` //! use optimizer::prelude::*; -//! use optimizer::sampler::grid::GridSearchSampler; +//! use optimizer::sampler::grid::GridSampler; //! -//! let sampler = GridSearchSampler::builder().n_points_per_param(5).build(); +//! let sampler = GridSampler::builder().n_points_per_param(5).build(); //! let study: Study = Study::with_sampler(Direction::Minimize, sampler); //! ``` @@ -353,22 +353,22 @@ struct GridState { /// # Examples /// /// ``` -/// use optimizer::sampler::grid::GridSearchSampler; +/// use optimizer::sampler::grid::GridSampler; /// /// // Default: 10 points per parameter -/// let sampler = GridSearchSampler::new(); +/// let sampler = GridSampler::new(); /// /// // Custom grid density -/// let sampler = GridSearchSampler::builder().n_points_per_param(20).build(); +/// let sampler = GridSampler::builder().n_points_per_param(20).build(); /// ``` -pub struct GridSearchSampler { +pub struct GridSampler { /// Number of grid points per parameter (used when auto-discretizing). n_points_per_param: usize, /// Thread-safe internal state for tracking grid positions. state: Mutex, } -impl GridSearchSampler { +impl GridSampler { /// Creates a new grid search sampler with default settings. /// /// Default settings: @@ -386,9 +386,9 @@ impl GridSearchSampler { /// # Examples /// /// ``` - /// use optimizer::sampler::grid::GridSearchSampler; + /// use optimizer::sampler::grid::GridSampler; /// - /// let sampler = GridSearchSampler::builder().n_points_per_param(20).build(); + /// let sampler = GridSampler::builder().n_points_per_param(20).build(); /// ``` #[must_use] pub fn builder() -> GridSearchSamplerBuilder { @@ -396,13 +396,13 @@ impl GridSearchSampler { } } -impl Default for GridSearchSampler { +impl Default for GridSampler { fn default() -> Self { Self::new() } } -impl GridSearchSampler { +impl GridSampler { /// Returns `true` if all grid points for all tracked distributions have been sampled. /// /// A distribution is considered exhausted when its `current_index` equals the number @@ -416,9 +416,9 @@ impl GridSearchSampler { /// # Examples /// /// ``` - /// use optimizer::sampler::grid::GridSearchSampler; + /// use optimizer::sampler::grid::GridSampler; /// - /// let sampler = GridSearchSampler::new(); + /// let sampler = GridSampler::new(); /// // Initially exhausted (no distributions tracked yet) /// assert!(sampler.is_exhausted()); /// ``` @@ -446,9 +446,9 @@ impl GridSearchSampler { /// # Examples /// /// ``` - /// use optimizer::sampler::grid::GridSearchSampler; + /// use optimizer::sampler::grid::GridSampler; /// - /// let sampler = GridSearchSampler::new(); + /// let sampler = GridSampler::new(); /// // No distributions tracked yet /// assert_eq!(sampler.grid_size(), 0); /// ``` @@ -459,7 +459,7 @@ impl GridSearchSampler { } } -/// Builder for configuring a [`GridSearchSampler`]. +/// Builder for configuring a [`GridSampler`]. /// /// # Examples /// @@ -511,7 +511,7 @@ impl GridSearchSamplerBuilder { self } - /// Builds the configured [`GridSearchSampler`]. + /// Builds the configured [`GridSampler`]. /// /// # Examples /// @@ -523,8 +523,8 @@ impl GridSearchSamplerBuilder { /// .build(); /// ``` #[must_use] - pub fn build(self) -> GridSearchSampler { - GridSearchSampler { + pub fn build(self) -> GridSampler { + GridSampler { n_points_per_param: self.n_points_per_param, state: Mutex::new(GridState::default()), } @@ -566,7 +566,7 @@ fn distribution_key(dist: &Distribution) -> String { } } -impl Sampler for GridSearchSampler { +impl Sampler for GridSampler { fn sample( &self, distribution: &Distribution, @@ -876,7 +876,7 @@ mod tests { #[test] fn test_sampler_exhausts_after_expected_samples() { - let sampler = GridSearchSampler::new(); + let sampler = GridSampler::new(); let dist = Distribution::Categorical(CategoricalDistribution { n_choices: 3 }); // Sample all 3 points @@ -890,7 +890,7 @@ mod tests { #[test] fn test_sampler_exhaustion_with_int_distribution() { - let sampler = GridSearchSampler::builder().n_points_per_param(5).build(); + let sampler = GridSampler::builder().n_points_per_param(5).build(); let dist = Distribution::Int(IntDistribution { low: 0, high: 100, @@ -910,7 +910,7 @@ mod tests { #[test] #[should_panic(expected = "GridSearchSampler: all grid points exhausted")] fn test_sampler_panics_after_exhaustion() { - let sampler = GridSearchSampler::new(); + let sampler = GridSampler::new(); let dist = Distribution::Categorical(CategoricalDistribution { n_choices: 2 }); // Sample all 2 points @@ -925,14 +925,14 @@ mod tests { #[test] fn test_is_exhausted_before_sampling() { - let sampler = GridSearchSampler::new(); + let sampler = GridSampler::new(); // Newly created sampler is vacuously exhausted (no distributions tracked) assert!(sampler.is_exhausted()); } #[test] fn test_is_exhausted_during_sampling() { - let sampler = GridSearchSampler::new(); + let sampler = GridSampler::new(); let dist = Distribution::Categorical(CategoricalDistribution { n_choices: 3 }); // After first sample, not exhausted @@ -950,7 +950,7 @@ mod tests { #[test] fn test_is_exhausted_multiple_distributions() { - let sampler = GridSearchSampler::new(); + let sampler = GridSampler::new(); // Use different n_choices so they have different distribution keys let dist1 = Distribution::Categorical(CategoricalDistribution { n_choices: 2 }); let dist2 = Distribution::Categorical(CategoricalDistribution { n_choices: 3 }); @@ -976,7 +976,7 @@ mod tests { #[test] fn test_builder_default() { - let sampler = GridSearchSampler::builder().build(); + let sampler = GridSampler::builder().build(); let dist = Distribution::Float(FloatDistribution { low: 0.0, high: 1.0, @@ -993,7 +993,7 @@ mod tests { #[test] fn test_builder_custom_n_points() { - let sampler = GridSearchSampler::builder().n_points_per_param(3).build(); + let sampler = GridSampler::builder().n_points_per_param(3).build(); let dist = Distribution::Float(FloatDistribution { low: 0.0, high: 1.0, @@ -1011,7 +1011,7 @@ mod tests { #[test] fn test_new_default() { - let sampler = GridSearchSampler::new(); + let sampler = GridSampler::new(); let dist = Distribution::Float(FloatDistribution { low: 0.0, high: 1.0, @@ -1031,8 +1031,8 @@ mod tests { #[test] fn test_reproducibility_same_grid_order() { // Two samplers with the same configuration should produce the same grid order - let sampler1 = GridSearchSampler::builder().n_points_per_param(5).build(); - let sampler2 = GridSearchSampler::builder().n_points_per_param(5).build(); + let sampler1 = GridSampler::builder().n_points_per_param(5).build(); + let sampler2 = GridSampler::builder().n_points_per_param(5).build(); let dist = Distribution::Float(FloatDistribution { low: 0.0, @@ -1051,8 +1051,8 @@ mod tests { #[test] fn test_reproducibility_int_distribution() { - let sampler1 = GridSearchSampler::new(); - let sampler2 = GridSearchSampler::new(); + let sampler1 = GridSampler::new(); + let sampler2 = GridSampler::new(); let dist = Distribution::Int(IntDistribution { low: 0, @@ -1073,8 +1073,8 @@ mod tests { #[test] fn test_reproducibility_categorical() { - let sampler1 = GridSearchSampler::new(); - let sampler2 = GridSearchSampler::new(); + let sampler1 = GridSampler::new(); + let sampler2 = GridSampler::new(); let dist = Distribution::Categorical(CategoricalDistribution { n_choices: 4 }); @@ -1091,13 +1091,13 @@ mod tests { #[test] fn test_grid_size_empty() { - let sampler = GridSearchSampler::new(); + let sampler = GridSampler::new(); assert_eq!(sampler.grid_size(), 0); } #[test] fn test_grid_size_single_distribution() { - let sampler = GridSearchSampler::builder().n_points_per_param(5).build(); + let sampler = GridSampler::builder().n_points_per_param(5).build(); let dist = Distribution::Float(FloatDistribution { low: 0.0, high: 1.0, @@ -1115,7 +1115,7 @@ mod tests { #[test] fn test_grid_size_multiple_distributions() { - let sampler = GridSearchSampler::builder().n_points_per_param(3).build(); + let sampler = GridSampler::builder().n_points_per_param(3).build(); let dist1 = Distribution::Float(FloatDistribution { low: 0.0, high: 1.0, diff --git a/src/sampler/mod.rs b/src/sampler/mod.rs index cfa5537..bea4200 100644 --- a/src/sampler/mod.rs +++ b/src/sampler/mod.rs @@ -22,10 +22,10 @@ use std::collections::HashMap; pub use bohb::BohbSampler; #[cfg(feature = "cma-es")] pub use cma_es::CmaEsSampler; -pub use de::{DifferentialEvolutionSampler, DifferentialEvolutionStrategy}; +pub use de::{DESampler, DEStrategy}; #[cfg(feature = "gp")] pub use gp::GpSampler; -pub use grid::GridSearchSampler; +pub use grid::GridSampler; pub use moead::{Decomposition, MoeadSampler}; pub use motpe::MotpeSampler; pub use nsga2::Nsga2Sampler; diff --git a/tests/sampler/differential_evolution.rs b/tests/sampler/differential_evolution.rs index 4c75d5f..1ffa5e9 100644 --- a/tests/sampler/differential_evolution.rs +++ b/tests/sampler/differential_evolution.rs @@ -1,9 +1,9 @@ use optimizer::prelude::*; -use optimizer::sampler::de::{DifferentialEvolutionSampler, DifferentialEvolutionStrategy}; +use optimizer::sampler::de::{DESampler, DEStrategy}; #[test] fn sphere_function() { - let sampler = DifferentialEvolutionSampler::with_seed(42); + let sampler = DESampler::with_seed(42); let study: Study = Study::with_sampler(Direction::Minimize, sampler); let x = FloatParam::new(-5.0, 5.0).name("x"); @@ -27,10 +27,7 @@ fn sphere_function() { #[test] fn rosenbrock_function() { - let sampler = DifferentialEvolutionSampler::builder() - .population_size(20) - .seed(42) - .build(); + let sampler = DESampler::builder().population_size(20).seed(42).build(); let study: Study = Study::with_sampler(Direction::Minimize, sampler); let x = FloatParam::new(-5.0, 5.0).name("x"); @@ -55,7 +52,7 @@ fn rosenbrock_function() { #[test] fn rastrigin_function() { - let sampler = DifferentialEvolutionSampler::builder() + let sampler = DESampler::builder() .population_size(30) .mutation_factor(0.7) .crossover_rate(0.9) @@ -88,7 +85,7 @@ fn rastrigin_function() { #[test] fn bounds_respected() { - let sampler = DifferentialEvolutionSampler::with_seed(123); + let sampler = DESampler::with_seed(123); let study: Study = Study::with_sampler(Direction::Minimize, sampler); let x = FloatParam::new(-2.0, 3.0).name("x"); @@ -112,8 +109,8 @@ fn bounds_respected() { #[test] fn strategy_best1() { - let sampler = DifferentialEvolutionSampler::builder() - .strategy(DifferentialEvolutionStrategy::Best1) + let sampler = DESampler::builder() + .strategy(DEStrategy::Best1) .population_size(15) .seed(42) .build(); @@ -140,8 +137,8 @@ fn strategy_best1() { #[test] fn strategy_current_to_best1() { - let sampler = DifferentialEvolutionSampler::builder() - .strategy(DifferentialEvolutionStrategy::CurrentToBest1) + let sampler = DESampler::builder() + .strategy(DEStrategy::CurrentToBest1) .population_size(15) .seed(42) .build(); @@ -168,7 +165,7 @@ fn strategy_current_to_best1() { #[test] fn mixed_params_float_and_categorical() { - let sampler = DifferentialEvolutionSampler::with_seed(42); + let sampler = DESampler::with_seed(42); let study: Study = Study::with_sampler(Direction::Minimize, sampler); let x = FloatParam::new(-5.0, 5.0).name("x"); @@ -201,7 +198,7 @@ fn seeded_reproducibility() { let y = FloatParam::new(-5.0, 5.0).name("y"); let run = |seed: u64| { - let sampler = DifferentialEvolutionSampler::with_seed(seed); + let sampler = DESampler::with_seed(seed); let study: Study = Study::with_sampler(Direction::Minimize, sampler); study .optimize(50, |trial: &mut optimizer::Trial| { @@ -224,7 +221,7 @@ fn different_seeds_different_results() { let y = FloatParam::new(-5.0, 5.0).name("y"); let run = |seed: u64| { - let sampler = DifferentialEvolutionSampler::with_seed(seed); + let sampler = DESampler::with_seed(seed); let study: Study = Study::with_sampler(Direction::Minimize, sampler); study .optimize(20, |trial: &mut optimizer::Trial| { @@ -246,7 +243,7 @@ fn different_seeds_different_results() { #[test] fn single_dimension() { - let sampler = DifferentialEvolutionSampler::with_seed(42); + let sampler = DESampler::with_seed(42); let study: Study = Study::with_sampler(Direction::Minimize, sampler); let x = FloatParam::new(-10.0, 10.0).name("x"); @@ -268,7 +265,7 @@ fn single_dimension() { #[test] fn integer_params() { - let sampler = DifferentialEvolutionSampler::with_seed(42); + let sampler = DESampler::with_seed(42); let study: Study = Study::with_sampler(Direction::Minimize, sampler); let n = IntParam::new(1, 20).name("n"); @@ -296,7 +293,7 @@ fn integer_params() { #[test] fn log_scale_params() { - let sampler = DifferentialEvolutionSampler::with_seed(42); + let sampler = DESampler::with_seed(42); let study: Study = Study::with_sampler(Direction::Minimize, sampler); let lr = FloatParam::new(1e-5, 1.0).log_scale().name("lr"); @@ -320,7 +317,7 @@ fn log_scale_params() { #[test] fn custom_mutation_and_crossover() { - let sampler = DifferentialEvolutionSampler::builder() + let sampler = DESampler::builder() .mutation_factor(0.5) .crossover_rate(0.7) .population_size(10)