1use crate::utils;
2use anyhow::{Context, Result, anyhow};
3use starkom_ff::{Field, PrimeField, ThreeAdicField};
4use std::any::{Any, TypeId};
5use std::collections::BTreeMap;
6use std::iter::{Product, Sum};
7use std::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
8use std::sync::{Mutex, OnceLock};
9
10fn make_lagrange0<F: PrimeField>(n: usize) -> Polynomial<F> {
15 let mut coefficients = vec![F::ZERO; n + 1];
16 coefficients[0] = -F::ONE;
17 coefficients[n] = F::ONE;
18 let zero = Polynomial { coefficients };
19 let (quotient, remainder) = zero.horner(F::ONE);
20 assert_eq!(remainder, F::ZERO);
21 quotient * F::try_from(n).unwrap().invert_unwrap()
22}
23
24#[derive(Debug, Default, Clone, PartialEq, Eq)]
27pub struct Polynomial<F: Field> {
28 coefficients: Vec<F>,
29}
30
31impl<F: Field> Polynomial<F> {
32 pub fn with_coefficients(coefficients: Vec<F>) -> Self {
35 Self { coefficients }
36 }
37
38 pub fn constant(y: F) -> Self {
40 Self {
41 coefficients: vec![y],
42 }
43 }
44
45 pub fn interpolate(points: &[(F, F)]) -> Result<Self> {
51 let k = points.len();
52 let x = points.iter().map(|(x, _)| *x).collect::<Vec<F>>();
53 let l = Self::from_roots(x.as_slice(), F::ONE).context("duplicate X-coordinates")?;
54 let w = {
55 let one = F::ONE;
56 let mut weights = vec![one; k];
57 for i in 0..k {
58 for j in 0..k {
59 if i != j {
60 weights[i] *= x[i] - x[j];
61 }
62 }
63 weights[i] = weights[i]
64 .invert()
65 .into_option()
66 .context("duplicate X-coordinates")?;
67 }
68 weights
69 };
70 let mut result = Self {
71 coefficients: Vec::with_capacity(points.len()),
72 };
73 for i in 0..k {
74 let (basis, remainder) = l.horner(x[i]);
75 assert_eq!(remainder, F::ZERO);
76 let (_, y) = points[i];
77 result += basis * w[i] * y;
78 }
79 Ok(result)
80 }
81
82 pub fn from_roots(roots: &[F], blinding_factor: F) -> Result<Self> {
92 let mut roots = roots.to_vec();
93 roots.sort();
94 for i in 1..roots.len() {
95 if roots[i] == roots[i - 1] {
96 return Err(anyhow!("duplicate roots"));
97 }
98 }
99 let n = roots.len() + 1;
100 let mut coefficients = vec![F::ZERO; n];
101 coefficients[0] = blinding_factor;
102 for i in 1..n {
103 for j in (0..i).rev() {
104 let c = coefficients[j];
105 coefficients[j + 1] -= c * roots[i - 1];
106 }
107 }
108 coefficients.reverse();
109 Ok(Self { coefficients })
110 }
111
112 pub fn len(&self) -> usize {
114 self.coefficients.len()
115 }
116
117 pub fn coefficients(&self) -> &[F] {
119 self.coefficients.as_slice()
120 }
121
122 fn degree_bound_of(coefficients: &[F]) -> usize {
123 for (i, &coefficient) in coefficients.iter().enumerate().rev() {
124 if coefficient != F::ZERO {
125 return i + 1;
126 }
127 }
128 0
129 }
130
131 pub fn degree_bound(&self) -> usize {
138 Self::degree_bound_of(self.coefficients.as_slice())
139 }
140
141 pub fn trim(mut self) -> Self {
150 if let Some(i) = self
151 .coefficients
152 .iter()
153 .rposition(|value| *value != F::ZERO)
154 {
155 self.coefficients.truncate(i + 1);
156 } else {
157 self.coefficients.clear();
158 }
159 self
160 }
161
162 pub fn pad(mut self, min_degree_bound: usize) -> Self {
165 if min_degree_bound > self.coefficients.len() {
166 self.coefficients.resize(min_degree_bound, F::ZERO);
167 }
168 self
169 }
170
171 pub fn take(self) -> Vec<F> {
176 return self.coefficients;
177 }
178
179 pub fn horner(&self, z: F) -> (Self, F) {
184 if self.coefficients.is_empty() {
185 return (Polynomial::default(), F::ZERO);
186 }
187 let n = self.len() - 1;
188 let mut coefficients = vec![F::ZERO; n];
189 if n < 1 {
190 return (Polynomial { coefficients }, self.coefficients[0]);
191 }
192 coefficients[n - 1] = self.coefficients[n];
193 for i in (1..n).rev() {
194 coefficients[i - 1] = self.coefficients[i] + z * coefficients[i];
195 }
196 let remainder = self.coefficients[0] + z * coefficients[0];
197 (Polynomial { coefficients }, remainder)
198 }
199
200 pub fn divide_by_zero(self, n: usize) -> Result<Self> {
216 assert!(n > 0);
217
218 let mut data = self.take();
219 if data.len() < n {
220 data.resize(n, F::ZERO);
221 }
222
223 let degree = data.len() - n;
224 let mut quotient = vec![F::ZERO; degree];
225
226 for i in 0..degree {
227 let c = -data[i];
228 quotient[i] = c;
229 data[i + n] -= c;
230 }
231
232 let remainder = &data[degree..];
233 if remainder.iter().any(|c| *c != F::ZERO) {
234 return Err(anyhow!("non-zero remainder in division by (x^n - 1)"));
235 }
236
237 if let Some(i) = quotient.iter().rposition(|c| *c != F::ZERO) {
238 quotient.truncate(i + 1);
239 }
240 Ok(Polynomial {
241 coefficients: quotient,
242 })
243 }
244
245 pub fn evaluate(&self, x: F) -> F {
253 let mut y = F::ZERO;
254 for coefficient in self.coefficients.iter().rev() {
255 y = y * x + *coefficient;
256 }
257 y
258 }
259
260 pub fn shift_domain_by(self, shift: F) -> Self {
265 let mut coefficients = self.coefficients;
266 let mut shift_pow = F::ONE;
267 for c in coefficients.iter_mut() {
268 *c *= shift_pow;
269 shift_pow *= shift;
270 }
271 Self { coefficients }
272 }
273
274 pub fn fold2(self, alpha: F) -> Self {
278 let coefficients = self.coefficients();
279 let m = (coefficients.len() + 1) / 2;
280 let new_coefficients = (0..m)
281 .map(|i| {
282 coefficients[2 * i]
283 + alpha * coefficients.get(2 * i + 1).copied().unwrap_or(F::ZERO)
284 })
285 .collect();
286 Self::with_coefficients(new_coefficients)
287 }
288}
289
290impl<F: PrimeField> Polynomial<F> {
291 fn fft2(data: &mut [F], omega: F) {
298 let n = data.len();
299 assert!(n.is_power_of_two());
300
301 let log_n = n.trailing_zeros();
302 assert!(log_n as usize <= F::S);
303
304 for i in 0..n {
305 let (j, _) = i.reverse_bits().overflowing_shr(usize::BITS - log_n);
306 if i < j {
307 data.swap(i, j);
308 }
309 }
310
311 let mut m = 1;
312 for _ in 0..log_n {
313 let step = m * 2;
314 let wm = omega.pow_small(n / step);
315 let mut w = F::ONE;
316 for k in 0..m {
317 for j in (k..n).step_by(step) {
318 let t = w * data[j + m];
319 let u = data[j];
320 data[j] = u + t;
321 data[j + m] = u - t;
322 }
323 w *= wm;
324 }
325 m = step;
326 }
327 }
328
329 fn ifft2(data: &mut [F], omega: F) {
336 Self::fft2(data, omega.invert_unwrap());
337 let n_inv = F::try_from(data.len()).unwrap().invert_unwrap();
338 for v in data.iter_mut() {
339 *v *= n_inv;
340 }
341 }
342
343 fn two_adic_root_of_unity(n: usize) -> F {
345 assert!(n.is_power_of_two());
346 let k = n.trailing_zeros() as usize;
347 assert!(k <= F::S);
348 let exponent = 1u64 << (F::S - k);
349 F::ROOT_OF_UNITY.pow_u64(exponent)
350 }
351
352 pub fn encode2(mut values: Vec<F>) -> Self {
371 assert!(!values.is_empty());
372 let n = values.len().next_power_of_two();
373 assert!(n.trailing_zeros() as usize <= F::S);
374 if n != values.len() {
375 values.resize(n, F::ZERO);
376 }
377 let omega = Self::two_adic_root_of_unity(values.len());
378 Self::ifft2(values.as_mut_slice(), omega);
379 Polynomial {
380 coefficients: values,
381 }
382 .trim()
383 }
384
385 pub fn decode2(self) -> Vec<F> {
397 let mut data = self.coefficients;
398 let n = data.len().next_power_of_two();
399 if n != data.len() {
400 data.resize(n, F::ZERO);
401 }
402 let omega = Self::two_adic_root_of_unity(n);
403 Self::fft2(&mut data, omega);
404 data
405 }
406
407 pub fn multiply(mut self, mut other: Self) -> Self {
410 self = self.trim();
411 other = other.trim();
412
413 let mut lhs = self.coefficients;
414 let mut rhs = other.coefficients;
415
416 if lhs.is_empty() || rhs.is_empty() {
417 return Polynomial {
418 coefficients: vec![],
419 };
420 }
421 if lhs.len() == 1 {
422 return Polynomial { coefficients: rhs } * lhs[0];
423 }
424 if rhs.len() == 1 {
425 return Polynomial { coefficients: lhs } * rhs[0];
426 }
427
428 let n = (lhs.len() + rhs.len() - 1).next_power_of_two();
429
430 lhs.resize(n, F::ZERO);
431 rhs.resize(n, F::ZERO);
432
433 let omega = Self::two_adic_root_of_unity(n);
434 Self::fft2(lhs.as_mut_slice(), omega);
435 Self::fft2(rhs.as_mut_slice(), omega);
436
437 for i in 0..n {
438 lhs[i] *= rhs[i];
439 }
440
441 Self::ifft2(lhs.as_mut_slice(), omega);
442
443 Polynomial { coefficients: lhs }.trim()
444 }
445
446 pub fn multiply_batch<'a, I: IntoIterator<Item = &'a Self>>(polynomials: I) -> Self
450 where
451 I::IntoIter: Clone,
452 {
453 let iter = polynomials.into_iter();
454 let n = {
455 let (count, total) =
456 iter.clone()
457 .fold((0usize, 0usize), |(count, total), polynomial| {
458 (count + 1, total + std::cmp::max(polynomial.len(), 1))
459 });
460 (total - count + 1).next_power_of_two()
461 };
462 let mut data = vec![F::ONE; n];
463 let omega = Self::two_adic_root_of_unity(n);
464 for polynomial in iter {
465 let m = polynomial.len();
466 assert!(n >= m);
467 let mut values = vec![F::ZERO; n];
468 values[0..m].copy_from_slice(&polynomial.coefficients);
469 Self::fft2(values.as_mut_slice(), omega);
470 for i in 0..n {
471 data[i] *= values[i];
472 }
473 }
474 Self::ifft2(data.as_mut_slice(), omega);
475 Polynomial { coefficients: data }.trim()
476 }
477
478 pub fn multiply_values2(mut lhs: Vec<F>, mut rhs: Vec<F>) -> Vec<F> {
487 let n = lhs.len();
488 assert!(n.is_power_of_two());
489 assert!(n.trailing_zeros() as usize + 1 <= F::S);
490 assert_eq!(rhs.len(), n);
491 let omega = Self::two_adic_root_of_unity(n);
492 Self::ifft2(&mut lhs, omega);
493 Self::ifft2(&mut rhs, omega);
494 let lhs_len = Self::degree_bound_of(lhs.as_slice());
495 let rhs_len = Self::degree_bound_of(rhs.as_slice());
496 let m = (lhs_len + rhs_len - 1).next_power_of_two();
497 lhs.resize(m, F::ZERO);
498 rhs.resize(m, F::ZERO);
499 let omega = Self::two_adic_root_of_unity(m);
500 Self::fft2(&mut lhs, omega);
501 Self::fft2(&mut rhs, omega);
502 for i in 0..m {
503 lhs[i] *= rhs[i];
504 }
505 lhs
506 }
507
508 pub fn shift_domain(self) -> Self {
516 self.shift_domain_by(F::MULTIPLICATIVE_GENERATOR)
517 }
518
519 pub fn domain_element2(index: usize, domain_size: usize) -> F {
529 let omega = Self::two_adic_root_of_unity(domain_size.next_power_of_two());
530 omega.pow_small(index)
531 }
532
533 pub fn coset_element2(index: usize, domain_size: usize) -> F {
540 F::MULTIPLICATIVE_GENERATOR * Self::domain_element2(index, domain_size)
541 }
542
543 pub fn evaluate_on_two_adic_domain(&self, index: usize, domain_size: usize) -> F {
547 self.evaluate(Self::domain_element2(index, domain_size))
548 }
549
550 pub fn evaluate_on_two_adic_coset(&self, index: usize, domain_size: usize) -> F {
554 self.evaluate(Self::coset_element2(index, domain_size))
555 }
556
557 pub fn lde2(self, m: usize) -> Vec<F> {
567 assert!(m.is_power_of_two());
568 assert!(m.trailing_zeros() as usize <= F::S);
569 assert!(self.coefficients.len() < m);
570 let mut data = self.coefficients;
571 data.resize(m, F::ZERO);
572 let omega = Self::two_adic_root_of_unity(m);
573 Self::fft2(&mut data, omega);
574 data
575 }
576
577 pub fn lagrange0_2(n: usize) -> &'static Self {
592 assert!(n.is_power_of_two());
593 let k = n.trailing_zeros() as usize;
594 assert!(k <= F::S);
595
596 static CACHE: OnceLock<Mutex<BTreeMap<(TypeId, usize), &'static (dyn Any + Send + Sync)>>> =
597 OnceLock::new();
598 let cache = CACHE.get_or_init(|| Mutex::new(BTreeMap::new()));
599
600 let polynomial = {
601 let mut map = cache.lock().unwrap();
602 *map.entry((TypeId::of::<F>(), k)).or_insert_with(|| {
603 Box::leak(Box::new(make_lagrange0::<F>(1 << k))) as &'static (dyn Any + Send + Sync)
604 })
605 };
606
607 polynomial.downcast_ref::<Polynomial<F>>().unwrap()
608 }
609}
610
611impl<F: ThreeAdicField> Polynomial<F> {
612 fn fft3(data: &mut [F], omega: F) {
619 let n = data.len();
620 assert!(utils::is_power_of_three(n));
621
622 let log_n = utils::ilog3(n);
623
624 for i in 0..n {
625 let mut j = 0;
626 let mut tmp = i;
627 for _ in 0..log_n {
628 j = j * 3 + tmp % 3;
629 tmp /= 3;
630 }
631 if i < j {
632 data.swap(i, j);
633 }
634 }
635
636 let omega3 = omega.pow_small(n / 3);
637 let omega3_square = omega3.square();
638
639 let mut m = 1;
640 for _ in 0..log_n {
641 let step = m * 3;
642 let wm = omega.pow_small(n / step);
643 let mut w = F::ONE;
644 let mut w2 = F::ONE;
645 for k in 0..m {
646 for j in (k..n).step_by(step) {
647 let t0 = data[j];
648 let t1 = w * data[j + m];
649 let t2 = w2 * data[j + 2 * m];
650 data[j] = t0 + t1 + t2;
651 data[j + m] = t0 + omega3 * t1 + omega3_square * t2;
652 data[j + 2 * m] = t0 + omega3_square * t1 + omega3 * t2;
653 }
654 w *= wm;
655 w2 = w * w;
656 }
657 m = step;
658 }
659 }
660
661 fn ifft3(data: &mut [F], omega: F) {
668 Self::fft3(data, omega.invert_unwrap());
669 let n_inv = F::try_from(data.len()).unwrap().invert_unwrap();
670 for v in data.iter_mut() {
671 *v *= n_inv;
672 }
673 }
674
675 fn three_adic_root_of_unity(n: usize) -> F {
677 assert!(utils::is_power_of_three(n));
678 let k = utils::ilog3(n);
679 assert!(k <= F::T);
680 let exponent = 3u64.pow((F::T - k) as u32);
681 F::THREE_ADIC_ROOT_OF_UNITY.pow_u64(exponent)
682 }
683
684 pub fn encode3(mut values: Vec<F>) -> Self {
703 assert!(!values.is_empty());
704 let n = utils::next_power_of_three(values.len());
705 assert!(utils::ilog3(n) <= F::T as usize);
706 if n != values.len() {
707 values.resize(n, F::ZERO);
708 }
709 let omega = Self::three_adic_root_of_unity(values.len());
710 Self::ifft3(values.as_mut_slice(), omega);
711 Polynomial {
712 coefficients: values,
713 }
714 .trim()
715 }
716
717 pub fn decode3(self) -> Vec<F> {
729 let mut data = self.coefficients;
730 let n = utils::next_power_of_three(data.len());
731 if n != data.len() {
732 data.resize(n, F::ZERO);
733 }
734 let omega = Self::three_adic_root_of_unity(n);
735 Self::fft3(&mut data, omega);
736 data
737 }
738
739 pub fn domain_element3(index: usize, domain_size: usize) -> F {
749 let omega = Self::three_adic_root_of_unity(utils::next_power_of_three(domain_size));
750 omega.pow_small(index)
751 }
752
753 pub fn coset_element3(index: usize, domain_size: usize) -> F {
760 F::MULTIPLICATIVE_GENERATOR * Self::domain_element3(index, domain_size)
761 }
762
763 pub fn evaluate_on_three_adic_domain(&self, index: usize, domain_size: usize) -> F {
767 self.evaluate(Self::domain_element3(index, domain_size))
768 }
769
770 pub fn evaluate_on_three_adic_coset(&self, index: usize, domain_size: usize) -> F {
774 self.evaluate(Self::coset_element3(index, domain_size))
775 }
776
777 pub fn lde3(self, m: usize) -> Vec<F> {
788 assert!(utils::is_power_of_three(m));
789 assert!(utils::ilog3(m) <= F::T);
790 assert!(self.coefficients.len() < m);
791 let mut data = self.coefficients;
792 data.resize(m, F::ZERO);
793 let omega = Self::three_adic_root_of_unity(m);
794 Self::fft3(&mut data, omega);
795 data
796 }
797
798 pub fn fold3(self, alpha: F) -> Self {
802 let coefficients = self.coefficients();
803 let m = (coefficients.len() + 2) / 3;
804 let alpha_square = alpha * alpha;
805 let new_coefficients = (0..m)
806 .map(|i| {
807 coefficients[3 * i]
808 + alpha * coefficients.get(3 * i + 1).copied().unwrap_or(F::ZERO)
809 + alpha_square * coefficients.get(3 * i + 2).copied().unwrap_or(F::ZERO)
810 })
811 .collect();
812 Self::with_coefficients(new_coefficients)
813 }
814
815 pub fn multiply_values3(mut lhs: Vec<F>, mut rhs: Vec<F>) -> Vec<F> {
824 let n = lhs.len();
825 assert!(utils::is_power_of_three(n));
826 assert!(utils::ilog3(n) + 1 <= F::T);
827 assert_eq!(rhs.len(), n);
828 let omega = Self::three_adic_root_of_unity(n);
829 Self::ifft3(&mut lhs, omega);
830 Self::ifft3(&mut rhs, omega);
831 let lhs_len = Self::degree_bound_of(lhs.as_slice());
832 let rhs_len = Self::degree_bound_of(rhs.as_slice());
833 let m = utils::next_power_of_three(lhs_len + rhs_len - 1);
834 lhs.resize(m, F::ZERO);
835 rhs.resize(m, F::ZERO);
836 let omega = Self::three_adic_root_of_unity(m);
837 Self::fft3(&mut lhs, omega);
838 Self::fft3(&mut rhs, omega);
839 for i in 0..m {
840 lhs[i] *= rhs[i];
841 }
842 lhs
843 }
844
845 pub fn lagrange0_3(n: usize) -> &'static Self {
860 assert!(utils::is_power_of_three(n));
861 let k = utils::ilog3(n);
862 assert!(k <= (F::T as usize));
863
864 static CACHE: OnceLock<Mutex<BTreeMap<(TypeId, usize), &'static (dyn Any + Send + Sync)>>> =
865 OnceLock::new();
866 let cache = CACHE.get_or_init(|| Mutex::new(BTreeMap::new()));
867
868 let polynomial = {
869 let mut map = cache.lock().unwrap();
870 *map.entry((TypeId::of::<F>(), k)).or_insert_with(|| {
871 Box::leak(Box::new(make_lagrange0::<F>(3usize.pow(k as u32))))
872 as &'static (dyn Any + Send + Sync)
873 })
874 };
875
876 polynomial.downcast_ref::<Polynomial<F>>().unwrap()
877 }
878}
879
880impl<F: Field> Neg for Polynomial<F> {
881 type Output = Self;
882
883 fn neg(mut self) -> Self::Output {
884 for coefficient in &mut self.coefficients {
885 *coefficient = -*coefficient;
886 }
887 self
888 }
889}
890
891impl<F: Field> Add<Polynomial<F>> for Polynomial<F> {
892 type Output = Self;
893
894 fn add(mut self, rhs: Self) -> Self::Output {
895 let len = rhs.len();
896 if len > self.len() {
897 return rhs + self;
898 }
899 for i in 0..len {
900 self.coefficients[i] += rhs.coefficients[i];
901 }
902 self
903 }
904}
905
906impl<F: Field> Add<&Polynomial<F>> for Polynomial<F> {
907 type Output = Self;
908
909 fn add(mut self, rhs: &Self) -> Self::Output {
910 let len = rhs.len();
911 if len > self.len() {
912 self.coefficients.resize(len, F::ZERO);
913 }
914 for i in 0..len {
915 self.coefficients[i] += rhs.coefficients[i];
916 }
917 self
918 }
919}
920
921impl<F: Field> AddAssign<Polynomial<F>> for Polynomial<F> {
922 fn add_assign(&mut self, mut rhs: Self) {
923 if rhs.len() > self.len() {
924 for i in 0..self.len() {
925 rhs.coefficients[i] += self.coefficients[i];
926 }
927 self.coefficients = rhs.coefficients;
928 } else {
929 for i in 0..rhs.len() {
930 self.coefficients[i] += rhs.coefficients[i];
931 }
932 }
933 }
934}
935
936impl<F: Field> AddAssign<&Polynomial<F>> for Polynomial<F> {
937 fn add_assign(&mut self, rhs: &Self) {
938 let len = rhs.len();
939 if len > self.len() {
940 self.coefficients.resize(len, F::ZERO);
941 }
942 for i in 0..len {
943 self.coefficients[i] += rhs.coefficients[i];
944 }
945 }
946}
947
948impl<F: Field> Add<F> for Polynomial<F> {
949 type Output = Self;
950
951 fn add(mut self, rhs: F) -> Self::Output {
952 if self.coefficients.is_empty() {
953 self.coefficients.push(rhs);
954 } else {
955 self.coefficients[0] += rhs;
956 }
957 self
958 }
959}
960
961impl<F: Field> AddAssign<F> for Polynomial<F> {
962 fn add_assign(&mut self, rhs: F) {
963 if self.coefficients.is_empty() {
964 self.coefficients.push(rhs);
965 } else {
966 self.coefficients[0] += rhs;
967 }
968 }
969}
970
971impl<F: Field> Sub<Polynomial<F>> for Polynomial<F> {
972 type Output = Self;
973
974 fn sub(mut self, rhs: Self) -> Self::Output {
975 if rhs.len() > self.len() {
976 return -(rhs - self);
977 }
978 for i in 0..rhs.len() {
979 self.coefficients[i] -= rhs.coefficients[i];
980 }
981 self
982 }
983}
984
985impl<F: Field> Sub<&Polynomial<F>> for Polynomial<F> {
986 type Output = Self;
987
988 fn sub(mut self, rhs: &Self) -> Self::Output {
989 let len = rhs.len();
990 if len > self.len() {
991 self.coefficients.resize(len, F::ZERO);
992 }
993 for i in 0..len {
994 self.coefficients[i] -= rhs.coefficients[i];
995 }
996 self
997 }
998}
999
1000impl<F: Field> SubAssign<Polynomial<F>> for Polynomial<F> {
1001 fn sub_assign(&mut self, mut rhs: Self) {
1002 if rhs.len() > self.len() {
1003 for i in 0..self.len() {
1004 rhs.coefficients[i] -= self.coefficients[i];
1005 }
1006 self.coefficients = rhs.coefficients;
1007 for i in 0..self.len() {
1008 self.coefficients[i] = -self.coefficients[i];
1009 }
1010 } else {
1011 for i in 0..rhs.len() {
1012 self.coefficients[i] -= rhs.coefficients[i];
1013 }
1014 }
1015 }
1016}
1017
1018impl<F: Field> SubAssign<&Polynomial<F>> for Polynomial<F> {
1019 fn sub_assign(&mut self, rhs: &Self) {
1020 let len = rhs.len();
1021 if len > self.len() {
1022 self.coefficients.resize(len, F::ZERO);
1023 }
1024 for i in 0..len {
1025 self.coefficients[i] -= rhs.coefficients[i];
1026 }
1027 }
1028}
1029
1030impl<F: Field> Sub<F> for Polynomial<F> {
1031 type Output = Self;
1032
1033 fn sub(mut self, rhs: F) -> Self::Output {
1034 if self.coefficients.is_empty() {
1035 self.coefficients.push(-rhs);
1036 } else {
1037 self.coefficients[0] -= rhs;
1038 }
1039 self
1040 }
1041}
1042
1043impl<F: Field> SubAssign<F> for Polynomial<F> {
1044 fn sub_assign(&mut self, rhs: F) {
1045 if self.coefficients.is_empty() {
1046 self.coefficients.push(-rhs);
1047 } else {
1048 self.coefficients[0] -= rhs;
1049 }
1050 }
1051}
1052
1053impl<F: Field> Mul<F> for Polynomial<F> {
1054 type Output = Self;
1055
1056 fn mul(mut self, rhs: F) -> Self::Output {
1057 for i in 0..self.len() {
1058 self.coefficients[i] *= rhs;
1059 }
1060 self
1061 }
1062}
1063
1064impl<F: Field> MulAssign<F> for Polynomial<F> {
1065 fn mul_assign(&mut self, rhs: F) {
1066 for i in 0..self.len() {
1067 self.coefficients[i] *= rhs;
1068 }
1069 }
1070}
1071
1072impl<F: PrimeField> Mul<Polynomial<F>> for Polynomial<F> {
1073 type Output = Self;
1074
1075 fn mul(self, rhs: Self) -> Self::Output {
1076 self.multiply(rhs)
1077 }
1078}
1079
1080impl<F: PrimeField> Mul<&Polynomial<F>> for Polynomial<F> {
1081 type Output = Self;
1082
1083 fn mul(self, rhs: &Self) -> Self::Output {
1084 self.multiply(rhs.clone())
1085 }
1086}
1087
1088impl<F: PrimeField> MulAssign<Polynomial<F>> for Polynomial<F> {
1089 fn mul_assign(&mut self, rhs: Self) {
1090 *self = std::mem::take(self).multiply(rhs);
1091 }
1092}
1093
1094impl<F: PrimeField> MulAssign<&Polynomial<F>> for Polynomial<F> {
1095 fn mul_assign(&mut self, rhs: &Self) {
1096 *self = std::mem::take(self).multiply(rhs.clone());
1097 }
1098}
1099
1100impl<F: Field> Sum<Polynomial<F>> for Polynomial<F> {
1101 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
1102 iter.fold(Polynomial::default(), |a, b| a + b)
1103 }
1104}
1105
1106impl<'a, F: Field> Sum<&'a Polynomial<F>> for Polynomial<F> {
1107 fn sum<I: Iterator<Item = &'a Polynomial<F>>>(iter: I) -> Self {
1108 iter.fold(Polynomial::default(), |a, b| a + b)
1109 }
1110}
1111
1112impl<F: PrimeField> Product<Polynomial<F>> for Polynomial<F> {
1113 fn product<I: Iterator<Item = Polynomial<F>>>(iter: I) -> Self {
1114 let polynomials = iter.collect::<Vec<_>>();
1115 Polynomial::multiply_batch(polynomials.iter())
1116 }
1117}
1118
1119impl<'a, F: PrimeField> Product<&'a Polynomial<F>> for Polynomial<F> {
1120 fn product<I: Iterator<Item = &'a Polynomial<F>>>(iter: I) -> Self {
1121 let polynomials = iter.collect::<Vec<_>>();
1122 Polynomial::multiply_batch(polynomials)
1123 }
1124}
1125
1126#[cfg(test)]
1127mod tests {
1128 use starkom_bluesky::{Scalar, from_const};
1129 use starkom_ff::{Field, PrimeField};
1130
1131 type Polynomial = super::Polynomial<Scalar>;
1132
1133 #[inline(always)]
1134 fn get_random_scalar() -> Scalar {
1135 Scalar::random_default()
1136 }
1137
1138 fn from_roots(roots: &[Scalar]) -> Polynomial {
1139 Polynomial::from_roots(roots, get_random_scalar()).unwrap()
1140 }
1141
1142 #[test]
1143 fn test_constant() {
1144 let p = Polynomial::constant(from_const(42));
1145 assert_eq!(p.evaluate(from_const(12)), from_const(42));
1146 assert_eq!(p.evaluate(from_const(34)), from_const(42));
1147 assert_eq!(p.evaluate(from_const(42)), from_const(42));
1148 }
1149
1150 #[test]
1151 fn test_zero() {
1152 let p = Polynomial::with_coefficients(vec![]);
1153 assert_eq!(p, Polynomial::default());
1154 assert_eq!(p.len(), 0);
1155 assert_eq!(p.degree_bound(), 0);
1156 assert_eq!(p.evaluate(from_const(42)), from_const(0));
1157 }
1158
1159 #[test]
1160 fn test_with_coefficients() {
1161 let p = Polynomial::with_coefficients(vec![from_const(12), from_const(34), from_const(56)]);
1162 assert_eq!(p.len(), 3);
1163 assert_eq!(p.degree_bound(), 3);
1164 assert_eq!(
1165 p.take(),
1166 vec![from_const(12), from_const(34), from_const(56)]
1167 );
1168 }
1169
1170 #[test]
1171 fn test_low_degree() {
1172 let p = Polynomial::with_coefficients(vec![
1173 from_const(12),
1174 from_const(34),
1175 from_const(56),
1176 from_const(0),
1177 from_const(0),
1178 ]);
1179 assert_eq!(p.len(), 5);
1180 assert_eq!(p.degree_bound(), 3);
1181 }
1182
1183 #[test]
1184 fn test_skip_degree() {
1185 let p = Polynomial::with_coefficients(vec![
1186 from_const(0),
1187 from_const(0),
1188 from_const(12),
1189 from_const(34),
1190 from_const(56),
1191 ]);
1192 assert_eq!(p.len(), 5);
1193 assert_eq!(p.degree_bound(), 5);
1194 }
1195
1196 #[test]
1197 fn test_trim_degree() {
1198 let mut p = Polynomial::with_coefficients(vec![
1199 from_const(12),
1200 from_const(34),
1201 from_const(56),
1202 from_const(0),
1203 from_const(0),
1204 ]);
1205 p = p.trim();
1206 assert_eq!(p.len(), 3);
1207 assert_eq!(p.degree_bound(), 3);
1208 }
1209
1210 #[test]
1211 fn test_no_trim() {
1212 let mut p = Polynomial::with_coefficients(vec![
1213 from_const(0),
1214 from_const(0),
1215 from_const(12),
1216 from_const(34),
1217 from_const(56),
1218 ]);
1219 p = p.trim();
1220 assert_eq!(p.len(), 5);
1221 assert_eq!(p.degree_bound(), 5);
1222 }
1223
1224 #[test]
1225 fn test_trim_all_zero() {
1226 let mut p =
1227 Polynomial::with_coefficients(vec![from_const(0), from_const(0), from_const(0)]);
1228 p = p.trim();
1229 assert_eq!(p.len(), p.degree_bound());
1230 assert_eq!(p, Polynomial::default());
1231 }
1232
1233 #[test]
1234 fn test_pad_extends() {
1235 let mut p = Polynomial::with_coefficients(vec![from_const(12), from_const(34)]);
1236 p = p.pad(5);
1237 assert_eq!(p.len(), 5);
1238 assert_eq!(
1239 p.take(),
1240 vec![
1241 from_const(12),
1242 from_const(34),
1243 from_const(0),
1244 from_const(0),
1245 from_const(0)
1246 ]
1247 );
1248 }
1249
1250 #[test]
1251 fn test_pad_exact() {
1252 let mut p =
1253 Polynomial::with_coefficients(vec![from_const(12), from_const(34), from_const(56)]);
1254 p = p.pad(3);
1255 assert_eq!(p.len(), 3);
1256 assert_eq!(
1257 p.take(),
1258 vec![from_const(12), from_const(34), from_const(56)]
1259 );
1260 }
1261
1262 #[test]
1263 fn test_pad_no_shrink() {
1264 let mut p = Polynomial::with_coefficients(vec![
1265 from_const(12),
1266 from_const(34),
1267 from_const(56),
1268 from_const(78),
1269 ]);
1270 p = p.pad(2);
1271 assert_eq!(p.len(), 4);
1272 assert_eq!(
1273 p.take(),
1274 vec![
1275 from_const(12),
1276 from_const(34),
1277 from_const(56),
1278 from_const(78)
1279 ]
1280 );
1281 }
1282
1283 #[test]
1284 fn test_pad_empty() {
1285 let mut p = Polynomial::default();
1286 p = p.pad(3);
1287 assert_eq!(p.len(), 3);
1288 assert_eq!(p.take(), vec![from_const(0), from_const(0), from_const(0)]);
1289 }
1290
1291 #[test]
1292 fn test_pad_zero_bound() {
1293 let mut p = Polynomial::with_coefficients(vec![from_const(12), from_const(34)]);
1294 p = p.pad(0);
1295 assert_eq!(p.len(), 2);
1296 assert_eq!(p.take(), vec![from_const(12), from_const(34)]);
1297 }
1298
1299 #[test]
1300 fn test_pad_preserves_evaluation() {
1301 let mut p =
1302 Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
1303 let before = p.evaluate(from_const(7));
1304 p = p.pad(6);
1305 assert_eq!(p.evaluate(from_const(7)), before);
1306 }
1307
1308 #[test]
1309 fn test_no_roots() {
1310 let p = from_roots(&[]);
1311 assert_eq!(p.len(), 1);
1312 assert_eq!(p.degree_bound(), 1);
1313 assert_ne!(p.evaluate(from_const(12)), from_const(0));
1314 assert_ne!(p.evaluate(from_const(34)), from_const(0));
1315 assert_ne!(p.evaluate(from_const(56)), from_const(0));
1316 assert_ne!(p.evaluate(from_const(78)), from_const(0));
1317 assert_ne!(p.evaluate(from_const(90)), from_const(0));
1318 assert_ne!(p.evaluate(from_const(13)), from_const(0));
1319 assert_ne!(p.evaluate(from_const(57)), from_const(0));
1320 assert_ne!(p.evaluate(from_const(92)), from_const(0));
1321 assert_ne!(p.evaluate(from_const(46)), from_const(0));
1322 assert_ne!(p.evaluate(from_const(80)), from_const(0));
1323 }
1324
1325 #[test]
1326 fn test_one_root() {
1327 let p = from_roots(&[from_const(12)]);
1328 assert_eq!(p.len(), 2);
1329 assert_eq!(p.degree_bound(), 2);
1330 assert_eq!(p.evaluate(from_const(12)), from_const(0));
1331 assert_ne!(p.evaluate(from_const(34)), from_const(0));
1332 assert_ne!(p.evaluate(from_const(56)), from_const(0));
1333 assert_ne!(p.evaluate(from_const(78)), from_const(0));
1334 assert_ne!(p.evaluate(from_const(90)), from_const(0));
1335 assert_ne!(p.evaluate(from_const(13)), from_const(0));
1336 assert_ne!(p.evaluate(from_const(57)), from_const(0));
1337 assert_ne!(p.evaluate(from_const(92)), from_const(0));
1338 assert_ne!(p.evaluate(from_const(46)), from_const(0));
1339 assert_ne!(p.evaluate(from_const(80)), from_const(0));
1340 let (q, v) = p.horner(from_const(12));
1341 assert_eq!(q.len(), 1);
1342 assert_eq!(q.degree_bound(), 1);
1343 assert_eq!(v, from_const(0));
1344 let (q, v) = p.horner(from_const(34));
1345 assert_eq!(q.len(), 1);
1346 assert_eq!(q.degree_bound(), 1);
1347 assert_ne!(v, from_const(0));
1348 }
1349
1350 #[test]
1351 fn test_three_roots() {
1352 let p = from_roots(&[from_const(12), from_const(34), from_const(56)]);
1353 assert_eq!(p.len(), 4);
1354 assert_eq!(p.degree_bound(), 4);
1355 assert_eq!(p.evaluate(from_const(12)), from_const(0));
1356 assert_eq!(p.evaluate(from_const(34)), from_const(0));
1357 assert_eq!(p.evaluate(from_const(56)), from_const(0));
1358 assert_ne!(p.evaluate(from_const(78)), from_const(0));
1359 assert_ne!(p.evaluate(from_const(90)), from_const(0));
1360 assert_ne!(p.evaluate(from_const(13)), from_const(0));
1361 assert_ne!(p.evaluate(from_const(57)), from_const(0));
1362 assert_ne!(p.evaluate(from_const(92)), from_const(0));
1363 assert_ne!(p.evaluate(from_const(46)), from_const(0));
1364 assert_ne!(p.evaluate(from_const(80)), from_const(0));
1365 let (q, v) = p.horner(from_const(12));
1366 assert_eq!(q.len(), 3);
1367 assert_eq!(q.degree_bound(), 3);
1368 assert_eq!(v, from_const(0));
1369 let (q, v) = q.horner(from_const(34));
1370 assert_eq!(q.len(), 2);
1371 assert_eq!(q.degree_bound(), 2);
1372 assert_eq!(v, from_const(0));
1373 let (q, v) = q.horner(from_const(56));
1374 assert_eq!(q.len(), 1);
1375 assert_eq!(q.degree_bound(), 1);
1376 assert_eq!(v, from_const(0));
1377 let (q, v) = p.horner(from_const(78));
1378 assert_eq!(q.len(), 3);
1379 assert_eq!(q.degree_bound(), 3);
1380 assert_ne!(v, from_const(0));
1381 let (q, v) = p.horner(from_const(90));
1382 assert_eq!(q.len(), 3);
1383 assert_eq!(q.degree_bound(), 3);
1384 assert_ne!(v, from_const(0));
1385 }
1386
1387 #[test]
1388 fn test_three_roots_reverse_order() {
1389 let p = from_roots(&[from_const(56), from_const(34), from_const(12)]);
1390 assert_eq!(p.len(), 4);
1391 assert_eq!(p.degree_bound(), 4);
1392 assert_eq!(p.evaluate(from_const(12)), from_const(0));
1393 assert_eq!(p.evaluate(from_const(34)), from_const(0));
1394 assert_eq!(p.evaluate(from_const(56)), from_const(0));
1395 assert_ne!(p.evaluate(from_const(78)), from_const(0));
1396 assert_ne!(p.evaluate(from_const(90)), from_const(0));
1397 assert_ne!(p.evaluate(from_const(13)), from_const(0));
1398 assert_ne!(p.evaluate(from_const(57)), from_const(0));
1399 assert_ne!(p.evaluate(from_const(92)), from_const(0));
1400 assert_ne!(p.evaluate(from_const(46)), from_const(0));
1401 assert_ne!(p.evaluate(from_const(80)), from_const(0));
1402 let (q, v) = p.horner(from_const(12));
1403 assert_eq!(q.len(), 3);
1404 assert_eq!(q.degree_bound(), 3);
1405 assert_eq!(v, from_const(0));
1406 let (q, v) = q.horner(from_const(34));
1407 assert_eq!(q.len(), 2);
1408 assert_eq!(q.degree_bound(), 2);
1409 assert_eq!(v, from_const(0));
1410 let (q, v) = q.horner(from_const(56));
1411 assert_eq!(q.len(), 1);
1412 assert_eq!(q.degree_bound(), 1);
1413 assert_eq!(v, from_const(0));
1414 let (q, v) = p.horner(from_const(78));
1415 assert_eq!(q.len(), 3);
1416 assert_eq!(q.degree_bound(), 3);
1417 assert_ne!(v, from_const(0));
1418 let (q, v) = p.horner(from_const(90));
1419 assert_eq!(q.len(), 3);
1420 assert_eq!(q.degree_bound(), 3);
1421 assert_ne!(v, from_const(0));
1422 }
1423
1424 #[test]
1425 fn test_seven_roots() {
1426 let p = from_roots(&[
1427 from_const(12),
1428 from_const(34),
1429 from_const(56),
1430 from_const(78),
1431 from_const(90),
1432 from_const(13),
1433 from_const(57),
1434 ]);
1435 assert_eq!(p.len(), 8);
1436 assert_eq!(p.degree_bound(), 8);
1437 assert_eq!(p.evaluate(from_const(12)), from_const(0));
1438 assert_eq!(p.evaluate(from_const(34)), from_const(0));
1439 assert_eq!(p.evaluate(from_const(56)), from_const(0));
1440 assert_eq!(p.evaluate(from_const(78)), from_const(0));
1441 assert_eq!(p.evaluate(from_const(90)), from_const(0));
1442 assert_eq!(p.evaluate(from_const(13)), from_const(0));
1443 assert_eq!(p.evaluate(from_const(57)), from_const(0));
1444 assert_ne!(p.evaluate(from_const(92)), from_const(0));
1445 assert_ne!(p.evaluate(from_const(46)), from_const(0));
1446 assert_ne!(p.evaluate(from_const(80)), from_const(0));
1447 }
1448
1449 #[test]
1450 fn test_seven_roots_reverse_order() {
1451 let p = from_roots(&[
1452 from_const(57),
1453 from_const(13),
1454 from_const(90),
1455 from_const(78),
1456 from_const(56),
1457 from_const(34),
1458 from_const(12),
1459 ]);
1460 assert_eq!(p.len(), 8);
1461 assert_eq!(p.degree_bound(), 8);
1462 assert_eq!(p.evaluate(from_const(12)), from_const(0));
1463 assert_eq!(p.evaluate(from_const(34)), from_const(0));
1464 assert_eq!(p.evaluate(from_const(56)), from_const(0));
1465 assert_eq!(p.evaluate(from_const(78)), from_const(0));
1466 assert_eq!(p.evaluate(from_const(90)), from_const(0));
1467 assert_eq!(p.evaluate(from_const(13)), from_const(0));
1468 assert_eq!(p.evaluate(from_const(57)), from_const(0));
1469 assert_ne!(p.evaluate(from_const(92)), from_const(0));
1470 assert_ne!(p.evaluate(from_const(46)), from_const(0));
1471 assert_ne!(p.evaluate(from_const(80)), from_const(0));
1472 }
1473
1474 #[test]
1475 fn test_duplicate_roots() {
1476 assert!(
1477 Polynomial::from_roots(
1478 &[
1479 from_const(12),
1480 from_const(34),
1481 from_const(56),
1482 from_const(12),
1483 from_const(90),
1484 from_const(12),
1485 from_const(57),
1486 ],
1487 get_random_scalar()
1488 )
1489 .is_err()
1490 );
1491 }
1492
1493 #[test]
1494 fn test_interpolate_zero_points() {
1495 let p = Polynomial::interpolate(&[]).unwrap();
1496 assert_eq!(p, Polynomial::default());
1497 }
1498
1499 #[test]
1500 fn test_interpolate_one_point1() {
1501 let p = Polynomial::interpolate(&[(from_const(12), from_const(34))]).unwrap();
1502 assert_eq!(p.len(), 1);
1503 assert_eq!(p.degree_bound(), 1);
1504 assert_eq!(p.evaluate(from_const(12)), from_const(34));
1505 }
1506
1507 #[test]
1508 fn test_interpolate_one_point2() {
1509 let p = Polynomial::interpolate(&[(from_const(34), from_const(56))]).unwrap();
1510 assert_eq!(p.len(), 1);
1511 assert_eq!(p.degree_bound(), 1);
1512 assert_eq!(p.evaluate(from_const(34)), from_const(56));
1513 }
1514
1515 #[test]
1516 fn test_interpolate_two_points1() {
1517 let p = Polynomial::interpolate(&[
1518 (from_const(12), from_const(34)),
1519 (from_const(56), from_const(78)),
1520 ])
1521 .unwrap();
1522 assert_eq!(p.len(), 2);
1523 assert_eq!(p.degree_bound(), 2);
1524 assert_eq!(p.evaluate(from_const(12)), from_const(34));
1525 assert_eq!(p.evaluate(from_const(56)), from_const(78));
1526 }
1527
1528 #[test]
1529 fn test_interpolate_two_points2() {
1530 let p = Polynomial::interpolate(&[
1531 (from_const(34), from_const(12)),
1532 (from_const(78), from_const(56)),
1533 ])
1534 .unwrap();
1535 assert_eq!(p.len(), 2);
1536 assert_eq!(p.degree_bound(), 2);
1537 assert_eq!(p.evaluate(from_const(34)), from_const(12));
1538 assert_eq!(p.evaluate(from_const(78)), from_const(56));
1539 }
1540
1541 #[test]
1542 fn test_interpolate_three_points1() {
1543 let p = Polynomial::interpolate(&[
1544 (from_const(12), from_const(34)),
1545 (from_const(56), from_const(78)),
1546 (from_const(90), from_const(12)),
1547 ])
1548 .unwrap();
1549 assert_eq!(p.len(), 3);
1550 assert_eq!(p.degree_bound(), 3);
1551 assert_eq!(p.evaluate(from_const(12)), from_const(34));
1552 assert_eq!(p.evaluate(from_const(56)), from_const(78));
1553 assert_eq!(p.evaluate(from_const(90)), from_const(12));
1554 }
1555
1556 #[test]
1557 fn test_interpolate_three_points2() {
1558 let p = Polynomial::interpolate(&[
1559 (from_const(34), from_const(12)),
1560 (from_const(78), from_const(56)),
1561 (from_const(12), from_const(90)),
1562 ])
1563 .unwrap();
1564 assert_eq!(p.len(), 3);
1565 assert_eq!(p.degree_bound(), 3);
1566 assert_eq!(p.evaluate(from_const(34)), from_const(12));
1567 assert_eq!(p.evaluate(from_const(78)), from_const(56));
1568 assert_eq!(p.evaluate(from_const(12)), from_const(90));
1569 }
1570
1571 #[test]
1572 fn test_duplicate_coordinates() {
1573 assert!(
1574 Polynomial::interpolate(&[
1575 (from_const(12), from_const(34)),
1576 (from_const(56), from_const(78)),
1577 (from_const(12), from_const(90)),
1578 ])
1579 .is_err()
1580 );
1581 }
1582
1583 #[test]
1584 fn test_encode2_one_value_1() {
1585 let p1 = Polynomial::encode2(vec![from_const(42)]);
1586 let p2 = Polynomial::encode2(vec![from_const(42)]);
1587 assert_eq!(p1, p2);
1588 assert_eq!(p1.len(), 1);
1589 assert_eq!(p1.degree_bound(), 1);
1590 assert_eq!(p2.len(), 1);
1591 assert_eq!(p2.degree_bound(), 1);
1592 assert_eq!(
1593 p1.evaluate(Polynomial::domain_element2(0, 1)),
1594 from_const(42)
1595 );
1596 assert_eq!(p1.evaluate_on_two_adic_domain(0, 1), from_const(42));
1597 assert_eq!(
1598 p2.evaluate(Polynomial::domain_element2(0, 1)),
1599 from_const(42)
1600 );
1601 assert_eq!(p2.evaluate_on_two_adic_domain(0, 1), from_const(42));
1602 }
1603
1604 #[test]
1605 fn test_encode2_one_value_2() {
1606 let p1 = Polynomial::encode2(vec![from_const(42)]);
1607 let p2 = Polynomial::encode2(vec![from_const(123)]);
1608 assert_eq!(p2.len(), 1);
1609 assert_eq!(p2.degree_bound(), 1);
1610 assert_ne!(p1, p2);
1611 assert_eq!(
1612 p2.evaluate(Polynomial::domain_element2(0, 1)),
1613 from_const(123)
1614 );
1615 assert_eq!(p2.evaluate_on_two_adic_domain(0, 1), from_const(123));
1616 }
1617
1618 #[test]
1619 fn test_encode2_two_values_1() {
1620 let p1 = Polynomial::encode2(vec![from_const(12), from_const(34)]);
1621 let p2 = Polynomial::encode2(vec![from_const(12), from_const(34)]);
1622 assert_eq!(p1, p2);
1623 assert_eq!(p1.len(), 2);
1624 assert_eq!(p1.degree_bound(), 2);
1625 assert_eq!(p2.len(), 2);
1626 assert_eq!(p2.degree_bound(), 2);
1627 assert_eq!(
1628 p1.evaluate(Polynomial::domain_element2(0, 2)),
1629 from_const(12)
1630 );
1631 assert_eq!(p1.evaluate_on_two_adic_domain(0, 2), from_const(12));
1632 assert_eq!(
1633 p1.evaluate(Polynomial::domain_element2(1, 2)),
1634 from_const(34)
1635 );
1636 assert_eq!(p1.evaluate_on_two_adic_domain(1, 2), from_const(34));
1637 assert_eq!(
1638 p2.evaluate(Polynomial::domain_element2(0, 2)),
1639 from_const(12)
1640 );
1641 assert_eq!(p2.evaluate_on_two_adic_domain(0, 2), from_const(12));
1642 assert_eq!(
1643 p2.evaluate(Polynomial::domain_element2(1, 2)),
1644 from_const(34)
1645 );
1646 assert_eq!(p2.evaluate_on_two_adic_domain(1, 2), from_const(34));
1647 }
1648
1649 #[test]
1650 fn test_encode2_two_values_2() {
1651 let p1 = Polynomial::encode2(vec![from_const(12), from_const(34)]);
1652 let p2 = Polynomial::encode2(vec![from_const(78), from_const(56)]);
1653 assert_eq!(p1.len(), 2);
1654 assert_eq!(p1.degree_bound(), 2);
1655 assert_eq!(p2.len(), 2);
1656 assert_eq!(p2.degree_bound(), 2);
1657 assert_ne!(p1, p2);
1658 assert_eq!(
1659 p2.evaluate(Polynomial::domain_element2(0, 2)),
1660 from_const(78)
1661 );
1662 assert_eq!(p2.evaluate_on_two_adic_domain(0, 2), from_const(78));
1663 assert_eq!(
1664 p2.evaluate(Polynomial::domain_element2(1, 2)),
1665 from_const(56)
1666 );
1667 assert_eq!(p2.evaluate_on_two_adic_domain(1, 2), from_const(56));
1668 }
1669
1670 #[test]
1671 fn test_encode2_three_values_1() {
1672 let p1 = Polynomial::encode2(vec![from_const(12), from_const(34), from_const(56)]);
1673 let p2 = Polynomial::encode2(vec![from_const(12), from_const(34), from_const(56)]);
1674 assert_eq!(p1, p2);
1675 assert_eq!(p1.len(), 4);
1676 assert_eq!(p1.degree_bound(), 4);
1677 assert_eq!(p2.len(), 4);
1678 assert_eq!(p2.degree_bound(), 4);
1679 assert_eq!(
1680 p1.evaluate(Polynomial::domain_element2(0, 3)),
1681 from_const(12)
1682 );
1683 assert_eq!(p1.evaluate_on_two_adic_domain(0, 3), from_const(12));
1684 assert_eq!(
1685 p1.evaluate(Polynomial::domain_element2(0, 4)),
1686 from_const(12)
1687 );
1688 assert_eq!(p1.evaluate_on_two_adic_domain(0, 4), from_const(12));
1689 assert_eq!(
1690 p1.evaluate(Polynomial::domain_element2(1, 3)),
1691 from_const(34)
1692 );
1693 assert_eq!(p1.evaluate_on_two_adic_domain(1, 3), from_const(34));
1694 assert_eq!(
1695 p1.evaluate(Polynomial::domain_element2(1, 4)),
1696 from_const(34)
1697 );
1698 assert_eq!(p1.evaluate_on_two_adic_domain(1, 4), from_const(34));
1699 assert_eq!(
1700 p1.evaluate(Polynomial::domain_element2(2, 3)),
1701 from_const(56)
1702 );
1703 assert_eq!(p1.evaluate_on_two_adic_domain(2, 3), from_const(56));
1704 assert_eq!(
1705 p1.evaluate(Polynomial::domain_element2(2, 4)),
1706 from_const(56)
1707 );
1708 assert_eq!(p1.evaluate_on_two_adic_domain(2, 4), from_const(56));
1709 assert_eq!(
1710 p1.evaluate(Polynomial::domain_element2(3, 4)),
1711 from_const(0)
1712 );
1713 assert_eq!(p1.evaluate_on_two_adic_domain(3, 4), from_const(0));
1714 assert_eq!(
1715 p2.evaluate(Polynomial::domain_element2(0, 3)),
1716 from_const(12)
1717 );
1718 assert_eq!(p2.evaluate_on_two_adic_domain(0, 3), from_const(12));
1719 assert_eq!(
1720 p2.evaluate(Polynomial::domain_element2(0, 4)),
1721 from_const(12)
1722 );
1723 assert_eq!(p2.evaluate_on_two_adic_domain(0, 4), from_const(12));
1724 assert_eq!(
1725 p2.evaluate(Polynomial::domain_element2(1, 3)),
1726 from_const(34)
1727 );
1728 assert_eq!(p2.evaluate_on_two_adic_domain(1, 3), from_const(34));
1729 assert_eq!(
1730 p2.evaluate(Polynomial::domain_element2(1, 4)),
1731 from_const(34)
1732 );
1733 assert_eq!(p2.evaluate_on_two_adic_domain(1, 4), from_const(34));
1734 assert_eq!(
1735 p2.evaluate(Polynomial::domain_element2(2, 3)),
1736 from_const(56)
1737 );
1738 assert_eq!(p2.evaluate_on_two_adic_domain(2, 3), from_const(56));
1739 assert_eq!(
1740 p2.evaluate(Polynomial::domain_element2(2, 4)),
1741 from_const(56)
1742 );
1743 assert_eq!(p2.evaluate_on_two_adic_domain(2, 4), from_const(56));
1744 assert_eq!(
1745 p2.evaluate(Polynomial::domain_element2(3, 4)),
1746 from_const(0)
1747 );
1748 assert_eq!(p2.evaluate_on_two_adic_domain(3, 4), from_const(0));
1749 }
1750
1751 #[test]
1752 fn test_encode2_three_values_2() {
1753 let p1 = Polynomial::encode2(vec![from_const(12), from_const(34), from_const(56)]);
1754 let p2 = Polynomial::encode2(vec![from_const(90), from_const(78), from_const(34)]);
1755 assert_eq!(p1.len(), 4);
1756 assert_eq!(p1.degree_bound(), 4);
1757 assert_eq!(p2.len(), 4);
1758 assert_eq!(p2.degree_bound(), 4);
1759 assert_ne!(p1, p2);
1760 assert_eq!(
1761 p2.evaluate(Polynomial::domain_element2(0, 3)),
1762 from_const(90)
1763 );
1764 assert_eq!(p2.evaluate_on_two_adic_domain(0, 3), from_const(90));
1765 assert_eq!(
1766 p2.evaluate(Polynomial::domain_element2(0, 4)),
1767 from_const(90)
1768 );
1769 assert_eq!(p2.evaluate_on_two_adic_domain(0, 4), from_const(90));
1770 assert_eq!(
1771 p2.evaluate(Polynomial::domain_element2(1, 3)),
1772 from_const(78)
1773 );
1774 assert_eq!(p2.evaluate_on_two_adic_domain(1, 3), from_const(78));
1775 assert_eq!(
1776 p2.evaluate(Polynomial::domain_element2(1, 4)),
1777 from_const(78)
1778 );
1779 assert_eq!(p2.evaluate_on_two_adic_domain(1, 4), from_const(78));
1780 assert_eq!(
1781 p2.evaluate(Polynomial::domain_element2(2, 3)),
1782 from_const(34)
1783 );
1784 assert_eq!(p2.evaluate_on_two_adic_domain(2, 3), from_const(34));
1785 assert_eq!(
1786 p2.evaluate(Polynomial::domain_element2(2, 4)),
1787 from_const(34)
1788 );
1789 assert_eq!(p2.evaluate_on_two_adic_domain(2, 4), from_const(34));
1790 assert_eq!(
1791 p2.evaluate(Polynomial::domain_element2(3, 4)),
1792 from_const(0)
1793 );
1794 assert_eq!(p2.evaluate_on_two_adic_domain(3, 4), from_const(0));
1795 }
1796
1797 #[test]
1798 fn test_encode2_four_values() {
1799 let p = Polynomial::encode2(vec![
1800 from_const(12),
1801 from_const(34),
1802 from_const(56),
1803 from_const(78),
1804 ]);
1805 assert_eq!(p.len(), 4);
1806 assert_eq!(p.degree_bound(), 4);
1807 assert_eq!(
1808 p.evaluate(Polynomial::domain_element2(0, 4)),
1809 from_const(12)
1810 );
1811 assert_eq!(p.evaluate_on_two_adic_domain(0, 4), from_const(12));
1812 assert_eq!(
1813 p.evaluate(Polynomial::domain_element2(1, 4)),
1814 from_const(34)
1815 );
1816 assert_eq!(p.evaluate_on_two_adic_domain(1, 4), from_const(34));
1817 assert_eq!(
1818 p.evaluate(Polynomial::domain_element2(2, 4)),
1819 from_const(56)
1820 );
1821 assert_eq!(p.evaluate_on_two_adic_domain(2, 4), from_const(56));
1822 assert_eq!(
1823 p.evaluate(Polynomial::domain_element2(3, 4)),
1824 from_const(78)
1825 );
1826 assert_eq!(p.evaluate_on_two_adic_domain(3, 4), from_const(78));
1827 }
1828
1829 #[test]
1830 fn test_decode2_one_value() {
1831 let values = vec![from_const(42)];
1832 let polynomial = Polynomial::encode2(values.clone());
1833 assert_eq!(polynomial.decode2(), values);
1834 }
1835
1836 #[test]
1837 fn test_decode2_two_values() {
1838 let values = vec![from_const(12), from_const(34)];
1839 let polynomial = Polynomial::encode2(values.clone());
1840 assert_eq!(polynomial.decode2(), values);
1841 }
1842
1843 #[test]
1844 fn test_decode2_three_values() {
1845 let polynomial = Polynomial::encode2(vec![from_const(12), from_const(34), from_const(56)]);
1846 assert_eq!(
1847 polynomial.decode2(),
1848 vec![
1849 from_const(12),
1850 from_const(34),
1851 from_const(56),
1852 from_const(0)
1853 ]
1854 );
1855 }
1856
1857 #[test]
1858 fn test_decode2_four_values() {
1859 let values = vec![
1860 from_const(12),
1861 from_const(34),
1862 from_const(56),
1863 from_const(78),
1864 ];
1865 let polynomial = Polynomial::encode2(values.clone());
1866 assert_eq!(polynomial.decode2(), values);
1867 }
1868
1869 #[test]
1870 fn test_encode3_one_value_1() {
1871 let p1 = Polynomial::encode3(vec![from_const(42)]);
1872 let p2 = Polynomial::encode3(vec![from_const(42)]);
1873 assert_eq!(p1, p2);
1874 assert_eq!(p1.len(), 1);
1875 assert_eq!(p1.degree_bound(), 1);
1876 assert_eq!(p2.len(), 1);
1877 assert_eq!(p2.degree_bound(), 1);
1878 assert_eq!(
1879 p1.evaluate(Polynomial::domain_element3(0, 1)),
1880 from_const(42)
1881 );
1882 assert_eq!(p1.evaluate_on_three_adic_domain(0, 1), from_const(42));
1883 assert_eq!(
1884 p2.evaluate(Polynomial::domain_element3(0, 1)),
1885 from_const(42)
1886 );
1887 assert_eq!(p2.evaluate_on_three_adic_domain(0, 1), from_const(42));
1888 }
1889
1890 #[test]
1891 fn test_encode3_one_value_2() {
1892 let p1 = Polynomial::encode3(vec![from_const(42)]);
1893 let p2 = Polynomial::encode3(vec![from_const(123)]);
1894 assert_eq!(p2.len(), 1);
1895 assert_eq!(p2.degree_bound(), 1);
1896 assert_ne!(p1, p2);
1897 assert_eq!(
1898 p2.evaluate(Polynomial::domain_element3(0, 1)),
1899 from_const(123)
1900 );
1901 assert_eq!(p2.evaluate_on_three_adic_domain(0, 1), from_const(123));
1902 }
1903
1904 #[test]
1905 fn test_encode3_two_values_1() {
1906 let p1 = Polynomial::encode3(vec![from_const(12), from_const(34)]);
1907 let p2 = Polynomial::encode3(vec![from_const(12), from_const(34)]);
1908 assert_eq!(p1, p2);
1909 assert_eq!(p1.len(), 3);
1910 assert_eq!(p1.degree_bound(), 3);
1911 assert_eq!(p2.len(), 3);
1912 assert_eq!(p2.degree_bound(), 3);
1913 assert_eq!(
1914 p1.evaluate(Polynomial::domain_element3(0, 2)),
1915 from_const(12)
1916 );
1917 assert_eq!(p1.evaluate_on_three_adic_domain(0, 2), from_const(12));
1918 assert_eq!(
1919 p1.evaluate(Polynomial::domain_element3(0, 3)),
1920 from_const(12)
1921 );
1922 assert_eq!(p1.evaluate_on_three_adic_domain(0, 3), from_const(12));
1923 assert_eq!(
1924 p1.evaluate(Polynomial::domain_element3(1, 2)),
1925 from_const(34)
1926 );
1927 assert_eq!(p1.evaluate_on_three_adic_domain(1, 2), from_const(34));
1928 assert_eq!(
1929 p1.evaluate(Polynomial::domain_element3(1, 3)),
1930 from_const(34)
1931 );
1932 assert_eq!(p1.evaluate_on_three_adic_domain(1, 3), from_const(34));
1933 assert_eq!(
1934 p1.evaluate(Polynomial::domain_element3(2, 3)),
1935 from_const(0)
1936 );
1937 assert_eq!(p1.evaluate_on_three_adic_domain(2, 3), from_const(0));
1938 assert_eq!(
1939 p2.evaluate(Polynomial::domain_element3(0, 2)),
1940 from_const(12)
1941 );
1942 assert_eq!(p2.evaluate_on_three_adic_domain(0, 2), from_const(12));
1943 assert_eq!(
1944 p2.evaluate(Polynomial::domain_element3(0, 3)),
1945 from_const(12)
1946 );
1947 assert_eq!(p2.evaluate_on_three_adic_domain(0, 3), from_const(12));
1948 assert_eq!(
1949 p2.evaluate(Polynomial::domain_element3(1, 2)),
1950 from_const(34)
1951 );
1952 assert_eq!(p2.evaluate_on_three_adic_domain(1, 2), from_const(34));
1953 assert_eq!(
1954 p2.evaluate(Polynomial::domain_element3(1, 3)),
1955 from_const(34)
1956 );
1957 assert_eq!(p2.evaluate_on_three_adic_domain(1, 3), from_const(34));
1958 assert_eq!(
1959 p2.evaluate(Polynomial::domain_element3(2, 3)),
1960 from_const(0)
1961 );
1962 assert_eq!(p2.evaluate_on_three_adic_domain(2, 3), from_const(0));
1963 }
1964
1965 #[test]
1966 fn test_encode3_two_values_2() {
1967 let p1 = Polynomial::encode3(vec![from_const(12), from_const(34)]);
1968 let p2 = Polynomial::encode3(vec![from_const(78), from_const(56)]);
1969 assert_eq!(p1.len(), 3);
1970 assert_eq!(p1.degree_bound(), 3);
1971 assert_eq!(p2.len(), 3);
1972 assert_eq!(p2.degree_bound(), 3);
1973 assert_ne!(p1, p2);
1974 assert_eq!(
1975 p2.evaluate(Polynomial::domain_element3(0, 2)),
1976 from_const(78)
1977 );
1978 assert_eq!(p2.evaluate_on_three_adic_domain(0, 2), from_const(78));
1979 assert_eq!(
1980 p2.evaluate(Polynomial::domain_element3(1, 2)),
1981 from_const(56)
1982 );
1983 assert_eq!(p2.evaluate_on_three_adic_domain(1, 2), from_const(56));
1984 assert_eq!(
1985 p2.evaluate(Polynomial::domain_element3(2, 3)),
1986 from_const(0)
1987 );
1988 assert_eq!(p2.evaluate_on_three_adic_domain(2, 3), from_const(0));
1989 }
1990
1991 #[test]
1992 fn test_encode3_three_values_1() {
1993 let p1 = Polynomial::encode3(vec![from_const(12), from_const(34), from_const(56)]);
1994 let p2 = Polynomial::encode3(vec![from_const(12), from_const(34), from_const(56)]);
1995 assert_eq!(p1, p2);
1996 assert_eq!(p1.len(), 3);
1997 assert_eq!(p1.degree_bound(), 3);
1998 assert_eq!(p2.len(), 3);
1999 assert_eq!(p2.degree_bound(), 3);
2000 assert_eq!(
2001 p1.evaluate(Polynomial::domain_element3(0, 3)),
2002 from_const(12)
2003 );
2004 assert_eq!(p1.evaluate_on_three_adic_domain(0, 3), from_const(12));
2005 assert_eq!(
2006 p1.evaluate(Polynomial::domain_element3(1, 3)),
2007 from_const(34)
2008 );
2009 assert_eq!(p1.evaluate_on_three_adic_domain(1, 3), from_const(34));
2010 assert_eq!(
2011 p1.evaluate(Polynomial::domain_element3(2, 3)),
2012 from_const(56)
2013 );
2014 assert_eq!(p1.evaluate_on_three_adic_domain(2, 3), from_const(56));
2015 assert_eq!(
2016 p2.evaluate(Polynomial::domain_element3(0, 3)),
2017 from_const(12)
2018 );
2019 assert_eq!(p2.evaluate_on_three_adic_domain(0, 3), from_const(12));
2020 assert_eq!(
2021 p2.evaluate(Polynomial::domain_element3(1, 3)),
2022 from_const(34)
2023 );
2024 assert_eq!(p2.evaluate_on_three_adic_domain(1, 3), from_const(34));
2025 assert_eq!(
2026 p2.evaluate(Polynomial::domain_element3(2, 3)),
2027 from_const(56)
2028 );
2029 assert_eq!(p2.evaluate_on_three_adic_domain(2, 3), from_const(56));
2030 }
2031
2032 #[test]
2033 fn test_encode3_three_values_2() {
2034 let p1 = Polynomial::encode3(vec![from_const(12), from_const(34), from_const(56)]);
2035 let p2 = Polynomial::encode3(vec![from_const(90), from_const(78), from_const(34)]);
2036 assert_eq!(p1.len(), 3);
2037 assert_eq!(p1.degree_bound(), 3);
2038 assert_eq!(p2.len(), 3);
2039 assert_eq!(p2.degree_bound(), 3);
2040 assert_ne!(p1, p2);
2041 assert_eq!(
2042 p2.evaluate(Polynomial::domain_element3(0, 3)),
2043 from_const(90)
2044 );
2045 assert_eq!(p2.evaluate_on_three_adic_domain(0, 3), from_const(90));
2046 assert_eq!(
2047 p2.evaluate(Polynomial::domain_element3(1, 3)),
2048 from_const(78)
2049 );
2050 assert_eq!(p2.evaluate_on_three_adic_domain(1, 3), from_const(78));
2051 assert_eq!(
2052 p2.evaluate(Polynomial::domain_element3(2, 3)),
2053 from_const(34)
2054 );
2055 assert_eq!(p2.evaluate_on_three_adic_domain(2, 3), from_const(34));
2056 }
2057
2058 #[test]
2059 fn test_encode3_nine_values3() {
2060 let p = Polynomial::encode3(vec![
2061 from_const(12),
2062 from_const(34),
2063 from_const(56),
2064 from_const(78),
2065 from_const(90),
2066 from_const(11),
2067 from_const(22),
2068 from_const(33),
2069 from_const(44),
2070 ]);
2071 assert_eq!(p.len(), 9);
2072 assert_eq!(p.degree_bound(), 9);
2073 assert_eq!(
2074 p.evaluate(Polynomial::domain_element3(0, 9)),
2075 from_const(12)
2076 );
2077 assert_eq!(p.evaluate_on_three_adic_domain(0, 9), from_const(12));
2078 assert_eq!(
2079 p.evaluate(Polynomial::domain_element3(1, 9)),
2080 from_const(34)
2081 );
2082 assert_eq!(p.evaluate_on_three_adic_domain(1, 9), from_const(34));
2083 assert_eq!(
2084 p.evaluate(Polynomial::domain_element3(2, 9)),
2085 from_const(56)
2086 );
2087 assert_eq!(p.evaluate_on_three_adic_domain(2, 9), from_const(56));
2088 assert_eq!(
2089 p.evaluate(Polynomial::domain_element3(3, 9)),
2090 from_const(78)
2091 );
2092 assert_eq!(p.evaluate_on_three_adic_domain(3, 9), from_const(78));
2093 assert_eq!(
2094 p.evaluate(Polynomial::domain_element3(4, 9)),
2095 from_const(90)
2096 );
2097 assert_eq!(p.evaluate_on_three_adic_domain(4, 9), from_const(90));
2098 assert_eq!(
2099 p.evaluate(Polynomial::domain_element3(5, 9)),
2100 from_const(11)
2101 );
2102 assert_eq!(p.evaluate_on_three_adic_domain(5, 9), from_const(11));
2103 assert_eq!(
2104 p.evaluate(Polynomial::domain_element3(6, 9)),
2105 from_const(22)
2106 );
2107 assert_eq!(p.evaluate_on_three_adic_domain(6, 9), from_const(22));
2108 assert_eq!(
2109 p.evaluate(Polynomial::domain_element3(7, 9)),
2110 from_const(33)
2111 );
2112 assert_eq!(p.evaluate_on_three_adic_domain(7, 9), from_const(33));
2113 assert_eq!(
2114 p.evaluate(Polynomial::domain_element3(8, 9)),
2115 from_const(44)
2116 );
2117 assert_eq!(p.evaluate_on_three_adic_domain(8, 9), from_const(44));
2118 }
2119
2120 #[test]
2121 fn test_decode3_one_value() {
2122 let values = vec![from_const(42)];
2123 let polynomial = Polynomial::encode3(values.clone());
2124 assert_eq!(polynomial.decode3(), values);
2125 }
2126
2127 #[test]
2128 fn test_decode3_two_values() {
2129 let values = vec![from_const(12), from_const(34)];
2130 let polynomial = Polynomial::encode3(values.clone());
2131 assert_eq!(
2132 polynomial.decode3(),
2133 vec![from_const(12), from_const(34), from_const(0)]
2134 );
2135 }
2136
2137 #[test]
2138 fn test_decode3_three_values() {
2139 let values = vec![from_const(12), from_const(34), from_const(56)];
2140 let polynomial = Polynomial::encode3(values.clone());
2141 assert_eq!(polynomial.decode3(), values);
2142 }
2143
2144 #[test]
2145 fn test_decode3_nine_values() {
2146 let values = vec![
2147 from_const(12),
2148 from_const(34),
2149 from_const(56),
2150 from_const(78),
2151 from_const(90),
2152 from_const(11),
2153 from_const(22),
2154 from_const(33),
2155 from_const(44),
2156 ];
2157 let polynomial = Polynomial::encode3(values.clone());
2158 assert_eq!(polynomial.decode3(), values);
2159 }
2160
2161 #[test]
2162 fn test_add_same_length() {
2163 let p1 = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2164 let p2 =
2165 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2166 assert_eq!(
2167 p1 + p2,
2168 Polynomial::with_coefficients(vec![from_const(11), from_const(22), from_const(33)])
2169 );
2170 }
2171
2172 #[test]
2173 fn test_add_lhs_longer() {
2174 let p1 = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2175 let p2 = Polynomial::with_coefficients(vec![from_const(10), from_const(20)]);
2176 assert_eq!(
2177 p1 + p2,
2178 Polynomial::with_coefficients(vec![from_const(11), from_const(22), from_const(3)])
2179 );
2180 }
2181
2182 #[test]
2183 fn test_add_rhs_longer() {
2184 let p1 = Polynomial::with_coefficients(vec![from_const(1), from_const(2)]);
2185 let p2 =
2186 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2187 assert_eq!(
2188 p1 + p2,
2189 Polynomial::with_coefficients(vec![from_const(11), from_const(22), from_const(30)])
2190 );
2191 }
2192
2193 #[test]
2194 fn test_add_commutative() {
2195 let p1 = Polynomial::with_coefficients(vec![from_const(1), from_const(2)]);
2196 let p2 =
2197 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2198 assert_eq!(p1.clone() + p2.clone(), p2 + p1);
2199 }
2200
2201 #[test]
2202 fn test_add_ref_same_length() {
2203 let p1 = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2204 let p2 =
2205 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2206 assert_eq!(
2207 p1 + &p2,
2208 Polynomial::with_coefficients(vec![from_const(11), from_const(22), from_const(33)])
2209 );
2210 }
2211
2212 #[test]
2213 fn test_add_ref_lhs_longer() {
2214 let p1 = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2215 let p2 = Polynomial::with_coefficients(vec![from_const(10), from_const(20)]);
2216 assert_eq!(
2217 p1 + &p2,
2218 Polynomial::with_coefficients(vec![from_const(11), from_const(22), from_const(3)])
2219 );
2220 }
2221
2222 #[test]
2223 fn test_add_ref_rhs_longer() {
2224 let p1 = Polynomial::with_coefficients(vec![from_const(1), from_const(2)]);
2225 let p2 =
2226 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2227 assert_eq!(
2228 p1 + &p2,
2229 Polynomial::with_coefficients(vec![from_const(11), from_const(22), from_const(30)])
2230 );
2231 }
2232
2233 #[test]
2234 fn test_add_ref_consistent_with_add() {
2235 let p1 = Polynomial::with_coefficients(vec![from_const(1), from_const(2)]);
2236 let p2 =
2237 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2238 assert_eq!(p1.clone() + &p2, p1 + p2);
2239 }
2240
2241 #[test]
2242 fn test_add_assign_same_length() {
2243 let mut p1 =
2244 Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2245 let p2 =
2246 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2247 p1 += p2;
2248 assert_eq!(
2249 p1,
2250 Polynomial::with_coefficients(vec![from_const(11), from_const(22), from_const(33)])
2251 );
2252 }
2253
2254 #[test]
2255 fn test_add_assign_lhs_longer() {
2256 let mut p1 =
2257 Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2258 let p2 = Polynomial::with_coefficients(vec![from_const(10), from_const(20)]);
2259 p1 += p2;
2260 assert_eq!(
2261 p1,
2262 Polynomial::with_coefficients(vec![from_const(11), from_const(22), from_const(3)])
2263 );
2264 }
2265
2266 #[test]
2267 fn test_add_assign_rhs_longer() {
2268 let mut p1 = Polynomial::with_coefficients(vec![from_const(1), from_const(2)]);
2269 let p2 =
2270 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2271 p1 += p2;
2272 assert_eq!(
2273 p1,
2274 Polynomial::with_coefficients(vec![from_const(11), from_const(22), from_const(30)])
2275 );
2276 }
2277
2278 #[test]
2279 fn test_add_assign_consistent_with_add() {
2280 let p1 = Polynomial::with_coefficients(vec![from_const(1), from_const(2)]);
2281 let p2 =
2282 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2283 let mut p1_assign = p1.clone();
2284 p1_assign += p2.clone();
2285 assert_eq!(p1_assign, p1 + p2);
2286 }
2287
2288 #[test]
2289 fn test_add_assign_ref_same_length() {
2290 let mut p1 =
2291 Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2292 let p2 =
2293 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2294 p1 += &p2;
2295 assert_eq!(
2296 p1,
2297 Polynomial::with_coefficients(vec![from_const(11), from_const(22), from_const(33)])
2298 );
2299 }
2300
2301 #[test]
2302 fn test_add_assign_ref_lhs_longer() {
2303 let mut p1 =
2304 Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2305 let p2 = Polynomial::with_coefficients(vec![from_const(10), from_const(20)]);
2306 p1 += &p2;
2307 assert_eq!(
2308 p1,
2309 Polynomial::with_coefficients(vec![from_const(11), from_const(22), from_const(3)])
2310 );
2311 }
2312
2313 #[test]
2314 fn test_add_assign_ref_rhs_longer() {
2315 let mut p1 = Polynomial::with_coefficients(vec![from_const(1), from_const(2)]);
2316 let p2 =
2317 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2318 p1 += &p2;
2319 assert_eq!(
2320 p1,
2321 Polynomial::with_coefficients(vec![from_const(11), from_const(22), from_const(30)])
2322 );
2323 }
2324
2325 #[test]
2326 fn test_add_assign_ref_consistent_with_add_assign() {
2327 let p1 = Polynomial::with_coefficients(vec![from_const(1), from_const(2)]);
2328 let p2 =
2329 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2330 let mut p1_assign_ref = p1.clone();
2331 p1_assign_ref += &p2;
2332 let mut p1_assign = p1;
2333 p1_assign += p2;
2334 assert_eq!(p1_assign_ref, p1_assign);
2335 }
2336
2337 #[test]
2338 fn test_sum_empty() {
2339 let polynomials: Vec<Polynomial> = vec![];
2340 assert_eq!(
2341 polynomials.into_iter().sum::<Polynomial>(),
2342 Polynomial::default()
2343 );
2344 }
2345
2346 #[test]
2347 fn test_sum_one_polynomial() {
2348 let p = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2349 assert_eq!(vec![p.clone()].into_iter().sum::<Polynomial>(), p);
2350 }
2351
2352 #[test]
2353 fn test_sum_several_polynomials() {
2354 let p1 = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2355 let p2 = Polynomial::with_coefficients(vec![from_const(10), from_const(20)]);
2356 let p3 = Polynomial::with_coefficients(vec![from_const(100)]);
2357 assert_eq!(
2358 vec![p1.clone(), p2.clone(), p3.clone()]
2359 .into_iter()
2360 .sum::<Polynomial>(),
2361 p1 + p2 + p3
2362 );
2363 }
2364
2365 #[test]
2366 fn test_sum_ref_empty() {
2367 let polynomials: Vec<Polynomial> = vec![];
2368 assert_eq!(
2369 polynomials.iter().sum::<Polynomial>(),
2370 Polynomial::default()
2371 );
2372 }
2373
2374 #[test]
2375 fn test_sum_ref_one_polynomial() {
2376 let p = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2377 assert_eq!([p.clone()].iter().sum::<Polynomial>(), p);
2378 }
2379
2380 #[test]
2381 fn test_sum_ref_several_polynomials() {
2382 let p1 = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2383 let p2 = Polynomial::with_coefficients(vec![from_const(10), from_const(20)]);
2384 let p3 = Polynomial::with_coefficients(vec![from_const(100)]);
2385 let polynomials = [p1.clone(), p2.clone(), p3.clone()];
2386 assert_eq!(polynomials.iter().sum::<Polynomial>(), p1 + p2 + p3);
2387 }
2388
2389 #[test]
2390 fn test_sum_ref_consistent_with_sum() {
2391 let p1 = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2392 let p2 = Polynomial::with_coefficients(vec![from_const(10), from_const(20)]);
2393 let polynomials = vec![p1, p2];
2394 assert_eq!(
2395 polynomials.iter().sum::<Polynomial>(),
2396 polynomials.into_iter().sum::<Polynomial>()
2397 );
2398 }
2399
2400 #[test]
2401 fn test_sub_same_length() {
2402 let p1 =
2403 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2404 let p2 = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2405 assert_eq!(
2406 p1 - p2,
2407 Polynomial::with_coefficients(vec![from_const(9), from_const(18), from_const(27)])
2408 );
2409 }
2410
2411 #[test]
2412 fn test_sub_lhs_longer() {
2413 let p1 =
2414 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2415 let p2 = Polynomial::with_coefficients(vec![from_const(1), from_const(2)]);
2416 assert_eq!(
2417 p1 - p2,
2418 Polynomial::with_coefficients(vec![from_const(9), from_const(18), from_const(30)])
2419 );
2420 }
2421
2422 #[test]
2423 fn test_sub_rhs_longer() {
2424 let p1 = Polynomial::with_coefficients(vec![from_const(10), from_const(20)]);
2425 let p2 = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2426 assert_eq!(
2427 p1 - p2,
2428 Polynomial::with_coefficients(vec![from_const(9), from_const(18), -from_const(3)])
2429 );
2430 }
2431
2432 #[test]
2433 fn test_sub_anticommutative() {
2434 let p1 = Polynomial::with_coefficients(vec![from_const(10), from_const(20)]);
2435 let p2 = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2436 assert_eq!(p1.clone() - p2.clone(), -(p2 - p1));
2437 }
2438
2439 #[test]
2440 fn test_sub_ref_same_length() {
2441 let p1 =
2442 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2443 let p2 = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2444 assert_eq!(
2445 p1 - &p2,
2446 Polynomial::with_coefficients(vec![from_const(9), from_const(18), from_const(27)])
2447 );
2448 }
2449
2450 #[test]
2451 fn test_sub_ref_lhs_longer() {
2452 let p1 =
2453 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2454 let p2 = Polynomial::with_coefficients(vec![from_const(1), from_const(2)]);
2455 assert_eq!(
2456 p1 - &p2,
2457 Polynomial::with_coefficients(vec![from_const(9), from_const(18), from_const(30)])
2458 );
2459 }
2460
2461 #[test]
2462 fn test_sub_ref_rhs_longer() {
2463 let p1 = Polynomial::with_coefficients(vec![from_const(10), from_const(20)]);
2464 let p2 = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2465 assert_eq!(
2466 p1 - &p2,
2467 Polynomial::with_coefficients(vec![from_const(9), from_const(18), -from_const(3)])
2468 );
2469 }
2470
2471 #[test]
2472 fn test_sub_ref_consistent_with_sub() {
2473 let p1 = Polynomial::with_coefficients(vec![from_const(10), from_const(20)]);
2474 let p2 = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2475 assert_eq!(p1.clone() - &p2, p1 - p2);
2476 }
2477
2478 #[test]
2479 fn test_sub_assign_same_length() {
2480 let mut p1 =
2481 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2482 let p2 = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2483 p1 -= p2;
2484 assert_eq!(
2485 p1,
2486 Polynomial::with_coefficients(vec![from_const(9), from_const(18), from_const(27)])
2487 );
2488 }
2489
2490 #[test]
2491 fn test_sub_assign_lhs_longer() {
2492 let mut p1 =
2493 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2494 let p2 = Polynomial::with_coefficients(vec![from_const(1), from_const(2)]);
2495 p1 -= p2;
2496 assert_eq!(
2497 p1,
2498 Polynomial::with_coefficients(vec![from_const(9), from_const(18), from_const(30)])
2499 );
2500 }
2501
2502 #[test]
2503 fn test_sub_assign_rhs_longer() {
2504 let mut p1 = Polynomial::with_coefficients(vec![from_const(10), from_const(20)]);
2505 let p2 = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2506 p1 -= p2;
2507 assert_eq!(
2508 p1,
2509 Polynomial::with_coefficients(vec![from_const(9), from_const(18), -from_const(3)])
2510 );
2511 }
2512
2513 #[test]
2514 fn test_sub_assign_consistent_with_sub() {
2515 let p1 = Polynomial::with_coefficients(vec![from_const(10), from_const(20)]);
2516 let p2 = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2517 let mut p1_assign = p1.clone();
2518 p1_assign -= p2.clone();
2519 assert_eq!(p1_assign, p1 - p2);
2520 }
2521
2522 #[test]
2523 fn test_sub_assign_ref_same_length() {
2524 let mut p1 =
2525 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2526 let p2 = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2527 p1 -= &p2;
2528 assert_eq!(
2529 p1,
2530 Polynomial::with_coefficients(vec![from_const(9), from_const(18), from_const(27)])
2531 );
2532 }
2533
2534 #[test]
2535 fn test_sub_assign_ref_lhs_longer() {
2536 let mut p1 =
2537 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2538 let p2 = Polynomial::with_coefficients(vec![from_const(1), from_const(2)]);
2539 p1 -= &p2;
2540 assert_eq!(
2541 p1,
2542 Polynomial::with_coefficients(vec![from_const(9), from_const(18), from_const(30)])
2543 );
2544 }
2545
2546 #[test]
2547 fn test_sub_assign_ref_rhs_longer() {
2548 let mut p1 = Polynomial::with_coefficients(vec![from_const(10), from_const(20)]);
2549 let p2 = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2550 p1 -= &p2;
2551 assert_eq!(
2552 p1,
2553 Polynomial::with_coefficients(vec![from_const(9), from_const(18), -from_const(3)])
2554 );
2555 }
2556
2557 #[test]
2558 fn test_sub_assign_ref_consistent_with_sub_assign() {
2559 let p1 = Polynomial::with_coefficients(vec![from_const(10), from_const(20)]);
2560 let p2 = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2561 let mut p1_assign_ref = p1.clone();
2562 p1_assign_ref -= &p2;
2563 let mut p1_assign = p1;
2564 p1_assign -= p2;
2565 assert_eq!(p1_assign_ref, p1_assign);
2566 }
2567
2568 #[test]
2569 fn test_multiply_empty() {
2570 let p1 = Polynomial::default();
2571 let p2 = Polynomial::default();
2572 assert_eq!(p1.multiply(p2), Polynomial::default());
2573 }
2574
2575 #[test]
2576 fn test_multiply_empty_by_non_empty() {
2577 let p1 = Polynomial::default();
2578 let p2 = Polynomial {
2579 coefficients: vec![from_const(12), from_const(34)],
2580 };
2581 assert_eq!(p1.multiply(p2), Polynomial::default());
2582 }
2583
2584 #[test]
2585 fn test_multiply_non_empty_by_empty() {
2586 let p1 = Polynomial {
2587 coefficients: vec![from_const(56), from_const(78)],
2588 };
2589 let p2 = Polynomial::default();
2590 assert_eq!(p1.multiply(p2), Polynomial::default());
2591 }
2592
2593 #[test]
2594 fn test_multiply_constant() {
2595 let p1 = Polynomial {
2596 coefficients: vec![from_const(3)],
2597 };
2598 let p2 = Polynomial {
2599 coefficients: vec![from_const(12), from_const(34), from_const(56)],
2600 };
2601 assert_eq!(
2602 p1.multiply(p2),
2603 Polynomial {
2604 coefficients: vec![from_const(36), from_const(102), from_const(168)]
2605 }
2606 );
2607 }
2608
2609 #[test]
2610 fn test_multiply_by_constant() {
2611 let p1 = Polynomial {
2612 coefficients: vec![from_const(12), from_const(34), from_const(56)],
2613 };
2614 let p2 = Polynomial {
2615 coefficients: vec![from_const(3)],
2616 };
2617 assert_eq!(
2618 p1.multiply(p2),
2619 Polynomial {
2620 coefficients: vec![from_const(36), from_const(102), from_const(168)]
2621 }
2622 );
2623 }
2624
2625 #[test]
2626 fn test_multiply_constant_by_constant() {
2627 let p1 = Polynomial {
2628 coefficients: vec![from_const(12)],
2629 };
2630 let p2 = Polynomial {
2631 coefficients: vec![from_const(34)],
2632 };
2633 assert_eq!(
2634 p1.multiply(p2),
2635 Polynomial {
2636 coefficients: vec![from_const(408)]
2637 }
2638 );
2639 }
2640
2641 #[test]
2642 fn test_multiply_polynomials1() {
2643 let p1 = Polynomial {
2644 coefficients: vec![from_const(1), from_const(2)],
2645 };
2646 let p2 = Polynomial {
2647 coefficients: vec![from_const(3), from_const(4)],
2648 };
2649 let result = Polynomial {
2650 coefficients: vec![from_const(3), from_const(10), from_const(8)],
2651 };
2652 assert_eq!(p1.clone().multiply(p2.clone()), result);
2653 assert_eq!(p2.multiply(p1), result);
2654 }
2655
2656 #[test]
2657 fn test_multiply_polynomials2() {
2658 let p1 = Polynomial {
2659 coefficients: vec![from_const(1), from_const(2)],
2660 };
2661 let p2 = Polynomial {
2662 coefficients: vec![from_const(3), from_const(4), from_const(5)],
2663 };
2664 let result = Polynomial {
2665 coefficients: vec![
2666 from_const(3),
2667 from_const(10),
2668 from_const(13),
2669 from_const(10),
2670 ],
2671 };
2672 assert_eq!(p1.clone().multiply(p2.clone()), result);
2673 assert_eq!(p2.multiply(p1), result);
2674 }
2675
2676 #[test]
2677 fn test_polynomial_mul_op() {
2678 let p1 = Polynomial {
2679 coefficients: vec![from_const(1), from_const(2)],
2680 };
2681 let p2 = Polynomial {
2682 coefficients: vec![from_const(3), from_const(4), from_const(5)],
2683 };
2684 let result = Polynomial {
2685 coefficients: vec![
2686 from_const(3),
2687 from_const(10),
2688 from_const(13),
2689 from_const(10),
2690 ],
2691 };
2692 assert_eq!(p1.clone() * p2.clone(), result);
2693 assert_eq!(p2 * p1, result);
2694 }
2695
2696 #[test]
2697 fn test_polynomial_mul_ref_op() {
2698 let p1 = Polynomial {
2699 coefficients: vec![from_const(1), from_const(2)],
2700 };
2701 let p2 = Polynomial {
2702 coefficients: vec![from_const(3), from_const(4), from_const(5)],
2703 };
2704 let result = Polynomial {
2705 coefficients: vec![
2706 from_const(3),
2707 from_const(10),
2708 from_const(13),
2709 from_const(10),
2710 ],
2711 };
2712 assert_eq!(p1.clone() * &p2, result);
2713 assert_eq!(p2 * &p1, result);
2714 }
2715
2716 #[test]
2717 fn test_polynomial_mul_assign() {
2718 let mut p1 = Polynomial {
2719 coefficients: vec![from_const(1), from_const(2)],
2720 };
2721 let p2 = Polynomial {
2722 coefficients: vec![from_const(3), from_const(4), from_const(5)],
2723 };
2724 p1 *= p2;
2725 assert_eq!(
2726 p1,
2727 Polynomial {
2728 coefficients: vec![
2729 from_const(3),
2730 from_const(10),
2731 from_const(13),
2732 from_const(10)
2733 ],
2734 }
2735 );
2736 }
2737
2738 #[test]
2739 fn test_polynomial_mul_assign_ref() {
2740 let mut p1 = Polynomial {
2741 coefficients: vec![from_const(1), from_const(2)],
2742 };
2743 let p2 = Polynomial {
2744 coefficients: vec![from_const(3), from_const(4), from_const(5)],
2745 };
2746 p1 *= &p2;
2747 assert_eq!(
2748 p1,
2749 Polynomial {
2750 coefficients: vec![
2751 from_const(3),
2752 from_const(10),
2753 from_const(13),
2754 from_const(10)
2755 ],
2756 }
2757 );
2758 }
2759
2760 #[test]
2761 fn test_multiply_no_polynomials() {
2762 assert_eq!(
2763 Polynomial::multiply_batch(&[]),
2764 Polynomial::default() + Scalar::ONE
2765 );
2766 }
2767
2768 #[test]
2769 fn test_multiply_one_polynomial() {
2770 let p = Polynomial {
2771 coefficients: vec![from_const(12), from_const(34)],
2772 };
2773 assert_eq!(Polynomial::multiply_batch(&[p.clone()]), p);
2774 }
2775
2776 #[test]
2777 fn test_multiply_two_polynomials() {
2778 let p1 = Polynomial {
2779 coefficients: vec![from_const(1), from_const(2)],
2780 };
2781 let p2 = Polynomial {
2782 coefficients: vec![from_const(3), from_const(4), from_const(5)],
2783 };
2784 let result = Polynomial {
2785 coefficients: vec![
2786 from_const(3),
2787 from_const(10),
2788 from_const(13),
2789 from_const(10),
2790 ],
2791 };
2792 assert_eq!(
2793 Polynomial::multiply_batch(&[p1.clone(), p2.clone()]),
2794 result
2795 );
2796 assert_eq!(Polynomial::multiply_batch(&[p2, p1]), result);
2797 }
2798
2799 #[test]
2800 fn test_multiply_three_polynomials() {
2801 let p1 = Polynomial {
2802 coefficients: vec![from_const(1), from_const(2)],
2803 };
2804 let p2 = Polynomial {
2805 coefficients: vec![from_const(3), from_const(4), from_const(5)],
2806 };
2807 let p3 = Polynomial {
2808 coefficients: vec![from_const(6), from_const(7), from_const(8), from_const(9)],
2809 };
2810 let result = Polynomial {
2811 coefficients: vec![
2812 from_const(18),
2813 from_const(81),
2814 from_const(172),
2815 from_const(258),
2816 from_const(264),
2817 from_const(197),
2818 from_const(90),
2819 ],
2820 };
2821 assert_eq!(
2822 Polynomial::multiply_batch(&[p1.clone(), p2.clone(), p3.clone()]),
2823 result
2824 );
2825 assert_eq!(
2826 Polynomial::multiply_batch(&[p1.clone(), p3.clone(), p2.clone()]),
2827 result
2828 );
2829 assert_eq!(
2830 Polynomial::multiply_batch(&[p2.clone(), p1.clone(), p3.clone()]),
2831 result
2832 );
2833 assert_eq!(
2834 Polynomial::multiply_batch(&[p2.clone(), p3.clone(), p1.clone()]),
2835 result
2836 );
2837 assert_eq!(
2838 Polynomial::multiply_batch(&[p3.clone(), p1.clone(), p2.clone()]),
2839 result
2840 );
2841 assert_eq!(
2842 Polynomial::multiply_batch(&[p3.clone(), p2.clone(), p1.clone()]),
2843 result
2844 );
2845 }
2846
2847 #[test]
2848 fn test_multiply_four_polynomials() {
2849 let p1 = Polynomial {
2850 coefficients: vec![from_const(1), from_const(2)],
2851 };
2852 let p2 = Polynomial {
2853 coefficients: vec![from_const(3), from_const(4)],
2854 };
2855 let p3 = Polynomial {
2856 coefficients: vec![from_const(5), from_const(6)],
2857 };
2858 let p4 = Polynomial {
2859 coefficients: vec![from_const(7), from_const(8)],
2860 };
2861 let result = Polynomial {
2862 coefficients: vec![
2863 from_const(105),
2864 from_const(596),
2865 from_const(1244),
2866 from_const(1136),
2867 from_const(384),
2868 ],
2869 };
2870 assert_eq!(
2871 Polynomial::multiply_batch(&[p1.clone(), p2.clone(), p3.clone(), p4.clone()]),
2872 result
2873 );
2874 assert_eq!(
2875 Polynomial::multiply_batch(&[p1.clone(), p2.clone(), p4.clone(), p3.clone()]),
2876 result
2877 );
2878 assert_eq!(
2879 Polynomial::multiply_batch(&[p1.clone(), p3.clone(), p2.clone(), p4.clone()]),
2880 result
2881 );
2882 assert_eq!(
2883 Polynomial::multiply_batch(&[p1.clone(), p3.clone(), p4.clone(), p2.clone()]),
2884 result
2885 );
2886 }
2888
2889 #[test]
2890 fn test_product_empty() {
2891 let polynomials: Vec<Polynomial> = vec![];
2892 assert_eq!(
2893 polynomials.into_iter().product::<Polynomial>(),
2894 Polynomial::multiply_batch(&[])
2895 );
2896 }
2897
2898 #[test]
2899 fn test_product_one_polynomial() {
2900 let p = Polynomial {
2901 coefficients: vec![from_const(12), from_const(34)],
2902 };
2903 assert_eq!(vec![p.clone()].into_iter().product::<Polynomial>(), p);
2904 }
2905
2906 #[test]
2907 fn test_product_several_polynomials() {
2908 let p1 = Polynomial {
2909 coefficients: vec![from_const(1), from_const(2)],
2910 };
2911 let p2 = Polynomial {
2912 coefficients: vec![from_const(3), from_const(4), from_const(5)],
2913 };
2914 let p3 = Polynomial {
2915 coefficients: vec![from_const(6), from_const(7), from_const(8), from_const(9)],
2916 };
2917 assert_eq!(
2918 vec![p1.clone(), p2.clone(), p3.clone()]
2919 .into_iter()
2920 .product::<Polynomial>(),
2921 Polynomial::multiply_batch(&[p1, p2, p3])
2922 );
2923 }
2924
2925 #[test]
2926 fn test_product_ref_empty() {
2927 let polynomials: Vec<Polynomial> = vec![];
2928 assert_eq!(
2929 polynomials.iter().product::<Polynomial>(),
2930 Polynomial::multiply_batch(&[])
2931 );
2932 }
2933
2934 #[test]
2935 fn test_product_ref_one_polynomial() {
2936 let p = Polynomial {
2937 coefficients: vec![from_const(12), from_const(34)],
2938 };
2939 assert_eq!([p.clone()].iter().product::<Polynomial>(), p);
2940 }
2941
2942 #[test]
2943 fn test_product_ref_several_polynomials() {
2944 let p1 = Polynomial {
2945 coefficients: vec![from_const(1), from_const(2)],
2946 };
2947 let p2 = Polynomial {
2948 coefficients: vec![from_const(3), from_const(4), from_const(5)],
2949 };
2950 let p3 = Polynomial {
2951 coefficients: vec![from_const(6), from_const(7), from_const(8), from_const(9)],
2952 };
2953 let polynomials = [p1.clone(), p2.clone(), p3.clone()];
2954 assert_eq!(
2955 polynomials.iter().product::<Polynomial>(),
2956 Polynomial::multiply_batch(&[p1, p2, p3])
2957 );
2958 }
2959
2960 #[test]
2961 fn test_product_ref_consistent_with_product() {
2962 let p1 = Polynomial {
2963 coefficients: vec![from_const(1), from_const(2)],
2964 };
2965 let p2 = Polynomial {
2966 coefficients: vec![from_const(3), from_const(4), from_const(5)],
2967 };
2968 let polynomials = vec![p1, p2];
2969 assert_eq!(
2970 polynomials.iter().product::<Polynomial>(),
2971 polynomials.into_iter().product::<Polynomial>()
2972 );
2973 }
2974
2975 #[test]
2976 fn test_divide_zero_by_zero() {
2977 let z = Polynomial {
2978 coefficients: vec![
2979 -from_const(1),
2980 from_const(0),
2981 from_const(0),
2982 from_const(0),
2983 from_const(1),
2984 ],
2985 };
2986 assert_eq!(
2987 z.divide_by_zero(4).unwrap(),
2988 Polynomial {
2989 coefficients: vec![from_const(1)]
2990 }
2991 );
2992 }
2993
2994 #[test]
2995 fn test_non_trivial_quotient1() {
2996 let ql = Polynomial::encode2(vec![
2997 from_const(0),
2998 from_const(0),
2999 from_const(1),
3000 from_const(1),
3001 ]);
3002 let qr = Polynomial::encode2(vec![
3003 from_const(0),
3004 from_const(0),
3005 from_const(1),
3006 from_const(1),
3007 ]);
3008 let qo = Polynomial::encode2(vec![-from_const(1); 4]);
3009 let qm = Polynomial::encode2(vec![
3010 from_const(1),
3011 from_const(1),
3012 from_const(0),
3013 from_const(0),
3014 ]);
3015 let qc = Polynomial::encode2(vec![from_const(0); 4]);
3016 let l = Polynomial::encode2(vec![
3017 from_const(3),
3018 from_const(9),
3019 from_const(3),
3020 from_const(30),
3021 ]);
3022 let r = Polynomial::encode2(vec![
3023 from_const(3),
3024 from_const(3),
3025 from_const(27),
3026 from_const(5),
3027 ]);
3028 let o = Polynomial::encode2(vec![
3029 from_const(9),
3030 from_const(27),
3031 from_const(30),
3032 from_const(35),
3033 ]);
3034 let lr = l.clone().multiply(r.clone());
3035 let p = ql.multiply(l) + qr.multiply(r) + qo.multiply(o) + qm.multiply(lr) + qc;
3036 let q = p.divide_by_zero(4).unwrap();
3037 assert_eq!(q.len(), 6);
3038 assert_eq!(q.degree_bound(), 6);
3039 }
3040
3041 #[test]
3042 fn test_non_trivial_quotient2() {
3043 let ql = Polynomial::encode2(vec![
3044 from_const(0),
3045 from_const(0),
3046 from_const(1),
3047 from_const(1),
3048 ]);
3049 let qr = Polynomial::encode2(vec![
3050 from_const(0),
3051 from_const(0),
3052 from_const(1),
3053 from_const(5),
3054 ]);
3055 let qo = Polynomial::encode2(vec![-from_const(1); 4]);
3056 let qm = Polynomial::encode2(vec![
3057 from_const(1),
3058 from_const(1),
3059 from_const(0),
3060 from_const(0),
3061 ]);
3062 let qc = Polynomial::encode2(vec![from_const(0); 4]);
3063 let l = Polynomial::encode2(vec![
3064 from_const(3),
3065 from_const(9),
3066 from_const(3),
3067 from_const(30),
3068 ]);
3069 let r = Polynomial::encode2(vec![
3070 from_const(3),
3071 from_const(3),
3072 from_const(27),
3073 from_const(1),
3074 ]);
3075 let o = Polynomial::encode2(vec![
3076 from_const(9),
3077 from_const(27),
3078 from_const(30),
3079 from_const(35),
3080 ]);
3081 let lr = l.clone().multiply(r.clone());
3082 let p = ql.multiply(l) + qr.multiply(r) + qo.multiply(o) + qm.multiply(lr) + qc;
3083 let q = p.divide_by_zero(4).unwrap();
3084 assert_eq!(q.len(), 6);
3085 assert_eq!(q.degree_bound(), 6);
3086 }
3087
3088 #[test]
3089 fn test_shift_domain2_1() {
3090 let values = vec![
3091 from_const(12),
3092 from_const(34),
3093 from_const(56),
3094 from_const(78),
3095 ];
3096 let p = Polynomial::encode2(values);
3097 let shifted = p.clone().shift_domain_by(Scalar::MULTIPLICATIVE_GENERATOR);
3098 assert_eq!(
3099 shifted.evaluate_on_two_adic_domain(0, 4),
3100 p.evaluate_on_two_adic_coset(0, 4)
3101 );
3102 assert_eq!(
3103 shifted.evaluate_on_two_adic_domain(1, 4),
3104 p.evaluate_on_two_adic_coset(1, 4)
3105 );
3106 assert_eq!(
3107 shifted.evaluate_on_two_adic_domain(2, 4),
3108 p.evaluate_on_two_adic_coset(2, 4)
3109 );
3110 assert_eq!(
3111 shifted.evaluate_on_two_adic_domain(3, 4),
3112 p.evaluate_on_two_adic_coset(3, 4)
3113 );
3114 }
3115
3116 #[test]
3117 fn test_shift_domain2_2() {
3118 let values = vec![
3119 from_const(12),
3120 from_const(34),
3121 from_const(56),
3122 from_const(78),
3123 ];
3124 let p = Polynomial::encode2(values);
3125 let shifted = p.clone().shift_domain();
3126 assert_eq!(
3127 shifted.evaluate_on_two_adic_domain(0, 4),
3128 p.evaluate_on_two_adic_coset(0, 4)
3129 );
3130 assert_eq!(
3131 shifted.evaluate_on_two_adic_domain(1, 4),
3132 p.evaluate_on_two_adic_coset(1, 4)
3133 );
3134 assert_eq!(
3135 shifted.evaluate_on_two_adic_domain(2, 4),
3136 p.evaluate_on_two_adic_coset(2, 4)
3137 );
3138 assert_eq!(
3139 shifted.evaluate_on_two_adic_domain(3, 4),
3140 p.evaluate_on_two_adic_coset(3, 4)
3141 );
3142 }
3143
3144 #[test]
3145 fn test_shift_domain3() {
3146 let values = vec![from_const(12), from_const(34), from_const(56)];
3147 let p = Polynomial::encode3(values);
3148 let shifted = p.clone().shift_domain_by(Scalar::MULTIPLICATIVE_GENERATOR);
3149 assert_eq!(
3150 shifted.evaluate_on_three_adic_domain(0, 3),
3151 p.evaluate_on_three_adic_coset(0, 3)
3152 );
3153 assert_eq!(
3154 shifted.evaluate_on_three_adic_domain(1, 3),
3155 p.evaluate_on_three_adic_coset(1, 3)
3156 );
3157 assert_eq!(
3158 shifted.evaluate_on_three_adic_domain(2, 3),
3159 p.evaluate_on_three_adic_coset(2, 3)
3160 );
3161 }
3162
3163 #[test]
3164 fn test_lde2_blowup2() {
3165 let values = vec![
3166 from_const(12),
3167 from_const(34),
3168 from_const(56),
3169 from_const(78),
3170 ];
3171 let p = Polynomial::encode2(values);
3172 let lde = p.clone().lde2(8);
3173 assert_eq!(
3174 lde,
3175 vec![
3176 p.evaluate_on_two_adic_domain(0, 8),
3177 p.evaluate_on_two_adic_domain(1, 8),
3178 p.evaluate_on_two_adic_domain(2, 8),
3179 p.evaluate_on_two_adic_domain(3, 8),
3180 p.evaluate_on_two_adic_domain(4, 8),
3181 p.evaluate_on_two_adic_domain(5, 8),
3182 p.evaluate_on_two_adic_domain(6, 8),
3183 p.evaluate_on_two_adic_domain(7, 8),
3184 ]
3185 );
3186 }
3187
3188 #[test]
3189 fn test_lde2_blowup4() {
3190 let values = vec![from_const(1), from_const(2), from_const(3), from_const(4)];
3191 let p = Polynomial::encode2(values);
3192 let lde = p.clone().lde2(16);
3193 assert_eq!(
3194 lde,
3195 vec![
3196 p.evaluate_on_two_adic_domain(0, 16),
3197 p.evaluate_on_two_adic_domain(1, 16),
3198 p.evaluate_on_two_adic_domain(2, 16),
3199 p.evaluate_on_two_adic_domain(3, 16),
3200 p.evaluate_on_two_adic_domain(4, 16),
3201 p.evaluate_on_two_adic_domain(5, 16),
3202 p.evaluate_on_two_adic_domain(6, 16),
3203 p.evaluate_on_two_adic_domain(7, 16),
3204 p.evaluate_on_two_adic_domain(8, 16),
3205 p.evaluate_on_two_adic_domain(9, 16),
3206 p.evaluate_on_two_adic_domain(10, 16),
3207 p.evaluate_on_two_adic_domain(11, 16),
3208 p.evaluate_on_two_adic_domain(12, 16),
3209 p.evaluate_on_two_adic_domain(13, 16),
3210 p.evaluate_on_two_adic_domain(14, 16),
3211 p.evaluate_on_two_adic_domain(15, 16),
3212 ]
3213 );
3214 }
3215
3216 #[test]
3217 fn test_lde2_shorter_polynomial() {
3218 let values = vec![from_const(42), from_const(42)];
3219 let p = Polynomial::encode2(values);
3220 assert_eq!(p.len(), 1);
3221 assert_eq!(p.degree_bound(), 1);
3222 let lde = p.clone().lde2(4);
3223 assert_eq!(
3224 lde,
3225 vec![
3226 p.evaluate_on_two_adic_domain(0, 4),
3227 p.evaluate_on_two_adic_domain(1, 4),
3228 p.evaluate_on_two_adic_domain(2, 4),
3229 p.evaluate_on_two_adic_domain(3, 4),
3230 ]
3231 );
3232 }
3233
3234 #[test]
3235 fn test_lde3_blowup3() {
3236 let values = vec![from_const(12), from_const(34), from_const(56)];
3237 let p = Polynomial::encode3(values);
3238 let lde = p.clone().lde3(9);
3239 assert_eq!(
3240 lde,
3241 vec![
3242 p.evaluate_on_three_adic_domain(0, 9),
3243 p.evaluate_on_three_adic_domain(1, 9),
3244 p.evaluate_on_three_adic_domain(2, 9),
3245 p.evaluate_on_three_adic_domain(3, 9),
3246 p.evaluate_on_three_adic_domain(4, 9),
3247 p.evaluate_on_three_adic_domain(5, 9),
3248 p.evaluate_on_three_adic_domain(6, 9),
3249 p.evaluate_on_three_adic_domain(7, 9),
3250 p.evaluate_on_three_adic_domain(8, 9),
3251 ]
3252 );
3253 }
3254
3255 #[test]
3256 fn test_lde3_blowup9() {
3257 let values = vec![from_const(1), from_const(2), from_const(3)];
3258 let p = Polynomial::encode3(values);
3259 let lde = p.clone().lde3(27);
3260 assert_eq!(
3261 lde,
3262 vec![
3263 p.evaluate_on_three_adic_domain(0, 27),
3264 p.evaluate_on_three_adic_domain(1, 27),
3265 p.evaluate_on_three_adic_domain(2, 27),
3266 p.evaluate_on_three_adic_domain(3, 27),
3267 p.evaluate_on_three_adic_domain(4, 27),
3268 p.evaluate_on_three_adic_domain(5, 27),
3269 p.evaluate_on_three_adic_domain(6, 27),
3270 p.evaluate_on_three_adic_domain(7, 27),
3271 p.evaluate_on_three_adic_domain(8, 27),
3272 p.evaluate_on_three_adic_domain(9, 27),
3273 p.evaluate_on_three_adic_domain(10, 27),
3274 p.evaluate_on_three_adic_domain(11, 27),
3275 p.evaluate_on_three_adic_domain(12, 27),
3276 p.evaluate_on_three_adic_domain(13, 27),
3277 p.evaluate_on_three_adic_domain(14, 27),
3278 p.evaluate_on_three_adic_domain(15, 27),
3279 p.evaluate_on_three_adic_domain(16, 27),
3280 p.evaluate_on_three_adic_domain(17, 27),
3281 p.evaluate_on_three_adic_domain(18, 27),
3282 p.evaluate_on_three_adic_domain(19, 27),
3283 p.evaluate_on_three_adic_domain(20, 27),
3284 p.evaluate_on_three_adic_domain(21, 27),
3285 p.evaluate_on_three_adic_domain(22, 27),
3286 p.evaluate_on_three_adic_domain(23, 27),
3287 p.evaluate_on_three_adic_domain(24, 27),
3288 p.evaluate_on_three_adic_domain(25, 27),
3289 p.evaluate_on_three_adic_domain(26, 27),
3290 ]
3291 );
3292 }
3293
3294 #[test]
3295 fn test_lde3_nine_values_blowup3() {
3296 let values = (1u64..=9).map(Scalar::from).collect();
3297 let p = Polynomial::encode3(values);
3298 let lde = p.clone().lde3(27);
3299 assert_eq!(
3300 lde,
3301 vec![
3302 p.evaluate_on_three_adic_domain(0, 27),
3303 p.evaluate_on_three_adic_domain(1, 27),
3304 p.evaluate_on_three_adic_domain(2, 27),
3305 p.evaluate_on_three_adic_domain(3, 27),
3306 p.evaluate_on_three_adic_domain(4, 27),
3307 p.evaluate_on_three_adic_domain(5, 27),
3308 p.evaluate_on_three_adic_domain(6, 27),
3309 p.evaluate_on_three_adic_domain(7, 27),
3310 p.evaluate_on_three_adic_domain(8, 27),
3311 p.evaluate_on_three_adic_domain(9, 27),
3312 p.evaluate_on_three_adic_domain(10, 27),
3313 p.evaluate_on_three_adic_domain(11, 27),
3314 p.evaluate_on_three_adic_domain(12, 27),
3315 p.evaluate_on_three_adic_domain(13, 27),
3316 p.evaluate_on_three_adic_domain(14, 27),
3317 p.evaluate_on_three_adic_domain(15, 27),
3318 p.evaluate_on_three_adic_domain(16, 27),
3319 p.evaluate_on_three_adic_domain(17, 27),
3320 p.evaluate_on_three_adic_domain(18, 27),
3321 p.evaluate_on_three_adic_domain(19, 27),
3322 p.evaluate_on_three_adic_domain(20, 27),
3323 p.evaluate_on_three_adic_domain(21, 27),
3324 p.evaluate_on_three_adic_domain(22, 27),
3325 p.evaluate_on_three_adic_domain(23, 27),
3326 p.evaluate_on_three_adic_domain(24, 27),
3327 p.evaluate_on_three_adic_domain(25, 27),
3328 p.evaluate_on_three_adic_domain(26, 27),
3329 ]
3330 );
3331 }
3332
3333 #[test]
3334 fn test_lde3_shorter_poly() {
3335 let values = vec![from_const(7), from_const(7), from_const(7)];
3336 let p = Polynomial::encode3(values);
3337 assert_eq!(p.len(), 1);
3338 assert_eq!(p.degree_bound(), 1);
3339 let lde = p.clone().lde3(9);
3340 assert_eq!(
3341 lde,
3342 vec![
3343 p.evaluate_on_three_adic_domain(0, 9),
3344 p.evaluate_on_three_adic_domain(1, 9),
3345 p.evaluate_on_three_adic_domain(2, 9),
3346 p.evaluate_on_three_adic_domain(3, 9),
3347 p.evaluate_on_three_adic_domain(4, 9),
3348 p.evaluate_on_three_adic_domain(5, 9),
3349 p.evaluate_on_three_adic_domain(6, 9),
3350 p.evaluate_on_three_adic_domain(7, 9),
3351 p.evaluate_on_three_adic_domain(8, 9),
3352 ]
3353 );
3354 }
3355
3356 #[test]
3357 fn test_fold2_degree_zero() {
3358 let p = Polynomial::with_coefficients(vec![from_const(5)]);
3359 assert_eq!(p.clone().fold2(from_const(2)).take(), vec![from_const(5)]);
3360 assert_eq!(p.fold2(from_const(3)).take(), vec![from_const(5)]);
3361 }
3362
3363 #[test]
3364 fn test_fold2_degree_one() {
3365 let p = Polynomial::with_coefficients(vec![from_const(2), from_const(3)]);
3366 assert_eq!(p.clone().fold2(from_const(2)).take(), vec![from_const(8)]);
3367 assert_eq!(p.fold2(from_const(3)).take(), vec![from_const(11)]);
3368 }
3369
3370 #[test]
3371 fn test_fold2_degree_two() {
3372 let p = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
3373 assert_eq!(
3374 p.clone().fold2(from_const(2)).take(),
3375 vec![from_const(5), from_const(3)],
3376 );
3377 assert_eq!(
3378 p.fold2(from_const(3)).take(),
3379 vec![from_const(7), from_const(3)],
3380 );
3381 }
3382
3383 #[test]
3384 fn test_fold2_degree_three() {
3385 let p = Polynomial::with_coefficients(vec![
3386 from_const(1),
3387 from_const(2),
3388 from_const(3),
3389 from_const(4),
3390 ]);
3391 assert_eq!(
3392 p.clone().fold2(from_const(2)).take(),
3393 vec![from_const(5), from_const(11)],
3394 );
3395 assert_eq!(
3396 p.fold2(from_const(3)).take(),
3397 vec![from_const(7), from_const(15)],
3398 );
3399 }
3400
3401 #[test]
3402 fn test_fold3_degree_zero() {
3403 let p = Polynomial::with_coefficients(vec![from_const(5)]);
3404 assert_eq!(p.clone().fold3(from_const(2)).take(), vec![from_const(5)]);
3405 assert_eq!(p.fold3(from_const(3)).take(), vec![from_const(5)]);
3406 }
3407
3408 #[test]
3409 fn test_fold3_degree_two() {
3410 let p = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
3411 assert_eq!(p.clone().fold3(from_const(2)).take(), vec![from_const(17)]);
3412 assert_eq!(p.fold3(from_const(3)).take(), vec![from_const(34)]);
3413 }
3414
3415 #[test]
3416 fn test_fold3_degree_three() {
3417 let p = Polynomial::with_coefficients(vec![
3418 from_const(1),
3419 from_const(2),
3420 from_const(3),
3421 from_const(4),
3422 ]);
3423 assert_eq!(
3424 p.clone().fold3(from_const(2)).take(),
3425 vec![from_const(17), from_const(4)],
3426 );
3427 assert_eq!(
3428 p.fold3(from_const(3)).take(),
3429 vec![from_const(34), from_const(4)],
3430 );
3431 }
3432
3433 #[test]
3434 fn test_fold3_degree_five() {
3435 let p = Polynomial::with_coefficients(vec![
3436 from_const(1),
3437 from_const(2),
3438 from_const(3),
3439 from_const(4),
3440 from_const(5),
3441 from_const(6),
3442 ]);
3443 assert_eq!(
3444 p.clone().fold3(from_const(2)).take(),
3445 vec![from_const(17), from_const(38)],
3446 );
3447 assert_eq!(
3448 p.fold3(from_const(3)).take(),
3449 vec![from_const(34), from_const(73)],
3450 );
3451 }
3452
3453 #[test]
3454 fn test_multiply_values2_same_constant() {
3455 let lhs = vec![from_const(42), from_const(42)];
3456 let rhs = vec![from_const(42), from_const(42)];
3457 let result = Polynomial::multiply_values2(lhs, rhs);
3458 assert_eq!(result, vec![from_const(1764)]);
3459 }
3460
3461 #[test]
3462 fn test_multiply_values2_different_constants() {
3463 let lhs = vec![from_const(3), from_const(3)];
3464 let rhs = vec![from_const(7), from_const(7)];
3465 let result = Polynomial::multiply_values2(lhs, rhs);
3466 assert_eq!(result, vec![from_const(21)]);
3467 }
3468
3469 #[test]
3470 fn test_multiply_values2_two_linear_polynomials() {
3471 let p = Polynomial::with_coefficients(vec![from_const(1), from_const(2)]);
3472 let q = Polynomial::with_coefficients(vec![from_const(3), from_const(4)]);
3473 let lhs = vec![
3474 p.evaluate_on_two_adic_domain(0, 2),
3475 p.evaluate_on_two_adic_domain(1, 2),
3476 ];
3477 let rhs = vec![
3478 q.evaluate_on_two_adic_domain(0, 2),
3479 q.evaluate_on_two_adic_domain(1, 2),
3480 ];
3481 let product = p.multiply(q);
3482 let result = Polynomial::multiply_values2(lhs, rhs);
3483 assert_eq!(
3484 result,
3485 vec![
3486 product.evaluate_on_two_adic_domain(0, 4),
3487 product.evaluate_on_two_adic_domain(1, 4),
3488 product.evaluate_on_two_adic_domain(2, 4),
3489 product.evaluate_on_two_adic_domain(3, 4),
3490 ]
3491 );
3492 }
3493
3494 #[test]
3495 fn test_multiply_values2_four_values() {
3496 let p = Polynomial::with_coefficients(vec![
3497 from_const(1),
3498 from_const(2),
3499 from_const(3),
3500 from_const(4),
3501 ]);
3502 let q = Polynomial::with_coefficients(vec![
3503 from_const(5),
3504 from_const(6),
3505 from_const(7),
3506 from_const(8),
3507 ]);
3508 let lhs = vec![
3509 p.evaluate_on_two_adic_domain(0, 4),
3510 p.evaluate_on_two_adic_domain(1, 4),
3511 p.evaluate_on_two_adic_domain(2, 4),
3512 p.evaluate_on_two_adic_domain(3, 4),
3513 ];
3514 let rhs = vec![
3515 q.evaluate_on_two_adic_domain(0, 4),
3516 q.evaluate_on_two_adic_domain(1, 4),
3517 q.evaluate_on_two_adic_domain(2, 4),
3518 q.evaluate_on_two_adic_domain(3, 4),
3519 ];
3520 let product = p.multiply(q);
3521 let result = Polynomial::multiply_values2(lhs, rhs);
3522 assert_eq!(
3523 result,
3524 vec![
3525 product.evaluate_on_two_adic_domain(0, 8),
3526 product.evaluate_on_two_adic_domain(1, 8),
3527 product.evaluate_on_two_adic_domain(2, 8),
3528 product.evaluate_on_two_adic_domain(3, 8),
3529 product.evaluate_on_two_adic_domain(4, 8),
3530 product.evaluate_on_two_adic_domain(5, 8),
3531 product.evaluate_on_two_adic_domain(6, 8),
3532 product.evaluate_on_two_adic_domain(7, 8),
3533 ]
3534 );
3535 }
3536
3537 #[test]
3538 fn test_multiply_values2_commutative() {
3539 let p = Polynomial::with_coefficients(vec![from_const(1), from_const(2)]);
3540 let q = Polynomial::with_coefficients(vec![from_const(3), from_const(4)]);
3541 let values_p = vec![
3542 p.evaluate_on_two_adic_domain(0, 2),
3543 p.evaluate_on_two_adic_domain(1, 2),
3544 ];
3545 let values_q = vec![
3546 q.evaluate_on_two_adic_domain(0, 2),
3547 q.evaluate_on_two_adic_domain(1, 2),
3548 ];
3549 let result_pq = Polynomial::multiply_values2(values_p.clone(), values_q.clone());
3550 let result_qp = Polynomial::multiply_values2(values_q, values_p);
3551 assert_eq!(result_pq, result_qp);
3552 }
3553
3554 #[test]
3555 fn test_multiply_values2_round_trip() {
3556 let p = Polynomial::with_coefficients(vec![
3557 from_const(1),
3558 from_const(2),
3559 from_const(3),
3560 from_const(4),
3561 ]);
3562 let q = Polynomial::with_coefficients(vec![
3563 from_const(5),
3564 from_const(6),
3565 from_const(7),
3566 from_const(8),
3567 ]);
3568 let lhs = vec![
3569 p.evaluate_on_two_adic_domain(0, 4),
3570 p.evaluate_on_two_adic_domain(1, 4),
3571 p.evaluate_on_two_adic_domain(2, 4),
3572 p.evaluate_on_two_adic_domain(3, 4),
3573 ];
3574 let rhs = vec![
3575 q.evaluate_on_two_adic_domain(0, 4),
3576 q.evaluate_on_two_adic_domain(1, 4),
3577 q.evaluate_on_two_adic_domain(2, 4),
3578 q.evaluate_on_two_adic_domain(3, 4),
3579 ];
3580 let product = p.clone().multiply(q.clone());
3581 let result = Polynomial::encode2(Polynomial::multiply_values2(lhs, rhs));
3582 assert_eq!(result, product);
3583 }
3584
3585 #[test]
3586 fn test_multiply_values3_same_constant() {
3587 let lhs = vec![from_const(42), from_const(42), from_const(42)];
3588 let rhs = vec![from_const(42), from_const(42), from_const(42)];
3589 let result = Polynomial::multiply_values3(lhs, rhs);
3590 assert_eq!(result, vec![from_const(1764)]);
3591 }
3592
3593 #[test]
3594 fn test_multiply_values3_different_constants() {
3595 let lhs = vec![from_const(3), from_const(3), from_const(3)];
3596 let rhs = vec![from_const(7), from_const(7), from_const(7)];
3597 let result = Polynomial::multiply_values3(lhs, rhs);
3598 assert_eq!(result, vec![from_const(21)]);
3599 }
3600
3601 #[test]
3602 fn test_multiply_values3_two_linear_polynomials() {
3603 let p = Polynomial::with_coefficients(vec![from_const(1), from_const(2)]);
3604 let q = Polynomial::with_coefficients(vec![from_const(3), from_const(4)]);
3605 let lhs = vec![
3606 p.evaluate_on_three_adic_domain(0, 3),
3607 p.evaluate_on_three_adic_domain(1, 3),
3608 p.evaluate_on_three_adic_domain(2, 3),
3609 ];
3610 let rhs = vec![
3611 q.evaluate_on_three_adic_domain(0, 3),
3612 q.evaluate_on_three_adic_domain(1, 3),
3613 q.evaluate_on_three_adic_domain(2, 3),
3614 ];
3615 let product = p.multiply(q);
3616 let result = Polynomial::multiply_values3(lhs, rhs);
3617 assert_eq!(
3618 result,
3619 vec![
3620 product.evaluate_on_three_adic_domain(0, 3),
3621 product.evaluate_on_three_adic_domain(1, 3),
3622 product.evaluate_on_three_adic_domain(2, 3),
3623 ]
3624 );
3625 }
3626
3627 #[test]
3628 fn test_multiply_values3_nine_values() {
3629 let p = Polynomial::with_coefficients(vec![
3630 from_const(1),
3631 from_const(2),
3632 from_const(3),
3633 from_const(4),
3634 from_const(5),
3635 from_const(6),
3636 from_const(7),
3637 from_const(8),
3638 from_const(9),
3639 ]);
3640 let q = Polynomial::with_coefficients(vec![
3641 from_const(10),
3642 from_const(11),
3643 from_const(12),
3644 from_const(13),
3645 from_const(14),
3646 from_const(15),
3647 from_const(16),
3648 from_const(17),
3649 from_const(18),
3650 ]);
3651 let lhs = vec![
3652 p.evaluate_on_three_adic_domain(0, 9),
3653 p.evaluate_on_three_adic_domain(1, 9),
3654 p.evaluate_on_three_adic_domain(2, 9),
3655 p.evaluate_on_three_adic_domain(3, 9),
3656 p.evaluate_on_three_adic_domain(4, 9),
3657 p.evaluate_on_three_adic_domain(5, 9),
3658 p.evaluate_on_three_adic_domain(6, 9),
3659 p.evaluate_on_three_adic_domain(7, 9),
3660 p.evaluate_on_three_adic_domain(8, 9),
3661 ];
3662 let rhs = vec![
3663 q.evaluate_on_three_adic_domain(0, 9),
3664 q.evaluate_on_three_adic_domain(1, 9),
3665 q.evaluate_on_three_adic_domain(2, 9),
3666 q.evaluate_on_three_adic_domain(3, 9),
3667 q.evaluate_on_three_adic_domain(4, 9),
3668 q.evaluate_on_three_adic_domain(5, 9),
3669 q.evaluate_on_three_adic_domain(6, 9),
3670 q.evaluate_on_three_adic_domain(7, 9),
3671 q.evaluate_on_three_adic_domain(8, 9),
3672 ];
3673 let product = p.multiply(q);
3674 let result = Polynomial::multiply_values3(lhs, rhs);
3675 assert_eq!(
3676 result,
3677 vec![
3678 product.evaluate_on_three_adic_domain(0, 27),
3679 product.evaluate_on_three_adic_domain(1, 27),
3680 product.evaluate_on_three_adic_domain(2, 27),
3681 product.evaluate_on_three_adic_domain(3, 27),
3682 product.evaluate_on_three_adic_domain(4, 27),
3683 product.evaluate_on_three_adic_domain(5, 27),
3684 product.evaluate_on_three_adic_domain(6, 27),
3685 product.evaluate_on_three_adic_domain(7, 27),
3686 product.evaluate_on_three_adic_domain(8, 27),
3687 product.evaluate_on_three_adic_domain(9, 27),
3688 product.evaluate_on_three_adic_domain(10, 27),
3689 product.evaluate_on_three_adic_domain(11, 27),
3690 product.evaluate_on_three_adic_domain(12, 27),
3691 product.evaluate_on_three_adic_domain(13, 27),
3692 product.evaluate_on_three_adic_domain(14, 27),
3693 product.evaluate_on_three_adic_domain(15, 27),
3694 product.evaluate_on_three_adic_domain(16, 27),
3695 product.evaluate_on_three_adic_domain(17, 27),
3696 product.evaluate_on_three_adic_domain(18, 27),
3697 product.evaluate_on_three_adic_domain(19, 27),
3698 product.evaluate_on_three_adic_domain(20, 27),
3699 product.evaluate_on_three_adic_domain(21, 27),
3700 product.evaluate_on_three_adic_domain(22, 27),
3701 product.evaluate_on_three_adic_domain(23, 27),
3702 product.evaluate_on_three_adic_domain(24, 27),
3703 product.evaluate_on_three_adic_domain(25, 27),
3704 product.evaluate_on_three_adic_domain(26, 27),
3705 ]
3706 );
3707 }
3708
3709 #[test]
3710 fn test_multiply_values3_commutative() {
3711 let p = Polynomial::with_coefficients(vec![from_const(1), from_const(2)]);
3712 let q = Polynomial::with_coefficients(vec![from_const(3), from_const(4)]);
3713 let values_p = vec![
3714 p.evaluate_on_three_adic_domain(0, 3),
3715 p.evaluate_on_three_adic_domain(1, 3),
3716 p.evaluate_on_three_adic_domain(2, 3),
3717 ];
3718 let values_q = vec![
3719 q.evaluate_on_three_adic_domain(0, 3),
3720 q.evaluate_on_three_adic_domain(1, 3),
3721 q.evaluate_on_three_adic_domain(2, 3),
3722 ];
3723 let result_pq = Polynomial::multiply_values3(values_p.clone(), values_q.clone());
3724 let result_qp = Polynomial::multiply_values3(values_q, values_p);
3725 assert_eq!(result_pq, result_qp);
3726 }
3727
3728 #[test]
3729 fn test_multiply_values3_round_trip() {
3730 let p = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
3731 let q = Polynomial::with_coefficients(vec![from_const(4), from_const(5), from_const(6)]);
3732 let lhs = vec![
3733 p.evaluate_on_three_adic_domain(0, 3),
3734 p.evaluate_on_three_adic_domain(1, 3),
3735 p.evaluate_on_three_adic_domain(2, 3),
3736 ];
3737 let rhs = vec![
3738 q.evaluate_on_three_adic_domain(0, 3),
3739 q.evaluate_on_three_adic_domain(1, 3),
3740 q.evaluate_on_three_adic_domain(2, 3),
3741 ];
3742 let product = p.clone().multiply(q.clone());
3743 let result = Polynomial::encode3(Polynomial::multiply_values3(lhs, rhs));
3744 assert_eq!(result, product);
3745 }
3746
3747 #[test]
3748 fn test_lagrange0_two_adic_1() {
3749 let n = 1;
3750 let l0 = Polynomial::lagrange0_2(n);
3751 assert_eq!(l0.evaluate(from_const(1)), from_const(1));
3752 }
3753
3754 #[test]
3755 fn test_lagrange0_two_adic_2() {
3756 let n = 2;
3757 let omega = Polynomial::domain_element2(1, n);
3758 let l0 = Polynomial::lagrange0_2(n);
3759 assert_eq!(l0.evaluate(from_const(1)), from_const(1));
3760 assert_eq!(l0.evaluate(omega), from_const(0));
3761 }
3762
3763 #[test]
3764 fn test_lagrange0_two_adic_4() {
3765 let n = 4;
3766 let omega = Polynomial::domain_element2(1, n);
3767 let l0 = Polynomial::lagrange0_2(n);
3768 assert_eq!(l0.evaluate(from_const(1)), from_const(1));
3769 assert_eq!(l0.evaluate(omega), from_const(0));
3770 assert_eq!(l0.evaluate(omega.square()), from_const(0));
3771 assert_eq!(l0.evaluate(omega.cube()), from_const(0));
3772 }
3773
3774 #[test]
3775 fn test_lagrange0_two_adic_8() {
3776 let n = 8;
3777 let omega = Polynomial::domain_element2(1, n);
3778 let l0 = Polynomial::lagrange0_2(n);
3779 assert_eq!(l0.evaluate(from_const(1)), from_const(1));
3780 assert_eq!(l0.evaluate(omega), from_const(0));
3781 assert_eq!(l0.evaluate(omega.pow_small(2)), from_const(0));
3782 assert_eq!(l0.evaluate(omega.pow_small(3)), from_const(0));
3783 assert_eq!(l0.evaluate(omega.pow_small(4)), from_const(0));
3784 assert_eq!(l0.evaluate(omega.pow_small(5)), from_const(0));
3785 assert_eq!(l0.evaluate(omega.pow_small(6)), from_const(0));
3786 assert_eq!(l0.evaluate(omega.pow_small(7)), from_const(0));
3787 }
3788
3789 #[test]
3790 fn test_lagrange0_three_adic_1() {
3791 let n = 1;
3792 let l0 = Polynomial::lagrange0_3(n);
3793 assert_eq!(l0.evaluate(from_const(1)), from_const(1));
3794 }
3795
3796 #[test]
3797 fn test_lagrange0_three_adic_3() {
3798 let n = 3;
3799 let omega = Polynomial::domain_element3(1, n);
3800 let l0 = Polynomial::lagrange0_3(n);
3801 assert_eq!(l0.evaluate(from_const(1)), from_const(1));
3802 assert_eq!(l0.evaluate(omega), from_const(0));
3803 assert_eq!(l0.evaluate(omega.square()), from_const(0));
3804 }
3805
3806 #[test]
3807 fn test_lagrange0_three_adic_9() {
3808 let n = 9;
3809 let omega = Polynomial::domain_element3(1, n);
3810 let l0 = Polynomial::lagrange0_3(n);
3811 assert_eq!(l0.evaluate(from_const(1)), from_const(1));
3812 assert_eq!(l0.evaluate(omega), from_const(0));
3813 assert_eq!(l0.evaluate(omega.pow_small(2)), from_const(0));
3814 assert_eq!(l0.evaluate(omega.pow_small(3)), from_const(0));
3815 assert_eq!(l0.evaluate(omega.pow_small(4)), from_const(0));
3816 assert_eq!(l0.evaluate(omega.pow_small(5)), from_const(0));
3817 assert_eq!(l0.evaluate(omega.pow_small(6)), from_const(0));
3818 assert_eq!(l0.evaluate(omega.pow_small(7)), from_const(0));
3819 assert_eq!(l0.evaluate(omega.pow_small(8)), from_const(0));
3820 }
3821}