hcomplex/algebra/
random.rs

1use core::ops::{Div};
2use num_traits::Float;
3use rand::Rng;
4use rand_distr::Distribution;
5use super::*;
6
7
8pub use rand_distr::StandardNormal;
9
10/// Distribution that only guarantees to produce an element which norm is greater than epsilon.
11pub struct NonZero;
12
13/// Distribution that provides points uniformly distubuted on the N-dimensional sphere,
14/// where N is the number of dimensions of a specified hypercomplex number.
15pub 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}