Skip to content

Commit

Permalink
Intersection theory: Schubert calculus
Browse files Browse the repository at this point in the history
  • Loading branch information
wdecker committed Jul 20, 2024
1 parent 1fe6e2f commit 6cf94b2
Show file tree
Hide file tree
Showing 6 changed files with 187 additions and 35 deletions.
1 change: 1 addition & 0 deletions experimental/IntersectionTheory/docs/doc.main
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"AbstractBundles.md",
"AbstractVarietyMaps.md",
"BlowUps.md",
"schubert.md",
"BottFormulas.md",
"examples.md"
],
Expand Down
16 changes: 14 additions & 2 deletions experimental/IntersectionTheory/docs/src/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,20 @@ DocTestSetup = Oscar.doctestsetup()

# Illustrating Examples From Enumerative Geometry

#### How Many Lines in $\mathbb P^3$ Meet Four General Lines in $\mathbb P^3$?

#### How Many Conics in $\mathbb P^3$ Meet Eight General Lines
```jldoctest
julia> G = abstract_grassmannian(2,4)
AbstractVariety of dim 4
julia> s1 = schubert_class(G, 1)
-c[1]
julia> integral(s1^4)
2
```
#### How Many Conics in $\mathbb P^3$ Meet Eight General Lines in $\mathbb P^3$?

```jldoctest
julia> G = abstract_grassmannian(3, 4)
Expand Down Expand Up @@ -69,7 +81,7 @@ julia> integral((6*HBl-2*e)^5)
```

#### Number of Twisted Cubics on the General Quintic Hypersurface
#### How Many Twisted Cubics lie on the General Quintic Hypersurface

```jldoctest
julia> G = abstract_grassmannian(3, 5)
Expand Down
58 changes: 58 additions & 0 deletions experimental/IntersectionTheory/docs/src/schubert.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
```@meta
CurrentModule = Oscar
```

# Schubert Calculus

To recall the definition of Schubert cycles on a Grassmannian $\mathrm{G}(k,n)$, we think of $\mathrm{G}(k, n)$ as the
Grassmannian $\mathrm{G}(k, W)$ of $k$-dimensional subspaces of an $n$-dimensional vector space $W$.

A *flag* in $W$ is a strictly increasing sequence of linear subspaces

$\{0\} \subset W_1 \subset \dots \subset W_{n-1} \subset W_n = W, \; \text{ with }\; \dim(W_i) = i.$

Let such a flag $\mathcal{W}$ be given. For any sequence $a = (a_1, \ldots, a_k)$
of integers with $n-k \geq a_1 \geq \ldots \geq a_k \geq 0$, we define
the *Schubert cycle* $\Sigma_a(\mathcal{W})$ by setting

$\Sigma_a(\mathcal{W}):= \{ V \in \mathrm{G}(k, W)\mid \dim(W_{n-k+i-a_i} \cap V) \geq i, i = 1, \ldots, k \} \,.$

Then we have:
- The Schubert cycle $\Sigma_a(\mathcal{W})$ is an irreducible subvariety of $\mathrm{G}(k, W)$ of codimension $|a| = \sum a_i$.
- Its cycle class $[\Sigma_a(\mathcal{W})]$ does not depend on the choice of the flag.

We define the *Schubert class* of $a = (a_1, \ldots, a_k)$ to be the cycle class

$\sigma_a := [\Sigma_a(\mathcal{W})] \,.$

The number of Schubert classes on the Grassmannian $\mathrm{G}(k, n)$ is equal to $\binom{n}{k}$.

Instead of $\sigma_a$, we write $\sigma_{a_1,\ldots,a_s}$ whenever
$a = (a_1, \ldots, a_s, 0, \ldots, 0)$, and $\sigma_{p^i}$ whenever
$a = (p, \ldots, p, 0, \ldots, 0) \in \mathbb Z^i \times \{0\}^{k-i}$.

We discuss how the cycle classes $\sigma_{1^i}$, $i = 1, \ldots, k$, and $\sigma_i$, $i = 1, \ldots, n-k$, are related to the Chern classes of the tautological vector bundles on $\mathrm{G}(k, W)$. Recall:

- The *tautological subbundle* on $\mathrm{G}(k, W)$ is the vector bundle of rank $k$ whose fiber at $V \in \mathrm{G}(k, W)$ is the subspace $V \subset W$.
- The *tautological quotient bundle* on $\mathrm{G}(k, W)$ is the vector bundle of rank $(n-k)$ whose fiber at $V \in \mathrm{G}(k, W)$ is the quotient vector space $W/V$.

We denote these vector bundles by $S$ and $Q$, respectively.

The Chern classes of $S$ and $Q$ are

$c_i(S) = (-1)^i \sigma_{1^i} \; \text{ for } \; i = 1, \ldots, k$

and

$c_i(Q) = \sigma_i \; \text{ for }\; i = 1, \ldots, n-k,$

respectively.

```@docs
schubert_class(G::AbstractVariety, λ::Int...)
```

```@docs
schubert_classes(G::AbstractVariety, m::Int)
```

3 changes: 2 additions & 1 deletion experimental/IntersectionTheory/src/IntersectionTheory.jl
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,9 @@ include("Types.jl")
include("Misc.jl")

include("Bott.jl") # integration using Bott's formula
include("Main.jl") # basic constructions for Schubert calculus
include("Main.jl") # basic constructors and functionality
include("blowup.jl") # blowup
include("schubert.jl") # Schubert calculus
# include("Moduli.jl") # moduli of matrices, twisted cubics
# include("Weyl.jl") # weyl groups

Expand Down
47 changes: 15 additions & 32 deletions experimental/IntersectionTheory/src/Main.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1971,7 +1971,7 @@ end
@doc raw"""
abstract_grassmannian(k::Int, n::Int; base::Ring = QQ, symbol::String = "c")
Return the abstract Grassmannian $\mathrm{Gr}(k, n)$ of `k`-dimensional subspaces of an
Return the abstract Grassmannian $\mathrm{G}(k, n)$ of `k`-dimensional subspaces of an
`n`-dimensional vector space.
# Examples
Expand All @@ -1986,9 +1986,23 @@ Quotient
c[2] -> [2]
by ideal (-c[1]^3 + 2*c[1]*c[2], c[1]^4 - 3*c[1]^2*c[2] + c[2]^2)
julia> S = tautological_bundles(G)[1]
AbstractBundle of rank 2 on AbstractVariety of dim 4
julia> V = [chern_class(S, i) for i = 1:2]
2-element Vector{MPolyQuoRingElem{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}}:
c[1]
c[2]
julia> is_regular_sequence(gens(modulus(CR)))
true
julia> Q = tautological_bundles(G)[2]
AbstractBundle of rank 2 on AbstractVariety of dim 4
julia> tangent_bundle(G) == dual(S)*Q
true
```
"""
function abstract_grassmannian(k::Int, n::Int; base::Ring = QQ, symbol::String = "c")
Expand Down Expand Up @@ -2164,34 +2178,3 @@ function abstract_flag_variety(F::AbstractBundle, dims::Vector{Int}; symbol::Str
if l == 2 set_attribute!(Fl, :grassmannian => :relative) end
return Fl
end

@doc raw"""
schubert_class(G::AbstractVariety, λ::Int...)
schubert_class(G::AbstractVariety, λ::Vector{Int})
schubert_class(G::AbstractVariety, λ::Partition)
Return the Schubert class $\sigma_\lambda$ on a (relative) Grassmannian $G$.
"""
function schubert_class(G::AbstractVariety, λ::Int...) schubert_class(G, collect(λ)) end
function schubert_class(G::AbstractVariety, λ::Partition) schubert_class(G, Vector(λ)) end
function schubert_class(G::AbstractVariety, λ::Vector{Int})
get_attribute(G, :grassmannian) === nothing && error("the abstract_variety is not a Grassmannian")
(length(λ) > rank(G.bundles[1]) || sort(λ, rev=true) != λ) && error("the Schubert input is not well-formed")
giambelli(G.bundles[2], λ)
end

@doc raw"""
schubert_classes(m::Int, G::AbstractVariety)
Return all the Schubert classes in codimension $m$ on a (relative) Grassmannian $G$.
"""
function schubert_classes(G::AbstractVariety, m::Int)
get_attribute(G, :grassmannian) === nothing && error("the abstract_variety is not a Grassmannian")
S, Q = G.bundles
res = elem_type(G.ring)[]
for i in 0:rank(S)
append!(res, [schubert_class(G, l) for l in partitions(m, i, 1, rank(Q))])
end
return res
end

97 changes: 97 additions & 0 deletions experimental/IntersectionTheory/src/schubert.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
@doc raw"""
schubert_class(G::AbstractVariety, λ::Int...)
schubert_class(G::AbstractVariety, λ::Vector{Int})
schubert_class(G::AbstractVariety, λ::Partition)
Return the Schubert class $\sigma_\lambda$ on a (relative) Grassmannian `G`.
# Examples
```jldoctest
julia> G = abstract_grassmannian(2,4)
AbstractVariety of dim 4
julia> s0 = schubert_class(G, 0)
1
julia> s1 = schubert_class(G, 1)
-c[1]
julia> s2 = schubert_class(G, 2)
c[1]^2 - c[2]
julia> s11 = schubert_class(G, [1, 1])
c[2]
julia> s21 = schubert_class(G, [2, 1])
-c[1]*c[2]
julia> s22 = schubert_class(G, [2, 2])
c[2]^2
julia> s1*s1 == s2+s11
true
julia> s1*s2 == s1*s11 == s21
true
julia> s1*s21 == s2*s2 == s22
true
```
```jldoctest
julia> G = abstract_grassmannian(2,5)
AbstractVariety of dim 6
julia> s3 = schubert_class(G, 5-2)
-c[1]^3 + 2*c[1]*c[2]
julia> s3^2 == point_class(G)
true
julia> Q = tautological_bundles(G)[2]
AbstractBundle of rank 3 on AbstractVariety of dim 6
julia> chern_class(Q, 3)
-c[1]^3 + 2*c[1]*c[2]
```
```jldoctest
julia> G = abstract_grassmannian(2,4)
AbstractVariety of dim 4
julia> s1 = schubert_class(G, 1)
-c[1]
julia> s1 == schubert_class(G, [1, 0])
true
julia> integral(s1^4)
2
```
"""
function schubert_class(G::AbstractVariety, λ::Int...) schubert_class(G, collect(λ)) end
function schubert_class(G::AbstractVariety, λ::Partition) schubert_class(G, Vector(λ)) end
function schubert_class(G::AbstractVariety, λ::Vector{Int})
get_attribute(G, :grassmannian) === nothing && error("the abstract_variety is not a Grassmannian")
(length(λ) > rank(G.bundles[1]) || sort(λ, rev=true) != λ) && error("the Schubert input is not well-formed")
giambelli(G.bundles[2], λ)
end

@doc raw"""
schubert_classes(G::AbstractVariety, m::Int)
Return all the Schubert classes in codimension `m` on a (relative) Grassmannian `G`.
"""
function schubert_classes(G::AbstractVariety, m::Int)
get_attribute(G, :grassmannian) === nothing && error("the abstract_variety is not a Grassmannian")
S, Q = G.bundles
res = elem_type(G.ring)[]
for i in 0:rank(S)
append!(res, [schubert_class(G, l) for l in partitions(m, i, 1, rank(Q))])
end
return res
end

0 comments on commit 6cf94b2

Please sign in to comment.