Skip to content

Commit

Permalink
deprecate SimplicialComplex for simplicial_complex (#3234)
Browse files Browse the repository at this point in the history
* deprecate SimplicialComplex for simplicial_complex

* adds a test for simplicial complex for graphs

* Update src/Combinatorics/SimplicialComplexes.jl

Co-authored-by: Max Horn <max@quendi.de>

* readd SimplicalComplex to exports

* fix doc

* fixed internal use of simplicial complexes to align with deprecations

* transpose incidence matrix of graph

* tranpose incidence matrix for graph

* fixes for test

* fixes dep warning

* fix docs for incidence matrix

* fix typo in docs

* adds function for convert graph to simplicial complex

* adjust use of simplicial complex in Groups test

* fix in docstring

---------

Co-authored-by: Max Horn <max@quendi.de>
  • Loading branch information
antonydellavecchia and fingolfin committed Jan 26, 2024
1 parent 4b3ed0e commit 83f513a
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 78 deletions.
2 changes: 1 addition & 1 deletion docs/src/Combinatorics/simplicialcomplexes.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ General textbooks offering details on the theory include:
## Construction

```@docs
SimplicialComplex(K::Vector{Vector{Int}})
simplicial_complex(K::Vector{Vector{Int}})
```

### Subcomplexes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ end

@attr Polymake.IncidenceMatrixAllocated{Polymake.NonSymmetric} function _minimal_nonfaces(v::NormalToricVarietyType)
I = ray_indices(maximal_cones(v))
K = SimplicialComplex(I)
K = simplicial_complex(I)
return minimal_nonfaces(IncidenceMatrix, K)
end

Expand Down
4 changes: 3 additions & 1 deletion src/Combinatorics/Graphs/functions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -588,7 +588,9 @@ julia> incidence_matrix(g)
[]
```
"""
incidence_matrix(g::Graph{T}) where {T <: Union{Directed, Undirected}} = IncidenceMatrix(Polymake.graph.incidence_matrix(pm_object(g)))
function incidence_matrix(g::Graph{T}) where {T <: Union{Directed, Undirected}}
IncidenceMatrix(Polymake.graph.incidence_matrix(pm_object(g)))
end

@doc raw"""
signed_incidence_matrix(g::Graph{Directed})
Expand Down
50 changes: 31 additions & 19 deletions src/Combinatorics/SimplicialComplexes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,33 @@ pm_object(K::SimplicialComplex) = K.pm_simplicialcomplex


@doc raw"""
SimplicialComplex(generators::Union{Vector{Vector{Int}}, Vector{Set{Int}}})
simplical_complex(generators::Union{Vector{Vector{Int}}, Vector{Set{Int}}})
Construct an abstract simplicial complex from a set of faces.
While arbitrary non-negative integers are allowed as vertices, they will be relabeled to consecutive integers starting at 1.
# Examples
```jldoctest
julia> K = SimplicialComplex([[1,2,3],[2,3,4]])
julia> K = simplicial_complex([[1,2,3],[2,3,4]])
Abstract simplicial complex of dimension 2 on 4 vertices
julia> G = complete_bipartite_graph(2,3)
Undirected graph with 5 nodes and the following edges:
(3, 1)(3, 2)(4, 1)(4, 2)(5, 1)(5, 2)
julia> K = simplicial_complex(G)
Abstract simplicial complex of dimension 1 on 5 vertices
```
Simplicial complex comprising the empty set only:
```jldoctest
julia> empty = SimplicialComplex(Vector{Set{Int}}([]))
julia> empty = simplicial_complex(Vector{Set{Int}}([]))
Abstract simplicial complex of dimension -1 on 0 vertices
```
The original vertices can be recovered:
```jldoctest
julia> L = SimplicialComplex([[0,2,17],[2,17,90]]);
julia> L = simplicial_complex([[0,2,17],[2,17,90]]);
julia> facets(L)
2-element Vector{Set{Int64}}:
Expand All @@ -47,21 +54,27 @@ julia> vertexindices(L)
90
```
"""
function SimplicialComplex(generators::Union{AbstractVector{<:AbstractVector{<:Base.Integer}}, AbstractVector{<:AbstractSet{<:Base.Integer}}})
K = Polymake.topaz.SimplicialComplex(INPUT_FACES=generators)
SimplicialComplex(K)
function simplicial_complex(generators::Union{AbstractVector{<:AbstractVector{<:Base.Integer}}, AbstractVector{<:AbstractSet{<:Base.Integer}}})
K = Polymake.topaz.SimplicialComplex(INPUT_FACES=generators)
SimplicialComplex(K)
end

function SimplicialComplex(generators::IncidenceMatrix)
K = Polymake.@convert_to Array{Set} Polymake.common.rows(generators)
SimplicialComplex(K)
function simplicial_complex(generators::IncidenceMatrix)
K = Polymake.@convert_to Array{Set} Polymake.common.rows(generators)
simplicial_complex(K)
end

function simplicial_complex(G::Graph)
IM = incidence_matrix(G)
edges_as_rows = IncidenceMatrix(transpose(IM))
simplicial_complex(edges_as_rows)
end

# more efficient UNEXPORTED+UNDOCUMENTED version, which requires consecutive vertices, and facets as generators;
# will produce errors / segfaults or worse if used improperly
function _SimplicialComplex(generators::Union{Vector{Vector{Int}}, Vector{Set{Int}}})
K = Polymake.topaz.SimplicialComplex(FACETS=generators)
SimplicialComplex(K)
K = Polymake.topaz.SimplicialComplex(FACETS=generators)
SimplicialComplex(K)
end

################################################################################
Expand Down Expand Up @@ -207,7 +220,7 @@ Return `i`-th reduced integral cohomology group of `K`.
# Examples
```jldoctest
julia> K = SimplicialComplex([[0,1],[1,2],[0,2]]);
julia> K = simplicial_complex([[0,1],[1,2],[0,2]]);
julia> cohomology(K,1)
GrpAb: Z
Expand All @@ -222,7 +235,7 @@ Return the minimal non-faces of the abstract simplicial complex `K`.
# Examples
```jldoctest
julia> K = SimplicialComplex([[1,2,3],[2,3,4]]);
julia> K = simplicial_complex([[1,2,3],[2,3,4]]);
julia> minimal_nonfaces(K)
1-element Vector{Set{Int64}}:
Expand Down Expand Up @@ -252,7 +265,7 @@ Return the Alexander dual of the abstract simplicial complex `K`.
# Examples
```jldoctest
julia> K = SimplicialComplex([[1,2,3],[2,3,4]]);
julia> K = simplicial_complex([[1,2,3],[2,3,4]]);
julia> alexander_dual(K)
Abstract simplicial complex of dimension 1 on 2 vertices
Expand Down Expand Up @@ -302,7 +315,7 @@ Return the Stanley-Reisner ring of the abstract simplicial complex `K`.
# Examples
```jldoctest
julia> K = SimplicialComplex([[1,2,3],[2,3,4]]);
julia> K = simplicial_complex([[1,2,3],[2,3,4]]);
julia> stanley_reisner_ring(K)
(Quotient of multivariate polynomial ring by ideal(x1*x4), Map: multivariate polynomial ring -> quotient of multivariate polynomial ring)
Expand Down Expand Up @@ -413,7 +426,7 @@ Return the star of the face `sigma` in the abstract simplicial complex `K`.
# Examples
```jldoctest
julia> K = SimplicialComplex([[1,2,3],[2,3,4]]);
julia> K = simplicial_complex([[1,2,3],[2,3,4]]);
julia> star_subcomplex(K,[1])
Abstract simplicial complex of dimension 2 on 3 vertices
Expand All @@ -428,7 +441,7 @@ Return the link of the face `sigma` in the abstract simplicial complex `K`.
# Examples
```jldoctest
julia> K = SimplicialComplex([[1,2,3],[2,3,4]]);
julia> K = simplicial_complex([[1,2,3],[2,3,4]]);
julia> link_subcomplex(K,[2,3])
Abstract simplicial complex of dimension 0 on 2 vertices
Expand All @@ -445,4 +458,3 @@ function Base.show(io::IO, K::SimplicialComplex)
n = nvertices(K)
print(io, "Abstract simplicial complex of dimension $(d) on $(n) vertices")
end

2 changes: 1 addition & 1 deletion src/PolyhedralGeometry/PolyhedralFan/properties.jl
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,7 @@ julia> primitive_collections(normal_fan(simplex(3)))
function primitive_collections(PF::_FanLikeType)
@req is_simplicial(PF) "PolyhedralFan must be simplicial."
I = ray_indices(maximal_cones(PF))
K = SimplicialComplex(I)
K = simplicial_complex(I)
return minimal_nonfaces(K)
end

Expand Down
3 changes: 3 additions & 0 deletions src/deprecations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,9 @@ end

@deprecate components(X::AbsSpec) connected_components(X::AbsSpec)

@deprecate SimplicialComplex(generators::Union{AbstractVector{<:AbstractVector{<:Base.Integer}}, AbstractVector{<:AbstractSet{<:Base.Integer}}}) simplicial_complex(generators)
@deprecate SimplicialComplex(generators::IncidenceMatrix) simplicial_complex(generators)

Base.@deprecate_binding is_finitelygenerated is_finitely_generated
Base.@deprecate_binding has_is_finitelygenerated has_is_finitely_generated
Base.@deprecate_binding set_is_finitelygenerated set_is_finitely_generated
Expand Down
1 change: 1 addition & 0 deletions src/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1321,6 +1321,7 @@ export show_subquo
export signed_incidence_matrix
export signed_permutahedron
export simplex
export simplicial_complex
export simplified_fp_group
export simplify
export simplify!
Expand Down
110 changes: 56 additions & 54 deletions test/Combinatorics/SimplicialComplexes.jl
Original file line number Diff line number Diff line change
@@ -1,58 +1,60 @@
@testset "SimplicialComplex" begin

@testset "properties" begin

sphere = SimplicialComplex([[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]])

sphere2 = SimplicialComplex(IncidenceMatrix([[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]]))

@test sphere isa SimplicialComplex
@test sphere2 isa SimplicialComplex
@test vertexindices(sphere) == [1, 2, 3, 4]
@test nvertices(sphere) == 4
@test facets(sphere) == Set{Int}.([[1, 3, 2], [1, 4, 2], [1, 3, 4], [3, 4, 2]])
@test facets(sphere2) == facets(sphere)
@test dim(sphere) == 2
@test f_vector(sphere) == [4, 6, 4]
@test h_vector(sphere) == [1, 1, 1, 1]
@test betti_numbers(sphere) == [0, 0, 1]
@test euler_characteristic(sphere) == 1
@test minimal_nonfaces(sphere) == [Set{Int}([1, 2, 3, 4])]
R, _ = polynomial_ring(ZZ, ["a", "x", "i_7", "n"])
@test stanley_reisner_ideal(R, sphere) == ideal([R([1], [[1, 1, 1, 1]])])
@test is_isomorphic(fundamental_group(sphere), free_group())

# from #1440, make sure empty columns at the end are kept
sc = SimplicialComplex([[1, 2, 4], [2, 3, 4]])
@test size(minimal_nonfaces(IncidenceMatrix, sc)) == (1, 4)
end

@testset "standard examples" begin

for (SC, fv, bn) in ((torus(), [7, 21, 14], [0, 2, 1]),
(klein_bottle(), [9, 27, 18], [0, 1, 0]),
(real_projective_plane(), [6, 15, 10], [0, 0, 0]),
(complex_projective_plane(), [9, 36, 84, 90, 36], [0, 0, 1, 0, 1]))

@test SC isa SimplicialComplex
@test f_vector(SC) == fv
@test betti_numbers(SC) == bn

end

end

@testset "torus homology" begin
T = torus()
H0 = homology(T, 0)
H1 = homology(T, 1)
H2 = homology(T, 2)
@test is_trivial(H0)
@test !is_trivial(H1)
@test !is_trivial(H2)
@test rank(H0) == 0
@test rank(H1) == 2
@test rank(H2) == 1
@testset "properties" begin

sphere = simplicial_complex([[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]])

sphere2 = simplicial_complex(IncidenceMatrix([[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]]))

@test sphere isa SimplicialComplex
@test sphere2 isa SimplicialComplex
@test vertexindices(sphere) == [1, 2, 3, 4]
@test nvertices(sphere) == 4
@test facets(sphere) == Set{Int}.([[1, 3, 2], [1, 4, 2], [1, 3, 4], [3, 4, 2]])
@test facets(sphere2) == facets(sphere)
@test dim(sphere) == 2
@test f_vector(sphere) == [4, 6, 4]
@test h_vector(sphere) == [1, 1, 1, 1]
@test betti_numbers(sphere) == [0, 0, 1]
@test euler_characteristic(sphere) == 1
@test minimal_nonfaces(sphere) == [Set{Int}([1, 2, 3, 4])]
R, _ = polynomial_ring(ZZ, ["a", "x", "i_7", "n"])
@test stanley_reisner_ideal(R, sphere) == ideal([R([1], [[1, 1, 1, 1]])])
@test is_isomorphic(fundamental_group(sphere), free_group())

# from #1440, make sure empty columns at the end are kept
sc = simplicial_complex([[1, 2, 4], [2, 3, 4]])
@test size(minimal_nonfaces(IncidenceMatrix, sc)) == (1, 4)
end

@testset "standard examples" begin
G = simplicial_complex(complete_bipartite_graph(2, 3))
for (SC, fv, bn) in ((torus(), [7, 21, 14], [0, 2, 1]),
(klein_bottle(), [9, 27, 18], [0, 1, 0]),
(real_projective_plane(), [6, 15, 10], [0, 0, 0]),
(complex_projective_plane(), [9, 36, 84, 90, 36], [0, 0, 1, 0, 1]),
(G, [5, 6], [0, 2]))


@test SC isa SimplicialComplex
@test f_vector(SC) == fv
@test betti_numbers(SC) == bn

end


end

@testset "torus homology" begin
T = torus()
H0 = homology(T, 0)
H1 = homology(T, 1)
H2 = homology(T, 2)
@test is_trivial(H0)
@test !is_trivial(H1)
@test !is_trivial(H2)
@test rank(H0) == 0
@test rank(H1) == 2
@test rank(H2) == 1
end

end
2 changes: 1 addition & 1 deletion test/Groups/describe.jl
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ end
end

@testset "describe() for some real world examples" begin
P = SimplicialComplex([[1,2,4,9],[1,2,4,15],[1,2,6,14],[1,2,6,15],[1,2,9,14],[1,3,4,12],[1,3,4,15],[1,3,7,10],[1,3,7,12],[1,3,10,15],[1,4,9,12],[1,5,6,13],[1,5,6,14],[1,5,8,11],[1,5,8,13],[1,5,11,14],[1,6,13,15],[1,7,8,10],[1,7,8,11],[1,7,11,12],[1,8,10,13],[1,9,11,12],[1,9,11,14],[1,10,13,15],[2,3,5,10],[2,3,5,11],[2,3,7,10],[2,3,7,13],[2,3,11,13],[2,4,9,13],[2,4,11,13],[2,4,11,15],[2,5,8,11],[2,5,8,12],[2,5,10,12],[2,6,10,12],[2,6,10,14],[2,6,12,15],[2,7,9,13],[2,7,9,14],[2,7,10,14],[2,8,11,15],[2,8,12,15],[3,4,5,14],[3,4,5,15],[3,4,12,14],[3,5,10,15],[3,5,11,14],[3,7,12,13],[3,11,13,14],[3,12,13,14],[4,5,6,7],[4,5,6,14],[4,5,7,15],[4,6,7,11],[4,6,10,11],[4,6,10,14],[4,7,11,15],[4,8,9,12],[4,8,9,13],[4,8,10,13],[4,8,10,14],[4,8,12,14],[4,10,11,13],[5,6,7,13],[5,7,9,13],[5,7,9,15],[5,8,9,12],[5,8,9,13],[5,9,10,12],[5,9,10,15],[6,7,11,12],[6,7,12,13],[6,10,11,12],[6,12,13,15],[7,8,10,14],[7,8,11,15],[7,8,14,15],[7,9,14,15],[8,12,14,15],[9,10,11,12],[9,10,11,16],[9,10,15,16],[9,11,14,16],[9,14,15,16],[10,11,13,16],[10,13,15,16],[11,13,14,16],[12,13,14,15],[13,14,15,16]])
P = simplicial_complex([[1,2,4,9],[1,2,4,15],[1,2,6,14],[1,2,6,15],[1,2,9,14],[1,3,4,12],[1,3,4,15],[1,3,7,10],[1,3,7,12],[1,3,10,15],[1,4,9,12],[1,5,6,13],[1,5,6,14],[1,5,8,11],[1,5,8,13],[1,5,11,14],[1,6,13,15],[1,7,8,10],[1,7,8,11],[1,7,11,12],[1,8,10,13],[1,9,11,12],[1,9,11,14],[1,10,13,15],[2,3,5,10],[2,3,5,11],[2,3,7,10],[2,3,7,13],[2,3,11,13],[2,4,9,13],[2,4,11,13],[2,4,11,15],[2,5,8,11],[2,5,8,12],[2,5,10,12],[2,6,10,12],[2,6,10,14],[2,6,12,15],[2,7,9,13],[2,7,9,14],[2,7,10,14],[2,8,11,15],[2,8,12,15],[3,4,5,14],[3,4,5,15],[3,4,12,14],[3,5,10,15],[3,5,11,14],[3,7,12,13],[3,11,13,14],[3,12,13,14],[4,5,6,7],[4,5,6,14],[4,5,7,15],[4,6,7,11],[4,6,10,11],[4,6,10,14],[4,7,11,15],[4,8,9,12],[4,8,9,13],[4,8,10,13],[4,8,10,14],[4,8,12,14],[4,10,11,13],[5,6,7,13],[5,7,9,13],[5,7,9,15],[5,8,9,12],[5,8,9,13],[5,9,10,12],[5,9,10,15],[6,7,11,12],[6,7,12,13],[6,10,11,12],[6,12,13,15],[7,8,10,14],[7,8,11,15],[7,8,14,15],[7,9,14,15],[8,12,14,15],[9,10,11,12],[9,10,11,16],[9,10,15,16],[9,11,14,16],[9,14,15,16],[10,11,13,16],[10,13,15,16],[11,13,14,16],[12,13,14,15],[13,14,15,16]])
pi_1 = fundamental_group(P)
@test describe(pi_1) == "SL(2,5)"

Expand Down

0 comments on commit 83f513a

Please sign in to comment.