def test__get_degree(self): d = 4 mon_lst = SERing.get_mon_P2(d) print(mon_lst) out = SERing.get_degree(mon_lst) print(out) assert out == d mat = SERing.random_matrix_QQ(4, len(mon_lst)) pol_lst = list(mat * sage_vector(mon_lst)) print(pol_lst) out = SERing.get_degree(pol_lst) print(out) assert out == d
def usecase_B2(): ''' We compute the projective isomorphisms between the images of birational maps: f:P2--->X and g:P1xP1--->Y Further explanation of this example can be found in the accompanying arxiv article on projective isomorphisms between rational surfaces. ''' x = [ring('x' + str(i)) for i in range(3)] y = [ring('y' + str(i)) for i in range(4)] z = [ring('z' + str(i)) for i in range(4)] c = [ring('c' + str(i)) for i in range(8)] # the maps f and g are parametrizations of (linear projections of) toric surfaces f = ring( '[x0^6*x1^2,x0*x1^5*x2^2,x1^3*x2^5,x0^5*x2^3+x0^5*x2^3+x0^5*x1*x2^2]') g = ring( '[y0^3*y1^2*y2^5,y1^5*y2^3*y3^2,y0^2*y1^3*y3^5,y0^5*y2^2*y3^3+y0^4*y1*y2^3*y3^2]' ) g = [g[0], g[1] + g[0], g[2], g[3] + g[2]] SETools.p('f =', len(f), f) SETools.p('g =', len(g), g) assert sage_gcd(f) == 1 assert sage_gcd(g) == 1 # we compute the implicit equations of the images of the maps f and g eqf = sage_ideal([z[i] - f[i] for i in range(4)]).elimination_ideal(x).gens() SETools.p('eqf =', eqf) assert len(eqf) == 1 assert eqf[0].degree() == 26 eqg = sage_ideal([z[i] - g[i] for i in range(4)]).elimination_ideal(y).gens() SETools.p('eqg =', eqg) assert len(eqg) == 1 assert eqg[0].degree() == 26 # We compute the coefficient matrix Mf and its kernel Kf Mf = SERing.get_matrix_P2(f) Kf = Mf.right_kernel_matrix().T SETools.p('Mf =', Mf.dimensions(), list(Mf)) SETools.p('Kf =', Kf.dimensions(), list(Kf)) assert (Mf * Kf).is_zero() # we do a basepoint analysis for f and g bf = LinearSeries(SERing.conv(f), PolyRing('x,y,z', True)).get_bp_tree() SETools.p('bf =', bf) bg = LinearSeries(SERing.conv(g), PolyRing('x,y,v,w', True)).get_bp_tree() SETools.p('bg =', bg) ################################################### # Computing compatible reductions of f and g # ################################################### # r0-reduction of f and g hf = LinearSeries.get([8], bf) hg = LinearSeries.get([5, 5], bg) SETools.p(len(hf.pol_lst), SERing.conv(hf.pol_lst)) SETools.p(len(hg.pol_lst), SERing.conv(hg.pol_lst)) assert len(hf.pol_lst) == len(hg.pol_lst) == 16 # r1-reduction of hf and hg hft = BasePointTree() hft.add('x', (0, 0), 2).add('t', (0, 0), 1) hft.add('y', (0, 0), 2).add('t', (0, 0), 1) hft.add('z', (0, 0), 1) hf = LinearSeries.get([5], hft) hgt = BasePointTree(['xv', 'xw', 'yv', 'yw']) hgt.add('xv', (0, 0), 1) hgt.add('xw', (0, 0), 1) hgt.add('yv', (0, 0), 1) hgt.add('yw', (0, 0), 1) hg = LinearSeries.get([3, 3], hgt) SETools.p(len(hf.pol_lst), SERing.conv(hf.pol_lst)) SETools.p(len(hg.pol_lst), SERing.conv(hg.pol_lst)) assert len(hf.pol_lst) == len(hg.pol_lst) == 12 # second r1-reduction of hf and hg hft = BasePointTree() hft.add('x', (0, 0), 1) hft.add('y', (0, 0), 1) hf = LinearSeries.get([2], hft) hg = LinearSeries(['x', 'y', 'v', 'w'], PolyRing('x,y,v,w')) SETools.p(len(hf.pol_lst), SERing.conv(hf.pol_lst)) SETools.p(len(hg.pol_lst), SERing.conv(hg.pol_lst)) assert len(hf.pol_lst) == len(hg.pol_lst) == 4 ################################################### # Computing the projective isomorphisms # ################################################### # we compute maps to P1xP1 from two pencils PolyRing.reset_base_field() bpt = BasePointTree() bpt.add('y', (0, 0), 1) pen1 = SERing.conv(LinearSeries.get([1], bpt).pol_lst) SETools.p('pen1 =', pen1) assert set([x[0], x[1]]) == set(pen1) # thus the first pencil defines a map pen1: (x0:x1:x2) |--> (x0:x1) bpt = BasePointTree() bpt.add('x', (0, 0), 1) pen2 = SERing.conv(LinearSeries.get([1], bpt).pol_lst) SETools.p('pen2 =', pen2) assert set([x[0], x[2]]) == set(pen2) # thus the second pencil defines a map pen2: (x0:x1:x2) |--> (x0:x2) # We find that # pen1 x pen2: P2-->P1xP1, (x0:x1:x2) |--> (x0:x1;x0:x2) and # pen2 x pen1: P2-->P1xP1, (x0:x1:x2) |--> (x0:x2;x0:x1) # we find the following compatible reparametrizations # by composing the maps pen1 x pen2 and pen2 x pen1 # with a parametrized map in the identity component of Aut(P1xP1). r0 = { y[0]: c[0] * x[0] + c[1] * x[1], y[1]: c[2] * x[0] + c[3] * x[1], y[2]: c[4] * x[0] + c[5] * x[2], y[3]: c[6] * x[0] + c[7] * x[2] } r1 = { y[0]: c[0] * x[0] + c[1] * x[2], y[1]: c[2] * x[0] + c[3] * x[2], y[2]: c[4] * x[0] + c[5] * x[1], y[3]: c[6] * x[0] + c[7] * x[1] } # Remark: all substitutions with .subs(...) are performed at the same time. ################################################### # reparametrization r0 # ################################################### # compose g with reparametrization r0 gcd0 = sage_gcd([comp.subs(r0) for comp in g]) assert gcd0 == 1 gr0 = [comp.subs(r0) / gcd0 for comp in g] SETools.p('gr0 =', len(gr0), gcd0, gr0) assert SERing.get_degree(gr0) == 10 assert SERing.get_degree(f) == 8 # find conditions on c so that gr0 has the same basepoints as f eqn0_lst = usecase_B2_helper_bp(gr0) eqn0_lst += [ring('(c0*c3-c1*c2)*(c4*c7-c5*c6)*t-1')] prime0_lst = sage_ideal(eqn0_lst).elimination_ideal( ring('t')).primary_decomposition() SETools.p('eqn0_lst =', len(eqn0_lst), eqn0_lst) for prime0 in prime0_lst: SETools.p('\t', prime0.gens()) sol00 = { c[1]: 0, c[2]: 0, c[5]: 0, c[6]: 0, c[0]: 1, c[4]: 1 } # notice that wlog c0=c4=1 sol01 = { c[0]: 0, c[3]: 0, c[4]: 0, c[7]: 0, c[1]: 1, c[5]: 1 } # notice that wlog c1=c5=1 assert len(prime0_lst) == 2 assert set([gen.subs(sol00) for gen in prime0_lst[0].gens()]) == set([0]) assert set([gen.subs(sol01) for gen in prime0_lst[1].gens()]) == set([0]) # sol00: notice that c3!=0 and c7!=0 gcd00 = sage_gcd([comp.subs(sol00) for comp in gr0]) assert gcd00 == x[0] * x[0] gr00 = [comp.subs(sol00) / gcd00 for comp in gr0] SETools.p('gr00 =', len(gr00), gcd00, gr00) assert SERing.get_degree(gr00) == 8 Mgr00 = SERing.get_matrix_P2(gr00) assert Mgr00.dimensions() == (4, 45) # find conditions for c so that Mgr00 has the same kernel as the matrix of f p00_lst = sage_ideal((Mgr00 * Kf).list() + [ring('c3*c7*t-1')]).elimination_ideal( ring('t')).primary_decomposition() assert [p00.gens() for p00 in p00_lst] == [[2 * c[3] - c[7]]] Mgr00 = Mgr00.subs({c[7]: 2 * c[3]}) SETools.p('Mgr00 =', Mgr00.dimensions(), list(Mgr00)) # found a solution: Mgr00 # sol01: notice that c2!=0 and c6!=0 gcd01 = sage_gcd([comp.subs(sol01) for comp in gr0]) assert gcd01 == x[0] * x[0] gr01 = [comp.subs(sol01) / gcd01 for comp in gr0] SETools.p('gr01 =', len(gr01), gcd01, gr01) assert SERing.get_degree(gr01) == 8 assert [] == sage_ideal((SERing.get_matrix_P2(gr01) * Kf).list() + [ring('c2*c6*t-1')]).elimination_ideal( ring('t')).primary_decomposition() # --> no solution ################################################### # reparametrization r1 # ################################################### # compose g with reparametrization r1 gcd1 = sage_gcd([comp.subs(r1) for comp in g]) assert gcd1 == 1 gr1 = [comp.subs(r1) / gcd1 for comp in g] SETools.p('gr1 =', gcd1, gr1) assert SERing.get_degree(gr1) == 10 assert SERing.get_degree(f) == 8 # find conditions on c so that gr1 has the same basepoints as f eqn1_lst = usecase_B2_helper_bp(gr1) eqn1_lst += [ring('(c0*c3-c1*c2)*(c4*c7-c5*c6)*t-1')] SETools.p('eqn1_lst =', len(eqn1_lst), eqn1_lst) prime1_lst = sage_ideal(eqn1_lst).elimination_ideal( ring('t')).primary_decomposition() for prime1 in prime1_lst: SETools.p('\t', prime1.gens()) sol10 = { c[0]: 0, c[3]: 0, c[5]: 0, c[6]: 0, c[1]: 1, c[4]: 1 } # notice that wlog c1=c4=1 sol11 = { c[1]: 0, c[2]: 0, c[4]: 0, c[7]: 0, c[0]: 1, c[5]: 1 } # notice that wlog c0=c5=1 assert len(prime1_lst) == 2 assert set([gen.subs(sol10) for gen in prime1_lst[0].gens()]) == set([0]) assert set([gen.subs(sol11) for gen in prime1_lst[1].gens()]) == set([0]) # sol10: notice that c2!=0 and c7!=0 gcd10 = sage_gcd([comp.subs(sol10) for comp in gr1]) assert gcd10 == x[0] * x[0] gr10 = [comp.subs(sol10) / gcd10 for comp in gr1] SETools.p('gr10 =', len(gr10), gcd10, gr10) assert SERing.get_degree(gr10) == 8 assert [] == sage_ideal((SERing.get_matrix_P2(gr10) * Kf).list() + [ring('c2*c7*t-1')]).elimination_ideal( ring('t')).primary_decomposition() # --> no solution # sol11: notice that c3!=0 and c6!=0 gcd11 = sage_gcd([comp.subs(sol11) for comp in gr1]) assert gcd11 == x[0] * x[0] gr11 = [comp.subs(sol11) / gcd11 for comp in gr1] SETools.p('gr11 =', len(gr11), gcd11, gr11) assert SERing.get_degree(gr11) == 8 assert [] == sage_ideal((SERing.get_matrix_P2(gr11) * Kf).list() + [ring('c3*c6*t-1')]).elimination_ideal( ring('t')).primary_decomposition() # --> no solution ################################################### # compute extended matrices # ################################################### # Mgr00 is the only case we have to consider as other cases had no solution Mgr = Mgr00 # compute the projective isomorphism between the images of f and g # in terms of parametrized matrix U Ef = sage_matrix(sage_QQ, list(Mf) + list(Kf.T)) Egr = sage_matrix(list(Mgr) + list(Kf.T)) UpI = Egr * ~Ef assert (UpI.submatrix(4, 4) - sage_identity_matrix(41)).is_zero() U = UpI.submatrix(0, 0, 4, 4) U = U / sage_gcd(U.list()) SETools.p('U =', U.dimensions(), list(U), '\n' + str(U)) # verify whether U*f is a parametrization for X for all (c0,...,c7) Uf = list(U * sage_vector(f)) eqg_sub = [eq.subs({z[i]: Uf[i] for i in range(4)}) for eq in eqg] if eqg_sub != [0]: SETools.p('Uf =', len(Uf), Uf) SETools.p('eqg_sub=', len(eqg_sub), eqg_sub) assert eqg_sub == [0]
def usecase_B1(): ''' We compute the automorphisms of a Roman surface from a set of compatible reparametrizations. If the domain the projective plane, then a parametrization of a Roman surface is basepoint free. The compatible reparametrizations are in this case linear automorphisms of the projective plane. ''' y = ring('y0,y1,y2,y3') x = ring('x0,x1,x2') c = ring('c0,c1,c2,c3,c4,c5,c6,c7,c8') # parametrizations f and g of Roman surface f = ring('[x0^2+x1^2+x2^2,x0*x1,x0*x2,x1*x2]') g = f # compatible reparametrizations are linear and indexed by c r = { x[0]: c[0] * y[0] + c[1] * y[1] + c[2] * y[2], x[1]: c[3] * y[0] + c[4] * y[1] + c[5] * y[2], x[2]: c[6] * y[0] + c[7] * y[1] + c[8] * y[2] } # compute kernel and coefficient matrix of f Mf = SERing.get_matrix_P2(f) Kf = Mf.right_kernel_matrix().T assert (Mf * Kf).is_zero() # compute the coefficient matrix of g composed with r gr = [comp.subs(r) for comp in g] assert sage_gcd(gr) == 1 assert SERing.get_degree(gr, 'y0,y1,y2') == SERing.get_degree(f) Mgr = SERing.get_matrix_P2(gr, 'y0,y1,y2') # output to screen SETools.p('f =', f) SETools.p('g =', g) SETools.p('r =', r) SETools.p('Mf =', Mf.dimensions(), list(Mf), SERing.get_mon_P2(2)) SETools.p('Kf.T =', Kf.T.dimensions(), list(Kf.T)) SETools.p('Mgr =', Mgr.dimensions(), list(Mgr), '\n' + str(Mgr)) # compute c such that Mgr*Kf==0 ec_lst = (Mgr * Kf).list() + [ sage_matrix(SERing.R, 3, 3, c).det() * ring('t') - 1 ] pc_lst = sage_ideal(ec_lst).elimination_ideal( ring('t')).primary_decomposition() SETools.p('sol_lst = ') sol_lst = [] for pc in pc_lst: s_lst = list(reversed(sorted(pc.gens()))) s_dct = ring( sage_solve([sage_SR(comp) for comp in s_lst], [sage_SR(comp) for comp in c], solution_dict=True)[0]) sol_lst += [s_dct] SETools.p('\t\t', s_lst, '-->', s_dct) # compute implicit equation for image Y of g eqg = sage_ideal([y[i] - g[i] for i in range(4)]).elimination_ideal(x).gens() SETools.p('eqg =', eqg) SETools.p( ' =', str(eqg.subs({y[0]: 1})).replace('y1', 'x').replace('y2', 'y').replace('y3', 'z')) # computing U and test each sol in sol_lst SETools.p('Testing each sol in sol_lst...') for sol in sol_lst: # compute the projective isomorphism in terms of parametrized matrix U Ef = sage_matrix(sage_QQ, list(Mf) + list(Kf.T)) Egr = sage_matrix(list(Mgr.subs(sol)) + list(Kf.T)) UpI = Egr * ~Ef assert (UpI.submatrix(4, 4) - sage_identity_matrix(2)).is_zero() U = UpI.submatrix(0, 0, 4, 4) U = U / sage_gcd(U.list()) assert U.dimensions() == (4, 4) # verify whether U*f is a parametrization for Y for all (c0,...,c7) Uf = list(U * sage_vector(f)) eqg_sub = [eq.subs({y[i]: Uf[i] for i in range(4)}) for eq in eqg] assert eqg_sub == [0] # output U with corresponding solution SETools.p('\t U =', list(U), ', sol =', sol)