AUTHORS:
This module implements the basic structure of finite simplicial
complexes. Given a set of “vertices”, a simplicial complex on
is a collection
of subsets of
satisfying the condition that if
is one of the subsets in
, then so is every subset of
. The
subsets
are called the ‘simplices’ of
.
A simplicial complex can be viewed as a purely combinatorial
object, as described above, but it also gives rise to a topological
space
(its geometric realization) as follows: first, the
points of
should be in general position in euclidean space. Next,
if
is in
, then the vertex
is in
. If
is in
, then the line segment from
to
is in
If
is in
, then the triangle with vertices
,
, and
is in
. In general,
is the union of the convex hulls of
simplices of
. Frequently, one abuses notation and uses
to
denote both the simplicial complex and the associated topological
space.
For any simplicial complex and any commutative ring
there is
an associated chain complex, with differential of degree
. The
term is the free
-module with basis given by the
-simplices of
. The differential is determined by its value on
any simplex: on the
-simplex with vertices
,
the differential is the alternating sum with
summand
multiplied by the
-simplex obtained by omitting vertex
.
In the implementation here, the vertex set must be finite. To define a
simplicial complex, specify its vertex set: this should be a list,
tuple, or set, or it can be a non-negative integer , in which case
the vertex set is
. Also specify the facets: the maximal
faces.
Note
The elements of the vertex set are not automatically contained in the simplicial complex: each one is only included if and only if it is a vertex of at least one of the specified facets.
EXAMPLES:
sage: SimplicialComplex([1, 3, 7], [[1], [3, 7]])
Simplicial complex with vertex set (1, 3, 7) and facets {(3, 7), (1,)}
sage: SimplicialComplex(2) # the empty simplicial complex
Simplicial complex with vertex set (0, 1, 2) and facets {()}
sage: X = SimplicialComplex(3, [[0,1], [1,2], [2,3], [3,0]])
sage: X
Simplicial complex with vertex set (0, 1, 2, 3) and facets {(1, 2), (2, 3), (0, 3), (0, 1)}
sage: X.stanley_reisner_ring()
Quotient of Multivariate Polynomial Ring in x0, x1, x2, x3 over Integer Ring by the ideal (x1*x3, x0*x2)
sage: X.is_pure()
True
Sage can perform a number of operations on simplicial complexes, such as the join and the product, and it can also compute homology:
sage: S = SimplicialComplex(3, [[0,1], [1,2], [0,2]]) # circle
sage: T = S.product(S) # torus
sage: T
Simplicial complex with 16 vertices and 18 facets
sage: T.homology() # this computes reduced homology
{0: 0, 1: Z x Z, 2: Z}
sage: T.euler_characteristic()
0
Sage knows about some basic combinatorial data associated to a simplicial complex:
sage: X = SimplicialComplex(3, [[0,1], [1,2], [2,3], [0,3]])
sage: X.f_vector()
[1, 4, 4]
sage: X.face_poset()
Finite poset containing 8 elements
sage: X.stanley_reisner_ring()
Quotient of Multivariate Polynomial Ring in x0, x1, x2, x3 over Integer Ring by the ideal (x1*x3, x0*x2)
Define a simplex.
Topologically, a simplex is the convex hull of a collection of vertices in general position. Combinatorially, it is defined just by specifying a set of vertices. It is represented in Sage by the tuple of the vertices.
INPUT:
OUTPUT: simplex with those vertices
X may be a non-negative integer , in which case the
simplicial complex will have
vertices
, or
it may be anything which may be converted to a tuple, in which
case the vertices will be that tuple.
Warning
The vertices should be distinct, and no error checking is done to make sure this is the case.
EXAMPLES:
sage: from sage.homology.simplicial_complex import Simplex
sage: Simplex(4)
(0, 1, 2, 3, 4)
sage: Simplex([3, 4, 1])
(3, 4, 1)
sage: X = Simplex((3, 'a', 'vertex')); X
(3, 'a', 'vertex')
sage: X == loads(dumps(X))
True
Simplex obtained by concatenating the underlying tuples of the two arguments.
INPUT:
EXAMPLES:
sage: from sage.homology.simplicial_complex import Simplex
sage: Simplex((1,2,3)) + Simplex((5,6))
(1, 2, 3, 5, 6)
Return True iff this simplex is the same as other: that is, if the vertices of the two are the same, even with a different ordering
INPUT:
EXAMPLES:
sage: from sage.homology.simplicial_complex import Simplex
sage: Simplex([0,1,2]) == Simplex([0,2,1])
True
sage: Simplex([0,1,2]) == Simplex(['a','b','c'])
False
Return True iff x is a vertex of this simplex.
EXAMPLES:
sage: from sage.homology.simplicial_complex import Simplex
sage: 3 in Simplex(5)
True
sage: 3 in Simplex(2)
False
Return the nth vertex in this simplex.
EXAMPLES:
sage: from sage.homology.simplicial_complex import Simplex
sage: Simplex(5)[2]
2
sage: Simplex(['a', 'b', 'c'])[1]
'b'
Hash value for this simplex. This computes the hash value of the Python frozenset of the underlying tuple, since this is what’s important when testing equality.
EXAMPLES:
sage: from sage.homology.simplicial_complex import Simplex
sage: Simplex([1,2,0]).__hash__() == Simplex(2).__hash__()
True
sage: Simplex([1,2,0,1,1,2]).__hash__() == Simplex(2).__hash__()
True
Define a simplex. See Simplex for full documentation.
EXAMPLES:
sage: from sage.homology.simplicial_complex import Simplex
sage: Simplex(2)
(0, 1, 2)
sage: Simplex(('a', 'b', 'c'))
('a', 'b', 'c')
Iterator for the vertices of this simplex.
EXAMPLES:
sage: from sage.homology.simplicial_complex import Simplex
sage: [v**2 for v in Simplex(3)]
[0, 1, 4, 9]
LaTeX representation.
EXAMPLES:
sage: from sage.homology.simplicial_complex import Simplex sage: Simplex(3)._latex_() \left(0, 1, 2, 3
ight)
Print representation.
EXAMPLES:
sage: from sage.homology.simplicial_complex import Simplex
sage: S = Simplex(5)
sage: S._repr_()
'(0, 1, 2, 3, 4, 5)'
The dimension of this simplex: the number of vertices minus 1.
EXAMPLES:
sage: from sage.homology.simplicial_complex import Simplex
sage: Simplex(5).dimension() == 5
True
sage: Simplex(5).face(1).dimension()
4
The nth face of this simplex.
INPUT:
OUTPUT: the simplex obtained by removing the nth vertex from this simplex
EXAMPLES:
sage: from sage.homology.simplicial_complex import Simplex
sage: S = Simplex(4)
sage: S.face(0)
(1, 2, 3, 4)
sage: S.face(3)
(0, 1, 2, 4)
The list of faces (of codimension 1) of this simplex.
EXAMPLES:
sage: from sage.homology.simplicial_complex import Simplex
sage: S = Simplex(4)
sage: S.faces()
[(1, 2, 3, 4), (0, 2, 3, 4), (0, 1, 3, 4), (0, 1, 2, 4), (0, 1, 2, 3)]
sage: len(Simplex(10).faces())
11
Return True iff this simplex is the empty simplex.
EXAMPLES:
sage: from sage.homology.simplicial_complex import Simplex
sage: [Simplex(n).is_empty() for n in range(-1,4)]
[True, False, False, False, False]
Return True iff this simplex is a face of other.
EXAMPLES:
sage: from sage.homology.simplicial_complex import Simplex
sage: Simplex(3).is_face(Simplex(5))
True
sage: Simplex(5).is_face(Simplex(2))
False
sage: Simplex(['a', 'b', 'c']).is_face(Simplex(8))
False
The join of this simplex with another one.
The join of two simplices and
is the simplex
.
INPUT:
EXAMPLES:
sage: from sage.homology.simplicial_complex import Simplex
sage: Simplex(2).join(Simplex(3))
('L0', 'L1', 'L2', 'R0', 'R1', 'R2', 'R3')
sage: Simplex(['a', 'b']).join(Simplex(['x', 'y', 'z']))
('La', 'Lb', 'Rx', 'Ry', 'Rz')
sage: Simplex(['a', 'b']).join(Simplex(['x', 'y', 'z']), rename_vertices=False)
('a', 'b', 'x', 'y', 'z')
The product of this simplex with another one, as a list of simplices.
INPUT:
other - the other simplex
this is False, then the vertices in the product are the set
of ordered pairs where
is a vertex in the
left-hand factor (self) and
is a vertex in the
right-hand factor (other). If this is True, then the
vertices are renamed as “LvRw” (e.g., the vertex (1,2)
would become “L1R2”). This is useful if you want to define
the Stanley-Reisner ring of the complex: vertex names like
(0,1) are not suitable for that, while vertex names like
“L0R1” are.
Algorithm: see Hatcher, p. 277-278 (who in turn refers to
Eilenberg-Steenrod, p. 68): given Simplex(m) and
Simplex(n), then Simplex(m) x Simplex(n) can be
triangulated as follows: for each path from
to
along the integer grid in the plane, going up or right
at each lattice point, associate an
-simplex with
vertices
,
, ..., where
is the
vertex
in the path
.
Note that there are choose
such paths. Note also
that each vertex in the product is a pair of vertices
where
is a vertex in the left-hand factor and
is a vertex in the right-hand factor.
Note
This produces a list of simplices – not a Simplex, not a SimplicialComplex.
EXAMPLES:
sage: from sage.homology.simplicial_complex import Simplex
sage: len(Simplex(2).product(Simplex(2)))
6
sage: Simplex(1).product(Simplex(1))
[((0, 0), (0, 1), (1, 1)), ((0, 0), (1, 0), (1, 1))]
REFERENCES:
The frozenset attached to this simplex.
EXAMPLES:
sage: from sage.homology.simplicial_complex import Simplex
sage: Simplex(3).set()
frozenset([0, 1, 2, 3])
The tuple attached to this simplex.
EXAMPLES:
sage: from sage.homology.simplicial_complex import Simplex
sage: Simplex(3).tuple()
(0, 1, 2, 3)
Although simplices are printed as if they were tuples, they are not the same type:
sage: type(Simplex(3).tuple())
<type 'tuple'>
sage: type(Simplex(3))
<class 'sage.homology.simplicial_complex.Simplex'>
Define a simplicial complex.
INPUT:
OUTPUT: a simplicial complex
vertex_set may be a non-negative integer (in which case
the simplicial complex will have
vertices
), or it may be anything which may be converted to a tuple.
Call the elements of this ‘vertices’.
maximal_faces should be a list or tuple or set (indeed, anything which may be converted to a set) whose elements are lists (or tuples, etc.) of vertices.
If vertex_check is True, check to see that each given maximal face is a subset of the vertex set. Raise an error for any bad face.
If maximality_check is True, check that each maximal face is, in fact, maximal. In this case, when producing the internal representation of the simplicial complex, omit those that are not. It is highly recommended that this be True; various methods for this class may fail if faces which are claimed to be maximal are in fact not.
If sort_facets is True, sort the vertices in each facet. If the vertices in different facets are not ordered compatibly (e.g., if you have facets (1, 3, 5) and (5, 3, 8)), then homology calculations may have unpredictable results.
If name_check is True, check the names of the vertices to see if they can be easily converted to generators of a polynomial ring – use this if you plan to use the Stanley-Reisner ring for the simplicial complex.
Note
The elements of vertex_set are not automatically in the simplicial complex: each one is only included if it is a vertex of at least one of the specified facets.
EXAMPLES:
sage: SimplicialComplex(4, [[1,2], [1,4]])
Simplicial complex with vertex set (0, 1, 2, 3, 4) and facets {(1, 2), (1, 4)}
sage: SimplicialComplex(3, [[0,2], [0,3], [0]])
Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 2), (0, 3)}
sage: SimplicialComplex(3, [[0,2], [0,3], [0]], maximality_check=False)
Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 2), (0, 3), (0,)}
sage: S = SimplicialComplex(['a', 'b', 'c'], (('a', 'b'), ('a', 'c'), ('b', 'c')))
sage: S
Simplicial complex with vertex set ('a', 'b', 'c') and facets {('b', 'c'), ('a', 'c'), ('a', 'b')}
sage: S == loads(dumps(S))
True
Two simplicial complexes are equal iff their vertex sets are equal and their sets of facets are equal.
EXAMPLES:
sage: SimplicialComplex(4, [[1,2], [2,3], [4]]) == SimplicialComplex(4, [[4], [2,3], [3], [2,1]])
True
sage: X = SimplicialComplex(4)
sage: X.add_face([1,3])
sage: X == SimplicialComplex(4, [[1,3]])
True
Define a simplicial complex. See SimplicialComplex for more documentation.
EXAMPLES:
sage: SimplicialComplex(3, [[0,2], [0,3], [0]])
Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 2), (0, 3)}
sage: SimplicialComplex(['a', 'b', 'c'], (('a', 'b'), ('a', 'c'), ('b', 'c')))
Simplicial complex with vertex set ('a', 'b', 'c') and facets {('b', 'c'), ('a', 'c'), ('a', 'b')}
The join of this simplicial complex with another one.
The join of two simplicial complexes and
is the
simplicial complex
with simplices of the form
for all simplices
in
and
in
.
INPUT:
EXAMPLES:
sage: S = SimplicialComplex(1, [[0], [1]])
sage: T = SimplicialComplex([2, 3], [[2], [3]])
sage: S.join(T)
Simplicial complex with vertex set ('L0', 'L1', 'R2', 'R3') and 4 facets
sage: S.join(T, rename_vertices=False)
Simplicial complex with vertex set (0, 1, 2, 3) and facets {(1, 3), (1, 2), (0, 2), (0, 3)}
The notation ‘*’ may be used, as well:
sage: S * S
Simplicial complex with vertex set ('L0', 'L1', 'R0', 'R1') and 4 facets
sage: S * S * S * S * S * S * S * S
Simplicial complex with 16 vertices and 256 facets
Return the complement of a simplex in the vertex set of this simplicial complex.
INPUT:
OUTPUT: its complement: the simplex formed by the vertices not contained in simplex.
Note that this only depends on the vertex set of the simplicial complex, not on its simplices.
EXAMPLES:
sage: X = SimplicialComplex(5)
sage: X._complement([1,2,3])
(0, 4, 5)
sage: X._complement([0,1,3,4])
(2, 5)
sage: X._complement([0,4,1,3])
(2, 5)
Find a contractible subcomplex of this simplicial complex,
preferably one which is as large as possible.
INPUT:
Motivation: if is the original complex and if
is
contractible, then the relative homology
is
isomorphic to the reduced homology of
. If
is large,
then the relative chain complex will be a good deal smaller
than the augmented chain complex for
, and this leads to a
speed improvement for computing the homology of
.
This just passes a subcomplex consisting of a facet to the method _enlarge_subcomplex.
Note
Thus when the simplicial complex is empty, so is the resulting ‘contractible subcomplex’, which is therefore not technically contractible. In this case, that doesn’t matter because the homology is computed correctly anyway.
EXAMPLES:
sage: sphere = SimplicialComplex(3, [[0,1,2,3]])
sage: sphere.remove_face([0,1,2,3])
sage: sphere
Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 2, 3), (0, 1, 2), (1, 2, 3), (0, 1, 3)}
sage: L = sphere._contractible_subcomplex(); L
Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 1, 2), (1, 2, 3), (0, 1, 3)}
sage: L.homology()
{0: 0, 1: 0, 2: 0}
Given a subcomplex of this simplicial complex
, find a
subcomplex
, as large as possible, containing
which is
homotopy equivalent to
(so that
is isomorphic
to
). This way, the chain complex for computing
will be smaller than that for computing
, so the computations should be faster.
INPUT:
OUTPUT: a complex containing subcomplex and contained
in self, homotopy equivalent to subcomplex.
Algorithm: start with the subcomplex and loop through the
facets of
which are not in
. For each one, see whether
its intersection with
is contractible, and if so, add it.
This is recursive: testing for contractibility calls this
routine again, via _contractible_subcomplex.
EXAMPLES:
sage: T = simplicial_complexes.Torus(); T
Simplicial complex with vertex set (0, 1, 2, 3, 4, 5, 6) and 14 facets
Inside the torus, define a subcomplex consisting of a loop:
sage: S = SimplicialComplex(T.vertices(), [[0,1], [1,2], [0,2]]) sage: S.homology() {0: 0, 1: Z} sage: L = T._enlarge_subcomplex(S) sage: L Simplicial complex with vertex set (0, 1, 2, 3, 4, 5, 6) and 8 facets sage: L.facets() {(0, 1, 5), (1, 3, 6), (1, 2), (1, 2, 4), (1, 3, 4), (0, 2), (1, 5, 6), (0, 1)} sage: L.homology() {0: 0, 1: Z, 2: 0}
The -vector of this simplicial complex as a dictionary: the
item associated to an integer
is the number of the
-faces.
EXAMPLES:
sage: S = Set(range(1,5))
sage: Z = SimplicialComplex(S, S.subsets()); Z
Simplicial complex with vertex set (1, 2, 3, 4) and facets {(1, 2, 3, 4)}
sage: [Z._f_dict()[n] for n in range(-1, 4)]
[1, 4, 6, 4, 1]
sage: Y = SimplicialComplex(5, [[1,2], [1,4]])
sage: Y._f_dict()[1]
2
The faces of this simplicial complex, as a list. (Flattened from the dictionary returned by the faces method.)
EXAMPLES:
sage: Y = SimplicialComplex(5, [[1,2], [1,4]])
sage: Y.faces()
{0: set([(4,), (2,), (1,)]), 1: set([(1, 2), (1, 4)]), -1: set([()])}
sage: Y._flattened_faces()
[(4,), (2,), (1,), (1, 2), (1, 4), ()]
Print representation. If there are only a few vertices or faces, they are listed. If there are lots, the number is given.
EXAMPLES:
sage: X = SimplicialComplex(3, [[0,1], [1,2]])
sage: X._repr_()
'Simplicial complex with vertex set (0, 1, 2, 3) and facets {(1, 2), (0, 1)}'
sage: SimplicialComplex(15)
Simplicial complex with 16 vertices and facets {()}
The polynomial algebra of which the Stanley-Reisner ring is a quotient.
INPUT:
OUTPUT: a polynomial algebra with coefficients in base_ring, with one generator for each vertex in the simplicial complex.
See the documentation for stanley_reisner_ring for a warning about the names of the vertices.
EXAMPLES:
sage: X = SimplicialComplex(3, [[1,2], [0]])
sage: X._stanley_reisner_base_ring()
Multivariate Polynomial Ring in x0, x1, x2, x3 over Integer Ring
sage: Y = SimplicialComplex(['a', 'b', 'c'])
sage: Y._stanley_reisner_base_ring(base_ring=QQ)
Multivariate Polynomial Ring in a, c, b over Rational Field
Given tuple L of simplices, returns new list, where each simplex is formed by taking a vertex from each simplex from L.
INPUT:
If simplices consists of , then the
output consists of all possible simplices of the form
, where
is a vertex of
. If a
vertex appears more than once in such a simplex, remove all
but one of its appearances. If such a simplex contains others
already produced, then ignore that larger simplex – the
output should be a list of minimal simplices constructed in
this way.
This is used in computing the minimal nonfaces and hence the Stanley-Reisner ring.
Note that this only depends on the vertex set of the simplicial complex, not on its simplices.
I don’t know if there is a standard name for this, but it looked sort of like the transpose of a matrix; hence the name for this method.
EXAMPLES:
sage: X = SimplicialComplex(5)
sage: X._transpose_simplices([1,2])
[(1,), (2,)]
sage: X._transpose_simplices([1,2], [3,4])
[(1, 3), (1, 4), (2, 3), (2, 4)]
In the following example, one can construct the simplices (1,2) and (1,3), but you can also construct (1,1) = (1,), which is a face of both of the others. So the answer omits (1,2) and (1,3):
sage: X._transpose_simplices([1,2], [1,3])
[(1,), (2, 3)]
Add a face to this simplicial complex
INPUT:
This changes the simplicial complex, adding a new face and all of its subfaces.
EXAMPLES:
sage: X = SimplicialComplex(2, [[0,1], [0,2]])
sage: X.add_face([0,1,2,]); X
Simplicial complex with vertex set (0, 1, 2) and facets {(0, 1, 2)}
sage: Y = SimplicialComplex(3); Y
Simplicial complex with vertex set (0, 1, 2, 3) and facets {()}
sage: Y.add_face([0,1])
sage: Y.add_face([1,2,3])
sage: Y
Simplicial complex with vertex set (0, 1, 2, 3) and facets {(1, 2, 3), (0, 1)}
If you add a face which is already present, there is no effect:
sage: Y.add_face([1,3]); Y
Simplicial complex with vertex set (0, 1, 2, 3) and facets {(1, 2, 3), (0, 1)}
The Alexander dual of this simplicial complex: according to the Macaulay2 documentation, this is the simplicial complex whose faces are the complements of its nonfaces.
Thus find the minimal nonfaces and take their complements to find the facets in the Alexander dual.
EXAMPLES:
sage: Y = SimplicialComplex(4); Y
Simplicial complex with vertex set (0, 1, 2, 3, 4) and facets {()}
sage: Y.alexander_dual()
Simplicial complex with vertex set (0, 1, 2, 3, 4) and 5 facets
sage: X = SimplicialComplex(3, [[0,1], [1,2], [2,3], [3,0]])
sage: X.alexander_dual()
Simplicial complex with vertex set (0, 1, 2, 3) and facets {(1, 3), (0, 2)}
The barycentric subdivision of this simplicial complex.
See http://en.wikipedia.org/wiki/Barycentric_subdivision for a definition.
EXAMPLES:
sage: triangle = SimplicialComplex(2, [[0,1], [1,2], [0, 2]])
sage: hexagon = triangle.barycentric_subdivision()
sage: hexagon
Simplicial complex with 6 vertices and 6 facets
sage: hexagon.homology(1) == triangle.homology(1)
True
Barycentric subdivisions can get quite large, since each
-dimensional facet in the original complex produces
facets in the subdivision:
sage: S4 = simplicial_complexes.Sphere(4)
sage: S4
Simplicial complex with vertex set (0, 1, 2, 3, 4, 5) and 6 facets
sage: S4.barycentric_subdivision()
Simplicial complex with 62 vertices and 720 facets
The Betti numbers of this simplicial complex as a dictionary (or a single Betti number, if only one dimension is given).
INPUT:
EXAMPLES: Build the two-sphere as a three-fold join of a two-point space with itself:
sage: S = SimplicialComplex(1, [[0], [1]])
sage: (S*S*S).betti()
{0: 0, 1: 0, 2: 1}
sage: (S*S*S).betti([1,2])
{1: 0, 2: 1}
sage: (S*S*S).betti(2)
1
Return the category to which this chain complex belongs: the category of all simplicial complexes.
EXAMPLES:
sage: SimplicialComplex(5, [[0,1], [1,2,3,4,5]]).category()
Category of simplicial complexes
The chain complex associated to this simplicial complex.
INPUT:
Note
If subcomplex is nonempty, then the argument augmented
has no effect: the chain complex relative to a nonempty
subcomplex is zero in dimension .
EXAMPLES:
sage: circle = SimplicialComplex(2, [[0,1], [1,2], [0, 2]])
sage: circle.chain_complex()
Chain complex with at most 2 nonzero terms over Integer Ring.
sage: circle.chain_complex()._latex_()
'\Bold{Z}^{3} \xrightarrow{d_{1}} \Bold{Z}^{3}'
sage: circle.chain_complex(base_ring=QQ, augmented=True)
Chain complex with at most 3 nonzero terms over Rational Field.
The reduced cohomology of this simplicial complex.
INPUT:
EXAMPLES:
sage: circle = SimplicialComplex(2, [[0,1], [1,2], [0, 2]])
sage: circle.cohomology()
{0: 0, 1: Z}
sage: P2 = SimplicialComplex(5, [[0,1,2], [0,2,3], [0,1,5], [0,4,5], [0,3,4], [1,2,4], [1,3,4], [1,3,5], [2,3,5], [2,4,5]]) # projective plane
sage: P2.cohomology()
{0: 0, 1: 0, 2: C2}
sage: P2.cohomology(base_ring=GF(2))
{0: Vector space of dimension 0 over Finite Field of size 2,
1: Vector space of dimension 1 over Finite Field of size 2,
2: Vector space of dimension 1 over Finite Field of size 2}
sage: P2.cohomology(base_ring=GF(3))
{0: Vector space of dimension 0 over Finite Field of size 3,
1: Vector space of dimension 0 over Finite Field of size 3,
2: Vector space of dimension 0 over Finite Field of size 3}
Relative cohomology:
sage: T = SimplicialComplex(1, [[0,1]])
sage: U = SimplicialComplex(1, [[0], [1]])
sage: T.cohomology(subcomplex=U)
{0: 0, 1: Z}
The cone on this simplicial complex.
The cone is the simplicial complex formed by adding a new
vertex and simplices of the form
for
every simplex
in the original simplicial
complex. That is, the cone is the join of the original
complex with a one-point simplicial complex.
EXAMPLES:
sage: S = SimplicialComplex(1, [[0], [1]])
sage: S.cone()
Simplicial complex with vertex set ('L0', 'L1', 'R0') and facets {('L0', 'R0'), ('L1', 'R0')}
The dimension of this simplicial complex: the maximum dimension of its faces.
EXAMPLES:
sage: U = SimplicialComplex(5, [[1,2], [1, 3, 4]])
sage: U.dimension()
2
sage: X = SimplicialComplex(3, [[0,1], [0,2], [1,2]])
sage: X.dimension()
1
The Euler characteristic of this simplicial complex: the
alternating sum over of the number of
-simplices.
EXAMPLES:
sage: Y = SimplicialComplex(5, [[1,2], [1,4]])
sage: Y.euler_characteristic()
1
sage: X = SimplicialComplex(3, [[0,1], [0,2], [1,2]])
sage: X.euler_characteristic()
0
The -vector of this simplicial complex: a list whose
item is the number of
-faces. Note that, like
all lists in Sage, this is indexed starting at 0: the 0th
element in this list is the number of -1 faces.
EXAMPLES:
sage: S = Set(range(1,5))
sage: Z = SimplicialComplex(S, S.subsets()); Z
Simplicial complex with vertex set (1, 2, 3, 4) and facets {(1, 2, 3, 4)}
sage: Z.f_vector()
[1, 4, 6, 4, 1]
sage: Y = SimplicialComplex(5, [[1,2], [1,4]])
sage: Y.f_vector()[2]
2
The face poset of this simplicial complex, the poset of nonempty faces, ordered by inclusion.
EXAMPLES:
sage: P = SimplicialComplex(3, [[0, 1], [1,2], [2,3]]).face_poset(); P
Finite poset containing 7 elements
sage: P.list()
[(3,), (2,), (2, 3), (1,), (0,), (0, 1), (1, 2)]
The faces of this simplicial complex, in the form of a dictionary of sets keyed by dimension. If the optional argument subcomplex is present, then return only the faces which are not in the subcomplex.
INPUT:
EXAMPLES:
sage: Y = SimplicialComplex(5, [[1,2], [1,4]])
sage: Y.faces()
{0: set([(4,), (2,), (1,)]), 1: set([(1, 2), (1, 4)]), -1: set([()])}
sage: L = SimplicialComplex(5, [[1,2]])
sage: Y.faces(subcomplex=L)
{0: set([(4,)]), 1: set([(1, 4)]), -1: set([])}
The maximal faces (a.k.a. facets) of this simplicial complex.
This just returns the set of facets used in defining the simplicial complex, so if the simplicial complex was defined with no maximality checking, none is done here, either.
EXAMPLES:
sage: Y = SimplicialComplex(5, [[0,2], [1,4]])
sage: Y.maximal_faces()
{(1, 4), (0, 2)}
facets is a synonym for maximal_faces:
sage: S = SimplicialComplex(2, [[0,1], [0,1,2]])
sage: S.facets()
{(0, 1, 2)}
The 1-skeleton of this simplicial complex, as a graph.
EXAMPLES:
sage: S = SimplicialComplex(3, [[0,1,2,3]])
sage: G = S.graph(); G
Graph on 4 vertices
sage: G.edges()
[(0, 1, None), (0, 2, None), (0, 3, None), (1, 2, None), (1, 3, None), (2, 3, None)]
The reduced homology of this simplicial complex.
INPUT:
Algorithm: if subcomplex is None, replace it with a facet
– a contractible subcomplex of the original complex. Then no
matter what subcomplex is, replace it with a subcomplex
which is homotopy equivalent and as large as possible.
Compute the homology of the original complex relative to
:
if
is large, then the relative chain complex will be small
enough to speed up computations considerably.
EXAMPLES:
sage: circle = SimplicialComplex(2, [[0,1], [1,2], [0, 2]])
sage: circle.homology()
{0: 0, 1: Z}
sage: sphere = SimplicialComplex(3, [[0,1,2,3]])
sage: sphere.remove_face([0,1,2,3])
sage: sphere
Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 2, 3), (0, 1, 2), (1, 2, 3), (0, 1, 3)}
sage: sphere.homology()
{0: 0, 1: 0, 2: Z}
Another way to get a two-sphere: take a two-point space and take its three-fold join with itself:
sage: S = SimplicialComplex(1, [[0], [1]])
sage: (S*S*S).homology(dim=2, cohomology=True)
Z
Relative homology:
sage: T = SimplicialComplex(2, [[0,1,2]])
sage: U = SimplicialComplex(2, [[0,1], [1,2], [0,2]])
sage: T.homology(subcomplex=U)
{0: 0, 1: 0, 2: Z}
True iff this simplicial complex is pure: a simplicial complex is pure iff all of its maximal faces have the same dimension.
Warning
This may give the wrong answer if the simplicial complex was constructed with maximality_check set to False.
EXAMPLES:
sage: U = SimplicialComplex(5, [[1,2], [1, 3, 4]])
sage: U.is_pure()
False
sage: X = SimplicialComplex(3, [[0,1], [0,2], [1,2]])
sage: X.is_pure()
True
The join of this simplicial complex with another one.
The join of two simplicial complexes and
is the
simplicial complex
with simplices of the form
for all simplices
in
and
in
.
INPUT:
EXAMPLES:
sage: S = SimplicialComplex(1, [[0], [1]])
sage: T = SimplicialComplex([2, 3], [[2], [3]])
sage: S.join(T)
Simplicial complex with vertex set ('L0', 'L1', 'R2', 'R3') and 4 facets
sage: S.join(T, rename_vertices=False)
Simplicial complex with vertex set (0, 1, 2, 3) and facets {(1, 3), (1, 2), (0, 2), (0, 3)}
The notation ‘*’ may be used, as well:
sage: S * S
Simplicial complex with vertex set ('L0', 'L1', 'R0', 'R1') and 4 facets
sage: S * S * S * S * S * S * S * S
Simplicial complex with 16 vertices and 256 facets
The link of a simplex in this simplicial complex.
The link of a simplex is the simplicial complex formed by
all simplices
which are disjoint from
but for which
is a simplex.
INPUT:
EXAMPLES:
sage: X = SimplicialComplex(4, [[0,1,2], [1,2,3]])
sage: from sage.homology.simplicial_complex import Simplex
sage: X.link(Simplex([0]))
Simplicial complex with vertex set (0, 1, 2, 3, 4) and facets {(1, 2)}
sage: X.link([1,2])
Simplicial complex with vertex set (0, 1, 2, 3, 4) and facets {(3,), (0,)}
sage: Y = SimplicialComplex(3, [[0,1,2,3]])
sage: Y.link([1])
Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 2, 3)}
The maximal faces (a.k.a. facets) of this simplicial complex.
This just returns the set of facets used in defining the simplicial complex, so if the simplicial complex was defined with no maximality checking, none is done here, either.
EXAMPLES:
sage: Y = SimplicialComplex(5, [[0,2], [1,4]])
sage: Y.maximal_faces()
{(1, 4), (0, 2)}
facets is a synonym for maximal_faces:
sage: S = SimplicialComplex(2, [[0,1], [0,1,2]])
sage: S.facets()
{(0, 1, 2)}
Set consisting of the minimal subsets of the vertex set of this simplicial complex which do not form faces.
Algorithm: first take the complement (within the vertex set)
of each facet, obtaining a set of simplices.
Now form the set of all simplices of the form
where vertex
is in face
. This set will
contain the minimal nonfaces and may contain some non-minimal
nonfaces also, so loop through the set to find the minimal
ones. (The last two steps are taken care of by the
_transpose_simplices routine.)
This is used in computing the Stanley-Reisner ring and the Alexander dual.
EXAMPLES:
sage: X = SimplicialComplex(4)
sage: X.minimal_nonfaces()
{(4,), (2,), (3,), (0,), (1,)}
sage: X.add_face([1,2])
sage: X.add_face([1,3])
sage: X.minimal_nonfaces()
{(4,), (2, 3), (0,)}
sage: Y = SimplicialComplex(3, [[0,1], [1,2], [2,3], [3,0]])
sage: Y.minimal_nonfaces()
{(1, 3), (0, 2)}
The set of faces of dimension n of this simplicial complex. If the optional argument subcomplex is present, then return the n-dimensional faces which are not in the subcomplex.
INPUT:
EXAMPLES:
sage: S = Set(range(1,5))
sage: Z = SimplicialComplex(S, S.subsets())
sage: Z
Simplicial complex with vertex set (1, 2, 3, 4) and facets {(1, 2, 3, 4)}
sage: Z.n_faces(2)
set([(1, 3, 4), (1, 2, 3), (2, 3, 4), (1, 2, 4)])
sage: K = SimplicialComplex(S, [[1,2,3], [2,3,4]])
sage: Z.n_faces(2, subcomplex=K)
set([(1, 3, 4), (1, 2, 4)])
The -skeleton of this simplicial complex: the simplicial
complex obtained by discarding all of the simplices in
dimensions larger than
.
INPUT:
EXAMPLES:
sage: X = SimplicialComplex(3, [[0,1], [1,2,3], [0,2,3]])
sage: X.n_skeleton(1)
Simplicial complex with vertex set (0, 1, 2, 3) and facets {(2, 3), (0, 2), (1, 3), (1, 2), (0, 3), (0, 1)}
sage: X.n_skeleton(2)
Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 2, 3), (1, 2, 3), (0, 1)}
The product of this simplicial complex with another one.
INPUT:
right - the other simplicial complex (the right-hand factor)
this is False, then the vertices in the product are the set
of ordered pairs where
is a vertex in self
and
is a vertex in right. If this is True, then the
vertices are renamed as “LvRw” (e.g., the vertex (1,2)
would become “L1R2”). This is useful if you want to define
the Stanley-Reisner ring of the complex: vertex names like
(0,1) are not suitable for that, while vertex names like
“L0R1” are.
The vertices in the product will be the set of ordered pairs
where
is a vertex in self and
is a vertex in
right.
Warning
If X and Y are simplicial complexes, then X*Y returns their join, not their product.
EXAMPLES:
sage: S = SimplicialComplex(3, [[0,1], [1,2], [0,2]]) # circle
sage: K = SimplicialComplex(1, [[0,1]]) # edge
sage: S.product(K).vertices() # cylinder
('L0R0', 'L0R1', 'L1R0', 'L1R1', 'L2R0', 'L2R1', 'L3R0', 'L3R1')
sage: S.product(K, rename_vertices=False).vertices()
((0, 0), (0, 1), (1, 0), (1, 1), (2, 0), (2, 1), (3, 0), (3, 1))
sage: T = S.product(S) # torus
sage: T
Simplicial complex with 16 vertices and 18 facets
sage: T.homology()
{0: 0, 1: Z x Z, 2: Z}
These can get large pretty quickly:
sage: T = simplicial_complexes.Torus(); T
Simplicial complex with vertex set (0, 1, 2, 3, 4, 5, 6) and 14 facets
sage: K = simplicial_complexes.KleinBottle(); K
Simplicial complex with 9 vertices and 18 facets
sage: T.product(K) # long time: 5 or 6 seconds
Simplicial complex with 63 vertices and 1512 facets
Remove a face from this simplicial complex
INPUT:
This changes the simplicial complex, removing the given face any face which contains it.
Algorithm: take the Alexander dual, add the complement of face, and then take the Alexander dual again.
EXAMPLES:
sage: S = range(1,5)
sage: Z = SimplicialComplex(S, [S]); Z
Simplicial complex with vertex set (1, 2, 3, 4) and facets {(1, 2, 3, 4)}
sage: Z.remove_face([1,2])
sage: Z
Simplicial complex with vertex set (1, 2, 3, 4) and facets {(1, 3, 4), (2, 3, 4)}
The Stanley-Reisner ring of this simplicial complex.
INPUT:
OUTPUT:
Thus the ideal is generated by the products corresponding to the minimal nonfaces of the simplicial complex.
Warning
This may be quite slow!
Also, this may behave badly if the vertices have the ‘wrong’ names. To avoid this, define the simplicial complex at the start with the flag name_check set to True.
More precisely, this is a quotient of a polynomial ring with one generator for each vertex. If the name of a vertex is a non-negative integer, then the corresponding polynomial generator is named ‘x’ followed by that integer (e.g., ‘x2’, ‘x3’, ‘x5’, ...). Otherwise, the polynomial generators are given the same names as the vertices. Thus if the vertex set is (2, ‘x2’), there will be problems.
EXAMPLES:
sage: X = SimplicialComplex(3, [[0,1], [1,2], [2,3], [0,3]])
sage: X.stanley_reisner_ring()
Quotient of Multivariate Polynomial Ring in x0, x1, x2, x3 over Integer Ring by the ideal (x1*x3, x0*x2)
sage: Y = SimplicialComplex(4); Y
Simplicial complex with vertex set (0, 1, 2, 3, 4) and facets {()}
sage: Y.stanley_reisner_ring()
Quotient of Multivariate Polynomial Ring in x0, x1, x2, x3, x4 over Integer Ring by the ideal (x4, x2, x3, x0, x1)
sage: Y.add_face([0,1,2,3,4])
sage: Y.stanley_reisner_ring(base_ring=QQ)
Quotient of Multivariate Polynomial Ring in x0, x1, x2, x3, x4 over Rational Field by the ideal (0)
The suspension of this simplicial complex.
INPUT:
The suspension is the simplicial complex formed by adding two
new vertices and
and simplices of the form
and
for every simplex
in the original simplicial complex. That
is, the cone is the join of the original complex with a
two-point simplicial complex.
EXAMPLES:
sage: S = SimplicialComplex(1, [[0], [1]])
sage: S.suspension()
Simplicial complex with vertex set ('L0', 'L1', 'R0', 'R1') and 4 facets
sage: S3 = S.suspension(3) # the 3-sphere
sage: S3.homology()
{0: 0, 1: 0, 2: 0, 3: Z}
The vertex set of this simplicial complex.
EXAMPLES:
sage: S = SimplicialComplex(15, [[0,1], [1,2]])
sage: S
Simplicial complex with 16 vertices and facets {(1, 2), (0, 1)}
sage: S.vertices()
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
Note that this actually returns a simplex:
sage: type(S.vertices())
<class 'sage.homology.simplicial_complex.Simplex'>
Given lists (or tuples or ...) t1 and t2, think of them as labelings for vertices: t1 labeling points on the x-axis, t2 labeling points on the y-axis, both increasing. Return the list of rectilinear paths along the grid defined by these points in the plane, starting from (t1[0], t2[0]), ending at (t1[last], t2[last]), and at each grid point, going either right or up. See the examples.
INPUT:
OUTPUT: list of lists of vertices making up the paths as described above
This is used when triangulating the product of simplices.
EXAMPLES:
sage: from sage.homology.simplicial_complex import lattice_paths
sage: lattice_paths([0,1,2], [0,1,2])
[[(0, 0), (0, 1), (0, 2), (1, 2), (2, 2)],
[(0, 0), (0, 1), (1, 1), (1, 2), (2, 2)],
[(0, 0), (1, 0), (1, 1), (1, 2), (2, 2)],
[(0, 0), (0, 1), (1, 1), (2, 1), (2, 2)],
[(0, 0), (1, 0), (1, 1), (2, 1), (2, 2)],
[(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)]]
sage: lattice_paths(('a', 'b', 'c'), (0, 3, 5))
[[('a', 0), ('a', 3), ('a', 5), ('b', 5), ('c', 5)],
[('a', 0), ('a', 3), ('b', 3), ('b', 5), ('c', 5)],
[('a', 0), ('b', 0), ('b', 3), ('b', 5), ('c', 5)],
[('a', 0), ('a', 3), ('b', 3), ('c', 3), ('c', 5)],
[('a', 0), ('b', 0), ('b', 3), ('c', 3), ('c', 5)],
[('a', 0), ('b', 0), ('c', 0), ('c', 3), ('c', 5)]]