- Clamp KDE candidates to parameter bounds before evaluating l(x)/g(x),
matching the univariate TPE behavior; without this, candidates scored
well at out-of-bounds locations but became suboptimal when clamped
- Sort HashMap iterations by ParamId before consuming the seeded RNG to
eliminate non-deterministic sampling caused by global ParamId counter
- Replace wall-clock timing assertion in async concurrency test with
atomic max-active counter to avoid CI flakiness
- Gate unused HashSet import behind cfg(feature = "async")
- 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
- 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)