Files
wifi-densepose/vendor/ruvector/crates/thermorust/src/noise.rs

49 lines
1.6 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! Thermal noise sources: Gaussian (Langevin) and Poisson spike noise.
use rand::Rng;
use rand_distr::{Distribution, Normal, Poisson};
/// Draw a Gaussian noise sample with standard deviation σ = √(2/β).
///
/// This matches the fluctuation-dissipation theorem for overdamped Langevin:
/// the noise amplitude must be √(2kT) = √(2/β) in dimensionless units.
#[inline]
pub fn langevin_noise(beta: f32, rng: &mut impl Rng) -> f32 {
if beta <= 0.0 || !beta.is_finite() {
return 0.0;
}
let sigma = (2.0 / beta).sqrt();
Normal::new(0.0_f32, sigma)
.unwrap_or_else(|_| Normal::new(0.0_f32, 1e-6).unwrap())
.sample(rng)
}
/// Draw `n` independent Langevin noise samples.
pub fn langevin_noise_vec(beta: f32, n: usize, rng: &mut impl Rng) -> Vec<f32> {
if beta <= 0.0 || !beta.is_finite() {
return vec![0.0; n];
}
let sigma = (2.0 / beta).sqrt();
let dist = Normal::new(0.0_f32, sigma).unwrap_or_else(|_| Normal::new(0.0_f32, 1e-6).unwrap());
(0..n).map(|_| dist.sample(rng)).collect()
}
/// Poisson spike noise: add a random kick of magnitude `kick` with rate λ.
///
/// Returns the kick to add to a single activation (0.0 if no spike this step).
#[inline]
pub fn poisson_spike(rate: f64, kick: f32, rng: &mut impl Rng) -> f32 {
if rate <= 0.0 || !rate.is_finite() {
return 0.0;
}
let dist = Poisson::new(rate).unwrap_or_else(|_| Poisson::new(1e-6).unwrap());
let count = dist.sample(rng) as u64;
if count > 0 {
// Random sign
let sign = if rng.gen::<bool>() { 1.0 } else { -1.0 };
sign * kick * count as f32
} else {
0.0
}
}