use crate::Rational;
use crate::gaussian_rational::GaussianRational;
use crate::rational_polynomial::RationalPolynomial;
use crate::rational_vector::RationalVector;
use malachite_base::max;
use malachite_base::num::basic::integers::PrimitiveInt;
use malachite_base::num::conversion::traits::ExactFrom;
use malachite_base::num::logic::traits::SignificantBits;
use malachite_base::test_util::bench::bucketers::Bucketer;
use malachite_nz::gaussian_integer::GaussianInteger;
use malachite_nz::integer::Integer;
use malachite_nz::natural::Natural;
use std::cmp::max;
pub fn quadruple_2_natural_bit_bucketer<T, U, V>(
var_name: &str,
) -> Bucketer<'_, (T, Natural, U, V)> {
Bucketer {
bucketing_function: &|(_, x, _, _)| usize::exact_from(x.significant_bits()),
bucketing_label: format!("{var_name}.significant_bits()"),
}
}
pub fn gaussian_rational_bit_bucketer(var_name: &str) -> Bucketer<'_, GaussianRational> {
Bucketer {
bucketing_function: &|x| {
usize::exact_from(
x.real
.significant_bits()
.max(x.imaginary.significant_bits()),
)
},
bucketing_label: format!(
"max({var_name}.real.significant_bits(), {var_name}.imaginary.significant_bits())"
),
}
}
pub fn rational_bit_bucketer(var_name: &str) -> Bucketer<'_, Rational> {
Bucketer {
bucketing_function: &|q| usize::exact_from(q.significant_bits()),
bucketing_label: format!("{var_name}.significant_bits()"),
}
}
pub fn pair_2_pair_1_rational_bit_bucketer<T, U>(
var_name: &str,
) -> Bucketer<'_, (T, (Rational, U))> {
Bucketer {
bucketing_function: &|(_, (q, _))| usize::exact_from(q.significant_bits()),
bucketing_label: format!("{var_name}.significant_bits()"),
}
}
pub fn triple_3_pair_1_rational_bit_bucketer<T, U, V>(
var_name: &str,
) -> Bucketer<'_, (T, U, (Rational, V))> {
Bucketer {
bucketing_function: &|(_, _, (q, _))| usize::exact_from(q.significant_bits()),
bucketing_label: format!("{var_name}.significant_bits()"),
}
}
pub fn pair_1_rational_bit_bucketer<T>(var_name: &str) -> Bucketer<'_, (Rational, T)> {
Bucketer {
bucketing_function: &|(q, _)| usize::exact_from(q.significant_bits()),
bucketing_label: format!("{var_name}.significant_bits()"),
}
}
pub fn pair_2_rational_bit_bucketer<T>(var_name: &str) -> Bucketer<'_, (T, Rational)> {
Bucketer {
bucketing_function: &|(_, q)| usize::exact_from(q.significant_bits()),
bucketing_label: format!("{var_name}.significant_bits()"),
}
}
pub fn triple_1_rational_bit_bucketer<T, U>(var_name: &str) -> Bucketer<'_, (Rational, T, U)> {
Bucketer {
bucketing_function: &|(q, _, _)| usize::exact_from(q.significant_bits()),
bucketing_label: format!("{var_name}.significant_bits()"),
}
}
pub fn triple_3_rational_bit_bucketer<T, U>(var_name: &str) -> Bucketer<'_, (T, U, Rational)> {
Bucketer {
bucketing_function: &|(_, _, q)| usize::exact_from(q.significant_bits()),
bucketing_label: format!("{var_name}.significant_bits()"),
}
}
pub fn quadruple_1_rational_bit_bucketer<T, U, V>(
var_name: &str,
) -> Bucketer<'_, (Rational, T, U, V)> {
Bucketer {
bucketing_function: &|(q, _, _, _)| usize::exact_from(q.significant_bits()),
bucketing_label: format!("{var_name}.significant_bits()"),
}
}
pub fn pair_gaussian_rational_gaussian_integer_max_bit_bucketer<'a>(
x_name: &'a str,
y_name: &'a str,
) -> Bucketer<'a, (GaussianRational, GaussianInteger)> {
Bucketer {
bucketing_function: &|(x, y)| {
usize::exact_from(
x.real
.significant_bits()
.max(x.imaginary.significant_bits())
.max(y.real.significant_bits())
.max(y.imaginary.significant_bits()),
)
},
bucketing_label: format!("max({x_name}.significant_bits(), {y_name}.significant_bits())"),
}
}
pub fn pair_gaussian_rational_integer_max_bit_bucketer<'a>(
x_name: &'a str,
y_name: &'a str,
) -> Bucketer<'a, (GaussianRational, Integer)> {
Bucketer {
bucketing_function: &|(x, y)| {
usize::exact_from(
x.real
.significant_bits()
.max(x.imaginary.significant_bits())
.max(y.significant_bits()),
)
},
bucketing_label: format!("max({x_name}.significant_bits(), {y_name}.significant_bits())"),
}
}
pub fn pair_gaussian_rational_natural_max_bit_bucketer<'a>(
x_name: &'a str,
y_name: &'a str,
) -> Bucketer<'a, (GaussianRational, Natural)> {
Bucketer {
bucketing_function: &|(x, y)| {
usize::exact_from(
x.real
.significant_bits()
.max(x.imaginary.significant_bits())
.max(y.significant_bits()),
)
},
bucketing_label: format!("max({x_name}.significant_bits(), {y_name}.significant_bits())"),
}
}
pub fn pair_gaussian_rational_rational_max_bit_bucketer<'a>(
x_name: &'a str,
y_name: &'a str,
) -> Bucketer<'a, (GaussianRational, Rational)> {
Bucketer {
bucketing_function: &|(x, y)| {
usize::exact_from(
x.real
.significant_bits()
.max(x.imaginary.significant_bits())
.max(y.significant_bits()),
)
},
bucketing_label: format!("max({x_name}.significant_bits(), {y_name}.significant_bits())"),
}
}
pub fn pair_1_gaussian_rational_bit_bucketer<T>(
var_name: &str,
) -> Bucketer<'_, (GaussianRational, T)> {
Bucketer {
bucketing_function: &|(x, _)| {
usize::exact_from(
x.real
.significant_bits()
.max(x.imaginary.significant_bits()),
)
},
bucketing_label: format!(
"max({var_name}.real.significant_bits(), {var_name}.imaginary.significant_bits())"
),
}
}
pub fn pair_gaussian_rational_max_bit_bucketer<'a>(
x_name: &'a str,
y_name: &'a str,
) -> Bucketer<'a, (GaussianRational, GaussianRational)> {
fn bits(x: &GaussianRational) -> u64 {
x.real
.significant_bits()
.max(x.imaginary.significant_bits())
}
Bucketer {
bucketing_function: &|(x, y)| usize::exact_from(max(bits(x), bits(y))),
bucketing_label: format!("max({x_name}.significant_bits(), {y_name}.significant_bits())"),
}
}
pub fn pair_rational_max_bit_bucketer<'a>(
x_name: &str,
y_name: &str,
) -> Bucketer<'a, (Rational, Rational)> {
Bucketer {
bucketing_function: &|(x, y)| {
usize::exact_from(max(x.significant_bits(), y.significant_bits()))
},
bucketing_label: format!("max({x_name}.significant_bits(), {y_name}.significant_bits())"),
}
}
pub fn quadruple_rational_max_bit_bucketer<'a>(
x_name: &'a str,
y_name: &'a str,
z_name: &'a str,
w_name: &'a str,
) -> Bucketer<'a, (Rational, Rational, Rational, Rational)> {
Bucketer {
bucketing_function: &|(x, y, z, w)| {
usize::exact_from(max!(
x.significant_bits(),
y.significant_bits(),
z.significant_bits(),
w.significant_bits()
))
},
bucketing_label: format!(
"max({x_name}.significant_bits(), {y_name}.significant_bits(), \
{z_name}.significant_bits(), {w_name}.significant_bits())"
),
}
}
pub fn triple_rational_max_bit_bucketer<'a>(
x_name: &'a str,
y_name: &'a str,
z_name: &'a str,
) -> Bucketer<'a, (Rational, Rational, Rational)> {
Bucketer {
bucketing_function: &|(x, y, z)| {
usize::exact_from(max!(
x.significant_bits(),
y.significant_bits(),
z.significant_bits()
))
},
bucketing_label: format!(
"max({x_name}.significant_bits(), {y_name}.significant_bits(), \
{z_name}.significant_bits())"
),
}
}
pub fn pair_2_pair_rational_max_bit_bucketer<'a, T>(
x_name: &str,
y_name: &str,
) -> Bucketer<'a, (T, (Rational, Rational))> {
Bucketer {
bucketing_function: &|(_, (x, y))| {
usize::exact_from(max(x.significant_bits(), y.significant_bits()))
},
bucketing_label: format!("max({x_name}.significant_bits(), {y_name}.significant_bits())"),
}
}
pub fn triple_3_pair_rational_max_bit_bucketer<'a, T, U>(
x_name: &str,
y_name: &str,
) -> Bucketer<'a, (T, U, (Rational, Rational))> {
Bucketer {
bucketing_function: &|(_, _, (x, y))| {
usize::exact_from(max(x.significant_bits(), y.significant_bits()))
},
bucketing_label: format!("max({x_name}.significant_bits(), {y_name}.significant_bits())"),
}
}
pub fn pair_2_rational_integer_max_bit_bucketer<'a, T>(
x_name: &str,
y_name: &str,
) -> Bucketer<'a, (T, (Rational, Integer))> {
Bucketer {
bucketing_function: &|(_, (x, y))| {
usize::exact_from(max(x.significant_bits(), y.significant_bits()))
},
bucketing_label: format!("max({x_name}.significant_bits(), {y_name}.significant_bits())"),
}
}
pub fn rational_natural_max_bit_bucketer<'a>(
x_name: &str,
y_name: &str,
) -> Bucketer<'a, (Rational, Natural)> {
Bucketer {
bucketing_function: &|(x, y)| {
usize::exact_from(max(x.significant_bits(), y.significant_bits()))
},
bucketing_label: format!("max({x_name}.significant_bits(), {y_name}.significant_bits())"),
}
}
pub fn rational_integer_max_bit_bucketer<'a>(
x_name: &str,
y_name: &str,
) -> Bucketer<'a, (Rational, Integer)> {
Bucketer {
bucketing_function: &|(x, y)| {
usize::exact_from(max(x.significant_bits(), y.significant_bits()))
},
bucketing_label: format!("max({x_name}.significant_bits(), {y_name}.significant_bits())"),
}
}
pub fn pair_2_rational_natural_max_bit_bucketer<'a, T>(
x_name: &str,
y_name: &str,
) -> Bucketer<'a, (T, (Rational, Natural))> {
Bucketer {
bucketing_function: &|(_, (x, y))| {
usize::exact_from(max(x.significant_bits(), y.significant_bits()))
},
bucketing_label: format!("max({x_name}.significant_bits(), {y_name}.significant_bits())"),
}
}
pub fn rational_deserialize_bucketer<'a>() -> Bucketer<'a, (String, String, String)> {
Bucketer {
bucketing_function: &|(_, _, s)| {
let n: Rational = serde_json::from_str(s).unwrap();
usize::exact_from(n.significant_bits())
},
bucketing_label: "n.significant_bits()".to_string(),
}
}
pub fn triple_3_pair_1_rational_bits_times_pair_2_bucketer<'a, T, U>(
x_name: &'a str,
y_name: &'a str,
) -> Bucketer<'a, (T, U, (Rational, u64))> {
Bucketer {
bucketing_function: &|&(_, _, (ref x, y))| usize::exact_from(x.significant_bits() * y),
bucketing_label: format!("{x_name}.significant_bits() * {y_name}"),
}
}
pub fn triple_3_pair_1_rational_bits_times_abs_pair_2_bucketer<'a, T, U>(
x_name: &'a str,
y_name: &'a str,
) -> Bucketer<'a, (T, U, (Rational, i64))> {
Bucketer {
bucketing_function: &|&(_, _, (ref x, y))| {
usize::exact_from(x.significant_bits() * y.unsigned_abs())
},
bucketing_label: format!("{x_name}.significant_bits() * {y_name}"),
}
}
pub fn triple_1_2_rational_bit_i64_max_bucketer<'a, T>(
x_name: &'a str,
y_name: &'a str,
) -> Bucketer<'a, (Rational, i64, T)> {
Bucketer {
bucketing_function: &|(x, y, _)| {
usize::exact_from(max(x.significant_bits(), y.unsigned_abs()))
},
bucketing_label: format!("max({x_name}.significant_bits(), {y_name})"),
}
}
pub fn vec_gaussian_rational_sum_bits_bucketer<'a>() -> Bucketer<'a, Vec<GaussianRational>> {
Bucketer {
bucketing_function: &|xs| {
usize::exact_from(
xs.iter()
.map(|x| x.real.significant_bits() + x.imaginary.significant_bits())
.sum::<u64>(),
)
},
bucketing_label:
"xs.map(|x| x.real.significant_bits() + x.imaginary.significant_bits()).sum()"
.to_string(),
}
}
pub fn vec_rational_sum_bits_bucketer<'a>() -> Bucketer<'a, Vec<Rational>> {
Bucketer {
bucketing_function: &|xs| {
usize::exact_from(
xs.iter()
.map(SignificantBits::significant_bits)
.sum::<u64>(),
)
},
bucketing_label: "xs.map(|x| x.significant_bits()).sum()".to_string(),
}
}
pub fn triple_3_vec_rational_sum_bits_bucketer<'a, T, U>() -> Bucketer<'a, (T, U, Vec<Rational>)> {
Bucketer {
bucketing_function: &|(_, _, xs)| {
usize::exact_from(
xs.iter()
.map(SignificantBits::significant_bits)
.sum::<u64>(),
)
},
bucketing_label: "xs.map(|x| x.significant_bits()).sum()".to_string(),
}
}
pub fn pair_rational_bit_i64_max_bucketer<'a>(
x_name: &'a str,
y_name: &'a str,
) -> Bucketer<'a, (Rational, i64)> {
Bucketer {
bucketing_function: &|(x, y)| {
usize::exact_from(max(x.significant_bits(), y.unsigned_abs()))
},
bucketing_label: format!("max({x_name}.significant_bits(), {y_name}.unsigned_abs())"),
}
}
pub fn pair_rational_bit_u64_max_bucketer<'a>(
x_name: &'a str,
y_name: &'a str,
) -> Bucketer<'a, (Rational, u64)> {
Bucketer {
bucketing_function: &|(x, y)| usize::exact_from(max(x.significant_bits(), *y)),
bucketing_label: format!("max({x_name}.significant_bits(), {y_name}.unsigned_abs())"),
}
}
pub fn triple_1_2_rational_bit_u64_max_bucketer<'a, T>(
x_name: &'a str,
y_name: &'a str,
) -> Bucketer<'a, (Rational, u64, T)> {
Bucketer {
bucketing_function: &|(x, y, _)| usize::exact_from(max(x.significant_bits(), *y)),
bucketing_label: format!("max({x_name}.significant_bits(), {y_name})"),
}
}
pub fn triple_rational_bit_i64_u64_max_bucketer<'a>(
x_name: &'a str,
y_name: &'a str,
z_name: &'a str,
) -> Bucketer<'a, (Rational, i64, u64)> {
Bucketer {
bucketing_function: &|(x, y, z)| {
usize::exact_from(max!(x.significant_bits(), y.unsigned_abs(), *z))
},
bucketing_label: format!(
"max({x_name}.significant_bits(), {y_name}.unsigned_abs(), {z_name})"
),
}
}
pub fn quadruple_1_2_3_rational_bit_i64_u64_max_bucketer<'a, T>(
x_name: &'a str,
y_name: &'a str,
z_name: &'a str,
) -> Bucketer<'a, (Rational, i64, u64, T)> {
Bucketer {
bucketing_function: &|(x, y, z, _)| {
usize::exact_from(max!(x.significant_bits(), y.unsigned_abs(), *z))
},
bucketing_label: format!(
"max({x_name}.significant_bits(), {y_name}.unsigned_abs(), {z_name})"
),
}
}
pub fn quadruple_1_2_3_rational_bit_u64_u64_max_bucketer<'a, T>(
x_name: &'a str,
y_name: &'a str,
z_name: &'a str,
) -> Bucketer<'a, (Rational, u64, u64, T)> {
Bucketer {
bucketing_function: &|(x, y, z, _)| usize::exact_from(max!(x.significant_bits(), *y, *z)),
bucketing_label: format!("max({x_name}.significant_bits(), {y_name}, {z_name})"),
}
}
pub fn triple_rational_rational_primitive_int_max_bit_bucketer<'a, T: PrimitiveInt>(
x_name: &'a str,
y_name: &'a str,
z_name: &'a str,
) -> Bucketer<'a, (Rational, Rational, T)> {
Bucketer {
bucketing_function: &|(x, y, z)| {
usize::exact_from(max!(
x.significant_bits(),
y.significant_bits(),
z.significant_bits()
))
},
bucketing_label: format!(
"max({x_name}.significant_bits(), {y_name}.significant_bits(), \
{z_name}.significant_bits())"
),
}
}
pub fn quadruple_1_2_3_rational_max_bit_bucketer<'a, T>(
x_name: &'a str,
y_name: &'a str,
z_name: &'a str,
) -> Bucketer<'a, (Rational, Rational, Rational, T)> {
Bucketer {
bucketing_function: &|(x, y, z, _)| {
usize::exact_from(max!(
x.significant_bits(),
y.significant_bits(),
z.significant_bits()
))
},
bucketing_label: format!(
"max({x_name}.significant_bits(), {y_name}.significant_bits(), \
{z_name}.significant_bits())"
),
}
}
pub fn quadruple_1_2_3_rational_rational_primitive_int_max_bit_bucketer<'a, T: PrimitiveInt, U>(
x_name: &'a str,
y_name: &'a str,
z_name: &'a str,
) -> Bucketer<'a, (Rational, Rational, T, U)> {
Bucketer {
bucketing_function: &|(x, y, z, _)| {
usize::exact_from(max!(
x.significant_bits(),
y.significant_bits(),
z.significant_bits()
))
},
bucketing_label: format!(
"max({x_name}.significant_bits(), {y_name}.significant_bits(), \
{z_name}.significant_bits())"
),
}
}
pub fn pair_rational_polynomial_max_bit_bucketer<'a>(
x_name: &'a str,
y_name: &'a str,
) -> Bucketer<'a, (RationalPolynomial, RationalPolynomial)> {
Bucketer {
bucketing_function: &|(p, q)| {
usize::exact_from(max(
p.numerator_ref()
.coefficients_asc()
.iter()
.map(SignificantBits::significant_bits)
.sum::<u64>()
+ p.denominator_ref().significant_bits(),
q.numerator_ref()
.coefficients_asc()
.iter()
.map(SignificantBits::significant_bits)
.sum::<u64>()
+ q.denominator_ref().significant_bits(),
))
},
bucketing_label: format!("max({x_name}'s total bits, {y_name}'s total bits)"),
}
}
pub fn triple_1_2_rational_polynomial_max_bit_bucketer<'a, T>(
x_name: &'a str,
y_name: &'a str,
) -> Bucketer<'a, (RationalPolynomial, RationalPolynomial, T)> {
Bucketer {
bucketing_function: &|(p, q, _)| {
usize::exact_from(max(
p.numerator_ref()
.coefficients_asc()
.iter()
.map(SignificantBits::significant_bits)
.sum::<u64>()
+ p.denominator_ref().significant_bits(),
q.numerator_ref()
.coefficients_asc()
.iter()
.map(SignificantBits::significant_bits)
.sum::<u64>()
+ q.denominator_ref().significant_bits(),
))
},
bucketing_label: format!("max({x_name}'s total bits, {y_name}'s total bits)"),
}
}
pub fn rational_vector_bit_bucketer(var_name: &str) -> Bucketer<'_, RationalVector> {
Bucketer {
bucketing_function: &|v| {
usize::exact_from(
v.elements
.iter()
.map(SignificantBits::significant_bits)
.sum::<u64>(),
)
},
bucketing_label: format!("{var_name}'s total element bits"),
}
}
pub fn pair_rational_vector_max_bit_bucketer<'a>(
x_name: &'a str,
y_name: &'a str,
) -> Bucketer<'a, (RationalVector, RationalVector)> {
Bucketer {
bucketing_function: &|(v, w)| {
usize::exact_from(max(
v.elements
.iter()
.map(SignificantBits::significant_bits)
.sum::<u64>(),
w.elements
.iter()
.map(SignificantBits::significant_bits)
.sum::<u64>(),
))
},
bucketing_label: format!(
"max({x_name}'s total element bits, {y_name}'s total element bits)"
),
}
}
pub fn pair_1_rational_vector_bit_bucketer<T>(var_name: &str) -> Bucketer<'_, (RationalVector, T)> {
Bucketer {
bucketing_function: &|(v, _)| {
usize::exact_from(
v.elements
.iter()
.map(SignificantBits::significant_bits)
.sum::<u64>(),
)
},
bucketing_label: format!("{var_name}'s total element bits"),
}
}
pub fn triple_1_rational_vector_bit_bucketer<T, U>(
var_name: &str,
) -> Bucketer<'_, (RationalVector, T, U)> {
Bucketer {
bucketing_function: &|(v, _, _)| {
usize::exact_from(
v.elements
.iter()
.map(SignificantBits::significant_bits)
.sum::<u64>(),
)
},
bucketing_label: format!("{var_name}'s total element bits"),
}
}
pub fn quadruple_1_rational_vector_bit_bucketer<T, U, V>(
var_name: &str,
) -> Bucketer<'_, (RationalVector, T, U, V)> {
Bucketer {
bucketing_function: &|(v, _, _, _)| {
usize::exact_from(
v.elements
.iter()
.map(SignificantBits::significant_bits)
.sum::<u64>(),
)
},
bucketing_label: format!("{var_name}'s total element bits"),
}
}
pub fn rational_polynomial_bit_bucketer(var_name: &str) -> Bucketer<'_, RationalPolynomial> {
Bucketer {
bucketing_function: &|p| {
usize::exact_from(
p.numerator_ref()
.coefficients_asc()
.iter()
.map(SignificantBits::significant_bits)
.sum::<u64>()
+ p.denominator_ref().significant_bits(),
)
},
bucketing_label: format!("{var_name}'s total stored bits"),
}
}
pub fn pair_1_rational_polynomial_bit_bucketer<T>(
var_name: &str,
) -> Bucketer<'_, (RationalPolynomial, T)> {
Bucketer {
bucketing_function: &|(p, _)| {
usize::exact_from(
p.numerator_ref()
.coefficients_asc()
.iter()
.map(SignificantBits::significant_bits)
.sum::<u64>()
+ p.denominator_ref().significant_bits(),
)
},
bucketing_label: format!("{var_name}'s total stored bits"),
}
}
pub fn triple_1_rational_polynomial_bit_bucketer<T, U>(
var_name: &str,
) -> Bucketer<'_, (RationalPolynomial, T, U)> {
Bucketer {
bucketing_function: &|(p, _, _)| {
usize::exact_from(
p.numerator_ref()
.coefficients_asc()
.iter()
.map(SignificantBits::significant_bits)
.sum::<u64>()
+ p.denominator_ref().significant_bits(),
)
},
bucketing_label: format!("{var_name}'s total stored bits"),
}
}