Regina 7.0 Calculation Engine
|
Regina's calculation engine is provided as a shared C++ library, and this API documentation is written to describe Regina's native C++ interface.
However, Regina also makes this library accessible through a Python module. If you are using Python, the notes below explain (briefly) how you should read this API documentation.
std::string
becomes the native Python string type, the C++ type std::vector<T>
becomes a native Python list holding objects of type T, and the C++ type std::optional<T>
will either become a Python object of type T or the Python value None
.regina
. For example, the C++ class regina::Link becomes the Python class regina.Link
.Triangulation3
, and the C++ class Matrix<regina::Integer> becomes the Python class MatrixInt
. See the individual class notes for how the Python class names are constructed.It is important to understand how the comparisons x == y
and x is y
operate under Python. As of Regina 7.0, this behaviour has changed significantly: many more classes now compare by value, and a few now have their comparisons disabled.
In general, you do not want to use the Python test x is y
. This is because each of Regina's Python objects is typically a "wrapper" that points to one of Regina's native C++ objects. Importantly, the same native C++ object could have many Python wrappers, and so x is y
could return False
even if both x and y wrap the same native C++ object.
Instead, you should always use the tests x == y
and/or x != y
. Regina implements this in different ways, depending on the type of class:
Most of Regina's classes use comparison by value. Here x == y
tests whether the contents of x and y are the same. What "the same " means will depend on the particular class; for example, GroupPresentation tests for identical presentations (not group isomorphism), Triangulation<3> tests for the same tetrahedron and vertex labellings (not just combinatorial isomorphism), and Attachment compares the attached file contents (ignoring the associated filenames). For the core numeric classes such as Integer, Rational, Polynomial, VectorInt and MatrixInt, this tests the usual mathematical equality.
For each such class, you can find out what is being compared by reading the documentation for the C++ class operators == and !=. See for example Link::operator==().
Some selected classes use comparison by reference. Here x == y
tests whether x and y refer to the same underlying C++ object (analogous to how x is y
would normally behave in a native Python application). This is typically used for the few classes that are passed around by pointer in C++, and whose location in memory is what defines them; the most common examples you will see are crossings within links (Crossing), and skeletal objects within triangulations (e.g., Tetrahedron<3>, Vertex<4>, BoundaryComponent<2>). This is also used with objects that manage or track long computations (e.g., ProgressTracker, GluingPermSearcher4, or TreeEnumeration).
These classes do not provide C++ class operators == or !=.
A few classes have explicitly disabled their comparison operators, since they are designed to be moved and/or copied (which makes it inappropriate to compare by reference), but they do not yet have their own customised comparisons implemented (often because such a test would be expensive and/or would be difficult to define cleanly).
These classes do not provide C++ class operators == or !=. If you attempt to compare two Python objects of such a class, you will receive a Python error with a message explain essentially what is written here.
If you wish to find out how a particular class C behaves, you can examine the attribute C.equalityType
. This will return one of the values BY_VALUE
, BY_REFERENCE
, DISABLED
or NEVER_INSTANTIATED
respctively:
Packet subclasses are a special case: it is often meaningful to compare packets by value (e.g., testing whether two triangulations are combinatorially identical), but it is also useful to know whether two Python wrappers identify the same underlying C++ packet (e.g., when traversing the packet tree). To resolve this, you can compare two packets of the same type by value using the operators x == y
and x != y
, and you can test whether two packets of any types reference the same underlying object by calling Packet::samePacket().
If you use special characters (such as accented letters, other international characters, exotic punctuation, mathematical symbols and so on), you may need to think about text encodings when passing strings between Python and Regina.
For Python 3 users, this is simple: all strings in Python are unicode, and these are converted seamlessly and transparently when moving between Regina and Python.
For Python 2 users, you need to take some care. All unicode
objects will be converted correctly and transparently. If you have a Python string, however, you will need to ensure it is encoded in UTF-8 when passing it to Regina. Conversely, you should assume that all strings that Regina sends back to Python will be UTF-8-encoded. See https://docs.python.org/2.7/howto/unicode.html for more information on how to work with UTF-8 strings in Python 2.
See the page on encodings for international strings for further discussion on text encodings within Regina, including an important note regarding filenames.