Skip to content

Commit

Permalink
Merge branch 'oscar-system:master' into ep/cox_ring_strict_transform
Browse files Browse the repository at this point in the history
  • Loading branch information
paemurru authored Nov 27, 2024
2 parents b724fb5 + 43d0c68 commit 9cbd0bd
Show file tree
Hide file tree
Showing 78 changed files with 4,056 additions and 695 deletions.
5 changes: 5 additions & 0 deletions docs/doc.main
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,11 @@
"Hecke/manual/orders/ideals.md",
"Hecke/manual/orders/frac_ideals.md",
],
"Elliptic Curves" => [
"Hecke/manual/elliptic_curves/intro.md",
"Hecke/manual/elliptic_curves/basics.md",
"Hecke/manual/elliptic_curves/finite_fields.md"
],
"NumberTheory/abelian_closure.md",
"NumberTheory/galois.md",
],
Expand Down
14 changes: 14 additions & 0 deletions docs/oscar_references.bib
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,20 @@ @Article{CMT04
doi = {10.1090/S0025-5718-03-01582-5}
}

@Article{CS12,
author = {Collinucci, Andres and Savelli, Raffaele},
title = {{On Flux Quantization in F-Theory}},
journal = {JHEP},
volume = {02},
pages = {015},
year = {2012},
doi = {10.1007/JHEP02(2012)015},
eprint = {1011.6388},
archiveprefix = {arXiv},
primaryclass = {hep-th},
reportnumber = {MAD-TH-10-09, LMU-ASC-100-10}
}

@Book{CS99,
author = {Conway, J. H. and Sloane, N. J. A.},
title = {Sphere packings, lattices and groups},
Expand Down
18 changes: 1 addition & 17 deletions experimental/BasisLieHighestWeight/src/MainAlgorithm.jl
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ function compute_monomials(
# if highest_weight is not a fundamental weight, partition into smaller summands is possible. This is the basecase of
# the recursion.
dim = dim_of_simple_module(L, highest_weight)
if is_zero(highest_weight) || is_fundamental(highest_weight)
if is_zero(highest_weight) || is_fundamental_weight(highest_weight)
push!(no_minkowski, highest_weight)
monomials = add_by_hand(
L, birational_seq, ZZx, highest_weight, monomial_ordering, Set{ZZMPolyRingElem}()
Expand Down Expand Up @@ -473,22 +473,6 @@ function operators_lusztig(L::LieAlgebra, reduced_expression::Vector{Int})
return operators
end

# TODO: upstream to LieAlgebras/RootSystem.jl
function is_fundamental(highest_weight::WeightLatticeElem)
hasone = false
for i in coefficients(highest_weight)
if iszero(i)
continue
elseif isone(i)
hasone && return false
hasone = true
else
return false
end
end
return hasone
end

function sub_weights(w::WeightLatticeElem)
# returns list of weights v != 0, highest_weight with 0 <= v <= w elementwise
@req is_dominant(w) "The input must be a dominant weight"
Expand Down
6 changes: 0 additions & 6 deletions experimental/BasisLieHighestWeight/test/MainAlgorithm-test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,6 @@ function check_dimension(
@test gap_dim == dim(basis) == length(monomials(basis)) # check if dimension is correct
end

@testset "is_fundamental" begin
R = root_system(:B, 3)
@test BasisLieHighestWeight.is_fundamental(WeightLatticeElem(R, [ZZ(0), ZZ(1), ZZ(0)]))
@test !BasisLieHighestWeight.is_fundamental(WeightLatticeElem(R, [ZZ(0), ZZ(1), ZZ(1)]))
end

@testset "sub_weights(_proper)" begin
sub_weights = BasisLieHighestWeight.sub_weights
sub_weights_proper = BasisLieHighestWeight.sub_weights_proper
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ include("Objects/new_complex_template.jl")
include("Objects/linear_strands.jl")

include("Morphisms/Types.jl")
include("Objects/cartan_eilenberg_resolution.jl")
include("Morphisms/cartan_eilenberg_resolutions.jl")
include("Morphisms/ext.jl")
include("Morphisms/simplified_complexes.jl")
Expand All @@ -25,3 +26,4 @@ include("Exports.jl")

include("base_change_types.jl")
include("base_change.jl")

20 changes: 20 additions & 0 deletions experimental/DoubleAndHyperComplexes/src/Morphisms/Types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -142,3 +142,23 @@ end
underlying_complex(c::SimpleFreeResolution) = c.underlying_complex
original_module(c::SimpleFreeResolution) = c.M

### Lifting morphisms through projective resolutions
mutable struct MapLifter{MorphismType} <: HyperComplexMorphismFactory{MorphismType}
dom::AbsHyperComplex
cod::AbsHyperComplex
orig_map::Map
start_index::Int
offset::Int
check::Bool

function MapLifter(::Type{MorphismType}, dom::AbsHyperComplex, cod::AbsHyperComplex, phi::Map;
start_index::Int=0, offset::Int=0, check::Bool=true
) where {MorphismType}
@assert dim(dom) == 1 && dim(cod) == 1 "lifting of maps is only implemented in dimension one"
@assert (is_chain_complex(dom) && is_chain_complex(cod)) || (is_cochain_complex(dom) && is_cochain_complex(cod))
@assert domain(phi) === dom[start_index]
@assert codomain(phi) === cod[start_index + offset]
return new{MorphismType}(dom, cod, phi, start_index, offset)
end
end

Original file line number Diff line number Diff line change
@@ -1,22 +1,4 @@
mutable struct MapLifter{MorphismType} <: HyperComplexMorphismFactory{MorphismType}
dom::AbsHyperComplex
cod::AbsHyperComplex
orig_map::Map
start_index::Int
offset::Int
check::Bool

function MapLifter(::Type{MorphismType}, dom::AbsHyperComplex, cod::AbsHyperComplex, phi::Map;
start_index::Int=0, offset::Int=0, check::Bool=true
) where {MorphismType}
@assert dim(dom) == 1 && dim(cod) == 1 "lifting of maps is only implemented in dimension one"
@assert (is_chain_complex(dom) && is_chain_complex(cod)) || (is_cochain_complex(dom) && is_cochain_complex(cod))
@assert domain(phi) === dom[start_index]
@assert codomain(phi) === cod[start_index + offset]
return new{MorphismType}(dom, cod, phi, start_index, offset)
end
end

### Lifting maps through projective resolutions
is_chain_complex(c::AbsHyperComplex) = (dim(c) == 1 ? direction(c, 1) == (:chain) : error("complex is not one-dimensional"))
is_cochain_complex(c::AbsHyperComplex) = (dim(c) == 1 ? direction(c, 1) == (:cochain) : error("complex is not one-dimensional"))

Expand Down Expand Up @@ -57,3 +39,6 @@ function lift_map(dom::AbsHyperComplex{DomChainType}, cod::AbsHyperComplex{CodCh
end

morphism_type(::Type{T1}, ::Type{T2}) where {T1<:ModuleFP, T2<:ModuleFP} = ModuleFPHom{<:T1, <:T2}

### Cartan Eilenberg resolutions

2 changes: 1 addition & 1 deletion experimental/DoubleAndHyperComplexes/src/Objects/Types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ end
upper_bounds::Vector=[nothing for i in 1:d],
lower_bounds::Vector=[nothing for i in 1:d]
) where {ChainType, MorphismType}
@assert d > 0 "can not create zero or negative dimensional hypercomplex"
@assert d >= 0 "can not create negative dimensional hypercomplex"
chains = Dict{Tuple, ChainType}()
morphisms = Dict{Tuple, Dict{Int, <:MorphismType}}()
return new{ChainType, MorphismType}(d, chains, morphisms,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
#= Cartan Eilenberg resolutions of 1-dimensional complexes
#
# Suppose
#
# 0 ← C₀ ← C₁ ← C₂ ← …
#
# is a bounded below complex. We compute a double complex
#
# 0 0 0
# ↑ ↑ ↑
# 0 ← P₀₀ ← P₀₁ ← P₀₂ ← …
# ↑ ↑ ↑
# 0 ← P₁₀ ← P₁₁ ← P₁₂ ← …
# ↑ ↑ ↑
# 0 ← P₂₀ ← P₂₁ ← P₂₂ ← …
# ↑ ↑ ↑
# ⋮ ⋮ ⋮
#
# whose total complex is quasi-isomorphic to C via some augmentation map
#
# ε = (εᵢ : P₀ᵢ → Cᵢ)ᵢ
#
# The challenge is that if we were only computing resolutions of the Cᵢ's
# and lifting the maps, then the rows of the resulting diagrams would
# not necessarily form complexes. To accomplish that, we split the original
# complex into short exact sequences
#
# 0 ← Bᵢ ← Cᵢ ← Zᵢ ← 0
#
# and apply the Horse shoe lemma to these. Together with the induced maps
# from Bᵢ ↪ Zᵢ₋₁ we get the desired double complex.
#
# If the original complex C is known to be exact, then there is no need
# to compute the resolutions of both Bᵢ and Zᵢ and we can shorten the procedure.
=#
### Production of the chains
struct CEChainFactory{ChainType} <: HyperComplexChainFactory{ChainType}
c::AbsHyperComplex
is_exact::Bool
kernel_resolutions::Dict{Int, <:AbsHyperComplex} # the kernels of Cᵢ → Cᵢ₋₁
boundary_resolutions::Dict{Int, <:AbsHyperComplex} # the boundaries of Cᵢ₊₁ → Cᵢ
induced_maps::Dict{Int, <:AbsHyperComplexMorphism} # the induced maps from the free
# resolutions of the boundary and kernel

function CEChainFactory(c::AbsHyperComplex; is_exact::Bool=false)
@assert dim(c) == 1 "complex must be 1-dimensional"
#@assert has_lower_bound(c, 1) "complex must be bounded from below"
return new{chain_type(c)}(c, is_exact, Dict{Int, AbsHyperComplex}(), Dict{Int, AbsHyperComplex}(), Dict{Int, AbsHyperComplexMorphism}())
end
end

function kernel_resolution(fac::CEChainFactory, i::Int)
if !haskey(fac.kernel_resolutions, i)
Z, _ = kernel(fac.c, i)
fac.kernel_resolutions[i] = free_resolution(SimpleFreeResolution, Z)[1]
end
return fac.kernel_resolutions[i]
end

function boundary_resolution(fac::CEChainFactory, i::Int)
if !haskey(fac.boundary_resolutions, i)
Z, _ = boundary(fac.c, i)
fac.boundary_resolutions[i] = free_resolution(SimpleFreeResolution, Z)[1]
end
return fac.boundary_resolutions[i]
end

function induced_map(fac::CEChainFactory, i::Int)
if !haskey(fac.induced_maps, i)
Z, inc = kernel(fac.c, i)
B, pr = boundary(fac.c, i)
@assert ambient_free_module(Z) === ambient_free_module(B)
img_gens = elem_type(Z)[Z(g) for g in ambient_representatives_generators(B)]
res_Z = kernel_resolution(fac, i)
res_B = boundary_resolution(fac, i)
aug_Z = augmentation_map(res_Z)
aug_B = augmentation_map(res_B)
img_gens = gens(res_B[0])
img_gens = aug_B[0].(img_gens)
img_gens = elem_type(res_Z[0])[preimage(aug_Z[0], Z(repres(aug_B[0](g)))) for g in gens(res_B[0])]
psi = hom(res_B[0], res_Z[0], img_gens; check=true) # TODO: Set to false
@assert domain(psi) === boundary_resolution(fac, i)[0]
@assert codomain(psi) === kernel_resolution(fac, i)[0]
fac.induced_maps[i] = lift_map(boundary_resolution(fac, i), kernel_resolution(fac, i), psi; start_index=0)
end
return fac.induced_maps[i]
end

function (fac::CEChainFactory)(self::AbsHyperComplex, I::Tuple)
(i, j) = I # i the resolution index, j the index in C

res_Z = kernel_resolution(fac, j)

if can_compute_map(fac.c, 1, (j,))
if fac.is_exact # Use the next kernel directly
res_B = kernel_resolution(fac, j-1)
return direct_sum(res_B[i], res_Z[i])[1]
else
res_B = boundary_resolution(fac, j-1)
return direct_sum(res_B[i], res_Z[i])[1]
end
end
# We may assume that the next map can not be computed and is, hence, zero.
return res_Z[i]
end

function can_compute(fac::CEChainFactory, self::AbsHyperComplex, I::Tuple)
(i, j) = I
can_compute_index(fac.c, (j,)) || return false
return i >= 0
end

### Production of the morphisms
struct CEMapFactory{MorphismType} <: HyperComplexMapFactory{MorphismType} end

function (fac::CEMapFactory)(self::AbsHyperComplex, p::Int, I::Tuple)
(i, j) = I
cfac = chain_factory(self)
if p == 1 # vertical upwards maps
if can_compute_map(cfac.c, 1, (j,))
# both dom and cod are direct sums in this case
dom = self[I]
cod = self[(i-1, j)]
pr1 = canonical_projection(dom, 1)
pr2 = canonical_projection(dom, 2)
@assert domain(pr1) === domain(pr2) === dom
inc1 = canonical_injection(cod, 1)
inc2 = canonical_injection(cod, 2)
@assert codomain(inc1) === codomain(inc2) === cod
res_Z = kernel_resolution(cfac, j)
@assert domain(map(res_Z, i)) === codomain(pr2)
@assert codomain(map(res_Z, i)) === domain(inc2)
res_B = boundary_resolution(cfac, j-1)
@assert domain(map(res_B, i)) === codomain(pr1)
@assert codomain(map(res_B, i)) === domain(inc1)
return compose(pr1, compose(map(res_B, i), inc1)) + compose(pr2, compose(map(res_Z, i), inc2))
else
res_Z = kernel_resolution(cfac, j)
return map(res_Z, i)
end
error("execution should never reach this point")
elseif p == 2 # the horizontal maps
dom = self[I]
cod = self[(i, j-1)]
if can_compute_map(cfac.c, 1, (j-1,))
# the codomain is also a direct sum
if !cfac.is_exact
psi = induced_map(cfac, j-1)
phi = psi[i]
inc = canonical_injection(cod, 2)
pr = canonical_projection(dom, 1)
@assert codomain(phi) === domain(inc)
@assert codomain(pr) === domain(phi)
return compose(pr, compose(phi, inc))
else
inc = canonical_injection(cod, 2)
pr = canonical_projection(dom, 1)
return compose(pr, inc)
end
error("execution should never reach this point")
else
# the codomain is just the kernel
if !cfac.is_exact
psi = induced_map(cfac, j-1)
phi = psi[i]
pr = canonical_projection(dom, 1)
return compose(pr, phi)
else
pr = canonical_projection(dom, 1)
return pr
end
error("execution should never reach this point")
end
error("execution should never reach this point")
end
error("direction $p out of bounds")
end

function can_compute(fac::CEMapFactory, self::AbsHyperComplex, p::Int, I::Tuple)
(i, j) = I
if p == 1 # vertical maps
return i > 0 && can_compute(chain_factory(self).c, j)
elseif p == 2 # horizontal maps
return i >= 0 && can_compute_map(chain_factory(self).c, j)
end
return false
end

### The concrete struct
@attributes mutable struct CartanEilenbergResolution{ChainType, MorphismType} <: AbsHyperComplex{ChainType, MorphismType}
internal_complex::HyperComplex{ChainType, MorphismType}

function CartanEilenbergResolution(
c::AbsHyperComplex{ChainType, MorphismType};
is_exact::Bool=false
) where {ChainType, MorphismType}
@assert dim(c) == 1 "complexes must be 1-dimensional"
@assert has_lower_bound(c, 1) "complexes must be bounded from below"
@assert direction(c, 1) == :chain "resolutions are only implemented for chain complexes"
chain_fac = CEChainFactory(c; is_exact)
map_fac = CEMapFactory{MorphismType}() # TODO: Do proper type inference here!

# Assuming d is the dimension of the new complex
internal_complex = HyperComplex(2, chain_fac, map_fac, [:chain, :chain]; lower_bounds = Union{Int, Nothing}[0, lower_bound(c, 1)])
# Assuming that ChainType and MorphismType are provided by the input
return new{ChainType, MorphismType}(internal_complex)
end
end

### Implementing the AbsHyperComplex interface via `underlying_complex`
underlying_complex(c::CartanEilenbergResolution) = c.internal_complex

Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,13 @@ end
map_fac = BaseChangeMapFactory(phi, orig)

d = dim(orig)
internal_complex = HyperComplex(d, chain_fac, map_fac, [direction(orig, i) for i in 1:d])
upper_bounds = Vector{Union{Int, Nothing}}([(has_upper_bound(orig, i) ? upper_bound(orig, i) : nothing) for i in 1:d])
lower_bounds = Vector{Union{Int, Nothing}}([(has_lower_bound(orig, i) ? lower_bound(orig, i) : nothing) for i in 1:d])
internal_complex = HyperComplex(d, chain_fac, map_fac,
[direction(orig, i) for i in 1:d],
lower_bounds = lower_bounds,
upper_bounds = upper_bounds
)
return new{ModuleFP, ModuleFPHom}(orig, internal_complex)
end
end
Expand Down
Loading

0 comments on commit 9cbd0bd

Please sign in to comment.