Ticket #8997: trac_8997_fix_rr_basis_and_doc.patch

File trac_8997_fix_rr_basis_and_doc.patch, 10.2 KB (added by minz, 11 years ago)

apply to 4.6

  • doc/en/constructions/algebraic_geometry.rst

    # HG changeset patch
    # User Moritz Minzlaff <minzlaff@daad-alumni.de>
    # Date 1290278473 -3600
    # Node ID f60c02c17b794574cdf738c1ba21aa462f9b11f4
    # Parent  120c07be6358d93bcff503363d379c26b8342f2b
    Trac 8997: fix riemann_roch_basis and documentation
    
    diff -r 120c07be6358 -r f60c02c17b79 doc/en/constructions/algebraic_geometry.rst
    a b  
    306306Riemann-Roch spaces using Singular
    307307==================================
    308308
    309 Can you compute a basis of a Riemann-Roch space in Sage?
     309To compute a basis of the Riemann-Roch space of a divisor :math:`D`
     310on a curve over a field :math:`F`, one can use Sage's wrapper
     311``riemann_roch_basis`` of Singular's implementation of the Brill
     312Noether algorithm. Note that this wrapper currently only works when
     313:math:`F` is prime and the divisor :math:`D` is supported on rational points.
     314Below are examples of how to use ``riemann_roch_basis`` and how to use
     315Singular itself to help an understanding of how the wrapper works.
    310316
    311 Unfortunately, the answer is "no" at the present time. The version
    312 of Singular currently used by (version 3.0.2) has a Brill-Noether
    313 algorithm implementation (computing a basis of a Riemann-Roch
    314 space) which appears to be buggy. The rest of this section is
    315 included to illustrate the syntax once the bugs in ``brnoeth`` get
    316 worked out (or to help any developers wishing to work on this
    317 themselves).
     317-  Using ``riemann_roch_basis``:
    318318
    319 To compute a basis for the Riemann-Roch space :math:`L(D)`
    320 associated to a divisor :math:`D` on a curve :math:`X` over a
    321 field :math:`F`, you can use 's "wrapper" ``riemann_roch_basis``
    322 to Singular or Singular itself. Both are illustrated below.
    323 
    324 
    325 
    326319   ::
    327320
    328321       sage: x, y, z = PolynomialRing(GF(5), 3, 'xyz').gens()
    329322       sage: f = x^7 + y^7 + z^7
    330        sage: C = Curve(f); pts = C.rational_points()
    331        sage: D = C.divisor([ (3, pts[0]), (-1,pts[1]), (10, pts[5]) ])
    332        sage: C.riemann_roch_basis(D)
    333        [x^8*y/(x^6*z^3 - x^5*y*z^3 + ...  # 32-bit
    334        [(x^9 + x^8*y)/(x^6*z^3 - ...  # 64-bit
     323       sage: X = Curve(f); pts = X.rational_points()
     324       sage: D = X.divisor([ (3, pts[0]), (-1,pts[1]), (10, pts[5]) ])
     325       sage: X.riemann_roch_basis(D)
     326       [(-2*x + y)/(x + y), (-x + z)/(x + y)]
    335327
    336    The output is somewhat random.
    337 
    338 -  Singular's ``BrillNoether`` command (for details on this command,
    339    see the section Brill-Noether in the Singular online documentation
     328-  Using Singular's ``BrillNoether`` command (for details see the section
     329   Brill-Noether in the Singular online documentation
    340330   (http://www.singular.uni-kl.de/Manual/html/sing_960.htm and the
    341331   paper {CF}):
    342332
     
    353343       Adjunction divisor computed successfully
    354344       <BLANKLINE>
    355345       The genus of the curve is 2
    356        sage: print singular.eval("X = NSplaces(1..2,X);")
     346       sage: print singular.eval("X = NSplaces(1,X);")
    357347       Computing non-singular affine places of degree 1 ...
    358        Computing non-singular affine places of degree 2 ...
    359348       sage: print singular("X[3];")
    360349       [1]:
    361350          1,1
     
    370359       [6]:
    371360          1,6
    372361
    373    The 6 Places in X[3] are of degree 1. We define the rational
    374    divisor {G = 4\*C[3][1]+4\*C[3][2]+4\*C[3][3]} (of degree 12):
     362   The first integer of each pair in the above list is the degree
     363   `d` of a point. The second integer is the index of this point
     364   in the list POINTS of the ring X[5][`d`][1]. Note that the
     365   order of this latter list is different every time the algorithm
     366   is run, e.g. `1`, `1` in the above list refers to a different
     367   rational point each time. A divisor is given by defining a list
     368   `G` of integers of the same length as X[3] such that if the
     369   `k`-th entry of X[3] is `d`, `i`, then the `k`-th entry of `G` is
     370   the multiplicity of the divisor at the `i`-th point in the list
     371   POINTS of the ring X[5][`d`][1]. Let us proceed by defining a
     372   "random" divisor of degree 12 and computing a basis of its
     373   Riemann-Roch space:
     374
     375   .. link
    375376
    376377   ::
    377378
     
    388389       Vector basis successfully computed
    389390       <BLANKLINE>
    390391
    391    Here is the vector basis of L(G):
    392 
    393    .. link
    394 
    395    ::
    396 
    397        sage: print singular.eval("LG;")
    398        [1]:                     # 32-bit
    399           _[1]=x2               # 32-bit
    400           _[2]=x2+z2            # 32-bit
    401        [2]:                     # 32-bit
    402           _[1]=-x4+x2z2         # 32-bit
    403           _[2]=x2y2+y2z2        # 32-bit
    404        [1]:                               # 64-bit
    405           _[1]=-x5+x4z-x3y2+2x3z2+x2y2z   # 64-bit
    406           _[2]=-x4z+x3y2+z5               # 64-bit
    407        [2]:                               # 64-bit
    408           _[1]=-2x5-x4z+2x3y2+2x3z2+x2z3  # 64-bit
    409           _[2]=-x4z+x3y2+z5               # 64-bit
    410        ...
    411392
    412393.. index::
    413394   pair: codes; algebraic-geometric
     
    421402and the divisor :math:`D`, you must also specify the evaluation
    422403divisor :math:`E`.
    423404
    424 As in the previous section, until the bugs in ``brnoth`` are worked
    425 out, this section is only included to illustrate syntax (or to help
    426 any developers wishing to work on this themselves).
     405Note that this section has not been updated since the wrapper
     406``riemann_roch_basis`` has been fixed. See above for how to
     407properly define a divisor for Singular's ``BrillNoether``
     408command.
    427409
    428410Here's an example, one which computes a generator matrix of an
    429411associated AG code. This time we use Singular's ``AGCode_L``
  • sage/schemes/plane_curves/projective_curve.py

    diff -r 120c07be6358 -r f60c02c17b79 sage/schemes/plane_curves/projective_curve.py
    a b  
    88- David Joyner (2005-11-13)
    99
    1010- David Kohel (2006-01)
     11
     12- Moritz Minzlaff (2010-11)
    1113"""
    1214
    1315#*****************************************************************************
     
    538540        r"""
    539541        Return a basis for the Riemann-Roch space corresponding to
    540542        `D`.
    541        
    542         .. warning::
    543543
    544           This function calls a Singular function that
    545           appears to be very buggy and should not be trusted.
    546        
    547544        This uses Singular's Brill-Noether implementation.
    548545       
    549546        INPUT:
    550        
    551        
    552         -  ``sort`` - bool (default: True), if True return the
    553            point list sorted. If False, returns the points in the order
    554            computed by Singular.
    555        
     547 
     548        -  ``D`` - a divisor
     549
     550        OUTPUT:
     551
     552        A list of function field elements that form a basis of the Riemann-Roch space
    556553       
    557554        EXAMPLE::
    558555       
    559556            sage: R.<x,y,z> = GF(2)[]
    560557            sage: f = x^3*y + y^3*z + x*z^3
    561558            sage: C = Curve(f); pts = C.rational_points()
    562             sage: D = C.divisor([ (4, pts[0]), (0,pts[1]), (4, pts[2]) ])
     559            sage: D = C.divisor([ (4, pts[0]), (4, pts[2]) ])
    563560            sage: C.riemann_roch_basis(D)
    564561            [x/y, 1, z/y, z^2/y^2, z/x, z^2/(x*y)]
    565562       
    566         The following example illustrates that the Riemann-Roch space
    567         function in Singular doesn't *not* work correctly.
    568        
    569563        ::
    570564       
    571565            sage: R.<x,y,z> = GF(5)[]
    572566            sage: f = x^7 + y^7 + z^7
    573567            sage: C = Curve(f); pts = C.rational_points()
    574568            sage: D = C.divisor([ (3, pts[0]), (-1,pts[1]), (10, pts[5]) ])
    575             sage: C.riemann_roch_basis(D)    # output is random (!!!!)
    576             [x/(y + x), (z + y)/(y + x)]
    577        
    578         The answer has dimension 2 (confirmed via Magma). But it varies
    579         between 1 and quite large with Singular.
     569            sage: C.riemann_roch_basis(D)
     570            [(-2*x + y)/(x + y), (-x + z)/(x + y)]
     571
     572
     573        .. NOTE::
     574            Currently this only works over prime field and divisors supported on rational points.
    580575        """
    581576        f = self.defining_polynomial()._singular_()
    582577        singular = f.parent()
     
    585580            X1 = f.Adj_div()
    586581        except (TypeError, RuntimeError), s:
    587582            raise RuntimeError, str(s) + "\n\n ** Unable to use the Brill-Noether Singular package to compute all points (see above)."
    588 
    589583        X2 = singular.NSplaces(1, X1)
    590         X3 = singular.extcurve(1, X2)
    591         R = X3[1][5]
     584        # retrieve list of all computed closed points (possibly of degree >1)
     585        v = X2[3].sage_flattened_str_list()    # We use sage_flattened_str_list since iterating through
     586                                               # the entire list through the sage/singular interface directly
     587                                               # would involve hundreds of calls to singular, and timing issues with
     588                                               # the expect interface could crop up.  Also, this is vastly
     589                                               # faster (and more robust).
     590        v = [ v[i].partition(',') for i in range(len(v)) ]
     591        pnts = [ ( int(v[i][0]), int(v[i][2])-1 ) for i in range(len(v))]
     592        # retrieve coordinates of rational points
     593        R = X2[5][1][1]
    592594        singular.set_ring(R)
    593 
    594         # We use sage_flattened_str_list since iterating through
    595         # the entire list through the sage/singular interface directly
    596         # would involve hundreds of calls to singular, and timing issues with
    597         # the expect interface could crop up.  Also, this is vastly
    598         # faster (and more robust).
    599595        v = singular('POINTS').sage_flattened_str_list()
    600         pnts = [self(int(v[3*i]), int(v[3*i+1]), int(v[3*i+2])) for i in range(len(v)/3)]
     596        coords = [self(int(v[3*i]), int(v[3*i+1]), int(v[3*i+2])) for i in range(len(v)/3)]
     597        # build correct representation of D for singular
    601598        Dsupport = D.support()
    602599        Dcoeffs = []
    603600        for x in pnts:
    604             Dcoeffs.append(D.coefficient(x))
     601            if x[0] == 1:
     602                Dcoeffs.append(D.coefficient(coords[x[1]]))
     603            else:
     604                Dcoeffs.append(0)
    605605        Dstr = str(tuple(Dcoeffs))
    606606        G = singular(','.join([str(x) for x in Dcoeffs]), type='intvec')
     607        # call singular's brill noether routine and return
    607608        T = X2[1][2]
    608609        T.set_ring()
    609610        LG = G.BrillNoether(X2)