From a3fb3b40954bad28eec179bee178f9572dba77e1 Mon Sep 17 00:00:00 2001 From: woojucy Date: Sat, 4 Jan 2025 20:53:45 +0900 Subject: [PATCH] Update CHANGELOG: Fix handling of duplicate terms in SparsePolynomial --- CHANGELOG.md | 2 ++ poly/src/polynomial/univariate/sparse.rs | 31 +++++++++++++++--------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c3034ecd..3cb495c96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ ### Bugfixes +- (`ark-poly`) Fix handling of duplicate terms in `SparsePolynomial::from_coefficients_vec`. Terms with the same degree are now correctly merged, and zero coefficient terms are removed. + ## v0.5.0 - [\#772](https://github.com/arkworks-rs/algebra/pull/772) (`ark-ff`) Implementation of `mul` method for `BigInteger`. diff --git a/poly/src/polynomial/univariate/sparse.rs b/poly/src/polynomial/univariate/sparse.rs index 7357ad429..db56c8126 100644 --- a/poly/src/polynomial/univariate/sparse.rs +++ b/poly/src/polynomial/univariate/sparse.rs @@ -236,20 +236,27 @@ impl SparsePolynomial { } /// Constructs a new polynomial from a list of coefficients. - /// The function does not combine like terms and so multiple monomials - /// of the same degree are ignored. pub fn from_coefficients_vec(mut coeffs: Vec<(usize, F)>) -> Self { - // While there are zeros at the end of the coefficient vector, pop them off. - while coeffs.last().map_or(false, |(_, c)| c.is_zero()) { - coeffs.pop(); - } - // Ensure that coeffs are in ascending order. + // Sort terms by degree coeffs.sort_by(|(c1, _), (c2, _)| c1.cmp(c2)); - // Check that either the coefficients vec is empty or that the last coeff is - // non-zero. - assert!(coeffs.last().map_or(true, |(_, c)| !c.is_zero())); - - Self { coeffs } + + // Merge duplicate terms + let mut merged_coeffs: Vec<(usize, F)> = Vec::new(); + for (degree, coeff) in coeffs { + if let Some((last_degree, last_coeff)) = merged_coeffs.last_mut() { + if *last_degree == degree { + *last_coeff += coeff; // Combine coefficients for duplicate degrees + continue; + } + } + merged_coeffs.push((degree, coeff)); + } + + // Remove zero coefficient terms + merged_coeffs.retain(|(_, coeff)| !coeff.is_zero()); + + // Create the SparsePolynomial + Self { coeffs: merged_coeffs } } /// Perform a naive n^2 multiplication of `self` by `other`.