Ejemplo n.º 1
0
def usecase__get_classes_dp1(rank):
    '''
    Computes classes in the Neron-Severi lattice with
    predefined self-intersection and intersection with the 
    canonical class.
    
    Parameters
    ----------
    rank : int  
    '''

    # canonical class
    d = get_ak(rank)

    # basis change
    a_lst = ['e0-e1', 'e0-e2']
    a_lst = [Div.new(a, rank) for a in a_lst]
    m1_lst = get_divs(d, 1, -1, True)
    print(d)
    M = sage_identity_matrix(rank)
    d_lst = []
    d_tup_lst = get_bases_lst(a_lst, M, d_lst, m1_lst, False)
    B = sage_matrix(sage_ZZ, [dt.e_lst for dt in d_tup_lst[0]])

    # list the classes
    for (dc, cc) in [(2, 0), (1, -1), (0, -2), (2, 2), (2, 4), (3, 1)]:
        NSTools.p('(dc, cc) =', (dc, cc))
        c_lst = get_divs(d, dc, cc, False)
        for c in c_lst:
            NSTools.p('\t\t', c, '\t\t', c.get_basis_change(B))
Ejemplo n.º 2
0
def basis_to_involution(d_lst, rank):
    '''
    Parameters
    ----------
    d_lst : list<Div>
        A list of "Div" objects of rank "rank".
    
    rank : int
        An integer in [3,...,9].
    
    Returns
    -------
    sage_MATRIX<sage_QQ>
        Returns matrix over QQ that correspond to an involution of 
            ZZ<h,e1,...,er>
        here r=rank-1. The first columns
        correspond to the elements in d_lst (where d_lst is sorted). 
        The appended columns are orthogonal to the first "len(d_lst)" columns.    
    '''
    if d_lst == []:
        return sage_identity_matrix(sage_QQ, rank)

    l = len(d_lst)
    V = complete_basis(d_lst)
    D = sage_diagonal_matrix(l * [-1] + (rank - l) * [1])
    M = V * D * V.inverse()  # MV=VD

    return M
Ejemplo n.º 3
0
def get_webs(dpl):
    '''
    Returns lists of families of conics for each possible complex basis change.
    The n-th family in each list correspond to a fixed family wrt.
    different bases for each n. 
    
    Parameters
    ----------
    dpl : DPLattice
        Represents the Neron-Severi lattice of a weak del Pezzo surface. 
        
    Returns
    -------
    list<list<Div>>
        A list of lists of Div objects. 
        Each Div object f has the property that 
        f*(3e0-e1-...-er)=2, f*f==0 and f*d>=0 for all d in dpl.d_lst.
        Such a Div object corresponds geometrically to a family of conics.
        For each index i, the i-th entry of each list of Div object corresponds
        to the same family of conics.          
    '''
    key = 'get_webs__' + str(dpl).replace('\n', '---')
    if key in NSTools.get_tool_dct():
        return NSTools.get_tool_dct()[key]

    ak = get_ak(dpl.get_rank())
    all_m1_lst = get_divs(ak, 1, -1, True)
    akc, cc = (3, 1)
    M = sage_identity_matrix(dpl.get_rank())

    fam_lst_lst = []
    for e0 in get_divs(ak, akc, cc, True):
        NSTools.p('e0 =', e0)
        for B_lst in get_bases_lst([e0], M, dpl.d_lst, all_m1_lst, True):
            B = sage_matrix(sage_ZZ, [d.e_lst for d in B_lst])
            dplB = dpl.get_basis_change(B)
            fam_lst_lst += [dplB.real_fam_lst]

    # reduce fam_lst
    pat_lst_lst = []
    rfam_lst_lst = []
    for fam_lst in fam_lst_lst:
        pat_lst = [0 if fam[0] != 1 else 1 for fam in fam_lst]
        if pat_lst not in pat_lst_lst:
            pat_lst_lst += [pat_lst]
            rfam_lst_lst += [fam_lst]

    # cache output
    NSTools.get_tool_dct()[key] = rfam_lst_lst
    NSTools.save_tool_dct()

    return rfam_lst_lst
Ejemplo n.º 4
0
    def __str__(self):

        self.set_attributes()

        s = '\n'
        s += 50 * '=' + '\n'

        s += 'Degree          = ' + str(self.get_degree()) + '\n'
        s += 'Rank            = ' + str(self.get_rank()) + '\n'
        s += 'Intersection    = ' + str(list(self.m1_lst[0].int_mat)) + '\n'
        s += 'Real structure  = ' + str(self.get_marked_Mtype()) + '\n'
        s += 'Singularities   = ' + str(self.type) + '\n'
        s += 'Cardinalities   = ' + '(' + str(len(self.or_lst)) + ', ' + str(
            len(self.sr_lst)) + ')\n'

        arrow = '  --->  '

        s += 'Real involution:\n'
        b_lst = [
            Div(row)
            for row in sage_identity_matrix(sage_ZZ, self.get_rank()).rows()
        ]
        for b in b_lst:
            s += '\t' + str(b) + arrow + str(b.mat_mul(self.M)) + '\n'

        s += 'Indecomposable (-2)-classes:\n'
        for d in self.d_lst:
            s += '\t' + str(d) + arrow + str(d.mat_mul(self.M)) + '\n'
        s += '\t#real = ' + str(len(self.real_d_lst)) + '\n'

        s += 'Indecomposable (-1)-classes:\n'
        for m1 in self.m1_lst:
            s += '\t' + str(m1) + arrow + str(m1.mat_mul(self.M)) + '\n'
        s += '\t#real = ' + str(len(self.real_m1_lst)) + '\n'

        s += 'Classes of conical families:\n'
        for fam in self.fam_lst:
            s += '\t' + str(fam) + arrow + str(fam.mat_mul(self.M)) + '\n'
        s += '\t#real = ' + str(len(self.real_fam_lst)) + '\n'

        s += 50 * '=' + '\n'

        return s
Ejemplo n.º 5
0
def usecase__construct_surfaces():
    '''
    We construct a surface parametrization and its Neron-Severi lattice. 
     
    Requires the linear_series package.
    '''

    # Blowup of projective plane in 3 colinear points
    # and 2 infinitely near points. The image of the
    # map associated to the linear series is a quartic
    # del Pezzo surface with 5 families of conics.
    # Moreover the surface contains 8 straight lines.
    #
    ring = PolyRing('x,y,z', True)
    p1 = (-1, 0)
    p2 = (0, 0)
    p3 = (1, 0)
    p4 = (0, 1)
    p5 = (2, 0)
    bp_tree = BasePointTree()
    bp_tree.add('z', p1, 1)
    bp_tree.add('z', p2, 1)
    bp_tree.add('z', p3, 1)
    bp = bp_tree.add('z', p4, 1)
    bp.add('t', p5, 1)
    ls = LinearSeries.get([3], bp_tree)
    NSTools.p(ls.get_bp_tree())
    NSTools.p('implicit equation =\n\t', ls.get_implicit_image())

    # construct NS-lattice where p1=e1,...,p5=e5
    rank = 6
    d_lst = ['e0-e1-e2-e3', 'e4-e5']  # basepoint p5 is infinitely near to p4
    Md_lst = []
    M = sage_identity_matrix(6)
    d_lst = [Div.new(d, rank) for d in d_lst]
    Md_lst = [Div.new(Md, rank) for Md in Md_lst]
    M = sage_matrix(M)
    dpl = DPLattice(d_lst, Md_lst, M)
    NSTools.p('Neron-Severi lattice =', dpl)

    # search representative for the equivalence class in classification
    assert dpl in DPLattice.get_cls(rank)
Ejemplo n.º 6
0
def is_integral_involution(M):
    '''
    Parameters
    ----------
    M : sage_matrix
        A matrix M.
    
    Returns
    -------
    bool
        Returns True if the matrix is an involution, 
        preserves inner product with signature (1,r) 
        and has integral coefficients.
    '''

    nrows, ncols = M.dimensions()

    # check whether involution
    if M * M != sage_identity_matrix(nrows):
        return False

    # check whether inner product is preserved
    S = sage_diagonal_matrix([1] + (ncols - 1) * [-1])
    if M.transpose() * S * M != S:
        return False

    # check whether coefficients are integral
    for r in range(nrows):
        for c in range(ncols):
            if M[r][c] not in sage_ZZ:
                return False

    # check whether canonical class is preserved
    ak = get_ak(nrows)
    if ak.mat_mul(M) != ak:
        return False

    return True
Ejemplo n.º 7
0
def cls_to_tex():
    '''
    Create tex code for the output of DPLattice.get_cls()
    
  
    Returns
    -------
    string
        A string representing a table of tables in Tex format.
        The table represent the classification of Neron-Severi
        lattice of weak del Pezzo surfaces.       
    '''

    # create a list of occuring divisors
    #
    div_lst = []
    for rank in range(3, 9 + 1):
        for dpl in DPLattice.get_cls(rank):

            # construct list for involution (e0,...,er)|-->(i0,...,ir)
            i_lst = [
                Div(row).mat_mul(dpl.M) for row in sage_identity_matrix(rank)
            ]

            # add each divisor that occurs to div_lst
            for elt in i_lst + dpl.d_lst:
                div_lst += [Div(elt.e_lst + (9 - len(elt.e_lst)) * [0])]
    div_lst = list(set(div_lst))
    div_lst.sort()
    e0 = Div([1, 0, 0, 0, 0, 0, 0, 0, 0])
    div_lst.remove(e0)
    div_lst = [e0] + div_lst

    # create dictionary characters for elements in div_lst
    #
    abc = 'abcdefghijklmnopqrstuvwxyz'
    ch_lst = []
    ch_lst += [
        '\\frac{' + ch1 + '}{' + ch2 + '}\\!' for ch1 in '0123456789'
        for ch2 in '0123456789'
    ]
    ch_lst += [
        '\\frac{' + ch1 + '}{' + ch2 + '}\\!' for ch1 in '0123456789'
        for ch2 in 'abcdef'
    ]

    NSTools.p('(len(ch_lst), len(div_lst)) =', (len(ch_lst), len(div_lst)))

    assert len(ch_lst) >= len(div_lst)

    # create legend and dictionary
    #
    lgd_lst = []
    sym_dct = {}
    for i in range(len(div_lst)):
        sym_dct.update({str(div_lst[i]): ch_lst[i]})
        lgd_lst += [[
            '$' + ch_lst[i] + '$ :',
            ('$' + str(div_lst[i]) + '$').replace('e', 'e_')
        ]]
    while len(lgd_lst) % 3 != 0:
        lgd_lst += [['', '']]
    nnrows = len(lgd_lst) / 3

    # create tex for legend
    #
    tex_lgd = ''
    tex_lgd += '\\begin{table}\n'
    tex_lgd += '\\setstretch{1.4}\n'
    tex_lgd += '\\tiny\n'
    tex_lgd += '\\caption{Classification of Neron-Severi lattices of weak del Pezzo surfaces (see THM{nsl})}\n'
    tex_lgd += '\\label{tab:nsl}\n'
    tex_lgd += 'A dictionary for symbols in the columns $\\sigma_A$ and $B$:\n\\\\\n'
    tex_lgd += '\\begin{tabular}{@{}l@{}l@{~~~~}l@{}l@{~~~~}l@{}l@{}}\n'
    for idx in range(nnrows):
        c1, c2, c3, c4, c5, c6 = lgd_lst[idx] + lgd_lst[
            idx + nnrows] + lgd_lst[idx + 2 * nnrows]
        tex_lgd += c1 + ' & ' + c2 + ' & ' + c3 + ' & ' + c4 + ' & ' + c5 + ' & ' + c6
        tex_lgd += '\\\\\n'
    tex_lgd += '\\end{tabular}\n'
    tex_lgd += '\\end{table}\n\n'

    # number of rows of the big table
    #
    nrows = 57

    # dictionary for replacing string symbols
    #
    rep_dct = {
        'A': 'A_',
        'D': 'D_',
        'E': 'E_',
        '{': '\\underline{',
        '[': '\\udot{',
        ']': '}'
    }

    # create classification table
    #
    tab_lst = []

    # rank 1 and 2
    tab9 = [['i  ', '$9$', "$A_0 $", '$A_0$', '$0$', '$1$', '']]
    tab8 = [['ii ', '$8$', "$A_0 $", '$A_0$', '$0$', '$2$', ''],
            ['iii', '$8$', "$A_0 $", '$A_0$', '$0$', '$1$', ''],
            ['iv ', '$8$', "$A_0 $", '$A_0$', '$1$', '$1$', ''],
            ['v  ', '$8$', "$A_0 $", '$A_1$', '$0$', '$1$', '']]
    tab_lst += [tab9, tab8]

    # rank 3,4,5,6,7,8 and 9
    idx = 0
    Mtype_lst = ['A1', '4A1']  # for breaking up table for degree 2 case
    for rank in range(3, 9 + 1):

        tab = []
        for dpl in DPLattice.get_cls(rank):

            col1 = '$' + str(idx) + '$'

            col2 = '$' + str(dpl.get_degree()) + '$'

            col3 = '$' + str(dpl.get_marked_Mtype()) + '$'
            for key in rep_dct:
                col3 = str(col3).replace(key, rep_dct[key])

            col4 = '$' + str(dpl.get_real_type()) + '$'
            for key in rep_dct:
                col4 = str(col4).replace(key, rep_dct[key])

            col5 = '$' + str(dpl.get_numbers()[4]) + '$'

            col6 = '$' + str(dpl.get_numbers()[5]) + '$'

            i_lst = [
                str(Div(rw).mat_mul(dpl.M))
                for rw in sage_identity_matrix(rank)
            ]
            col7 = ''
            for i in i_lst:
                col7 += sym_dct[i]
            if col7 in [
                    '012', '0123', '01234', '012345', '0123456', '01234567',
                    '012345678'
            ]:
                col7 = ''

            col8 = ''
            for d in dpl.d_lst:
                col8 += sym_dct[str(d)]

            # these subroot systems cannot be realized as weak del Pezzo surfaces
            if col4 in [
                    '$7\underline{A_1}$', '$8\underline{A_1}$',
                    '$4\underline{A_1}+\underline{D_4}$'
            ]:
                col1 = '$\\times$'

            # break (sometimes) the table for degree 2 according to Mtype
            if dpl.get_degree() == 2 and dpl.Mtype in Mtype_lst:
                nheaders = len(
                    tab) / nrows  # each header shifts the row number
                while len(
                        tab
                ) % nrows != nrows - 1 - nheaders:  # add rows until end of table
                    tab += [7 * ['']]
                Mtype_lst.remove(dpl.Mtype)

            # add row
            tab += [[
                col1, col2, col3, col4, col5, col6,
                '$' + col7 + '||\!' + col8 + '$'
            ]]
            idx += 1

        tab_lst += [tab]

    # reformat table
    #
    #         i     d     A     B     E     G     Ac%Bc
    hl = '@{~}l@{~~~}l@{~~~}l@{~~}l@{~~}l@{~~}l@{~~}l@{}'
    hrow = ['', 'd', '$D(A)$', '$D(B)$', '$\#E$', '$\#G$', '$\sigma_A||B$']
    etab_lst = []
    etab = [hrow]
    tab_idx = 0
    for tab in tab_lst:

        for row in tab:
            if len(etab) >= nrows:
                etab_lst += [etab]
                etab = [hrow]
            etab += [row]

        if len(etab) < nrows and tab_idx <= 3:
            etab += [
                7 * [''], 7 * ['']
            ]  # add two empty rows to separate tables with different rank
        else:
            while len(etab) < nrows:
                etab += [7 * ['']]  # add empty rows to fill up table
            etab_lst += [etab]
            etab = [hrow]

        tab_idx += 1
    NSTools.p('etab_lst: ', [len(etab) for etab in etab_lst])

    # create tex for main classification table
    #
    tex_tab = ''
    tab_idx = 0
    for etab in etab_lst:

        if tab_idx % 2 == 0:
            tex_tab += '\\begin{table}\n'
            tex_tab += '\\setstretch{1.6}\n'
            tex_tab += '\\centering\\tiny\n'
            tex_tab += '\\begin{tabular}{@{}l@{\\hspace{1cm}}l@{}}\n'
        elif tab_idx % 2 == 1:
            tex_tab += '&\n'

        tex_tab += '\\begin{tabular}{' + hl + '}\n'
        for row in etab:
            col1, col2, col3, col4, col5, col6, col78 = row
            tex_tab += col1 + ' & ' + col2 + ' & ' + col3 + ' & ' + col4 + ' & '
            tex_tab += col5 + ' & ' + col6 + ' & ' + col78
            tex_tab += ' \\\\\n'
            if row == hrow:
                tex_tab += '\\hline\n'

        tex_tab += '\\end{tabular}\n'

        if tab_idx % 2 == 1:
            tex_tab += '\\end{tabular}\n'
            tex_tab += '\\end{table}\n\n'

        tab_idx += 1

    if tab_idx % 2 == 1:
        tex_tab += '&\n'
        tex_tab += '\\end{tabular}\n\n'

    # creating tex for commands
    tex_cmd = ''
    tex_cmd += '\\newcommand{\\udot}[1]{\\tikz[baseline=(todotted.base)]{\\node[inner sep=1pt,outer sep=0pt] (todotted) {$#1$};\\draw[densely dotted] (todotted.south west) -- (todotted.south east);}}'
    tex_cmd += '\n'
    tex_cmd += '\\newcommand{\\udash}[1]{\\tikz[baseline=(todotted.base)]{\\node[inner sep=1pt,outer sep=0pt] (todotted) {$#1$};\\draw[densely dashed] (todotted.south west) -- (todotted.south east);}}'
    tex_cmd += '\n\n'

    out = tex_cmd + tex_lgd + tex_tab

    return out
Ejemplo n.º 8
0
    def get_bas_lst(rank=9):
        '''
        See [Algorithm 5, http://arxiv.org/abs/1302.6678] for more info. 
        
        Parameters
        ----------
        rank : int
            An integer in [3,...,9].    
        
        Returns
        -------
        list<DPLattice>
            A list of "DPLattice" objects dpl such that dpl.d_lst 
            is the bases of a root subsystem and dpl.Mtype == A0. 
            The list contains exactly one representative for all 
            root subsystems up to equivalence.  
             
            The list represents a classification of root 
            subsystems of the root system with Dynkin type either:
                A1, A1+A2, A4, D5, E6, E7 or E8,
            corresponding to ranks 3, 4, 5, 6, 7, 8 and 9 respectively 
            (eg. A1+A2 if rank equals 4, and E8 if rank equals 9).
            Note that the root systems live in a subspace of 
            the vector space associated to the Neron-Severi lattice 
            of a weak Del Pezzo surface.
        '''
        # check whether classification of root bases is in cache
        key = 'get_bas_lst__' + str(rank)
        if key in NSTools.get_tool_dct():
            return NSTools.get_tool_dct()[key]

        NSTools.p('start')

        A = [12, 23, 34, 45, 56, 67, 78]
        B = [1123, 1145, 1456, 1567, 1678, 278]
        C = [1127, 1347, 1567, 234, 278, 308]
        D = [1123, 1345, 1156, 1258, 1367, 1247, 1468, 1178]

        dpl_lst = []
        for (lst1, lst2) in [(A, []), (A, B), (A, C), ([], D)]:

            # restrict to divisors in list, that are of rank at most "max_rank"
            lst1 = [
                Div.new(str(e), rank) for e in lst1
                if rank >= Div.get_min_rank(str(e))
            ]
            lst2 = [
                Div.new(str(e), rank) for e in lst2
                if rank >= Div.get_min_rank(str(e))
            ]

            # the involution is trivial
            Md_lst = []
            M = sage_identity_matrix(sage_QQ, rank)

            # loop through the lists
            sub1 = sage_Subsets(range(len(lst1)))
            sub2 = sage_Subsets(range(len(lst2)))
            eta = ETA(len(sub1) * len(sub2), 20)
            for idx2_lst in sub2:
                for idx1_lst in sub1:

                    eta.update('get_bas_lst rank =', rank)

                    d_lst = [lst1[idx1] for idx1 in idx1_lst]
                    d_lst += [lst2[idx2] for idx2 in idx2_lst]

                    if not is_root_basis(d_lst):
                        continue

                    dpl = DPLattice(d_lst, Md_lst, M)

                    if dpl not in dpl_lst:
                        dpl.set_attributes()
                        dpl_lst += [dpl]

        # cache output
        dpl_lst.sort()
        NSTools.get_tool_dct()[key] = dpl_lst
        NSTools.save_tool_dct()

        return dpl_lst