- Remove stale #[allow(dead_code)] and #[allow(too_many_lines)] attributes
- Replace #[allow(dead_code)] with #[cfg(test)] for test-only methods
- Delete unused fill_remaining_independent() and ParamMeta.dist field
- Extract sample_float/int/categorical helpers from TpeSampler, MotpeSampler,
and SamplingEngine to shorten match-heavy sample() methods
- Extract try_fit_kdes() helper to consolidate repeated fallback blocks
- Refactor sample_tpe_float/int to take &FloatDistribution/&IntDistribution
instead of destructured args, removing #[allow(too_many_arguments)]
Fix direct path references for in-scope items (GammaStrategy,
CompletedTrial) and convert feature-gated items to plain backtick
formatting so docs build cleanly without --all-features.
- Add sampler/common.rs with distribution helpers (internal_bounds,
from_internal, to_internal, sample_random) used by 8 samplers
- Add sampler/tpe/common.rs with TPE sampling functions
(sample_tpe_float, sample_tpe_int, sample_tpe_categorical)
shared by TpeSampler, MultivariateTpeSampler, and MotpeSampler
- Remove ~940 lines of near-identical code across sampler modules
- Use Vec::with_capacity() in param_importance() and fanova_with_config()
where iteration count is known or bounded
- Fix flaky MultivariateTpeSampler doctest by increasing trials from 30
to 50
- Add Trial::into_completed() and into_multi_objective_trial() to move
fields instead of cloning 5 HashMaps/Vecs per trial completion
- Fire after_trial callback before pushing to storage, eliminating the
clone-from-storage pattern at all 4 call sites
- Optimize top_trials(n) to sort indices and clone only N trials instead
of cloning all completed trials
- Remove unused set_complete/set_pruned methods
- Replace Mutex<fastrand::Rng> with a stored seed + MurmurHash3 mixer
in RandomSampler, TpeSampler, and MotpeSampler so parallel workers
no longer serialize on a shared lock
- Add mix_seed() and distribution_fingerprint() to rng_util for
deterministic per-call RNG derivation from (seed, trial_id, distribution)
- Include an AtomicU64 call counter to disambiguate parameters that
share the same distribution within a trial
Remove the conditional guard on pruned trial assertions since the test
explicitly prunes 2 trials. Assert the expected count first, then check
summary content unconditionally to catch regressions.
- Add `CompletedTrial::validate()` checking all f64 fields are finite
- Call validate after deserializing each trial in journal storage
- Make `distribution` and `param` modules public (types already in public fields)
- Add blanket `impl Objective<V> for Fn(&mut Trial) -> Result<V, E>`
so closures work directly with `optimize`
- Rewrite optimize, optimize_async, optimize_parallel to accept
`impl Objective<V>` with before_trial/after_trial hooks
- Remove optimize_with, optimize_with_async, optimize_with_parallel
- Remove max_retries and retry logic from Objective trait
- Add explicit closure type annotations for HRTB inference
- Convert FnMut test closures to Fn via RefCell/Cell
- Delete 20 duplicate tests already covered by parameter_tests.rs
- Move 11 pure Trial unit tests into src/trial.rs
- Split remaining 84 integration tests into tests/study/ (9 modules)
- Group sampler tests into tests/sampler/ (7 modules)
- Group pruner tests into tests/pruner/ (2 modules)
- Split pruning_and_callbacks into pruning and early_stopping
- Split advanced_features into async_parallel, journal_storage, ask_and_tell, multi_objective
- Each example now requires only its own feature flag
- Trim sampler_comparison winner logic and verbose header
- Update CI workflow and README to match new example names
- Sampler, pruner, storage, parameter, and multi_objective types are no
longer re-exported at the crate root; access via module paths instead
(e.g. optimizer::sampler::TpeSampler, optimizer::parameter::FloatParam)
- Prelude continues to re-export everything for convenience
- Add module-level pub use re-exports in sampler/mod.rs and parameter.rs
- Update derive macro to reference optimizer::parameter::Categorical
- Rename sampler::differential_evolution to sampler::de
- Fix all downstream imports in tests, benches, and doctests
- Fix all rustdoc intra-doc links to use explicit module paths
Extract shared evolutionary algorithm infrastructure (genetic operators,
candidate management, Das-Dennis reference points) from NSGA-II into a
new genetic.rs module, then build two new multi-objective samplers on top:
- NSGA-III: reference-point-based niching for well-distributed fronts
on 3+ objective problems (Das-Dennis structured points, normalization,
perpendicular distance association, niching selection)
- MOEA/D: decomposition-based optimization with three scalarization
methods (Tchebycheff, WeightedSum, PBI), weight-vector neighborhoods,
and neighborhood-based mating selection
Both implement MultiObjectiveSampler with builder pattern, seeded RNG,
and SBX crossover / polynomial mutation via the shared genetic module.
Replace the internal Vec<CompletedTrial<V>> with a pluggable Storage<V>
trait. MemoryStorage is the default (no behavior change for existing
users). Behind the `journal` feature flag, JournalStorage persists
trials to a JSONL file with fs2 file locking for multi-process safety.
- Storage<V> trait with push(), trials_arc(), refresh() methods
- MemoryStorage<V> wraps Arc<RwLock<Vec<CompletedTrial<V>>>>
- JournalStorage<V> appends JSON lines with exclusive file locks
- Study::with_sampler_and_storage() general constructor
- Study::with_journal() convenience constructor (journal feature)
- Refresh from storage on create_trial() for multi-process discovery
- MSRV bumped to 1.89
Population-based optimizer with mutation + crossover. Supports three
strategies (Rand1, Best1, CurrentToBest1), configurable F and CR,
and auto-sized populations. No extra dependencies needed.
fastrand is smaller, faster, and has no dependencies. Add rng_util
helper for f64 range generation since fastrand lacks a built-in
equivalent. Migrate all samplers, KDE modules, and fANOVA to use
fastrand's concrete Rng type instead of rand's trait-based generics.