qfall_math/integer/poly_over_z/
evaluate.rs1use super::PolyOverZ;
14use crate::{integer::Z, rational::Q, traits::Evaluate};
15use flint_sys::fmpz_poly::{fmpz_poly_evaluate_fmpq, fmpz_poly_evaluate_fmpz};
16
17impl<Integer: Into<Z>> Evaluate<Integer, Z> for PolyOverZ {
18 fn evaluate(&self, value: Integer) -> Z {
36 let value = value.into();
37 let mut res = Z::default();
38
39 unsafe { fmpz_poly_evaluate_fmpz(&mut res.value, &self.poly, &value.value) };
40
41 res
42 }
43}
44
45impl<Rational: Into<Q>> Evaluate<Rational, Q> for PolyOverZ {
46 fn evaluate(&self, value: Rational) -> Q {
65 let value = value.into();
66 let mut res = Q::default();
67
68 unsafe { fmpz_poly_evaluate_fmpq(&mut res.value, &self.poly, &value.value) };
69
70 res
71 }
72}
73
74#[cfg(test)]
75mod test_evaluate_z {
76 use crate::integer::{PolyOverZ, Z};
77 use crate::traits::Evaluate;
78 use std::str::FromStr;
79
80 #[test]
82 fn eval_z() {
83 let poly = PolyOverZ::from_str("2 1 2").unwrap();
84
85 let res: Z = poly.evaluate(Z::from(3));
86
87 assert_eq!(7, res);
88 }
89
90 #[test]
92 fn eval_z_ref() {
93 let poly = PolyOverZ::from_str("2 1 2").unwrap();
94
95 let res: Z = poly.evaluate(&Z::from(3));
96
97 assert_eq!(7, res);
98 }
99
100 #[test]
102 fn eval_z_negative() {
103 let poly = PolyOverZ::from_str("2 1 2").unwrap();
104
105 let res: Z = poly.evaluate(-5);
106
107 assert_eq!(-9, res);
108 }
109
110 #[test]
112 fn eval_z_large() {
113 let poly = PolyOverZ::from_str("2 1 2").unwrap();
114
115 let res: Z = poly.evaluate(&Z::from_str(&"1".repeat(65)).unwrap());
116
117 let mut res_cmp_str = "2".repeat(64);
118 res_cmp_str.push('3');
119 assert_eq!(Z::from_str(&res_cmp_str).unwrap(), res);
120 }
121
122 #[test]
124 fn eval_max() {
125 let poly = PolyOverZ::from_str("2 1 2").unwrap();
126
127 let _: Z = poly.evaluate(i64::MAX);
129 let _: Z = poly.evaluate(i32::MAX);
130 let _: Z = poly.evaluate(i16::MAX);
131 let _: Z = poly.evaluate(i8::MAX);
132
133 let _: Z = poly.evaluate(u64::MAX);
135 let _: Z = poly.evaluate(u32::MAX);
136 let _: Z = poly.evaluate(u16::MAX);
137 let _: Z = poly.evaluate(u8::MAX);
138 }
139
140 #[test]
142 fn eval_min() {
143 let poly = PolyOverZ::from_str("2 1 2").unwrap();
144
145 let _: Z = poly.evaluate(i64::MIN);
147 let _: Z = poly.evaluate(i32::MIN);
148 let _: Z = poly.evaluate(i16::MIN);
149 let _: Z = poly.evaluate(i8::MIN);
150
151 let _: Z = poly.evaluate(u64::MIN);
153 let _: Z = poly.evaluate(u32::MIN);
154 let _: Z = poly.evaluate(u16::MIN);
155 let _: Z = poly.evaluate(u8::MIN);
156 }
157}
158
159#[cfg(test)]
160mod test_evaluate_q {
161 use crate::{integer::PolyOverZ, rational::Q, traits::Evaluate};
162 use std::str::FromStr;
163
164 #[test]
166 fn evaluate_positive() {
167 let poly = PolyOverZ::from_str("2 1 3").unwrap();
168 let value = Q::from((3, 2));
169
170 let res_ref = poly.evaluate(&value);
171 let res = poly.evaluate(value);
172
173 assert_eq!(Q::from((11, 2)), res);
174 assert_eq!(res_ref, res);
175 }
176
177 #[test]
179 fn evaluate_negative() {
180 let poly = PolyOverZ::from_str("2 1 3").unwrap();
181 let value = Q::from((-3, 2));
182
183 let res_ref = poly.evaluate(&value);
184 let res = poly.evaluate(value);
185
186 assert_eq!(Q::from((-7, 2)), res);
187 assert_eq!(res_ref, res);
188 }
189
190 #[test]
192 fn evaluate_large_positive() {
193 let poly = PolyOverZ::from_str(&format!("2 {} 1", (u64::MAX - 1) / 2)).unwrap();
194 let value = Q::from((u64::MAX - 1) / 2);
195
196 let res_ref = poly.evaluate(&value);
197 let res = poly.evaluate(value);
198
199 assert_eq!(Q::from(u64::MAX - 1), res);
200 assert_eq!(res_ref, res);
201 }
202
203 #[test]
205 fn evaluate_large_negative() {
206 let poly = PolyOverZ::from_str(&format!("2 {} 2", u64::MAX)).unwrap();
207 let value = Q::from_str(&format!("-{}", (u64::MAX - 1) / 2)).unwrap();
208
209 let res_ref = poly.evaluate(&value);
210 let res = poly.evaluate(value);
211
212 assert_eq!(Q::ONE, res);
213 assert_eq!(res_ref, res);
214 }
215}