use crate::itertools::Itertools;
use crate::{ComparableFloat, ComparableFloatRef, Float};
use malachite_base::num::conversion::traits::RoundingFrom;
use malachite_base::rounding_modes::RoundingMode::*;
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::{MomentStats, moment_stats};
pub fn random_floats_helper_helper<I: Clone + Iterator<Item = Float>>(
xs: I,
expected_values: &[&str],
expected_values_hex: &[&str],
expected_common_values: &[(&str, usize)],
expected_common_values_hex: &[(&str, usize)],
expected_sample_median: (&str, Option<&str>),
expected_sample_median_hex: (&str, Option<&str>),
expected_sample_moment_stats: MomentStats,
) {
let comparable_xs = xs.clone().map(ComparableFloat);
let raw_actual_values = xs.clone().take(20).collect_vec();
let actual_values = raw_actual_values
.iter()
.map(Float::to_string)
.take(20)
.collect_vec();
let actual_values_hex = raw_actual_values
.iter()
.map(|x| format!("{:#x}", ComparableFloatRef(x)))
.take(20)
.collect_vec();
let actual_values = actual_values.iter().map(String::as_str).collect_vec();
let actual_values_hex = actual_values_hex.iter().map(String::as_str).collect_vec();
for x in xs.clone().take(1000000) {
assert!(x.is_valid());
}
let raw_common_values = common_values_map(1000000, 10, comparable_xs.clone())
.into_iter()
.collect_vec();
let actual_common_values = raw_common_values
.iter()
.map(|(x, freq)| (x.0.to_string(), *freq))
.collect_vec();
let actual_common_values = actual_common_values
.iter()
.map(|(x, freq)| (x.as_str(), *freq))
.collect_vec();
let actual_common_values_hex = raw_common_values
.iter()
.map(|(x, freq)| (format!("{x:#x}"), *freq))
.collect_vec();
let actual_common_values_hex = actual_common_values_hex
.iter()
.map(|(x, freq)| (x.as_str(), *freq))
.collect_vec();
let (median_lo, median_hi) = median(comparable_xs.take(1000000));
let (median_lo_hex, median_hi_hex) = (
format!("{median_lo:#x}"),
median_hi.as_ref().map(|x| format!("{x:#x}")),
);
let (median_lo, median_hi) = (
median_lo.0.to_string(),
median_hi.map(|x| Float::to_string(&x.0)),
);
let actual_sample_median = (median_lo.as_str(), median_hi.as_deref());
let actual_sample_median_hex = (median_lo_hex.as_str(), median_hi_hex.as_deref());
let actual_sample_moment_stats =
moment_stats(xs.take(1000000).map(|x| f64::rounding_from(&x, Nearest).0));
assert_eq!(
(
actual_values.as_slice(),
actual_values_hex.as_slice(),
actual_common_values.as_slice(),
actual_common_values_hex.as_slice(),
actual_sample_median,
actual_sample_median_hex,
actual_sample_moment_stats
),
(
expected_values,
expected_values_hex,
expected_common_values,
expected_common_values_hex,
expected_sample_median,
expected_sample_median_hex,
expected_sample_moment_stats
)
);
}
pub fn random_floats_helper_helper_no_common_values<I: Clone + Iterator<Item = Float>>(
xs: I,
expected_values: &[&str],
expected_values_hex: &[&str],
expected_sample_median: (&str, Option<&str>),
expected_sample_median_hex: (&str, Option<&str>),
expected_sample_moment_stats: MomentStats,
) {
let comparable_xs = xs.clone().map(ComparableFloat);
let raw_actual_values = xs.clone().take(20).collect_vec();
let actual_values = raw_actual_values
.iter()
.map(Float::to_string)
.take(20)
.collect_vec();
let actual_values_hex = raw_actual_values
.iter()
.map(|x| format!("{:#x}", ComparableFloatRef(x)))
.take(20)
.collect_vec();
let actual_values = actual_values.iter().map(String::as_str).collect_vec();
let actual_values_hex = actual_values_hex.iter().map(String::as_str).collect_vec();
for x in xs.clone().take(1000000) {
assert!(x.is_valid());
}
let (median_lo, median_hi) = median(comparable_xs.take(1000000));
let (median_lo_hex, median_hi_hex) = (
format!("{median_lo:#x}"),
median_hi.as_ref().map(|x| format!("{x:#x}")),
);
let (median_lo, median_hi) = (
median_lo.0.to_string(),
median_hi.map(|x| Float::to_string(&x.0)),
);
let actual_sample_median = (median_lo.as_str(), median_hi.as_deref());
let actual_sample_median_hex = (median_lo_hex.as_str(), median_hi_hex.as_deref());
let actual_sample_moment_stats =
moment_stats(xs.take(1000000).map(|x| f64::rounding_from(&x, Nearest).0));
assert_eq!(
(
actual_values.as_slice(),
actual_values_hex.as_slice(),
actual_sample_median,
actual_sample_median_hex,
actual_sample_moment_stats
),
(
expected_values,
expected_values_hex,
expected_sample_median,
expected_sample_median_hex,
expected_sample_moment_stats
)
);
}