Regina Calculation Engine
|
Stores an intermediate tableaux for the dual simplex method, and contains all of the core machinery for using the dual simplex method. More...
#include <enumerate/ntreelp.h>
Public Member Functions | |
LPData () | |
Constructs a new tableaux. More... | |
~LPData () | |
Destroys this tableaux. More... | |
void | reserve (const LPInitialTableaux< LPConstraint > *origTableaux) |
Reserves enough memory for this tableaux to work with. More... | |
void | initStart () |
Initialises this tableaux by beginning at the original starting tableaux and working our way to any feasible basis. More... | |
void | initClone (const LPData &parent) |
Initialises this tableaux to be a clone of the given tableaux. More... | |
unsigned | columns () const |
Returns the number of columns in this tableaux. More... | |
unsigned | coordinateColumns () const |
Returns the number of columns in this tableaux that correspond to normal coordinates or angle structure coordinates. More... | |
bool | isFeasible () const |
Returns whether or not this system is feasible. More... | |
bool | isActive (unsigned pos) const |
Determines whether the given variable is currently active. More... | |
int | sign (unsigned pos) const |
Returns the sign of the given variable under the current basis. More... | |
void | constrainZero (unsigned pos) |
Constrains this system further by setting the given variable to zero and deactivating it. More... | |
void | constrainPositive (unsigned pos) |
Constrains this system further by constraining the given variable to be strictly positive. More... | |
void | constrainOct (unsigned quad1, unsigned quad2) |
Declares that two quadrilateral coordinates within a tetrahedron are to be combined into a single octagon coordinate, for use with almost normal surfaces, and constrains the system accordingly. More... | |
void | dump (std::ostream &out) const |
Writes details of this tableaux to the given output stream. More... | |
void | extractSolution (NRay &v, const char *type) const |
Extracts the values of the individual variables from the current basis, with some modifications (as described below). More... | |
Stores an intermediate tableaux for the dual simplex method, and contains all of the core machinery for using the dual simplex method.
This class forms part of the tree traversal algorithms for enumerating and locating normal surfaces, as described in "A tree traversal algorithm for decision problems in knot theory and 3-manifold topology", Burton and Ozlen, Algorithmica 65:4 (2013), pp. 772-801, and "A fast branching algorithm for unknot recognition with experimental polynomial-time behaviour", Burton and Ozlen, arXiv:1211.1079. It is also used for locating a single strict angle structure, and for enumerating all taut angle structures.
This class is designed to represent a state partway through the tree traversal algorithm, where the tableaux has been altered to constrain some variables:
We do not store the full tableaux (which is dense and slow to work with). Instead we store the matrix of row operations that were applied to the original starting tableaux (in the notation of Burton and Ozlen, we store the matrix M_beta^{-1}, where M is the original matrix stored in the class LPInitialTableaux, and beta is the current basis).
If the system is infeasible (because the constraints on variables as described above are too severe), then the contents of the internal data members are undefined (other than the data member feasible_, which is guaranteed to be false
). This is because the code is optimised to abort any operation as soon as infeasibility is detected, which may leave the data members in a broken state. If you are not sure, you should always call isFeasible() before performing any other query or operation on this tableaux.
This class is designed to be used in a backtracking search, which means the API is cumbersome but we can quickly rewrite and copy data. The rules are as follows:
Like LPInitialTableaux, this class can enforce additional linear constraints (such as positive Euler characteristic) through the template parameter LPConstraint. If there are no such constraints, simply use the template parameter LPConstraintNone.
In the context of normal surfaces (not angle structures): Although the underlying coordinate system is based on quadrilaterals and (optionally) triangles, this class has elementary support for octagons also, as seen in almost normal surface theory. For the purposes of this class, an octagon is represented as a pair of quadrilaterals of different types in the same tetrahedron: these meet the boundary of the tetrahedron in the same arcs as a single octagon, and therefore interact with the matching equations in the same way.
To declare that you will be using octagons in some tetrahedron, you must call constrainOct(quad1, quad2), where quad1 and quad2 are the two corresponding quadrilateral columns. This will have the following effects, all of which may alter the tableaux:
This class has been optimised to ensure that you only have one octagon type declared at any given time (which is consistent with the constraints of almost normal surface theory).
All tableaux elements are of the integer class Integer, which is supplied as a template argument. This same integer class will be used as a template argument for LPConstraint.
|
inline |
Constructs a new tableaux.
You must call reserve() before doing anything else with this tableaux.
|
inline |
Destroys this tableaux.
This is safe even if reserve() was never called.
|
inline |
Returns the number of columns in this tableaux.
Note that, if we are imposing extra constraints through the template parameter LPConstraint, then there will be extra variables to enforce these, and so the number of columns will be larger than in the original matching equation matrix.
void regina::LPData< LPConstraint, Integer >::constrainOct | ( | unsigned | quad1, |
unsigned | quad2 | ||
) |
Declares that two quadrilateral coordinates within a tetrahedron are to be combined into a single octagon coordinate, for use with almost normal surfaces, and constrains the system accordingly.
This constrains the system in several ways, as discussed in detail in the LPData class notes. In theory, we set the two quadrilateral coordinates to be equal, and also insist that the number of octagons be strictly positive. In practice, we do this through several changes of variable; see the LPData class notes for a detailed discussion of precisely how the variables and tableaux will change.
This routine will work even if one of the given quadrilateral variables has already been deactivated, but in this case the routine will immediately set the system to infeasible and return.
This routine is not used with angle structure coordinates.
quad1 | one of the two quadrilateral types that we combine to form the new octagon type. |
quad2 | the other of the two quadrilateral types that we combine to form the new octagon type. |
void regina::LPData< LPConstraint, Integer >::constrainPositive | ( | unsigned | pos | ) |
Constrains this system further by constraining the given variable to be strictly positive.
We do this using a change of variable that effectively replaces x_pos with the new variable x'_pos = x_pos - 1 (which we simply constrain to be non-negative as usual). See the LPData class notes for details.
This routine will work even if the given variable has already been deactivated, but in this case the routine will immediately set the system to infeasible and return.
pos | the index of the variable that is to be constrained as positive. This must be between 0 and origTableaux_->columns()-1 inclusive. |
void regina::LPData< LPConstraint, Integer >::constrainZero | ( | unsigned | pos | ) |
Constrains this system further by setting the given variable to zero and deactivating it.
See the LPData class notes for details.
This routine will work even if the given variable has already been deactivated (and it will do nothing in this case).
pos | the index of the variable that is to be set to zero. This must be between 0 and origTableaux_->columns()-1 inclusive. |
|
inline |
Returns the number of columns in this tableaux that correspond to normal coordinates or angle structure coordinates.
This is precisely the number of columns in the original matrix of matching equations.
void regina::LPData< LPConstraint, Integer >::dump | ( | std::ostream & | out | ) | const |
Writes details of this tableaux to the given output stream.
The output is "rough" and wasteful, and is intended for debugging purposes only.
The precise output is subject to change in future versions of Regina.
out | the output stream to write to. |
void regina::LPData< LPConstraint, Integer >::extractSolution | ( | NRay & | v, |
const char * | type | ||
) | const |
Extracts the values of the individual variables from the current basis, with some modifications (as described below).
The values of the variables are store in the given vector v.
The modifications are as follows:
This routine is not used as an internal part of the tree traversal algorithm; instead it is offered as a helper routine for reconstructing the normal surfaces or angle structures that result.
v | the vector into which the values of the variables will be placed. |
type | the type vector corresponding to the current state of this tableaux, indicating which variables were previously fixed as positive via calls to constrainPositive(). This is necessary because LPData does not keep such historical data on its own. As a special case, when extracting a strict angle structure one may pass type = 0, in which case this routine will assume that every coordinate was constrained as positive. |
void regina::LPData< LPConstraint, Integer >::initClone | ( | const LPData< LPConstraint, Integer > & | parent | ) |
Initialises this tableaux to be a clone of the given tableaux.
This is used in the tree traversal algorithm as we work our way down the search tree, and child nodes "inherit" tableaux from their parent nodes.
parent | the tableaux to clone. |
void regina::LPData< LPConstraint, Integer >::initStart | ( | ) |
Initialises this tableaux by beginning at the original starting tableaux and working our way to any feasible basis.
This routine also explicitly enforces the additional constraints from the template parameter LPConstraint (i.e., this routine is responsible for forcing the corresponding linear function(s) to be zero or strictly positive as appropriate).
It is possible that a feasible basis cannot be found; you should test isFeasible() after running this routine to see whether this is the case.
|
inline |
|
inline |
Returns whether or not this system is feasible.
A system may become infeasible when we add too many extra constraints on the variables (such as forcing them to be positive, or setting them to zero); see the LPData class notes for details on these constraints.
true
if this system is feasible, or false
if it is infeasible.
|
inline |
Reserves enough memory for this tableaux to work with.
You must call this routine before doing anything else with this tableaux.
The data in this tableaux will not be initialised, and the contents and behaviour of this tableaux will remain undefined until you call one of the initialisation routines initStart() or initClone().
origTableaux | the original starting tableaux that holds the adjusted matrix of matching equations, before the tree traversal algorithm began. |
|
inline |
Returns the sign of the given variable under the current basis.
This does not attempt to "undo" any changes of variable caused by prior calls to constrainPositive() or constrainOct(); it simply tests the sign of the variable in the given column of the tableaux in its current form.
Specifically: if the given variable is inactive or non-basic, this routine returns zero. If the given variable is in the basis, this routine returns the sign of the corresponding integer on the right-hand side of the tableaux.
pos | the index of the variable to query. This must be between 0 and origTableaux_->columns()-1 inclusive. |