use std::borrow::Borrow; use crate::field::extension_field::Frobenius; use crate::field::field::Field; use crate::polynomial::polynomial::PolynomialCoeffs; #[derive(Debug, Copy, Clone)] pub struct ReducingFactor { base: F, count: u64, } impl ReducingFactor { pub fn new(base: F) -> Self { Self { base, count: 0 } } fn mul(&mut self, x: F) -> F { self.count += 1; self.base * x } fn mul_poly(&mut self, p: &mut PolynomialCoeffs) { self.count += 1; *p *= self.base; } pub fn reduce(&mut self, iter: impl DoubleEndedIterator>) -> F { iter.rev() .fold(F::ZERO, |acc, x| self.mul(acc) + *x.borrow()) } pub fn reduce_polys( &mut self, polys: impl DoubleEndedIterator>>, ) -> PolynomialCoeffs { polys.rev().fold(PolynomialCoeffs::empty(), |mut acc, x| { self.mul_poly(&mut acc); acc += x.borrow(); acc }) } pub fn shift(&mut self, x: F) -> F { let tmp = self.base.exp(self.count) * x; self.count = 0; tmp } pub fn shift_poly(&mut self, p: &mut PolynomialCoeffs) { *p *= self.base.exp(self.count); self.count = 0; } pub fn reset(&mut self) { self.count = 0; } pub fn repeated_frobenius(&self, count: usize) -> Self where F: Frobenius, { Self { base: self.base.repeated_frobenius(count), count: self.count, } } }