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