@@ -116,6 +116,28 @@ impl<T> Sum<T> {
116116/// The indices refer to external lists managed by the containing LinearMap.
117117pub type LinearCombination < G > = Sum < Weighted < Term < G > , <G as group:: Group >:: Scalar > > ;
118118
119+ impl < G : PrimeGroup > LinearMap < G > {
120+ fn map ( & self , scalars : & [ G :: Scalar ] ) -> Result < Vec < G > , InvalidInstance > {
121+ self . linear_combinations . iter ( ) . map (
122+ |lc| {
123+ let weighted_coefficients =
124+ lc. 0 . iter ( )
125+ . map ( |weighted| weighted. term . scalar . value ( scalars) * weighted. weight )
126+ . collect :: < Vec < _ > > ( ) ;
127+ let elements =
128+ lc. 0 . iter ( )
129+ . map ( |weighted| self . group_elements . get ( weighted. term . elem ) )
130+ . collect :: < Result < Vec < _ > , InvalidInstance > > ( ) ;
131+ match elements {
132+ Ok ( elements) => Ok ( msm_pr ( & weighted_coefficients, & elements) ) ,
133+ Err ( error) => Err ( error) ,
134+ }
135+ }
136+ ) .
137+ collect :: < Result < Vec < _ > , InvalidInstance > > ( ) . into ( )
138+ }
139+ }
140+
119141/// Ordered mapping of [GroupVar] to group elements assignments.
120142#[ derive( Clone , Debug ) ]
121143pub struct GroupMap < G > ( Vec < Option < G > > ) ;
@@ -465,23 +487,16 @@ impl<G: PrimeGroup> LinearRelation<G> {
465487 panic ! ( "invalid LinearRelation: different number of constraints and image variables" ) ;
466488 }
467489
468- for ( lc, lhs) in iter:: zip (
469- self . linear_map . linear_combinations . as_slice ( ) ,
470- self . image . as_slice ( ) ,
490+ let mapped_scalars = self . linear_map . map ( scalars) ?;
491+
492+ for ( mapped_scalar, lhs) in iter:: zip (
493+ mapped_scalars,
494+ & self . image ,
471495 ) {
472- // TODO: The multiplication by the (public) weight is potentially wasteful in the
473- // weight is most commonly 1, but multiplication is constant time.
474- let weighted_coefficients =
475- lc. 0 . iter ( )
476- . map ( |weighted| weighted. term . scalar . value ( scalars) * weighted. weight )
477- . collect :: < Vec < _ > > ( ) ;
478- let elements =
479- lc. 0 . iter ( )
480- . map ( |weighted| self . linear_map . group_elements . get ( weighted. term . elem ) )
481- . collect :: < Result < Vec < _ > , _ > > ( ) ?;
496+
482497 self . linear_map
483498 . group_elements
484- . assign_element ( * lhs, msm_pr ( & weighted_coefficients , & elements ) )
499+ . assign_element ( * lhs, mapped_scalar )
485500 }
486501 Ok ( ( ) )
487502 }
0 commit comments