One Hat Cyber Team
Your IP :
216.73.216.115
Server IP :
194.44.31.54
Server :
Linux zen.imath.kiev.ua 4.18.0-553.77.1.el8_10.x86_64 #1 SMP Fri Oct 3 14:30:23 UTC 2025 x86_64
Server Software :
Apache/2.4.37 (Rocky Linux) OpenSSL/1.1.1k
PHP Version :
5.6.40
Buat File
|
Buat Folder
Eksekusi
Dir :
~
/
usr
/
share
/
Macaulay2
/
Edit File:
GKMVarieties.m2
-*------------------------------------------------------------------------------------------- Copyright 2020 Christopher Eur and Ritvik Ramkumar. You may redistribute this file under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or any later version. -------------------------------------------------------------------------------------------*- newPackage("GKMVarieties", Version => "0.1", Date => "August 1, 2020", Authors => { {Name => "Chris Eur", Email => "chriseur@stanford.edu", HomePage => "https://web.stanford.edu/~chriseur"}, {Name => "Ritvik Ramkumar", Email => "ritvik@math.berkeley.edu", HomePage => "https://math.berkeley.edu/~ritvik"} }, Headline => "computations with GKM manifolds and moment graphs", HomePage => "https://github.com/chrisweur/GKMVarieties", PackageExports => {"Graphs", "Matroids", "NormalToricVarieties"}, AuxiliaryFiles => true, Keywords => {"Equivariant Cohomology", "Toric Geometry", "Flag Varieties", "Matroids"}, DebuggingMode => false ) export { "GKMVariety", "makeGKMVariety", "KClass", "makeKClass", "ampleKClass", "trivialKClass", "EquivariantMap", "pushforward", "diagonalMap", "FlagMatroid", "flagMatroid", --"tFlagVariety", "flagMap", "flagGeomTuttePolynomial", "KPolynomials", "charts", "points", "ptsMap", "characterRing", "HTpt", "projectiveSpace", "MomentGraph", "momentGraph", "constituents", "makeCharacterRing", --"makeHTpt", "generalizedFlagVariety", "lieType", "cellOrder", "bruhatOrder", "generalizedSchubertVariety", "orbitClosure", "toFraction", "affineToricRing", "setIndicator", --"unastrsk", --"toCharacterRing", --"tHilbNumer", "RREFMethod" } ------------------------------------------------------------------------------------------------ -------------------------------< internal auxiliary functions >--------------------------------- ------------------------------------------------------------------------------------------------ --input: a list L = {l_1, ... , l_d} of list of integers, or --a matrix A whose columns are l_i's, representing exponents of a monomial map --output: a quotient ring R/I, where R has variables x_1, ... x_d of degrees l_1, ... , l_d and --I is the toric ideal defined by the monomial map affineToricRing = method(); affineToricRing(List) := QuotientRing => L -> ( d := #L; x := symbol x; R := QQ[apply(#L, i -> x_i), Degrees => L]; I := if #L == 0 then ideal(0_R) else toricGroebner(transpose matrix L, R); R/I ) affineToricRing(Matrix) := QuotientRing => A -> affineToricRing(entries transpose A) --internal auxiliary function: --default Macaulay2 can't do fraction fields for Laurent rings --but by shifting so that we exit Laurent rings and then going back, we can. --Here given two Laurent polynomials f,g and a ring S with Inverses=>false, outputs the ratio --f/g of f and g by multiplying both of them with a big enough monomial to make them polynomials --the output is the ratio in the new ring S, --and a function goBack which puts the element in the ring of f if the denominator is a monomial toFraction = method(); toFraction(RingElement,RingElement,Ring) := (f,g,S) -> ( R := ring f; if not R === ring g then error " the two polynomials live in different rings "; if not (#gens R) == (#gens S) then error " the temporary ring is no good "; Exps := -((transpose (exponents f | exponents g))/min); mult := product(#Exps, i -> R_i^(Exps_i)); numer := sub(mult*f, apply(#(gens R), i -> R_i=>S_i)); denom := sub(mult*g, apply(#(gens R), i -> R_i=>S_i)); rat := numer / denom; goBack := ratFct -> ( N := numerator ratFct; D := denominator ratFct; if not #(terms D) == 1 then error "denominator not a monomial"; sub(N, apply(#(gens S), i -> S_i=>R_i))*(sub(D, apply(#(gens S), i -> S_i=>R_i)))^(-1) ); {rat, goBack} ) --auxiliary function: --makes a polynomial ring with n variables, representing equivariant cohomology --ring of a point where T = = (kk^*)^n. makeHTpt = method() makeHTpt(ZZ) := Ring => n -> ( t := symbol t; QQ[t_0..t_(n-1)] ) ----------------------------------------------------------------------------------------------- --------------------------------------< moment graphs >---------------------------------------- ----------------------------------------------------------------------------------------------- --a MomentGraph G is a MutableHashTable with the minimal data of: --G.vertices : a list representing vertices of the graph G --G.edges : a hash table whose keys are pairs {p,q} of vertices and values v are directed weights -- of the edge p --> q where v is a list of numbers such that matrix{v} * basis(1,G.HTpt) -- gives the weight --G.HTpt : a polynomial ring, represent the equivariant cohomology ring of a point MomentGraph = new Type of HashTable MomentGraph.synonym = "moment graph" globalAssignment MomentGraph net MomentGraph := G -> net ofClass class G | " on " | toString(#G.vertices) | " vertices with " | toString(#G.edges) | " edges " --given a list V representing the vertices, E a hash table of edges, and H a ring for HTpt --outputs a moment graph with such data momentGraph = method() momentGraph(List,HashTable,Ring) := MomentGraph => (V,E,H) -> ( new MomentGraph from { symbol vertices => V, symbol edges => E, symbol HTpt => H, cache => new CacheTable } ) --outputs the graph underlying a moment graph G underlyingGraph(MomentGraph) := Graph => G -> graph(G.vertices, keys G.edges, EntryMode => "edges") --If a moment graph G comes from a possibly singular GKM variety with a torus invariant -- Whitney stratification consisting of affine spaces, --the vertices of G correspond to each strata, --and are ordered v1 <= v2 if the closure of stratum of v2 is contained in that of v1. cellOrder = method() cellOrder(MomentGraph,Poset) := (G,P) -> ( if G.cache.?cellOrder then ( print "warning: overwriting a previously defined cell order on this moment graph " ); if G.vertices =!= P.GroundSet then ( error "the ground set of the poset is not the vertices of this moment graph " ); G.cache.cellOrder = P; ) cellOrder(MomentGraph) := Poset => G -> ( if G.cache.?cellOrder then G.cache.cellOrder else error " no cell order defined on this moment graph" ) --------------------------------------< GKM varieties >------------------------------------------- --for setting up a character ring: given n, outputs the character ring of T = (kk^*)^n makeCharacterRing = method(); makeCharacterRing(ZZ) := Ring => n -> ( T := symbol T; ZZ[T_0..T_(n-1), MonomialOrder => GLex, Inverses=>true] ) --a GKMVariety X is a HashTable with minimal data of: --X.points : a list representing torus-invariant points --X.characterRing : a ring representing the character ring of the torus --additionally, a GKMVariety X can have: --X.charts : a hash table whose keys are X.points and values are (negative of) the characters --of the affine chart at the point --X.momentGraph : a MomentGraph which is the moment graph of the GKM variety GKMVariety = new Type of MutableHashTable GKMVariety.synonym = "GKM variety" globalAssignment GKMVariety net GKMVariety := X -> net ofClass class X | " with an action of a " | toString(#gens X.characterRing) | "-dimensional torus" makeGKMVariety = method() --a list L representing the torus-fixed points, and a character ring R defines a GKMVariety makeGKMVariety(List, Ring) := GKMVariety => (L,R) -> ( new GKMVariety from { symbol points => L, symbol characterRing => R, cache => new CacheTable } ) --makeGKMVariety created from G, a moment graph, and a character ring R compatible with G.HTpt makeGKMVariety(MomentGraph,Ring) := GKMVariety => (G,R) -> ( if not #(gens R) == #(gens G.HTpt) then ( error "HTpt not compatible with the character ring" ); new GKMVariety from { symbol points => G.vertices, symbol characterRing => R, symbol momentGraph => G, cache => new CacheTable } ) --makeGKMVariety created from a moment graph G --the character ring is created from G.HTpt makeGKMVariety(MomentGraph) := GKMVariety => G -> ( R := makeCharacterRing numgens (G.HTpt); makeGKMVariety(G,R) ) --returns the moment graph of the GKM variety X if it is defined momentGraph(GKMVariety) := MomentGraph => X -> ( if X.?momentGraph then X.momentGraph else error "no moment graph defined for this GKM variety" ) --given GKMVariety X with X.momentGraph undefined, sets a moment graph G to be the --moment graph of X, granted that the two sanity checks (characterRing dimension, fixed points) work out momentGraph(GKMVariety,MomentGraph) := (X,G) -> ( if X.?momentGraph then ( print " warning: overwriting a previously defined moment graph on this GKM variety " ); if #(gens X.characterRing) != #(gens G.HTpt) then ( error "HTpt not compatible with the character ring" ); if not G.vertices === X.points then ( error "the torus-fixed points are not compatible" ); X.momentGraph = G; ) --makeGKMVariety created from list L of points and corresponding list M of their charts' characters, --and R the character ring of the torus makeGKMVariety(List,List,Ring) := GKMVariety => (L,M,R) -> ( new GKMVariety from { symbol points => L, symbol charts => hashTable apply(#L, i -> (L_i,M_i)), symbol characterRing => R, cache => new CacheTable } ) --given a GKMVariety X with an action of a torus T, whose X.charts have not been defined yet, --and a list L = {l_1, ... , l_m} where l_i is a list of characters of the torus action --at the affine chart around p_i where X.points = {p_1, ... , p_m} --defines X.charts to be the hash table whose keys are X.points and values the characters charts = method() charts(GKMVariety) := X -> ( if X.?charts then X.charts else error "no charts defined for this GKM variety" ) charts(GKMVariety,List) := (X,L) -> ( if X.?charts then ( print " warning: overwriting previously defined charts on this GKM variety " ); if not #X.points == #L then ( error "number of charts in the list not equal to number of points" ); X.charts = hashTable apply(#X.points, i -> (X.points_i,L_i)) ) --internal auxiliary function: --input: a Laurent polynomial f and a GKMVariety X --output: a Laurent polynomial f considered as an element of X.characterRing toCharacterRing = (X,f) -> ( if f == 1 then return 1_(X.characterRing); R := ring f; n := #(gens R); if not #(gens X.characterRing) == n then error "rings have different number of variables"; sub(f,apply(n, i -> R_i=>X.characterRing_i)) ) --projective space PP^n as a T=(k^*)^(n+1) variety, where (t_0, ... , t_n) acts on the --coordinates [x_0, ... , x_n] by [t_0^(-1)x_0, ... , t_n^(-1)x_n] --input: an integer n and the character ring R of T projectiveSpace = method() projectiveSpace(ZZ,Ring) := GKMVariety => (n,R) -> ( V := apply(n+1, i -> set {i}); E := hashTable apply(subsets(V,2), i -> ({i_0, i_1}, setIndicator(i_1,n+1) - setIndicator(i_0,n+1)) ); t := symbol t; H := QQ[t_0..t_n]; G := momentGraph(V,E,H); X := makeGKMVariety(G,R); L := apply(V, v -> (select(V, w -> w =!= v))/(w -> setIndicator(w,n+1) - setIndicator(v,n+1))); charts(X,L); X.cache.ampleKClass = makeKClass(X, (X.points)/(i -> R_(setIndicator(i,n+1)))); X ) --when only given an integer n projectiveSpace(ZZ) := GKMVariety => n -> ( R := makeCharacterRing(n+1); projectiveSpace(n,R) ) --product of two TVarieties X,Y with an action of a common torus T --the product is endowed with the diagonal action of T GKMVariety ** GKMVariety := GKMVariety => (X,Y) -> ( R := X.characterRing; if not R === Y.characterRing then error "character rings need be same"; L := elements ((set X.points) ** (set Y.points)); XxY := makeGKMVariety(L,R); if X.?charts and Y.?charts then ( M := apply(L, l -> (X.charts)#(first l) | (Y.charts)#(last l)); charts(XxY,M); ); XxY --TODO: if both has moment graphs, then should also compute the moment graph ) --the product function above does NOT automatically compute the product moment graph MomentGraph ** MomentGraph := MomentGraph => (G1,G2) -> ( if numgens G1.HTpt =!= numgens G2.HTpt then ( error " the two HTpt are different " ); H := G1.HTpt; V := (elements((set G1.vertices) ** (set G2.vertices)))/splice; E1 := flatten apply(G2.vertices, q -> (keys G1.edges)/(k -> ({(k_0,q), (k_1,q)}, G1.edges#k))); E2 := flatten apply(G1.vertices, p -> (keys G2.edges)/(k -> ({(p,k_0), (p,k_1)}, G2.edges#k))); mixedCand := select(elements ((set keys G1.edges) ** (set keys G2.edges)), i -> rank matrix {G1.edges#(i_0), G2.edges#(i_1)} < 2); mixedE := apply(mixedCand, i -> ( char1 := G1.edges#(i_0); char2 := G2.edges#(i_1); primitive := char1 // (gcd char1); firsts := {first select(char1, i -> i != 0), first select(char2, i -> i != 0)}; g := gcd (firsts/(i -> i / first select(primitive, i -> i!= 0))); trueChar := g * primitive; if firsts_0 * firsts_1 > 0 then ({(first i_0, first i_1), (last i_0, last i_1)}, trueChar) else ({(first i_0, last i_1), (last i_0, first i_1)}, trueChar) ) ); momentGraph(V, hashTable (E1 | E2 | mixedE), H) ) --Given a list L of characters of torus of X, outputs the numerator in the Hilbert series --of the associated monomial subalgebra tHilbNumer = method(); tHilbNumer(GKMVariety,List) := RingElement => (X,L) -> ( if L == {} then return toCharacterRing(X,1); A := affineToricRing L; I := ideal A; f := value numerator hilbertSeries I; toCharacterRing(X,f) ) cellOrder(GKMVariety) := Poset => X -> ( G := momentGraph X; cellOrder G ) --a KClass C has data of: --C.variety = a GKMVariety X that the equivariant K-class C lives on --C.KPolynomials = a hash table whose keys are points of X and values are the Hilbert series at the point KClass = new Type of HashTable KClass.synonym = "equivariant K-class" globalAssignment GKMVariety net KClass := C -> net ofClass class C | " on a GKM variety " --a KClass is given by a GKMVariety X and a list L of Laurent polynomials for each torus-invariant --points in X, (listed in the order of X.points) makeKClass = method(); makeKClass(GKMVariety,List) := KClass => (X,L) -> ( K := X.points; if any(L, l -> ring l =!= X.characterRing) then L = L/(f -> toCharacterRing(X,f)); new KClass from { symbol variety => X, symbol KPolynomials => hashTable apply(#K, i -> (K_i,L_i)) } ) makeGKMVariety(KClass) := GKMVariety => C -> C.variety --tests whether a KClass satisfies the edge-compatibility criterion isWellDefined(KClass) := Boolean => C -> ( X := C.variety; if not X.?momentGraph then ( error "a moment graph needs to be defined for this GKM variety " ); G := X.momentGraph; R := X.characterRing; x := symbol x; S := QQ[x_0..x_(#gens R - 1)]; badEdges := select(keys G.edges, e -> ( pt1 := first e; pt2 := last e; lambda := G.edges#e; ratio := toFraction(C.KPolynomials#pt1 - C.KPolynomials#pt2, 1 - R_lambda, S); #(terms(QQ,denominator first ratio)) != 1 ) ); if #badEdges != 0 then ( << "incompatible edges " | toString(badEdges) << return false ); true ) --the trivial KClass (where X^T --> R is a constant 1 function) of a GKMVariety X --in other words, the KClass of the structure sheaf of X trivialKClass = method(); trivialKClass(GKMVariety) := KClass => X -> ( R := X.characterRing; L := apply(X.points, p -> 1_R); makeKClass(X,L) ) --multiplying two KClasses KClass * KClass := (C1,C2) -> ( X1 := C1.variety; X2 := C2.variety; if not X1 === X2 then error "the GKM varieties are different"; L := apply(X1.points, p -> C1.KPolynomials#p * C2.KPolynomials#p); makeKClass(X1,L) ) KClass ^ ZZ := (C,d) -> ( if d > 0 then return product(d, i -> C) else if d == 0 then return trivialKClass C.variety else if d < 0 then ( if not all(values C.KPolynomials, f -> 1 == #terms f) then ( error "unable to compute the inverse of this K-class" ); L := apply(C.variety.points, p -> (C.KPolynomials#p)^(-1)); Cneg := makeKClass(C.variety,L); return product(-d, i -> Cneg) ) ) --adding two KClasses KClass + KClass := (C1,C2) -> ( X1 := C1.variety; X2 := C2.variety; if not X1 === X2 then error "the GKM varieties are different"; L := apply(X1.points, p -> C1.KPolynomials#p + C2.KPolynomials#p); makeKClass(X1,L) ) --if a GKMVariety X has a distinguished O(1) equivariant line bundle, then returns its KClass ampleKClass = method(); ampleKClass(GKMVariety) := KClass => X -> ( if X.cache.?ampleKClass then return X.cache.ampleKClass else error "no distinguished ample line bundle on this GKM variety"; ) --if a GKMVariety X does not have an ample class defined, and C is a KClass on X, --sets the ampleKClass of X to be C ampleKClass(GKMVariety,KClass) := (X,C) -> ( if X.cache?ampleKClass then ( print " warning: overwriting a previously defined ampleKClass on this GKM variety " ); if C.variety =!= X then error "not a KClass of this GKM variety"; X.cache.ampleKClass = C ) --a EquivariantMap f has data of: --f.source: the source makeGKMVariety X, --f.target: the target makeGKMVariety Y --f.ptsMap: a hash table whose keys are X.points and values are the point Y.points that it maps to EquivariantMap = new Type of HashTable EquivariantMap.synonym = "equivariant map" globalAssignment EquivariantMap net EquivariantMap := phi -> net ofClass class phi | " of GKM varieties " --a EquivariantMap is given by providing the source X and target Y and a list L of pairs (X point, Y point) map(GKMVariety,GKMVariety,List) := EquivariantMap => opts -> (X,Y,L) -> ( if not X.characterRing === Y.characterRing then error "character rings need be same"; new EquivariantMap from { symbol source => X, symbol target => Y, symbol ptsMap => hashTable L, cache => new CacheTable } ) --pullback map of KClasses given a EquivariantMap pullback(EquivariantMap) := FunctionClosure => {} >> o -> phi -> ( X := phi.source; Y := phi.target; if not phi.cache.?pullback then phi.cache.pullback = C -> ( if C.variety =!= Y then ( error "the KClass to pullback is not a KClass of the target GKM variety" ); L := apply(X.points, p -> C.KPolynomials#((phi.ptsMap)#p)); makeKClass(X,L) ); phi.cache.pullback ) --given a EquivariantMap, computes the pushforward map as a function pushforward = method(); pushforward(EquivariantMap) := FunctionClosure => phi -> ( if phi.cache.?pushforward then return phi.cache.pushforward; X := phi.source; Y := phi.target; R := X.characterRing; Ydenoms := hashTable apply(Y.points, q -> (q, product((Y.charts)#q, l -> 1-R_l))); Xdenoms := hashTable apply(X.points, p -> (p, product((X.charts)#p, l -> 1-R_l))); x := symbol x; S := QQ[x_0..x_(#(gens R)-1)]; pushforwardFct := C -> ( if not C.variety === X then error " KClass not of the source GKM variety "; L := apply(Y.points, q -> ( preimages := select(X.points, p -> (phi.ptsMap)#p === q); if #preimages == 0 then return 0_R; Ydenom := Ydenoms#q; toSum := apply(preimages, p -> toFraction(Ydenom * C.KPolynomials#p, Xdenoms#p, S)); val := (last first toSum) sum(toSum/first) ) ); makeKClass(Y,L) ); phi.cache.pushforward = pushforwardFct ) --given a GKMVariety X outputs the diagonal map X -> X x X diagonalMap = method(); diagonalMap(GKMVariety) := EquivariantMap => X -> ( Y := X ** X; ptPairs := apply(X.points, p -> ( Q := first select(Y.points, q -> (first q) === (last q) and (first q) === p); (p,Q) ) ); map(X,Y,ptPairs) ) --given two maps, takes Cartesian product of them EquivariantMap ** EquivariantMap := EquivariantMap => (phi,psi) -> ( X := phi.source ** psi.source; Y := phi.target ** psi.target; ptPairs := apply(X.points, p -> ( Q := ((phi.ptsMap)#(first p),(psi.ptsMap)#(last p)); (p,Q) ) ); map(X,Y,ptPairs) ) --composition f o g of two EquivariantMaps g: X --> Y, f: Y --> Z; compose(EquivariantMap,EquivariantMap) := EquivariantMap => {} >> o -> (f,g) -> ( Y1 := g.target; Y2 := f.source; if not Y1.points === Y2.points then ( error " check sources and targets of the equivariant morphisms " ); Z := f.target; X := g.source; ptPairs := apply(X.points, p -> (p, f.ptsMap#(g.ptsMap#p))); map(X,Z,ptPairs) ) --the equivariant Euler characteristic of a KClass, i.e. the Lefschetz trace, --i.e. the pushforward to a point euler(KClass) := RingElement => C -> ( X := C.variety; R := X.characterRing; pt := symbol pt; tPoint := makeGKMVariety({pt},{{}},R); tpt := first tPoint.points; structureMap := map(X,tPoint,apply(X.points, i -> (i,tpt))); pushC := (pushforward(structureMap))C; pushC.KPolynomials#tpt ) ----------------------------------------------------------------------------------------------- ---------------------------------< normal toric varieties >------------------------------------ --given a NormalToricVariety X, outputs a GKM variety Y with the data --Y.points are lists where each list is the indices of the rays defining the torus fixed point --X need be smooth, non-degenerate, and must have fixed-points. --WARNING: as usual, if an affine chart AA^m has characters a_1, ... , a_m, the torus (kk^*)^n --acts on AA^m by t * (x_1, ... , x_m) = (t^(-a_1)x_1, ... , t^(-a_m)x_m) --in other words, to agree with the usual normal toric variety literature, --one should consider OUTER normal cones of cones, not inner normal cones makeGKMVariety(NormalToricVariety,Ring) := GKMVariety => (X,R) -> ( if not isSmooth X then ( error " the normal toric variety is not smooth " ); n := dim X; if not n == #(gens R) then ( error " the character ring is incompatible with the torus of the toric variety " ); pts := select(max X, i -> #i == n); if pts == {} then ( error " no torus-fixed points on this normal toric variety " ); rys := rays X; chrts := apply(pts, p -> - entries transpose inverse matrix rys_p); Y := makeGKMVariety(pts,chrts,R); GEdgePairs := select(subsets(pts,2), i -> #(unique flatten i) == #(first i) + 1); GEdges := hashTable apply(GEdgePairs, i -> ( p := first i; q := last i; (i, first select(Y.charts#p, i -> member(-i,Y.charts#q))) ) ); momentGraph(Y,momentGraph(Y.points, GEdges, makeHTpt n)); Y.cache.normalToricVariety = X; Y ) makeGKMVariety(NormalToricVariety) := GKMVariety => X -> makeGKMVariety(X,makeCharacterRing dim X) --given a GKM variety X, returns a normal toric variety if X was constructed from one normalToricVariety(GKMVariety) := NormalToricVariety => opts -> X -> ( if X.cache.?normalToricVariety then X.cache.normalToricVariety else error " no normal toric variety structure on this GKM variety " ) --given a ToricDivisor D on a GKMVariety Y whose normal toric variety is X, --outputs the KClass of D on Y makeKClass(GKMVariety,ToricDivisor) := KClass => (Y,D) -> ( if not normalToricVariety D === normalToricVariety Y then ( error " the toric divisor is not of this GKM variety " ); R := Y.characterRing; hlbs := apply(Y.points, p -> ( l := flatten entries (matrix{(entries D)_p} * - matrix Y.charts#p); R_l ) ); makeKClass(Y,hlbs) ) ------------------------------------------------------------------------------------------------- --------------------------------< generalized flag varieties >----------------------------------- ------------------------------------------------------------------------------------------------- ---------< internal auxiliary functions: signed subsets, flags, and indicator vectors >---------- --makes a string "n*" given a positive integer n astrsk = n -> toString(n) | "*" --given either integer n or "n*", outputs n unastrsk = i -> if instance(i,String) then value first i else if instance(i,ZZ) then i else error --given a set s consisting of elements e where e is an integer i or "i*" with 0 <= i <= n-1 --outputs the signed indicator vector setIndicator = method() setIndicator(Set,ZZ) := List => (s,n) -> ( if (elements s)/unastrsk != unique (elements s/unastrsk) then ( error " the signed subset is not admissible " ); apply(n, i -> ( if member(i,s) then 1 else if member(astrsk i, s) then -1 else 0 ) ) ) --given a list of integers of length n, outputs the corresponding flag of signed subsets vecToFlag = v -> sort apply(max (v/abs), i -> ( supp := positions(v, j -> abs j > i); set apply(supp, j -> if v_j > 0 then j else astrsk j) ) ) --likewise, but applying "unique" redVecToFlag = v -> unique vecToFlag v flagToVec = (L,n) -> sum(L, s -> setIndicator(s,n)) --all signed permutations of a list --allows for repeated entries, just like the ordinary "permutations" function signedPermutations = L -> ( if #L == 1 then {{first L}, {- first L}} else flatten apply(#L, i -> flatten apply(signedPermutations(drop(L,{i,i})), j -> {j | {L_i}, j | {-L_i}}) ) ) --all even signed permutations (i.e. signed permutations with same parity of minus signs) --again, allows for repeated entries, like ordinary "permutations" and "signedPermutations" evenSignedPermutations = L -> ( SP := signedPermutations L; if any(L, i -> i == 0) then SP else ( parity := mod(#select(L, i -> i < 0),2); select(SP, l -> mod(#select(l, i -> i < 0),2) == parity) ) ) ---------------------< internal auxiliary functions: roots and weights >------------------------- --internal auxiliary functions for generalizedFlagVariety --given a classical Lie type LT, the root system dimension d, and list L = {l_1, ... , l_m}, --outputs the highest weight vector w_(l_1) + ... + w_(l_m) where w_i's are fundamental weights --(w_d in the orthogonal case ("B" and "D"), strictly speaking we are using --twice of the fundamental weight) highestWeight := (LT,d,L) -> ( if LT == "A" then n := d+1 else n = d; if member(LT,{"A","C"}) or (LT == "B" and not member(d,L)) then sum(L, i -> setIndicator(set apply(i, j -> j),n)) else if LT == "B" and member(d,L) then ( hw := sum(L, i -> ( if i < d then setIndicator(set apply(i, j -> j),n) else if i == d then 1/2 * setIndicator(set apply(i, j -> j),n) ) ); if all(hw, i -> liftable(i,ZZ)) then hw/(i -> lift(i,ZZ)) else error " spin groups not implemented yet " ) else if LT == "D" then ( hw = sum(L, i -> ( if i < d-1 then setIndicator(set apply(i, j -> j),n) else if i == d then 1/2 * setIndicator(set apply(d, j -> j),n) else if i == d-1 then 1/2 * setIndicator(set (apply(d-1, j -> j) | {astrsk(d-1)}),n) ) ); if all(hw, i -> liftable(i,ZZ)) then hw/(i -> lift(i,ZZ)) else error " spin groups not implemented yet " ) ) --the Weyl group orbit of the highest weight of (LT,d,L) with notation as above extremalWeights := (LT,d,L) -> ( lambda := highestWeight(LT,d,L); if LT == "A" then unique (permutations lambda) else if member(LT,{"B","C"}) then unique (signedPermutations lambda) else if LT == "D" then unique (evenSignedPermutations lambda) ) --given a classical Lie type LT, outputs a function f where, given a list v representing --a nonzero vector, f outputs {v / (abs gcd v)}, that is, a root if v is a (positive) -- multiple of a root, and f(v) = {} otherwise toRoot := LT -> ( if member(LT,{"A","D"}) then ( f := v -> ( non0s := select(v, i -> i != 0); if #non0s == 2 and abs first non0s == abs last non0s then {v // (abs gcd v)} else {} ) ) else if LT == "B" then ( f = v -> ( non0s := select(v, i -> i != 0); if #non0s == 1 or (#non0s == 2 and abs first non0s == abs last non0s) then {v // (abs gcd v)} else {} ) ) else if LT == "C" then ( f = v -> ( non0s := select(v, i -> i != 0); if #non0s == 1 then {2 * (v // (abs gcd v))} else if (#non0s == 2 and abs first non0s == abs last non0s) then {v // (abs gcd v)} else {} ) ) ) --input: LT, d, L --a string LT which is "A", "B", "C", or "D", representing the classical Lie types, --(we follow the convention in Example 3.4 of https://arxiv.org/pdf/1904.11029.pdf --for the ordering of simple roots and fundamental weights) --an integer d, representing the dimension of the root system, --(we do *not* check the low d isogenies, --for example, A_3 = D_3 but the code will not recognized this and output different things) --a list L of integers each ranging from 1 to d. --output: --a generalized flag variety G/P as a GKM variety with charts, --where G is the classical Lie group of type LT with an action of a d-torus T, --(except in the case of "A", we let T be the (d+1)-torus by *not* projectivizing the torus) --and P is the parabolic subgroup corresponding to W_([d]\L) --that is, subgroup of the Weyl group generated by elements *not* in L --the ample class is defined to be embedding of G/P coming from the representation of G --whose highest weight vector equals sum(L, i -> w_i) where w_i is the i-th fundamental weight --(except in the orthogonal case "B,D", the "half"-fundamental weights are doubled --that is, we are not considering the Spin representations but representations of SO(n). generalizedFlagVariety = method() generalizedFlagVariety(String,ZZ,List) := GKMVariety => (LT,d,L) -> ( if not member(LT,{"A","B","C","D"}) then ( error " the first argument must be one of \"A\", \"B\", \"C\", or \"D\" " ); if d <= 0 then ( error " the second argument (dimension) must be a positive integer " ); if not all(L, i -> 1 <= i and i <= d) then ( error " indices for the weights must be between 1 and the dimension (inclusive) " ); toRootFunc := toRoot LT; R := if LT == "A" then makeCharacterRing(d+1) else makeCharacterRing d; extrWts := extremalWeights(LT,d,L); GEdgesDouble := new MutableHashTable; chrts := apply(extrWts, v -> ( lambdas := {}; apply(delete(v,extrWts), w -> ( lambda := toRootFunc(w-v); if #lambda == 1 then ( lambdas = lambdas | lambda; GEdgesDouble#({v,w}/redVecToFlag) = first lambda; ) ) ); lambdas ) ); X := makeGKMVariety(extrWts/redVecToFlag, chrts, R); GEdges := hashTable apply(unique ((keys GEdgesDouble)/set), i -> ( e := elements i; (e, GEdgesDouble#e) ) ); H := if LT == "A" then makeHTpt(d+1) else makeHTpt d; G := momentGraph(X.points, GEdges, H); momentGraph(X,G); X.cache.ampleKClass = makeKClass(X, apply(extrWts, i -> R_i)); X.cache.lieType = LT; X ) ------------------------------------------------ -- Lines 870 - 882 can be replaced with ------------------------------------------------ -* chrts := apply(extrWts, v -> ( lambdas := select(apply(delete(v,extrWts), w-> {w,toRootFunc(w-v)}), u-> #u_1 == 1); apply(lambdas, u -> GEdgesDouble#({v,u_0}/redVecToFlag) = first u_1); apply(lambdas, u -> u_1) ); *- --same as generalizedFlagVariety but with the ring R provided for the character ring. generalizedFlagVariety(String,ZZ,List,Ring) := GKMVariety => (LT,d,L,R) -> ( X := generalizedFlagVariety(LT,d,L); S := X.characterRing; if #(gens R) != #(gens S) then error " check character ring "; conversion := map(R,S,gens R); X.characterRing = R; C := ampleKClass X; X.cache.ampleKClass = makeKClass(X, apply(X.points, i -> conversion C.KPolynomials#i)); X ) --if a GKMVariety is a generalized flag variety, returns its Lie type lieType = method() lieType(GKMVariety) := String => X -> ( if X.cache.?lieType then X.cache.lieType else error " no Lie Type defined for this GKM variety " ) --given a generalized flag variety, computes & stores the bruhat order for its moment graph --and then returns the poset bruhatOrder = method() bruhatOrder(GKMVariety) := Poset => X -> ( if not X.cache.?lieType then ( error " not a generalized flag variety " ); if X.momentGraph.cache.?cellOrder then return X.momentGraph.cache.cellOrder; LT := lieType X; G := X.momentGraph; n := #(gens X.characterRing); posWt := apply(n, i -> n - i); negRoots := select(values G.edges, v -> sum(n, i -> v_i * posWt_i) < 0); ground := G.vertices; rels := apply(keys G.edges, k -> if member(G.edges#k,negRoots) then k else reverse k); P := poset(ground,rels); cellOrder(X.momentGraph, P); P ) --Schubert variety of a generalized flag variety --input: is (X,v), where X is a generalized flag variety and v is a vertex in its moment graph --output: a GKMVariety representing a Schubert variety whose torus fixed points correspond to all --vertices w in the moment graph of X where v <= w generalizedSchubertVariety = method() generalizedSchubertVariety(GKMVariety,Thing) := GKMVariety => (X,v) -> ( G := momentGraph X; if not member(v,G.vertices) then ( error " the second argument must be a vertex of the moment graph of the GKMVariety " ); P := bruhatOrder X; V := principalFilter(P,v); E := hashTable apply(select(keys G.edges, k -> all(k, i -> member(i,V))), j -> (j,G.edges#j)); Y := makeGKMVariety(momentGraph(V,E,G.HTpt),X.characterRing); cellOrder(Y.momentGraph, subposet(P,V)); Y.cache.lieType = lieType X; Y ) -------------------------------------------------------------------------------------------------- --------------------------------< Torus orbit closures of points >------------------------------------ ---------------------------< auxiliary functions for TOrbClosure >-------------------------------- convertToNum = (n,L) -> apply(toList L, v -> if v === unastrsk(v) then v else n + unastrsk v) revMat = M -> matrix apply( reverse entries M, v-> reverse v) -- Takes in a mutable matrix and outputs the RREF with the identity block in the beginning rowRed = M -> mutableMatrix revMat transpose gens gb image transpose matrix revMat M --the equivariant K-class of a torus orbit closure of a point in a generalized flag variety --input: X a generalizedFlagVariety and MatLst a list of matrices, {M1,...,Mn}, that defines a point in X. -- For convenience we assume that the ranks of the M_i are distinct. --output: The makeKClass of the closure of the orbit of the point corresponding to {M1,...,Mn} tOrbClosure = method() tOrbClosure(GKMVariety,List) := KClass => (X,MatLst) -> ( if X.cache.?lieType then Typ := X.cache.lieType else ( error "Torus orbit closures are only implemented for Lie types" ); R := X.characterRing; m := numgens X.characterRing; x := symbol x; S := QQ[x_0..x_(m-1)]; QS := frac(QQ[x_0..x_(m-1), Degrees => apply(m, i -> setIndicator(set {i},m))]); rks := apply(first X.points, v -> #(elements v)); if not all(MatLst, v -> numcols v == ( if Typ === "A" then m else if Typ === "B" then 2*m+1 else 2*m ) ) then error "the column size of the matrices are incorrect"; if not rks === apply(MatLst, v -> rank v) then ( error " the ranks of the matrices are incorrect " ); (if Typ === "A" then Gens := apply(gens QS, v -> v^(-1)) else if Typ === "C" or Typ === "D" then Gens = apply(gens QS, v -> v^(-1)) | gens QS else if Typ === "B" then Gens = apply(gens QS, v -> v^(-1)) | gens QS |{1} ); Lst := apply(X.points, pt -> ( degList := {}; convertPt := apply(pt, v -> convertToNum(m,v)); if any(#rks, v -> determinant (rowRed MatLst_v)_(convertPt_v) == 0) then 0_R else ( for j in toList(0..#rks-1) do ( L := (reverse convertPt)#j; M := mutableMatrix sub((reverse MatLst)#j,QS); for i in toList(0..#L-1) do M = columnSwap(M,i,L#i); M = rowRed M; for i in reverse toList(0..#L-1) do M = columnSwap(M,i,L#i); for i in L do M = columnMult(M,i,0); for v in toList(0..#L-1) do M = rowMult(M,v,sub(Gens_(L_v)^(-1),ring M)); for v in toList(0..#Gens-1) do M = columnMult(M,v,sub(Gens_v, ring M)); degList = degList | apply(flatten entries M, v-> degree v); ); degs := - unique delete(-infinity, degList); tHilbSer := hilbertSeries affineToricRing degs; numer := toCharacterRing(X,value numerator tHilbSer); denom := toCharacterRing(X,value denominator tHilbSer); fracVal := toFraction(numer * product(X.charts#pt, l -> (1-R_l)), denom, S); (last fracVal)(first fracVal) -* degs *- ) ) ); makeKClass(X,Lst) -* hashTable apply(#X.points, i -> (X.points_i, Lst_i)) --and comment this *- ) --same as the tOrbClosure but computed in the different way --(without row reducing but just computing minors) --given a GKMVariety X that is a generalized flag variety consisting of linear subspaces of --dimensions rks = {r_1, ... , r_k}, and a matrix A that is k' x (appropriate numcols), --where k' >= k, and the first r_i rows span an appropriate isotropic subspace, --outputs the KClass of the torus-orbit closure. orbitClosure = method(Options => {RREFMethod => false}) orbitClosure(GKMVariety,Matrix) := KClass => opts -> (X,A) -> ( rks := apply(first X.points, v -> #(elements v)); MatLst := apply(rks, i -> A^(apply(i, j -> j))); if opts.RREFMethod then return tOrbClosure(X,MatLst); if X.cache.?lieType then Typ := X.cache.lieType else ( error "Torus orbit closures are only implemented for Lie types" ); R := X.characterRing; n := numgens R; col := ( if Typ === "A" then n else if Typ === "B" then 2*n+1 else 2*n ); if not numcols A == col then ( error "the column size of the matrices are incorrect" ); if not rks === apply(MatLst, v -> rank v) then ( error " the ranks of the matrices are incorrect" ); nonzeroMinors := Mat -> select(subsets(numcols Mat, numrows Mat), l -> determinant Mat_l != 0); toWeights := l -> ( if Typ === "A" then setIndicator(set l,n) else if Typ === "B" then ( pos := setIndicator(set select(l, i -> i < n),n); neg := setIndicator(set ((select(l, i -> i > n-1 and i < 2*n))/(j -> j-n)),n); pos - neg ) else ( post := setIndicator(set select(l, i -> i < n),n); nega := setIndicator(set ((select(l, i -> i > n-1))/(j -> j-n)),n); post - nega ) ); weightLst := apply(MatLst, m -> (unique ((nonzeroMinors m)/toWeights))/(i -> R_i)); basePolytopeWeights := ( init := matrix{{1_R}}; apply(weightLst, l -> init = init ** matrix{l}); (unique flatten entries init)/(f -> first exponents f) ); x := symbol x; S := QQ[x_0..x_(n-1)]; Lst := apply(X.points, pt -> ( start := sum(pt, i -> setIndicator(i,n)); if not member(start,basePolytopeWeights) then return 0_R; --degs := delete(apply(n, i -> 0), basePolytopeWeights/(w -> w - start)); --above "degs" is mathematically easier to verify but is slower degs := select(X.charts#pt, i -> member(start+i,basePolytopeWeights)); tHilbSer := hilbertSeries affineToricRing degs; numer := toCharacterRing(X,value numerator tHilbSer); denom := toCharacterRing(X,value denominator tHilbSer); fracVal := toFraction(numer * product(X.charts#pt, l -> (1-R_l)), denom, S); (last fracVal)(first fracVal) ) ); makeKClass(X,Lst) ) ---------------------------------------------------------------------------------------------- --------------------------------< ordinary flag varieties >----------------------------------- --swaps the (l_0,l_1)th places in the vector v swap = (v,l) -> apply(#v, i -> if i == first l then v_(last l) else if i == last l then v_(first l) else v_i ) --converts a pair s into a length n list where s_0 has -1 and s_1 has 1 and 0 everywhere else swapIndicator = (s,n) -> ( apply(n, i -> if i == first s then -1 else if i == last s then 1 else 0 ) ) -*-----------< subsumed in generalizedFlagVariety command now >-------------- --Given a list K = {k_1, ... , k_m} and a number n defining flag variety Fl(K;n) consisting of --flags of linear subspaces of kk^n of dimensions k_1, ... , k_m, returns the GKMVariety where --the action of T = (kk^*)^n on the vector space kk^n is (t.v) = (t^-1v) tFlagVariety = method(); tFlagVariety(List,ZZ,Ring) := GKMVariety => (K,n,R) -> ( if not #(gens R) == n then << "check character ring" << return error; if not max K < n then << "check rank sequence K" << return error; E := set toList(0..(n-1)); pts := (unique permutations sum(K/(k -> toList(k:1) | toList(n-k:0))))/vecToFlag; chrts := apply(pts, p -> (toList sum(p, l -> l**(E-l)))/(s -> swapIndicator(s,n))); X := makeGKMVariety(pts,chrts,R); L := apply(X.points, p -> (Exps := flagToVec(p,n); product(#Exps, i -> R_i^(Exps_i)))); X.cache.ampleKClass = makeKClass(X,L); X ) --if one does not want to make the characterRing beforehand. --NOT recommended for use... tFlagVariety(List,ZZ) := GKMVariety => (K,n) -> tFlagVariety(K,n,makeCharacterRing n) --Given two lists Kso, Kta (for rank sequences of source and target flag varieties) and n, --creates the two TVarieties and makes a EquivariantMap between them (given the characterRing R). flagMap(List,List,ZZ,Ring) := EquivariantMap => (Kso,Kta,n,R) -> ( Flso := tFlagVariety(Kso,n,R); Flta := tFlagVariety(Kta,n,R); ptPairs := apply(Flso.points, p -> (p,first select(Flta.points, q -> isSubset(q,p)))); map(Flso,Flta,ptPairs) ) ----------------*- --if X and Y are already generalizedFlagVariety, then the following outputs the corresponding -- flagMap X --> Y flagMap = method(); flagMap(GKMVariety,GKMVariety) := EquivariantMap => (X,Y) -> ( if not (X.cache.?lieType and Y.cache.?lieType) then ( error "both GKM varieties need have a lieType" ); if not X.characterRing === Y.characterRing then error "character ring need be same"; ptPairs := apply(X.points, p -> (p,first select(Y.points, q -> isSubset(q,p)))); map(X,Y,ptPairs) ) ----------------------------------< ordinary flag matroids >-------------------------------------- FlagMatroid = new Type of HashTable FlagMatroid.synonym = "flag matroid" globalAssignment FlagMatroid net FlagMatroid := M -> net ofClass class M | " with rank sequence " | toString((M.constituents)/rank) | " on " | toString(#M.groundSet) | " elements " flagMatroid = method() --Given a list L of concordant matroids (M_1, ... , M_k) returns the flag matroid object --Convention: M_i is quotient of M_(i+1) --Does not check concordance of matroids in the list, but checks same cardinality of ground set. flagMatroid(List) := FlagMatroid => L -> ( E := (first L).groundSet; n := #E; if any(L, m -> not #m.groundSet == n) then error "ground set not all same size"; new FlagMatroid from { symbol groundSet => E, symbol constituents => L, cache => new CacheTable } ) --Given l x n matrix A and a list r of ranks, outputs the associated flag matroid flagMatroid(Matrix,List) := FlagMatroid => (A,r) -> ( k := #r; l := numcols A; if r == {} or any(k-1, i -> r_i > r_(i+1)) or r_(k-1) > l then ( error "check rank sequence" ); ML := apply(k, i -> matroid A^(toList(0..(r_i-1))) ); flagMatroid ML ) --checks that the constituents of a flag matroid M are concordant isWellDefined(FlagMatroid) := Boolean => M -> ( L := M.constituents; k := #L; all(k-1, i -> isSubset(flats L_i, flats L_(i+1))) and all(L, isWellDefined) ) --for a flag matroid F, outputs a list of chains of bases of the constituent matroids bases(FlagMatroid) := List => M -> ( if not M.cache.?bases then M.cache.bases = ( ML := M.constituents; k := #ML; BL := flatten apply(k, i -> (bases ML_i)/(b -> (i,b)) ); rel := (a,b) -> first a < first b and isSubset(last a, last b); P := poset(BL, rel , AntisymmetryStrategy => "none"); (maximalChains P)/(c -> c/last) ); M.cache.bases ) --computes the lattice points of the base polytope of a flag matroid M latticePoints(FlagMatroid) := M -> ( n := #M.groundSet; BL := M.constituents/bases/(B -> B/(b -> setIndicator(b,n))); k := #BL; unique apply((k:0)..toSequence(BL/(B -> #B-1)), i -> sum(k, j -> (BL_j)_(i_j))) ) -*-----------------< not needed at this the moment >---------- --direct sum, deletion, restriction, and contraction of a flag matroid is done by doing --respective operation on the operation on each constituents FlagMatroid ++ FlagMatroid := FlagMatroid => (M,N) -> ( ML := M.constituents; NL := N.constituents; if not #ML == #NL then << "two flag matroids have different number of constituents" << return error; flagMatroid apply(#ML, i -> ML_i ++ NL_i) ) restriction(FlagMatroid,Set) := FlagMatroid => (M,S) -> ( flagMatroid(M.constituents/(m -> restriction(m,S))) ) restriction(FlagMatroid,List) := FlagMatroid => (M,L) -> ( flagMatroid(M.constituents/(m -> restriction(m,L))) ) contraction(FlagMatroid,Set) := FlagMatroids => (M,S) -> ( flagMatroid(M.constituents/(m -> contraction(m,S))) ) contraction(FlagMatroid,List) := FlagMatroids => (M,L) -> ( flagMatroid(M.constituents/(m -> contraction(m,L))) ) deletion(FlagMatroid,Set) := FlagMatroid => (M,S) -> ( flagMatroid(M.constituents/(m -> deletion(m,S))) ) deletion(FlagMatroid,List) := FlagMatroid => (M,L) -> ( flagMatroid(M.constituents/(m -> deletion(m,L))) ) FlagMatroid | Set := (M,S) -> restriction(M,S) FlagMatroid \ Set := (M,S) -> deletion(M,S) FlagMatroid / Set := (M,S) -> contraction(M,S) FlagMatroid | List := (M,L) -> restriction(M,L) FlagMatroid \ List := (M,L) -> deletion(M,L) FlagMatroid / List := (M,L) -> contraction(M,L) dual(FlagMatroid) := FlagMatroid => {} >> opts -> M -> ( ML := M.constituents; flagMatroid apply(reverse ML, m -> dual m) ) face(Matroid,Set) := (M,S) -> (M | S) ++ (M / S) face(FlagMatroid,Set) := (M,S) -> (M | S) ++ (M / S) --rank (of a subset) in a flag matroid rank(FlagMatroid) := ZZ => M -> sum(M.constituents/rank) rank(FlagMatroid,Set) := ZZ => (M,A) -> sum(M.constituents, m -> rank(m,A)) -------------------------*- --given a flag matroid M, returns the KClass of its 'torus-orbit' in the flag-variety X makeKClass(GKMVariety,FlagMatroid) := KClass => (X,M) -> ( if not (lieType X) === "A" then error "the GKM variety is not a flag variety"; E := M.groundSet; K := M.constituents/rank; R := X.characterRing; if not (#(gens R) == #E and (first X.points)/(s -> #s) == K) then error "wrong flag variety for the flag matroid"; B := bases M; L := apply(X.points, p -> ( if not member(p,B) then return 0_R; vp := flagToVec(p,#E); rays := select(X.charts#p, r -> member(vecToFlag(swap(vp,positions(r, i -> not i == 0))),B)); nonrays := select(X.charts#p, r -> not member(r,rays)); ConeP := tHilbNumer(X,rays); if #nonrays == 0 then ConeP else ConeP * product(nonrays, l -> (1-R_l)) ) ); makeKClass(X,L) ) --internal method --sets up the varieties involved in the Fourier-Mukai themed push-pull diagram for the --flag geometric Tutte polynomial of a flag matroid. The characterRing R should be given. --Given a list K and an integer n, sets up Fl(K;n) <-f- Fl(1,K,n-1;n) -g-> Fl(1;n) x Fl(n-1;n) fourierMukai = method(); fourierMukai(List,ZZ,Ring) := List => (K,n,R) -> ( FlK := generalizedFlagVariety("A",n-1,K,R); Fl1Kn1 := generalizedFlagVariety("A",n-1,unique ({1}|K|{n-1}), R); Fl1 := generalizedFlagVariety("A",n-1,{1},R); Fln1 := generalizedFlagVariety("A",n-1,{n-1},R); piK := flagMap(Fl1Kn1,FlK); f := flagMap(Fl1Kn1,Fl1); g := flagMap(Fl1Kn1,Fln1); pi1n1 := compose(f ** g, diagonalMap Fl1Kn1); --<< "{{Fl(K;n), Fl(1,K,n-1;n), Fl(1;n) x Fl(n-1;n)},{pi_K, pi_(1(n-1))}}" << {{FlK, Fl1Kn1, pi1n1.target}, {piK, pi1n1}} ) fourierMukai(List,ZZ) := List => (K,n) -> fourierMukai(K,n, makeCharacterRing n) ---< auxiliary functions for converting equivariant class to in terms of alpha, beta >--- --takes in a makeKClass C of Fl(1;n) x Fl(n-1;n) and outputs the matrix whose (i,j)th entry --is the KPolynomials value at the point {set{i}, [n]\set{j}} toMatrix = C -> ( R := C.variety.characterRing; n := #(gens R); E := set toList(0..(n-1)); matrix apply(n, i -> apply(n, j -> ( if i == j then return 0_R; C.KPolynomials#(({set{i}}, {E - set{j}})) )) ) ) aa = (i0,i,j,R) -> (R_i-R_(i0))*(R_i^(-1)); bb = (j0,i,j,R) -> (R_(j0) - R_j)*(R_(j0)^(-1)); equiToNonEquiStep = (i0,j0,X) -> ( R := ring X_(0,0); n := #(gens R); t := symbol t; S := QQ[t_0..t_(n-1)]; denom := sub(product(i0, k -> aa(k,i0,j0,R))*product(j0, k -> bb(k,i0,j0,R)),R); c := first toFraction(X_(i0,j0), denom,S); cVal := sub(c, apply(gens ring c, r -> r=>1)); XX := matrix apply(n, i -> apply(n, j -> ( numer := X_(i0,j0) * product(i0, k -> aa(k,i,j,R)) * product(j0, k -> bb(k,i,j,R)); ratio := toFraction(numer,denom,S); (last ratio) (first toFraction(X_(i,j),1_R,S) - first ratio) )) ); {cVal,XX} ) --internal method --Given a KClass in P^(n-1) x P^(n-1) = Gr(n-1;n) x Gr(1;n), --outputs the polynomial in representing its K-class --where x,y are the structure sheaves of the two hyperplanes toPolynomial = method(); toPolynomial(KClass) := Matrix => C -> ( T := toMatrix C; n := numcols T; TList := {T}; M := matrix apply(n, i -> apply(n, j -> ( out := equiToNonEquiStep(i,j,TList_(-1)); TList = append(TList, last out); first out )) ); x := symbol x; y := symbol y; S := ZZ[x,y]; sum(n, i -> sum(n, j -> M_(i,j) * S_0^j * S_1^i)) ) --given a flag matroid M, outputs the flag-geometric Tutte polynomial of M flagGeomTuttePolynomial = method(); flagGeomTuttePolynomial(FlagMatroid) := RingElement => M -> ( if not M.cache.?flagGeomTuttePolynomial then M.cache.flagGeomTuttePolynomial = ( n := #M.groundSet; R := makeCharacterRing n; K := M.constituents/rank; FM := fourierMukai(K,n,R); FlK := first first FM; f := first last FM; g := last last FM; yM := makeKClass(FlK,M); YM := (pushforward g)( (pullback f)(yM * (ampleKClass FlK)) ); toPolynomial YM ); M.cache.flagGeomTuttePolynomial ) load "GKMVarieties/Documentation_GKMVarieties.m2" load "GKMVarieties/Tests_GKMVarieties.m2" end --------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------- restart uninstallPackage "GKMVarieties" installPackage "GKMVarieties" --42 seconds viewHelp GKMVarieties check "GKMVarieties" needsPackage "GKMVarieties" -----------------------< canned examples >--------------------------- FM = flagMatroid {uniformMatroid(1,5),uniformMatroid(3,5)} time flagGeomTuttePolynomial FM -- 7 seconds FM = flagMatroid {uniformMatroid(2,6),uniformMatroid(4,6)} --time flagGeomTuttePolynomial FM --700 seconds -*-- i11 : FM = flagMatroid {uniformMatroid(2,6),uniformMatroid(4,6)} o11 = a flag matroid with rank sequence {2, 4} on 6 elements o11 : FlagMatroid i12 : time flagGeomTuttePolynomial FM -- used 691.322 seconds 4 4 4 3 3 4 4 2 3 3 2 4 4 3 2 2 3 4 4 3 o12 = x y + 2x y + 2x y + 3x y - 6x y + 3x y + 4x y + 18x y + 18x y + 4x*y + 5x + 14x y -------------------------------------------------------------------------------------------- 2 2 3 4 3 2 2 3 + 18x y + 14x*y + 5y + 2x + 6x y + 6x*y + 2y o12 : ZZ[x, y] --*- --canned examples for displaying error messages --for bruhatOrder Fl3 = generalizedFlagVariety("A",2,{1,2}) cellOrder Fl3 P = bruhatOrder Fl3 #(coveringRelations P) == 8 cellOrder Fl3 --for (cellOrder, MomentGraph, Poset) PP3 = projectiveSpace 3 cellOrder PP3 V = (momentGraph PP3).vertices P = poset(V, {{V_0,V_1},{V_1,V_2},{V_2,V_3}}) cellOrder(momentGraph PP3, P) cellOrder PP3 --for setIndicator T3 = set{1,"1*","2*",3} setIndicator(T3,4)
Simpan