Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 77 additions & 14 deletions M2/Macaulay2/packages/CotangentSchubert.m2
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
newPackage(
"CotangentSchubert",
AuxiliaryFiles => true,
Version => "0.71",
Date => "25 Jul 2023", -- "22 Mar 2021",
Version => "0.8",
Date => "15 June 2026", -- "22 Mar 2021",
Authors => {{Name => "Paul Zinn-Justin",
Email => "pzinn@unimelb.edu.au",
HomePage => "http://blogs.unimelb.edu.au/paul-zinn-justin/"}},
Headline => "Cotangent Schubert calculus",
Keywords => {"Intersection Theory"},
Keywords => {"Intersection Theory", "Flag Varieties", "Equivariant Cohomology"},
PackageImports => {"VectorGraphics"},
AuxiliaryFiles => true,
DebuggingMode => false,
Expand Down Expand Up @@ -51,11 +51,23 @@ multidoc ///

References: @BR{}@
[1] A. Knutson and P. Zinn-Justin, Schubert puzzles and integrability I: invariant trilinear forms,
Communications of the American Mathematical Society 6:1-67,
@HREF{"http://arxiv.org/abs/1706.10019","arXiv:1706.10019"}@. @BR{}@
[2] A. Knutson and P. Zinn-Justin, Schubert puzzles and integrability II: multiplying motivic Segre classes,
Communications of the American Mathematical Society 6:68–152,
@HREF{"http://arxiv.org/abs/2102.00563","arXiv:2102.00563"}@. @BR{}@
[3] A. Knutson and P. Zinn-Justin, Schubert puzzles and integrability III: separated descents,
@HREF{"http://arxiv.org/abs/2306.13855","arXiv:2306.13855"}@.
Node
Key
LabelList
Headline
A list encoding a fixed point or puzzle label
Description
Text
@TT "LabelList"@ is a subtype of @TO{List}@ used to encode fixed points of flag
varieties and the corresponding labels of puzzles. The label list returned by
@TO{setupCotangent}@ consists of objects of this type.
Node
Key
setupCotangent
Expand Down Expand Up @@ -96,6 +108,31 @@ multidoc ///
Text
the first output is a "diagonal algebra", i.e., a vector space over @TT "FF"@ with componentwise product. The last two outputs
are the same as above.
Node
Key
Partial
Headline
Choose the partial or full flag variety ring
Description
Text
This boolean option applies to class computations after using @TO{setupCotangent}@ with
@TT "Presentation=>Borel"@. Setting @TT "Partial=>true"@ returns a class in the
cohomology or K-theory ring @TT "A"@ of the specified partial flag variety, while
@TT "Partial=>false"@ returns the corresponding class in the ring @TT "B"@ of the
full flag variety.

The option is accepted by @TO{tautoClass}@, @TO{zeroSection}@,
@TO{dualZeroSection}@, @TO{canonicalClass}@, and the class families
@TO{sClass}@, @TO{stableClass}@, @TO{segreClass}@, @TO{chernClass}@,
@TO{schubertClass}@ and their primed variants.

When the ring @TT "A"@ is supplied explicitly, the default is @TT "Partial=>true"@.
When @TT "B"@ is supplied, or when the ring argument is omitted, the default is
@TT "Partial=>false"@.
Example
(A,B,FF,I) = setupCotangent(2,4,Presentation=>Borel,Equivariant=>false);
schubertClass("0101",Partial=>true)
schubertClass("0101",Partial=>false)
Node
Key
chernClass
Expand Down Expand Up @@ -194,16 +231,18 @@ multidoc ///
Headline
Compute the class of a tautological bundle
Usage
tautoClass (i,j)
tautoClass (i,j,A)
tautoClass (j,i)
tautoClass (j,i,A)
Inputs
i : ZZ
j : ZZ
i : ZZ
A : Ring
Description
Text
This function computes the i-th Chern class of the j-th tautological bundle of the flag variety whose K-theory (or cohomology)
This function computes the j-th Chern class of the i-th tautological bundle of the flag variety whose K-theory (or cohomology)
ring is given by @TT "A"@. If @TT "A"@ is not specified, then the ring that was defined last is used.
Example
(A,B,FF,I) = setupCotangent(2,3,Presentation=>Borel); {tautoClass(1,1,A),tautoClass(2,1,A),tautoClass(1,2,A)}
Node
Key
pushforwardToPoint
Expand Down Expand Up @@ -267,9 +306,10 @@ multidoc ///
Class of the canonical bundle of a flag variety
Description
Text
This function returns the class of the canonical bundle of the flag variety
in the cohomology ring given as argument (or the last ring defined with @TO {setupCotangent}@
if no argument is given).
This function returns the K-theory class of the canonical bundle of the flag variety
when @TT "Ktheory=>true"@, and its first Chern class when @TT "Ktheory=>false"@.
The ring is given as argument, or is the last ring defined with @TO {setupCotangent}@
if no argument is given.
Node
Key
puzzle
Expand All @@ -279,6 +319,7 @@ multidoc ///
[puzzle, Equivariant]
[puzzle, Labels]
[puzzle, Paths]
[puzzle, Separation]
[puzzle, Steps]
Puzzle
Headline
Expand Down Expand Up @@ -313,9 +354,15 @@ multidoc ///
this will not occur in normal puzzle computations). The special symbol "#" stands for any single digit,
whereas "*" stands for any puzzle label.

Note that only puzzles up to d=3 are implemented.

One more symbol in boundary strings is allowed, namely "_"; this will trigger the option @TT "Separation"@ which allows the computation
of separated or almost separated descent puzzles, see paper [3] for details.

@TT "Labels"@ and @TT "Paths"@ are drawing options which only affect HTML and TeX output of puzzles.
Example
puzzle ("0101","1001",Equivariant=>false)
puzzle("1_20__","4_32_4",Generic=>false,Equivariant=>false)
Node
Key
fugacity
Expand Down Expand Up @@ -395,11 +442,8 @@ multidoc ///
Caveat
At the moment, the interactive part only works on nonequivariant puzzles.
///
-- TODO: 12 of the symbols listed below as `undocumented` also appear in
-- option-doc Usage sub-keys via [puzzle, Ktheory], [setupCotangent, Borel],
-- etc. Either give each its own doc node or remove it from doc Usage.
undocumented {
Presentation, Ktheory, Equivariant, Partial, Borel, EquivLoc,
Presentation, Ktheory, Equivariant, Borel, EquivLoc,
Paths, Labels, Length, Steps, Ktheory', Separation,
(restrict,Matrix),(restrict,Matrix,RingElement),
(inversion,String),
Expand Down Expand Up @@ -444,6 +488,9 @@ assert(class stableClass "0101" === B and class stableClass' "0101" === B)
///

TEST /// -- tautoClass, zeroSection, dualZeroSection, and pushforwardToPointFromCotangent
(A,B,FF,I)=setupCotangent(1,2,3,Presentation=>Borel)
-- on a full flag, first Chern classes are just variables
assert(all(1..3,i->tautoClass(1,i)==x_i))
(A,B,FF,I) = setupCotangent(2,4,Presentation=>Borel,Ktheory=>false,Equivariant=>false);
-- the 0-th Chern class of any tautological bundle is the identity
assert(tautoClass(0,1) == 1)
Expand All @@ -458,6 +505,22 @@ assert(pushforwardToPoint 1_A == 0)
assert(pushforwardToPointFromCotangent(zeroSection A * dualZeroSection A) == #I)
///

TEST /// -- canonicalClass in cohomology and K-theory
-- on P^1, the first Chern class is the difference of the two Chern roots
(A,B,FF,I) = setupCotangent(1,2,Presentation=>Borel,Ktheory=>false,Equivariant=>false);
assert(canonicalClass A == tautoClass(1,2,A) - tautoClass(1,1,A))
assert(canonicalClass() == canonicalClass B)
-- the Borel and localization presentations agree after restriction
(A,B,FF,I) = setupCotangent(1,2,Presentation=>Borel,Ktheory=>false,Equivariant=>true);
r = restrict canonicalClass A;
(D,FF,I) = setupCotangent(1,2,Presentation=>EquivLoc,Ktheory=>false,Equivariant=>true);
assert(r == canonicalClass D)
assert(canonicalClass() == canonicalClass D)
-- retain the existing multiplicative K-theory behavior
(D,FF,I) = setupCotangent(1,2,Presentation=>EquivLoc,Ktheory=>true,Equivariant=>true);
assert(canonicalClass() == canonicalClass D)
///

TEST /// -- inversion counts the inversions of a label string
assert(inversion "01" == 0)
assert(inversion "10" == 1)
Expand Down
43 changes: 23 additions & 20 deletions M2/Macaulay2/packages/CotangentSchubert/cotangent.m2
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ cotOpts := opts ++ { Presentation => EquivLoc }
debug Core -- to use BaseRing, generatorSymbols, frame

-- labeling of classes
-- TODO: LabelList is exported (at CotangentSchubert.m2:33) but has no doc node.
LabelList = new Type of List;
new LabelList from String := (T,s) -> (
l:=separate(" ",s);
Expand Down Expand Up @@ -62,17 +61,9 @@ expandElem := (P,vrs,els) -> (
sub(C,ring first els) * product(#vrs, i -> (els#i)^(ee#i)) + expandElem(Q,vrs,els)
)

-- FIXME: tautoClass(i,j) errors with "array index out of bounds" when j is
-- outside the (undocumented) range of valid tautological-bundle indices for
-- the current setup. The doc gives no bound on j; on setupCotangent(2,4)
-- only j=1 is accepted (tautoClass(0,2) errors).
tautoClass = method(Dispatch=>{Thing,Thing,Type},Options=>true); -- "Chern classes" -- renamed tautoClass to avoid confusion with motivic classes
zeroSection = method(Dispatch=>{Type},Options=>true) -- note the {}
dualZeroSection = method(Dispatch=>{Type},Options=>true) -- note the {}
-- FIXME: canonicalClass is exported and documented but no method appears to
-- be installed in setupCotangent's body; calling canonicalClass on any ring
-- produced by setupCotangent (Borel/EquivLoc, equivariant or not) errors with
-- "no method found". See the doc node at CotangentSchubert.m2:263-272.
canonicalClass = method(Dispatch=>{Type},Options=>true) -- note the {}
zeroSectionInv = method(Dispatch=>{Type},Options=>true) -- internal use only
segreClass = method(Dispatch=>{Thing,Type},Options=>true)
Expand Down Expand Up @@ -153,7 +144,8 @@ defineB = (FF,n,Kth,Equiv) -> ( -- TODO remove FF

-- diagonal algebra
DiagonalAlgebra = new Type of Type;
DiagonalAlgebra List := (D,l) -> new D from {map(D.Module,(ring D)^1,apply(splice l, i -> {i}))}; -- cannot be new D from List because would break existing Vector code
-- Infer the source degree as vector does; new D from List breaks inherited Vector code.
DiagonalAlgebra List := (D,l) -> new D from {map(D.Module,,apply(splice l, i -> {i}))};
new DiagonalAlgebra from Module := (X,M) -> (
D := new DiagonalAlgebra of Vector from hashTable { global Module => M };
new D from Vector := (D,v) -> (
Expand Down Expand Up @@ -258,9 +250,9 @@ setupCotangent = cotOpts >> curCotOpts -> dims0 -> (
BB := defineB(FF,n,curCotOpts.Ktheory,curCotOpts.Equivariant);
x := getSymbol "x";
-- Chern classes
inds := splice apply(d+1, i -> apply(1..dimdiffs#i,j->(j,i)));
v := (j,i) -> x_(j,toList(dims#i+1..dims#(i+1))); -- variable name
e := (j,i) -> elem(j,apply(dims#i..dims#(i+1)-1,k->BB_k)); -- expression in terms of Chern roots
inds := splice apply(d+1, i -> apply(1..dimdiffs#i,j->(j,i+1)));
v := (j,i) -> x_(j,toList(dims#(i-1)+1..dims#i)); -- variable name
e := (j,i) -> elem(j,apply(dims#(i-1)..dims#i-1,k->BB_k)); -- expression in terms of Chern roots
args := v\inds;
if curCotOpts.Ktheory then (
args = append(args,DegreeRank=>0);
Expand All @@ -283,12 +275,16 @@ setupCotangent = cotOpts >> curCotOpts -> dims0 -> (
b = sub(b,AB);
-- scan(d+1,i->b=expandElem(b,toList(AB_(dims#i)..AB_(dims#(i+1)-1)),toList(AB_(n+dims#i)..AB_(n+dims#(i+1)-1))));
-- fails because of https://github.com/Macaulay2/M2/issues/2020
v := seq -> apply(toList seq, j -> AB_j);
scan(d+1,i->b=expandElem(b,v(dims#i..dims#(i+1)-1),v(n+dims#i..n+dims#(i+1)-1)));
vv := seq -> apply(toList seq, j -> AB_j);
scan(d+1,i->b=expandElem(b,vv(dims#i..dims#(i+1)-1),vv(n+dims#i..n+dims#(i+1)-1)));
sub(b,AA)
),BB,AA);
--
tautoClass (ZZ,ZZ,AA) := { Partial => true} >> o -> (j,i,AA) -> if o.Partial then AA_(dims#i+j-1) else e (j,i);
tautoClass (ZZ,ZZ,AA) := { Partial => true} >> o -> (j,i,AA) -> ( -- j^th Chern class of i^th tautological bundle
if i<1 or i>d+1 then error ("second index outside the range 1.."|toString(d+1));
if j<0 or j>dimdiffs#(i-1) then error ("first index outside the range 0.."|toString(dimdiffs#(i-1)));
if o.Partial then AA_(dims#(i-1)+j-1) else e (j,i)
);
zeroSection AA := { Partial => true} >> o -> (cacheValue (zeroSection,o.Partial)) (if o.Partial then AA -> lift(zeroSection(AA,Partial=>false),AA)
else if curCotOpts.Ktheory then
AA -> product(n,j->product(n,k->if ω0#j<ω0#k then 1-FF_0^2*BB_j*BB_k^(-1) else 1))
Expand All @@ -297,8 +293,10 @@ setupCotangent = cotOpts >> curCotOpts -> dims0 -> (
else if curCotOpts.Ktheory then
AA -> product(n,j->product(n,k->if ω0#j<ω0#k then 1-FF_0^-2*BB_k*BB_j^(-1) else 1))
else AA -> product(n,j->product(n,k->if ω0#j<ω0#k then -FF_0+BB_j-BB_k else 1)));
if curCotOpts.Ktheory then canonicalClass AA := { Partial => true} >> o -> (cacheValue (canonicalClass,o.Partial)) (if o.Partial then AA -> lift(canonicalClass(AA,Partial=>false),AA)
else AA -> product(n,j->product(n,k->if ω0#j<ω0#k then BB_k*BB_j^(-1) else 1)));
canonicalClass AA := { Partial => true} >> o -> (cacheValue (canonicalClass,o.Partial)) (if o.Partial then AA -> lift(canonicalClass(AA,Partial=>false),AA)
else if curCotOpts.Ktheory then
AA -> product(n,j->product(n,k->if ω0#j<ω0#k then BB_k*BB_j^(-1) else 1))
else AA -> sum(n,j->sum(n,k->if ω0#j<ω0#k then BB_k-BB_j else 0_BB)));
zeroSectionInv AA := { Partial => true } >> o -> (cacheValue (zeroSectionInv,o.Partial)) (AA -> (zeroSection(AA,o))^(-1));
-- Segre Classes TODO rethink: closure?
sClasses AA := {Partial=>true} >> o -> (cacheValue (sClasses,o.Partial)) (if o.Partial then AA -> lift(sClasses(AA,Partial=>false),AA)
Expand Down Expand Up @@ -542,18 +540,23 @@ setupCotangent = cotOpts >> curCotOpts -> dims0 -> (
weights D := (cacheValue weights) (D -> map(FF^1,M, { apply(I,i->product(n,j->product(n,k->if i#j<i#k then (1-FF_(k+1)/FF_(j+1))^(-1) else 1))) }));
cotweights D := (cacheValue cotweights) (D -> map(FF^1,M, { apply(I,i->product(n,j->product(n,k->if i#j<i#k then (1-FF_(k+1)/FF_(j+1))^(-1)*(1-FF_0^2*FF_(j+1)/FF_(k+1))^(-1) else 1))) }));
canonicalClass D := {} >> o -> (cacheValue canonicalClass) (D -> D apply(I,i->product(n,j->product(n,k->if i#j<i#k then FF_(j+1)^-1*FF_(k+1) else 1))));
installMethod(canonicalClass,{}>>o->()->canonicalClass D);
) else (
zeroSection D := {} >> o -> (cacheValue zeroSection) (D -> D apply(I,i->product(n,j->product(n,k->if i#j<i#k then FF_0-FF_(j+1)+FF_(k+1) else 1))));
zeroSectionInv D := {} >> o -> (cacheValue zeroSectionInv) (D -> D apply(I,i->product(n,j->product(n,k->if i#j<i#k then (FF_0-FF_(j+1)+FF_(k+1))^(-1) else 1))));
dualZeroSection D := {} >> o -> (cacheValue dualZeroSection) (D -> D apply(I,i->product(n,j->product(n,k->if i#j<i#k then -FF_0+FF_(j+1)-FF_(k+1) else 1))));
weights D := (cacheValue weights) (D -> map(FF^1,M, { apply(I,i->product(n,j->product(n,k->if i#j<i#k then (FF_(j+1)-FF_(k+1))^(-1) else 1))) }));
cotweights D := (cacheValue cotweights) (D -> map(FF^1,M, { apply(I,i->product(n,j->product(n,k->if i#j<i#k then (FF_(j+1)-FF_(k+1))^(-1)*(FF_0-FF_(j+1)+FF_(k+1))^(-1) else 1))) }));
canonicalClass D := {} >> o -> (cacheValue canonicalClass) (D -> D apply(I,i->sum(n,j->sum(n,k->if i#j<i#k then FF_(k+1)-FF_(j+1) else 0_FF))));
);
installMethod(zeroSection,{}>>o->()->zeroSection D);
installMethod(dualZeroSection,{}>>o->()->dualZeroSection D);
installMethod(canonicalClass,{}>>o->()->canonicalClass D);
-- Chern classes of tautological bundles
tautoClass (ZZ,ZZ,D) := {} >> o -> (j,i,AA) -> D apply(I,s->elem(j,apply((subs s)#i,k->FF_(k+1))));
tautoClass (ZZ,ZZ,D) := {} >> o -> (j,i,AA) -> (
if i<1 or i>d+1 then error ("second index outside the range 1.."|toString(d+1));
if j<0 or j>dimdiffs#(i-1) then error ("first index outside the range 0.."|toString(dimdiffs#(i-1)));
D apply(I,s->elem(j,apply((subs s)#(i-1),k->FF_(k+1))))
);
tautoClass (ZZ,ZZ) := {} >> o -> (j,i) -> tautoClass(j,i,D);
-- pushforward to point
pushforwardToPoint D := pushforwardToPoint Vector := m -> ((weights D)*m)_0;
Expand Down
4 changes: 1 addition & 3 deletions M2/Macaulay2/packages/CotangentSchubert/puzzles.m2
Original file line number Diff line number Diff line change
Expand Up @@ -281,9 +281,7 @@ neside = p -> new LabelList from apply(p.Length,i->p#(0,i,0))
-- computation of (d<=3) equivariant fugacities
myload "fugacity.m2"

-- TODO: `assoc` is exported here but has no doc node and is not on the
-- undocumented {} list at CotangentSchubert.m2:398-405.
export { "puzzle", "bottom", "fugacity", "fugacityTally", "fugacityVector", "Puzzle", "assoc", "doublePuzzle" }
export { "puzzle", "bottom", "fugacity", "fugacityTally", "fugacityVector", "Puzzle", "doublePuzzle" }
end

-- ex of use
Expand Down
7 changes: 4 additions & 3 deletions M2/Macaulay2/packages/CotangentSchubert/puzzles/assoc.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
if (this.anim) return;
e=event.target;
while (e.tagName!='use') { e=e.parentElement; if (e===null) return; }
while (e.tagName!='use') { e=e.parentElement; if (e===null) return; };
xx=e.x.baseVal.value; yy=e.y.baseVal.value;
k=(xx+yy)%2; i=(yy-xx-k)/2; j=(yy+xx+k)/2;
// just shift so always same set up
Expand All @@ -23,14 +23,15 @@ nodes[0].before(nodes[2]);
nodes[1].before(nodes[3]);
window.setTimeout(() => { // need small pause for transition to work correctly after nodes moved
// update colors
c=nodes.map(u=>+u.dataset.col)
c=nodes.map(u=>+u.dataset.col);
mis=[0,1,2,3].filter(x=>c.indexOf(x)<0);
if (c[0]==c[2]) nodes[0].dataset.col=nodes[2].dataset.col = c[0]<c[1] ? mis.shift() : mis.pop();
if (c[1]==c[3]) nodes[1].dataset.col=nodes[3].dataset.col = mis[0];
// animate squares
for (l=0; l<4; l++) {
nodes[l].x.baseVal.value += shifts[l][0];
nodes[l].y.baseVal.value += shifts[l][1];
}
};
this.anim='';
},0);

10 changes: 6 additions & 4 deletions M2/Macaulay2/packages/CotangentSchubert/puzzles/assoc.m2
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ cvS := hashTable { "0" => 0, "1" => 1, "10" => 3 } -- hcol S side
--
DoublePuzzle = new SelfInitializingType of BasicList
html DoublePuzzle := html @@ hypertext
getPuzzleJS := get (puzzleDir|"assoc.js");
getPuzzleJS = replace("\n"," ",replace("//.*$","",getPuzzleJS))

hypertext DoublePuzzle := A -> (
(P1,P2) := toSequence A;
n:=P1#Length;
Expand Down Expand Up @@ -92,9 +95,9 @@ hypertext DoublePuzzle := A -> (
"style"=>"width:"|sz|";height:"|sz|";stroke:black;stroke-width:0.01",
"viewBox"=>toString(-n-1)|" -1 "|toString(2*n+1)|" "|toString(2*n+1),
lst1,lst2,defs,
"onclick"=>get (puzzleDir|"assoc.js")}, -- , "class" => "labels"
INPUT{"type"=>"checkbox","id"=>"labels","onclick"=>Sid|".classList.toggle('labels')"},
LABEL{"for"=>"labels","Labels"}
"onclick"=>getPuzzleJS}, -- , "class" => "labels"
INPUT{"type"=>"checkbox","id"=>Sid|"toggle","onclick"=>Sid|".classList.toggle('labels')"},
LABEL{"for"=>Sid|"toggle","Labels"}
}
)

Expand All @@ -112,4 +115,3 @@ doublePuzzle = puzzleOpts >> o -> (a,b,c,d) -> (
flatten apply(P,p->apply(puzzle(c,d,reverse bottom p,o),q->DoublePuzzle(p,q)))
)

-- if topLevelMode === WebApp then print STYLE get (puzzleDir|"assoc.css")
Loading