// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::striped::striped_random_unsigned_range; use malachite_base::random::EXAMPLE_SEED; use malachite_base::strings::ToBinaryString; use malachite_base::test_util::stats::common_values_map::common_values_map; use malachite_base::test_util::stats::median; use malachite_base::test_util::stats::moments::{moment_stats, CheckedToF64, MomentStats}; use std::panic::catch_unwind; fn striped_random_unsigned_range_helper( a: T, b: T, m_numerator: u64, m_denominator: u64, expected_values: &[&str], expected_common_values: &[(&str, usize)], expected_sample_median: (T, Option), expected_sample_moment_stats: MomentStats, ) { let xs = striped_random_unsigned_range::(EXAMPLE_SEED, a, b, m_numerator, m_denominator); let actual_values = xs .clone() .map(|x| x.to_binary_string()) .take(20) .collect_vec(); let actual_common_values = common_values_map(1000000, 10, xs.clone()) .iter() .map(|(x, frequency)| (x.to_binary_string(), *frequency)) .collect_vec(); let actual_sample_median = median(xs.clone().take(1000000)); let actual_sample_moment_stats = moment_stats(xs.take(1000000)); assert_eq!( ( actual_values, actual_common_values, actual_sample_median, actual_sample_moment_stats ), ( expected_values .iter() .map(ToString::to_string) .collect_vec(), expected_common_values .iter() .map(|(x, frequency)| (x.to_string(), *frequency)) .collect_vec(), expected_sample_median, expected_sample_moment_stats ) ); } #[test] fn test_striped_random_unsigned_range() { // u8, 5, 6, m = 4 let values = &["101"; 20]; let common_values = &[("101", 1000000)]; let sample_median = (5, None); let sample_moment_stats = MomentStats { mean: NiceFloat(5.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; striped_random_unsigned_range_helper::( 5, 6, 4, 1, values, common_values, sample_median, sample_moment_stats, ); // u8, 0, 8, m = 4 let values = &[ "0", "0", "0", "101", "11", "100", "11", "11", "0", "111", "111", "100", "0", "11", "111", "0", "0", "1", "0", "0", ]; let common_values = &[ ("111", 281415), ("0", 280832), ("110", 94370), ("11", 93804), ("100", 93374), ("1", 93351), ("10", 31559), ("101", 31295), ]; let sample_median = (4, None); let sample_moment_stats = MomentStats { mean: NiceFloat(3.5039770000000354), standard_deviation: NiceFloat(2.8721055747415143), skewness: NiceFloat(-0.0024668908296986798), excess_kurtosis: NiceFloat(-1.6474519863189017), }; striped_random_unsigned_range_helper::( 0, 8, 4, 1, values, common_values, sample_median, sample_moment_stats, ); // u8, 1, 7, m = 4 let values = &[ "1", "1", "1", "110", "1", "110", "10", "11", "11", "100", "100", "110", "1", "1", "110", "1", "1", "11", "1", "1", ]; let common_values = &[ ("110", 375034), ("1", 374765), ("100", 93832), ("11", 93634), ("101", 31588), ("10", 31147), ]; let sample_median = (4, None); let sample_moment_stats = MomentStats { mean: NiceFloat(3.5014329999999694), standard_deviation: NiceFloat(2.207774177939804), skewness: NiceFloat(-0.0014160236801414635), excess_kurtosis: NiceFloat(-1.753353488243057), }; striped_random_unsigned_range_helper::( 1, 7, 4, 1, values, common_values, sample_median, sample_moment_stats, ); // u16, 10000, 20001, m = 4 let values = &[ "10011100011111", "11010011001111", "10011100011100", "100111000011111", "11111100000000", "10011100111100", "10011110110000", "100000000000111", "11111111111111", "10101111001111", "100111000000000", "11000000000111", "11111111000000", "100000000001111", "100000000101100", "100011110000000", "100100011110010", "100011000000111", "100110111111111", "11111111110100", ]; let common_values = &[ ("100111000100000", 70337), ("100111000000000", 16785), ("10011111111111", 12552), ("10011100010000", 11029), ("10011100011111", 11017), ("100000000000000", 10528), ("11111111111111", 8012), ("100111000000111", 5466), ("100111000000001", 5462), ("100111000001111", 5448), ]; let sample_median = (16383, None); let sample_moment_stats = MomentStats { mean: NiceFloat(15546.241523000184), standard_deviation: NiceFloat(3460.441923849274), skewness: NiceFloat(-0.39481033379336405), excess_kurtosis: NiceFloat(-1.1600583805474893), }; striped_random_unsigned_range_helper::( 10000, 20001, 4, 1, values, common_values, sample_median, sample_moment_stats, ); } fn striped_random_unsigned_range_fail_helper() { assert_panic!(striped_random_unsigned_range::( EXAMPLE_SEED, T::TWO, T::TWO, 5, 1, )); assert_panic!(striped_random_unsigned_range::( EXAMPLE_SEED, T::ONE, T::TWO, 1, 1, )); } #[test] fn striped_random_unsigned_range_fail() { apply_fn_to_unsigneds!(striped_random_unsigned_range_fail_helper); }