pub fn batch_normalize<'a>(v: &'a mut [ExtendedPoint]) -> impl Iterator<Item = AffinePoint> + 'a {
    let mut acc = Fq::one();
    for p in v.iter_mut() {
        // We use the `t1` field of `ExtendedPoint` to store the product
        // of previous z-coordinates seen.
        p.t1 = acc;
        acc *= &p.z;
    }

    // This is the inverse, as all z-coordinates are nonzero.
    acc = acc.invert().unwrap();

    for p in v.iter_mut().rev() {
        let mut q = *p;

        // Compute tmp = 1/z
        let tmp = q.t1 * acc;

        // Cancel out z-coordinate in denominator of `acc`
        acc *= &q.z;

        // Set the coordinates to the correct value
        q.u *= &tmp; // Multiply by 1/z
        q.v *= &tmp; // Multiply by 1/z
        q.z = Fq::one(); // z-coordinate is now one
        q.t1 = q.u;
        q.t2 = q.v;

        *p = q;
    }

    // All extended points are now normalized, but the type
    // doesn't encode this fact. Let us offer affine points
    // to the caller.

    v.iter().map(|p| AffinePoint { u: p.u, v: p.v })
}
/// This takes a mutable slice of `ExtendedPoint`s and "normalizes" them using
/// only a single inversion for the entire batch. This normalization results in
/// all of the points having a Z-coordinate of one. Further, an iterator is
/// returned which can be used to obtain `AffinePoint`s for each element in the
/// slice.
///
/// This costs 5 multiplications per element, and a field inversion.
This takes a mutable slice of `ExtendedPoint`s and "normalizes" them using
only a single inversion for the entire batch. This normalization results in
all of the points having a Z-coordinate of one. Further, an iterator is
returned which can be used to obtain `AffinePoint`s for each element in the
slice.

This costs 5 multiplications per element, and a field inversion.
This takes a mutable slice of ` ExtendedPoint ` s and " normalizes " them using only a single inversion for the entire batch . This normalization results in all of the points having a Z - coordinate of one . Further an iterator is returned which can be used to obtain ` AffinePoint ` s for each element in the slice . This costs 5 multiplications per element and a field inversion .
pub fn batch_normalize<'a>(v: &'a mut [ExtendedPoint]) -> impl Iterator<Item = AffinePoint> + 'a {
    let mut acc = Fq::one();
    for p in v.iter_mut() {
        // We use the `t1` field of `ExtendedPoint` to store the product
        // of previous z-coordinates seen.
        p.t1 = acc;
        acc *= &p.z;
    }
    // This is the inverse, as all z-coordinates are nonzero.
    acc = acc.invert().unwrap();
    for p in v.iter_mut().rev() {
        let mut q = *p;
        // Compute tmp = 1/z
        let tmp = q.t1 * acc;
        // Cancel out z-coordinate in denominator of `acc`
        acc *= &q.z;
        // Set the coordinates to the correct value
        q.u *= &tmp; // Multiply by 1/z
        q.v *= &tmp; // Multiply by 1/z
        q.z = Fq::one(); // z-coordinate is now one
        q.t1 = q.u;
        q.t2 = q.v;
        *p = q;
    }
    // All extended points are now normalized, but the type
    // doesn't encode this fact. Let us offer affine points
    // to the caller.
    v.iter().map(|p| AffinePoint { u: p.u, v: p.v })
}
pub fn batch_normalize < ' a > ( v : & ' a mut [ ExtendedPoint ] ) -> impl Iterator < Item = AffinePoint > + ' a { let mut acc = Fq :: one ( ) ; for p in v . iter_mut ( ) { // We use the `t1` field of `ExtendedPoint` to store the product // of previous z-coordinates seen. p . t1 = acc ; acc *= & p . z ; } // This is the inverse, as all z-coordinates are nonzero. acc = acc . invert ( ) . unwrap ( ) ; for p in v . iter_mut ( ) . rev ( ) { let mut q = * p ; // Compute tmp = 1/z let tmp = q . t1 * acc ; // Cancel out z-coordinate in denominator of `acc` acc *= & q . z ; // Set the coordinates to the correct value q . u *= & tmp ; // Multiply by 1/z q . v *= & tmp ; // Multiply by 1/z q . z = Fq :: one ( ) ; // z-coordinate is now one q . t1 = q . u ; q . t2 = q . v ; * p = q ; } // All extended points are now normalized, but the type // doesn't encode this fact. Let us offer affine points // to the caller. v . iter ( ) . map ( | p | AffinePoint { u : p . u , v : p . v } ) }
This takes a mutable slice of `ExtendedPoint`s and "normalizes" them using
only a single inversion for the entire batch.
This takes a mutable slice of ` ExtendedPoint ` s and " normalizes " them using only a single inversion for the entire batch .
v
&'a mut [ExtendedPoint]
v
&'a mut [ExtendedPoint]