use crate::rational_polynomial::RationalPolynomial;
use core::cmp::Ordering::{self, *};
use core::cmp::max;
use malachite_base::num::arithmetic::traits::Sign;
use malachite_base::num::basic::traits::{One, Zero};
use malachite_nz::integer::Integer;
use std::vec::Vec;
pub fn rational_polynomial_cmp_naive(p: &RationalPolynomial, q: &RationalPolynomial) -> Ordering {
let ps = p.to_coefficients_asc();
let qs = q.to_coefficients_asc();
match ps.len().cmp(&qs.len()) {
Equal => ps.iter().rev().cmp(qs.iter().rev()),
Greater => ps.last().unwrap().sign(),
Less => qs.last().unwrap().sign().reverse(),
}
}
pub fn rational_polynomial_shortlex_cmp_naive(
p: &RationalPolynomial,
q: &RationalPolynomial,
) -> Ordering {
let ps = p.to_coefficients_asc();
let qs = q.to_coefficients_asc();
match ps.len().cmp(&qs.len()) {
Equal => ps.iter().rev().cmp(qs.iter().rev()),
c => c,
}
}
pub fn rational_polynomial_difference_numerator(
p: &RationalPolynomial,
q: &RationalPolynomial,
) -> Vec<Integer> {
let a = Integer::from(p.denominator_ref());
let b = Integer::from(q.denominator_ref());
let ps = p.numerator_ref().coefficients_asc();
let qs = q.numerator_ref().coefficients_asc();
let mut ds = Vec::new();
for i in 0..max(ps.len(), qs.len()) {
let x = ps.get(i).map_or_else(|| Integer::ZERO, Clone::clone);
let y = qs.get(i).map_or_else(|| Integer::ZERO, Clone::clone);
ds.push(&b * x - &a * y);
}
while ds.last() == Some(&Integer::ZERO) {
ds.pop();
}
ds
}
pub fn rational_polynomial_cmp_evaluated(
p: &RationalPolynomial,
q: &RationalPolynomial,
) -> Ordering {
let ds = rational_polynomial_difference_numerator(p, q);
if ds.is_empty() {
return Equal;
}
let bound = Integer::ONE
+ ds.iter()
.map(|d| Integer::from(d.unsigned_abs_ref()))
.max()
.unwrap();
let mut sum = Integer::ZERO;
for d in ds.iter().rev() {
sum *= &bound;
sum += d;
}
sum.sign()
}