Finite simplicial complexes

AUTHORS:

  • John H. Palmieri (2009-04)

This module implements the basic structure of finite simplicial complexes. Given a set V of “vertices”, a simplicial complex on V is a collection K of subsets of V satisfying the condition that if S is one of the subsets in K, then so is every subset of S. The subsets S are called the ‘simplices’ of K.

A simplicial complex K can be viewed as a purely combinatorial object, as described above, but it also gives rise to a topological space |K| (its geometric realization) as follows: first, the points of V should be in general position in euclidean space. Next, if \{v\} is in K, then the vertex v is in |K|. If \{v, w\} is in K, then the line segment from v to w is in |K| If \{u,
v, w\} is in K, then the triangle with vertices u, v, and w is in |K|. In general, |K| is the union of the convex hulls of simplices of K. Frequently, one abuses notation and uses K to denote both the simplicial complex and the associated topological space.

For any simplicial complex K and any commutative ring R there is an associated chain complex, with differential of degree -1. The n^{th} term is the free R-module with basis given by the n-simplices of K. The differential is determined by its value on any simplex: on the n-simplex with vertices (v_0, v_1, ..., v_n), the differential is the alternating sum with i^{th} summand (-1)^i multiplied by the (n-1)-simplex obtained by omitting vertex v_i.

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 n, in which case the vertex set is (0, ..., n). 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)
class sage.homology.simplicial_complex.Simplex(X)

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:

  • X - set of vertices

OUTPUT: simplex with those vertices

X may be a non-negative integer n, in which case the simplicial complex will have n+1 vertices (0, 1, ..., n), 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
__add__(other)

Simplex obtained by concatenating the underlying tuples of the two arguments.

INPUT:

  • other - another simplex.

EXAMPLES:

sage: from sage.homology.simplicial_complex import Simplex
sage: Simplex((1,2,3)) + Simplex((5,6))
(1, 2, 3, 5, 6)        
__cmp__(other)

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:

  • other - the other simplex

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
__contains__(x)

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
__getitem__(n)

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__()

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
__init__(X)

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')
__iter__()

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]
__weakref__
list of weak references to the object (if defined)
_latex_()

LaTeX representation.

EXAMPLES:

sage: from sage.homology.simplicial_complex import Simplex
sage: Simplex(3)._latex_()
\left(0, 
1, 
2, 
3

ight)

_repr_()

Print representation.

EXAMPLES:

sage: from sage.homology.simplicial_complex import Simplex
sage: S = Simplex(5)
sage: S._repr_()
'(0, 1, 2, 3, 4, 5)'
dimension()

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
face(n)

The nth face of this simplex.

INPUT:

  • n - an integer between 0 and the dimension of this simplex

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)
faces()

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
is_empty()

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]
is_face(other)

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
join(right, rename_vertices=True)

The join of this simplex with another one.

The join of two simplices [v_0, ..., v_k] and [w_0, ...,
w_n] is the simplex [v_0, ..., v_k, w_0, ..., w_n].

INPUT:

  • right - the other simplex (the right-hand factor)
  • rename_vertices – boolean (optional, default True). If this is True, the vertices in the join will be renamed by this formula: vertex “v” in the left-hand factor –> vertex “Lv” in the join, vertex “w” in the right-hand factor –> vertex “Rw” in the join. If this is false, this tries to construct the join without renaming the vertices; this may cause problems if the two factors have any vertices with names in common.

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')
product(other, rename_vertices=False)

The product of this simplex with another one, as a list of simplices.

INPUT:

  • other - the other simplex

  • rename_vertices – boolean (optional, default True). If

    this is False, then the vertices in the product are the set of ordered pairs (v,w) where v is a vertex in the left-hand factor (self) and w 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 f from (0,0) to (m,n) along the integer grid in the plane, going up or right at each lattice point, associate an (m+n)-simplex with vertices v_0, v_1, ..., where v_k is the k^{th} vertex in the path f.

Note that there are m+n choose n such paths. Note also that each vertex in the product is a pair of vertices (v,w) where v is a vertex in the left-hand factor and w 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:

  • A. Hatcher, “Algebraic Topology”, Cambridge University Press (2002).
set()

The frozenset attached to this simplex.

EXAMPLES:

sage: from sage.homology.simplicial_complex import Simplex
sage: Simplex(3).set()
frozenset([0, 1, 2, 3])
tuple()

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'>
class sage.homology.simplicial_complex.SimplicialComplex(vertex_set=[], maximal_faces=[], **kwds)

Define a simplicial complex.

INPUT:

  • vertex_set - set of vertices
  • maximal_faces - set of maximal faces
  • vertex_check - boolean (optional, default True)
  • maximality_check - boolean (optional, default True)
  • sort_facets - boolean (optional, default True)
  • name_check - boolean (optional, default False)

OUTPUT: a simplicial complex

vertex_set may be a non-negative integer n (in which case the simplicial complex will have n+1 vertices \{0, 1, ...,
n\}), 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
__cmp__(right)

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
__init__(vertex_set=[], maximal_faces=[], **kwds)

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')}            
__mul__(right, rename_vertices=True)

The join of this simplicial complex with another one.

The join of two simplicial complexes S and T is the simplicial complex S*T with simplices of the form [v_0,
..., v_k, w_0, ..., w_n] for all simplices [v_0, ..., v_k] in S and [w_0, ..., w_n] in T.

INPUT:

  • right - the other simplicial complex (the right-hand factor)
  • rename_vertices – boolean (optional, default True). If this is True, the vertices in the join will be renamed by the formula: vertex “v” in the left-hand factor –> vertex “Lv” in the join, vertex “w” in the right-hand factor –> vertex “Rw” in the join. If this is false, this tries to construct the join without renaming the vertices; this will cause problems if the two factors have any vertices with names in common.

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
__weakref__
list of weak references to the object (if defined)
_complement(simplex)

Return the complement of a simplex in the vertex set of this simplicial complex.

INPUT:

  • simplex - a simplex (need not be in the simplicial complex)

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)
_contractible_subcomplex(verbose=False)

Find a contractible subcomplex L of this simplicial complex, preferably one which is as large as possible.

INPUT:

  • verbose - boolean (optional, default False). If True, print some messages as the simplicial complex is computed.

Motivation: if K is the original complex and if L is contractible, then the relative homology H_*(K,L) is isomorphic to the reduced homology of K. If L is large, then the relative chain complex will be a good deal smaller than the augmented chain complex for K, and this leads to a speed improvement for computing the homology of K.

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}
_enlarge_subcomplex(subcomplex, verbose=False)

Given a subcomplex S of this simplicial complex K, find a subcomplex L, as large as possible, containing S which is homotopy equivalent to S (so that H_{*}(K,S) is isomorphic to H_{*}(K,L)). This way, the chain complex for computing H_{*}(K,L) will be smaller than that for computing H_{*}(K,S), so the computations should be faster.

INPUT:

  • subcomplex - a subcomplex of this simplicial complex
  • verbose - boolean (optional, default False). If True, print some messages as the simplicial complex is computed.

OUTPUT: a complex L containing subcomplex and contained in self, homotopy equivalent to subcomplex.

Algorithm: start with the subcomplex S and loop through the facets of K which are not in S. For each one, see whether its intersection with S 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}
_f_dict()

The f-vector of this simplicial complex as a dictionary: the item associated to an integer n is the number of the n-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
_flattened_faces()

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), ()]
_repr_()

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 {()}
_stanley_reisner_base_ring(base_ring=Integer Ring)

The polynomial algebra of which the Stanley-Reisner ring is a quotient.

INPUT:

  • base_ring - a commutative ring (optional, default ZZ)

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
_transpose_simplices(*simplices)

Given tuple L of simplices, returns new list, where each simplex is formed by taking a vertex from each simplex from L.

INPUT:

  • simplices - a bunch of simplices

If simplices consists of (f_0, f_1, f_2, ...), then the output consists of all possible simplices of the form (v_0,
v_1, v_2, ...), where v_i is a vertex of f_i. 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_face(face)

Add a face to this simplicial complex

INPUT:

  • face - a subset of the vertex set

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)}
alexander_dual()

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)}
barycentric_subdivision()

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 n-dimensional facet in the original complex produces (n+1)! 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
betti(dim=None, subcomplex=None)

The Betti numbers of this simplicial complex as a dictionary (or a single Betti number, if only one dimension is given).

INPUT:

  • dim - integer or list of integers or None (optional, default None). If None, then return every Betti number, as a dictionary with keys the non-negative integers. If dim is an integer or list, return the Betti number for each given dimension. (Actually, if dim is a list, return the Betti numbers, as a dictionary, in the range from min(dim) to max(dim). If dim is a number, return the Betti number in that dimension.)
  • subcomplex - a subcomplex of this simplicial complex (optional, default None). Compute the Betti numbers of the homology relative to this subcomplex.

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
category()

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
chain_complex(dimensions=None, base_ring=Integer Ring, subcomplex=None, augmented=False, cochain=False, verbose=False, check_diffs=False)

The chain complex associated to this simplicial complex.

INPUT:

  • dimensions - if None, compute the chain complex in all dimensions. If a list or tuple of integers, compute the chain complex in those dimensions, setting the chain groups in all other dimensions to zero.
  • base_ring - commutative ring (optional, default ZZ)
  • subcomplex - a subcomplex of this simplicial complex (optional, default empty). Compute the chain complex relative to this subcomplex.
  • augmented - boolean (optional, default False). If True, return the augmented chain complex (that is, include a class in dimension -1 corresponding to the empty cell). This is ignored if dimensions is specified.
  • cochain - boolean (optional, default False). If True, return the cochain complex (that is, the dual of the chain complex).
  • verbose - boolean (optional, default False). If True, print some messages as the chain complex is computed.
  • check_diffs - boolean (optional, default False). If True, make sure that the chain complex is actually a chain complex: the differentials are composable and their product is zero.

Note

If subcomplex is nonempty, then the argument augmented has no effect: the chain complex relative to a nonempty subcomplex is zero in dimension -1.

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.
cohomology(dim=None, base_ring=Integer Ring, subcomplex=None, enlarge=True, algorithm='auto', verbose=False)

The reduced cohomology of this simplicial complex.

INPUT:

  • dim - integer or list of integers or None (optional, default None). If None, then return the cohomology in every dimension. If dim is an integer or list, return the cohomology in the given dimensions. (Actually, if dim is a list, return the cohomology in the range from min(dim) to max(dim).)
  • base_ring - commutative ring (optional, default ZZ). Must be ZZ or a field.
  • subcomplex - a subcomplex of this simplicial complex (optional, default empty). Compute cohomology relative to this subcomplex.
  • enlarge - boolean (optional, default True). If True, find a new subcomplex homotopy equivalent to, and probably larger than, the given one.
  • algorithm - string (optional, default ‘auto’). This only has an effect if working over the integers. If ‘dhsw’, then preprocess each boundary matrix using the Dumas, Heckenbach, Saunders, and Welker elimination algorithm. If ‘pari’, then compute elementary divisors using Pari. If ‘linbox’, then use LinBox. If ‘auto’, then use ‘dhsw’ for large matrices and Pari for small ones.
  • verbose - boolean (optional, default False). If True, print some messages as the cohomology is computed.

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}
cone()

The cone on this simplicial complex.

The cone is the simplicial complex formed by adding a new vertex C and simplices of the form [C, v_0, ..., v_k] for every simplex [v_0, ..., v_k] 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')}
dimension()

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
euler_characteristic()

The Euler characteristic of this simplicial complex: the alternating sum over n \geq 0 of the number of n-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
f_vector()

The f-vector of this simplicial complex: a list whose n^{th} item is the number of (n-1)-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
face_poset()

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)]
faces(subcomplex=None)

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:

  • subcomplex - a subcomplex of this simplicial complex (optional, default None). Return faces which are not in this subcomplex.

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([])}
facets()

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)}
graph()

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)]
homology(dim=None, base_ring=Integer Ring, subcomplex=None, cohomology=False, enlarge=True, algorithm='auto', verbose=False)

The reduced homology of this simplicial complex.

INPUT:

  • dim - integer or list of integers or None (optional, default None). If None, then return the homology in every dimension. If dim is an integer or list, return the homology in the given dimensions. (Actually, if dim is a list, return the homology in the range from min(dim) to max(dim).)
  • base_ring - commutative ring (optional, default ZZ). Must be ZZ or a field.
  • subcomplex - a subcomplex of this simplicial complex (optional, default None). Compute homology relative to this subcomplex.
  • cohomology - boolean (optional, default False). If True, compute cohomology rather than homology.
  • enlarge - boolean (optional, default True). If True, find a new subcomplex homotopy equivalent to, and probably larger than, the given one.
  • algorithm - string (optional, default ‘auto’). This only has an effect if working over the integers. If ‘dhsw’, then preprocess each boundary matrix using the Dumas, Heckenbach, Saunders, and Welker elimination algorithm. If ‘pari’, then compute elementary divisors using Pari. If ‘linbox’, then use LinBox. If ‘auto’, then use ‘dhsw’ for large matrices and Pari for small ones.
  • verbose - boolean (optional, default False). If True, print some messages as the homology is computed.

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 L which is homotopy equivalent and as large as possible. Compute the homology of the original complex relative to L: if L 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}
is_pure()

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
join(right, rename_vertices=True)

The join of this simplicial complex with another one.

The join of two simplicial complexes S and T is the simplicial complex S*T with simplices of the form [v_0,
..., v_k, w_0, ..., w_n] for all simplices [v_0, ..., v_k] in S and [w_0, ..., w_n] in T.

INPUT:

  • right - the other simplicial complex (the right-hand factor)
  • rename_vertices – boolean (optional, default True). If this is True, the vertices in the join will be renamed by the formula: vertex “v” in the left-hand factor –> vertex “Lv” in the join, vertex “w” in the right-hand factor –> vertex “Rw” in the join. If this is false, this tries to construct the join without renaming the vertices; this will cause problems if the two factors have any vertices with names in common.

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 F is the simplicial complex formed by all simplices G which are disjoint from F but for which F
\cup G is a simplex.

INPUT:

  • simplex - a simplex in this simplicial complex.

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)}
maximal_faces()

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)}
minimal_nonfaces()

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 (f_1, f_2, ...) of simplices. Now form the set of all simplices of the form (v_1, v_2,
...) where vertex v_i is in face f_i. 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)}
n_faces(n, subcomplex=None)

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:

  • n - non-negative integer
  • subcomplex - a subcomplex of this simplicial complex (optional, default None). Return n-dimensional faces which are not in this subcomplex.

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)])
n_skeleton(n)

The n-skeleton of this simplicial complex: the simplicial complex obtained by discarding all of the simplices in dimensions larger than n.

INPUT:

  • n - non-negative integer

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)}
product(right, rename_vertices=True)

The product of this simplicial complex with another one.

INPUT:

  • right - the other simplicial complex (the right-hand factor)

  • rename_vertices – boolean (optional, default True). If

    this is False, then the vertices in the product are the set of ordered pairs (v,w) where v is a vertex in self and w 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 (v,w) where v is a vertex in self and w 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_face(face)

Remove a face from this simplicial complex

INPUT:

  • face - a face of the simplicial complex

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)}
stanley_reisner_ring(base_ring=Integer Ring)

The Stanley-Reisner ring of this simplicial complex.

INPUT:

  • base_ring - a commutative ring (optional, default ZZ)

OUTPUT:

  • a quotient of a polynomial algebra with coefficients in base_ring, with one generator for each vertex in the simplicial complex, by the ideal generated by the products of those vertices which do not form faces in it.

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)            
suspension(n=1)

The suspension of this simplicial complex.

INPUT:

  • n - positive integer (optional, default 1): suspend this many times.

The suspension is the simplicial complex formed by adding two new vertices S_0 and S_1 and simplices of the form [S_0,
v_0, ..., v_k] and [S_1, v_0, ..., v_k] for every simplex [v_0, ..., v_k] 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}
vertices()

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'>
sage.homology.simplicial_complex.lattice_paths(t1, t2)

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:

  • t1, t2 - tuples, lists, other iterables.

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)]]

Previous topic

Homology of Simplicial Complexes

Next topic

Chain complexes

This Page