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