Skip to content

Commit

Permalink
goodnight moon
Browse files Browse the repository at this point in the history
  • Loading branch information
thofma committed Jan 31, 2025
1 parent 14d38b4 commit 4308263
Show file tree
Hide file tree
Showing 14 changed files with 327 additions and 182 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
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
31 changes: 20 additions & 11 deletions src/AlgAssAbsOrd/Elem.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,23 @@ Base.hash(x::AlgAssAbsOrdElem, h::UInt) = hash(elem_in_algebra(x, copy = false),
#
################################################################################

(O::AlgAssAbsOrd{S, T})(a::T, check::Bool = true) where {S, T} = begin
(O::AlgAssAbsOrd)(a::AbstractAssociativeAlgebraElem, check::Bool = true) = begin
if check
(x, y) = _check_elem_in_order(a, O)
!x && error("Algebra element not in the order")
return AlgAssAbsOrdElem{S, T}(O, deepcopy(a), y)
return AlgAssAbsOrdElem{typeof(O), typeof(a)}(O, deepcopy(a), y)
else
return AlgAssAbsOrdElem{S, T}(O, deepcopy(a))
return AlgAssAbsOrdElem{typeof(O), typeof(a)}(O, deepcopy(a))
end
end

(O::AlgAssAbsOrd{S, T})(a::T, arr::Vector{ZZRingElem}, check::Bool = false) where {S, T} = begin
(O::AlgAssAbsOrd)(a::AbstractAssociativeAlgebraElem, arr::Vector, check::Bool = false) = begin
if check
(x, y) = _check_elem_in_order(a, O)
(!x || arr != y) && error("Algebra element not in the order")
return AlgAssAbsOrdElem{S, T}(O, deepcopy(a), y)
return AlgAssAbsOrdElem{typeof(O), typeof(a)}(O, deepcopy(a), y)
else
return AlgAssAbsOrdElem{S, T}(O, deepcopy(a), deepcopy(arr))
return AlgAssAbsOrdElem{typeof(O), typeof(a)}(O, deepcopy(a), deepcopy(arr))
end
end

Expand All @@ -35,17 +35,17 @@ end
N = matrix(ZZ, 1, degree(O), arr)
NM = N*M
x = elem_from_mat_row(algebra(O), NM, 1)
return AlgAssAbsOrdElem{S, T}(O, x, deepcopy(arr))
return AlgAssAbsOrdElem{typeof(O), typeof(x)}(O, x, deepcopy(arr))
end

(O::AlgAssAbsOrd{S, T})(a::AlgAssAbsOrdElem{S, T}, check::Bool = true) where {S, T} = begin
(O::AlgAssAbsOrd{S, T})(a::AlgAssAbsOrdElem, check::Bool = true) where {S, T} = begin
b = elem_in_algebra(a) # already a copy
if check
(x, y) = _check_elem_in_order(b, O)
!x && error("Algebra element not in the order")
return AlgAssAbsOrdElem{S, T}(O, b, y)
return AlgAssAbsOrdElem{typeof(O), typeof(b)}(O, b, y)
else
return AlgAssAbsOrdElem{S, T}(O, b)
return AlgAssAbsOrdElem{typeof(O), typeof(b)}(O, b)
end
end

Expand Down Expand Up @@ -73,7 +73,7 @@ end
#
################################################################################

(O::AlgAssAbsOrd{S, T})() where {S, T} = AlgAssAbsOrdElem{S, T}(O)
(O::AlgAssAbsOrd{S, T})() where {S, T} = elem_type(O)(O)

one(O::AlgAssAbsOrd) = O(one(algebra(O)))

Expand Down Expand Up @@ -140,6 +140,15 @@ end
Returns the coordinates of $x$ in the basis of `parent(x)`.
"""
function coordinates(x::Union{ AlgAssAbsOrdElem, AlgAssRelOrdElem }; copy::Bool = true)
assure_has_coord(x)
if copy
return deepcopy(x.coordinates)::Vector{elem_type(base_ring(parent(x)))}
else
return x.coordinates::Vector{elem_type(base_ring(parent(x)))}
end
end

function coordinates(x::AlgAssRelOrdElem; copy::Bool = true)
assure_has_coord(x)
if copy
return deepcopy(x.coordinates)
Expand Down
73 changes: 44 additions & 29 deletions src/AlgAssAbsOrd/Ideal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,19 @@ function ideal(A::AbstractAssociativeAlgebra{QQFieldElem}, M::QQMatrix; M_in_hnf
end
end
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)))
return AlgAssAbsOrdIdl{ZZRing, typeof(A)}(A, ZZ, sub(M, k:nrows(M), 1:ncols(M)))
end

function ideal(A::AbstractAssociativeAlgebra, R::Ring, M::MatElem; M_in_hnf::Bool=false)
if !M_in_hnf
if false #is_square(M) && (dim(A) > 50 || sum(nbits, numerator(M)) > 1000)
M = _hnf_integral(M, R, :lowerleft, compute_det = true)
else
M = _hnf_integral(M, R, :lowerleft)
end
end
k = something(findfirst(i -> !is_zero_row(M, i), 1:nrows(M)), nrows(M) + 1)
return AlgAssAbsOrdIdl{typeof(R), typeof(A)}(A, R, sub(M, k:nrows(M), 1:ncols(M)))
end

@doc raw"""
Expand All @@ -94,8 +106,8 @@ If the ideal is known to be a right/left/twosided ideal of $O$, `side` may be
set to `:right`/`:left`/`:twosided` respectively.
If `M_in_hnf == true`, it is assumed that $M$ is already in lower left HNF.
"""
function ideal(A::AbstractAssociativeAlgebra{QQFieldElem}, O::AlgAssAbsOrd, M::QQMatrix; side::Symbol=:nothing, M_in_hnf::Bool=false)
a = ideal(A, M; M_in_hnf)
function ideal(A::AbstractAssociativeAlgebra, O::AlgAssAbsOrd, M::MatElem; side::Symbol=:nothing, M_in_hnf::Bool=false)
a = ideal(A, base_ring(O), M; M_in_hnf)
a.order = O
_set_sidedness(a, side)
if is_maximal_known(O) && is_maximal(O)
Expand All @@ -115,7 +127,7 @@ end
Returns the twosided principal ideal of $O$ generated by $x$.
"""
function ideal(O::AlgAssAbsOrd{S, T}, x::T) where {S, T}
function ideal(O::AlgAssAbsOrd, x::AbstractAssociativeAlgebraElem)
A = algebra(O)
@assert parent(x) === A
if iszero(x)
Expand Down Expand Up @@ -145,7 +157,7 @@ function ideal(O::AlgAssAbsOrd{S, T}, x::T) where {S, T}
return ideal(A, O, M; side=:twosided, M_in_hnf=true)
end

ideal(O::AlgAssAbsOrd{S, T}, x::AlgAssAbsOrdElem{S, T}) where { S, T } = ideal(O, elem_in_algebra(x, copy = false))
ideal(O::AlgAssAbsOrd, x::AlgAssAbsOrdElem) = ideal(O, elem_in_algebra(x, copy = false))

@doc raw"""
ideal(O::AlgAssAbsOrd, x::AbstractAssociativeAlgebraElem, side::Symbol) -> AlgAssAbsOrdIdl
Expand All @@ -154,7 +166,7 @@ ideal(O::AlgAssAbsOrd{S, T}, x::AlgAssAbsOrdElem{S, T}) where { S, T } = ideal(O
Returns the ideal $O \cdot x$ if `side == :left`, and $x \cdot O$ if
`side == :right`.
"""
function ideal(O::AlgAssAbsOrd{S, T}, x::T, side::Symbol) where { S, T }
function ideal(O::AlgAssAbsOrd, x::AbstractAssociativeAlgebraElem, side::Symbol)
A = algebra(O)
@assert parent(x) === A
if iszero(x)
Expand All @@ -174,7 +186,7 @@ function ideal(O::AlgAssAbsOrd{S, T}, x::T, side::Symbol) where { S, T }
return ideal(A, O, M; side)
end

ideal(O::AlgAssAbsOrd{S, T}, x::AlgAssAbsOrdElem{S, T}, side::Symbol) where { S, T } = ideal(O, elem_in_algebra(x, copy = false), side)
ideal(O::AlgAssAbsOrd, x::AlgAssAbsOrdElem, side::Symbol) = ideal(O, elem_in_algebra(x, copy = false), side)

@doc raw"""
*(O::AlgAssAbsOrd, x::AbstractAssociativeAlgebraElem) -> AlgAssAbsOrdIdl
Expand All @@ -188,10 +200,10 @@ ideal(O::AlgAssAbsOrd{S, T}, x::AlgAssAbsOrdElem{S, T}, side::Symbol) where { S,
Returns the ideal $O \cdot x$ or $x \cdot O$ respectively.
"""
*(O::AlgAssAbsOrd{S, T}, x::T) where {S, T <: Union{AssociativeAlgebraElem, MatAlgebraElem, GroupAlgebraElem}} = ideal(O, x, :left)
*(x::T, O::AlgAssAbsOrd{S, T}) where {S, T <: Union{AssociativeAlgebraElem, MatAlgebraElem, GroupAlgebraElem}} = ideal(O, x, :right)
*(O::AlgAssAbsOrd{S, T}, x::AlgAssAbsOrdElem{S, T}) where {S, T} = ideal(O, x, :left)
*(x::AlgAssAbsOrdElem{S, T}, O::AlgAssAbsOrd{S, T}) where {S, T} = ideal(O, x, :right)
*(O::AlgAssAbsOrd, x::T) where {T <: Union{AssociativeAlgebraElem, MatAlgebraElem, GroupAlgebraElem}} = ideal(O, x, :left)
*(x::T, O::AlgAssAbsOrd) where {T <: Union{AssociativeAlgebraElem, MatAlgebraElem, GroupAlgebraElem}} = ideal(O, x, :right)
*(O::AlgAssAbsOrd, x::AlgAssAbsOrdElem) = ideal(O, x, :left)
*(x::AlgAssAbsOrdElem, O::AlgAssAbsOrd) = ideal(O, x, :right)
*(O::AlgAssAbsOrd, x::Union{ Int, ZZRingElem }) = ideal(O, O(x), :left)
*(x::Union{ Int, ZZRingElem }, O::AlgAssAbsOrd) = ideal(O, O(x), :right)

Expand Down Expand Up @@ -227,7 +239,7 @@ lattice over $\mathbb Z$.
If the ideal is known to be a right/left/twosided ideal of $O$, `side` may be
set to `:right`/`:left`/`:twosided` respectively.
"""
function ideal_from_lattice_gens(A::S, O::AlgAssAbsOrd{S, T}, v::Vector{T}, side::Symbol = :nothing) where { S <: AbstractAssociativeAlgebra{QQFieldElem}, T <: AbstractAssociativeAlgebraElem{QQFieldElem} }
function ideal_from_lattice_gens(A::S, O::AlgAssAbsOrd, v::Vector, side::Symbol = :nothing) where { S <: AbstractAssociativeAlgebra{QQFieldElem}}
a = ideal_from_lattice_gens(A, v)
a.order = O
_set_sidedness(a, side)
Expand Down Expand Up @@ -412,9 +424,9 @@ Returns the basis matrix of $a$ with respect to the basis of $O$.
function basis_matrix_wrt(a::AlgAssAbsOrdIdl, O::AlgAssAbsOrd; copy::Bool = true)
assure_has_basis_matrix_wrt(a, O)
if copy
return deepcopy(a.basis_matrix_wrt[O])
return deepcopy(a.basis_matrix_wrt[O])::dense_matrix_type(base_ring(algebra(a)))
else
return a.basis_matrix_wrt[O]
return a.basis_matrix_wrt[O]::dense_matrix_type(base_ring(algebra(a)))
end
end

Expand Down Expand Up @@ -626,19 +638,21 @@ end

*(x::Union{ Int, ZZRingElem, QQFieldElem }, a::AlgAssAbsOrdIdl) = a*x

function *(a::AlgAssAbsOrdIdl{S, T}, x::T) where { S, T <: Union{AssociativeAlgebraElem, GroupAlgebraElem, MatAlgebraElem} }
base_ring(a::AlgAssAbsOrdIdl) = a.base_ring

function *(a::AlgAssAbsOrdIdl, x::T) where {T <: Union{AssociativeAlgebraElem, GroupAlgebraElem, MatAlgebraElem} }
if iszero(x)
return _zero_ideal(algebra(a))
end
M = basis_matrix(a, copy = false)* representation_matrix(x, :right)
b = ideal(algebra(a), M)
b = ideal(algebra(a), base_ring(a), M)
if isdefined(a, :left_order)
b.left_order = left_order(a)
end
return b
end

function *(x::T, a::AlgAssAbsOrdIdl{S, T}) where { S, T <: Union{AssociativeAlgebraElem, GroupAlgebraElem, MatAlgebraElem}}
function *(x::T, a::AlgAssAbsOrdIdl) where {T <: Union{AssociativeAlgebraElem, GroupAlgebraElem, MatAlgebraElem}}
if iszero(x)
return _zero_ideal(algebra(a))
end
Expand All @@ -650,7 +664,7 @@ function *(x::T, a::AlgAssAbsOrdIdl{S, T}) where { S, T <: Union{AssociativeAlge
return b
end

function *(a::AlgAssAbsOrdIdl{S, T}, x::AlgAssAbsOrdElem{S, T}) where { S, T }
function *(a::AlgAssAbsOrdIdl, x::AlgAssAbsOrdElem)
b = a*elem_in_algebra(x, copy = false)
if isdefined(a, :order) && parent(x) === order(a) && is_right_ideal(a)
b.order = order(a)
Expand All @@ -660,7 +674,7 @@ function *(a::AlgAssAbsOrdIdl{S, T}, x::AlgAssAbsOrdElem{S, T}) where { S, T }
return b
end

function *(x::AlgAssAbsOrdElem{S, T}, a::AlgAssAbsOrdIdl{S, T}) where { S, T }
function *(x::AlgAssAbsOrdElem, a::AlgAssAbsOrdIdl)
b = elem_in_algebra(x, copy = false)*a
if isdefined(a, :order) && parent(x) === order(a) && is_left_ideal(a)
b.order = order(a)
Expand All @@ -682,15 +696,15 @@ end
Returns `true` if $x$ is in $a$ and `false` otherwise.
"""
function in(x::T, a::AlgAssAbsOrdIdl{S, T}) where { S, T }
function in(x::AbstractAssociativeAlgebraElem, a::AlgAssAbsOrdIdl)
parent(x) !== algebra(a) && error("Algebra of element and ideal must be equal")
A = algebra(a)
t = matrix(QQ, 1, dim(A), coefficients(x, copy = false))
t = t*basis_mat_inv(a, copy = false)
return is_one(denominator(t))
end

in(x::AlgAssAbsOrdElem{S, T}, a::AlgAssAbsOrdIdl{S, T}) where { S, T } = in(elem_in_algebra(x, copy = false), a)
in(x::AlgAssAbsOrdElem, a::AlgAssAbsOrdIdl) = in(elem_in_algebra(x, copy = false), a)

################################################################################
#
Expand Down Expand Up @@ -803,8 +817,8 @@ function _colon_raw(a::AlgAssAbsOrdIdl{S, T}, b::AlgAssAbsOrdIdl{S, T}, side::Sy
K = base_ring(A)
d = dim(A)
bb = basis(b, copy = false)
B = QQMatrix(basis_mat_inv(a, copy = false))
M = zero_matrix(QQ, d^2, d)
B = basis_mat_inv(a, copy = false)
M = zero_matrix(base_ring(A), d^2, d)
for i = 1:d
N = representation_matrix(bb[i], side)*B
for s = 1:d
Expand All @@ -813,7 +827,7 @@ function _colon_raw(a::AlgAssAbsOrdIdl{S, T}, b::AlgAssAbsOrdIdl{S, T}, side::Sy
end
end
end
M = sub(_hnf_integral(M, :upperright), 1:d, 1:d)
M = sub(_hnf_integral(M, base_ring(a), :upperright), 1:d, 1:d)
N = inv(transpose(M))
return N
end
Expand All @@ -825,7 +839,8 @@ Given an ideal $a$, it returns the ring $(a : a)$.
"""
function ring_of_multipliers(a::AlgAssAbsOrdIdl, action::Symbol = :left)
M = _colon_raw(a, a, action)
return Order(algebra(a), _hnf_integral(M))
R = base_ring(a)
return Order(algebra(a), R, _hnf_integral(M, R))
end

@doc raw"""
Expand Down Expand Up @@ -1480,15 +1495,15 @@ end

FracIdealSet(O::AlgAssAbsOrd) = IdealSet(O)

elem_type(::Type{AlgAssAbsOrdIdlSet{S, T}}) where {S, T} = AlgAssAbsOrdIdl{S, T}
elem_type(::Type{AlgAssAbsOrdIdlSet{AlgAssAbsOrd{S, T}}}) where {S, T} = AlgAssAbsOrdIdl{S, T}

parent_type(::Type{AlgAssAbsOrdIdl{S, T}}) where {S, T} = AlgAssAbsOrdIdlSet{S, T}
parent_type(::Type{U}) where {S, T, U <: AlgAssAbsOrdIdl{S, T}} = AlgAssAbsOrdIdlSet{AlgAssAbsOrd{S, T}}

function Base.one(S::AlgAssAbsOrdIdlSet)
return ideal(order(S), one(order(S)))
end

==(x::AlgAssAbsOrdIdlSet, y::AlgAssAbsOrdIdlSet) = x.order === y.order
==(x::AlgAssAbsOrdIdlSet, y::AlgAssAbsOrdIdlSet) = x.order === y.order

################################################################################
#
Expand Down Expand Up @@ -2098,7 +2113,7 @@ end
#
################################################################################

function swan_module(R::AlgAssAbsOrd{<: GroupAlgebra}, r::IntegerUnion)
function swan_module(R::AlgAssAbsOrd{<: Any, <: GroupAlgebra}, r::IntegerUnion)
A = algebra(R)
n = order(group(A))
@req is_coprime(n, r) "Argument must be coprime to group order"
Expand Down
Loading

0 comments on commit 4308263

Please sign in to comment.