From e6374ba9f0a2dd64e15809169cd14f04936fa85c Mon Sep 17 00:00:00 2001 From: ssolit <49683577+ssolit@users.noreply.github.com> Date: Wed, 3 Jul 2024 22:07:51 -0400 Subject: [PATCH 1/2] Mul mle by scalar (#845) * poly * scalar works * updated changelog * clean up --- CHANGELOG.md | 1 + .../multivariate/multilinear/dense.rs | 55 ++++++++++++++++++- 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2acaf9643..237a72262 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - [\#772](https://github.com/arkworks-rs/algebra/pull/772) (`ark-ff`) Implementation of `mul` method for `BigInteger`. - [\#794](https://github.com/arkworks-rs/algebra/pull/794) (`ark-ff`) Fix `wasm` compilation. - [\#837](https://github.com/arkworks-rs/algebra/pull/837) (`ark-serialize`) Fix array deserialization panic. +- [\#845](https://github.com/arkworks-rs/algebra/pull/845) (`Algebra`) Implementation of `mul` method for `DenseMultilinearExtension * F`. ### Breaking changes diff --git a/poly/src/evaluations/multivariate/multilinear/dense.rs b/poly/src/evaluations/multivariate/multilinear/dense.rs index 9e7fe482e..315c54e28 100644 --- a/poly/src/evaluations/multivariate/multilinear/dense.rs +++ b/poly/src/evaluations/multivariate/multilinear/dense.rs @@ -11,7 +11,7 @@ use ark_std::{ fmt::Formatter, iter::IntoIterator, log2, - ops::{Add, AddAssign, Index, Neg, Sub, SubAssign}, + ops::{Add, AddAssign, Index, Mul, MulAssign, Neg, Sub, SubAssign}, rand::Rng, slice::{Iter, IterMut}, vec::*, @@ -331,6 +331,44 @@ impl<'a, F: Field> SubAssign<&'a DenseMultilinearExtension> for DenseMultilin } } +impl Mul for DenseMultilinearExtension { + type Output = DenseMultilinearExtension; + + fn mul(self, scalar: F) -> Self::Output { + &self * &scalar + } +} + +impl<'a, 'b, F: Field> Mul<&'a F> for &'b DenseMultilinearExtension { + type Output = DenseMultilinearExtension; + + fn mul(self, scalar: &'a F) -> Self::Output { + if scalar.is_zero() { + return DenseMultilinearExtension::zero(); + } else if scalar.is_one() { + return self.clone(); + } + let result: Vec = self.evaluations.iter().map(|&x| x * scalar).collect(); + + DenseMultilinearExtension { + num_vars: self.num_vars, + evaluations: result, + } + } +} + +impl MulAssign for DenseMultilinearExtension { + fn mul_assign(&mut self, scalar: F) { + *self = &*self * &scalar + } +} + +impl<'a, F: Field> MulAssign<&'a F> for DenseMultilinearExtension { + fn mul_assign(&mut self, scalar: &'a F) { + *self = &*self * scalar + } +} + impl fmt::Debug for DenseMultilinearExtension { fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> { write!(f, "DenseML(nv = {}, evaluations = [", self.num_vars)?; @@ -394,7 +432,7 @@ impl Polynomial for DenseMultilinearExtension { #[cfg(test)] mod tests { use crate::{DenseMultilinearExtension, MultilinearExtension, Polynomial}; - use ark_ff::{Field, Zero}; + use ark_ff::{Field, One, Zero}; use ark_std::{ops::Neg, test_rng, vec::*, UniformRand}; use ark_test_curves::bls12_381::Fr; @@ -471,6 +509,7 @@ mod tests { const NV: usize = 10; let mut rng = test_rng(); for _ in 0..20 { + let scalar = Fr::rand(&mut rng); let point: Vec<_> = (0..NV).map(|_| Fr::rand(&mut rng)).collect(); let poly1 = DenseMultilinearExtension::rand(NV, &mut rng); let poly2 = DenseMultilinearExtension::rand(NV, &mut rng); @@ -482,6 +521,8 @@ mod tests { assert_eq!((&poly1 - &poly2).evaluate(&point), v1 - v2); // test negate assert_eq!(poly1.clone().neg().evaluate(&point), -v1); + // test mul poly by scalar + assert_eq!((&poly1 * &scalar).evaluate(&point), v1 * scalar); // test add assign { let mut poly1 = poly1.clone(); @@ -515,6 +556,16 @@ mod tests { assert_eq!(zero.evaluate(&point), scalar * v1); } } + // test mul_assign for poly * scalar + { + let mut poly1_cloned = poly1.clone(); + poly1_cloned *= Fr::one(); + assert_eq!(poly1_cloned.evaluate(&point), v1); + poly1_cloned *= scalar; + assert_eq!(poly1_cloned.evaluate(&point), v1 * scalar); + poly1_cloned *= Fr::zero(); + assert_eq!(poly1_cloned, DenseMultilinearExtension::zero()); + } } } From dcf73a5f9610ba9d16a3c8e0de0b3835e5e5d5e4 Mon Sep 17 00:00:00 2001 From: Cesar Descalzo Date: Thu, 4 Jul 2024 04:08:27 +0200 Subject: [PATCH 2/2] Impl sub, mul and div for actual objects (#843) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Impl sub, mul and div for actual objects * Add non-reference scalar multiplication Co-authored-by: Antonio Mejías Gil * Implement arithmetic operators with a macro Co-authored-by: Antonio Mejías Gil * Undonde smaller breaking change Co-authored-by: Antonio Mejías Gil * Add non-reference scalar multiplication Co-authored-by: Antonio Mejías Gil --------- Co-authored-by: Antonio Mejías Gil --- poly/src/polynomial/univariate/dense.rs | 53 +++++++++++++++++++++---- 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/poly/src/polynomial/univariate/dense.rs b/poly/src/polynomial/univariate/dense.rs index 1df019d58..dca859fd0 100644 --- a/poly/src/polynomial/univariate/dense.rs +++ b/poly/src/polynomial/univariate/dense.rs @@ -285,14 +285,6 @@ impl DerefMut for DensePolynomial { } } -impl Add for DensePolynomial { - type Output = DensePolynomial; - - fn add(self, other: DensePolynomial) -> Self { - &self + &other - } -} - impl<'a, 'b, F: Field> Add<&'a DensePolynomial> for &'b DensePolynomial { type Output = DensePolynomial; @@ -601,6 +593,15 @@ impl<'b, F: Field> Mul for &'b DensePolynomial { } } +impl Mul for DensePolynomial { + type Output = DensePolynomial; + + #[inline] + fn mul(self, elem: F) -> DensePolynomial { + &self * elem + } +} + /// Performs O(nlogn) multiplication of polynomials if F is smooth. impl<'a, 'b, F: FftField> Mul<&'a DensePolynomial> for &'b DensePolynomial { type Output = DensePolynomial; @@ -620,6 +621,37 @@ impl<'a, 'b, F: FftField> Mul<&'a DensePolynomial> for &'b DensePolynomial } } +macro_rules! impl_op { + ($trait:ident, $method:ident, $field_bound:ident) => { + impl $trait> for DensePolynomial { + type Output = DensePolynomial; + + #[inline] + fn $method(self, other: DensePolynomial) -> DensePolynomial { + (&self).$method(&other) + } + } + + impl<'a, F: $field_bound> $trait<&'a DensePolynomial> for DensePolynomial { + type Output = DensePolynomial; + + #[inline] + fn $method(self, other: &'a DensePolynomial) -> DensePolynomial { + (&self).$method(other) + } + } + + impl<'a, F: $field_bound> $trait> for &'a DensePolynomial { + type Output = DensePolynomial; + + #[inline] + fn $method(self, other: DensePolynomial) -> DensePolynomial { + self.$method(&other) + } + } + }; +} + impl Zero for DensePolynomial { /// Returns the zero polynomial. fn zero() -> Self { @@ -632,6 +664,11 @@ impl Zero for DensePolynomial { } } +impl_op!(Add, add, Field); +impl_op!(Sub, sub, Field); +impl_op!(Mul, mul, FftField); +impl_op!(Div, div, Field); + #[cfg(test)] mod tests { use crate::{polynomial::univariate::*, GeneralEvaluationDomain};