Skip to content

Commit

Permalink
fix: fix random sampling for unconstrained domains
Browse files Browse the repository at this point in the history
Previously, numbers from [0, 1) were generated, which is hardly a number
from the entire domain of real numbers. This bug was present even when
using rand crate in the past, because we used the `Standard`
distribution which generates floats from [0, 1) range.
  • Loading branch information
pnevyk committed Nov 12, 2023
1 parent 67a0d45 commit 278fbe0
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 4 deletions.
12 changes: 10 additions & 2 deletions src/core/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,11 @@ pub trait Sample {

impl Sample for f32 {
fn sample_any(rng: &mut Rng) -> Self {
rng.f32()
// Sampling from the whole range is likely not desired. Choosing
// sqrt(MAX) as an arbitrary bound.
let max = f32::MAX.sqrt();
let min = -max;
rng.f32_range(min..=max)
}

fn sample_uniform(lower: Self, upper: Self, rng: &mut Rng) -> Self {
Expand All @@ -65,7 +69,11 @@ impl Sample for f32 {

impl Sample for f64 {
fn sample_any(rng: &mut Rng) -> Self {
rng.f64()
// Sampling from the whole range is likely not desired. Choosing
// cbrt(MAX) as an arbitrary bound.
let max = f64::MAX.cbrt();
let min = -max;
rng.f64_range(min..=max)
}

fn sample_uniform(lower: Self, upper: Self, rng: &mut Rng) -> Self {
Expand Down
7 changes: 5 additions & 2 deletions src/solver/lipo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,10 @@ mod tests {
let n = 2;

let f = Sphere::new(n);
let dom = f.domain();
// We are going to run LIPO without any local optimization and "any
// potential minimizer" strategy. In such a setting, it would be
// impossible for LIPO to find good points in the unconstrained domain.
let dom = (0..n).map(|_| (-1.0, 1.0)).collect();
let eps = convert(1e-3);
let rng = Rng::with_seed(3);
let mut options = LipoOptions::default();
Expand All @@ -443,7 +446,7 @@ mod tests {

for x in f.initials() {
let optimizer = Lipo::with_options(&f, &dom, options.clone(), rng.clone());
optimize(&f, &dom, optimizer, x, convert(0.0), 250, eps).unwrap();
optimize(&f, &dom, optimizer, x, convert(0.0), 1000, eps).unwrap();
}
}
}

0 comments on commit 278fbe0

Please sign in to comment.