def get_S1xS1_pmz(xyvw_pmz_lst):
    '''
    Attributes
    ----------
    xyvw_pmz_lst: list<sage_POLY>
        A list of bi-homogeneous polynomials in QQ[x,y;v,w] 
        that represent a parametric map P^1xP^1 ---> P^n.
        
    Returns
    -------
    list<sage_POLY>
        Returns a list of polynomials in 
            QQ[c0,s0,s1,c1] / <c0^2+s0^2-1,c1^2+s1^2-1>          
        that represents the composition of the input parametric map
        with a birational map:          
              S^1xS^1       --->       P^1xP^1
        (1:c0:s0)x(1:c1:s1) |--> (1-s0:c0)x(1-s1:c1)            
    '''

    R = sage_PolynomialRing(sage_QQ, 'x,y,v,w')
    x, y, v, w = R.gens()
    xyvw_pmz_lst = sage__eval(str(xyvw_pmz_lst), R.gens_dict())
    c0, s0, c1, s1 = OrbRing.coerce('c0,s0,c1,s1')
    sub_dct = {x: 1 - s0, y: c0, v: 1 - s1, w: c1}
    pmz_lst = [
        OrbRing.coerce(xyvw_pmz.subs(sub_dct)) for xyvw_pmz in xyvw_pmz_lst
    ]

    return pmz_lst
def approx_QQ(mat):
    '''
    Computes a matrix over QQ that approximates the 
    input matrix "mat" over algebraic closure of the rationals QQbar.
    
    Attributes
    ----------
    mat: sage_matrix<QQbar>
        A matrix defined over QQbar.
    
    close_exact: bool 
    
    Returns
    -------
    sage_matrix<QQ>
        An approximation of the iput matrix over QQ.
    '''
    # compute rational approximation of U
    #
    A = []
    for row in list(mat):
        for col in row:

            tmp = sage__eval(str(col).replace('?', ''))
            if tmp in sage_QQ:
                A += [tmp]
            else:
                A += [tmp.simplest_rational()]

    return sage_matrix(sage_QQ, mat.nrows(), mat.ncols(), A)
Example #3
0
    def coerce_ff( self, elt ):
        '''
        Some symbolic methods in sage are not available in the polynomial 
        ring over a number field, but are available in the polynomial ring
        over a fraction field.
        
        INPUT:
            - "elt"  -- String of an symbolic expression 
                        with polynomials in "self.pol_ring".
        OUTPUT:
            - Elements in a polynomial ring R with generators "self.gens()".
              The ground field of R is the fraction field of a polynomial ring 
              whose generators corresponds to the roots in the 
              number field "PolyRing.num_field".
              For example R=FF[x,y,z] where FF=FractionField( QQ[a0,a1,a2,a3] ). 
        '''
        eval_dct = {}

        # construct fraction field FF
        FF = sage_QQ
        if PolyRing.num_field != sage_QQ:
            ngens = PolyRing.num_field.gens_dict().keys()  # (a0,a1,...)
            FF = sage_FractionField( sage_PolynomialRing( sage_QQ, ngens ) )
            eval_dct.update( FF.gens_dict() )

        # construct polynomial ring R over FF
        pgens = self.pol_ring.gens_dict().keys()
        R = sage_PolynomialRing( FF, pgens )
        eval_dct.update( R.gens_dict() )

        # coerce "elt" to R
        return sage__eval( str( elt ), eval_dct )
Example #4
0
 def coerce( self, elt ):
     '''
     INPUT:
         - "elt"  -- A string of a list of polynomials in "self.pol_ring". 
     OUTPUT:
         - Coerces the string "elt" to an element of "self.pol_ring".
     '''
     return sage__eval( str( elt ), self.ring_dct )
Example #5
0
def get_implicit_image(ls):
    '''
    INPUT:
        - "ls" -- LinearSeries object. Elements in "ls.pol_lst"
                  should be homogeneous polynomials over QQ. 
                  These polynomials represent a map F between 
                  projective spaces. We assume that the polynomials 
                  are co-prime.
    OUTPUT
        - A list of polynomials in QQ[x0,...,xn]. 
          These polynomials represent the ideal of the image
          of the map F in projective n-space, where n is 
          "len(ls.pol_lst)-1".
          
          
          This method might not terminate within reasonable time.
    '''

    # QQ[x0,...,xn]
    vx_lst = ['x' + str(i) for i in range(len(ls.pol_lst))]
    ring = sage_PolynomialRing(sage_QQ, vx_lst + list(ls.ring.gens()))
    x_lst = ring.gens()[0:len(vx_lst)]
    v_lst = ring.gens()[len(vx_lst):]

    # coerce "ls.pol_lst""
    p_lst = [sage__eval(str(pol), ring.gens_dict()) for pol in ls.pol_lst]

    # construct ideal
    s_lst = [x_lst[i] - p_lst[i] for i in range(len(p_lst))]
    s_ideal = ring.ideal(s_lst)
    LSTools.p(len(s_lst), s_lst)

    # eliminate all variables except for the xi's
    e_lst = list(s_ideal.elimination_ideal(v_lst).gens())
    LSTools.p(len(e_lst), e_lst)

    # test
    dct = {x_lst[i]: p_lst[i] for i in range(len(p_lst))}
    r_lst = [e.subs(dct) for e in e_lst]
    LSTools.p('test:', sum(r_lst) == 0)

    return e_lst
Example #6
0
def hilbert_poly(X, base=sage_QQ):
    '''
    Computes the Hilbert polynomial of an ideal.
    
    Parameters
    ----------
    X : string(sage_POLY)
        A polynomial in the variables x=(x0,...,xn)
        or y=(y0,...,yn).
    
    base : sage_RING 
        Ground field of polynomials.      
    
    Returns
    -------
    sage_POLY
        Hilbert polynomial of ideal.
    
    '''
    # make sure that the input are strings
    X = str(X)

    # if the input are polynomials in x then the output
    # is a list of poynomials in y
    (vx, vy) = ('x', 'y') if 'x' in X else ('y', 'x')

    # detect the number of x-variables occurring
    n_lst = []
    n = 0
    while n < 50:
        if vx + str(n) in X:
            n_lst += [n]
        n = n + 1
    n = max(n_lst)

    x_lst = [vx + str(i) for i in range(n + 1)]
    ring = sage_PolynomialRing(base, x_lst)
    x_lst = ring.gens()
    dct = ring_dict(ring)
    X = sage__eval(X, dct)

    return sage_ideal(X).hilbert_polynomial()
def get_deg_surf(imp_lst, emb_dim):
    '''
    Attributes
    ----------
    imp_lst: list<sage_POLY>
        A list of polynomials in QQ[x0,...,xn]
        defining a surface where n==emb_dim.
        
    emb_dim: int
        A non-negative integer, representing the embedding dimension. 
    
    Returns
    -------    
        Degree of surface defined by "imp_lst".
    '''

    ring = sage_PolynomialRing(sage_QQ,
                               ['x' + str(i) for i in range(emb_dim + 1)])
    imp_lst = sage__eval(str(imp_lst), ring.gens_dict())
    hpol = ring.ideal(imp_lst).hilbert_polynomial()

    return hpol.diff().diff()
Example #8
0
    def coerce_sr( self, elt ):
        '''
        Some symbolic methods in sage are not available in the 
        polynomial ring over a number field, but are available 
        in the "SymbolicRing" of Sage.
        
        INPUT:
            - "elt"  -- String of expression with 
                        polynomials in "self.pol_ring".
        OUTPUT:
            - Elements in the "SymbolicRing" of Sage. This can be seen
              as a polynomial ring over QQ where generators correspond to
              the roots in "PolyRing.num_field" and "self.gens()".
              For example: QQ[a0,a1,a2,x,y,z]. 
        '''
        # construct dictionary for "sage_eval"
        sym_dct = self.ring_dct.copy()
        for key in sym_dct.keys():
            sym_dct[key] = sage_SR( str( sym_dct[key] ) )  # SR = Symbolic Ring

        # coerce "elt" to symbolic ring
        return sage__eval( str( elt ), sym_dct )
Example #9
0
def usecase__neron_severi_lattice():
    '''
    Compute NS-lattice of a linear series and
    the dimension of complete linear with base points. 
    '''

    # Blowup of projective plane in 3 colinear points
    # and 2 infinitly near points. The image of the
    # map associated to the linear series is a quartic
    # del pezzo surface with 5 families of conics. Moreover
    # the surface contains 8 straight lines.
    #
    ring = PolyRing('x,y,z', True)
    p1 = (-1, 0)
    p2 = (0, 0)
    p3 = (1, 0)
    p4 = (0, 1)
    p5 = (2, 0)
    bp_tree = BasePointTree()
    bp_tree.add('z', p1, 1)
    bp_tree.add('z', p2, 1)
    bp_tree.add('z', p3, 1)
    bp = bp_tree.add('z', p4, 1)
    bp.add('t', p5, 1)
    ls = LinearSeries.get([3], bp_tree)
    LSTools.p('ls     = ', ls)
    LSTools.p(ls.get_bp_tree(), '\n\n   ', ls.get_implicit_image())

    # Detects that 3 base points lie on a line.
    #
    bp_tree = BasePointTree()
    bp_tree.add('z', p1, 1)
    bp_tree.add('z', p2, 1)
    bp_tree.add('z', p3, 1)
    ls123 = LinearSeries.get([1], bp_tree)
    LSTools.p('ls123  =', ls123)
    assert ls123.pol_lst == ring.coerce('[y]')

    # example of infinitly near base points
    # that is colinear with another simple base point.
    #
    bp_tree = BasePointTree()
    bp_tree.add('z', p1, 1)
    bp = bp_tree.add('z', p4, 1)
    bp.add('t', (1, 0), 1)
    ls1 = LinearSeries.get([1], bp_tree)
    LSTools.p('ls1    =', ls1)
    assert ls1.pol_lst == ring.coerce('[x-y+z]')

    # Detects that an infinitly near base points
    # is not colinear with other point.
    #
    for p in [p1, p2, p3]:
        bp_tree = BasePointTree()
        bp = bp_tree.add('z', p4, 1)
        bp.add('t', p5, 1)
        bp_tree.add('z', p, 1)
        ls45i = LinearSeries.get([1], bp_tree)
        assert ls45i.pol_lst == []

    # line with predefined tangent
    #
    bp_tree = BasePointTree()
    bp = bp_tree.add('z', p4, 1)
    bp.add('t', p5, 1)
    ls45 = LinearSeries.get([1], bp_tree)
    LSTools.p('ls45   =', ls45)
    assert ls45.pol_lst == ring.coerce('[x-2*y+2*z]')

    # class of conics through 5 basepoints
    #
    bp_tree = BasePointTree()
    bp_tree.add('z', p1, 1)
    bp_tree.add('z', p2, 1)
    bp_tree.add('z', p3, 1)
    bp = bp_tree.add('z', p4, 1)
    bp.add('t', p5, 1)
    ls1234 = LinearSeries.get([2], bp_tree)
    LSTools.p('ls1234 =', ls1234)
    LSTools.p('\t\t', sage_factor(ls1234.pol_lst[0]))
    assert ring.coerce('(x - 2*y + 2*z, 1)') in ring.aux_gcd(ls1234.pol_lst)[0]
    assert ring.coerce('(y, 1)') in ring.aux_gcd(ls1234.pol_lst)[0]

    # class of conics through 4 basepoints
    # has a fixed component
    #
    bp_tree = BasePointTree()
    bp_tree.add('z', p4, 1)
    ls4 = LinearSeries.get([1], bp_tree)
    LSTools.p('ls4    =', ls4)

    bp_tree = BasePointTree()
    bp_tree.add('z', p1, 1)
    bp_tree.add('z', p2, 1)
    bp_tree.add('z', p3, 1)
    bp_tree.add('z', p4, 1)
    ls1234 = LinearSeries.get([2], bp_tree)
    LSTools.p('ls1234 =', ls1234)

    # return

    # Compose map associated to linear series "ls"
    # with the inverse stereographic projection "Pinv".
    #
    R = sage_PolynomialRing(sage_QQ, 'y0,y1,y2,y3,y4,x,y,z')
    y0, y1, y2, y3, y4, x, y, z = R.gens()
    delta = y1**2 + y2**2 + y3**2 + y4**2
    Pinv = [
        y0**2 + delta, 2 * y0 * y1, 2 * y0 * y2, 2 * y0 * y3, 2 * y0 * y4,
        -y0**2 + delta
    ]
    H = sage__eval(str(ls.pol_lst), R.gens_dict())
    PinvH = [
        elt.subs({
            y0: H[0],
            y1: H[1],
            y2: H[2],
            y3: H[3],
            y4: H[4]
        }) for elt in Pinv
    ]
    LSTools.p('Pinv        =', Pinv)
    LSTools.p('H           =', H)
    LSTools.p('Pinv o H    =', PinvH)

    # In order to compute the NS-lattice of the image
    # of "PinvH" we do a base point analysis.
    #
    ls_PinvH = LinearSeries([str(elt) for elt in PinvH], ring)
    LSTools.p('ls_PinvH    =', ls_PinvH)
    LSTools.p('\t\t', ls_PinvH.get_implicit_image())

    if False:  # takes a long time
        LSTools.p(ls_PinvH.get_bp_tree())
Example #10
0
def get_linear_series(deg_lst, bp_tree):
    '''
    INPUT:
        - "deg_lst" -- A list of either one or two integers representing the degree of polynomials.
        - "bp_tree" -- BasePointTree where base points might be in 
                       overlapping charts.
                       We require that "bp_tree.chart_lst" equals either 
                       ['z', 'x', 'y'] or ['xv', 'xw', 'yv', 'yw'].                       
    OUTPUT:
        - Return A LinearSeries "ls" with base points defined by "bp_tree".
          The polynomials in "ls.pol_lst" are either 
                  * homogeneous in (x:y:z) and of degree "deg_tup[0]" or          
                  * bi-homogenous in (x:y)(v:w) and of bi-degree ("deg_tup[0]","deg_tup[1]")
          Note that there might unassigned base points. 
    '''

    #
    # Obtain generators of polynomial ring from "bp_tree.chart_lst"
    # Note that for initializing PolyRing, it is important that the
    # base field is not reset to the rationals QQ. The input "bp_tree"
    # could already be defined over some extension field.
    #
    if bp_tree.chart_lst == ['z', 'x', 'y']:
        ring = PolyRing('x,y,z', False)
    elif bp_tree.chart_lst == ['xv', 'xw', 'yv', 'yw']:
        ring = PolyRing('x,y,v,w', False)
    else:
        raise ValueError('Expect "bp_tree.chart_lst" in ',
                         (['z', 'x', 'y'], ['xv', 'xw', 'yv', 'yw']))

    #
    # Obtain linear series defined by
    # monomials of degree "deg_lst[0]" or bidegree ("deg_lst[0]","deg_lst[1]").
    #
    mon_lst = get_mon_lst(deg_lst, ring.gens())
    LSTools.p('mon_lst =', mon_lst)
    ls = class_linear_series.LinearSeries(mon_lst, ring)

    #
    # For each chart "c" we obtain a list of linear series.
    #
    ls_lst = []
    for c in bp_tree.chart_lst:
        ls_lst += get_ls_lst(ls.copy().chart(c), bp_tree[c])

    #
    # Create matrix whose coefficients are obtained
    # by evaluating each polynomial in linear series
    # in "ls_lst" at (0,0).
    #
    row_lst = []
    for ls in ls_lst:
        LSTools.p(ls)
        for g in ls.ring.gens():
            ls.subs({g: 0})
        row = sage__eval(str(ls.pol_lst), PolyRing.num_field.gens_dict())
        row_lst += [row]
    LSTools.p('matrix =', row_lst)

    #
    # Compute kernel.
    #
    kern = list(sage_matrix(row_lst).right_kernel().matrix())
    LSTools.p('kernel =', kern)
    LSTools.p(mon_lst)

    #
    # Obtain linear series from linear conditions on "mon_lst".
    #
    if kern != []:
        mon_lst = ring.coerce(mon_lst)  # update w.r.t. PolyRing.num_field
        kern = ring.coerce(kern)
        pol_lst = sage_matrix(kern) * sage_vector(mon_lst)
    else:
        pol_lst = []

    LSTools.p(pol_lst)

    return class_linear_series.LinearSeries(pol_lst, ring)
Example #11
0
def invert_map(f, X, base=sage_QQ):
    '''
    Computes the inverse of a map defined by polynomials.
    
    If the parameters f and X are not strings, then
    they are automatically converted to strings.
    
    Parameters
    ----------
    f : string(list<sage_POLY>)
        A string of a list of m+1 polynomials in 
        x=(x0,...,xn) or y=(y0,...,yn) with n<=50 that
        define a projective map:
        F: X ---> P^m
        where P^m denotes projective n-space.

    X : string(list<sage_POLY>)
        A string of a list of polynomials in 
        the same variables as parameter f that 
        define the ideal of a variety X in 
        projective space.
    
    base : sage_RING 
        Ground field of polynomials.           
              
    Returns
    -------
    list<sage_POLY>
            Suppose that the input were polynomials in x.
        The output is of the form
            [ p0(x)-r0(y) ,..., pn(x)-rn(y) ]
        were ri(y) are rational functions and pi(x) are
        polynomials. If f is a birational map, then pi(x)=xi.
        The polynomials live in the polynomial ring R[x]
        where R=B(y) and base ring B is defined by the base
        parameter.  
    '''
    # make sure that the input are strings
    f = str(f)
    X = str(X)

    # if the input are polynomials in x then the output
    # is a list of poynomials in y
    (vx, vy) = ('x', 'y') if 'x' in f else ('y', 'x')

    # detect the number of x-variables occurring
    n_lst = []
    n = 0
    while n < 50:
        if vx + str(n) in f or vx + str(n) in X:
            n_lst += [n]
        n = n + 1
    n = max(n_lst)

    # construct ring B(y0,...ym)[x0,...,xn]
    # over fraction field B(y0,...ym)
    # where m is the number of elements in map f and B equals base
    #
    # For example B is rationals sage_QQ so that:
    # xring  = sage_PolynomialRing( sage_QQ, 'x0,x1,x2,x3,x4')
    # yfield = sage_FractionField( sage_PolynomialRing( sage_QQ, 'y0,y1,y2,y3' ) )
    # ring   = sage_PolynomialRing( yfield, 'x0,x1,x2,x3,x4')
    #
    x_lst = [vx + str(i) for i in range(n + 1)]
    y_lst = [vy + str(i) for i in range(len(f.split(',')))]
    yfield = sage_FractionField(sage_PolynomialRing(base, y_lst))
    ring = sage_PolynomialRing(yfield, x_lst)
    y_lst = yfield.gens()
    x_lst = ring.gens()

    dct = ring_dict(ring)
    X = sage__eval(X, dct)
    f = sage__eval(f, dct)
    map = [y_lst[i] - f[i] for i in range(len(f))]
    gb_lst = list(sage_ideal(X + map).groebner_basis())

    OrbTools.p(gb_lst)

    return gb_lst
Example #12
0
def euclidean_type_form(X, base=sage_QQ):
    '''
    Outputs the equation of a hypersurface in P^n in a form 
    so that the intersection with the hyperplane at infinity
    becomes apparent. 
    
    Parameters
    ----------
    X : string(sage_POLY)
        A polynomial in the variables x=(x0,...,xn)
        or y=(y0,...,yn).
    
    base : sage_RING 
        Ground field of polynomials.      
    
    Returns
    -------
    string
        A string of the equations in the normal form
            X1 + X2
        where
            X1 = sage_factor( X.subs({x0:0}) )
            X2 = sage_factor( X-X1 )
        If #variables is equal to 3, then
        also include the form in x,y and z variables.
    '''
    # make sure that the input are strings
    X = str(X)

    # if the input are polynomials in x then the output
    # is a list of poynomials in y
    (vx, vy) = ('x', 'y') if 'x' in X else ('y', 'x')

    # detect the number of x-variables occurring
    n_lst = []
    n = 0
    while n < 50:
        if vx + str(n) in X:
            n_lst += [n]
        n = n + 1
    n = max(n_lst)

    x_lst = [vx + str(i) for i in range(n + 1)]
    ring = sage_PolynomialRing(base, x_lst)
    x_lst = ring.gens()
    dct = ring_dict(ring)
    X = sage__eval(X, dct)
    XA = sage_factor(X.subs({x_lst[0]: 0}))
    XB = sage_factor(X - XA)
    assert X == XA + XB
    OrbTools.p('X =', XA, '+', XB)
    out = str(XA) + ' + ' + str(XB)

    if n == 3:
        x0, x1, x2, x3 = ring.gens()
        x, y, z = sage_var('x,y,z')
        W = X.subs({x1: x, x2: y, x3: z})
        WA = W.subs({x0: 0})
        WB = W - WA
        assert W == WA + WB
        WA = sage_factor(WA.subs({x0: 1}))
        WB = sage_factor(WB.subs({x0: 1}))
        OrbTools.p('W =', WA, '+', WB)
        out += '\n' + str(WA) + ' + ' + str(WB)

    return out
Example #13
0
def compose_maps(g, f, base=sage_QQ):
    '''
    Computes the composition of polynomial maps.
    
    Both parameters and return value are all polynomials 
    in either x=(x0,...,xn) or y=(y0,...,yn) with n<=50,
    but not both.
    
    The input parameters are explicitly converted to 
    strings, in case they are not strings.
    
    Parameters
    ----------
    f : string(list<sage_POLY>)
        A string of a list of b+1 polynomials that
        defines a projective map:
        f: P^a ---> P^b
        where P^a denotes projective n-space.    
        If the value is not a string, then it will
        be converted to a string.
    
    g : string(list<sage_POLY>)
        A string of a list of c+1 polynomials that
        defines a projective map: g: P^b ---> P^c.   
        If the value is not a string, then it will
        be converted to a string.         
    
    base : sage_RING 
        Ground field of polynomials.       
    
    Returns
    -------
    list<sage_POLY>
        The composition of the maps f o g: P^a ---> P^c.    
    '''
    # make sure that the input are strings
    g = str(g)
    f = str(f)

    # check variables
    (vf, vg) = ('x', 'y') if 'x' in f else ('y', 'x')
    if vg not in g:
        g = g.replace(vf, vg)

    # detect the number of vf-variables occurring
    n_lst = []
    n = 0
    while n < 50:
        if vf + str(n) in f or vg + str(n) in g:
            n_lst += [n]
        n = n + 1
    n = max(n_lst)

    # construct the ring
    v_lst = []
    v_lst += [vf + str(i) for i in range(n + 1)]
    v_lst += [vg + str(i) for i in range(n + 1)]
    ring = sage_PolynomialRing(base, v_lst)
    vg_lst = ring.gens()[n + 1:]
    dct = ring_dict(ring)
    g_lst = sage__eval(g, dct)
    f_lst = sage__eval(f, dct)

    # compose the maps
    for i in range(len(f_lst)):
        g_lst = [g.subs({vg_lst[i]: f_lst[i]}) for g in g_lst]

    OrbTools.p(g_lst)

    return g_lst
Example #14
0
def preimage_map(f, X, Y, base=sage_QQ):
    '''
    Computes the preimage f^{-1}(Y) of a variety Y under a map 
    f: X ---> P^m, defined by polynomials, where the domain 
    X is a variety and P^m denotes projective space.
    
    If the parameters f, X and Y are not strings, then
    they are automatically converted to strings.
    
    Parameters
    ----------
    f : string(list<sage_POLY>)
        A string of a list of m+1 polynomials in 
        x=(x0,...,xn) or y=(y0,...,yn) with n<=50 that
        define a projective map:
        f: X ---> P^m
        where P^m denotes projective n-space.

    X : string(list<sage_POLY>)
        A string of a list of polynomials in 
        the same variables as parameter f that 
        define the ideal of a variety X in 
        projective space.

    Y : string(list<sage_POLY>)
        A string of a list of polynomials in y if
        f consists of polynomials in x (and vice versa). 
        Polynomials define the generators of an ideal of 
        a variety Y in projective space.
    
    base : sage_RING 
        Ground field of polynomials.     
        
    Returns
    -------
    list(list<sage_POLY>)
        A list of lists of polynomials. Each list of polynomials
        defines a component in the primary decomposition of the ideal 
        of the preimage f^{-1}(Y). 
        The polynomials are in x or y if parameter f represents 
        polynomials in x respectively y.
        Note that some of the components in the primary decomposition
        are not part of the ideal, but correspond to the locus 
        where the map f is not defined.             
    '''
    # make sure that the input are strings
    f = str(f)
    X = str(X)
    Y = str(Y)

    # if the input are polynomials in x then the output
    # is a list of poynomials in y
    (vx, vy) = ('x', 'y') if 'x' in f else ('y', 'x')

    # detect the number of x-variables occurring
    n_lst = []
    n = 0
    while n < 50:
        if vx + str(n) in f or vx + str(n) in X:
            n_lst += [n]
        n = n + 1
    n = max(n_lst)

    # construct polynomial ring B[x0,...,xn,y0,...,ym]
    # where B is given by parameter base.
    x_lst = [vx + str(i) for i in range(n + 1)]
    y_lst = [vy + str(i) for i in range(len(f.split(',')))]
    mord = 'degrevlex' if base == sage_QQ else 'lex'  # needed for elimination
    xyring = sage_PolynomialRing(base, y_lst + x_lst, order=mord)
    y_lst = xyring.gens()[:len(y_lst)]
    x_lst = xyring.gens()[len(y_lst):]

    # coerce into common ring with xi and yi variables
    dct = ring_dict(xyring)
    f_lst = sage__eval(f, dct)
    X_lst = sage__eval(X, dct)
    Y_lst = sage__eval(Y, dct)
    mf_lst = [y_lst[i] - f_lst[i] for i in range(len(f_lst))]

    # compute image by using groebner basis
    OrbTools.p(X_lst + mf_lst + Y_lst)
    try:

        img_id = sage_ideal(X_lst + mf_lst + Y_lst).elimination_ideal(y_lst)
        img_lst = img_id.primary_decomposition()
        img_lst = [img.gens() for img in img_lst]
        OrbTools.p(img_lst)
        return img_lst

    except Exception, e:

        OrbTools.p('Exception occurred:', repr(e))
        gb_lst = sage_ideal(X_lst + mf_lst + Y_lst).groebner_basis()
        OrbTools.p(gb_lst)
        e_lst = []
        for gb in gb_lst:
            if vy not in str(gb):
                e_lst += [gb]
        return e_lst
Example #15
0
def image_map(f, X, base=sage_QQ):
    '''
    Computes the image f(X) of a variety X
    under a map f, defined by polynomials.
    
    If the parameters f and X are not strings, then
    they are automatically converted to strings.
    
    Parameters
    ----------
    f : string(list<sage_POLY>)
        A string of a list of m+1 polynomials in 
        x=(x0,...,xn) or y=(y0,...,yn) with n<=50 that
        define a projective map:
        f: X ---> P^m
        where P^m denotes projective n-space.

    X : string(list<sage_POLY>)
        A string of a list of polynomials in 
        the same variables as parameter f that 
        define the ideal of a variety X in 
        projective space.
    
    base : sage_RING 
        Ground field of polynomials. 
        
    Returns
    -------
    list<sage_POLY>
        A list of polynomials that define the
        ideal of f(X). The polynomials are in y
        if the input are polynomials in x, and
        vice versa.            
    '''
    # make sure that the input are strings
    f = str(f)
    X = str(X)

    # if the input are polynomials in x then the output
    # is a list of poynomials in y
    (vx, vy) = ('x', 'y') if 'x' in f else ('y', 'x')

    # detect the number of x-variables occurring
    n_lst = []
    n = 0
    while n < 50:
        if vx + str(n) in f or vx + str(n) in X:
            n_lst += [n]
        n = n + 1
    n = max(n_lst)

    # construct polynomial ring B[x0,...,xn,y0,...,ym]
    # where B is given by parameter base.
    x_lst = [vx + str(i) for i in range(n + 1)]
    y_lst = [vy + str(i) for i in range(len(f.split(',')))]
    mord = 'degrevlex' if base == sage_QQ else 'lexdeg'  # needed for elimination
    xyring = sage_PolynomialRing(base, x_lst + y_lst, mord)
    x_lst = xyring.gens()[:len(x_lst)]
    y_lst = xyring.gens()[len(x_lst):]

    # coerce into common ring with xi and yi variables
    dct = ring_dict(xyring)
    f_lst = sage__eval(f, dct)
    X_lst = sage__eval(X, dct)
    mf_lst = [y_lst[i] - f_lst[i] for i in range(len(f_lst))]

    # compute image by using groebner basis
    OrbTools.p(X_lst + mf_lst)
    try:

        # compute image by using groebner basis
        img_lst = sage_ideal(X_lst + mf_lst).elimination_ideal(x_lst).gens()
        OrbTools.p(img_lst)
        return img_lst

    except Exception, e:

        OrbTools.p('Exception occurred:', repr(e))
        gb_lst = sage_ideal(X_lst + mf_lst).groebner_basis()
        OrbTools.p(gb_lst)
        e_lst = []
        for gb in gb_lst:
            if vx not in str(gb):
                e_lst += [gb]
        return e_lst
Example #16
0
def usecase__linear_normalization__and__adjoint():
    '''
    In this usecase are some applications of the 
    "linear_series" library.  we show by example 
    how to compute a linear normalization X of a surface Y, 
    or equivalently, how to compute the completion of a 
    linear series. Also we contruct an example of a surface Z 
    such that X is its adjoint surface.     
    '''
    #
    # Linear series corresponding to the parametrization
    # of a cubic surface X in P^4 that is the projection
    # of the Veronese embedding of P^2 into P^5.
    #
    ring = PolyRing('x,y,z', True)
    bp_tree = BasePointTree()
    bp = bp_tree.add('z', (0, 0), 1)
    ls = LinearSeries.get([2], bp_tree)
    imp_lst = ls.get_implicit_image()
    LSTools.p('linear series      =', ls.get_bp_tree())
    LSTools.p('implicit image     =', imp_lst)

    #
    # compute Hilbert polynomial of X in QQ[x0,...,x6]
    #
    R = sage_PolynomialRing(sage_QQ,
                            ['x' + str(i) for i in range(len(ls.pol_lst))])
    x_lst = R.gens()
    imp_lst = sage__eval(str(imp_lst), R.gens_dict())
    hpol = R.ideal(imp_lst).hilbert_polynomial()
    hdeg = hpol.diff().diff()
    LSTools.p('Hilbert polynomial =', hpol)
    LSTools.p('implicit degree    =', hdeg)

    #
    # projection of X in P^4 to Y in P^3, where Y is singular.
    #
    ls = LinearSeries(['x^2-x*y', 'x*z', 'y^2', 'y*z'],
                      PolyRing('x,y,z', True))
    bp_tree = ls.get_bp_tree()
    LSTools.p('basepoint tree of projection =', bp_tree)
    eqn = ls.get_implicit_image()
    assert len(eqn) == 1
    eqn = sage_SR(eqn[0])
    x0, x1, x2, x3 = sage_var('x0,x1,x2,x3')
    LSTools.p('eqn       =', eqn)
    LSTools.p('D(eqn,x0) =', sage_diff(eqn, x0))
    LSTools.p('D(eqn,x1) =', sage_diff(eqn, x1))
    LSTools.p('D(eqn,x2) =', sage_diff(eqn, x2))
    LSTools.p('D(eqn,x3) =', sage_diff(eqn, x3))

    #
    # compute normalization X of Y
    #
    ls_norm = LinearSeries.get([2], bp_tree)
    LSTools.p('normalization = ', ls_norm)
    LSTools.p('              = ', ls_norm.get_implicit_image())

    #
    # define pre-adjoint surface Z
    #
    ring = PolyRing('x,y,z', True)
    bp_tree = BasePointTree()
    bp_tree.add('z', (0, 0), 2)
    bp_tree.add('z', (0, 1), 1)
    ls = LinearSeries.get([5], bp_tree)
    LSTools.p(ls.get_bp_tree())
Example #17
0
def get_implicit_projection(ls, deg):
    '''
    This function does not work properly, since the output polynomial still contains
    undeterminate variables. These need to be solved.
    
    INPUT:
        - "ls"  -- LinearSeries s.t. "ls.pol_lst" consist of polynomials in x,y,z 
                   and of the same degree. Note that the polynomials in "ls.pol_lst"
                   define a birational map from the projective plane to a surface S in
                   projective n-space where n equals "len(ls.pol_lst)-1".
        - "deg" -- An integer representing the degree of the parametrized surface S.
    OUTPUT:
        - A polynomial F(x0:x1:x2:x3) of degree at most "deg" and 
          undetermined coefficients in (r0,r1,...). 
          The ".parent()" of the polynomial is "SymbolicRing".
          The zero-set V(F) is a projection of the surface S by the map
          (x0:x1:...:xn) |-> (x0:x1:x2:x3) 
    '''
    p0, p1, p2, p3 = ls.pol_lst[0:4]

    # construct a polynomial ring
    c_len = len(sage_Compositions(deg + 4, length=4).list())
    c_str_lst = ['c' + str(i) for i in range(c_len)]

    R = sage_PolynomialRing(PolyRing.num_field, ['x0', 'x1', 'x2', 'x3'] +
                            c_str_lst + ['x', 'y', 'z'],
                            order='lex')
    x0, x1, x2, x3 = R.gens()[0:4]
    c_lst = R.gens()[4:4 + c_len]
    x, y, z = R.gens()[4 + c_len:]
    m_lst = []
    for a, b, c, d in sage_Compositions(deg + 4, length=4):
        m_lst += [x0**(a - 1) * x1**(b - 1) * x2**(c - 1) * x3**(d - 1)]

    R_dict = R.gens_dict()
    R_dict.update(PolyRing.num_field.gens_dict())

    p0, p1, p2, p3 = sage__eval(str([p0, p1, p2, p3]), R_dict)

    LSTools.p(R)
    LSTools.p('m_lst =', m_lst)
    LSTools.p('(p0, p1, p2, p3) =', (p0, p1, p2, p3))

    # construct polynomial in x0, x1, x2 with coefficients in c_lst
    F = 0
    for i in range(len(m_lst)):
        F += c_lst[i] * m_lst[i]
    LSTools.p('F =', F)

    # compute F( p0(x,y,z):...: p3(x,y,z) )
    FP = sage_expand(F.subs({
        x0: p0,
        x1: p1,
        x2: p2,
        x3: p3
    }))  # expand to prevent a bug in sage.
    LSTools.p('FP =', FP)

    # obtain coefficients w.r.t. x, y and z
    coef_lst = []
    pmzdeg = p0.total_degree()
    comp_lst = sage_Compositions(deg * pmzdeg + 3,
                                 length=3).list()  # e.g. [1,1,2]=[0,0,1]
    LSTools.p('comp_lst =', comp_lst)
    for comp in comp_lst:
        coef = FP.coefficient({x: comp[0] - 1, y: comp[1] - 1, z: comp[2] - 1})
        coef_lst += [coef]
    LSTools.p('coef_lst =', coef_lst)

    # compute groebner basis and reduce F w.r.t. the GB
    #
    # alternative code
    # ----------------
    # GB = list( R.ideal( coef_lst ).groebner_basis() )
    # LSTools.p( 'GB =', GB )
    # red_F = F.reduce( R.ideal( GB ) )
    # for g in GB:
    #    red_F = red_F.quo_rem( g )[1]
    # LSTools.p( 'red_F =', red_F )
    # ----------------
    #
    scoef_lst = [sage_SR(coef) for coef in coef_lst]
    sc_lst = [sage_SR(c) for c in c_lst]
    sol_lst = sage_solve(scoef_lst, sc_lst, solution_dict=True)
    LSTools.p(sol_lst)
    red_F = sage_expand(sage_SR(F).subs(sol_lst[0]))
    LSTools.p('red_F =', red_F)

    # check the solutions
    sp0, sp1, sp2, sp3 = sage_SR(p0), sage_SR(p1), sage_SR(p2), sage_SR(p3)
    sx0, sx1, sx2, sx3 = sage_SR(x0), sage_SR(x1), sage_SR(x2), sage_SR(x3)
    chk_F = sage_expand(red_F.subs({sx0: sp0, sx1: sp1, sx2: sp2, sx3: sp3}))
    LSTools.p('chk_F =', chk_F)
    if chk_F != 0:
        warnings.warn('The polynomial red_F(p0:p1:p2:p3) does not vanish.')

    return red_F
Example #18
0
 def coerce(expr):
     return sage__eval(str(expr), OrbRing.R.gens_dict())
Example #19
0
def usecase__get_implicit__DP6():
    '''
    Construct linear series of curves in P^1xP^1, 
    with a given tree of (infinitely near) base points.
    The defining polynomials of this linear series, correspond to a parametric map
    of an anticanonical model of a Del Pezzo surface of degree 6 in P^6.
    Its ideal is generated by quadratic forms. We search for a quadratic form in
    this ideal of signature (1,6). This quadratic form corresponds to a hyperquadric 
    in P^6, such that the sextic Del Pezzo surface is contained in this hyperquadric.         
    We construct a real projective isomorphism from this hyperquadric to the projectivization
    of the unit 5-sphere in P^6. 
    '''

    #
    # parametrization of degree 6 del Pezzo surface in projective 6-space.
    # See ".usecase__get_linear_series__P1P1_DP6()" for the construction of
    # this linear series.
    #
    pmz_lst = [
        'x^2*v^2 - y^2*w^2', 'x^2*v*w + y^2*v*w', 'x^2*w^2 + y^2*w^2',
        'x*y*v^2 - y^2*v*w', 'x*y*v*w - y^2*w^2', 'y^2*v*w + x*y*w^2',
        'y^2*v^2 + y^2*w^2'
    ]
    ls = LinearSeries(pmz_lst, PolyRing('x,y,v,w', True))

    #
    # base points of linear series
    #
    bp_tree = ls.get_bp_tree()
    LSTools.p('parametrization    =', ls.pol_lst)
    LSTools.p('base points        =' + str(bp_tree))

    #
    # implicit image in projective 6-space
    # of map associated to linear series
    #
    imp_lst = ls.get_implicit_image()
    LSTools.p('implicit equations =', imp_lst)

    #
    # compute Hilbert polynomial in QQ[x0,...,x6]
    #
    ring = sage_PolynomialRing(sage_QQ, ['x' + str(i) for i in range(7)])
    x_lst = ring.gens()
    imp_lst = sage__eval(str(imp_lst), ring.gens_dict())
    hpol = ring.ideal(imp_lst).hilbert_polynomial()
    hdeg = hpol.diff().diff()
    LSTools.p('Hilbert polynomial =', hpol)
    LSTools.p('implicit degree    =', hdeg)

    #
    # equation of unit sphere is not in the ideal
    #
    s_pol = sum([-x_lst[0]**2] + [x**2 for x in x_lst[1:]])
    LSTools.p('Inside sphere?: ', s_pol in ring.ideal(imp_lst))

    #
    # compute random quadrics containing del Pezzo surface
    # until a quadric with signature (1,6) is found
    # or set a precomputed quadric with given "c_lst"
    #
    LSTools.p(
        'Look for quadric in ideal of signature (1,6)...(may take a while)...')
    sig = []
    while sorted(sig) != [0, 1, 6]:

        # set coefficient list
        c_lst = []
        c_lst = [-1, -1, 0, 0, 0, -1, 1, 0, -1, -1,
                 -1]  # uncomment to speed up execution
        if c_lst == []:
            lst = [-1, 0, 1]
            for imp in imp_lst:
                idx = int(sage_ZZ.random_element(0, len(lst)))
                c_lst += [lst[idx]]

        # obtain quadric in ideal from "c_lst"
        i_lst = range(len(imp_lst))
        M_pol = [
            c_lst[i] * imp_lst[i] for i in i_lst
            if imp_lst[i].total_degree() == 2
        ]
        M_pol = sum(M_pol)

        # eigendecomposition
        M = sage_invariant_theory.quadratic_form(
            M_pol, x_lst).as_QuadraticForm().matrix()
        M = sage_matrix(sage_QQ, M)
        vx = sage_vector(x_lst)
        D, V = M.eigenmatrix_right()

        # determine signature of quadric
        num_pos = len([d for d in D.diagonal() if d > 0])
        num_neg = len([d for d in D.diagonal() if d < 0])
        num_zer = len([d for d in D.diagonal() if d == 0])
        sig = [num_pos, num_neg, num_zer]
        LSTools.p('\t sig =', sig, c_lst)

    #
    # output of M.eigenmatrix_right() ensures that
    # D has signature either (--- --- +) or (- +++ +++)
    #
    if num_pos < num_neg:  # (--- --- +) ---> (+ --- ---)
        V.swap_columns(0, 6)
        D.swap_columns(0, 6)
        D.swap_rows(0, 6)

    #
    # diagonal orthonormalization
    # note: M == W.T*D*W == W.T*L.T*J*L*W = U.T*J*U
    #
    W = sage_matrix([col / col.norm() for col in V.columns()])
    J = []
    for d in D.diagonal():
        if d > 0:
            J += [1]
        elif d < 0:
            J += [-1]
    J = sage_diagonal_matrix(J)
    L = sage_diagonal_matrix([d.abs().sqrt() for d in D.diagonal()])
    U = L * W

    #
    # Do some tests
    #
    assert M_pol in ring.ideal(imp_lst)
    assert vx * M * vx == M_pol
    assert M * V == V * D

    #
    # output values
    #
    LSTools.p('quadratic form of signature (1,6) in ideal =', M_pol)
    LSTools.p('matrix M associated to quadratic form      =', list(M))
    LSTools.p('M == U.T*J*U                               =',
              list(U.T * J * U))
    LSTools.p('U                                          =', list(U))
    LSTools.p('J                                          =', list(J))