This page lists some important bugs that appeared in previous versions of Regina, which might have affected your computations.
Please write to the developers if you need further information or assistance.
Affected versions | 7.0–7.3 | Fixed in version 7.4 (expected late 2023) |
Main symptom | In C++/Python, if the connectness of a normal surface s has already been computed, then s.components() would return the entire surface as a single component. | |
Affected users | C++/Python programmers only | This only affected C++/Python users who called NormalSurface::components() on a disconnected surface, after some routine that computes connectedness for that same surface. |
Was I affected? | Examine your code, and see if it calls s.components() after any of s.isConnected(), s.isOrientable(), s.isTwoSided() or s.components() for some normal surface s which could be disconnected. |
Only C++/Python programmers were affected by this issue.
The bug did not affect:
Essentially, to trigger this bug, you would have needed to create your own normal surfaces in C++/Python code (e.g., by forming sums of vertex and/or fundamental surfaces), and then call the specific routines in the specific order as described above.
A workaround (if you are using Regina 7.0–7.3) is, instead of calling s.components(), to call (s*1).components(). This has the effect of creating a new surface whose connectedness is not yet known (which means the bug is not triggered).
Affected versions | 7.1–7.3 | Fixed in version 7.4 (expected late 2023) |
Main symptom | In C++/Python, calling isThinTriangleLink() before isNormalTriangleLink() could make the latter routine answer incorrectly; likewise for tetrahedron links. | |
Affected users | C++/Python programmers only | This only affected C++/Python users who called isThinTriangleLink() and then isNormalTriangleLink(), or isThinTetrahedronLink() and then isNormalTetrahedronLink(), on the same normal surface/hypersurface. |
Was I affected? | Examine your code, and see if it tests for both thin and normalised triangle/tetrahedron links on the same surface/hypersurface, with the thin test appearing first. |
Only C++/Python programmers were affected by this issue: the bug did not appear in the graphical user interface.
The bug only affected (i) triangle links in normal surfaces, and (ii) triangle and tetrahedron links in normal hypersurfaces. It did not affect vertex or edge link tests at all.
The bug only affected surface/hypersurfaces s that are normalised but not thin triangle/tetrahedron links:
A workaround (if you are using Regina 7.1–7.3) is to simply call the normalised link test before the thin link test. Subsequent calls to either test on the same surface will then return the correct results.
There are two issues here: the first issue was the bug itself, and the second issue was the only other place where the affected code was being used within Regina.
Incorrect HomGroupPresentation simplification routines | ||
---|---|---|
Affected versions | 4.96–7.2 | Fixed in version 7.3 |
Main symptom | In C++ or Python, calling any of the three high-level HomGroupPresentation simplification routines could give incorrect results. | |
Affected users | C++/Python programmers only | This affected programmers who called intelligentSimplify(), intelligentNielsen() or smallCancellation() on a HomGroupPresentation object. |
Was I affected? | Easy to test | Check your C++/Python code to see if you are explicitly working with group homomorphisms (i.e., HomGroupPresentation objects), and calling one of the simplification functions listed above. |
Incorrect GroupPresentation recognition for extensions over Z | ||
Affected versions | 4.96–7.2 | Fixed in version 7.3 |
Main symptom | If a finitely presented group was an extension over Z, then GroupPresentation::recogniseGroup() (which generates the plain text “name” of a fundamental group / knot group in the graphical user interface) might have described this extension using the wrong monodromy. | |
Affected users | All users | |
Was I affected? | Easy to test | Only if you relied on the human-readable group names in the user interface or the string-based routine GroupPresentation::recogniseGroup(), and you were using the specific monodromies that were reported for extensions over Z. |
The two issues above are related:
Although this was an old bug that affected all users, it is nevertheless easily to isolate the scope of the bug.
In particular, you were not affected if:
To avoid simliar problems in the future, GroupPresentation::simplifyWord() has now been renamed to GroupPresentation::simplifyAndConjugate(), in order to make its behaviour clearer.
Incorrectly-bound swap() for fixed-width bitmasks | ||
---|---|---|
Affected versions | 7.0–7.1 | Fixed in version 7.2 |
Main symptom | In Python, calling regina.swap() with fixed-width bitmasks (types Bitmask8, Bitmask16, ..., Bitmask256) led to undefined behaviour. | |
Affected users | Python programmers only | This only affected those rare Python programmers who called one of the specialised swap functions above. |
Was I affected? | Unlikely | Just examine your Python code, and see if you are explicitly creating objects of type Bitmask8, ..., or Bitmask256, and explicitly swapping them via regina.swap(). |
Incorrectly-bound Cyclotomic.negate() | ||
Affected versions | 5.0–7.1 | Fixed in version 7.2 |
Main symptom | In Python, calling Cyclotomic.negate() would in fact perform a multiplicative inversion instead. | |
Affected users | Python programmers only | This only affected Python programmers who did their own arithmetic on cyclotomic field elements and called x.negate() instead of the more natural -x. |
Was I affected? | Unlikely | Just examine your Python code, and see if you are explicitly creating Cyclotomic objects and/or retrieving them as Turaev-Viro invariants, and explicitly calling negate() on these objects. |
Only Python programmers were affected by these issues: any C++ code that worked with bitmasks and/or cyclotomic field elements (including Regina's Turaev-Viro computations) was unaffected. Moreover, to trigger these bugs, you had to do the following in your own code.
To trigger the swap() bug:
It seems unlikely that anybody would have been affected by these issues:
The cause of the swap() problem was that, as noted above, Regina's C++ calculation engine does not overload regina::swap() for fixed-width bitmasks (since they are so small that a specialised swap function is unnecessary). The Python bindings incorrectly declared a regina.swap() overload for fixed-width bitmasks, but forwarded this to the C++ function that takes the more general Bitmask type instead. In Regina 7.2, the Python bindings for heavily overloaded functions such as regina::swap() have been rewritten to use typesafe C++-casts instead of the old C-style casts to resolve the overloads, thus preventing such an issue from occuring again.
The cause of the Cyclotomic.negate() function was much simpler: the python name Cyclotomic.negate was accidentally bound to the C++ method Cyclotomic::inverse() in the code that connects the two languages.
Affected versions | 4.94–4.96 | Fixed in version 5.0. |
Main symptom | Regina computed embedded vertex normal surfaces, even if you asked for something else (e.g., fundamental surfaces, or immersed/singular surfaces). | |
Affected users | C++ programmers only | This only affected C++ programmers, and only those who called the NNormalSurfaceList::enumerate() function in a certain way. |
Was I affected? | Easy to test | Just examine your C++ code and see if your calls to enumerate() follow the pattern described below. |
Only C++ programmers were affected by this issue. If you only used Regina through Python or the graphical user interface, then you were not affected.
The problem was triggered when the user called NNormalSurfaceList::enumerate(tri, coords, which), and:
The problem did not occur if:
The cause of the problem was that versions 4.94–4.96 of Regina contained two enumerate() functions: the modern function that takes NormalList and NormalAlg flags, and an old deprecated function that took a bool argument for whether to enumerate embedded surfaces only. If a single flag was passed (of the enum type NormalListFlag), then the C++ priority rules for type conversions meant that this was interpreted as a bool instead of implicitly calling the NormalList(NormalListFlag) constructor. Therefore the old function would be called instead.
This was fixed in Regina 5.0 by removing the old deprecated function entirely.
It is easy to test whether you were affected by this issue:
Affected versions | 4.94 only | Fixed in version 4.95. |
Main symptom | The mod and gcd operations gave incorrect results in some rare scenarios when working with extremely large integers. | |
Affected users | All users | This affected all users, but only in rare situations which are unlikely to be seen in practice (described below). |
Was I affected? | Unlikely | The bug was quite difficult to trigger, and had relatively benign impacts unless you were working with experimental code direct from the repository. See below for details. |
This issue only appeared where large integers were present, and only then in certain rare scenarios. Here “large integer” means an integer too large to fit into a native long type on a computer (i.e., its absolute value is ≥ 231 on a typical 32-bit machine, or ≥ 263 on a typical 64-bit machine).
There were in fact two bugs, both thankfully hard to trigger:
The mod error could in theory affect Regina's algebraic code (e.g., matrix computations related to homology). However, if you were simply calling getHomologyH1() on 3-manifold triangluations, it is extremely unlikely that you would encounter the bug. The more dangerous scenario is if you were using experimental (and more complex) algebraic code from the git repository (and in fact, this is how the bug was spotted).
The gcd error was extremely rare, in that there was only one pair of integers that could trigger it. In theory this error could affect normal surface enumeration, but here the symptom would have been both mild and obvious: you would have seen vertex surfaces that were not scaled down to their lowest integer multiple.