// 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_bit_chunks; 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_bit_chunks_helper( chunk_size: u64, 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_bit_chunks::( EXAMPLE_SEED, chunk_size, 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_bit_chunks() { // u8, chunk_size = 0, m = 4 let values = &["0"; 20]; let common_values = &[("0", 1000000)]; let sample_median = (0, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.0), standard_deviation: NiceFloat(0.0), skewness: NiceFloat(f64::NAN), excess_kurtosis: NiceFloat(f64::NAN), }; striped_random_unsigned_bit_chunks_helper::( 0, 4, 1, values, common_values, sample_median, sample_moment_stats, ); // u8, chunk_size = 3, 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_bit_chunks_helper::( 3, 4, 1, values, common_values, sample_median, sample_moment_stats, ); // chunk_size = 1, u8, m = 2 let values = &[ "0", "0", "0", "1", "0", "1", "0", "0", "0", "1", "1", "1", "0", "0", "1", "0", "0", "0", "0", "0", ]; let common_values = &[("1", 500454), ("0", 499546)]; let sample_median = (1, None); let sample_moment_stats = MomentStats { mean: NiceFloat(0.500454000000004), standard_deviation: NiceFloat(0.5000000438840368), skewness: NiceFloat(-0.0018160007486136712), excess_kurtosis: NiceFloat(-1.9999967021412284), }; striped_random_unsigned_bit_chunks_helper::( 1, 2, 1, values, common_values, sample_median, sample_moment_stats, ); // chunk_size = 6, u8, m = 5/4 let values = &[ "10100", "10110", "10100", "100110", "10010", "101101", "10101", "10001", "10101", "101001", "101101", "101010", "11011", "1101", "100001", "11110", "111", "101", "10110", "10010", ]; let common_values = &[ ("101010", 164180), ("10101", 164004), ("101011", 41169), ("101101", 41127), ("10010", 41114), ("100101", 40919), ("1010", 40893), ("110101", 40851), ("10110", 40844), ("101001", 40812), ]; let sample_median = (32, None); let sample_moment_stats = MomentStats { mean: NiceFloat(31.51096499999948), standard_deviation: NiceFloat(13.555827954398234), skewness: NiceFloat(-0.0016679039370573313), excess_kurtosis: NiceFloat(-1.0970963271830174), }; striped_random_unsigned_bit_chunks_helper::( 6, 5, 4, values, common_values, sample_median, sample_moment_stats, ); // chunk_size = 45, u64, m = 32 let values = &[ "11111111111", "111111111111111111111", "0", "111111111111111111111111111000000000000000000", "111111111", "111111111111111111111111111111111100000000000", "0", "1111111111111111111111111111111111", "1100000000111111111111111111111111111111", "111111111111111111100000000000000011111111111", "111111111111111111111111111111111111111100000", "111111111111111111111111111111111111111111111", "11111111111111111111111111", "1111111", "111111111111111110000000000000000000000000000", "11111111111111", "0", "11111111111111111111111111111", "11111111111111111111111111111111111111111111", "1000000011111111111111111111111110000000", ]; let common_values = &[ ("0", 123843), ("111111111111111111111111111111111111111111111", 123659), ("111111111111111100000000000000000000000000000", 4110), ("111111110000000000000000000000000000000000000", 4093), ("111111111111111111111111111111111", 4092), ("1111111111111111111111111111111111", 4081), ("11111111111111111111111111111111111111", 4078), ("1111111", 4072), ("111111111111111111111000000000000000000000000", 4057), ("111111111111111111111111111111111111111110000", 4051), ]; let sample_median = (17592186044416, None); let sample_moment_stats = MomentStats { mean: NiceFloat(17607908125347.086), standard_deviation: NiceFloat(16886338134364.322), skewness: NiceFloat(-0.0018748788166730555), excess_kurtosis: NiceFloat(-1.9429442153094645), }; striped_random_unsigned_bit_chunks_helper::( 45, 32, 1, values, common_values, sample_median, sample_moment_stats, ); // chunk_size = 4, u64, m = 2 let values = &[ "11", "110", "11", "1100", "101", "1010", "110", "100", "101", "1101", "1111", "1100", "111", "11", "1101", "100", "1", "10", "0", "0", ]; let common_values = &[ ("1110", 62873), ("1010", 62820), ("1000", 62739), ("100", 62694), ("1001", 62689), ("110", 62619), ("1011", 62601), ("11", 62507), ("1100", 62467), ("101", 62457), ]; let sample_median = (8, None); let sample_moment_stats = MomentStats { mean: NiceFloat(7.5009610000000775), standard_deviation: NiceFloat(4.606733799393635), skewness: NiceFloat(-0.0007329768450960305), excess_kurtosis: NiceFloat(-1.20818908668768), }; striped_random_unsigned_bit_chunks_helper::( 4, 2, 1, values, common_values, sample_median, sample_moment_stats, ); // chunk_size = 10, u64, m = 33/32 let values = &[ "101010101", "101010101", "101011010", "1010101010", "101010101", "1010101010", "101010101", "101010101", "101010001", "1010101001", "1010110101", "1010101010", "101101010", "101101010", "1010101101", "101011010", "101010101", "101010010", "101010101", "101010101", ]; let common_values = &[ ("1010101010", 379066), ("101010101", 378152), ("1010110101", 12071), ("101011010", 12069), ("101001010", 12042), ("1011010101", 11977), ("101010110", 11960), ("1001010101", 11941), ("1010010101", 11934), ("100101010", 11903), ]; let sample_median = (565, None); let sample_moment_stats = MomentStats { mean: NiceFloat(511.639053000003), standard_deviation: NiceFloat(177.48758065877436), skewness: NiceFloat(-0.0017256448985827214), excess_kurtosis: NiceFloat(-1.734924505103183), }; striped_random_unsigned_bit_chunks_helper::( 10, 33, 32, values, common_values, sample_median, sample_moment_stats, ); } fn striped_random_unsigned_bit_chunks_fail_helper() { assert_panic!(striped_random_unsigned_bit_chunks::( EXAMPLE_SEED, 4, 1, 0 )); assert_panic!(striped_random_unsigned_bit_chunks::( EXAMPLE_SEED, 4, 2, 3 )); assert_panic!(striped_random_unsigned_bit_chunks::( EXAMPLE_SEED, 200, 4, 1 )); } #[test] fn striped_random_unsigned_bit_chunks_fail() { apply_fn_to_unsigneds!(striped_random_unsigned_bit_chunks_fail_helper); }