Пример #1
0
    def test__qmat__qpol(self):
        x = MARing.x()
        q = MARing.q()

        g_lst = DSegre.get_ideal_lst()
        chk_qpol = 0
        for i in range(len(g_lst)):
            chk_qpol += q[i] * g_lst[i]

        qmat = DSegre.get_qmat()
        qpol = list(sage_vector(x).row() * qmat *
                    sage_vector(x).column())[0][0]
        assert qpol == chk_qpol
Пример #2
0
    def get_qmat(exc_idx_lst=[]):
        '''        
        Parameters
        ----------
        exc_idx_lst : list<int>
            A list of integers in [0,8].      
              
        Returns
        -------
        sage_matrix<MARing.R>
            A symmetric 9x9 matrix with entries
            in the ring QQ[q0,...,q19] which is a subring 
            of "MARing.R". It represents the Gramm matrix 
            of a quadratic form in the ideal of the              
            double Segre surface or a projection of 
            the double Segre surface with ideal defined
            by "get_ideal_lst( exc_idx_lst )".
            
        Method
        ------
        We obtain generators of the ideal 
        of the (projection of) the double Segre surface
        with the method "get_ideal_lst( exc_idx_lst )".
        If the ideal is of a projection of the double Segre
        surface, then the returned matrix with parameters
        q0,...,q19 is not of full rank.                        
        '''
        x = MARing.x()
        q = MARing.q()

        g_lst = DSegre.get_ideal_lst(exc_idx_lst)
        qpol = 0
        for i in range(len(g_lst)):
            qpol += q[i] * g_lst[i]

        qmat = sage_invariant_theory.quadratic_form(
            qpol, x).as_QuadraticForm().matrix()
        qmat = sage_matrix(MARing.R, qmat)

        return qmat
Пример #3
0
    def get_qmat():
        '''
        Returns
        -------
        sage_matrix
            A symmetric 5x5 matrix with entries in the 
            ring QQ[q0,...,q5] which is a subring 
            of "MARing.R". It represents the Gramm matrix 
            of a quadratic form in the ideal of the              
            Veronese with ideal defined by ".get_ideal_lst()".                        
        '''
        x = MARing.x()[:6]
        q = MARing.q()[:6]

        g_lst = Veronese.get_ideal_lst()
        qpol = 0
        for i in range(len(g_lst)):
            qpol += q[i] * g_lst[i]

        qmat = sage_invariant_theory.quadratic_form(
            qpol, x).as_QuadraticForm().matrix()
        qmat = sage_matrix(MARing.R, qmat)

        return qmat
Пример #4
0
    def get_invariant_qf(c_lst_lst, exc_idx_lst=[]):
        '''
        Computes quadratic forms in the ideal of the
        double Segre surface that are invariant under
        a given subgroup of Aut(P^1xP^1). 
        
        Parameters
        ----------        
        c_lst_lst : list<list<MARing.FF>>  
            A list of "c_lst"-lists.
            A c_lst is a list of length 8 with elements 
            c0,...,c7 in QQ(k), 
            where QQ(k) is a subfield of "MARing.FF".
            If we substitute k:=0 in the entries of 
            "c_lst" then we should obtain the list:
                [1,0,0,1,1,0,0,1].                                                                      
            A c_lst represents a pair of two matrices:                                
                ( [ c0 c1 ]   [ c4 c5 ] ) 
                ( [ c2 c3 ] , [ c6 c7 ] )                                   
            with the property that 
                c0*c3-c1*c2!=0 and c4*c7-c5*c6!=0.
            If the two matrices are not normalized
            to have determinant 1 then the method should be 
            taken with care (it should be checked that the
            tangent vectors at the identity generate the 
            correct Lie algebra).                                             
        
        exc_idx_lst : list<int>
            A list of integers in [0,8].                                     
        
        Returns
        -------
        A list of quadratic forms in the ideal of (a projection of) 
        the double Segre surface S:
            ".get_ideal_lst( exc_idx_lst )"
        such that the quadratic forms are invariant 
        under the automorphisms of S as defined by "c_lst_lst"
        and such that the quadratic forms generate the module of  
        all invariant quadratic forms. Note that Aut(S)=Aut(P^1xP^1).   
        '''

        # for verbose output
        #
        mt = MATools()
        sage_set_verbose(-1)

        # initialize vectors for indeterminates of "MARing.R"
        #
        x = MARing.x()
        q = MARing.q()
        r = MARing.r()

        # obtain algebraic conditions on q0,...,q19
        # so that the associated quadratic form is invariant
        # wrt. the automorphism defined by input "c_lst_lst"
        #
        iq_lst = []
        for c_lst in c_lst_lst:
            iq_lst += DSegre.get_invariant_q_lst(c_lst, exc_idx_lst)
        iq_lst = list(MARing.R.ideal(iq_lst).groebner_basis())

        # solve the ideal defined by "iq_lst"
        #
        sol_dct = MARing.solve(iq_lst, q)

        # substitute the solution in the quadratic form
        # associated to the symmetric matrix qmat.
        #
        qmat = DSegre.get_qmat(exc_idx_lst)
        qpol = list(sage_vector(x).row() * qmat *
                    sage_vector(x).column())[0][0]
        sqpol = qpol.subs(sol_dct)
        mt.p('sqpol   =', sqpol)
        mt.p('r       =', r)
        assert sqpol.subs({ri: 0 for ri in r}) == 0
        iqf_lst = []  # iqf=invariant quadratic form
        for i in range(len(r)):
            coef = sqpol.coefficient(r[i])
            if coef != 0:
                iqf_lst += [coef]
        mt.p('iqf_lst =', iqf_lst)

        return iqf_lst
Пример #5
0
    def change_basis(iqf_lst, involution='identity'):
        '''
        This method allows us to change coordinates of the 
        ideal generated by "iqf_lst" so that 
        the antiholomorphic involution defined by "involution"
        becomes complex conjugation.
                        
        Parameters
        ----------
        iqf_lst: list<MARing>     
            A list of elements in the subring NF[x0,...,x8] 
            of "MARing.R" where NF denotes the Gaussian 
            rationals QQ(I) with I^2=-1.
                               
        involution: str  
            Either one of the following strings:
            'identity', 'leftright', 'rotate', 'diagonal'.

        Returns
        -------
            We consider the input "iqf_lst" as a map. 
            We compose this map composed with the map corresponding to 
            <identity>, <leftright>, <rotate> or <diagonal>.
            We return a list of elements in NF[x0,...,x8] that
            represents the composition.
            
        Notes
        ----- 
        A double Segre surface in projective 8-space P^8 is represented 
        by a toric parametrization whose completion to P^1xP^1 is provided 
        by "get_pmz_lst": 
            
            (s,u) |-->
            (1:s:s^{-1}:u:u^{-1}:s*u:s^{-1}*u^{-1}:s*u^{-1}:s^{-1}*u)
            =
            (x0:x1:x2:x3:x4:x5:x6:x7:x8)
            
        We can put the exponents of the monomials in a lattice
        where x0 corresponds to coordinate (0,0), x6 to (-1,-1)
        x5 to (1,1) and x8 to (-1,1): 
                    
            x8 x3 x5
            x2 x0 x1
            x6 x4 x7
                  
        An antiholomorphic involution, that preserves the toric structure,
        acts on the above lattice as a unimodular involution:
                  
            identity_*:    ( a, b ) |--> ( a, b)
            leftright_*:   ( a, b ) |--> (-a, b)
            rotate_*:      ( a, b ) |--> (-a,-b)  
            diagonal_*:    ( a, b ) |--> ( b, a)
        
        These unimodular lattice involutions induce an involution on P^8.
        
        We compose the toric parametrization of the double Segre surface 
        with the one of the following maps in order to make the antiholomorphic
        involution that acts on P^8, equal to complex conjugation.  

            identity: (x0:...:x8) |--> (x0:...:x8) 

            leftright:  x3 |--> x3,
                        x0 |--> x0,  
                        x4 |--> x4,                     
                        x1 |--> x1 + I*x2, 
                        x2 |--> x1 - I*x2, 
                        x5 |--> x5 + I*x8, 
                        x8 |--> x5 - I*x8,                                
                        x7 |--> x7 + I*x6,
                        x6 |--> x7 - I*x6 
                                 
            rotate: x0 |--> x0,
                    x1 |--> x1 + I*x2, x2 |--> x1 - I*x2, 
                    x3 |--> x3 + I*x4, x4 |--> x3 - I*x4, 
                    x5 |--> x5 + I*x6, x6 |--> x5 - I*x6, 
                    x7 |--> x7 + I*x8, x8 |--> x7 - I*x8      
                            
            diagonal:   x5 |--> x5,
                        x0 |--> x0, 
                        x6 |--> x6, 
                        x3 |--> x3 + I*x1,  
                        x1 |--> x3 - I*x1,
                        x8 |--> x8 + I*x7,  
                        x7 |--> x8 - I*x7,
                        x2 |--> x2 + I*x4,  
                        x4 |--> x2 - I*x4  
        '''

        I = ring('I')
        x = x0, x1, x2, x3, x4, x5, x6, x7, x8 = MARing.x()
        z = z0, z1, z2, z3, z4, z5, z6, z7, z8 = MARing.z()

        dct = {}

        dct['identity'] = {x[i]: z[i] for i in range(9)}

        dct['rotate'] = {
            x0: z0,
            x1: z1 + I * z2,
            x2: z1 - I * z2,
            x3: z3 + I * z4,
            x4: z3 - I * z4,
            x5: z5 + I * z6,
            x6: z5 - I * z6,
            x7: z7 + I * z8,
            x8: z7 - I * z8
        }

        dct['leftright'] = {
            x0: z0,
            x3: z3,
            x4: z4,
            x5: z5 + I * z8,
            x8: z5 - I * z8,
            x1: z1 + I * z2,
            x2: z1 - I * z2,
            x7: z7 + I * z6,
            x6: z7 - I * z6
        }

        dct['diagonal'] = {
            x0: z0,
            x6: z6,
            x5: z5,
            x3: z3 + I * z1,
            x1: z3 - I * z1,
            x8: z8 + I * z7,
            x7: z8 - I * z7,
            x2: z2 + I * z4,
            x4: z2 - I * z4
        }

        zx_dct = {z[i]: x[i] for i in range(9)}

        new_lst = [iqf.subs(dct[involution]).subs(zx_dct) for iqf in iqf_lst]

        return new_lst
Пример #6
0
    def change_basis(iqf_lst):
        '''
        Parameters
        ----------
        iqf_lst : list     
            A list of elements in the subring NF[x0,...,x5] 
            of "MARing.R" where NF denotes the Gaussian 
            rationals QQ(I) with I^2=-1.
                                                                       
        Returns
        -------
        list 
            The input "iqf_lst" where we make the following substitution            
            for each polynomial  
                x0 |--> x0,
                x1 |--> x1, 
                x2 |--> x2 + I*x3, 
                x3 |--> x2 - I*x3,  
                x4 |--> x4 + I*x5,
                x5 |--> x4 - I*x5.               
                                     
        Notes
        -----
        We consider a toric parametrization of the Veronese surface:
        
        (s,t)
        |-->
        (1  : s*t : s  : t  : s^2 : t^2 )
        =
        (x0 : x1  : x2 : x3 : x4  : x5  )
                            
        We can put the exponents of the monomials in a lattice
        where x0 corresponds to coordinate (0,0), x4 to (2,0)
        and x5 to (0,2):  
                
              x5 x7 x8      
              x3 x1 x6
              x0 x2 x4  
        
        The monomial parametrization of the Veronese corresponds to the 
        following lattice polygon:
        
              *
              * *
              * * * 
              
        An antiholomorphic involution acts on the above lattice polygon 
        as a unimodular involution:
              
                ( a, b ) |--> ( b, a)
        
        This unimodular lattice involutions induce an involution on P^5: 

                x0 |--> x0,
                x1 |--> x1, 
                x2 |--> x2 + I*x3, 
                x3 |--> x2 - I*x3,  
                x4 |--> x4 + I*x5,
                x5 |--> x4 - I*x5,                                  
        '''

        I = ring('I')
        x = x0, x1, x2, x3, x4, x5 = MARing.x()[:6]
        z = z0, z1, z2, z3, z4, z5 = MARing.z()[:6]

        dct = {
            x0: z0,
            x1: z1,
            x2: z2 + I * z3,
            x3: z2 - I * z3,
            x4: z4 + I * z5,
            x5: z4 - I * z5
        }

        zx_dct = {z[i]: x[i] for i in range(6)}
        new_lst = [iqf.subs(dct).subs(zx_dct) for iqf in iqf_lst]

        return new_lst
Пример #7
0
    def get_invariant_qf(c_lst_lst):
        '''
        Parameters
        ----------    
        c_lst_lst : list 
            A list of "c_lst"-lists.
            A c_lst is a list of length 9 with elements 
            c0,...,c8 in the subring in QQ(k)  of "MARing.FF". 
            The matrix                         
                [ c0 c1 c2 ]
            M = [ c3 c4 c5 ]
                [ c6 c7 c8 ]                                                         
            represents---for each value of k---an 
            automorphism of P^2. If we set k:=0 then 
            "c_lst" must correspond to the identity matrix: 
            [ 1,0,0, 0,1,0, 0,0,1 ]. If M is not normalized
            to have determinant 1 then the method should be 
            taken with care (see doc. ".get_c_lst_lst_dct").         
        
        Returns
        -------
        list<MARing.R>
            A list of quadratic forms in the ideal of the Veronese surface V
            (see ".get_ideal_lst()"), such that the quadratic forms are 
            invariant under the automorphisms of V as defined by "c_lst_lst"
            and such that the quadratic forms generate the module of  
            all invariant quadratic forms. Note that Aut(V)=Aut(P^2).   
        '''

        # for verbose output
        #
        mt = MATools()

        # initialize vectors for indeterminates of "MARing.R"
        #
        x = MARing.x()[:6]
        q = MARing.q()[:6]
        r = MARing.r()[:6]

        # obtain algebraic conditions on q0,...,q19
        # so that the associated quadratic form is invariant
        # wrt. the automorphism defined by input "c_lst_lst"
        #
        iq_lst = []
        for c_lst in c_lst_lst:
            iq_lst += Veronese.get_invariant_q_lst(c_lst)
        iq_lst = list(MARing.R.ideal(iq_lst).groebner_basis())

        # solve the ideal defined by "iq_lst"
        #
        sol_dct = MARing.solve(iq_lst, q)

        # substitute the solution in the quadratic form
        # associated to the symmetric matrix qmat.
        #
        qmat = Veronese.get_qmat()
        qpol = list(sage_vector(x).row() * qmat *
                    sage_vector(x).column())[0][0]
        sqpol = qpol.subs(sol_dct)
        mt.p('sqpol   =', sqpol)
        mt.p('r       =', r)
        assert sqpol.subs({ri: 0 for ri in r}) == 0
        iqf_lst = []  # iqf=invariant quadratic form
        for i in range(len(r)):
            coef = sqpol.coefficient(r[i])
            if coef != 0:
                iqf_lst += [coef]
        mt.p('iqf_lst =', iqf_lst)

        return iqf_lst
Пример #8
0
    def test__get_aut_P8__rotation_matrix(self):
        '''
        OUTPUT:
            - We verify that for the 1-parameter subgroup of rotations 
              with matrix
              
                  [ cos(k) -sin(k) ]
                  [ sin(k)  cos(k) ]
            
              it is for our Lie algebra methods sufficient to consider 
              1-parameter subgroups that have the same tangent vector
              at the identity. Note that for k=0 we need to get the identity
              and the determinant should be 1.   
        '''
        k = ring('k')
        I = ring('I')
        a, b, c, d, e, f, g, h = ring('a, b, c, d, e, f, g, h')
        x = MARing.x()
        q = MARing.q()
        r = MARing.r()

        #
        # We consider the representation of the
        # following matrix into P^8
        #
        #   (  [ 1 -k ] ,  [ 1 0 ] )
        #   (  [ k  1 ]    [ 0 1 ] )
        #
        # We define A to be the tangent vector at the
        # identity of this representation
        #
        N = DSegre.get_aut_P8([1, -k, k, 1] + [1, 0, 0, 1])
        A = MARing.diff_mat(N, k).subs({k: 0})

        #
        # We consider the representation of the
        # following matrix into P^8
        #
        #   (  [ cos(k) -sin(k) ] ,  [ 1 0 ] )
        #   (  [ sin(k)  cos(k) ]    [ 0 1 ] )
        #
        # We define B to be the tangent vector at the
        # identity of this representation
        #
        M = DSegre.get_aut_P8([a, b, c, d] + [e, f, g, h])

        a, b, c, d, e, f, g, h = sage_var('a, b, c, d, e, f, g, h')
        k = sage_var('k')
        M = sage__eval(str(list(M)), {
            'a': a,
            'b': b,
            'c': c,
            'd': d,
            'e': e,
            'f': f,
            'g': g,
            'h': h,
            'k': k
        })
        M = sage_matrix(M)
        M = M.subs({
            a: sage_cos(k),
            b: -sage_sin(k),
            c: sage_sin(k),
            d: sage_cos(k),
            e: 1,
            f: 0,
            g: 0,
            h: 1
        })

        # differentiate the entries of M wrt. k
        dmat = []
        for row in M:
            drow = []
            for col in row:
                drow += [sage_diff(col, k)]
            dmat += [drow]
        M = sage_matrix(dmat)
        B = M.subs({k: 0})

        assert str(A) == str(B)