def get_bp_lst_chart(ls, chart, depth=0): ''' INPUT: - "ls" -- LinearSeries. - "chart" -- A String representing the current chart of linear series "ls". - "depth" -- Integer representing the recursive depth of this function call. OUTPUT: - Returns a list of BasePoint objects representing base points of linear series "ls". ''' LSTools.p('input =', (depth, chart, str(ls))) nls = ls.copy() if chart == 's': nls.pol_lst = [nls.ring.gens()[0]] + nls.pol_lst elif chart == 't': nls.pol_lst = [nls.ring.gens()[1]] + nls.pol_lst sol_lst = nls.get_solution_set() bp_lst = [] # if no solutions, add empty base point with BasePoint.mult=0. if sol_lst == []: bp_lst += [BasePoint(depth, chart, ls)] for sol in sol_lst: bp = BasePoint(depth, chart, ls) bp.sol = sol if in_previous_chart(sol, chart): bp.mult = -1 # this indicates that base point was already considered. else: ls_t, bp.mult = ls.copy().translate_to_origin(sol).blow_up_origin( 't') bp.bp_lst_t = get_bp_lst_chart(ls_t, 't', depth + 1) ls_s, mult_s = ls.copy().translate_to_origin(sol).blow_up_origin( 's') bp.bp_lst_s = get_bp_lst_chart(ls_s, 's', depth + 1) if bp.mult != mult_s: raise Exception( 'Unexpected multiplicities: (bp.mult, mult_s) =', (bp.mult, mult_s)) bp_lst += [bp] return bp_lst
def get_ls_lst(ls, bp_lst): ''' Helper for "get_linear_series" method. ''' ind_str = None ls_lst = [] for bp in bp_lst: if ind_str == None: ind_str = bp.depth * '\t' LSTools.p(ind_str + 'input = len( bp_lst ):' + str(len(bp_lst)) + ',' + str(ls)) # base points which do not have multiplicity at least # can be ignored # if bp.mult <= 0: continue LSTools.p('basepoint = ' + str(bp)[1:].replace('\n', '\n' + ind_str)) # translate the base point to the origin # nls = ls.copy().translate_to_origin(bp.sol) LSTools.p(ind_str + 'translated =', nls) # # Loop through (a,b) s.t. # (a-1)+(b-1)=bp.mult-1 and (a-1)>=(b-1)>=0 # for m in range(1, bp.mult + 1): for a, b in sage_Compositions(m - 1 + 2, length=2): ls_lst += [nls.copy().diff(a - 1, b - 1)] LSTools.p(ind_str + str(a - 1) + ',' + str(b - 1) + ',' + str(ls_lst[-1])) # # Continue recursively. # u, v = nls.gens() ls_lst += get_ls_lst(nls.copy().subs({ u: u * v }).quo(v**bp.mult), bp.bp_lst_t) ls_lst += get_ls_lst(nls.copy().subs({ v: v * u }).quo(u**bp.mult), bp.bp_lst_s) if ind_str != None: LSTools.p(ind_str + 'output =', [str(ls) for ls in ls_lst]) return ls_lst
def usecase__get_linear_series__P2(): ''' Construct linear series of curves in the plane P^2, with a given tree of (infinitely near) base points. ''' # Example from PhD thesis (page 159). PolyRing.reset_base_field() bp_tree = BasePointTree() bp = bp_tree.add('z', (0, 0), 1) bp = bp.add('t', (0, 0), 1) bp = bp.add('t', (-1, 0), 1) bp = bp.add('t', (0, 0), 1) LSTools.p(bp_tree) ls = LinearSeries.get([2], bp_tree) LSTools.p(ls.get_bp_tree())
def factor( self, pol ): ''' INPUT: - "pol" -- A univariate polynomial in "self.pol_ring". OUTPUT - A list of factors of "pol" in "PolyRing.pol_ring": [ ( <polynomial-factor>, <multiplicity> ), ... ] If "pol" is a constant then the empty list is returned. ''' LSTools.p( 'factoring ', pol, ' in ', self ) if pol in self.get_num_field(): return [] else: fct_lst = sage_factor( pol ) LSTools.p( '\t', fct_lst ) return fct_lst
def usecase__get_base_points__P2(): ''' We obtain (infinitely near) base points of a linear series defined over a number field. ''' ring = PolyRing('x,y,z', True) ring.ext_num_field('t^2 + 1') ring.ext_num_field('t^3 + a0') a0, a1 = ring.root_gens() x, y, z = ring.gens() pol_lst = [x**2 + a0 * y * z, y + a1 * z + x] ls = LinearSeries(pol_lst, ring) LSTools.p(ls) bp_tree = ls.get_bp_tree() LSTools.p(bp_tree)
def usecase__get_base_points__P1P1(): ''' We obtain (infinitely near) base points of a linear series defined by bi-homogeneous polynomials. Such polynomials are defined on P^1xP^1 (the fiber product of the projective line with itself). The coordinate functions of P^1xP^1 are (x:y)(v:w). ''' pol_lst = [ '17/5*v^2*x^2 + 6/5*v*w*x^2 + w^2*x^2 + 17/5*v^2*y^2 + 6/5*v*w*y^2 + w^2*y^2', '6/5*v^2*x^2 + 8/5*v*w*x^2 + 6/5*v^2*y^2 + 8/5*v*w*y^2', '7/5*v^2*x^2 + 6/5*v*w*x^2 + w^2*x^2 + 7/5*v^2*y^2 + 6/5*v*w*y^2 + w^2*y^2', '4*v^2*x*y', '-2*v^2*x^2 + 2*v^2*y^2', '2/5*v^2*x^2 + 6/5*v*w*x^2 - 4*v^2*x*y - 2/5*v^2*y^2 - 6/5*v*w*y^2', '2*v^2*x^2 + 4/5*v^2*x*y + 12/5*v*w*x*y - 2*v^2*y^2' ] ls = LinearSeries(pol_lst, PolyRing('x,y,v,w')) LSTools.p(ls) bp_tree = ls.get_bp_tree() LSTools.p(bp_tree)
def usecase__get_base_points__and__get_linear_series(): ''' We obtain (infinitely near) base points of a linear series defined over QQ. The base points are defined over a number field. ''' ring = PolyRing('x,y,z', True) ls = LinearSeries(['x^2+y^2', 'y^2+x*z'], ring) bp_tree = ls.get_bp_tree() LSTools.p(bp_tree) ls = LinearSeries.get([2], bp_tree) LSTools.p(ls) LSTools.p(ls.get_bp_tree())
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
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()) if __name__ == '__main__': ################################################ # # # Configuration of LSTools for debug output # # # ################################################ LSTools.start_timer() mod_lst = [] mod_lst += ['__main__.py'] # mod_lst += ['get_linear_series.py'] # mod_lst += ['get_solution_set.py'] LSTools.filter(mod_lst) # output only from specified modules # LSTools.filter( None ) # uncomment for showing all debug output ################################################ # # # End of configuration of LSTools # # # ################################################ ################################################ # #
def usecase__get_linear_series__P1P1_DP6(): ''' Construct linear series of curves in P^1xP^1, with a given tree of (infinitely near) base points. ''' # construct ring over Gaussian rationals # ring = PolyRing('x,y,v,w', True) ring.ext_num_field('t^2 + 1') a0 = ring.root_gens()[0] # setup base point tree for 2 simple complex conjugate base points. # bp_tree = BasePointTree(['xv', 'xw', 'yv', 'yw']) bp = bp_tree.add('xv', (-a0, a0), 1) bp = bp_tree.add('xv', (a0, -a0), 1) LSTools.p( 'We consider linear series of curves in P^1xP^1 with the following base point tree:' ) LSTools.p(bp_tree) # # Construct linear series is defined by a list of polynomials # in (x:y)(v:w) of bi-degree (2,2) with base points as in "bp_tree". # 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. # # We expect that the linear series is defined by the following set of polynomials: # # [ '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.get([2, 2], bp_tree) LSTools.p( 'The linear series of bi-degree (2,2) corresponding to this base point tree is as follows:' ) LSTools.p(ls.get_bp_tree()) # # construct corresponding linear series of bi-degree (1,1) # and 2 simple complex conjugate base points # # We expect that the linear series is defined by the following set of polynomials: # # ['x * v - y * w', 'y * v + x * w' ] # # ls = LinearSeries.get([1, 1], bp_tree) LSTools.p( 'The linear series of bi-degree (1,1) corresponding to this base point tree is as follows:' ) LSTools.p(ls.get_bp_tree())
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)
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
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))
def get_solution_set(ls): ''' INPUT: - "ls" -- Assumes that "ls.pol_lst" is a list of polynomials in two variables and that its zero-set is 0-dimensional. OUTPUT: - The number field of "ls.ring" is extended with roots in the zero-set. - Returns zero-set of "ls.pol_lst". Thus the set of points on which all polynomials in "ls.pol_lst" vanish. ''' LSTools.p('input =', ls) if len(ls.gens()) != 2: raise Exception('Not implemented for polynomials in', ls.gens()) # Try all possible pairs of polynomials in pol_lst # until their resultant wrt. y is nonzero. xres = 0 x, y = ls.gens() interval = range(len(ls.pol_lst)) for i, j in sage_Combinations(interval, 2): xres = ls.ring.resultant(ls.pol_lst[i], ls.pol_lst[j], y) if xres not in [0, 1]: # resultant(x,x,y)=1 break if xres in [0, 1]: if sage_gcd(ls.pol_lst) != 1: raise ValueError('Expect gcd of "pol_lst" to be 1:', sage_gcd(ls.pol_lst)) # TODO: handle this case as well. raise Exception( 'All pairs of polynomials in "pol_lst" have a common factor: ', ls.pol_lst) # extend number field with roots of resultant tres = str(xres).replace(str(x), 't') ls.ring.ext_num_field(tres) ls.pol_lst = ls.ring.coerce(ls.pol_lst) xres = ls.ring.coerce(xres) x, y = ls.ring.gens() # factor resultant in linear factors fct_lst = ls.ring.factor(xres) # obtain candidates for x-coordinates of solutions xsol_lst = [] for fct in fct_lst: xsol_lst += [-fct[0].subs({xres.variables()[0]: 0})] xsol_lst = list(set(xsol_lst)) LSTools.p(xsol_lst) # find y-coordinate for each x-coordinate xysol_lst = [] for xsol in xsol_lst: # substitute x-coord xsol = ls.ring.coerce( xsol) # ring.num_field is changed during while loop ypol_lst = [pol.subs({x: xsol}) for pol in ls.pol_lst] ypol_lst = [ypol for ypol in ypol_lst if ypol != 0] ypol = ypol_lst[0] # extend number field with roots of polynomial in y tpol = str(ypol).replace(str(y), 't') ls.ring.ext_num_field(tpol) ls.pol_lst = ls.ring.coerce(ls.pol_lst) ypol = ls.ring.coerce(ypol) ypol_lst = ls.ring.coerce(ypol_lst) x, y = ls.ring.gens() # obtain candidates for y-coordinates ysol_lst = [] if ypol not in ls.ring.get_num_field(): for fct in ls.ring.factor(ypol): ysol_lst += [-fct[0].subs({ypol.variables()[0]: 0})] # check whether (xsol, ysol) is in the zero-set of "ls.pol_lst" for ysol in ysol_lst: lst = [ypol.subs({y: ysol}) for ypol in ypol_lst] if set(lst) == {0}: xysol_lst += [(xsol, ysol)] xysol_lst = list(set(xysol_lst)) LSTools.p('output =', xysol_lst) return xysol_lst
def usecase__get_base_points__examples(): ''' We obtain (infinitely near) base points of several examples of linear series in order to test "get_base_point_tree.get_bp_tree()". ''' pol_lst_lst = [] # 0 pol_lst_lst += [['x^2*z + y^2*z', 'y^3 + z^3']] # 1 pol_lst_lst += [['x^3*z^2 + y^5', 'x^5']] # 2 (example from PhD thesis) pol_lst_lst += [['x^2', 'x*z + y^2']] # 3 pol_lst_lst += [['x^2 + y^2', 'x*z + y^2']] # 4 pol_lst_lst += [['x*z', 'y^2', 'y*z', 'z^2']] # 5 pol_lst_lst += [['x^5', 'y^2*z^3']] # 6 pol_lst_lst += [['x^2*y', 'x*y^2', 'x*y*z', '( x^2 + y^2 + z^2 )*z']] # 7 (weighted projective plane P(2:1:1)) pol_lst_lst += [[ 'z^6', 'y*z^5', 'y^2*z^4', 'y^3*z^3', 'y^4*z^2', 'y^5*z', 'y^6', 'x^2*z^4', 'x^2*y*z^3', 'x^2*y^2*z^2', 'x^3*z^3' ]] # 8 (provided by Martin Weimann) pol_lst_lst += [[ 'y^2*(x^3+x^2*z+2*x*z^2+z^3)+y*(2*x^3+2*x*z^2)*z+z^2*(x^3-x^2*z+x*z^2)', 'z^5' ]] # 9 pol_lst_lst += [['x^3*y^4+x*y^4*z^2+3*x^2*y^3*z^2+3*x*y^2*z^4+y', 'z^7']] # 10 (degree 6 del Pezzo in S^5, which is the orbital product of 2 circles) pol_lst_lst += [[ 'x^2*y^2 + 6/5*x^2*y*z + 17/5*x^2*z^2 + y^2*z^2 + 6/5*y*z^3 + 17/5*z^4', '8/5*x^2*y*z + 6/5*x^2*z^2 + 8/5*y*z^3 + 6/5*z^4', 'x^2*y^2 + 6/5*x^2*y*z + 7/5*x^2*z^2 + y^2*z^2 + 6/5*y*z^3 + 7/5*z^4', '4*x*z^3', '2*x^2*z^2 - 2*z^4', '-6/5*x^2*y*z - 2/5*x^2*z^2 - 4*x*z^3 + 6/5*y*z^3 + 2/5*z^4', '-2*x^2*z^2 + 12/5*x*y*z^2 + 4/5*x*z^3 + 2*z^4' ]] BasePointTree.short = True idx = 0 for pol_lst in pol_lst_lst: ls = LinearSeries(pol_lst, PolyRing('x,y,z', True)) LSTools.p(3 * ('\n' + 50 * '=')) LSTools.p('index for example =', idx) LSTools.p(ls) bp_tree = ls.get_bp_tree() LSTools.p(bp_tree) idx += 1
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())
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())