use fastrand::Rng;
use fastrand_contrib::RngExt;
use super::domain::Domain;
pub trait RealField: nalgebra::RealField {
const EPSILON_SQRT: Self;
const EPSILON_CBRT: Self;
}
impl RealField for f32 {
const EPSILON_SQRT: Self = 0.00034526698;
const EPSILON_CBRT: Self = 0.0049215667;
}
impl RealField for f64 {
const EPSILON_SQRT: Self = 0.000000014901161193847656;
const EPSILON_CBRT: Self = 0.0000060554544523933395;
}
pub trait Problem {
type Field: RealField + Copy;
fn domain(&self) -> Domain<Self::Field>;
}
pub trait Sample {
fn sample_any(rng: &mut Rng) -> Self;
fn sample_uniform(lower: Self, upper: Self, rng: &mut Rng) -> Self;
fn sample_normal(mu: Self, sigma: Self, rng: &mut Rng) -> Self;
}
impl Sample for f32 {
fn sample_any(rng: &mut Rng) -> Self {
let max = f32::MAX.sqrt();
let min = -max;
rng.f32_range(min..=max)
}
fn sample_uniform(lower: Self, upper: Self, rng: &mut Rng) -> Self {
rng.f32_range(lower..=upper)
}
fn sample_normal(mu: Self, sigma: Self, rng: &mut Rng) -> Self {
rng.f32_normal_approx(mu, sigma)
}
}
impl Sample for f64 {
fn sample_any(rng: &mut Rng) -> Self {
let max = f64::MAX.cbrt();
let min = -max;
rng.f64_range(min..=max)
}
fn sample_uniform(lower: Self, upper: Self, rng: &mut Rng) -> Self {
rng.f64_range(lower..=upper)
}
fn sample_normal(mu: Self, sigma: Self, rng: &mut Rng) -> Self {
rng.f64_normal_approx(mu, sigma)
}
}