Skip to content

Commit 461715b

Browse files
committed
polishing and size
1 parent f322497 commit 461715b

File tree

4 files changed

+93
-34
lines changed

4 files changed

+93
-34
lines changed

docs/src/CommutativeAlgebra/homological_algebra.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,16 @@ supporting computations in homological algebra.
1717
```@docs
1818
prune_with_map(M::ModuleFP)
1919
```
20-
## Finiteness as a set
20+
## Finiteness and cardinality as a set
2121

2222
```@docs
2323
is_finite(M::SubquoModule{T}) where {T<:Union{ZZRingElem, FieldElem}}
2424
```
2525

26+
```@docs
27+
size(M::SubquoModule{T}) where {T<:Union{ZZRingElem, FieldElem}}
28+
```
29+
2630
## Presentations
2731

2832
```@docs

src/Modules/UngradedModules/FreeResolutions.jl

Lines changed: 4 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -502,39 +502,11 @@ function free_resolution(M::SubquoModule{T};
502502
return FreeResolution(cc)
503503
end
504504

505-
# kept for the comments
506-
# function free_resolution(M::SubquoModule{T}) where {T<:RingElem}
507-
# # This generic code computes a free resolution in a lazy way.
508-
# # We start out with a presentation of M and implement
509-
# # an iterative fill function to compute every higher term
510-
# # on request.
511-
# R = base_ring(M)
512-
# p = presentation(M)
513-
# p.fill = function(C::Hecke.ComplexOfMorphisms, k::Int)
514-
# # TODO: Use official getter and setter methods instead
515-
# # of messing manually with the internals of the complex.
516-
# for i in first(chain_range(C)):k-1
517-
# N = domain(map(C, i))
518-
519-
# if iszero(N) # Fill up with zero maps
520-
# C.complete = true
521-
# phi = hom(N, N, elem_type(N)[]; check=false)
522-
# pushfirst!(C.maps, phi)
523-
# continue
524-
# end
525-
526-
# K, inc = kernel(map(C, i))
527-
# nz = findall(!is_zero, gens(K))
528-
# F = FreeMod(R, length(nz))
529-
# phi = hom(F, C[i], iszero(length(nz)) ? elem_type(C[i])[] : inc.(gens(K)[nz]); check=false)
530-
# pushfirst!(C.maps, phi)
531-
# end
532-
# return first(C.maps)
533-
# end
534-
# return p
535-
# end
536-
537505
function free_resolution(M::SubquoModule{T}; length::Int=0) where {T<:RingElem}
506+
# This generic code computes a free resolution in a lazy way.
507+
# We start out with a presentation of M and implement
508+
# an iterative fill function to compute every higher term
509+
# on request.
538510
R = base_ring(M)
539511
p = presentation(M)
540512
p.fill = function(C::Hecke.ComplexOfMorphisms, k::Int)

src/Modules/UngradedModules/Presentation.jl

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -706,7 +706,7 @@ end
706706
@doc raw"""
707707
is_finite(M::SubquoModule{T}) where {T<:Union{ZZRingElem, FieldElem}}
708708
709-
Determine whether the finitely presented module `M` over `ZZ` or a field is finite as a set.
709+
Determine whether the finitely presented module `M` over `ZZRing` or a `Field` is finite as a set.
710710
711711
This is done by computing a minimal presentation.
712712
@@ -782,3 +782,62 @@ function is_finite(M::SubquoModule{T}) where {T<:Union{ZZRingElem, FieldElem}}
782782
error("The base ring $(typeof(R)) is not supported.")
783783
end
784784
end
785+
786+
@doc raw"""
787+
size(M::SubquoModule{T}) where {T<:Union{ZZRingElem, FieldElem}}
788+
789+
Compute the cardinality of the finitely presented module `M` over `ZZRing` or a `Field` as a set.
790+
Returns `PosInf` if the module is infinite.
791+
792+
This is done by computing a minimal presentation.
793+
794+
# Examples
795+
```jldoctest
796+
julia> R = ZZ;
797+
798+
julia> F = free_module(FreeMod, R, 2);
799+
800+
julia> M = cokernel(hom(F, F, matrix(ZZ, [2 0; 0 3])));
801+
802+
julia> size(M)
803+
6
804+
805+
julia> N = cokernel(hom(F, F, matrix(ZZ, [1 0; 0 0])));
806+
807+
julia> size(N)
808+
infinity
809+
810+
julia> K, a = finite_field(7, "a");
811+
812+
julia> G = free_module(FreeMod, K, 3);
813+
814+
julia> H = free_module(FreeMod, K, 1);
815+
816+
julia> L = cokernel(hom(H, G, matrix(K, [1 0 0])));
817+
818+
julia> size(L)
819+
49
820+
```
821+
"""
822+
function size(M::SubquoModule{T}) where {T<:Union{ZZRingElem, FieldElem}}
823+
M_prime, _ = prune_with_map_atomic(M)
824+
R = base_ring(M_prime)
825+
pres = presentation(M_prime)
826+
rel_matrix = matrix(map(pres, 1))
827+
nc, nr = size(rel_matrix, 2), size(rel_matrix, 1)
828+
has_free_generator = any(j -> all(i -> iszero(rel_matrix[i, j]), 1:nr), 1:nc)
829+
if isa(R, ZZRing)
830+
if has_free_generator
831+
return PosInf()
832+
end
833+
return prod(abs(rel_matrix[i,i]) for i in 1:min(nr,nc))
834+
elseif isa(R, Field)
835+
if is_finite(R)
836+
q = order(R)
837+
dim = ngens(M_prime)
838+
return q^dim
839+
else
840+
return nc == 0 ? 1 : PosInf()
841+
end
842+
end
843+
end

test/Modules/UngradedModules.jl

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1731,4 +1731,28 @@ end
17311731
@test_throws AssertionError graded_free_module(ZZ, [1])
17321732
end
17331733

1734+
@testset "size of modules" begin
1735+
R = ZZ
1736+
F = free_module(FreeMod, R, 2)
1737+
M = cokernel(hom(F, F, matrix(ZZ, [2 0; 0 3])))
1738+
@test size(M) == 6
1739+
1740+
N = cokernel(hom(F, F, matrix(ZZ, [7 0; 0 0])))
1741+
@test size(N) == PosInf()
1742+
1743+
K, a = finite_field(7, "a")
1744+
G = free_module(FreeMod, K, 3)
1745+
H = free_module(FreeMod, K, 1)
1746+
L = cokernel(hom(H, G, matrix(K, [1 0 0])))
1747+
@test size(L) == 49
1748+
1749+
K, a = finite_field(7, "a")
1750+
G = free_module(FreeMod, K, 3)
1751+
L = cokernel(hom(G, G, matrix(K, [1 0 0; 0 1 0; 0 0 1])))
1752+
@test size(L) == 1
1753+
1754+
G = free_module(FreeMod, QQ, 3)
1755+
L = cokernel(hom(G, G, matrix(QQ, [1 0 0; 0 1 0; 0 0 1])))
1756+
@test size(L) == 1
1757+
end
17341758
end

0 commit comments

Comments
 (0)