forked from oscar-system/Oscar.jl
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement
change_base_ring
for hypercomplexes (oscar-system#3794)
- Loading branch information
1 parent
aca84ef
commit 85af063
Showing
12 changed files
with
225 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
function change_base_ring(phi::Any, C::AbsHyperComplex) | ||
res = BaseChangeComplex(phi, C) | ||
red_map = BaseChangeMorphism(res) | ||
res.red_map = red_map | ||
return res, red_map | ||
end | ||
|
||
function base_change_map(comp::BaseChangeComplex) | ||
# The field is not set when using the internal constructor of the type. | ||
if !isdefined(comp, :red_map) | ||
comp.red_map = BaseChangeMorphism(comp) | ||
end | ||
return comp.red_map::BaseChangeMorphism | ||
end | ||
|
||
function original_complex(comp::BaseChangeComplex) | ||
return comp.orig | ||
end | ||
|
106 changes: 106 additions & 0 deletions
106
experimental/DoubleAndHyperComplexes/src/base_change_types.jl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
# change of base rings for complexes of morphisms | ||
|
||
### Production of the chains | ||
struct BaseChangeChainFactory{ChainType} <: HyperComplexChainFactory{ChainType} | ||
phi::Any # Whatever serves as a base change map | ||
orig::AbsHyperComplex | ||
red_map_cache::Dict{Tuple, Any} | ||
|
||
function BaseChangeChainFactory(phi::Any, orig::AbsHyperComplex) | ||
# TODO: Can we be more specific about the type? | ||
return new{ModuleFP}(phi, orig, Dict{Tuple, Any}()) | ||
end | ||
end | ||
|
||
function (fac::BaseChangeChainFactory)(self::AbsHyperComplex, i::Tuple) | ||
res, m = change_base_ring(fac.phi, fac.orig[i]) | ||
fac.red_map_cache[i] = m | ||
return res | ||
end | ||
|
||
function can_compute(fac::BaseChangeChainFactory, self::AbsHyperComplex, i::Tuple) | ||
return can_compute_index(fac.orig, i) | ||
end | ||
|
||
### Production of the morphisms | ||
struct BaseChangeMapFactory{MorphismType} <: HyperComplexMapFactory{MorphismType} | ||
phi::Any # Whatever serves as a base change map | ||
orig::AbsHyperComplex | ||
|
||
function BaseChangeMapFactory(phi::Any, orig::AbsHyperComplex) | ||
return new{ModuleFPHom}(phi, orig) | ||
end | ||
end | ||
|
||
function (fac::BaseChangeMapFactory)(self::AbsHyperComplex, p::Int, i::Tuple) | ||
f = map(fac.orig, p, i) | ||
next = _codomain_index(self, p, i) | ||
# Fill the cache | ||
self[i] | ||
self[next] | ||
dom_bc = chain_factory(self).red_map_cache[i] | ||
cod_bc = chain_factory(self).red_map_cache[next] | ||
res = change_base_ring(fac.phi, f; domain_base_change=dom_bc, codomain_base_change=cod_bc) | ||
end | ||
|
||
function can_compute(fac::BaseChangeMapFactory, self::AbsHyperComplex, p::Int, i::Tuple) | ||
return can_compute_map(fac.orig, p, i) | ||
end | ||
|
||
### The concrete struct | ||
@attributes mutable struct BaseChangeComplex{ChainType, MorphismType} <: AbsHyperComplex{ChainType, MorphismType} | ||
orig::AbsHyperComplex | ||
internal_complex::HyperComplex{ChainType, MorphismType} | ||
red_map::AbsHyperComplexMorphism | ||
|
||
function BaseChangeComplex(phi::Any, orig::AbsHyperComplex{CT, MT}) where {CT<:ModuleFP, MT<:ModuleFPHom} | ||
chain_fac = BaseChangeChainFactory(phi, orig) | ||
map_fac = BaseChangeMapFactory(phi, orig) | ||
|
||
d = dim(orig) | ||
internal_complex = HyperComplex(d, chain_fac, map_fac, [direction(orig, i) for i in 1:d]) | ||
return new{ModuleFP, ModuleFPHom}(orig, internal_complex) | ||
end | ||
end | ||
|
||
### Implementing the AbsHyperComplex interface via `underlying_complex` | ||
underlying_complex(c::BaseChangeComplex) = c.internal_complex | ||
|
||
######################################################################## | ||
# Type for the base change morphism | ||
######################################################################## | ||
struct BaseChangeMorphismFactory{MorphismType} <: HyperComplexMorphismFactory{MorphismType} | ||
cod::BaseChangeComplex | ||
|
||
function BaseChangeMorphismFactory(comp::BaseChangeComplex{CT, MT}) where {CT, MT} | ||
# TODO: Can we do more about the type? | ||
return new{ModuleFPHom}(comp) | ||
end | ||
end | ||
|
||
function (fac::BaseChangeMorphismFactory)(self::AbsHyperComplexMorphism, i::Tuple) | ||
# fill the cache | ||
fac.cod[i] | ||
|
||
return chain_factory(fac.cod).red_map_cache[i] | ||
end | ||
|
||
function can_compute(fac::BaseChangeMorphismFactory, self::AbsHyperComplexMorphism, i::Tuple) | ||
return can_compute_index(fac.cod, i) | ||
end | ||
|
||
|
||
@attributes mutable struct BaseChangeMorphism{DomainType, CodomainType, MorphismType} <: AbsHyperComplexMorphism{DomainType, CodomainType, MorphismType, BaseChangeMorphism{DomainType, CodomainType, MorphismType}} | ||
internal_morphism::HyperComplexMorphism{DomainType, CodomainType, MorphismType} | ||
|
||
function BaseChangeMorphism(cod::BaseChangeComplex) | ||
map_factory = BaseChangeMorphismFactory(cod) | ||
dom = cod.orig | ||
|
||
internal_morphism = HyperComplexMorphism(dom, cod, map_factory, cached=true, offset=[0 for i in 1:dim(dom)]) | ||
return new{typeof(cod.orig), typeof(cod), ModuleFPHom}(internal_morphism) | ||
end | ||
end | ||
|
||
underlying_morphism(phi::BaseChangeMorphism) = phi.internal_morphism | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
@testset "base change" begin | ||
R, (x, y) = QQ[:x, :y] | ||
R2 = FreeMod(R, 2) | ||
C = koszul_complex(Oscar.KoszulComplex, x*R2[1] + y*R2[2]) | ||
|
||
U = complement_of_point_ideal(R, [0, 0]) | ||
|
||
L, loc = localization(R, U) | ||
|
||
CC, red = change_base_ring(loc, C) | ||
@test !is_zero(CC[0]) | ||
@test !is_zero(CC[1]) | ||
@test !is_zero(CC[2]) | ||
a = compose(map(C, 1), red[0]) | ||
b = compose(red[1], map(CC, 1)) | ||
@test all(a(g) == b(g) for g in gens(C[1])) | ||
a = compose(map(C, 2), red[1]) | ||
b = compose(red[2], map(CC, 2)) | ||
@test all(a(g) == b(g) for g in gens(C[2])) | ||
|
||
F1 = FreeMod(ZZ, 2) | ||
v = 15*F1[1] + 21*F1[2] | ||
C = koszul_complex(Oscar.KoszulComplex, v) | ||
|
||
CC, red = change_base_ring(QQ, C) | ||
@test !is_zero(CC[0]) | ||
@test !is_zero(CC[1]) | ||
@test !is_zero(CC[2]) | ||
a = compose(map(C, 1), red[0]) | ||
b = compose(red[1], map(CC, 1)) | ||
@test all(a(g) == b(g) for g in gens(C[1])) | ||
a = compose(map(C, 2), red[1]) | ||
b = compose(red[2], map(CC, 2)) | ||
@test all(a(g) == b(g) for g in gens(C[2])) | ||
end | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters