2
2
3
3
//! Polynomials over Finite Fields
4
4
5
- use core:: { iter, ops} ;
5
+ use core:: { fmt , iter, ops, slice } ;
6
6
7
7
use super :: { ExtensionField , Field , FieldVec } ;
8
8
@@ -15,6 +15,13 @@ pub struct Polynomial<F> {
15
15
}
16
16
17
17
impl < F : Field > Polynomial < F > {
18
+ /// Determines whether the residue is representable, given the current
19
+ /// compilation context.
20
+ pub fn has_data ( & self ) -> bool { self . inner . has_data ( ) }
21
+
22
+ /// Panics if [`Self::has_data`] is false, with an informative panic message.
23
+ pub fn assert_has_data ( & self ) { self . inner . assert_has_data ( ) }
24
+
18
25
/// Provides access to the underlying [`FieldVec`].
19
26
pub fn into_inner ( self ) -> FieldVec < F > { self . inner }
20
27
@@ -39,6 +46,18 @@ impl<F: Field> Polynomial<F> {
39
46
degree_without_leading_zeros - leading_zeros
40
47
}
41
48
49
+ /// An iterator over the coefficients of the polynomial.
50
+ ///
51
+ /// Yields value in "little endian" order; that is, the constant term is returned first.
52
+ ///
53
+ /// # Panics
54
+ ///
55
+ /// Panics if [`Self::has_data`] is false.
56
+ pub fn iter ( & self ) -> slice:: Iter < F > {
57
+ self . assert_has_data ( ) ;
58
+ self . inner . iter ( )
59
+ }
60
+
42
61
/// The leading term of the polynomial.
43
62
///
44
63
/// For the constant 0 polynomial, will return 0.
@@ -55,7 +74,15 @@ impl<F: Field> Polynomial<F> {
55
74
/// factor of the polynomial.
56
75
pub fn zero_is_root ( & self ) -> bool { self . inner . is_empty ( ) || self . leading_term ( ) == F :: ZERO }
57
76
58
- /// An iterator over the roots of the residue, when interpreted as a polynomial.
77
+ /// Helper function to add leading 0 terms until the polynomial has a specified
78
+ /// length.
79
+ fn zero_pad_up_to ( & mut self , len : usize ) {
80
+ while self . inner . len ( ) < len {
81
+ self . inner . push ( F :: default ( ) ) ;
82
+ }
83
+ }
84
+
85
+ /// An iterator over the roots of the polynomial.
59
86
///
60
87
/// Takes a base element `base`. The roots of the residue will be yielded as
61
88
/// nonnegative integers between 0 and 1 less than the order of the base,
@@ -201,6 +228,19 @@ impl<F: Field> Polynomial<F> {
201
228
}
202
229
}
203
230
231
+ impl < F : Field > fmt:: Display for Polynomial < F > {
232
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
233
+ if self . has_data ( ) {
234
+ for fe in self . iter ( ) {
235
+ write ! ( f, "{}" , fe) ?;
236
+ }
237
+ Ok ( ( ) )
238
+ } else {
239
+ f. write_str ( "<residue>" )
240
+ }
241
+ }
242
+ }
243
+
204
244
impl < F : Field > iter:: FromIterator < F > for Polynomial < F > {
205
245
#[ inline]
206
246
fn from_iter < I > ( iter : I ) -> Self
@@ -215,6 +255,59 @@ impl<F> From<FieldVec<F>> for Polynomial<F> {
215
255
fn from ( inner : FieldVec < F > ) -> Self { Self { inner } }
216
256
}
217
257
258
+ impl < F : Field > ops:: Add < & Polynomial < F > > for Polynomial < F > {
259
+ type Output = Polynomial < F > ;
260
+
261
+ fn add ( mut self , other : & Polynomial < F > ) -> Polynomial < F > {
262
+ self += other;
263
+ self
264
+ }
265
+ }
266
+
267
+ impl < F : Field > ops:: Add < Polynomial < F > > for Polynomial < F > {
268
+ type Output = Polynomial < F > ;
269
+ fn add ( self , other : Polynomial < F > ) -> Polynomial < F > { self + & other }
270
+ }
271
+
272
+ impl < F : Field > ops:: Sub < & Polynomial < F > > for Polynomial < F > {
273
+ type Output = Polynomial < F > ;
274
+ fn sub ( mut self , other : & Polynomial < F > ) -> Polynomial < F > {
275
+ self -= other;
276
+ self
277
+ }
278
+ }
279
+
280
+ impl < F : Field > ops:: Sub < Polynomial < F > > for Polynomial < F > {
281
+ type Output = Polynomial < F > ;
282
+ fn sub ( self , other : Polynomial < F > ) -> Polynomial < F > { self - & other }
283
+ }
284
+
285
+ impl < F : Field > ops:: AddAssign < & Polynomial < F > > for Polynomial < F > {
286
+ fn add_assign ( & mut self , other : & Self ) {
287
+ self . zero_pad_up_to ( other. inner . len ( ) ) ;
288
+ for i in 0 ..other. inner . len ( ) {
289
+ self . inner [ i] += & other. inner [ i] ;
290
+ }
291
+ }
292
+ }
293
+
294
+ impl < F : Field > ops:: AddAssign for Polynomial < F > {
295
+ fn add_assign ( & mut self , other : Polynomial < F > ) { * self += & other; }
296
+ }
297
+
298
+ impl < F : Field > ops:: SubAssign < & Polynomial < F > > for Polynomial < F > {
299
+ fn sub_assign ( & mut self , other : & Polynomial < F > ) {
300
+ self . zero_pad_up_to ( other. inner . len ( ) ) ;
301
+ for i in 0 ..other. inner . len ( ) {
302
+ self . inner [ i] -= & other. inner [ i] ;
303
+ }
304
+ }
305
+ }
306
+
307
+ impl < F : Field > ops:: SubAssign for Polynomial < F > {
308
+ fn sub_assign ( & mut self , other : Polynomial < F > ) { * self -= & other; }
309
+ }
310
+
218
311
/// An iterator over the roots of a polynomial.
219
312
///
220
313
/// This iterator is constructed by the [`Polynomial::find_nonzero_distinct_roots`]
0 commit comments