Ejemplo n.º 1
0
    def test__get_linear_series__3(self):

        PolyRing.reset_base_field()
        bp_tree_1 = BasePointTree()
        bp_tree_1.add('z', (0, 0), 2).add('t', (1, 0), 1)
        bp_tree_1.add('z', (2, 3), 1)

        bp_tree_2 = LinearSeries.get([3], bp_tree_1).get_bp_tree()

        assert self.equal_output_strings(bp_tree_1.alt_str(),
                                         bp_tree_2.alt_str())
Ejemplo n.º 2
0
    def test__get_linear_series__1(self):

        # Example from phd thesis of Niels Lubbes (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)

        ls = LinearSeries.get([2], bp_tree)

        assert str(ls) == '{ 2, <<x^2, y^2 + x*z>>, QQ[x, y, z] }'
Ejemplo n.º 3
0
def usecase_B4():
    '''
    We compute the projective automorphism of the 
    rational normal scrolls that is parametrized 
    the birational map f: P2 ---> X.
     
    Further explanation of this example can be found 
    in the accompanying arxiv article on projective
    isomorphisms between rational surfaces.
    '''

    # e0-e1
    p1 = (0, 0)
    p2 = (1, 0)
    p3 = (0, 1)
    PolyRing.reset_base_field()
    bpt = BasePointTree()
    bpt.add('z', p1, 1)
    f0p1 = SERing.conv(LinearSeries.get([1], bpt).pol_lst)
    SETools.p('f0p1 =', len(f0p1), f0p1)

    # e0-e2-e3
    bpt = BasePointTree()
    bpt.add('z', p2, 1)
    bpt.add('z', p3, 1)
    f1m2 = SERing.conv(LinearSeries.get([1], bpt).pol_lst)
    SETools.p('f1m2 =', len(f1m2), f1m2)

    # 2e0-e1-e2-e3
    bpt = BasePointTree()
    bpt.add('z', p1, 1)
    bpt.add('z', p2, 1)
    bpt.add('z', p3, 1)
    f1m1 = SERing.conv(LinearSeries.get([2], bpt).pol_lst)
    SETools.p('f1m1 =', len(f1m1), f1m1)

    # 3e0-2e1-e2-e3
    bpt = BasePointTree()
    bpt.add('z', p1, 2)
    bpt.add('z', p2, 1)
    bpt.add('z', p3, 1)
    f1m0 = SERing.conv(LinearSeries.get([3], bpt).pol_lst)
    SETools.p('f1m0 =', len(f1m0), f1m0)

    # set generators for the graded coordinate ring of f
    U = [ring('x1'), ring('x2'), ring('x1+x2-x0'), ring('x1*x2')]
    u = ring('u0,u1,u2,u3')

    # obtain monomials of weight (1,0)
    w_lst = [(0, 1), (0, 1), (1, -2), (1, -1)]
    M1m0 = SERing.get_wmon_lst(u, w_lst, 1, 0)
    SETools.p('M1m0 =', len(M1m0), M1m0)

    # compose F with projective isomorphism P
    z = [ring('z' + str(i)) for i in range(6)]
    c = [ring('c' + str(i)) for i in range(8)]
    dctZ = {u[i]: z[i] for i in range(4)}
    dctP = {
        z[0]: c[0] * u[0] + c[1] * u[1],
        z[1]: c[2] * u[0] + c[3] * u[1],
        z[2]: c[4] * u[2],
        z[3]: c[5] * u[3] + c[6] * u[0] * u[2] + c[7] * u[1] * u[2]
    }
    PoF = [comp.subs(dctZ).subs(dctP) for comp in M1m0]
    SETools.p('PoF wrt u =', len(PoF), PoF)
    PoF = [comp.subs({u[i]: U[i] for i in range(4)}) for comp in PoF]
    PoF = [comp / sage_gcd(PoF) for comp in PoF]
    SETools.p('PoF =', len(PoF), PoF)

    # recover matrix for automorphism P
    F = [comp.subs({u[i]: U[i] for i in range(4)}) for comp in M1m0]
    M = []
    for pol in [comp.subs(dctZ).subs(dctP) for comp in M1m0]:
        row = []
        for mon in M1m0:
            row += [pol.coefficient(mon)]
        M += [row]
    M = sage_matrix(M)
    SETools.p('M =', M.dimensions(), '\n' + str(M))
    MF = list(M * sage_vector(F))
    assert MF == PoF

    # compute the inverse Q of F
    t = ring('t')
    x = ring('x0,x1,x2')
    ide = [F[i] * z[0] - z[i] * F[0] for i in range(5)] + [t * F[0] - 1]
    I1 = sage_ideal(ide).elimination_ideal([t, x[2]]).gens()
    I2 = sage_ideal(ide).elimination_ideal([t, x[1]]).gens()
    I1 = [
        elt for elt in I1 if elt.degree(x[0]) == 1 and elt.degree(x[1]) == 1
    ][0]
    I2 = [
        elt for elt in I2 if elt.degree(x[0]) == 1 and elt.degree(x[2]) == 1
    ][0]
    Q0 = I1.coefficient(x[1])
    Q1 = -I1.coefficient(x[0])
    Q2 = I2.coefficient(x[0])
    Q = [Q0, Q1, Q2]
    SETools.p('Q =', Q)
    QoF = [comp.subs({z[i]: F[i] for i in range(5)}) for comp in Q]
    QoF = [comp / sage_gcd(QoF) for comp in QoF]
    assert QoF == [x[0], x[1], x[2]]

    # compute the composition
    QoPoF = [comp.subs({z[i]: PoF[i] for i in range(5)}) for comp in Q]
    QoPoF = [comp / sage_gcd(QoPoF) for comp in QoPoF]
    SETools.p('QoPoF =', len(QoPoF), QoPoF)

    # from the compatible reparametrizations QoPoF we compute the
    # projective automorphisms U of X.
    f = f1m0
    gr = [comp.subs({x[i]: QoPoF[i] for i in range(3)}) for comp in f]
    gcd_gr = sage_gcd(gr)

    gr = [comp / gcd_gr for comp in gr]
    Mf = SERing.get_matrix_P2(f)
    Mgr = SERing.get_matrix_P2(gr)
    Kf = Mf.right_kernel_matrix().T
    SETools.p('f   =', len(f), f)
    SETools.p('gr  =', len(gr), gr)
    SETools.p('\t gcd_gr  =', gcd_gr)
    SETools.p('Mf  =', Mf.dimensions(), list(Mf))
    SETools.p('Mgr =', Mgr.dimensions(), list(Mgr))
    SETools.p('Kf  =', Kf.dimensions(), list(Kf))

    assert (Mf * Kf).is_zero()
    assert (Mgr * Kf).is_zero()

    Ef = sage_matrix(sage_QQ, list(Mf) + list(Kf.T))
    Egr = sage_matrix(list(Mgr) + list(Kf.T))
    UpI = Egr * ~Ef
    assert (UpI.submatrix(5, 5) - sage_identity_matrix(5)).is_zero()
    U = UpI.submatrix(0, 0, 5, 5)
    SETools.p('UpI =', UpI.dimensions(), list(UpI))
    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))
    SETools.p('Uf  =', len(Uf), Uf)
    eqX = sage_ideal([z[i] - f[i]
                      for i in range(5)]).elimination_ideal([x[0], x[1],
                                                             x[2]]).gens()
    eqXs = [eq.subs({z[i]: Uf[i] for i in range(5)}) for eq in eqX]
    SETools.p('eqX =', len(eqX), eqX)
    SETools.p('eqXs=', len(eqXs), eqXs)
    assert eqXs == [0, 0, 0]
Ejemplo n.º 4
0
def usecase_B5():
    '''
    We compute the projective isomorphism between two 
    conic bundles that are parametrized by the 
    birational maps 
    
    ff: P2 ---> X     and    gg: P1xP1 ---> Y
     
    Further explanation of this example can be found 
    in the accompanying arxiv article on projective
    isomorphisms between rational surfaces.
    '''

    # we construct linear series associated to ff in order to determine
    # the generators of the graded coordinate ring of conic bundle X

    # basepoints in chart x0!=0;
    p1 = (0, 0)
    p2 = (0, 1)
    p3 = (1, 0)

    # 0f+p = e0-e1
    PolyRing.reset_base_field()
    bp_tree = BasePointTree()
    bp_tree.add('z', p1, 1)
    f0p1 = SERing.conv(LinearSeries.get([1], bp_tree).pol_lst)
    SETools.p('f0p1 =', len(f0p1), f0p1)

    # 1f-3p = e0+e1-e2-e3
    bp_tree = BasePointTree()
    bp_tree.add('z', p2, 1)
    bp_tree.add('z', p3, 1)
    f1m3 = SERing.conv(LinearSeries.get([1], bp_tree).pol_lst)
    SETools.p('f1m3 =', len(f1m3), f1m3)

    # 1f-2p = 2e0-e2-e3
    bp_tree = BasePointTree()
    bp_tree.add('z', p2, 1)
    bp_tree.add('z', p3, 1)
    f1m2 = SERing.conv(LinearSeries.get([2], bp_tree).pol_lst)
    SETools.p('f1m2 =', len(f1m2), f1m2)

    # 1f-1p = 3e0-e1-e2-e3
    bp_tree = BasePointTree()
    bp_tree.add('z', p1, 1)
    bp_tree.add('z', p2, 1)
    bp_tree.add('z', p3, 1)
    f1m1 = SERing.conv(LinearSeries.get([3], bp_tree).pol_lst)
    SETools.p('f1m1 =', len(f1m1), f1m1)

    # 1f-0p = 4e0-2e1-e2-e3
    bp_tree = BasePointTree()
    bp_tree.add('z', p1, 2)
    bp_tree.add('z', p2, 1)
    bp_tree.add('z', p3, 1)
    f1m0 = SERing.conv(LinearSeries.get([4], bp_tree).pol_lst)
    SETools.p('f1m0 =', len(f1m0), f1m0)

    # 2f-4p = 4e0-2e2-2e3
    bp_tree = BasePointTree()
    bp_tree.add('z', p2, 2)
    bp_tree.add('z', p3, 2)
    f2m4 = SERing.conv(LinearSeries.get([4], bp_tree).pol_lst)
    SETools.p('f2m4 =', len(f2m4), f2m4)

    # by inspection we recover the generators of graded ring of ff
    U = ring('x1'), ring('x2'), ring('x1+x2-x0'), ring('x1*x2'), ring(
        '(x1+x2-x0)^2')

    # compute bidegree (2,d) in order to find a relation between the generators
    u = u0, u1, u2, u3, u4 = ring('u0,u1,u2,u3,u4')
    SETools.p(
        'Compare number of monomials of given bi-weight with dimension predicted by the Riemann-Roch formula...'
    )
    for d in reversed([-i for i in range(8)]):
        w_lst = [(0, 1), (0, 1), (1, -3), (1, -2), (1, -2)]
        SETools.p('\tweight=', (2, d), ',\t#monomials=',
                  len(SERing.get_wmon_lst(u, w_lst, 2, d)), ',\tRR=',
                  29 + 5 * d)

    # template for generators of coordinate ring for weight (2,-1) and (1,0)
    T2m4 = ring(
        '[u3^2,u3*u4,u4^2,u0*u2*u3,u0*u2*u4,u1*u2*u3,u1*u2*u4,u0^2*u2^2,u0*u1*u2^2,u1^2*u2^2]'
    )
    T1m0 = ring(
        '[u1^2*u4,u1^2*u3,u1^3*u2,u0*u1*u4,u0*u1*u3,u0*u1^2*u2,u0^2*u4,u0^2*u3,u0^2*u1*u2,u0^3*u2]'
    )
    SETools.p('T2m4 =', T2m4)
    SETools.p('T1m0 =', T1m0)

    # find linear relation for f2m4
    a = a0, a1, a2, a3, a4, a5, a6, a7, a8, a9 = [
        elt.subs({u[i]: U[i]
                  for i in range(5)}) for elt in T2m4
    ]  # @UnusedVariable
    mata = sage_matrix(sage_QQ, SERing.get_matrix_P2(a))
    kera = mata.transpose().right_kernel().matrix()
    SETools.p('kera =', kera)
    assert kera * sage_vector(a) == sage_vector([0])
    assert a1 - a8 == 0

    # construct map gg from ff
    # sage_Permutations(10).random_element().to_matrix().rows()
    ff = f1m0
    matp = [(0, 0, 0, 0, 1, 0, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0, 0, 1, 0, 0),
            (0, 0, 0, 1, 0, 0, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0, 0, 0, 0, 1),
            (0, 0, 0, 0, 0, 0, 1, 0, 0, 0), (0, 0, 0, 0, 0, 1, 0, 0, 0, 0),
            (0, 0, 0, 0, 0, 0, 0, 0, 1, 0), (0, 0, 1, 0, 0, 0, 0, 0, 0, 0),
            (0, 1, 0, 0, 0, 0, 0, 0, 0, 0), (1, 0, 0, 0, 0, 0, 0, 0, 0, 0)]
    matp = sage_matrix(matp)
    x0, x1, x2, y0, y1, y2, y3 = ring(
        'x0,x1,x2,y0,y1,y2,y3')  # P2(x0:x1:x2) and P1xP1(y0:y1;y2:y3)
    gg = [comp.subs({x0: y1 * y3, x1: y0 * y2, x2: y1 * y2}) for comp in ff]
    gg = list(matp * sage_vector(gg))
    gcd_gg = sage_gcd(gg)
    gg = [comp / gcd_gg for comp in gg]
    SETools.p('gcd_gg =', gcd_gg)
    SETools.p('ff     =', len(ff), ff)
    SETools.p('gg     =', len(gg), gg)

    # we construct linear series associated to gg in order to determine
    # the generators of the graded coordinate ring of conic bundle Y

    # determine and set basepoint tree
    ls = LinearSeries(SERing.conv(gg), PolyRing('x,y,v,w'))
    bp_tree = ls.get_bp_tree()
    SETools.p('bp_tree(gg) =', bp_tree)
    tree_211 = BasePointTree(['xv', 'xw', 'yv', 'yw'])
    tree_211.add('xw', (0, 0), 2).add('t', (1, 0), 1)
    tree_211.add('yv', (0, 1), 1)

    # 1g+0q = 4l0+2l1-2e1-e2-e3
    g1m0 = SERing.conv(LinearSeries.get([4, 2], tree_211).pol_lst)
    SETools.p('g1m0 =', len(g1m0), g1m0)

    # 1g-3q = (l0+l1-e1-e2-e3) + (b-e1)
    g1m3 = SERing.conv(LinearSeries.get([1, 2], tree_211).pol_lst)
    SETools.p('g1m3 =', len(g1m3), g1m3)

    # 1g-2q = 2l0+2l1-2e1-e2-e3
    g1m2 = SERing.conv(LinearSeries.get([2, 2], tree_211).pol_lst)
    SETools.p('g1m2 =', len(g1m2), g1m2)

    # 1g-1q = 3l0+2l1-2e1-e2-e3
    g1m1 = SERing.conv(LinearSeries.get([3, 2], tree_211).pol_lst)
    SETools.p('g1m1 =', len(g1m1), g1m1)

    # 2g-4q = 4l0+4l1-4e1-2e2-2e3
    tree_422 = BasePointTree(['xv', 'xw', 'yv', 'yw'])
    tree_422.add('xw', (0, 0), 4).add('t', (1, 0), 2)
    tree_422.add('yv', (0, 1), 2)
    g2m4 = SERing.conv(LinearSeries.get([4, 4], tree_422).pol_lst)
    SETools.p('g2m4 =', len(g2m4), g2m4)

    # by inspection we recover the generators of graded ring of gg
    V = ring('y0'), ring('y1'), ring('y0*y2^2+y1*y2^2-y1*y2*y3'), ring(
        'y0*y1*y2^2'), ring('y0^2*y2^2+y1^2*y2^2-y1^2*y3^2')

    # find linear relation for g2m4
    b = b0, b1, b2, b3, b4, b5, b6, b7, b8, b9 = [
        elt.subs({u[i]: V[i]
                  for i in range(5)}) for elt in T2m4
    ]  # @UnusedVariable
    matb = sage_matrix(sage_QQ, SERing.get_matrix_P1xP1(b))
    kerb = matb.transpose().right_kernel().matrix()
    SETools.p('kerb =', kerb)
    assert kerb * sage_vector(b) == sage_vector([0])
    assert 2 * b0 + b1 - 2 * b3 - 2 * b5 + b8 == 0

    # compute inverse of G
    G = [elt.subs({u[i]: V[i] for i in range(5)}) for elt in T1m0]
    z = ring('z0,z1,z2,z3,z4,z5,z6,z7,z8,z9')
    t = ring('t')
    ide = [G[i] * z[0] - z[i] * G[0] for i in range(10)] + [t * G[0] - 1]
    I01 = sage_ideal(ide).elimination_ideal([t, y2, y3]).gens()
    I23 = sage_ideal(ide).elimination_ideal([t, y0, y1]).gens()
    I01 = [elt for elt in I01
           if elt.degree(y0) == 1 and elt.degree(y1) == 1][0]
    I23 = [elt for elt in I23
           if elt.degree(y2) == 1 and elt.degree(y3) == 1][0]
    Q0 = I01.coefficient(y1)
    Q1 = -I01.coefficient(y0)
    Q2 = I23.coefficient(y3)
    Q3 = -I23.coefficient(y2)
    Q = [Q0, Q1, Q2, Q3]
    SETools.p('Q =', Q)  # [-z9, -z8, -z8, -z6 - 2*z7 + z8 + z9]

    # check the inverse
    QoG = [q.subs({z[i]: G[i] for i in range(10)}) for q in Q]
    gcd01 = sage_gcd(QoG[0], QoG[1])
    gcd23 = sage_gcd(QoG[2], QoG[3])
    QoG = [QoG[0] / gcd01, QoG[1] / gcd01, QoG[2] / gcd23, QoG[3] / gcd23]
    SETools.p('QoG =', QoG)
    assert QoG == [y0, y1, y2, y3]

    # compose F with projective isomorphism P
    c = c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12 = [
        ring('c' + str(i)) for i in range(13)
    ]
    dctZ = {u[i]: z[i] for i in range(5)}
    dctP = {
        z[0]: c0 * u0 + c1 * u1,
        z[1]: c2 * u0 + c3 * u1,
        z[2]: c4 * u2,
        z[3]: c5 * u3 + c6 * u4 + c7 * u0 * u2 + c8 * u1 * u2,
        z[4]: c9 * u3 + c10 * u4 + c11 * u0 * u2 + c12 * u1 * u2
    }
    PoF = [comp.subs(dctZ).subs(dctP) for comp in T1m0]
    PoF = [comp.subs({u[i]: U[i] for i in range(5)}) for comp in PoF]
    PoF = [comp / sage_gcd(PoF) for comp in PoF]
    SETools.p('PoF =', len(PoF), PoF)

    # compose PoF with Q
    QoPoF = [comp.subs({z[i]: PoF[i] for i in range(10)}) for comp in Q]
    gcd01 = sage_gcd(QoPoF[0], QoPoF[1])
    gcd23 = sage_gcd(QoPoF[2], QoPoF[3])
    QoPoF = [
        QoPoF[0] / gcd01, QoPoF[1] / gcd01, QoPoF[2] / gcd23, QoPoF[3] / gcd23
    ]
    SETools.p('QoPoF =', len(QoPoF), QoPoF)

    # create a list of equations for the ci
    b = T2m4
    rel_g4m2 = 2 * b[0] + b[1] - 2 * b[3] - 2 * b[5] + b[8]
    SETools.p('rel_g4m2 =', rel_g4m2)
    rel_g4m2 = rel_g4m2.subs(dctZ).subs(dctP).subs(
        {u[i]: U[i]
         for i in range(5)})
    SETools.p('rel_g4m2 =', rel_g4m2)
    rel_lst = []
    x = ring('[x0,x1,x2]')
    for exp in sage_Compositions(4 + 3, length=3):
        rel_lst += [rel_g4m2.coefficient({x[i]: exp[i] - 1 for i in range(3)})]
    SETools.p('rel_lst =', len(rel_lst), rel_lst)
    t = ring('t')
    rel_lst += [(c0 * c3 - c1 * c2) * c4 * (c5 * c10 - c9 * c6) * t - 1]

    # solve for ci and put the solutions in dictionary form
    prime_lst = sage_ideal(rel_lst).elimination_ideal(
        t).primary_decomposition()
    SETools.p('prime_lst =', len(prime_lst))
    for gen_lst in [prime.gens() for prime in prime_lst]:
        sol_dct = sage_solve([sage_SR(gen) for gen in gen_lst],
                             [sage_SR(elt) for elt in c],
                             solution_dict=True)
        assert len(sol_dct) == 1
        SETools.p('\t gen_lst =', gen_lst)
        SETools.p('\t sol_dct =', sol_dct[0])
    prime_lst2 = []
    prime_lst2 += [prime_lst[0].gens() + [c0 - 1, c4 - 1]]
    prime_lst2 += [prime_lst[1].gens() + [c1 - 1, c4 - 1]]
    prime_lst2 += [prime_lst[2].gens() + [c1 - 1, c4 - 1]]
    prime_lst2 += [prime_lst[3].gens() + [c0 - 1, c4 - 1]]
    SETools.p('Added equations to prime_lst to simplify solutions:')
    for gen_lst in prime_lst2:
        sol_dct = sage_solve([sage_SR(gen) for gen in gen_lst],
                             [sage_SR(elt) for elt in c],
                             solution_dict=True)
        assert len(sol_dct) == 1
        SETools.p('\t gen_lst =', gen_lst)
        SETools.p('\t sol_dct =', sol_dct[0])
    r0, r1 = ring('r0,r1')
    sol0 = {
        c0: 1,
        c1: 0,
        c2: 0,
        c3: -r0 * r1,
        c4: 1,
        c5: 0,
        c6: r0,
        c7: 0,
        c8: 0,
        c9: r1,
        c10: -2 * r0,
        c11: 2,
        c12: -2 * r0 * r1
    }
    sol1 = {
        c0: 0,
        c1: 1,
        c2: -r0 * r1,
        c3: 0,
        c4: 1,
        c5: 0,
        c6: r0,
        c7: 0,
        c8: 0,
        c9: r1,
        c10: -2 * r0,
        c11: -2 * r0 * r1,
        c12: 2
    }
    sol2 = {
        c0: 0,
        c1: 1,
        c2: -r0 * r1,
        c3: 0,
        c4: 1,
        c5: r0,
        c6: 0,
        c7: 0,
        c8: 0,
        c9: -2 * r0,
        c10: r1,
        c11: -2 * r0 * r1,
        c12: 2
    }
    sol3 = {
        c0: 1,
        c1: 0,
        c2: 0,
        c3: -r0 * r1,
        c4: 1,
        c5: r0,
        c6: 0,
        c7: 0,
        c8: 0,
        c9: -2 * r0,
        c10: r1,
        c11: 2,
        c12: -2 * r0 * r1
    }
    sol_lst = [sol0, sol1, sol2, sol3]
    SETools.p('Simplified solutions by hand:')
    for sol in sol_lst:
        SETools.p('\t', sol)

    #  compose compatible reparametrizations with gg
    y = ring('[y0,y1,y2,y3]')
    gr_lst = []
    SETools.p('Computing (gg o r) for each sol in sol_lst...')
    for sol in sol_lst:
        gr = [
            comp.subs({y[i]: QoPoF[i]
                       for i in range(4)}).subs(sol) for comp in gg
        ]
        SETools.p('\t gr =', gr)
        gcd_gr = sage_gcd(gr)
        SETools.p('\t\t gcd_gr    =', gcd_gr)
        gr_lst += [[comp / gcd_gr for comp in gr]]
        SETools.p('\t\t gr/gcd_gr =', gr_lst[-1])
    SETools.p('gr_lst =', len(gr_lst))
    for gr in gr_lst:
        SETools.p('\t gr =', gr)

    # get coefficient matrix of ff and its kernel
    mff = SERing.get_matrix_P2(ff)
    kff = mff.right_kernel_matrix().T
    SETools.p('mff =', mff.dimensions(), list(mff))
    SETools.p('kff =', kff.dimensions(), list(kff))
    assert (mff * kff).is_zero()

    # get implicit equations for image of gg
    z = ring('z0,z1,z2,z3,z4,z5,z6,z7,z8,z9')
    y = ring('y0,y1,y2,y3')
    igg = SERing.R.ideal([z[i] - gg[i] for i in range(10)
                          ]).elimination_ideal([y[i] for i in range(4)])
    SETools.p('igg =', list(igg.gens()))

    # Compute isomorphisms for each gr
    SETools.p('Compute projective isomorphism for each gr in gr_lst:')
    for gr in gr_lst:

        mgr = SERing.get_matrix_P2(gr)
        mgk = mgr * kff
        assert mgk.is_zero()  # because the surfaces in P^9 are linearly normal

        Ef = sage_matrix(sage_QQ, mff.rows() + kff.T.rows())
        Egr = sage_matrix(mgr.rows() + kff.T.rows())
        UpI = Egr * Ef.inverse()
        assert (UpI.submatrix(10, 10) - sage_identity_matrix(5)).is_zero()
        U = UpI.submatrix(0, 0, 10, 10)
        SETools.p('\tU =', U.dimensions(), list(U))

        # check if the answer is correct by substituting into the equations of Y
        Uff = list(U * sage_vector(ff))
        iggs = igg.subs({z[i]: Uff[i] for i in range(10)})
        assert iggs.is_zero()
Ejemplo n.º 5
0
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]