Home > Software engineering >  Sage / Python: Empty tuple from non-empty generator
Sage / Python: Empty tuple from non-empty generator

Time:09-16

New to Sage, I am running into the following problem with this piece of code:

    abc2 = ((x * d).numerator() for x in abc)
    for x in abc2:
        show (type(x))
        show (gcd (x.coefficients()))
    g = (gcd (x.coefficients()) for x in abc2)
    print ("g =", tuple(g))

printing the following output:

<class 'sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular'>
177282774041995797378340812360777728/101
<class 'sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular'>
177282774041995797378340812360777728
<class 'sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular'>
177282774041995797378340812360777728
g = ()

As you can infer from the prints in the loop, 3 gcds are computed as expected from gcd (x.coefficients()). However, when gcd (x.coefficients()) is used in the generator after the loop, the generator is empty where I'd expect it to have 3 elements?

What am I missing here? I checked the generated .py file and that portion is unchanged, so my understanding of Python is wrong?

$ sage --version
SageMath version 9.0, Release Date: 2020-01-01

FYI, here is the complete Sage code, the snip above starts at line 24:

#!/usr/bin/env sage

R.<a,b,c> = QQ[]
    
def to_xy (abc, E):
    (a2, a1) = E
    (a, b, c) = abc

    d = 6*a   6*b - c
    x = -28 * (a   b   2*c) / d
    y = 364 * (a - b) / d
    return (x, y)


def to2_abc (P, E):
    """ Get back from a point P = (x,y) on
        E: y^2 = x^3   a2 x^2   a1 x  to (a,b,c).
    """
    (x,y) = P

    abc = (-56/101 - 12 * x, 56 - x   y, 56 - x - y)

    d = lcm (x.denominator() for x in abc)
    abc2 = ((x * d).numerator() for x in abc)
    for x in abc2:
        show (type(x))
        show (gcd (x.coefficients()))
    g = (gcd (x.coefficients()) for x in abc2)
    print ("g =", tuple(g))


def ECadd (P, E):
    (xP, yP) = P
    (a2,a1) = E

    # Get to short Weierstrass form  E': y^2 = x^2   A x   B.
    k = -a2 / 3
    A = 3*k*k   2*a2*k   a1
    # B = (k*k   a2*k   a1) * k

    (xS, yS) = (xP-k, yP)

    # Add S to itself on E'.
    s = (3 * xS*xS   A) / (2 * yS)
    xSS = s*s - xS - xS
    ySS = -yS - s * (xSS - xS)

    # Return P P on E.
    (xPP, yPP) = (xSS k, ySS)
    return (xPP, yPP)


E = (109, 224)

P = to_xy ((a,b,c), E)
P2 = ECadd (P, E)

to2_abc (P2, E)

CodePudding user response:

When you iterate over a generator, the iteration stops when the generator is exhausted, so when you iterate over it a second time, there are no elements left.

If you need to iterate over the data more than once, convert it to another type like a list first, then iterate over that.

  • Related