Skip to content

move code from Oscar.jl/experimental/GModule/Misc.jl here #1456

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
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
8 changes: 7 additions & 1 deletion src/GrpAb/Elem.jl
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ The sequence of generators of $G$.
gens(G::FinGenAbGroup) = FinGenAbGroupElem[G[i] for i = 1:ngens(G)]

@doc raw"""
gen(G::FinGenAbGroup, i::Int) -> Vector{FinGenAbGroupElem}
gen(G::FinGenAbGroup, i::Int) -> FinGenAbGroupElem

The $i$-th generator of $G$.
"""
Expand Down Expand Up @@ -293,6 +293,12 @@ function (A::FinGenAbGroup)(x::ZZMatrix)
return z
end

function (A::FinGenAbGroup)(x::FinGenAbGroupElem)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ThomasBreuer @fieker so this is the function we talked about this morning, which is the reason (or at least a reason) why the GModule tests are run in Oscar even when "exclude experimental" is active...

But this PR here is waiting for @ThomasBreuer to finish it up -- then we can make a Hecke release, adjust Oscar, and perhaps get rid of that hack in Oscar....

fl, m = is_subgroup(parent(x), A)
@assert fl
return m(x)
end

function (A::FinGenAbGroup)()
y = zero_matrix(FlintZZ, 1, ngens(A))
z = FinGenAbGroupElem(A, y)
Expand Down
59 changes: 59 additions & 0 deletions src/GrpAb/GrpAbFinGen.jl
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,36 @@ function abelian_group(M::AbstractMatrix{<:IntegerUnion}; name::String = "")
return abelian_group(FinGenAbGroup, M, name=name)
end

function abelian_group(M::Generic.FreeModule{ZZRingElem})
A = free_abelian_group(rank(M))
return A, MapFromFunc(A, M, x->M(x.coeff), y->A(y.v))
end

#TODO: for modern fin. fields as well
function abelian_group(M::AbstractAlgebra.FPModule{fqPolyRepFieldElem})
k = base_ring(M)
A = abelian_group([characteristic(k) for i = 1:dim(M)*degree(k)])
n = degree(k)
function to_A(m::AbstractAlgebra.FPModuleElem{fqPolyRepFieldElem})
a = ZZRingElem[]
for i=1:dim(M)
c = m[i]
for j=0:n-1
push!(a, coeff(c, j))
end
end
return A(a)
end
function to_M(a::FinGenAbGroupElem)
m = fqPolyRepFieldElem[]
for i=1:dim(M)
push!(m, k([a[j] for j=(i-1)*n+1:i*n]))
end
return M(m)
end
return A, MapFromFunc(A, M, to_M, to_A)
end

function abelian_group(::Type{FinGenAbGroup}, M::AbstractMatrix{<:IntegerUnion}; name::String = "")
return abelian_group(matrix(FlintZZ, M), name=name)
end
Expand Down Expand Up @@ -662,6 +692,27 @@ function direct_sum(G::FinGenAbGroup...; task::Symbol = :sum, kwargs...)
return _direct_product(:sum, G...; task = task, kwargs...)
end

@doc raw"""
direct_sum(G::FinGenAbGroup, H::FinGenAbGroup, V::Vector{<:Map{FinGenAbGroup, FinGenAbGroup}})

For groups `G = prod G_i` and `H = prod H_i` as well as maps `V_i: G_i -> H_i`,
build the induced map from `G -> H`.
"""
function direct_sum(G::FinGenAbGroup, H::FinGenAbGroup, V::Vector{<:Map{FinGenAbGroup, FinGenAbGroup}})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is already added in #1488 under the name hom_direct_sum. Once #1488 gets merged, this should get removed here.

dG = get_attribute(G, :direct_product)
dH = get_attribute(H, :direct_product)

if dG === nothing || dH === nothing
error("both groups need to be direct products")
end
@assert length(V) == length(dG) == length(dH)

@assert all(i -> domain(V[i]) == dG[i] && codomain(V[i]) == dH[i], 1:length(V))
h = hom(G, H, cat([matrix(V[i]) for i=1:length(V)]..., dims=(1,2)), check = !true)
return h
end


@doc raw"""
direct_product(G::FinGenAbGroup...) -> FinGenAbGroup, Vector{FinGenAbGroupHom}

Expand Down Expand Up @@ -839,6 +890,13 @@ function matrix(M::Generic.IdentityMap{FinGenAbGroup})
return identity_matrix(FlintZZ, ngens(domain(M)))
end

function dual(h::Map{FinGenAbGroup, FinGenAbGroup})
A = domain(h)
B = codomain(h)
@assert is_free(A) && is_free(B)
return hom(B, A, transpose(h.map))
end

@doc raw"""
hom(G::FinGenAbGroup, H::FinGenAbGroup, A::Matrix{ <: Map{FinGenAbGroup, FinGenAbGroup}}) -> Map

Expand Down Expand Up @@ -1506,6 +1564,7 @@ end

#checks if the image of mG contains the image of mH

is_sub_with_data(M::FinGenAbGroup, N::FinGenAbGroup) = is_subgroup(M, N)

#cannot define == as this produces problems elsewhere... need some thought
function is_eq(G::FinGenAbGroup, H::FinGenAbGroup, L::GrpAbLattice = GroupLattice)
Expand Down
3 changes: 3 additions & 0 deletions src/GrpAb/Map.jl
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,9 @@ function cokernel(h::FinGenAbGroupHom, add_to_lattice::Bool = true)
return quo(codomain(h), FinGenAbGroupElem[mS(g) for g in gens(S)], add_to_lattice)
end

cokernel(h::Map) = quo(codomain(h), image(h)[1])


################################################################################
#
# Surjectivity
Expand Down
2 changes: 2 additions & 0 deletions src/LocalField/map.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ mutable struct LocalFieldMor{S, T, U, V, W} <: Map{S, T, HeckeMap, LocalFieldMor
end
end

parent(f::LocalFieldMor) = NfMorSet(domain(f))

################################################################################
#
# Identity
Expand Down
4 changes: 4 additions & 0 deletions src/Map/Map.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ function pseudo_inv(a::Map)
return InverseMap(a)
end

function pseudo_inv(h::Generic.ModuleHomomorphism)
return MapFromFunc(codomain(h), domain(h), x -> preimage(h, x))
end

#function show(io::IO, M::CoerceMap)
# println(io, "Coerce: $(domain(M)) -> $(codomain(M))")
#end
Expand Down
2 changes: 2 additions & 0 deletions src/Map/NumberField.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ function elem_type(::Type{NfMorSet{T}}) where {T}
return morphism_type(T, T)
end

elem_type(::Type{NfMorSet{T}}) where {T <: LocalField} = LocalFieldMor{T, T}

function show(io::IO, S::NfMorSet{T}) where {T}
print(io, "Set of automorphisms of ", S.field)
end
Expand Down
34 changes: 34 additions & 0 deletions src/Misc/Fields.jl
Original file line number Diff line number Diff line change
Expand Up @@ -177,3 +177,37 @@ function preimage(f::FldToVecMor{FqField}, v::Vector)
return dot(f.B, (f.L).(map(f.f, v)))::elem_type(f.L)
end

#XXX: have a type for an implicit field - in Hecke?
# add all(?) the other functions to it
function relative_field(m::Map{<:AbstractAlgebra.Field, <:AbstractAlgebra.Field})
k = domain(m)
K = codomain(m)
@assert base_field(k) == base_field(K)
kt, t = polynomial_ring(k, cached = false)
f = defining_polynomial(K)
Qt = parent(f)
#the Trager construction, works for extensions of the same field given
#via primitive elements
h = gcd(gen(k) - map_coefficients(k, Qt(m(gen(k))), parent = kt), map_coefficients(k, f, parent = kt))
coordinates = function(x::FieldElem)
@assert parent(x) == K
c = collect(Hecke.coefficients(map_coefficients(k, Qt(x), parent = kt) % h))
c = vcat(c, zeros(k, degree(h)-length(c)))
return c
end
rep_mat = function(x::FieldElem)
@assert parent(x) == K
c = map_coefficients(k, Qt(x), parent = kt) % h
m = collect(Hecke.coefficients(c))
m = vcat(m, zeros(k, degree(h) - length(m)))
r = m
for i in 2:degree(h)
c = shift_left(c, 1) % h
m = collect(Hecke.coefficients(c))
m = vcat(m, zeros(k, degree(h) - length(m)))
r = hcat(r, m)
end
return transpose(matrix(r))
end
return h, coordinates, rep_mat
end
23 changes: 23 additions & 0 deletions src/Misc/RatRecon.jl
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,18 @@ function rational_reconstruction(a::ZZRingElem, b::ZZRingElem, N::ZZRingElem, D:
return fl!=0, numerator(res), denominator(res)
end

function induce_rational_reconstruction(a::ZZMatrix, pg::ZZRingElem; ErrorTolerant::Bool = false)
c = zero_matrix(QQ, nrows(a), ncols(a))
for i=1:nrows(a)
for j=1:ncols(a)
fl, n, d = rational_reconstruction(a[i,j], pg, ErrorTolerant = ErrorTolerant)
fl || return fl, c
c[i,j] = n//d
end
end
return true, c
end

#Note: the vector version might be useful - or the mult by previous den version
#Note: missing reconstruction modulo a true ideal. W/o denominators

Expand Down Expand Up @@ -137,6 +149,17 @@ function rational_reconstruction(a::AbsSimpleNumFieldElem, b::ZZRingElem; ErrorT
return true, K(res)
end

function induce_rational_reconstruction(a::Generic.MatSpaceElem{AbsSimpleNumFieldElem}, pg::ZZRingElem; ErrorTolerant::Bool = false)
c = parent(a)()
for i=1:nrows(a)
for j=1:ncols(a)
fl, c[i,j] = rational_reconstruction(a[i,j], pg)#, ErrorTolerant = ErrorTolerant)
fl || return fl, c
end
end
return true, c
end

# to appease the Singular crowd...
farey_lift = rational_reconstruction

Expand Down
2 changes: 2 additions & 0 deletions src/NumField/ComplexEmbeddings/Generic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,8 @@ Complex embedding corresponding to 0.62
"""
restrict(f::NumFieldEmb, K::NumFieldHom)

restrict(::Hecke.NumFieldEmb, ::Map{QQField, AbsSimpleNumField}) = complex_embeddings(QQ)[1]

################################################################################
#
# Extension
Expand Down
2 changes: 2 additions & 0 deletions src/NumField/ComplexEmbeddings/QQ.jl
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ complex_embeddings(::QQField) = [QQEmb()]

is_real(::QQEmb) = true

extend(::QQEmb, mp::MapFromFunc{QQField, AbsSimpleNumField}) = complex_embeddings(codomain(mp))

restrict(::NumFieldEmb, ::QQField) = QQEmb()

restrict(e::NumFieldEmb, f::NumFieldHom{QQField}) = QQEmb()
Expand Down
15 changes: 15 additions & 0 deletions src/NumField/NfAbs/Elem.jl
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,21 @@ function induce_inner_crt(a::AbsSimpleNumFieldElem, b::AbsSimpleNumFieldElem, pi
return c
end

function induce_crt(a::Generic.MatSpaceElem{AbsSimpleNumFieldElem}, b::Generic.MatSpaceElem{AbsSimpleNumFieldElem}, p::ZZRingElem, q::ZZRingElem)
c = parent(a)()
pi = invmod(p, q)
mul!(pi, pi, p)
pq = p*q
z = ZZRingElem(0)

for i=1:nrows(a)
for j=1:ncols(a)
c[i,j] = induce_inner_crt(a[i,j], b[i,j], pi, pq, z)
end
end
return c
end

################################################################################
#
# Norm
Expand Down
1 change: 1 addition & 0 deletions src/NumFieldOrd/NfOrd/Ideal/Relative.jl
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ function minimum(m::T, I::AbsSimpleNumFieldOrderFractionalIdeal) where T <: Map{
return minimum(m, numerator(I))//denominator(I)
end

Base.minimum(::Map{QQField, AbsSimpleNumField}, I::Union{Hecke.AbsNumFieldOrderIdeal, Hecke.AbsNumFieldOrderFractionalIdeal}) = minimum(I)*ZZ

################################################################################
#
Expand Down
34 changes: 34 additions & 0 deletions src/QuadForm/Spaces.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,26 @@ function hom(V::AbstractSpace, W::AbstractSpace, B::MatElem; check::Bool = false
return AbstractSpaceMor(V, W, B)
end

function hom(F::AbstractAlgebra.FPModule{T}, G::AbstractAlgebra.FPModule{T}) where T
k = base_ring(F)
@assert base_ring(G) == k
H = free_module(k, dim(F)*dim(G))
return H, MapFromFunc(H, Hecke.MapParent(F, G, "homomorphisms"), x->hom(F, G, matrix(k, dim(F), dim(G), vec(collect(x.v)))), y->H(vec(collect(transpose(matrix(y))))))
end

function id_hom(A::AbstractAlgebra.FPModule)
return Generic.ModuleHomomorphism(A, A, identity_matrix(base_ring(A), ngens(A)))
end

function dual(h::Map{<:AbstractAlgebra.FPModule{ZZRingElem}, <:AbstractAlgebra.FPModule{ZZRingElem}})
A = domain(h)
B = codomain(h)
@assert is_free(A) && is_free(B)
return hom(B, A, transpose(matrix(h)))
end

parent(H::AbstractAlgebra.Generic.ModuleHomomorphism{<:FieldElem}) = Hecke.MapParent(domain(H), codomain(H), "homomorphisms")

matrix(f::AbstractSpaceMor) = f.matrix

function image(f::AbstractSpaceMor, v::Vector)
Expand Down Expand Up @@ -755,6 +775,20 @@ end

direct_product(x::Vararg{AbstractSpace}) = direct_product(collect(x))

function direct_product(M::AbstractAlgebra.Module...; task::Symbol = :none)
D, inj, pro = direct_sum(M...)
if task == :none
return D
elseif task == :both
return D, pro, inj
elseif task == :sum
return D, inj
elseif task == :prod
return D, pro
end
error("illegal task")
end

@doc raw"""
biproduct(x::Vararg{T}) where T <: AbstractSpace -> T, Vector{AbstractSpaceMor}, Vector{AbstractSpaceMor}
biproduct(x::Vector{T}) where T <: AbstractSpace -> T, Vector{AbstractSpaceMor}, Vector{AbstractSpaceMor}
Expand Down
1 change: 1 addition & 0 deletions src/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -783,6 +783,7 @@ export reduction_type
export refine_alpha_bound
export regulator
export relations
export relative_field
export relative_residue_field
export relative_simple_extension
export rels
Expand Down