@@ -17,8 +17,7 @@ use crate::fft::{DensePolynomial, EvaluationDomain, Evaluations as EvaluationsOn
17
17
use snarkvm_fields:: { Field , PrimeField } ;
18
18
use snarkvm_utilities:: { cfg_iter, cfg_iter_mut, CanonicalDeserialize , CanonicalSerialize } ;
19
19
20
- use anyhow:: { ensure, Result } ;
21
- use hashbrown:: HashMap ;
20
+ use anyhow:: Result ;
22
21
use std:: borrow:: Cow ;
23
22
24
23
#[ cfg( feature = "serial" ) ]
@@ -142,7 +141,7 @@ impl<F: Field> LabeledPolynomial<F> {
142
141
#[ derive( Debug , Clone ) ]
143
142
pub struct LabeledPolynomialWithBasis < ' a , F : PrimeField > {
144
143
pub info : PolynomialInfo ,
145
- pub polynomial : Vec < ( F , PolynomialWithBasis < ' a , F > ) > ,
144
+ pub polynomial : PolynomialWithBasis < ' a , F > ,
146
145
}
147
146
148
147
impl < ' a , F : PrimeField > LabeledPolynomialWithBasis < ' a , F > {
@@ -155,16 +154,6 @@ impl<'a, F: PrimeField> LabeledPolynomialWithBasis<'a, F> {
155
154
) -> Self {
156
155
let polynomial = PolynomialWithBasis :: new_monomial_basis_ref ( polynomial, degree_bound) ;
157
156
let info = PolynomialInfo :: new ( label, degree_bound, hiding_bound) ;
158
- Self { info, polynomial : vec ! [ ( F :: one( ) , polynomial) ] }
159
- }
160
-
161
- /// Construct a new labeled polynomial by consuming `polynomial`.
162
- pub fn new_linear_combination (
163
- label : PolynomialLabel ,
164
- polynomial : Vec < ( F , PolynomialWithBasis < ' a , F > ) > ,
165
- hiding_bound : Option < usize > ,
166
- ) -> Self {
167
- let info = PolynomialInfo :: new ( label, None , hiding_bound) ;
168
157
Self { info, polynomial }
169
158
}
170
159
@@ -175,7 +164,7 @@ impl<'a, F: PrimeField> LabeledPolynomialWithBasis<'a, F> {
175
164
) -> Self {
176
165
let polynomial = PolynomialWithBasis :: new_lagrange_basis ( polynomial) ;
177
166
let info = PolynomialInfo :: new ( label, None , hiding_bound) ;
178
- Self { info, polynomial : vec ! [ ( F :: one ( ) , polynomial ) ] }
167
+ Self { info, polynomial }
179
168
}
180
169
181
170
pub fn new_lagrange_basis_ref (
@@ -185,7 +174,7 @@ impl<'a, F: PrimeField> LabeledPolynomialWithBasis<'a, F> {
185
174
) -> Self {
186
175
let polynomial = PolynomialWithBasis :: new_lagrange_basis_ref ( polynomial) ;
187
176
let info = PolynomialInfo :: new ( label, None , hiding_bound) ;
188
- Self { info, polynomial : vec ! [ ( F :: one ( ) , polynomial ) ] }
177
+ Self { info, polynomial }
189
178
}
190
179
191
180
/// Return the label for `self`.
@@ -199,96 +188,23 @@ impl<'a, F: PrimeField> LabeledPolynomialWithBasis<'a, F> {
199
188
}
200
189
201
190
pub fn degree ( & self ) -> usize {
202
- self . polynomial
203
- . iter ( )
204
- . map ( |( _, p) | match p {
205
- PolynomialWithBasis :: Lagrange { evaluations } => evaluations. domain ( ) . size ( ) - 1 ,
206
- PolynomialWithBasis :: Monomial { polynomial, .. } => polynomial. degree ( ) ,
207
- } )
208
- . max ( )
209
- . unwrap_or ( 0 )
191
+ match & self . polynomial {
192
+ PolynomialWithBasis :: Lagrange { evaluations } => evaluations. domain ( ) . size ( ) - 1 ,
193
+ PolynomialWithBasis :: Monomial { polynomial, .. } => polynomial. degree ( ) ,
194
+ }
210
195
}
211
196
212
197
/// Evaluate the polynomial in `self`.
213
198
pub fn evaluate ( & self , point : F ) -> F {
214
- self . polynomial . iter ( ) . map ( |( coeff, p) | p. evaluate ( point) * coeff) . sum ( )
215
- }
216
-
217
- /// Compute a linear combination of the terms in `self.polynomial`, producing an iterator
218
- /// over polynomials of the same time.
219
- pub fn sum ( & self ) -> Result < impl Iterator < Item = PolynomialWithBasis < ' a , F > > > {
220
- if self . polynomial . len ( ) == 1 && self . polynomial [ 0 ] . 0 . is_one ( ) {
221
- Ok ( vec ! [ self . polynomial[ 0 ] . 1 . clone( ) ] . into_iter ( ) )
222
- } else {
223
- use PolynomialWithBasis :: * ;
224
- let mut lagrange_polys = HashMap :: < usize , Vec < _ > > :: new ( ) ;
225
- let mut dense_polys = HashMap :: < _ , DensePolynomial < F > > :: new ( ) ;
226
- let mut sparse_poly = SparsePolynomial :: zero ( ) ;
227
- // We have sets of polynomials divided along three criteria:
228
- // 1. All `Lagrange` polynomials are in the set corresponding to their domain.
229
- // 2. All `Dense` polynomials are in the set corresponding to their degree bound.
230
- // 3. All `Sparse` polynomials are in the set corresponding to their degree bound.
231
- for ( c, poly) in self . polynomial . iter ( ) {
232
- match poly {
233
- Monomial { polynomial, degree_bound } => {
234
- use Polynomial :: * ;
235
- match polynomial. as_ref ( ) {
236
- Dense ( p) => {
237
- if let Some ( e) = dense_polys. get_mut ( degree_bound) {
238
- // Zip safety: `p` could be of smaller degree than `e`,
239
- // so it's okay to just use `zip` here.
240
- ensure ! ( e. len( ) >= p. coeffs. len( ) ) ;
241
- cfg_iter_mut ! ( e) . zip ( & p. coeffs ) . for_each ( |( e, f) | * e += * c * f)
242
- } else {
243
- let mut e: DensePolynomial < F > = p. clone ( ) . into_owned ( ) ;
244
- cfg_iter_mut ! ( e) . for_each ( |e| * e *= c) ;
245
- dense_polys. insert ( degree_bound, e) ;
246
- }
247
- }
248
- Sparse ( p) => sparse_poly += ( * c, p. as_ref ( ) ) ,
249
- }
250
- }
251
- Lagrange { evaluations } => {
252
- let domain = evaluations. domain ( ) . size ( ) ;
253
- if let Some ( e) = lagrange_polys. get_mut ( & domain) {
254
- ensure ! ( e. len( ) == evaluations. evaluations. len( ) ) ;
255
- cfg_iter_mut ! ( e) . zip_eq ( & evaluations. evaluations ) . for_each ( |( e, f) | * e += * c * f)
256
- } else {
257
- let mut e = evaluations. clone ( ) . into_owned ( ) . evaluations ;
258
- cfg_iter_mut ! ( e) . for_each ( |e| * e *= c) ;
259
- lagrange_polys. insert ( domain, e) ;
260
- }
261
- }
262
- }
263
- }
264
- let sparse_poly = Polynomial :: from ( sparse_poly) ;
265
- let sparse_poly = Monomial { polynomial : Cow :: Owned ( sparse_poly) , degree_bound : None } ;
266
- Ok ( lagrange_polys
267
- . into_iter ( )
268
- . map ( |( k, v) | {
269
- let domain = EvaluationDomain :: new ( k) . unwrap ( ) ;
270
- Lagrange { evaluations : Cow :: Owned ( EvaluationsOnDomain :: from_vec_and_domain ( v, domain) ) }
271
- } )
272
- . chain ( {
273
- dense_polys
274
- . into_iter ( )
275
- . map ( |( degree_bound, p) | PolynomialWithBasis :: new_dense_monomial_basis ( p, * degree_bound) )
276
- } )
277
- . chain ( [ sparse_poly] )
278
- . collect :: < Vec < _ > > ( )
279
- . into_iter ( ) )
280
- }
199
+ self . polynomial . evaluate ( point)
281
200
}
282
201
283
202
/// Retrieve the degree bound in `self`.
284
203
pub fn degree_bound ( & self ) -> Option < usize > {
285
- self . polynomial
286
- . iter ( )
287
- . filter_map ( |( _, p) | match p {
288
- PolynomialWithBasis :: Monomial { degree_bound, .. } => * degree_bound,
289
- _ => None ,
290
- } )
291
- . max ( )
204
+ match self . polynomial {
205
+ PolynomialWithBasis :: Monomial { degree_bound, .. } => degree_bound,
206
+ _ => None ,
207
+ }
292
208
}
293
209
294
210
/// Retrieve whether the polynomial in `self` should be hidden.
@@ -308,7 +224,7 @@ impl<'a, F: PrimeField> From<&'a LabeledPolynomial<F>> for LabeledPolynomialWith
308
224
polynomial : Cow :: Borrowed ( other. polynomial ( ) ) ,
309
225
degree_bound : other. degree_bound ( ) ,
310
226
} ;
311
- Self { info : other. info . clone ( ) , polynomial : vec ! [ ( F :: one ( ) , polynomial ) ] }
227
+ Self { info : other. info . clone ( ) , polynomial }
312
228
}
313
229
}
314
230
@@ -318,7 +234,7 @@ impl<'a, F: PrimeField> From<LabeledPolynomial<F>> for LabeledPolynomialWithBasi
318
234
polynomial : Cow :: Owned ( other. polynomial ) ,
319
235
degree_bound : other. info . degree_bound ,
320
236
} ;
321
- Self { info : other. info . clone ( ) , polynomial : vec ! [ ( F :: one ( ) , polynomial ) ] }
237
+ Self { info : other. info . clone ( ) , polynomial }
322
238
}
323
239
}
324
240
0 commit comments