use crate::rational_polynomial::RationalPolynomial;
use malachite_base::num::arithmetic::traits::{DivExact, Gcd};
use malachite_base::num::basic::unsigneds::PrimitiveUnsigned;
use malachite_base::polynomial::{EqTruncated, slices_eq_truncated};
use malachite_base::unsigned_polynomial::UnsignedPolynomial;
use malachite_nz::integer::Integer;
use malachite_nz::integer_polynomial::IntegerPolynomial;
use malachite_nz::natural::Natural;
use malachite_nz::natural_polynomial::NaturalPolynomial;
fn integer_is_zero(x: &Integer) -> bool {
*x == 0u32
}
fn natural_is_zero(x: &Natural) -> bool {
*x == 0u32
}
fn natural_to_integer(x: &Natural) -> Integer {
Integer::from(x)
}
#[cfg_attr(dylint_lib = "malachite_lints", allow(use_cmp_product))]
fn eq_scaled(x: &Integer, y: Integer, d: &Integer) -> bool {
*x == y * d
}
impl EqTruncated for RationalPolynomial {
#[cfg_attr(dylint_lib = "malachite_lints", allow(use_cmp_product))]
fn eq_truncated(&self, other: &Self, len: u64) -> bool {
let xs = self.numerator.coefficients_asc();
let ys = other.numerator.coefficients_asc();
if self.denominator == other.denominator {
return slices_eq_truncated(xs, ys, len, integer_is_zero, integer_is_zero, |x, y| {
x == y
});
}
let gcd = (&self.denominator).gcd(&other.denominator);
let x_factor = Integer::from((&other.denominator).div_exact(&gcd));
let y_factor = Integer::from((&self.denominator).div_exact(&gcd));
slices_eq_truncated(xs, ys, len, integer_is_zero, integer_is_zero, |x, y| {
x * &x_factor == y * &y_factor
})
}
}
impl<T: PrimitiveUnsigned> EqTruncated<UnsignedPolynomial<T>> for RationalPolynomial
where
Integer: From<T> + PartialEq<T>,
{
fn eq_truncated(&self, other: &UnsignedPolynomial<T>, len: u64) -> bool {
let xs = self.numerator.coefficients_asc();
let ys = other.coefficients_asc();
if self.denominator == 1u32 {
return slices_eq_truncated(
xs,
ys,
len,
integer_is_zero,
|&y| y == T::ZERO,
|x, y| x == y,
);
}
let d = natural_to_integer(&self.denominator);
slices_eq_truncated(
xs,
ys,
len,
integer_is_zero,
|&y| y == T::ZERO,
|x, &y| eq_scaled(x, Integer::from(y), &d),
)
}
}
impl<T: PrimitiveUnsigned> EqTruncated<RationalPolynomial> for UnsignedPolynomial<T>
where
Integer: From<T> + PartialEq<T>,
{
#[inline]
fn eq_truncated(&self, other: &RationalPolynomial, len: u64) -> bool {
other.eq_truncated(self, len)
}
}
impl EqTruncated<NaturalPolynomial> for RationalPolynomial {
fn eq_truncated(&self, other: &NaturalPolynomial, len: u64) -> bool {
let xs = self.numerator.coefficients_asc();
let ys = other.coefficients_asc();
if self.denominator == 1u32 {
return slices_eq_truncated(xs, ys, len, integer_is_zero, natural_is_zero, |x, y| {
x == y
});
}
slices_eq_truncated(xs, ys, len, integer_is_zero, natural_is_zero, |x, y| {
*x == y * &self.denominator
})
}
}
impl EqTruncated<RationalPolynomial> for NaturalPolynomial {
#[inline]
fn eq_truncated(&self, other: &RationalPolynomial, len: u64) -> bool {
other.eq_truncated(self, len)
}
}
impl EqTruncated<IntegerPolynomial> for RationalPolynomial {
#[cfg_attr(dylint_lib = "malachite_lints", allow(use_cmp_product))]
fn eq_truncated(&self, other: &IntegerPolynomial, len: u64) -> bool {
let xs = self.numerator.coefficients_asc();
let ys = other.coefficients_asc();
if self.denominator == 1u32 {
return slices_eq_truncated(xs, ys, len, integer_is_zero, integer_is_zero, |x, y| {
x == y
});
}
let d = Integer::from(&self.denominator);
slices_eq_truncated(xs, ys, len, integer_is_zero, integer_is_zero, |x, y| {
*x == y * &d
})
}
}
impl EqTruncated<RationalPolynomial> for IntegerPolynomial {
#[inline]
fn eq_truncated(&self, other: &RationalPolynomial, len: u64) -> bool {
other.eq_truncated(self, len)
}
}