hcomplex/algebra/
random.rs1use core::ops::{Div};
2use num_traits::Float;
3use rand::Rng;
4use rand_distr::Distribution;
5use super::*;
6
7
8pub use rand_distr::StandardNormal;
9
10pub struct NonZero;
12
13pub struct Unit;
16
17
18impl<T, U> Distribution<Construct<T, U>> for StandardNormal where StandardNormal: Distribution<U> {
19 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Construct<T, U> {
20 Construct::new(rng.sample(Self), rng.sample(Self))
21 }
22}
23
24impl<T: Float, U: NormSqr<Output=T> + Clone> Distribution<Construct<T, U>> for NonZero where StandardNormal: Distribution<Construct<T, U>> {
25 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Construct<T, U> {
26 loop {
27 let x = rng.sample(&StandardNormal);
28 if x.clone().norm() > T::epsilon() {
29 break x;
30 }
31 }
32 }
33}
34
35impl<T: Float, U: NormSqr<Output=T> + Div<T, Output=U> + Clone> Distribution<Construct<T, U>> for Unit where NonZero: Distribution<Construct<T, U>> {
36 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Construct<T, U> {
37 rng.sample(&NonZero).normalize()
38 }
39}