Skip to content

Commit fd6a826

Browse files
authored
poly: add specific unit tests and simplify DensePolynomial addition (#869)
* poly: add specific unit tests and simplify DensePolynomial addition * clean up print statements * cleanup comments * fix comment
1 parent 4bd448c commit fd6a826

File tree

1 file changed

+119
-11
lines changed

1 file changed

+119
-11
lines changed

poly/src/polynomial/univariate/dense.rs

Lines changed: 119 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -378,27 +378,34 @@ impl<'a, F: Field> AddAssign<&'a DensePolynomial<F>> for DensePolynomial<F> {
378378

379379
impl<'a, F: Field> AddAssign<(F, &'a DensePolynomial<F>)> for DensePolynomial<F> {
380380
fn add_assign(&mut self, (f, other): (F, &'a DensePolynomial<F>)) {
381+
// No need to modify self if other is zero
382+
if other.is_zero() {
383+
return;
384+
}
385+
386+
// If the first polynomial is zero, just copy the second one and scale by f.
381387
if self.is_zero() {
382-
self.coeffs.truncate(0);
388+
self.coeffs.clear();
383389
self.coeffs.extend_from_slice(&other.coeffs);
384390
self.coeffs.iter_mut().for_each(|c| *c *= &f);
385391
return;
386-
} else if other.is_zero() {
387-
return;
388-
} else if self.degree() >= other.degree() {
389-
} else {
390-
// Add the necessary number of zero coefficients.
392+
}
393+
394+
// If the degree of the first polynomial is smaller, resize it.
395+
if self.degree() < other.degree() {
391396
self.coeffs.resize(other.coeffs.len(), F::zero());
392397
}
398+
399+
// Add corresponding coefficients from the second polynomial, scaled by f.
393400
self.coeffs
394401
.iter_mut()
395402
.zip(&other.coeffs)
396-
.for_each(|(a, b)| {
397-
*a += &(f * b);
398-
});
403+
.for_each(|(a, b)| *a += f * b);
404+
399405
// If the leading coefficient ends up being zero, pop it off.
400-
// This can happen if they were the same degree, or if a
401-
// polynomial's coefficients were constructed with leading zeros.
406+
// This can happen:
407+
// - if they were the same degree,
408+
// - if a polynomial's coefficients were constructed with leading zeros.
402409
self.truncate_leading_zeros();
403410
}
404411
}
@@ -1030,4 +1037,105 @@ mod tests {
10301037

10311038
assert_eq!(eval1, eval2);
10321039
}
1040+
1041+
#[test]
1042+
fn test_add_assign_with_zero_self() {
1043+
// Create a polynomial poly1 which is a zero polynomial
1044+
let mut poly1 = DensePolynomial::<Fr> { coeffs: Vec::new() };
1045+
1046+
// Create another polynomial poly2, which is: 2 + 3x (coefficients [2, 3])
1047+
let poly2 = DensePolynomial {
1048+
coeffs: vec![Fr::from(2), Fr::from(3)],
1049+
};
1050+
1051+
// Add poly2 to the zero polynomial
1052+
// Since poly1 is zero, it should just take the coefficients of poly2.
1053+
poly1 += (Fr::from(1), &poly2);
1054+
1055+
// After addition, poly1 should be equal to poly2
1056+
assert_eq!(poly1.coeffs, vec![Fr::from(2), Fr::from(3)]);
1057+
}
1058+
1059+
#[test]
1060+
fn test_add_assign_with_zero_other() {
1061+
// Create a polynomial poly1: 2 + 3x (coefficients [2, 3])
1062+
let mut poly1 = DensePolynomial {
1063+
coeffs: vec![Fr::from(2), Fr::from(3)],
1064+
};
1065+
1066+
// Create an empty polynomial poly2 (zero polynomial)
1067+
let poly2 = DensePolynomial::<Fr> { coeffs: Vec::new() };
1068+
1069+
// Add zero polynomial poly2 to poly1.
1070+
// Since poly2 is zero, poly1 should remain unchanged.
1071+
poly1 += (Fr::from(1), &poly2);
1072+
1073+
// After addition, poly1 should still be [2, 3]
1074+
assert_eq!(poly1.coeffs, vec![Fr::from(2), Fr::from(3)]);
1075+
}
1076+
1077+
#[test]
1078+
fn test_add_assign_with_different_degrees() {
1079+
// Create polynomial poly1: 1 + 2x + 3x^2 (coefficients [1, 2, 3])
1080+
let mut poly1 = DensePolynomial {
1081+
coeffs: vec![Fr::from(1), Fr::from(2), Fr::from(3)],
1082+
};
1083+
1084+
// Create another polynomial poly2: 4 + 5x (coefficients [4, 5])
1085+
let poly2 = DensePolynomial {
1086+
coeffs: vec![Fr::from(4), Fr::from(5)],
1087+
};
1088+
1089+
// Add poly2 to poly1.
1090+
// poly1 is degree 2, poly2 is degree 1, so poly2 will be padded with a zero
1091+
// to match the degree of poly1.
1092+
poly1 += (Fr::from(1), &poly2);
1093+
1094+
// After addition, the result should be:
1095+
// 5 + 7x + 3x^2 (coefficients [5, 7, 3])
1096+
assert_eq!(poly1.coeffs, vec![Fr::from(5), Fr::from(7), Fr::from(3)]);
1097+
}
1098+
1099+
#[test]
1100+
fn test_add_assign_with_equal_degrees() {
1101+
// Create polynomial poly1: 1 + 2x + 3x^2 (coefficients [1, 2, 3])
1102+
let mut poly1 = DensePolynomial {
1103+
coeffs: vec![Fr::from(1), Fr::from(2), Fr::from(3)],
1104+
};
1105+
1106+
// Create polynomial poly2: 4 + 5x + 6x^2 (coefficients [4, 5, 6])
1107+
let poly2 = DensePolynomial {
1108+
coeffs: vec![Fr::from(4), Fr::from(5), Fr::from(6)],
1109+
};
1110+
1111+
// Add poly2 to poly1.
1112+
// Since both polynomials have the same degree, we can directly add corresponding terms.
1113+
poly1 += (Fr::from(1), &poly2);
1114+
1115+
// After addition, the result should be:
1116+
// 5 + 7x + 9x^2 (coefficients [5, 7, 9])
1117+
assert_eq!(poly1.coeffs, vec![Fr::from(5), Fr::from(7), Fr::from(9)]);
1118+
}
1119+
1120+
#[test]
1121+
fn test_add_assign_with_smaller_degrees() {
1122+
// Create polynomial poly1: 1 + 2x (degree 1)
1123+
let mut poly1 = DensePolynomial {
1124+
coeffs: vec![Fr::from(1), Fr::from(2)],
1125+
};
1126+
1127+
// Create polynomial poly2: 3 + 4x + 5x^2 (degree 2)
1128+
let poly2 = DensePolynomial {
1129+
coeffs: vec![Fr::from(3), Fr::from(4), Fr::from(5)],
1130+
};
1131+
1132+
// Add poly2 to poly1.
1133+
// poly1 has degree 1, poly2 has degree 2. So poly1 must be padded with zero coefficients
1134+
// for the higher degree terms to match poly2's degree.
1135+
poly1 += (Fr::from(1), &poly2);
1136+
1137+
// After addition, the result should be:
1138+
// 4 + 6x + 5x^2 (coefficients [4, 6, 5])
1139+
assert_eq!(poly1.coeffs, vec![Fr::from(4), Fr::from(6), Fr::from(5)]);
1140+
}
10331141
}

0 commit comments

Comments
 (0)