Skip to content

Commit

Permalink
feat: arbitrary base rings for AlgAssAbsOrd (#1728)
Browse files Browse the repository at this point in the history
* rename ___hnf!

* rename ____hnf -> __hnf_integral

* s/___hnf(/_hnf_integral(/g

* s/___hnf_modular_eldiv!(/_hnf_integral_modular_eldiv!(/g

* fix some nightly breakage

* add _hnf_integral versions for QQMatrix

* FakeFmpqMat -> QQMatrix for AlgAssAbsOrd[Idl]

* Add arbitrary base rings for AlgAssAbsOrd[Idl]
  • Loading branch information
thofma authored Feb 2, 2025
1 parent 41aea2f commit 429d727
Show file tree
Hide file tree
Showing 32 changed files with 805 additions and 380 deletions.
6 changes: 4 additions & 2 deletions src/AlgAss/AlgGrp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ Generic.dim(A::GroupAlgebra) = order(Int, group(A))

elem_type(::Type{GroupAlgebra{T, S, R}}) where {T, S, R} = GroupAlgebraElem{T, GroupAlgebra{T, S, R}}

order_type(::Type{GroupAlgebra{QQFieldElem, S, R}}) where { S, R } = AlgAssAbsOrd{GroupAlgebra{QQFieldElem, S, R}, elem_type(GroupAlgebra{QQFieldElem, S, R})}
#order_type(::Type{GroupAlgebra{QQFieldElem, S, R}}) where { S, R } = AlgAssAbsOrd{ZZRing, GroupAlgebra{QQFieldElem, S, R}}

# order_type(::Type{S}, ::Type{T}) where {S <: GroupAlgebra, T} = AlgAssAbsOrd{T, S}

order_type(::Type{GroupAlgebra{T, S, R}}) where { T <: NumFieldElem, S, R } = AlgAssRelOrd{T, fractional_ideal_type(order_type(parent_type(T))), GroupAlgebra{T, S, R}}

Expand All @@ -29,7 +31,7 @@ group(A::GroupAlgebra) = A.group

has_one(A::GroupAlgebra) = true

function (A::GroupAlgebra{T, S, R})(c::Union{Vector{T}, SRow{T}}; copy::Bool = false) where {T, S, R}
function (A::GroupAlgebra{T, S, R})(c::Union{Vector, SRow}; copy::Bool = false) where {T, S, R}
c isa Vector && length(c) != dim(A) && error("Dimensions don't match.")
return GroupAlgebraElem{T, typeof(A)}(A, copy ? deepcopy(c) : c)
end
Expand Down
6 changes: 3 additions & 3 deletions src/AlgAss/AlgMat.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ has_one(A::MatAlgebra) = true

elem_type(::Type{MatAlgebra{T, S}}) where { T, S } = MatAlgebraElem{T, S}

order_type(::Type{MatAlgebra{QQFieldElem, S}}) where { S } = AlgAssAbsOrd{MatAlgebra{QQFieldElem, S}, elem_type(MatAlgebra{QQFieldElem, S})}

order_type(::Type{MatAlgebra{T, S}}) where { T <: NumFieldElem, S } = AlgAssRelOrd{T, fractional_ideal_type(order_type(parent_type(T))), MatAlgebra{T, S}}
#order_type(::Type{MatAlgebra{QQFieldElem, S}}) where { S } = AlgAssAbsOrd{MatAlgebra{QQFieldElem, S}, elem_type(MatAlgebra{QQFieldElem, S})}
#
#order_type(::Type{MatAlgebra{T, S}}) where { T <: NumFieldElem, S } = AlgAssRelOrd{T, fractional_ideal_type(order_type(parent_type(T))), MatAlgebra{T, S}}

matrix_algebra_type(K::Field) = matrix_algebra_type(typeof(K))

Expand Down
4 changes: 2 additions & 2 deletions src/AlgAss/AlgQuat.jl
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ dimension_of_center(A::QuaternionAlgebra) = 1

(A::QuaternionAlgebra{T})(a::QQFieldElem) where {T} = A(map(base_ring(A), [a, 0, 0, 0]))

order_type(::Type{QuaternionAlgebra{QQFieldElem}}) = AlgAssAbsOrd{QuaternionAlgebra{QQFieldElem}, elem_type(QuaternionAlgebra{QQFieldElem})}

#order_type(::Type{QuaternionAlgebra{QQFieldElem}}) = AlgAssAbsOrd{QuaternionAlgebra{QQFieldElem}, elem_type(QuaternionAlgebra{QQFieldElem})}
#
order_type(::Type{QuaternionAlgebra{T}}) where {T <: NumFieldElem} = AlgAssRelOrd{T, fractional_ideal_type(order_type(parent_type(T))), QuaternionAlgebra{T}}

################################################################################
Expand Down
223 changes: 222 additions & 1 deletion src/AlgAss/Conversions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -152,14 +152,235 @@ It is assumed that $p$ is prime.
"""
quo(I::Union{ AbsNumFieldOrderIdeal, AlgAssAbsOrdIdl }, J::Union{ AbsNumFieldOrderIdeal, AlgAssAbsOrdIdl }, p::Union{ Integer, ZZRingElem }) = StructureConstantAlgebra(I, J, p)

function StructureConstantAlgebra(I::AlgAssAbsOrdIdl, J::AlgAssAbsOrdIdl, p::IntegerUnion)
@assert order(I) === order(J)

O = order(I)
Oalgebra = _algebra(O)

n = degree(O)
BmatJinI = _hnf_integral(basis_matrix(J, copy = false)*basis_mat_inv(I, copy = false), :lowerleft)
@assert isone(denominator(BmatJinI)) "J is not a subset of I"
BmatJinI = numerator(BmatJinI)
basis_elts = Vector{Int}()
for i = 1:n
if valuation(BmatJinI[i, i], p) == 0
continue
end

push!(basis_elts, i)
end

r = length(basis_elts)
Fp = GF(p, cached = false)

if r == 0
A = zero_algebra(Fp)

local _image_zero

let A = A
function _image_zero(a::Union{ AbsNumFieldOrderElem, AlgAssAbsOrdElem })
return A()
end
end

local _preimage_zero

let O = O
function _preimage_zero(a::AssociativeAlgebraElem)
return O()
end
end

OtoA = AbsOrdToAlgAssMor{typeof(O), elem_type(Fp)}(O, A, _image_zero, _preimage_zero)
return A, OtoA
end

BI = basis(I, copy = false)
BmatI = basis_matrix(I, copy = false)
BmatIinv = inv(BmatI)

mult_table = Array{elem_type(Fp), 3}(undef, r, r, r)
for i = 1:r
M = representation_matrix(_elem_in_algebra(BI[basis_elts[i]], copy = false))
M = mul!(M, BmatI, M)
M = mul!(M, M, BmatIinv)
@assert denominator(M) == 1
M = numerator(M) # M is now the representation matrix in the basis of I
# TODO: fix type
if r != degree(O)
M = reduce_rows_mod_hnf!(M, BmatJinI, basis_elts)
end
for j = 1:r
for k = 1:r
mult_table[i, j, k] = Fp(M[basis_elts[j], basis_elts[k]])
end
end
end

A = StructureConstantAlgebra(Fp, mult_table)
if is_commutative(O)
A.is_commutative = 1
end

t = zero_matrix(QQ, 1, n)

local _image

let BmatJinI = BmatJinI, I = I, r = r, A = A, t = t, Fp = Fp
function _image(a::AlgAssAbsOrdElem)
elem_to_mat_row!(t, 1, _elem_in_algebra(a, copy = false))
t = mul!(t, t, basis_mat_inv(I, copy = false))
@assert isone(denominator(t)) "Not an element of the domain"
c = reduce_vector_mod_hnf(numerator(t), BmatJinI)
return A([ Fp(c[i]) for i in basis_elts ])
end
end

local _preimage

temppp = zero(Oalgebra)

let BI = BI, basis_elts = basis_elts, r = r, Oalgebra = Oalgebra, temppp = temppp
function _preimage(a::AssociativeAlgebraElem)
acoords = map(x -> QQ(lift(ZZ, x)), coefficients(a, copy = false))
z = zero(Oalgebra)
for i in 1:r
if is_zero(acoords[i])
continue
end
temppp = mul!(temppp, acoords[i], BI[basis_elts[i]])
z = add!(z, z, temppp)
end
_zz = O(z)
return _zz
end
end

OtoA = AbsOrdToAlgAssMor{typeof(O), elem_type(Fp)}(O, A, _image, _preimage)

return A, OtoA
end

function StructureConstantAlgebra(I::AbsNumFieldOrderIdeal, J::AbsNumFieldOrderIdeal, p::IntegerUnion)
@assert order(I) === order(J)

O = order(I)
Oalgebra = _algebra(O)

n = degree(O)
BmatJinI = _hnf_integral(basis_matrix(J, copy = false)*basis_mat_inv(I, copy = false), :lowerleft)
@assert isone(BmatJinI.den) "J is not a subset of I"
BmatJinI = BmatJinI.num
basis_elts = Vector{Int}()
for i = 1:n
if valuation(BmatJinI[i, i], p) == 0
continue
end

push!(basis_elts, i)
end

r = length(basis_elts)
Fp = GF(p, cached = false)

if r == 0
A = zero_algebra(Fp)

local _image_zero

let A = A
function _image_zero(a::Union{ AbsNumFieldOrderElem, AlgAssAbsOrdElem })
return A()
end
end

local _preimage_zero

let O = O
function _preimage_zero(a::AssociativeAlgebraElem)
return O()
end
end

OtoA = AbsOrdToAlgAssMor{typeof(O), elem_type(Fp)}(O, A, _image_zero, _preimage_zero)
return A, OtoA
end

BI = basis(I, copy = false)
BmatI = basis_matrix(I, copy = false)
BmatIinv = inv(BmatI)

mult_table = Array{elem_type(Fp), 3}(undef, r, r, r)
for i = 1:r
M = FakeFmpqMat(representation_matrix(_elem_in_algebra(BI[basis_elts[i]], copy = false)))
M = mul!(M, BmatI, M)
M = mul!(M, M, BmatIinv)
@assert M.den == 1
M = M.num # M is now the representation matrix in the basis of I
if r != degree(O)
M = reduce_rows_mod_hnf!(M, BmatJinI, basis_elts)
end
for j = 1:r
for k = 1:r
mult_table[i, j, k] = Fp(M[basis_elts[j], basis_elts[k]])
end
end
end

A = StructureConstantAlgebra(Fp, mult_table)
if is_commutative(O)
A.is_commutative = 1
end

t = FakeFmpqMat(zero_matrix(ZZ, 1, n))

local _image

let BmatJinI = BmatJinI, I = I, r = r, A = A, t = t, Fp = Fp
function _image(a::Union{AbsNumFieldOrderElem, AlgAssAbsOrdElem})
elem_to_mat_row!(t.num, 1, t.den, _elem_in_algebra(a, copy = false))
t = mul!(t, t, basis_mat_inv(I, copy = false))
@assert isone(t.den) "Not an element of the domain"
c = reduce_vector_mod_hnf(t.num, BmatJinI)
return A([ Fp(c[i]) for i in basis_elts ])
end
end

local _preimage

temppp = zero(Oalgebra)

let BI = BI, basis_elts = basis_elts, r = r, Oalgebra = Oalgebra, temppp = temppp
function _preimage(a::AssociativeAlgebraElem)
acoords = map(x -> QQ(lift(ZZ, x)), coefficients(a, copy = false))
z = zero(Oalgebra)
for i in 1:r
if is_zero(acoords[i])
continue
end
temppp = mul!(temppp, acoords[i], BI[basis_elts[i]])
z = add!(z, z, temppp)
end
_zz = O(z)
return _zz
end
end

OtoA = AbsOrdToAlgAssMor{typeof(O), elem_type(Fp)}(O, A, _image, _preimage)

return A, OtoA
end

function StructureConstantAlgebra(I::Union{ AbsNumFieldOrderIdeal, AlgAssAbsOrdIdl }, J::Union{AbsNumFieldOrderIdeal, AlgAssAbsOrdIdl}, p::IntegerUnion)
@assert order(I) === order(J)

O = order(I)
Oalgebra = _algebra(O)

n = degree(O)
BmatJinI = hnf(basis_matrix(J, copy = false)*basis_mat_inv(I, copy = false), :lowerleft)
BmatJinI = _hnf_integral(basis_matrix(J, copy = false)*basis_mat_inv(I, copy = false), :lowerleft)
@assert isone(BmatJinI.den) "J is not a subset of I"
BmatJinI = BmatJinI.num
basis_elts = Vector{Int}()
Expand Down
2 changes: 1 addition & 1 deletion src/AlgAss/Elem.jl
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ function one(A::AbstractAssociativeAlgebra)
if _is_dense(A)
return A(deepcopy(A.one)) # deepcopy needed by mul!
else
return A(deepcopy(A.sparse_one))
return A(deepcopy(A.sparse_one)::sparse_row_type(base_ring(A)))
end
end

Expand Down
7 changes: 5 additions & 2 deletions src/AlgAss/StructureConstantAlgebra.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@
elem_type(::Type{StructureConstantAlgebra{T}}) where {T} = AssociativeAlgebraElem{T, StructureConstantAlgebra{T}}

# Definitions for orders
order_type(::Type{StructureConstantAlgebra{QQFieldElem}}) = AlgAssAbsOrd{StructureConstantAlgebra{QQFieldElem}, elem_type(StructureConstantAlgebra{QQFieldElem})}
order_type(::Type{StructureConstantAlgebra{T}}) where {T <: NumFieldElem} = AlgAssRelOrd{T, fractional_ideal_type(order_type(parent_type(T)))}
order_type(::Type{StructureConstantAlgebra{QQFieldElem}}) = AlgAssAbsOrd{ZZRing, StructureConstantAlgebra{QQFieldElem}}

#order_type(::Type{T}, ::Type{ZZRing}) where {T} = AlgAssAbsOrd{ZZRing, T}
#
#order_type(::Type{StructureConstantAlgebra{T}}) where {T <: NumFieldElem} = AlgAssRelOrd{T, fractional_ideal_type(order_type(parent_type(T)))}

################################################################################
#
Expand Down
4 changes: 2 additions & 2 deletions src/AlgAssAbsOrd/Conjugacy/Husert.jl
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ function _issimilar_husert_generic(A, B)
M = hcat(M, _M)
end

M = sub(hnf(FakeFmpqMat(transpose(M)), :upperright), 1:la, 1:la)
M = sub(_hnf_integral(FakeFmpqMat(transpose(M)), :upperright), 1:la, 1:la)
N = inv(M)

SS = N
Expand All @@ -147,7 +147,7 @@ function _issimilar_husert_generic(A, B)
end
M = hcat(M, _M)
end
M = sub(hnf(FakeFmpqMat(transpose(M)), :upperright), 1:la, 1:la)
M = sub(_hnf_integral(FakeFmpqMat(transpose(M)), :upperright), 1:la, 1:la)
N = inv(M)

bcolonb = N
Expand Down
Loading

0 comments on commit 429d727

Please sign in to comment.