################################################ # From the Bergman fan of E6 to the Naruki fan # ################################################ #The following functions are used to compute the Naruki fan from the Bergman fan of E6 and ensure that the 40x36 0-1 matrix mapping the Bergman fan to the Naruki fan is a map of fans. # The algorithm starts from the Bergman fan and the matrix and constructs the Naruki fan as a set: it is the union of the images of the maximal cones C from Berg(E6). We realize this image as the cone spanned by the images of the corresponding rays in C. # By the action of Berg(E6) we need only check the images of the 21 orbit-representatives of maximal cones in Berg(E6) and action on W(E6) to obtain the cells in the image. # We first compute the dimension of the images of the 21 orbits, and conclude that the dimension of the Naruki fan is 4 (5 if we consider the image of the map in R^40). In particular, this implies that when computing the images of maximal cones, we only need to keep the ones that have maximal dimension. The images of the remaining cones will be contained in the ones that have maximal dimension. # A preliminary calculation shows that the dimension of any cone (not only of maximal dimension) need not be preserved under the linear map. Indeed, when looking at the images of rays, we obtain 3 types of rays coming from 5 orbits of rays in Berg(E6). The remaining two orbits map to a multiple of the all-ones vectors, and hence map to the origin in the 39-dimensional tropical projective torus. # The relevant function is "yoshida_cone_orbits". It can be adapted to only consider images of cones that don't drop dimension when viewed in R^40. # Using this function we find three types of rays: 36 rays of type (a), 40 rays of type (b) and 270 rays of type (a2), i.e. sums of 2 type (a) rays. # Using yoshida_cone_orbits(Yoshida_matrix, BergmanFan[1][4],5) we conclude that the Naruki fan is the union of the W(E6)-orbits of Yoshida_map([0,1,4,36]) and Yoshida_map([0,1,4,29]). These cones are of type (aaaa) and (aaab). # Once the above set description of the Naruki fan is given, it goes over the list of all the cones and refines the structure by checking overlaps between cones and adding the rays of the overlap (a polyhedron) to the list of rays in the Naruki fan. These rays are obtained from a baricentric subdivision of cone (aaaa) and the induced subdivision of (aaab). The rays added are of type (a2), described above), type (a3) = sum of 3 type (a) rays and type (a4) = sum of 4 type (a) rays. ######################################### # Data associated to the root system E6 # ######################################### RootSystemE6 = load("../../General/L6.sobj") L6 = RootSystemE6.root_lattice() # L6.dynkin_diagram() # O 2 # | # | # O---O---O---O---O # 1 3 4 5 6 # E6 #diagram = [{1,3}, {3,4}, {4,2}, {4,5}, {5,6}] # Weyl group # These are in the alpha basis weyl_gens = L6.weyl_group().gens() os.chdir("../../Yoshida/Scripts") load("Yoshida.sage") os.chdir("../../NarukiFan/Scripts") ############################################### # Data associated to the Bergman fan Berg(E6) # ############################################### # This data was computed in the folder BergmanFan and in Yoshida. E6_1_Numbers = load("../../BergmanFan/Scripts/Input/E6_1_Numbers.sobj") E6_2_Numbers = load("../../BergmanFan/Scripts/Input/E6_2_Numbers.sobj") E6_4_Numbers = load("../../BergmanFan/Scripts/Input/E6_4_Numbers.sobj") E6_7_Numbers = load("../../BergmanFan/Scripts/Input/E6_7_Numbers.sobj") E6_8_Numbers = load("../../BergmanFan/Scripts/Input/E6_8_Numbers.sobj") E6_12_Numbers = load("../../BergmanFan/Scripts/Input/E6_12_Numbers.sobj") E6_13_Numbers = load("../../BergmanFan/Scripts/Input/E6_13_Numbers.sobj") vertexIndexListE6 = E6_1_Numbers[1] + E6_2_Numbers[1]+E6_4_Numbers[1]+E6_7_Numbers[1]+E6_8_Numbers[1]+E6_12_Numbers[1]+E6_13_Numbers[1] # We load the Bergman fan of E6: BergmanFan = load("../../BergmanFan/Output/BergmanFanOfE6TruncatedFVectorAndOrbitsPerDimension.sobj") ############################### # Functions for Bergman Cones # ############################### ##################################### # Construction of cones of Berg(E6) # ##################################### # The following function converts a flat of a matroid given as a complete list of all indices of elements in the ground set contained in the flat. def flat_to_vertex(flat): v = zero_vector(36) for root in flat: v[root] = 1 return v # The following function picks a cell in the Bergman complex (given as a list of vertex indices) and returns the list of 0-1 incidence vectors giving the rays of the cone over the input cell. # vertexIndexListE6 is the list of all flats of the reflection arrangement E6. # "flat_numbers" = list of vertex indices generating a cell in the Bergman complex of E6 def cone_from_flat_numbers(flat_numbers): vs = [flat_to_vertex(vertexIndexListE6[f]) for f in flat_numbers] return vs ########################################################################## # Projection to canonical representatives in a tropical projective torus # ########################################################################## # The following function picks a vertex and computes its canonical representative in the tropical projective torus by setting the last coordinate to be 0. # v = vector with real entries. def projection(v): last = v[-1] subtract = vector([v[-1] for i in range(0, len(v))]) return v - subtract ################################################################################## # Compute the images of cones whose dimension is preserved under the Yoshida map # ################################################################################## # The following function picks orbits of cones of fixed dimension in the Bergman fan Berg(E6) and computes a tuple with 3 entries: # (1) "cone_representatives" = list of pairs, where the first entry is a W(E6)-orbit representative of cones in Berg(E6) (given as a list of vertex indices) whose image under the yoshida_matrix has dimension = dim when viewed in R^40. The second entry in the pair is the list of the images of the vertices in the first entry under the yoshida_matrix (the result is a list of vertices in R^40). # (2) "containments" = list of pairs where the first entry is a representative of an orbit in Berg(E6) whose image has the expected dimension "dim" and the second one is a cone in Berg(E6) whose image under the Yoshida_matrix lies inside the image of the first entry. # (3) "overlaps" = list of pairs of cones in the Naruki fan that overlap. # Input data: # orbits = list of cells (each given as a list of vertex indices) in a fixed W(E6)-orbit # yoshida_matrix = 40x36 matrix associated to the tropical Yoshida map. # dim = expected dimension of the image cones in R^40 (i.e. before looking at the image in the tropical projective torus R^40/R.(1,...,1) ) def yoshida_cone_orbits(yoshida_matrix, orbits, dim): cone_representatives = [] containments = [] overlaps = [] # First, select the full dimensional orbits in the domain that map to cones of the expected dimension dim viewed in R^40. full_orbits = [] for orbit in orbits: flats = orbit[0] Ycone = [yoshida_matrix*v for v in cone_from_flat_numbers(flats)] if span(Ycone).dimension() == dim: full_orbits.append(orbit) # Next, order (arrange) the full dimensional orbits in the domain collected in "full_orbits" by volume (in descending order) # The following function computes the square of the volume of a cone in Berg(E6) (in its linear span) def volume_square(flat_numbers): # cone in Bergman fan of E6 from the list of vertices cone = cone_from_flat_numbers(flat_numbers) # we take an orthonormal basis spanning the cone to normalize the volume basis = span(cone).basis_matrix().gram_schmidt()[0] transform = matrix(cone).transpose()\basis.transpose() return transform.det()^2 / prod([c.norm()^2 for c in cone]) * prod([b.norm()^2 for b in basis.rows()]) # We sort the orbits by the volume_square, in descending order, to organize the search of containments and overlaps. Note that we always choose the first cone in each orbit as a representative. full_orbits.sort(key=lambda o: volume_square(o[0]), reverse=True) for orbit in full_orbits: print "Next orbit" # We pick the first cone on the orbit as a representative. flats = orbit[0] # We compute the image under the yoshida_matrix as a list of images of the rays of the cone the domain Ycone = [yoshida_matrix*v for v in cone_from_flat_numbers(flats)] # ################################# # # This part may be removed (CHECK!) # # We double check that the representatives of the orbits in full_orbits have images of the expected dimension. # if span(Ycone).dimension() < dim: # print "Collapsed" # continue # ################################# # Check if the new cone is in the orbit of previous cones. The output is True (if its image has already been encountered, or included in a cone in the image already encountered) or False (if not). # orbit is the orbit in "full_orbits" (in Berg(E6)) we are currently analyzing # cone_representatives are the ones we already encountered. def same_as_previous(): # the term OLD refers to cells/cones in Berg(E6) and Naruki fan we already encountered. # "old_flat" is the cell in Berg(E6), whereas "old_vertices" is the list of the rays in R^40 spanning the image of the cone "old_flat" in the Naruki fan. for [old_flats,old_vertices] in cone_representatives: # We convert the old cell into a polyhedron Pold = Polyhedron(rays=old_vertices) # "flats" is a cell in the orbit list "orbit" for flats in orbit: # The term NEW refers to the new cell "orbit" from Berg(E6) we are testing. We write the list of the images of the vertices "flats" of "orbit" new_vertices = [yoshida_matrix*v for v in cone_from_flat_numbers(flats)] # We transform the list new_vertices into a polyhedron. Pnew = Polyhedron(rays=new_vertices) # We compute the the intersection between the polyhedron Pold already encountered and the polyhedron Pnew to see if we must add orbit to the list "cone_representatives" or not. common = Pnew.intersection(Pold) # If the intersection has lower dimension, we will output False in the end (not encontered) if common.dim() < dim: continue # If the new cone and the old cone agree, we return True (the cone has been encountered before) if Pnew == Pold: return True # If the intersection agrees with Pnew, it is because "Pnew" is contained in the old polyhedron. We add the ordered pair [old_cell, new_cell] to the "containments" list and return True (the cone has been encountered before, in this case, included in one we encountered before) if common == Pnew: print "New contained in old" containments.append([old_flats, flats]) return True # If the intersection is Pold, that means that Pnew contains Pold. But if common == Pold: # Should never happen with sorted full_orbits # I DON'T THINK THIS IS TRUE (THE SORTING WAS DONE BY descending Volume in THE DOMAIN, NOT THE VOLUME OF THE IMAGES.) print "Old contained in new" # I think the pair should be this one, not the one commented. Second entry is the smallest one. containments.append([flats,old_flats]) return False # If all the previous options fail, it's because the intersection in properly contained in earlier cones and has also maximal dimension. We then record the intersection as an overlap: we add the pair (old cone in Berg(E6), new cone in Berg(E6)), and we would return False. else: print "Overlap" overlaps.append([old_flats, flats]) return False # We enter here if the image of orbit has either been encountered before (or contained in one already encountered if same_as_previous(): continue # In this case, the orbit has new information, and we add the pair to the representatives (the cone in Berg(E6) and its image under the yoshida_map). print ([flats, Ycone]) cone_representatives.append([flats, Ycone]) return (cone_representatives, containments, overlaps) ################## # Check overlaps # ################## # The following function checks overlaps/containment between the images of a cone "big" in Berg(E6) and all cells in the orbit of a cone "small" of the same dimension as "big" whose image is contained in the image of "big". The output is a pair of lists: # "contained" list of all cells in the orbit of the 2nd entry in "containment" whose image is contained in the image of the 1st entry of "containment" # "overlap" lists all cells in the orbit of the 2nd entry that overlap with the 1st entry of "containment" but are not contained. The overlap has maximal dimension. # Input data # "yoshida_matrix" is the 40x36 matrix of the tropical Yoshida map. from R^36 to R^40. # "orbits" is the list of all W(E6) orbits of cells in Berg(E6) that have the same dimension as big and small. # "containment" is a pair [big, small] of cones in Berg(E6) where the image of big contains the image of small. We use it cases where big and small have the same dimension, and the dimension of their images in the Naruki fan viewed in R^40 is also preserved. def check_overlaps(yoshida_matrix, orbits, containment): # we start by labeling the two cells in containment. [big, small] = containment # we construct the polyhedron in the Naruki fan giving the image of the big cell P = Polyhedron(rays=[yoshida_matrix*v for v in cone_from_flat_numbers(big)]) # we assign the dimension of P in R^40 to the variable "dim". It is expected that big, and small have dimension dim. dim = P.dim() # We initialize the value of "small_orbit" to be None. It will later be assigned the value of the orbit containing the cell "small" small_orbit = None # We initialize the two lists "overlap" and "contained" to be the empty lists. We append elements to these two list as we go along. overlap = [] contained = [] #Find the W(E6) orbit of the small cone and assign it to the variable "small_orbit" for orbit in orbits: if small in orbit: small_orbit = orbit # Once we fold the orbit of the cell "small", we loop through all the cells (called "another_small") in this orbit and check the intersection of their images with the polyhedron P. We know that P contains this image of small, but the intersection between P and the other cells is unknown. This loop allows us to find the rays we need to add to the Naruki fan to ensure that the Yoshida_map is a a map of fans. for another_small in small_orbit: # we construct the polyhedron in the Naruki fan giving the image of the cell "another_small" Q = Polyhedron(rays=[yoshida_matrix*v for v in cone_from_flat_numbers(another_small)]) # we compute the intersection with the big polyhedron. common = P.intersection(Q) # If the intersection is empty, the dimension is -1. We don't record any information. if common.dim() == -1: continue # Second case: Q is contained in P. We add the cell "another_small" to the list of cells in "contained". elif common == Q: contained.append(another_small) # Third case: the dimension of the overlap is the same as the dimension of P, so Q and P overlap. We add the cell "another_small" to elif common.dim() == dim: overlap.append(another_small) print "Overlap" # We check if new rays need to be added (rays in the intersection that are not rays in the image of the big cell). if not all([v in P.rays() for v in common.rays()]): print "with new rays" else: print "the intersection lies in the boundary of P" if not all([v in P.rays() for v in common.rays()]): print "with new rays" return (contained, overlap) ############################# # SUPPORT OF THE NARUKI FAN # ############################# # We compute the Cones in the Naruki fan: # We first load the Yoshida_matrix computed earlier: Yoshida_matrix = load("../../Yoshida/Output/Yoshida_matrix.sobj") # Then, we take the orbits of the maximal cones and the expected dimension 5. # we check that the dimension of the Naruki fan in R^40 is 5 by computing the dimension of the images of all representatives: alldimensions = [] for x in BergmanFan[1][4]: flats = x[0] Ycone=[Yoshida_matrix*v for v in cone_from_flat_numbers(flats)] alldimensions.append((flats, span(Ycone).dimension())) # print str(alldimensions) # [([0, 1, 4, 36, 55], 4), ([0, 1, 4, 36, 473], 5), ([0, 1, 4, 36, 687], 5), ([0, 1, 4, 158, 473], 5), ([0, 1, 4, 158, 691], 5), ([0, 1, 4, 158, 717], 4), ([0, 1, 4, 426, 687], 4), ([0, 1, 36, 55, 714], 4), ([0, 1, 36, 165, 490], 5), ([0, 1, 36, 165, 687], 5), ([0, 1, 36, 165, 716], 4), ([0, 1, 36, 471, 687], 5), ([0, 1, 36, 471, 714], 4), ([0, 1, 156, 426, 687], 4), ([0, 1, 156, 426, 691], 4), ([0, 1, 156, 471, 687], 5), ([0, 1, 156, 471, 714], 4), ([0, 36, 159, 429, 687], 4), ([0, 36, 159, 429, 695], 4), ([0, 36, 159, 471, 687], 5), ([0, 36, 159, 471, 714], 4)] # # We check that the dimensions are 4 or 5: # set([x[1] for x in alldimensions]) # {4, 5} # # We classify the cells by the dimension of their image dim5Images = [x[0] for x in alldimensions if x[1]==5] # dim5Images # [[0, 1, 4, 36, 473], # [0, 1, 4, 36, 687], # [0, 1, 4, 158, 473], # [0, 1, 4, 158, 691], # [0, 1, 36, 165, 490], # [0, 1, 36, 165, 687], # [0, 1, 36, 471, 687], # [0, 1, 156, 471, 687], # [0, 36, 159, 471, 687]] dim4Images = [x[0] for x in alldimensions if x[1]==4] # dim4Images # [[0, 1, 4, 36, 55], # [0, 1, 4, 158, 717], # [0, 1, 4, 426, 687], # [0, 1, 36, 55, 714], # [0, 1, 36, 165, 716], # [0, 1, 36, 471, 714], # [0, 1, 156, 426, 687], # [0, 1, 156, 426, 691], # [0, 1, 156, 471, 714], # [0, 36, 159, 429, 687], # [0, 36, 159, 429, 695], # [0, 36, 159, 471, 714]] # From this we conclude that to get the set description of the Naruki fan, it suffices to restrict ourselves to the images of maximal cones in Berg(E6) whose dimension is 5 in R^40. # The calculation takes about 1 minute on a 2.4 GHz Intel(R) Core 2 Duo with 3MB cache and 2GB RAM. #narukiCones = yoshida_cone_orbits(Yoshida_matrix, BergmanFan[1][4],5) # We save the calculation as an sobj file #save(narukiCones, "../Output/NarukiCones.sobj") # We load the precomputed data: narukiCones = load("../Output/NarukiCones.sobj") # We record the output # ([[[0, 1, 4, 36, 687], # [(0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0), # (0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1), # (0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0), # (1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 3, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1), # (5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5)]], # [[0, 1, 4, 158, 691], # [(0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0), # (0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1), # (0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0), # (1, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 3, 2, 1, 1, 2, 1, 1, 2, 2, 2, 2, 2, 3, 2, 1, 1, 1, 3, 1, 2, 2, 1), # (5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5)]]], # [[[0, 1, 4, 36, 687], [0, 1, 4, 36, 473]], # [[0, 1, 4, 158, 691], [0, 1, 4, 158, 473]], # [[0, 1, 4, 36, 687], [0, 1, 36, 165, 687]], # [[0, 1, 4, 36, 687], [0, 1, 36, 473, 688]], # [[0, 1, 4, 36, 687], [0, 1, 36, 165, 490]], # [[0, 1, 4, 158, 691], [0, 1, 158, 473, 688]], # [[0, 1, 4, 36, 687], [0, 36, 165, 490, 695]]], # []) ############################################ # Yoshida map in tropical projective torus # ############################################ # The following function takes a cell in the Bergman complex, given as a list of vertex indices, and returns a polyhedron describing its image in the tropical projective torus under the tropicalization of the Yoshida map. If the image of a vertex is a multiply of the all-ones' vector, the image is not considered in the list of rays generating the polyhedron. #In particular, the function can output an empty polyhedron (i.e. generated by no rays) # c = cone in Berg(E6) given as a a list of ray indices. def Yoshida_map(c): return Polyhedron(rays=[projection(Yoshida_matrix*v) for v in cone_from_flat_numbers(c) if projection(Yoshida_matrix*v) != 0 ]) ############################################################################ # Analysis of the fan structure from the set description of the Naruki fan # ############################################################################ # The variable "narukiCones" computed earlier is a list of 3 elements. The first entry is a list of two items. The two items are maximal cones in the Bergman fan with the property that the image of any other cone in Berg(E6) under the Yoshida matrix is contained in a W(E6)-conjugate of the image of one of these two cones. The second entry is a list of cones in the Bergman fan that map to a 5-dimensional cone and are contained in one of the two cones listed above. The third entry is the empty list. # We first notice that the last vector in both entries of narukicones[0] is a multiply of the all-ones' vector. Furthermore, out of the 9 orbit representatives of maximal cones in Berg(E6) whose dimension under the Yoshida_map is 4 (the cells in "dim5Images"), only 2 rays map to the origin, as the following calculation shows. # The following function 'joinElements' joins several lists into a single sorted list (after removing elements that appear more than once). It was coded in "../../BergmanFan/Scripts/BergmanFansArrangements.sage" # begin is a list of lists. def joinElements(begin): L = [] allLists= copy.copy(begin) while len(allLists)>0: oneList = allLists.pop() for x in oneList: if x not in L: L.append(x) # if x in L: # # print str(x) + ' was in the previous lists' # else: # L.append(x) return sorted(L) # raysRep = sorted(list(set(joinElements(dim5Images)))) # [(x, Yoshida_map([x])) for x in raysRep if Yoshida_map.dim()==-1] # [(687, The empty polyhedron in ZZ^0), (691, The empty polyhedron in ZZ^0)] # In order to analyze the result, we must study the containments listed in narukiCones[1] when using the Yoshida_map: ############## # FIRST CONE # ############## # # First cone in the list: # firstCone = narukiCones[0][0][0] # print firstCone # [0, 1, 4, 36, 687] # print firstCone[0:-1] # [0, 1, 4, 36] # Yoshida_map(firstCone[0:-1]) == Yoshida_map(firstCone) # True # # The output is a 4-dimensional polyhedral cone in Z^40 all of whose rays have last coordinate 0. # Yoshida_map(firstCone) # A 4-dimensional polyhedron in ZZ^40 defined as the convex hull of 1 vertex and 4 rays # # We list the 4 generating rays: # Yoshida_map(firstCone).rays() # (A ray in the direction (-1, 0, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, 0, 0, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0), # A ray in the direction (0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, -1, -1, -1, 0, 0, 0, -1, 0, 0, 2, 0, -1, 0, 0, -1, -1, -1, 0, 0, -1, -1, -1, 0, 0, 0, 0, 0), # A ray in the direction (0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0), # A ray in the direction (0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0)) ############### # SECOND CONE # ############### # # Second cone in the list: # secondCone = narukiCones[0][1][0] # print secondCone # [0, 1, 4, 158, 691] # print secondCone[0:-1] # [0, 1, 4, 158] # Yoshida_map(secondCone[0:-1]) == Yoshida_map(secondCone) # True # # The output is a 4-dimensional polyhedral cone in Z^40 all of whose rays have last coordinate 0. # Yoshida_map(secondCone) # A 4-dimensional polyhedron in ZZ^40 defined as the convex hull of 1 vertex and 4 rays # # We list the 4 generating rays: # Yoshida_map(secondCone).rays() # (A ray in the direction (-1, 0, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, 0, 0, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0), # A ray in the direction (0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0), # A ray in the direction (0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0), # A ray in the direction (0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 2, 1, 0, 0, 0, 2, 0, 1, 1, 0)) ########################################################## # Checking for potential overlaps with all 9 full orbits # ########################################################## # The following function checks overlaps/containment between the images of other maximal cells in Berg(E6) whose image has maximal dimension with respect to a reference cone. The calculation is done in the tropical projective torus. The output is a pair of lists: # "contained" is cell in Berg(E6) whose image is contained in the Naruki cone of "refCone" # "overlap" lists all cells in the orbit of some cell in "dim5Image" what overlaps with but is not contained in the image of "refCone" # "boundaryNewRays" lists all cells in the orbit of some cell in "dim5Image" whose image lies in the boundary of the image of refCone but the rays of the intersection are not among the rays in the image of "refCone". They will lead to new rays in the Naruki fan. # Input data # "refCone" will be either firstCone = [0, 1, 4, 36, 687] or secondCone = [0, 1, 4, 158, 691], namely, the two cones in narukiCones[0]. max_orbits5dimCells = [[orbit for orbit in BergmanFan[1][-1] if dim5Images[k] in orbit][0] for k in range(0, len(dim5Images))] [len(x) for x in max_orbits5dimCells] [6480, 3240, 3240, 1620, 12960, 6480, 12960, 6480, 25920] sum([len(x) for x in max_orbits5dimCells]) 79380 def all_maximal_overlapping_cones(refCone): max_orbits5dimCells = [[orbit for orbit in BergmanFan[1][-1] if dim5Images[k] in orbit][0] for k in range(0, len(dim5Images))] # We record containment, overlappings and cells that will lead to new rays with "refCone" contained = [] overlap =[] boundaryNewRays = [] P = Yoshida_map(refCone) # The dimension is projective dim = P.dim() for x in max_orbits5dimCells: print len(x) for another_small in x: Q = Yoshida_map(another_small) # we compute the intersection with the reference polyhedron. common = P.intersection(Q) # If the intersection is empty, the dimension is -1. We don't record any information. if common.dim() == -1: continue # Second case: Q is contained in P. We add the cell "another_small" to the list of cells in "contained". elif common == Q: contained.append(another_small) # Third case: the dimension of the overlap is the same as the dimension of P, so Q and P overlap. We add the cell "another_small" to elif common.dim() == dim: overlap.append(another_small) print "Overlap" # We check if new rays need to be added (rays in the intersection that are not rays in the image of the big cell). if not all([v in P.rays() for v in common.rays()]): print "with new rays" # # I think the remaining case should be added: else: print "the intersection lies in the boundary of P" if not all([v in P.rays() for v in common.rays()]): print "with new rays" # We need to collect the new rays: boundaryNewRays.append(another_small) # continue print 'Done with ' + str(another_small) print 'Done with ' + str(max_orbits5dimCells.index(x)) + ' step' return (contained, overlap, boundaryNewRays) # We run this function against firstCone and secondCone. The calculation for each cone takes about 120 minutes on a 2.4 GHz Intel(R) Core 2 Duo with 3MB cache and 2GB RAM. # con_overl_newRays_firstCone = all_maximal_overlapping_cones(firstCone) # save(con_overl_newRays_firstCone, "Input/con_overl_newRays_firstCone.sobj") con_overl_newRays_firstCone = load("Input/con_overl_newRays_firstCone.sobj") #[len(x) for x in con_overl_newRays_firstCone] #[63, 0, 588] # There are no overlaps, only containments. # con_overl_newRays_secondCone = all_maximal_overlapping_cones(secondCone) # save(con_overl_newRays_secondCone, "Input/con_overl_newRays_secondCone.sobj") con_overl_newRays_secondCone = load("Input/con_overl_newRays_secondCone.sobj") [len(x) for x in con_overl_newRays_secondCone] [7, 70, 644] # There are overlaps and containments. ########################################## # Analysis of overlaps with other orbits # ########################################## # max1_overlaps contains cones in the Bergman fan that are in the orbit of [0,1,4,36,687] or [0,1,4,158,691] but whose image overlaps with the image of [0,1,4,36,687]. # max2_overlaps contains cones in the Bergman fan that are in the orbit of [0,1,4,36,687] or [0,1,4,158,691] but whose image overlaps with the image of [0,1,4,158,691]. def maximal_overlapping_cones(): # We record the W(E6)-orbit of firstCone = [0, 1, 4, 36, 687] max_orbit1 = [orbit for orbit in BergmanFan[1][-1] if narukiCones[0][0][0] in orbit][0] # We record the W(E6)-orbit of secondCone = [0, 1, 4, 158, 691] max_orbit2 = [orbit for orbit in BergmanFan[1][-1] if narukiCones[0][1][0] in orbit][0] # We record the canonical representative of these two orbits max1 = max_orbit1[0] max2 = max_orbit2[0] # We create the naruki cones in R^40 obtained as the image of max1 and max2 under the Yoshida_matrix. We record the results # Computation of overlaps with max1 Poly1 = Polyhedron(rays=[Yoshida_matrix*v for v in cone_from_flat_numbers(max1)]) # max1_overlaps contains cones in the Bergman fan that are in the orbit of [0,1,4,36,687] or [0,1,4,158,691] but whose image overlaps with the image of [0,1,4,36,687]. max1_overlaps = [c for c in max_orbit1+max_orbit2 if Polyhedron(rays=[Yoshida_matrix*v for v in cone_from_flat_numbers(c)]).intersection(Poly1).dim() == 5] # save(max1_overlaps, "Input/Overlaps_with_max1.sobj") # Computation of overlaps with max2 Poly2 = Polyhedron(rays=[Yoshida_matrix*v for v in cone_from_flat_numbers(max2)]) # max2_overlaps contains cones in the Bergman fan that are in the orbit of [0,1,4,36,687] or [0,1,4,158,691] but whose image overlaps with the image of [0,1,4,158,691]. max2_overlaps = [c for c in max_orbit1+max_orbit2 if Polyhedron(rays=[Yoshida_matrix*v for v in cone_from_flat_numbers(c)]).intersection(Poly2).dim() == 5] # save(max2_overlaps, "Input/Overlaps_with_max2.sobj") return (max_orbit1, max_orbit2) # We compute the two maximal orbits and save the data of the overlaps # (max_orbit1, max_orbit2) = maximal_overlapping_cones() # # We save the data: # save(max_orbit1, "Input/max_orbit1.sobj") # save(max_orbit2, "Input/max_orbit2.sobj") # We load the precomputed data of the overlaps: max1_overlaps = load("Overlaps_with_max1.sobj") max2_overlaps = load("Overlaps_with_max2.sobj") # max1_overlaps contains 3 cones, but when looking at their image under the Yoshida_map (i.e. in the tropical projective torus R^40/ R (1,...1)) they go to the same 4-dimensional cone without any partial overlaps. # We record the data: print max1_overlaps [[0, 1, 4, 36, 687], [0, 1, 4, 55, 692], [0, 1, 4, 73, 691]] print max2_overlaps [[0, 1, 4, 158, 691], [0, 1, 4, 172, 692], [0, 1, 4, 204, 687], [0, 1, 29, 165, 687], [0, 1, 29, 238, 692], [0, 4, 29, 165, 687], [0, 4, 29, 172, 692], [0, 4, 29, 309, 691], [1, 4, 29, 204, 687], [1, 4, 29, 238, 692], [1, 4, 29, 309, 691]] # all = [Polyhedron(rays=[projection(Yoshida_matrix*v) for v in cone_from_flat_numbers(c) if projection(Yoshida_matrix*v) != 0]) for c in max2_overlaps] # [(i,j) for i in range(0,9) for j in range(0,9) if all[i].intersection(all[j]).dim() < 4] # [(1, 6), (2, 8), (3, 5), (5, 3), (6, 1), (8, 2)]