@@ -378,27 +378,34 @@ impl<'a, F: Field> AddAssign<&'a DensePolynomial<F>> for DensePolynomial<F> {
378
378
379
379
impl < ' a , F : Field > AddAssign < ( F , & ' a DensePolynomial < F > ) > for DensePolynomial < F > {
380
380
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.
381
387
if self . is_zero ( ) {
382
- self . coeffs . truncate ( 0 ) ;
388
+ self . coeffs . clear ( ) ;
383
389
self . coeffs . extend_from_slice ( & other. coeffs ) ;
384
390
self . coeffs . iter_mut ( ) . for_each ( |c| * c *= & f) ;
385
391
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 ( ) {
391
396
self . coeffs . resize ( other. coeffs . len ( ) , F :: zero ( ) ) ;
392
397
}
398
+
399
+ // Add corresponding coefficients from the second polynomial, scaled by f.
393
400
self . coeffs
394
401
. iter_mut ( )
395
402
. zip ( & other. coeffs )
396
- . for_each ( |( a, b) | {
397
- * a += & ( f * b) ;
398
- } ) ;
403
+ . for_each ( |( a, b) | * a += f * b) ;
404
+
399
405
// 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.
402
409
self . truncate_leading_zeros ( ) ;
403
410
}
404
411
}
@@ -1030,4 +1037,105 @@ mod tests {
1030
1037
1031
1038
assert_eq ! ( eval1, eval2) ;
1032
1039
}
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
+ }
1033
1141
}
0 commit comments