Ticket #727: trac_727_more_conic_files5.patch

File trac_727_more_conic_files5.patch, 104.7 KB (added by Marco Streng, 12 years ago)

apply on sage 4.4.4 after trac_727_more_conic_files1,2,3,4, shouldn't require trac_9334-hilbert.patch

  • doc/en/reference/index.rst

    # HG changeset patch
    # User Marco Streng <marco.streng@gmail.com>
    # Date 1279304786 -7200
    # Node ID 3f7ced9b5b3ed3245cb70031127644b595c0f262
    # Parent  dd59f5b6d61d4ac60bc704125145ee772476c5a2
    Trac 727: corrections and more tests for Conics
    
    diff -r dd59f5b6d61d -r 3f7ced9b5b3e doc/en/reference/index.rst
    a b  
    8888   modfrm
    8989   modabvar
    9090   modmisc
     91   quadratic_forms
    9192
    9293   history_and_license
    9394
  • doc/en/reference/plane_curves.rst

    diff -r dd59f5b6d61d -r 3f7ced9b5b3e doc/en/reference/plane_curves.rst
    a b  
    1111   sage/schemes/plane_curves/affine_curve
    1212   sage/schemes/plane_curves/projective_curve
    1313
     14   sage/schemes/plane_conics/constructor
     15   sage/schemes/plane_conics/con_field
     16   sage/schemes/plane_conics/con_global_field
     17   sage/schemes/plane_conics/con_number_field
     18   sage/schemes/plane_conics/con_rational_field
     19   sage/schemes/plane_conics/con_finite_field
     20   sage/schemes/plane_conics/con_prime_finite_field
     21
    1422   sage/schemes/elliptic_curves/constructor
    1523   sage/schemes/elliptic_curves/ell_generic
    1624   sage/schemes/elliptic_curves/ell_field
  • new file doc/en/reference/quadratic_forms.rst

    diff -r dd59f5b6d61d -r 3f7ced9b5b3e doc/en/reference/quadratic_forms.rst
    - +  
     1.. _ch:schemes:
     2
     3Quadratic Forms
     4===============
     5
     6.. toctree::
     7   :maxdepth: 2
     8
     9    sage/quadratic_forms/fsolve.py
     10
  • sage/quadratic_forms/qfsolve.py

    diff -r dd59f5b6d61d -r 3f7ced9b5b3e sage/quadratic_forms/qfsolve.py
    a b  
    2929
    3030_gp_for_simon_interpreter = None    # Global GP interpreter for Denis Simon's code
    3131def _gp_for_simon():
     32    r"""
     33    Start a GP interpreter for the use of Denis Simon's Qfsolve and Qfparam
     34    if it is not started already.
     35   
     36    EXAMPLE ::
     37   
     38        sage: from sage.quadratic_forms.qfsolve import _gp_for_simon
     39        sage: _gp_for_simon()
     40        GP/PARI interpreter
     41    """
    3242    global _gp_for_simon_interpreter
    3343    if _gp_for_simon_interpreter is None:
    3444        _gp_for_simon_interpreter = Gp(script_subdirectory='simon')
     
    5565    prime p if no solution exists over the p-adic field Q_p.
    5666
    5767    EXAMPLES:
    58         sage: from sage.schemes.plane_curves.qfsolve import Qfsolve
    59         sage: R.<x,y,z> = QQ[]
    60         sage: M = Curve(-12*y^2 - 24*x*z - z^2).symmetric_matrix(); M
     68        sage: from sage.quadratic_forms.qfsolve import Qfsolve
     69        sage: M = Matrix(QQ, [[0, 0, -12], [0, -12, 0], [-12, 0, -1]]); M
    6170        [  0   0 -12]
    6271        [  0 -12   0]
    6372        [-12   0  -1]
     
    6675        sage: sol[0].parent() is QQ
    6776        True
    6877       
    69         sage: C = Curve(x^2 + y^2 + z^2)
    70         sage: ret = Qfsolve(C.symmetric_matrix()); ret
     78        sage: M = Matrix(QQ, [[1, 0, 0], [0, 1, 0], [0, 0, 1]])
     79        sage: ret = Qfsolve(M); ret
    7180        -1
    7281        sage: ret.parent() is ZZ
    7382        True
    7483
    75         sage: C = Curve(x^2 + y^2 - 7*z^2)
    76         sage: Qfsolve(C.symmetric_matrix())
     84        sage: M = Matrix(QQ, [[1, 0, 0], [0, 1, 0], [0, 0, -7]])
     85        sage: Qfsolve(M)
    7786        7
    7887    """
    7988    gp = _gp_for_simon()
     
    8897    r"""
    8998
    9099    EXAMPLES:
    91         sage: from sage.schemes.plane_curves.qfsolve import Qfsolve, Qfparam
    92         sage: R.<x,y,z> = QQ[]
    93         sage: M = Curve(-12*y^2 - 24*x*z - z^2).symmetric_matrix(); M
     100        sage: from sage.quadratic_forms.qfsolve import Qfsolve, Qfparam
     101        sage: M = Matrix(QQ, [[0, 0, -12], [0, -12, 0], [-12, 0, -1]]); M
    94102        [  0   0 -12]
    95103        [  0 -12   0]
    96104        [-12   0  -1]
  • sage/schemes/plane_conics/con_field.py

    diff -r dd59f5b6d61d -r 3f7ced9b5b3e sage/schemes/plane_conics/con_field.py
    a b  
    2424#                  http://www.gnu.org/licenses/
    2525#*****************************************************************************
    2626
    27 from sage.libs.pari.gen import pari
    28 from sage.misc.all import add, sage_eval
    29 from sage.rings.all import (PolynomialRing, ZZ, QQ, MPolynomialRing,
    30                             degree_lowest_rational_function,
    31                             is_PrimeField, is_FiniteField,
     27from sage.rings.all import (PolynomialRing, QQ,
    3228                            is_ComplexField, is_RealField,
    33                             is_pAdicField, is_Field,
    34                             is_RationalField)
     29                            is_Field)
    3530from sage.modules.free_module_element import vector
    3631from sage.structure.sequence import Sequence
    3732from sage.structure.element import is_Vector
    38 from sage.schemes.generic.projective_space import (ProjectiveSpace,
    39                                                    is_ProjectiveSpace)
     33from sage.schemes.generic.projective_space import ProjectiveSpace
    4034from sage.matrix.constructor import Matrix
    4135from sage.matrix.matrix import is_Matrix
    4236
    43 from sage.schemes.plane_curves.curve import Curve_generic_projective
    4437from sage.schemes.plane_curves.projective_curve import ProjectiveCurve_generic
    45 from sage.quadratic_forms.qfsolve import Qfsolve, Qfparam
    46 
    47 from sage.rings.number_field.number_field import is_NumberField                           
    48 
    49 from sage.rings.all import RR
    5038
    5139class ProjectiveConic_field(ProjectiveCurve_generic):
     40    r"""
     41    Create a projective plane conic curve over a field.
     42    See ``Conic`` for full documentation.
     43   
     44    EXAMPLES::
     45   
     46        sage: K = FractionField(PolynomialRing(QQ, 't'))
     47        sage: P.<X, Y, Z> = K[]
     48        sage: Conic(X^2 + Y^2 - Z^2)
     49        Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Rational Field defined by X^2 + Y^2 - Z^2
     50       
     51    TESTS::
     52   
     53        sage: K = FractionField(PolynomialRing(QQ, 't'))
     54        sage: Conic([K(1), 1, -1])._test_pickling()
     55    """
    5256    def __init__(self, A, f):
     57        r"""
     58        See ``Conic`` for full documentation.
     59
     60        EXAMPLES:
     61
     62        ::
     63
     64            sage: c = Conic([1, 1, 1]); c
     65            Projective Conic Curve over Rational Field defined by x^2 + y^2 + z^2
     66        """
    5367        ProjectiveCurve_generic.__init__(self, A, f)
    5468        self._coefficients = [f[(2,0,0)], f[(1,1,0)], f[(1,0,1)],
    5569                                f[(0,2,0)], f[(0,1,1)], f[(0,0,2)]]
     
    6276
    6377
    6478    def _repr_type(self):
     79        r"""
     80        Returns ``'Projective Conic'``, which is the first part of the
     81        plain text representation of this object as output by
     82        the function ``_repr_`` of the class ``Curve_generic``.
     83
     84        EXAMPLES::
     85
     86            sage: c = Conic([1, 1, 1]); c
     87            Projective Conic Curve over Rational Field defined by x^2 + y^2 + z^2
     88            sage: c._repr_()
     89            'Projective Conic Curve over Rational Field defined by x^2 + y^2 + z^2'
     90            sage: c._repr_type()
     91            'Projective Conic'
     92        """
    6593        return "Projective Conic"
    6694
    6795    def base_extend(self, S):
    6896        r"""
    69         Returns the conic over `S`, given by the same equation as self.
     97        Returns the conic over ``S`` given by the same equation as ``self``.
    7098
    71         EXAMPLES:
    72 
    73         ::
     99        EXAMPLES::
    74100
    75101            sage: c = Conic([1, 1, 1]); c
    76102            Projective Conic Curve over Rational Field defined by x^2 + y^2 + z^2
     
    78104            False
    79105            sage: d = c.base_extend(QuadraticField(-1, 'i')); d
    80106            Projective Conic Curve over Number Field in i with defining polynomial x^2 + 1 defined by x^2 + y^2 + z^2
    81             sage: d.rational_point()
    82             (-i : 1 : 0)
     107            sage: d.rational_point(algorithm = 'rnfisnorm')
     108            (i : 1 : 0)
    83109        """
    84110        if is_Field(S):
    85111            B = self.base_ring()
     
    94120            if self._rational_point != None:
    95121                pt = [S(c) for c in Sequence(self._rational_point)]
    96122                if not pt == [0,0,0]:
    97                     _ = con.point(pt)
     123                    # The following line stores the point in the cache
     124                    # if (and only if) there is no point in the cache.
     125                    pt = con.point(pt)
    98126            return con
    99127        return ProjectiveCurve_generic.base_extend(self, S)
    100128   
    101129    def cache_point(self, p):
    102130        r"""
    103         Replace the point in the cache of self by `p` for use
    104         by self.rational_point and self.parametrization.
     131        Replace the point in the cache of ``self`` by ``p`` for use
     132        by ``self.rational_point()`` and ``self.parametrization()``.
    105133       
    106         EXAMPLES:
    107 
    108         ::
     134        EXAMPLES::
    109135
    110136            sage: c = Conic([1, -1, 1])
    111137            sage: c.point([15, 17, 8])
     
    122148
    123149    def coefficients(self):
    124150        r"""
    125         Gives a the 6 coefficients of the conic
     151        Gives a the `6` coefficients of the conic ``self``
    126152        in lexicographic order.
    127153       
    128         EXAMPLES:
    129        
    130         ::
     154        EXAMPLES::
    131155       
    132156            sage: Conic(QQ, [1,2,3,4,5,6]).coefficients()
    133157            [1, 2, 3, 4, 5, 6]
     
    143167       
    144168    def derivative_matrix(self):
    145169        r"""
    146         Gives the derivative of the defining polynomial,
    147         which is a linear map, as a `3 \times 3` matrix.
     170        Gives the derivative of the defining polynomial of
     171        the conic ``self``, which is a linear map,
     172        as a `3 \times 3` matrix.
    148173       
    149         Examples:
     174        EXAMPLES:
    150175       
    151         In characteristic different from 2, the
     176        In characteristic different from `2`, the
    152177        derivative matrix is twice the symmetric matrix:
    153178
    154179        ::
     
    163188            [1 2 1]
    164189            [1 1 0]
    165190
    166         An example in characteristic 2:
     191        An example in characteristic `2`:
    167192
    168193        ::
    169194
     
    185210       
    186211    def determinant(self):
    187212        r"""
    188         Gives the determinant of the symmetric matrix that defines the conic.
    189         This is defined only if the base field has characteristic different
    190         from 2.
     213        Returns the determinant of the symmetric matrix that defines
     214        the conic ``self``.
     215       
     216        This is defined only if the base field has characteristic
     217        different from `2`.
    191218
    192219        EXAMPLES:
    193220
     
    199226            sage: C.symmetric_matrix().determinant()
    200227            41/4
    201228
    202         Determinants are only defined in characteristic different from 2::
     229        Determinants are only defined in characteristic different from `2`::
    203230
    204231            sage: C = Conic(GF(2), [1, 1, 1, 1, 1, 0])
    205232            sage: C.is_smooth()
     
    217244        r"""
    218245        Returns a diagonal matrix `D` and a matrix `T` such that `T^t A T = D`
    219246        holds, where `(x, y, z) A (x, y, z)^t` is the defining polynomial
    220         of the conic `self`.
     247        of the conic ``self``.
    221248
    222         EXAMPLE:
     249        EXAMPLES:
    223250
    224251        ::
    225252
     
    236263            [    0     0 41/12]
    237264         
    238265        Diagonal matrices are only defined in characteristic different
    239         from 2:
     266        from `2`:
    240267       
    241268        ::
    242269
     
    275302       
    276303    def diagonalization(self,names = None):
    277304        r"""
    278         Returns a diagonal conic C, an isomorphism of schemes M: C -> self
    279         and the inverse N of M.
     305        Returns a diagonal conic `C`, an isomorphism of schemes `M: C` -> ``self``
     306        and the inverse `N` of `M`.
    280307       
    281         EXAMPLES:
     308        EXAMPLES::
    282309       
    283         ::
    284310            sage: Conic(GF(5), [1,0,1,1,0,1]).diagonalization()           
    285311            (Projective Conic Curve over Finite Field of size 5 defined by x^2 + y^2 + 2*z^2,
    286312             Scheme morphism:
     
    313339
    314340    def gens(self):
    315341        r"""
    316         Returns the generators of the coordinate ring of self.
     342        Returns the generators of the coordinate ring of ``self``.
    317343       
    318344        EXAMPLES:
     345       
     346        ::
     347       
    319348            sage: P.<x,y,z> = QQ[]
    320349            sage: c = Conic(x^2+y^2+z^2)
    321350            sage: c.gens()
    322351            (xbar, ybar, zbar)
    323352            sage: c.defining_polynomial()(c.gens())
    324353            0
     354           
     355        The function ``gens()`` is required for the following construction:
     356       
     357        ::
     358       
     359            sage: C.<a,b,c> = Conic(GF(3), [1, 1, 1])
     360            sage: C
     361            Projective Conic Curve over Finite Field of size 3 defined by a^2 + b^2 + c^2
     362
    325363        """
    326364        return self.coordinate_ring().gens()
    327365
    328 
    329366    def has_rational_point(self, point = False,
    330367                           algorithm = 'default', read_cache = True):
    331368        r"""
    332         Returns True if and only if self has a point defined over its base field B.
     369        Returns True if and only if the conic ``self``
     370        has a point over its base field `B`.
    333371
    334         If point is True, then returns a second output, which is
    335         a rational point if one exists, and is None otherwise.
     372        If ``point`` is True, then returns a second output, which is
     373        a rational point if one exists.
    336374       
    337         Points are cached whenever they are found. If read_cache is True,
    338         then cached information is used for the output if available.
     375        Points are cached whenever they are found. Cached information
     376        is used if and only if ``read_cache`` is True.
    339377       
    340378        EXAMPLES:
    341379
    342         Examples over real and complex fields ::
    343 
    344380            sage: Conic(RR, [1, 1, 1]).has_rational_point()
    345381            False
    346382            sage: Conic(CC, [1, 1, 1]).has_rational_point()
     
    387423       
    388424    def has_singular_point(self, point = False):
    389425        r"""
    390         Return True if and only if self has a rational
     426        Return True if and only if the conic ``self`` has a rational
    391427        singular point.
    392428       
    393         If point is True, then also return a rational singular
    394         point (or None if no such point exists).
     429        If ``point`` is True, then also return a rational singular
     430        point (or ``None`` if no such point exists).
    395431       
    396432        EXAMPLES:
    397433       
     
    413449            sage: Conic([1, 1, -1]).has_singular_point(point = True)
    414450            (False, None)
    415451
    416         has_singular_point is not implemented over all fields
    417         of characteristic 2. It is implemented over finite fields.
     452        ``has_singular_point`` is not implemented over all fields
     453        of characteristic `2`. It is implemented over finite fields.
    418454
    419455        ::
    420456
     
    457493
    458494    def hom(self, x, Y=None):
    459495        r"""
    460         Return the scheme morphism from self to Y defined by x.
    461         Here x can be a matrix or a sequence of polynomials.
    462         If Y is omitted, then a natural image is found if possible.
     496        Return the scheme morphism from ``self`` to ``Y`` defined by ``x``.
     497        Here ``x`` can be a matrix or a sequence of polynomials.
     498        If ``Y`` is omitted, then a natural image is found if possible.
    463499
    464500        EXAMPLES:
    465501       
    466         Morphisms given by matrices. In the first example, Y is omitted,
    467         in the second example, Y is specified.
     502        Here are a few Morphisms given by matrices. In the first
     503        example, ``Y`` is omitted, in the second example, ``Y`` is specified.
    468504
    469505        ::
    470506           
     
    487523                  Defn: Defined on coordinates by sending (x : y : z) to
    488524                          (1/2*z : y : x)
    489525
    490         A ValueError is raised if the wrong codomain Y is specified:
     526        ``ValueError`` is raised if the wrong codomain ``Y`` is specified:
    491527
    492528        ::
    493529       
     
    540576
    541577    def is_smooth(self):
    542578        r"""
    543         Returns True if and only if self is smooth.
     579        Returns True if and only if ``self`` is smooth.
    544580
    545581        EXAMPLES:
    546582
     
    562598    def matrix(self):
    563599        r"""
    564600        Returns a matrix `M` such that `(x, y, z) M (x, y, z)^t`
    565         is the defining equation of self.
     601        is the defining equation of ``self``.
     602
    566603        The matrix `M` is upper triangular if the base field has
    567         characteristic 2 and symmetric otherwise.
     604        characteristic `2` and symmetric otherwise.
    568605
    569         EXAMPLES:
     606        EXAMPLES::
     607       
    570608            sage: R.<x, y, z> = QQ[]
    571609            sage: C = Conic(x^2 + x*y + y^2 + z^2)
    572610            sage: C.matrix()
     
    589627
    590628    def parametrization(self, point=None, morphism=True):
    591629        r"""
    592         Return a parametrization of self and the inverse
    593         of the parametrization.
     630        Return a parametrization `f` of ``self`` together with the
     631        inverse of `f`.
    594632
    595         If point is specified, then that point is used
    596         for the parametrization. Otherwise, use rational_point
     633        If ``point`` is specified, then that point is used
     634        for the parametrization. Otherwise, use ``self.rational_point()``
    597635        to find a point.
    598636           
    599         If morphism is False, then returns the tuples of three
    600         polynomials that give the parametrization.
    601        
    602         Raises ValueError if no rational point exists or self is non-smooth.
    603 
    604         ALGORITHM:
    605        
    606             Uses Denis Simon's Qfparam if the base field is `QQ`.
    607             Gives a straightforward non-optimized parametrization
    608             otherwise.
     637        If ``morphism`` is True, then `f` is returned in the form
     638        of a Scheme morphism. Otherwise, it is a tuple of polynomials
     639        that gives the parametrization.
    609640       
    610641        EXAMPLES:
    611             sage: R.<x,y,z> = QQ[]
    612             sage: C = Conic(7*x^2 + 2*y*z + z^2)
    613             sage: (p, i) = C.parametrization(morphism = False); (p, i)
    614             ([-2*x*y, 7*x^2 + y^2, -2*y^2], [-1/2*x, -1/2*z])
    615             sage: C.defining_polynomial()(p)
    616             0
    617             sage: i[0](p) / i[1](p)
    618             x/y
    619642
    620             sage: C = Conic(x^2 + 2*y^2 + z^2)
    621             sage: C.parametrization()
    622             Traceback (most recent call last):
    623             ...
    624             ValueError: Conic Projective Conic Curve over Rational Field defined by x^2 + 2*y^2 + z^2 has no rational points over Rational Field!
    625 
    626             sage: C = Conic(x^2 + y^2 + 7*z^2)
    627             sage: C.parametrization()
    628             Traceback (most recent call last):
    629             ...
    630             ValueError: Conic Projective Conic Curve over Rational Field defined by x^2 + y^2 + 7*z^2 has no rational points over Rational Field!
    631 
    632             sage: c = Conic([1,1,-1])
    633             sage: c.param()
    634             (Scheme morphism:
    635               From: Projective Space of dimension 1 over Rational Field
    636               To:   Projective Conic Curve over Rational Field defined by x^2 + y^2 - z^2
    637               Defn: Defined on coordinates by sending (x : y) to
    638                     (2*x*y : x^2 - y^2 : x^2 + y^2),
    639              Scheme morphism:
    640                From: Projective Conic Curve over Rational Field defined by x^2 + y^2 - z^2
    641                To:   Projective Space of dimension 1 over Rational Field
    642                Defn: Defined on coordinates by sending (x : y : z) to
    643                      (1/2*x : -1/2*y + 1/2*z))
     643        An example over a finite field ::
     644       
    644645            sage: c = Conic(GF(2), [1,1,1,1,1,0])
    645             sage: c.param()
     646            sage: c.parametrization()
    646647            (Scheme morphism:
    647648              From: Projective Space of dimension 1 over Finite Field of size 2
    648649              To:   Projective Conic Curve over Finite Field of size 2 defined by x^2 + x*y
     
    655656              To:   Projective Space of dimension 1 over Finite Field of size 2
    656657              Defn: Defined on coordinates by sending (x : y : z) to
    657658                    (y : x))
     659
     660        An example with ``morphism = False`` ::
     661
     662            sage: R.<x,y,z> = QQ[]
     663            sage: C = Curve(7*x^2 + 2*y*z + z^2)
     664            sage: (p, i) = C.parametrization(morphism = False); (p, i)
     665            ([-2*x*y, 7*x^2 + y^2, -2*y^2], [-1/2*x, -1/2*z])
     666            sage: C.defining_polynomial()(p)
     667            0
     668            sage: i[0](p) / i[1](p)
     669            x/y
     670           
     671        A ``ValueError`` is raised if ``self`` has no rational point ::
     672
     673            sage: C = Conic(x^2 + y^2 + 7*z^2)
     674            sage: C.parametrization()
     675            Traceback (most recent call last):
     676            ...
     677            ValueError: Conic Projective Conic Curve over Rational Field defined by x^2 + y^2 + 7*z^2 has no rational points over Rational Field!
     678           
     679        A ``ValueError`` is raised if ``self`` is not smooth ::
     680       
     681            sage: C = Conic(x^2 + y^2)
     682            sage: C.parametrization()
     683            Traceback (most recent call last):
     684            ...
     685            ValueError: The conic self (=Projective Conic Curve over Rational Field defined by x^2 + y^2) is not smooth, hence does not have a parametrization.
    658686        """
    659687        if (not self._parametrization is None) and not point:
    660688            par = self._parametrization
    661689        else:
    662690            if not self.is_smooth():
    663                 raise ValueError, "The conic self (=%s) is not smooth, hence does not have a parametrization.", self
     691                raise ValueError, "The conic self (=%s) is not smooth, hence does not have a parametrization." % self
    664692            if point == None:
    665693                point = self.rational_point()
    666694            point = Sequence(point)
     
    668696            Q = PolynomialRing(B, 'x,y')
    669697            [x, y] = Q.gens()
    670698            gens = self.ambient_space().gens()
    671             if is_RationalField(B):
    672                 from sage.quadratic_forms.qfsolve import Qfparam
    673                 from sage.rings.arith import lcm
    674                 M = self.symmetric_matrix()
    675                 M *= lcm([ t.denominator() for t in M.list() ])
    676                 par1 = Qfparam(M, point)
    677                 B = Matrix([[par1[i][j] for j in range(3)] for i in range(3)])
    678                 # self is in the image of B and does not lie on a line,
    679                 # hence B is invertible
    680                 A = B.inverse()
    681                 par2 = [sum([A[i,j]*gens[j] for j in range(3)]) for i in [1,0]]
    682                 par = ([Q(pol(x/y)*y**2) for pol in par1], par2)
    683             else:
    684                 P = PolynomialRing(B, 4, ['X', 'Y', 'T0', 'T1'])
    685                 [X, Y, T0, T1] = P.gens()
    686                 c3 = [j for j in range(2,-1,-1) if point[j] != 0][0]
    687                 c1 = [j for j in range(3) if j != c3][0]
    688                 c2 = [j for j in range(3) if j != c3 and j != c1][0]
    689                 L = [0,0,0]
    690                 L[c1] = Y*T1*point[c1] + Y*T0
    691                 L[c2] = Y*T1*point[c2] + X*T0
    692                 L[c3] = Y*T1*point[c3]
    693                 bezout = P(self.defining_polynomial()(L) / T0)
    694                 t = [bezout([x,y,0,-1]),bezout([x,y,1,0])]
    695                 par = (tuple([Q(p([x,y,t[0],t[1]])/y) for  p in L]),
    696                        tuple([gens[m]*point[c3]-gens[c3]*point[m]
    697                            for m in [c2,c1]]))
     699            P = PolynomialRing(B, 4, ['X', 'Y', 'T0', 'T1'])
     700            [X, Y, T0, T1] = P.gens()
     701            c3 = [j for j in range(2,-1,-1) if point[j] != 0][0]
     702            c1 = [j for j in range(3) if j != c3][0]
     703            c2 = [j for j in range(3) if j != c3 and j != c1][0]
     704            L = [0,0,0]
     705            L[c1] = Y*T1*point[c1] + Y*T0
     706            L[c2] = Y*T1*point[c2] + X*T0
     707            L[c3] = Y*T1*point[c3]
     708            bezout = P(self.defining_polynomial()(L) / T0)
     709            t = [bezout([x,y,0,-1]),bezout([x,y,1,0])]
     710            par = (tuple([Q(p([x,y,t[0],t[1]])/y) for  p in L]),
     711                   tuple([gens[m]*point[c3]-gens[c3]*point[m]
     712                       for m in [c2,c1]]))
    698713            if self._parametrization is None:
    699714                self._parametrization = par
    700715        if not morphism:
     
    702717        P1 = ProjectiveSpace(self.base_ring(), 1, 'x,y')
    703718        return P1.hom(par[0],self), self.Hom(P1)(par[1], check = False)
    704719       
    705     param = parametrization
    706                    
    707720    def point(self, v, check=True):
    708721        r"""
    709         Constructs a point on self corresponding to the input.
     722        Constructs a point on ``self`` corresponding to the input ``v``.
    710723       
    711         If no rational point on self is known yet, then also caches the point
    712         for use by self.rational_point and self.parametrization
     724        If ``check`` is True, then checks if ``v`` defines a valid
     725        point on ``self``.
     726       
     727        If no rational point on ``self`` is known yet, then also caches the point
     728        for use by ``self.rational_point()`` and ``self.parametrization()``.
    713729
    714         EXAMPLES:
    715 
    716         ::
     730        EXAMPLES ::
    717731
    718732            sage: c = Conic([1, -1, 1])
    719733            sage: c.point([15, 17, 8])
     
    732746        return p
    733747
    734748       
    735     def random_rational_point(self, bound=None):
     749    def random_rational_point(self, *args1, **args2):
    736750        r"""
    737         Return a random rational point of this conic.
     751        Return a random rational point of the conic ``self``.
    738752       
    739         The output is the image of a random point X on the
    740         projective line under a parametrization of self.
    741         If a bound is specified and the base field is `\QQ`,
    742         then that is a bound on the naive height of X.
     753        ALGORITHM:
     754       
     755            1. Compute a parametrization `f` of ``self`` using
     756               ``self.parametrization()``.
     757            2. Computes a random point `(x:y)` on the projective
     758               line.
     759            3. Output `f(x:y)`.
     760       
     761        The coordinates x and y are computed using
     762        ``B.random_element``, where ``B`` is the base field of
     763        ``self`` and additional arguments to ``random_rational_point``
     764        are passed to ``random_element``.
     765           
    743766        If the base field is a finite field, then the
    744         output is uniformly distributed over the rational
    745         points of self.
     767        output is uniformly distributed over the points of self.
    746768
    747         EXAMPLES:
     769        EXAMPLES ::
    748770           
    749         ::
    750771            sage: c = Conic(GF(2), [1,1,1,1,1,0])
    751             sage: [c.random_rational_point() for _ in range(10)] # output is random
     772            sage: [c.random_rational_point() for i in range(10)] # output is random
     773            [(1 : 0 : 1), (1 : 0 : 1), (1 : 0 : 1), (0 : 1 : 1), (1 : 0 : 1), (0 : 0 : 1), (1 : 0 : 1), (1 : 0 : 1), (0 : 0 : 1), (1 : 0 : 1)]
    752774           
    753             [(0 : 0 : 1),
    754              (1 : 0 : 1),
    755              (1 : 0 : 1),
    756              (0 : 0 : 1),
    757              (1 : 0 : 1),
    758              (0 : 1 : 1),
    759              (0 : 1 : 1),
    760              (0 : 0 : 1),
    761              (0 : 0 : 1),
    762              (1 : 0 : 1)]
     775            sage: d = Conic(QQ, [1, 1, -1])
     776            sage: d.random_rational_point(den_bound = 1, num_bound = 5) # output is random
     777            (-24/25 : 7/25 : 1)
     778           
     779            sage: Conic(QQ, [1, 1, 1]).random_rational_point()
     780            Traceback (most recent call last):
     781            ...
     782            ValueError: Conic Projective Conic Curve over Rational Field defined by x^2 + y^2 + z^2 has no rational points over Rational Field!
     783
    763784        """
    764785        if not self.is_smooth():
    765786            raise NotImplementedError, "Sorry, random points not implemented " \
     
    768789        x = 0
    769790        y = 0
    770791        B = self.base_ring()
    771         if is_RationalField(B) and bound != None:
    772             if bound < 1:
    773                 raise ValueError, "The bound (= %s) needs to be at least 1" % \
    774                                   bound
    775             while x == 0 and y == 0:
    776                 x = ZZ.random_element(-bound, bound+1)
    777                 y = ZZ.random_element(-bound, bound+1)
    778         else:
    779             while x == 0 and y == 0:
    780                 x = B.random_element()
    781                 y = B.random_element()
     792        while x == 0 and y == 0:
     793            x = B.random_element(*args1, **args2)
     794            y = B.random_element(*args1, **args2)
    782795        return par[0]([x,y])
    783796
    784797
    785798    def rational_point(self, algorithm = 'default', read_cache = True):
    786         r"""Return a rational point (x0, y0, z0) on self.
     799        r"""
     800        Return a point on ``self`` defined over the base field.
    787801
    788         Raises ValueError if no rational point exists.
     802        Raises ``ValueError`` if no rational point exists.
    789803
    790         See has_rational_point(self) for the algorithm used and for the use of
    791         the parameters algorithm and read_cache.
     804        See ``self.has_rational_point`` for the algorithm used
     805        and for the use of the parameters ``algorithm`` and ``read_cache``.
    792806         
    793807        EXAMPLES:
    794808
    795         Examples over QQ ::
     809        Examples over `\QQ` ::
    796810       
    797811            sage: R.<x,y,z> = QQ[]
    798812            sage: C = Conic(7*x^2 + 2*y*z + z^2)
     
    806820            ValueError: Conic Projective Conic Curve over Rational Field defined by x^2 + 2*y^2 + z^2 has no rational points over Rational Field!
    807821
    808822            sage: C = Conic(x^2 + y^2 + 7*z^2)
    809             sage: C.rational_point(algorithm = 'all')
     823            sage: C.rational_point(algorithm = 'rnfisnorm')
    810824            Traceback (most recent call last):
    811825            ...
    812826            ValueError: Conic Projective Conic Curve over Rational Field defined by x^2 + y^2 + 7*z^2 has no rational points over Rational Field!
    813827
    814828        Examples over number fields ::
    815829           
    816             sage: _.<x> = QQ[]
     830            sage: P.<x> = QQ[]
    817831            sage: L.<b> = NumberField(x^3-5)
    818832            sage: C = Conic(L, [3, 2, -5])
    819             sage: C.rational_point(algorithm = 'all')  # long time (1 second)
    820             (-1 : -1 : 1)
     833            sage: C.rational_point(algorithm = 'rnfisnorm')  # long time (1/2 second), output is random
     834            (37632*b^2 + 88168*b - 260801 : -99528*b^2 + 153348*b + 28799 : 1)
    821835       
    822836        Examples over finite fields ::
    823837       
     
    827841            sage: C.rational_point()  # output is random
    828842            (4*a^19 + 5*a^18 + 4*a^17 + a^16 + 6*a^15 + 3*a^13 + 6*a^11 + a^9 + 3*a^8 + 2*a^7 + 4*a^6 + 3*a^5 + 3*a^4 + a^3 + a + 6 : 5*a^18 + a^17 + a^16 + 6*a^15 + 4*a^14 + a^13 + 5*a^12 + 5*a^10 + 2*a^9 + 6*a^8 + 6*a^7 + 6*a^6 + 2*a^4 + 3 : 1)
    829843             
    830         Examples over real and complex fields ::
     844        Examples over `\RR` and `\CC` ::
    831845
    832846            sage: Conic(CC, [1, 2, 3]).rational_point()
    833847            (0 : 1.22474487139159*I : 1)
     
    847861
    848862    def singular_point(self):
    849863        r"""
    850         Returns a singular rational point of self
     864        Returns a singular rational point of ``self``
    851865       
    852866        EXAMPLES:
    853867       
     
    856870            sage: Conic(GF(2), [1,1,1,1,1,1]).singular_point()
    857871            (1 : 1 : 1)
    858872
    859         A ValueError is raised if the conic has no rational singular point
     873        ``ValueError`` is raised if the conic has no rational singular point
    860874           
    861875        ::
    862876
     
    873887
    874888    def symmetric_matrix(self):
    875889        r"""
    876         The symmetric matrix M such that (x y z) M (x y z)^t
    877         is the defining equation of  self.
     890        The symmetric matrix `M` such that `(x y z) M (x y z)^t`
     891        is the defining equation of ``self``.
    878892       
    879         EXAMPLES:
     893        EXAMPLES ::
     894       
    880895            sage: R.<x, y, z> = QQ[]
    881896            sage: C = Conic(x^2 + x*y/2 + y^2 + z^2)
    882897            sage: C.symmetric_matrix()
     
    904919
    905920    def upper_triangular_matrix(self):
    906921        r"""
    907         The upper-triangular matrix M such that (x y z) M (x y z)^t
    908         is the defining equation of self.
     922        The upper-triangular matrix `M` such that `(x y z) M (x y z)^t`
     923        is the defining equation of ``self``.
    909924
    910         EXAMPLES:
     925        EXAMPLES::
     926
    911927            sage: R.<x, y, z> = QQ[]
    912928            sage: C = Conic(x^2 + x*y + y^2 + z^2)
    913929            sage: C.upper_triangular_matrix()
     
    929945    def variable_names(self):
    930946        r"""
    931947        Returns the variable names of the defining polynomial
    932         of self
     948        of ``self``.
    933949
    934950        EXAMPLES:
    935951
     
    940956            ('x', 'y', 'z')
    941957            sage: c.variable_name()
    942958            'x'
     959           
     960        The function ``variable_names()`` is required
     961        for the following construction:
     962       
     963        ::
     964       
     965            sage: C.<p,q,r> = Conic(QQ, [1, 1, 1])
     966            sage: C
     967            Projective Conic Curve over Rational Field defined by p^2 + q^2 + r^2
     968
    943969        """
    944970        return self.defining_polynomial().parent().variable_names()
    945971   
  • sage/schemes/plane_conics/con_finite_field.py

    diff -r dd59f5b6d61d -r 3f7ced9b5b3e sage/schemes/plane_conics/con_finite_field.py
    a b  
    33
    44AUTHORS:
    55
    6 - Marco Streng (2009-08-07)
     6- Marco Streng (2010-08-07)
    77
    88- Nick Alexander (2008-01-08)
    99
     
    2424#                  http://www.gnu.org/licenses/
    2525#*****************************************************************************
    2626
    27 from sage.libs.pari.gen import pari
    28 from sage.misc.all import add, sage_eval
    29 from sage.rings.all import (PolynomialRing, ZZ, QQ, MPolynomialRing,
    30                             degree_lowest_rational_function,
    31                             is_PrimeField, is_FiniteField,
    32                             is_ComplexField, is_RealField,
    33                             is_pAdicField, is_Field,
    34                             is_RationalField)
    35 from sage.modules.free_module_element import vector
    36 from sage.structure.sequence import Sequence
    37 from sage.structure.element import is_Vector
    38 from sage.schemes.generic.projective_space import (ProjectiveSpace,
    39                                                    is_ProjectiveSpace)
    40 from sage.matrix.constructor import Matrix
    41 from sage.matrix.matrix import is_Matrix
    42 
    43 from sage.schemes.plane_curves.curve import Curve_generic_projective
    44 from sage.schemes.plane_curves.projective_curve import ProjectiveCurve_generic
     27from sage.rings.all import PolynomialRing
    4528from sage.schemes.plane_curves.projective_curve import ProjectiveCurve_finite_field
    46 
    47 from sage.quadratic_forms.qfsolve import Qfsolve, Qfparam
    48 
    4929from con_field import ProjectiveConic_field
    5030
    5131class ProjectiveConic_finite_field(ProjectiveConic_field, ProjectiveCurve_finite_field):
     32    r"""
     33    Create a projective plane conic curve over a finite field.
     34    See ``Conic`` for full documentation.
     35   
     36    EXAMPLES::
     37   
     38        sage: K.<a> = FiniteField(9, 'a')
     39        sage: P.<X, Y, Z> = K[]
     40        sage: Conic(X^2 + Y^2 - a*Z^2)
     41        Projective Conic Curve over Finite Field in a of size 3^2 defined by X^2 + Y^2 + (-a)*Z^2
     42       
     43    TESTS::
     44   
     45        sage: K.<a> = FiniteField(4, 'a')
     46        sage: Conic([a, 1, -1])._test_pickling()
     47    """
    5248    def __init__(self, A, f):
     49        r"""
     50        See ``Conic`` for full documentation.
     51
     52        EXAMPLES ::
     53
     54            sage: Conic([GF(3)(1), 1, 1])
     55            Projective Conic Curve over Finite Field of size 3 defined by x^2 + y^2 + z^2
     56        """
    5357        ProjectiveConic_field.__init__(self, A, f)
    5458
    5559
    5660    def count_points(self, n):
    5761        r"""
    5862        If the base field `B` of `self` is finite of order `q`,
    59         then returns the number of points over `GF{q}, ..., GF{q^n}`.
     63        then returns the number of points over `\GF{q}, ..., \GF{q^n}`.
    6064       
    61         EXAMPLES:
     65        EXAMPLES::
    6266
    6367            sage: P.<x,y,z> = GF(3)[]
    64             sage: c = Conic(x^2+y^2+z^2)
     68            sage: c = Curve(x^2+y^2+z^2); c
     69            Projective Conic Curve over Finite Field of size 3 defined by x^2 + y^2 + z^2
    6570            sage: c.count_points(4)
    6671            [4, 10, 28, 82]
    6772        """       
     
    7378    def has_rational_point(self, point = False, read_cache = True, \
    7479                           algorithm = 'default'):
    7580        r"""
    76         Always returns True because self has a point defined over
    77         its finite base field B.
     81        Always returns ``True`` because self has a point defined over
     82        its finite base field `B`.
    7883
    79         If 'point' is True, then returns a second output S, which is a
    80         rational point.
     84        If ``point`` is True, then returns a second output `S`, which is a
     85        rational point if one exists.
    8186       
    82         Points are cached. If 'read_cache' is True, then cached information
     87        Points are cached. If ``read_cache`` is True, then cached information
    8388        is used for the output if available. If no cached point is available
    84         or 'read_cache' is False, then random y-coordinates are tried
    85         if 'self' is smooth and a singular point is returned otherwise.
     89        or ``read_cache`` is False, then random `y`-coordinates are tried
     90        if ``self`` is smooth and a singular point is returned otherwise.
    8691       
    87         EXAMPLES:
     92        EXAMPLES ::
    8893
    89         ::
    90        
    9194            sage: Conic(FiniteField(37), [1, 2, 3, 4, 5, 6]).has_rational_point()
    9295            True
    9396           
     
    111114            (True,
    112115             (a^18 + 2*a^17 + 4*a^16 + 6*a^13 + a^12 + 6*a^11 + 3*a^10 + 4*a^9 + 2*a^8 + 4*a^7 + a^6 + 4*a^4 + 6*a^2 + 3*a + 6 : 5*a^19 + 5*a^18 + 5*a^17 + a^16 + 2*a^15 + 3*a^14 + 4*a^13 + 5*a^12 + a^11 + 3*a^10 + 2*a^8 + 3*a^7 + 4*a^6 + 4*a^5 + 6*a^3 + 5*a^2 + 2*a + 4 : 1))
    113116             
     117        TESTS ::
     118       
     119            sage: l = Sequence(cartesian_product_iterator([[0, 1] for i in range(6)]))
     120            sage: bigF = GF(next_prime(2^100))
     121            sage: bigF2 = GF(next_prime(2^50)^2, 'b')
     122            sage: m = [[F(b) for b in a] for a in l for F in [GF(2), GF(4, 'a'), GF(5), GF(9, 'a'), bigF, bigF2]]
     123            sage: m += [[F.random_element() for i in range(6)] for j in range(20) for F in [GF(5), bigF]]
     124            sage: c = [Conic(a) for a in m if a != [0,0,0,0,0,0]]
     125            sage: assert all([C.has_rational_point() for C in c])
     126            sage: r = randrange(0, 5)
     127            sage: assert all([C.defining_polynomial()(Sequence(C.has_rational_point(point = True)[1])) == 0 for C in c[r::5]]) # long time: 1.6 seconds
    114128        """
    115129        if not point:
    116130            return True
  • sage/schemes/plane_conics/con_global_field.py

    diff -r dd59f5b6d61d -r 3f7ced9b5b3e sage/schemes/plane_conics/con_global_field.py
    a b  
    2424#                  http://www.gnu.org/licenses/
    2525#*****************************************************************************
    2626
    27 from sage.libs.pari.gen import pari
    28 from sage.misc.all import add, sage_eval
    29 from sage.rings.all import (PolynomialRing, ZZ, QQ, MPolynomialRing,
    30                             degree_lowest_rational_function,
    31                             is_PrimeField, is_FiniteField,
    32                             is_ComplexField, is_RealField,
    33                             is_pAdicField, is_Field,
    34                             is_RationalField, is_RingHomomorphism)
    35 from sage.rings.number_field.number_field import is_NumberField                           
    36 from sage.modules.free_module_element import vector
    37 from sage.structure.sequence import Sequence
    38 from sage.structure.element import is_Vector
    39 from sage.schemes.generic.projective_space import (ProjectiveSpace,
    40                                                    is_ProjectiveSpace)
    41 from sage.matrix.constructor import Matrix
    42 from sage.matrix.matrix import is_Matrix
    43 
    44 from sage.schemes.plane_curves.curve import Curve_generic_projective
    45 from sage.schemes.plane_curves.projective_curve import ProjectiveCurve_generic
    46 from sage.quadratic_forms.qfsolve import Qfsolve, Qfparam
    47 
    4827from con_field import ProjectiveConic_field
    4928
    5029class ProjectiveConic_global_field(ProjectiveConic_field):
     30    r"""
     31    Create a projective plane conic curve over a global field.
     32    See ``Conic`` for full documentation.
     33   
     34    EXAMPLES::
     35   
     36        sage: K.<a> = NumberField(x^3 - 2, 'a')
     37        sage: P.<X, Y, Z> = K[]
     38        sage: Conic(X^2 + Y^2 - a*Z^2)
     39        Projective Conic Curve over Number Field in a with defining polynomial x^3 - 2 defined by X^2 + Y^2 + (-a)*Z^2
     40       
     41    TESTS::
     42   
     43        sage: K.<a> = NumberField(x^3 - 3, 'a')
     44        sage: Conic([a, 1, -1])._test_pickling()
     45    """
    5146    def __init__(self, A, f):
     47        r"""
     48        See ``Conic`` for full documentation.
     49
     50        EXAMPLES:
     51
     52        ::
     53
     54            sage: Conic([1, 1, 1])
     55            Projective Conic Curve over Rational Field defined by x^2 + y^2 + z^2
     56        """
    5257        ProjectiveConic_field.__init__(self, A, f)
    5358        # a single prime such that self has no point over the completion
    5459        self._local_obstruction = None
     
    6065
    6166    def is_locally_solvable(self, p):
    6267        r"""
    63         Returns True if and only if self has a solution over the completion
    64         of the base field `B` of self at `p`. Here `p` is a finite prime
     68        Returns ``True`` if and only if ``self`` has a solution over the completion
     69        of the base field `B` of self at ``p``. Here ``p`` is a finite prime
    6570        or infinite place of `B`.
    6671
    6772        EXAMPLES:
    6873
    69         An example over QQ ::
     74        An example over `\QQ` ::
    7075
    7176            sage: C = Conic(QQ, [1,2,3])
    7277            sage: C.is_locally_solvable(-1)
     
    7681            sage: C.is_locally_solvable(3)
    7782            True
    7883
    79         Example over a number field ::
     84        An example over a number field ::
    8085
    81             sage: _.<x> = QQ[]
     86            sage: P.<x> = QQ[]
    8287            sage: K.<a> = NumberField(x^3 + 5)
    8388            sage: C = Conic(K, [1, 2, 3 - a])
    8489            sage: [p1, p2] = K.places()
    8590            sage: C.is_locally_solvable(p1)
    86             False
     91            Traceback (most recent call last):
     92            ...
     93            NotImplementedError: is_locally_solvable not yet implemented for conics over number fields, please implement it using generalized_hilbert_symbol of Trac 9334
    8794            sage: C.is_locally_solvable(p2)
    88             True
     95            Traceback (most recent call last):
     96            ...
     97            NotImplementedError: is_locally_solvable not yet implemented for conics over number fields, please implement it using generalized_hilbert_symbol of Trac 9334
    8998        """
    90         raise TypeError, "is_locally_solvable not yet implemented for" \
    91                          "conics over global field %s" % B
     99        raise NotImplementedError, "please implement is_locally_solvable for " \
     100                                   "conics over global field %s" % B
    92101
    93102    def local_obstructions(self, finite = True, infinite = True, read_cache = True):
    94103        r"""
    95104        Returns the sequence of finite primes and/or infinite places
    96105        such that self is locally solvable at those primes and places.
    97106       
    98         If the base field is `QQ`, then the infinite place is denoted `-1`.
     107        If the base field is `\QQ`, then the infinite place is denoted `-1`.
    99108
    100         The parameters finite and infinite (both True by default) are
    101         used to specify whether to look at finite and/or infinite places.
    102         Note that finite = True involves factorization of the determinant
     109        The parameters ``finite`` and ``infinite`` (both ``True`` by default)
     110        are used to specify whether to look at finite and/or infinite places.
     111        Note that ``finite = True`` involves factorization of the determinant
    103112        of self, hence may be slow.
    104113       
    105         Local obstructions are cached. The parameter read_cache can be used
    106         to specify whether to look at the cache before computing anything.
     114        Local obstructions are cached. The parameter ``read_cache`` specifies
     115        whether to look at the cache before computing anything.
    107116
    108         EXAMPLES:
    109 
    110         Examples over QQ ::
     117        EXAMPLES::
    111118
    112119            sage: Conic(QQ, [1, 1, 1]).local_obstructions()
    113120            [2, -1]
     
    116123            sage: Conic(QQ, [1, 2, 3, 4, 5, 6]).local_obstructions()
    117124            [41, -1]
    118125
     126        """
     127        raise NotImplementedError, "please implement local_obstructions for " \
     128                                   "conics over global field %s" % B
    119129
    120         Examples over number fields ::
    121 
    122             sage: K.<i> = QuadraticField(-1)
    123             sage: Conic(K, [1, 1, 1]).local_obstructions()
    124             []
    125             sage: Conic(K, [1, 2, -3]).local_obstructions()
    126             []
    127             sage: Conic(K, [1, 2, 3, 4, 5, 6]).local_obstructions()
    128             [Fractional ideal (5*i - 4), Fractional ideal (-5*i - 4)]
    129 
    130             sage: _.<x> = QQ[]
    131             sage: L.<b> = NumberField(x^4-2)
    132             sage: Conic(L, [1, 1, 1]).local_obstructions() # long time (2 seconds)
    133             [Ring morphism:
    134               From: Number Field in b with defining polynomial x^4 - 2
    135               To:   Real Field with 106 bits of precision
    136               Defn: b |--> -1.189207115002721066717492233629, Ring morphism:
    137               From: Number Field in b with defining polynomial x^4 - 2
    138               To:   Real Field with 106 bits of precision
    139               Defn: b |--> 1.189207115002721066717492233629]
    140             sage: Conic(L, [b, 1, 1]).local_obstructions() # long time (2 seconds)
    141             [Fractional ideal (b),
    142              Ring morphism:
    143              From: Number Field in b with defining polynomial x^4 - 2
    144              To:   Real Field with 106 bits of precision
    145              Defn: b |--> 1.189207115002721066717492233629]
    146         """
    147         obs0 = []
    148         obs1 = []
    149         B = self.base_ring()
    150         if infinite:
    151             if read_cache and self._infinite_obstructions != None:
    152                 obs0 = self._infinite_obstructions
    153             else:
    154                 if is_RationalField(B):
    155                     if not self.is_locally_solvable(-1):
    156                         obs0 = [-1]
    157                 elif is_NumberField(B):
    158                     for b in B.places():
    159                         if not self.is_locally_solvable(b):
    160                             obs0.append(b)
    161                 else:
    162                     raise TypeError, "Base field (=%s) needs to be QQ or a" \
    163                                      "number field in local_obstructions" % B
    164                 self._infinite_obstructions = obs0
    165         if finite:
    166             if read_cache and self._finite_obstructions != None:
    167                 obs1 = self._finite_obstructions
    168             else:
    169                 candidates = []
    170                 if is_RationalField(B):
    171                     if self.determinant() != 0:
    172                         for a in self.symmetric_matrix().list():
    173                             if a != 0:
    174                                 for f in a.factor():
    175                                     if f[1] < 0 and not f[0] in candidates:
    176                                         candidates.append(f[0])
    177                         for f in (2*self.determinant()).factor():
    178                             if f[1] > 0 and not f[0] in candidates:
    179                                 candidates.append(f[0])
    180                 elif is_NumberField(B):
    181                     if self.determinant() != 0:
    182                         O = B.maximal_order()
    183                         for a in self.symmetric_matrix().list():
    184                             if a != 0:
    185                                 for f in O.fractional_ideal(a).factor():
    186                                     if f[1] < 0 and not f[0] in candidates:
    187                                         candidates.append(f[0])
    188                         for f in O.fractional_ideal(2*self.determinant()).factor():
    189                             if f[1] > 0 and not f[0] in candidates:
    190                                 candidates.append(f[0])       
    191                 else:
    192                     raise TypeError, "Base field (=%s) needs to be QQ or a " \
    193                                      "number field in local_obstructions" % B
    194                 for b in candidates:
    195                     if not self.is_locally_solvable(b):
    196                        obs1.append(b)
    197                 self._infinite_obstructions = obs1
    198         obs = obs1 + obs0
    199         if finite and infinite and len(obs)%2==1:
    200             raise RuntimeError, "Bug in local_obstructions or in " \
    201                                 "is_locally_solvable: the number of bad places" \
    202                                 "for conic self (=%s) is odd" % self
    203         return obs
    204 
    205 
  • sage/schemes/plane_conics/con_number_field.py

    diff -r dd59f5b6d61d -r 3f7ced9b5b3e sage/schemes/plane_conics/con_number_field.py
    a b  
    33
    44AUTHORS:
    55
    6 - Marco Streng (2009-08-07)
     6- Marco Streng (2010-08-07)
    77
    88- Nick Alexander (2008-01-08)
    99
     
    2424#                  http://www.gnu.org/licenses/
    2525#*****************************************************************************
    2626
    27 from sage.libs.pari.gen import pari
    28 from sage.misc.all import add, sage_eval
    29 from sage.rings.all import (PolynomialRing, ZZ, QQ, RR, MPolynomialRing,
    30                             degree_lowest_rational_function,
    31                             is_PrimeField, is_FiniteField,
    32                             is_ComplexField, is_RealField,
    33                             is_pAdicField, is_Field,
    34                             is_RationalField, is_RingHomomorphism)
     27from sage.rings.all import is_RationalField
    3528from sage.rings.number_field.number_field import is_NumberField                           
    3629from sage.modules.free_module_element import vector
    37 from sage.structure.sequence import Sequence
    38 from sage.structure.element import is_Vector
    39 from sage.schemes.generic.projective_space import (ProjectiveSpace,
    40                                                    is_ProjectiveSpace)
    41 from sage.matrix.constructor import Matrix
    42 from sage.matrix.matrix import is_Matrix
    43 
    44 from sage.schemes.plane_curves.curve import Curve_generic_projective
    45 from sage.schemes.plane_curves.projective_curve import ProjectiveCurve_generic
    46 from sage.quadratic_forms.qfsolve import Qfsolve, Qfparam
    47 
    4830from con_global_field import ProjectiveConic_global_field
    49 
     31from rnfisnorm import _rnfisnorm
    5032
    5133class ProjectiveConic_number_field(ProjectiveConic_global_field):
     34    r"""
     35    Create a projective plane conic curve over a number field.
     36    See ``Conic`` for full documentation.
     37   
     38    EXAMPLES::
     39   
     40        sage: K.<a> = NumberField(x^3 - 2, 'a')
     41        sage: P.<X, Y, Z> = K[]
     42        sage: Conic(X^2 + Y^2 - a*Z^2)
     43        Projective Conic Curve over Number Field in a with defining polynomial x^3 - 2 defined by X^2 + Y^2 + (-a)*Z^2
     44       
     45    TESTS::
     46   
     47        sage: K.<a> = NumberField(x^3 - 3, 'a')
     48        sage: Conic([a, 1, -1])._test_pickling()
     49    """
    5250    def __init__(self, A, f):
     51        r"""
     52        See ``Conic`` for full documentation.
     53
     54        EXAMPLES ::
     55
     56            sage: Conic([1, 1, 1])
     57            Projective Conic Curve over Rational Field defined by x^2 + y^2 + z^2
     58        """
    5359        ProjectiveConic_global_field.__init__(self, A, f)
    5460
    5561
    5662    def has_rational_point(self, point = False, obstruction = False,
    5763                           algorithm = 'default', read_cache = True):
    5864        r"""
    59         Returns True if and only if self has a point defined over its base field B.
     65        Returns ``True`` if and only if ``self`` has a point
     66        defined over its base field `B`.
    6067
    61         If point or obstruction is True, then returns a second output S:
    62         - if point is True and self has a rational point,
    63           then S is a rational point;
    64         - if obstruction is True, self has no rational point,
    65           then S is a prime or infinite place
    66           of the base ring such that no rational point exists
    67           over the localization at S.
     68        If ``point`` or ``obstruction`` is True, then returns
     69        a second output ``S``:
     70        - if ``point`` is True and ``self`` has a rational point,
     71          then ``S`` is a rational point;
     72        - if ``obstruction`` is True, ``self`` has no rational point,
     73          then ``S`` is a prime or infinite place of `B` such that no
     74          rational point exists over the completion at ``S``.
    6875       
    69         Points and obstructions are cached, whenever they are found.
    70         If read_cache is True,
    71         then cached information is used for the output if available.
     76        Points and obstructions are cached whenever they are found.
     77        Cached information is used for the output if available, but only
     78        if ``read_cache`` is True.
    7279       
    7380        ALGORITHM:
    7481           
    7582            The parameter ``algorithm``
    7683            specifies the algorithm to be used:
    7784           
    78                 ``rnfisnorm`` - Use PARI's rnfisnorm (cannot be combined with
    79                                 obstruction = True)
    80                 ``local``     - Check if a local solution exists for all primes
    81                                 and infinite places of K (cannot be combined with
    82                                 point = True)
    83                 ``default``   - Use ``qfsolve`` over `\QQ`. Use ``local`` over
    84                                 other number fields. If the output is True and
    85                                 point is True, then use ``rnfisnorm`` to find
    86                                 the point.
    87                 ``all``       - Use all applicable algorithms, check that the
    88                                 outputs agree, and return the common answer.
     85                ``'rnfisnorm'`` - Use PARI's rnfisnorm (cannot be combined with
     86                                  ``obstruction = True``)
     87                ``'local'``     - Check if a local solution exists for all primes
     88                                  and infinite places of `B` (cannot be combined with
     89                                  ``point = True``)
     90                ``'default'``   - Use ``algorithm = 'local'`` first. If a rational
     91                                  point exists, then use ``algorithm = 'rnfisnorm'``
     92                                  to find one.
     93           
     94        NOTE:
     95       
     96            Algorithms for local solubility of conics over number fields
     97            of degree `> 1` have not been implemented yet, so
     98            'rnfisnorm' is the only working algorithm.
     99           
     100            To implement algorithms for local solubility, use Hilbert symbols
     101            from Trac #9334.
     102           
     103            The algorithm 'rnfisnorm' only works for small examples and
     104            gives the error
     105            ``GP/PARI ERROR: *** rnfisnorm: precision too low in isunit.``
     106            if the examples become to large.
     107            Instead of improving rnfisnorm.py, replace it by Trac #2329
     108            as soon as that ticket is finished.
    89109           
    90110        EXAMPLES:
    91 
    92         The following would not terminate quickly with algorithm = 'rnfisnorm' ::
     111       
     112        An example over `\QQ` ::
    93113
    94114            sage: C = Conic(QQ, [1, 113922743, -310146482690273725409])
    95115            sage: C.has_rational_point(point = True)
     
    101121           
    102122            sage: K.<i> = QuadraticField(-1)
    103123            sage: C = Conic(K, [1, 3, -5])
    104             sage: C.has_rational_point(point = True, obstruction = True, \
    105                                        algorithm = 'all')
    106             (False, Fractional ideal (-i - 2))
    107 
    108             sage: _.<x> = QQ[]
     124            sage: C.has_rational_point(point = True, obstruction = True)
     125            Traceback (most recent call last):
     126            ...
     127            NotImplementedError: is_locally_solvable not yet implemented for conics over number fields, please implement it using generalized_hilbert_symbol of Trac 9334
     128            sage: C.has_rational_point(algorithm = "rnfisnorm")
     129            False
     130            sage: C.has_rational_point(algorithm = "rnfisnorm", obstruction = True)
     131            Traceback (most recent call last):
     132            ...
     133            ValueError: Algorithm rnfisnorm cannot be combined with obstruction = True in has_rational_point
     134           
     135            sage: P.<x> = QQ[]
    109136            sage: L.<b> = NumberField(x^3-5)
    110137            sage: C = Conic(L, [1, 2, -3])
    111             sage: C.has_rational_point(point = True, obstruction = True, \
    112                                        algorithm = 'all') # long time (1 second)
     138            sage: C.has_rational_point(point = True, algorithm = 'rnfisnorm')
    113139            (True, (5/3 : -1/3 : 1))
    114140       
     141        TESTS:
     142       
     143        Create a bunch of conics over number fields and check if ``has_rational_point``
     144        runs without errors for ``algorithm = 'rnfisnorm'``. Check if all points
     145        returned are valid. ::
     146
     147            sage: P.<X> = QQ[]
     148            sage: Q = P.fraction_field()
     149            sage: c = [1, X/2, 1/X]
     150            sage: l = Sequence(cartesian_product_iterator([c for i in range(3)]))
     151            sage: l = l + [[X, 1, 1, 1, 1, 1]] + [[X, 1/5, 1, 1, 2, 1]]
     152            sage: K.<a> = QuadraticField(-23)
     153            sage: L.<b> = QuadraticField(19)
     154            sage: M.<c> = NumberField(X^3+3*X+1)
     155            sage: m = [[Q(b)(F.gen()) for b in a] for a in l for F in [K, L, M]]
     156            sage: d = []
     157            sage: c = [Conic(a) for a in m if a != [0,0,0]] # long time: 1 second
     158            sage: d = [C.has_rational_point(algorithm = 'rnfisnorm', point = True) for C in c] # long time: 15 seconds
     159            sage: assert all([c[k].defining_polynomial()(Sequence(d[k][1])) == 0 for k in range(len(c)) if d[k][0]])
     160
     161        Create a bunch of conics that are known to have rational points already over `\QQ`
     162        and check if points are found by ``has_rational_point``.
     163
     164            sage: l = Sequence(cartesian_product_iterator([[-1, 0, 1] for i in range(3)]))
     165            sage: K.<a> = QuadraticField(-23)
     166            sage: L.<b> = QuadraticField(19)
     167            sage: M.<c> = NumberField(x^5+3*x+1)
     168            sage: m = [[F(b) for b in a] for a in l for F in [K, L, M]]
     169            sage: c = [Conic(a) for a in m if a != [0,0,0] and a != [1,1,1] and a != [-1,-1,-1]] # long time 0.4 seconds
     170            sage: r = randrange(0, 5)
     171            sage: assert all([C.has_rational_point(algorithm = 'rnfisnorm') for C in c[r::5]]) # long time: 0.7 seconds
     172            sage: assert all([C.defining_polynomial()(Sequence(C.has_rational_point(point = True)[1])) == 0 for C in c[r::5]]) # uses cache, long time if previous line isn't run
    115173        """
    116174        if read_cache:
    117175            if self._rational_point is not None:
     
    129187                if obstruction:
    130188                    return True, None
    131189                return True
     190        if self.has_singular_point():
     191            if point:
     192                return self.has_singular_point(point = True)
     193            if obstruction:
     194                return True, None
     195            return True
    132196        B = self.base_ring()
    133197        if algorithm == 'default':
    134198            ret = self.has_rational_point(point = False, obstruction = True,
     
    149213            if point or obstruction:
    150214                return ret
    151215            return False
    152         if algorithm == 'all':
    153             ret = []
    154             ret.append(self.has_rational_point(obstruction = True,
    155                                                algorithm = 'local',
    156                                                read_cache = False))
    157             ret.append(self.has_rational_point(point = True,
    158                                                algorithm = 'rnfisnorm',
    159                                                read_cache = False))
    160             if all([r[0] for r in ret]):
    161                 if point or obstruction:
    162                     return [a for a in ret if a[1] != None][0]
    163                 return True
    164             if all([not r[0] for r in ret]):
    165                 if point or obstruction:
    166                     return [a for a in ret if a[1] != None][0]
    167                 return False
    168             raise RuntimeError, "Bug in has_rational_point: different " \
    169                                 "algorithms yield different outputs for conic " \
    170                                 "self (=%s)" % self
    171216        if algorithm == 'local':
    172217            if point:
    173                 raise ValueError, "Algorithm local cannot be combined with " \
     218                raise ValueError, "Algorithm 'local' cannot be combined with " \
    174219                                  "point = True in has_rational_point"
    175220            obs = self.local_obstructions(infinite = True, finite = False,
    176221                                          read_cache = read_cache)
     
    199244                        return True, pt
    200245                    return True
    201246            if (-abc[1]/abc[0]).is_square():
    202                 pt = self.point(T*vector([1, (-abc[1]/abc[0]).sqrt(), 0]))
     247                pt = self.point(T*vector([(-abc[1]/abc[0]).sqrt(), 1, 0]))
    203248                if point or obstruction:
    204249                    return True, pt
    205250                return True
    206251            if is_RationalField(B):
    207252                K = B
    208                 [KtoB, BtoK] = [K.hom(K) for _ in range(2)]
    209             elif is_NumberField(B):
     253                [KtoB, BtoK] = [K.hom(K) for i in range(2)]
     254            else:
    210255                K = B.absolute_field('Y')
    211256                [KtoB, BtoK] = K.structure()
    212             else:
    213                 raise TypeError, "Algorithm rnfisnorm is only for QQ and number " \
    214                                  "fields, not for %s" % B
    215             from rnfisnorm import rnfisnorm
    216             isnorm = rnfisnorm(BtoK(-abc[1]/abc[0]), BtoK(-abc[2]/abc[0]))
     257            isnorm = _rnfisnorm(BtoK(-abc[1]/abc[0]), BtoK(-abc[2]/abc[0]))
    217258            if isnorm[0]:
    218259                pt = self.point(T*vector([KtoB(isnorm[1][0]),
    219260                                          KtoB(isnorm[1][1]), 1]))
     
    231272
    232273    def is_locally_solvable(self, p):
    233274        r"""
    234         Returns True if and only if self has a solution over the completion
    235         of the base field `B` of self at `p`. Here `p` is a finite prime
    236         or infinite place of `B`.
     275        Returns ``True`` if and only if ``self`` has a solution over the
     276        completion of the base field `B` of ``self`` at ``p``. Here ``p``
     277        is a finite prime or infinite place of `B`.
    237278
    238279        EXAMPLES::
    239280
    240             sage: _.<x> = QQ[]
     281            sage: P.<x> = QQ[]
    241282            sage: K.<a> = NumberField(x^3 + 5)
    242283            sage: C = Conic(K, [1, 2, 3 - a])
    243284            sage: [p1, p2] = K.places()
    244285            sage: C.is_locally_solvable(p1)
    245             False
     286            Traceback (most recent call last):
     287            ...
     288            NotImplementedError: is_locally_solvable not yet implemented for conics over number fields, please implement it using generalized_hilbert_symbol of Trac 9334
    246289            sage: C.is_locally_solvable(p2)
    247             True
     290            Traceback (most recent call last):
     291            ...
     292            NotImplementedError: is_locally_solvable not yet implemented for conics over number fields, please implement it using generalized_hilbert_symbol of Trac 9334
    248293            sage: O = K.maximal_order()
    249294            sage: f = (2*O).factor(); f
    250295            (Fractional ideal (-a^2 - a + 1)) * (Fractional ideal (a^2 - 2*a + 3))
    251296            sage: C.is_locally_solvable(f[0][0])
    252             True
     297            Traceback (most recent call last):
     298            ...
     299            NotImplementedError: is_locally_solvable not yet implemented for conics over number fields, please implement it using generalized_hilbert_symbol of Trac 9334
    253300            sage: C.is_locally_solvable(f[1][0])
    254             False
     301            Traceback (most recent call last):
     302            ...
     303            NotImplementedError: is_locally_solvable not yet implemented for conics over number fields, please implement it using generalized_hilbert_symbol of Trac 9334
    255304        """
     305        raise NotImplementedError, "is_locally_solvable not yet implemented for conics over number fields, please implement it using generalized_hilbert_symbol of Trac 9334"
     306
     307    def local_obstructions(self, finite = True, infinite = True, read_cache = True):
     308        r"""
     309        Returns the sequence of finite primes and/or infinite places
     310        such that ``self`` is locally solvable at those primes and places.
     311       
     312        If the base field is `\QQ`, then the infinite place is denoted `-1`.
     313
     314        The parameters ``finite`` and ``infinite`` (both True by default) are
     315        used to specify whether to look at finite and/or infinite places.
     316        Note that ``finite = True`` involves factorization of the determinant
     317        of ``self``, hence may be slow.
     318       
     319        Local obstructions are cached. The parameter ``read_cache``
     320        specifies whether to look at the cache before computing anything.
     321
     322        EXAMPLES ::
     323
     324            sage: K.<i> = QuadraticField(-1)
     325            sage: Conic(K, [1, 1, 1]).local_obstructions()
     326            Traceback (most recent call last):
     327            ...
     328            NotImplementedError: is_locally_solvable not yet implemented for conics over number fields, please implement it using generalized_hilbert_symbol of Trac 9334
     329        """
     330        obs0 = []
     331        obs1 = []
    256332        B = self.base_ring()
    257         D, T = self.diagonal_matrix()
    258         abc = [D[j, j] for j in range(3)]
    259         if abc[2] == 0:
    260             return True
    261         a = -abc[0]/abc[2]
    262         b = -abc[1]/abc[2]
    263         from sage.rings.arith import generalized_hilbert_symbol
    264         if is_RingHomomorphism(p):
    265                    
    266             def generalized_infinite_hilbert_symbol(a, b, p):
    267                 one = ZZ(1)
    268                 zero = ZZ(0)
    269                 if is_RealField(p.codomain()):
    270                     if a == 0 or b == 0:
    271                         return zero
    272                     if p(a) > 0 or p(b) > 0:
    273                         return one
    274                     return -one
    275                 if is_ComplexField(p.codomain()):
    276                     if all([im.is_real() for im in p.im_gens()]):
    277                         raise TypeError, "Could not determine whether the place p " \
    278                                          "(= %s) is real or complex in " \
    279                                          "is_locally_solvable" % p
    280                     if a == 0 or b == 0:
    281                         return zero
    282                     return one
    283                 raise ValueError, "p (=%s) must be a prime or infinite place in is_locally_solvable" % p
    284                
    285             hs = generalized_infinite_hilbert_symbol(a, b, p)
    286         else:
    287             hs = generalized_hilbert_symbol(a, b, p)
    288         if hs == -1:
    289             if self._local_obstruction == None:
    290                 self._local_obstruction = p
    291             return False
    292         return True
     333        if infinite:
     334            if read_cache and self._infinite_obstructions != None:
     335                obs0 = self._infinite_obstructions
     336            else:
     337                for b in B.places():
     338                    if not self.is_locally_solvable(b):
     339                        obs0.append(b)
     340                self._infinite_obstructions = obs0
     341        if finite:
     342            if read_cache and self._finite_obstructions != None:
     343                obs1 = self._finite_obstructions
     344            else:
     345                candidates = []
     346                if self.determinant() != 0:
     347                    O = B.maximal_order()
     348                    for a in self.symmetric_matrix().list():
     349                        if a != 0:
     350                            for f in O.fractional_ideal(a).factor():
     351                                if f[1] < 0 and not f[0] in candidates:
     352                                    candidates.append(f[0])
     353                    for f in O.fractional_ideal(2*self.determinant()).factor():
     354                        if f[1] > 0 and not f[0] in candidates:
     355                            candidates.append(f[0])       
     356                for b in candidates:
     357                    if not self.is_locally_solvable(b):
     358                       obs1.append(b)
     359                self._infinite_obstructions = obs1
     360        obs = obs1 + obs0
     361        if finite and infinite:
     362            assert len(obs) % 2 == 0
     363        return obs
    293364
    294365
  • sage/schemes/plane_conics/con_prime_finite_field.py

    diff -r dd59f5b6d61d -r 3f7ced9b5b3e sage/schemes/plane_conics/con_prime_finite_field.py
    a b  
    33
    44AUTHORS:
    55
    6 - Marco Streng (2009-08-07)
     6- Marco Streng (2010-08-07)
    77
    8 - Nick Alexander (2008-01-08)
    98
    109"""
    1110#*****************************************************************************
    12 #       Copyright (C) 2008 Nick Alexander <ncalexander@gmail.com>
    13 #       Copyright (C) 2009 Marco Streng <marco.streng@gmail.com>
     11#       Copyright (C) 2010 Marco Streng <marco.streng@gmail.com>
    1412#
    1513#  Distributed under the terms of the GNU General Public License (GPL)
    1614#
     
    2422#                  http://www.gnu.org/licenses/
    2523#*****************************************************************************
    2624
    27 from sage.libs.pari.gen import pari
    28 from sage.misc.all import add, sage_eval
    29 from sage.rings.all import (PolynomialRing, ZZ, QQ, MPolynomialRing,
    30                             degree_lowest_rational_function,
    31                             is_PrimeField, is_FiniteField,
    32                             is_ComplexField, is_RealField,
    33                             is_pAdicField, is_Field,
    34                             is_RationalField)
    35 from sage.modules.free_module_element import vector
    36 from sage.structure.sequence import Sequence
    37 from sage.structure.element import is_Vector
    38 from sage.schemes.generic.projective_space import (ProjectiveSpace,
    39                                                    is_ProjectiveSpace)
    40 from sage.matrix.constructor import Matrix
    41 from sage.matrix.matrix import is_Matrix
    42 
    43 from sage.schemes.plane_curves.curve import Curve_generic_projective
    4425from sage.schemes.plane_curves.projective_curve import ProjectiveCurve_prime_finite_field
    45 from sage.quadratic_forms.qfsolve import Qfsolve, Qfparam
    46 
    4726from con_finite_field import ProjectiveConic_finite_field
    4827
    4928class ProjectiveConic_prime_finite_field(ProjectiveConic_finite_field, ProjectiveCurve_prime_finite_field):
     29    r"""
     30    Create a projective plane conic curve over a prime finite field.
     31    See ``Conic`` for full documentation.
     32   
     33    EXAMPLES::
     34   
     35        sage: P.<X, Y, Z> = FiniteField(5)[]
     36        sage: Conic(X^2 + Y^2 - 2*Z^2)
     37        Projective Conic Curve over Finite Field of size 5 defined by X^2 + Y^2 - 2*Z^2
     38 
     39    TESTS::
     40   
     41        sage: Conic([FiniteField(7)(1), 1, -1])._test_pickling()
     42    """
    5043    def __init__(self, A, f):
     44        r"""
     45        See ``Conic`` for full documentation.
     46
     47        EXAMPLES ::
     48
     49            sage: Conic([GF(3)(1), 1, 1])
     50            Projective Conic Curve over Finite Field of size 3 defined by x^2 + y^2 + z^2
     51        """
    5152        ProjectiveConic_finite_field.__init__(self, A, f)
    5253        ProjectiveCurve_prime_finite_field.__init__(self, A, f)
    5354
  • sage/schemes/plane_conics/con_rational_field.py

    diff -r dd59f5b6d61d -r 3f7ced9b5b3e sage/schemes/plane_conics/con_rational_field.py
    a b  
    11r"""
    2 Projective plane conics over QQ.
     2Projective plane conics over `\QQ`.
    33
    44AUTHORS:
    55
    6 - Marco Streng (2009-08-07)
     6- Marco Streng (2010-08-07)
    77
    88- Nick Alexander (2008-01-08)
    99
    1010"""
    1111#*****************************************************************************
    1212#       Copyright (C) 2008 Nick Alexander <ncalexander@gmail.com>
    13 #       Copyright (C) 2009 Marco Streng <marco.streng@gmail.com>
     13#       Copyright (C) 2009/2010 Marco Streng <marco.streng@gmail.com>
    1414#
    1515#  Distributed under the terms of the GNU General Public License (GPL)
    1616#
     
    2424#                  http://www.gnu.org/licenses/
    2525#*****************************************************************************
    2626
    27 from sage.libs.pari.gen import pari
    28 from sage.misc.all import add, sage_eval
    29 from sage.rings.all import (PolynomialRing, ZZ, QQ, RR, MPolynomialRing,
    30                             degree_lowest_rational_function,
    31                             is_PrimeField, is_FiniteField,
    32                             is_ComplexField, is_RealField,
    33                             is_pAdicField, is_Field,
    34                             is_RationalField, is_RingHomomorphism)
    35 from sage.modules.free_module_element import vector
     27from sage.rings.all import (PolynomialRing, ZZ, QQ,
     28                            is_RealField, is_RingHomomorphism)
    3629from sage.structure.sequence import Sequence
    37 from sage.structure.element import is_Vector
    38 from sage.schemes.generic.projective_space import (ProjectiveSpace,
    39                                                    is_ProjectiveSpace)
     30from sage.schemes.generic.projective_space import ProjectiveSpace
    4031from sage.matrix.constructor import Matrix
    41 from sage.matrix.matrix import is_Matrix
    4232
    43 from sage.schemes.plane_curves.curve import Curve_generic_projective
    44 from sage.schemes.plane_curves.projective_curve import ProjectiveCurve_generic
    4533from sage.quadratic_forms.qfsolve import Qfsolve, Qfparam
    4634
    4735from con_number_field import ProjectiveConic_number_field
    4836
    4937from sage.structure.element import is_InfinityElement
    5038
     39from sage.rings.arith import (lcm, hilbert_symbol)
     40
    5141class ProjectiveConic_rational_field(ProjectiveConic_number_field):
     42    r"""
     43    Create a projective plane conic curve over `\QQ`.
     44    See ``Conic`` for full documentation.
     45   
     46    EXAMPLES::
     47   
     48        sage: P.<X, Y, Z> = QQ[]
     49        sage: Conic(X^2 + Y^2 - 3*Z^2)
     50        Projective Conic Curve over Rational Field defined by X^2 + Y^2 - 3*Z^2
     51       
     52    TESTS::
     53   
     54        sage: Conic([2, 1, -1])._test_pickling()
     55    """
    5256    def __init__(self, A, f):
     57        r"""
     58        See ``Conic`` for full documentation.
     59
     60        EXAMPLES::
     61       
     62            sage: Conic([1, 1, 1])
     63            Projective Conic Curve over Rational Field defined by x^2 + y^2 + z^2
     64        """
    5365        ProjectiveConic_number_field.__init__(self, A, f)
    5466
    5567
    5668    def has_rational_point(self, point = False, obstruction = False,
    5769                           algorithm = 'default', read_cache = True):
    5870        r"""
    59         Returns True if and only if self has a point defined over `QQ`.
     71        Returns True if and only if ``self`` has a point defined over `\QQ`.
    6072
    61         If point or obstruction is True, then returns a second output S:
    62         - if point is True and self has a rational point,
    63           then S is a rational point;
    64         - if obstruction is True, self has no rational point,
    65           then S is a prime or infinite place
    66           of the base ring such that no rational point exists
    67           over the localization at S.
     73        If ``point`` or ``obstruction`` is True, then returns
     74        a second output ``S``:
     75        - if ``point`` is True and ``self`` has a rational point,
     76          then ``S`` is a rational point;
     77        - if ``obstruction`` is True and ``self`` has no rational point,
     78          then ``S`` is a prime such that no rational point exists
     79          over the completion at ``S`` or `-1` if no point exists over `\RR`.
    6880       
    6981        Points and obstructions are cached, whenever they are found.
    70         If read_cache is True,
    71         then cached information is used for the output if available.
     82        Cached information is used if and only if ``read_cache`` is True.
    7283       
    7384        ALGORITHM:
    7485           
    75             The parameter ``algorithm``
    76             specifies the algorithm to be used:
     86        The parameter ``algorithm``
     87        specifies the algorithm to be used:
    7788           
    78                 ``qfsolve``   - Use Denis Simon's Qfsolve (only over `\QQ)
    79                 ``rnfisnorm`` - Use PARI's rnfisnorm (cannot be combined with
    80                                 obstruction = True)
    81                 ``local``     - Check if a local solution exists for all primes
    82                                 and infinite places of K (cannot be combined with
    83                                 point = True)
    84                 ``default``   - Use ``qfsolve`` over `\QQ`. Use ``local`` over
    85                                 other number fields. If the output is True and
    86                                 point is True, then use ``rnfisnorm`` to find
    87                                 the point.
    88                 ``all``       - Use all applicable algorithms, check that the
    89                                 outputs agree, and return the common answer.
     89        - ``'qfsolve'``   - Use Denis Simon's Qfsolve (only over `\QQ`)
     90        - ``'rnfisnorm'`` - Use PARI's rnfisnorm (cannot be combined with
     91                            ``obstruction = True``)
     92        - ``'local'``     - Check if a local solution exists for all primes
     93                            and infinite places of `\QQ` (cannot be combined with
     94                            point = True)
     95        - ``'default'``   - Use ``'qfsolve'`` over `\QQ`. Use ``'local'`` over
     96                            other number fields. If self has a rational point
     97                            and ``point`` is True, then use ``'rnfisnorm'`` to find
     98                            the point.
    9099           
    91         EXAMPLES:
     100        EXAMPLES::
    92101
    93102            sage: C = Conic(QQ, [1, 2, -3])
    94             sage: C.has_rational_point(point = True, obstruction = True)
     103            sage: C.has_rational_point(point = True)
    95104            (True, (-1 : -1 : 1))
    96105            sage: D = Conic(QQ, [1, 3, -5])
    97             sage: D.has_rational_point(point = True, obstruction = True, \
    98                                        algorithm = 'all')
     106            sage: D.has_rational_point(point = True)
    99107            (False, 3)
    100 
    101         The following would not terminate quickly with algorithm = 'rnfisnorm' ::
     108            sage: P.<X,Y,Z> = QQ[]
     109            sage: E = Curve(X^2 + Y^2 + Z^2); E
     110            Projective Conic Curve over Rational Field defined by X^2 + Y^2 + Z^2
     111            sage: E.has_rational_point(obstruction = True)
     112            (False, -1)
     113           
     114        The following would not terminate quickly with
     115        ``algorithm = 'rnfisnorm'`` ::
    102116
    103117            sage: C = Conic(QQ, [1, 113922743, -310146482690273725409])
    104118            sage: C.has_rational_point(point = True)
     
    106120            sage: C.has_rational_point(algorithm = 'local', read_cache = False)
    107121            True
    108122
     123        TESTS:
     124       
     125        Create a bunch of conics over `\QQ`, check if ``has_rational_point`` runs without errors
     126        and returns consistent answers for all algorithms. Check if all points returned are valid. ::
     127
     128            sage: l = Sequence(cartesian_product_iterator([[-1, 0, 1] for i in range(6)]))
     129            sage: l += [[QQ(randrange(-2,3)) for i in range(3)] for j in range(200)]
     130            sage: c = [Conic(QQ, a) for a in l if a != [0,0,0] and a != (0,0,0,0,0,0)]
     131            sage: d = []
     132            sage: d = [[C]+[C.has_rational_point(algorithm = algorithm, read_cache = False, obstruction = (algorithm != 'rnfisnorm'), point = (algorithm != 'local')) for algorithm in ['local', 'qfsolve', 'rnfisnorm']] for C in c[::10]] # long time: 7 seconds
     133            sage: assert all([e[1][0] == e[2][0] and e[1][0] == e[3][0] for e in d])
     134            sage: assert all([e[0].defining_polynomial()(Sequence(e[i][1])) == 0 for e in d for i in [2,3] if e[1][0]])
    109135        """
    110136        if read_cache:
    111137            if self._rational_point is not None:
     
    123149                if obstruction:
    124150                    return True, None
    125151                return True
     152        if self.has_singular_point():
     153            if point:
     154                return self.has_singular_point(point = True)
     155            if obstruction:
     156                return True, None
     157            return True
    126158        if algorithm == 'default':
    127159            algorithm = 'qfsolve'
    128         if algorithm == 'all':
    129             ret = []
    130             ret.append(self.has_rational_point(point = True,
    131                                                obstruction = True,
    132                                                algorithm = 'qfsolve',
    133                                                read_cache = False))
    134             ret.append(self.has_rational_point(obstruction = True,
    135                                                algorithm = 'local',
    136                                                read_cache = False))
    137             ret.append(self.has_rational_point(point = True,
    138                                                algorithm = 'rnfisnorm',
    139                                                read_cache = False))
    140             if all([r[0] for r in ret]):
    141                 if point or obstruction:
    142                     return [a for a in ret if a[1] != None][0]
    143                 return True
    144             if all([not r[0] for r in ret]):
    145                 if point or obstruction:
    146                     return [a for a in ret if a[1] != None][0]
    147                 return False
    148             raise RuntimeError, "Bug in has_rational_point: different " \
    149                                 "algorithms yield different outputs for conic " \
    150                                 "self (=%s)" % self
    151160        if algorithm == 'qfsolve':                       
    152             from sage.quadratic_forms.qfsolve import Qfsolve
    153             from sage.rings.arith import lcm
    154161            M = self.symmetric_matrix()
    155162            M *= lcm([ t.denominator() for t in M.list() ])
    156163            pt = Qfsolve(M)
    157164            if pt in ZZ:
    158                 if pt == -1:
    159                     pt = QQ.embeddings(RR)[0]
    160165                if self._local_obstruction == None:
    161166                    self._local_obstruction = pt
    162167                if point or obstruction:
     
    166171            if point or obstruction:
    167172                return True, pt
    168173            return True
    169         return ProjectiveConic_number_field.has_rational_point(self, point = point, \
    170                                             obstruction = obstruction, \
    171                                             algorithm = algorithm, \
    172                                             read_cache = read_cache)
     174        ret = ProjectiveConic_number_field.has_rational_point( \
     175                                           self, point = point, \
     176                                           obstruction = obstruction, \
     177                                           algorithm = algorithm, \
     178                                           read_cache = read_cache)
     179        if point or obstruction:
     180            if is_RingHomomorphism(ret[1]):
     181                ret[1] = -1
     182        return ret
    173183                                           
    174184    def is_locally_solvable(self, p):
    175185        r"""
    176         Returns True if and only if self has a solution over the
    177         p-adic numbers.. Here `p` is a prime number or equals
    178         -1, infinity, or `\RR` to denote the infinite place.
     186        Returns True if and only if ``self`` has a solution over the
     187        `p`-adic numbers. Here `p` is a prime number or equals
     188        `-1`, infinity, or `\RR` to denote the infinite place.
    179189
    180         EXAMPLES:
     190        EXAMPLES::
    181191       
    182         ::
    183 
    184192            sage: C = Conic(QQ, [1,2,3])
    185193            sage: C.is_locally_solvable(-1)
    186194            False
     
    203211            return True
    204212        a = -abc[0]/abc[2]
    205213        b = -abc[1]/abc[2]
    206         from sage.rings.arith import hilbert_symbol
    207214        if is_RealField(p) or is_InfinityElement(p):
    208215            p = -1
    209216        elif is_RingHomomorphism(p):
    210             if p.domain == QQ and is_RealField(p.codomain):
     217            if p.domain() is QQ and is_RealField(p.codomain()):
    211218                p = -1
    212219            else:
    213220                raise TypeError, "p (=%s) needs to be a prime of base field " \
    214                                      "B ( =`QQ`) in is_locally_solvable" % p
     221                                 "B ( =`QQ`) in is_locally_solvable" % p
    215222        if hilbert_symbol(a, b, p) == -1:
    216223            if self._local_obstruction == None:
    217224                self._local_obstruction = p
    218225            return False
    219226        return True
    220227
     228    def local_obstructions(self, finite = True, infinite = True, read_cache = True):
     229        r"""
     230        Returns the sequence of finite primes and/or infinite places
     231        such that self is locally solvable at those primes and places.
     232       
     233        The infinite place is denoted `-1`.
     234
     235        The parameters ``finite`` and ``infinite`` (both True by default) are
     236        used to specify whether to look at finite and/or infinite places.
     237        Note that ``finite = True`` involves factorization of the determinant
     238        of ``self``, hence may be slow.
     239       
     240        Local obstructions are cached. The parameter ``read_cache`` specifies
     241        whether to look at the cache before computing anything.
     242
     243        EXAMPLES ::
     244
     245            sage: Conic(QQ, [1, 1, 1]).local_obstructions()
     246            [2, -1]
     247            sage: Conic(QQ, [1, 2, -3]).local_obstructions()
     248            []
     249            sage: Conic(QQ, [1, 2, 3, 4, 5, 6]).local_obstructions()
     250            [41, -1]
     251           
     252        """
     253        obs0 = []
     254        obs1 = []
     255        if infinite:
     256            if read_cache and self._infinite_obstructions != None:
     257                obs0 = self._infinite_obstructions
     258            else:
     259                if not self.is_locally_solvable(-1):
     260                    obs0 = [-1]
     261                self._infinite_obstructions = obs0
     262        if finite:
     263            if read_cache and self._finite_obstructions != None:
     264                obs1 = self._finite_obstructions
     265            else:
     266                candidates = []
     267                if self.determinant() != 0:
     268                    for a in self.symmetric_matrix().list():
     269                        if a != 0:
     270                            for f in a.factor():
     271                                if f[1] < 0 and not f[0] in candidates:
     272                                    candidates.append(f[0])
     273                    for f in (2*self.determinant()).factor():
     274                        if f[1] > 0 and not f[0] in candidates:
     275                            candidates.append(f[0])
     276                for b in candidates:
     277                    if not self.is_locally_solvable(b):
     278                       obs1.append(b)
     279                self._infinite_obstructions = obs1
     280        obs = obs1 + obs0
     281        if finite and infinite:
     282            assert len(obs) % 2 == 0
     283        return obs
     284
     285    def parametrization(self, point=None, morphism=True):
     286        r"""
     287        Return a parametrization `f` of ``self`` together with the
     288        inverse of `f`.
     289
     290        If ``point`` is specified, then that point is used
     291        for the parametrization. Otherwise, use ``self.rational_point()``
     292        to find a point.
     293           
     294        If ``morphism`` is True, then `f` is returned in the form
     295        of a Scheme morphism. Otherwise, it is a tuple of polynomials
     296        that gives the parametrization.
     297       
     298        ALGORITHM:
     299       
     300            Uses Denis Simon's Qfparam.
     301       
     302        EXAMPLES ::
     303
     304            sage: c = Conic([1,1,-1])
     305            sage: c.parametrization()
     306            (Scheme morphism:
     307              From: Projective Space of dimension 1 over Rational Field
     308              To:   Projective Conic Curve over Rational Field defined by x^2 + y^2 - z^2
     309              Defn: Defined on coordinates by sending (x : y) to
     310                    (2*x*y : x^2 - y^2 : x^2 + y^2),
     311             Scheme morphism:
     312               From: Projective Conic Curve over Rational Field defined by x^2 + y^2 - z^2
     313               To:   Projective Space of dimension 1 over Rational Field
     314               Defn: Defined on coordinates by sending (x : y : z) to
     315                     (1/2*x : -1/2*y + 1/2*z))
     316       
     317        An example with ``morphism = False`` ::
     318
     319            sage: R.<x,y,z> = QQ[]
     320            sage: C = Curve(7*x^2 + 2*y*z + z^2)
     321            sage: (p, i) = C.parametrization(morphism = False); (p, i)
     322            ([-2*x*y, 7*x^2 + y^2, -2*y^2], [-1/2*x, -1/2*z])
     323            sage: C.defining_polynomial()(p)
     324            0
     325            sage: i[0](p) / i[1](p)
     326            x/y
     327           
     328        A ``ValueError`` is raised if ``self`` has no rational point ::
     329
     330            sage: C = Conic(x^2 + 2*y^2 + z^2)
     331            sage: C.parametrization()
     332            Traceback (most recent call last):
     333            ...
     334            ValueError: Conic Projective Conic Curve over Rational Field defined by x^2 + 2*y^2 + z^2 has no rational points over Rational Field!
     335
     336        A ``ValueError`` is raised if ``self`` is not smooth ::
     337       
     338            sage: C = Conic(x^2 + y^2)
     339            sage: C.parametrization()
     340            Traceback (most recent call last):
     341            ...
     342            ValueError: The conic self (=Projective Conic Curve over Rational Field defined by x^2 + y^2) is not smooth, hence does not have a parametrization.
     343        """
     344        if (not self._parametrization is None) and not point:
     345            par = self._parametrization
     346        else:
     347            if not self.is_smooth():
     348                raise ValueError, "The conic self (=%s) is not smooth, hence does not have a parametrization." % self
     349            if point == None:
     350                point = self.rational_point()
     351            point = Sequence(point)
     352            Q = PolynomialRing(QQ, 'x,y')
     353            [x, y] = Q.gens()
     354            gens = self.ambient_space().gens()
     355            M = self.symmetric_matrix()
     356            M *= lcm([ t.denominator() for t in M.list() ])
     357            par1 = Qfparam(M, point)
     358            B = Matrix([[par1[i][j] for j in range(3)] for i in range(3)])
     359            # self is in the image of B and does not lie on a line,
     360            # hence B is invertible
     361            A = B.inverse()
     362            par2 = [sum([A[i,j]*gens[j] for j in range(3)]) for i in [1,0]]
     363            par = ([Q(pol(x/y)*y**2) for pol in par1], par2)
     364            if self._parametrization is None:
     365                self._parametrization = par
     366        if not morphism:
     367            return par
     368        P1 = ProjectiveSpace(self.base_ring(), 1, 'x,y')
     369        return P1.hom(par[0],self), self.Hom(P1)(par[1], check = False)
     370
  • sage/schemes/plane_conics/constructor.py

    diff -r dd59f5b6d61d -r 3f7ced9b5b3e sage/schemes/plane_conics/constructor.py
    a b  
    11r"""
    2 Plane conic constructors
     2Plane conic constructor.
    33
    44AUTHORS:
    55
    6 - Marco Streng (2009-08-07)
     6- Marco Streng (2010-08-07)
     7
     8- Nick Alexander (2008-01-08)
    79
    810"""
    9 
    1011#*****************************************************************************
    11 #       Copyright (C) 2009 Marco Streng <marco.streng@gmail.com>
     12#       Copyright (C) 2008 Nick Alexander <ncalexander@gmail.com>
     13#       Copyright (C) 2009/2010 Marco Streng <marco.streng@gmail.com>
    1214#
    1315#  Distributed under the terms of the GNU General Public License (GPL)
    1416#
     
    2527from sage.matrix.constructor import Matrix
    2628from sage.modules.free_module_element import vector
    2729from sage.quadratic_forms.all import is_QuadraticForm
    28 from sage.rings.all import (PolynomialRing, is_MPolynomial,
    29                             is_MPolynomialRing, is_Ring,
     30from sage.rings.all import (is_MPolynomial, PolynomialRing,
    3031                            is_IntegralDomain, is_FiniteField,
    3132                            is_PrimeFiniteField,
    3233                            is_RationalField)
     
    4647
    4748def Conic(base_field, F=None, names=None, unique=True):
    4849    r"""
    49     Return the plane projective conic curve defined by `F`
    50     over base_field, where `F` can be either a two- or
    51     three-variable polynomial, a list or matrix of coefficients,
    52     a ternary quadratic form, or a list or tuple of 5 points
    53     in the plane.
    54 
    55     The input form Conic(F, names=None) is also accepted,
    56     in which case the fraction field of the base ring of `F`
     50    Return the plane projective conic curve defined by ``F``
     51    over ``base_field``.
     52   
     53    The input form ``Conic(F, names=None)`` is also accepted,
     54    in which case the fraction field of the base ring of ``F``
    5755    is used as base field.
    5856
    59     The argument names is a list, tuple, or comma separated string
    60     of three variable names.
     57    INPUT:
     58   
     59    - ``base_field`` -- The base field of the conic.
     60   
     61    - ``names`` -- a list, tuple, or comma separated string
     62      of three variable names specifying the names
     63      of the coordinate functions of the ambient
     64      space `\Bold{P}^3`. If not specified or read
     65      off from ``F``, then this defaults to ``'x,y,z'``.
    6166
    62     If `F` is a polynomial, then it needs to have degree 2
    63     and if it has three variables, then it needs to be
    64     homogeneous. If `F` is a polynomial or quadratic form,
    65     then the output is the curve in the projective plane
    66     defined by `F=0`.
     67    - ``F`` -- a polynomial, list, matrix, ternary quadratic form,
     68      or list or tuple of 5 points in the plane.
     69                   
     70                   If ``F`` is a polynomial or quadratic form,
     71                   then the output is the curve in the projective plane
     72                   defined by ``F = 0``.
    6773
    68     If `F` is a matrix, then the output is the zero locus
    69     of `(x,y,z) F (x,y,z)^t`.
     74                   If ``F`` is a polynomial, then it must be a polynomial
     75                   of degree at most 2 in 2 variables, or a homogeneous
     76                   polynomial in of degree 2 in 3 variables.
     77                   
     78                   If ``F`` is a matrix, then the output is the zero locus
     79                   of `(x,y,z) F (x,y,z)^t`.
    7080   
    71     If `F` is a list of coefficients, then it has
    72     length 3 or 6 and gives the coefficients of
    73     the monomials `x^2, y^2, z^2` or all 6 monomials
    74     in lexicographic order.
     81                   If ``F`` is a list of coefficients, then it has
     82                   length 3 or 6 and gives the coefficients of
     83                   the monomials `x^2, y^2, z^2` or all 6 monomials
     84                   `x^2, xy, xz, y^2, yz, z^2` in lexicographic order.
    7585
    76     If `F` is a list of points in the plane, then the output
    77     is a conic through those points. If the argument unique
    78     is true and there is no unique conic through those points,
    79     then a ValueError is raised.
     86                   If ``F`` is a list of 5 points in the plane, then the output
     87                   is a conic through those points.
     88     
     89    - ``unique`` -- Used only if ``F`` is a list of points in the plane.
     90      If the conic through the points is not unique, then
     91      raise ``ValueError`` if and only if ``unique`` is True
     92                   
     93    OUTPUT:
    8094   
    81     EXAMPLE: Conic curves given by equations
     95    A plane projective conic curve defined by ``F`` over a field.
    8296   
    83     ::
     97    EXAMPLES:
     98   
     99    Conic curves given by polynomials ::
    84100
    85101        sage: X,Y,Z = QQ['X,Y,Z'].gens()
    86102        sage: Conic(X^2 - X*Y + Y^2 - Z^2)
     
    89105        sage: Conic(x^2 - x + 2*y^2 - 3, 'U,V,W')
    90106        Projective Conic Curve over Finite Field of size 7 defined by U^2 + 2*V^2 - U*W - 3*W^2
    91107
    92     EXAMPLE: Conic curves given by matrices
    93 
    94     ::
     108    Conic curves given by matrices ::
    95109
    96110        sage: Conic(matrix(QQ, [[1, 2, 0], [4, 0, 0], [7, 0, 9]]), 'x,y,z')
    97111        Projective Conic Curve over Rational Field defined by x^2 + 6*x*y + 7*x*z + 9*z^2
     
    102116        sage: Conic(C.symmetric_matrix(), 'x,y,z')
    103117        Projective Conic Curve over Finite Field of size 11 defined by x^2 + y^2 - 2*z^2
    104118
    105     EXAMPLE: Conics given by coefficients
    106 
    107     ::
     119    Conics given by coefficients ::
    108120   
    109121        sage: Conic(QQ, [1,2,3])
    110122        Projective Conic Curve over Rational Field defined by x^2 + 2*y^2 + 3*z^2
    111123        sage: Conic(GF(7), [1,2,3,4,5,6], 'X')
    112124        Projective Conic Curve over Finite Field of size 7 defined by X0^2 + 2*X0*X1 - 3*X1^2 + 3*X0*X2 - 2*X1*X2 - X2^2
    113125   
    114     EXAMPLE: The conic through a given set of points
    115 
    116     ::
     126    The conic through a set of points ::
    117127
    118128        sage: C = Conic(QQ, [[10,2],[3,4],[-7,6],[7,8],[9,10]]); C
    119129        Projective Conic Curve over Rational Field defined by x^2 + 13/4*x*y - 17/4*y^2 - 35/2*x*z + 91/4*y*z - 37/2*z^2
     
    166176                raise ValueError, "points in F (=%s) do not define a unique " \
    167177                                   "conic" % F
    168178            con = Conic(base_field, Sequence(M.right_kernel().gen()), names)
    169             _ = con.point(F[0])
     179            con.point(F[0])
    170180            return con
    171181        F = Sequence(F, universe = base_field)
    172182        base_field = F.universe().fraction_field()
     
    192202                         "a sequence of points or coefficients" % F
    193203
    194204    if F.total_degree() != 2:
    195         return TypeError, "F (=%s) must have degree 2" % F
     205        raise TypeError, "F (=%s) must have degree 2" % F
    196206
    197207    if base_field == None:
    198208        base_field = F.base_ring()
     
    211221        raise ValueError, "F must be nonzero over base field %s" % base_field
    212222
    213223    if F.total_degree() != 2:
    214         return TypeError, "F (=%s) must have degree 2 over base field %s" % \
     224        raise TypeError, "F (=%s) must have degree 2 over base field %s" % \
    215225                          (F, base_field)
    216226
    217227    if F.parent().ngens() == 3:
  • sage/schemes/plane_conics/rnfisnorm.py

    diff -r dd59f5b6d61d -r 3f7ced9b5b3e sage/schemes/plane_conics/rnfisnorm.py
    a b  
    33
    44The function rnfisnorm is a wrapper for the PARI function with the same name.
    55On input a relative quadratic number field `L` and an element `x` of its
    6 base field `K`, the function rnfisnorm(L, x) determines whether `x` is the
     6base field `K`, the function ``rnfisnorm(L, x)`` determines whether `x` is the
    77relative norm `N_{L/K}(y)` of an element `y\in L`.
    88
    99AUTHORS:
     
    2929from sage.libs.pari.gen import pari
    3030from sage.rings.all import (NumberField, PolynomialRing, is_NumberField,
    3131                            is_NumberFieldElement, is_AbsoluteNumberField,
    32                             is_RationalField, ZZ, QQ)
     32                            is_RationalField, ZZ, QQ)
     33from sage.rings.arith import LCM                           
    3334from sage.structure.sequence import Sequence
    3435
    3536
    3637
    37 def rnfisnorm(L, x, galois_check = 2, extra_primes = 0):
     38def _rnfisnorm(L, x, galois_check = 2, extra_primes = 0):
    3839    r"""
    39     WARNING: This function should not be in sage.schemes.plane_conics,
    40     where it is now, and will be removed from here. It can be added
    41     to number_field, or replaced by the patch of trac #2329.
     40    WARNING:
     41   
     42        This function will be removed after Trac #2329 is completed.
     43        Then use ``x.is_norm(L)`` instead.
    4244   
    4345    For a relative number field `L` and an element `x` of its base field `K`,
    4446    determine whether `x` is the relative norm `N_{L/K}(y)` of an element
    4547    `y\in L`.
    4648   
    47     The output takes the form (True, y) if the answer is positive, and
    48     (False, None) otherwise.
     49    The output takes the form ``(True, y)`` if the answer is positive, and
     50    ``(False, None)`` otherwise.
    4951   
    5052    The output is guaranteed if `L/K` is Galois. Otherwise, the parameters
    51     galois_check and extra_primes can be used as follows.
     53    ``galois_check`` and ``extra_primes`` can be used as follows.
    5254   
    53     galois_check can be 0, 1, or 2.
    54         0 do not care if L/K is Galois
    55         1 assume L/K is Galois
    56         2 let PARI determine whether L/K is Galois
     55    ``galois_check`` can be 0, 1, or 2.
    5756   
    58     extra_primes:
    59         The norm equation is solved in S-units, where `S` is a set determined
     57        0. do not care if L/K is Galois
     58        1. assume L/K is Galois
     59        2. let PARI determine whether L/K is Galois
     60   
     61    ``extra_primes``:
     62        The norm equation is solved in `S`-units, where `S` is a set determined
    6063        by the PARI. If extra_primes is a positive integer, add all primes
    61         <= extra_primes to `S`. If extra_primes is a negative integer, add
     64        ``<=`` extra_primes to `S`. If extra_primes is a negative integer, add
    6265        all primes dividing extra_primes to `S`. If `S` contains all primes
    6366        less than `12`log(disc(`M`)), where `M` is the normal closure of `L/K`,
    6467        then the output is guaranteed under GRH.
     
    6972        group for a suitable set of primes `S` of `L`.
    7073   
    7174    EXAMPLES:
    72    
    73     Absolute number fields are interpreted as relative fields over `QQ`.
     75    This also works over `\QQ`.
     76   
     77    ::
     78   
     79        sage: from sage.schemes.plane_conics.rnfisnorm import _rnfisnorm
     80        sage: _rnfisnorm(5/4, 1/5)
     81
     82    Absolute number fields are interpreted as relative fields over `\QQ`.
    7483   
    7584    ::
    76         sage: from sage.schemes.plane_conics.rnfisnorm import rnfisnorm
    77         sage: rnfisnorm(QuadraticField(-1, 'i'), 2)
     85        sage: from sage.schemes.plane_conics.rnfisnorm import _rnfisnorm
     86        sage: _rnfisnorm(QuadraticField(-1, 'i'), 2)
    7887        (True, i + 1)
    79         sage: rnfisnorm(CyclotomicField(7), 7)
     88        sage: _rnfisnorm(CyclotomicField(7), 7)
    8089        (True,  zeta7 - 1)
    81         sage: rnfisnorm(CyclotomicField(7), 3)
     90        sage: _rnfisnorm(CyclotomicField(7), 3)
    8291        (False, None)
    8392
    8493    A higher degree example:
    8594   
    8695    ::
    8796   
    88         sage: from sage.schemes.plane_conics.rnfisnorm import rnfisnorm
     97        sage: from sage.schemes.plane_conics.rnfisnorm import _rnfisnorm
    8998        sage: P.<x> = QQ[]
    9099        sage: K.<a> = NumberField(x^3 + x + 1)
    91100        sage: Q.<X> = K[]
    92101        sage: L.<b> = NumberField(X^4 + a)
    93         sage: t = rnfisnorm(L, -a); t
     102        sage: t = _rnfisnorm(L, -a); t
    94103        (True, b^3 + 1)
    95104        sage: t[1].norm(K) == -a
    96105        True
    97         sage: rnfisnorm(K, 2)
     106        sage: _rnfisnorm(K, 2)
    98107        (False, None)
    99         sage: t = rnfisnorm(L, 2); t
     108        sage: t = _rnfisnorm(L, 2); t
    100109        (True, -a*b^3 + b^2 + (a^2 + 1)*b + a^2 + 1)
    101110        sage: t[1].norm(K) == 2
    102111        True
     
    108117   
    109118    ::
    110119   
    111         sage: from sage.schemes.plane_conics.rnfisnorm import rnfisnorm
    112         sage: rnfisnorm(-1, 2)
     120        sage: from sage.schemes.plane_conics.rnfisnorm import _rnfisnorm
     121        sage: _rnfisnorm(-1, 2)
    113122        (True, (1, 1))
    114123        sage: K.<b> = NumberField(x^5+x+3)
    115         sage: rnfisnorm(b, 1 - b)
     124        sage: _rnfisnorm(b, 1 - b)
    116125        (True, (-1, 1))
    117         sage: rnfisnorm(b/2, -5)
     126        sage: _rnfisnorm(b/2, -5)
    118127        (False, None)
    119         sage: rnfisnorm(b, (1 - b)/3)
     128        sage: _rnfisnorm(b, (1 - b)/3)
    120129        (False, None)
    121130    """
    122131    if is_NumberFieldElement(L) or L in QQ:
     
    131140        x = K(x)
    132141        den = L.denominator()
    133142        L = NumberField(X**2-L*den**2, K.variable_name() + 'L')
    134         ret = rnfisnorm(L, x, galois_check = galois_check,
     143        ret = _rnfisnorm(L, x, galois_check = galois_check,
    135144                      extra_primes = extra_primes)
    136145        if ret[0]:
    137146            ret1 = ret[1].vector()
     
    153162        xpari = x._pari_('y')
    154163    else:
    155164        raise ValueError, "Base field of L (=%s) needs to be an absolute" \
    156                           "number field in rnfisnorm" % L
    157     T = pari("rnfisnorm(rnfisnorminit(%s, %s, %s), %s, %s)" %
    158               (pol1, pol2, galois_check, xpari, extra_primes))
     165                          "number field in _rnfisnorm" % L
     166    T = pari("rnfisnorm(rnfisnorminit(%s, %s, %s), %s, %s)" % (pol1, \
     167                            pol2, galois_check, xpari, extra_primes))
    159168    if T[1] == 1:
    160         Q = PolynomialRing(K, 'X')
    161         return True, L(Q(T[0].lift()))
     169        Q = PolynomialRing(K, 'X')
     170        u = T[0].lift()
     171        d = ZZ(LCM([u.polcoeff(k).eval(0).denominator() for k in range(u.lift().poldegree()+1)]))
     172        return True, L(Q(d*u))/d
    162173    return False, None
    163174   
    164175   
  • sage/schemes/plane_curves/constructor.py

    diff -r dd59f5b6d61d -r 3f7ced9b5b3e sage/schemes/plane_curves/constructor.py
    a b  
    4242                          AffineCurve_finite_field,
    4343                          AffineCurve_prime_finite_field)
    4444
     45from sage.schemes.plane_conics.constructor import Conic
     46
    4547def Curve(F):
    4648    """
    4749    Return the plane or space curve defined by `F`, where
     
    101103   
    102104        sage: x,y,z = QQ['x,y,z'].gens()
    103105        sage: Curve((x-y)*(x+y))
    104         Projective Curve over Rational Field defined by x^2 - y^2
     106        Projective Conic Curve over Rational Field defined by x^2 - y^2
    105107        sage: Curve((x-y)^2*(x+y)^2)
    106108        Projective Curve over Rational Field defined by x^4 - 2*x^2*y^2 + y^4
    107109   
     
    144146   
    145147        sage: x,y,z = QQ['x,y,z'].gens()
    146148        sage: Curve(x^2+y^2)
    147         Projective Curve over Rational Field defined by x^2 + y^2
     149        Projective Conic Curve over Rational Field defined by x^2 + y^2
    148150        sage: Curve(x^2+y^2+z)
    149151        Traceback (most recent call last):
    150152        ...
     
    203205            raise ValueError, "defining polynomial of curve must be nonzero"
    204206        P2 = ProjectiveSpace(2, P.base_ring())
    205207        P2._coordinate_ring = P
     208       
     209        if F.total_degree() == 2 and k.is_field():
     210            return Conic(F)
     211       
    206212        if is_FiniteField(k):
    207213            if k.is_prime_field():
    208214                return ProjectiveCurve_prime_finite_field(P2, F)