Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| da2d367fb7 | |||
| ab74468603 | |||
| 4225d61027 |
+6
-6
@@ -3,7 +3,7 @@ members = ["optimizer-derive"]
|
||||
|
||||
[package]
|
||||
name = "optimizer"
|
||||
version = "1.0.0"
|
||||
version = "1.0.1"
|
||||
edition = "2024"
|
||||
rust-version = "1.89"
|
||||
license = "MIT"
|
||||
@@ -16,14 +16,14 @@ categories = ["algorithms", "science", "mathematics"]
|
||||
readme = "README.md"
|
||||
|
||||
[dependencies]
|
||||
fastrand = "2.3"
|
||||
fastrand = "2"
|
||||
thiserror = "2"
|
||||
parking_lot = "0.12"
|
||||
tokio = { version = "1.30", features = ["sync", "rt-multi-thread"], optional = true }
|
||||
optimizer-derive = { version = "0.1.0", path = "optimizer-derive", optional = true }
|
||||
tokio = { version = "1", features = ["sync", "rt-multi-thread"], optional = true }
|
||||
optimizer-derive = { version = "0.1", path = "optimizer-derive", optional = true }
|
||||
serde = { version = "1", features = ["derive"], optional = true }
|
||||
serde_json = { version = "1", optional = true }
|
||||
tracing = { version = "0.1.29", optional = true }
|
||||
tracing = { version = "0.1.26", optional = true }
|
||||
sobol_burley = { version = "0.5", optional = true }
|
||||
nalgebra = { version = "0.34", optional = true }
|
||||
fs2 = { version = "0.4", optional = true }
|
||||
@@ -40,7 +40,7 @@ cma-es = ["dep:nalgebra"]
|
||||
gp = ["dep:nalgebra"]
|
||||
|
||||
[dev-dependencies]
|
||||
tokio = { version = "1.30", features = ["rt-multi-thread", "macros", "time"] }
|
||||
tokio = { version = "1.50", features = ["rt-multi-thread", "macros", "time"] }
|
||||
optimizer-derive = { version = "0.1.0", path = "optimizer-derive" }
|
||||
serde_json = "1"
|
||||
criterion = { version = "0.8", features = ["html_reports"] }
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#![deny(clippy::complexity)]
|
||||
#![deny(clippy::perf)]
|
||||
#![deny(clippy::pedantic)]
|
||||
#![deny(clippy::std_instead_of_core)]
|
||||
|
||||
//! Bayesian and population-based optimization library with an Optuna-like API
|
||||
//! for hyperparameter tuning and black-box optimization. It ships 12 samplers
|
||||
|
||||
@@ -295,10 +295,10 @@ pub(crate) fn crossover(
|
||||
child2[i] = ParamValue::Int((c2.round() as i64).clamp(d.low, d.high));
|
||||
}
|
||||
}
|
||||
(ParamValue::Categorical(_), ParamValue::Categorical(_), _) => {
|
||||
if rng_util::f64_range(rng, 0.0, 1.0) < 0.5 {
|
||||
core::mem::swap(&mut child1[i], &mut child2[i]);
|
||||
}
|
||||
(ParamValue::Categorical(_), ParamValue::Categorical(_), _)
|
||||
if rng_util::f64_range(rng, 0.0, 1.0) < 0.5 =>
|
||||
{
|
||||
core::mem::swap(&mut child1[i], &mut child2[i]);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
+34
-66
@@ -642,6 +642,22 @@ impl Default for TpeSamplerBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
/// Deterministically pick a parameter value matching `target_dist` from a
|
||||
/// trial. When multiple parameters share the same distribution (e.g. two
|
||||
/// `FloatParam::new(-5.0, 5.0)` in the same study), the one with the
|
||||
/// smallest [`ParamId`] is chosen so behavior does not depend on
|
||||
/// `HashMap` iteration order.
|
||||
fn find_matching_value<'t>(
|
||||
t: &'t CompletedTrial,
|
||||
target_dist: &Distribution,
|
||||
) -> Option<&'t ParamValue> {
|
||||
t.distributions
|
||||
.iter()
|
||||
.filter(|(_, dist)| *dist == target_dist)
|
||||
.min_by_key(|(id, _)| *id)
|
||||
.and_then(|(id, _)| t.params.get(id))
|
||||
}
|
||||
|
||||
impl TpeSampler {
|
||||
fn sample_float(
|
||||
&self,
|
||||
@@ -653,33 +669,17 @@ impl TpeSampler {
|
||||
let target_dist = Distribution::Float(d.clone());
|
||||
let good_values: Vec<f64> = good_trials
|
||||
.iter()
|
||||
.filter_map(|t| {
|
||||
t.distributions.iter().find_map(|(id, dist)| {
|
||||
if *dist == target_dist {
|
||||
t.params.get(id).and_then(|v| match v {
|
||||
ParamValue::Float(f) => Some(*f),
|
||||
_ => None,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.filter_map(|t| match find_matching_value(t, &target_dist)? {
|
||||
ParamValue::Float(f) => Some(*f),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
|
||||
let bad_values: Vec<f64> = bad_trials
|
||||
.iter()
|
||||
.filter_map(|t| {
|
||||
t.distributions.iter().find_map(|(id, dist)| {
|
||||
if *dist == target_dist {
|
||||
t.params.get(id).and_then(|v| match v {
|
||||
ParamValue::Float(f) => Some(*f),
|
||||
_ => None,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.filter_map(|t| match find_matching_value(t, &target_dist)? {
|
||||
ParamValue::Float(f) => Some(*f),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
|
||||
@@ -708,33 +708,17 @@ impl TpeSampler {
|
||||
let target_dist = Distribution::Int(d.clone());
|
||||
let good_values: Vec<i64> = good_trials
|
||||
.iter()
|
||||
.filter_map(|t| {
|
||||
t.distributions.iter().find_map(|(id, dist)| {
|
||||
if *dist == target_dist {
|
||||
t.params.get(id).and_then(|v| match v {
|
||||
ParamValue::Int(i) => Some(*i),
|
||||
_ => None,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.filter_map(|t| match find_matching_value(t, &target_dist)? {
|
||||
ParamValue::Int(i) => Some(*i),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
|
||||
let bad_values: Vec<i64> = bad_trials
|
||||
.iter()
|
||||
.filter_map(|t| {
|
||||
t.distributions.iter().find_map(|(id, dist)| {
|
||||
if *dist == target_dist {
|
||||
t.params.get(id).and_then(|v| match v {
|
||||
ParamValue::Int(i) => Some(*i),
|
||||
_ => None,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.filter_map(|t| match find_matching_value(t, &target_dist)? {
|
||||
ParamValue::Int(i) => Some(*i),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
|
||||
@@ -764,33 +748,17 @@ impl TpeSampler {
|
||||
let target_dist = Distribution::Categorical(d.clone());
|
||||
let good_indices: Vec<usize> = good_trials
|
||||
.iter()
|
||||
.filter_map(|t| {
|
||||
t.distributions.iter().find_map(|(id, dist)| {
|
||||
if *dist == target_dist {
|
||||
t.params.get(id).and_then(|v| match v {
|
||||
ParamValue::Categorical(i) => Some(*i),
|
||||
_ => None,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.filter_map(|t| match find_matching_value(t, &target_dist)? {
|
||||
ParamValue::Categorical(i) => Some(*i),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
|
||||
let bad_indices: Vec<usize> = bad_trials
|
||||
.iter()
|
||||
.filter_map(|t| {
|
||||
t.distributions.iter().find_map(|(id, dist)| {
|
||||
if *dist == target_dist {
|
||||
t.params.get(id).and_then(|v| match v {
|
||||
ParamValue::Categorical(i) => Some(*i),
|
||||
_ => None,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.filter_map(|t| match find_matching_value(t, &target_dist)? {
|
||||
ParamValue::Categorical(i) => Some(*i),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user