use crate::crypto::UnsignedTorus;
use crate::math::dispersion::LogStandardDev;
use crate::math::random::fill_with_random_gaussian;
use crate::math::tensor::Tensor;
use crate::test_tools::assert_noise_distribution;
fn test_normal_random<T: UnsignedTorus>() {
let std_dev: f64 = f64::powi(2., -20);
let mean: f64 = 0.;
let k = 1_000_000;
let mut samples_int = Tensor::allocate(T::ZERO, k);
fill_with_random_gaussian(&mut samples_int, mean, std_dev);
let mut samples_float = Tensor::allocate(0f64, k);
samples_float.fill_with_one(&samples_int, |a| a.into_torus());
for x in samples_float.iter_mut() {
if *x > 0.5 {
*x = 1. - *x;
}
}
let mut number_of_samples_outside_confidence_interval: usize = 0;
for s in samples_float.iter() {
if *s > 3. * std_dev || *s < -3. * std_dev {
number_of_samples_outside_confidence_interval += 1;
}
}
let proportion_of_samples_outside_confidence_interval: f64 =
(number_of_samples_outside_confidence_interval as f64) / (k as f64);
assert!(
proportion_of_samples_outside_confidence_interval < 0.003,
"test normal random : proportion = {} ; n = {}",
proportion_of_samples_outside_confidence_interval,
number_of_samples_outside_confidence_interval
);
}
#[test]
fn test_normal_random_u32() {
test_normal_random::<u32>();
}
#[test]
fn test_normal_random_u64() {
test_normal_random::<u64>();
}
fn test_distribution<T: UnsignedTorus>() {
let std_dev: f64 = f64::powi(2., -5);
let mean: f64 = 0.;
let k = 1_000_000;
let first = Tensor::allocate(T::ZERO, k);
let mut second = Tensor::allocate(T::ZERO, k);
fill_with_random_gaussian(&mut second, mean, std_dev);
assert_noise_distribution(&first, &second, LogStandardDev(-5.));
}
#[test]
fn test_distribution_u32() {
test_distribution::<u32>();
}
#[test]
fn test_distribution_u64() {
test_distribution::<u64>();
}