---
title: "Handbook of Magma Functions, Part XVIII: Topology"
version: "2.30-1"
canonical: "https://docs.magma-maths.org/Topology/index-topology.html"
---

# Topology

- [Simplicial Homology](https://docs.magma-maths.org/Topology/SimplicialHomology/index-simplicial-homology.md): Finite simplicial complexes, construction, and homology computation.

<a id="simplicial"></a>
<a id="smpcpx-chap"></a>
## Simplicial Homology

- [Introduction](https://docs.magma-maths.org/Topology/SimplicialHomology/introduction.md)
- [Simplicial Complexes](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md)
  - [`SimplicialComplex(f): SeqEnum[SetEnum] → SmpCpx`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#function-simplicialcomplex-seqenum-setenum)
  - [Example: Constructing a Simplicial Complex](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#example-ex-083856)
  - [`SimplicialComplex(G): Grph → SmpCpx`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#function-simplicialcomplex-grph)
  - [`FlagComplex(G): Grph → SmpCpx`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#function-flagcomplex-grph)
  - [`CliqueComplex(G): Grph → SmpCpx`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#function-cliquecomplex-grph)
  - [`Dimension(X): SmpCpx → RngIntElt`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#function-dimension-smpcpx)
  - [Example: Dimension of a Simplicial Complex](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#example-ex-cb69ff)
  - [`Faces(X, d): SmpCpx, RngIntElt → SeqEnum[SetEnum]`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#function-faces-smpcpx-rngintelt)
  - [Example: Faces of a Simplicial Complex](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#example-ex-36668a)
  - [`Facets(X): SmpCpx → SeqEnum[SetEnum]`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#function-facets-smpcpx)
  - [Example: Facets of a Simplicial Complex](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#example-ex-4ea384)
  - [`Normalization(X): SmpCpx → SmpCpx`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#function-smpcpx-normalization)
  - [`Normalization(~X): SmpCpx`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#procedure-normalization-smpcpx-ref)
  - [`Shift(X, n): SmpCpx, RngIntElt → SmpCpx`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#function-shift-smpcpx-rngintelt)
  - [`Shift(~X, n): SmpCpx, RngIntElt`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#procedure-shift-smpcpx-rngintelt-ref)
  - [Example: Normalizing and Shifting Labels](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#example-ex-0f49fd)
  - [`Boundary(X): SmpCpx → SmpCpx`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#function-boundary-smpcpx)
  - [Example: Boundary of a Simplicial Complex](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#example-ex-c50a0b)
  - [`S + T: SmpCpx, SmpCpx → SmpCpx`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#operation-op-plus-smpcpx-smpcpx)
  - [Example: Disjoint Union of Two Circles](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#example-ex-48ad79)
  - [`S eq T: SmpCpx, SmpCpx → BoolElt`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#operation-op-eq-smpcpx-smpcpx)
  - [Example: Equality of Simplicial Complexes](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#example-ex-4ee2fb)
  - [`Product(S, T): SmpCpx, SmpCpx → SmpCpx`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#function-product-smpcpx-smpcpx)
  - [Example: Torus as a Product of Circles](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#example-ex-80e5c8)
  - [`Join(S, T): SmpCpx, SmpCpx → SmpCpx`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#function-join-smpcpx-smpcpx)
  - [`S * T: SmpCpx, SmpCpx → SmpCpx`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#operation-op-times-smpcpx-smpcpx)
  - [Example: Join of Two Edges](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#example-ex-b9ce13)
  - [`AddSimplex(X, s): SmpCpx, SetEnum → SmpCpx`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#function-addsimplex-smpcpx-setenum)
  - [`AddSimplex(~X, s): SmpCpx, SetEnum`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#procedure-addsimplex-smpcpx-setenum-ref)
  - [`AddSimplex(X, s): SmpCpx, SeqEnum → SmpCpx`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#function-addsimplex-smpcpx-seqenum)
  - [`AddSimplex(~X, s): SmpCpx, SeqEnum`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#procedure-addsimplex-smpcpx-seqenum-ref)
  - [`Prune(X, f): SmpCpx, SetEnum → SmpCpx`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#function-prune-smpcpx-setenum)
  - [`Prune(~X, f): SmpCpx, SetEnum`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#procedure-prune-smpcpx-setenum-ref)
  - [`Glue(X, e): SmpCpx, SeqEnum → SmpCpx`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#function-glue-smpcpx-seqenum)
  - [`Glue(~X, e): SmpCpx, SeqEnum`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#procedure-glue-smpcpx-seqenum-ref)
  - [Example: Connected Sum of Two Tori](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#example-ex-ecfc35)
  - [`BarycentricSubdivision(X): SmpCpx → SmpCpx`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#function-barycentricsubdivision-smpcpx)
  - [`Skeleton(X, q): SmpCpx, RngIntElt → SmpCpx`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#function-skeleton-smpcpx-rngintelt)
  - [`UnderlyingGraph(X): SmpCpx → GrphUnd, GrphVertSet, GrphEdgeSet`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#function-underlyinggraph-smpcpx)
  - [`Cone(X): SmpCpx → SmpCpx`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#function-cone-smpcpx)
  - [`Suspension(X): SmpCpx → SmpCpx`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#function-suspension-smpcpx)
  - [Example: Cone and Suspension](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#example-ex-d8fe8c)
  - [Standard Topological Objects](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#standard-topological-objects)
    - [`Simplex(n): RngIntElt → SmpCpx`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#function-simplex-rngintelt)
    - [`Sphere(n): RngIntElt → SmpCpx`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#function-sphere-rngintelt)
    - [`KleinBottle() → SmpCpx`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#function-kleinbottle)
    - [`Torus() → SmpCpx`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#function-torus)
    - [`Cylinder() → SmpCpx`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#function-cylinder)
    - [`MoebiusStrip() → SmpCpx`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#function-moebiusstrip)
    - [`LensSpace(p): RngIntElt → SmpCpx`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#function-lensspace-rngintelt)
    - [`SimplicialProjectivePlane() → SmpCpx`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#function-simplicialprojectiveplane)
- [Homology Computation](https://docs.magma-maths.org/Topology/SimplicialHomology/homology-computation.md)
  - [`Homology(X): SmpCpx → SeqEnum, SeqEnum`](https://docs.magma-maths.org/Topology/SimplicialHomology/homology-computation.md#function-homology-smpcpx)
  - [`Homology(~X): SmpCpx`](https://docs.magma-maths.org/Topology/SimplicialHomology/homology-computation.md#procedure-homology-smpcpx-ref)
  - [`Homology(X, A): SmpCpx, Rng → SeqEnum, SeqEnum`](https://docs.magma-maths.org/Topology/SimplicialHomology/homology-computation.md#function-homology-smpcpx-rng)
  - [`Homology(~X, A): SmpCpx, Rng`](https://docs.magma-maths.org/Topology/SimplicialHomology/homology-computation.md#procedure-homology-smpcpx-rng-ref)
  - [Example: Homology of a Simplicial Complex](https://docs.magma-maths.org/Topology/SimplicialHomology/homology-computation.md#example-ex-a2198f)
  - [`HomologyGroup(X, q): SmpCpx, RngIntElt → ModRng`](https://docs.magma-maths.org/Topology/SimplicialHomology/homology-computation.md#function-homologygroup-smpcpx-rngintelt)
  - [`HomologyGroup(X, q, A): SmpCpx, RngIntElt, Rng → ModRng`](https://docs.magma-maths.org/Topology/SimplicialHomology/homology-computation.md#function-homologygroup-smpcpx-rngintelt-rng)
  - [`BettiNumber(X, q): SmpCpx, RngIntElt → RngIntElt`](https://docs.magma-maths.org/Topology/SimplicialHomology/homology-computation.md#function-bettinumber-smpcpx-rngintelt)
  - [`BettiNumber(X, q, A): SmpCpx, RngIntElt, Rng → RngIntElt`](https://docs.magma-maths.org/Topology/SimplicialHomology/homology-computation.md#function-bettinumber-smpcpx-rngintelt-rng)
  - [`TorsionCoefficients(X, q): SmpCpx, RngIntElt → SeqEnum[RngElt]`](https://docs.magma-maths.org/Topology/SimplicialHomology/homology-computation.md#function-torsioncoefficients-smpcpx-rngintelt)
  - [`TorsionCoefficients(X, q, A): SmpCpx, RngIntElt, Rng → SeqEnum[RngElt]`](https://docs.magma-maths.org/Topology/SimplicialHomology/homology-computation.md#function-torsioncoefficients-smpcpx-rngintelt-rng)
  - [`EulerCharacteristic(X): SmpCpx → RngIntElt`](https://docs.magma-maths.org/Topology/SimplicialHomology/homology-computation.md#function-eulercharacteristic-smpcpx)
  - [`BoundaryMatrix(X, q, A): SmpCpx, RngIntElt, Rng → Mtrx`](https://docs.magma-maths.org/Topology/SimplicialHomology/homology-computation.md#function-boundarymatrix-smpcpx-rngintelt-rng)
  - [`ChainComplex(X, A): SmpCpx, Rng → ModCpx`](https://docs.magma-maths.org/Topology/SimplicialHomology/homology-computation.md#function-chaincomplex-smpcpx-rng)
  - [Example: Chain Complex of a Simplicial Complex](https://docs.magma-maths.org/Topology/SimplicialHomology/homology-computation.md#example-ex-dacb67)
  - [`HomologyGenerators(X): SmpCpx`](https://docs.magma-maths.org/Topology/SimplicialHomology/homology-computation.md#procedure-homologygenerators-smpcpx)
  - [`HomologyGenerators(X, A): SmpCpx, Rng`](https://docs.magma-maths.org/Topology/SimplicialHomology/homology-computation.md#procedure-homologygenerators-smpcpx-rng)
  - [`HomologyGenerators(H, M, X): SeqEnum, SeqEnum, SmpCpx`](https://docs.magma-maths.org/Topology/SimplicialHomology/homology-computation.md#procedure-homologygenerators-seqenum-seqenum-smpcpx)
  - [Example: Homology Generators](https://docs.magma-maths.org/Topology/SimplicialHomology/homology-computation.md#example-ex-1e8d54)
- [Bibliography](https://docs.magma-maths.org/Topology/SimplicialHomology/bibliography.md)

### Introduction

This chapter presents the category of finite simplicial complexes.

We define an abstract simplicial complex $K$ to be a subset of the power set of some set $V$ of vertices, with the property that if $S\in K$ and $T\subset S$ then $T\in K$.

For detailed reading on simplicial complexes and their homology, we refer to [[Hat02](https://docs.magma-maths.org/references.md#cite-hatcher02)] and [[Arm83](https://docs.magma-maths.org/references.md#cite-armstrong83)].

Simplicial complexes may be defined over any `SetEnum`, however, many of the construction methods operate over `SetEnum[RngIntElt]`. The handbook refers to such simplicial complexes as *normalized*.

A simplicial complex carries the category name `SmpCpx`. Constructors and package internal functions guarantee that the closure under subsets relation is kept intact.

### Simplicial Complexes

The module supports creation of simplicial complexes from lists of faces, as well as a few preprogrammed complex types. Furthermore, several standard techniques for modifying and recombining simplicial complexes are available.

<a id="function-simplicialcomplex-seqenum-setenum"></a>
#### `SimplicialComplex(f): SeqEnum[SetEnum] -> SmpCpx`

Constructs an abstract simplicial complex with the faces in the list $f$. The argument should be a sequence of sets. There is no requirement on the type of the elements in the face sets, however several of the constructions require the sets to have integer entries. See [`Normalization`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#function-smpcpx-normalization) for automated renumbering of the face set elements.

<a id="example-ex-083856"></a>
#### `Example: Constructing a Simplicial Complex (ex-083856)`

We give a simplicial complex by listing the facets, or also redundant faces if we want to.

```magma
> sc := SimplicialComplex([{1,2,3},{1,2,4},{1,3,4},{2,3,4},{1,5},{2,5}]);
```

We can view the facets (faces not included in any other faces) of the complex, or by giving the `:Maximal` output flag, we can view all faces.

```magma
> sc;
Simplicial complex
[
    { 2, 3, 4 },
    { 1, 2, 3 },
    { 1, 2, 4 },
    { 2, 5 },
    { 1, 5 },
    { 1, 3, 4 }
]

> sc:Maximal;
Simplicial complex
{
    {},
    { 4 },
    { 2, 3, 4 },
    { 2, 3 },
    { 3, 4 },
    { 1, 3 },
    { 3 },
    { 1 },
    { 1, 4 },
    { 1, 2, 3 },
    { 2 },
    { 1, 2 },
    { 1, 2, 4 },
    { 2, 5 },
    { 1, 5 },
    { 5 },
    { 2, 4 },
    { 1, 3, 4 }
}
```

<a id="function-simplicialcomplex-grph"></a>
#### `SimplicialComplex(G): Grph -> SmpCpx`

Constructs a 1-dimensional simplicial complex isomorphic to the graph $G$.

<a id="function-flagcomplex-grph"></a>
#### `FlagComplex(G): Grph -> SmpCpx`

<a id="function-cliquecomplex-grph"></a>
#### `CliqueComplex(G): Grph -> SmpCpx`

Constructs a simplicial complex with an $n$-simplex for each $n$-clique in the graph $G$.

<a id="function-dimension-smpcpx"></a>
#### `Dimension(X): SmpCpx -> RngIntElt`

Returns the dimension of the highest dimensional face of the simplicial complex $X$. Note that there is a difference between degrees and dimensions of faces. A face is said to have degree $n$ if there are $n$ elements in the face as a set, and it is said to have dimension $n$ if there are $n+1$ elements in the face as a set.

<a id="example-ex-cb69ff"></a>
#### `Example: Dimension of a Simplicial Complex (ex-cb69ff)`

The recently defined simplicial complex has top dimension 2.

```magma
> Dimension(sc);
2
```

<a id="function-faces-smpcpx-rngintelt"></a>
#### `Faces(X, d): SmpCpx, RngIntElt -> SeqEnum[SetEnum]`

Returns the faces of one degree $d$ of the simplicial complex $X$. Recall that the degree of a face is the number of elements in the face as a set, and one more than the dimension of the face.

The order of faces returned for each degree is also the correspondence between faces and the basis of the corresponding module in a chain complex constructed from the simplicial complex.

If the complex does not possess any faces of the requested degree, an empty sequence is returned.

<a id="example-ex-36668a"></a>
#### `Example: Faces of a Simplicial Complex (ex-36668a)`

We can list faces of any degree in the defined simplicial complex.

```magma
> Faces(sc,2);
[
    { 2, 3 },
    { 3, 4 },
    { 1, 3 },
    { 1, 4 },
    { 1, 2 },
    { 2, 5 },
    { 1, 5 },
    { 2, 4 }
]
> Faces(sc,5);
[]
```

<a id="function-facets-smpcpx"></a>
#### `Facets(X): SmpCpx -> SeqEnum[SetEnum]`

Returns the facets of the simplicial complex $X$. The facets of a simplicial complex are the faces that are not themselves subsets of another face. This is what the normal printing mode for a simplicial complex outputs.

<a id="example-ex-4ea384"></a>
#### `Example: Facets of a Simplicial Complex (ex-4ea384)`

We can read the facets both by fetching the sequence of facets and by printing the complex as such.

```magma
> Facets(sc);
[
    { 2, 3, 4 },
    { 1, 2, 3 },
    { 1, 2, 4 },
    { 2, 5 },
    { 1, 5 },
    { 1, 3, 4 }
]
> sc;
Simplicial complex
[
    { 2, 3, 4 },
    { 1, 2, 3 },
    { 1, 2, 4 },
    { 2, 5 },
    { 1, 5 },
    { 1, 3, 4 }
]
```

<a id="function-smpcpx-normalization"></a>
#### `Normalization(X): SmpCpx -> SmpCpx`

<a id="procedure-normalization-smpcpx-ref"></a>
#### `Normalization(~X): SmpCpx`

Relabels the points (elements of the face sets) of the simplicial complex $X$ using $1,2,3,\ldots$. This ensures that the simplicial complex is built on subsets of the integers, which is a prerequisite for several functions handling simplicial complexes. We call a simplicial complex on subsets of the integers *normalized* in this handbook.

Note the two calling signatures of this function. The first signature copies the simplicial complex and returns a new complex with the desired modification, whereas the second signature modifies the complex in place.

<a id="function-shift-smpcpx-rngintelt"></a>
#### `Shift(X, n): SmpCpx, RngIntElt -> SmpCpx`

<a id="procedure-shift-smpcpx-rngintelt-ref"></a>
#### `Shift(~X, n): SmpCpx, RngIntElt`

Shifts all integer points in the normalized simplicial complex $X$ by an offset given by $n$.

Note the two calling signatures of this function. The first signature copies the simplicial complex and returns a new complex with the desired modification, whereas the second signature modifies the complex in place.

<a id="example-ex-0f49fd"></a>
#### `Example: Normalizing and Shifting Labels (ex-0f49fd)`

We define a simplicial complex using string labels, normalize it, and then shift the labels.

```magma
> cpx := Boundary(SimplicialComplex([{"a","b","c"}]));
> cpx;
Simplicial complex
[
    { c, a },
    { c, b },
    { b, a }
]

> Normalization(~cpx);
> cpx;
Simplicial complex
[
    { 1, 3 },
    { 2, 3 },
    { 1, 2 }
]

> Shift(~cpx,-2);
> cpx;
Simplicial complex
[
    { -1, 1 },
    { 0, 1 },
    { -1, 0 }
]
```

<a id="function-boundary-smpcpx"></a>
#### `Boundary(X): SmpCpx -> SmpCpx`

Returns the simplicial complex generated by all simplexes that lie in the boundary of the simplicial complex $X$. This can be used to easily acquire a simplicial complex representing the $n$-sphere.

<a id="example-ex-c50a0b"></a>
#### `Example: Boundary of a Simplicial Complex (ex-c50a0b)`

We can determine the boundary of our previously defined simplicial complex, or construct a 4-sphere.

```magma
> Boundary(sc);
Simplicial complex
[
    { 2, 3 },
    { 3, 4 },
    { 1, 3 },
    { 1, 4 },
    { 1, 2 },
    { 5 },
    { 2, 4 }
]
> sph4 := Boundary(SimplicialComplex([{1,2,3,4,5,6}]));
> sph4;
Simplicial complex
[
    { 1, 2, 3, 5, 6 },
    { 2, 3, 4, 5, 6 },
    { 1, 3, 4, 5, 6 },
    { 1, 2, 3, 4, 5 },
    { 1, 2, 4, 5, 6 },
    { 1, 2, 3, 4, 6 }
]
```

<a id="operation-op-plus-smpcpx-smpcpx"></a>
#### `S + T: SmpCpx, SmpCpx -> SmpCpx`

Returns the topological sum, or disjoint union, of two simplicial complexes. Requires both complexes to be normalized using [`Normalization`](https://docs.magma-maths.org/Topology/SimplicialHomology/simplicial-complexes.md#function-smpcpx-normalization).

<a id="example-ex-48ad79"></a>
#### `Example: Disjoint Union of Two Circles (ex-48ad79)`

We can construct a disjoint union of two circles.

```magma
> sph2 := Boundary(SimplicialComplex([{1,2,3}]));
> sph2 + sph2;
Simplicial complex
[
    { 4, 6 },
    { 2, 3 },
    { 4, 5 },
    { 5, 6 },
    { 1, 3 },
    { 1, 2 }
]
```

<a id="operation-op-eq-smpcpx-smpcpx"></a>
#### `S eq T: SmpCpx, SmpCpx -> BoolElt`

Compares two simplicial complexes. Will not try to find an isomorphism, rather does the comparison by ensuring that the points are in the same universe and then doing a set comparison on the set of faces.

<a id="example-ex-4ee2fb"></a>
#### `Example: Equality of Simplicial Complexes (ex-4ee2fb)`

Shifting a complex, for instance, will break equality, since the labels differ.

```magma
> sc eq Shift(sc,2);
false
> sc eq Shift(Shift(sc,2),-2);
true
```

Furthermore, isomorphic complexes with different labels will not be equal.

```magma
> circ1 := Boundary(SimplicialComplex([{1,2,3}]));
> circ2 := Boundary(SimplicialComplex([{"a","b","c"}]));
> circ1 eq circ2;
false
```

<a id="function-product-smpcpx-smpcpx"></a>
#### `Product(S, T): SmpCpx, SmpCpx -> SmpCpx`

Returns the cartesian product of two simplicial complexes. This will work on any complexes, since the new points will be pairs of points from the component complexes.

<a id="example-ex-80e5c8"></a>
#### `Example: Torus as a Product of Circles (ex-80e5c8)`

Using the two different circles from the last example, we can now construct a torus.

```magma
> Product(circ1,circ2);
Simplicial complex
[
    { <3, b>, <1, b>, <3, c> },
    { <1, c>, <3, c>, <1, a> },
    { <2, a>, <3, b>, <3, a> },
    { <3, b>, <1, b>, <1, a> },
    { <1, b>, <2, b>, <2, c> },
    { <2, a>, <3, c>, <3, a> },
    { <1, c>, <1, b>, <3, c> },
    { <3, c>, <2, b>, <2, c> },
    { <1, c>, <1, b>, <2, c> },
    { <3, c>, <3, a>, <1, a> },
    { <2, a>, <3, c>, <2, c> },
    { <3, b>, <3, a>, <1, a> },
    { <2, a>, <1, a>, <2, b> },
    { <2, a>, <1, a>, <2, c> },
    { <1, c>, <1, a>, <2, c> },
    { <3, b>, <3, c>, <2, b> },
    { <1, b>, <1, a>, <2, b> },
    { <2, a>, <3, b>, <2, b> }
]
```

If we want something less unwieldy – especially after repeated cartesian products – we can always normalize the resulting complexes.

```magma
> line := SimplicialComplex([{1,2}]);
> square := Product(line,line);
> cube1 := Product(square,line);
> cube2 := Product(line,square);
> cube1 eq cube2;
false
> Normalization(cube1) eq Normalization(cube2);
false
> cube1;
Simplicial complex
[
    { <<1, 2>, 1>, <<1, 2>, 2>, <<1, 1>, 1>, <<2, 2>, 2> },
    { <<2, 1>, 1>, <<2, 2>, 1>, <<1, 1>, 1>, <<2, 2>, 2> },
    { <<1, 2>, 2>, <<1, 1>, 1>, <<1, 1>, 2>, <<2, 2>, 2> },
    { <<1, 2>, 1>, <<2, 2>, 1>, <<1, 1>, 1>, <<2, 2>, 2> },
    { <<1, 1>, 1>, <<1, 1>, 2>, <<2, 1>, 2>, <<2, 2>, 2> },
    { <<2, 1>, 1>, <<1, 1>, 1>, <<2, 1>, 2>, <<2, 2>, 2> }
]
> Normalization(cube1);
Simplicial complex
[
    { 3, 4, 5, 8 },
    { 4, 5, 6, 8 },
    { 1, 3, 4, 5 },
    { 2, 4, 5, 7 },
    { 1, 2, 4, 5 },
    { 4, 5, 6, 7 }
]
```

<a id="function-join-smpcpx-smpcpx"></a>
#### `Join(S, T): SmpCpx, SmpCpx -> SmpCpx`

<a id="operation-op-times-smpcpx-smpcpx"></a>
#### `S * T: SmpCpx, SmpCpx -> SmpCpx`

Constructs the join of two simplicial complexes. The join of two simplicial complexes is defined as the complex generated by faces on the form $\{x_1,\dots,x_r,y_1,\dots,y_s\}$ for $\{x_1,\dots,x_r\}\in S$ and $\{y_1,\dots,y_s\}\in T$. Requires both simplicial complexes to be normalized.

<a id="example-ex-b9ce13"></a>
#### `Example: Join of Two Edges (ex-b9ce13)`

The join of two edges is a 3-simplex.

```magma
> SimplicialComplex([{1,2}]) * SimplicialComplex([{1,2}]);
Simplicial complex
[
    { 1, 2, 3, 4 }
]
```

<a id="function-addsimplex-smpcpx-setenum"></a>
#### `AddSimplex(X, s): SmpCpx, SetEnum -> SmpCpx`

<a id="procedure-addsimplex-smpcpx-setenum-ref"></a>
#### `AddSimplex(~X, s): SmpCpx, SetEnum`

<a id="function-addsimplex-smpcpx-seqenum"></a>
#### `AddSimplex(X, s): SmpCpx, SeqEnum -> SmpCpx`

<a id="procedure-addsimplex-smpcpx-seqenum-ref"></a>
#### `AddSimplex(~X, s): SmpCpx, SeqEnum`

Adds either a single simplex $s$ expressed as a set or a sequence of simplexes to a simplicial complex. The functional versions of the function call return a new complex with the added simplices included, and the procedural change the complex in place.

<a id="function-prune-smpcpx-setenum"></a>
#### `Prune(X, f): SmpCpx, SetEnum -> SmpCpx`

<a id="procedure-prune-smpcpx-setenum-ref"></a>
#### `Prune(~X, f): SmpCpx, SetEnum`

Removes a face $f$ and all faces containing $f$ from a simplicial complex $X$. If $f$ is not a face of $X$, then $X$ is returned unchanged.

Note the two calling signatures of this function. The first signature copies the simplicial complex and returns a new complex with the desired modification, whereas the second signature modifies the complex in place.

<a id="function-glue-smpcpx-seqenum"></a>
#### `Glue(X, e): SmpCpx, SeqEnum -> SmpCpx`

<a id="procedure-glue-smpcpx-seqenum-ref"></a>
#### `Glue(~X, e): SmpCpx, SeqEnum`

In the simplicial complex $X$, identify all points identified by pairs in the sequence $e$.

The sequence $e$ should be a sequence of pairs of elements of the face sets of $X$. The identification will eliminate the first component of each pair, replacing it with the second component wherever it occurs in $X$.

Note the two calling signatures of this function. The first signature copies the simplicial complex and returns a new complex with the desired modification, whereas the second signature modifies the complex in place.

<a id="example-ex-ecfc35"></a>
#### `Example: Connected Sum of Two Tori (ex-ecfc35)`

We can, for instance, construct the connected sum of two tori using `Product`, `Prune`, the topological sum, and `Glue`.

```magma
> circ := SimplicialComplex([{1,2},{2,3},{3,1}]);
> torus := Product(circ,circ);
> Normalization(~torus);
> torus;
Simplicial complex
[
    { 2, 3, 6 },
    { 1, 2, 9 },
    { 2, 6, 8 },
    { 4, 7, 8 },
    { 3, 5, 9 },
    { 4, 6, 7 },
    { 1, 8, 9 },
    { 1, 4, 8 },
    { 6, 8, 9 },
    { 2, 7, 8 },
    { 2, 3, 9 },
    { 5, 6, 9 },
    { 1, 3, 5 },
    { 1, 4, 6 },
    { 3, 6, 7 },
    { 1, 5, 6 },
    { 1, 2, 7 },
    { 1, 3, 7 }
]

> oneholetorus := Prune(torus,{1,2,7});
> twoholetorus := Prune(Prune(torus,{1,2,7}),{6,8,9});
> threetori := oneholetorus + twoholetorus + oneholetorus;
> threetorus := Glue(threetori,[<1,10>,<2,11>,<7,16>,<15,19>,<17,20>,<18,25>]);
```

Note that we find the glue data by considering that the maximal point in the original torus had number $9$, so for the second added torus, all points will be shifted by $9$ and in the third all points will be shifted by $18$. Thus, the excised facets $\{1,2,7\}$ and $\{6,8,9\}$ turn into $\{10,11,16\}$ and $\{15,17,18\}$, and the excised facet $\{1,2,7\}$ in the third torus turns into $\{19,20,25\}$.

<a id="function-barycentricsubdivision-smpcpx"></a>
#### `BarycentricSubdivision(X): SmpCpx -> SmpCpx`

Constructs the barycentric subdivision of the simplicial complex $X$. Abstractly, this is a simplicial complex whose faces are chains $X_1 \subset \dots \subset X_n$ of faces from $X$. The new complex has more faces but the same homotopy type as the old complex.

<a id="function-skeleton-smpcpx-rngintelt"></a>
#### `Skeleton(X, q): SmpCpx, RngIntElt -> SmpCpx`

Returns the $q$-skeleton of the simplicial complex $X$. This is the complex consisting of all faces of $X$ of dimension at most $q$.

<a id="function-underlyinggraph-smpcpx"></a>
#### `UnderlyingGraph(X): SmpCpx -> GrphUnd, GrphVertSet, GrphEdgeSet`

Constructs a graph isomorphic, as a graph, to the 1-skeleton of the simplicial complex $X$.

<a id="function-cone-smpcpx"></a>
#### `Cone(X): SmpCpx -> SmpCpx`

Constructs a cone over the simplicial complex $X$. The cone is generated by all faces of the complex, with an additional vertex included into each face. Any cone is acyclic, in other words all homology groups vanish. Requires a normalized simplicial complex.

<a id="function-suspension-smpcpx"></a>
#### `Suspension(X): SmpCpx -> SmpCpx`

Constructs the suspension, or double cone, over the normalized simplicial complex $X$. The suspension has the added property that all the homology groups occur in it, shifted up by one dimension.

<a id="example-ex-d8fe8c"></a>
#### `Example: Cone and Suspension (ex-d8fe8c)`

For computation of the relevant homology, and a demonstration of the stated facts about the cone and suspension operations, please refer to examples in the Section on homology computation.

```magma
> circ := Boundary(SimplicialComplex([{1,2,3}]));
> Cone(circ);
Simplicial complex
[
    { 1, 3, 4 },
    { 2, 3, 4 },
    { 1, 2, 4 }
]

> Suspension(circ);
Simplicial complex
[
    { 1, 3, 5 },
    { 1, 3, 4 },
    { 1, 2, 5 },
    { 2, 3, 4 },
    { 1, 2, 4 },
    { 2, 3, 5 }
]
```

#### Standard Topological Objects

<a id="function-simplex-rngintelt"></a>
##### `Simplex(n): RngIntElt -> SmpCpx`

Returns the $n$-dimensional simplex as a simplicial complex.

<a id="function-sphere-rngintelt"></a>
##### `Sphere(n): RngIntElt -> SmpCpx`

Returns a simplicial complex triangulating the $n$-sphere.

<a id="function-kleinbottle"></a>
##### `KleinBottle() -> SmpCpx`

Returns a triangulation of the Klein bottle as an abstract simplicial complex.

<a id="function-torus"></a>
##### `Torus() -> SmpCpx`

Returns a triangulation of a torus as an abstract simplicial complex.

<a id="function-cylinder"></a>
##### `Cylinder() -> SmpCpx`

Returns a triangulation of a cylinder as an abstract simplicial complex.

<a id="function-moebiusstrip"></a>
##### `MoebiusStrip() -> SmpCpx`

Returns a triangulation of the Moebius strip as an abstract simplicial complex.

<a id="function-lensspace-rngintelt"></a>
##### `LensSpace(p): RngIntElt -> SmpCpx`

Constructs the lens space $L(p,1)$. This has a 1-dimensional homology generator of order $p$.

<a id="function-simplicialprojectiveplane"></a>
##### `SimplicialProjectivePlane() -> SmpCpx`

Constructs a triangulation of the projective plane.

Examples for the usage of `LensSpace` and `SimplicialProjectivePlane` will be given in Section [Homology Computation](https://docs.magma-maths.org/Topology/SimplicialHomology/homology-computation.md#hom-comp) on homology computation.

<a id="hom-comp"></a>
<a id="id1"></a>
### Homology Computation

The code computes exclusively reduced homology of the given simplicial complexes. If you want the non-reduced homology, just add a single free rank to dimension 0 and let it be generated by any single point in the complex.

<a id="function-homology-smpcpx"></a>
#### `Homology(X): SmpCpx -> SeqEnum, SeqEnum`

<a id="procedure-homology-smpcpx-ref"></a>
#### `Homology(~X): SmpCpx`

<a id="function-homology-smpcpx-rng"></a>
#### `Homology(X, A): SmpCpx, Rng -> SeqEnum, SeqEnum`

<a id="procedure-homology-smpcpx-rng-ref"></a>
#### `Homology(~X, A): SmpCpx, Rng`

Calculates the reduced homology of a simplicial complex `X` with coefficients in the ring $A$. The procedural form of this command caches the results of the calculation in the simplicial complex object. If no ring is given, then the function defaults to integer coefficients.

<a id="example-ex-a2198f"></a>
#### `Example: Homology of a Simplicial Complex (ex-a2198f)`

The resulting modules are stored in falling dimension, always including the dimension $-1$ vanishing homology module at the very end.

```magma
> circ := Boundary(SimplicialComplex([{1,2,3}]));
> Homology(circ,Integers());
[
    Full Quotient RSpace of degree 1 over Integer Ring
    Column moduli:
    [ 0 ],

    Full Quotient RSpace of degree 0 over Integer Ring
    Column moduli:
    [ ],

    Full Quotient RSpace of degree 0 over Integer Ring
    Column moduli:
    [ ]
]
[
    Mapping from: RSpace of degree 3, dimension 1 over Integer Ring to Full
    Quotient RSpace of degree 1 over Integer Ring
    Column moduli:
    [ 0 ],
    Mapping from: RSpace of degree 3, dimension 2 over Integer Ring to Full
    Quotient RSpace of degree 0 over Integer Ring
    Column moduli:
    [ ],
    Mapping from: Full RSpace of degree 1 over Integer Ring to Full Quotient
    RSpace of degree 0 over Integer Ring
    Column moduli:
    [ ]
]
> lens3 := LensSpace(3);
> Homology(~lens3,Integers());
> Homology(lens3,Integers())[3];
Full Quotient RSpace of degree 1 over Integer Ring
Column moduli:
[ 3 ]
```

<a id="function-homologygroup-smpcpx-rngintelt"></a>
#### `HomologyGroup(X, q): SmpCpx, RngIntElt -> ModRng`

<a id="function-homologygroup-smpcpx-rngintelt-rng"></a>
#### `HomologyGroup(X, q, A): SmpCpx, RngIntElt, Rng -> ModRng`

Calculates and returns the $q$th homology group of $X$ with coefficients in $A$. If no ring is given, the function defaults to integer coefficients. If the homology is cached in $X$, the cached results are returned. This function will not compute the entire homology in order to return one homology group.

<a id="function-bettinumber-smpcpx-rngintelt"></a>
#### `BettiNumber(X, q): SmpCpx, RngIntElt -> RngIntElt`

<a id="function-bettinumber-smpcpx-rngintelt-rng"></a>
#### `BettiNumber(X, q, A): SmpCpx, RngIntElt, Rng -> RngIntElt`

Returns the $q$th Betti number, computed as the free rank of the $q$-dimensional homology group, with coefficients in $A$. If no ring is given, then the function will default to integer coefficients.

Note that the Betti number computations compensate for the homology computations being reduced. Thus, `BettiNumber(X,0) eq Rank(HomologyGroup(X,0)) + 1`.

<a id="function-torsioncoefficients-smpcpx-rngintelt"></a>
#### `TorsionCoefficients(X, q): SmpCpx, RngIntElt -> SeqEnum[RngElt]`

<a id="function-torsioncoefficients-smpcpx-rngintelt-rng"></a>
#### `TorsionCoefficients(X, q, A): SmpCpx, RngIntElt, Rng -> SeqEnum[RngElt]`

Returns the torsion coefficients of the $q$th homology group of $X$ with coefficients in $A$. If no ring is given, then the function will default to integer coefficients.

<a id="function-eulercharacteristic-smpcpx"></a>
#### `EulerCharacteristic(X): SmpCpx -> RngIntElt`

Computes the Euler characteristic of the complex. If homology is cached, this is used for computation, and else the characteristic is computed using the ranks of the chain groups.

<a id="function-boundarymatrix-smpcpx-rngintelt-rng"></a>
#### `BoundaryMatrix(X, q, A): SmpCpx, RngIntElt, Rng -> Mtrx`

Returns the $q$th boundary matrix of the corresponding chain complex to the simplicial complex $X$ with coefficients in $A$.

<a id="function-chaincomplex-smpcpx-rng"></a>
#### `ChainComplex(X, A): SmpCpx, Rng -> ModCpx`

Constructs a reduced chain complex of free A-modules corresponding to the abstract simplicial complex $X$.

Note that the produced complex includes one extra rank 1 module on each end, with the zero map leading to it, to simulate the maps to and from the zero module that would end a chain complex constructed from a simplicial complex in ordinary cases.

<a id="example-ex-dacb67"></a>
#### `Example: Chain Complex of a Simplicial Complex (ex-dacb67)`

```magma
> ChainComplex(SimplicialComplex([{1}]),Integers());
Chain complex with terms of degree 2 down to -1
Dimensions of terms: 1 1 1 1
> BoundaryMaps(ChainComplex(SimplicialComplex([{1}]),Integers()));
[*
    [0],

    [-1],

    [0]
*]
> ChainComplex(SimplicialComplex([{1,2,3}]),GF(3));
Chain complex with terms of degree 4 down to -1
Dimensions of terms: 1 1 3 3 1 1
> BoundaryMaps(ChainComplex(SimplicialComplex([{1,2,3}]),GF(3)));
[*
    [0],

    [1 2 2],

    [1 0 2]
    [0 1 2]
    [1 2 0],

    [2]
    [2]
    [2],

    [0]
*]
```

<a id="procedure-homologygenerators-smpcpx"></a>
#### `HomologyGenerators(X): SmpCpx`

<a id="procedure-homologygenerators-smpcpx-rng"></a>
#### `HomologyGenerators(X, A): SmpCpx, Rng`

<a id="procedure-homologygenerators-seqenum-seqenum-smpcpx"></a>
#### `HomologyGenerators(H, M, X): SeqEnum, SeqEnum, SmpCpx`

Prints generators of the homology groups of the simplicial complex $X$ with coefficients in $A$ together with their order, in order of dimension. The latter calling form expects $H,M$ to be the result from `H,M := ChainComplex(A,smp);`. This function will recalculate homology each time unless the homology is already cached in the simplicial complex using `Homology(A, smp)`.

If no ring is given, the function defaults to integer coefficients.

<a id="example-ex-1e8d54"></a>
#### `Example: Homology Generators (ex-1e8d54)`

This function gives a condensed form of the actual bases of the homology groups, as well as mappings back to an actual chain representative for each homology class.

```magma
> HomologyGenerators(threetorus,Integers());

*** dimension 2 ***
inf: { 21, 23, 27 } - { 4, 6, 16 } - { 20, 24, 26 } + { 20, 25, 26 } -
  { 14, 19, 25 } + { 12, 14, 25 } + { 3, 6, 11 } - { 10, 14, 19 } +
  { 19, 20, 27 } - { 3, 9, 11 } - { 10, 13, 20 } + { 10, 13, 19 } -
  { 10, 12, 14 } - { 12, 16, 19 } - { 11, 19, 20 } - { 13, 16, 20 } +
  { 21, 24, 25 } + { 24, 26, 27 } - { 20, 21, 24 } - { 19, 22, 26 } -
  { 3, 10, 16 } - { 4, 6, 10 } - { 22, 25, 26 } + { 11, 16, 20 } +
  { 4, 8, 16 } - { 5, 6, 9 } + { 4, 8, 10 } - { 11, 12, 19 } - { 3, 5, 9 } +
  { 11, 12, 25 } + { 8, 9, 10 } + { 20, 21, 27 } + { 3, 6, 16 } +
  { 10, 11, 25 } + { 19, 22, 24 } - { 9, 10, 11 } + { 3, 5, 10 } +
  { 10, 20, 25 } - { 8, 11, 16 } - { 19, 26, 27 } - { 19, 23, 24 } +
  { 10, 12, 16 } - { 19, 21, 23 } - { 6, 8, 9 } + { 13, 16, 19 } +
  { 19, 21, 25 } + { 23, 24, 27 } - { 22, 24, 25 } + { 5, 6, 10 } +
  { 6, 8, 11 }


*** dimension 1 ***
inf: -1*{ 10, 13 } + { 3, 5 } - { 8, 9 } - { 8, 16 } - { 19, 22 } +
  { 20, 26 } + { 9, 11 } - { 3, 16 } + { 5, 10 } + { 22, 26 } + { 11, 20 } +
  2*{ 10, 20 } + { 13, 19 } - 2*{ 10, 11 }

inf: { 3, 9 } - { 3, 5 } - { 9, 11 } - { 5, 10 } + { 10, 11 }

inf: -1*{ 26, 27 } - { 11, 19 } + 2*{ 19, 22 } - { 20, 26 } -
  2*{ 22,  26 } + { 11, 20 } + { 19, 21 } - { 21, 27 }

inf: { 10, 13 } + { 11, 19 } - { 11, 20 } - { 10, 20 } - { 13, 19 }

inf: -1*{ 11, 19 } + { 19, 22 } - { 20, 26 } - { 22, 26 } + { 11, 20 }

inf: { 11, 20 } + { 10, 20 } - { 10, 11 }
```

The six found generators are the generators of each of the contained torus homology groups.

Notice that each generator is printed out with a prefix. This gives the order of the generator - so that for instance torsion elements of homology may be recognized. Thus, we see with the projective plane:

```magma
> HomologyGenerators(SimplicialProjectivePlane(),Integers());

*** dimension 1 ***
  2: { 3, 6 } + { 2, 3 } - { 2, 6 }
```

We can further take this opportunity to verify the claims about `Cone` and `Suspension` with regard to the homology.

```magma
> HomologyGenerators(Cone(SimplicialProjectivePlane()),Integers());
Complex is acyclic.

> HomologyGenerators(Suspension(SimplicialProjectivePlane()),Integers());

*** dimension 2 ***
  2: { 1, 5, 7 } - { 1, 4, 7 } + { 1, 2, 5 } + { 1, 5, 8 } - { 2, 3, 8 } -
  { 3, 5, 7 } - { 1, 2, 8 } + { 5, 6, 8 } + { 1, 4, 5 } - { 4, 6, 8 } +
  { 3, 4, 7 } + { 2, 3, 5 } - { 4, 5, 6 } - { 3, 4, 8 }
```
