Skip to content

Commit

Permalink
feat: prepare for FakeFmpqMat extinction
Browse files Browse the repository at this point in the history
- To generalize some constructions, we need to replace FakeFmpqMat with
  QQMatrix. Since both have different behaviour for `hnf` related
  functions, we first make the names of the methods for FakeFmpqMat
  unique.
  • Loading branch information
thofma committed Jan 30, 2025
1 parent 41aea2f commit 273bc7d
Show file tree
Hide file tree
Showing 13 changed files with 75 additions and 74 deletions.
2 changes: 1 addition & 1 deletion src/AlgAss/Conversions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ function StructureConstantAlgebra(I::Union{ AbsNumFieldOrderIdeal, AlgAssAbsOrdI
Oalgebra = _algebra(O)

n = degree(O)
BmatJinI = hnf(basis_matrix(J, copy = false)*basis_mat_inv(I, copy = false), :lowerleft)
BmatJinI = ___hnf(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
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(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(FakeFmpqMat(transpose(M)), :upperright), 1:la, 1:la)
N = inv(M)

bcolonb = N
Expand Down
42 changes: 21 additions & 21 deletions src/AlgAssAbsOrd/Ideal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,9 @@ If `M_in_hnf == true`, it is assumed that $M$ is already in lower left HNF.
function ideal(A::AbstractAssociativeAlgebra{QQFieldElem}, M::FakeFmpqMat; M_in_hnf::Bool=false)
if !M_in_hnf
if false #is_square(M) && (dim(A) > 50 || sum(nbits, numerator(M)) > 1000)
M = hnf(M, :lowerleft, compute_det = true)
M = ___hnf(M, :lowerleft, compute_det = true)

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

View check run for this annotation

Codecov / codecov/patch

src/AlgAssAbsOrd/Ideal.jl#L78

Added line #L78 was not covered by tests
else
M = hnf(M, :lowerleft)
M = ___hnf(M, :lowerleft)
end
end
k = something(findfirst(i -> !is_zero_row(M, i), 1:nrows(M)), nrows(M) + 1)
Expand Down Expand Up @@ -140,7 +140,7 @@ function ideal(O::AlgAssAbsOrd{S, T}, x::T) where {S, T}
elem_to_mat_row!(M, ii + j, t2)
end
end
M = sub(hnf(FakeFmpqMat(M), :lowerleft), nrows(M) - degree(O) + 1:nrows(M), 1:ncols(M))
M = sub(___hnf(FakeFmpqMat(M), :lowerleft), nrows(M) - degree(O) + 1:nrows(M), 1:ncols(M))

return ideal(A, O, M; side=:twosided, M_in_hnf=true)
end
Expand Down Expand Up @@ -207,7 +207,7 @@ function ideal_from_lattice_gens(A::AbstractAssociativeAlgebra{QQFieldElem}, v::
for i = 1:length(v)
elem_to_mat_row!(M, i, v[i])
end
M = hnf(FakeFmpqMat(M), :lowerleft)
M = ___hnf(FakeFmpqMat(M), :lowerleft)
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))
Expand Down Expand Up @@ -340,7 +340,7 @@ function assure_has_basis_matrix_wrt(a::AlgAssAbsOrdIdl, O::AlgAssAbsOrd)
return nothing
end

M = hnf(basis_matrix(a, copy = false)*basis_mat_inv(FakeFmpqMat, O, copy = false), :lowerleft)
M = ___hnf(basis_matrix(a, copy = false)*basis_mat_inv(FakeFmpqMat, O, copy = false), :lowerleft)
a.basis_matrix_wrt[O] = M
return nothing
end
Expand Down Expand Up @@ -454,9 +454,9 @@ function +(a::AlgAssAbsOrdIdl{S, T}, b::AlgAssAbsOrdIdl{S, T}) where {S, T}
d = dim(algebra(a))
M = vcat(basis_matrix(a, copy = false), basis_matrix(b, copy = false))
if nrows(M) >= ncols(M) && is_lower_triangular(M)
M = hnf(M, :lowerleft, triangular_top = true)
M = ___hnf(M, :lowerleft, triangular_top = true)
else
M = hnf(M, :lowerleft)
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))
Expand Down Expand Up @@ -489,9 +489,9 @@ function sum(a::Vector{AlgAssAbsOrdIdl{S, T}}) where {S, T}
j += d
end
if !iszero(g)
M = sub(hnf_modular_eldiv(bigmat, g, :lowerleft), (nrows(bigmat) - d + 1):nrows(bigmat), 1:d)
M = sub(___hnf_modular_eldiv(bigmat, g, :lowerleft), (nrows(bigmat) - d + 1):nrows(bigmat), 1:d)

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

View check run for this annotation

Codecov / codecov/patch

src/AlgAssAbsOrd/Ideal.jl#L492

Added line #L492 was not covered by tests
else
M = sub(hnf(bigmat, :lowerleft), (nrows(bigmat) - d + 1):nrows(bigmat), 1:d)
M = sub(___hnf(bigmat, :lowerleft), (nrows(bigmat) - d + 1):nrows(bigmat), 1:d)

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

View check run for this annotation

Codecov / codecov/patch

src/AlgAssAbsOrd/Ideal.jl#L494

Added line #L494 was not covered by tests
end

c = ideal(algebra(a[1]), M; M_in_hnf=true)
Expand Down Expand Up @@ -535,11 +535,11 @@ function *(a::AlgAssAbsOrdIdl{S, T}, b::AlgAssAbsOrdIdl{S, T}) where {S, T}

if is_full_rank(a) && is_full_rank(b)
el = b.basis_matrix.den * a.eldiv_mul * a.basis_matrix.den * b.eldiv_mul * denominator_of_structure_constant_table(A) * oned
H = sub(hnf_modular_eldiv!(FakeFmpqMat(M), el), (d2 - d + 1):d2, 1:d)
@hassert :AlgAssOrd 1 H == sub(hnf(FakeFmpqMat(M)), (d2 - d + 1):d2, 1:d)
H = sub(___hnf_modular_eldiv!(FakeFmpqMat(M), el), (d2 - d + 1):d2, 1:d)
@hassert :AlgAssOrd 1 H == sub(___hnf(FakeFmpqMat(M)), (d2 - d + 1):d2, 1:d)
else
H = sub(hnf(FakeFmpqMat(M)), (d2 - d + 1):d2, 1:d)
#H = sub(__hnf(FakeFmpqMat(M)), (d2 - d + 1):d2, 1:d)
H = sub(___hnf(FakeFmpqMat(M)), (d2 - d + 1):d2, 1:d)

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

View check run for this annotation

Codecov / codecov/patch

src/AlgAssAbsOrd/Ideal.jl#L541

Added line #L541 was not covered by tests
#H = sub(____hnf(FakeFmpqMat(M)), (d2 - d + 1):d2, 1:d)
end

c = ideal(A, H; M_in_hnf=true)
Expand Down Expand Up @@ -576,7 +576,7 @@ function intersect(a::AlgAssAbsOrdIdl{S, T}, b::AlgAssAbsOrdIdl{S, T}) where {S,
M1 = hcat(basis_matrix(a, copy = false), basis_matrix(a, copy = false))
M2 = hcat(FakeFmpqMat(zero_matrix(ZZ, d, d), ZZRingElem(1)), basis_matrix(b, copy = false))
M = vcat(M1, M2)
H = sub(hnf(M, :lowerleft), 1:d, 1:d)
H = sub(___hnf(M, :lowerleft), 1:d, 1:d)
c = ideal(algebra(a), H; M_in_hnf=true)

if isdefined(a, :order) && isdefined(b, :order) && order(a) === order(b)
Expand Down Expand Up @@ -814,7 +814,7 @@ function _colon_raw(a::AlgAssAbsOrdIdl{S, T}, b::AlgAssAbsOrdIdl{S, T}, side::Sy
end
end
end
M = sub(hnf(FakeFmpqMat(M), :upperright), 1:d, 1:d)
M = sub(___hnf(FakeFmpqMat(M), :upperright), 1:d, 1:d)
N = inv(transpose(M))
return N
end
Expand All @@ -826,7 +826,7 @@ 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(M))
return Order(algebra(a), ___hnf(M))
end

@doc raw"""
Expand Down Expand Up @@ -1272,7 +1272,7 @@ function _from_submodules_to_ideals(M::ModAlgAss, O::AlgAssAbsOrd, I::AlgAssAbsO
end
m = m*basis_matrix(FakeFmpqMat, O, copy = false)
m = vcat(m, basis_matrix(I, copy = false))
m = sub(hnf(m, :lowerleft), nrows(x) + 1:nrows(m), 1:degree(O))
m = sub(___hnf(m, :lowerleft), nrows(x) + 1:nrows(m), 1:degree(O))
J = ideal(algebra(O), O, m; side=:twosided, M_in_hnf=true)
if isdefined(I, :gens)
append!(g, I.gens)
Expand Down Expand Up @@ -1648,7 +1648,7 @@ function _as_order_of_smaller_algebra(m::AbsAlgAssMor, O::AlgAssAbsOrd, OB::AlgA
elem_to_mat_row!(M, i, basis_in_A[i])
end
M = FakeFmpqMat(M)
MM = sub(hnf!(M, :lowerleft), (dim(B) - dim(A) + 1):dim(B), 1:dim(A))
MM = sub(___hnf!(M, :lowerleft), (dim(B) - dim(A) + 1):dim(B), 1:dim(A))
OO = Order(A, MM)
return OO
end
Expand All @@ -1671,7 +1671,7 @@ function _as_ideal_of_larger_algebra(m::AbsAlgAssMor, I::AlgAssAbsOrdIdl, O::Alg
elem_to_mat_row!(M, (i - 1)*dim(B) + j, t)
end
end
M = sub(hnf(FakeFmpqMat(M), :lowerleft), dim(B)*(dim(A) - 1) + 1:dim(A)*dim(B), 1:dim(B))
M = sub(___hnf(FakeFmpqMat(M), :lowerleft), dim(B)*(dim(A) - 1) + 1:dim(A)*dim(B), 1:dim(B))
return ideal(B, O, M; side=:nothing, M_in_hnf=true)
end

Expand Down Expand Up @@ -2002,7 +2002,7 @@ function maximal_integral_ideal(O::AlgAssAbsOrd, p::Union{ ZZRingElem, Int }, si
end
end
N = FakeFmpqMat(N)
N = sub(hnf(N, :lowerleft), nrows(N) - degree(O) + 1:nrows(N), 1:degree(O))
N = sub(___hnf(N, :lowerleft), nrows(N) - degree(O) + 1:nrows(N), 1:degree(O))

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

View check run for this annotation

Codecov / codecov/patch

src/AlgAssAbsOrd/Ideal.jl#L2005

Added line #L2005 was not covered by tests

M = ideal(algebra(O), O, N; side, M_in_hnf=true)
if side == :left
Expand Down Expand Up @@ -2082,7 +2082,7 @@ function maximal_integral_ideal_containing(I::AlgAssAbsOrdIdl, p::Union{ ZZRingE
b = toOP\(BtoOP(toC\(basis_c[i])))
elem_to_mat_row!(t, i, elem_in_algebra(b, copy = false))
end
m = hnf(vcat(basis_matrix(P), FakeFmpqMat(t)), :lowerleft)
m = ___hnf(vcat(basis_matrix(P), FakeFmpqMat(t)), :lowerleft)

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

View check run for this annotation

Codecov / codecov/patch

src/AlgAssAbsOrd/Ideal.jl#L2085

Added line #L2085 was not covered by tests
m = sub(m, length(basis_c) + 1:nrows(m), 1:ncols(m))

M = ideal(algebra(O), O, m; side, M_in_hnf=true)
Expand Down
8 changes: 4 additions & 4 deletions src/AlgAssAbsOrd/Order.jl
Original file line number Diff line number Diff line change
Expand Up @@ -852,7 +852,7 @@ function any_order(A::AbstractAssociativeAlgebra{QQFieldElem})
M[1, i] = deepcopy(coefficients(oneA, copy = false)[i])
end
M = FakeFmpqMat(M)
M = hnf!(M, :lowerleft)
M = ___hnf!(M, :lowerleft)
O = Order(A, sub(M, 2:di + 1, 1:di))
return O
end::order_type(A)
Expand Down Expand Up @@ -892,7 +892,7 @@ function maximal_order_via_decomposition(A::AbstractAssociativeAlgebra{QQFieldEl
end
end
FakeM = FakeFmpqMat(M)
FakeM = hnf!(FakeM, :lowerleft)
FakeM = ___hnf!(FakeM, :lowerleft)
OO = Order(A, FakeM)
OO.is_maximal = 1
A.maximal_order = [OO]
Expand All @@ -915,7 +915,7 @@ function _maximal_order_via_decomposition(O::AlgAssAbsOrd, cache_in_substructure
append!(bas, Mibas)
end
M = Order(A, bas, isbasis = true)
N = Order(A, hnf(basis_matrix(FakeFmpqMat, M, copy = false)))
N = Order(A, ___hnf(basis_matrix(FakeFmpqMat, M, copy = false)))
N.is_maximal = 1
return N
end
Expand Down Expand Up @@ -946,7 +946,7 @@ function _simple_maximal_order(O::AlgAssAbsOrd{S1, S2}, ::Val{with_transform} =
end
end
M = FakeFmpqMat(M)
M = hnf!(M, :upperright)
M = ___hnf!(M, :upperright)

Check warning on line 949 in src/AlgAssAbsOrd/Order.jl

View check run for this annotation

Codecov / codecov/patch

src/AlgAssAbsOrd/Order.jl#L949

Added line #L949 was not covered by tests
M = QQMatrix(sub(M, 1:n, 1:n))

# Compute M * O * M^-1
Expand Down
2 changes: 1 addition & 1 deletion src/AlgAssAbsOrd/PIP/maximal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ function _isprincipal_maximal_simple_nice(I::AlgAssAbsOrdIdl, M, side = :right)
end
end
#@show z
h = transpose(hnf(transpose(FakeFmpqMat(z))))
h = transpose(___hnf(transpose(FakeFmpqMat(z))))

Check warning on line 331 in src/AlgAssAbsOrd/PIP/maximal.jl

View check run for this annotation

Codecov / codecov/patch

src/AlgAssAbsOrd/PIP/maximal.jl#L331

Added line #L331 was not covered by tests
#@show h
@assert all(i -> is_zero_column(h, i), 1:(d^2 - d))
T = sub(h, 1:d, (d^2 - d + 1:d^2))
Expand Down
4 changes: 2 additions & 2 deletions src/AlgAssAbsOrd/PIP/unit_group_generators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ global __GLn_generators_quadratic = [(-4, 1, [[[ 1, 0 ],[ 0, 0 ],[ 0, -1 ],[ 1,
################################################################################

function _orbit_stabilizer(G, idity, a)
OT = Tuple{typeof(idity), FakeFmpqMat}[(idity, hnf(basis_matrix(FakeFmpqMat, a)))]
OT = Tuple{typeof(idity), FakeFmpqMat}[(idity, ___hnf(basis_matrix(FakeFmpqMat, a)))]
Y = typeof(idity)[]
m = 1
while m <= length(OT)
Expand All @@ -311,6 +311,6 @@ end

function _operate(g::AbstractAssociativeAlgebraElem, b)
M = representation_matrix(g, :right)
c = hnf(b * FakeFmpqMat(M))
c = ___hnf(b * FakeFmpqMat(M))
return c
end
19 changes: 10 additions & 9 deletions src/LinearAlgebra/FakeFmpqMat.jl
Original file line number Diff line number Diff line change
Expand Up @@ -238,16 +238,20 @@ end
#
################################################################################

function hnf!(x::FakeFmpqMat, shape = :lowerleft)
function ___hnf!(x::FakeFmpqMat, shape = :lowerleft)
x.num = _hnf(x.num, shape)
return x
end

function __hnf(x::FakeFmpqMat)
function ____hnf(x::FakeFmpqMat)

Check warning on line 246 in src/LinearAlgebra/FakeFmpqMat.jl

View check run for this annotation

Codecov / codecov/patch

src/LinearAlgebra/FakeFmpqMat.jl#L246

Added line #L246 was not covered by tests
FakeFmpqMat(Nemo.__hnf(x.num), x.den)
end

function hnf(x::FakeFmpqMat, shape = :lowerleft; triangular_top::Bool = false, compute_det::Bool = false)
#function hnf_integral(x::QQMatrix, args...; kw...)
# return QQMatrix(hnf(FakeFmpqMat(x, args...; kw...)))
#end

function ___hnf(x::FakeFmpqMat, shape = :lowerleft; triangular_top::Bool = false, compute_det::Bool = false)
if triangular_top
@assert ncols(x) <= nrows(x)
z = one(ZZ)
Expand All @@ -269,7 +273,7 @@ function hnf(x::FakeFmpqMat, shape = :lowerleft; triangular_top::Bool = false, c
return FakeFmpqMat(h, denominator(x))
end

function hnf_modular_eldiv(x::FakeFmpqMat, g::ZZRingElem; shape = :lowerleft, cutoff::Bool = false)
function ___hnf_modular_eldiv(x::FakeFmpqMat, g::ZZRingElem; shape = :lowerleft, cutoff::Bool = false)

Check warning on line 276 in src/LinearAlgebra/FakeFmpqMat.jl

View check run for this annotation

Codecov / codecov/patch

src/LinearAlgebra/FakeFmpqMat.jl#L276

Added line #L276 was not covered by tests
h = _hnf_modular_eldiv(x.num, g, shape)
if cutoff
# Since we are modular, we are in the full rank situation
Expand All @@ -285,7 +289,7 @@ function hnf_modular_eldiv(x::FakeFmpqMat, g::ZZRingElem; shape = :lowerleft, cu
return FakeFmpqMat(h, denominator(x))
end

function hnf_modular_eldiv!(x::FakeFmpqMat, g::ZZRingElem; shape = :lowerleft, cutoff::Bool = false)
function ___hnf_modular_eldiv!(x::FakeFmpqMat, g::ZZRingElem; shape = :lowerleft, cutoff::Bool = false)
h = hnf_modular_eldiv!(x.num, g, shape)
# Since we are modular, we are in the full rank situation
if cutoff
Expand All @@ -300,10 +304,7 @@ function hnf_modular_eldiv!(x::FakeFmpqMat, g::ZZRingElem; shape = :lowerleft, c
return x
end

function _hnf_modular_iterative_eldiv(x::Vector{FakeFmpqMat}, g::ZZRingElem, shape = :lowerleft, cutoff::Bool = false)
end

function hnf!!(x::FakeFmpqMat, shape = :lowerleft)
function ___hnf!!(x::FakeFmpqMat, shape = :lowerleft)

Check warning on line 307 in src/LinearAlgebra/FakeFmpqMat.jl

View check run for this annotation

Codecov / codecov/patch

src/LinearAlgebra/FakeFmpqMat.jl#L307

Added line #L307 was not covered by tests
_hnf!(x.num, shape)
end

Expand Down
6 changes: 3 additions & 3 deletions src/ModAlgAss/Lattices/Basics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ function lattice(V::ModAlgAss{QQField}, O::AlgAssAbsOrd, B::Vector{<:ModAlgAssEl
end
end
M = matrix(coordinates.(BB))
MM = QQMatrix(hnf!(FakeFmpqMat(M), :upperright))
MM = QQMatrix(___hnf!(FakeFmpqMat(M), :upperright))
r = nrows(MM)
while is_zero_row(MM, r)
r = r - 1
Expand All @@ -73,7 +73,7 @@ function _lattice(V::ModAlgAss{QQField}, O::AlgAssAbsOrd, B::QQMatrix; check::Bo
@hassert :ModLattice _defines_lattice(V, O, B)

if !is_hnf
BB = QQMatrix(hnf!(FakeFmpqMat(B), :upperright))
BB = QQMatrix(___hnf!(FakeFmpqMat(B), :upperright))
else
BB = B
end
Expand Down Expand Up @@ -154,7 +154,7 @@ end
################################################################################

function _hnf_nonzero(a::QQMatrix)
b = QQMatrix(hnf(FakeFmpqMat(a)))
b = QQMatrix(___hnf(FakeFmpqMat(a)))
i = 1
while is_zero_row(b, i)
i += 1
Expand Down
2 changes: 1 addition & 1 deletion src/NumFieldOrd/NfOrd/FracIdeal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ function fractional_ideal(O::AbsNumFieldOrder, M::QQMatrix)
end

function fractional_ideal(O::AbsNumFieldOrder, M::FakeFmpqMat; M_in_hnf::Bool = false)
!M_in_hnf ? M = hnf(M) : nothing
!M_in_hnf ? M = ___hnf(M) : nothing
z = AbsNumFieldOrderFractionalIdeal(O, M)
return z
end
Expand Down
8 changes: 4 additions & 4 deletions src/NumFieldOrd/NfOrd/NfOrd.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1081,7 +1081,7 @@ function _order(K::S, elt::Vector{T}; cached::Bool = true, check::Bool = true, e
# M.d divides B.den and we can choose (B.den/M.den)*det(M.num) as
# modulus for the HNF of B.num.
mm = ZZ(m*denominator(B, copy = false))
hnf_modular_eldiv!(B, mm, shape = :lowerleft)
___hnf_modular_eldiv!(B, mm, shape = :lowerleft)
B = sub(B, nrows(B) - n + 1:nrows(B), 1:n)

# Check if we have a better modulus
Expand All @@ -1090,7 +1090,7 @@ function _order(K::S, elt::Vector{T}; cached::Bool = true, check::Bool = true, e
m = new_m
end
else
hnf!(B)
___hnf!(B)
k = findfirst(k -> !is_zero_row(B, k), nrows(B) - n + 1:nrows(B))
B = sub(B, nrows(B) - n + k:nrows(B), 1:n)
if nrows(B) == n
Expand Down Expand Up @@ -1132,14 +1132,14 @@ function ==(R::AbsNumFieldOrder, S::AbsNumFieldOrder)
end
assure_has_basis_matrix(R)
assure_has_basis_matrix(S)
return hnf(R.basis_matrix) == hnf(S.basis_matrix)
return ___hnf(R.basis_matrix) == ___hnf(S.basis_matrix)
end

function hash(R::AbsNumFieldOrder, h::UInt)
h = hash(nf(R), h)
h = hash(discriminant(R), h)
assure_has_basis_matrix(R)
h = hash(hnf(R.basis_matrix), h)
h = hash(___hnf(R.basis_matrix), h)
return h
end

Expand Down
Loading

0 comments on commit 273bc7d

Please sign in to comment.