Skip to content
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

feat: improve code for orders in algebras #1337

Merged
merged 1 commit into from
Jan 7, 2024
Merged
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
6 changes: 1 addition & 5 deletions src/AlgAss/AbsAlgAss.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1248,11 +1248,7 @@ function _radical_prime_field(A::AbsAlgAss{T}) where { T } #<: Union{ fpFieldEle
MF = representation_matrix(a)
for m = 1:nrows(MF)
for n = 1:ncols(MF)
if T <: FqFieldElem
MZ[m, n] = lift(ZZ, MF[m, n])
else
MZ[m, n] = lift(MF[m, n])
end
MZ[m, n] = lift(ZZ, MF[m, n])
end
end
t = tr(MZ^Int(pl))
Expand Down
6 changes: 3 additions & 3 deletions src/AlgAss/AlgMatElem.jl
Original file line number Diff line number Diff line change
Expand Up @@ -227,17 +227,17 @@ function (A::AlgMat)()
return A(zero_matrix(coefficient_ring(A), n, n), check = false)
end

function (A::AlgMat{T, S})(M::S; check::Bool = true) where {T, S}
function (A::AlgMat{T, S})(M::S; check::Bool = true, deepcopy::Bool = true) where {T, S}
@assert base_ring(M) === coefficient_ring(A)
if check
b, c = _check_matrix_in_algebra(M, A)
@req b "Matrix not an element of the matrix algebra"
z = AlgMatElem{T, typeof(A), S}(A, deepcopy(M))
z = AlgMatElem{T, typeof(A), S}(A, deepcopy ? Base.deepcopy(M) : M)
z.coeffs = c
z.has_coeffs = true
return z
else
return AlgMatElem{T, typeof(A), S}(A, deepcopy(M))
return AlgMatElem{T, typeof(A), S}(A, deepcopy ? Base.deepcopy(M) : M)
end
end

Expand Down
1 change: 0 additions & 1 deletion src/AlgAss/Elem.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1040,7 +1040,6 @@ function normred_over_center(a::AbsAlgAssElem, ZtoA::AbsAlgAssMor)
_, ZtoB = center(B)
n1 = _normred_over_center_simple(BtoA\a, ZtoB)
t, n2 = haspreimage(ZtoA, BtoA(ZtoB(n1)))
@assert t
n += n2
end
return n
Expand Down
2 changes: 1 addition & 1 deletion src/AlgAssAbsOrd/Conjugacy/Conjugacy.jl
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ function _isGLZ_conjugate_integral(A::QQMatrix, B::QQMatrix)
OI = ideal_from_lattice_gens(AA, idealgens)
@hassert :Conjugacy 1 OO == right_order(OI)
@vprintln :Conjugacy 1 "Testing if ideal is principal..."
fl, y = _isprincipal(OI, OO, :right)::Tuple{Bool,
fl, y = _is_principal_with_data_bhj(OI, OO, side = :right)::Tuple{Bool,
AlgAssElem{QQFieldElem,AlgAss{QQFieldElem}}}

if !fl
Expand Down
2 changes: 1 addition & 1 deletion src/AlgAssAbsOrd/Conjugacy/Husert.jl
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ function _issimilar_husert_generic(A, B)

#@assert right_order(ide) == ideO

fl, y = _isprincipal(ide, ideO, :right)
fl, y = _is_principal_with_data_bhj(ide, ideO, side = :right)

if fl
dec = decompose(A)
Expand Down
2 changes: 1 addition & 1 deletion src/AlgAssAbsOrd/ICM.jl
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ function is_isomorphic_with_map(I::T, J::T) where { T <: Union{ NfAbsOrdIdl, NfO
JS = extend(J, S)
IJ = colon(IS, JS)
IJ.order = S
t, a = is_principal(numerator(IJ, copy = false))
t, a = is_principal_with_data(numerator(IJ, copy = false))
if !t
return false, zero(A)
end
Expand Down
124 changes: 93 additions & 31 deletions src/AlgAssAbsOrd/Ideal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@
M = hnf(M, :lowerleft)
end
end
return AlgAssAbsOrdIdl{typeof(A), elem_type(A)}(A, M)
k = something(findfirst(i -> !is_zero_row(M, i), 1:nrows(M)), nrows(M) + 1)
return AlgAssAbsOrdIdl{typeof(A), elem_type(A)}(A, sub(M, k:nrows(M), 1:ncols(M)))
end

@doc raw"""
Expand Down Expand Up @@ -207,10 +208,11 @@
elem_to_mat_row!(M, i, v[i])
end
M = hnf(FakeFmpqMat(M), :lowerleft)
if length(v) >= dim(A)
M = sub(M, (nrows(M) - dim(A) + 1):nrows(M), 1:dim(A))
end

i = something(findfirst(k -> !is_zero_row(M, k), 1:nrows(M)), nrows(M) + 1)
#if length(v) >= dim(A)
# M = sub(M, (nrows(M) - dim(A) + 1):nrows(M), 1:dim(A))
#end
M = sub(M, i:nrows(M), 1:ncols(M))
return ideal(A, M; M_in_hnf=true)
end

Expand Down Expand Up @@ -253,7 +255,7 @@

function iszero(a::AlgAssAbsOrdIdl)
if a.iszero == 0
if is_zero_row(basis_matrix(a, copy = false).num, dim(algebra(a)))
if is_zero(basis_matrix(a, copy = false))
a.iszero = 1
else
a.iszero = 2
Expand Down Expand Up @@ -325,8 +327,8 @@

M = basis_matrix(a, copy = false)
A = algebra(a)
b = Vector{elem_type(A)}(undef, dim(A))
for i = 1:dim(A)
b = Vector{elem_type(A)}(undef, nrows(M))
for i = 1:nrows(M)
b[i] = elem_from_mat_row(A, M.num, i, M.den)
end
a.basis = b
Expand Down Expand Up @@ -451,11 +453,13 @@

d = dim(algebra(a))
M = vcat(basis_matrix(a, copy = false), basis_matrix(b, copy = false))
if all(i -> !iszero(M[i, i]), 1:d)
M = sub(hnf(M, :lowerleft, triangular_top = true), (d + 1):2*d, 1:d)
if nrows(M) >= ncols(M) && is_lower_triangular(M)
M = hnf(M, :lowerleft, triangular_top = true)
else
M = sub(hnf(M, :lowerleft), (d + 1):2*d, 1:d)
M = hnf(M, :lowerleft)
end
k = findfirst(i -> !is_zero_row(M, i), 1:nrows(M))
M = sub(M, k:nrows(M), 1:ncols(M))
c = ideal(algebra(a), M; M_in_hnf=true)
if isdefined(a, :order) && isdefined(b, :order) && order(a) === order(b)
c.order = order(a)
Expand Down Expand Up @@ -956,6 +960,38 @@
"""
normred(a::AlgAssAbsOrdIdl; copy::Bool = true) = normred(a, order(a), copy = copy)

function normred_over_center(a::AlgAssAbsOrdIdl, ZtoA::AbsAlgAssMor)
A = algebra(order(a))
Adec = decompose(A)
Z = domain(ZtoA)
n = ideal_from_lattice_gens(Z, elem_type(Z)[])
for (B, BtoA) in Adec
_, ZtoB = center(B)

Check warning on line 969 in src/AlgAssAbsOrd/Ideal.jl

View check run for this annotation

Codecov / codecov/patch

src/AlgAssAbsOrd/Ideal.jl#L963-L969

Added lines #L963 - L969 were not covered by tests
# Compute the project AtoB(a)
aa = ideal_from_lattice_gens(B, [preimage(BtoA, c) for c in basis(a)])
n1 = _normred_over_center_simple(aa, ZtoB)

Check warning on line 972 in src/AlgAssAbsOrd/Ideal.jl

View check run for this annotation

Codecov / codecov/patch

src/AlgAssAbsOrd/Ideal.jl#L971-L972

Added lines #L971 - L972 were not covered by tests
#n1 = _normred_over_center_simple(BtoA\a, ZtoB)
#@show QQMatrix(basis_matrix(ZtoB(n1)))
#@show det(QQMatrix(basis_matrix(_as_ideal_of_smaller_algebra(ZtoA, BtoA(ZtoB(n1))))))
n2 = _as_ideal_of_smaller_algebra(ZtoA, BtoA(ZtoB(n1)))
n += n2
end
return n

Check warning on line 979 in src/AlgAssAbsOrd/Ideal.jl

View check run for this annotation

Codecov / codecov/patch

src/AlgAssAbsOrd/Ideal.jl#L976-L979

Added lines #L976 - L979 were not covered by tests
end

function _normred_over_center_simple(a::AlgAssAbsOrdIdl, ZtoA::AbsAlgAssMor)
A = algebra(a)
Z = domain(ZtoA)
fields = as_number_fields(Z)
@assert length(fields) == 1
K, ZtoK = fields[1]
B, BtoA = _as_algebra_over_center(A)
@assert base_ring(B) === K
aa = ideal_from_lattice_gens(B, [preimage(BtoA, c) for c in basis(a)])
n = normred(aa, left_order(aa))
return ideal_from_lattice_gens(Z, [preimage(ZtoK, c) for c in basis(n)])

Check warning on line 992 in src/AlgAssAbsOrd/Ideal.jl

View check run for this annotation

Codecov / codecov/patch

src/AlgAssAbsOrd/Ideal.jl#L982-L992

Added lines #L982 - L992 were not covered by tests
end

################################################################################
#
# Locally free basis
Expand Down Expand Up @@ -1495,14 +1531,20 @@
It is assumed that the order of $a$ contains $O$.
"""
function contract(A::AlgAssAbsOrdIdl, O::AlgAssAbsOrd)
AA = algebra(O)
# Assumes O \subseteq order(A)

d = degree(O)
M1 = hcat(basis_matrix(A, copy = false), basis_matrix(A, copy = false))
M2 = hcat(FakeFmpqMat(zero_matrix(FlintZZ, d, d), ZZRingElem(1)), basis_matrix(O, copy = false))
M = vcat(M1, M2)
H = sub(hnf(M, :lowerleft), 1:d, 1:d)
return ideal(algebra(A), O, H; side=:nothing, M_in_hnf=true)
BM = QQMatrix(basis_matrix(A))
BN = QQMatrix(basis_matrix(O))
dM = denominator(BM)
dN = denominator(BN)
d = lcm(dM, dN)
BMint = change_base_ring(ZZ, d * BM)
BNint = change_base_ring(ZZ, d * BN)
H = vcat(BMint, BNint)
k, K = left_kernel(H)
BI = divexact(change_base_ring(QQ, hnf(view(K, 1:k, 1:nrows(BM)) * BMint)), d)
N = FakeFmpqMat(BI)
return ideal(algebra(O), O, N; side = :nothing)
end

intersect(O::AlgAssAbsOrd, A::AlgAssAbsOrdIdl) = contract(A, O)
Expand All @@ -1527,20 +1569,41 @@
@assert dim(A) <= dim(B)
@assert algebra(I) === B
OA = maximal_order(A)
# Transport OA to B
M = zero_matrix(FlintQQ, dim(B), dim(B))
BM = zero_matrix(QQ, dim(A), dim(B))
for i = 1:dim(A)
t = m(basis_alg(OA, copy = false)[i])
elem_to_mat_row!(M, i, t)
end
# Compute the intersection of M and I
M = FakeFmpqMat(M)
M1 = hcat(M, M)
M2 = hcat(FakeFmpqMat(zero_matrix(FlintZZ, dim(B), dim(B)), ZZRingElem(1)), basis_matrix(I, copy = false))
N = sub(hnf(vcat(M1, M2), :lowerleft), 1:dim(B), 1:dim(B))
# Map the basis to A
basis_in_A = Vector{elem_type(A)}(undef, dim(B))
for i = 1:dim(B)
elem_to_mat_row!(BM, i, t)
end
BN = QQMatrix(basis_matrix(I))
dM = denominator(BM)
dN = denominator(BN)
d = lcm(dM, dN)
BMint = change_base_ring(ZZ, d * BM)
BNint = change_base_ring(ZZ, d * BN)
H = vcat(BMint, BNint)
k, K = left_kernel(H)
BI = divexact(change_base_ring(QQ, hnf(view(K, 1:k, 1:nrows(BM)) * BMint)), d)
N = FakeFmpqMat(BI)
#@show BI

#OA = maximal_order(A)
## Transport OA to B
#M = zero_matrix(FlintQQ, dim(B), dim(B))
#for i = 1:dim(A)
# t = m(basis_alg(OA, copy = false)[i])
# elem_to_mat_row!(M, i, t)
#end
## Compute the intersection of M and I
#M = FakeFmpqMat(M)
#M1 = hcat(M, M)
#IB = basis_matrix(I, copy = false)
#M2 = hcat(FakeFmpqMat(zero_matrix(FlintZZ, nrows(IB), dim(B)), ZZRingElem(1)), IB)
#H = hnf(vcat(M1, M2), :lowerleft)
#k = findfirst(i-> !is_zero_row(H, i), 1:nrows(H))
#N = sub(H, k:nrows(H), 1:dim(B))
## Map the basis to A
basis_in_A = Vector{elem_type(A)}(undef, nrows(N))
for i = 1:nrows(N)
t = elem_from_mat_row(B, N.num, i, N.den)
b, s = haspreimage(m, t)
@assert b
Expand Down Expand Up @@ -2259,7 +2322,6 @@
push!(res, (I + P^(ee), P))
end
end

@hassert :AlgAssOrd 1 prod(x[1] for x in res; init = 1 * O) == I
@hassert :AlgAssOrd all(x -> all(y -> y[2] === x[2] || x[2] + y[2] == 1*O, res), res)

Expand Down
Loading
Loading