Regina 7.3 Calculation Engine
Public Member Functions | Static Public Member Functions | Static Public Attributes | Protected Member Functions | Protected Attributes | List of all members
regina::Triangulation< 4 > Class Reference

Represents a 4-dimensional triangulation, typically of a 4-manifold. More...

#include <triangulation/dim4.h>

Inheritance diagram for regina::Triangulation< 4 >:
regina::detail::TriangulationBase< 4 > regina::Snapshottable< Triangulation< dim > > regina::PacketData< Triangulation< dim > > regina::Output< Triangulation< dim > > regina::TightEncodable< Triangulation< dim > >

Public Member Functions

bool isReadOnlySnapshot () const
 Determines if this object is a read-only deep copy that was created by a snapshot. More...
 
std::shared_ptr< PacketOf< Triangulation< dim > > > packet ()
 Returns the packet that holds this data, if there is one. More...
 
std::shared_ptr< const PacketOf< Triangulation< dim > > > packet () const
 Returns the packet that holds this data, if there is one. More...
 
std::string anonID () const
 A unique string ID that can be used in place of a packet ID. More...
 
std::string str () const
 Returns a short text representation of this object. More...
 
std::string utf8 () const
 Returns a short text representation of this object using unicode characters. More...
 
std::string detail () const
 Returns a detailed text representation of this object. More...
 
std::string tightEncoding () const
 Returns the tight encoding of this object. More...
 
Constructors and Destructors
 Triangulation ()=default
 Default constructor. More...
 
 Triangulation (const Triangulation &src)=default
 Creates a new copy of the given triangulation. More...
 
 Triangulation (const Triangulation &src, bool cloneProps)
 Creates a new copy of the given triangulation, with the option of whether or not to clone its computed properties also. More...
 
 Triangulation (Triangulation &&src) noexcept=default
 Moves the given triangulation into this new triangulation. More...
 
 Triangulation (const std::string &description)
 "Magic" constructor that tries to find some way to interpret the given string as a triangulation. More...
 
 ~Triangulation ()
 Destroys this triangulation. More...
 
Pentachora
Pentachoron< 4 > * newPentachoron ()
 A dimension-specific alias for newSimplex(). More...
 
Pentachoron< 4 > * newPentachoron (const std::string &desc)
 A dimension-specific alias for newSimplex(). More...
 
template<int k>
std::array< Pentachoron< 4 > *, k > newPentachora ()
 A dimension-specific alias for newSimplices(). More...
 
void newPentachora (size_t k)
 A dimension-specific alias for newSimplices(). More...
 
void removePentachoron (Pentachoron< 4 > *tet)
 A dimension-specific alias for removeSimplex(). More...
 
void removePentachoronAt (size_t index)
 A dimension-specific alias for removeSimplexAt(). More...
 
void removeAllPentachora ()
 A dimension-specific alias for removeAllSimplices(). More...
 
Triangulationoperator= (const Triangulation &src)
 Sets this to be a (deep) copy of the given triangulation. More...
 
Triangulationoperator= (Triangulation &&src)
 Moves the contents of the given triangulation into this triangulation. More...
 
void swap (Triangulation< 4 > &other)
 Swaps the contents of this and the given triangulation. More...
 
Skeletal Queries
bool hasBoundaryTetrahedra () const
 A dimension-specific alias for hasBoundaryFacets(). More...
 
size_t countBoundaryTetrahedra () const
 A dimension-specific alias for countBoundaryFacets(). More...
 
Basic Properties
long eulerCharManifold () const
 Returns the Euler characteristic of the corresponding compact manifold. More...
 
bool isIdeal () const
 Determines if this triangulation is ideal. More...
 
bool isClosed () const
 Determines if this triangulation is closed. More...
 
Algebraic Properties
IntersectionForm intersectionForm () const
 Returns the intersection form of this 4-manifold. More...
 
Skeletal Transformations
bool intelligentSimplify ()
 Attempts to simplify the triangulation as intelligently as possible without further input. More...
 
bool simplifyToLocalMinimum (bool perform=true)
 Uses all known simplification moves to reduce the triangulation monotonically to some local minimum number of pentachora. More...
 
bool simplifyExhaustive (int height=1, unsigned threads=1, ProgressTrackerOpen *tracker=nullptr)
 Attempts to simplify this triangulation using a slow but exhaustive search through the Pachner graph. More...
 
template<typename Action , typename... Args>
bool retriangulate (int height, unsigned threads, ProgressTrackerOpen *tracker, Action &&action, Args &&... args) const
 Explores all triangulations that can be reached from this via Pachner moves, without exceeding a given number of additional pentachora. More...
 
bool twoZeroMove (Triangle< 4 > *t, bool check=true, bool perform=true)
 Checks the eligibility of and/or performs a 2-0 move about the given triangle of degree 2. More...
 
bool twoZeroMove (Edge< 4 > *e, bool check=true, bool perform=true)
 Checks the eligibility of and/or performs a 2-0 move about the given edge of degree 2. More...
 
bool twoZeroMove (Vertex< 4 > *v, bool check=true, bool perform=true)
 Checks the eligibility of and/or performs a 2-0 move about the given vertex of degree 2. More...
 
bool fourFourMove (Edge< 4 > *e, bool check=true, bool perform=true)
 Checks the eligibility of and/or performs a 4-4 move about the given edge. More...
 
bool openBook (Tetrahedron< 4 > *t, bool check=true, bool perform=true)
 Checks the eligibility of and/or performs a book opening move about the given tetrahedron. More...
 
bool shellBoundary (Pentachoron< 4 > *p, bool check=true, bool perform=true)
 Checks the eligibility of and/or performs a boundary shelling move on the given pentachoron. More...
 
bool collapseEdge (Edge< 4 > *e, bool check=true, bool perform=true)
 Checks the eligibility of and/or performs a collapse of an edge in such a way that the topology of the manifold does not change and the number of vertices of the triangulation decreases by one. More...
 
bool snapEdge (Edge< 4 > *e, bool check=true, bool perform=true)
 Snaps together the endpoints of an edge connecting an internal vertex with some different (possibly boundary) vertex, which reduces the number of vertices in this triangulation by one without changing the topology. More...
 
Subdivisions and Covers
bool idealToFinite ()
 Converts an ideal triangulation into a finite triangulation. More...
 
Simplices
size_t size () const
 Returns the number of top-dimensional simplices in the triangulation. More...
 
auto simplices () const
 Returns an object that allows iteration through and random access to all top-dimensional simplices in this triangulation. More...
 
Simplex< dim > * simplex (size_t index)
 Returns the top-dimensional simplex at the given index in the triangulation. More...
 
const Simplex< dim > * simplex (size_t index) const
 Returns the top-dimensional simplex at the given index in the triangulation. More...
 
Simplex< dim > * newSimplex ()
 Creates a new top-dimensional simplex and adds it to this triangulation. More...
 
Simplex< dim > * newSimplex (const std::string &desc)
 Creates a new top-dimensional simplex with the given description and adds it to this triangulation. More...
 
std::array< Simplex< dim > *, k > newSimplices ()
 Creates k new top-dimensional simplices, adds them to this triangulation, and returns them in a std::array. More...
 
void newSimplices (size_t k)
 Creates k new top-dimensional simplices and adds them to this triangulation. More...
 
void removeSimplex (Simplex< dim > *simplex)
 Removes the given top-dimensional simplex from this triangulation. More...
 
void removeSimplexAt (size_t index)
 Removes the top-dimensional simplex at the given index in this triangulation. More...
 
void removeAllSimplices ()
 Removes all simplices from the triangulation. More...
 
void moveContentsTo (Triangulation< dim > &dest)
 Moves the contents of this triangulation into the given destination triangulation, without destroying any pre-existing contents. More...
 
Skeletal Queries
size_t countComponents () const
 Returns the number of connected components in this triangulation. More...
 
size_t countBoundaryComponents () const
 Returns the number of boundary components in this triangulation. More...
 
size_t countFaces () const
 Returns the number of subdim-faces in this triangulation. More...
 
size_t countFaces (int subdim) const
 Returns the number of subdim-faces in this triangulation, where the face dimension does not need to be known until runtime. More...
 
size_t countVertices () const
 A dimension-specific alias for countFaces<0>(). More...
 
size_t countEdges () const
 A dimension-specific alias for countFaces<1>(). More...
 
size_t countTriangles () const
 A dimension-specific alias for countFaces<2>(). More...
 
size_t countTetrahedra () const
 A dimension-specific alias for countFaces<3>(). More...
 
size_t countPentachora () const
 A dimension-specific alias for countFaces<4>(). More...
 
std::vector< size_t > fVector () const
 Returns the f-vector of this triangulation, which counts the number of faces of all dimensions. More...
 
auto components () const
 Returns an object that allows iteration through and random access to all components of this triangulation. More...
 
auto boundaryComponents () const
 Returns an object that allows iteration through and random access to all boundary components of this triangulation. More...
 
auto faces () const
 Returns an object that allows iteration through and random access to all subdim-faces of this triangulation, in a way that is optimised for C++ programmers. More...
 
auto faces (int subdim) const
 Returns an object that allows iteration through and random access to all subdim-faces of this triangulation, in a way that is optimised for Python programmers. More...
 
auto vertices () const
 A dimension-specific alias for faces<0>(). More...
 
auto edges () const
 A dimension-specific alias for faces<1>(). More...
 
auto triangles () const
 A dimension-specific alias for faces<2>(), or an alias for simplices() in dimension dim = 2. More...
 
auto tetrahedra () const
 A dimension-specific alias for faces<3>(), or an alias for simplices() in dimension dim = 3. More...
 
auto pentachora () const
 A dimension-specific alias for faces<4>(), or an alias for simplices() in dimension dim = 4. More...
 
Component< dim > * component (size_t index) const
 Returns the requested connected component of this triangulation. More...
 
BoundaryComponent< dim > * boundaryComponent (size_t index) const
 Returns the requested boundary component of this triangulation. More...
 
Face< dim, subdim > * face (size_t index) const
 Returns the requested subdim-face of this triangulation, in a way that is optimised for C++ programmers. More...
 
auto face (int subdim, size_t index) const
 Returns the requested subdim-face of this triangulation, in a way that is optimised for Python programmers. More...
 
Face< dim, 0 > * vertex (size_t index) const
 A dimension-specific alias for face<0>(). More...
 
Face< dim, 1 > * edge (size_t index) const
 A dimension-specific alias for face<1>(). More...
 
Face< dim, 2 > * triangle (size_t index)
 A dimension-specific alias for face<2>(), or an alias for simplex() in dimension dim = 2. More...
 
auto triangle (size_t index) const
 A dimension-specific alias for face<2>(), or an alias for simplex() in dimension dim = 2. More...
 
Face< dim, 3 > * tetrahedron (size_t index)
 A dimension-specific alias for face<3>(), or an alias for simplex() in dimension dim = 3. More...
 
auto tetrahedron (size_t index) const
 A dimension-specific alias for face<3>(), or an alias for simplex() in dimension dim = 3. More...
 
Face< dim, 4 > * pentachoron (size_t index)
 A dimension-specific alias for face<4>(), or an alias for simplex() in dimension dim = 4. More...
 
auto pentachoron (size_t index) const
 A dimension-specific alias for face<4>(), or an alias for simplex() in dimension dim = 4. More...
 
Face< dim, subdim > * translate (const Face< dim, subdim > *other) const
 Translates a face of some other triangulation into the corresponding face of this triangulation, using simplex numbers for the translation. More...
 
FacetPairing< dim > pairing () const
 Returns the dual graph of this triangulation, expressed as a facet pairing. More...
 
Basic Properties
bool isEmpty () const
 Determines whether this triangulation is empty. More...
 
bool isValid () const
 Determines if this triangulation is valid. More...
 
bool hasBoundaryFacets () const
 Determines if this triangulation has any boundary facets. More...
 
size_t countBoundaryFacets () const
 Returns the total number of boundary facets in this triangulation. More...
 
size_t countBoundaryFaces () const
 Returns the number of boundary subdim-faces in this triangulation. More...
 
size_t countBoundaryFaces (int subdim) const
 Returns the number of boundary subdim-faces in this triangulation, where the face dimension does not need to be known until runtime. More...
 
bool isOrientable () const
 Determines if this triangulation is orientable. More...
 
bool isConnected () const
 Determines if this triangulation is connected. More...
 
bool isOriented () const
 Determines if this triangulation is oriented; that is, if the vertices of its top-dimensional simplices are labelled in a way that preserves orientation across adjacent facets. More...
 
long eulerCharTri () const
 Returns the Euler characteristic of this triangulation. More...
 
Algebraic Properties
const GroupPresentationgroup () const
 Returns the fundamental group of this triangulation. More...
 
const GroupPresentationfundamentalGroup () const
 An alias for group(), which returns the fundamental group of this triangulation. More...
 
void simplifiedFundamentalGroup (GroupPresentation newGroup)
 Notifies the triangulation that you have simplified the presentation of its fundamental group. More...
 
AbelianGroup homology () const
 Returns the kth homology group of this triangulation, treating any ideal vertices as though they had been truncated. More...
 
AbelianGroup homology (int k) const
 Returns the kth homology group of this triangulation, treating any ideal vertices as though they had been truncated, where the parameter k does not need to be known until runtime. More...
 
MarkedAbelianGroup markedHomology () const
 Returns the kth homology group of this triangulation, without truncating ideal vertices, but with explicit coordinates that track the individual k-faces of this triangulation. More...
 
MarkedAbelianGroup markedHomology (int k) const
 Returns the kth homology group of this triangulation, without truncating ideal vertices, but with explicit coordinates that track the individual k-faces of this triangulation, where the parameter k does not need to be known until runtime. More...
 
MatrixInt boundaryMap () const
 Returns the boundary map from subdim-faces to (subdim-1)-faces of the triangulation. More...
 
MatrixInt boundaryMap (int subdim) const
 Returns the boundary map from subdim-faces to (subdim-1)-faces of the triangulation, where the face dimension does not need to be known until runtime. More...
 
MatrixInt dualBoundaryMap () const
 Returns the boundary map from dual subdim-faces to dual (subdim-1)-faces of the triangulation. More...
 
MatrixInt dualBoundaryMap (int subdim) const
 Returns the boundary map from dual subdim-faces to dual (subdim-1)-faces of the triangulation, where the face dimension does not need to be known until runtime. More...
 
MatrixInt dualToPrimal () const
 Returns a map from dual chains to primal chains that preserves homology classes. More...
 
MatrixInt dualToPrimal (int subdim) const
 Returns a map from dual chains to primal chains that preserves homology classes, where the chain dimension does not need to be known until runtime. More...
 
Skeletal Transformations
void orient ()
 Relabels the vertices of top-dimensional simplices in this triangulation so that all simplices are oriented consistently, if possible. More...
 
void reflect ()
 Relabels the vertices of top-dimensional simplices in this triangulation so that all simplices reflect their orientation. More...
 
bool pachner (Face< dim, k > *f, bool check=true, bool perform=true)
 Checks the eligibility of and/or performs a (dim + 1 - k)-(k + 1) Pachner move about the given k-face. More...
 
Subdivisions, Extensions and Covers
void makeDoubleCover ()
 Converts this triangulation into its double cover. More...
 
void subdivide ()
 Does a barycentric subdivision of the triangulation. More...
 
void barycentricSubdivision ()
 Deprecated routine that performs a barycentric subdivision of the triangulation. More...
 
bool finiteToIdeal ()
 Converts each real boundary component into a cusp (i.e., an ideal vertex). More...
 
Decompositions
std::vector< Triangulation< dim > > triangulateComponents () const
 Returns the individual connected components of this triangulation. More...
 
Isomorphism Testing
bool operator== (const Triangulation< dim > &other) const
 Determines if this triangulation is combinatorially identical to the given triangulation. More...
 
bool operator!= (const Triangulation< dim > &other) const
 Determines if this triangulation is not combinatorially identical to the given triangulation. More...
 
std::optional< Isomorphism< dim > > isIsomorphicTo (const Triangulation< dim > &other) const
 Determines if this triangulation is combinatorially isomorphic to the given triangulation. More...
 
std::optional< Isomorphism< dim > > isContainedIn (const Triangulation< dim > &other) const
 Determines if an isomorphic copy of this triangulation is contained within the given triangulation, possibly as a subcomplex of some larger component (or components). More...
 
bool findAllIsomorphisms (const Triangulation< dim > &other, Action &&action, Args &&... args) const
 Finds all ways in which this triangulation is combinatorially isomorphic to the given triangulation. More...
 
bool findAllSubcomplexesIn (const Triangulation< dim > &other, Action &&action, Args &&... args) const
 Finds all ways in which an isomorphic copy of this triangulation is contained within the given triangulation, possibly as a subcomplex of some larger component (or components). More...
 
bool makeCanonical ()
 Relabel the top-dimensional simplices and their vertices so that this triangulation is in canonical form. More...
 
Building Triangulations
void insertTriangulation (const Triangulation< dim > &source)
 Inserts a copy of the given triangulation into this triangulation. More...
 
Exporting Triangulations
void writeTextShort (std::ostream &out) const
 Writes a short text representation of this object to the given output stream. More...
 
void writeTextLong (std::ostream &out) const
 Writes a detailed text representation of this object to the given output stream. More...
 
Encoding::Signature isoSig () const
 Constructs the isomorphism signature of the given type for this triangulation. More...
 
std::pair< typename Encoding::Signature, Isomorphism< dim > > isoSigDetail () const
 Constructs the isomorphism signature for this triangulation, along with the relabelling that will occur when the triangulation is reconstructed from it. More...
 
void tightEncode (std::ostream &out) const
 Writes the tight encoding of this triangulation to the given output stream. More...
 
std::string dumpConstruction () const
 Returns C++ code that can be used to reconstruct this triangulation. More...
 

Static Public Member Functions

static Triangulation< dim > tightDecoding (const std::string &enc)
 Reconstructs an object of type T from its given tight encoding. More...
 

Static Public Attributes

static constexpr int dimension
 A compile-time constant that gives the dimension of the triangulation. More...
 

Protected Member Functions

void swap (Snapshottable &other) noexcept
 Swap operation. More...
 
void takeSnapshot ()
 Must be called before modification and/or destruction of the type T contents. More...
 

Protected Attributes

MarkedVector< Simplex< dim > > simplices_
 The top-dimensional simplices that form the triangulation. More...
 
MarkedVector< Component< dim > > components_
 The connected components that form the triangulation. More...
 
MarkedVector< BoundaryComponent< dim > > boundaryComponents_
 The components that form the boundary of the triangulation. More...
 
std::array< size_t, dim > nBoundaryFaces_
 The number of boundary faces of each dimension. More...
 
bool valid_
 Is this triangulation valid? See isValid() for details on what this means. More...
 
uint8_t topologyLock_
 If non-zero, this will cause Triangulation<dim>::clearAllProperties() to preserve any computed properties that related to the manifold (as opposed to the specific triangulation). More...
 
PacketHeldBy heldBy_
 Indicates whether this Held object is in fact the inherited data for a PacketOf<Held>. More...
 

Normal Hypersurfaces

class regina::Face< 4, 4 >
 
class regina::detail::SimplexBase< 4 >
 
class regina::detail::TriangulationBase< 4 >
 
class regina::XMLTriangulationReader< 4 >
 
class regina::XMLWriter< Triangulation< 4 > >
 
template<int subdim>
std::pair< NormalHypersurface, bool > linkingSurface (const Face< 4, subdim > &face) const
 Returns the link of the given face as a normal hypersurface. More...
 

Importing Triangulations

static Triangulation< dim > fromGluings (size_t size, std::initializer_list< std::tuple< size_t, int, size_t, Perm< dim+1 > > > gluings)
 Creates a triangulation from a hard-coded list of gluings. More...
 
static Triangulation< dim > fromGluings (size_t size, Iterator beginGluings, Iterator endGluings)
 Creates a triangulation from a list of gluings. More...
 
static Triangulation< dim > fromIsoSig (const std::string &sig)
 Recovers a full triangulation from an isomorphism signature. More...
 
static Triangulation< dim > fromSig (const std::string &sig)
 Alias for fromIsoSig(), to recover a full triangulation from an isomorphism signature. More...
 
static size_t isoSigComponentSize (const std::string &sig)
 Deduces the number of top-dimensional simplices in a connected triangulation from its isomorphism signature. More...
 
static Triangulation< dim > tightDecode (std::istream &input)
 Reconstructs a triangulation from its given tight encoding. More...
 
void ensureSkeleton () const
 Ensures that all "on demand" skeletal objects have been calculated. More...
 
bool calculatedSkeleton () const
 Determines whether the skeletal objects and properties of this triangulation have been calculated. More...
 
void cloneSkeleton (const TriangulationBase &src)
 Builds the skeleton of this triangulation as a clone of the skeleton of the given triangulation. More...
 
void clearBaseProperties ()
 Clears all properties that are managed by this base class. More...
 
void swapBaseData (TriangulationBase< dim > &other)
 Swaps all data that is managed by this base class, including simplices, skeletal data, cached properties and the snapshotting data, with the given triangulation. More...
 
void writeXMLBaseProperties (std::ostream &out) const
 Writes a chunk of XML containing properties of this triangulation. More...
 

Detailed Description

Represents a 4-dimensional triangulation, typically of a 4-manifold.

This is a specialisation of the generic Triangulation class template; see the Triangulation documentation for a general overview of how the triangulation classes work.

This 4-dimensional specialisation offers significant extra functionality, including many functions specific to 4-manifolds.

A 4-manifold triangulation is built from pentachora: a pentachoron is a 4-dimensional simplex, with five vertices.

This class implements C++ move semantics and adheres to the C++ Swappable requirement. It is designed to avoid deep copies wherever possible, even when passing or returning objects by value.

Constructor & Destructor Documentation

◆ Triangulation() [1/5]

regina::Triangulation< 4 >::Triangulation ( )
default

Default constructor.

Creates an empty triangulation.

◆ Triangulation() [2/5]

regina::Triangulation< 4 >::Triangulation ( const Triangulation< 4 > &  src)
default

Creates a new copy of the given triangulation.

This will also clone any computed properties (such as homology, fundamental group, and so on), as well as the skeleton (vertices, edges, components, etc.). In particular, the same numbering and labelling will be used for all skeletal objects.

If you want a "clean" copy that resets all properties to unknown and leaves the skeleton uncomputed, you can use the two-argument copy constructor instead.

Parameters
srcthe triangulation to copy.

◆ Triangulation() [3/5]

regina::Triangulation< 4 >::Triangulation ( const Triangulation< 4 > &  src,
bool  cloneProps 
)

Creates a new copy of the given triangulation, with the option of whether or not to clone its computed properties also.

If cloneProps is true, then this constructor will also clone any computed properties (such as homology, fundamental group, and so on), as well as the skeleton (vertices, edges, components, etc.). In particular, the same numbering and labelling will be used for all skeletal objects in both triangulations.

If cloneProps is false, then these properties and skeletal objects will be marked as unknown in the new triangulation, and will be recomputed on demand if/when they are required. Note in particular that, when the skeleton is recomputed, there is no guarantee that the numbering and labelling for skeletal objects will be the same as in the source triangulation.

Regardless of the argument cloneProps, if it is known that all vertex links of copy are 3-sphere or 3-balls, this knowledge will be copied over to the new triangulation.

Parameters
srcthe triangulation to copy.
clonePropstrue if this should also clone any computed properties as well as the skeleton of the given triangulation, or false if the new triangulation should have such properties and skeletal data marked as unknown.

◆ Triangulation() [4/5]

regina::Triangulation< 4 >::Triangulation ( Triangulation< 4 > &&  src)
defaultnoexcept

Moves the given triangulation into this new triangulation.

This is much faster than the copy constructor, but is still linear time. This is because every pentachoron must be adjusted to point back to this new triangulation instead of src.

All pentachora and skeletal objects (faces, components and boundary components) that belong to src will be moved into this triangulation, and so any pointers or references to Pentachoron<4>, Face<4, subdim>, Component<4> or BoundaryComponent<4> objects will remain valid. Likewise, all cached properties will be moved into this triangulation.

The triangulation that is passed (src) will no longer be usable.

Note
This operator is marked noexcept, and in particular does not fire any change events. This is because this triangulation is freshly constructed (and therefore has no listeners yet), and because we assume that src is about to be destroyed (an action that will fire a packet destruction event).
Parameters
srcthe triangulation to move.

◆ Triangulation() [5/5]

regina::Triangulation< 4 >::Triangulation ( const std::string &  description)

"Magic" constructor that tries to find some way to interpret the given string as a triangulation.

At present, Regina understands the following types of strings (and attempts to parse them in the following order):

This list may grow in future versions of Regina.

Exceptions
InvalidArgumentRegina could not interpret the given string as representing a triangulation using any of the supported string types.
Parameters
descriptiona string that describes a 4-manifold triangulation.

◆ ~Triangulation()

Destroys this triangulation.

The constituent pentachora, the cellular structure and all other properties will also be deallocated.

Member Function Documentation

◆ anonID()

std::string regina::PacketData< Triangulation< dim > >::anonID
inherited

A unique string ID that can be used in place of a packet ID.

This is an alternative to Packet::internalID(), and is designed for use when Held is not actually wrapped by a PacketOf<Held>. (An example of such a scenario is when a normal surface list needs to write its triangulation to file, but the triangulation is a standalone object that is not stored in a packet.)

The ID that is returned will:

  • remain fixed throughout the lifetime of the program for a given object, even if the contents of the object are changed;
  • not clash with the anonID() returned from any other object, or with the internalID() returned from any packet of any type;

These IDs are not preserved when copying or moving one object to another, and are not preserved when writing to a Regina data file and then reloading the file contents.

Warning
If this object is wrapped in a PacketOf<Held>, then anonID() and Packet::internalID() may return different values.

See Packet::internalID() for further details.

Returns
a unique ID that identifies this object.

◆ barycentricSubdivision()

void regina::detail::TriangulationBase< dim >::barycentricSubdivision
inlineinherited

Deprecated routine that performs a barycentric subdivision of the triangulation.

Deprecated:
This routine has been renamed to subdivide(), both to shorten the name but also to make it clearer that this triangulation will be modified directly.
Precondition
dim is one of Regina's standard dimensions.

◆ boundaryComponent()

BoundaryComponent< dim > * regina::detail::TriangulationBase< dim >::boundaryComponent ( size_t  index) const
inlineinherited

Returns the requested boundary component of this triangulation.

Note that each time the triangulation changes, all boundary components will be deleted and replaced with new ones. Therefore this object should be considered temporary only.

Parameters
indexthe index of the desired boundary component; this must be between 0 and countBoundaryComponents()-1 inclusive.
Returns
the requested boundary component.

◆ boundaryComponents()

auto regina::detail::TriangulationBase< dim >::boundaryComponents
inlineinherited

Returns an object that allows iteration through and random access to all boundary components of this triangulation.

Note that, in Regina's standard dimensions, each ideal vertex forms its own boundary component, and some invalid vertices do also. See the BoundaryComponent class notes for full details on what constitutes a boundary component in standard and non-standard dimensions.

The object that is returned is lightweight, and can be happily copied by value. The C++ type of the object is subject to change, so C++ users should use auto (just like this declaration does).

The returned object is guaranteed to be an instance of ListView, which means it offers basic container-like functions and supports range-based for loops. Note that the elements of the list will be pointers, so your code might look like:

for (BoundaryComponent<dim>* b : tri.boundaryComponents()) { ... }

The object that is returned will remain up-to-date and valid for as long as the triangulation exists. In contrast, however, remember that the individual boundary components within this list will be deleted and replaced each time the triangulation changes. Therefore it is best to treat this object as temporary only, and to call boundaryComponents() again each time you need it.

Returns
access to the list of all boundary components.

◆ boundaryMap() [1/2]

MatrixInt regina::detail::TriangulationBase< dim >::boundaryMap ( ) const
inherited

Returns the boundary map from subdim-faces to (subdim-1)-faces of the triangulation.

For C++ programmers who know subdim at compile time, you should use this template function boundaryMap<subdim>(), which is slightly faster than passing subdim as an ordinary runtime argument to boundaryMap(subdim).

See the non-templated boundaryMap(int) for full details on what this function computes and how the matrix it returns should be interpreted.

Precondition
This triangulation is valid and non-empty.
Python
Not present. Instead use the variant boundaryMap(subdim).
Template Parameters
subdimthe face dimension; this must be between 1 and dim inclusive.
Returns
the boundary map from subdim-faces to (subdim-1)-faces.

◆ boundaryMap() [2/2]

MatrixInt regina::detail::TriangulationBase< dim >::boundaryMap ( int  subdim) const
inlineinherited

Returns the boundary map from subdim-faces to (subdim-1)-faces of the triangulation, where the face dimension does not need to be known until runtime.

For C++ programmers who know subdim at compile time, you are better off using the template function boundaryMap<subdim>() instead, which is slightly faster.

This is the boundary map that you would use if you were building the homology groups manually from a chain complex.

Unlike homology(), this code does not use the dual skeleton: instead it uses the primal (i.e., ordinary) skeleton.

  • The main advantage of this is that you can easily match rows and columns of the returned matrix to faces of this triangulation.
  • The main disadvantage is that ideal vertices are not treated as though they were truncated; instead they are just treated as 0-faces that appear as part of the chain complex.

The matrix that is returned should be thought of as acting on column vectors. Specifically, the cth column of the matrix corresponds to the cth subdim-face of this triangulation, and the rth row corresponds to the rth (subdim-1)-face of this triangulation.

For the boundary map, we fix orientations as follows. In simplicial homology, for any k, the orientation of a k-simplex is determined by assigning labels 0,...,k to its vertices. For this routine, since every k-face f is already a k-simplex, these labels will just be the inherent vertex labels 0,...,k of the corresponding Face<k> object. If you need to convert these labels into vertex numbers of a top-dimensional simplex containing f, you can use either Simplex<dim>::faceMapping<k>(), or the equivalent routine FaceEmbedding<k>::vertices().

If you wish to convert these boundary maps to homology groups yourself, either the AbelianGroup class (if you do not need to track which face is which) or the MarkedAbelianGroup class (if you do need to track individual faces) can help you do this.

Note that, unlike many of the templated face-related routines, this routine explicitly supports the case subdim = dim.

Precondition
This triangulation is valid and non-empty.
Exceptions
InvalidArgumentThe face dimension subdim is outside the supported range (i.e., less than 1 or greater than dim).
Parameters
subdimthe face dimension; this must be between 1 and dim inclusive.
Returns
the boundary map from subdim-faces to (subdim-1)-faces.

◆ calculatedSkeleton()

bool regina::detail::TriangulationBase< dim >::calculatedSkeleton
inlineprotectedinherited

Determines whether the skeletal objects and properties of this triangulation have been calculated.

These are only calculated "on demand", when a skeletal property is first queried.

Returns
true if and only if the skeleton has been calculated.

◆ clearBaseProperties()

void regina::detail::TriangulationBase< dim >::clearBaseProperties ( )
protectedinherited

Clears all properties that are managed by this base class.

This includes deleting all skeletal objects and emptying the corresponding internal lists, as well as clearing other cached properties and deallocating the corresponding memory where required.

Note that TriangulationBase almost never calls this routine itself (the one exception is the copy assignment operator). Typically clearBaseProperties() is only ever called by Triangulation<dim>::clearAllProperties(), which in turn is called by "atomic" routines that change the triangluation (before firing packet change events), as well as the Triangulation<dim> destructor.

◆ cloneSkeleton()

void regina::detail::TriangulationBase< dim >::cloneSkeleton ( const TriangulationBase< 4 > &  src)
protectedinherited

Builds the skeleton of this triangulation as a clone of the skeleton of the given triangulation.

This clones all skeletal objects (e.g., faces, components and boundary components) and skeletal properties (e.g., validity and orientability). In general, this function clones the same properties and data that calculateSkeleton() computes.

For this parent class, cloneSkeleton() clones properties and data that are common to all dimensions. Some Triangulation<dim> subclasses may track additional skeletal properties or data, in which case they should reimplement this function (just as they also reimplement calculateSkeleton()). Their reimplementations must call this parent implementation.

This function is intended only for use by the copy constructor (and related "copy-like" constructors), and the copy assignment operator. Other code should typically not need to call this function directly.

The real point of this routine is to ensure that, when a triangulation is cloned, its skeleton is cloned with exactly the same numbering/labelling of its skeletal objects. To this end, it is fine to leave some "large" skeletal properties to be computed on demand where this is allowed (e.g., triangulated vertex links or triangulated boundary components, which are allowed to remain uncomputed until required, even when the full skeleton has been computed).

Precondition
No skeletal objects have been computed for this triangulation, and the corresponding internal lists are all empty.
The skeleton has been fully computed for the given source triangulation.
The given source triangulation is combinatorially identical to this triangulation (i.e., both triangulations have the same number of top-dimensional simplices, with gluings between the same pairs of numbered simplices using the same gluing permutations).
Warning
Any call to cloneSkeleton() must first cast down to Triangulation<dim>, to ensure that you are catching the subclass implementation if this exists. You should never directly call this parent implementation (unless of course you are reimplementing cloneSkeleton() in a Triangulation<dim> subclass).
Parameters
srcthe triangulation whose skeleton should be cloned.

◆ collapseEdge()

bool regina::Triangulation< 4 >::collapseEdge ( Edge< 4 > *  e,
bool  check = true,
bool  perform = true 
)

Checks the eligibility of and/or performs a collapse of an edge in such a way that the topology of the manifold does not change and the number of vertices of the triangulation decreases by one.

If the routine is asked to both check and perform, the move will only be performed if the check shows it is legal.

If you are trying to reduce the number of vertices without changing the topology, and if e is an edge connecting an internal vertex with some different vertex, then either collapseEdge() or snapEdge() may be more appropriate for your situation.

  • The advantage of collapseEdge() is that it decreases the number of tetrahedra, whereas snapEdge() increases this number (but only by four).
  • The disadvantages of collapseEdge() are that it cannot always be performed, and its validity tests are expensive; snapEdge() on the other hand can always be used for edges e of the type described above.

If this triangulation is currently oriented, then this operation will preserve the orientation.

Note that after performing this move, all skeletal objects (facets, components, etc.) will be reconstructed, which means any pointers to old skeletal objects (such as the argument e) can no longer be used.

The eligibility requirements for this move are somewhat involved, and are discussed in detail in the collapseEdge() source code for those who are interested.

Precondition
If the move is being performed and no check is being run, it must be known in advance that the move is legal.
The given edge is an edge of this triangulation.
Parameters
ethe edge to collapse.
checktrue if we are to check whether the move is allowed (defaults to true).
performtrue if we are to perform the move (defaults to true).
Returns
If check is true, the function returns true if and only if the given edge may be collapsed without changing the topology of the manifold. If check is false, the function simply returns true.

◆ component()

Component< dim > * regina::detail::TriangulationBase< dim >::component ( size_t  index) const
inlineinherited

Returns the requested connected component of this triangulation.

Note that each time the triangulation changes, all component objects will be deleted and replaced with new ones. Therefore this component object should be considered temporary only.

Parameters
indexthe index of the desired component; this must be between 0 and countComponents()-1 inclusive.
Returns
the requested component.

◆ components()

auto regina::detail::TriangulationBase< dim >::components
inlineinherited

Returns an object that allows iteration through and random access to all components of this triangulation.

The object that is returned is lightweight, and can be happily copied by value. The C++ type of the object is subject to change, so C++ users should use auto (just like this declaration does).

The returned object is guaranteed to be an instance of ListView, which means it offers basic container-like functions and supports range-based for loops. Note that the elements of the list will be pointers, so your code might look like:

for (Component<dim>* c : tri.components()) { ... }

The object that is returned will remain up-to-date and valid for as long as the triangulation exists. In contrast, however, remember that the individual component objects within this list will be deleted and replaced each time the triangulation changes. Therefore it is best to treat this object as temporary only, and to call components() again each time you need it.

Returns
access to the list of all components.

◆ countBoundaryComponents()

size_t regina::detail::TriangulationBase< dim >::countBoundaryComponents
inlineinherited

Returns the number of boundary components in this triangulation.

Note that, in Regina's standard dimensions, each ideal vertex forms its own boundary component, and some invalid vertices do also. See the BoundaryComponent class notes for full details on what constitutes a boundary component in standard and non-standard dimensions.

Returns
the number of boundary components.

◆ countBoundaryFaces() [1/2]

size_t regina::detail::TriangulationBase< dim >::countBoundaryFaces
inlineinherited

Returns the number of boundary subdim-faces in this triangulation.

This is the fastest way to count faces if you know subdim at compile time.

Specifically, this counts the number of subdim-faces for which isBoundary() returns true. This may lead to some unexpected results in non-standard scenarios; see the documentation for the non-templated countBoundaryFaces(int) for details.

Python
Not present. Instead use the variant countBoundaryFaces(subdim).
Template Parameters
subdimthe face dimension; this must be between 0 and dim-1 inclusive.
Returns
the number of boundary subdim-faces.

◆ countBoundaryFaces() [2/2]

size_t regina::detail::TriangulationBase< dim >::countBoundaryFaces ( int  subdim) const
inlineinherited

Returns the number of boundary subdim-faces in this triangulation, where the face dimension does not need to be known until runtime.

This routine takes linear time in the dimension dim. For C++ programmers who know subdim at compile time, you are better off using the template function countBoundaryFaces<subdim>() instead, which is fast constant time.

Specifically, this counts the number of subdim-faces for which isBoundary() returns true. This may lead to some unexpected results in non-standard scenarios; for example:

  • In non-standard dimensions, ideal vertices are not recognised and so will not be counted as boundary;
  • In an invalid triangulation, the number of boundary faces reported here may be smaller than the number of faces obtained when you triangulate the boundary using BoundaryComponent::build(). This is because "pinched" faces (where separate parts of the boundary are identified together) will only be counted once here, but will "spring apart" into multiple faces when the boundary is triangulated.
Exceptions
InvalidArgumentThe face dimension subdim is outside the supported range (i.e., negative or greater than dim-1).
Parameters
subdimthe face dimension; this must be between 0 and dim-1 inclusive.
Returns
the number of boundary subdim-faces.

◆ countBoundaryFacets()

size_t regina::detail::TriangulationBase< dim >::countBoundaryFacets
inlineinherited

Returns the total number of boundary facets in this triangulation.

This routine counts facets of top-dimensional simplices that are not glued to some adjacent top-dimensional simplex.

This is equivalent to calling countBoundaryFaces<dim-1>().

Returns
the total number of boundary facets.

◆ countBoundaryTetrahedra()

size_t regina::Triangulation< 4 >::countBoundaryTetrahedra ( ) const
inline

A dimension-specific alias for countBoundaryFacets().

See countBoundaryFacets() for further information.

◆ countComponents()

size_t regina::detail::TriangulationBase< dim >::countComponents
inlineinherited

Returns the number of connected components in this triangulation.

Returns
the number of connected components.

◆ countEdges()

size_t regina::detail::TriangulationBase< dim >::countEdges
inlineinherited

A dimension-specific alias for countFaces<1>().

This alias is available for all dimensions dim.

See countFaces() for further information.

◆ countFaces() [1/2]

size_t regina::detail::TriangulationBase< dim >::countFaces
inlineinherited

Returns the number of subdim-faces in this triangulation.

This is the fastest way to count faces if you know subdim at compile time.

For convenience, this routine explicitly supports the case subdim = dim. This is not the case for the routines face() and faces(), which give access to individual faces (the reason relates to the fact that top-dimensional simplices are built manually, whereas lower-dimensional faces are deduced properties).

Python
Not present. Instead use the variant countFaces(subdim).
Template Parameters
subdimthe face dimension; this must be between 0 and dim inclusive.
Returns
the number of subdim-faces.

◆ countFaces() [2/2]

size_t regina::detail::TriangulationBase< dim >::countFaces ( int  subdim) const
inlineinherited

Returns the number of subdim-faces in this triangulation, where the face dimension does not need to be known until runtime.

This routine takes linear time in the dimension dim. For C++ programmers who know subdim at compile time, you are better off using the template function countFaces<subdim>() instead, which is fast constant time.

For convenience, this routine explicitly supports the case subdim = dim. This is not the case for the routines face() and faces(), which give access to individual faces (the reason relates to the fact that top-dimensional simplices are built manually, whereas lower-dimensional faces are deduced properties).

Exceptions
InvalidArgumentThe face dimension subdim is outside the supported range (i.e., negative or greater than dim).
Parameters
subdimthe face dimension; this must be between 0 and dim inclusive.
Returns
the number of subdim-faces.

◆ countPentachora()

size_t regina::detail::TriangulationBase< dim >::countPentachora
inlineinherited

A dimension-specific alias for countFaces<4>().

This alias is available for dimensions dim ≥ 4.

See countFaces() for further information.

◆ countTetrahedra()

size_t regina::detail::TriangulationBase< dim >::countTetrahedra
inlineinherited

A dimension-specific alias for countFaces<3>().

This alias is available for dimensions dim ≥ 3.

See countFaces() for further information.

◆ countTriangles()

size_t regina::detail::TriangulationBase< dim >::countTriangles
inlineinherited

A dimension-specific alias for countFaces<2>().

This alias is available for all dimensions dim.

See countFaces() for further information.

◆ countVertices()

size_t regina::detail::TriangulationBase< dim >::countVertices
inlineinherited

A dimension-specific alias for countFaces<0>().

This alias is available for all dimensions dim.

See countFaces() for further information.

◆ detail()

std::string regina::Output< Triangulation< dim > , false >::detail ( ) const
inherited

Returns a detailed text representation of this object.

This text may span many lines, and should provide the user with all the information they could want. It should be human-readable, should not contain extremely long lines (which cause problems for users reading the output in a terminal), and should end with a final newline. There are no restrictions on the underlying character set.

Returns
a detailed text representation of this object.

◆ dualBoundaryMap() [1/2]

MatrixInt regina::detail::TriangulationBase< dim >::dualBoundaryMap ( ) const
inherited

Returns the boundary map from dual subdim-faces to dual (subdim-1)-faces of the triangulation.

For C++ programmers who know subdim at compile time, you should use this template function dualBoundaryMap<subdim>(), which is slightly faster than passing subdim as an ordinary runtime argument to dualBoundaryMap(subdim).

See the non-templated dualBoundaryMap(int) for full details on what this function computes and how the matrix it returns should be interpreted.

Precondition
This triangulation is valid and non-empty.
Python
Not present. Instead use the variant dualBoundaryMap(subdim).
Template Parameters
subdimthe dual face dimension; this must be between 1 and dim inclusive if dim is one of Regina's standard dimensions, or between 1 and (dim - 1) inclusive otherwise.
Returns
the boundary map from dual subdim-faces to dual (subdim-1)-faces.

◆ dualBoundaryMap() [2/2]

MatrixInt regina::detail::TriangulationBase< dim >::dualBoundaryMap ( int  subdim) const
inlineinherited

Returns the boundary map from dual subdim-faces to dual (subdim-1)-faces of the triangulation, where the face dimension does not need to be known until runtime.

For C++ programmers who know subdim at compile time, you are better off using the template function dualBoundaryMap<subdim>() instead, which is slightly faster.

This function is analogous to boundaryMap(), but is designed to work with dual faces instead of ordinary (primal) faces. In particular, this is used in the implementation of homology(), which works with the dual skeleton in order to effectively truncate ideal vertices.

The matrix that is returned should be thought of as acting on column vectors. Specifically, the cth column of the matrix corresponds to the cth dual subdim-face of this triangulation, and the rth row corresponds to the rth dual (subdim-1)-face of this triangulation. Here we index dual faces in the same order as the (primal) faces of the triangulation that they are dual to, except that we omit primal boundary faces (i.e., primal faces for which Face::isBoundary() returns true). Therefore, for triangulations with boundary, the dual face indices and the corresponding primal face indices might not be equal.

For this dual boundary map, for positive dual face dimensions k, we fix the orientations of the dual k-faces as follows:

  • In simplicial homology, the orientation of a k-simplex is determined by assigning labels 0,...,k to its vertices.
  • Consider a dual k-face d, and let this be dual to the primal (dim-k)-face f. In general, d will not be a simplex. Let B denote the barycentre of f (which also appears as the "centre" point of d).
  • Let emb be an arbitrary FaceEmbedding<dim-k> for f (i.e., chosen from f.embeddings()), and let s be the corresponding top-dimensional simplex containing f (i.e., emb.simplex()). For the special case of dual edges (k = 1), this choice matters; here we choose emb to be the first embedding (that is, f.front()). For larger k this choice does not matter; see below for the reasons why.
  • Now consider how d intersects the top-dimensional simplex s. This intersection is a k-polytope with B as one of its vertices. We can extend this polytope away from B, pushing it all the way through the simplex s, until it becomes a k-simplex g whose vertices are B along with the k "unused" vertices of s that do not appear in f.
  • We can now define the orientation of the dual k-face d to be the orientation of this k-simplex g that contains it. All that remains now is to orient g by choosing a labelling 0,...,k for its vertices.
  • To orient g, we assign the label 0 to B, and we assign the labels 1,...,k to the "unused" vertices v[dim-k+1],...,v[dim] of s respectively, where v is the permutation emb.vertices().
  • Finally, we note that for k > 1, the orientation for d does not depend on the particular choice of s and emb: by the preconditions and the fact that this routine only considers duals of non-boundary faces, the link of f must be a sphere, and therefore the images of those "other" vertices are fixed in a way that preserves orientation as you walk around the link. See the documentation for Simplex<dim>::faceMapping() for details.
  • For the special case of dual edges (k = 1), the conditions above can be described more simply: the two endpoints of the dual edge d correspond to the two top-dimensional simplices on either side of the (dim-1)-face f, and we orient d by labelling these endpoints (0, 1) in the order (f.back(), f.front()).

If you wish to convert these boundary maps to homology groups yourself, either the AbelianGroup class (if you do not need to track which dual face is which) or the MarkedAbelianGroup class (if you do need to track individual dual faces) can help you do this.

Precondition
This triangulation is valid and non-empty.
Exceptions
InvalidArgumentThe face dimension subdim is outside the supported range (as documented for the subdim argument below).
Parameters
subdimthe dual face dimension; this must be between 1 and dim inclusive if dim is one of Regina's standard dimensions, or between 1 and (dim - 1) inclusive otherwise.
Returns
the boundary map from dual subdim-faces to dual (subdim-1)-faces.

◆ dualToPrimal() [1/2]

MatrixInt regina::detail::TriangulationBase< dim >::dualToPrimal ( ) const
inherited

Returns a map from dual chains to primal chains that preserves homology classes.

For C++ programmers who know subdim at compile time, you should use this template function dualToPrimal<subdim>(), which is slightly faster than passing subdim as an ordinary runtime argument to dualToPrimal(subdim).

See the non-templated dualToPrimal(int) for full details on what this function computes and how the matrix it returns should be interpreted.

Precondition
This trianguation is valid, non-empty, and non-ideal. Note that Regina can only detect ideal triangulations in standard dimensions; for higher dimensions it is the user's reponsibility to confirm this some other way.
Python
Not present. Instead use the variant dualToPrimal(subdim).
Template Parameters
subdimthe chain dimension; this must be between 0 and (dim - 1) inclusive.
Returns
the map from dual subdim-chains to primal subdim-chains.

◆ dualToPrimal() [2/2]

MatrixInt regina::detail::TriangulationBase< dim >::dualToPrimal ( int  subdim) const
inlineinherited

Returns a map from dual chains to primal chains that preserves homology classes, where the chain dimension does not need to be known until runtime.

For C++ programmers who know subdim at compile time, you are better off using the template function dualToPrimal<subdim>() instead, which is slightly faster.

The matrix that is returned should be thought of as acting on column vectors. Specifically, the cth column of the matrix corresponds to the cth dual subdim-face of this triangulation, and the rth row corresponds to the rth primal subdim-face of this triangulation.

We index and orient these dual and primal faces in the same manner as dualBoundaryMap() and boundaryMap() respectively. In particular, dual faces are indexed in the same order as the primal (dim-subdim)-faces of the triangulation that they are dual to, except that we omit primal boundary faces. See dualBoundaryMap() and boundaryMap() for further details.

The key feature of this map is that, if a column vector v represents a cycle c in the dual chain complex (i.e., it is a chain with zero boundary), and if this map is represented by the matrix M, then the vector M×v represents a cycle in the primal chain complex that belongs to the same subdimth homology class as c.

Regarding implementation: the map is constructed by (i) subdividing each dual face into smaller subdim-simplices whose vertices are barycentres of primal faces of different dimensions, (ii) moving each barycentre to vertex 0 of the corresponding face, and then (iii) discarding any resulting simplices with repeated vertices (which become "flattened" to a dimension less than subdim).

Precondition
This trianguation is valid, non-empty, and non-ideal. Note that Regina can only detect ideal triangulations in standard dimensions; for higher dimensions it is the user's reponsibility to confirm this some other way.
Exceptions
InvalidArgumentThe chain dimension subdim is outside the supported range (as documented for the subdim argument below).
Parameters
subdimthe chain dimension; this must be between 0 and (dim - 1) inclusive.
Returns
the map from dual subdim-chains to primal subdim-chains.

◆ dumpConstruction()

std::string regina::detail::TriangulationBase< dim >::dumpConstruction
inherited

Returns C++ code that can be used to reconstruct this triangulation.

This code will call Triangulation<dim>::fromGluings(), passing a hard-coded C++ initialiser list.

The main purpose of this routine is to generate this hard-coded initialiser list, which can be tedious and error-prone to write by hand.

Note that the number of lines of code produced grows linearly with the number of simplices. If this triangulation is very large, the returned string will be very large as well.

Returns
the C++ code that was generated.

◆ edge()

Face< dim, 1 > * regina::detail::TriangulationBase< dim >::edge ( size_t  index) const
inlineinherited

A dimension-specific alias for face<1>().

This alias is available for all dimensions dim.

See face() for further information.

◆ edges()

auto regina::detail::TriangulationBase< dim >::edges
inlineinherited

A dimension-specific alias for faces<1>().

This alias is available for all dimensions dim.

See faces() for further information.

◆ ensureSkeleton()

void regina::detail::TriangulationBase< dim >::ensureSkeleton
inlineprotectedinherited

Ensures that all "on demand" skeletal objects have been calculated.

◆ eulerCharManifold()

long regina::Triangulation< 4 >::eulerCharManifold ( ) const

Returns the Euler characteristic of the corresponding compact manifold.

Instead of simply calculating V-E+F-T+P, this routine also treats ideal vertices as 3-manifold boundary components (i.e., effectively truncates them).

For ideal triangulations, this routine therefore computes the proper Euler characteristic of the manifold (unlike eulerCharTri(), which does not).

For triangulations whose vertex links are all 3-spheres or 3-balls, this routine and eulerCharTri() give identical results.

This routine does not yet handle invalid triangulations correctly. For this reason, this routine currently insists on a valid triangulation as a precondition.

Precondition
This triangulation is valid.
Returns
the Euler characteristic of the corresponding compact manifold.

◆ eulerCharTri()

long regina::detail::TriangulationBase< dim >::eulerCharTri
inlineinherited

Returns the Euler characteristic of this triangulation.

This will be evaluated strictly as the alternating sum of the number of i-faces (that is, countVertices() - countEdges() + countTriangles() - ...).

Note that this routine handles ideal triangulations in a non-standard way. Since it computes the Euler characteristic of the triangulation (and not the underlying manifold), this routine will treat each ideal boundary component as a single vertex, and not as an entire (dim-1)-dimensional boundary component.

In Regina's standard dimensions, for a routine that handles ideal boundary components properly (by treating them as (dim-1)-dimensional boundary components when computing Euler characteristic), you can use the routine eulerCharManifold() instead.

Returns
the Euler characteristic of this triangulation.

◆ face() [1/2]

auto regina::detail::TriangulationBase< dim >::face ( int  subdim,
size_t  index 
) const
inlineinherited

Returns the requested subdim-face of this triangulation, in a way that is optimised for Python programmers.

For C++ users, this routine is not very useful: since precise types must be know at compile time, this routine returns a std::variant v that could store a pointer to any class Face<dim, ...>. This means you cannot access the face directly: you will still need some kind of compile-time knowledge of subdim before you can extract and use an appropriate Face<dim, subdim> object from v. However, once you know subdim at compile time, you are better off using the (simpler and faster) routine face<subdim>() instead.

For Python users, this routine is much more useful: the return type can be chosen at runtime, and so this routine simply returns a Face<dim, subdim> object of the appropriate face dimension that you can use immediately.

The specific return type for C++ programmers will be std::variant<Face<dim, 0>*, ..., Face<dim, dim-1>*>.

Exceptions
InvalidArgumentThe face dimension subdim is outside the supported range (i.e., negative, or greater than or equal to dim).
Parameters
subdimthe face dimension; this must be between 0 and dim-1 inclusive.
indexthe index of the desired face, ranging from 0 to countFaces<subdim>()-1 inclusive.
Returns
the requested face.

◆ face() [2/2]

Face< dim, subdim > * regina::detail::TriangulationBase< dim >::face ( size_t  index) const
inlineinherited

Returns the requested subdim-face of this triangulation, in a way that is optimised for C++ programmers.

Python
Not present. Instead use the variant face(subdim, index).
Template Parameters
subdimthe face dimension; this must be between 0 and dim-1 inclusive.
Parameters
indexthe index of the desired face, ranging from 0 to countFaces<subdim>()-1 inclusive.
Returns
the requested face.

◆ faces() [1/2]

auto regina::detail::TriangulationBase< dim >::faces
inlineinherited

Returns an object that allows iteration through and random access to all subdim-faces of this triangulation, in a way that is optimised for C++ programmers.

The object that is returned is lightweight, and can be happily copied by value. The C++ type of the object is subject to change, so C++ users should use auto (just like this declaration does).

The returned object is guaranteed to be an instance of ListView, which means it offers basic container-like functions and supports range-based for loops. Note that the elements of the list will be pointers, so your code might look like:

for (Face<dim, subdim>* f : tri.faces<subdim>()) { ... }

The object that is returned will remain up-to-date and valid for as long as the triangulation exists. In contrast, however, remember that the individual faces within this list will be deleted and replaced each time the triangulation changes. Therefore it is best to treat this object as temporary only, and to call faces() again each time you need it.

Python
Not present. Instead use the variant faces(subdim).
Template Parameters
subdimthe face dimension; this must be between 0 and dim-1 inclusive.
Returns
access to the list of all subdim-faces.

◆ faces() [2/2]

auto regina::detail::TriangulationBase< dim >::faces ( int  subdim) const
inlineinherited

Returns an object that allows iteration through and random access to all subdim-faces of this triangulation, in a way that is optimised for Python programmers.

C++ users should not use this routine. The return type must be fixed at compile time, and so it is a std::variant that can hold any of the lightweight return types from the templated faces<subdim>() function. This means that the return value will still need compile-time knowledge of subdim to extract and use the appropriate face objects. However, once you know subdim at compile time, you are much better off using the (simpler and faster) routine faces<subdim>() instead.

For Python users, this routine is much more useful: the return type can be chosen at runtime, and so this routine returns a Python list of Face<dim, subdim> objects (holding all the subdim-faces of the triangulation), which you can use immediately.

Exceptions
InvalidArgumentThe face dimension subdim is outside the supported range (i.e., negative, or greater than or equal to dim).
Parameters
subdimthe face dimension; this must be between 0 and dim-1 inclusive.
Returns
access to the list of all subdim-faces.

◆ findAllIsomorphisms()

bool regina::detail::TriangulationBase< dim >::findAllIsomorphisms ( const Triangulation< dim > &  other,
Action &&  action,
Args &&...  args 
) const
inlineinherited

Finds all ways in which this triangulation is combinatorially isomorphic to the given triangulation.

This routine behaves identically to isIsomorphicTo(), except that instead of returning just one isomorphism, all such isomorphisms will be found and processed. See the isIsomorphicTo() notes for details on this.

For each isomorphism that is found, this routine will call action (which must be a function or some other callable object).

  • The first argument to action must be of type (const Isomorphism<dim>&); this will be a reference to the isomorphism that was found. If action wishes to keep the isomorphism, it should take a deep copy (not a reference), since the isomorphism may be changed and reused after action returns.
  • If there are any additional arguments supplied in the list args, then these will be passed as subsequent arguments to action.
  • action must return a bool. A return value of false indicates that the search for isomorphisms should continue, and a return value of true indicates that the search should terminate immediately.
  • This triangulation must remain constant while the search runs (i.e., action must not modify the triangulation).
Warning
For large dimensions, this routine can become extremely slow: its running time includes a factor of (dim+1)!.
Python
There are two versions of this function available in Python. The first form is findAllIsomorphisms(other, action), which mirrors the C++ function: it takes action which may be a pure Python function, the return value indicates whether action ever terminated the search, but it does not take an additonal argument list (args). The second form is findAllIsomorphisms(other), which returns a Python list containing all of the isomorphisms that were found.
Parameters
otherthe triangulation to compare with this one.
actiona function (or other callable object) to call for each isomorphism that is found.
argsany additional arguments that should be passed to action, following the initial isomorphism argument.
Returns
true if action ever terminated the search by returning true, or false if the search was allowed to run to completion.

◆ findAllSubcomplexesIn()

bool regina::detail::TriangulationBase< dim >::findAllSubcomplexesIn ( const Triangulation< dim > &  other,
Action &&  action,
Args &&...  args 
) const
inlineinherited

Finds all ways in which an isomorphic copy of this triangulation is contained within the given triangulation, possibly as a subcomplex of some larger component (or components).

This routine behaves identically to isContainedIn(), except that instead of returning just one isomorphism (which may be boundary incomplete and need not be onto), all such isomorphisms will be found and processed. See the isContainedIn() notes for details on this.

For each isomorphism that is found, this routine will call action (which must be a function or some other callable object).

  • The first argument to action must be of type (const Isomorphism<dim>&); this will be a reference to the isomorphism that was found. If action wishes to keep the isomorphism, it should take a deep copy (not a reference), since the isomorphism may be changed and reused after action returns.
  • If there are any additional arguments supplied in the list args, then these will be passed as subsequent arguments to action.
  • action must return a bool. A return value of false indicates that the search for isomorphisms should continue, and a return value of true indicates that the search should terminate immediately.
  • This triangulation must remain constant while the search runs (i.e., action must not modify the triangulation).
Warning
For large dimensions, this routine can become extremely slow: its running time includes a factor of (dim+1)!.
Python
There are two versions of this function available in Python. The first form is findAllSubcomplexesIn(other, action), which mirrors the C++ function: it takes action which may be a pure Python function, the return value indicates whether action ever terminated the search, but it does not take an additonal argument list (args). The second form is findAllSubcomplexesIn(other), which returns a Python list containing all of the isomorphisms that were found.
Parameters
otherthe triangulation in which to search for isomorphic copies of this triangulation.
actiona function (or other callable object) to call for each isomorphism that is found.
argsany additional arguments that should be passed to action, following the initial isomorphism argument.
Returns
true if action ever terminated the search by returning true, or false if the search was allowed to run to completion.

◆ finiteToIdeal()

bool regina::detail::TriangulationBase< dim >::finiteToIdeal
inherited

Converts each real boundary component into a cusp (i.e., an ideal vertex).

Only boundary components formed from real (dim-1)-faces will be affected; ideal boundary components are already cusps and so will not be changed.

One side-effect of this operation is that all spherical boundary components will be filled in with balls.

This operation is performed by attaching a new dim-simplex to each boundary (dim-1)-face, and then gluing these new simplices together in a way that mirrors the adjacencies of the underlying boundary facets. Each boundary component will thereby be pushed up through the new simplices and converted into a cusp formed using vertices of these new simplices.

In Regina's standard dimensions, where triangulations also support an idealToFinite() operation, this routine is a loose converse of that operation.

In dimension 2, every boundary component is spherical and so this routine simply fills all the punctures in the underlying surface. (In dimension 2, triangulations cannot have cusps).

Warning
If a real boundary component contains vertices whose links are not discs, this operation may have unexpected results.
Returns
true if changes were made, or false if the original triangulation contained no real boundary components.

◆ fourFourMove()

bool regina::Triangulation< 4 >::fourFourMove ( Edge< 4 > *  e,
bool  check = true,
bool  perform = true 
)

Checks the eligibility of and/or performs a 4-4 move about the given edge.

This involves replacing the four pentachora joined at that edge with four new pentachora joined along a new edge a. In more detail, the original configuration of four pentachora should be equivalent to the join of a double edge and a square with diagonal given by the edge e. The 4-4 move essentially performs a 2-2 move on this square, with the new diagonal corresponding precisely to the new edge a. This move can be done if:

  • the link of edge e is a 2-2 move away from being combinatorially isomorphic to the boundary of a tetrahedron, and
  • the four pentachora joined at e are distinct.

If the routine is asked to both check and perform, the move will only be performed if the check shows it is legal.

If this triangulation is currently oriented, then this 4-4 move will label the new pentachora in a way that preserves the orientation.

Note that after performing this move, all skeletal objects (triangles, components, etc.) will be reconstructed, which means any pointers to old skeletal objects (such as the argument e) can no longer be used.

Precondition
If the move is being performed and no check is being run, it must be known in advance that the move is legal.
The given edge e is an edge of this triangulation.
Parameters
ethe edge about which to perform the move.
checktrue if we are to check whether the move is allowed (defaults to true).
performtrue if we are to perform the move (defaults to true).
Returns
If check is true, the function returns true if and only if the requested move may be performed without changing the topology of the manifold. If check is false, the function simply returns true.
Author
Alex He

◆ fromGluings() [1/2]

Triangulation< dim > regina::detail::TriangulationBase< dim >::fromGluings ( size_t  size,
Iterator  beginGluings,
Iterator  endGluings 
)
staticinherited

Creates a triangulation from a list of gluings.

This routine is an analogue to the variant of fromGluings() that takes a C++ initialiser list; however, here the input data may be constructed at runtime (which makes it accessible to Python, amongst other things).

The iterator range (beginGluings, endGluings) should encode the list of gluings for the triangulation. Each iterator in this range must dereference to a tuple of the form (simp, facet, adj, gluing); here simp, facet and adj are all integers, and gluing is of type Perm<dim+1>. Each such tuple indicates that facet facet of top-dimensional simplex number simp should be glued to top-dimensional simplex number adj using the permutation gluing. In other words, such a tuple encodes the same information as calling simplex(simp).join(facet, simplex(adj), gluing) upon the triangulation being constructed.

Every gluing should be encoded from one direction only. This means, for example, that to build a closed 3-manifold triangulation with n tetrahedra, you would pass a list of 2n such tuples. If you attempt to make the same gluing twice (e.g., once from each direction), then this routine will throw an exception.

Any facet of a simplex that does not feature in the given list of gluings (either as a source or a destination) will be left as a boundary facet.

Note that, as usual, the top-dimensional simplices are numbered 0,...,(size-1), and the facets of each simplex are numbered 0,...,dim.

As an example, Python users can construct the figure eight knot complement as follows:

tri = Triangulation3.fromGluings(2, [
( 0, 0, 1, Perm4(1,3,0,2) ), ( 0, 1, 1, Perm4(2,0,3,1) ),
( 0, 2, 1, Perm4(0,3,2,1) ), ( 0, 3, 1, Perm4(2,1,0,3) )])
Note
The assumption is that the iterators dereference to a std::tuple<size_t, int, size_t, Perm<dim+1>>. However, this is not strictly necessary - the dereferenced type may be any type that supports std::get (and for which std::get<0..3>() yields suitable integer/permutation types).
Exceptions
InvalidArgumentThe given list of gluings does not correctly describe a triangulation with size top-dimensional simplices.
Python
The gluings should be passed as a single Python list of tuples (not an iterator pair).
Parameters
sizethe number of top-dimensional simplices in the triangulation to construct.
beginGluingsthe beginning of the list of gluings, as described above.
endGluingsa past-the-end iterator indicating the end of the list of gluings.
Returns
the reconstructed triangulation.

◆ fromGluings() [2/2]

Triangulation< dim > regina::detail::TriangulationBase< dim >::fromGluings ( size_t  size,
std::initializer_list< std::tuple< size_t, int, size_t, Perm< dim+1 > > >  gluings 
)
inlinestaticinherited

Creates a triangulation from a hard-coded list of gluings.

This routine takes a C++ initialiser list, which makes it useful for creating hard-coded examples directly in C++ code without needing to write a tedious sequence of calls to Simplex<dim>::join().

Each element of the initialiser list should be a tuple of the form (simp, facet, adj, gluing), which indicates that facet facet of top-dimensional simplex number simp should be glued to top-dimensional simplex number adj using the permutation gluing. In other words, such a tuple encodes the same information as calling simplex(simp).join(facet, simplex(adj), gluing) upon the triangulation being constructed.

Every gluing should be encoded from one direction only. This means, for example, that to build a closed 3-manifold triangulation with n tetrahedra, you would pass a list of 2n such tuples. If you attempt to make the same gluing twice (e.g., once from each direction), then this routine will throw an exception.

Any facet of a simplex that does not feature in the given list of gluings (either as a source or a destination) will be left as a boundary facet.

Note that, as usual, the top-dimensional simplices are numbered 0,...,(size-1), and the facets of each simplex are numbered 0,...,dim.

As an example, you can construct the figure eight knot complement using the following code:

Triangulation<3> tri = Triangulation<3>::fromGluings(2, {
{ 0, 0, 1, {1,3,0,2} }, { 0, 1, 1, {2,0,3,1} },
{ 0, 2, 1, {0,3,2,1} }, { 0, 3, 1, {2,1,0,3} }});
static Triangulation< dim > fromGluings(size_t size, std::initializer_list< std::tuple< size_t, int, size_t, Perm< dim+1 > > > gluings)
Creates a triangulation from a hard-coded list of gluings.
Definition: triangulation.h:4293
Note
If you have an existing triangulation that you would like to hard-code in this way, you can call dumpConstruction() to generate the corresponding C++ source code.
Exceptions
InvalidArgumentThe given list of gluings does not correctly describe a triangulation with size top-dimensional simplices.
Python
Not present. Instead, use the variant of fromGluings() that takes this same data using a Python list (which need not be constant).
Parameters
sizethe number of top-dimensional simplices in the triangulation to construct.
gluingsdescribes the gluings between these top-dimensional simplices, as described above.
Returns
the reconstructed triangulation.

◆ fromIsoSig()

static Triangulation< dim > regina::detail::TriangulationBase< dim >::fromIsoSig ( const std::string &  sig)
staticinherited

Recovers a full triangulation from an isomorphism signature.

See isoSig() for more information on isomorphism signatures. It will be assumed that the signature describes a triangulation of dimension dim.

Currently this routine only supports isomorphism signatures that were created with the default encoding (i.e., there was no Encoding template parameter passed to isoSig()).

Calling isoSig() followed by fromIsoSig() is not guaranteed to produce an identical triangulation to the original, but it is guaranteed to produce a combinatorially isomorphic triangulation. In other words, fromIsoSig() may reconstruct the triangulation with its simplices and/or vertices relabelled. The optional argument to isoSig() allows you to determine the precise relabelling that will be used, if you need to know it.

For a full and precise description of the isomorphism signature format for 3-manifold triangulations, see Simplification paths in the Pachner graphs of closed orientable 3-manifold triangulations, Burton, 2011, arXiv:1110.6080. The format for other dimensions is essentially the same, but with minor dimension-specific adjustments.

Warning
Do not mix isomorphism signatures between dimensions! It is possible that the same string could corresponding to both a p-dimensional triangulation and a q-dimensional triangulation for different dimensions p and q.
Exceptions
InvalidArgumentThe given string was not a valid dim-dimensional isomorphism signature created using the default encoding.
Parameters
sigthe isomorphism signature of the triangulation to construct. Note that isomorphism signatures are case-sensitive (unlike, for example, dehydration strings for 3-manifolds).
Returns
the reconstructed triangulation.

◆ fromSig()

Triangulation< dim > regina::detail::TriangulationBase< dim >::fromSig ( const std::string &  sig)
inlinestaticinherited

Alias for fromIsoSig(), to recover a full triangulation from an isomorphism signature.

This alias fromSig() is provided to assist with generic code that can work with both triangulations and links.

See fromIsoSig() for further details.

Exceptions
InvalidArgumentThe given string was not a valid dim-dimensional isomorphism signature created using the default encoding.
Parameters
sigthe isomorphism signature of the triangulation to construct. Note that isomorphism signatures are case-sensitive (unlike, for example, dehydration strings for 3-manifolds).
Returns
the reconstructed triangulation.

◆ fundamentalGroup()

const GroupPresentation & regina::detail::TriangulationBase< dim >::fundamentalGroup
inlineinherited

An alias for group(), which returns the fundamental group of this triangulation.

See group() for further details, including how ideal vertices and invalid faces are managed.

Note
In Regina 7.2, the routine fundamentalGroup() was renamed to group() for brevity and for consistency with Link::group(). This more expressive name fundamentalGroup() will be kept as a long-term alias, and you are welcome to continue using it if you prefer.
Precondition
This triangulation has at most one component.
Warning
In dimension 3, if you are calling this from the subclass SnapPeaTriangulation then any fillings on the cusps will be ignored. (This is the same as for every routine implemented by Regina's Triangulation<3> class.) If you wish to compute the fundamental group with fillings, call SnapPeaTriangulation::fundamentalGroupFilled() instead.
Returns
the fundamental group.

◆ fVector()

std::vector< size_t > regina::detail::TriangulationBase< dim >::fVector
inlineinherited

Returns the f-vector of this triangulation, which counts the number of faces of all dimensions.

The vector that is returned will have length dim+1. If this vector is f, then f[k] will be the number of k-faces for each 0 ≤ kdim.

This routine is significantly more heavyweight than countFaces(). Its advantage is that, unlike the templatised countFaces(), it allows you to count faces whose dimensions are not known until runtime.

Returns
the f-vector of this triangulation.

◆ group()

const GroupPresentation & regina::detail::TriangulationBase< dim >::group ( ) const
inherited

Returns the fundamental group of this triangulation.

The fundamental group is computed in the dual 2-skeleton. This means:

  • If the triangulation contains any ideal vertices, the fundamental group will be calculated as if each such vertex had been truncated.
  • Likewise, if the triangulation contains any invalid faces of dimension 0,1,...,(dim-3), these will effectively be truncated also.
  • In contrast, if the triangulation contains any invalid (dim-2)-faces (i.e., codimension-2-faces that are identified with themselves under a non-trivial map), the fundamental group will be computed without truncating the centroid of the face. For instance, if a 3-manifold triangulation has an edge identified with itself in reverse, then the fundamental group will be computed without truncating the resulting projective plane cusp. This means that, if a barycentric subdivision is performed on a such a triangulation, the result of group() might change.

Bear in mind that each time the triangulation changes, the fundamental group will be deleted. Thus the reference that is returned from this routine should not be kept for later use. Instead, group() should be called again; this will be instantaneous if the group has already been calculated.

Before Regina 7.2, this routine was called fundamentalGroup(). It has since been renamed to group() for brevity and for consistency with Link::group(). The more expressive name fundamentalGroup() will be kept, and you are welcome to use that instead if you prefer.

Precondition
This triangulation has at most one component.
Warning
In dimension 3, if you are calling this from the subclass SnapPeaTriangulation then any fillings on the cusps will be ignored. (This is the same as for every routine implemented by Regina's Triangulation<3> class.) If you wish to compute the fundamental group with fillings, call SnapPeaTriangulation::fundamentalGroupFilled() instead.
Returns
the fundamental group.

◆ hasBoundaryFacets()

bool regina::detail::TriangulationBase< dim >::hasBoundaryFacets
inlineinherited

Determines if this triangulation has any boundary facets.

This routine returns true if and only if the triangulation contains some top-dimension simplex with at least one facet that is not glued to an adjacent simplex.

Returns
true if and only if there are boundary facets.

◆ hasBoundaryTetrahedra()

bool regina::Triangulation< 4 >::hasBoundaryTetrahedra ( ) const
inline

A dimension-specific alias for hasBoundaryFacets().

See hasBoundaryFacets() for further information.

◆ homology() [1/2]

AbelianGroup regina::detail::TriangulationBase< dim >::homology ( ) const
inherited

Returns the kth homology group of this triangulation, treating any ideal vertices as though they had been truncated.

For C++ programmers who know subdim at compile time, you should use this template function homology<subdim>(), which is slightly faster than passing subdim as an ordinary runtime argument to homology(subdim).

See the non-templated homology(int) for full details on exactly what this function computes.

Precondition
Unless you are computing first homology (k = 1), this triangulation must be valid, and every face that is not a vertex must have a ball or sphere link. The link condition already forms part of the validity test if dim is one of Regina's standard dimensions, but in higher dimensions it is the user's own responsibility to ensure this. See isValid() for details.
Exceptions
FailedPreconditionThis triangulation is invalid, and the homology dimension k is not 1.
Python
Not present. Instead use the variant homology(k).
Template Parameters
kthe dimension of the homology group to return; this must be between 1 and (dim - 1) inclusive if dim is one of Regina's standard dimensions, or between 1 and (dim - 2) inclusive if not.
Returns
the kth homology group.

◆ homology() [2/2]

AbelianGroup regina::detail::TriangulationBase< dim >::homology ( int  k) const
inlineinherited

Returns the kth homology group of this triangulation, treating any ideal vertices as though they had been truncated, where the parameter k does not need to be known until runtime.

For C++ programmers who know k at compile time, you are better off using the template function homology<k>() instead, which is slightly faster.

A problem with computing homology is that, if dim is not one of Regina's standard dimensions, then Regina cannot actually detect ideal vertices (since in general this requires solving undecidable problems). Currently we resolve this by insisting that, in higher dimensions, the homology dimension k is at most (dim-2); the underlying algorithm will then effectively truncate all vertices (since truncating "ordinary" vertices whose links are spheres or balls does not affect the kth homology in such cases).

In general, this routine insists on working with a valid triangulation (see isValid() for what this means). However, for historical reasons, if you are computing first homology (k = 1) then your triangulation is allowed to be invalid, though the results might or might not be useful to you. The homology will be computed using the dual skeleton: what this means is that any invalid faces of dimension 0,1,...,(dim-3) will be treated as though their centroids had been truncated, but any invalid (dim-2)-faces will be treated without such truncation. A side-effect is that, after performing a barycentric on an invalid triangulation, the group returned by homology<1>() might change.

Warning
In dimension 3, if you are calling this from the subclass SnapPeaTriangulation then any fillings on the cusps will be ignored. (This is the same as for every routine implemented by Regina's Triangulation<3> class.) If you wish to compute homology with fillings, call SnapPeaTriangulation::homologyFilled() instead.
Precondition
Unless you are computing first homology (k = 1), this triangulation must be valid, and every face that is not a vertex must have a ball or sphere link. The link condition already forms part of the validity test if dim is one of Regina's standard dimensions, but in higher dimensions it is the user's own responsibility to ensure this. See isValid() for details.
Exceptions
FailedPreconditionThis triangulation is invalid, and the homology dimension k is not 1.
InvalidArgumentThe homology dimension k is outside the supported range. This range depends upon the triangulation dimension dim; for details see the documentation below for the argument k.
Python
Like the C++ template function homology<k>(), you can omit the homology dimension k; this will default to 1.
Parameters
kthe dimension of the homology group to return; this must be between 1 and (dim - 1) inclusive if dim is one of Regina's standard dimensions, or between 1 and (dim - 2) inclusive if not.
Returns
the kth homology group.

◆ idealToFinite()

bool regina::Triangulation< 4 >::idealToFinite ( )

Converts an ideal triangulation into a finite triangulation.

All ideal or invalid vertices are truncated and thus converted into real boundary components made from unglued facets of pentachora.

Returns
true if and only if the triangulation was changed.

◆ insertTriangulation()

void regina::detail::TriangulationBase< dim >::insertTriangulation ( const Triangulation< dim > &  source)
inherited

Inserts a copy of the given triangulation into this triangulation.

The top-dimensional simplices of source will be copied into this triangulation in the same order in which they appear in source. That is, if the original size of this triangulation was S, then the simplex at index i in source will be copied into this triangulation as a new simplex at index S+i.

The copies will use the same vertex numbering and descriptions as the original simplices from source, and any gluings between the simplices of source will likewise be copied across as gluings between their copies in this triangulation.

This routine behaves correctly when source is this triangulation.

Parameters
sourcethe triangulation whose copy will be inserted.

◆ intelligentSimplify()

bool regina::Triangulation< 4 >::intelligentSimplify ( )

Attempts to simplify the triangulation as intelligently as possible without further input.

Specifically, this routine will attempt to reduce the number of pentachora in the triangulation.

Currently this routine uses simplifyToLocalMinimum() in combination with random 3-3 moves and book opening moves.

If this triangulation is currently oriented, then this operation will preserve the orientation.

Warning
The specific behaviour of this routine will almost certainly change between releases. At present, simplification for 4-manifold triangulations is extremely weak (as opposed to 3-manifolds, where a rich library of simplification techinques is available to call upon).
Returns
true if and only if the triangulation was changed.

◆ intersectionForm()

IntersectionForm regina::Triangulation< 4 >::intersectionForm ( ) const

Returns the intersection form of this 4-manifold.

The intersection form is stored as a square matrix with respect to an arbitrary basis of the second homology group; you can access this matrix via IntersectionForm::matrix(). This matrix is guaranteed to be symmetric and unimodular, but will not be normalised in any way. You can, however, query invariants of the intersection form via routines such as IntersectionForm::signature() and IntersectionForm::even(), which in the simply connected case are enough to determine the topology of the underlying 4-manifold.

(As an implementation detail, the basis is currently chosen to be the one produced by constructing a MarkedAbelianGroup using the boundary maps on the dual faces. This specific choice of basis is subject to change in future releases of Regina.)

The sign convention for counting intersections is as follows: in a pentachoron with positive orientation and vertices (0,1,2,3,4), the triangles with ordered vertices (0,1,2) and ordered vertices (2,3,4) have positive intersection.

Precondition
This triangulation is valid, non-empty, orientable and closed.
Exceptions
FailedPreconditionThis triangulation is invalid, empty, non-orientable, or not closed.
Returns
the intersection form of this 4-manifold.

◆ isClosed()

bool regina::Triangulation< 4 >::isClosed ( ) const
inline

Determines if this triangulation is closed.

This is the case if and only if it has no boundary components.

Note that ideal triangulations are not closed. Triangulations with invalid vertices are also considered not closed; see Vertex<4>::isBoundary() for details.

Returns
true if and only if this triangulation is closed.

◆ isConnected()

bool regina::detail::TriangulationBase< dim >::isConnected
inlineinherited

Determines if this triangulation is connected.

This routine returns false only if there is more than one connected component. In particular, it returns true for the empty triangulation.

Returns
true if and only if this triangulation is connected.

◆ isContainedIn()

std::optional< Isomorphism< dim > > regina::detail::TriangulationBase< dim >::isContainedIn ( const Triangulation< dim > &  other) const
inlineinherited

Determines if an isomorphic copy of this triangulation is contained within the given triangulation, possibly as a subcomplex of some larger component (or components).

Specifically, this routine determines if there is a boundary incomplete combinatorial isomorphism from this triangulation to other. Boundary incomplete isomorphisms are described in detail in the Isomorphism class notes.

In particular, note that facets of top-dimensional simplices that lie on the boundary of this triangulation need not correspond to boundary facets of other, and that other may contain more top-dimensional simplices than this triangulation.

If a boundary incomplete isomorphism is found, the details of this isomorphism are returned. Thus, to test whether an isomorphism exists, you can just call if (isContainedIn(other)).

If more than one such isomorphism exists, only one will be returned. For a routine that returns all such isomorphisms, see findAllSubcomplexesIn().

Warning
For large dimensions, this routine can become extremely slow: its running time includes a factor of (dim+1)!.
Parameters
otherthe triangulation in which to search for an isomorphic copy of this triangulation.
Returns
details of the isomorphism if such a copy is found, or no value otherwise.

◆ isEmpty()

bool regina::detail::TriangulationBase< dim >::isEmpty
inlineinherited

Determines whether this triangulation is empty.

An empty triangulation is one with no simplices at all.

Returns
true if and only if this triangulation is empty.

◆ isIdeal()

bool regina::Triangulation< 4 >::isIdeal ( ) const
inline

Determines if this triangulation is ideal.

A triangulation is ideal if and only if (i) the triangulation is valid, and (ii) one of the vertex links is closed but not a 3-sphere.

Note that for 4-manifolds, isIdeal() will only return true if the triangulation is valid (unlike 3-manifolds, where invalid ideal triangulations are allowed). This is to avoid situations like 4-manifold vertices whose links are cusped 3-manifolds (a situation that has no analogue in lower dimensions).

Returns
true if and only if this triangulation is ideal.

◆ isIsomorphicTo()

std::optional< Isomorphism< dim > > regina::detail::TriangulationBase< dim >::isIsomorphicTo ( const Triangulation< dim > &  other) const
inlineinherited

Determines if this triangulation is combinatorially isomorphic to the given triangulation.

Two triangulations are isomorphic if and only it is possible to relabel their top-dimensional simplices and the (dim+1) vertices of each simplex in a way that makes the two triangulations combinatorially identical, as returned by isIdenticalTo().

Equivalently, two triangulations are isomorphic if and only if there is a one-to-one and onto boundary complete combinatorial isomorphism from this triangulation to other, as described in the Isomorphism class notes.

In particular, note that this triangulation and other must contain the same number of top-dimensional simplices for such an isomorphism to exist.

If the triangulations are isomorphic, then this routine returns one such boundary complete isomorphism (i.e., one such relabelling). Otherwise it returns no value. Thus, to test whether an isomorphism exists, you can just call if (isIsomorphicTo(other)).

There may be many such isomorphisms between the two triangulations. If you need to find all such isomorphisms, you may call findAllIsomorphisms() instead.

If you need to ensure that top-dimensional simplices are labelled the same in both triangulations (i.e., that the triangulations are related by the identity isomorphism), you should call the stricter test isIdenticalTo() instead.

Warning
For large dimensions, this routine can become extremely slow: its running time includes a factor of (dim+1)!.
Todo:
Optimise: Improve the complexity by choosing a simplex mapping from each component and following gluings to determine the others.
Parameters
otherthe triangulation to compare with this one.
Returns
details of the isomorphism if the two triangulations are combinatorially isomorphic, or no value otherwise.

◆ isOrientable()

bool regina::detail::TriangulationBase< dim >::isOrientable
inlineinherited

Determines if this triangulation is orientable.

Returns
true if and only if this triangulation is orientable.

◆ isOriented()

bool regina::detail::TriangulationBase< dim >::isOriented
inherited

Determines if this triangulation is oriented; that is, if the vertices of its top-dimensional simplices are labelled in a way that preserves orientation across adjacent facets.

Specifically, this routine returns true if and only if every gluing permutation has negative sign.

Note that orientable triangulations are not always oriented by default. You can call orient() if you need the top-dimensional simplices to be oriented consistently as described above.

A non-orientable triangulation can never be oriented.

Returns
true if and only if all top-dimensional simplices are oriented consistently.
Author
Matthias Goerner

◆ isoSig()

Encoding::Signature regina::detail::TriangulationBase< dim >::isoSig ( ) const
inherited

Constructs the isomorphism signature of the given type for this triangulation.

Support for different types of signature is new to Regina 7.0 (see below for details); all isomorphism signatures created in Regina 6.0.1 or earlier are of the default type IsoSigClassic.

An isomorphism signature is a compact representation of a triangulation that uniquely determines the triangulation up to combinatorial isomorphism. That is, for any fixed signature type T, two triangulations of dimension dim are combinatorially isomorphic if and only if their isomorphism signatures of type T are the same.

The length of an isomorphism signature is proportional to n log n, where n is the number of top-dimenisonal simplices. The time required to construct it is worst-case O((dim!) n² log² n). Whilst this is fine for large triangulations, it becomes very slow for large dimensions; the main reason for introducing different signature types is that some alternative types can be much faster to compute in practice.

Whilst the format of an isomorphism signature bears some similarity to dehydration strings for 3-manifolds, they are more general: isomorphism signatures can be used with any triangulations, including closed, bounded and/or disconnected triangulations, as well as triangulations with many simplices. Note also that 3-manifold dehydration strings are not unique up to isomorphism (they depend on the particular labelling of tetrahedra).

The routine fromIsoSig() can be used to recover a triangulation from an isomorphism signature (only if the default encoding has been used, but it does not matter which signature type was used). The triangulation recovered might not be identical to the original, but it will be combinatorially isomorphic. If you need the precise relabelling, you can call isoSigDetail() instead.

Regina supports several different variants of isomorphism signatures, which are tailored to different computational needs; these are currently determined by the template parameters Type and Encoding:

  • The Type parameter identifies which signature type is to be constructed. Essentially, different signature types use different rules to determine which labelling of a triangulation is "canonical". The default type IsoSigClassic is slow (it never does better than the worst-case time described above); its main advantage is that it is consistent with the original implementation of isomorphism signatures in Regina 4.90.
  • The Encoding parameter controls how Regina encodes a canonical labelling into a final signature. The default encoding IsoSigPrintable returns a std::string consisting entirely of printable characters in the 7-bit ASCII range. Importantly, this default encoding is currently the only encoding from which Regina can reconstruct a triangulation from its isomorphism signature.

You may instead pass your own type and/or encoding parameters as template arguments. Currently this facility is for internal use only, and the requirements for type and encoding parameters may change in future versions of Regina. At present:

  • The Type parameter should be a class that is constructible from a componenent reference, and that offers the member functions simplex(), perm() and next(); see the implementation of IsoSigClassic for details.
  • The Encoding parameter should be a class that offers a Signature type alias, and static functions emptySig() and encode(). See the implementation of IsoSigPrintable for details.

For a full and precise description of the classic isomorphism signature format for 3-manifold triangulations, see Simplification paths in the Pachner graphs of closed orientable 3-manifold triangulations, Burton, 2011, arXiv:1110.6080. The format for other dimensions is essentially the same, but with minor dimension-specific adjustments.

Python
Although this is a templated function, all of the variants supplied with Regina are available to Python users. For the default type and encoding, you can simply call isoSig(). For other signature types, you should call the function as isoSig_Type, where the suffix Type is an abbreviated version of the Type template parameter; one such example is isoSig_EdgeDegrees (for the case where Type is the class IsoSigEdgeDegrees). Currently Regina only offers one encoding (the default), and so there are no suffixes for encodings.
Warning
Do not mix isomorphism signatures between dimensions! It is possible that the same string could corresponding to both a p-dimensional triangulation and a q-dimensional triangulation for different dimensions p and q.
Returns
the isomorphism signature of this triangulation.

◆ isoSigComponentSize()

static size_t regina::detail::TriangulationBase< dim >::isoSigComponentSize ( const std::string &  sig)
staticinherited

Deduces the number of top-dimensional simplices in a connected triangulation from its isomorphism signature.

See isoSig() for more information on isomorphism signatures. It will be assumed that the signature describes a triangulation of dimension dim.

Currently this routine only supports isomorphism signatures that were created with the default encoding (i.e., there was no Encoding template parameter passed to isoSig()).

If the signature describes a connected triangulation, this routine will simply return the size of that triangulation (e.g., the number of tetrahedra in the case dim = 3). You can also pass an isomorphism signature that describes a disconnected triangulation; however, this routine will only return the number of top-dimensional simplices in the first connected component. If you need the total size of a disconnected triangulation, you will need to reconstruct the full triangulation by calling fromIsoSig() instead.

This routine is very fast, since it only examines the first few characters of the isomorphism signature (in which the size of the first component is encoded). However, a side-effect of this is that it is possible to pass an invalid isomorphism signature and still receive a positive result. If you need to test whether a signature is valid or not, you must call fromIsoSig() instead, which will examine the entire signature in full.

Warning
Do not mix isomorphism signatures between dimensions! It is possible that the same string could corresponding to both a p-dimensional triangulation and a q-dimensional triangulation for different dimensions p and q.
Parameters
sigthe isomorphism signature of a dim-dimensional triangulation. Note that isomorphism signature are case-sensitive (unlike, for example, dehydration strings for 3-manifolds).
Returns
the number of top-dimensional simplices in the first connected component, or 0 if this could not be determined because the given string was not a valid isomorphism signature created using the default encoding.

◆ isoSigDetail()

std::pair< typename Encoding::Signature, Isomorphism< dim > > regina::detail::TriangulationBase< dim >::isoSigDetail ( ) const
inherited

Constructs the isomorphism signature for this triangulation, along with the relabelling that will occur when the triangulation is reconstructed from it.

Essentially, an isomorphism signature is a compact representation of a triangulation that uniquely determines the triangulation up to combinatorial isomorphism. See isoSig() for much more detail on isomorphism signatures as well as the support for different signature types and encodings.

As described in the isoSig() notes, you can call fromIsoSig() to recover a triangulation from an isomorphism signature (assuming the default encoding was used). Whilst the triangulation that is recovered will be combinatorially isomorphic to the original, it might not be identical. This routine returns not only the isomorphism signature, but also an isomorphism that describes the precise relationship between this triangulation and the reconstruction from fromIsoSig().

Specifically, if this routine returns the pair (sig, relabelling), this means that the triangulation reconstructed from fromIsoSig(sig) will be identical to relabelling(this).

Python
Although this is a templated function, all of the variants supplied with Regina are available to Python users. For the default type and encoding, you can simply call isoSigDetail(). For other signature types, you should call the function as isoSigDetail_Type, where the suffix Type is an abbreviated version of the Type template parameter; one such example is isoSigDetail_EdgeDegrees (for the case where Type is the class IsoSigEdgeDegrees). Currently Regina only offers one encoding (the default), and so there are no suffixes for encodings.
Precondition
This triangulation must be non-empty and connected. The facility to return a relabelling for disconnected triangulations may be added to Regina in a later release.
Exceptions
FailedPreconditionThis triangulation is either empty or disconnected.
Returns
a pair containing (i) the isomorphism signature of this triangulation, and (ii) the isomorphism between this triangulation and the triangulation that would be reconstructed from fromIsoSig().

◆ isReadOnlySnapshot()

bool regina::Snapshottable< Triangulation< dim > >::isReadOnlySnapshot ( ) const
inlineinherited

Determines if this object is a read-only deep copy that was created by a snapshot.

Recall that, if an image I of type T has a snapshot pointing to it, and if that image I is about to be modified or destroyed, then the snapshot will make an internal deep copy of I and refer to that instead.

The purpose of this routine is to identify whether the current object is such a deep copy. This may be important information, since a snapshot's deep copy is read-only: it must not be modified or destroyed by the outside world. (Of course the only way to access this deep copy is via const reference from the SnapshotRef dereference operators, but there are settings in which this constness is "forgotten", such as Regina's Python bindings.)

Returns
true if and only if this object is a deep copy that was taken by a Snapshot object of some original type T image.

◆ isValid()

bool regina::detail::TriangulationBase< dim >::isValid
inlineinherited

Determines if this triangulation is valid.

There are several conditions that might make a dim-dimensional triangulation invalid:

  1. if some face is identified with itself under a non-identity permutation (e.g., an edge is identified with itself in reverse, or a triangle is identified with itself under a rotation);
  2. if some subdim-face does not have an appropriate link. Here the meaning of "appropriate" depends upon the type of face:
    • for a face that belongs to some boundary facet(s) of this triangulation, its link must be a topological ball;
    • for a vertex that does not belong to any boundary facets, its link must be a closed (dim - 1)-manifold;
    • for a (subdim ≥ 1)-face that does not belong to any boundary facets, its link must be a topological sphere.

Condition (1) is tested for all dimensions dim. Condition (2) is more difficult, since it relies on undecidable problems. As a result, (2) is only tested when dim is one of Regina's standard dimensions.

If a triangulation is invalid then you can call Face<dim, subdim>::isValid() to discover exactly which face(s) are responsible, and you can call Face<dim, subdim>::hasBadIdentification() and/or Face<dim, subdim>::hasBadLink() to discover exactly which conditions fail.

Note that all invalid vertices are considered to be on the boundary; see isBoundary() for details.

Returns
true if and only if this triangulation is valid.

◆ linkingSurface()

template<int subdim>
std::pair< NormalHypersurface, bool > regina::Triangulation< 4 >::linkingSurface ( const Face< 4, subdim > &  face) const

Returns the link of the given face as a normal hypersurface.

Constructing the link of a face begins with building the frontier of a regular neighbourhood of the face. If this is already a normal hypersurface, then then link is called thin. Otherwise some basic normalisation steps are performed until the hypersurface becomes normal; note that these normalisation steps could change the topology of the hypersurface, and in some pathological cases could even reduce it to the empty hypersurface.

Although normalisation of arbitrary embedded 3-manifolds is messy, for face links the process is thankfully simpler. Essentially, any changes will be limited to operations analagous to compressions and boundary compressions along discs and 3-balls, as well as removing trivial 4-sphere components.

Template Parameters
subdimthe dimension of the face to link; this must be between 0 and 3 inclusive.
Precondition
The given face is a face of this triangulation.
Returns
a pair (s, thin), where s is the face linking normal hypersurface, and thin is true if and only if this link is thin (i.e., no additional normalisation steps were required).

◆ makeCanonical()

bool regina::detail::TriangulationBase< dim >::makeCanonical ( )
inherited

Relabel the top-dimensional simplices and their vertices so that this triangulation is in canonical form.

This is essentially the lexicographically smallest labelling when the facet gluings are written out in order.

Two triangulations are isomorphic if and only if their canonical forms are identical.

The lexicographic ordering assumes that the facet gluings are written in order of simplex index and then facet number. Each gluing is written as the destination simplex index followed by the gluing permutation (which in turn is written as the images of 0,1,...,dim in order).

Precondition
This routine currently works only when the triangulation is connected. It may be extended to work with disconnected triangulations in later versions of Regina.
Returns
true if the triangulation was changed, or false if the triangulation was in canonical form to begin with.

◆ makeDoubleCover()

void regina::detail::TriangulationBase< dim >::makeDoubleCover
inherited

Converts this triangulation into its double cover.

Each orientable component will be duplicated, and each non-orientable component will be converted into its orientable double cover.

◆ markedHomology() [1/2]

MarkedAbelianGroup regina::detail::TriangulationBase< dim >::markedHomology
inlineinherited

Returns the kth homology group of this triangulation, without truncating ideal vertices, but with explicit coordinates that track the individual k-faces of this triangulation.

For C++ programmers who know subdim at compile time, you should use this template function markedHomology<subdim>(), which is slightly faster than passing subdim as an ordinary runtime argument to markedHomology(subdim).

See the non-templated markedHomology(int) for full details on what this function computes, some important caveats to be aware of, and how the group that it returns should be interpreted.

Precondition
This triangulation is valid and non-empty.
Exceptions
FailedPreconditionThis triangulation is empty or invalid.
Python
Not present. Instead use the variant markedHomology(k).
Template Parameters
kthe dimension of the homology group to compute; this must be between 1 and (dim-1) inclusive.
Returns
the kth homology group of the union of all simplices in this triangulation, as described above.

◆ markedHomology() [2/2]

MarkedAbelianGroup regina::detail::TriangulationBase< dim >::markedHomology ( int  k) const
inlineinherited

Returns the kth homology group of this triangulation, without truncating ideal vertices, but with explicit coordinates that track the individual k-faces of this triangulation, where the parameter k does not need to be known until runtime.

For C++ programmers who know k at compile time, you are better off using the template function markedHomology<k>() instead, which is slightly faster.

This is a specialised homology routine; you should only use it if you need to understand how individual k-faces (or chains of k-faces) appear within the homology group.

  • The major disadvantage of this routine is that it does not truncate ideal vertices. Instead it computes the homology of the union of all top-dimensional simplices, working directly with the boundary maps between (k+1)-faces, k-faces and (k-1)-faces of the triangulation. If your triangulation is ideal, then this routine will almost certainly not give the correct homology group for the underlying manifold. If, however, all of your vertex links are spheres or balls (i.e., the triangulation is closed or all of its boundary components are built from unglued (dim-1)-faces), then the homology of the manifold will be computed correctly.
  • The major advantage is that, instead of returning a simpler AbelianGroup, this routine returns a MarkedAbelianGroup. This allows you to track chains of individual k-faces of the triangulation as they appear within the homology group. Specifically, the chain complex cordinates with this MarkedAbelianGroup represent precisely the k-faces of the triangulation in the same order as they appear in the list faces<k>(), using the inherent orientation provided by Face<dim, k>.
Precondition
This triangulation is valid and non-empty.
Exceptions
FailedPreconditionThis triangulation is empty or invalid.
InvalidArgumentThe homology dimension k is outside the supported range (i.e., less than 1 or greater than or equal to dim).
Python
Like the C++ template function markedHomology<k>(), you can omit the homology dimension k; this will default to 1.
Parameters
kthe dimension of the homology group to compute; this must be between 1 and (dim-1) inclusive.
Returns
the kth homology group of the union of all simplices in this triangulation, as described above.

◆ moveContentsTo()

void regina::detail::TriangulationBase< dim >::moveContentsTo ( Triangulation< dim > &  dest)
inherited

Moves the contents of this triangulation into the given destination triangulation, without destroying any pre-existing contents.

All top-dimensional simplices that currently belong to dest will remain there (and will keep the same indices in dest). All top-dimensional simplices that belong to this triangulation will be moved into dest also (but in general their indices will change).

This triangulation will become empty as a result.

Any pointers or references to Simplex<dim> objects will remain valid.

If your intention is to replace the simplices in dest (i.e., you do not need to preserve the original contents), then consider using the move assignment operator instead (which is more streamlined and also moves across any cached properties from the source triangulation).

Precondition
dest is not this triangulation.
Parameters
destthe triangulation into which simplices should be moved.

◆ newPentachora() [1/2]

template<int k>
std::array< Pentachoron< 4 > *, k > regina::Triangulation< 4 >::newPentachora
inline

A dimension-specific alias for newSimplices().

See newSimplices() for further information.

◆ newPentachora() [2/2]

void regina::Triangulation< 4 >::newPentachora ( size_t  k)
inline

A dimension-specific alias for newSimplices().

See newSimplices() for further information.

◆ newPentachoron() [1/2]

Pentachoron< 4 > * regina::Triangulation< 4 >::newPentachoron ( )
inline

A dimension-specific alias for newSimplex().

See newSimplex() for further information.

◆ newPentachoron() [2/2]

Pentachoron< 4 > * regina::Triangulation< 4 >::newPentachoron ( const std::string &  desc)
inline

A dimension-specific alias for newSimplex().

See newSimplex() for further information.

◆ newSimplex() [1/2]

Simplex< dim > * regina::detail::TriangulationBase< dim >::newSimplex
inherited

Creates a new top-dimensional simplex and adds it to this triangulation.

The new simplex will have an empty description. All (dim+1) facets of the new simplex will be boundary facets.

The new simplex will become the last simplex in this triangulation; that is, it will have index size()-1.

Returns
the new simplex.

◆ newSimplex() [2/2]

Simplex< dim > * regina::detail::TriangulationBase< dim >::newSimplex ( const std::string &  desc)
inherited

Creates a new top-dimensional simplex with the given description and adds it to this triangulation.

All (dim+1) facets of the new simplex will be boundary facets.

Descriptions are optional, may have any format, and may be empty. How descriptions are used is entirely up to the user.

The new simplex will become the last simplex in this triangulation; that is, it will have index size()-1.

Parameters
descthe description to give to the new simplex.
Returns
the new simplex.

◆ newSimplices() [1/2]

std::array< Simplex< dim > *, k > regina::detail::TriangulationBase< dim >::newSimplices
inherited

Creates k new top-dimensional simplices, adds them to this triangulation, and returns them in a std::array.

The main purpose of this routine is to support structured binding; for example:

auto [r, s, t] = ans.newSimplices<3>();
r->join(0, s, {1, 2, 3, 0});
...

All new simplices will have empty descriptions, and all facets of each new simplex will be boundary facets.

The new simplices will become the last k simplices in this triangulation. Specifically, if the return value is the array ret, then each simplex ret[i] will have index size()-k+i in the overall triangulation.

Python
For Python users, the two variants of newSimplices() are essentially merged: the argument k is passed as an ordinary runtime argument, and the new top-dimensional simplices will be returned in a Python tuple of size k.
Template Parameters
kthe number of new top-dimensional simplices to add; this must be non-negative.
Returns
an array containing all of the new simplices, in the order in which they were added.

◆ newSimplices() [2/2]

void regina::detail::TriangulationBase< dim >::newSimplices ( size_t  k)
inherited

Creates k new top-dimensional simplices and adds them to this triangulation.

This is similar to the templated routine newSimplices<k>(), but with two key differences:

  • This routine has the disadvantage that it does not return the new top-dimensional simplices, which means you cannot use it with structured binding.
  • This routine has the advantage that k does not need to be known until runtime, which means this routine is accessible to Python users.

All new simplices will have empty descriptions, and all facets of each new simplex will be boundary facets.

The new simplices will become the last k simplices in this triangulation.

Python
For Python users, the two variants of newSimplices() are essentially merged: the argument k is passed as an ordinary runtime argument, and the new top-dimensional simplices will be returned in a Python tuple of size k.
Parameters
kthe number of new top-dimensional simplices to add; this must be non-negative.

◆ openBook()

bool regina::Triangulation< 4 >::openBook ( Tetrahedron< 4 > *  t,
bool  check = true,
bool  perform = true 
)

Checks the eligibility of and/or performs a book opening move about the given tetrahedron.

This involves taking a tetrahedron meeting the boundary along precisely one, two or three triangles, and ungluing it to create two new boundary facets (thus exposing the pentachora it initially joined). This move is intended to open the way for new shellBoundary() moves.

This move can be done if:

  • all vertices, edges and triangles of the tetrahedron are valid;
  • the tetrahedron meets the boundary in precisely one, two or three triangles (and therefore also joins two pentachora);
  • if the tetrahedron meets the boundary in precisely one triangle, then the remaining vertex of the tetrahedron is non-boundary, and no two of the remaining three edges of the tetrahedron are identified;
  • if the tetrahedron meets the boundary in precisely two triangles, then the remaining edge of the tetrahedron is non-boundary, and the remaining two triangles of the tetrahedron are not identified.

The validity condition in particular is stronger than it needs to be, but the resulting "lost opportunities" only affect invalid triangulations.

If the routine is asked to both check and perform, the move will only be performed if the check shows it is legal.

If this triangulation is currently oriented, then this operation will (trivially) preserve the orientation.

Note that after performing this move, all skeletal objects (edges, components, etc.) will be reconstructed, which means that any pointers to old skeletal objects (such as the argument t) can no longer be used.

Precondition
If the move is being performed and no check is being run, it must be known in advance that the move is legal.
The given tetrahedron is a tetrahedron of this triangulation.
Parameters
tthe tetrahedron about which to perform the move.
checktrue if we are to check whether the move is allowed (defaults to true).
performtrue if we are to perform the move (defaults to true).
Returns
If check is true, the function returns true if and only if the requested move may be performed without changing the topology of the manifold. If check is false, the function simply returns true.

◆ operator!=()

bool regina::detail::TriangulationBase< dim >::operator!= ( const Triangulation< dim > &  other) const
inlineinherited

Determines if this triangulation is not combinatorially identical to the given triangulation.

Here "identical" means that the triangulations have the same number of top-dimensional simplices, with gluings between the same pairs of numbered simplices using the same gluing permutations. In other words, "identical" means that the triangulations are isomorphic via the identity isomorphism.

For the less strict notion of isomorphic triangulations, which allows relabelling of the top-dimensional simplices and their vertices, see isIsomorphicTo() instead.

This test does not examine the textual simplex descriptions, as seen in Simplex<dim>::description(); these may still differ. It also does not test whether lower-dimensional faces are numbered identically (vertices, edges and so on); this routine is only concerned with top-dimensional simplices.

(At the time of writing, two identical triangulations will always number their lower-dimensional faces in the same way. However, it is conceivable that in future versions of Regina there may be situations in which identical triangulations can acquire different numberings for vertices, edges, and so on.)

Parameters
otherthe triangulation to compare with this.
Returns
true if and only if the two triangulations are not combinatorially identical.

◆ operator=() [1/2]

Triangulation< 4 > & regina::Triangulation< 4 >::operator= ( const Triangulation< 4 > &  src)
inline

Sets this to be a (deep) copy of the given triangulation.

This will also clone any computed properties (such as homology, fundamental group, and so on), as well as the skeleton (vertices, edges, components, etc.). In particular, this triangulation will use the same numbering and labelling for all skeletal objects as in the source triangulation.

Parameters
srcthe triangulation to copy.
Returns
a reference to this triangulation.

◆ operator=() [2/2]

Triangulation< 4 > & regina::Triangulation< 4 >::operator= ( Triangulation< 4 > &&  src)
inline

Moves the contents of the given triangulation into this triangulation.

This is much faster than copy assignment, but is still linear time. This is because every pentachoron must be adjusted to point back to this triangulation instead of src.

All pentachora and skeletal objects (faces, components and boundary components) that belong to src will be moved into this triangulation, and so any pointers or references to Pentachoron<4>, Face<4, subdim>, Component<4> or BoundaryComponent<4> objects will remain valid. Likewise, all cached properties will be moved into this triangulation.

The triangulation that is passed (src) will no longer be usable.

Note
This operator is not marked noexcept, since it fires change events on this triangulation which may in turn call arbitrary code via any registered packet listeners. It deliberately does not fire change events on src, since it assumes that src is about to be destroyed (which will fire a destruction event instead).
Parameters
srcthe triangulation to move.
Returns
a reference to this triangulation.

◆ operator==()

bool regina::detail::TriangulationBase< dim >::operator== ( const Triangulation< dim > &  other) const
inherited

Determines if this triangulation is combinatorially identical to the given triangulation.

Here "identical" means that the triangulations have the same number of top-dimensional simplices, with gluings between the same pairs of numbered simplices using the same gluing permutations. In other words, "identical" means that the triangulations are isomorphic via the identity isomorphism.

For the less strict notion of isomorphic triangulations, which allows relabelling of the top-dimensional simplices and their vertices, see isIsomorphicTo() instead.

This test does not examine the textual simplex descriptions, as seen in Simplex<dim>::description(); these may still differ. It also does not test whether lower-dimensional faces are numbered identically (vertices, edges and so on); this routine is only concerned with top-dimensional simplices.

(At the time of writing, two identical triangulations will always number their lower-dimensional faces in the same way. However, it is conceivable that in future versions of Regina there may be situations in which identical triangulations can acquire different numberings for vertices, edges, and so on.)

In Regina 6.0.1 and earlier, this comparison was called isIdenticalTo().

Parameters
otherthe triangulation to compare with this.
Returns
true if and only if the two triangulations are combinatorially identical.

◆ orient()

void regina::detail::TriangulationBase< dim >::orient
inherited

Relabels the vertices of top-dimensional simplices in this triangulation so that all simplices are oriented consistently, if possible.

This routine works by flipping vertices (dim - 1) and dim of each top-dimensional simplices that has negative orientation. The result will be a triangulation where the top-dimensional simplices have their vertices labelled in a way that preserves orientation across adjacent facets. In particular, every gluing permutation will have negative sign.

If this triangulation includes both orientable and non-orientable components, the orientable components will be oriented as described above and the non-orientable components will be left untouched.

◆ pachner()

bool regina::detail::TriangulationBase< dim >::pachner ( Face< dim, k > *  f,
bool  check = true,
bool  perform = true 
)
inherited

Checks the eligibility of and/or performs a (dim + 1 - k)-(k + 1) Pachner move about the given k-face.

This involves replacing the (dim + 1 - k) top-dimensional simplices meeting that k-face with (k + 1) new top-dimensional simplices joined along a new internal (dim - k)-face. This can be done iff (i) the given k-face is valid and non-boundary; (ii) the (dim + 1 - k) top-dimensional simplices that contain it are distinct; and (iii) these simplices are joined in such a way that the link of the given k-face is the standard triangulation of the (dim - 1 - k)-sphere as the boundary of a (dim - k)-simplex.

If the routine is asked to both check and perform, the move will only be performed if the check shows it is legal. In In the special case k = dim, the move is always legal and so the check argument will simply be ignored.

Note that after performing this move, all skeletal objects (facets, components, etc.) will be reconstructed, which means any pointers to old skeletal objects (such as the argument v) can no longer be used.

If this triangulation is currently oriented, then this Pachner move will label the new top-dimensional simplices in a way that preserves the orientation.

See the page on Pachner moves on triangulations for definitions and terminology relating to Pachner moves. After the move, the new belt face will be formed from vertices 0,1,...,(dim - k) of simplices().back().

Warning
For the case k = dim in Regina's standard dimensions, the labelling of the belt face has changed as of Regina 5.96 (the first prerelease for Regina 6.0). In versions 5.1 and earlier, the belt face was simplices().back()->vertex(dim), and as of version 5.96 it is now simplices().back()->vertex(0).
Precondition
If the move is being performed and no check is being run, it must be known in advance that the move is legal.
The given k-face is a k-face of this triangulation.
Parameters
fthe k-face about which to perform the move.
checktrue if we are to check whether the move is allowed (defaults to true).
performtrue if we are to perform the move (defaults to true).
Returns
If check is true, the function returns true if and only if the requested move may be performed without changing the topology of the manifold. If check is false, the function simply returns true.
Template Parameters
kthe dimension of the given face. This must be between 0 and (dim) inclusive. You can still perform a Pachner move about a 0-face dim-face, but these moves use specialised implementations (as opposed to this generic template implementation).

◆ packet() [1/2]

std::shared_ptr< PacketOf< Triangulation< dim > > > regina::PacketData< Triangulation< dim > >::packet ( )
inlineinherited

Returns the packet that holds this data, if there is one.

If this object is being held by a packet p of type PacketOf<Held>, then that packet p will be returned. Otherwise, if this is a "standalone" object of type Held, then this routine will return null.

There is a special case when dealing with a packet q that holds a SnapPea triangulation. Here q is of type PacketOf<SnapPeaTriangulation>, and it holds a Triangulation<3> "indirectly" in the sense that Packetof<SnapPeaTriangulation> derives from SnapPeaTriangulation, which in turn derives from Triangulation<3>. In this scenario:

The function inAnyPacket() is specific to Triangulation<3>, and is not offered for other Held types.

Returns
the packet that holds this data, or null if this data is not (directly) held by a packet.

◆ packet() [2/2]

std::shared_ptr< const PacketOf< Triangulation< dim > > > regina::PacketData< Triangulation< dim > >::packet ( ) const
inlineinherited

Returns the packet that holds this data, if there is one.

See the non-const version of this function for further details, and in particular for how this functions operations in the special case of a packet that holds a SnapPea triangulation.

Returns
the packet that holds this data, or null if this data is not (directly) held by a packet.

◆ pairing()

FacetPairing< dim > regina::detail::TriangulationBase< dim >::pairing
inlineinherited

Returns the dual graph of this triangulation, expressed as a facet pairing.

Calling tri.pairing() is equivalent to calling FacetPairing<dim>(tri).

Precondition
This triangulation is not empty.
Returns
the dual graph of this triangulation.

◆ pentachora()

auto regina::detail::TriangulationBase< dim >::pentachora
inlineinherited

A dimension-specific alias for faces<4>(), or an alias for simplices() in dimension dim = 4.

This alias is available for dimensions dim ≥ 4.

See faces() for further information.

◆ pentachoron() [1/2]

Face< dim, 4 > * regina::detail::TriangulationBase< dim >::pentachoron ( size_t  index)
inlineinherited

A dimension-specific alias for face<4>(), or an alias for simplex() in dimension dim = 4.

This alias is available for dimensions dim ≥ 4.

See face() for further information.

◆ pentachoron() [2/2]

auto regina::detail::TriangulationBase< dim >::pentachoron ( size_t  index) const
inlineinherited

A dimension-specific alias for face<4>(), or an alias for simplex() in dimension dim = 4.

This alias is available for dimensions dim ≥ 4. It returns a const pentachoron pointer in dimension dim = 4, and a non-const pentachoron pointer in all higher dimensions.

See face() for further information.

◆ reflect()

void regina::detail::TriangulationBase< dim >::reflect
inherited

Relabels the vertices of top-dimensional simplices in this triangulation so that all simplices reflect their orientation.

In particular, if this triangulation is oriented, then it will be converted into an isomorphic triangulation with the opposite orientation.

This routine works by flipping vertices (dim - 1) and dim of every top-dimensional simplex.

◆ removeAllPentachora()

void regina::Triangulation< 4 >::removeAllPentachora ( )
inline

A dimension-specific alias for removeAllSimplices().

See removeAllSimplices() for further information.

◆ removeAllSimplices()

void regina::detail::TriangulationBase< dim >::removeAllSimplices
inlineinherited

Removes all simplices from the triangulation.

As a result, this triangulation will become empty.

All of the simplices that belong to this triangulation will be destroyed immediately.

◆ removePentachoron()

void regina::Triangulation< 4 >::removePentachoron ( Pentachoron< 4 > *  tet)
inline

A dimension-specific alias for removeSimplex().

See removeSimplex() for further information.

◆ removePentachoronAt()

void regina::Triangulation< 4 >::removePentachoronAt ( size_t  index)
inline

A dimension-specific alias for removeSimplexAt().

See removeSimplexAt() for further information.

◆ removeSimplex()

void regina::detail::TriangulationBase< dim >::removeSimplex ( Simplex< dim > *  simplex)
inlineinherited

Removes the given top-dimensional simplex from this triangulation.

The given simplex will be unglued from any adjacent simplices (if any), and will be destroyed immediately.

Precondition
The given simplex is a top-dimensional simplex in this triangulation.
Parameters
simplexthe simplex to remove.

◆ removeSimplexAt()

void regina::detail::TriangulationBase< dim >::removeSimplexAt ( size_t  index)
inlineinherited

Removes the top-dimensional simplex at the given index in this triangulation.

This is equivalent to calling removeSimplex(simplex(index)).

The given simplex will be unglued from any adjacent simplices (if any), and will be destroyed immediately.

Parameters
indexspecifies which top-dimensionalsimplex to remove; this must be between 0 and size()-1 inclusive.

◆ retriangulate()

template<typename Action , typename... Args>
bool regina::Triangulation< 4 >::retriangulate ( int  height,
unsigned  threads,
ProgressTrackerOpen tracker,
Action &&  action,
Args &&...  args 
) const
inline

Explores all triangulations that can be reached from this via Pachner moves, without exceeding a given number of additional pentachora.

Specifically, this routine will iterate through all triangulations that can be reached from this triangulation via 1-5, 2-4, 3-3 and 4-2 Pachner moves, without ever exceeding height additional pentachora beyond the original number. Note that 5-1 moves are currently not supported, though this may be added in a future verson of Regina.

For every such triangulation (including this starting triangulation), this routine will call action (which must be a function or some other callable object).

  • action must take the following initial argument(s). Either (a) the first argument must be a triangulation (the precise type is discussed below), representing the triangluation that has been found; or else (b) the first two arguments must be of types const std::string& followed by a triangulation, representing both the triangulation and its isomorphism signature. The second form is offered in order to avoid unnecessary recomputation within the action function; however, note that the signature might not be of the IsoSigClassic type (i.e., it might not match the output from the default version of isoSig()). If there are any additional arguments supplied in the list args, then these will be passed as subsequent arguments to action.
  • The triangulation argument will be passed as an rvalue; a typical action could (for example) take it by const reference and query it, or take it by value and modify it, or take it by rvalue reference and move it into more permanent storage.
  • action must return a boolean. If action ever returns true, then this indicates that processing should stop immediately (i.e., no more triangulations will be processed).
  • action may, if it chooses, make changes to this triangulation (i.e., the original triangulation upon which retriangulate() was called). This will not affect the search: all triangulations that this routine visits will be obtained via Pachner moves from the original form of this triangulation, before any subsequent changes (if any) were made.
  • action will only be called once for each triangulation (including this starting triangulation). In other words, no triangulation will be revisited a second time in a single call to retriangulate().

This routine can be very slow and very memory-intensive, since the number of triangulations it visits may be superexponential in the number of tetrahedra, and it records every triangulation that it visits (so as to avoid revisiting the same triangulation again). It is highly recommended that you begin with height = 1, and if necessary try increasing height one at a time until this routine becomes too expensive to run.

If height is negative, then there will be no bound on the number of additional pentachora. This means that the routine will never terminate, unless action returns true for some triangulation that is passed to it.

Since Regina 7.0, this routine will not return until the exploration of triangulations is complete, regardless of whether a progress tracker was passed. If you need the old behaviour (where passing a progress tracker caused the enumeration to start in the background), simply call this routine in a new detached thread.

To assist with performance, this routine can run in parallel (multithreaded) mode; simply pass the number of parallel threads in the argument threads. Even in multithreaded mode, this routine will not return until processing has finished (i.e., either action returned true, or the search was exhausted). All calls to action will be protected by a mutex (i.e., different threads will never be calling action at the same time); as a corollary, the action should avoid expensive operations where possible (otherwise it will become a serialisation bottleneck in the multithreading).

If this triangulation is not connected, then this routine will do nothing: it will immediately return false, and if a progress tracker was passed then it will be immediately marked as finished.

Precondition
This triangulation is connected.
Exceptions
FailedPreconditionThis triangulation has more than one connected component. If a progress tracker was passed, it will be marked as finished before the exception is thrown.
Warning
The API for this class or function has not yet been finalised. This means that the interface may change in new versions of Regina, without maintaining backward compatibility. If you use this class directly in your own code, please check the detailed changelog with each new release to see if you need to make changes to your code.
Python
This function is available in Python, and the action argument may be a pure Python function. However, its form is more restricted: the arguments tracker and args are removed, so you call it as retriangulate(height, threads, action). Moreover, action must take exactly two arguments (const std::string&, Triangulation<4>&&) representing a signature and the triangulation, as described in option (b) above.
Parameters
heightthe maximum number of additional pentachora to allow beyond the number of pentachora originally present in the triangulation, or a negative number if this should not be bounded.
threadsthe number of threads to use. If this is 1 or smaller then the routine will run single-threaded.
trackera progress tracker through which progress will be reported, or null if no progress reporting is required.
actiona function (or other callable object) to call for each triangulation that is found.
argsany additional arguments that should be passed to action, following the initial triangulation argument(s).
Returns
true if some call to action returned true (thereby terminating the search early), or false if the search ran to completion.

◆ shellBoundary()

bool regina::Triangulation< 4 >::shellBoundary ( Pentachoron< 4 > *  p,
bool  check = true,
bool  perform = true 
)

Checks the eligibility of and/or performs a boundary shelling move on the given pentachoron.

This involves simply popping off a pentachoron that touches the boundary. This can be done if:

  • all edges and triangles of the pentachoron are valid;
  • precisely one, two, three or four facets of the pentachoron lie in the boundary;
  • if one facet lies in the boundary, then the opposite vertex does not lie in the boundary, and no two of the remaining four edges are identified;
  • if two facets lie in the boundary, then the edge that sits opposite their common triangle does not lie in the boundary, and no two of the remaining three triangles are identified;
  • if three facets lie in the boundary, then the triangle that sits opposite their common edge does not lie in the boundary, and the remaining two facets of the tetrahedron are not identified.

The validity condition in particular is stronger than it needs to be, but the resulting "lost opportunities" only affect invalid triangulations.

If the routine is asked to both check and perform, the move will only be performed if the check shows it is legal.

If this triangulation is currently oriented, then this operation will (trivially) preserve the orientation.

Note that after performing this move, all skeletal objects (edges, components, etc.) will be reconstructed, which means that any pointers to old skeletal objects can no longer be used.

Precondition
If the move is being performed and no check is being run, it must be known in advance that the move is legal.
The given pentachoron is a pentachoron of this triangulation.
Parameters
pthe pentachoron upon which to perform the move.
checktrue if we are to check whether the move is allowed (defaults to true).
performtrue if we are to perform the move (defaults to true).
Returns
If check is true, this function returns true if and only if the requested move may be performed without changing the topology of the manifold. If check is false, this function simply returns true.

◆ simplex() [1/2]

Simplex< dim > * regina::detail::TriangulationBase< dim >::simplex ( size_t  index)
inlineinherited

Returns the top-dimensional simplex at the given index in the triangulation.

Note that indexing may change when a simplex is added to or removed from the triangulation.

Parameters
indexspecifies which simplex to return; this value should be between 0 and size()-1 inclusive.
Returns
the indexth top-dimensional simplex.

◆ simplex() [2/2]

const Simplex< dim > * regina::detail::TriangulationBase< dim >::simplex ( size_t  index) const
inlineinherited

Returns the top-dimensional simplex at the given index in the triangulation.

Note that indexing may change when a simplex is added to or removed from the triangulation.

Parameters
indexspecifies which simplex to return; this value should be between 0 and size()-1 inclusive.
Returns
the indexth top-dimensional simplex.

◆ simplices()

auto regina::detail::TriangulationBase< dim >::simplices
inlineinherited

Returns an object that allows iteration through and random access to all top-dimensional simplices in this triangulation.

The object that is returned is lightweight, and can be happily copied by value. The C++ type of the object is subject to change, so C++ users should use auto (just like this declaration does).

The returned object is guaranteed to be an instance of ListView, which means it offers basic container-like functions and supports range-based for loops. Note that the elements of the list will be pointers, so your code might look like:

for (Simplex<dim>* s : tri.simplices()) { ... }

The object that is returned will remain up-to-date and valid for as long as the triangulation exists: even as simplices are added and/or removed, it will always reflect the simplices that are currently in the triangulation. Nevertheless, it is recommended to treat this object as temporary only, and to call simplices() again each time you need it.

Returns
access to the list of all top-dimensional simplices.

◆ simplifiedFundamentalGroup()

void regina::detail::TriangulationBase< dim >::simplifiedFundamentalGroup ( GroupPresentation  newGroup)
inlineinherited

Notifies the triangulation that you have simplified the presentation of its fundamental group.

The old group presentation will be replaced by the (hopefully simpler) group that is passed.

This routine is useful for situations in which some external body (such as GAP) has simplified the group presentation better than Regina can.

Regina does not verify that the new group presentation is equivalent to the old, since this is - well, hard.

If the fundamental group has not yet been calculated for this triangulation, then this routine will store the new group as the fundamental group, under the assumption that you have worked out the group through some other clever means without ever having needed to call group() at all.

Note that this routine will not fire a packet change event.

Parameters
newGroupa new (and hopefully simpler) presentation of the fundamental group of this triangulation.

◆ simplifyExhaustive()

bool regina::Triangulation< 4 >::simplifyExhaustive ( int  height = 1,
unsigned  threads = 1,
ProgressTrackerOpen tracker = nullptr 
)
inline

Attempts to simplify this triangulation using a slow but exhaustive search through the Pachner graph.

This routine is more powerful but much slower than intelligentSimplify().

Specifically, this routine will iterate through all triangulations that can be reached from this triangulation via 1-5, 2-4, 3-3 and 4-2 Pachner moves, without ever exceeding height additional pentachora beyond the original number. Note that 5-1 moves are currently not supported, though this may be added in a future verson of Regina.

If at any stage it finds a triangulation with fewer pentachora than the original, then this routine will call intelligentSimplify() to shrink the triangulation further if possible and will then return true. If it cannot find a triangulation with fewer pentachora then it will leave this triangulation unchanged and return false.

This routine can be very slow and very memory-intensive: the number of triangulations it visits may be superexponential in the number of pentachora, and it records every triangulation that it visits (so as to avoid revisiting the same triangulation again). It is highly recommended that you begin with height = 1, and if this fails then try increasing height one at a time until either you find a simplification or the routine becomes too expensive to run.

If height is negative, then there will be no bound on the number of additional pentachora. This means that the routine will not terminate until a simpler triangulation is found. If no simpler diagram exists then the only way to terminate this function is to cancel the operation via a progress tracker (read on for details).

If you want a fast simplification routine, you should call intelligentSimplify() instead. The benefit of simplifyExhaustive() is that, for very stubborn triangulations where intelligentSimplify() finds itself stuck at a local minimum, simplifyExhaustive() is able to "climb out" of such wells.

Since Regina 7.0, this routine will not return until either the triangulation is simplified or the exhaustive search is complete, regardless of whether a progress tracker was passed. If you need the old behaviour (where passing a progress tracker caused the exhaustive search to start in the background), simply call this routine in a new detached thread.

To assist with performance, this routine can run in parallel (multithreaded) mode; simply pass the number of parallel threads in the argument threads. Even in multithreaded mode, this routine will not return until processing has finished (i.e., either the triangulation was simplified or the search was exhausted).

If this routine is unable to simplify the triangulation, then the triangulation will not be changed.

Precondition
This triangulation is connected.
Exceptions
FailedPreconditionThis triangulation has more than one connected component. If a progress tracker was passed, it will be marked as finished before the exception is thrown.
Python
The global interpreter lock will be released while this function runs, so you can use it with Python-based multithreading.
Parameters
heightthe maximum number of additional pentachora to allow beyond the number of pentachora originally present in the triangulation, or a negative number if this should not be bounded.
threadsthe number of threads to use. If this is 1 or smaller then the routine will run single-threaded.
trackera progress tracker through which progress will be reported, or null if no progress reporting is required.
Returns
true if and only if the triangulation was successfully simplified to fewer pentachora.

◆ simplifyToLocalMinimum()

bool regina::Triangulation< 4 >::simplifyToLocalMinimum ( bool  perform = true)

Uses all known simplification moves to reduce the triangulation monotonically to some local minimum number of pentachora.

End users will probably not want to call this routine. You should call intelligentSimplify() if you want a fast method of simplifying a triangulation.

The moves used by this routine include collapsing edges, 4-2 moves, and boundary shelling moves.

Moves that do not reduce the number of pentachora (such as 3-3 moves or book opening moves) are not used in this routine. Such moves do however feature in intelligentSimplify().

If this triangulation is currently oriented, then this operation will preserve the orientation.

Warning
The specific behaviour of this routine will almost certainly change between releases. At present, simplification for 4-manifold triangulations is extremely weak (as opposed to 3-manifolds, where a rich library of simplification techinques is available to call upon).
Parameters
performtrue if we are to perform the simplifications, or false if we are only to investigate whether simplifications are possible (defaults to true).
Returns
if perform is true, this routine returns true if and only if the triangulation was changed to reduce the number of pentachora; if perform is false, this routine returns true if and only if it determines that it is capable of performing such a change.

◆ size()

size_t regina::detail::TriangulationBase< dim >::size
inlineinherited

Returns the number of top-dimensional simplices in the triangulation.

Returns
The number of top-dimensional simplices.

◆ snapEdge()

bool regina::Triangulation< 4 >::snapEdge ( Edge< 4 > *  e,
bool  check = true,
bool  perform = true 
)

Snaps together the endpoints of an edge connecting an internal vertex with some different (possibly boundary) vertex, which reduces the number of vertices in this triangulation by one without changing the topology.

This operation essentially works by taking a triangle t that meets the given edge e, and folding the other two edges of t together about their common vertex. This can be done if and only if e is an edge whose endpoints are distinct and not both boundary (i.e., an edge of the type described above).

If the routine is asked to both check and perform, the move will only be performed if the check shows it is legal.

Depending on your situation, collapseEdge() may be a more appropriate method for reducing the number of vertices without changing the topology.

  • The advantage of collapseEdge() is that it decreases the number of tetrahedra, whereas snapEdge() increases this number (but only by four).
  • The disadvantages of collapseEdge() are that it cannot always be performed, and its validity tests are expensive; snapEdge() on the other hand can always be used for edges e of the type described above.

If this triangulation is currently oriented, then this operation will preserve the orientation.

Note that after performing this move, all skeletal objects (triangles, components, etc.) will be reconstructed, which means any pointers to old skeletal objects (such as the argument e) can no longer be used.

Precondition
If the move is being performed and no check is being run, it must be known in advance that the move is legal.
The given edge e is an edge of this triangulation.
Parameters
ethe edge whose endpoints are to be snapped together.
checktrue if we are to check whether the move is allowed (defaults to true).
performtrue if we are to perform the move (defaults to true).
Returns
If check is true, the function returns true if and only if the requested move may be performed without changing the topology of the manifold. If check is false, the function simply returns true.
Author
Alex He

◆ str()

std::string regina::Output< Triangulation< dim > , false >::str ( ) const
inherited

Returns a short text representation of this object.

This text should be human-readable, should use plain ASCII characters where possible, and should not contain any newlines.

Within these limits, this short text ouptut should be as information-rich as possible, since in most cases this forms the basis for the Python __str__() and __repr__() functions.

Python
The Python "stringification" function __str__() will use precisely this function, and for most classes the Python __repr__() function will incorporate this into its output.
Returns
a short text representation of this object.

◆ subdivide()

void regina::detail::TriangulationBase< dim >::subdivide
inherited

Does a barycentric subdivision of the triangulation.

This is done in-place, i.e., the triangulation will be modified directly.

Each top-dimensional simplex s is divided into (dim + 1) factorial sub-simplices by placing an extra vertex at the centroid of every face of every dimension. Each of these sub-simplices t is described by a permutation p of (0, ..., dim). The vertices of such a sub-simplex t are:

  • vertex p[0] of s;
  • the centre of edge (p[0], p[1]) of s;
  • the centroid of triangle (p[0], p[1], p[2]) of s;
  • ...
  • the centroid of face (p[0], p[1], p[2], p[dim]) of s, which is the entire simplex s itself.

The sub-simplices have their vertices numbered in a way that mirrors the original simplex s:

  • vertex p[0] of s will be labelled p[0] in t;
  • the centre of edge (p[0], p[1]) of s will be labelled p[1] in t;
  • the centroid of triangle (p[0], p[1], p[2]) of s will be labelled p[2] in t;
  • ...
  • the centroid of s itself will be labelled p[dim] in t.

In particular, if this triangulation is currently oriented, then this barycentric subdivision will preserve the orientation.

If simplex s has index i in the original triangulation, then its sub-simplex corresponding to permutation p will have index ((dim + 1)! * i + p.orderedSnIndex()) in the resulting triangulation. In other words: sub-simplices are ordered first according to the original simplex that contains them, and then according to the lexicographical ordering of the corresponding permutations p.

Precondition
dim is one of Regina's standard dimensions. This precondition is a safety net, since in higher dimensions the triangulation would explode too quickly in size (and for the highest dimensions, possibly beyond the limits of size_t).
Warning
In dimensions 3 and 4, both the labelling and ordering of sub-simplices in the subdivided triangulation has changed as of Regina 5.1. (Earlier versions of Regina made no guarantee about the labelling and ordering; these guarantees are also new to Regina 5.1).
Todo:
Lock the topological properties of the underlying manifold, to avoid recomputing them after the subdivision. However, only do this for valid triangulations (since we can have scenarios where invalid triangulations becoming valid and ideal after subdivision, which may change properties such as Triangulation<4>::knownSimpleLinks).

◆ swap() [1/2]

void regina::Snapshottable< Triangulation< dim > >::swap ( Snapshottable< Triangulation< dim > > &  other)
inlineprotectednoexceptinherited

Swap operation.

This should only be called when the entire type T contents of this object and other are being swapped. If one object has a current snapshot, then the other object will move in as the new image for that same snapshot. This avoids a deep copies of this object and/or other, even though both objects are changing.

In particular, if the swap function for T calls this base class function (as it should), then there is no need to call takeSnapshot() from either this object or src.

Parameters
otherthe snapshot image being swapped with this.

◆ swap() [2/2]

void regina::Triangulation< 4 >::swap ( Triangulation< 4 > &  other)

Swaps the contents of this and the given triangulation.

All pentachora that belong to this triangulation will be moved to other, and all pentachora that belong to other will be moved to this triangulation. Likewise, all skeletal objects (such as lower-dimensional faces, components, and boundary components) and all cached properties (such as homology and fundamental group) will be swapped.

In particular, any pointers or references to Pentachoron<4> and/or Face<4, subdim> objects will remain valid.

This routine will behave correctly if other is in fact this triangulation.

Note
This swap function is not marked noexcept, since it fires change events on both triangulations which may in turn call arbitrary code via any registered packet listeners.
Parameters
otherthe triangulation whose contents should be swapped with this.

◆ swapBaseData()

void regina::detail::TriangulationBase< dim >::swapBaseData ( TriangulationBase< dim > &  other)
protectedinherited

Swaps all data that is managed by this base class, including simplices, skeletal data, cached properties and the snapshotting data, with the given triangulation.

Note that TriangulationBase never calls this routine itself. Typically swapBaseData() is only ever called by Triangulation<dim>::swap().

Parameters
otherthe triangulation whose data should be swapped with this.

◆ takeSnapshot()

void regina::Snapshottable< Triangulation< dim > >::takeSnapshot ( )
inlineprotectedinherited

Must be called before modification and/or destruction of the type T contents.

See the Snapshot class notes for a full explanation of how this requirement works.

There are a few exceptions where takeSnapshot() does not need to be called: these are where type T move, copy and/or swap operations call the base class operations (as they should). See the Snapshottable move, copy and swap functions for details.

If this object has a current snapshot, then this function will trigger a deep copy with the snapshot.

After this function returns, this object is guaranteed to be completely unenrolled from the snapshotting machinery.

◆ tetrahedra()

auto regina::detail::TriangulationBase< dim >::tetrahedra
inlineinherited

A dimension-specific alias for faces<3>(), or an alias for simplices() in dimension dim = 3.

This alias is available for dimensions dim ≥ 3.

See faces() for further information.

◆ tetrahedron() [1/2]

Face< dim, 3 > * regina::detail::TriangulationBase< dim >::tetrahedron ( size_t  index)
inlineinherited

A dimension-specific alias for face<3>(), or an alias for simplex() in dimension dim = 3.

This alias is available for dimensions dim ≥ 3.

See face() for further information.

◆ tetrahedron() [2/2]

auto regina::detail::TriangulationBase< dim >::tetrahedron ( size_t  index) const
inlineinherited

A dimension-specific alias for face<3>(), or an alias for simplex() in dimension dim = 3.

This alias is available for dimensions dim ≥ 3. It returns a const tetrahedron pointer in dimension dim = 3, and a non-const tetrahedron pointer in all higher dimensions.

See face() for further information.

◆ tightDecode()

Triangulation< dim > regina::detail::TriangulationBase< dim >::tightDecode ( std::istream &  input)
staticinherited

Reconstructs a triangulation from its given tight encoding.

See the page on tight encodings for details.

The tight encoding will be read from the given input stream. If the input stream contains leading whitespace then it will be treated as an invalid encoding (i.e., this routine will throw an exception). The input routine may contain further data: if this routine is successful then the input stream will be left positioned immediately after the encoding, without skipping any trailing whitespace.

Exceptions
InvalidInputThe given input stream does not begin with a tight encoding of a dim-dimensional triangulation.
Python
Not present. Use tightDecoding() instead, which takes a string as its argument.
Parameters
inputan input stream that begins with the tight encoding for a dim-dimensional triangulation.
Returns
the triangulation represented by the given tight encoding.

◆ tightDecoding()

static Triangulation< dim > regina::TightEncodable< Triangulation< dim > >::tightDecoding ( const std::string &  enc)
inlinestaticinherited

Reconstructs an object of type T from its given tight encoding.

See the page on tight encodings for details.

The tight encoding should be given as a string. If this string contains leading whitespace or any trailing characters at all (including trailing whitespace), then it will be treated as an invalid encoding (i.e., this routine will throw an exception).

Exceptions
InvalidArgumentThe given string is not a tight encoding of an object of type T.
Parameters
encthe tight encoding for an object of type T.
Returns
the object represented by the given tight encoding.

◆ tightEncode()

void regina::detail::TriangulationBase< dim >::tightEncode ( std::ostream &  out) const
inherited

Writes the tight encoding of this triangulation to the given output stream.

See the page on tight encodings for details.

Python
Not present. Use tightEncoding() instead, which returns a string.
Parameters
outthe output stream to which the encoded string will be written.

◆ tightEncoding()

std::string regina::TightEncodable< Triangulation< dim > >::tightEncoding ( ) const
inlineinherited

Returns the tight encoding of this object.

See the page on tight encodings for details.

Exceptions
FailedPreconditionThis may be thrown for some classes T if the object is in an invalid state. If this is possible, then a more detailed explanation of "invalid" can be found in the class documentation for T, under the member function T::tightEncode(). See FacetPairing::tightEncode() for an example of this.
Returns
the resulting encoded string.

◆ translate()

Face< dim, subdim > * regina::detail::TriangulationBase< dim >::translate ( const Face< dim, subdim > *  other) const
inlineinherited

Translates a face of some other triangulation into the corresponding face of this triangulation, using simplex numbers for the translation.

Typically this routine would be used when the given face comes from a triangulation that is combinatorially identical to this, and you wish to obtain the corresponding face of this triangulation.

Specifically: if other refers to face i of top-dimensional simplex number k of some other triangulation, then this routine will return face i of top-dimensional simplex number k of this triangulation. Note that this routine does not use the face indices within each triangulation (which is outside the user's control), but rather the simplex numbering (which the user has full control over).

This routine behaves correctly even if other is a null pointer.

Precondition
This triangulation contains at least as many top-dimensional simplices as the triangulation containing other (though, as noted above, in typical scenarios both triangulations would actually be combinatorially identical).
Template Parameters
subdimthe face dimension; this must be between 0 and dim-1 inclusive.
Parameters
otherthe face to translate.
Returns
the corresponding face of this triangulation.

◆ triangle() [1/2]

Face< dim, 2 > * regina::detail::TriangulationBase< dim >::triangle ( size_t  index)
inlineinherited

A dimension-specific alias for face<2>(), or an alias for simplex() in dimension dim = 2.

This alias is available for all dimensions dim.

See face() for further information.

◆ triangle() [2/2]

auto regina::detail::TriangulationBase< dim >::triangle ( size_t  index) const
inlineinherited

A dimension-specific alias for face<2>(), or an alias for simplex() in dimension dim = 2.

This alias is available for all dimensions dim. It returns a const triangle pointer in dimension dim = 2, and a non-const triangle pointer in all higher dimensions.

See face() for further information.

◆ triangles()

auto regina::detail::TriangulationBase< dim >::triangles
inlineinherited

A dimension-specific alias for faces<2>(), or an alias for simplices() in dimension dim = 2.

This alias is available for all dimensions.

See faces() for further information.

◆ triangulateComponents()

std::vector< Triangulation< dim > > regina::detail::TriangulationBase< dim >::triangulateComponents
inherited

Returns the individual connected components of this triangulation.

This triangulation will not be modified.

This function is new to Regina 7.0, and it has two important changes of behaviour from the old splitIntoComponents() from Regina 6.0.1 and earlier:

  • This function does not insert the resulting components into the packet tree.
  • This function does not assign labels to the new components.
Returns
a list of individual component triangulations.

◆ twoZeroMove() [1/3]

bool regina::Triangulation< 4 >::twoZeroMove ( Edge< 4 > *  e,
bool  check = true,
bool  perform = true 
)

Checks the eligibility of and/or performs a 2-0 move about the given edge of degree 2.

This involves taking the two pentachora joined at that edge and squashing them flat. This can be done if:

  • the edge is valid and non-boundary and has a 2-sphere edge link;
  • the two pentachora are distinct;
  • the triangles opposite e in each pentachoron are distinct and not both boundary;
  • if facets f1 and f2 of one pentachoron are to be flattened onto facets g1 and g2 of the other respectively, then (a) f1 and g1 are distinct, (b) f2 and g2 are distinct, (c) we do not have both f1 = g2 and g1 = f2, (d) we do not have both f1 = f2 and g1 = g2, and (e) we do not have two of the facets boundary and the other two identified;
  • the two pentachora meet each other on all three facets touching the edge (as opposed to meeting each other on one facet and being glued to themselves along the other two).

If the routine is asked to both check and perform, the move will only be performed if the check shows it is legal.

If this triangulation is currently oriented, then this operation will preserve the orientation.

Note that after performing this move, all skeletal objects (tetrahedra, components, etc.) will be reconstructed, which means any pointers to old skeletal objects (such as the argument f) can no longer be used.

Precondition
If the move is being performed and no check is being run, it must be known in advance that the move is legal.
The given edge is an edge of this triangulation.
Parameters
ethe edge about which to perform the move.
checktrue if we are to check whether the move is allowed (defaults to true).
performtrue if we are to perform the move (defaults to true).
Returns
If check is true, the function returns true if and only if the requested move may be performed without changing the topology of the manifold. If check is false, the function simply returns true.

◆ twoZeroMove() [2/3]

bool regina::Triangulation< 4 >::twoZeroMove ( Triangle< 4 > *  t,
bool  check = true,
bool  perform = true 
)

Checks the eligibility of and/or performs a 2-0 move about the given triangle of degree 2.

This involves taking the two pentachora joined at that triangle and squashing them flat.

The eligibility requirements for this move are somewhat involved, and are discussed in detail in the source code for those who are interested.

If the routine is asked to both check and perform, the move will only be performed if the check shows it is legal.

If this triangulation is currently oriented, then this operation will preserve the orientation.

Note that after performing this move, all skeletal objects (tetrahedra, components, etc.) will be reconstructed, which means any pointers to old skeletal objects (such as the argument f) can no longer be used.

Precondition
If the move is being performed and no check is being run, it must be known in advance that the move is legal.
The given triangle is a triangle of this triangulation.
Parameters
tthe triangle about which to perform the move.
checktrue if we are to check whether the move is allowed (defaults to true).
performtrue if we are to perform the move (defaults to true).
Returns
If check is true, the function returns true if and only if the requested move may be performed without changing the topology of the manifold. If check is false, the function simply returns true.

◆ twoZeroMove() [3/3]

bool regina::Triangulation< 4 >::twoZeroMove ( Vertex< 4 > *  v,
bool  check = true,
bool  perform = true 
)

Checks the eligibility of and/or performs a 2-0 move about the given vertex of degree 2.

This involves taking the two pentachora joined at that vertex and squashing them flat. This can be done if:

  • the vertex is non-boundary and has a 3-sphere vertex link;
  • the two pentachora are distinct;
  • the tetrahedra opposite v in each pentachoron are distinct and not both boundary;
  • the two pentachora meet each other on all four facets touching the vertex (as opposed to meeting each other on two facets and being glued to themselves along the other two).

If the routine is asked to both check and perform, the move will only be performed if the check shows it is legal.

If this triangulation is currently oriented, then this operation will preserve the orientation.

Note that after performing this move, all skeletal objects (tetrahedra, components, etc.) will be reconstructed, which means any pointers to old skeletal objects (such as the argument v) can no longer be used.

Precondition
If the move is being performed and no check is being run, it must be known in advance that the move is legal.
The given vertex is a vertex of this triangulation.
Parameters
vthe vertex about which to perform the move.
checktrue if we are to check whether the move is allowed (defaults to true).
performtrue if we are to perform the move (defaults to true).
Returns
If check is true, the function returns true if and only if the requested move may be performed without changing the topology of the manifold. If check is false, the function simply returns true.

◆ utf8()

std::string regina::Output< Triangulation< dim > , false >::utf8 ( ) const
inherited

Returns a short text representation of this object using unicode characters.

Like str(), this text should be human-readable, should not contain any newlines, and (within these constraints) should be as information-rich as is reasonable.

Unlike str(), this function may use unicode characters to make the output more pleasant to read. The string that is returned will be encoded in UTF-8.

Returns
a short text representation of this object.

◆ vertex()

Face< dim, 0 > * regina::detail::TriangulationBase< dim >::vertex ( size_t  index) const
inlineinherited

A dimension-specific alias for face<0>().

This alias is available for all dimensions dim.

See face() for further information.

◆ vertices()

auto regina::detail::TriangulationBase< dim >::vertices
inlineinherited

A dimension-specific alias for faces<0>().

This alias is available for all dimensions dim.

See faces() for further information.

◆ writeTextLong()

void regina::detail::TriangulationBase< dim >::writeTextLong ( std::ostream &  out) const
inherited

Writes a detailed text representation of this object to the given output stream.

Python
Not present. Use detail() instead.
Parameters
outthe output stream to which to write.

◆ writeTextShort()

void regina::detail::TriangulationBase< dim >::writeTextShort ( std::ostream &  out) const
inherited

Writes a short text representation of this object to the given output stream.

Python
Not present. Use str() instead.
Parameters
outthe output stream to which to write.

◆ writeXMLBaseProperties()

void regina::detail::TriangulationBase< dim >::writeXMLBaseProperties ( std::ostream &  out) const
protectedinherited

Writes a chunk of XML containing properties of this triangulation.

This routine covers those properties that are managed by this base class TriangulationBase and that have already been computed for this triangulation.

This routine is typically called from within Triangulation<dim>::writeXMLPacketData(). The XML elements that it writes are child elements of the tri element.

Parameters
outthe output stream to which the XML should be written.

Member Data Documentation

◆ boundaryComponents_

MarkedVector<BoundaryComponent<dim> > regina::detail::TriangulationBase< dim >::boundaryComponents_
protectedinherited

The components that form the boundary of the triangulation.

◆ components_

MarkedVector<Component<dim> > regina::detail::TriangulationBase< dim >::components_
protectedinherited

The connected components that form the triangulation.

This list is only filled if/when the skeleton of the triangulation is computed.

◆ dimension

constexpr int regina::detail::TriangulationBase< dim >::dimension
staticconstexprinherited

A compile-time constant that gives the dimension of the triangulation.

◆ H2_

std::optional<AbelianGroup> regina::Triangulation< 4 >::H2_

Second homology group of the triangulation.

◆ heldBy_

PacketHeldBy regina::PacketData< Triangulation< dim > >::heldBy_
protectedinherited

Indicates whether this Held object is in fact the inherited data for a PacketOf<Held>.

As a special case, this field is also used to indicate when a Triangulation<3> is in fact the inherited data for a SnapPeaTriangulation. See the PacketHeldBy enumeration for more details on the different values that this data member can take.

◆ nBoundaryFaces_

std::array<size_t, dim> regina::detail::TriangulationBase< dim >::nBoundaryFaces_
protectedinherited

The number of boundary faces of each dimension.

◆ simplices_

MarkedVector<Simplex<dim> > regina::detail::TriangulationBase< dim >::simplices_
protectedinherited

The top-dimensional simplices that form the triangulation.

◆ topologyLock_

uint8_t regina::detail::TriangulationBase< dim >::topologyLock_
protectedinherited

If non-zero, this will cause Triangulation<dim>::clearAllProperties() to preserve any computed properties that related to the manifold (as opposed to the specific triangulation).

This allows you to avoid recomputing expensive invariants when the underlying manifold is retriangulated.

This property should be managed by creating and destroying TopologyLock objects. The precise value of topologyLock_ indicates the number of TopologyLock objects that currently exist for this triangulation.

◆ valid_

bool regina::detail::TriangulationBase< dim >::valid_
protectedinherited

Is this triangulation valid? See isValid() for details on what this means.


The documentation for this class was generated from the following file:

Copyright © 1999-2023, The Regina development team
This software is released under the GNU General Public License, with some additional permissions; see the source code for details.
For further information, or to submit a bug or other problem, please contact Ben Burton (bab@maths.uq.edu.au).