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