################################################################################################################################################# # Functions to calculation of all 135 tropical nodal points induced by parameteres ds giving the desired point in each cone in the Naruki fan. # ################################################################################################################################################# # The following script includes all the functions required to compute all the 135 nodal points associated to each extremal curve in X, where X is a smooth del Pezzo with no Eckardt points, anticanonically embedded. # The result will always be families (of true or expected valuations, or tropical matrices with or without 'None' entries), indexed by the pairs of extremal curves intersecting. Each element of the family is a family of 45 elements, representing the classical (resp. tropical) coordinates for each anticanonical triangle. The order of the coordinates of each node is given in decreasing order for X+Y. # The functions are used in "ComputationOfAllTropicalNodesPerNarukiCones.sage" ########################################################################### # Setting up the ambient rings with the W(E6) action. ########################################################################### # A list of variables d_1, ..., d_6 for the coefficients ds = [var("d%s"%i) for i in range(1,7)] # A list of variables E_1, ..., E_6 Es = [var("E%s"%i) for i in range(1,7)] # A list of variables F_12, ..., F_56 Fs = [var("F%s%s"%(i,j)) for i in range(1,7) for j in range(1,7) if i < j] # A list of variables G_1, ..., G_6 Gs = [var("G%s"%i) for i in range(1,7)] # A list of variables X_12, ..., X_65 Xs = [var("X%s%s"%(i,j)) for i in range(1,7) for j in range(1,7) if i != j] # A list of variables Y_123456, ..., Y_162534 Ys = [var("Y%s%s%s%s%s%s"%(i,j,k,l,m,n)) for i in range(1,7) for j in range(1,7) for k in range(1,7) for l in range(1,7) for m in range(1,7) for n in range(1,7) if i values[1][0]: # monomial = values[1][1] else: monomial = values[1][1] #Could have picked either one linear_form = linear_form + e*monomial else: print "Got more than a binomial. Abort???" return linear_form # The following function is a modification of the function yoshida_to_trop_yoshida from '../../TropicalMatricesWithAndWithoutNones/Scripts/computeTMsMacros.sage' def yoshida_to_trop_yoshida_with_Nones(c, cone): if c == 0: return +Infinity c = YField(expand(c)).factor() linear_form = 0 interior_point =sum([vector(r) for r in cone.rays()]) for (f,e) in c: if len(YRing(f).monomials()) == 1: linear_form = linear_form + e*f elif len(YRing(f).monomials()) == 2: values = [(interior_point[Yoshidas.index(m)], m) for m in YRing(f).monomials()] if values[0][0] < values[1][0]: monomial = values[0][1] linear_form = linear_form + e*monomial elif values[0][0] > values[1][0]: monomial = values[1][1] linear_form = linear_form + e*monomial else: monomial = None #Could have picked either one linear_form = None else: print "Got more than a binomial. Abort???" return linear_form ################################## # Macros to Build Tropical Nodes # ################################## # We start by creating ambient rings and quotient fields YCRing = PolynomialRing(QQ, Yoshidas + cross_variables) YCField = FractionField(YCRing) # The following fucntion substitutes the entries of each node by the valuation of Cross functions, # c = rational function in Yoshida and Cross functions # cone = cone name # dictionaryCrossValuations = dictionary indexed by cone names of true valuations of all 135 Cross functions (entries 'None' are included) def yoshida_and_cross_to_trop_yoshida_and_cross_with_Nones(c, cone,dictionaryCrossValuations): if c == 0: return +Infinity c = YCField(expand(c)).factor() linear_form = 0 for (f,e) in c: # print f if len(YCRing(f).monomials()) == 1: if SR(f) in Yoshidas: linear_form = linear_form + e*f elif SR(f) in cross_variables: if dictionaryCrossValuations[cone][SR(f)] != None: linear_form = linear_form + e*dictionaryCrossValuations[cone][SR(f)] else: linear_form = None return None else: print 'There is an error. Abort???' return linear_form ####################################################### # Revealing None values for TM with and without Nones # ####################################################### # The following function creates the values of the Yoshida functions given the value of the parameteres d1,...,d6 (vald is a dictionary) def substituteValdsInYField(valds,Yoshidas): return {SR(Yoshidas[i]): SR(expand(factor(SR(Yoshidas[i]).substitute(y_to_d)).substitute(valds))) for i in range(0,len(Yoshidas))} # The following function computes the value of the ditionary of nodes in terms of the values of the specialized Yoshidas # valYoshidas is a dictionary with keys in SR and values in Qt obtained from the function "substituteValdsInYField" # dictNodes will be a dictionary corresponding to either ClassicalNodesDictionaries or ClassicalNodesDictionaries10. def nodesWithValDs(valYoshidas,dictNodes,key): dictNodesSubs = {} print str(key) for k in dictNodes[key].keys(): print str(k) dictNodesSubs[k] = {} for x in dictNodes[key][k].keys(): print str(x) dictNodesSubs[k][x] = expand(SR(expand(dictNodes[key][k][x])).substitute(valYoshidas)) print '' return {key: dictNodesSubs} # The following function computes the valuation of a particular coordinate of a particular node, exploiting its factorized form. It is much faster to compute the valuations for the factorizations. # pair is an element in all135Nodes.keys() # dictNodes is the dictionary "all135Nodes" # coord is an element in "keys" # We assume dictNodes[pair][coord] is factored unless it is 0 (in which case it is an element in YField). This assumption holds for any entry all135Nodes[pair][coord]. def coordTropicalNodeWithValDsFactored(valYoshidas,dictNodes,pair,coord): dictNodesSubs = {} if dictNodes[pair][coord]==0: return +Infinity else: factorizedExpression = list(dictNodes[pair][coord]) factorizedExpressionsInt = [(QtField(SR(expand(f)).substitute(valYoshidas)),e) for (f,e) in factorizedExpression] sumVals = 0 for (f,e) in factorizedExpressionsInt: if f ==0: if e<0: print 'error' return else: return +Infinity L = list(f.factor()) factorsInLWitht = [x for x in L if x[0]==QtField(t)] sumVals = sumVals + e*sum([x[1] for x in factorsInLWitht]) return sumVals # Since for most entries, the Cross functions appearing have a known valuation (because there are no ties between the two Yoshida summands involved), it is easier to construct the tropical matrices by just computing the 'None' entries for those. # The following two functions compute the valuations of the Yoshidas associated to the scalars of the extremal rays of each cone. Each function corresponds to each of the representatives of maximal cones in the Naruki fan. def computeValsYoshidasNaruki_aa2a3a4(a,b,c,d): w = YM*vector(a*va + b*va2 + c*va3 + d*va4) valuationsYoshidas = {SR(Yoshidas[i]): QQ(w[i]) for i in range(0,len(w))} # print valuationsYoshidas return valuationsYoshidas def computeValsYoshidasNaruki_aa2a3b(a,b,c,d): w = YM*vector(a*va + b*va2 + c*va3 + d*vb) valuationsYoshidas = {SR(Yoshidas[i]): QQ(w[i]) for i in range(0,len(w))} # print valuationsYoshidas return valuationsYoshidas # We merge these two into a single function, depending on the cone and the scalars. def computeValsYoshidasNaruki(cone,a,b,c,d): if 'b' in cone: valuationsYoshidas = computeValsYoshidasNaruki_aa2a3b(a,b,c,d) else: valuationsYoshidas = computeValsYoshidasNaruki_aa2a3a4(a,b,c,d) return valuationsYoshidas # The following function will replace the values on each matrix that are not nones. To use it we will pick an entry on TM_with_nones or TM_no_nones associated to the variable 'cone': def replaceLinearValues(entry, cone, a,b,c,d): if entry is None: return entry if entry == +Infinity: return entry else: if 'b' in cone: valuationsYoshidas = computeValsYoshidasNaruki_aa2a3b(a,b,c,d) else: valuationsYoshidas = computeValsYoshidasNaruki_aa2a3a4(a,b,c,d) # print entry newEntry = SR(expand(entry)).substitute(valuationsYoshidas) return SR(newEntry) # The following function will replace a None entry for the valuation of the classical entry coming from our choice of valYoshidas (i.e. rational functions in t obtained from valds). # The variable "dictNode" corresponds to the 135 nodes, with keys = tuple of pair of curves that meet, and values that are dictionaries indexed by the anticanonical coordinates. # The variable "entry" is either 'None' or a linear function in the Yoshidas. When it's value is None, we compute its true value by looking at the corresponding entry in the classical node. # When we use it, we need to go over the entire list of nodes and coordinates. we can use it before or after "replaceLinearValues". # "valYoshidas" is computed by knowing the scalars (a,b,c,d), which are input variables for "replaceLinearValues". # WARNING: we need to convert ANY exact values (in ZZ) to an entry in the Symbolic Ring (we do so by SR()). Otherwise, when we use this function to construct matrices of 10 x45 nodes associated to an extremal curve, any Integer value will be replaced by 'A positive integer'. The entries '+Infinity' remain unaltered. def replaceNone(entry,valYoshidas,dictNodes,pair,coord): if entry is None: return SR(coordTropicalNodeWithValDsFactored(valYoshidas,dictNodes,pair,coord)) else: return SR(entry) # TM_with_nones is a dictionary whose values are also a dictionary (whith keys given by 'keys') # Note: valYoshidas have been precomputed for specific choices of a,b,c,d (they are 0/1). If other values are needed, they have to be precomputed (in the previous section) def trueTropicalNodes(TNodes_with_nones, cone, a,b,c,d, dictNodes,valYoshidas): all135tropicalNodes = {} for pair in dictNodes.keys(): print str(pair) all135tropicalNodes[pair] ={} for key in keys: # print str(key) entry = TNodes_with_nones[pair][key] if entry is None: newEntry = replaceNone(entry,valYoshidas,dictNodes,pair,key) else: newEntry = replaceLinearValues(entry,cone, a,b,c,d) all135tropicalNodes[pair][key] = newEntry return all135tropicalNodes # The following function computes the expected (TNodes_no_nones) and the true tropical nodes (working with TNodes_with_nones and valYoshidas) def computeExpectedAndTrueTropicalNodes(cone,a,b,c,d,dictNodes,valYoshidas): TNodes_with_nones =load('../../TropicalConvexHulls/Scripts/Input/TropicalNodes'+str(cone)+'_with_nones_signed_ordered_permutedCols.sobj') TNodes_no_nones = load('../../TropicalConvexHulls/Scripts/Input/TropicalNodes'+str(cone)+'_no_nones_signed_ordered_permutedCols.sobj') expectedTNodes = trueTropicalNodes(TNodes_no_nones, cone, a,b,c,d, dictNodes,valYoshidas) trueTNodes = trueTropicalNodes(TNodes_with_nones, cone, a,b,c,d, dictNodes,valYoshidas) return (expectedTNodes,trueTNodes) # The following function generates the dictionaries of True and Expected tropical Nodes and compares them, for a choice of Yoshidas (rational functions in t) whose valuation gives the linear combination of the 4 extremal rays in the maximal cone containing the "cone". def generateTrueAndExpectedNodes(cone,a,b,c,d,dictNodes,valYoshidas): (expectedTNodes,trueTNodes) = computeExpectedAndTrueTropicalNodes(cone,a,b,c,d,dictNodes,valYoshidas) # save(expectedTNodes, '../../TropicalConvexHulls/Scripts/Input/expectedTNodes_no_nones_' + str(cone) + '.sobj') # save(trueTNodes, '../../TropicalConvexHulls/Scripts/Input/trueTNodes_no_nones_' + str(cone) + '.sobj') # # We save the output as plain texts in the Output folder of the Yoshida folder. The computation for each cone is stored on a folder named by the 'cone' variable: # f=file('../Output/'+str(cone)+'/trueTNodes_no_nones'+str(cone)+'_signed_ordered_permutedCols.txt','w') # g=file('../Output/'+str(cone)+'/expectedTNodes_no_nones'+str(cone)+'_signed_ordered_permutedCols.txt','w') # f.write('#Cone ' + str(cone) + '\n') # g.write('#Cone ' + str(cone) + '\n') # f.write('trueTNodes = {}' + '\n'+'\n') # g.write('expectedTNodes = {}' + '\n'+'\n') # for pair in dictNodes.keys(): # f.write('#Node' + str(pair) +'\n') # g.write('#Node' + str(pair) +'\n') # f.write('trueTNodes['+str(pair)+'] =' + str(trueTNodes[pair])+'\n') # g.write('expectedTNodes['+str(pair)+'] =' + str(expectedTNodes[pair])+'\n') # f.write('\n') # g.write('\n') # f.close() # g.close() print 'Done' # return True return (expectedTNodes,trueTNodes) # The following function compares the expected and true valuations: def compareTNodes(TNodes_with_nones, expectedTNodes,trueTNodes,dictNodesKeys): jumps = {} for pair in dictNodesKeys: print str(pair) jumps[pair] = [] for key in keys: if TNodes_with_nones[pair][key] is None: print str(key) a = expectedTNodes[pair][key] b = trueTNodes[pair][key] if a == b: print 'No jump' else: print 'Jump' jumps[pair].append((key,a,b)) else: a = expectedTNodes[pair][key] b = trueTNodes[pair][key] if a == b: print 'No jump' else: print (pair, key) return 'error' print 'Done with pair' print '' return jumps # The following function takes stored input for expected and true tropicalizations of all 135 obtained from specialization of Yoshida valuations and concrete parameters in Q[t] and outputs the differences: def generateJumps(cone,dictNodes): # Finally, we compare the values of the 135 nodes for each of the 4 families computed earlier for each of the cones expectedTNodes =load('../../TropicalConvexHulls/Scripts/Input/expectedTNodes_no_nones_' + str(cone) + '.sobj') trueTNodes = load('../../TropicalConvexHulls/Scripts/Input/trueTNodes_no_nones_' + str(cone) + '.sobj') TNodes_with_nones =load('../../TropicalConvexHulls/Scripts/Input/TropicalNodes'+str(cone)+'_with_nones_signed_ordered_permutedCols.sobj') jumps = compareTNodes(TNodes_with_nones, expectedTNodes,trueTNodes,dictNodes.keys()) # print str(jumps) values = [] for key in jumps.keys(): values = values + [x[1] for x in jumps[key]] + [x[2] for x in jumps[key]] print 'Check if +Infinity is contained in values' print [+Infinity not in values][0] return jumps