use super::MatPolyOverZ;
use crate::{
integer::{MatZ, Z},
traits::{Evaluate, MatrixDimensions},
};
use flint_sys::fmpz_poly_mat::fmpz_poly_mat_evaluate_fmpz;
impl<Integer: Into<Z>> Evaluate<Integer, MatZ> for MatPolyOverZ {
fn evaluate(&self, value: Integer) -> MatZ {
let value = value.into();
let mut res = MatZ::new(self.get_num_rows(), self.get_num_columns());
unsafe { fmpz_poly_mat_evaluate_fmpz(&mut res.matrix, &self.matrix, &value.value) };
res
}
}
#[cfg(test)]
mod test_evaluate {
use crate::integer::{MatPolyOverZ, MatZ, Z};
use crate::traits::Evaluate;
use std::str::FromStr;
#[test]
fn eval_z() {
let poly_str = "[[1 17],[2 24 42]]";
let poly = MatPolyOverZ::from_str(poly_str).unwrap();
let res = poly.evaluate(Z::from(3));
assert_eq!(MatZ::from_str("[[17],[150]]").unwrap(), res);
}
#[test]
fn eval_z_ref() {
let poly_str = "[[1 17],[2 24 42]]";
let poly = MatPolyOverZ::from_str(poly_str).unwrap();
let res = poly.evaluate(&Z::from(3));
assert_eq!(MatZ::from_str("[[17],[150]]").unwrap(), res);
}
#[test]
fn eval_z_negative() {
let poly_str = "[[1 17],[2 24 42]]";
let poly = MatPolyOverZ::from_str(poly_str).unwrap();
let res = poly.evaluate(&Z::from(-5));
assert_eq!(MatZ::from_str("[[17],[-186]]").unwrap(), res);
}
#[test]
fn eval_z_large() {
let poly_str = "[[1 17],[2 6 2]]";
let poly = MatPolyOverZ::from_str(poly_str).unwrap();
let res = poly.evaluate(&Z::from_str(&"1".repeat(65)).unwrap());
let res_cmp_str = format!("[[17],[{}8]]", "2".repeat(64));
assert_eq!(MatZ::from_str(&res_cmp_str).unwrap(), res);
}
#[test]
fn eval_large_with_large() {
let poly_str = format!("[[2 {} -1, 1 1],[1 {}, 2 0 1]]", u64::MAX, u64::MAX);
let poly = MatPolyOverZ::from_str(&poly_str).unwrap();
let res = poly.evaluate(Z::from(u64::MAX));
let res_cmp_str = format!("[[0, 1],[{}, {}]]", u64::MAX, u64::MAX);
assert_eq!(MatZ::from_str(&res_cmp_str).unwrap(), res);
}
#[test]
fn eval_max() {
let poly_str = "[[1 17],[2 24 42]]";
let poly = MatPolyOverZ::from_str(poly_str).unwrap();
let _ = poly.evaluate(i64::MAX);
let _ = poly.evaluate(i32::MAX);
let _ = poly.evaluate(i16::MAX);
let _ = poly.evaluate(i8::MAX);
let _ = poly.evaluate(u64::MAX);
let _ = poly.evaluate(u32::MAX);
let _ = poly.evaluate(u16::MAX);
let _ = poly.evaluate(u8::MAX);
}
#[test]
fn eval_min() {
let poly_str = "[[1 17],[2 24 42]]";
let poly = MatPolyOverZ::from_str(poly_str).unwrap();
let _ = poly.evaluate(i64::MIN);
let _ = poly.evaluate(i32::MIN);
let _ = poly.evaluate(i16::MIN);
let _ = poly.evaluate(i8::MIN);
let _ = poly.evaluate(u64::MIN);
let _ = poly.evaluate(u32::MIN);
let _ = poly.evaluate(u16::MIN);
let _ = poly.evaluate(u8::MIN);
}
}