コード例 #1
0
    def test__get_linear_series__2(self):

        ring = PolyRing('x,y,z', True)
        ls = LinearSeries(['x^2+y^2', 'y^2+x*z'], ring)
        bp_tree_1 = ls.get_bp_tree()

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

        assert self.equal_output_strings(str(bp_tree_1), str(bp_tree_2))
コード例 #2
0
    def test__get_base_point_tree(self):

        ring = PolyRing('x,y,z', True)
        ring.ext_num_field('t^2 + 1')
        ring.ext_num_field('t^3 + a0')

        ls = LinearSeries(['x^2+a0*y*z', 'y+a1*z+x'], ring)

        out = str(ls.get_bp_tree())
        chk = """
            { 2, <<x^2 + a0*y*z, x + y + a1*z>>, QQ( <a0|t^2 + 1>, <a1|t^2 + a0*t - 1>, <a2|t^2 - a0*t - a0*a1> )[x, y, z] }
            chart=z, depth=0, mult=1, sol=(-a2 + a0, a2 - a1 - a0), { 2, <<x^2 + a0*y, x + y + a1>>, QQ( <a0|t^2 + 1>, <a1|t^2 + a0*t - 1>, <a2|t^2 - a0*t - a0*a1> )[x, y] }
            chart=z, depth=0, mult=1, sol=(a2, -a2 - a1), { 2, <<x^2 + a0*y, x + y + a1>>, QQ( <a0|t^2 + 1>, <a1|t^2 + a0*t - 1>, <a2|t^2 - a0*t - a0*a1> )[x, y] }
            """
        assert self.equal_output_strings(out, chk)
コード例 #3
0
def usecase__roman_circles():
    '''
    We compute circles on a Roman surface.
    '''
    # parametrization of the Roman surface
    #
    p_lst = '[ z^2+x^2+y^2, -z*x, -x*y, z*y ]'

    # we consider the stereographic projection from
    #     S^3 = { x in P^4 | -x0^2+x1^2+x2^2+x3^2+x4^2 = 0 }
    # where the center of projection is (1:0:0:0:1):
    #     (x0:x1:x2:x3:x4) |---> (x0-x4:x1:x2:x3)

    # inverse stereographic projection into 3-sphere
    #
    s_lst = '[ y0^2+y1^2+y2^2+y3^2, 2*y0*y1, 2*y0*y2, 2*y0*y3, -y0^2+y1^2+y2^2+y3^2 ]'

    # compose p_lst with s_lst
    #
    ring = PolyRing('x,y,z,y0,y1,y2,y3')
    x, y, z, y0, y1, y2, y3 = ring.gens()
    p_lst = ring.coerce(p_lst)
    s_lst = ring.coerce(s_lst)
    dct = {y0: p_lst[0], y1: p_lst[1], y2: p_lst[2], y3: p_lst[3]}
    sp_lst = [s.subs(dct) for s in s_lst]
    NSTools.p('sp_lst =')
    for sp in sp_lst:
        NSTools.p('\t\t', sage_factor(sp))
    NSTools.p('gcd(sp_lst) =', sage_gcd(sp_lst))

    # determine base points
    #
    ring = PolyRing('x,y,z', True)
    sp_lst = ring.coerce(sp_lst)
    ls = LinearSeries(sp_lst, ring)
    NSTools.p(ls.get_bp_tree())

    # We expect that the basepoints come from the intersection
    # of the Roman surface with the absolute conic:
    #    A = { (y0:y1:y2:y3) in P^3 | y0=y1^2+y2^2+y3^2 = 0 }
    #
    # Circles are the image via p_lst of lines that pass through
    # complex conjugate points.
    #
    ring = PolyRing('x,y,z',
                    False)  # reinitialize ring with updated numberfield
    a0, a1, a2, a3 = ring.root_gens()

    # a0=(1-I*sqrt(3)) with conjugate a0-1 and minimal polynomial t^2-t+1

    # we compute candidate classes of circles
    #
    h = Div.new('4e0-e1-e2-e3-e4-e5-e6-e7-e8')
    div_lst = get_divs(h, 2, -2, False) + get_divs(h, 2, -1, False)
    NSTools.p('Classes of circles up to permutation:')
    for c in div_lst:
        NSTools.p('\t\t', c)

    # We recover the preimages of circles in the Roman surface
    # under the map p_lst, by constructing for each candidate
    # class the corresponding linear series.

    # 2e0-e1-e2-e3-e4-e5-e6-e7-e8
    b = [(a0 - 1, -a0), (-a0, a0 - 1)]
    b += [(-a0 + 1, a0), (a0, -a0 + 1)]
    b += [(a0 - 1, a0), (-a0, -a0 + 1)]
    b += [(-a0 + 1, -a0), (a0, a0 - 1)]
    bp_tree = BasePointTree()
    for i in range(6):
        bp_tree.add('z', b[i], 1)
    NSTools.p('basepoints =', b)
    NSTools.p(LinearSeries.get([2], bp_tree))

    # e0-e1-e2
    b = [(a0 - 1, -a0), (-a0, a0 - 1)]
    bp_tree = BasePointTree()
    bp = bp_tree.add('z', b[0], 1)
    bp = bp_tree.add('z', b[1], 1)
    NSTools.p('basepoints =', b)
    NSTools.p(LinearSeries.get([1], bp_tree))

    # e0-e3-e4
    b = [(-a0 + 1, a0), (a0, -a0 + 1)]
    bp_tree = BasePointTree()
    bp = bp_tree.add('z', b[0], 1)
    bp = bp_tree.add('z', b[1], 1)
    NSTools.p('basepoints =', b)
    NSTools.p(LinearSeries.get([1], bp_tree))

    # e0-e5-e6
    b = [(a0 - 1, a0), (-a0, -a0 + 1)]
    bp_tree = BasePointTree()
    bp = bp_tree.add('z', b[0], 1)
    bp = bp_tree.add('z', b[1], 1)
    NSTools.p('basepoints =', b)
    NSTools.p(LinearSeries.get([1], bp_tree))

    # e0-e7-e8
    b = [(-a0 + 1, -a0), (a0, a0 - 1)]
    bp_tree = BasePointTree()
    bp = bp_tree.add('z', b[0], 1)
    bp = bp_tree.add('z', b[1], 1)
    NSTools.p('basepoints =', b)
    NSTools.p(LinearSeries.get([1], bp_tree))

    return
コード例 #4
0
def CH1_cyclide():
    '''
    Creates povray image of a CH1 cyclide, which is
    an inversion of a Circular Hyperboloid of 1 sheet.    
    '''

    # Construct a trigonometric parametrization by rotating a circle.
    r, R = 1, 1
    c0, s0, c1, s1 = sage_var('c0,s0,c1,s1')
    x, y, v, w, a0 = sage_var('x,y,v,w,a0')
    q2 = sage_QQ(1) / 2
    MX = sage_matrix([(1, 0, 0), (0, c1, s1), (0, -s1, c1)])
    MXc = MX.subs({c1: a0, s1: a0})  # a0=1/sqrt(2)=cos(pi/4)=sin(pi/4)
    MZ = sage_matrix([(c1, s1, 0), (-s1, c1, 0), (0, 0, 1)])
    V = sage_vector([r * c0, 0, r * s0])
    V = MXc * V
    V[0] = V[0] + R
    pmz_AB_lst = list(MZ * V)
    OrbTools.p('V =', V)
    OrbTools.p('pmz_AB_lst =', pmz_AB_lst)
    for pmz in pmz_AB_lst:
        OrbTools.p('\t\t', sage_factor(pmz))

    # Convert the trigonometric parametrization to a rational parametrization
    # We convert via the following formulas,
    #
    #     cos(s) = (y^2-x^2) / (y^2+x^2)
    #     sin(s) = 2*x*y / (y^2+x^2)
    #     y=1; x = arctan( s/2 )
    #
    C0 = (y**2 - x**2) / (y**2 + x**2)
    S0 = 2 * x * y / (y**2 + x**2)
    C1 = (w**2 - v**2) / (w**2 + v**2)
    S1 = 2 * v * w / (w**2 + v**2)
    den = (y**2 + x**2) * (w**2 + v**2)
    dct = {c0: C0, s0: S0, c1: C1, s1: S1}
    pmz_lst = [den] + [(elt.subs(dct) * den).simplify_full()
                       for elt in list(MZ * V)]
    OrbTools.p('pmz_lst =', pmz_lst)
    for pmz in pmz_lst:
        OrbTools.p('\t\t', sage_factor(pmz))

    # do a basepoint analysis on the rational parametrization
    # The True argument is for resetting the number field to QQ!
    ring = PolyRing('x,y,v,w', True).ext_num_field('t^2-1/2')
    ls = LinearSeries([str(pmz) for pmz in pmz_lst], ring)
    OrbTools.p(ls.get_bp_tree())

    # construct linear series for families of conics
    ring = PolyRing(
        'x,y,v,w')  # construct polynomial ring over new ground field
    OrbTools.p(ring)
    x, y, v, w = ring.gens()
    a0, a1 = ring.root_gens()

    p1 = ['xv', (0, 2 * a0 * a1)]
    p2 = ['xv', (0, -2 * a0 * a1)]
    p3 = ['xv', (a1, 2 * a0 * a1)]
    p4 = ['xv', (-a1, -2 * a0 * a1)]

    bpt_1234 = BasePointTree(['xv', 'xw', 'yv', 'yw'])
    bpt_1234.add(p1[0], p1[1], 1)
    bpt_1234.add(p2[0], p2[1], 1)
    bpt_1234.add(p3[0], p3[1], 1)
    bpt_1234.add(p4[0], p4[1], 1)

    bpt_12 = BasePointTree(['xv', 'xw', 'yv', 'yw'])
    bpt_12.add(p1[0], p1[1], 1)
    bpt_12.add(p2[0], p2[1], 1)

    bpt_34 = BasePointTree(['xv', 'xw', 'yv', 'yw'])
    bpt_34.add(p3[0], p3[1], 1)
    bpt_34.add(p4[0], p4[1], 1)

    ls_22 = LinearSeries.get([2, 2], bpt_1234)  # |2(l1+l2)-e1-e2-e3-e4|
    ls_21 = LinearSeries.get([2, 1], bpt_1234)
    ls_12 = LinearSeries.get([1, 2], bpt_1234)
    ls_11a = LinearSeries.get([1, 1], bpt_12)
    ls_11b = LinearSeries.get([1, 1], bpt_34)

    OrbTools.p('linear series 22 =\n', ls_22)
    OrbTools.p('linear series 21 =\n', ls_21)
    OrbTools.p('linear series 12 =\n', ls_12)
    OrbTools.p('linear series 11a =\n', ls_11a)
    OrbTools.p('linear series 11b =\n', ls_11b)

    # compute reparametrization from the linear series of families
    ring = PolyRing(
        'x,y,v,w,c0,s0,c1,s1')  # construct polynomial ring with new generators
    OrbTools.p(ring)
    x, y, v, w, c0, s0, c1, s1 = ring.gens()
    a0, a1 = ring.root_gens()
    pmz_AB_lst = [1] + ring.coerce(pmz_AB_lst)
    pmz_lst = ring.coerce(pmz_lst)

    X = 1 - s0
    Y = c0
    V = 1 - s1
    W = c1
    CB_dct = {
        x: X,
        y: Y,
        v: W * X - 2 * a0 * V * Y,
        w: V * X + 2 * a0 * W * Y
    }
    pmz_CB_lst = [pmz.subs(CB_dct) for pmz in pmz_lst]  # CB  11b

    # output
    OrbTools.p('pmz_AB_lst =\n', pmz_AB_lst)
    OrbTools.p('pmz_CB_lst =\n', pmz_CB_lst)

    # approximate by map defined over rational numbers
    ci_idx = 0  # index defining the complex embedding
    OrbTools.p('complex embeddings =')
    for i in range(len(a0.complex_embeddings())):
        a0q = OrbRing.approx_QQ_coef(a0, i)
        OrbTools.p('\t\t' + str(i) + ' =', a0q, sage_n(a0q))
    pmz_AB_lst = OrbRing.approx_QQ_pol_lst(pmz_AB_lst, ci_idx)
    pmz_CB_lst = OrbRing.approx_QQ_pol_lst(pmz_CB_lst, ci_idx)

    # mathematica input
    ms = ''
    for pmz, AB in [(pmz_lst, 'ZZ'), (pmz_AB_lst, 'AB'), (pmz_CB_lst, 'CB')]:
        s = 'pmz' + AB + '=' + str(pmz) + ';'
        s = s.replace('[', '{').replace(']', '}')
        ms += '\n' + s
    OrbTools.p('Mathematica input =', ms)

    # PovInput ring cyclide
    #
    pin = PovInput()

    pin.path = './' + get_time_str() + '_CH1_cyclide/'
    pin.fname = 'orb'
    pin.scale = 1
    pin.cam_dct['location'] = (0, -5, 0)
    pin.cam_dct['lookat'] = (0, 0, 0)
    pin.cam_dct['rotate'] = (20, 0, 0)
    pin.shadow = True
    pin.light_lst = [(1, 0, 0), (0, 1, 0), (0, 0, 1), (-1, 0, 0), (0, -1, 0),
                     (0, 0, -1), (10, 0, 0), (0, 10, 0), (0, 0, 10),
                     (-10, 0, 0), (0, -10, 0), (0, 0, -10)]
    pin.axes_dct['show'] = False
    pin.axes_dct['len'] = 1.2
    pin.height = 400
    pin.width = 800
    pin.quality = 11
    pin.ani_delay = 10

    pin.impl = None

    pin.pmz_dct['A'] = (pmz_AB_lst, 0)
    pin.pmz_dct['B'] = (pmz_AB_lst, 1)
    pin.pmz_dct['C'] = (pmz_CB_lst, 0)

    pin.pmz_dct['FA'] = (pmz_AB_lst, 0)
    pin.pmz_dct['FB'] = (pmz_AB_lst, 1)
    pin.pmz_dct['FC'] = (pmz_CB_lst, 0)

    v0_lst = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 360, 10)]

    v1_lst_A = [(sage_QQ(i) / 180) * sage_pi for i in range(180, 360, 10)]
    v1_lst_B = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 180, 10)]
    v1_lst_C = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 180, 10)]

    v1_lst_FA = [(sage_QQ(i) / 180) * sage_pi for i in range(180, 360, 2)]
    v1_lst_FB = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 180, 2)]
    v1_lst_FC = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 180, 2)]

    prec = 50

    pin.curve_dct['A'] = {
        'step0': v0_lst,
        'step1': v1_lst_A,
        'prec': prec,
        'width': 0.03
    }
    pin.curve_dct['B'] = {
        'step0': v0_lst,
        'step1': v1_lst_B,
        'prec': prec,
        'width': 0.03
    }
    pin.curve_dct['C'] = {
        'step0': v0_lst,
        'step1': v1_lst_C,
        'prec': prec,
        'width': 0.03
    }

    pin.curve_dct['FA'] = {
        'step0': v0_lst,
        'step1': v1_lst_FA,
        'prec': prec,
        'width': 0.02
    }
    pin.curve_dct['FB'] = {
        'step0': v0_lst,
        'step1': v1_lst_FB,
        'prec': prec,
        'width': 0.02
    }
    pin.curve_dct['FC'] = {
        'step0': v0_lst,
        'step1': v1_lst_FC,
        'prec': prec,
        'width': 0.02
    }

    col_A = (0.6, 0.4, 0.1, 0.0)
    col_B = (0.1, 0.15, 0.0, 0.0)
    col_C = (0.2, 0.3, 0.2, 0.0)
    colFF = (0.1, 0.1, 0.1, 0.0)

    pin.text_dct['A'] = [True, col_A, 'phong 0.2 phong_size 5']
    pin.text_dct['B'] = [True, col_B, 'phong 0.2 phong_size 5']
    pin.text_dct['C'] = [True, col_C, 'phong 0.2 phong_size 5']
    pin.text_dct['FA'] = [True, colFF, 'phong 0.2 phong_size 5']
    pin.text_dct['FB'] = [True, colFF, 'phong 0.2 phong_size 5']
    pin.text_dct['FC'] = [True, colFF, 'phong 0.2 phong_size 5']

    # raytrace image/animation
    create_pov(pin, ['A', 'B', 'C'])
    create_pov(pin, ['A', 'B', 'C', 'FA', 'FB', 'FC'])
    create_pov(pin, ['A', 'B', 'FA', 'FB'])
    create_pov(pin, ['B', 'C', 'FA', 'FB'])
コード例 #5
0
def perseus_cyclide():
    '''
    Creates povray image of the Perseus cyclide.
    '''

    # We first construct a trigonometric parametrization
    # by rotating a circle.
    #     cos(pi/3) = 1/2
    #     sin(pi/3) = sqrt(3)/2
    #
    r, R = 1, 2
    c0, s0, c1, s1 = sage_var('c0,s0,c1,s1')
    x, y, v, w, a0 = sage_var('x,y,v,w,a0')
    q2 = sage_QQ(1) / 2
    MZ = sage_matrix([(c1, s1, 0), (-s1, c1, 0), (0, 0, 1)])
    MZc = MZ.subs({c1: q2, s1: q2 * a0})
    V = sage_vector([r * c0, 0, r * s0])
    V = MZc * V
    V[0] = V[0] + R
    pmz_AB_lst = list(MZ * V)

    OrbTools.p('V =', V)
    OrbTools.p('pmz_AB_lst =', pmz_AB_lst)
    for pmz in pmz_AB_lst:
        OrbTools.p('\t\t', sage_factor(pmz))

    # We convert the trigonometric parametrization to a
    # rational parametrization, via the following formulas:
    #
    #     cos(s) = (y^2-x^2) / (y^2+x^2)
    #     sin(s) = 2*x*y / (y^2+x^2)
    #     y=1; x = arctan( s/2 )
    #
    C0 = (y**2 - x**2) / (y**2 + x**2)
    S0 = 2 * x * y / (y**2 + x**2)
    C1 = (w**2 - v**2) / (w**2 + v**2)
    S1 = 2 * v * w / (w**2 + v**2)
    den = (y**2 + x**2) * (w**2 + v**2)
    dct = {c0: C0, s0: S0, c1: C1, s1: S1}
    pmz_lst = [den] + [(elt.subs(dct) * den).simplify_full()
                       for elt in list(MZ * V)]
    OrbTools.p('pmz_lst =', pmz_lst)
    for pmz in pmz_lst:
        OrbTools.p('\t\t', sage_factor(pmz))

    # do a basepoint analysis on the rational parametrization
    #
    ring = PolyRing('x,y,v,w', True).ext_num_field('t^2-3')
    ls = LinearSeries([str(pmz) for pmz in pmz_lst], ring)
    OrbTools.p(ls.get_bp_tree())

    # construct linear series for families of conics
    #
    ring = PolyRing(
        'x,y,v,w')  # construct polynomial ring over new ground field
    OrbTools.p(ring)
    x, y, v, w = ring.gens()
    a0, a1, a2, a3 = ring.root_gens()

    p1 = ['xv', (-a3, a1)]
    p2 = ['xv', (-a2, -a1)]
    p3 = ['xv', (a3, a1)]
    p4 = ['xv', (a2, -a1)]

    bpt_1234 = BasePointTree(['xv', 'xw', 'yv', 'yw'])
    bpt_1234.add(p1[0], p1[1], 1)
    bpt_1234.add(p2[0], p2[1], 1)
    bpt_1234.add(p3[0], p3[1], 1)
    bpt_1234.add(p4[0], p4[1], 1)

    bpt_12 = BasePointTree(['xv', 'xw', 'yv', 'yw'])
    bpt_12.add(p1[0], p1[1], 1)
    bpt_12.add(p2[0], p2[1], 1)

    bpt_34 = BasePointTree(['xv', 'xw', 'yv', 'yw'])
    bpt_34.add(p3[0], p3[1], 1)
    bpt_34.add(p4[0], p4[1], 1)

    ls_22 = LinearSeries.get([2, 2], bpt_1234)
    ls_21 = LinearSeries.get([2, 1], bpt_1234)
    ls_12 = LinearSeries.get([1, 2], bpt_1234)
    ls_11a = LinearSeries.get([1, 1], bpt_12)
    ls_11b = LinearSeries.get([1, 1], bpt_34)

    OrbTools.p('linear series 22 =\n', ls_22)
    OrbTools.p('linear series 21 =\n', ls_21)
    OrbTools.p('linear series 12 =\n', ls_12)
    OrbTools.p('linear series 11a =\n', ls_11a)
    OrbTools.p('linear series 11b =\n', ls_11b)

    # compute reparametrization from the linear series of families
    ring = PolyRing('x,y,v,w,c0,s0,c1,s1')
    OrbTools.p(ring)
    x, y, v, w, c0, s0, c1, s1 = ring.gens()
    a0, a1, a2, a3 = ring.root_gens()
    pmz_AB_lst = [1] + ring.coerce(pmz_AB_lst)
    pmz_lst = ring.coerce(pmz_lst)

    q2 = sage_QQ(1) / 2
    a = 2 * a0 / 3
    b = (-a0 * a1 / 3 - q2) * a3
    c = (a0 * a1 / 3 - q2) * a2
    d = (a1 / 2 - a0 / 3) * a3
    e = (-a1 / 2 - a0 / 3) * a2
    bc = b + c
    de = d + e

    X = 1 - s0
    Y = c0
    V = 1 - s1
    W = c1
    CB_dct = {
        x: X,
        y: Y,
        v: W * X + bc * W * Y - de * V * Y,
        w: V * X + bc * V * Y + de * W * Y
    }
    DB_dct = {
        x: X,
        y: Y,
        v: W * X - bc * W * Y + de * V * Y,
        w: V * X - bc * V * Y - de * W * Y
    }
    EB_dct = {
        x: X,
        y: Y,
        v: W * X**2 + W * Y**2 - a * V * Y**2,
        w: V * X**2 + V * Y**2 + a * W * Y**2
    }
    pmz_CB_lst = [pmz.subs(CB_dct) for pmz in pmz_lst]  # CB  11a
    pmz_DB_lst = [pmz.subs(DB_dct) for pmz in pmz_lst]  # CB  11b
    pmz_EB_lst = [pmz.subs(EB_dct) for pmz in pmz_lst]  # CB  21

    # output
    OrbTools.p('pmz_AB_lst =\n', pmz_AB_lst)
    OrbTools.p('pmz_CB_lst =\n', pmz_CB_lst)
    OrbTools.p('pmz_DB_lst =\n', pmz_DB_lst)
    OrbTools.p('pmz_EB_lst =\n', pmz_EB_lst)

    # approximate by map defined over rational numbers
    ci_idx = 5  # index defining the complex embedding
    pmz_AB_lst = OrbRing.approx_QQ_pol_lst(pmz_AB_lst, ci_idx)
    pmz_CB_lst = OrbRing.approx_QQ_pol_lst(pmz_CB_lst, ci_idx)
    pmz_DB_lst = OrbRing.approx_QQ_pol_lst(pmz_DB_lst, ci_idx)
    pmz_EB_lst = OrbRing.approx_QQ_pol_lst(pmz_EB_lst, ci_idx)

    # mathematica input
    ms = ''
    for pmz, AB in [(pmz_lst, 'ZZ'), (pmz_AB_lst, 'AB'), (pmz_CB_lst, 'CB'),
                    (pmz_DB_lst, 'DB'), (pmz_EB_lst, 'EB')]:
        s = 'pmz' + AB + '=' + str(pmz) + ';'
        s = s.replace('[', '{').replace(']', '}')
        ms += '\n' + s
    OrbTools.p('Mathematica input =', ms)

    # PovInput ring cyclide
    #
    pin = PovInput()

    pin.path = './' + get_time_str() + '_perseus_cyclide/'
    pin.fname = 'orb'
    pin.scale = 1
    pin.cam_dct['location'] = (0, 7, 0)
    pin.cam_dct['lookat'] = (0, 0, 0)
    pin.cam_dct['rotate'] = (45, 0, 0)
    pin.shadow = True
    pin.light_lst = [(0, 0, -10), (0, -10, 0), (-10, 0, 0), (0, 0, 10),
                     (0, 10, 0), (10, 0, 0)]
    pin.axes_dct['show'] = False
    pin.axes_dct['len'] = 1.2
    pin.height = 400
    pin.width = 800
    pin.quality = 11
    pin.ani_delay = 10

    pin.impl = None

    pin.pmz_dct['A'] = (pmz_AB_lst, 0)
    pin.pmz_dct['B'] = (pmz_AB_lst, 1)
    pin.pmz_dct['C'] = (pmz_CB_lst, 0)
    pin.pmz_dct['D'] = (pmz_DB_lst, 0)
    pin.pmz_dct['E'] = (pmz_EB_lst, 0)

    pin.pmz_dct['FA'] = (pmz_AB_lst, 0)
    pin.pmz_dct['FB'] = (pmz_AB_lst, 1)
    pin.pmz_dct['FC'] = (pmz_CB_lst, 0)
    pin.pmz_dct['FD'] = (pmz_DB_lst, 0)
    pin.pmz_dct['FE'] = (pmz_EB_lst, 0)

    v0_lst = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 360, 10)]
    v1_lst_A = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 360, 10)]  # 5
    v1_lst_B = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 360, 15)]
    v1_lst_C = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 360, 36)]
    v1_lst_D = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 360, 36)]
    v1_lst_E = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 360, 10)]  # 5

    v1_lst_F = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 360, 1)]

    prec = 50

    pin.curve_dct['A'] = {
        'step0': v0_lst,
        'step1': v1_lst_A,
        'prec': prec,
        'width': 0.04
    }
    pin.curve_dct['B'] = {
        'step0': v0_lst,
        'step1': v1_lst_B,
        'prec': prec,
        'width': 0.04
    }
    pin.curve_dct['C'] = {
        'step0': v0_lst,
        'step1': v1_lst_C,
        'prec': prec,
        'width': 0.05
    }
    pin.curve_dct['D'] = {
        'step0': v0_lst,
        'step1': v1_lst_D,
        'prec': prec,
        'width': 0.05
    }
    pin.curve_dct['E'] = {
        'step0': v0_lst,
        'step1': v1_lst_E,
        'prec': prec,
        'width': 0.04
    }

    pin.curve_dct['FA'] = {
        'step0': v0_lst,
        'step1': v1_lst_F,
        'prec': prec,
        'width': 0.01
    }
    pin.curve_dct['FB'] = {
        'step0': v0_lst,
        'step1': v1_lst_F,
        'prec': prec,
        'width': 0.01
    }
    pin.curve_dct['FC'] = {
        'step0': v0_lst,
        'step1': v1_lst_F,
        'prec': prec,
        'width': 0.01
    }
    pin.curve_dct['FD'] = {
        'step0': v0_lst,
        'step1': v1_lst_F,
        'prec': prec,
        'width': 0.01
    }
    pin.curve_dct['FE'] = {
        'step0': v0_lst,
        'step1': v1_lst_F,
        'prec': prec,
        'width': 0.01
    }

    col_A = (0.6, 0.0, 0.0, 0.0)  # red
    col_B = (0.8, 0.6, 0.2, 0.0)  # beige
    col_C = (0.6, 0.0, 0.0, 0.0
             )  # red   *** rgbt2pov( ( 74, 33, 0, 0 ) )     # brown
    col_D = (0.2, 0.6, 0.0, 0.0
             )  # green *** rgbt2pov( ( 28, 125, 154, 0 ) )  # blue
    col_E = (0.2, 0.6, 0.0, 0.0)  # green
    colFF = (0.1, 0.1, 0.1, 0.0)

    pin.text_dct['A'] = [True, col_A, 'phong 0.2 phong_size 5']
    pin.text_dct['B'] = [True, col_B, 'phong 0.2 phong_size 5']
    pin.text_dct['C'] = [True, col_C, 'phong 0.2 phong_size 5']
    pin.text_dct['D'] = [True, col_D, 'phong 0.2 phong_size 5']
    pin.text_dct['E'] = [True, col_E, 'phong 0.2 phong_size 5']

    pin.text_dct['FA'] = [True, colFF, 'phong 0.2 phong_size 5']
    pin.text_dct['FB'] = [True, colFF, 'phong 0.2 phong_size 5']
    pin.text_dct['FC'] = [True, colFF, 'phong 0.2 phong_size 5']
    pin.text_dct['FD'] = [True, colFF, 'phong 0.2 phong_size 5']
    pin.text_dct['FE'] = [True, colFF, 'phong 0.2 phong_size 5']

    # raytrace image/animation
    create_pov(pin, ['C', 'D', 'FC', 'FD'])
    create_pov(pin, ['A', 'B', 'FC', 'FD'])
    create_pov(pin, ['E', 'B', 'FC', 'FD'])
コード例 #6
0
def ring_cyclide():
    '''
    Creates povray image of 4 families of circles on a ring cyclide. 
    '''

    # We construct a trigonometric parametrization of the ring cyclide,
    # by rotating a circle of radius r along a circle of radius R.
    R = 2
    r = 1
    x, y, v, w, c0, s0, c1, s1 = sage_var('x,y,v,w,c0,s0,c1,s1')
    V = sage_vector([r * c0 + R, 0, r * s0])
    M = sage_matrix([(c1, -s1, 0), (s1, c1, 0), (0, 0, 1)])
    pmz_AB_lst = [1] + list(M * V)
    OrbTools.p('pmz_AB_lst =', pmz_AB_lst)
    for pmz in pmz_AB_lst:
        OrbTools.p('\t\t', sage_factor(pmz))

    # convert pmz_AB_lst to rational parametrization pmz_lst
    C0 = (y**2 - x**2) / (y**2 + x**2)
    S0 = 2 * x * y / (y**2 + x**2)
    C1 = (w**2 - v**2) / (w**2 + v**2)
    S1 = 2 * v * w / (w**2 + v**2)
    den = (y**2 + x**2) * (w**2 + v**2)
    dct = {c0: C0, s0: S0, c1: C1, s1: S1}
    pmz_lst = [den] + [(elt.subs(dct) * den).simplify_full()
                       for elt in list(M * V)]
    OrbTools.p('pmz_lst =', pmz_lst)

    # find basepoints
    ls = LinearSeries(pmz_lst, PolyRing('x,y,v,w', True))
    OrbTools.p(ls.get_bp_tree())

    # construct linear series for families of conics
    a0, a1 = PolyRing('x,y,v,w').ext_num_field('t^2+1/3').ext_num_field(
        't^2+1').root_gens()

    p1 = ['xv', (-a0, a1)]
    p2 = ['xv', (a0, -a1)]
    p3 = ['xv', (-a0, -a1)]
    p4 = ['xv', (a0, a1)]

    bpt_1234 = BasePointTree(['xv', 'xw', 'yv', 'yw'])
    bpt_1234.add(p1[0], p1[1], 1)
    bpt_1234.add(p2[0], p2[1], 1)
    bpt_1234.add(p3[0], p3[1], 1)
    bpt_1234.add(p4[0], p4[1], 1)

    bpt_12 = BasePointTree(['xv', 'xw', 'yv', 'yw'])
    bpt_12.add(p1[0], p1[1], 1)
    bpt_12.add(p2[0], p2[1], 1)

    bpt_34 = BasePointTree(['xv', 'xw', 'yv', 'yw'])
    bpt_34.add(p3[0], p3[1], 1)
    bpt_34.add(p4[0], p4[1], 1)

    ls_22 = LinearSeries.get([2, 2], bpt_1234)  # |2(l1+l2)-e1-e2-e3-e4|
    ls_21 = LinearSeries.get([2, 1], bpt_1234)
    ls_12 = LinearSeries.get([1, 2], bpt_1234)
    ls_11a = LinearSeries.get([1, 1], bpt_12)
    ls_11b = LinearSeries.get([1, 1], bpt_34)

    OrbTools.p('linear series 22 =\n', ls_22)
    OrbTools.p('linear series 21 =\n', ls_21)
    OrbTools.p('linear series 12 =\n', ls_12)
    OrbTools.p('linear series 11a =\n', ls_11a)
    OrbTools.p('linear series 11b =\n', ls_11b)

    # compute reparametrization
    ring = PolyRing(
        'x,y,v,w,c0,s0,c1,s1')  # construct polynomial ring with new generators
    pmz_lst = ring.coerce(pmz_lst)
    x, y, v, w, c0, s0, c1, s1 = ring.gens()
    X = 1 - s0
    Y = c0
    # see get_S1xS1_pmz()
    V = 1 - s1
    W = c1
    q = sage_n(sage_sqrt(3)).exact_rational()  # approximation of sqrt(3)
    CB_dct = {x: X, y: Y, v: W * X + q * V * Y, w: V * X - q * W * Y}
    DB_dct = {x: X, y: Y, v: W * X - q * V * Y, w: V * X + q * W * Y}
    pmz_CB_lst = [pmz.subs(CB_dct) for pmz in pmz_lst]
    pmz_DB_lst = [pmz.subs(DB_dct) for pmz in pmz_lst]

    # output
    OrbTools.p('pmz_AB_lst =\n', pmz_AB_lst)
    OrbTools.p('pmz_CB_lst =\n', pmz_CB_lst)
    OrbTools.p('pmz_DB_lst =\n', pmz_DB_lst)

    # mathematica
    for pmz, AB in [(pmz_AB_lst, 'AB'), (pmz_CB_lst, 'CB'),
                    (pmz_DB_lst, 'DB')]:
        s = 'pmz' + AB + '=' + str(pmz) + ';'
        s = s.replace('[', '{').replace(']', '}')
        print(s)

    # PovInput ring cyclide
    #
    pin = PovInput()

    pin.path = './' + get_time_str() + '_ring_cyclide/'
    pin.fname = 'orb'
    pin.scale = 1
    pin.cam_dct['location'] = (0, -7, 0)
    pin.cam_dct['lookat'] = (0, 0, 0)
    pin.cam_dct['rotate'] = (55, 0, 0)  # 45
    pin.shadow = True
    pin.light_lst = [(0, 0, -5), (0, -5, 0), (-5, 0, 0), (0, 0, 5), (0, 5, 0),
                     (5, 0, 0), (-5, -5, -5), (5, -5, 5), (-5, -5, 5),
                     (5, -5, -5)]
    pin.axes_dct['show'] = False
    pin.axes_dct['len'] = 1.2
    pin.width = 800
    pin.height = 400
    pin.quality = 11
    pin.ani_delay = 10

    pin.impl = None

    pin.pmz_dct['A'] = (pmz_AB_lst, 0)
    pin.pmz_dct['B'] = (pmz_AB_lst, 1)
    pin.pmz_dct['C'] = (pmz_CB_lst, 0)
    pin.pmz_dct['D'] = (pmz_DB_lst, 0)
    pin.pmz_dct['FA'] = (pmz_AB_lst, 0)
    pin.pmz_dct['FB'] = (pmz_AB_lst, 1)
    pin.pmz_dct['FC'] = (pmz_CB_lst, 0)
    pin.pmz_dct['FD'] = (pmz_DB_lst, 0)
    pin.pmz_dct['WA'] = (pmz_AB_lst, 0)
    pin.pmz_dct['WB'] = (pmz_AB_lst, 1)
    pin.pmz_dct['WC'] = (pmz_CB_lst, 0)
    pin.pmz_dct['WD'] = (pmz_DB_lst, 0)

    v0_lst = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 360, 10)]
    v1_lst = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 360, 24)]

    v1_lst_A = [
        sage_pi / 2 + (sage_QQ(i) / 180) * sage_pi for i in range(0, 360, 12)
    ]
    v1_lstFF = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 360, 1)]

    v1_lst_WA = [
        0.1, 0.52, 0.94, 1.36, 1.78, 2.2, 2.61, 3.04, 3.45, 3.88, 4.3, 4.712,
        5.13, 5.55, 5.965
    ]
    v1_lst_WB = [
        0, 0.7, 1.31, 1.8, 2.18, 2.5, 2.77, 3.015, 3.26, 3.51, 3.78, 4.099,
        4.49, 4.97, 5.579
    ]
    v1_lst_WD = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 360, 24)]
    v1_lst_WC = [(sage_QQ(i) / 180) * sage_pi for i in range(0, 360, 24)]

    pin.curve_dct['A'] = {
        'step0': v0_lst,
        'step1': v1_lst_A,
        'prec': 10,
        'width': 0.05
    }
    pin.curve_dct['B'] = {
        'step0': v0_lst,
        'step1': v1_lst,
        'prec': 10,
        'width': 0.05
    }
    pin.curve_dct['C'] = {
        'step0': v0_lst,
        'step1': v1_lst,
        'prec': 10,
        'width': 0.05
    }
    pin.curve_dct['D'] = {
        'step0': v0_lst,
        'step1': v1_lst,
        'prec': 10,
        'width': 0.05
    }
    pin.curve_dct['FA'] = {
        'step0': v0_lst,
        'step1': v1_lstFF,
        'prec': 10,
        'width': 0.02
    }
    pin.curve_dct['FB'] = {
        'step0': v0_lst,
        'step1': v1_lstFF,
        'prec': 10,
        'width': 0.02
    }
    pin.curve_dct['FC'] = {
        'step0': v0_lst,
        'step1': v1_lstFF,
        'prec': 10,
        'width': 0.02
    }
    pin.curve_dct['FD'] = {
        'step0': v0_lst,
        'step1': v1_lstFF,
        'prec': 10,
        'width': 0.02
    }
    pin.curve_dct['WA'] = {
        'step0': v0_lst,
        'step1': v1_lst_WA,
        'prec': 10,
        'width': 0.05
    }
    pin.curve_dct['WB'] = {
        'step0': v0_lst,
        'step1': v1_lst_WB,
        'prec': 10,
        'width': 0.05
    }
    pin.curve_dct['WC'] = {
        'step0': v0_lst,
        'step1': v1_lst_WC,
        'prec': 10,
        'width': 0.05
    }
    pin.curve_dct['WD'] = {
        'step0': v0_lst,
        'step1': v1_lst_WD,
        'prec': 10,
        'width': 0.05
    }

    # A = | rotated circle
    # B = - horizontal circle
    # C = / villarceau circle
    # D = \ villarceau circle
    col_A = rgbt2pov((28, 125, 154, 0))  # blue
    col_B = rgbt2pov((74, 33, 0, 0))  # brown
    col_C = rgbt2pov((75, 102, 0, 0))  # green
    col_D = rgbt2pov((187, 46, 0, 0))  # red/orange
    colFF = rgbt2pov((179, 200, 217, 0))  # light blue

    pin.text_dct['A'] = [True, col_A, 'phong 0.2 phong_size 5']
    pin.text_dct['B'] = [True, col_B, 'phong 0.2 phong_size 5']
    pin.text_dct['C'] = [True, col_C, 'phong 0.2 phong_size 5']
    pin.text_dct['D'] = [True, col_D, 'phong 0.2 phong_size 5']
    pin.text_dct['FA'] = [True, colFF, 'phong 0.2 phong_size 5']
    pin.text_dct['FB'] = [True, colFF, 'phong 0.2 phong_size 5']
    pin.text_dct['FC'] = [True, colFF, 'phong 0.2 phong_size 5']
    pin.text_dct['FD'] = [True, colFF, 'phong 0.2 phong_size 5']
    pin.text_dct['WA'] = [True, col_A, 'phong 0.2 phong_size 5']
    pin.text_dct['WB'] = [True, col_B, 'phong 0.2 phong_size 5']
    pin.text_dct['WC'] = [True, col_C, 'phong 0.2 phong_size 5']
    pin.text_dct['WD'] = [True, col_D, 'phong 0.2 phong_size 5']

    # raytrace image/animation
    create_pov(pin, ['A', 'C', 'D'])
    create_pov(pin, ['A', 'C', 'D'] + ['FA', 'FC', 'FD'])

    create_pov(pin, ['WA', 'WB', 'WC', 'WD'])
    create_pov(pin, ['WA', 'WB', 'WC', 'WD'] + ['FA', 'FC', 'FD'])

    create_pov(pin, ['WA', 'WB', 'WD'])
    create_pov(pin, ['WA', 'WB', 'WD'] + ['FA', 'FC', 'FD'])
コード例 #7
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()
コード例 #8
0
ファイル: orb_product.py プロジェクト: niels-lubbes/orbital
def get_orb_bp_tree( pmz_lst ):
    '''
    Parameters
    ----------
    pmz_lst : list
        A list of 9 elements p0,...,p8 in QQ[c0,s0,c1,s1]
        such that -p0^2+p1^2+...+p8^2==0.
        Some of the polynomials can be equal to zero. 
        The list should represent a parametrization:
            S^1xS^1--->S^7.
        Here (c0,s0) is a points on S^1 such that
        thus c0^2+s0^2-1==0. Similarly for (c1,s1).
                                                                                 
    Returns
    -------
    linear_series.BasePointTree
        Base points of a parametrizing map given by the composition:
            P^1xP^1---->S^1xS^1--->S^7--->S^n          
        with 2<=n<=7. The composition of the latter two maps 
        are defined by omitting the zero polynomials from "pmz_lst". 
    '''

    # setup dictionary for reparametrization'
    #
    c0, s0, c1, s1 = OrbRing.coerce( 'c0,s0,c1,s1' )
    dct1 = {}
    dct1[c0] = '2*t0*t1/(t0^2+t1^2)'
    dct1[s0] = '(-t0^2+t1^2)/(t0^2+t1^2)'
    dct1[c1] = '2*v0*v1/(v0^2+v1^2)'
    dct1[s1] = '(-v0^2+v1^2)/(v0^2+v1^2)'
    for key in dct1: dct1[key] = OrbRing.coerce( dct1[key] )

    # apply reparametrization and multiply out denominators
    # where we only consider non-zero entries
    #
    ps_lst = [ pmz for pmz in pmz_lst if pmz != 0 ]
    gcm1 = OrbRing.coerce( '(t0^2+t1^2)*(v0^2+v1^2)' )
    ps_lst = [ OrbRing.coerce( ps.subs( dct1 ) * gcm1 ) for ps in ps_lst ]

    # ensure that polynomials are co-prime
    #
    gcd1 = sage_gcd( ps_lst )
    ps_lst = [ OrbRing.coerce( ps / gcd1 ) for ps in ps_lst ]
    OrbTools.p( 'gcd =', gcd1 )
    OrbTools.p( 'ps_lst =', ps_lst )

    # Verify whether "ps_lst" represents a map P^1xP^1--->S^n
    # where "n==len(ps_lst)".
    #
    sum1 = sum( [-ps_lst[0] ** 2] + [ ps ** 2 for ps in ps_lst[1:] ] )
    OrbTools.p( 'sum =', sum1 )
    if sum1 != 0:
        warnings.warn( 'Warning: Not parametrization of surface in S^7: ' + str( sum1 ), )

    # set coordinates x,y,v,w
    #
    t0, t1, v0, v1 = OrbRing.coerce( 't0,t1,v0,v1' )
    dct2 = {}
    dct2[t0] = sage_var( 'x' )
    dct2[t1] = sage_var( 'y' )
    dct2[v0] = sage_var( 'v' )
    dct2[v1] = sage_var( 'w' )
    xyvw_lst = [ str( ps.subs( dct2 ) ) for ps in ps_lst ]

    #
    # Compute base point tree using "linear_series" package
    #
    ls = LinearSeries( xyvw_lst, PolyRing( 'x,y,v,w', True ) )
    bp_tree = ls.get_bp_tree()
    OrbTools.p( ls )
    OrbTools.p( bp_tree )

    return bp_tree