// 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::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::WrappingFrom; use malachite_base::num::float::NiceFloat; use malachite_base::num::random::striped::striped_random_signed_inclusive_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_signed_inclusive_range_helper< U: PrimitiveUnsigned + WrappingFrom, S: CheckedToF64 + PrimitiveSigned + WrappingFrom, >( a: S, b: S, m_numerator: u64, m_denominator: u64, expected_values: &[&str], expected_common_values: &[(&str, usize)], expected_sample_median: (S, Option), expected_sample_moment_stats: MomentStats, ) { let xs = striped_random_signed_inclusive_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_signed_inclusive_range() { // i16, 50, 200, m = 4 let values = &[ "110010", "11000000", "10100110", "110111", "111111", "11001000", "1111000", "111111", "110010", "1111111", "111110", "11000001", "111101", "110111", "11001000", "110011", "111111", "11000011", "11000000", "11000000", ]; let common_values = &[ ("11001000", 187162), ("11000000", 79165), ("111111", 78685), ("110010", 70343), ("110011", 70101), ("110111", 26718), ("111100", 26467), ("111110", 26443), ("111000", 26309), ("11000001", 26222), ]; let sample_median = (128, None); let sample_moment_stats = MomentStats { mean: NiceFloat(126.78841600000145), standard_deviation: NiceFloat(62.97286483710745), skewness: NiceFloat(-0.01241704115437865), excess_kurtosis: NiceFloat(-1.7551228249647437), }; striped_random_signed_inclusive_range_helper::( 50, 200, 4, 1, values, common_values, sample_median, sample_moment_stats, ); // i16, -200, -50, m = 4 let values = &[ "1111111111001110", "1111111101000000", "1111111101011010", "1111111111001001", "1111111111000001", "1111111100111000", "1111111110001000", "1111111111000001", "1111111111001110", "1111111110000001", "1111111111000010", "1111111100111111", "1111111111000011", "1111111111001001", "1111111100111000", "1111111111001101", "1111111111000001", "1111111100111101", "1111111101000000", "1111111101000000", ]; let common_values = &[ ("1111111100111000", 187162), ("1111111101000000", 79165), ("1111111111000001", 78685), ("1111111111001110", 70343), ("1111111111001101", 70101), ("1111111111001001", 26718), ("1111111111000100", 26467), ("1111111111000010", 26443), ("1111111111001000", 26309), ("1111111100111111", 26222), ]; let sample_median = (-128, None); let sample_moment_stats = MomentStats { mean: NiceFloat(-126.78841600000145), standard_deviation: NiceFloat(62.97286483710745), skewness: NiceFloat(0.01241704115437865), excess_kurtosis: NiceFloat(-1.7551228249647437), }; striped_random_signed_inclusive_range_helper::( -200, -50, 4, 1, values, common_values, sample_median, sample_moment_stats, ); // i16, -50, 200, m = 4 let values = &[ "1111111111001110", "1111111111001111", "11000111", "11111", "1111111111111111", "11000011", "1000000", "11000001", "1111111", "11000011", "11000100", "1111111111111111", "11001000", "1111111111010010", "1111111111110100", "1111111111011111", "1111111111111111", "1111111111001111", "1111111111111111", "1111111111010000", ]; let common_values = &[ ("1111111111001110", 93920), ("11001000", 93547), ("1111111111111111", 79262), ("1111111111010000", 70793), ("11000000", 39521), ("0", 33351), ("1111111111001111", 23264), ("1111111111111001", 19879), ("1111111111100000", 19842), ("1111111111110001", 19780), ]; let sample_median = (-1, None); let sample_moment_stats = MomentStats { mean: NiceFloat(42.632988000001404), standard_deviation: NiceFloat(91.45288785939469), skewness: NiceFloat(0.7466366203634324), excess_kurtosis: NiceFloat(-1.0394231672402725), }; striped_random_signed_inclusive_range_helper::( -50, 200, 4, 1, values, common_values, sample_median, sample_moment_stats, ); } fn striped_random_signed_inclusive_range_fail_helper< U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >() { assert_panic!(striped_random_signed_inclusive_range::( EXAMPLE_SEED, S::TWO, S::ONE, 5, 1, )); assert_panic!(striped_random_signed_inclusive_range::( EXAMPLE_SEED, S::NEGATIVE_ONE, S::from(-2i8), 5, 1, )); assert_panic!(striped_random_signed_inclusive_range::( EXAMPLE_SEED, S::ONE, S::TWO, 1, 1, )); } #[test] fn striped_random_signed_inclusive_range_fail() { apply_fn_to_unsigned_signed_pairs!(striped_random_signed_inclusive_range_fail_helper); }