Ticket #5674: twist.patch

File twist.patch, 25.2 KB (added by cremona, 12 years ago)

apply to 3.4.1.apha0 + #4667 patches

  • sage/schemes/elliptic_curves/all.py

    # HG changeset patch
    # User John Cremona <john.cremona@gmail.com>
    # Date 1238759297 -3600
    # Node ID 3fa8b641e0fe5afd6bb7e02d410fd1d65c93b9d3
    # Parent  653655f60cc4b06809628ab06e56002e3d64e70c
    [mq]: twist
    
    diff -r 653655f60cc4 -r 3fa8b641e0fe sage/schemes/elliptic_curves/all.py
    a b  
    1818#*****************************************************************************
    1919
    2020from constructor import (EllipticCurve, EllipticCurve_from_c4c6,
    21                          EllipticCurve_from_cubic)
     21                         EllipticCurve_from_j, EllipticCurve_from_cubic)
    2222
    2323
    2424from ell_generic import is_EllipticCurve, Hasse_bounds
  • sage/schemes/elliptic_curves/constructor.py

    diff -r 653655f60cc4 -r 3fa8b641e0fe sage/schemes/elliptic_curves/constructor.py
    a b  
    5656      over R with given a-invariants. Here R can be an arbitrary ring.
    5757      Note that addition need not be defined.
    5858   
     59           
    5960    - EllipticCurve(j): Return an elliptic curve with j-invariant
    60       `j`.
     61      `j`.  Warning: this is deprecated.  Use ``EllipticCurve_from_j(j)`` instead.         
     62
    6163   
    6264    EXAMPLES: We illustrate creating elliptic curves.
    6365   
     
    113115        sage: E(0)
    114116        (0 : 1 : 0)
    115117    """
    116     # TODO - - implement
    117         #sage: E = EllipticCurve(ZZ, [0, 0,1,-1,0])
    118         #sage: E
    119         #Elliptic Curve defined by y^2 + y = x^3 - x over Integer Ring
    120 
    121     #Of course, arithmetic on elliptic curves over Z need not be defined:
    122         #sage: P = E([0,0])
    123         #sage: P + P + P + P
    124         #(2, -3)
    125         #sage: P + P + P + P + P
    126         #Traceback (most recent call last):
    127         #...
    128         #ArithmeticError: Point (1/4, -5/8) is not on curve.
    129     #
    130118    import ell_generic, ell_finite_field, ell_number_field, ell_rational_field, ell_padic_field  # here to avoid circular includes
    131119   
    132120    if isinstance(x, SymbolicEquation):
     
    191179        return ell_rational_field.EllipticCurve_rational_field(x)
    192180       
    193181    if rings.is_RingElement(x) and y is None:
     182        from sage.misc.misc import deprecation
     183        deprecation("'EllipticCurve(j)' is deprecated; use 'EllipticCurve_from_j(j)' instead.")
    194184        # Fixed for all characteristics and cases by John Cremona
    195185        j=x
    196186        F=j.parent().fraction_field()
    197187        char=F.characteristic()
     188        print "constructin an elliptic curve from j = ",j
    198189        if char==2:
    199190            if j==0:
    200191                return EllipticCurve(F, [ 0, 0, 1, 0, 0 ])
     
    257248        K = K.fraction_field()
    258249    return EllipticCurve([-K(c4)/K(48), -K(c6)/K(864)])
    259250
     251def EllipticCurve_from_j(j):
     252    """
     253    Return an elliptic curve with given `j`-invariant.
     254   
     255    EXAMPLES::
     256
     257        sage: E = EllipticCurve_from_j(0); E; E.j_invariant(); E.label()
     258        Elliptic Curve defined by y^2 + y = x^3 over Rational Field
     259        0
     260        '27a3'
     261
     262        sage: E = EllipticCurve_from_j(1728); E; E.j_invariant(); E.label()
     263        Elliptic Curve defined by y^2 = x^3 - x over Rational Field
     264        1728
     265        '32a2'
     266
     267        sage: E = EllipticCurve_from_j(1); E; E.j_invariant()
     268        Elliptic Curve defined by y^2 + x*y = x^3 + 36*x + 3455 over Rational Field
     269        1
     270
     271    """
     272    try:
     273        K = j.parent()
     274    except AttributeError:
     275        K = rings.RationalField()
     276    if not rings.is_Field(K):
     277        K = K.fraction_field()
     278
     279    char=K.characteristic()
     280    if char==2:
     281        if j == 0:
     282            return EllipticCurve(K, [ 0, 0, 1, 0, 0 ])
     283        else:
     284            return EllipticCurve(K, [ 1, 0, 0, 0, 1/j ])
     285    if char == 3:
     286        if j==0:
     287            return EllipticCurve(K, [ 0, 0, 0, 1, 0 ])
     288        else:
     289            return EllipticCurve(K, [ 0, j, 0, 0, -j**2 ])
     290
     291    if K is rings.RationalField():
     292        # we construct the minimal twist, i.e. the curve with minimal
     293        # conductor with this j_invariant:
     294
     295        if j == 0:
     296            return EllipticCurve(K, [ 0, 0, 1, 0, 0 ]) # 27a3
     297        if j == 1728:
     298            return EllipticCurve(K, [ 0, 0, 0, -1, 0 ]) # 32a2
     299
     300        n = j.numerator()
     301        m = n-1728*j.denominator()
     302        a4 = -3*n*m
     303        a6 = -2*n*m**2
     304
     305        # Now E=[0,0,0,a4,a6] has j-invariant j=n/d
     306
     307        from sage.sets.set import Set
     308        for p in Set(n.prime_divisors()+m.prime_divisors()):
     309            e = min(a4.valuation(p)//2,a6.valuation(p)//3)
     310            if e>0:
     311                p  = p**e
     312                a4 /= p**2
     313                a6 /= p**3
     314
     315        # Now E=[0,0,0,a4,a6] is minimal at all p != 2,3
     316
     317        tw = [-1,2,-2,3,-3,6,-6]
     318        E1 = EllipticCurve([0,0,0,a4,a6])
     319        Elist = [E1] + [E1.quadratic_twist(t) for t in tw]
     320        crv_cmp = lambda E,F: cmp(E.conductor(),F.conductor())
     321        Elist.sort(cmp=crv_cmp)
     322        return Elist[0]
     323
     324    # defaults for all other fields:   
     325    if j == 0:
     326        return EllipticCurve(K, [ 0, 0, 0, 0, 1 ])
     327    if j == 1728:
     328        return EllipticCurve(K, [ 0, 0, 0, 1, 0 ])
     329    k=j-1728
     330    return EllipticCurve(K, [0,0,0,-3*j*k, -2*j*k**2])
     331
    260332def EllipticCurve_from_cubic(F, P):
    261333    r"""
    262334    Given a nonsingular homogenous cubic polynomial F over
    263     `\mathbb{Q}` in three variables x, y, z and a projective
    264     solution P=[a,b,c] to F(P)=0, find the minimal Weierstrass equation
    265     of the elliptic curve over `\mathbb{Q}` that is isomorphic
    266     to the curve defined by `F=0`.
     335    `\mathbb{Q}` in three variables x, y, z and a projective solution
     336    P=[a,b,c] to F(P)=0, find the minimal Weierstrass equation of the
     337    elliptic curve over `\mathbb{Q}` that is isomorphic to the curve
     338    defined by `F=0`.
    267339   
    268340    .. note::
    269341
  • sage/schemes/elliptic_curves/ell_finite_field.py

    diff -r 653655f60cc4 -r 3fa8b641e0fe sage/schemes/elliptic_curves/ell_finite_field.py
    a b  
    3232
    3333from ell_generic import Hasse_bounds
    3434from ell_field import EllipticCurve_field
    35 from constructor import EllipticCurve
     35from constructor import EllipticCurve, EllipticCurve_from_j
    3636from sage.schemes.hyperelliptic_curves.hyperelliptic_finite_field import HyperellipticCurve_finite_field
    3737import sage.rings.ring as ring
    3838from sage.rings.all import Integer, ZZ, PolynomialRing, ComplexField, FiniteField, GF, polygen
     
    830830        jkj=kj.gen() if j_deg>1 else j_pol.roots(multiplicities=False)[0]
    831831
    832832        # recursive call which will do all the real work:
    833         Ej = EllipticCurve(jkj)
     833        Ej = EllipticCurve_from_j(jkj)
    834834        N=Ej.cardinality(extension_degree=d//j_deg)
    835835
    836836        # if curve ia a (quadratic) twist of the "standard" one:
    837         if not self.is_isomorphic(EllipticCurve(j)): N=2*(q+1)-N
     837        if not self.is_isomorphic(EllipticCurve_from_j(j)): N=2*(q+1)-N
    838838           
    839839        self._order = N
    840840        return self._order
  • sage/schemes/elliptic_curves/ell_generic.py

    diff -r 653655f60cc4 -r 3fa8b641e0fe sage/schemes/elliptic_curves/ell_generic.py
    a b  
    13691369       
    13701370        EXAMPLES::
    13711371       
    1372             sage: E=EllipticCurve(GF(13)(1728)); E
     1372            sage: E=EllipticCurve_from_j(GF(13)(1728)); E
    13731373            Elliptic Curve defined by y^2  = x^3 + x over Finite Field of size 13
    13741374            sage: E1=E.quartic_twist(2); E1
    13751375            Elliptic Curve defined by y^2  = x^3 + 5*x over Finite Field of size 13
     
    14071407       
    14081408        EXAMPLES::
    14091409       
    1410             sage: E=EllipticCurve(GF(13)(0)); E
     1410            sage: E=EllipticCurve_from_j(GF(13)(0)); E
    14111411            Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 13
    14121412            sage: E1=E.sextic_twist(2); E1
    14131413            Elliptic Curve defined by y^2 = x^3 + 11 over Finite Field of size 13
     
    14381438        assert c4==0
    14391439        return EllipticCurve(K,[0,0,0,0,-54*c6*D])
    14401440
     1441    def is_quadratic_twist(self, other):
     1442        """
     1443        returns D if self is a quadratic twist of other by D, else 0.
     1444
     1445        INPUT:
     1446               
     1447            -  E,F - elliptic curves with the same base field
     1448
     1449        OUTPUT:
     1450
     1451            - 0 if the curves are not quadratic twists
     1452            - D if F is E.quadratic_twist(E) (up to isomorphism)
     1453                (including D=1 if E and F are isomorphic)
     1454
     1455        .. note::
     1456
     1457        Not fully implemented in characteristic 2, or in
     1458        characteristic 3 when both `j`-invariants are 0.
     1459
     1460        EXAMPLES::
     1461
     1462            sage: E = EllipticCurve('11a1')
     1463            sage: Et = E.quadratic_twist(-24)
     1464            sage: E.is_quadratic_twist(Et)
     1465            -6
     1466           
     1467            sage: E1=EllipticCurve([0,0,1,0,0])
     1468            sage: E1.j_invariant()
     1469            0
     1470            sage: E2=EllipticCurve([0,0,0,0,2])
     1471            sage: E1.is_quadratic_twist(E2)
     1472            2
     1473           
     1474            sage: E1=EllipticCurve([0,0,0,1,0])
     1475            sage: E1.j_invariant()
     1476            1728
     1477            sage: E2=EllipticCurve([0,0,0,2,0])
     1478            sage: E1.is_quadratic_twist(E2)
     1479            0
     1480            sage: E2=EllipticCurve([0,0,0,25,0])
     1481            sage: E1.is_quadratic_twist(E2)
     1482            5
     1483           
     1484            sage: F = GF(101)
     1485            sage: E1 = EllipticCurve(F,[4,7])
     1486            sage: E2 = E1.quadratic_twist()
     1487            sage: D = E1.is_quadratic_twist(E2); D!=0
     1488            True
     1489            sage: F = GF(101)
     1490            sage: E1 = EllipticCurve(F,[4,7])
     1491            sage: E2 = E1.quadratic_twist()
     1492            sage: D = E1.is_quadratic_twist(E2)
     1493            sage: E1.quadratic_twist(D).is_isomorphic(E2)
     1494            True
     1495            sage: E1.is_isomorphic(E2)
     1496            False
     1497            sage: F2 = GF(101^2,'a')
     1498            sage: E1.change_ring(F2).is_isomorphic(E2.change_ring(F2))
     1499            True
     1500           
     1501            # Characteristic 3 example:
     1502            sage: F = GF(3^5,'a')
     1503            sage: E1 = EllipticCurve_from_j(F(1))
     1504            sage: E2 = E1.quadratic_twist(-1)
     1505            sage: D = E1.is_quadratic_twist(E2); D!=0
     1506            True
     1507            sage: E1.quadratic_twist(D).is_isomorphic(E2)
     1508            True
     1509           
     1510            sage: E1 = EllipticCurve_from_j(F(0))
     1511            sage: E2 = E1.quadratic_twist()
     1512            sage: D = E1.is_quadratic_twist(E2); D
     1513            1
     1514            sage: E1.is_isomorphic(E2)
     1515            True
     1516
     1517        """
     1518        from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve
     1519        E = self
     1520        F = other
     1521        if not is_EllipticCurve(E) or not is_EllipticCurve(F):
     1522            raise ValueError, "arguments are not elliptic curves"
     1523        K = E.base_ring()
     1524        zero = K.zero_element()
     1525        if not K == F.base_ring():
     1526            return zero
     1527        j=E.j_invariant()
     1528        if  j != F.j_invariant():
     1529            return zero
     1530   
     1531        if E.is_isomorphic(F):
     1532            return K.one_element()
     1533       
     1534        char=K.characteristic()
     1535       
     1536        if char==2:
     1537            raise NotImplementedError, "not implemented in characteristic 2"
     1538        elif char==3:
     1539            if j==0:
     1540                raise NotImplementedError, "not implemented in characteristic 3 for curves of j-invariant 0"
     1541            D = E.b2()/F.b2()
     1542           
     1543        else:
     1544            # now char!=2,3:
     1545            c4E,c6E = E.c_invariants()
     1546            c4F,c6F = F.c_invariants()
     1547
     1548            if j==0:
     1549                um = c6E/c6F
     1550                x=polygen(K)
     1551                ulist=(x**3-um).roots(multiplicities=False)
     1552                if len(ulist)==0:
     1553                    D = zero
     1554                else:
     1555                    D = ulist[0]
     1556            elif j==1728:
     1557                um=c4E/c4F
     1558                x=polygen(K)
     1559                ulist=(x**2-um).roots(multiplicities=False)
     1560                if len(ulist)==0:
     1561                    D = zero
     1562                else:
     1563                    D = ulist[0]
     1564            else:
     1565                D = (c6E*c4F)/(c6F*c4E)
     1566       
     1567        # Normalization of output:
     1568       
     1569        if D.is_zero():
     1570            return D
     1571       
     1572        if K is rings.QQ:
     1573            D = D.squarefree_part()
     1574
     1575        assert E.quadratic_twist(D).is_isomorphic(F)
     1576
     1577        return D
     1578
     1579    def is_quartic_twist(self, other):
     1580        """
     1581        returns D if self is a quartic twist of other by D, else 0.
     1582
     1583        INPUT:
     1584               
     1585            - E,F - elliptic curves with the same base field, whose
     1586               characteristic must not be 2 or 3.
     1587
     1588        OUTPUT:
     1589
     1590            - 0 if the curves are not quartic twists
     1591            - D if F is E.quartic_twist(E) (up to isomorphism)
     1592                (including D=1 if E and F are isomorphic)
     1593
     1594        .. note::
     1595
     1596        Not fully implemented in characteristics 2 or 3.
     1597
     1598        EXAMPLES::
     1599
     1600            sage: E = EllipticCurve_from_j(GF(13)(1728))
     1601            sage: E1 = E.quartic_twist(2)
     1602            sage: D = E.is_quartic_twist(E1); D!=0
     1603            True
     1604            sage: E.quartic_twist(D).is_isomorphic(E1)
     1605            True
     1606
     1607            sage: E = EllipticCurve_from_j(1728)
     1608            sage: E1 = E.quartic_twist(12345)
     1609            sage: D = E.is_quartic_twist(E1); D
     1610            15999120
     1611            sage: (D/12345).is_perfect_power(4)
     1612            True
     1613        """
     1614        from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve
     1615        E = self
     1616        F = other
     1617        if not is_EllipticCurve(E) or not is_EllipticCurve(F):
     1618            raise ValueError, "arguments are not elliptic curves"
     1619        K = E.base_ring()
     1620        zero = K.zero_element()
     1621        if not K == F.base_ring():
     1622            return zero
     1623        j=E.j_invariant()
     1624        if  j != F.j_invariant() or j!=K(1728):
     1625            return zero
     1626   
     1627        if E.is_isomorphic(F):
     1628            return K.one_element()
     1629       
     1630        char=K.characteristic()
     1631       
     1632        if char==2:
     1633            raise NotImplementedError, "not implemented in characteristic 2"
     1634        elif char==3:
     1635            raise NotImplementedError, "not implemented in characteristic 3"           
     1636        else:
     1637            # now char!=2,3:
     1638            D = F.c4()/E.c4()
     1639       
     1640        if D.is_zero():
     1641            return D
     1642       
     1643        assert E.quartic_twist(D).is_isomorphic(F)
     1644
     1645        return D
     1646
     1647    def is_sextic_twist(self, other):
     1648        """
     1649        returns D if self is a sextic twist of other by D, else 0.
     1650
     1651        INPUT:
     1652               
     1653            - E,F - elliptic curves with the same base field, whose
     1654               characteristic must not be 2 or 3.
     1655
     1656        OUTPUT:
     1657
     1658            - 0 if the curves are not sextic twists
     1659            - D if F is E.sextic_twist(E) (up to isomorphism)
     1660                (including D=1 if E and F are isomorphic)
     1661
     1662        .. note::
     1663
     1664        Not fully implemented in characteristics 2 or 3.
     1665
     1666        EXAMPLES::
     1667
     1668            sage: E = EllipticCurve_from_j(GF(13)(0))
     1669            sage: E1 = E.sextic_twist(2)
     1670            sage: D = E.is_sextic_twist(E1); D!=0
     1671            True
     1672            sage: E.sextic_twist(D).is_isomorphic(E1)
     1673            True
     1674
     1675            sage: E = EllipticCurve_from_j(0)
     1676            sage: E1 = E.sextic_twist(12345)
     1677            sage: D = E.is_sextic_twist(E1); D
     1678            575968320
     1679            sage: (D/12345).is_perfect_power(6)
     1680            True
     1681        """
     1682        from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve
     1683        E = self
     1684        F = other
     1685        if not is_EllipticCurve(E) or not is_EllipticCurve(F):
     1686            raise ValueError, "arguments are not elliptic curves"
     1687        K = E.base_ring()
     1688        zero = K.zero_element()
     1689        if not K == F.base_ring():
     1690            return zero
     1691        j=E.j_invariant()
     1692        if  j != F.j_invariant() or not j.is_zero():
     1693            return zero
     1694   
     1695        if E.is_isomorphic(F):
     1696            return K.one_element()
     1697       
     1698        char=K.characteristic()
     1699       
     1700        if char==2:
     1701            raise NotImplementedError, "not implemented in characteristic 2"
     1702        elif char==3:
     1703            raise NotImplementedError, "not implemented in characteristic 3"           
     1704        else:
     1705            # now char!=2,3:
     1706            D = F.c6()/E.c6()
     1707       
     1708        if D.is_zero():
     1709            return D
     1710       
     1711        assert E.sextic_twist(D).is_isomorphic(F)
     1712
     1713        return D
     1714
    14411715    def rst_transform(self, r, s, t):
    14421716        """
    14431717        Transforms the elliptic curve using the unimodular (u=1) transform
     
    25032777       
    25042778        EXAMPLES::
    25052779       
    2506             sage: E = EllipticCurve(QQ(0)) # a curve with j=0 over QQ
     2780            sage: E = EllipticCurve_from_j(QQ(0)) # a curve with j=0 over QQ
    25072781            sage: E.automorphisms();       
    2508             [Generic endomorphism of Abelian group of points on Elliptic Curve defined by y^2 = x^3 + 1 over Rational Field
    2509             Via:  (u,r,s,t) = (-1, 0, 0, 0), Generic endomorphism of Abelian group of points on Elliptic Curve defined by y^2 = x^3 + 1 over Rational Field
     2782            [Generic endomorphism of Abelian group of points on Elliptic Curve defined by y^2 + y = x^3 over Rational Field
     2783            Via:  (u,r,s,t) = (-1, 0, 0, -1), Generic endomorphism of Abelian group of points on Elliptic Curve defined by y^2 + y = x^3 over Rational Field
    25102784            Via:  (u,r,s,t) = (1, 0, 0, 0)]
    25112785       
    25122786        We can also find automorphisms defined over extension fields::
    25132787       
    25142788            sage: K.<a> = NumberField(x^2+3) # adjoin roots of unity
    25152789            sage: E.automorphisms(K)
    2516             [Generic endomorphism of Abelian group of points on Elliptic Curve defined by y^2 = x^3 + 1 over Number Field in a with defining polynomial x^2 + 3
     2790            [Generic endomorphism of Abelian group of points on Elliptic Curve defined by y^2 + y = x^3 over Number Field in a with defining polynomial x^2 + 3
    25172791            Via:  (u,r,s,t) = (1, 0, 0, 0),
    25182792            ...
    2519             Generic endomorphism of Abelian group of points on Elliptic Curve defined by y^2 = x^3 + 1 over Number Field in a with defining polynomial x^2 + 3
     2793            Generic endomorphism of Abelian group of points on Elliptic Curve defined by y^2 + y = x^3 over Number Field in a with defining polynomial x^2 + 3
    25202794            Via:  (u,r,s,t) = (-1/2*a - 1/2, 0, 0, 0)]
    25212795       
    25222796        ::
    25232797       
    2524             sage: [ len(EllipticCurve(GF(q,'a')(0)).automorphisms()) for q in [2,4,3,9,5,25,7,49]]
     2798            sage: [ len(EllipticCurve_from_j(GF(q,'a')(0)).automorphisms()) for q in [2,4,3,9,5,25,7,49]]
    25252799            [2, 24, 2, 12, 2, 6, 6, 6]
    25262800        """
    25272801        if field==None:
     
    25372811       
    25382812        EXAMPLES::
    25392813       
    2540             sage: E = EllipticCurve(QQ(0)) # a curve with j=0 over QQ
    2541             sage: F = EllipticCurve('36a1') # should be the same one
     2814            sage: E = EllipticCurve_from_j(QQ(0)) # a curve with j=0 over QQ
     2815            sage: F = EllipticCurve('27a3') # should be the same one
    25422816            sage: E.isomorphisms(F);       
    25432817            [Generic morphism:
    2544             From: Abelian group of points on Elliptic Curve defined by y^2 = x^3 + 1 over Rational Field
    2545             To:   Abelian group of points on Elliptic Curve defined by y^2 = x^3 + 1 over Rational Field
    2546             Via:  (u,r,s,t) = (-1, 0, 0, 0), Generic morphism:
    2547             From: Abelian group of points on Elliptic Curve defined by y^2 = x^3 + 1 over Rational Field
    2548             To:   Abelian group of points on Elliptic Curve defined by y^2 = x^3 + 1 over Rational Field
     2818            From: Abelian group of points on Elliptic Curve defined by y^2 + y = x^3 over Rational Field
     2819            To:   Abelian group of points on Elliptic Curve defined by y^2 + y = x^3 over Rational Field
     2820            Via:  (u,r,s,t) = (-1, 0, 0, -1), Generic morphism:
     2821            From: Abelian group of points on Elliptic Curve defined by y^2 + y = x^3 over Rational Field
     2822            To:   Abelian group of points on Elliptic Curve defined by y^2 + y = x^3 over Rational Field
    25492823            Via:  (u,r,s,t) = (1, 0, 0, 0)]
    25502824       
    25512825        We can also find istomorphisms defined over extension fields::
  • sage/schemes/elliptic_curves/ell_rational_field.py

    diff -r 653655f60cc4 -r 3fa8b641e0fe sage/schemes/elliptic_curves/ell_rational_field.py
    a b  
    34323432       
    34333433    def minimal_quadratic_twist(self):
    34343434        r"""
    3435         Determines a quadratic twist with minimal conductor. Returns a global
    3436         minimal model of the twist and the fundamental discriminant of the
    3437         quadratic field over which they are isomorphic.
    3438        
    3439         The implementation is not optimal at all. It factors the conductor `N` and tries to twist
    3440         by `(-1)^((p-1)/2) p` if `p^2` divides `N`. For 2 and 3 we try and check if it smaller.
     3435        Determines a quadratic twist with minimal conductor. Returns a
     3436        global minimal model of the twist and the fundamental
     3437        discriminant of the quadratic field over which they are
     3438        isomorphic.
     3439       
    34413440       
    34423441        EXAMPLES::
    34433442       
     
    34543453            True
    34553454            sage: D
    34563455            -24
    3457              
    3458         """
    3459         N = self.conductor()
    3460         D = 1
    3461         Nt = N
    3462         for (p,f) in factor(N):
    3463             if f > 1 and p > 3:
    3464                 if p % 4 == 1:
    3465                     DD = p
    3466                 else:
    3467                     DD = (-p)
    3468                 Et = self.quadratic_twist(DD)
    3469                 if Et.conductor() < Nt:
    3470                     Nt = Et.conductor()
    3471                     D *= DD
    3472         Et = self.quadratic_twist(D)
    3473         Nt = Et.conductor()
    3474         # try with -3
    3475         Ett = Et.quadratic_twist(-3)
    3476         if Ett.conductor() < Nt:
    3477             D *= (-3)
    3478             Et = Ett
    3479             Nt = Ett.conductor()
    3480         # try with -4, 8 or -8
    3481         DD = 1
    3482         for D2 in [-4,8,-8]:
    3483             Ett = Et.quadratic_twist(D2)
    3484             if Ett.conductor() < Nt :
    3485                 Nt = Ett.conductor()
    3486                 DD = D2
    3487         D *= DD
    3488         Et = self.quadratic_twist(D)
    3489         return Et, D
    3490            
     3456
     3457            sage: E = EllipticCurve([0,0,0,0,1000])
     3458            sage: E.minimal_quadratic_twist()
     3459            (Elliptic Curve defined by y^2 = x^3 + 1 over Rational Field, 40)
     3460            sage: E = EllipticCurve([0,0,0,1600,0])
     3461            sage: E.minimal_quadratic_twist()
     3462            (Elliptic Curve defined by y^2 = x^3 + 4*x over Rational Field, 5)
     3463
     3464
     3465        """
     3466        j = self.j_invariant()
     3467        if j!=0 and j!=1728:
     3468            # the constructor from j will give the minimal twist
     3469            Et = constructor.EllipticCurve_from_j(j)
     3470        else:
     3471            if j==0:
     3472                c = -2*self.c6()
     3473                for p in c.support():
     3474                    e = c.valuation(p)//3
     3475                    c /= p**(3*e)
     3476                E1 = constructor.EllipticCurve([0,0,0,0,c])
     3477            elif j==1728:
     3478                c = -3*self.c4()
     3479                for p in c.support():
     3480                    e = c.valuation(p)//2
     3481                    c /= p**(2*e)
     3482                E1 = constructor.EllipticCurve([0,0,0,c,0])
     3483            tw = [-1,2,-2,3,-3,6,-6]
     3484            Elist = [E1] + [E1.quadratic_twist(t) for t in tw]
     3485            crv_cmp = lambda E,F: cmp(E.conductor(),F.conductor())
     3486            Elist.sort(cmp=crv_cmp)
     3487            Et = Elist[0]
     3488
     3489        Et = Et.minimal_model()
     3490
     3491        D = self.is_quadratic_twist(Et) # 1 or square-free
     3492        if D % 4 != 1:
     3493            D *= 4
     3494
     3495        return Et, D           
    34913496           
    34923497
    34933498    ##########################################################
  • sage/schemes/elliptic_curves/weierstrass_morphism.py

    diff -r 653655f60cc4 -r 3fa8b641e0fe sage/schemes/elliptic_curves/weierstrass_morphism.py
    a b  
    211211
    212212    EXAMPLES:
    213213    sage: from sage.schemes.elliptic_curves.weierstrass_morphism import *
    214     sage: isomorphisms(EllipticCurve(0),EllipticCurve('36a1'))
    215     [(-1, 0, 0, 0), (1, 0, 0, 0)]
    216     sage: isomorphisms(EllipticCurve(0),EllipticCurve('36a1'),JustOne=True)
     214    sage: isomorphisms(EllipticCurve_from_j(0),EllipticCurve('27a3'))
     215    [(-1, 0, 0, -1), (1, 0, 0, 0)]
     216    sage: isomorphisms(EllipticCurve_from_j(0),EllipticCurve('27a3'),JustOne=True)
    217217    (1, 0, 0, 0)
    218     sage: isomorphisms(EllipticCurve(0),EllipticCurve('36a2'))
     218    sage: isomorphisms(EllipticCurve_from_j(0),EllipticCurve('27a1'))
    219219    []
    220     sage: isomorphisms(EllipticCurve(0),EllipticCurve('36a2'),JustOne=True)
     220    sage: isomorphisms(EllipticCurve_from_j(0),EllipticCurve('27a1'),JustOne=True)
    221221    """   
    222222    from ell_generic import is_EllipticCurve
    223223    if not is_EllipticCurve(E) or not is_EllipticCurve(F):
     
    417417        sage: w1==w2
    418418        False
    419419
    420         sage: E=EllipticCurve(GF(7)(0))
     420        sage: E=EllipticCurve_from_j(GF(7)(0))
    421421        sage: F=E.change_weierstrass_model(2,3,4,5)
    422422        sage: a=E.isomorphisms(F)
    423423        sage: b=[w*a[0] for w in F.automorphisms()]