Classes | Typedefs | Functions | Variables

chomp::homology Namespace Reference

This namespace contains the core of the homology computation procedures and related classes and templates contained in the CHomP C++ library. More...

Classes

class  bmpfile
 The class 'bmpfile' is an elementary interface that can be used to read or create and write images in the uncompressed Windows BMP format. More...
class  ColorPalette
 Provides a palette of distinct RGB colors. More...
class  Power
 This is a helper class which makes the compiler compute n^k during the compilation of the program. More...
class  Power< number, 0 >
 This is a specialization which defines n^0, necessary to stop the recursion defined in the "Power" template. More...
class  SetOfFullCubes
 This is an abstract class which defines a set of full cubes represented as a bitmap for the purpose of the class "bincube". More...
class  FixDimBitmap
 A fixed-dimensional bitmap of the size 2^n in each direction. More...
class  bincube
 A binary n-dimensional hypercube for storing cubes as bits. More...
class  NeighborsBdd
 This is a class used by the classes "Acyclic1d", "Acyclic2d", and "Acyclic3d" to use binary decision diagrams for the verification if a cubical neighborhood of a cube in the class "bincube" is acyclic. More...
class  Acyclic1d
 This class defines a procedure for verifying if a full-cubical neighborhood in a given set of a full cube of dimension 1 is acyclic. More...
class  Acyclic2d
 This class defines a procedure for verifying if a full-cubical neighborhood in a given set of a full cube of dimension 2 is acyclic. More...
class  Acyclic3d
 This class defines a procedure for verifying if a full-cubical neighborhood in a given set of a full cube of dimension 3 is acyclic. More...
class  hashNumber
 A class of numbers that can be used in a hashed set. More...
class  tCellBase
 This class defines cubical cell in R^n with edges parallel to the axes and with size 0 or 1 in each direction. More...
class  tCellFix
 This class defines cubical cell in R^n with edges parallel to the axes and with size 0 or 1 in each direction. More...
class  tCellVar
 This class defines cubical cell in R^n with edges parallel to the axes and with size 0 or 1 in each direction. More...
class  tCubeBase
 This class defines a hypercube in R^n with edges parallel to the axes and with size 1 in each direction. More...
class  tCubeFix
 This class defines a hypercube in R^n with edges parallel to the axes and with size 1 in each direction. More...
class  tCubeVar
 This class defines a hypercube in R^n with edges parallel to the axes and with size 1 in each direction. More...
class  tPointBase
 This class keeps a common set of points which are indexed for the use of other classes, like cubes or cubical cells. More...
class  tPointBaseInitializer
 This class is used to deallocate memory kept in the static variables of the corresponding class "tPointBase" upon program exit, and also to show the information on how many points were in use. More...
class  tWrapBase
 This class is a simplified version of the point base class used only for the space wrapping support. More...
class  psethashstat
 This is a small class used only to collect and display statistics on how successful the hashing procedures were. More...
class  tPointset
 This class represents a set of points in R^n with integer coordinates. More...
class  tNeighbors
 This class can be used for iterating point's neighbors. More...
class  tRectangle
 This class can be used for iterating a rectangular set of points, given its left and right bound. More...
class  tCube2l
 A (hyper)cube with additional information about the layer number. More...
class  tCell2l
 A general cubical cell with additional information about the layer number. More...
class  chain
 This class defines objects which represent chains as finite sequences of elements identified by integral numbers with coefficients in a given Euclidean domain. More...
class  simplelist
 This class defines a simple list of pointers to objects of the given type. More...
class  mmatrix
 A class for representing sparse matrices containing elements of the 'euclidom' type. More...
class  chaincomplex
 This is an implementation of a chain complex over an arbitrary ring. More...
class  chainmap
 This class defines a chain map between two chain complexes. More...
class  Neighbors
 The neighborhood of a cube in a set of cubes. More...
class  gcomplex
 The class that defines a geometric complex - a set of cells (cubes, simplices, etc). More...
class  mvcellmap
 This class represents a multivalued map whose domain is a geometric complex. More...
class  MapClass
 This is a general map class that may be inherited by your particular class that computes a map. More...
class  BufferedMapClass
 This class is a wrapper for a map that computes the image of a cube as a rectangular box (i.e., using the interval arithmetic). More...
class  BitFields
 This class defines a simple table of bit fields with very limited functionality that is used for storing the information on the verified combinations of cubes' neighbors. More...
class  Tabulated
 A class for storing tabulated configurations of neighbors for various dimensions. More...
class  Simplex
 This class defines a simplex as a geometric cell that can be used as a member of a geometric complex. More...
class  BitField
 This class defines a bit field that is part of some larger array or that uses an allocated piece of memory. More...
class  SetOfBitFields
 This class defines a set of bit fields of the same length which are to be stored in a contiguous piece of memory to avoid multiple memory allocation/deallocation. More...
class  BitSets
 This class uses bit representation to store many small sets. More...
class  dummyRounding
 A dummy class for rounding operations which does not actually do any rounding. More...
class  dummyArray
 A dummy array of integers that ignores all the assigned values. More...
class  diGraph
 This class defines a directed graph with very limited number of operations, and a few specific algorithms implemented on it, like DFS. More...
class  FibonacciHeap
 This template contains the definition of a Fibonacci heap that can be used as an efficient priority queue, for example, in the Dijxtra graph algorithm. More...
class  flatMatrix
 This class defines a simple data structure for a flat 2-dim square matrix whose entries are stored in a single array. More...
class  hashstat
 This is a small class used to gather and display hashing statistics for the hashing tables in the class "hashedset". More...
class  hashedset
 This is a template for a set of objects of the given type. More...
class  mvmap
 This class defines a multivalued map. More...
class  primeint
 This is a simple class which is a wrapper for computing the smallest prime number greater or equal to the given integer. More...
class  integer
 This class defines integer numbers with overflow control and with some specific properties of an Euclidean domain. More...
class  local_var
 Local variable guardian. More...
class  multitable
 A container for elements placed in a table (like a vector) that is actually built of many smaller tables. More...
class  pool
 This template contains the definition of a pool of elements that are stored in an extensible table. More...
class  setunion
 A union of two hashed sets. More...
class  word
 A word, that is, a string with very few properties. More...
class  argflags
 This is a helper class which defines specific flags indicating various types of command-line arguments and the state of interpreting them. More...
class  argelement
 This is a helper class which defines common properties of a command-line argument bound with any type of a variable. More...
class  argunit
 This is a helper class which defines one command-line argument which is bound with some specific variable. More...
class  arguments
 The objects of this class gather the expected command-line arguments and decode them. More...
class  outputstream
 This class defines an output stream for replacing the standard 'cout'. More...
class  textfile
 A class for reading text data from a text file. More...
class  timeused
 A class that stores the time at which it was initialized and then returns or displays the time used since the initialization. More...

Typedefs

typedef hashedset< hashNumber
< int > > 
hashIntQueue
typedef tCellBase< coordinateCubicalCell
 The default type of a cubical cell.
typedef CubicalCell ElementaryCell
 An alternative name for a cubical cell.
typedef hashedset< CubicalCellSetOfCubicalCells
 The default type of a set of cubical cells.
typedef gcomplex< CubicalCell,
integer
CubicalComplex
 The default type of a cubical complex.
typedef mvcellmap< CubicalCell,
integer, CubicalCell
CubicalMultivaluedMap
 The default type of a cubical multivalued map.
typedef CubicalCell qcell
 An abbreviation for a cubical cell [deprecated].
typedef SetOfCubicalCells qcells
 An abbreviation for a set of cubical cell [deprecated].
typedef CubicalComplex cubicalcomplex
 An abbreviation for a cubical complex [deprecated].
typedef tCubeBase< coordinateCube
 The default cube type.
typedef Cube FullCube
 An alternative name for a cube.
typedef Cube HyperCube
 An alternative name for a cube.
typedef hashedset< CubeSetOfCubes
 The default type of a set of cubes.
typedef mvmap< Cube, CubeCombinatorialMultivaluedMap
 The default type of a combinatorial cubical multivalued map.
typedef Cube cube
 A lower-case name of a cube [deprecated].
typedef SetOfCubes cubes
 An abbreviation for a set of cubes [deprecated].
typedef CombinatorialMultivaluedMap CubicalMap
 An abbreviation for a combinatorial cubical multivalued map.
typedef CombinatorialMultivaluedMap cubicalmap
 A lower-case version of the name of a combinatorial cubical multivalued map [deprecated].
typedef tPointBase< coordinatePointBase
 The default type of the point base class.
typedef short int coordinate
 The default type of coordinates.
typedef tPointset< coordinatepointset
 The pointset class with the default type of coordinates.
typedef tNeighbors< coordinateneighbors
 The neighbors class with the default type of coordinates.
typedef tRectangle< coordinaterectangle
 The rectangle class with the default type of coordinates.
typedef short int theLayerType
 The type of the layer variable.
typedef tCube2l< tCubeBase
< coordinate > > 
Cube2l
 A typical full cube in the two-layer setting.
typedef tCell2l< tCellBase
< coordinate > > 
CubicalCell2l
 A typical cubical cell in the two-layer setting.
typedef mvmap< Cube2l, Cube2lCombinatorialMultivaluedMap2l
 A typical multivalued map on full cubes in the two-layer setting.
typedef hashedset< Cube2lSetOfCubes2l
 A typical set of full cubes in the two-layer setting.
typedef hashedset< CubicalCell2lSetOfCubicalCells2l
 A typical set of cubical cells in the two-layer setting.
typedef gcomplex
< CubicalCell2l, integer
CubicalComplex2l
 A typical cubical complex in the two-layer setting.
typedef mvcellmap
< CubicalCell2l, integer,
CubicalCell2l
CubicalMultivaluedMap2l
 A typical multivalued cubical-cellular map in the two-layer setting.
typedef chaincomplex< integerChainComplex
 A class for representing a chain complex with integral coefficients.
typedef chainmap< integerChainMap
 A class for representing a chain map with integral coefficients.
typedef chain< integerChain
 A class for representing a chain with integral coefficients.
typedef hashedset< simplexSetOfSimplices
 A class for representing a set of simplices.
typedef gcomplex< simplex,
integer
SimplicialComplex
 A class for representing a simplicial complex.
typedef Simplex simplex
 A lower-case name for a simplex [deprecated].
typedef gcomplex< simplex,
integer
simplicialcomplex
 A lower-case name for a simplicial complex [deprecated].
typedef hashedset< simplexsimplices
 An alternative name for a set of simplices [deprecated].
typedef BitField bitfield
 A lower-case version of the name of a bit field [deprecated].
typedef SetOfBitFields bitfieldset
 A lower-case version of the name of a bit field set [deprecated].
typedef signed short numbertype
 The type of number used to store the value of an object of type "integer".
typedef hashedset< wordwords
 The default type of a set of words.

Functions

template<class coordinate >
void bit2neighborAlg (int number, const coordinate *src, coordinate *dest, int Dim)
template<class settype >
settype::iterator bit2neighborAlg (const typename settype::iterator &q, int n)
template<int Dim, int twoPower>
bool operator== (const typename bincube< Dim, twoPower >::neighborhood_iterator &x1, const typename bincube< Dim, twoPower >::neighborhood_iterator &x2)
template<int Dim, int twoPower>
bool operator!= (const typename bincube< Dim, twoPower >::neighborhood_iterator &x1, const typename bincube< Dim, twoPower >::neighborhood_iterator &x2)
template<int Dim, int twoPower>
std::ostream & operator<< (std::ostream &out, const bincube< Dim, twoPower > &b)
template<int Dim, int twoPower>
std::istream & operator>> (std::istream &in, bincube< Dim, twoPower > &b)
template<class Number >
int_t hashkey1 (const hashNumber< Number > &n)
 The first hashing key.
template<class Number >
int_t hashkey2 (const hashNumber< Number > &n)
 The second hashing key.
template<class SetT , class QueueT >
void addneighbors (const int &c, const SetT &s, QueueT &q)
 Adds the neighbors of the cube 'c' in the set 's' to the set 'q'.
template<typename SetT , typename Acyclic , typename QueueT >
int reduceFullCubesAlg (SetT &X, bool quiet)
 Reduces the set of full cubes.
template<class FullCubSet >
int reduceFullCubes (FullCubSet &X, bool quiet=false)
 Reduces the set of full cubes.
int readbitpoints (std::istream &in, pointset &p, int *bitcode_depth=NULL)
 Reads a set of full cubical sets represented as a set of points from a file encoded in the "bitcode" format used by Bill Kalies.
int writebitpoints (std::ostream &out, pointset &p, bool sorted=true, int fixed_depth=0, coordinate *fixed_corner=NULL)
 Writes a full cubical set represented by a set of points to a file in the "bitcode" format.
template<class coordtype >
int operator!= (const tCellBase< coordtype > &c1, const tCellBase< coordtype > &c2)
 Checks if the two cells are different.
template<class coordtype >
tCellBase< coordtype > operator* (const tCellBase< coordtype > &c1, const tCellBase< coordtype > &c2)
 Computes the Cartesian product of two cells.
template<class coordtype >
std::ostream & operator<< (std::ostream &out, const tCellBase< coordtype > &c)
 Writes a cell to an output stream.
template<class coordtype >
std::istream & operator>> (std::istream &in, tCellBase< coordtype > &c)
 Reads a cell from an input stream.
template<class coordtype >
tCellBase< coordtype > boundarycell (const tCellBase< coordtype > &q, int i, bool onlyexisting)
 Computes the i-th boundary element of a cell.
template<class coordtype >
tCellBase< coordtype > boundarycell (const tCellBase< coordtype > &q, int i)
 Computes the i-th boundary element of a cell.
template<class coordtype >
int boundarylength (const tCellBase< coordtype > &q)
 Returns the length of the boundary of a cell.
template<class coordtype >
int boundarycoef (const tCellBase< coordtype > &q, int i)
 Returns the i-th coefficient in the boundary of a cell.
template<int dimfix, class coordtype >
int operator!= (const tCellFix< dimfix, coordtype > &c1, const tCellFix< dimfix, coordtype > &c2)
 Checks if the two cells are different.
template<int dim1, int dim2, class coordtype >
tCellFix< dim1+dim2, coordtype > operator* (const tCellFix< dim1, coordtype > &c1, const tCellFix< dim2, coordtype > &c2)
 Computes the Cartesian product of two cells.
template<int dimfix, class coordtype >
std::ostream & operator<< (std::ostream &out, const tCellFix< dimfix, coordtype > &c)
 Writes a cell to an output stream.
template<int dimfix, class coordtype >
std::istream & operator>> (std::istream &in, tCellFix< dimfix, coordtype > &c)
 Reads a cell from an input stream.
template<int dimfix, class coordtype >
tCellFix< dimfix, coordtype > boundarycell (const tCellFix< dimfix, coordtype > &q, int i, bool onlyexisting)
 Computes the i-th boundary element of a cell.
template<int dimfix, class coordtype >
tCellFix< dimfix, coordtype > boundarycell (const tCellFix< dimfix, coordtype > &q, int i)
 Computes the i-th boundary element of a cell.
template<int dimfix, class coordtype >
int boundarylength (const tCellFix< dimfix, coordtype > &q)
 Returns the length of the boundary of a cell.
template<int dimfix, class coordtype >
int boundarycoef (const tCellFix< dimfix, coordtype > &q, int i)
 Returns the i-th coefficient in the boundary of a cell.
template<class celltype >
celltype CubicalBoundaryCell (const celltype &q, int i, bool onlyexisting)
 Returns the i-th boundary element of a cell.
template<class celltype >
celltype CubicalBoundaryCell (const celltype &q, int i)
 Returns the i-th cell in the boundary of the given cell.
template<class celltype >
int CubicalBoundaryLength (const celltype &q)
 Returns the length of the boundary of a cubical cell.
template<class celltype >
int CubicalBoundaryCoef (const celltype &q, int i)
 Returns the i-th coefficient in the boundary of a cubical cell.
template<class celltype >
std::ostream & WriteCubicalCell (std::ostream &out, const celltype &c)
 Writes a cubical cell to the output stream in the text form.
template<class celltype >
std::istream & ReadCubicalCell (std::istream &in, celltype &c)
 Reads a cubical cell form the input text stream.
template<class coordtype >
int CommonCell (coordtype *left, coordtype *right, const coordtype *c1, const coordtype *c2, int spcdim, const coordtype *wrap=0)
 Computes the left and right corner of a cell which is the intersection of the two given cubes.
template<class coordtype >
int operator!= (const tCellVar< coordtype > &c1, const tCellVar< coordtype > &c2)
 Checks if the two cells are different.
template<class coordtype >
tCellVar< coordtype > operator* (const tCellVar< coordtype > &c1, const tCellVar< coordtype > &c2)
 Computes the Cartesian product of two cells.
template<class coordtype >
std::ostream & operator<< (std::ostream &out, const tCellVar< coordtype > &c)
 Writes a cell to an output stream.
template<class coordtype >
std::istream & operator>> (std::istream &in, tCellVar< coordtype > &c)
 Reads a cell from an input stream.
template<class coordtype >
tCellVar< coordtype > boundarycell (const tCellVar< coordtype > &q, int i, bool onlyexisting)
 Computes the i-th boundary element of a cell.
template<class coordtype >
tCellVar< coordtype > boundarycell (const tCellVar< coordtype > &q, int i)
 Computes the i-th boundary element of a cell.
template<class coordtype >
int boundarylength (const tCellVar< coordtype > &q)
 Returns the length of the boundary of a cell.
template<class coordtype >
int boundarycoef (const tCellVar< coordtype > &q, int i)
 Returns the i-th coefficient in the boundary of a cell.
template<class coordtype >
int operator!= (const tCubeBase< coordtype > &c1, const tCubeBase< coordtype > &c2)
 The operator != for comparing full cubes.
template<class coordtype >
tCubeBase< coordtype > operator* (const tCubeBase< coordtype > &c1, const tCubeBase< coordtype > &c2)
 Computes the Cartesian product of two cubes.
template<class coordtype >
std::ostream & operator<< (std::ostream &out, const tCubeBase< coordtype > &c)
 Writes a cube to an output stream in the text mode.
template<class coordtype >
std::istream & operator>> (std::istream &in, tCubeBase< coordtype > &c)
 Reads a cube from an input stream in the text mode.
template<class coordtype >
std::istream & operator>> (std::istream &in, hashedset< tCubeBase< coordtype > > &s)
 Reads a set of cubes from an input stream in the text mode.
template<class coordtype >
std::istream & operator>> (std::istream &in, mvmap< tCubeBase< coordtype >, tCubeBase< coordtype > > &m)
 Reads a cubical map from an input stream in the text mode.
template<int dim1, int dim2, class coordtype >
int operator!= (const tCubeFix< dim1, coordtype > &c1, const tCubeFix< dim2, coordtype > &c2)
 The operator != for comparing full cubes.
template<int dim1, int dim2, class coordtype >
tCubeFix< dim1+dim2, coordtype > operator* (const tCubeFix< dim1, coordtype > &c1, const tCubeFix< dim2, coordtype > &c2)
 Computes the Cartesian product of two cubes.
template<int dimfix, class coordtype >
std::ostream & operator<< (std::ostream &out, const tCubeFix< dimfix, coordtype > &c)
 Writes a cube to an output stream in the text mode.
template<int dimfix, class coordtype >
std::istream & operator>> (std::istream &in, tCubeFix< dimfix, coordtype > &c)
 Reads a cube from an input stream in the text mode.
template<int dimfix, class coordtype >
std::istream & operator>> (std::istream &in, hashedset< tCubeFix< dimfix, coordtype > > &s)
 Reads a set of cubes from an input stream in the text mode.
template<int dimfix, class coordtype >
std::istream & operator>> (std::istream &in, mvmap< tCubeFix< dimfix, coordtype >, tCubeFix< dimfix, coordtype > > &m)
 Reads a cubical map from an input stream in the text mode.
template<class dest_cube , class src_cube >
dest_cube cube_cast (const src_cube &src)
 Converts one cube into another.
template<class cubetype >
std::ostream & WriteCube (std::ostream &out, const cubetype &c)
 Writes a cube to the output stream in the text mode.
template<class cubetype >
std::istream & ReadCubeFix (std::istream &in, cubetype &c, int dimfix)
 Reads a cube from the input text stream.
template<class cubetype >
std::istream & ReadCube (std::istream &in, cubetype &c)
 Reads a cube from the input text stream.
template<class cubsettype >
std::istream & ReadCubes (std::istream &in, cubsettype &s)
 Reads a set of cubes and ignores the line at the beginning of the file which starts with the letter 'd' (like "dimension 2").
template<class tCube >
std::istream & ReadCubicalMap (std::istream &in, mvmap< tCube, tCube > &m)
 Reads a combinatorial cubical multivalued map from an input text stream.
template<class coordtype >
int operator!= (const tCubeVar< coordtype > &c1, const tCubeVar< coordtype > &c2)
 The operator != for comparing full cubes.
template<class coordtype >
tCubeVar< coordtype > operator* (const tCubeVar< coordtype > &c1, const tCubeVar< coordtype > &c2)
 Computes the Cartesian product of two cubes.
template<class coordtype >
std::ostream & operator<< (std::ostream &out, const tCubeVar< coordtype > &c)
 Writes a cube to an output stream in the text mode.
template<class coordtype >
std::istream & operator>> (std::istream &in, tCubeVar< coordtype > &c)
 Reads a cube from an input stream in the text mode.
template<class coordtype >
std::istream & operator>> (std::istream &in, hashedset< tCubeVar< coordtype > > &s)
 Reads a set of cubes from an input stream in the text mode.
template<class coordtype >
std::istream & operator>> (std::istream &in, mvmap< tCubeVar< coordtype >, tCubeVar< coordtype > > &m)
 Reads a cubical map from an input stream in the text mode.
template<class euclidom , class tCell >
std::ostream & writegenerators (std::ostream &out, const chain< euclidom > *hom, const chaincomplex< euclidom > &c, const gcomplex< tCell, euclidom > &g, const int *level, int xdim, int format=0)
 Writes projected homology generators of a cubical complex to a file.
template<class euclidom , class tCell , class tCube >
int_t createimages (mvcellmap< tCell, euclidom, tCube > &m, const mvmap< tCube, tCube > &f1, const mvmap< tCube, tCube > &f2, const hashedset< tCube > &dom1, const hashedset< tCube > &dom2)
 Creates images of cells in 'm' as unions of cubes determined by f1 and f2.
template<class euclidom , class tCell , class tCube >
int_t createimages (mvcellmap< tCell, euclidom, tCube > &m, const mvmap< tCube, tCube > &f, const hashedset< tCube > &dom)
 A wrapper for the above function if there is only one map.
template<class euclidom , class tCell , class tCube >
int_t createimages (mvcellmap< tCell, euclidom, tCube > &m, const mvmap< tCube, tCube > &f1, const mvmap< tCube, tCube > &f2)
 Creates images of cells in m as unions of cubes determined by f1 and f2.
template<class euclidom , class tCell , class tCube >
int_t createimages (mvcellmap< tCell, euclidom, tCube > &m, const mvmap< tCube, tCube > &f)
 A wrapper for the above function if there is only one map.
template<class euclidom , class tCell >
void createprojection (const gcomplex< tCell, euclidom > &Fcompl, const gcomplex< tCell, euclidom > &Ycompl, chainmap< euclidom > &cmap, int offset, int outdim, int discarddim, int *level=NULL)
 Creates the chain map of the projection from a cell complex of the graph of a map to a cell complex of the codomain of the map.
template<class euclidom , class tCell >
void project (const gcomplex< tCell, euclidom > &c, gcomplex< tCell, euclidom > &img, const gcomplex< tCell, euclidom > &only, int offset, int outdim, int discarddim, const int *level, bool watchforimages)
 Creates the image of the projection from the set of cubical cells in the given geometric complex to the subspace of R^n spanned by the 'outdim' subsequent standard vectors with the first number 'offset'.
template<class tCube >
std::istream & readdomain (std::istream &in, hashedset< tCube > &dom)
 Reads the domain of a multivalued cubical map.
template<class tCube >
std::istream & readimage (std::istream &in, hashedset< tCube > &img)
 Reads the image of a multivalued cubical map.
template<class tCube >
std::istream & readimage (std::istream &in, const hashedset< tCube > &dom, hashedset< tCube > &img)
 Read the image of a set under a multivalued cubical map.
template<class tCube >
std::istream & readselective (std::istream &in, const hashedset< tCube > &dom1, const hashedset< tCube > &dom2, mvmap< tCube, tCube > &m)
 Reads the restriction of a multivalued map to the given pair of sets.
template<class tCube >
std::istream & readselective (std::istream &in, const hashedset< tCube > &dom, mvmap< tCube, tCube > &m)
 Reads a restriction of a multivalued cubical map to the given set.
int_t getmaxneighbors (int dim)
 Returns the maximal number of neighbors of a cube: 3^dim - 1.
template<class tCube >
int_t neighbor2bit (const tCube &q, const tCube &neighbor)
 Returns the number of the neighbor bit for the given neighbor of 'q' or -1 if not a neighbor or the same cube as 'q'.
template<class tCube >
int_t neighbor2bit (const tCube &q, const typename tCube::CellType &face)
 Returns the number of the neighbor bit for the neighbor which intersects the given cube at the face provided.
template<class tCube >
tCube bit2neighbor (const tCube &q, int_t number, bool unconditional=false)
 Creates the neighbor of the given cube with the specified number.
template<class tCube , class tCubeSet1 , class tCubeSet2 >
int_t getneighbors_scan (const tCube &q, BitField *bits, const tCubeSet1 &theset, tCubeSet2 *neighbors, int_t limit)
 Gets neighbors of the given cube from the given set and indicates them in the bit field provided.
template<class tCube , class tCubeSet1 , class tCubeSet2 >
int_t getneighbors_generate (const tCube &q, BitField *bits, const tCubeSet1 &theset, tCubeSet2 *neighbors, int_t limit)
 Gets neighbors of the given cube from the given set and indicates them in the bit field provided.
template<class tCube , class tCubeSet1 , class tCubeSet2 >
int_t getneighbors (const tCube &q, BitField *bits, const tCubeSet1 &theset, tCubeSet2 *neighbors, int_t limit)
 Gets neighbors of the given cube from the given set and indicates them in the bit field provided.
template<class tCube , class tCubeSet >
int_t getneighbors (const tCube &q, BitField *bits, const tCubeSet &theset, int_t limit)
template<class tCube , class tCubeSet >
int_t addneighbors (const tCube &q, const BitField &bits, tCubeSet &set, const tCubeSet &notthese)
 Adds neighbors listed in the given bit field to the set of cubes unless they are in the 'forbidden' set.
template<class tCube , class tCubeSet >
int_t addneighbors (const tCube &q, const BitField &bits, tCubeSet &set, bool unconditional=false)
 Adds neighbors listed in the given bit field to the set of cubes.
template<class tCube , class tCell >
int_t addneighbors (const tCube &q, const BitField &bits, gcomplex< tCell, integer > &c, bool unconditional=false)
 Adds intersections of neighbors listed in the given bit field with the given cube to the cubical complex.
template<class coordtype >
int thesame (const coordtype *c1, const coordtype *c2, int dim)
 Compare two points. Returns true iff they have the same coordinates.
template<class coordtype >
void copycoord (coordtype *destination, const coordtype *source, int dim)
 Copies the coordinates of one point to another.
template<class coordtype >
void wrapcoord (coordtype *destination, const coordtype *source, const coordtype *wrap, int dim)
 Wraps coordinates stored in 'c' accordint to the wrap table 'wrap' and store the result in the table called 'result'.
bool numberisprime (unsigned n)
 Verifies if the given number is a prime number.
unsigned ceilprimenumber (unsigned n)
 Computes the smallest prime number greater than or equal to the given number.
template<class coordtype >
int_t pointhashkey (const coordtype *c, int dim, int_t hashsize)
 Generates the main hashing key for points.
template<class coordtype >
int_t pointhashadd (const coordtype *c, int dim, int_t hashsize)
 Generates the second hashing key for points.
template<class coordtype >
coordtype rounddown (double x)
 Rounds down the given real number to an integral type.
template<class coordtype >
void roundpoint (const double *p, coordtype *c, const double *grid, int dim)
 Rounds down the double coordinates of a point to integer ones.
template<class coordtype >
void cubemiddle (coordtype *c, double *p, double *grid, int dim)
 Computes the middle of a cube with its left lower etc.
template<class coordtype >
coordtype * allocatepoint (int dim, char *errormessage=NULL)
 Allocate a point with 'new'. In case of failure throw an error message.
template<class coordtype >
int countneighbors (const tPointset< coordtype > &p, const coordtype *c, int which=1, int maxcount=0)
 Counts how many neighbors of the point there are in the set, depending on 'which': 1 = in the set, 0 = out of the set.
template<class coordtype >
int countneighbors (const tPointset< coordtype > &p, const tPointset< coordtype > &q, const coordtype *c, int which=1, int maxcount=0)
 Counts neighbors with respect to the union of the sets 'p' and 'q'.
template<class coordtype >
int attheborder (const tPointset< coordtype > &p, const coordtype *c)
 Verifies if the point is at the border of a given set.
template<class coordtype >
int_t findboundarypoint (tPointset< coordtype > &p, int_t n, int direction=1)
 Finds a boundary point starting at the given one.
template<class coordtype >
int_t findboundarypoint (tPointset< coordtype > &p, tPointset< coordtype > &q, int_t n, int direction=1)
 Finds a point in 'p' at the boundary of the union of 'p' and 'q'.
template<class coordtype >
tPointset< coordtype > * computeboundary (tPointset< coordtype > &p)
 Creates the set of all the boundary points with the 'new' operator.
template<class coordtype >
void computeboundary (tPointset< coordtype > &p, tPointset< coordtype > &b)
 Computes the boundary points of the given set and adds them to the other set of points.
template<class coordtype >
void enhancepoint (tPointset< coordtype > &p, coordtype *c)
 Enhances the set by adding the neighborhood of the point with given coordinates.
template<class coordtype >
void enhancepoint (tPointset< coordtype > &p, int_t n)
 Enhances the set by adding the neighborhood of the point with given number.
template<class coordtype >
void enhance (tPointset< coordtype > &p)
 Enhances the set of points by adding to it all the neighbors of all the points in the set.
template<class coordtype >
int read (textfile &f, coordtype *c, int maxdim)
 Reads a point from a text file and removes a pair of parentheses, braces or brackets if present.
template<class coordtype >
int read (std::istream &in, coordtype *c, int maxdim)
 Reads a point from a text file and removes a pair of parentheses, braces or brackets if present.
template<class coordtype >
int write (std::ostream &out, const coordtype *c, int dim, char parenthesis=40, char closing=0)
template<class coordtype >
int readcubeorcell (std::istream &in, coordtype *left, coordtype *right, int maxdim, int *type=NULL)
 Reads a cube or a cell from a text file.
template<class coordtype >
int_t read (textfile &f, tPointset< coordtype > &p, int_t first=0, int_t howmany=-1, coordtype *wrap=NULL, int maxdim=0, int quiet=0, tPointset< coordtype > *notthese=NULL)
 Reads a set of points from an input stream (starting at the point given).
template<class coordtype >
int_t read (std::istream &in, tPointset< coordtype > &p, int_t first=0, int_t howmany=-1, coordtype *wrap=NULL, int maxdim=0, int quiet=0, tPointset< coordtype > *notthese=NULL)
 Reads a set of points from an input stream (starting at the point given).
template<class coordtype >
int_t read (textfile &f, tPointset< coordtype > &p, coordtype *wrap, int maxdim, int quiet=0, tPointset< coordtype > *notthese=NULL)
 Reads a set of points from an input stream (starting at the point given).
template<class coordtype >
int_t read (std::istream &in, tPointset< coordtype > &p, coordtype *wrap, int maxdim, int quiet=0, tPointset< coordtype > *notthese=NULL)
 Reads a set of points from an input stream (starting at the point given).
template<class coordtype >
textfileoperator>> (textfile &f, tPointset< coordtype > &p)
 Reads a set of points from an input stream (starting at the point given).
template<class coordtype >
std::istream & operator>> (std::istream &in, tPointset< coordtype > &p)
 Reads a set of points from an input stream (starting at the point given).
template<class coordtype >
int_t write (std::ostream &out, tPointset< coordtype > &p, int_t first=0, int_t howmany=-1, int quiet=0)
 Writes a set of points to a file (starting at the point given).
template<class coordtype >
std::ostream & operator<< (std::ostream &out, tPointset< coordtype > &p)
 Writes a set of points to a file (starting at the point given).
std::ostream & operator<< (std::ostream &out, const psethashstat &s)
 Writes the information gathered in a hashing statistics collector object to an output stream.
template<class coordtype >
int countneighbors (const tPointset< coordtype > &p, const tPointset< coordtype > &q, coordtype *c, int which, int maxcount)
template<class coordtype >
void computeboundary (const tPointset< coordtype > &p, tPointset< coordtype > &b)
template<class coordtype >
int readcoordinates (std::istream &in, coordtype *coord, int maxdim, int closing)
 Reads the coordinates of a point.
template<class coordtype >
int readcoordinates (std::istream &in, coordtype *coord, int maxdim)
template<class tCube >
int operator== (const tCube2l< tCube > &c1, const tCube2l< tCube > &c2)
 The operator == verifies if two cubes are equal.
template<class tCube >
int operator!= (const tCube2l< tCube > &c1, const tCube2l< tCube > &c2)
 The operator != verifies whether two cubes are different.
template<class tCube >
tCube2l< tCube > operator* (const tCube2l< tCube > &c1, const tCube2l< tCube > &c2)
 The operator * computes the Cartesian product of two cubes.
template<class tCube >
std::ostream & operator<< (std::ostream &out, const tCube2l< tCube > &c)
 The operator << writes a cube to the output stream in the text mode.
template<class tCube >
std::istream & operator>> (std::istream &in, tCube2l< tCube > &c)
 The operator >> reads a cube from the input stream in the text mode.
template<class tCube >
std::istream & operator>> (std::istream &in, hashedset< tCube2l< tCube > > &s)
 A specialized version of the operator >> for reading a set of cubes and ignores the first line "dimension N".
template<class tCube >
std::istream & operator>> (std::istream &in, mvmap< tCube2l< tCube >, tCube2l< tCube > > &m)
 A specialized version of the operator >> that reads a combinatorial cubical multivalued map.
template<class tCell >
int operator== (const tCell2l< tCell > &c1, const tCell2l< tCell > &c2)
 The operator == verifies if two cells are equal.
template<class tCell >
int operator!= (const tCell2l< tCell > &c1, const tCell2l< tCell > &c2)
 The operator != verifies whether two cubes are different.
template<class tCell >
tCell2l< tCell > operator* (const tCell2l< tCell > &c1, const tCell2l< tCell > &c2)
 The operator * computes the Cartesian product of two cells.
template<class tCell >
std::ostream & operator<< (std::ostream &out, const tCell2l< tCell > &c)
 The operator << writes a cubical cell to the text output stream.
template<class tCell >
std::istream & operator>> (std::istream &in, tCell2l< tCell > &c)
 The operator >> reads a cubical cell from the text input stream.
template<class tCell >
tCell2l< tCell > boundarycell (const tCell2l< tCell > &q, int i, bool onlyexisting)
 Computes the given boundary element of a cell.
template<class tCell >
tCell2l< tCell > boundarycell (const tCell2l< tCell > &q, int i)
 Computes the given boundary element of a cell.
template<class tCell >
int boundarylength (const tCell2l< tCell > &q)
 Returns the length of the boundary of a cell.
template<class tCell >
int boundarycoef (const tCell2l< tCell > &q, int i)
 Returns the given coefficient in the boundary of a cell.
template<class tCube >
tCube2l< tCube > bit2neighbor (const tCube2l< tCube > &q, int_t number, bool unconditional=false)
 Specialization of the "bit2neighbor" function for two-layer cubes.
template<class tCube >
int_t neighbor2bit (const tCube2l< tCube > &q, const tCube2l< tCube > &neighbor)
 Specialization of the "neighbor2bit" function for two-layer cubes.
template<class tCube >
bool intersection2l (const tCube &q0, const tCube &q1, BitField *bits)
 Computes the intersection between two cubes at different layers.
template<class tCube , class tCubeSet1 , class tCubeSet2 >
int_t getneighbors_scan (const tCube2l< tCube > &q2l, BitField *bits, const tCubeSet1 &theset, tCubeSet2 *neighbors, int_t limit)
 Specialization of the function which gets neighbors of the given cube by scanning the entire set of possible neighbors.
template<class tCube , class tCubeSet1 , class tCubeSet2 >
int_t getneighbors_generate (const tCube2l< tCube > &q2l, BitField *bits, const tCubeSet1 &theset, tCubeSet2 *neighbors, int_t limit)
 Specialization of the function which gets neighbors of the given cube by generating all the possible neighbors and checking if they are present in the given set.
template<class euclidom , class tCell , class tCube >
int_t createimages (mvcellmap< tCell2l< tCell >, euclidom, tCube2l< tCube > > &m, const mvmap< tCube2l< tCube >, tCube2l< tCube > > &f1, const mvmap< tCube2l< tCube >, tCube2l< tCube > > &f2, const hashedset< tCube2l< tCube > > &dom1, const hashedset< tCube2l< tCube > > &dom2)
 Specialization of the "createimages" function for two-layer cubes.
template<class euclidom >
outputstreamshow_homology (outputstream &out, const chain< euclidom > &c)
 Shows a chain as a list of generators of one level of a homology module.
template<class euclidom >
std::ostream & show_homology (std::ostream &out, const chain< euclidom > &c)
 Shows a chain as a list of generators of one level of a homology module.
template<class euclidom >
std::ostream & operator<< (std::ostream &out, const chain< euclidom > &c)
 Outputs the given chain to a standard output stream in the text mode.
template<class euclidom >
std::istream & operator>> (std::istream &in, chain< euclidom > &c)
 Reads a chain from a standard input stream in the text mode.
template<class euclidom >
std::ostream & operator<< (std::ostream &out, const mmatrix< euclidom > &m)
 Writes a matrix to the output stream as a map in terms of columns.
template<class euclidom >
std::ostream & operator<< (std::ostream &out, const chaincomplex< euclidom > &c)
 Writes a chain complex to an output stream in the text format.
template<class euclidom >
std::ostream & operator<< (std::ostream &out, const chainmap< euclidom > &m)
 Writes a chain map to an output stream in the text format.
template<class NeighborCheck >
bool acyclic1d (NeighborCheck &n)
 Verifies whether the neighborhood of a 1-dimensional "cube" is acyclic.
template<class NeighborCheck >
bool acyclic2d (NeighborCheck &n)
 Verifies whether the neighborhood of a 2-dimensional "cube" is acyclic.
template<class NeighborCheck >
bool acyclic3d_Malandain (NeighborCheck &n)
 Verifies whether the neighborhood of a 3-dimensional cube is acyclic.
template<class NeighborCheck >
bool acyclic3d (NeighborCheck &n)
 Verifies whether the neighborhood of a 3-dimensional cube is acyclic.
template<class tCube , class tCubeSet >
bool bddacyclic (const tCube &q, int dim, const tCubeSet &s, BitField &b)
 Uses binary decision diagrams to verify whether the neighborhood of the given cube in the given set is acyclic.
int acyclic (int dim, BitField &b)
 Checks whether this cube's nieghbors form an acyclic set.
template<class tCube >
bool acyclic (const hashedset< tCube > &cset)
 Checks thoroughly whether the given set of cubes is acyclic.
template<class tCube , class tCubeSet1 , class tCubeSet2 >
bool acyclic (const tCube &q, int dim, const tCubeSet1 &cset, BitField *b, int_t maxneighbors, tCubeSet2 *neighbors)
 Verifies the acyclicity of a neighborhood of the given cube.
template<class tCube , class tCubeSet >
bool acyclic (const tCube &q, int dim, const tCubeSet &cset, BitField *b, int_t maxneighbors)
 Verifies the acyclicity of a neighborhood of the given cube.
template<class tCube >
bool acyclic_rel (const tCube &q, int dim, const hashedset< tCube > &cset, const hashedset< tCube > &other, BitField *b, int_t maxneighbors, hashedset< tCube > *neighbors_main, hashedset< tCube > *neighbors_other)
 Verifies whether a cube from the other set can be removed.
template<class tCube , class tCell >
int_t computeimage (hashedset< tCube > &img, const tCell &face, const mvmap< tCube, tCube > &map, const hashedset< tCube > &cset, const tCube &ignore)
 Computes the image of the face under the combinatorial cubical multivalued map, but doesn't take the given cube into consideration.
template<class tCube >
bool remainsacyclic (const mvmap< tCube, tCube > &map, const tCube &q, const hashedset< tCube > &cset1, const hashedset< tCube > *cset2=0)
 Verifies if the map remains acyclic after the addition or removal of the given cube to/from the union of the first and the second set.
template<class tCube , class tCubeSet >
void addcubeneighbors (const tCube &q, int dim, const tCubeSet &cubset, bitfield *b, hashedset< tCube > &neighbors, hashedset< tCube > &queue, const hashedset< tCube > &notthese)
 A small helper function which adds neighbors of the given cube to the given set.
template<class tCube >
int_t cubreducequiet (const hashedset< tCube > &maincset, hashedset< tCube > &cset, bool quiet=true)
 Reduce the set 'cset' towards 'maincset'.
template<class tCube >
int_t cubreduce (const hashedset< tCube > &maincset, hashedset< tCube > &cset)
 Reduces a pair of sets of cubes for relative homology computation.
template<class tCube >
int_t cubreducequiet (hashedset< tCube > &cset, hashedset< tCube > &other, mvmap< tCube, tCube > &map, const hashedset< tCube > &keep, bool quiet=true)
 Reduces a pair of sets of cubes for relative homology computation.
template<class tCube >
int_t cubreduce (hashedset< tCube > &cset, hashedset< tCube > &other, mvmap< tCube, tCube > &cubmap, const hashedset< tCube > &keep)
 Reduces a pair of sets of cubes for relative homology computation.
template<class tCube >
int_t cubreducequiet (hashedset< tCube > &cset, hashedset< tCube > &other, const hashedset< tCube > &keep, bool quiet=true)
 Reduces a pair of sets of cubes for relative homology computation.
template<class tCube >
int_t cubreduce (hashedset< tCube > &cset, hashedset< tCube > &other, const hashedset< tCube > &keep)
 Reduces a pair of sets of cubes for relative homology computation.
template<class tCube >
int_t cubexpand (hashedset< tCube > &cset, hashedset< tCube > &other, bool quiet=false)
 Expands the set 'other' towards 'cset' without changing the homology of (cset + other, other).
template<class tCube >
int_t cubexpand (hashedset< tCube > &cset, hashedset< tCube > &other, hashedset< tCube > &imgsrc, hashedset< tCube > &img, const mvmap< tCube, tCube > &map, bool indexmap, bool checkacyclic, bool quiet=false)
 Expands the set 'other' towards 'cset' without changing the homology of (cset + other, other).
template<class cell >
int boundarycoef (const cell &, int i)
template<class cell >
int boundarylength (const cell &)
template<class cell >
cell boundarycell (const cell &, int i)
template<class element >
int_t findelem (const multitable< element > &tab, const element &e, int_t len)
 Finds the given element in the table of given length.
template<class cell , class euclidom >
chaincomplex< euclidom > & createchaincomplex (chaincomplex< euclidom > &c, const gcomplex< cell, euclidom > &g, bool quiet=false)
 Creates an algebraic chain complex based on the data from the given geometric cell complex.
template<class cell , class euclidom >
std::ostream & writechaincomplex (std::ostream &out, const gcomplex< cell, euclidom > &g, bool symbolicnames=false, bool quiet=false)
 Writes out a chain complex of the geometric cell complex.
template<class cell , class euclidom >
chaincomplex< euclidom > & createchaincomplex (chaincomplex< euclidom > &c, const gcomplex< cell, euclidom > &g, const gcomplex< cell, euclidom > &rel, bool quiet=false)
 Creates a relative algebraic chain complex with the data from the given pair of geometric cell complexes.
template<class cell , class euclidom >
std::ostream & writegenerators (std::ostream &out, const chain< euclidom > *hom, const chaincomplex< euclidom > &c, const gcomplex< cell, euclidom > &g, const int *level=NULL)
 Writes the homology generators of the geometric complex to a file.
template<class cell , class euclidom >
gcomplex< cell, euclidom > & creategraph (const mvmap< cell, cell > &m, gcomplex< cell, euclidom > &graph)
 Add a graph of a multivalued cell map to the cell complex.
template<class cell , class euclidom >
bool acyclic (gcomplex< cell, euclidom > &c)
 Checks whether this chain complex is acyclic.
template<class cell , class euclidom >
std::ostream & operator<< (std::ostream &out, const gcomplex< cell, euclidom > &c)
 Writes a geometric complex to the output stream in the text format.
template<class cell , class euclidom >
std::istream & operator>> (std::istream &in, gcomplex< cell, euclidom > &c)
 Reads a geometric complex from an input stream in the text format.
template<class cell , class euclidom , class element >
void creategraph (const mvcellmap< cell, euclidom, element > &m, gcomplex< cell, euclidom > &c, bool addbd)
 Creates the full graph of a map as a cellular complex.
template<class cell , class euclidom , class element >
void creategraph (const mvcellmap< cell, euclidom, element > &m, const gcomplex< cell, euclidom > &rel, gcomplex< cell, euclidom > &c, bool addbd)
 Creates the full graph of a map as a cellular complex.
template<class cell , class euclidom , class element >
void createcellmap (const mvcellmap< cell, euclidom, element > &m, mvcellmap< cell, euclidom, cell > &cm)
 Creates the graph of the map as a cell complex while reducing as possible.
template<class cell , class euclidom , class element >
bool createcellmap (const mvcellmap< cell, euclidom, element > &m, const mvcellmap< cell, euclidom, element > &rel, mvcellmap< cell, euclidom, cell > &cm, bool verifyacyclicity)
 Creates the graph of the map as a cell complex while reducing as possible.
template<class cell , class euclidom , class element >
std::ostream & operator<< (std::ostream &out, const mvcellmap< cell, euclidom, element > &m)
 Writes a multivalued cellular map to the output stream.
template<class euclidom >
int BettiNumber (const chain< euclidom > &c)
 Returns the Betti number that corresponds to the given chain which describes one homology group.
template<class euclidom >
int TorsionCoefficient (const chain< euclidom > &c, int start=0)
 Returns the next position in the chain containing a torsion coefficient.
template<class euclidom >
void ShowHomology (const chain< euclidom > &c)
 Shows (that is, writes to 'sout') one level of the homology module encoded in the given chain.
template<class euclidom >
void ShowHomology (const chain< euclidom > *hom, int maxlevel)
 Shows (that is, writes to 'sout') the entire homology module encoded in an array of chains.
template<class euclidom >
void ShowHomology (const chainmap< euclidom > &hmap)
 Show (that is, writes to 'sout') the homology map encoded in terms of a chain map.
template<class euclidom >
void ShowGenerator (const chain< euclidom > &c)
 Shows (that is, writes to 'sout') one generator of the homology module of a chain complex.
template<class euclidom >
void ShowGenerators (const chain< euclidom > *c, int count)
 Shows (that is, writes to 'sout') all the generators of one level of the homology module of a chain complex.
template<class euclidom >
void ShowGenerators (chain< euclidom > const *const *const gen, const chain< euclidom > *hom, int maxlevel)
 Shows (that is, writes to 'sout') all the generators of the entire homology module of a chain complex.
template<class euclidom >
void ShowGenerators (const chaincomplex< euclidom > &c, const chain< euclidom > *hom, int maxlevel)
 Shows (that is, writes to 'sout') all the generators of the entire homology module of a chain complex.
template<class cell , class euclidom >
void ShowGenerator (const chain< euclidom > &c, const hashedset< cell > &s)
 Shows (that is, writes to 'sout') one generator of the homology module of a geometric complex.
template<class cell , class euclidom >
void ShowGenerators (const chain< euclidom > *c, int count, const hashedset< cell > &s)
 Shows (that is, writes to 'sout') all the generators of one level of the homology module of a geometric complex.
template<class euclidom , class cell >
void ShowGenerators (chain< euclidom > *const *gen, const chain< euclidom > *hom, int maxlevel, const gcomplex< cell, euclidom > &gcompl)
 Shows all the generators of the entire homology module of a geometric complex.
template<class euclidom >
chain< euclidom > ** ExtractGenerators (const chaincomplex< euclidom > &cx, chain< euclidom > *hom, int maxlevel)
 Extracts homology generators from a chain complex in the simple form.
template<class euclidom >
int Homology (chaincomplex< euclidom > &cx, const char *Xname, chain< euclidom > *&hom)
 Transforms the chain complex into a simple form and compute its homology.
template<class cell , class euclidom >
int Homology (gcomplex< cell, euclidom > &Xcompl, const char *Xname, chain< euclidom > *&hom, chain< euclidom > ***gen=0)
 Computes the homology of a given cubical complex.
template<class euclidom , class cubetype >
int Homology (hashedset< cubetype > &Xcubes, const char *Xname, chain< euclidom > *&hom, chain< euclidom > ***gen=0, gcomplex< typename cubetype::CellType, euclidom > **gcompl=0)
 Computes the homology of a given set of cubes.
template<class cell , class euclidom >
int Homology (gcomplex< cell, euclidom > &Xcompl, const char *Xname, gcomplex< cell, euclidom > &Acompl, const char *Aname, chain< euclidom > *&hom, chain< euclidom > ***gen=0)
 Computes the relative homology of the given pair of cubical complexes.
template<class euclidom , class cubetype >
int Homology (hashedset< cubetype > &Xcubes, const char *Xname, hashedset< cubetype > &Acubes, const char *Aname, chain< euclidom > *&hom, chain< euclidom > ***gen=0, gcomplex< typename cubetype::CellType, euclidom > **gcompl=0)
 Computes the relative homology of a given pair of sets of cubes.
template<class euclidom >
chainmap< euclidom > * HomologyMap (const chainmap< euclidom > &cmap, const chain< euclidom > *hom_cx, const chain< euclidom > *hom_cy, int maxlevel)
 Extracts the homomorphism induced in homology from the chain map on two chain complexes whose homology has just been computed.
template<class euclidom >
chainmap< euclidom > * HomologyMap (const chainmap< euclidom > &cmap, const chain< euclidom > *hom_cx, int maxlevel)
 Extracts the endomorphism induced in homology from the chain map on one chain complex whose homology has just been computed.
template<class euclidom , class cubetype >
int Homology (mvmap< cubetype, cubetype > &Fcubmap, const char *Fname, hashedset< cubetype > &Xcubes, const char *Xname, hashedset< cubetype > &Acubes, const char *Aname, hashedset< cubetype > &Ycubes, const char *Yname, hashedset< cubetype > &Bcubes, const char *Bname, chain< euclidom > *&hom_cx, int &maxlevel_cx, chain< euclidom > *&hom_cy, int &maxlevel_cy, chainmap< euclidom > *&hom_f, bool inclusion=false, int careful=0x01, chain< euclidom > ***gfgen=0, gcomplex< typename cubetype::CellType, euclidom > **gfcompl=0, chain< euclidom > ***gygen=0, gcomplex< typename cubetype::CellType, euclidom > **gycompl=0)
 Computes the homomorphism induced in homology by a combinatorial cubical multivalued map.
template<class euclidom , class cubetype >
int Homology (mvmap< cubetype, cubetype > &Fcubmap, hashedset< cubetype > &Xcubes, hashedset< cubetype > &Acubes, hashedset< cubetype > &Ycubes, hashedset< cubetype > &Bcubes, chain< euclidom > *&hom_cx, int &maxlevel_cx, chain< euclidom > *&hom_cy, int &maxlevel_cy, chainmap< euclidom > *&hom_f, bool inclusion=false, int careful=0x01, chain< euclidom > ***gfgen=0, gcomplex< typename cubetype::CellType, euclidom > **gfcompl=0, chain< euclidom > ***gygen=0, gcomplex< typename cubetype::CellType, euclidom > **gycompl=0)
 A version of the above procedure with the default names.
template<class euclidom , class cubetype >
int Homology (mvmap< cubetype, cubetype > &Fcubmap, const char *Fname, hashedset< cubetype > &Xcubes, const char *Xname, hashedset< cubetype > &Acubes, const char *Aname, chain< euclidom > *&hom, int &maxlevel, chainmap< euclidom > *&hom_f, int careful=0x01, chain< euclidom > ***gfgen=0, gcomplex< typename cubetype::CellType, euclidom > **gfcompl=0, chain< euclidom > ***gygen=0, gcomplex< typename cubetype::CellType, euclidom > **gycompl=0)
 Computes the endomorphism induced in homology by a combinatorial cubical multivalued map.
template<class euclidom , class cubetype >
int Homology (mvmap< cubetype, cubetype > &Fcubmap, hashedset< cubetype > &Xcubes, hashedset< cubetype > &Acubes, chain< euclidom > *&hom, int &maxlevel, chainmap< euclidom > *&hom_f, int careful=0x01, chain< euclidom > ***gfgen=0, gcomplex< typename cubetype::CellType, euclidom > **gfcompl=0, chain< euclidom > ***gygen=0, gcomplex< typename cubetype::CellType, euclidom > **gycompl=0)
 A version of the above procedure with the default names.
template<class euclidom , class cubetype >
int Homology2l (mvmap< cubetype, cubetype > &Fcubmap0, const char *Fname, hashedset< cubetype > &Xcubes0, const char *Xname, hashedset< cubetype > &Acubes0, const char *Aname, chain< euclidom > *&hom_cx, int &maxlevel, chainmap< euclidom > *&hom_f, int careful=0x01, chain< euclidom > ***gfgen=0, gcomplex< tCell2l< typename cubetype::CellType >, euclidom > **gfcompl=0, chain< euclidom > ***gygen=0, gcomplex< tCell2l< typename cubetype::CellType >, euclidom > **gycompl=0)
 Computes the endomorphism induced in homology by a combinatorial cubical multivalued map using the two-layer construction developped by P.
template<class euclidom , class cubetype >
int Homology2l (mvmap< cubetype, cubetype > &Fcubmap, hashedset< cubetype > &Xcubes, hashedset< cubetype > &Acubes, chain< euclidom > *&hom, int &maxlevel, chainmap< euclidom > *&hom_f, int careful=0x01, chain< euclidom > ***gfgen=0, gcomplex< tCell2l< typename cubetype::CellType >, euclidom > **gfcompl=0, chain< euclidom > ***gygen=0, gcomplex< tCell2l< typename cubetype::CellType >, euclidom > **gycompl=0)
 A version of the above procedure with the default names.
bool acyclic (const cube &q, const cubes &X)
 Verifies whether the neighborhood of q in X is acyclic.
template<int dim, int twoPower>
void ComputeBettiNumbers (bincube< dim, twoPower > &b, int *result)
 Computes the Betti Numbers of a set of full cubes in a bincube.
template<int dim, int twoPower, class coordtype >
void ComputeBettiNumbers (char *binary_buffer, int *result, const coordtype *space_wrapping=0)
 Computes the Betti Numbers of the Homology of a full cubical set defined by means of an n-dimensional bitmap.
template<class coordtype >
void ComputeBettiNumbers (coordtype *coord, int n, int dim, int *result)
 Computes the Betti numbers of the given set of full cubes.
template<class coordtype >
void SetSpaceWrapping (int dim, const coordtype *wrap)
 Sets space wrapping in each direction separately.
template<class tCube >
void scancubes (const char *name)
 Reads all the cubes from the given file and ignores them.
template<class settype >
void readtheset (const char *name, settype &s, const char *pluralname, const char *what)
 Reads a given set from the file and shows appropriate messages.
template<class cell , class euclidom >
void readcells (const char *name, gcomplex< cell, euclidom > &s, const char *what)
 Uses the general procedure "readtheset" to read a geometric complex.
template<class element >
void readelements (const char *name, hashedset< element > &s, const char *what)
 Uses the general procedure "readtheset" to read a set of elements.
void readelements (const char *name, cubes &cub, const char *what)
 Reads a set of cubes from the given file.
template<class element >
void readmapdomain (const char *name, hashedset< element > &cub)
 Reads the domain of a cubical multivalued map from the given file.
template<class element >
void readmapimage (const char *name, hashedset< element > &cub)
 Reads the domain of a cubical multivalued map from the given file.
template<class element >
void readmapimage (const char *filename, const hashedset< element > &dom, const char *domname, hashedset< element > &cub)
 Reads the image of a set by a cubical multivalued map from the given file.
template<class element >
void readmaprestriction (mvmap< element, element > &Fcubmap, const char *mapname, const hashedset< element > &Xcubes, const hashedset< element > &Acubes, const char *Xname, const char *purpose=0)
 Reads the restriction of a multivalued map to the union of two sets.
template<class element >
void readmaprestriction (mvmap< element, element > &Fcubmap, const char *mapname, const hashedset< element > &Xcubes, const char *Xname, const char *purpose=NULL)
 Reads the restriction of a multivalued map to the given set.
template<class settype >
void savetheset (const char *name, const settype &s, const char *pluralname, const char *what, const char *filecomment=0)
 Saves a given set to a file and shows appropriate messages.
template<class cell , class euclidom >
void savecells (const char *name, const gcomplex< cell, euclidom > &s, const char *what, const char *filecomment=0)
 Uses the general procedure "savetheset" to save a geometric complex.
template<class element >
void saveelements (const char *name, const hashedset< element > &s, const char *what, const char *filecomment=0)
 Uses the general procedure "savetheset" to save a set of elements.
void saveelements (const char *name, const cubes &cub, const char *what, const char *filecomment=0)
 Saves a set of cubes to the given file.
template<class cubsettype >
bool checkinclusion (const cubsettype &Xcubes, const cubsettype &Ycubes, const cubsettype &Bcubes, const char *Xname, const char *YBname)
 Checks if X is a subset of the union of Y and B.
template<class cubsettype >
bool checkinclusion (const cubsettype &Xcubes, const cubsettype &Ycubes, const char *Xname, const char *Yname)
 Checks for the inclusion of X in Y.
template<class maptype , class cubsettype >
bool checkimagecontained (const maptype &Fcubmap, const cubsettype &Xcubes, const cubsettype &Ycubes, const cubsettype &Bcubes, const char *Xname, const char *Yname)
 Checks if the image of X by F is contained in the union of Y and B.
template<class maptype , class cubsettype >
bool checkimagecontained (const maptype &Fcubmap, const cubsettype &Xcubes, const cubsettype &Ycubes, const char *Xname, const char *Yname)
 Checks if the image of X by F is contained in the set Y alone.
template<class maptype , class cubsettype >
bool checkimagedisjoint (const maptype &Fcubmap, const cubsettype &Acubes, const cubsettype &Ycubes, const char *Aname, const char *Yname)
 Checks if the image of A by F is disjoint from Y (actually, from Y\B).
template<class tCell , class tCube , class tCoef >
bool checkacyclicmap (const mvcellmap< tCell, tCoef, tCube > &Fcellcubmap, const char *Xname)
 Checks if the image of each element of the domain of this map is acyclic.
template<class cubsettype >
void restrictAtoneighbors (const cubsettype &Xcubes, cubsettype &Acubes, const char *Xname, const char *Aname, const cubsettype *keepcubes=0)
 Restricts the set of cubes 'Acubes' to these cubes which are neighbors of any of the cubes in 'Xcubes' and displays appropriate messages.
template<class cubsettype >
void removeAfromX (cubsettype &Xcubes, const cubsettype &Acubes, const char *Xname, const char *Aname)
 Removes 'Acubes' from 'Xcubes' and shows messages.
template<class cell , class euclidom >
void removeAfromX (gcomplex< cell, euclidom > &X, const gcomplex< cell, euclidom > &A, const char *Xname, const char *Aname)
 Removes from 'X' all the cells that appear in 'A'.
template<class cubsettype >
void expandAinX (cubsettype &Xcubes, cubsettype &Acubes, const char *Xname, const char *Aname)
 Expands the other element of the pair into the main portion of the set.
template<class cubsettype , class maptype >
void expandAinX (cubsettype &Xcubes, cubsettype &Acubes, cubsettype &Ycubes, cubsettype &Bcubes, const maptype &Fcubmap, const char *Xname, const char *Aname, const char *Bname, bool indexmap, bool checkacyclic)
 Expands the other element of the pair into the main portion of the set.
template<class cubsettype >
void reducepair (cubsettype &Xcubes, cubsettype &Acubes, const cubsettype &Xkeepcubes, const char *Xname, const char *Aname)
 Reduces the pair of sets of cubes. Keeps the given cubes untouched.
template<class maptype , class cubsettype >
void reducepair (cubsettype &Xcubes, cubsettype &Acubes, maptype &Fcubmap, const cubsettype &Xkeepcubes, const char *Xname, const char *Aname)
 Reduces the pair of sets of cubes.
template<class maptype , class cubsettype >
void addmapimg (const maptype &Fcubmap, const maptype &FcubmapA, const cubsettype &Xcubes, const cubsettype &Acubes, cubsettype &Ykeepcubes, bool indexmap)
 Adds the images of both maps to the set of cubes to be kept.
template<class maptype , class cubsettype >
void addmapimg (const maptype &Fcubmap, const cubsettype &Xcubes, const cubsettype &Acubes, cubsettype &Ykeepcubes, bool indexmap)
 Adds the image of the given map to the set of cubes to be kept.
template<class tCubes , class tCell , class tCoef >
void cubes2cells (tCubes &Xcubes, gcomplex< tCell, tCoef > &Xcompl, const char *Xname, bool deletecubes=true)
 Transforms cubes to full-dimensional cells.
template<class cell , class euclidom >
void collapse (gcomplex< cell, euclidom > &Xcompl, gcomplex< cell, euclidom > &Acompl, gcomplex< cell, euclidom > &Xkeepcompl, const char *Xname, const char *Aname, bool addbd=true, bool addcob=false, bool disjoint=true, const int *level=NULL)
 Collapses a pair of geometric complexes.
template<class cell , class euclidom >
void collapse (gcomplex< cell, euclidom > &Xcompl, gcomplex< cell, euclidom > &Acompl, const char *Xname, const char *Aname, bool addbd=true, bool addcob=false, bool disjoint=true, const int *level=NULL)
 Collapses a pair of geometric complexes.
template<class cell , class euclidom >
void collapse (gcomplex< cell, euclidom > &Xcompl, gcomplex< cell, euclidom > &Xkeepcompl, const char *Xname, bool addbd=true, bool addcob=false, bool disjoint=true, const int *level=NULL)
 Collapses a single geometric complex.
template<class cell , class euclidom >
void collapse (gcomplex< cell, euclidom > &Xcompl, const char *Xname, bool addbd=true, bool addcob=false, bool disjoint=true, const int *level=NULL)
 Collapses a single geometric complex.
template<class cell , class euclidom >
void decreasedimension (gcomplex< cell, euclidom > &Acompl, int dim, const char *name)
 Decreases the dimension of the geometric complex by adding boundary cells to all the cells on higher dimensions and then removing these cells.
template<class cell , class euclidom >
void addboundaries (gcomplex< cell, euclidom > &Xcompl, gcomplex< cell, euclidom > &Acompl, int minlevel, bool bothsets, const char *Xname, const char *Aname)
 Adds boundaries to the geometric complex X or to both X and A.
template<class tCube >
int ReadBitmapFile (const char *bmpname, hashedset< tCube > &cset, int mingray=0, int maxgray=128)
 Reads the squares from a bitmap file to the set of cubes.
template<class TCube >
std::ostream & operator<< (std::ostream &out, const BufferedMapClass< TCube > &map)
template<class TSetOfCubes >
int neighborhood (const TSetOfCubes &X, TSetOfCubes &result)
 Computes a cubical neighborhood of width 1 around the set.
template<class TSetOfCubes , class TMap >
void invariantpart (TSetOfCubes &X, const TMap &F, TSetOfCubes &result)
 Computes X := Inv (X).
template<class HSet >
bool inclusion (const HSet &X, const HSet &Y)
 Verifies if X is a subset of Y. Returns true if yes, false if not.
template<class TSetOfCubes , class TMap >
int ExitSetM (const TSetOfCubes &N, const TSetOfCubes &Q1, const TMap &F, TSetOfCubes &resultQ2)
 Computes iteratively Q2 := (F (Q1 + Q2) - Q1) * N.
template<class TSetOfCubes , class TMap >
int IndexPairM (const TMap &F, const TSetOfCubes &initialS, TSetOfCubes &resultQ1, TSetOfCubes &resultQ2)
 Constructs a combinatorial index pair satisfying Mrozek's definition.
template<class TSetOfCubes , class TMap >
int IndexPairP (const TMap &F, const TSetOfCubes &initialS, TSetOfCubes &resultQ1, TSetOfCubes &resultQ2)
 Constructs a combinatorial index pair satisfying Pilarczyk's definition.
int operator== (const Simplex &s, const Simplex &t)
 The operator == that compares whether the two simplices are the same, that is, have the same vertices in the same order.
int operator!= (const Simplex &s, const Simplex &t)
 The operator != verifies if the two simplices are different.
int boundarylength (const Simplex &s)
 Returns the length of the boundary of a simplex.
int boundarycoef (const Simplex &, int i)
 Returns the i-th coefficient in the boundary of a simplex.
Simplex boundarycell (const Simplex &s, int i)
 Returns the i-th boundary face of a simplex.
Simplex boundarycell (const Simplex &s, int i, bool)
 Returns the i-th boundary face of a simplex.
std::ostream & operator<< (std::ostream &out, const Simplex &s)
 Writes a simplex to the output stream in the text format.
std::istream & operator>> (std::istream &in, Simplex &s)
 Reads a simplex from an imput stream from a text format.
int bitcountbyte (char n)
int bitcount (int number)
void int2bits (int bits, int_t length, BitField &field)
int bits2int (const BitField &field, int_t length)
template<class wType1 , class wType2 >
bool operator== (const diGraph< wType1 > &g1, const diGraph< wType2 > &g2)
template<class wType1 , class wType2 >
bool operator!= (const diGraph< wType1 > &g1, const diGraph< wType2 > &g2)
template<class wType >
std::ostream & operator<< (std::ostream &out, const diGraph< wType > &g)
 Writes a graph in the text mode to an output stream.
template<class wType , class Table1 , class Table2 >
int_t SCC (const diGraph< wType > &g, Table1 &compVertices, Table2 &compEnds, diGraph< wType > *scc=0, diGraph< wType > *transposed=0, bool copyweights=false)
 Computes strongly connected components of the graph 'g'.
template<class wType , class Table1 , class Table2 >
int_t SCC_Tarjan (const diGraph< wType > &g, Table1 &compVertices, Table2 &compEnds)
 Computes strongly connected components of the graph 'g' using Tarjan's algorithm (as described in the Wikipedia).
template<class wType >
int_t addRenumEdges (const diGraph< wType > &g, int_t vertex, const int_t *newNum, int_t cur, int_t *srcVert, diGraph< wType > &result)
 A helper function for "collapseVertices".
template<class wType , class Table1 , class Table2 >
int_t collapseVertices (const diGraph< wType > &g, int_t compNum, Table1 &compVertices, Table2 &compEnds, diGraph< wType > &result, int_t *newNumbers=0)
 Collapses disjoint subsets of vertices to single vertices and creates a corresponding graph in which the first vertices come from the collapsed ones.
template<class wType , class TabSets >
int_t addRenumEdges2 (const diGraph< wType > &g, int_t vertex, const int_t *newNum, TabSets &numSets, int_t cur, int_t *srcVert, diGraph< wType > &result)
 A helper function for "collapseVertices2".
template<class wType , class Table1 , class Table2 >
int_t collapseVertices2 (const diGraph< wType > &g, int_t compNum, Table1 &compVertices, Table2 &compEnds, diGraph< wType > &result)
 Collapses (possibly non-disjoint) subsets of vertices to single vertices and creates a corresponding graph in which the first vertices come from the collapsed ones.
template<class wType >
int_t connectionGraph (const diGraph< wType > &g, int_t nVert, diGraph< wType > &result)
 Computes the graph that represents connections between a number of the first vertices in the given graph.
template<class GraphType >
int_t computePeriod (const GraphType &g)
 Computes the period of a strongly connected graph.
template<class wType >
int_t inclusionGraph (const diGraph< wType > &g, int_t nVert, diGraph< wType > &result)
 Computes the graph that represents flow-induced relations on Morse sets.
template<class wType , class TConn >
int_t inclusionGraph (const diGraph< wType > &g, int_t nVert, diGraph< wType > &result, TConn &connections)
 A more complicated version of the 'inclusionGraph' function.
template<class wType , class matrix >
void graph2matrix (const diGraph< wType > &g, matrix &m)
 Creates the adjacency matrix of the given graph.
template<class wType , class matrix >
void matrix2graph (const matrix &m, int_t n, diGraph< wType > &g)
 Creates a graph based on the given adjacency matrix.
template<class matrix >
void transitiveClosure (matrix &m, int_t n)
 Computes the transitive closure of an acyclic graph defined by its adjacency matrix, using the Warshall's algorithm: S.
template<class matrix >
void transitiveReduction (matrix &m, int_t n)
 Computes the transitive reduction of a CLOSED acyclic graph defined by its adjacency matrix, using the algorithm by D.
template<class wType >
void transitiveReduction (const diGraph< wType > &g, diGraph< wType > &gRed)
 Computes the transitive reduction of an arbitrary acyclic graph.
std::ostream & operator<< (std::ostream &out, const hashstat &s)
 Shows hashing statistics in a concise and readable way to the output stream in the text format.
template<class stream , class element >
stream & write (stream &out, const hashedset< element > &s, bool size)
 Writes the entire hashed set to an output stream in the text mode.
template<class element >
std::ostream & operator<< (std::ostream &out, const hashedset< element > &s)
 Writes a hashed set to an output stream as a large one (each element is written on a separate line, with some comments at the beginning).
template<class stream , class element >
stream & read (stream &in, hashedset< element > &s, bool size)
 Reads a hashed set from an input stream, either a small size style or a large one.
template<class element >
std::istream & operator>> (std::istream &in, hashedset< element > &s)
 Reads a hashed set from an input stream in a large size style (each element occupies one line, any comments are ignored).
template<class element >
hashedset< element > & operator+= (hashedset< element > &s, const hashedset< element > &u)
 Operator += adds one hashed set to another.
template<class element >
hashedset< element > & operator-= (hashedset< element > &s, const hashedset< element > &u)
 Operator -= removes the contents of one set from another.
int_t hashkey1 (const unsigned long &number)
 The first hash key for an unsigned int number.
int_t hashkey2 (const unsigned long &number)
 The second hash key for an unsigned int number.
int_t hashkey1 (const unsigned int &number)
int_t hashkey2 (const unsigned int &number)
int_t hashkey1 (const signed int &number)
int_t hashkey2 (const signed int &number)
int_t hashkey1 (const signed long &number)
int_t hashkey2 (const signed long &number)
int_t hashkey1 (const unsigned short &number)
int_t hashkey2 (const unsigned short &number)
int_t hashkey1 (const signed short &number)
int_t hashkey2 (const signed short &number)
int_t hashkey1 (const unsigned char &number)
int_t hashkey2 (const unsigned char &number)
int_t hashkey1 (const signed char &number)
int_t hashkey2 (const signed char &number)
template<class T >
int_t hashkey1 (const T &x)
 A template function that extracts the first hash key from an object which has the method "hashkey1".
template<class T >
int_t hashkey2 (const T &x)
 A template function that extracts the second hash key from an object which has the method "hashkey2".
template<class domelement , class imgelement >
hashedset< imgelement > & retrieveimage (const mvmap< domelement, imgelement > &m, hashedset< imgelement > &img)
 Adds images of all the elements from the domain of the map to 'img'.
template<class domelement , class imgelement >
hashedset< imgelement > & creategraph (const mvmap< domelement, imgelement > &m, hashedset< imgelement > &graph)
 Adds a graph of a multivalued map to the given set.
template<class domelement , class imgelement >
std::istream & readdomain (std::istream &in, hashedset< domelement > &dom, const mvmap< domelement, imgelement > &)
 Reads the domain of a multivalued map.
template<class domelement , class imgelement >
std::istream & readimage (std::istream &in, hashedset< imgelement > &img, const mvmap< domelement, imgelement > &)
 Reads the image of a multivalued map.
template<class domelement , class imgelement >
std::istream & readselective (std::istream &in, mvmap< domelement, imgelement > &m, const hashedset< domelement > &dom1, const hashedset< domelement > &dom2)
 Reads a restriction of a multivalued map to the union of the given sets.
template<class domelement , class imgelement >
std::istream & readrestriction (std::istream &in, mvmap< domelement, imgelement > &m, const hashedset< domelement > &dom, const hashedset< imgelement > &img)
 Reads a restriction of a multivalued map to the two given sets.
template<class domelement , class imgelement >
std::istream & readselective (std::istream &in, mvmap< domelement, imgelement > &m, const hashedset< domelement > &dom)
 Reads a restriction of a multivalued map to the given set.
template<class domelement , class imgelement >
std::ostream & operator<< (std::ostream &out, const mvmap< domelement, imgelement > &m)
 Writes a multivalued map to the output stream.
template<class domelement , class imgelement >
std::istream & operator>> (std::istream &in, mvmap< domelement, imgelement > &m)
 Reads a multivalued map from an input stream.
std::ostream & operator<< (std::ostream &out, const primeint &p)
 Writes an object of the type "primeint" to an output stream.
std::istream & operator>> (std::istream &in, primeint &p)
 Reads a prime number from an input stream.
std::ostream & operator<< (std::ostream &out, const integer &n)
std::istream & operator>> (std::istream &in, integer &n)
int operator!= (const integer &n, const integer &m)
int operator== (const integer &n, int m)
int operator!= (const integer &n, int m)
integer operator- (const integer &n, const integer &m)
bool operator< (const integer &x, const integer &y)
bool operator> (const integer &x, const integer &y)
template<typename T >
void my_swap (T &x, T &y)
template<class set1type , class set2type >
setunion< set1type, set2type > makesetunion (const set1type &set1, const set2type &set2)
 Creates an object which represents the union of two sets.
int_t hashkey1 (const word &w)
int_t hashkey2 (const word &w)
int operator== (const word &w1, const word &w2)
 Compares two words. Returns 1 if they are the same, 0 otherwise.
int operator!= (const word &w1, const word &w2)
 Compares two words. Returns 0 if they are the same, 1 otherwise.
int operator== (const word &w, const char *c)
 Compares a word with a C-style string.
int operator!= (const word &w, const char *c)
 Compares a word with a C-style string.
int operator== (const char *c, const word &w)
 Compares a C-style string with a word.
int operator!= (const char *c, const word &w)
 Compares a C-style string with a word.
int operator< (const word &w1, const word &w2)
 Compares two words in an alphabetical way (by ASCII codes).
int operator> (const word &w1, const word &w2)
 Compares two words in an alphabetical way (by ASCII codes).
int operator<= (const word &w1, const word &w2)
 Compares two words in an alphabetical way (by ASCII codes).
int operator>= (const word &w1, const word &w2)
 Compares two words in an alphabetical way (by ASCII codes).
template<class type >
wordoperator<< (word &w, const type &elem)
 Appends the string value of a given element to a word.
std::ostream & operator<< (std::ostream &out, const word &w)
 Writes the given word to an output stream.
std::istream & operator>> (std::istream &in, word &w)
 Reads a word from an input stream.
std::ostream & operator<< (std::ostream &out, const argelement &p)
template<class type >
int readfromstring (char *str, type &t)
 A template for reading a variable from a string.
int readfromstring (char *str, char *&t)
 A specialization of the above template for interpreting a string as a string (no processing is necessary).
int readfromstring (char *str, const char *&t)
 A specialization of the above template for interpreting a string as a const string (no processing is necessary).
int readfromstring (char *str, bool &t)
 A specialization of the above template for reading a bool type.
template<class type >
void arg (arguments &a, const char *name, type &value)
 Adds a command line argument.
template<class type >
void arg (arguments &a, const char *name, type &value, type defaultvalue)
 Adds a command line argument with a default value.
void arg (arguments &a, const char *name, char *&value, const char *defaultvalue)
 A specialization of the above for C-style strings.
template<class type >
void arg (arguments &a, const char *name, type *value, int &count, int size)
 Adds a command line argument whose repeated occurrences fill in consecutive elements of the given array.
template<class type >
void arg (arguments &a, const char *name, type *value, int &count, int size, type defaultvalue)
 A version of the above with a default value of the arguments.
template<class type >
void argoblig (arguments &arg, const char *name, type &value)
 Defines an obligatory command line argument.
template<class type >
void argoblig (arguments &arg, const char *name, type &value, type defaultvalue)
 A version of the above with the default value provided.
void argoblig (arguments &arg, const char *name, char *&value, const char *defaultvalue)
 A version of the above for reading an array of argument values.
template<class type >
void argbreak (arguments &arg, const char *name, type &value)
 Adds an argument whose appearence interrupts the analysis of the command line and makes the analyzing function return the value of 1.
template<class type >
void argbreak (arguments &arg, const char *name, type &value, type defaultvalue)
 A version of the above with the default value provided.
void argbreak (arguments &arg, const char *name, char *&value, const char *defaultvalue)
 A version of the above for the C-style string.
void argbreak (arguments &arg, const char *name)
 A version of the above which ignores the value of the argument.
template<class type >
void argswitch (arguments &arg, const char *name, type &value, const type &defaultvalue)
 Defines a command line argument which is a switch, that is, there is no value given for it in the command line.
void argswitch (arguments &arg, const char *name, char *&value, const char *defaultvalue)
 A version of the above for the C-style string.
void argswitch (arguments &arg, const char *name)
 Defines an ignored switch (no value is set when this argument appears).
void arghelp (arguments &a)
 Adds the typical arguments which should make the program display help information.
void argstreams (arguments &a, char *&logfilename, char *&seqfilename, bool &quiet, bool &debug)
 Adds typical command line arguments for manipulating output streams.
void setstreams (const char *logfilename, char *seqfilename, bool quiet, bool debug)
 Sets the parameters of the output streams depending on the file names acquired from the command line.
template<typename type >
outputstreamoperator<< (outputstream &out, const type &object)
 The operator << for writing any kind of object to the output stream.
outputstreamoperator<< (outputstream &out, const char *object)
 A specialization of the operator << for writing a C-style string to the output stream.
outputstreamoperator<< (outputstream &out, std::ostream &(*object)(std::ostream &))
 A specialization of the operator << for putting manipulators (like std::endl, std::flush) to the output stream.
template<class type >
void swapelements (type &x, type &y)
 A simple template for swapping two elements with the use of a temporary variable of the same type and the assignment operator.
template<class type >
int sortelements (type *tab, int n)
 A simple template that sorts an array using the bubble sort method, removes repeated elements and returns the new number of the elements.
void ignoreline (std::istream &in)
 Ignores the input characters until the end of a line, including this end of the line.
void ignorecomments (std::istream &in)
 Ignores white characters (spaces, tabulators, CRs and LFs), as well as comments from the input text file.
int closingparenthesis (int ch)
 Returns the matching closing parenthesis for the given opening one or EOF if none.
int readparenthesis (std::istream &in)
 Reads an opening parenthesis from the input file.
std::string commandline (int argc, char *argv[])
 Returns the entire command line as a single string.
const char * currenttime (void)
 Retrieves the current time as a pointer to a C-style string.
template<class settype >
static void savetheset (const settype &c, const char *prefix, const char *filename, const char *name)
 Writes the given object to a file whose name is a concatenation of the prefix and the given file name.
void fileerror (const char *filename, const char *what="open")
 Throws a message about the inability to do something with a file.

Variables

const int DimBits = (sizeof (int_t) > 4) ? 7 : 6
 The number of signed bits to store the dimension (i.e., 6: max 31).
const int NumBits = (sizeof (int_t) << 3) - DimBits
 The number of bits in an integer number that remain to be used for other purposes, because the high 'DimBits' bits are used for the dimension.
const int_t SignBit = static_cast<int_t> (1) << ((sizeof (int_t) << 3) - 1)
 The sign bit of the int_t number.
const int_t NumMask = (~(static_cast<int_t> (0) ^ SignBit)) >> (DimBits - 1)
 The mask of the bits remaining after the dimension bits are excluded.
const int MaxBasDim1 = static_cast<int> (1u << (DimBits - 1))
 The maximal dimension that can be represented using 'DimBits' bits.
const int MaxBasDim2 = static_cast<int> ((sizeof (int_t) << 3) - DimBits)
 The maximal dimension which still leaves enough bits in the integer to have one bit for each direction.
const int MaxBasDim = (MaxBasDim1 < MaxBasDim2) ? MaxBasDim1 : MaxBasDim2
 The maximal dimension that can be used if the high bits of an integer store the value of the dimension, and the number of remaining bits is at least as large as the dimension.
const int MaxBddDimPossible = 3
 The maximal dimension for which binary decision diagrams are programmed.
int MaxBddDim
 The maximal dimension for which binary decision diagrams are used.
bool UseMalandainCode
 The variable which controls which binary decision diagrams should be used in dimension 3, either programmed by P.
BitFields knownbits
 The global table of BitFields which store the acyclicity information for reducing full cubical sets.
Tabulated tabulated
 The global instance of this class which stores tabulated configurations to use in the full cube reduction procedures.
unsigned char bitcounttable []
outputstream sout
 A replacement for standard output stream, with optional logging and other features provided by the class 'outputstream'.
outputstream scon
 The console output stream to which one should put all the junk that spoils the log file, like progress indicators.
outputstream serr
 A wrapper for the standard error stream.
outputstream slog
 The output stream to which one can send messages for logging only.
outputstream sbug
 An output stream for writing additional debug messages.
outputstream sseq
 An auxiliary stream which captures sequences of processed data.
timeused program_time
 The external variable which measures the time used by the program from its start.

Detailed Description

This namespace contains the core of the homology computation procedures and related classes and templates contained in the CHomP C++ library.


Typedef Documentation

A lower-case version of the name of a bit field [deprecated].

Definition at line 56 of file bitfield.h.

A lower-case version of the name of a bit field set [deprecated].

Definition at line 62 of file bitfield.h.

A class for representing a chain with integral coefficients.

Definition at line 87 of file homology.h.

A class for representing a chain complex with integral coefficients.

Definition at line 81 of file homology.h.

A class for representing a chain map with integral coefficients.

Definition at line 84 of file homology.h.

The default type of a combinatorial cubical multivalued map.

This is a map which assigns a set of cubes to each cube in its domain.

Definition at line 75 of file cube.h.

A typical multivalued map on full cubes in the two-layer setting.

Definition at line 1231 of file twolayer.h.

typedef short int chomp::homology::coordinate

The default type of coordinates.

Definition at line 63 of file pointset.h.

The default cube type.

Definition at line 62 of file cube.h.

A lower-case name of a cube [deprecated].

Definition at line 78 of file cube.h.

A typical full cube in the two-layer setting.

Definition at line 1225 of file twolayer.h.

An abbreviation for a set of cubes [deprecated].

Definition at line 81 of file cube.h.

The default type of a cubical cell.

Definition at line 62 of file cell.h.

A typical cubical cell in the two-layer setting.

Definition at line 1228 of file twolayer.h.

An abbreviation for a cubical complex [deprecated].

Definition at line 85 of file cell.h.

The default type of a cubical complex.

Definition at line 71 of file cell.h.

A typical cubical complex in the two-layer setting.

Definition at line 1240 of file twolayer.h.

An abbreviation for a combinatorial cubical multivalued map.

Definition at line 84 of file cube.h.

A lower-case version of the name of a combinatorial cubical multivalued map [deprecated].

Definition at line 88 of file cube.h.

The default type of a cubical multivalued map.

The image of each cubical cell is a set of cubical cells.

Definition at line 75 of file cell.h.

A typical multivalued cubical-cellular map in the two-layer setting.

Definition at line 1244 of file twolayer.h.

An alternative name for a cubical cell.

Definition at line 65 of file cell.h.

An alternative name for a cube.

Definition at line 65 of file cube.h.

Definition at line 1033 of file bincube.h.

An alternative name for a cube.

Definition at line 68 of file cube.h.

The neighbors class with the default type of coordinates.

Definition at line 84 of file pointset.h.

typedef signed short chomp::homology::numbertype

The type of number used to store the value of an object of type "integer".

Note that "signed short" (or even "signed char") uses less memory but limits the range of correctly stored numbers which may cause to interrupt the computations in the numbers become too large. Use "signed long" for large prime numbers.

Definition at line 127 of file integer.h.

The default type of the point base class.

Definition at line 60 of file pointbas.h.

The pointset class with the default type of coordinates.

Definition at line 78 of file pointset.h.

An abbreviation for a cubical cell [deprecated].

Definition at line 79 of file cell.h.

An abbreviation for a set of cubical cell [deprecated].

Definition at line 82 of file cell.h.

The rectangle class with the default type of coordinates.

Definition at line 87 of file pointset.h.

The default type of a set of cubes.

Definition at line 71 of file cube.h.

A typical set of full cubes in the two-layer setting.

Definition at line 1234 of file twolayer.h.

The default type of a set of cubical cells.

Definition at line 68 of file cell.h.

A typical set of cubical cells in the two-layer setting.

Definition at line 1237 of file twolayer.h.

A class for representing a set of simplices.

The type of a set of simplices.

Definition at line 90 of file homology.h.

A lower-case name for a simplex [deprecated].

Definition at line 63 of file simplex.h.

An alternative name for a set of simplices [deprecated].

Definition at line 69 of file simplex.h.

A lower-case name for a simplicial complex [deprecated].

Definition at line 66 of file simplex.h.

A class for representing a simplicial complex.

The type of a simplicial complex.

Definition at line 93 of file homology.h.

typedef short int chomp::homology::theLayerType

The type of the layer variable.

It holds the values for the layer numbers (0 and 1), as well as the layer numbers of the Cartesian product of cubes obtained from the layers by bitwise OR on the layer of the first cube shifted by 2 bits to the left and the layer of the other cube.

Definition at line 67 of file twolayer.h.

The default type of a set of words.

Definition at line 54 of file words.h.


Function Documentation

int chomp::homology::acyclic ( int  dim,
BitField &  b 
) [inline]

Checks whether this cube's nieghbors form an acyclic set.

Returns: 1 = yes for sure, 0 = probably no, but it is not sure.

Definition at line 69 of file cubisets.h.

References addneighbors(), bits2int(), chomp::homology::Tabulated::get(), getmaxneighbors(), knownbits, chomp::homology::tCubeBase< coordtype >::MaxDim, and tabulated.

Referenced by acyclic(), acyclic_rel(), checkacyclicmap(), createcellmap(), cubexpand(), cubreducequiet(), Homology(), and Homology2l().

{
        // look for the answer in the tabulated data
        const char *table = tabulated [dim];
        if (table)
        {
                return Tabulated::get (table,
                        bits2int (b, getmaxneighbors (dim)));
        }

        // look for the answer among the known combinations
        SetOfBitFields *known = knownbits [dim];
        int answer = known ? known -> check (b) : -1;

        // if the answer is known then return it
        if (answer >= 0)
                return answer;

        // create a model cube for building the neighborhood
        coordinate c [Cube::MaxDim];
        for (int i = 0; i < dim; ++ i)
                c [i] = 0;
        Cube qzero (c, dim);

        // find out whether the set of neighbors is acyclic or not
/*      SetOfCubes neighbors;
        addneighbors (qzero, b, neighbors, true);
        SetOfCubes empty;
        cubreducequiet (empty, neighbors, empty, known); // nie ma takiego
        answer = (neighbors. size () == 1);
*/
// /*
        gcomplex<CubicalCell,integer> neighbors;
        addneighbors (qzero, b, neighbors, true);
        answer = static_cast<int> (acyclic (neighbors));
//*/
        // add the answer to the list of known ones
        if (known)
                known -> add (b, answer);

        return answer;
} /* acyclic */

template<class tCube >
bool chomp::homology::acyclic ( const hashedset< tCube > &  cset  )  [inline]

Checks thoroughly whether the given set of cubes is acyclic.

Returns true if yes, false if not.

Definition at line 115 of file cubisets.h.

References acyclic(), and cubreducequiet().

{
        // the empty set is not acyclic
        if (cset. empty ())
                return false;

        // a singleton is acyclic
        if (cset. size () == 1)
                return true;

        // reduce the set and see if there is only one cube remaining
        hashedset<tCube> emptycubes;
        hashedset<tCube> theset = cset;
        cubreducequiet (emptycubes, theset, emptycubes); // !!!
        if (theset. size () == 1)
                return true;

        // create a cubical complex from this set of cubes
        gcomplex<typename tCube::CellType,integer> ccompl;
        int_t size = cset. size ();
        for (int_t i = 0; i < size; ++ i)
                ccompl. add (typename tCube::CellType (cset [i]));

        // check whether this geometric complex is acyclic or not
        return acyclic (ccompl);
} /* acyclic */

template<class tCube , class tCubeSet1 , class tCubeSet2 >
bool chomp::homology::acyclic ( const tCube &  q,
int  dim,
const tCubeSet1 &  cset,
BitField *  b,
int_t  maxneighbors,
tCubeSet2 *  neighbors 
) [inline]

Verifies the acyclicity of a neighborhood of the given cube.

Parameters:
q - the cube whose neighborhood is verified
dim - the dimension of the cube
cset - the set to search for the cubes adjacent to q
b - a pointer to a bitfield in which neighbors are marked
neighbors - a pointer to a set of cubes to which the neighbors are added (unless BDDs are used) if the pointer is not null
maxneighbors - the maximal possible number of neighbors: should be equal to 3^dim - 1 Uses BDDs if available. Marks verified neighbors in b.

Definition at line 153 of file cubisets.h.

References acyclic(), bddacyclic(), getneighbors(), and MaxBddDim.

{
        // use a binary decision diagram code if possible
        if (dim <= MaxBddDim)
                return bddacyclic (q, dim, cset, *b);

        // get the neighbors of the cube
        int_t n = getneighbors (q, b, cset, neighbors, 0);

        // if the answer is obvious from the number of neighbors, return it
        if ((n == 0) || (n == maxneighbors))
                return false;
        if (n == 1)
                return true;

        // return the information on whether this set of neighbors is acyclic
        return acyclic (dim, *b);
} /* acyclic */

template<class tCube , class tCubeSet >
bool chomp::homology::acyclic ( const tCube &  q,
int  dim,
const tCubeSet &  cset,
BitField *  b,
int_t  maxneighbors 
) [inline]

Verifies the acyclicity of a neighborhood of the given cube.

Calls the above procedure with a null pointer to the set of neighbors.

Definition at line 176 of file cubisets.h.

References acyclic().

{
        hashedset<tCube> *neighbors = 0;
        return acyclic (q, dim, cset, b, maxneighbors, neighbors);
} /* acyclic */

template<class cell , class euclidom >
bool chomp::homology::acyclic ( gcomplex< cell, euclidom > &  c  ) 

Checks whether this chain complex is acyclic.

This verification destroys the chain complex. Acknowledgement: There was a memory leak here - "hom" was not deleted. Thanks to Marc Niethammer for pointing this out. [July 29, 2004]

Definition at line 1448 of file gcomplex.h.

References collapse(), and createchaincomplex().

{
        // collapse the geometric complex and check if you can get one elem.
        gcomplex<cell,euclidom> empty;
        c. collapse (empty, empty, true, false, false, NULL, true);
        if (c. size () == 1)
                return true;

        // create the corresponding chain complex and compute its homology
        chaincomplex<euclidom> cx (c. dim ());
        createchaincomplex (cx, c, true);
        chain<euclidom> *hom;
        cx. simple_form (static_cast<int *> (0), true);
        cx. simple_homology (hom, 0);

        // if there is anything above the zero level, the set is not acyclic
        for (int i = 1; i <= cx. dim (); ++ i)
        {
                if (!hom [i]. empty ())
                {
                        delete [] hom;
                        return false;
                }
        }

        // if there is more than one connected component, it is not acyclic
        if (hom [0]. size () != 1)
        {
                delete [] hom;
                return false;
        }

        // if the coefficient is not 1, the set is not acyclic
        if (hom [0]. getcoefficient (0) == 1)
        {
                delete [] hom;
                return true;
        }
        else
        {
                delete [] hom;
                return false;
        }
} /* acyclic */

bool chomp::homology::acyclic ( const cube &  q,
const cubes &  X 
) [inline]

Verifies whether the neighborhood of q in X is acyclic.

Uses BDDs for dimensions 2 and 3, and computes homology otherwise.

Definition at line 2000 of file homology.h.

References acyclic(), and getmaxneighbors().

{
        int dim = q. dim ();
        BitField b;
        int_t maxneighbors = getmaxneighbors (dim);
        b. allocate (maxneighbors);
        bool result = acyclic (q, dim, X, &b, maxneighbors);
        b. free ();
        return result;
} /* acyclic */

template<class NeighborCheck >
bool chomp::homology::acyclic1d ( NeighborCheck &  n  ) 

Verifies whether the neighborhood of a 1-dimensional "cube" is acyclic.

Definition at line 50 of file cubacycl.h.

Referenced by bddacyclic(), and chomp::homology::Acyclic1d< SetT >::check().

{
        if (n. check (0)) goto K4; else goto K5;
K4:     if (n. check (1)) return false; else return true;
K5:     if (n. check (1)) return true; else return false;
} /* acyclic1d */

template<class NeighborCheck >
bool chomp::homology::acyclic2d ( NeighborCheck &  n  ) 

Verifies whether the neighborhood of a 2-dimensional "cube" is acyclic.

Definition at line 64 of file cubacycl.h.

Referenced by bddacyclic(), and chomp::homology::Acyclic2d< SetT >::check().

{
        if (n. check (0)) goto L659; else goto L20;
L12:    return !n. check (5);
L13:    return n. check (5);
L14:    return !n. check (6);
L16:    return !n. check (7);
L17:    return n. check (7);
L18:    if (n. check (2)) goto L514; else goto L523;
L20:    if (n. check (1)) goto L40; else goto L18;
L21:    if (n. check (5)) return true; else goto L651;
L23:    if (n. check (4)) goto L514; else goto L21;
L24:    if (n. check (4)) return false; else goto L514;
L40:    if (n. check (2)) goto L513; else goto L637;
L505:   if (n. check (6)) return false; else goto L16;
L507:   if (n. check (5)) return true; else goto L16;
L508:   if (n. check (2)) goto L507; else goto L646;
L513:   if (n. check (5)) return true; else goto L14;
L514:   if (n. check (5)) return false; else goto L505;
L523:   if (n. check (3)) goto L24; else goto L23;
L637:   if (n. check (3)) return false; else goto L513;
L646:   if (n. check (4)) return false; else goto L507;
L651:   if (n. check (6)) goto L16; else goto L17;
L658:   if (n. check (2)) goto L12; else goto L13;
L659:   if (n. check (1)) goto L658; else goto L508;
} /* acyclic2d */

template<class NeighborCheck >
bool chomp::homology::acyclic3d ( NeighborCheck &  n  ) 

Verifies whether the neighborhood of a 3-dimensional cube is acyclic.

Definition at line 614 of file cubacycl.h.

Referenced by bddacyclic(), and chomp::homology::Acyclic3d< SetT >::check().

{
        if (n. check (0)) goto K1043; else goto K978;
K14:    return !n. check (6);
K15:    return n. check (6);
K36:    return !n. check (17);
K37:    return n. check (17);
K38:    return !n. check (18);
K39:    return n. check (18);
K48:    return !n. check (23);
K49:    return n. check (23);
K50:    return !n. check (24);
K52:    return !n. check (25);
K53:    return n. check (25);
K54:    if (n. check (17)) goto K2585; else goto K154;
K56:    if (n. check (20)) return false; else goto K2302;
K57:    if (n. check (7)) goto K1863; else goto K939;
K59:    if (n. check (20)) goto K2302; else goto K2088;
K63:    if (n. check (17)) goto K15; else goto K2377;
K64:    if (n. check (4)) goto K1575; else goto K1541;
K65:    if (n. check (1)) goto K504; else goto K1046;
K67:    if (n. check (4)) goto K1402; else goto K793;
K68:    if (n. check (16)) return false; else goto K174;
K69:    if (n. check (18)) goto K49; else goto K1636;
K76:    if (n. check (19)) return false; else goto K1900;
K78:    if (n. check (19)) goto K690; else goto K1873;
K79:    if (n. check (20)) goto K57; else goto K1797;
K80:    if (n. check (20)) goto K2317; else goto K237;
K82:    if (n. check (19)) goto K1559; else goto K1414;
K85:    if (n. check (20)) goto K2317; else goto K464;
K90:    if (n. check (4)) goto K862; else goto K1928;
K92:    if (n. check (4)) goto K59; else goto K2119;
K93:    if (n. check (7)) goto K1863; else return false;
K97:    if (n. check (5)) goto K361; else goto K244;
K98:    if (n. check (1)) return false; else goto K1299;
K101:   if (n. check (13)) return false; else goto K184;
K102:   if (n. check (1)) goto K2536; else goto K2453;
K105:   if (n. check (20)) goto K248; else goto K712;
K106:   if (n. check (1)) goto K1410; else goto K139;
K112:   if (n. check (5)) goto K359; else goto K121;
K115:   if (n. check (4)) goto K307; else goto K101;
K117:   if (n. check (14)) goto K2247; else goto K580;
K118:   if (n. check (4)) goto K826; else goto K2473;
K119:   if (n. check (13)) return false; else goto K2174;
K121:   if (n. check (8)) goto K106; else goto K226;
K123:   if (n. check (4)) goto K1814; else goto K1442;
K124:   if (n. check (10)) goto K1086; else goto K1683;
K125:   if (n. check (14)) goto K355; else goto K1816;
K127:   if (n. check (1)) return false; else goto K1000;
K131:   if (n. check (17)) return false; else goto K200;
K134:   if (n. check (19)) return false; else goto K1862;
K137:   if (n. check (11)) goto K177; else goto K167;
K139:   if (n. check (4)) goto K891; else goto K1234;
K143:   if (n. check (13)) return false; else goto K2460;
K154:   if (n. check (15)) return false; else goto K342;
K155:   if (n. check (14)) goto K1410; else goto K1549;
K156:   if (n. check (1)) return false; else goto K2181;
K158:   if (n. check (4)) goto K1610; else goto K1250;
K163:   if (n. check (16)) return false; else goto K2112;
K164:   if (n. check (17)) goto K2585; else return false;
K165:   if (n. check (10)) return false; else goto K1607;
K166:   if (n. check (20)) goto K2422; else goto K2417;
K167:   if (n. check (1)) goto K504; else goto K977;
K172:   if (n. check (7)) goto K988; else goto K559;
K174:   if (n. check (19)) goto K1950; else goto K465;
K175:   if (n. check (19)) goto K1948; else goto K164;
K177:   if (n. check (1)) return false; else goto K2279;
K181:   if (n. check (14)) goto K533; else goto K118;
K182:   if (n. check (19)) return false; else goto K2368;
K184:   if (n. check (20)) goto K1607; else goto K2423;
K185:   if (n. check (20)) return false; else goto K1614;
K192:   if (n. check (20)) goto K2410; else goto K2063;
K195:   if (n. check (7)) goto K1153; else goto K268;
K198:   if (n. check (23)) return true; else goto K52;
K199:   if (n. check (1)) goto K117; else goto K1399;
K200:   if (n. check (15)) goto K2377; else goto K1992;
K202:   if (n. check (7)) goto K273; else goto K1332;
K203:   if (n. check (19)) return true; else goto K37;
K204:   if (n. check (16)) return false; else goto K1794;
K205:   if (n. check (13)) return false; else goto K1442;
K215:   if (n. check (19)) goto K545; else goto K37;
K219:   if (n. check (7)) goto K182; else goto K2264;
K222:   if (n. check (1)) goto K728; else goto K1954;
K224:   if (n. check (7)) goto K1226; else goto K261;
K225:   if (n. check (7)) goto K1922; else goto K2403;
K226:   if (n. check (9)) goto K452; else goto K1825;
K229:   if (n. check (15)) goto K1571; else goto K453;
K230:   if (n. check (19)) goto K1949; else goto K1263;
K232:   if (n. check (7)) goto K1153; else return false;
K235:   if (n. check (19)) goto K2063; else goto K1760;
K236:   if (n. check (6)) goto K1940; else goto K1506;
K237:   if (n. check (7)) goto K2112; else goto K163;
K238:   if (n. check (20)) return false; else goto K2058;
K241:   if (n. check (1)) goto K624; else goto K2371;
K242:   if (n. check (1)) goto K1832; else goto K687;
K244:   if (n. check (8)) goto K258; else goto K2277;
K246:   if (n. check (23)) return true; else goto K803;
K248:   if (n. check (7)) goto K987; else goto K1804;
K249:   if (n. check (14)) return false; else goto K1135;
K251:   if (n. check (4)) goto K872; else goto K2576;
K254:   if (n. check (7)) goto K1924; else return false;
K255:   if (n. check (17)) goto K14; else goto K2377;
K257:   if (n. check (14)) return false; else goto K832;
K258:   if (n. check (1)) goto K832; else goto K863;
K260:   if (n. check (19)) goto K839; else goto K722;
K261:   if (n. check (19)) goto K2058; else goto K873;
K267:   if (n. check (16)) return false; else goto K2313;
K268:   if (n. check (16)) return false; else goto K1253;
K273:   if (n. check (19)) return false; else goto K1769;
K278:   if (n. check (19)) goto K686; else goto K37;
K281:   if (n. check (22)) goto K2381; else goto K1559;
K285:   if (n. check (11)) goto K1257; else goto K199;
K293:   if (n. check (7)) goto K1565; else goto K2296;
K307:   if (n. check (20)) goto K1607; else goto K203;
K342:   if (n. check (6)) return false; else goto K2000;
K350:   if (n. check (6)) goto K1805; else goto K2602;
K354:   if (n. check (6)) goto K867; else goto K2002;
K355:   if (n. check (4)) goto K1762; else goto K1519;
K356:   if (n. check (7)) goto K1297; else goto K1794;
K359:   if (n. check (8)) goto K1256; else goto K2365;
K360:   if (n. check (19)) return false; else goto K1761;
K361:   if (n. check (8)) goto K1773; else goto K2344;
K368:   if (n. check (19)) return false; else goto K36;
K399:   if (n. check (17)) goto K15; else goto K1571;
K401:   if (n. check (14)) goto K427; else goto K875;
K411:   if (n. check (13)) return false; else goto K762;
K427:   if (n. check (4)) goto K928; else goto K2134;
K428:   if (n. check (1)) goto K2247; else goto K1135;
K433:   if (n. check (17)) return false; else goto K1571;
K448:   if (n. check (1)) goto K921; else goto K856;
K451:   if (n. check (7)) goto K578; else goto K1939;
K452:   if (n. check (11)) goto K222; else goto K2113;
K453:   if (n. check (6)) goto K2544; else goto K2002;
K454:   if (n. check (14)) goto K1135; else goto K67;
K464:   if (n. check (7)) goto K1799; else goto K2349;
K465:   if (n. check (17)) goto K14; else return false;
K486:   if (n. check (21)) goto K1242; else goto K198;
K492:   if (n. check (17)) goto K15; else goto K2421;
K494:   if (n. check (8)) goto K428; else goto K1147;
K497:   if (n. check (7)) goto K1924; else goto K2306;
K504:   if (n. check (20)) return false; else goto K1559;
K507:   if (n. check (7)) goto K1470; else goto K2487;
K521:   if (n. check (14)) goto K1648; else goto K1171;
K522:   if (n. check (14)) return false; else goto K1608;
K523:   if (n. check (14)) goto K248; else goto K2317;
K524:   if (n. check (12)) goto K98; else goto K2215;
K533:   if (n. check (4)) goto K1542; else return false;
K543:   if (n. check (14)) goto K2044; else goto K1405;
K545:   if (n. check (17)) return true; else goto K39;
K559:   if (n. check (22)) goto K174; else goto K1864;
K578:   if (n. check (19)) goto K2410; else goto K2063;
K580:   if (n. check (20)) goto K832; else goto K1950;
K590:   if (n. check (6)) goto K2497; else goto K2602;
K591:   if (n. check (14)) goto K863; else goto K225;
K592:   if (n. check (15)) goto K2467; else goto K2602;
K624:   if (n. check (20)) goto K37; else return true;
K649:   if (n. check (5)) goto K1520; else goto K2586;
K685:   if (n. check (10)) goto K454; else goto K2267;
K686:   if (n. check (17)) return true; else goto K2363;
K687:   if (n. check (10)) goto K2028; else goto K181;
K690:   if (n. check (17)) return false; else goto K229;
K691:   if (n. check (6)) goto K1242; else return false;
K698:   if (n. check (1)) goto K1457; else goto K685;
K703:   if (n. check (20)) goto K2302; else goto K281;
K712:   if (n. check (7)) goto K1110; else goto K2199;
K718:   if (n. check (19)) goto K2058; else return false;
K722:   if (n. check (17)) goto K2585; else goto K1593;
K724:   if (n. check (17)) goto K14; else goto K236;
K725:   if (n. check (18)) return false; else goto K1233;
K728:   if (n. check (14)) return false; else goto K1410;
K731:   if (n. check (13)) return false; else goto K2119;
K741:   if (n. check (14)) goto K1608; else goto K451;
K751:   if (n. check (7)) goto K1264; else goto K1179;
K752:   if (n. check (20)) goto K921; else goto K686;
K761:   if (n. check (7)) goto K1813; else goto K1253;
K762:   if (n. check (20)) goto K2120; else goto K2350;
K773:   if (n. check (19)) return false; else goto K433;
K785:   if (n. check (22)) goto K2533; else goto K690;
K792:   if (n. check (8)) goto K1534; else goto K2314;
K793:   if (n. check (20)) goto K225; else goto K942;
K803:   if (n. check (24)) goto K52; else goto K53;
K826:   if (n. check (20)) goto K2317; else goto K908;
K831:   if (n. check (16)) goto K2092; else goto K1623;
K832:   if (n. check (17)) goto K14; else goto K354;
K839:   if (n. check (17)) goto K2585; else goto K592;
K843:   if (n. check (22)) goto K2112; else goto K260;
K856:   if (n. check (10)) goto K2302; else goto K2120;
K862:   if (n. check (20)) goto K225; else goto K2386;
K863:   if (n. check (7)) goto K134; else goto K1527;
K867:   if (n. check (18)) return false; else goto K48;
K871:   if (n. check (10)) goto K2028; else goto K2310;
K872:   if (n. check (20)) goto K2302; else goto K2381;
K873:   if (n. check (17)) return false; else goto K198;
K875:   if (n. check (4)) goto K1957; else goto K119;
K891:   if (n. check (20)) goto K863; else goto K2367;
K894:   if (n. check (17)) goto K15; else goto K691;
K907:   if (n. check (14)) return false; else goto K2247;
K908:   if (n. check (7)) goto K175; else goto K1048;
K909:   if (n. check (16)) return false; else goto K920;
K920:   if (n. check (19)) goto K690; else goto K2175;
K921:   if (n. check (17)) return true; else goto K38;
K924:   if (n. check (10)) goto K1245; else goto K1441;
K928:   if (n. check (20)) goto K863; else goto K1972;
K937:   if (n. check (4)) goto K1204; else goto K2119;
K939:   if (n. check (16)) return false; else goto K1804;
K942:   if (n. check (7)) goto K785; else goto K843;
K966:   if (n. check (20)) goto K921; else goto K545;
K977:   if (n. check (10)) goto K2001; else goto K251;
K978:   if (n. check (2)) goto K97; else goto K1563;
K983:   if (n. check (4)) goto K1903; else goto K184;
K987:   if (n. check (19)) goto K832; else goto K1042;
K988:   if (n. check (22)) goto K2416; else goto K1862;
K1000:  if (n. check (10)) return false; else goto K983;
K1001:  if (n. check (6)) goto K1735; else goto K1090;
K1002:  if (n. check (14)) goto K1846; else goto K123;
K1042:  if (n. check (17)) goto K14; else goto K350;
K1043:  if (n. check (2)) goto K649; else goto K1904;
K1044:  if (n. check (20)) goto K2317; else goto K2057;
K1046:  if (n. check (10)) goto K2001; else goto K937;
K1048:  if (n. check (16)) return false; else goto K1179;
K1067:  if (n. check (17)) return false; else goto K1001;
K1075:  if (n. check (1)) goto K2437; else goto K2123;
K1086:  if (n. check (14)) goto K1923; else goto K90;
K1087:  if (n. check (20)) goto K1608; else goto K202;
K1090:  if (n. check (21)) goto K2602; else goto K69;
K1095:  if (n. check (19)) goto K2058; else goto K1769;
K1108:  if (n. check (1)) goto K2198; else goto K2570;
K1110:  if (n. check (19)) goto K1042; else goto K465;
K1112:  if (n. check (20)) goto K1608; else goto K761;
K1134:  if (n. check (22)) goto K175; else goto K1948;
K1135:  if (n. check (4)) goto K185; else goto K1977;
K1136:  if (n. check (22)) goto K215; else goto K545;
K1147:  if (n. check (9)) goto K285; else goto K2256;
K1149:  if (n. check (19)) goto K2144; else goto K839;
K1153:  if (n. check (22)) goto K1332; else goto K2063;
K1171:  if (n. check (4)) goto K79; else goto K1289;
K1179:  if (n. check (19)) goto K1948; else goto K54;
K1180:  if (n. check (20)) goto K2144; else goto K1948;
K1181:  if (n. check (6)) goto K1242; else goto K1506;
K1196:  if (n. check (7)) return false; else goto K2495;
K1200:  if (n. check (7)) goto K1149; else return false;
K1204:  if (n. check (20)) return false; else goto K82;
K1210:  if (n. check (19)) goto K1862; else goto K2368;
K1211:  if (n. check (7)) goto K78; else goto K909;
K1217:  if (n. check (14)) goto K1135; else goto K1633;
K1221:  if (n. check (10)) goto K591; else goto K523;
K1226:  if (n. check (19)) return false; else goto K2058;
K1233:  if (n. check (23)) return false; else goto K2352;
K1234:  if (n. check (20)) goto K248; else goto K507;
K1238:  if (n. check (7)) goto K360; else goto K1794;
K1242:  if (n. check (18)) goto K198; else return false;
K1245:  if (n. check (4)) goto K1460; else goto K762;
K1250:  if (n. check (20)) goto K1200; else goto K1300;
K1253:  if (n. check (22)) goto K1332; else goto K235;
K1256:  if (n. check (1)) goto K752; else goto K1245;
K1257:  if (n. check (1)) goto K907; else goto K1471;
K1263:  if (n. check (17)) goto K14; else goto K2421;
K1264:  if (n. check (19)) return false; else goto K131;
K1270:  if (n. check (14)) return false; else goto K863;
K1285:  if (n. check (20)) return false; else goto K690;
K1288:  if (n. check (7)) goto K2250; else goto K174;
K1289:  if (n. check (13)) return false; else goto K2490;
K1297:  if (n. check (19)) goto K1949; else goto K465;
K1299:  if (n. check (10)) return false; else goto K1302;
K1300:  if (n. check (7)) goto K1134; else goto K2092;
K1302:  if (n. check (14)) return false; else goto K2341;
K1307:  if (n. check (4)) goto K105; else goto K143;
K1327:  if (n. check (11)) goto K1910; else goto K1915;
K1328:  if (n. check (20)) goto K2120; else goto K215;
K1332:  if (n. check (19)) goto K2063; else goto K37;
K1393:  if (n. check (1)) goto K543; else goto K124;
K1395:  if (n. check (1)) goto K752; else goto K2486;
K1399:  if (n. check (10)) goto K1867; else goto K401;
K1402:  if (n. check (20)) return false; else goto K1598;
K1405:  if (n. check (20)) goto K2144; else goto K839;
K1409:  if (n. check (17)) return false; else goto K590;
K1410:  if (n. check (20)) goto K832; else goto K1949;
K1413:  if (n. check (1)) goto K966; else goto K1763;
K1414:  if (n. check (17)) return false; else goto K39;
K1423:  if (n. check (14)) goto K139; else goto K2429;
K1438:  if (n. check (17)) goto K15; else return false;
K1441:  if (n. check (4)) goto K1498; else return false;
K1442:  if (n. check (20)) goto K451; else goto K195;
K1449:  if (n. check (20)) return false; else goto K1211;
K1457:  if (n. check (14)) goto K2247; else goto K1285;
K1460:  if (n. check (20)) goto K2302; else goto K76;
K1461:  if (n. check (17)) return false; else goto K236;
K1470:  if (n. check (22)) goto K1297; else goto K1949;
K1471:  if (n. check (10)) goto K249; else goto K1217;
K1475:  if (n. check (19)) goto K2410; else goto K1760;
K1498:  if (n. check (20)) goto K2120; else goto K278;
K1506:  if (n. check (18)) goto K198; else goto K1233;
K1507:  if (n. check (4)) goto K80; else goto K1947;
K1519:  if (n. check (13)) return false; else goto K1112;
K1520:  if (n. check (8)) goto K1803; else goto K1693;
K1521:  if (n. check (4)) goto K1449; else goto K85;
K1527:  if (n. check (19)) goto K832; else goto K724;
K1534:  if (n. check (1)) goto K504; else goto K2001;
K1538:  if (n. check (20)) goto K451; else goto K2062;
K1541:  if (n. check (20)) goto K1970; else goto K1801;
K1542:  if (n. check (20)) goto K248; else goto K356;
K1543:  if (n. check (21)) goto K1506; else goto K2581;
K1549:  if (n. check (20)) goto K399; else goto K63;
K1558:  if (n. check (1)) goto K257; else goto K2173;
K1559:  if (n. check (17)) return false; else goto K38;
K1562:  if (n. check (13)) return false; else goto K1234;
K1563:  if (n. check (3)) goto K2598; else goto K112;
K1565:  if (n. check (22)) goto K174; else goto K1950;
K1571:  if (n. check (6)) goto K2544; else return false;
K1575:  if (n. check (20)) goto K863; else goto K1288;
K1587:  if (n. check (4)) goto K1328; else goto K731;
K1593:  if (n. check (15)) goto K691; else goto K1181;
K1598:  if (n. check (7)) goto K1922; else goto K920;
K1599:  if (n. check (1)) goto K624; else goto K983;
K1607:  if (n. check (19)) goto K37; else return true;
K1608:  if (n. check (7)) goto K1226; else goto K1475;
K1610:  if (n. check (20)) goto K225; else goto K751;
K1611:  if (n. check (20)) return false; else goto K224;
K1614:  if (n. check (7)) goto K134; else goto K2313;
K1623:  if (n. check (22)) goto K1179; else goto K1700;
K1633:  if (n. check (4)) goto K2209; else goto K2174;
K1636:  if (n. check (23)) return true; else goto K50;
K1648:  if (n. check (4)) goto K1542; else goto K1562;
K1664:  if (n. check (20)) goto K93; else goto K254;
K1683:  if (n. check (14)) goto K1307; else goto K1507;
K1687:  if (n. check (17)) goto K15; else goto K2467;
K1692:  if (n. check (7)) goto K1860; else goto K2411;
K1693:  if (n. check (1)) goto K37; else goto K165;
K1700:  if (n. check (19)) goto K1948; else goto K2451;
K1705:  if (n. check (8)) goto K2045; else goto K1835;
K1728:  if (n. check (10)) return false; else goto K2302;
K1735:  if (n. check (21)) goto K1805; else goto K48;
K1760:  if (n. check (17)) return true; else goto K198;
K1761:  if (n. check (17)) return false; else goto K2377;
K1762:  if (n. check (20)) goto K1608; else goto K1925;
K1763:  if (n. check (10)) goto K92; else goto K1587;
K1764:  if (n. check (4)) goto K166; else goto K2490;
K1769:  if (n. check (17)) return false; else goto K49;
K1772:  if (n. check (7)) goto K578; else return false;
K1773:  if (n. check (1)) goto K921; else goto K2302;
K1789:  if (n. check (1)) goto K2410; else goto K1608;
K1794:  if (n. check (19)) goto K63; else goto K1438;
K1797:  if (n. check (7)) goto K1794; else goto K204;
K1798:  if (n. check (19)) goto K63; else goto K492;
K1799:  if (n. check (22)) goto K2112; else goto K839;
K1801:  if (n. check (7)) goto K1565; else return false;
K1803:  if (n. check (1)) goto K36; else goto K1607;
K1804:  if (n. check (19)) goto K399; else goto K894;
K1805:  if (n. check (18)) goto K48; else return false;
K1813:  if (n. check (22)) goto K718; else goto K2058;
K1814:  if (n. check (20)) return false; else goto K1843;
K1816:  if (n. check (4)) goto K1538; else goto K205;
K1822:  if (n. check (7)) goto K1799; else return false;
K1824:  if (n. check (19)) return false; else goto K1873;
K1825:  if (n. check (11)) goto K242; else goto K524;
K1828:  if (n. check (14)) goto K863; else goto K2422;
K1832:  if (n. check (14)) goto K1410; else goto K1180;
K1835:  if (n. check (11)) goto K1075; else goto K1108;
K1843:  if (n. check (7)) goto K1095; else goto K2091;
K1846:  if (n. check (4)) goto K1611; else goto K1112;
K1855:  if (n. check (14)) goto K139; else goto K1764;
K1859:  if (n. check (7)) goto K2190; else goto K267;
K1860:  if (n. check (22)) goto K1110; else goto K1042;
K1861:  if (n. check (20)) goto K1772; else goto K232;
K1862:  if (n. check (17)) return false; else goto K354;
K1863:  if (n. check (19)) goto K399; else goto K1687;
K1864:  if (n. check (19)) goto K1950; else goto K724;
K1867:  if (n. check (14)) goto K1135; else goto K64;
K1873:  if (n. check (17)) return false; else goto K592;
K1900:  if (n. check (17)) return false; else goto K2363;
K1903:  if (n. check (20)) return false; else goto K368;
K1904:  if (n. check (5)) goto K2108; else goto K1705;
K1905:  if (n. check (13)) goto K2473; else goto K1044;
K1910:  if (n. check (1)) goto K752; else goto K924;
K1915:  if (n. check (12)) return false; else goto K1395;
K1922:  if (n. check (19)) return false; else goto K690;
K1923:  if (n. check (4)) goto K2200; else goto K2460;
K1924:  if (n. check (22)) goto K1794; else goto K63;
K1925:  if (n. check (7)) goto K718; else goto K1332;
K1926:  if (n. check (20)) goto K1998; else goto K1238;
K1928:  if (n. check (20)) goto K1200; else goto K1822;
K1934:  if (n. check (7)) goto K174; else goto K68;
K1939:  if (n. check (16)) return false; else goto K1475;
K1940:  if (n. check (18)) return false; else goto K198;
K1947:  if (n. check (13)) return false; else goto K85;
K1948:  if (n. check (17)) goto K2585; else goto K200;
K1949:  if (n. check (17)) goto K14; else goto K1001;
K1950:  if (n. check (17)) goto K14; else goto K590;
K1954:  if (n. check (10)) goto K2343; else goto K1855;
K1957:  if (n. check (20)) goto K2422; else goto K1934;
K1970:  if (n. check (7)) goto K2292; else return false;
K1972:  if (n. check (7)) goto K2416; else goto K174;
K1977:  if (n. check (20)) goto K863; else goto K172;
K1985:  if (n. check (19)) goto K433; else goto K2003;
K1992:  if (n. check (6)) goto K2321; else goto K1090;
K1996:  if (n. check (16)) return false; else goto K1332;
K1998:  if (n. check (7)) goto K773; else goto K1804;
K2000:  if (n. check (21)) return false; else goto K725;
K2001:  if (n. check (4)) goto K56; else goto K703;
K2002:  if (n. check (18)) goto K48; else goto K1636;
K2003:  if (n. check (17)) return false; else goto K691;
K2019:  if (n. check (1)) return false; else goto K1728;
K2028:  if (n. check (14)) goto K139; else goto K158;
K2041:  if (n. check (11)) goto K156; else goto K1395;
K2044:  if (n. check (20)) goto K832; else goto K1042;
K2045:  if (n. check (1)) goto K238; else goto K1846;
K2057:  if (n. check (7)) goto K1134; else goto K831;
K2058:  if (n. check (17)) return false; else goto K48;
K2062:  if (n. check (7)) goto K1332; else goto K1996;
K2063:  if (n. check (17)) return true; else goto K49;
K2067:  if (n. check (16)) return false; else goto K230;
K2082:  if (n. check (20)) return false; else goto K2177;
K2084:  if (n. check (13)) return false; else goto K2473;
K2087:  if (n. check (14)) goto K832; else goto K2144;
K2088:  if (n. check (19)) return false; else goto K1414;
K2091:  if (n. check (16)) return false; else goto K261;
K2092:  if (n. check (22)) return false; else goto K2099;
K2099:  if (n. check (19)) return false; else goto K2376;
K2108:  if (n. check (8)) goto K1599; else goto K2434;
K2112:  if (n. check (19)) goto K839; else goto K164;
K2113:  if (n. check (1)) goto K155; else goto K2415;
K2117:  if (n. check (14)) return false; else goto K1846;
K2119:  if (n. check (20)) goto K2120; else goto K1136;
K2120:  if (n. check (19)) goto K921; else goto K545;
K2122:  if (n. check (4)) goto K1498; else goto K411;
K2123:  if (n. check (10)) goto K2117; else goto K1002;
K2134:  if (n. check (13)) return false; else goto K1977;
K2144:  if (n. check (17)) goto K2585; else goto K229;
K2147:  if (n. check (1)) goto K2087; else goto K1221;
K2152:  if (n. check (19)) goto K1687; else goto K894;
K2173:  if (n. check (10)) goto K1270; else goto K1828;
K2174:  if (n. check (20)) goto K2422; else goto K293;
K2175:  if (n. check (17)) return false; else goto K1593;
K2177:  if (n. check (7)) goto K1210; else goto K1985;
K2181:  if (n. check (10)) return false; else goto K1245;
K2190:  if (n. check (19)) goto K1862; else goto K1409;
K2198:  if (n. check (14)) goto K238; else goto K192;
K2199:  if (n. check (19)) goto K1687; else goto K1438;
K2200:  if (n. check (20)) goto K863; else goto K219;
K2209:  if (n. check (20)) return false; else goto K1859;
K2214:  if (n. check (4)) goto K2082; else goto K2460;
K2215:  if (n. check (1)) goto K1832; else goto K871;
K2232:  if (n. check (4)) goto K826; else goto K1905;
K2245:  if (n. check (15)) goto K2421; else goto K2303;
K2247:  if (n. check (20)) return false; else goto K1862;
K2250:  if (n. check (19)) return false; else goto K1409;
K2256:  if (n. check (11)) goto K698; else goto K1393;
K2264:  if (n. check (19)) goto K1042; else goto K2360;
K2267:  if (n. check (14)) goto K2214; else goto K1521;
K2277:  if (n. check (9)) goto K1558; else goto K2147;
K2279:  if (n. check (10)) return false; else goto K2001;
K2292:  if (n. check (19)) goto K832; else goto K1950;
K2293:  if (n. check (4)) goto K1087; else goto K1861;
K2296:  if (n. check (16)) return false; else goto K559;
K2302:  if (n. check (19)) return false; else goto K1559;
K2303:  if (n. check (6)) goto K486; else goto K1543;
K2306:  if (n. check (16)) return false; else goto K2487;
K2310:  if (n. check (14)) goto K1648; else goto K2232;
K2312:  if (n. check (11)) goto K65; else goto K1413;
K2313:  if (n. check (19)) goto K1862; else goto K1461;
K2314:  if (n. check (9)) goto K137; else goto K2312;
K2317:  if (n. check (7)) goto K1149; else goto K2557;
K2321:  if (n. check (21)) goto K2602; else goto K49;
K2341:  if (n. check (4)) return false; else goto K2084;
K2343:  if (n. check (14)) return false; else goto K139;
K2344:  if (n. check (9)) goto K2019; else goto K448;
K2349:  if (n. check (16)) return false; else goto K843;
K2350:  if (n. check (22)) goto K278; else goto K686;
K2352:  if (n. check (24)) return false; else goto K52;
K2360:  if (n. check (17)) goto K14; else goto K691;
K2363:  if (n. check (21)) goto K39; else return true;
K2365:  if (n. check (9)) goto K2041; else goto K1327;
K2367:  if (n. check (7)) goto K2515; else goto K230;
K2368:  if (n. check (17)) return false; else goto K350;
K2371:  if (n. check (10)) goto K983; else goto K115;
K2376:  if (n. check (17)) return false; else goto K154;
K2377:  if (n. check (6)) goto K2321; else return false;
K2381:  if (n. check (19)) goto K1559; else return false;
K2386:  if (n. check (7)) goto K1824; else goto K2112;
K2387:  if (n. check (19)) goto K1949; else goto K255;
K2403:  if (n. check (19)) goto K2144; else goto K722;
K2410:  if (n. check (17)) return true; else goto K48;
K2411:  if (n. check (22)) goto K2199; else goto K2152;
K2412:  if (n. check (14)) goto K1846; else goto K2293;
K2415:  if (n. check (10)) goto K1423; else goto K521;
K2416:  if (n. check (19)) goto K1862; else return false;
K2417:  if (n. check (7)) goto K2387; else goto K2067;
K2421:  if (n. check (6)) goto K486; else goto K2000;
K2422:  if (n. check (7)) goto K2292; else goto K2555;
K2423:  if (n. check (22)) goto K203; else return true;
K2429:  if (n. check (4)) goto K1926; else goto K1664;
K2434:  if (n. check (11)) goto K127; else goto K241;
K2437:  if (n. check (14)) return false; else goto K238;
K2451:  if (n. check (17)) goto K2585; else goto K2245;
K2453:  if (n. check (10)) goto K522; else goto K741;
K2460:  if (n. check (20)) goto K248; else goto K1692;
K2467:  if (n. check (6)) goto K2602; else return false;
K2473:  if (n. check (20)) return false; else goto K1196;
K2486:  if (n. check (10)) goto K1245; else goto K2122;
K2487:  if (n. check (22)) goto K1794; else goto K1798;
K2490:  if (n. check (20)) goto K57; else goto K497;
K2495:  if (n. check (16)) return false; else goto K2092;
K2497:  if (n. check (18)) return false; else goto K49;
K2515:  if (n. check (19)) return false; else goto K1067;
K2533:  if (n. check (19)) goto K690; else return false;
K2536:  if (n. check (14)) return false; else goto K2410;
K2544:  if (n. check (18)) goto K48; else goto K49;
K2555:  if (n. check (16)) return false; else goto K1527;
K2557:  if (n. check (16)) return false; else goto K2403;
K2570:  if (n. check (10)) goto K2412; else goto K125;
K2576:  if (n. check (13)) return false; else goto K703;
K2581:  if (n. check (18)) goto K198; else goto K246;
K2585:  if (n. check (15)) goto K15; else return true;
K2586:  if (n. check (8)) goto K1789; else goto K102;
K2598:  if (n. check (5)) goto K792; else goto K494;
K2602:  if (n. check (18)) goto K49; else return false;
} /* acyclic3d */

template<class NeighborCheck >
bool chomp::homology::acyclic3d_Malandain ( NeighborCheck &  n  ) 

Verifies whether the neighborhood of a 3-dimensional cube is acyclic.

This procedure has been received from G. Malandain, see L. Robert and G. Malandain, Computer Vision and Image Understanding, Fast Binary Image Processing Using Binary Decision Diagrams, October 1998, No. 1, Vol. 72, pp. 1--9.

Definition at line 102 of file cubacycl.h.

Referenced by bddacyclic().

{
        int statInv = 0;

/*L147001:*/ if (n. check (5)) {goto L143033;} else {goto L120232;}
L143033: if (n. check (0)) {goto L123529;} else {goto L118136;}
L123529: if (n. check (17)) {goto L146041;} else {goto L144920;}
L146041: if (n. check (2)) {goto L124809;} else {goto L145112;}
L124809: if (n. check (1)) {goto L106441;} else {goto L124904;}
L106441: if (n. check (8)) {goto L105737;} else {goto L105736;}
L124904: if (n. check (8)) {goto L105736;} else {goto L106537;}
L106537: if (n. check (10)) {goto L105737;} else {goto L105736;}
L145112: if (n. check (1)) {goto L124648;} else {goto L108505;}
L124648: if (n. check (8)) {goto L105736;} else {goto L106473;}
L106473: if (n. check (11)) {goto L105737;} else {goto L105736;}
L108505: if (n. check (8)) {goto L106281;} else {goto L114329;}
L106281: if (n. check (4)) {goto L105737;} else {goto L105736;}
L114329: if (n. check (4)) {goto L128185;} else {goto L115769;}
L128185: if (n. check (11)) {goto L105737;} else {goto L106537;}
L115769: if (n. check (11)) {goto L106537;} else {goto L144408;}
L144408: if (n. check (10)) {goto L105736;} else {goto L106569;}
L106569: if (n. check (13)) {goto L105737;} else {goto L105736;}
L144920: if (n. check (2)) {goto L109080;} else {goto L116761;}
L109080: if (n. check (1)) {statInv=!statInv;goto L106441;} else {goto L118697;}
L118697: if (n. check (19)) {goto L105737;} else {goto L124904;}
L116761: if (n. check (20)) {goto L117817;} else {goto L127624;}
L117817: if (n. check (1)) {goto L105737;} else {goto L117017;}
L117017: if (n. check (19)) {goto L105737;} else {goto L108505;}
L127624: if (n. check (1)) {goto L124648;} else {goto L114553;}
L114553: if (n. check (19)) {goto L108505;} else {goto L118680;}
L118680: if (n. check (8)) {goto L130584;} else {goto L130041;}
L130584: if (n. check (22)) {statInv=!statInv;goto L106281;} else {goto L105736;}
L130041: if (n. check (22)) {goto L126505;} else {goto L137305;}
L126505: if (n. check (4)) {goto L127657;} else {goto L105737;}
L127657: if (n. check (11)) {goto L106537;} else {statInv=!statInv;goto L106537;}
L137305: if (n. check (4)) {goto L127657;} else {goto L115769;}
L118136: if (n. check (17)) {goto L131608;} else {goto L137497;}
L131608: if (n. check (2)) {goto L115784;} else {goto L108185;}
L115784: if (n. check (1)) {goto L117608;} else {goto L121673;}
L117608: if (n. check (9)) {statInv=!statInv;goto L106441;} else {goto L105736;}
L121673: if (n. check (9)) {goto L105737;} else {goto L134921;}
L134921: if (n. check (8)) {goto L105737;} else {goto L106537;}
L108185: if (n. check (1)) {goto L145497;} else {goto L120857;}
L145497: if (n. check (3)) {goto L146729;} else {goto L118584;}
L146729: if (n. check (9)) {goto L105737;} else {goto L130201;}
L130201: if (n. check (8)) {goto L105737;} else {goto L106473;}
L118584: if (n. check (9)) {goto L124648;} else {goto L120680;}
L120680: if (n. check (8)) {goto L105736;} else {goto L119432;}
L119432: if (n. check (12)) {statInv=!statInv;goto L106473;} else {goto L105736;}
L120857: if (n. check (3)) {goto L129049;} else {goto L115481;}
L129049: if (n. check (9)) {goto L105737;} else {goto L120265;}
L120265: if (n. check (8)) {goto L105737;} else {goto L114329;}
L115481: if (n. check (9)) {goto L108505;} else {goto L126889;}
L126889: if (n. check (8)) {goto L106281;} else {goto L146681;}
L146681: if (n. check (4)) {goto L129465;} else {goto L121080;}
L129465: if (n. check (12)) {goto L109273;} else {goto L106537;}
L109273: if (n. check (11)) {goto L106537;} else {goto L105737;}
L121080: if (n. check (12)) {goto L121864;} else {goto L107128;}
L121864: if (n. check (11)) {statInv=!statInv;goto L106537;} else {goto L105737;}
L107128: if (n. check (11)) {statInv=!statInv;goto L106537;} else {goto L144408;}
L137497: if (n. check (18)) {goto L109625;} else {goto L144984;}
L109625: if (n. check (2)) {goto L116633;} else {goto L116569;}
L116633: if (n. check (1)) {goto L105737;} else {goto L107753;}
L107753: if (n. check (19)) {goto L105737;} else {goto L121673;}
L116569: if (n. check (20)) {goto L137753;} else {goto L126057;}
L137753: if (n. check (1)) {goto L105737;} else {goto L122249;}
L122249: if (n. check (19)) {goto L105737;} else {goto L120857;}
L126057: if (n. check (1)) {goto L145497;} else {goto L119273;}
L119273: if (n. check (19)) {goto L120857;} else {goto L107833;}
L107833: if (n. check (3)) {goto L135929;} else {goto L122824;}
L135929: if (n. check (9)) {goto L105737;} else {goto L107961;}
L107961: if (n. check (8)) {goto L105737;} else {goto L130041;}
L122824: if (n. check (9)) {goto L118680;} else {goto L121448;}
L121448: if (n. check (8)) {goto L130584;} else {goto L124136;}
L124136: if (n. check (22)) {goto L143960;} else {goto L125928;}
L143960: if (n. check (4)) {goto L146936;} else {goto L105737;}
L146936: if (n. check (12)) {goto L121864;} else {statInv=!statInv;goto L106537;}
L125928: if (n. check (4)) {goto L146936;} else {goto L121080;}
L144984: if (n. check (2)) {goto L120456;} else {goto L128441;}
L120456: if (n. check (1)) {goto L117608;} else {goto L117657;}
L117657: if (n. check (19)) {goto L121673;} else {goto L127016;}
L127016: if (n. check (9)) {goto L124904;} else {statInv=!statInv;goto L134921;}
L128441: if (n. check (20)) {goto L121577;} else {goto L114488;}
L121577: if (n. check (1)) {goto L145497;} else {goto L124089;}
L124089: if (n. check (19)) {goto L120857;} else {goto L129337;}
L129337: if (n. check (3)) {goto L130169;} else {goto L135480;}
L130169: if (n. check (9)) {goto L108505;} else {goto L107225;}
L107225: if (n. check (8)) {goto L106281;} else {goto L126025;}
L126025: if (n. check (4)) {goto L123049;} else {goto L121864;}
L123049: if (n. check (11)) {goto L105737;} else {statInv=!statInv;goto L106537;}
L135480: if (n. check (9)) {goto L130904;} else {goto L146968;}
L130904: if (n. check (8)) {statInv=!statInv;goto L106281;} else {goto L126505;}
L146968: if (n. check (8)) {statInv=!statInv;goto L106281;} else {goto L143960;}
L114488: if (n. check (1)) {goto L146616;} else {goto L129881;}
L146616: if (n. check (3)) {goto L134312;} else {goto L136217;}
L134312: if (n. check (9)) {goto L124648;} else {statInv=!statInv;goto L130201;}
L136217: if (n. check (21)) {goto L105737;} else {goto L118584;}
L129881: if (n. check (19)) {goto L133913;} else {goto L125960;}
L133913: if (n. check (3)) {goto L108953;} else {goto L122217;}
L108953: if (n. check (9)) {goto L108505;} else {goto L136281;}
L136281: if (n. check (8)) {goto L106281;} else {goto L143177;}
L143177: if (n. check (4)) {goto L109273;} else {goto L121864;}
L122217: if (n. check (21)) {goto L105737;} else {goto L115481;}
L125960: if (n. check (3)) {goto L134536;} else {goto L134697;}
L134536: if (n. check (9)) {goto L118680;} else {goto L135096;}
L135096: if (n. check (8)) {goto L130584;} else {goto L137704;}
L137704: if (n. check (22)) {goto L143128;} else {goto L121864;}
L143128: if (n. check (4)) {goto L121864;} else {goto L105737;}
L134697: if (n. check (21)) {goto L105737;} else {goto L122824;}
L120232: if (n. check (0)) {goto L126936;} else {goto L126121;}
L126936: if (n. check (17)) {goto L123272;} else {goto L132825;}
L123272: if (n. check (2)) {goto L123848;} else {goto L131161;}
L123848: if (n. check (1)) {goto L114968;} else {goto L119785;}
L114968: if (n. check (14)) {statInv=!statInv;goto L106441;} else {goto L105736;}
L119785: if (n. check (7)) {goto L135721;} else {goto L128600;}
L135721: if (n. check (14)) {goto L105737;} else {goto L134921;}
L128600: if (n. check (14)) {goto L124904;} else {goto L135352;}
L135352: if (n. check (8)) {goto L105736;} else {goto L136472;}
L136472: if (n. check (16)) {statInv=!statInv;goto L106537;} else {goto L105736;}
L131161: if (n. check (1)) {goto L113913;} else {goto L145833;}
L113913: if (n. check (14)) {goto L105737;} else {goto L130201;}
L145833: if (n. check (7)) {goto L132249;} else {goto L142617;}
L132249: if (n. check (14)) {goto L105737;} else {goto L120265;}
L142617: if (n. check (14)) {goto L108505;} else {goto L137769;}
L137769: if (n. check (8)) {goto L106281;} else {goto L125321;}
L125321: if (n. check (4)) {goto L142841;} else {goto L129368;}
L142841: if (n. check (11)) {goto L105737;} else {goto L136472;}
L129368: if (n. check (11)) {goto L136472;} else {goto L106809;}
L106809: if (n. check (16)) {goto L105737;} else {goto L130457;}
L130457: if (n. check (10)) {goto L105737;} else {goto L106569;}
L132825: if (n. check (23)) {goto L136121;} else {goto L123080;}
L136121: if (n. check (2)) {goto L123785;} else {goto L132537;}
L123785: if (n. check (1)) {goto L105737;} else {goto L108697;}
L108697: if (n. check (19)) {goto L105737;} else {goto L119785;}
L132537: if (n. check (20)) {goto L138169;} else {goto L142761;}
L138169: if (n. check (1)) {goto L105737;} else {goto L116793;}
L116793: if (n. check (19)) {goto L105737;} else {goto L145833;}
L142761: if (n. check (1)) {goto L113913;} else {goto L135737;}
L135737: if (n. check (19)) {goto L145833;} else {goto L131481;}
L131481: if (n. check (7)) {goto L123753;} else {goto L107608;}
L123753: if (n. check (14)) {goto L105737;} else {goto L107961;}
L107608: if (n. check (14)) {goto L118680;} else {goto L109400;}
L109400: if (n. check (8)) {goto L130584;} else {goto L128504;}
L128504: if (n. check (22)) {goto L135224;} else {goto L124712;}
L135224: if (n. check (4)) {goto L144696;} else {goto L105737;}
L144696: if (n. check (11)) {goto L136472;} else {goto L105737;}
L124712: if (n. check (4)) {goto L144696;} else {goto L129368;}
L123080: if (n. check (2)) {goto L107192;} else {goto L114137;}
L107192: if (n. check (1)) {goto L114968;} else {goto L130521;}
L130521: if (n. check (19)) {goto L119785;} else {goto L133768;}
L133768: if (n. check (7)) {goto L136760;} else {goto L127209;}
L136760: if (n. check (14)) {goto L124904;} else {statInv=!statInv;goto L134921;}
L127209: if (n. check (25)) {goto L105737;} else {goto L128600;}
L114137: if (n. check (20)) {goto L107801;} else {goto L132280;}
L107801: if (n. check (1)) {goto L113913;} else {goto L143225;}
L143225: if (n. check (19)) {goto L145833;} else {goto L136249;}
L136249: if (n. check (7)) {goto L132345;} else {goto L130361;}
L132345: if (n. check (14)) {goto L108505;} else {goto L107225;}
L130361: if (n. check (25)) {goto L105737;} else {goto L142617;}
L132280: if (n. check (1)) {goto L114008;} else {goto L106649;}
L114008: if (n. check (14)) {goto L124648;} else {statInv=!statInv;goto L130201;}
L106649: if (n. check (19)) {goto L137465;} else {goto L121512;}
L137465: if (n. check (7)) {goto L130329;} else {goto L144904;}
L130329: if (n. check (14)) {goto L108505;} else {goto L136281;}
L144904: if (n. check (14)) {goto L130904;} else {goto L132040;}
L132040: if (n. check (8)) {statInv=!statInv;goto L106281;} else {goto L135224;}
L121512: if (n. check (7)) {goto L134152;} else {goto L117401;}
L134152: if (n. check (14)) {goto L118680;} else {goto L135096;}
L117401: if (n. check (25)) {goto L105737;} else {goto L107608;}
L126121: if (n. check (17)) {goto L123817;} else {goto L145849;}
L123817: if (n. check (6)) {goto L123465;} else {goto L119336;}
L123465: if (n. check (2)) {goto L122809;} else {goto L117305;}
L122809: if (n. check (1)) {goto L118169;} else {goto L107769;}
L118169: if (n. check (9)) {goto L105737;} else {goto L123337;}
L123337: if (n. check (14)) {goto L105737;} else {goto L106441;}
L107769: if (n. check (9)) {goto L105737;} else {goto L125993;}
L125993: if (n. check (7)) {goto L135721;} else {goto L145145;}
L145145: if (n. check (14)) {goto L134921;} else {goto L114105;}
L114105: if (n. check (8)) {goto L105737;} else {goto L136472;}
L117305: if (n. check (1)) {goto L143769;} else {goto L146873;}
L143769: if (n. check (3)) {goto L125865;} else {goto L132665;}
L125865: if (n. check (9)) {goto L105737;} else {goto L113913;}
L132665: if (n. check (9)) {goto L113913;} else {goto L128825;}
L128825: if (n. check (14)) {goto L105737;} else {goto L135865;}
L135865: if (n. check (8)) {goto L105737;} else {goto L119432;}
L146873: if (n. check (3)) {goto L146297;} else {goto L146233;}
L146297: if (n. check (9)) {goto L105737;} else {goto L117241;}
L117241: if (n. check (7)) {goto L132249;} else {goto L106585;}
L106585: if (n. check (14)) {goto L120265;} else {goto L126537;}
L126537: if (n. check (8)) {goto L105737;} else {goto L125321;}
L146233: if (n. check (9)) {goto L145833;} else {goto L125417;}
L125417: if (n. check (7)) {goto L134009;} else {goto L125369;}
L134009: if (n. check (14)) {goto L105737;} else {goto L145977;}
L145977: if (n. check (8)) {goto L105737;} else {goto L146681;}
L125369: if (n. check (14)) {goto L126889;} else {goto L136233;}
L136233: if (n. check (8)) {goto L106281;} else {goto L136440;}
L136440: if (n. check (4)) {goto L136056;} else {goto L108601;}
L136056: if (n. check (12)) {goto L144696;} else {goto L136472;}
L108601: if (n. check (12)) {goto L105737;} else {goto L118617;}
L118617: if (n. check (11)) {goto L105737;} else {goto L106809;}
L119336: if (n. check (2)) {goto L134824;} else {goto L124105;}
L134824: if (n. check (1)) {goto L115992;} else {goto L128377;}
L115992: if (n. check (9)) {goto L114968;} else {goto L146072;}
L146072: if (n. check (15)) {statInv=!statInv;goto L123337;} else {goto L105736;}
L128377: if (n. check (9)) {goto L119785;} else {goto L130729;}
L130729: if (n. check (7)) {goto L122041;} else {goto L108056;}
L122041: if (n. check (15)) {goto L107273;} else {goto L134921;}
L107273: if (n. check (14)) {goto L134921;} else {goto L105737;}
L108056: if (n. check (15)) {goto L134568;} else {goto L134440;}
L134568: if (n. check (14)) {statInv=!statInv;goto L134921;} else {statInv=!statInv;goto L106441;}
L134440: if (n. check (14)) {statInv=!statInv;goto L134921;} else {goto L135352;}
L124105: if (n. check (1)) {goto L136841;} else {goto L108153;}
L136841: if (n. check (3)) {goto L143209;} else {goto L120488;}
L143209: if (n. check (9)) {goto L113913;} else {goto L143161;}
L143161: if (n. check (15)) {goto L123017;} else {goto L130201;}
L123017: if (n. check (14)) {goto L130201;} else {goto L105737;}
L120488: if (n. check (9)) {goto L114008;} else {goto L143832;}
L143832: if (n. check (15)) {goto L123496;} else {goto L120680;}
L123496: if (n. check (14)) {goto L120680;} else {statInv=!statInv;goto L106441;}
L108153: if (n. check (3)) {goto L136825;} else {goto L120873;}
L136825: if (n. check (9)) {goto L145833;} else {goto L121833;}
L121833: if (n. check (7)) {goto L108441;} else {goto L131321;}
L108441: if (n. check (15)) {goto L126729;} else {goto L120265;}
L126729: if (n. check (14)) {goto L120265;} else {goto L105737;}
L131321: if (n. check (15)) {goto L145177;} else {goto L129945;}
L145177: if (n. check (14)) {goto L107225;} else {goto L107065;}
L107065: if (n. check (8)) {goto L106281;} else {goto L105737;}
L129945: if (n. check (14)) {goto L107225;} else {goto L137769;}
L120873: if (n. check (9)) {goto L137465;} else {goto L109305;}
L109305: if (n. check (7)) {goto L121257;} else {goto L135992;}
L121257: if (n. check (15)) {goto L114393;} else {goto L126889;}
L114393: if (n. check (14)) {goto L126889;} else {goto L107065;}
L135992: if (n. check (15)) {goto L108376;} else {goto L146136;}
L108376: if (n. check (14)) {goto L146968;} else {goto L143384;}
L143384: if (n. check (8)) {statInv=!statInv;goto L106281;} else {goto L105737;}
L146136: if (n. check (14)) {goto L146968;} else {goto L106968;}
L106968: if (n. check (8)) {statInv=!statInv;goto L106281;} else {goto L136440;}
L145849: if (n. check (23)) {goto L136025;} else {goto L131385;}
L136025: if (n. check (18)) {goto L128953;} else {goto L144505;}
L128953: if (n. check (6)) {goto L136921;} else {goto L115561;}
L136921: if (n. check (2)) {goto L115705;} else {goto L124425;}
L115705: if (n. check (1)) {goto L105737;} else {goto L116729;}
L116729: if (n. check (19)) {goto L105737;} else {goto L107769;}
L124425: if (n. check (20)) {goto L114617;} else {goto L133241;}
L114617: if (n. check (1)) {goto L105737;} else {goto L116825;}
L116825: if (n. check (19)) {goto L105737;} else {goto L146873;}
L133241: if (n. check (1)) {goto L143769;} else {goto L123241;}
L123241: if (n. check (19)) {goto L146873;} else {goto L125481;}
L125481: if (n. check (3)) {goto L137737;} else {goto L123433;}
L137737: if (n. check (9)) {goto L105737;} else {goto L108409;}
L108409: if (n. check (7)) {goto L123753;} else {goto L135769;}
L135769: if (n. check (14)) {goto L107961;} else {goto L134025;}
L134025: if (n. check (8)) {goto L105737;} else {goto L128504;}
L123433: if (n. check (9)) {goto L131481;} else {goto L114905;}
L114905: if (n. check (7)) {goto L131865;} else {goto L108632;}
L131865: if (n. check (14)) {goto L105737;} else {goto L129849;}
L129849: if (n. check (8)) {goto L105737;} else {goto L124136;}
L108632: if (n. check (14)) {goto L121448;} else {goto L109112;}
L109112: if (n. check (8)) {goto L130584;} else {goto L116281;}
L116281: if (n. check (22)) {goto L105737;} else {goto L135193;}
L135193: if (n. check (4)) {goto L105737;} else {goto L108601;}
L115561: if (n. check (2)) {goto L127913;} else {goto L134873;}
L127913: if (n. check (1)) {goto L105737;} else {goto L145689;}
L145689: if (n. check (19)) {goto L105737;} else {goto L128377;}
L134873: if (n. check (20)) {goto L115353;} else {goto L116217;}
L115353: if (n. check (1)) {goto L105737;} else {goto L131193;}
L131193: if (n. check (19)) {goto L105737;} else {goto L108153;}
L116217: if (n. check (1)) {goto L136841;} else {goto L137209;}
L137209: if (n. check (19)) {goto L108153;} else {goto L107865;}
L107865: if (n. check (3)) {goto L142969;} else {goto L124232;}
L142969: if (n. check (9)) {goto L131481;} else {goto L129193;}
L129193: if (n. check (7)) {goto L146201;} else {goto L106616;}
L146201: if (n. check (15)) {goto L132297;} else {goto L107961;}
L132297: if (n. check (14)) {goto L107961;} else {goto L105737;}
L106616: if (n. check (15)) {goto L134280;} else {goto L121336;}
L134280: if (n. check (14)) {goto L135096;} else {goto L124616;}
L124616: if (n. check (8)) {goto L130584;} else {goto L105737;}
L121336: if (n. check (14)) {goto L135096;} else {goto L109400;}
L124232: if (n. check (9)) {goto L143576;} else {goto L145816;}
L143576: if (n. check (7)) {goto L134152;} else {goto L105737;}
L145816: if (n. check (7)) {goto L145656;} else {goto L145577;}
L145656: if (n. check (15)) {goto L134408;} else {goto L121448;}
L134408: if (n. check (14)) {goto L121448;} else {goto L124616;}
L145577: if (n. check (15)) {goto L105737;} else {goto L122153;}
L122153: if (n. check (14)) {goto L105737;} else {goto L119721;}
L119721: if (n. check (8)) {goto L105737;} else {goto L116281;}
L144505: if (n. check (6)) {goto L127689;} else {goto L117912;}
L127689: if (n. check (2)) {goto L129081;} else {goto L142873;}
L129081: if (n. check (1)) {goto L118169;} else {goto L120937;}
L120937: if (n. check (19)) {goto L107769;} else {goto L122745;}
L122745: if (n. check (9)) {goto L119785;} else {goto L108665;}
L108665: if (n. check (7)) {goto L131129;} else {goto L134568;}
L131129: if (n. check (14)) {goto L105737;} else {statInv=!statInv;goto L124904;}
L142873: if (n. check (20)) {goto L125065;} else {goto L137977;}
L125065: if (n. check (1)) {goto L143769;} else {goto L106873;}
L106873: if (n. check (19)) {goto L146873;} else {goto L122889;}
L122889: if (n. check (3)) {goto L120137;} else {goto L116921;}
L120137: if (n. check (9)) {goto L145833;} else {goto L120121;}
L120121: if (n. check (7)) {goto L128009;} else {goto L145177;}
L128009: if (n. check (14)) {goto L105737;} else {goto L114057;}
L114057: if (n. check (8)) {goto L105737;} else {goto L126025;}
L116921: if (n. check (9)) {goto L136537;} else {goto L109465;}
L136537: if (n. check (7)) {goto L121129;} else {goto L144904;}
L121129: if (n. check (14)) {goto L105737;} else {goto L127305;}
L127305: if (n. check (8)) {goto L105737;} else {goto L126505;}
L109465: if (n. check (7)) {goto L126089;} else {goto L108376;}
L126089: if (n. check (14)) {goto L105737;} else {goto L128137;}
L128137: if (n. check (8)) {goto L105737;} else {goto L143960;}
L137977: if (n. check (1)) {goto L137369;} else {goto L131033;}
L137369: if (n. check (3)) {goto L121961;} else {goto L120809;}
L121961: if (n. check (9)) {goto L113913;} else {goto L108281;}
L108281: if (n. check (14)) {goto L105737;} else {statInv=!statInv;goto L124648;}
L120809: if (n. check (21)) {goto L105737;} else {goto L132665;}
L131033: if (n. check (19)) {goto L115257;} else {goto L131833;}
L115257: if (n. check (3)) {goto L143801;} else {goto L117273;}
L143801: if (n. check (9)) {goto L145833;} else {goto L118777;}
L118777: if (n. check (7)) {goto L144089;} else {goto L144841;}
L144089: if (n. check (14)) {goto L105737;} else {goto L121353;}
L121353: if (n. check (8)) {goto L105737;} else {goto L143177;}
L144841: if (n. check (14)) {goto L136281;} else {goto L135801;}
L135801: if (n. check (8)) {goto L106281;} else {goto L135224;}
L117273: if (n. check (21)) {goto L105737;} else {goto L146233;}
L131833: if (n. check (3)) {goto L122505;} else {goto L119593;}
L122505: if (n. check (9)) {goto L131481;} else {goto L123721;}
L123721: if (n. check (7)) {goto L133721;} else {goto L134280;}
L133721: if (n. check (14)) {goto L105737;} else {goto L133561;}
L133561: if (n. check (8)) {goto L105737;} else {goto L137704;}
L119593: if (n. check (21)) {goto L105737;} else {goto L123433;}
L117912: if (n. check (2)) {goto L137048;} else {goto L136601;}
L137048: if (n. check (1)) {goto L115992;} else {goto L119881;}
L119881: if (n. check (19)) {goto L128377;} else {goto L137912;}
L137912: if (n. check (9)) {goto L119944;} else {goto L127336;}
L119944: if (n. check (7)) {goto L136760;} else {goto L105737;}
L127336: if (n. check (7)) {goto L115576;} else {goto L105737;}
L115576: if (n. check (15)) {goto L134568;} else {statInv=!statInv;goto L134921;}
L136601: if (n. check (20)) {goto L128025;} else {goto L129304;}
L128025: if (n. check (1)) {goto L136841;} else {goto L120985;}
L120985: if (n. check (19)) {goto L108153;} else {goto L120041;}
L120041: if (n. check (3)) {goto L118553;} else {goto L120712;}
L118553: if (n. check (9)) {goto L118905;} else {goto L119177;}
L118905: if (n. check (7)) {goto L132345;} else {goto L105737;}
L119177: if (n. check (7)) {goto L126249;} else {goto L105737;}
L126249: if (n. check (15)) {goto L145177;} else {goto L107225;}
L120712: if (n. check (9)) {goto L124200;} else {goto L127848;}
L124200: if (n. check (7)) {goto L107672;} else {goto L105737;}
L107672: if (n. check (14)) {goto L130904;} else {goto L144024;}
L144024: if (n. check (8)) {statInv=!statInv;goto L106281;} else {goto L143128;}
L127848: if (n. check (7)) {goto L146920;} else {goto L105737;}
L146920: if (n. check (15)) {goto L108376;} else {goto L146968;}
L129304: if (n. check (1)) {goto L125560;} else {goto L132601;}
L125560: if (n. check (3)) {goto L125576;} else {goto L121769;}
L125576: if (n. check (9)) {goto L114008;} else {goto L124008;}
L124008: if (n. check (15)) {goto L115496;} else {statInv=!statInv;goto L130201;}
L115496: if (n. check (14)) {statInv=!statInv;goto L130201;} else {statInv=!statInv;goto L106441;}
L121769: if (n. check (21)) {goto L105737;} else {goto L120488;}
L132601: if (n. check (19)) {goto L106681;} else {goto L133080;}
L106681: if (n. check (3)) {goto L144729;} else {goto L109209;}
L144729: if (n. check (9)) {goto L137465;} else {goto L108985;}
L108985: if (n. check (7)) {goto L123113;} else {goto L144568;}
L123113: if (n. check (15)) {goto L133785;} else {goto L136281;}
L133785: if (n. check (14)) {goto L136281;} else {goto L107065;}
L144568: if (n. check (15)) {goto L137272;} else {goto L138440;}
L137272: if (n. check (14)) {goto L144024;} else {goto L143384;}
L138440: if (n. check (14)) {goto L144024;} else {goto L132040;}
L109209: if (n. check (21)) {goto L105737;} else {goto L120873;}
L133080: if (n. check (3)) {goto L114632;} else {goto L126409;}
L114632: if (n. check (9)) {goto L143576;} else {goto L143896;}
L143896: if (n. check (7)) {goto L131112;} else {goto L105737;}
L131112: if (n. check (15)) {goto L134280;} else {goto L135096;}
L126409: if (n. check (21)) {goto L105737;} else {goto L124232;}
L131385: if (n. check (18)) {goto L128985;} else {goto L132920;}
L128985: if (n. check (6)) {goto L115833;} else {goto L143816;}
L115833: if (n. check (2)) {goto L120841;} else {goto L138329;}
L120841: if (n. check (1)) {goto L118169;} else {goto L143481;}
L143481: if (n. check (19)) {goto L107769;} else {goto L121801;}
L121801: if (n. check (9)) {goto L105737;} else {goto L118809;}
L118809: if (n. check (7)) {goto L121609;} else {goto L116665;}
L121609: if (n. check (14)) {goto L134921;} else {statInv=!statInv;goto L124904;}
L116665: if (n. check (25)) {goto L105737;} else {goto L145145;}
L138329: if (n. check (20)) {goto L125225;} else {goto L124553;}
L125225: if (n. check (1)) {goto L143769;} else {goto L117721;}
L117721: if (n. check (19)) {goto L146873;} else {goto L127081;}
L127081: if (n. check (3)) {goto L120905;} else {goto L130009;}
L120905: if (n. check (9)) {goto L105737;} else {goto L126265;}
L126265: if (n. check (7)) {goto L136137;} else {goto L107321;}
L136137: if (n. check (14)) {goto L120265;} else {goto L114057;}
L107321: if (n. check (25)) {goto L105737;} else {goto L106585;}
L130009: if (n. check (9)) {goto L136249;} else {goto L124745;}
L124745: if (n. check (7)) {goto L115609;} else {goto L115385;}
L115609: if (n. check (14)) {goto L126889;} else {goto L109561;}
L109561: if (n. check (8)) {goto L106281;} else {goto L143960;}
L115385: if (n. check (25)) {goto L105737;} else {goto L125369;}
L124553: if (n. check (1)) {goto L143417;} else {goto L129209;}
L143417: if (n. check (3)) {goto L138297;} else {goto L130712;}
L138297: if (n. check (9)) {goto L105737;} else {goto L126857;}
L126857: if (n. check (14)) {goto L130201;} else {statInv=!statInv;goto L124648;}
L130712: if (n. check (9)) {goto L114008;} else {goto L123496;}
L129209: if (n. check (19)) {goto L144537;} else {goto L132217;}
L144537: if (n. check (3)) {goto L117785;} else {goto L137625;}
L117785: if (n. check (9)) {goto L105737;} else {goto L108521;}
L108521: if (n. check (7)) {goto L125513;} else {goto L119001;}
L125513: if (n. check (14)) {goto L120265;} else {goto L121353;}
L119001: if (n. check (14)) {goto L127305;} else {goto L119737;}
L119737: if (n. check (8)) {goto L105737;} else {goto L135224;}
L137625: if (n. check (9)) {goto L137465;} else {goto L143353;}
L143353: if (n. check (7)) {goto L114393;} else {goto L108376;}
L132217: if (n. check (3)) {goto L137113;} else {goto L145208;}
L137113: if (n. check (9)) {goto L105737;} else {goto L119849;}
L119849: if (n. check (7)) {goto L132761;} else {goto L138025;}
L132761: if (n. check (14)) {goto L107961;} else {goto L133561;}
L138025: if (n. check (25)) {goto L105737;} else {goto L135769;}
L145208: if (n. check (9)) {goto L121512;} else {goto L138040;}
L138040: if (n. check (7)) {goto L134408;} else {goto L133017;}
L133017: if (n. check (25)) {goto L105737;} else {goto L108632;}
L143816: if (n. check (2)) {goto L137176;} else {goto L127721;}
L137176: if (n. check (1)) {goto L115992;} else {goto L146009;}
L146009: if (n. check (19)) {goto L128377;} else {goto L130120;}
L130120: if (n. check (9)) {goto L133768;} else {goto L120296;}
L120296: if (n. check (7)) {goto L115576;} else {goto L126153;}
L126153: if (n. check (25)) {goto L105737;} else {goto L108056;}
L127721: if (n. check (20)) {goto L125161;} else {goto L118664;}
L125161: if (n. check (1)) {goto L136841;} else {goto L144249;}
L144249: if (n. check (19)) {goto L108153;} else {goto L126713;}
L126713: if (n. check (3)) {goto L123305;} else {goto L143192;}
L123305: if (n. check (9)) {goto L136249;} else {goto L137657;}
L137657: if (n. check (7)) {goto L126249;} else {goto L146377;}
L146377: if (n. check (25)) {goto L105737;} else {goto L131321;}
L143192: if (n. check (9)) {goto L116184;} else {goto L125128;}
L116184: if (n. check (7)) {goto L107672;} else {goto L137433;}
L137433: if (n. check (25)) {goto L105737;} else {goto L144904;}
L125128: if (n. check (7)) {goto L146920;} else {goto L134137;}
L134137: if (n. check (25)) {goto L105737;} else {goto L135992;}
L118664: if (n. check (1)) {goto L109432;} else {goto L109033;}
L109432: if (n. check (3)) {goto L125576;} else {goto L105737;}
L109033: if (n. check (19)) {goto L134217;} else {goto L122120;}
L134217: if (n. check (3)) {goto L144729;} else {goto L105737;}
L122120: if (n. check (3)) {goto L115672;} else {goto L145433;}
L115672: if (n. check (9)) {goto L121512;} else {goto L136664;}
L136664: if (n. check (7)) {goto L131112;} else {goto L143321;}
L143321: if (n. check (25)) {goto L105737;} else {goto L106616;}
L145433: if (n. check (9)) {goto L105737;} else {goto L114873;}
L114873: if (n. check (7)) {goto L105737;} else {goto L126377;}
L126377: if (n. check (25)) {goto L105737;} else {goto L145577;}
L132920: if (n. check (6)) {goto L118488;} else {goto L115001;}
L118488: if (n. check (2)) {goto L133976;} else {goto L118537;}
L133976: if (n. check (1)) {goto L107704;} else {goto L115161;}
L107704: if (n. check (9)) {goto L114968;} else {statInv=!statInv;goto L123337;}
L115161: if (n. check (19)) {goto L108489;} else {goto L131416;}
L108489: if (n. check (9)) {goto L119785;} else {goto L123209;}
L123209: if (n. check (7)) {goto L107273;} else {goto L134568;}
L131416: if (n. check (9)) {goto L133768;} else {goto L130024;}
L130024: if (n. check (7)) {goto L134568;} else {goto L125721;}
L125721: if (n. check (25)) {goto L105737;} else {goto L134568;}
L118537: if (n. check (20)) {goto L125833;} else {goto L117368;}
L125833: if (n. check (1)) {goto L118521;} else {goto L106745;}
L118521: if (n. check (3)) {goto L143305;} else {goto L130712;}
L143305: if (n. check (9)) {goto L113913;} else {goto L123017;}
L106745: if (n. check (19)) {goto L109593;} else {goto L135257;}
L109593: if (n. check (3)) {goto L132089;} else {goto L137625;}
L132089: if (n. check (9)) {goto L145833;} else {goto L129113;}
L129113: if (n. check (7)) {goto L126729;} else {goto L145177;}
L135257: if (n. check (3)) {goto L145561;} else {goto L127976;}
L145561: if (n. check (9)) {goto L136249;} else {goto L114361;}
L114361: if (n. check (7)) {goto L145177;} else {goto L119113;}
L119113: if (n. check (25)) {goto L105737;} else {goto L145177;}
L127976: if (n. check (9)) {goto L116184;} else {goto L127112;}
L127112: if (n. check (7)) {goto L108376;} else {goto L108313;}
L108313: if (n. check (25)) {goto L105737;} else {goto L108376;}
L117368: if (n. check (1)) {goto L119528;} else {goto L107289;}
L119528: if (n. check (3)) {goto L118232;} else {goto L106841;}
L118232: if (n. check (9)) {goto L114008;} else {goto L115496;}
L106841: if (n. check (21)) {goto L105737;} else {goto L130712;}
L107289: if (n. check (19)) {goto L133817;} else {goto L118200;}
L133817: if (n. check (3)) {goto L136089;} else {goto L130617;}
L136089: if (n. check (9)) {goto L137465;} else {goto L134121;}
L134121: if (n. check (7)) {goto L133785;} else {goto L137272;}
L130617: if (n. check (21)) {goto L105737;} else {goto L137625;}
L118200: if (n. check (3)) {goto L145880;} else {goto L114201;}
L145880: if (n. check (9)) {goto L121512;} else {goto L108856;}
L108856: if (n. check (7)) {goto L134280;} else {goto L127593;}
L127593: if (n. check (25)) {goto L105737;} else {goto L134280;}
L114201: if (n. check (21)) {goto L105737;} else {goto L145208;}
L115001: if (n. check (24)) {goto L121929;} else {goto L107640;}
L121929: if (n. check (2)) {goto L105737;} else {goto L123593;}
L123593: if (n. check (20)) {goto L105737;} else {goto L144281;}
L144281: if (n. check (1)) {goto L105737;} else {goto L122473;}
L122473: if (n. check (19)) {goto L105737;} else {goto L143545;}
L143545: if (n. check (3)) {goto L105737;} else {goto L126793;}
L126793: if (n. check (21)) {goto L105737;} else {goto L145433;}
L107640: if (n. check (2)) {goto L137176;} else {goto L132857;}
L132857: if (n. check (20)) {goto L125161;} else {goto L143912;}
L143912: if (n. check (1)) {goto L125560;} else {goto L134601;}
L134601: if (n. check (19)) {goto L106681;} else {goto L125608;}
L125608: if (n. check (3)) {goto L115672;} else {goto L135609;}
L135609: if (n. check (21)) {goto L145433;} else {goto L109016;}
L109016: if (n. check (9)) {goto L121512;} else {goto L143000;}
L143000: if (n. check (7)) {goto L145656;} else {goto L132889;}
L132889: if (n. check (25)) {goto L145577;} else {goto L143928;}
L143928: if (n. check (15)) {goto L108632;} else {goto L135672;}
L135672: if (n. check (14)) {goto L121448;} else {goto L118008;}
L118008: if (n. check (8)) {goto L130584;} else {goto L128344;}
L128344: if (n. check (22)) {goto L136440;} else {goto L115448;}
L115448: if (n. check (4)) {goto L136056;} else {goto L122056;}
L122056: if (n. check (12)) {goto L129368;} else {goto L129688;}
L129688: if (n. check (11)) {goto L136472;} else {goto L136376;}
L136376: if (n. check (16)) {goto L144408;} else {statInv=!statInv;goto L130457;}
L105736: return !statInv;
L105737: return statInv;
} /* acyclic3d_Malandain */

template<class tCube >
bool chomp::homology::acyclic_rel ( const tCube &  q,
int  dim,
const hashedset< tCube > &  cset,
const hashedset< tCube > &  other,
BitField *  b,
int_t  maxneighbors,
hashedset< tCube > *  neighbors_main,
hashedset< tCube > *  neighbors_other 
)

Verifies whether a cube from the other set can be removed.

Definition at line 185 of file cubisets.h.

References acyclic(), bddacyclic(), getneighbors(), makesetunion(), and MaxBddDim.

Referenced by cubreducequiet().

{
        // use a binary decision diagram code if possible
        if (dim <= MaxBddDim)
        {
                if (!getneighbors (q, b, cset, 1))
                        return true;
                if (!bddacyclic (q, dim, other, *b))
                        return false;
                return bddacyclic (q, dim, makesetunion (cset, other), *b);
        }

        // get the neighbors from the other set
        int_t nother = getneighbors (q, b, other, neighbors_other, 0);

        // verify if this set of neighbors is acyclic
        bool otheracyclic = (nother < maxneighbors) &&
                ((nother == 1) || (nother && acyclic (dim, *b)));

        // add the neighbors from 'cset'
        int_t ncset = getneighbors (q, b, cset, neighbors_main, 0);

        // if there are no cubes in 'cset', then this cube is ok
        if (!ncset)
                return true;

        // if there are neighbors in 'cset' and the neighbors
        // from 'other' are not acyclic, skip this cube
        if (!otheracyclic)
                return false;

        // if there are neighbors from 'cset' then check if the neighbors
        // from both 'cset' and 'other' taken together form an acyclic set
        if ((ncset + nother > 1) && ((ncset + nother == maxneighbors) ||
                !acyclic (dim, *b)))
        {
                return false;
        }
        return true;
} /* acyclic_rel */

template<class cell , class euclidom >
void chomp::homology::addboundaries ( gcomplex< cell, euclidom > &  Xcompl,
gcomplex< cell, euclidom > &  Acompl,
int  minlevel,
bool  bothsets,
const char *  Xname,
const char *  Aname 
)

Adds boundaries to the geometric complex X or to both X and A.

Definition at line 836 of file homtools.h.

References sout.

Referenced by chomp::homology::gcomplex< cell, euclidom >::addboundaries(), createcellmap(), creategraph(), decreasedimension(), Homology(), Homology2l(), and remainsacyclic().

{
        // if there are no cells in the complex, there is nothing to do
        if (Xcompl. empty ())
                return;

        // say what you are doing
        sout << "Adding boundaries of " << cell::pluralname () << " in ";
        if (!Acompl. empty ())
                sout << Xname << " and " << Aname << "... ";
        else
                sout << Xname << "... ";

        // add the boundaries and count the number of added cells
        int_t howmany = 0;
        for (int i = Xcompl. dim (); (i >= minlevel) && i; -- i)
        {
                if (bothsets)
                {
                        howmany += Xcompl. addboundaries (i, true);
                        if (Acompl. dim () >= i)
                                howmany += Acompl. addboundaries (i,
                                        true);
                }
                else
                        howmany += Xcompl. addboundaries (i, Acompl);
        }

        // show the total number of added cells
        sout << howmany << ' ' << cell::pluralname () << " added.\n";
        return;
} /* addboundaries */

template<class tCube , class tCubeSet >
void chomp::homology::addcubeneighbors ( const tCube &  q,
int  dim,
const tCubeSet &  cubset,
bitfield *  b,
hashedset< tCube > &  neighbors,
hashedset< tCube > &  queue,
const hashedset< tCube > &  notthese 
) [inline]

A small helper function which adds neighbors of the given cube to the given set.

All the neighbors of 'q' which appear in 'cubset' are added to the set 'neighbors' using the 'getneighbors' function if BDDs are in use. Otherwise, it is assumed that all the neighbors of 'q' are already in the set 'neighbors'. Then all the neighbors which are not in the 'notthese' set are added to the queue.

Definition at line 357 of file cubisets.h.

References getneighbors(), and MaxBddDim.

Referenced by cubreducequiet().

{
        // determine the neighbors of this cube (if not done yet)
        if (dim <= MaxBddDim)
                getneighbors (q, b, cubset, &neighbors, 0);

        // add the computed neighbors of this cube to the queue
        for (int_t j = 0; j < neighbors. size (); ++ j)
        {
                if (!notthese. check (neighbors [j]))
                        queue. add (neighbors [j]);
        }

        return;
} /* addcubeneighbors */

template<class maptype , class cubsettype >
void chomp::homology::addmapimg ( const maptype &  Fcubmap,
const cubsettype &  Xcubes,
const cubsettype &  Acubes,
cubsettype &  Ykeepcubes,
bool  indexmap 
) [inline]

Adds the image of the given map to the set of cubes to be kept.

Includes the sets 'Xcubes' and 'Acubes' if this is an index map.

Definition at line 707 of file homtools.h.

References addmapimg().

{
        addmapimg (Fcubmap, Fcubmap, Xcubes, Acubes, Ykeepcubes, indexmap);
        return;
} /* addmapimg */

template<class maptype , class cubsettype >
void chomp::homology::addmapimg ( const maptype &  Fcubmap,
const maptype &  FcubmapA,
const cubsettype &  Xcubes,
const cubsettype &  Acubes,
cubsettype &  Ykeepcubes,
bool  indexmap 
)

Adds the images of both maps to the set of cubes to be kept.

The image of each set is taken using the corresponding map. Includes the sets 'Xcubes' and 'Acubes' if this is an index map.

Definition at line 659 of file homtools.h.

References retrieveimage(), and sout.

Referenced by addmapimg(), and Homology2l().

{
        if (Fcubmap. getdomain (). empty () &&
                FcubmapA. getdomain (). empty ())
        {
                return;
        }
        sout << "Computing the image of the map... ";
        int_t prev = Ykeepcubes. size ();
        const cubsettype &Fdomain = Fcubmap. getdomain ();
        if (!Fdomain. empty ())
        {
                if (Fdomain. size () == Xcubes. size ())
                        retrieveimage (Fcubmap, Ykeepcubes);
                else
                {
                        int_t n = Xcubes. size ();
                        for (int_t i = 0; i < n; ++ i)
                                Ykeepcubes. add (Fcubmap (Xcubes [i]));
                }
        }
        const cubsettype &FdomainA = FcubmapA. getdomain ();
        if (!FdomainA. empty ())
        {
                if (FdomainA. size () == Acubes. size ())
                        retrieveimage (FcubmapA, Ykeepcubes);
                else
                {
                        int_t n = Acubes. size ();
                        for (int_t i = 0; i < n; ++ i)
                                Ykeepcubes. add (FcubmapA (Acubes [i]));
                }
        }
        if (indexmap)
        {
                sout << "and of the inclusion... ";
                Ykeepcubes. add (Xcubes);
                Ykeepcubes. add (Acubes);
        }
        sout << (Ykeepcubes. size () - prev) << " cubes.\n";
        return;
} /* addmapimg */

template<class tCube , class tCubeSet >
int_t chomp::homology::addneighbors ( const tCube &  q,
const BitField &  bits,
tCubeSet &  set,
const tCubeSet &  notthese 
)

Adds neighbors listed in the given bit field to the set of cubes unless they are in the 'forbidden' set.

Returns the number of added neighbors.

Definition at line 343 of file neighbor.h.

References bit2neighbor(), and getmaxneighbors().

{
        int_t maxneighbors = getmaxneighbors (q. dim ());

        int_t count = 0;
        int_t number = bits. find (0, maxneighbors);
        while (number >= 0)
        {
                tCube neighbor = bit2neighbor (q, number);
                if (!notthese. check (neighbor))
                        set. add (neighbor);
                number = bits. find (number + 1, maxneighbors);
                ++ count;
        }

        return count;
} /* addneighbors */

template<class tCube , class tCubeSet >
int_t chomp::homology::addneighbors ( const tCube &  q,
const BitField &  bits,
tCubeSet &  set,
bool  unconditional = false 
)

Adds neighbors listed in the given bit field to the set of cubes.

If not 'unconditional', then adds only cubes which already exist.

Definition at line 365 of file neighbor.h.

References bit2neighbor(), and getmaxneighbors().

{
        int_t maxneighbors = getmaxneighbors (q. dim ());
        int_t count = 0;

        int_t number = bits. find (0, maxneighbors);
        while (number >= 0)
        {
                tCube neighbor = bit2neighbor (q, number, unconditional);
                set. add (neighbor);
                number = bits. find (number + 1, maxneighbors);
                ++ count;
        }

        return count;
} /* addneighbors */

template<class SetT , class QueueT >
void chomp::homology::addneighbors ( const int &  c,
const SetT &  s,
QueueT &  q 
)

Adds the neighbors of the cube 'c' in the set 's' to the set 'q'.

Definition at line 1039 of file bincube.h.

Referenced by acyclic(), reduceFullCubesAlg(), and remainsacyclic().

{
        typename SetT::neighborhood_iterator cur = s. neighborhood_begin (c),
                end = s. neighborhood_end (c);
        while (cur != end)
        {
                q. add (hashNumber<int> (cur));
                ++ cur;
        }
        return;
} /* addneighbors */

template<class tCube , class tCell >
int_t chomp::homology::addneighbors ( const tCube &  q,
const BitField &  bits,
gcomplex< tCell, integer > &  c,
bool  unconditional = false 
)

Adds intersections of neighbors listed in the given bit field with the given cube to the cubical complex.

If not 'unconditional', then adds only cubes which already exist.

Definition at line 387 of file neighbor.h.

References getmaxneighbors().

{
        // define the type of coordinates
        typedef typename tCube::CoordType coordType;

        // determine the space dimension
        int dim = q. dim ();

        // compute the maximal number of neighbors
        int_t maxneighbors = getmaxneighbors (dim);

        // extract the coordinates of the central cube
        coordType coord [tCube::MaxDim];
        q. coord (coord);

        // prepare arrays for the coordinates of boundary cells
        coordType cLeft [tCube::MaxDim];
        coordType cRight [tCube::MaxDim];

        // prepare a counter of boundary cells
        int_t count = 0;

        // find the first neighbor number
        int_t number = bits. find (0, maxneighbors);

        // process all the neighbor numbers
        while (number >= 0)
        {
                // prepare the coordinates of the boundary cell
                int_t n = number + 1;
                for (int i = dim - 1; i >= 0; -- i)
                {
                        switch (n % 3)
                        {
                                case 2:
                                        cLeft [i] = coord [i];
                                        cRight [i] = coord [i];
                                        break;
                                case 1:
                                        cLeft [i] = coord [i] + 1;
                                        cRight [i] = coord [i] + 1;
                                        break;
                                case 0:
                                        cLeft [i] = coord [i];
                                        cRight [i] = coord [i] + 1;
                                        break;
                        }
                        n /= 3;
                }

                // add the cell to the complex of boundary cells
                c. add (tCell (cLeft, cRight, dim));

                // increase the counter of boundary cells
                ++ count;

                // take the next neighbor number
                number = bits. find (number + 1, maxneighbors);
        }

        return count;
} /* addneighbors */

template<class wType >
int_t chomp::homology::addRenumEdges ( const diGraph< wType > &  g,
int_t  vertex,
const int_t newNum,
int_t  cur,
int_t srcVert,
diGraph< wType > &  result 
) [inline]

A helper function for "collapseVertices".

Definition at line 3012 of file digraph.h.

Referenced by collapseVertices().

{
        int_t nEdges = g. countEdges (vertex);
        // add all the edges that start at the component
        for (int_t edge = 0; edge < nEdges; ++ edge)
        {
                // determine the dest. vertex of the edge
                int_t dest = newNum [g. getEdge (vertex, edge)];
                // if this is an edge to self, then ignore it
                if (dest == cur)
                        continue;
                // if the edge has already been added,
                // then skip it
                if (srcVert [dest] == cur)
                        continue;
                // remember that the dest. vertex has an edge
                // pointing out from the current vertex
                srcVert [dest] = cur;
                // add the edge to the result graph
                result. addEdge (dest);
        }
        return 0;
} /* addRenumEdges */

template<class wType , class TabSets >
int_t chomp::homology::addRenumEdges2 ( const diGraph< wType > &  g,
int_t  vertex,
const int_t newNum,
TabSets &  numSets,
int_t  cur,
int_t srcVert,
diGraph< wType > &  result 
) [inline]

A helper function for "collapseVertices2".

Definition at line 3127 of file digraph.h.

Referenced by collapseVertices2().

{
        int_t nEdges = g. countEdges (vertex);

        // add all the edges that start at this vertex
        for (int_t edge = 0; edge < nEdges; ++ edge)
        {
                // determine the dest. vertex of the edge
                int_t destNumber = newNum [g. getEdge (vertex, edge)];

                // consider all the destination vertices
                int_t destSize = (destNumber < 0) ?
                        numSets [-destNumber]. size () :
                        static_cast<int_t> (1);
                for (int_t i = 0; i < destSize; ++ i)
                {
                        // determine the consecutive destination vertex
                        int_t dest = (destNumber < 0) ?
                                numSets [-destNumber] [i] : destNumber;

                        // if this is an edge to self, then ignore it
                        if (dest == cur)
                                continue;

                        // if the edge has already been added,
                        // then skip it
                        if (srcVert [dest] == cur)
                                continue;

                        // add the edge to the result graph
                        result. addEdge (dest);
                }
        }
        return 0;
} /* addRenumEdges2 */

template<class coordtype >
coordtype* chomp::homology::allocatepoint ( int  dim,
char *  errormessage = NULL 
) [inline]

Allocate a point with 'new'. In case of failure throw an error message.

Definition at line 248 of file pointset.h.

{
        coordtype *temp = new coordtype [dim];
        if (!temp)
        {
                throw (errormessage ? errormessage :
                        "Can't allocate memory for a temporary point.");
        }
        return temp;
} /* allocatepoint */

template<class type >
void chomp::homology::arg ( arguments &  a,
const char *  name,
type &  value 
) [inline]

Adds a command line argument.

The actual argument name consists of the dash and its name provided to the function. If name == 0, then the value of this argument is read directly from the command line without any preceding string. The value variable is filled in by the value read from the command line string using the operator >>.

Definition at line 605 of file arg.h.

Referenced by argstreams(), and chomp::multiwork::mwSubdivMain().

{
        argunit<type> *p = new argunit<type> (name, value);
        a. add (p);
        return;
} /* arg */

template<class type >
void chomp::homology::arg ( arguments &  a,
const char *  name,
type &  value,
type  defaultvalue 
) [inline]

Adds a command line argument with a default value.

The name must be nonempty. If the name of the argument appears but its value is not specified, then the default value is used instead.

Definition at line 616 of file arg.h.

{
        argunit<type> *p = new argunit<type> (name, value, defaultvalue);
        a. add (p);
        return;
} /* arg */

void chomp::homology::arg ( arguments &  a,
const char *  name,
char *&  value,
const char *  defaultvalue 
) [inline]

A specialization of the above for C-style strings.

Definition at line 625 of file arg.h.

{
        argunit<char *> *p =
                new argunit<char *> (name, value,
                        const_cast<char *> (defaultvalue));
        a. add (p);
        return;
} /* arg */

template<class type >
void chomp::homology::arg ( arguments &  a,
const char *  name,
type *  value,
int &  count,
int  size 
) [inline]

Adds a command line argument whose repeated occurrences fill in consecutive elements of the given array.

The counter indicates the position in the array. The given size of the array will not be exceeded.

Definition at line 640 of file arg.h.

{
        argunit<type> *p = new argunit<type> (name, value, count, size);
        a. add (p);
        return;
} /* arg */

template<class type >
void chomp::homology::arg ( arguments &  a,
const char *  name,
type *  value,
int &  count,
int  size,
type  defaultvalue 
) [inline]

A version of the above with a default value of the arguments.

Definition at line 650 of file arg.h.

{
        argunit<type> *p = new argunit<type> (name, value, count, size,
                defaultvalue);
        a. add (p);
        return;
} /* argoblig */

void chomp::homology::argbreak ( arguments &  arg,
const char *  name 
) [inline]

A version of the above which ignores the value of the argument.

Definition at line 732 of file arg.h.

{
        char *dummystring = NULL;
        argunit<char *> *p = new argunit<char *> (name, dummystring);
        p -> set (argflags::breakinterpreting);
        p -> set (argflags::ignorevalue);
        arg. add (p);
        return;
} /* argbreak */

template<class type >
void chomp::homology::argbreak ( arguments &  arg,
const char *  name,
type &  value 
) [inline]

Adds an argument whose appearence interrupts the analysis of the command line and makes the analyzing function return the value of 1.

This is useful for arguments whose appearence should make the program ignore all the remaining arguments, e.g., to display help information.

Definition at line 698 of file arg.h.

Referenced by arghelp().

{
        argunit<type> *p = new argunit<type> (name, value);
        p -> set (argflags::breakinterpreting);
        p -> set (argflags::ignorevalue);
        arg. add (p);
        return;
} /* argbreak */

template<class type >
void chomp::homology::argbreak ( arguments &  arg,
const char *  name,
type &  value,
type  defaultvalue 
) [inline]

A version of the above with the default value provided.

Definition at line 709 of file arg.h.

{
        argunit<type> *p = new argunit<type> (name, value, defaultvalue);
        p -> set (argflags::breakinterpreting);
        p -> set (argflags::ignorevalue);
        arg. add (p);
        return;
} /* argbreak */

void chomp::homology::argbreak ( arguments &  arg,
const char *  name,
char *&  value,
const char *  defaultvalue 
) [inline]

A version of the above for the C-style string.

Definition at line 720 of file arg.h.

{
        argunit<char *> *p =
                new argunit<char *> (name, value, (char *) defaultvalue);
        p -> set (argflags::breakinterpreting);
        p -> set (argflags::ignorevalue);
        arg. add (p);
        return;
} /* argbreak */

void chomp::homology::arghelp ( arguments &  a  )  [inline]

Adds the typical arguments which should make the program display help information.

If help is requested, the command line analysis is interrupted, and the procedure returns the value 1.

Definition at line 779 of file arg.h.

References argbreak().

Referenced by chomp::multiwork::mwSubdivMain().

{
        argbreak (a, "?");
        argbreak (a, "h");
        argbreak (a, "H");
        argbreak (a, "-help");
        return;
} /* arghelp */

template<class type >
void chomp::homology::argoblig ( arguments &  arg,
const char *  name,
type &  value 
) [inline]

Defines an obligatory command line argument.

If this argument does not appear, then an error is displayed and error code is returned by the analysis procedure.

Definition at line 663 of file arg.h.

{
        argunit<type> *p = new argunit<type> (name, value);
        p -> set (argflags::obligatory);
        arg. add (p);
        return;
} /* argoblig */

template<class type >
void chomp::homology::argoblig ( arguments &  arg,
const char *  name,
type &  value,
type  defaultvalue 
) [inline]

A version of the above with the default value provided.

Definition at line 673 of file arg.h.

{
        argunit<type> *p = new argunit<type> (name, value, defaultvalue);
        p -> set (argflags::obligatory);
        arg. add (p);
        return;
} /* argoblig */

void chomp::homology::argoblig ( arguments &  arg,
const char *  name,
char *&  value,
const char *  defaultvalue 
) [inline]

A version of the above for reading an array of argument values.

Definition at line 683 of file arg.h.

{
        argunit<char *> *p =
                new argunit<char *> (name, value, (char *) defaultvalue);
        p -> set (argflags::obligatory);
        arg. add (p);
        return;
} /* argoblig */

void chomp::homology::argstreams ( arguments &  a,
char *&  logfilename,
char *&  seqfilename,
bool &  quiet,
bool &  debug 
) [inline]

Adds typical command line arguments for manipulating output streams.

This is an internal function used by the macro "algstreamprepare".

Definition at line 794 of file arg.h.

References arg(), and argswitch().

{
        arg (a, "-log", logfilename);
        arg (a, "-seq", seqfilename);
        argswitch (a, "-quiet", quiet, true);
        argswitch (a, "-debug", debug, true);
        return;
} /* argstreams */

void chomp::homology::argswitch ( arguments &  arg,
const char *  name 
) [inline]

Defines an ignored switch (no value is set when this argument appears).

Definition at line 767 of file arg.h.

{
        char *dummystring = NULL;
        argunit<char *> *p = new argunit<char *> (name, dummystring);
        p -> set (argflags::ignorevalue);
        arg. add (p);
        return;
} /* argswitch */

void chomp::homology::argswitch ( arguments &  arg,
const char *  name,
char *&  value,
const char *  defaultvalue 
) [inline]

A version of the above for the C-style string.

Definition at line 756 of file arg.h.

{
        argunit<char *> *p =
                new argunit<char *> (name, value, (char *) defaultvalue);
        p -> set (argflags::ignorevalue);
        arg. add (p);
        return;
} /* argswitch */

template<class type >
void chomp::homology::argswitch ( arguments &  arg,
const char *  name,
type &  value,
const type &  defaultvalue 
) [inline]

Defines a command line argument which is a switch, that is, there is no value given for it in the command line.

The appearence of this argument sets the predefined default value to the given variable.

Definition at line 746 of file arg.h.

Referenced by argstreams(), and chomp::multiwork::mwSubdivMain().

{
        argunit<type> *p = new argunit<type> (name, value, defaultvalue);
        p -> set (argflags::ignorevalue);
        arg. add (p);
        return;
} /* argswitch */

template<class coordtype >
int chomp::homology::attheborder ( const tPointset< coordtype > &  p,
const coordtype *  c 
)

Verifies if the point is at the border of a given set.

Definition at line 1806 of file pointset.h.

References countneighbors(), and OUTSIDE.

Referenced by computeboundary(), and findboundarypoint().

{
        return (countneighbors (p, c, OUTSIDE, 1));

} /* attheborder */

template<class tCube , class tCubeSet >
bool chomp::homology::bddacyclic ( const tCube &  q,
int  dim,
const tCubeSet &  s,
BitField &  b 
)

Uses binary decision diagrams to verify whether the neighborhood of the given cube in the given set is acyclic.

Uses the bitfield provided to record each tested neighbor in. Verifies whether the neighborhood of the given cube is acyclic or not using the code generated from binary decision diagrams.

Definition at line 1199 of file cubacycl.h.

References acyclic1d(), acyclic2d(), acyclic3d(), acyclic3d_Malandain(), and UseMalandainCode.

Referenced by acyclic(), and acyclic_rel().

{
        switch (dim)
        {
        case 1:
        {
                Neighbors<tCube,tCubeSet> n (q, s, b);
                return acyclic1d (n);
        //      break;
        }
        case 2:
        {
                Neighbors<tCube,tCubeSet> n (q, s, b);
                return acyclic2d (n);
        //      break;
        }
        case 3:
        {
                Neighbors<tCube,tCubeSet> n (q, s, b);
                if (UseMalandainCode)
                        return acyclic3d_Malandain (n);
                else
                        return acyclic3d (n);
        //      break;
        }
        }
        throw "Trying to use a BDD for dimension other than 1-3.";
} /* bddacyclic */

template<class euclidom >
int chomp::homology::BettiNumber ( const chain< euclidom > &  c  ) 

Returns the Betti number that corresponds to the given chain which describes one homology group.

Definition at line 105 of file homology.h.

Referenced by ComputeBettiNumbers().

{
        int betti = 0;
        for (int i = 0; i < c. size (); ++ i)
        {
                if (c. coef (i). delta () == 1)
                        ++ betti;
        }
        return betti;
} /* BettiNumber */

template<class tCube >
tCube2l<tCube> chomp::homology::bit2neighbor ( const tCube2l< tCube > &  q,
int_t  number,
bool  unconditional = false 
) [inline]

Specialization of the "bit2neighbor" function for two-layer cubes.

Throws an exception, because there might be more than one neighbor in the given direction.

Definition at line 922 of file twolayer.h.

{
        throw "Trying to use 'bit2neighbor' for a 2-layer cube.";
        return q;
} /* bit2neighbor */

template<class tCube >
tCube chomp::homology::bit2neighbor ( const tCube &  q,
int_t  number,
bool  unconditional = false 
)

Creates the neighbor of the given cube with the specified number.

If the coordinates of the neighbor do not belong to 'PointBase', then returns 'q', unless 'unconditional' is set to true.

Definition at line 166 of file neighbor.h.

Referenced by addneighbors(), chomp::homology::Neighbors< cubetype, settype >::check(), and getneighbors_generate().

{
        // define the type of coordinates
        typedef typename tCube::CoordType coordType;

        coordType c0 [tCube::MaxDim];
        q. coord (c0);
        coordType c1 [tCube::MaxDim];
        int dim = q. dim ();

        ++ number;
        for (int i = dim - 1; i >= 0; -- i)
        {
                switch (number % 3)
                {
                        case 2:
                                c1 [i] = c0 [i] - 1;
                                break;
                        case 1:
                                c1 [i] = c0 [i] + 1;
                                break;
                        case 0:
                                c1 [i] = c0 [i];
                                break;
                        default:
                                throw "Erratic neighbor.";
                }
                number /= 3;
        }

        if (unconditional || tCube::PointBase::check (c1, dim))
                return tCube (c1, dim);
        else
                return q;
} /* bit2neighbor */

template<class settype >
settype::iterator chomp::homology::bit2neighborAlg ( const typename settype::iterator &  q,
int  n 
)

Definition at line 693 of file bincube.h.

References bit2neighborAlg(), chomp::homology::bincube< Dim, twoPower >::coord2num(), and chomp::homology::bincube< Dim, twoPower >::num2coord().

{
        const int Dim = settype::MaxDim;
        int coord [Dim];
        q. b -> num2coord (q, coord);
        bit2neighborAlg (n, coord, coord, Dim);
        try
        {
                return typename settype::iterator (q. b,
                        q. b -> coord2num (coord));
        }
        catch (...)
        {
        }
        return q;
} /* bit2neighborAlg */

template<class coordinate >
void chomp::homology::bit2neighborAlg ( int  number,
const coordinate *  src,
coordinate *  dest,
int  Dim 
) [inline]

Definition at line 665 of file bincube.h.

Referenced by bit2neighborAlg(), and chomp::homology::bincube< Dim, twoPower >::neighborhood_iterator::operator++().

{
        ++ number;
        for (int i = Dim - 1; i >= 0; -- i)
        {
                dest [i] = src [i];
                switch (number % 3)
                {
                        case 2:
                                -- (dest [i]);
                                break;
                        case 1:
                                ++ (dest [i]);
                                break;
                        case 0:
                                break;
                        default:
                                throw "Erratic neighbor.";
                }
                number /= 3;
        }

        return;
} /* bit2neighborAlg */

int chomp::homology::bitcount ( int  number  )  [inline]

Definition at line 49 of file bitcount.h.

References bitcountbyte().

{
        if (!number)
                return 0;
        unsigned int n = static_cast<unsigned int> (number);
        if (n < 256)
                return bitcountbyte (static_cast<unsigned char> (n));
        int c = 0;
        while (n > 255)
        {
                if (n & 1)
                        ++ c;
                n >>= 1;
        }
        return c + bitcountbyte (static_cast<unsigned char> (n));
} /* bitcount */

int chomp::homology::bitcountbyte ( char  n  )  [inline]

Definition at line 44 of file bitcount.h.

References bitcounttable.

Referenced by bitcount(), and chomp::homology::bincube< Dim, twoPower >::count().

{
        return bitcounttable [static_cast<unsigned char> (n)];
} /* bitcountbyte */

int chomp::homology::bits2int ( const BitField &  field,
int_t  length 
) [inline]

The length must not exceed the size of the integer.

Definition at line 214 of file bitfield.h.

Referenced by acyclic().

{
        const unsigned char *tab = field. table;
        if (!tab)
                throw "Trying to set values to an undefined bitfield.";
        int n = 0;
        int shiftvalue = 0;
        while (length >= 8)
        {
                n |= (*(tab ++)) << shiftvalue;
                length -= 8;
                shiftvalue += 8;
        }
        const int bitmasks [] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
        if (length > 0)
                n |= ((*(tab ++)) & bitmasks [length]) << shiftvalue;
        return n;
} /* bits2int */

template<class tCell >
tCell2l<tCell> chomp::homology::boundarycell ( const tCell2l< tCell > &  q,
int  i,
bool  onlyexisting 
) [inline]

Computes the given boundary element of a cell.

If only existing cells are considered and the requested cell doesn't exist, returns '*this'.

Definition at line 878 of file twolayer.h.

References CubicalBoundaryCell().

{
        tCell c = CubicalBoundaryCell (q. cell (), i, onlyexisting);
        if (c == q. cell ())
                return q;
        typename tCell2l<tCell>::LayerType l
                (tCell2l<tCell>::droplayer (c, q. layer ()));
        return tCell2l<tCell> (c, l);
} /* boundarycell */

Simplex chomp::homology::boundarycell ( const Simplex &  s,
int  i 
) [inline]

Returns the i-th boundary face of a simplex.

Definition at line 338 of file simplex.h.

{
        return Simplex (s, i);
} /* boundarycell */

Simplex chomp::homology::boundarycell ( const Simplex &  s,
int  i,
bool   
) [inline]

Returns the i-th boundary face of a simplex.

Definition at line 344 of file simplex.h.

References boundarycell().

{
        return boundarycell (s, i);
} /* boundarycell */

template<class tCell >
tCell2l<tCell> chomp::homology::boundarycell ( const tCell2l< tCell > &  q,
int  i 
) [inline]

Computes the given boundary element of a cell.

Definition at line 891 of file twolayer.h.

References CubicalBoundaryCell().

{
        tCell c = CubicalBoundaryCell (q. cell (), i);
        typename tCell2l<tCell>::LayerType l
                (tCell2l<tCell>::droplayer (c, q. layer ()));
        return tCell2l<tCell> (c, l);
} /* boundarycell */

template<class coordtype >
tCellBase<coordtype> chomp::homology::boundarycell ( const tCellBase< coordtype > &  q,
int  i,
bool  onlyexisting 
) [inline]

Computes the i-th boundary element of a cell.

If only existing cells are considered, returns '*this' if the requested boundary cell doesn't exist.

Definition at line 474 of file cellbase.h.

References CubicalBoundaryCell().

Referenced by chomp::homology::gcomplex< cell, euclidom >::addboundaries(), boundarycell(), chomp::homology::gcomplex< cell, euclidom >::collapse(), createchaincomplex(), intersection2l(), chomp::homology::tCube2l< tCube >::setlayers(), and writechaincomplex().

{
        return CubicalBoundaryCell (q, i, onlyexisting);
} /* boundarycell */

template<class coordtype >
tCellBase<coordtype> chomp::homology::boundarycell ( const tCellBase< coordtype > &  q,
int  i 
) [inline]

Computes the i-th boundary element of a cell.

Definition at line 482 of file cellbase.h.

References CubicalBoundaryCell().

{
        return CubicalBoundaryCell (q, i);
} /* boundarycell */

template<class coordtype >
tCellVar<coordtype> chomp::homology::boundarycell ( const tCellVar< coordtype > &  q,
int  i,
bool  onlyexisting 
) [inline]

Computes the i-th boundary element of a cell.

Definition at line 546 of file cellvar.h.

References CubicalBoundaryCell().

{
        return CubicalBoundaryCell (q, i, onlyexisting);
} /* boundarycell */

template<class coordtype >
tCellVar<coordtype> chomp::homology::boundarycell ( const tCellVar< coordtype > &  q,
int  i 
) [inline]

Computes the i-th boundary element of a cell.

Definition at line 554 of file cellvar.h.

References CubicalBoundaryCell().

{
        return CubicalBoundaryCell (q, i);
} /* boundarycell */

template<class cell >
cell chomp::homology::boundarycell ( const cell &  ,
int  i 
)
template<int dimfix, class coordtype >
tCellFix<dimfix,coordtype> chomp::homology::boundarycell ( const tCellFix< dimfix, coordtype > &  q,
int  i 
) [inline]

Computes the i-th boundary element of a cell.

Definition at line 494 of file cellfix.h.

References CubicalBoundaryCell().

{
        return CubicalBoundaryCell (q, i);
} /* boundarycell */

template<int dimfix, class coordtype >
tCellFix<dimfix,coordtype> chomp::homology::boundarycell ( const tCellFix< dimfix, coordtype > &  q,
int  i,
bool  onlyexisting 
) [inline]

Computes the i-th boundary element of a cell.

Definition at line 486 of file cellfix.h.

References CubicalBoundaryCell().

{
        return CubicalBoundaryCell (q, i, onlyexisting);
} /* boundarycell */

int chomp::homology::boundarycoef ( const Simplex &  ,
int  i 
) [inline]

Returns the i-th coefficient in the boundary of a simplex.

Definition at line 329 of file simplex.h.

{
        if (i & 1)
                return -1;
        else
                return 1;
} /* boundarycoef */

template<class tCell >
int chomp::homology::boundarycoef ( const tCell2l< tCell > &  q,
int  i 
) [inline]

Returns the given coefficient in the boundary of a cell.

Definition at line 908 of file twolayer.h.

References CubicalBoundaryCoef().

{
        return CubicalBoundaryCoef (q. cell (), i);
} /* boundarycoef */

template<class coordtype >
int chomp::homology::boundarycoef ( const tCellBase< coordtype > &  q,
int  i 
) [inline]

Returns the i-th coefficient in the boundary of a cell.

Definition at line 497 of file cellbase.h.

References CubicalBoundaryCoef().

Referenced by chomp::homology::gcomplex< cell, euclidom >::addboundaries(), createchaincomplex(), and writechaincomplex().

{
        return CubicalBoundaryCoef (q, i);
} /* boundarycoef */

template<class cell >
int chomp::homology::boundarycoef ( const cell &  ,
int  i 
)
template<class coordtype >
int chomp::homology::boundarycoef ( const tCellVar< coordtype > &  q,
int  i 
) [inline]

Returns the i-th coefficient in the boundary of a cell.

Definition at line 569 of file cellvar.h.

References CubicalBoundaryCoef().

{
        return CubicalBoundaryCoef (q, i);
} /* boundarycoef */

template<int dimfix, class coordtype >
int chomp::homology::boundarycoef ( const tCellFix< dimfix, coordtype > &  q,
int  i 
) [inline]

Returns the i-th coefficient in the boundary of a cell.

Definition at line 508 of file cellfix.h.

References CubicalBoundaryCoef().

{
        return CubicalBoundaryCoef (q, i);
} /* boundarycoef */

int chomp::homology::boundarylength ( const Simplex &  s  )  [inline]

Returns the length of the boundary of a simplex.

Definition at line 322 of file simplex.h.

{
        int d = s. dim ();
        return (d ? (d + 1) : 0);
} /* boundarylength */

template<class tCell >
int chomp::homology::boundarylength ( const tCell2l< tCell > &  q  )  [inline]

Returns the length of the boundary of a cell.

Definition at line 901 of file twolayer.h.

References CubicalBoundaryLength().

{
        return CubicalBoundaryLength (q. cell ());
} /* boundarylength */

template<class coordtype >
int chomp::homology::boundarylength ( const tCellBase< coordtype > &  q  )  [inline]
template<class coordtype >
int chomp::homology::boundarylength ( const tCellVar< coordtype > &  q  )  [inline]

Returns the length of the boundary of a cell.

Definition at line 562 of file cellvar.h.

References CubicalBoundaryLength().

{
        return CubicalBoundaryLength (q);
} /* boundarylength */

template<class cell >
int chomp::homology::boundarylength ( const cell &   ) 
template<int dimfix, class coordtype >
int chomp::homology::boundarylength ( const tCellFix< dimfix, coordtype > &  q  )  [inline]

Returns the length of the boundary of a cell.

Definition at line 501 of file cellfix.h.

References CubicalBoundaryLength().

{
        return CubicalBoundaryLength (q);
} /* boundarylength */

unsigned chomp::homology::ceilprimenumber ( unsigned  n  )  [inline]

Computes the smallest prime number greater than or equal to the given number.

Returns the computed prime number.

Definition at line 156 of file pointset.h.

References numberisprime().

Referenced by chomp::homology::tPointset< coordtype >::rehash().

{
        while (!numberisprime (n))
                ++ n;

        return n;
} /* prime number */

template<class tCell , class tCube , class tCoef >
bool chomp::homology::checkacyclicmap ( const mvcellmap< tCell, tCoef, tCube > &  Fcellcubmap,
const char *  Xname 
)

Checks if the image of each element of the domain of this map is acyclic.

Shows messages and a warning if necessary. Returns true = yes.

Definition at line 455 of file homtools.h.

References acyclic(), scon, and sout.

{
        sout << "Verifying if the map on " << Xname << " is acyclic... ";

        // retrieve the domain cell complex and analyze each dimension
        const gcomplex<tCell,tCoef> &dom = Fcellcubmap. getdomain ();
        int_t counter = 0;
        bool failed = false;
        for (int_t d = 0; !failed && (d <= dom. dim ()); ++ d)
        {
                // retrieve the set of cells in this dimension and analyze it
                const hashedset<tCell> &qset = dom [d];
                for (int_t i = 0; !failed && (i < qset. size ()); ++ i)
                {
                        // show progress indicator
                        if (counter && !(counter % 373))
                                scon << std::setw (10) << counter <<
                                        "\b\b\b\b\b\b\b\b\b\b";
                        ++ counter;

                        // reduce the image of this cell
                        const hashedset<tCube> &img = Fcellcubmap (qset [i]);
                        if (img. size () == 1)
                                continue;

                        // if could not be reduced, compute the homology
                        if (!acyclic (img))
                                failed = true;
                }
        }
        if (failed)
                sout << "Failed.\n*** WARNING: The map on " << Xname <<
                        " is NOT acyclic. ***\n"
                        "*** The result of the computations "
                        "may be totally wrong. ***\n";
        else
                sout << "Passed.         \n";
        return !failed;
} /* checkacyclicmap */

template<class maptype , class cubsettype >
bool chomp::homology::checkimagecontained ( const maptype &  Fcubmap,
const cubsettype &  Xcubes,
const cubsettype &  Ycubes,
const cubsettype &  Bcubes,
const char *  Xname,
const char *  Yname 
)

Checks if the image of X by F is contained in the union of Y and B.

Displays messages and a warning if necessary. Returns true if yes.

Definition at line 385 of file homtools.h.

References sout.

Referenced by checkimagecontained(), Homology(), and Homology2l().

{
        sout << "Verifying if the image of " << Xname <<
                " is contained in " << Yname << "... ";
        bool failed = false;
        for (int_t i = 0; !failed && (i < Xcubes. size ()); ++ i)
        {
                if (!Fcubmap. getdomain (). check (Xcubes [i]))
                        continue;
                const cubsettype &cset = Fcubmap (Xcubes [i]);
                for (int_t j = 0; !failed && (j < cset. size ()); ++ j)
                {
                        if (!Ycubes. check (cset [j]) &&
                                !Bcubes. check (cset [j]))
                        {
                                failed = true;
                        }
                }
        }
        if (failed)
                sout << "Failed.\nWARNING: The image of " << Xname <<
                        " is NOT contained in " << Yname << ".\n";
        else
                sout << "Passed.\n";
        return !failed;
} /* checkimagecontained */

template<class maptype , class cubsettype >
bool chomp::homology::checkimagecontained ( const maptype &  Fcubmap,
const cubsettype &  Xcubes,
const cubsettype &  Ycubes,
const char *  Xname,
const char *  Yname 
) [inline]

Checks if the image of X by F is contained in the set Y alone.

Displays messages and a warning if necessary. Returns true if yes.

Definition at line 417 of file homtools.h.

References checkimagecontained().

{
        cubsettype empty;
        return checkimagecontained (Fcubmap, Xcubes, Ycubes, empty,
                Xname, Yname);
} /* checkimagecontained */

template<class maptype , class cubsettype >
bool chomp::homology::checkimagedisjoint ( const maptype &  Fcubmap,
const cubsettype &  Acubes,
const cubsettype &  Ycubes,
const char *  Aname,
const char *  Yname 
)

Checks if the image of A by F is disjoint from Y (actually, from Y\B).

Displays messages and a warning if necessary. Returns true if yes.

Definition at line 429 of file homtools.h.

References sout.

Referenced by Homology(), and Homology2l().

{
        sout << "Verifying if the image of " << Aname <<
                " is disjoint from " << Yname << "... ";
        bool failed = false;
        for (int_t i = 0; !failed && (i < Acubes. size ()); ++ i)
        {
                if (!Fcubmap. getdomain (). check (Acubes [i]))
                        continue;
                const cubsettype &cset = Fcubmap (Acubes [i]);
                for (int_t j = 0; !failed && (j < cset. size ()); ++ j)
                        if (Ycubes. check (cset [j]))
                                failed = true;
        }
        if (failed)
                sout << "Failed.\nSERIOUS WARNING: The image of " << Aname <<
                        " is NOT disjoint from " << Yname << ".\n";
        else
                sout << "Passed.\n";
        return !failed;
} /* checkimagedisjoint */

template<class cubsettype >
bool chomp::homology::checkinclusion ( const cubsettype &  Xcubes,
const cubsettype &  Ycubes,
const char *  Xname,
const char *  Yname 
) [inline]

Checks for the inclusion of X in Y.

Displays messages and a warning if necessary. Returns the result: true = passed.

Definition at line 375 of file homtools.h.

References checkinclusion().

{
        cubsettype empty;
        return checkinclusion (Xcubes, Ycubes, empty, Xname, Yname);
} /* checkinclusion */

template<class cubsettype >
bool chomp::homology::checkinclusion ( const cubsettype &  Xcubes,
const cubsettype &  Ycubes,
const cubsettype &  Bcubes,
const char *  Xname,
const char *  YBname 
)

Checks if X is a subset of the union of Y and B.

Displays messages and a warning if necessary. Returns the result: true = passed.

Definition at line 350 of file homtools.h.

References sout.

Referenced by checkinclusion(), and Homology().

{
        sout << "Verifying if " << Xname << " is contained in " <<
                YBname << "... ";
        bool failed = false;
        for (int_t i = 0; !failed && (i < Xcubes. size ()); ++ i)
        {
                if (!Ycubes. check (Xcubes [i]) &&
                        !Bcubes. check (Xcubes [i]))
                {
                        failed = true;
                }
        }
        if (failed)
                sout << "Failed.\nWARNING: The set " << Xname <<
                        " is NOT contained in " << YBname << ".\n";
        else
                sout << "Passed.\n";
        return !failed;
} /* checkinclusion */

int chomp::homology::closingparenthesis ( int  ch  )  [inline]

Returns the matching closing parenthesis for the given opening one or EOF if none.

Definition at line 387 of file textfile.h.

Referenced by operator>>(), readcubeorcell(), ReadCubicalCell(), ReadCubicalMap(), readimage(), readparenthesis(), readtheset(), scancubes(), and write().

{
        switch (ch)
        {
                case '(':
                        return ')';
                case '{':
                        return '}';
                case '[':
                        return ']';
                case '<':
                        return '>';
                case '/':
                        return '/';
                default:
                        return EOF;
        }
} /* closingparenthesis */

template<class cell , class euclidom >
void chomp::homology::collapse ( gcomplex< cell, euclidom > &  Xcompl,
gcomplex< cell, euclidom > &  Acompl,
const char *  Xname,
const char *  Aname,
bool  addbd = true,
bool  addcob = false,
bool  disjoint = true,
const int *  level = NULL 
) [inline]

Collapses a pair of geometric complexes.

This version does not take any complex to keep.

Definition at line 774 of file homtools.h.

References collapse().

{
        gcomplex<cell,euclidom> empty;
        collapse (Xcompl, Acompl, empty, Xname, Aname,
                addbd, addcob, disjoint, level);
        return;
} /* collapse */

template<class cell , class euclidom >
void chomp::homology::collapse ( gcomplex< cell, euclidom > &  Xcompl,
gcomplex< cell, euclidom > &  Acompl,
gcomplex< cell, euclidom > &  Xkeepcompl,
const char *  Xname,
const char *  Aname,
bool  addbd = true,
bool  addcob = false,
bool  disjoint = true,
const int *  level = NULL 
)

Collapses a pair of geometric complexes.

Definition at line 743 of file homtools.h.

References sout.

Referenced by acyclic(), collapse(), createcellmap(), Homology(), and Homology2l().

{
        // say what you are about to do
        sout << "Collapsing faces in " << Xname;
        if (!Acompl. empty ())
                sout << " and " << Aname;
        sout << "... ";

        // collapse the faces as requested to
        int_t count = Xcompl. collapse (Acompl, Xkeepcompl,
                addbd, addcob, disjoint, level);

        // say something about the result
        sout << (count << 1) << " removed, " <<
                Xcompl. size () << " left.\n";

        // if something remains in A, say it
        if (!Acompl. empty ())
                sout << "There are " << Acompl. size () << " faces "
                        "of dimension up to " << Acompl. dim () <<
                        " left in " << Aname << ".\n";

        return;
} /* collapse */

template<class cell , class euclidom >
void chomp::homology::collapse ( gcomplex< cell, euclidom > &  Xcompl,
const char *  Xname,
bool  addbd = true,
bool  addcob = false,
bool  disjoint = true,
const int *  level = NULL 
) [inline]

Collapses a single geometric complex.

This version does not take any complex to keep.

Definition at line 801 of file homtools.h.

References collapse().

{
        gcomplex<cell,euclidom> empty;
        collapse (Xcompl, empty, empty, Xname, "",
                addbd, addcob, disjoint, level);
        return;
} /* collapse */

template<class cell , class euclidom >
void chomp::homology::collapse ( gcomplex< cell, euclidom > &  Xcompl,
gcomplex< cell, euclidom > &  Xkeepcompl,
const char *  Xname,
bool  addbd = true,
bool  addcob = false,
bool  disjoint = true,
const int *  level = NULL 
) [inline]

Collapses a single geometric complex.

Definition at line 787 of file homtools.h.

References collapse().

{
        gcomplex<cell,euclidom> empty;
        collapse (Xcompl, empty, Xkeepcompl, Xname, "",
                addbd, addcob, disjoint, level);
        return;
} /* collapse */

template<class wType , class Table1 , class Table2 >
int_t chomp::homology::collapseVertices ( const diGraph< wType > &  g,
int_t  compNum,
Table1 &  compVertices,
Table2 &  compEnds,
diGraph< wType > &  result,
int_t newNumbers = 0 
) [inline]

Collapses disjoint subsets of vertices to single vertices and creates a corresponding graph in which the first vertices come from the collapsed ones.

The result graph must be initially empty. Saves translation table from old to new vertex numbers. The table must have sufficient length.

Definition at line 3044 of file digraph.h.

References addRenumEdges().

{
        // do nothing if the input graph is empty
        int_t nVert = g. countVertices ();
        if (!nVert)
                return 0;

        // compute the new numbers of vertices: newNum [i] is the
        // number of vertex 'i' from 'g' in the resulting graph
        int_t *newNum = newNumbers ? newNumbers : new int_t [nVert];
        for (int_t i = 0; i < nVert; ++ i)
                newNum [i] = -1;
        int_t cur = 0; // current vertex number in the new graph
        int_t pos = 0; // position in compVertices
        while (cur < compNum)
        {
                int_t posEnd = compEnds [cur];
                while (pos < posEnd)
                        newNum [compVertices [pos ++]] = cur;
                ++ cur;
        }
        for (int_t i = 0; i < nVert; ++ i)
        {
                if (newNum [i] < 0)
                        newNum [i] = cur ++;
        }

        // prepare a table to mark the most recent source vertex for edges:
        // srcVert [j] contains i if the edge i -> j has just been added
        int_t newVert = nVert - (compNum ? compEnds [compNum - 1] :
                static_cast<int_t> (0)) + compNum;
        // debug:
        if (cur != newVert)
                throw "DEBUG: Wrong numbers.";
        int_t *srcVert = new int_t [newVert];
        for (int_t i = 0; i < newVert; ++ i)
                srcVert [i] = -1;

        // scan the input graph and create the resulting graph: begin with
        // the vertices in the collapsed groups
        cur = 0, pos = 0;
        while (cur < compNum)
        {
                // add a new vertex to the result graph
                result. addVertex ();
                // for all the vertices in this component...
                int_t posEnd = compEnds [cur];
                while (pos < posEnd)
                {
                        // take the next vertex from the component
                        int_t vertex = compVertices [pos ++];
                        // add the appropriate edges to the result graph
                        addRenumEdges (g, vertex, newNum, cur,
                                srcVert, result);
                }
                ++ cur;
        }
        // process the remaining vertices of the graph
        for (int_t vertex = 0; vertex < nVert; ++ vertex)
        {
                // debug
                if (newNum [vertex] > cur)
                        throw "DEBUG: Wrong order.";
                // if the vertex has already been processed, skip it
                if (newNum [vertex] != cur)
                        continue;
                // add the appropriate edges to the result graph
                result. addVertex ();
                addRenumEdges (g, vertex, newNum, cur, srcVert, result);
                ++ cur;
        }

        // free memory and exit
        delete [] srcVert;
        if (!newNumbers)
                delete [] newNum;
        return 0;
} /* collapseVertices */

template<class wType , class Table1 , class Table2 >
int_t chomp::homology::collapseVertices2 ( const diGraph< wType > &  g,
int_t  compNum,
Table1 &  compVertices,
Table2 &  compEnds,
diGraph< wType > &  result 
) [inline]

Collapses (possibly non-disjoint) subsets of vertices to single vertices and creates a corresponding graph in which the first vertices come from the collapsed ones.

The result graph must be initially empty.

Definition at line 3170 of file digraph.h.

References addRenumEdges2().

{
        // do nothing if the input graph is empty
        int_t nVert = g. countVertices ();
        if (!nVert)
                return 0;

        // compute the new numbers of vertices: newNum [i] is the
        // number of vertex 'i' from 'g' in the resulting graph,
        // unless negative; then it points to a set of numbers,
        // with -1 meaning "not defined, yet"
        int_t *newNum = new int_t [nVert];
        for (int_t i = 0; i < nVert; ++ i)
                newNum [i] = -1;

        // sets of numbers of vertices; the numbers refering to the sets
        // begin with 2, thus the first two sets are skipped
        multitable<hashedset<int_t> > numSets;
        // the number of the set waiting to be used next
        int_t numSetCur = 2;

        int_t cur = 0; // current vertex number in the new graph
        int_t pos = 0; // position in compVertices
        while (cur < compNum)
        {
                int_t posEnd = compEnds [cur];
                while (pos < posEnd)
                {
                        int_t number = compVertices [pos ++];
                        if (newNum [number] == -1)
                                newNum [number] = cur;
                        else if (newNum [number] < 0)
                                numSets [-newNum [number]]. add (cur);
                        else
                        {
                                numSets [numSetCur]. add (newNum [number]);
                                numSets [numSetCur]. add (cur);
                                newNum [number] = -(numSetCur ++);
                        }
                }
                ++ cur;
        }
        for (int_t i = 0; i < nVert; ++ i)
        {
                if (newNum [i] == -1)
                        newNum [i] = cur ++;
        }

        // prepare a table to mark the most recent source vertex for edges:
        // srcVert [j] contains i if the edge i -> j has just been added
        int_t newVert = cur;
        int_t *srcVert = new int_t [newVert];
        for (int_t i = 0; i < newVert; ++ i)
                srcVert [i] = -1;

        // scan the input graph and create the resulting graph: begin with
        // the vertices in the collapsed groups
        cur = 0;
        pos = 0;
        while (cur < compNum)
        {
                // add a new vertex to the result graph
                result. addVertex ();

                // for all the vertices in this component...
                int_t posEnd = compEnds [cur];
                while (pos < posEnd)
                {
                        // take the next vertex from the component
                        int_t vertex = compVertices [pos ++];

                        // add the appropriate edges to the result graph
                        addRenumEdges2 (g, vertex, newNum, numSets, cur,
                                srcVert, result);
                }
                ++ cur;
        }

        // process the remaining vertices of the graph
        for (int_t vertex = 0; vertex < nVert; ++ vertex)
        {
                // debug
                if (newNum [vertex] > cur)
                        throw "DEBUG: Wrong order 2.";

                // if the vertex has already been processed, skip it
                if (newNum [vertex] != cur)
                        continue;

                // add the appropriate edges to the result graph
                result. addVertex ();
                addRenumEdges2 (g, vertex, newNum, numSets, cur,
                        srcVert, result);
                ++ cur;
        }

        // free memory and exit
        delete [] srcVert;
        delete [] newNum;
        return 0;
} /* collapseVertices2 */

std::string chomp::homology::commandline ( int  argc,
char *  argv[] 
) [inline]

Returns the entire command line as a single string.

Definition at line 417 of file textfile.h.

{
        std::string s;
        for (int i = 0; i < argc; ++ i)
        {
                if (i)
                        s += ' ';
                s += argv [i];
        }
        return s;
} /* commandline */

template<class coordtype >
int chomp::homology::CommonCell ( coordtype *  left,
coordtype *  right,
const coordtype *  c1,
const coordtype *  c2,
int  spcdim,
const coordtype *  wrap = 0 
) [inline]

Computes the left and right corner of a cell which is the intersection of the two given cubes.

Returns the actual dimension of this cell.

Definition at line 329 of file cellmain.h.

Referenced by chomp::homology::tCellBase< coordtype >::tCellBase(), and chomp::homology::tCellFix< dimfix, coordtype >::tCellFix().

{
        // calculate the coordinates of both vertices of the cubical cell
        // and the dimension of the cubical cell
        int celldim = 0;
        for (int i = 0; i < spcdim; ++ i)
        {
                if (c1 [i] == c2 [i])
                {
                        left [i] = c1 [i];
                        right [i] = c1 [i];
                        ++ (right [i]);
                        ++ celldim;
                }
                else if ((c1 [i] - c2 [i] == -1) || (wrap && wrap [i] &&
                        (c1 [i] - c2 [i] == wrap [i] - 1)))
                {
                        left [i] = c2 [i];
                        right [i] = c2 [i];
                }
                else if ((c1 [i] - c2 [i] == 1) || (wrap && wrap [i] &&
                        (c1 [i] - c2 [i] == -wrap [i] + 1)))
                {
                        left [i] = c1 [i];
                        right [i] = c1 [i];
                }
                else
                        throw "The cubes do not intersect.";
        }

        return celldim;
} /* CommonCell */

template<int dim, int twoPower>
void chomp::homology::ComputeBettiNumbers ( bincube< dim, twoPower > &  b,
int *  result 
)

Computes the Betti Numbers of a set of full cubes in a bincube.

This procedure makes use of the technique of splitting the set of cubes into connected components and computing relative homology of each component with respect to some cube in each of them.

Definition at line 2021 of file homology.h.

References BettiNumber(), Homology(), reduceFullCubes(), ShowHomology(), and sout.

Referenced by ComputeBettiNumbers(), and ComputeBettiNumbers().

{
        using namespace chomp::homology;
        typedef typename bincube<dim,twoPower>::iterator cubetype;
        typedef typename bincube<dim,twoPower>::neighborhood_iterator
                neighbortype;

        // perform the reduction of full cubes in the binary cube first
        sout << "Reducing the binary cube";
        int prev = b. count ();
        reduceFullCubes (b);
        sout << (prev - b. count ()) << " cubes removed, " <<
                b. count () << " left.\n";

        // create an extra binary cube to store connected components
        bincube<dim,twoPower> c;

        // set the correct wrapping for the new binary cube and the space
        coordinate wrap [dim];
        bool setwrapping = false;
        for (int i = 0; i < dim; ++ i)
        {
                if (b. wrapped (i))
                {
                        wrap [i] = 1 << twoPower;
                        setwrapping = true;
                        c. wrap (i);
                }
                else
                        wrap [i] = 0;
        }
        if (setwrapping)
                tPointBase<coordinate>::setwrapping (wrap);

        // reset the table to store Betti numbers
        for (int i = 0; i <= dim; ++ i)
                result [i] = 0;

        // gather Betti numbers for each connected component separately
        bool first_run = true;
        while (!b. empty ())
        {
                // increase the 0th Betti number which counts conn. comp.
                ++ *result;

                // extract a connected component
                if (first_run)
                        first_run = false;
                else
                        c. clear ();
                hashIntQueue s;
                s. push (static_cast<int> (b. begin ()));
                while (!s. empty ())
                {
                        int n = s. front ();
                        s. pop ();
                        neighbortype cur = b. neighborhood_begin (n);
                        neighbortype end = b. neighborhood_end (n);
                        while (cur != end)
                        {
                                s. push (static_cast<int> (cur));
                                ++ cur;
                        }
                        c. add (n);
                        b. remove (n);
                }

                // if the component has just one cube, the answer is obvious
                if (c. count () == 1)
                        continue;

                // transform the binary cube into the usual set of cubes
                // (in the future this step will be postponed)
                SetOfCubes X;
                cubetype cur (c. begin ()), end (c. end ());
                while (cur != end)
                {
                        X. add (cube_cast<Cube> (cur));
                        ++ cur;
                }

                // say which connected component is processed
                sout << "Connected component no. " << *result <<
                        " (" << X. size () << " cubes):\n";

                // prepare a pair of sets for relative homology computation
                SetOfCubes A;
                int_t number = X. size () - 1;
                A. add (X [number]);
                X. removenum (number);
                
                // compute the relative homology
                Chain *chn = 0;
                int maxlevel = Homology (X, "X", A, "A", chn);

                // display the result
                ShowHomology (chn, maxlevel);

                // update the Betti number count
                for (int i = 1; i <= maxlevel; ++ i)
                        result [i] += BettiNumber (chn [i]);

                // release the memory assigned to the table of chains
                if (chn)
                        delete [] chn;
        }
        
        sout << "Computed Betti numbers:";
        for (int i = 0; i <= dim; ++ i)
                sout << " " << result [i];
        sout << ".\n";

        return;
} /* ComputeBettiNumbers */

template<int dim, int twoPower, class coordtype >
void chomp::homology::ComputeBettiNumbers ( char *  binary_buffer,
int *  result,
const coordtype *  space_wrapping = 0 
)

Computes the Betti Numbers of the Homology of a full cubical set defined by means of an n-dimensional bitmap.

The size of this bitmap in each direction must equal 2^n, where n=twoPower. The subsequent bits of the binary buffer correspond to the cubes (0,0,...,0), (1,0,...,0), (2,0,...,0), ..., (2^n-1,0,...,0), then (0,1,0,...,0), (1,1,0,...,0), ..., (2^n-1,1,0,...,0), ..., (2^n-1,...,2^n-1). That is, the first coordinate changes the fastest, the second changes less frequently, and the last one changes the slowest.

Definition at line 2145 of file homology.h.

References ComputeBettiNumbers(), and sout.

{
        using namespace chomp::homology;

        // create a binary cube based on the binary buffer
        bincube<dim,twoPower> b (binary_buffer);
        
        // set the space wrapping if requested to
        if (space_wrapping)
        {
                for (int i = 0; i < dim; ++ i)
                {
                        if (!space_wrapping [i])
                                continue;
                        int w = space_wrapping [i];
                        if (w != (1 << twoPower))
                                sout << "WARNING: Wrapping [" << i <<
                                        "] set to " << (1 << twoPower) <<
                                        ".\n";
                        b. wrap (i);
                }
        }

        ComputeBettiNumbers (b, result);
        return;
} /* ComputeBettiNumbers */

template<class coordtype >
void chomp::homology::ComputeBettiNumbers ( coordtype *  coord,
int  n,
int  dim,
int *  result 
)

Computes the Betti numbers of the given set of full cubes.

Parameters:
coord - a table of coordinates of all the cubes; the i-th coordinate of the k-th cube is stored in coord [dim * k + i]
n - the number of cubes in the table,
dim - the space dimension,
result - a table into which the result is written; its size must be at least (dim + 1),

Definition at line 2187 of file homology.h.

References BettiNumber(), Homology(), chomp::homology::tCubeBase< coordtype >::MaxDim, scon, and sout.

{
        using namespace chomp::homology;

        // create a corresponding set of cubes
        SetOfCubes X;
        coordinate c [Cube::MaxDim];
        coordtype const *coordpointer = coord;
        for (int i = 0; i < n; ++ i)
        {
                for (int j = 0; j < dim; ++ j)
                        c [j] = static_cast<coordtype> (*(coordpointer ++));
                X. add (Cube (c, dim));
        }

        // turn off screen output
        bool soutput = sout. show;
        sout. show = false;
        bool coutput = scon. show;
        scon. show = false;
        
        // compute the homology of the constructed cubical set
        Chain *hom;
        int maxlevel = Homology (X, "X", hom);

        // fill out the resulting table of Betti numbers
        for (int j = 0; j <= dim; ++ j)
                result [j] = (j <= maxlevel) ? BettiNumber (hom [j]) : 0;

        // free unused memory and finish
        if (hom)
                delete [] hom;
        sout. show = soutput;
        scon. show = coutput;
        return;
} /* ComputeBettiNumbers */

template<class coordtype >
void chomp::homology::computeboundary ( tPointset< coordtype > &  p,
tPointset< coordtype > &  b 
)

Computes the boundary points of the given set and adds them to the other set of points.

template<class coordtype >
tPointset< coordtype > * chomp::homology::computeboundary ( tPointset< coordtype > &  p  ) 

Creates the set of all the boundary points with the 'new' operator.

Definition at line 1899 of file pointset.h.

{
        // create a new set of points
        tPointset<coordtype> *boundary = new tPointset<coordtype>;

        // if cannot allocate memory for it, return nothing
        if (!boundary)
                return NULL;

        // copy the global parameters (the defaults may be different)
        boundary -> dimension (p. dimension ());
        boundary -> gridsize (p. gridsize ());
        boundary -> wrapspace (p. wrapspace ());

        // compute the boundary
        computeboundary (p, *boundary);

        return boundary;
} /* computeboundary */

template<class coordtype >
void chomp::homology::computeboundary ( const tPointset< coordtype > &  p,
tPointset< coordtype > &  b 
)

Definition at line 1885 of file pointset.h.

References attheborder().

{
        // add all the points which are at the border
        int_t size = p. size ();
        for (int_t i = 0; i < size; ++ i)
        {
                coordtype *c = p [i];
                if (attheborder (p, c))
                        b. add (c);
        }
        return;
} /* computeboundary */

template<class tCube , class tCell >
int_t chomp::homology::computeimage ( hashedset< tCube > &  img,
const tCell &  face,
const mvmap< tCube, tCube > &  map,
const hashedset< tCube > &  cset,
const tCube &  ignore 
)

Computes the image of the face under the combinatorial cubical multivalued map, but doesn't take the given cube into consideration.

Returns the number of cubes whose images were added to 'img'.

Definition at line 237 of file cubisets.h.

Referenced by remainsacyclic().

{
        // get the coordinates of the cubical cell
        typename tCell::CoordType left [tCell::MaxDim];
        face. leftcoord (left);
        typename tCell::CoordType right [tCell::MaxDim];
        face. rightcoord (right);

        // find the images of all the cubes containing this cell
        int spacedim = face. spacedim ();
        typename tCell::CoordType leftb [tCell::MaxDim];
        typename tCell::CoordType rightb [tCell::MaxDim];
        for (int j = 0; j < spacedim; ++ j)
        {
                typename tCell::CoordType diff =
                        (left [j] == right [j]) ? 1 : 0;
                leftb [j] = (left [j] - diff);
                rightb [j] = (right [j] + diff);
        }
        tRectangle<typename tCell::CoordType> r (leftb, rightb, spacedim);
        const typename tCell::CoordType *c;
        int_t countimages = 0;
        while ((c = r. get ()) != NULL)
        {
                if (!tCube::PointBase::check (c, spacedim))
                        continue;
                tCube q (c, spacedim);
                if (q == ignore)
                        continue;
                if (!cset. check (q))
                        continue;
                img. add (map (q));
                ++ countimages;
        }

        return countimages;
} /* computeimage */

template<class GraphType >
int_t chomp::homology::computePeriod ( const GraphType &  g  )  [inline]

Computes the period of a strongly connected graph.

The period of a graph is defined as the greatest common divisor of the lengths of all the cycles in the graph. Period 1 means that the graph is aperiodic. The complexity of this operation is linear (one DFS).

Definition at line 3393 of file digraph.h.

{
        // remember the number of vertices in the input graph
        int_t nVertG = g. countVertices ();
        if (!nVertG)
                return 0;

        // prepare an array to record the depth of each visited vertex
        std::vector<int_t> visited (nVertG, 0);

        // run DFS starting at the first vertex
        // prepare stacks for the DFS algorithm
        std::stack<int_t> s_vertex;
        std::stack<int_t> s_edge;

        // mark the starting vertex as visited
        visited [0] = 1;

        // use DFS to visit vertices reachable from that vertex
        int_t vertex = 0;
        int_t edge = 0;
        int_t level = 1;
        int_t period = 0;
        while (1)
        {
                // go back with the recursion
                // if all the edges have been processed
                if (edge >= g. countEdges (vertex))
                {
                        // if this was the top recursion level then quit
                        if (s_vertex. empty ())
                                break;

                        // return from the recursion
                        vertex = s_vertex. top ();
                        s_vertex. pop ();
                        edge = s_edge. top ();
                        s_edge. pop ();
                        -- level;
                        continue;
                }

                // take the next vertex
                int_t next = g. getEdge (vertex, edge ++);

                // update the GCD of the cycle lengths
                if (visited [next])
                {
                        // determine the period provided by the cycle
                        int_t newPeriod = visited [next] - level - 1;
                        if (newPeriod < 0)
                                newPeriod = -newPeriod;

                        // compute the GCD of the old and new periods
                        int_t a = newPeriod;
                        int_t b = period;
                        while (b)
                        {
                                int_t t = b;
                                b = a % b;
                                a = t;
                        }
                        period = a;

                        // if the graph turns out to be aperiodic
                        // then immediately return the result
                        if (period == 1)
                                return period;
                }

                // go to the deeper recursion level if not visited
                else
                {
                        // store the previous variables at the stacks
                        s_vertex. push (vertex);
                        s_edge. push (edge);

                        // take the new vertex
                        vertex = next;
                        edge = 0;
                        ++ level;

                        // mark the new vertex as visited
                        visited [vertex] = level;
                }
        }

        // return the computed peirod and exit
        return period;
} /* computePeriod */

template<class wType >
int_t chomp::homology::connectionGraph ( const diGraph< wType > &  g,
int_t  nVert,
diGraph< wType > &  result 
) [inline]

Computes the graph that represents connections between a number of the first vertices in the given graph.

The vertices of the result graph are the first "nVert" vertices from the source graph. An edge is added to the new graph iff there exists a path from one vertex to another, without going through any other vertex in that set. Runs DFS starting from each of the first "nVert" vertices, and thus may be a little inefficient in some cases.

Definition at line 3283 of file digraph.h.

{
        // remember the number of vertices in the input graph
        int_t nVertG = g. countVertices ();
        if (!nVertG)
                return 0;

        // prepare a bitfield in which visited vertices will be marked
        BitField visited;
        visited. allocate (nVertG);
        visited. clearall (nVertG);

        // run DFS for each of the starting vertices
        for (int_t startVertex = 0; startVertex < nVert; ++ startVertex)
        {
                // add this vertex to the resulting graph
                result. addVertex ();

                // prepare a counter and a stack of visited vertices
                int_t nVisited = 0;
                std::stack<int_t> s_visited;

                // prepare stacks for the DFS algorithm
                std::stack<int_t> s_vertex;
                std::stack<int_t> s_edge;

                // mark the starting vertex as visited
                visited. set (startVertex);
                s_visited. push (startVertex);
                ++ nVisited;

                // use DFS to visit vertices reachable from that vertex
                int_t vertex = startVertex;
                int_t edge = 0;
                while (1)
                {
                        // go back with the recursion
                        // if all the edges have been processed
                        if (edge >= g. countEdges (vertex))
                        {
                                // if this was the top recursion level
                                // then quit
                                if (s_vertex. empty ())
                                        break;

                                // return from the recursion
                                vertex = s_vertex. top ();
                                s_vertex. pop ();
                                edge = s_edge. top ();
                                s_edge. pop ();
                                continue;
                        }

                        // take the next vertex
                        int_t next = g. getEdge (vertex, edge ++);

                        // go to the deeper recursion level if not visited
                        if (!visited. test (next))
                        {
                                // add an edge to the result if necessary
                                if (next < nVert)
                                        result. addEdge (next);

                                // store the previous variables at the stacks
                                s_vertex. push (vertex);
                                s_edge. push (edge);

                                // take the new vertex
                                vertex = next;
                                edge = 0;

                                // mark the new vertex as visited
                                visited. set (vertex);
                                s_visited. push (vertex);
                                ++ nVisited;
                        }
                }

                // if this was the last vertex then skip the rest
                if (startVertex == nVert - 1)
                        break;

                // mark each vertex as non-visited
                if (nVisited > (nVertG >> 6))
                {
                        visited. clearall (nVertG);
                }
                else
                {
                        while (!s_visited. empty ())
                        {
                                int_t vertex = s_visited. top ();
                                s_visited. pop ();
                                visited. clear (vertex);
                        }
                }
        }

        // free memory and exit
        visited. free ();
        return 0;
} /* connectionGraph */

template<class coordtype >
void chomp::homology::copycoord ( coordtype *  destination,
const coordtype *  source,
int  dim 
) [inline]
template<class coordtype >
int chomp::homology::countneighbors ( const tPointset< coordtype > &  p,
const coordtype *  c,
int  which = 1,
int  maxcount = 0 
)

Counts how many neighbors of the point there are in the set, depending on 'which': 1 = in the set, 0 = out of the set.

Returns the number of neighbors of the given point in a given set.

If 'maxcount' > 0 then counts up to this number and quits. Use countneighbors (c, OUTSIDE, 1) to check for a boundary point or countneighbors (c, INSIDE, 1) to check if the point is not isolated.

Definition at line 1740 of file pointset.h.

References INSIDE, and OUTSIDE.

Referenced by attheborder(), countneighbors(), and findboundarypoint().

{
        if (p. empty ())
        {
                if (which == INSIDE)
                        return 0;
                else
                        return maxcount;
        }

        int count = 0;
        tNeighbors<coordtype> neigh (c, p. dimension ());
        while ((c = neigh. get ()) != NULL)
        {
                if (which == INSIDE)
                {
                        if (p. check (c))
                                ++ count;
                }
                else if (which == OUTSIDE)
                {
                        if (!p. check (c))
                                ++ count;
                }

                if (maxcount && (count >= maxcount))
                        return count;
        }

        return count;
} /* countneighbors */

template<class coordtype >
int chomp::homology::countneighbors ( const tPointset< coordtype > &  p,
const tPointset< coordtype > &  q,
const coordtype *  c,
int  which = 1,
int  maxcount = 0 
)

Counts neighbors with respect to the union of the sets 'p' and 'q'.

template<class coordtype >
int chomp::homology::countneighbors ( const tPointset< coordtype > &  p,
const tPointset< coordtype > &  q,
coordtype *  c,
int  which,
int  maxcount 
)

Definition at line 1774 of file pointset.h.

References countneighbors(), INSIDE, and OUTSIDE.

{
        if ((q. empty ()) || (p. dimension () != q. dimension ()))
                return countneighbors (p, c, which, maxcount);
        else if (p. empty ())
                return countneighbors (q, c, which, maxcount);

        int count = 0;
        tNeighbors<coordtype> neigh (c, p. dimension ());
        while ((c = neigh. get ()) != NULL)
        {
                if (which == INSIDE)
                {
                        if (p. check (c) || q. check (c))
                                ++ count;
                }
                else if (which == OUTSIDE)
                {
                        if (!p. check (c) && !q. check (c))
                                ++ count;
                }

                if (maxcount && (count >= maxcount))
                        return count;
        }

        return count;
} /* countneighbors */

template<class cell , class euclidom , class element >
bool chomp::homology::createcellmap ( const mvcellmap< cell, euclidom, element > &  m,
const mvcellmap< cell, euclidom, element > &  rel,
mvcellmap< cell, euclidom, cell > &  cm,
bool  verifyacyclicity 
)

Creates the graph of the map as a cell complex while reducing as possible.

Note: There must be a constructor for 'cell' from 'element' and the Cartesian product operator for cells. The domain of 'rel' must be a subset of the domain of 'm'. If the acyclicity is to be verified, returns true if Ok, false if not.

Definition at line 1949 of file gcomplex.h.

References acyclic(), addboundaries(), collapse(), and scon.

{
        // prepare the default result
        bool result = true;

        // go through all the dimensions of the domain cell complex
        const gcomplex<cell,euclidom> &dom = m. getdomain ();
        const gcomplex<cell,euclidom> &reldom = rel. getdomain ();

        int maxdim = m. dim ();
        for (int d = maxdim; d >= 0; -- d)
        {
                // go through all the cells of this dimension
                const hashedset<cell> &cset = m. get (d);
                for (int_t i = 0; i < cset. size (); ++ i)
                {
                        // extract the cell of interest and its image
                        const cell &thecell = cset [i];
                        const hashedset<element> &set = m (thecell);

                        // the image must not be empty!
                        if (set. empty ())
                                throw "An empty image of a cell found.";

                        // if this is maximal dimension, extract one point
                        if (d == maxdim)
                        {
                                if (reldom. check (thecell))
                                        continue;
                                //      throw "This cell shouldn't be here.";
                        //      cm. add (d, thecell, cell (set [0]. coord (),
                        //              set [0]. coord (), set [0]. dim ()));
                                cm. add (d, thecell, cell (set [0], 0));
                                continue;
                        }

                        // create a cell complex of the image of this cell
                        gcomplex<cell,euclidom> img;
                        for (int_t j = 0; j < set. size (); ++ j)
                                img. add (cell (set [j]));

                        // create a cell complex to keep while collapsing
                        gcomplex<cell,euclidom> keep;
                        const hashedset<cell> &cob =
                                dom. getcob (thecell, d);

                        for (int_t j = 0; j < cob. size (); ++ j)
                                keep. add (cm (cob [j]));

                        // create a cell complex from 'rel'
                        gcomplex<cell,euclidom> other;
                        if (reldom. check (thecell))
                        {
                                const hashedset<element> &relset =
                                        rel (thecell);
                                for (int_t j = 0; j < relset. size (); ++ j)
                                {
                                        cell c = cell (relset [j]);
                                        keep. add (c);
                                        other. add (c);
                                //      img. remove (c);
                                }
                        }

                        // reduce 'img' towards 'keep'
                        gcomplex<cell,euclidom> empty;
                        img. collapse (empty, keep, 1, 0, 0, NULL, 1);

                        // verify the acyclicity of this image if requested
                        if (verifyacyclicity)
                        {
                                gcomplex<cell,euclidom> imgdupl (img);
                                if (!acyclic (imgdupl))
                                {
                                        result = false;
                                        verifyacyclicity = false;
                                }
                        }

                        // remove the other cells and their faces from img
                        other. addboundaries ();
                        img. remove (other);

                        // verify the acyclicity of the other complex
                        if (verifyacyclicity && other. size ())
                        {
                                // note: acycl. check destroys 'other'
                                if (!acyclic (other))
                                {
                                        result = false;
                                        verifyacyclicity = false;
                                }
                        }

                        // set this to be the image of this cell
                        // *** THIS MUST BE IMPROVED ***
                        for (int j = 0; j <= img. dim (); ++ j)
                                cm. add (d, thecell, img [j]);

                        // show progress indicator
                        if (i && !(i % 373))
                                scon << std::setw (12) << i <<
                                        "\b\b\b\b\b\b\b\b\b\b\b\b";
                }
                if (cset. size () > 373)
                        scon << "            \b\b\b\b\b\b\b\b\b\b\b\b";
                scon << '.';
        }
        scon << ' ';
        return result;
} /* createcellmap */

template<class cell , class euclidom , class element >
void chomp::homology::createcellmap ( const mvcellmap< cell, euclidom, element > &  m,
mvcellmap< cell, euclidom, cell > &  cm 
)

Creates the graph of the map as a cell complex while reducing as possible.

Note: There must be a constructor for 'cell' from 'element' and the Cartesian product operator for cells.

Definition at line 1875 of file gcomplex.h.

References collapse(), and scon.

Referenced by Homology(), and Homology2l().

{
        // go through all the dimensions of the domain cell complex
        int spacedim = -1;
        const gcomplex<cell,euclidom> &dom = m. getdomain ();
        for (int d = m. dim (); d >= 0; -- d)
        {
                // go through all the cells of this dimension
                const hashedset<cell> &cset = m. get (d);
                for (int_t i = 0; i < cset. size (); ++ i)
                {
                        // extract the cell of interest and its image
                        const cell &thecell = cset [i];
                        const hashedset<element> &set = m (thecell);

                        // the image must not be empty!
                        if (set. empty ())
                                throw "An empty image of a cell found.";

                        // correct the dimension of the space if necessary
                        if (spacedim < 0)
                                spacedim = set [0]. dim ();

                        // if this is maximal dimension, extract one point
                        if (d == spacedim)
                        {
                        //      cm. add (d, thecell, cell (set [0]. coord (),
                        //              set [0]. coord (), spacedim));
                                cm. add (d, thecell, cell (set [0], 0));
                                continue;
                        }

                        // create a cell complex of the image of this cell
                        gcomplex<cell,euclidom> img;
                        for (int_t j = 0; j < set. size (); ++ j)
                                img. add (cell (set [j]));

                        // create a cell complex to keep while collapsing
                        gcomplex<cell,euclidom> keep;
                        const hashedset<cell> &cob =
                                dom. getcob (thecell, d);
                        for (int_t j = 0; j < cob. size (); ++ j)
                                keep. add (cm (cob [j]));

                        // reduce 'img' towards 'keep'
                        gcomplex<cell,euclidom> empty;
                        img. collapse (empty, keep, 1, 0, 0, NULL, 1);

                        // set this to be the image of this cell
                        // *** THIS MUST BE IMPROVED ***
                        for (int j = 0; j <= img. dim (); ++ j)
                                cm. add (d, thecell, img [j]);

                        // show progress indicator
                        if (i && !(i % 373))
                                scon << std::setw (12) << i <<
                                        "\b\b\b\b\b\b\b\b\b\b\b\b";
                }
                if (cset. size () > 373)
                        scon << "            \b\b\b\b\b\b\b\b\b\b\b\b";
                scon << '.';
        }
        scon << ' ';
        return;
} /* createcellmap */

template<class cell , class euclidom >
chaincomplex<euclidom>& chomp::homology::createchaincomplex ( chaincomplex< euclidom > &  c,
const gcomplex< cell, euclidom > &  g,
bool  quiet = false 
)

Creates an algebraic chain complex based on the data from the given geometric cell complex.

Boundary formulas are restricted to cells which are in the geom. complex. The chain complex should already be initialized with the right dimension.

Definition at line 1129 of file gcomplex.h.

References boundarycell(), boundarycoef(), boundarylength(), and scon.

Referenced by acyclic(), Homology(), and Homology2l().

{
        if (g. dim () < 0)
                return c;
        c. def_gen (0, g [0]. size ());
        for (int d = 1; d <= g. dim (); ++ d)
        {
                c. def_gen (d, g [d]. size ());
                for (int_t i = 0; i < g [d]. size (); ++ i)
                {
                        int len = boundarylength (g [d] [i]);
                        for (int j = 0; j < len; ++ j)
                        {
                                // take the j-th boundary cell
                                cell thecell = boundarycell (g [d] [i], j);
        
                                // add it to the chain complex
                                if (g. check (thecell))
                                {
                                        int icoef = boundarycoef
                                                (g [d] [i], j);
                                        euclidom coef;
                                        if (icoef < 0)
                                        {
                                                coef = -icoef;
                                                coef = -coef;
                                        }
                                        else
                                                coef = icoef;
                                        c. add (d, g [d - 1]. getnumber
                                                (thecell), i, coef);
                                }
                        }
                }
                if (!quiet)
                {
                        if (d < g. dim ())
                                scon << '.';
                        else
                                scon << ". ";
                }
        }
        return c;
} /* createchaincomplex */

template<class cell , class euclidom >
chaincomplex<euclidom>& chomp::homology::createchaincomplex ( chaincomplex< euclidom > &  c,
const gcomplex< cell, euclidom > &  g,
const gcomplex< cell, euclidom > &  rel,
bool  quiet = false 
)

Creates a relative algebraic chain complex with the data from the given pair of geometric cell complexes.

Boundary formulas are restricted to cells which are in the geom. complex. The chain complex should already be initialized with the right dimension.

Definition at line 1261 of file gcomplex.h.

References boundarycell(), boundarycoef(), boundarylength(), and scon.

{
        // if the geometric complex is empty, don't modify the chain complex
        if (g. dim () < 0)
                return c;

        // prepare a table of numbers of ignored cells in the geom. complex
        multitable<int_t> *numbers0 = new multitable<int_t>;
        int_t count0 = g [0]. size ();
        if (rel. dim () >= 0)
        {
                count0 -= rel [0]. size ();
                int_t j = 0;
                for (int_t i = 0; i < rel [0]. size (); ++ i)
                {
                        (*numbers0) [j] = g [0]. getnumber (rel [0] [i]);
                        if ((*numbers0) [j] < 0)
                                ++ count0;
                        else
                                ++ j;
                }
        }

        // set the number of generators of the given dimension
        c. def_gen (0, count0);

        // create boundary matrices
        for (int d = 1; d <= g. dim (); ++ d)
        {
                // prepare a table of numbers to be ignored
                multitable<int_t> *numbers1 = new multitable<int_t>;
                int_t count1 = g [d]. size ();
                if (rel. dim () >= d)
                {
                        count1 -= rel [d]. size ();
                        int_t j = 0;
                        for (int_t i = 0; i < rel [d]. size (); ++ i)
                        {
                                (*numbers1) [j] =
                                        g [d]. getnumber (rel [d] [i]);
                                if ((*numbers1) [j] < 0)
                                        ++ count1;
                                else
                                        ++ j;
                        }
                }

                // set the number of generators of this dimension
                c. def_gen (d, count1);

                // create the boundary connections with coefficients
                for (int_t i = 0; i < g [d]. size (); ++ i)
                {
                        // if this cell is in the other complex, ignore it
                        if ((rel. dim () >= d) &&
                                (rel [d]. check (g [d] [i])))
                                continue;

                        // determine the number of this cell
                        int_t n1 = i;
                        if (n1 >= count1)
                                n1 = (*numbers1) [n1 - count1];

                        // get the length of the cell
                        int len = boundarylength (g [d] [i]);

                        // retrieve boundary cells and make boundary formula
                        for (int j = 0; j < len; ++ j)
                        {
                                // take the j-th boundary cell
                                cell thecell = boundarycell (g [d] [i], j);

                                // add it to the chain complex if relevant
                                if (g [d - 1]. check (thecell) &&
                                        ((rel. dim () < d - 1) ||
                                        (!rel [d - 1]. check (thecell))))
                                {
                                        // determine the number of the cell
                                        int_t n0 = g [d - 1].
                                                getnumber (thecell);

                                        // if out of range, translate it
                                        if (n0 >= count0)
                                                n0 = (*numbers0)
                                                        [n0 - count0];

                                        // determine the right coefficient
                                        int icoef = boundarycoef
                                                (g [d] [i], j);
                                        euclidom coef;
                                        if (icoef < 0)
                                        {
                                                coef = -icoef;
                                                coef = -coef;
                                        }
                                        else
                                                coef = icoef;

                                        // add this link to the boundary
                                        c. add (d, n0, n1, coef);
                                }
                        }
                }

                // forget unnecessary tables and prepare for the next loop
                delete numbers0;
                numbers0 = numbers1;
                count0 = count1;

                // show progress indicator
                if (!quiet)
                {
                        if (d < g. dim ())
                                scon << '.';
                        else
                                scon << ". ";
                }
        }

        // release used memory
        delete numbers0;

        // finish
        return c;
} /* createchaincomplex */

template<class domelement , class imgelement >
hashedset<imgelement>& chomp::homology::creategraph ( const mvmap< domelement, imgelement > &  m,
hashedset< imgelement > &  graph 
)

Adds a graph of a multivalued map to the given set.

The operator * is used to create the Cartesian products (pairs) of elements from the domain and elements in their images.

Definition at line 1135 of file hashsets.h.

{
        for (int_t i = 0; i < m. getdomain (). size (); ++ i)
        {
                const domelement &e = m. get (i);
                const hashedset<imgelement> &f = m (i);
                int_t n = f. size ();
                for (int_t j = 0; j < n; ++ j)
                        graph. add (e * f [j]);
        }
        return graph;
} /* creategraph */

template<class cell , class euclidom >
gcomplex<cell,euclidom>& chomp::homology::creategraph ( const mvmap< cell, cell > &  m,
gcomplex< cell, euclidom > &  graph 
)

Add a graph of a multivalued cell map to the cell complex.

Definition at line 1430 of file gcomplex.h.

Referenced by Homology(), and Homology2l().

{
        for (int_t i = 0; i < m. size (); ++ i)
        {
                const cell &e = m. get (i);
                const hashedset<cell> &f = m (i);
                for (int_t j = 0; j < f. size (); ++ j)
                        graph. add (e * f [j]);
        }
        return graph;
} /* creategraph */

template<class cell , class euclidom , class element >
void chomp::homology::creategraph ( const mvcellmap< cell, euclidom, element > &  m,
gcomplex< cell, euclidom > &  c,
bool  addbd 
)

Creates the full graph of a map as a cellular complex.

Note: There must be a constructor for 'cell' from 'element' and the Cartesian product operator for cells.

Definition at line 1789 of file gcomplex.h.

References addboundaries(), and scon.

{
        // go through all the dimensions of the domain cell complex
        for (int d1 = 0; d1 <= m. dim (); ++ d1)
        {
                // go through all the cells of this dimension
                const hashedset<cell> &cset = m. get (d1);
                for (int_t i = 0; i < cset. size (); ++ i)
                {
                        // create a cell complex of the image of this cell
                        const cell &thecell = cset [i];
                        const hashedset<element> &set = m (thecell);
                        gcomplex<cell,euclidom> img;
                        for (int_t j = 0; j < set. size (); ++ j)
                                img. add (cell (set [j]));
                        if (addbd)
                                img. addboundaries ();

                        // go through all the dimensions of this cell complex
                        for (int d2 = 0; d2 <= img. dim (); ++ d2)
                        {
                                // add all the products to the graph
                                const hashedset<cell> &cs = img [d2];
                                for (int_t j = 0; j < cs. size (); ++ j)
                                        c. add (thecell * cs [j]);
                        }
                }
                if (d1 < m. dim ())
                        scon << '.';
                else
                        scon << ' ';
        }
        return;
} /* creategraph */

template<class cell , class euclidom , class element >
void chomp::homology::creategraph ( const mvcellmap< cell, euclidom, element > &  m,
const gcomplex< cell, euclidom > &  rel,
gcomplex< cell, euclidom > &  c,
bool  addbd 
)

Creates the full graph of a map as a cellular complex.

Note: There must be a constructor for 'cell' from 'element' and the Cartesian product operator for cells.

Definition at line 1829 of file gcomplex.h.

References addboundaries(), and scon.

{
        // go through all the dimensions of the domain cell complex
        for (int d1 = 0; d1 <= m. dim (); ++ d1)
        {
                // go through all the cells of this dimension
                const hashedset<cell> &cset = m. get (d1);
                for (int_t i = 0; i < cset. size (); ++ i)
                {
                        // create a cell complex of the image of this cell
                        const cell &thecell = cset [i];
                        const hashedset<element> &set = m (thecell);
                        gcomplex<cell,euclidom> img;
                        for (int_t j = 0; j < set. size (); ++ j)
                                img. add (cell (set [j]));
                        if (addbd)
                                img. addboundaries ();

                        // go through all the dimensions of this cell complex
                        for (int d2 = 0; d2 <= img. dim (); ++ d2)
                        {
                                // add all the products to the graph
                                const hashedset<cell> &cs = img [d2];
                                for (int_t j = 0; j < cs. size (); ++ j)
                                {
                                        cell bigcell = thecell * cs [j];
                                        if (!rel. check (bigcell))
                                                c. add (bigcell);
                                }
                        }
                }
                if (d1 < m. dim ())
                        scon << '.';
                else
                        scon << ' ';
        }
        return;
} /* creategraph */

template<class euclidom , class tCell , class tCube >
int_t chomp::homology::createimages ( mvcellmap< tCell, euclidom, tCube > &  m,
const mvmap< tCube, tCube > &  f1,
const mvmap< tCube, tCube > &  f2,
const hashedset< tCube > &  dom1,
const hashedset< tCube > &  dom2 
)

Creates images of cells in 'm' as unions of cubes determined by f1 and f2.

The domains of interest must be given explicitly. Returns the total number of cubes in all the images of cells.

Definition at line 148 of file cubmaps.h.

Referenced by createimages(), Homology(), and Homology2l().

{
        typedef typename tCell::CoordType coordType;
        int_t countimages = 0;
        coordType leftbound [tCell::MaxDim];
        coordType rightbound [tCell::MaxDim];
        coordType left [tCell::MaxDim];
        coordType right [tCell::MaxDim];
        for (int d = 0; d <= m. dim (); ++ d)
        {
                const hashedset<tCell> &cset = m. get (d);
                if (cset. empty ())
                        continue;
                const int spacedim = cset [0]. spacedim ();
                for (int_t i = 0; i < cset. size (); ++ i)
                {
                        cset [i]. leftcoord (left);
                        cset [i]. rightcoord (right);
                        for (int_t j = 0; j < spacedim; ++ j)
                        {
                                // compensate for space wrapping
                                if (right [j] < left [j])
                                        right [j] = left [j] + 1;
                                // compute the bounds
                                leftbound [j] = static_cast<coordType>
                                        (left [j] - (left [j] == right [j]));
                                rightbound [j] = static_cast<coordType>
                                        (right [j] +
                                        (left [j] == right [j]));
                        }
                        tRectangle<coordType> r (leftbound, rightbound,
                                spacedim);
                        const coordType *c;
                        while ((c = r. get ()) != NULL)
                        {
                                if (!tCube::PointBase::check (c, spacedim))
                                        continue;
                                tCube q (c, spacedim);
                                if (dom1. check (q))
                                        m. add (d, i, f1 (q));
                                if (dom2. check (q))
                                        m. add (d, i, f2 (q));
                        }
                        countimages += m (cset [i]). size ();
                }
        }
        return countimages;
} /* createimages */

template<class euclidom , class tCell , class tCube >
int_t chomp::homology::createimages ( mvcellmap< tCell, euclidom, tCube > &  m,
const mvmap< tCube, tCube > &  f,
const hashedset< tCube > &  dom 
) [inline]

A wrapper for the above function if there is only one map.

Definition at line 201 of file cubmaps.h.

References createimages().

{
        mvmap<tCube,tCube> emptymap;
        hashedset<tCube> emptyset;
        return createimages (m, f, emptymap, dom, emptyset);
} /* createimages */

template<class euclidom , class tCell , class tCube >
int_t chomp::homology::createimages ( mvcellmap< tCell, euclidom, tCube > &  m,
const mvmap< tCube, tCube > &  f1,
const mvmap< tCube, tCube > &  f2 
)

Creates images of cells in m as unions of cubes determined by f1 and f2.

Return the total number of cubes in all the images of cells.

Definition at line 212 of file cubmaps.h.

References createimages().

{
        const hashedset<tCube> &dom1 = f1. getdomain ();
        const hashedset<tCube> &dom2 = f2. getdomain ();
        return createimages (m, f1, f2, dom1, dom2);
} /* createimages */

template<class euclidom , class tCell , class tCube >
int_t chomp::homology::createimages ( mvcellmap< tCell, euclidom, tCube > &  m,
const mvmap< tCube, tCube > &  f 
) [inline]

A wrapper for the above function if there is only one map.

Definition at line 222 of file cubmaps.h.

References createimages().

{
        mvmap<tCube,tCube> emptymap;
        return createimages (m, f, emptymap);
} /* createimages */

template<class euclidom , class tCell , class tCube >
int_t chomp::homology::createimages ( mvcellmap< tCell2l< tCell >, euclidom, tCube2l< tCube > > &  m,
const mvmap< tCube2l< tCube >, tCube2l< tCube > > &  f1,
const mvmap< tCube2l< tCube >, tCube2l< tCube > > &  f2,
const hashedset< tCube2l< tCube > > &  dom1,
const hashedset< tCube2l< tCube > > &  dom2 
)

Specialization of the "createimages" function for two-layer cubes.

This function creates images of cells in 'm' as unions of cubes determined by f1 and f2. The domains of interest are given explicitly. Returns the total number of cubes in all the images of cells.

Definition at line 1117 of file twolayer.h.

References chomp::homology::tCell2l< tCell >::identify().

{
        typedef typename tCube::CoordType coordType;
        int_t countimages = 0;
        coordType leftbound [tCell::MaxDim];
        coordType rightbound [tCell::MaxDim];
        coordType left [tCell::MaxDim];
        coordType right [tCell::MaxDim];

        // go through all the dimensions of the cellular complex separtely
        for (int d = 0; d <= m. dim (); ++ d)
        {
                const hashedset<tCell2l<tCell> > &cset = m. get (d);
                if (cset. empty ())
                        continue;
                const int spacedim = cset [0]. spacedim ();

                // go through the cells of the specified dimension
                for (int_t i = 0; i < cset. size (); ++ i)
                {
                        // remember the cell whose image is computed
                        const tCell2l<tCell> &thecell = cset [i];

                        // determine tha layer of the cell
                        const typename tCube2l<tCube>::LayerType layer =
                                thecell. layer ();

                        // check if the layers are identified at the cell
                        bool idlayers = tCell2l<tCell>::identify ().
                                check (thecell. cell ());

                        // get the coordinates of the corners of the cell
                        thecell. leftcoord (left);
                        thecell. rightcoord (right);

                        // compute the bounds for full cubes to get imgs of
                        for (int j = 0; j < spacedim; ++ j)
                        {
                                // compensate for space wrapping
                                if (right [j] < left [j])
                                        right [j] = left [j] + 1;

                                // compute the bounds for full cubes
                                leftbound [j] = static_cast<coordType>
                                        (left [j] - (left [j] == right [j]));
                                rightbound [j] = static_cast<coordType>
                                        (right [j] +
                                        (left [j] == right [j]));
                        }

                        // go through the full cubes in the computed range
                        tRectangle<coordType> r (leftbound, rightbound,
                                spacedim);
                        const coordType *c;
                        while ((c = r. get ()) != NULL)
                        {
                                // determine the core cube
                                if (!tCube::PointBase::check (c, spacedim))
                                        continue;
                                tCube q0 (c, spacedim);

                                // add the images of the 2-layer cube
                                tCube2l<tCube> q (q0, layer);
                                if (dom1. check (q))
                                        m. add (d, i, f1 (q));
                                if (dom2. check (q))
                                        m. add (d, i, f2 (q));

                                // determine if the cubes at the other
                                // layer must also be considered
                                typename tCube2l<tCube>::LayerType l = layer;
                                if (idlayers && !layer &&
                                        tCube2l<tCube>::layer1 ().
                                        check (q0))
                                {
                                        l = 1;
                                }
                                else if (idlayers && layer &&
                                        tCube2l<tCube>::layer0 ().
                                        check (q0))
                                {
                                        l = 0;
                                }
                                if (l != layer)
                                {
                                        tCube2l<tCube> ql (q0, l);
                                        if (dom1. check (ql))
                                                m. add (d, i, f1 (ql));
                                        if (dom2. check (ql))
                                                m. add (d, i, f2 (ql));
                                }
                        }
                        countimages += m (thecell). size ();
                }
        }
        return countimages;
} /* createimages */

template<class euclidom , class tCell >
void chomp::homology::createprojection ( const gcomplex< tCell, euclidom > &  Fcompl,
const gcomplex< tCell, euclidom > &  Ycompl,
chainmap< euclidom > &  cmap,
int  offset,
int  outdim,
int  discarddim,
int *  level = NULL 
)

Creates the chain map of the projection from a cell complex of the graph of a map to a cell complex of the codomain of the map.

If a table of levels is given, creates the map only at given levels.

Definition at line 238 of file cubmaps.h.

Referenced by Homology(), and Homology2l().

{
        typedef typename tCell::CoordType coordType;
        // go through the list of all the dimensions which are of concern
        for (int d = 0; d <= Ycompl. dim (); ++ d)
        {
                if ((!level || level [d]) && (Fcompl. dim () >= d))
                {
                        // take sets of cells of this dimension
                        const hashedset<tCell> &Fset = Fcompl [d];
                        if (Fset. empty ())
                                continue;
                        const hashedset<tCell> &Yset = Ycompl [d];
                        if (Yset. empty ())
                                continue;

                        // go through the list of cells in Fcompl of dim. d
                        for (int_t i = 0; i < Fset. size (); ++ i)
                        {
                                // get this cell and its coordinates
                                const tCell &Fcell = Fset [i];
                                coordType left [tCell::MaxDim];
                                Fcell. leftcoord (left);
                                coordType right [tCell::MaxDim];
                                Fcell. rightcoord (right);

                                // check if this cell has no width in the
                                // directions that are discarded
                                register int j;
                                for (j = 0; j < offset; ++ j)
                                        if (left [j] != right [j])
                                        {
                                                j = offset + 33;
                                                break;
                                        }
                                if (j > offset)
                                        continue;
                                for (j = 0; j < discarddim; ++ j)
                                        if (left [offset + outdim + j] !=
                                                right [offset + outdim + j])
                                        {
                                                j = discarddim + 33;
                                                break;
                                        }
                                if (j > discarddim)
                                        continue;

                                // create the projected cell
                                if (!(tCell::PointBase::check
                                        (left + offset, outdim)))
                                        continue;
                                if (!(tCell::PointBase::check
                                        (right + offset, outdim)))
                                        continue;
                        //      tCell projected (left + offset,
                        //              right + offset, outdim);
                                tCell projected (Fcell, offset, outdim);

                                // find its number in Y
                                int_t nr = Yset. getnumber (projected);

                                // if not found, discard it
                                if (nr < 0)
                                        continue;

                                // add the pair to the projection map
                                euclidom e;
                                e = 1;
                                cmap. add (d, nr, i, e);
                        }
                }
        }
        return;
} /* createprojection */

template<class dest_cube , class src_cube >
dest_cube chomp::homology::cube_cast ( const src_cube &  src  )  [inline]

Converts one cube into another.

Definition at line 59 of file cubemain.h.

{
        typename dest_cube::CoordType tab [src_cube::MaxDim];
        src. coord (tab);
        return dest_cube (tab, src. dim ());
} /* cube_cast */

template<class coordtype >
void chomp::homology::cubemiddle ( coordtype *  c,
double *  p,
double *  grid,
int  dim 
) [inline]

Computes the middle of a cube with its left lower etc.

corner represented by the given point with respect to the given grid.

Definition at line 231 of file pointset.h.

{
        if (grid)
        {
                for (int i = 0; i < dim; ++ i)
                        p [i] = (c [i] + 0.5) * grid [i];
        }
        else
        {
                for (int i = 0; i < dim; ++ i)
                        p [i] = c [i] + 0.5;
        }
        return;
} /* cubemiddle */

template<class tCubes , class tCell , class tCoef >
void chomp::homology::cubes2cells ( tCubes &  Xcubes,
gcomplex< tCell, tCoef > &  Xcompl,
const char *  Xname,
bool  deletecubes = true 
)

Transforms cubes to full-dimensional cells.

Definition at line 717 of file homtools.h.

References sout.

Referenced by Homology(), and Homology2l().

{
        // if there are no cubes to transform, do nothing
        if (Xcubes. empty ())
                return;

        // transform cubes into the cells of the same dimension
        int_t prev = Xcompl. size ();
        sout << "Transforming " << Xname << " into cells... ";
        for (int_t i = 0; i < Xcubes. size (); ++ i)
                Xcompl. add (tCell (Xcubes [i]));
        sout << (Xcompl. size () - prev) << " cells added.\n";

        // forget the set of cubes if requested to
        if (deletecubes)
        {
                tCubes empty;
                Xcubes = empty;
        }

        return;
} /* cubes2cells */

template<class tCube >
int_t chomp::homology::cubexpand ( hashedset< tCube > &  cset,
hashedset< tCube > &  other,
bool  quiet = false 
)

Expands the set 'other' towards 'cset' without changing the homology of (cset + other, other).

The two sets must be disjoint.

Definition at line 800 of file cubisets.h.

References acyclic(), getmaxneighbors(), getneighbors(), scon, and sseq.

Referenced by expandAinX().

{
        // if the case is trivial, return the answer
        if (cset. empty () || other. empty ())
                return 0;

        // remember the initial number of cubes in the main set
        int_t prev = cset. size ();

        // determine the dimension of the cubes
        int dim = cset [0]. dim ();

        // compute the maximal number of neighbors of a cube
        int_t maxneighbors = getmaxneighbors (dim);

        // prepare a bitfield and allocate it if necessary
        static BitField b;
        static int_t _maxneighbors = 0;
        if (maxneighbors != _maxneighbors)
        {
                if (_maxneighbors > 0)
                        b. free ();
                _maxneighbors = maxneighbors;
                b. allocate (maxneighbors);
        }

        // prepare a queue for cubes to check
        hashedset<tCube> queue;

        // prepare a counter for displaying the progress of computations
        int_t count = 0;

        // go through the main set, move cubes to the other set
        // if possible, and add their neighbors to the queue
        for (int_t i = 0; i < cset. size (); ++ i)
        {
                // show progress indicator if suitable
                ++ count;
                if (!quiet && !(count % 373))
                        scon << std::setw (10) << count <<
                                "\b\b\b\b\b\b\b\b\b\b";

                // clear the neighborbits
                b. clearall (maxneighbors);

                // if the neighborhood of the cube is not acyclic, skip it
                if (!acyclic (cset [i], dim, other, &b, maxneighbors))
                        continue;
                
                // remove this cube from the queue
                queue. remove (cset [i]);

                // add neighbors from 'cset' to the queue
                b. clearall (maxneighbors);
                getneighbors (cset [i], &b, cset, &queue, 0);

                // move the cube to the other set
                if (!quiet)
                        sseq << '2' << cset [i] << '\n';
                other. add (cset [i]);
                cset. removenum (i);
                -- i;
        }

        // show a temporary progress indicator and reset the counter
        if (!quiet)
                scon << '*';
        count = 0;

        // take cubes from the queue and move them from 'cset' to 'other'
        while (queue. size ())
        {
                // show progress indicator
                if (!quiet && !(count % 373))
                        scon << std::setw (10) << count <<
                                "\b\b\b\b\b\b\b\b\b\b";
                ++ count;

                // take a cube from the queue
                const tCube c = queue [0];
                queue. removenum (0);

                // clear the neighborbits
                b. clearall (maxneighbors);

                // if the neighborhood of the cube is not acyclic, skip it
                if (!acyclic (c, dim, other, &b, maxneighbors))
                        continue;

                // add the neighbors from 'cset' to the queue
                b. clearall (maxneighbors);
                getneighbors (c, &b, cset, &queue, 0);

                // move this cube from 'cset' to 'other'
                if (!quiet)
                        sseq << '2' << c << '\n';
                cset. remove (c);
                other. add (c);
        }

        // erase the temporary progress indicator
        if (!quiet)
                scon << "\b \b";

        // return the number of cubes removed from 'cset'
        return prev - cset. size ();
} /* cubexpand */

template<class tCube >
int_t chomp::homology::cubexpand ( hashedset< tCube > &  cset,
hashedset< tCube > &  other,
hashedset< tCube > &  imgsrc,
hashedset< tCube > &  img,
const mvmap< tCube, tCube > &  map,
bool  indexmap,
bool  checkacyclic,
bool  quiet = false 
)

Expands the set 'other' towards 'cset' without changing the homology of (cset + other, other).

The two sets must be disjoint. Increases 'img' if necessary to cover F (other), but moves cubes only if it can prove that the inclusion of the old 'img' into the new, enlarged 'img' induces an isomorphism in homology. Every cube added to 'img' is removed from 'imgsrc'.

Definition at line 916 of file cubisets.h.

References acyclic(), cubreducequiet(), getmaxneighbors(), getneighbors(), remainsacyclic(), scon, and sseq.

{
        // if the case is trivial, return the answer
        if (cset. empty () || other. empty ())
                return 0;

        // remember the initial number of cubes in the main set
        int_t prev = cset. size ();

        // determine the space dimension
        int dim = cset [0]. dim ();

        // compute the maximal number of neighbors of a cube
        int_t maxneighbors = getmaxneighbors (dim);

        // prepare a bitfield and allocate it if necessary
        static BitField b;
        static int_t _maxneighbors = 0;
        if (maxneighbors != _maxneighbors)
        {
                if (_maxneighbors > 0)
                        b. free ();
                _maxneighbors = maxneighbors;
                b. allocate (maxneighbors);
        }

        // prepare a queue for cubes to check
        hashedset<tCube> queue;

        // prepare a counter for displaying the progress of computations
        int_t count = 0;

        // go through the main set, move cubes to the other set
        // if possible, and add their neighbors to the queue
        for (int_t i = 0; i < cset. size (); ++ i)
        {
                // show progress indicator
                ++ count;
                if (!quiet && !(count % 373))
                        scon << std::setw (10) << count <<
                                "\b\b\b\b\b\b\b\b\b\b";

                // take a cube from 'cset'
                const tCube &c = cset [i];

                // clear the neighborbits
                b. clearall (maxneighbors);

                // if the neighborhood of the cube is not acyclic, skip it
                if (!acyclic (c, dim, other, &b, maxneighbors))
                        continue;
                
                // take the image and reduce what is outside 'img'
                const hashedset<tCube> &cubimage = map (c);
                hashedset<tCube> ximage = cubimage;
                if (indexmap)
                        ximage. add (c);
                ximage. remove (img);
                cubreducequiet (img, ximage);

                // if the image could not be reduced, skip the cube
                if (!ximage. empty ())
                        continue;

                // make sure that the acyclicity of the map is not spoiled
                if (checkacyclic && !remainsacyclic (map, c, other))
                        continue;

                // add the image of this cube to the image of the map
                if (!quiet && !cubimage. empty ())
                {
                        sseq << "R\n";
                        for (int_t j = 0; j < cubimage. size (); ++ j)
                                sseq << '2' << cubimage [j] << '\n';
                        if (indexmap)
                                sseq << '2' << c << '\n';
                }
                img. add (cubimage);
                if (indexmap)
                        img. add (c);

                // remove from 'imgsrc' all the cubes added to 'img'
                imgsrc. remove (cubimage);
                if (indexmap)
                        imgsrc. remove (c);

                // remove this cube from the queue
                queue. remove (c);

                // add neighbors from 'cset' to the queue
                b. clearall (maxneighbors);
                getneighbors (c, &b, cset, &queue, 0);

                // move the cube to the other set
                if (!quiet)
                        sseq << "L\n" << '2' << c << '\n';
                other. add (c);
                cset. removenum (i);
                -- i;
        }

        // show a temporary progress indicator and reset the counter
        if (!quiet)
                scon << '*';
        count = 0;

        // take cubes from the queue and move them from 'cset' to 'other'
        while (!queue. empty ())
        {
                // show progress indicator
                if (!quiet && !(count % 373))
                        scon << std::setw (10) << count <<
                                "\b\b\b\b\b\b\b\b\b\b";
                ++ count;

                // take a cube from the queue
                tCube c = queue [0];
                queue. removenum (0);

                // clear the neighborbits
                b. clearall (maxneighbors);

                // if the neighborhood of the cube is not acyclic, skip it
                if (!acyclic (c, dim, other, &b, maxneighbors))
                        continue;
                
                // take the image and reduce what is outside 'img'
                const hashedset<tCube> &cubimage = map (c);
                hashedset<tCube> ximage = cubimage;
                if (indexmap)
                        ximage. add (c);
                ximage. remove (img);
                cubreducequiet (img, ximage);

                // if the image could not be reduced, skip the cube
                if (!ximage. empty ())
                        continue;

                // make sure that the acyclicity of the map is not spoiled
                if (checkacyclic && !remainsacyclic (map, c, other))
                        continue;

                // add the image of this cube to the image of the map
                if (!quiet && !cubimage. empty ())
                {
                        sseq << "R\n";
                        for (int_t i = 0; i < cubimage. size (); ++ i)
                                sseq << '2' << cubimage [i] << '\n';
                        if (indexmap)
                                sseq << '2' << c << '\n';
                }
                img. add (cubimage);
                if (indexmap)
                        img. add (c);

                // remove from 'imgsrc' all the cubes added to 'img'
                imgsrc. remove (cubimage);
                if (indexmap)
                        imgsrc. remove (c);

                // add the neighbors from 'cset' to the queue
                b. clearall (maxneighbors);
                getneighbors (c, &b, cset, &queue, 0);

                // move this cube from 'cset' to 'other'
                if (!quiet)
                        sseq << "L\n" << '2' << c << '\n';
                cset. remove (c);
                other. add (c);
        }

        // erase the temporary progress indicator
        if (!quiet)
                scon << "\b \b";

        // return the number of cubes removed from 'cset'
        return prev - cset. size ();
} /* cubexpand */

template<class celltype >
celltype chomp::homology::CubicalBoundaryCell ( const celltype &  q,
int  i,
bool  onlyexisting 
) [inline]

Returns the i-th boundary element of a cell.

If only existing cells are considered, returns '*this' if the requested boundary cell doesn't exist.

For a cubical cell whose non-zero intervals in the Cartesian product are [p1-,p1+], [p2-,p2+], etc., the boundary is an alternating sum of cells in which these intervals are replaced by single elements, first by those with larger values (signs begin with a '+'), and then by those with smaller values (signs begin with a '-').

Definition at line 73 of file cellmain.h.

Referenced by boundarycell(), and CubicalBoundaryCell().

{
        typedef typename celltype::CoordType coordtype;
        coordtype origleft [celltype::MaxDim];
        q. leftcoord (origleft);
        coordtype origright [celltype::MaxDim];
        q. rightcoord (origright);
        coordtype newcoord [celltype::MaxDim];
        int sd = q. spacedim ();
        int d = q. dim ();
        int count = 0;

        // if this is the first set of cells
        if (i < d)
        {
                for (int j = 0; j < sd; ++ j)
                {
                        // copy the coordinates of the right vertex
                        newcoord [j] = origleft [j];

                        // modify the desired coordinate and finalize
                        if (origleft [j] != origright [j])
                        {
                                if (i == count ++)
                                {
                                        newcoord [j] = origright [j];
                                        for (j = j + 1; j < sd; ++ j)
                                                newcoord [j] = origleft [j];
                                        if (onlyexisting &&
                                                !celltype::PointBase::check
                                                        (newcoord, sd))
                                                return q;
                                        return celltype (newcoord,
                                                origright, sd);
                                }
                        }
                }
                throw "False cubical cell's dimension.";
        }
        else
        {
                i -= d;
                for (int j = 0; j < sd; ++ j)
                {
                        // copy the coordinates of the right vertex
                        newcoord [j] = origright [j];

                        // modify the desired coordinate and finalize
                        if (origleft [j] != origright [j])
                        {
                                if (i == count ++)
                                {
                                        newcoord [j] = origleft [j];
                                        for (j = j + 1; j < sd; j ++)
                                                newcoord [j] = origright [j];
                                        if (onlyexisting &&
                                                !celltype::PointBase::check
                                                        (newcoord, sd))
                                                return q;
                                        return celltype (origleft,
                                                newcoord, sd);
                                }
                        }
                }
                throw "False dimension of a cubical cell.";
        }
} /* boundarycell */

template<class celltype >
celltype chomp::homology::CubicalBoundaryCell ( const celltype &  q,
int  i 
) [inline]

Returns the i-th cell in the boundary of the given cell.

Definition at line 144 of file cellmain.h.

References CubicalBoundaryCell().

{
        return CubicalBoundaryCell (q, i, false);
} /* boundarycell */

template<class celltype >
int chomp::homology::CubicalBoundaryCoef ( const celltype &  q,
int  i 
) [inline]

Returns the i-th coefficient in the boundary of a cubical cell.

Definition at line 158 of file cellmain.h.

Referenced by boundarycoef().

{
        int d = q. dim ();
        if (i >= d)
                i -= d - 1;
        return (i & 1) ? 1 : -1;
} /* boundarycoef */

template<class celltype >
int chomp::homology::CubicalBoundaryLength ( const celltype &  q  )  [inline]

Returns the length of the boundary of a cubical cell.

Definition at line 151 of file cellmain.h.

Referenced by boundarylength().

{
        return q. dim () << 1;
} /* boundarylength */

template<class tCube >
int_t chomp::homology::cubreduce ( const hashedset< tCube > &  maincset,
hashedset< tCube > &  cset 
) [inline]

Reduces a pair of sets of cubes for relative homology computation.

Returns the number of cubes removed from both sets.

Definition at line 504 of file cubisets.h.

References cubreducequiet().

Referenced by reducepair().

{
        return cubreducequiet (maincset, cset, false);
} /* cubreduce */

template<class tCube >
int_t chomp::homology::cubreduce ( hashedset< tCube > &  cset,
hashedset< tCube > &  other,
mvmap< tCube, tCube > &  cubmap,
const hashedset< tCube > &  keep 
) [inline]

Reduces a pair of sets of cubes for relative homology computation.

Does not remove any cubes from the set 'keep'. Additionally makes sure that the acyclicity of the given map is preserved. Returns the number of cubes removed from both sets.

Definition at line 764 of file cubisets.h.

References cubreducequiet().

{
        return cubreducequiet (cset, other, cubmap, keep, false);
} /* cubreduce */

template<class tCube >
int_t chomp::homology::cubreduce ( hashedset< tCube > &  cset,
hashedset< tCube > &  other,
const hashedset< tCube > &  keep 
) [inline]

Reduces a pair of sets of cubes for relative homology computation.

Does not remove any cubes from the set 'keep'. Returns the number of cubes removed from both sets.

Definition at line 786 of file cubisets.h.

References cubreducequiet().

{
        return cubreducequiet (cset, other, keep, false);
} /* cubreduce */

template<class tCube >
int_t chomp::homology::cubreducequiet ( const hashedset< tCube > &  maincset,
hashedset< tCube > &  cset,
bool  quiet = true 
)

Reduce the set 'cset' towards 'maincset'.

These sets must be disjoint. If 'quiet' is set to true, then suppresses any messages. Returns the number of cubes removed from 'cset'.

Definition at line 379 of file cubisets.h.

References acyclic(), addcubeneighbors(), getmaxneighbors(), makesetunion(), scon, and sseq.

Referenced by acyclic(), cubexpand(), cubreduce(), cubreducequiet(), and remainsacyclic().

{
        // remember the initial number of cubes in the set to be reduced
        int_t prev = cset. size ();

        // if the case is trivial, return the answer
        if (!prev)
                return 0;

        // determine the space dimension
        int dim = cset [0]. dim ();

        // compute the maximal number of neighbors of a cube
        int_t maxneighbors = getmaxneighbors (dim);

        // prepare a bitfield and allocate it if necessary
        static BitField b;
        static int_t _maxneighbors = 0;
        if (maxneighbors != _maxneighbors)
        {
                if (_maxneighbors > 0)
                        b. free ();
                _maxneighbors = maxneighbors;
                b. allocate (maxneighbors);
        }

        // prepare a queue for cubes to check
        hashedset<tCube> queue;

        // prepare a counter for displaying the progress of computations
        int_t count = 0;

        // remove cubes which can be removed
        // and add their neighbors to the queue
        for (int_t i = 0; i < cset. size (); ++ i)
        {
                // show progress indicator
                ++ count;
                if (!quiet && !(count % 373))
                        scon << std::setw (10) << count <<
                                "\b\b\b\b\b\b\b\b\b\b";

                // clear the neighborbits
                b. clearall (maxneighbors);

                // prepare a set for storing the neighbors of the cube
                hashedset<tCube> neighbors;

                // if the neighborhood of the cube is not acyclic, skip it
                if (!acyclic (cset [i], dim, makesetunion (maincset, cset),
                        &b, maxneighbors, &neighbors))
                {
                        continue;
                }

                // remove this cube from the queue
                queue. remove (cset [i]);

                // determine the neighbors of this cube (if not done yet)
                // and add the computed neighbors of this cube to the queue
                addcubeneighbors (cset [i], dim, cset, &b, neighbors,
                        queue, maincset);

                // remove this cube from 'cset'
                if (!quiet)
                        sseq << '0' << cset [i] << '\n';
                cset. removenum (i);
                -- i;
        }

        // add a temporary progress indicator and reset the counter
        if (!quiet)
                scon << "*";
        count = 0;

        // take cubes from the queue and remove them if possible
        while (!queue. empty ())
        {
                // update the progress indicator
                if (!quiet && !(count % 373))
                        scon << std::setw (10) << count <<
                                "\b\b\b\b\b\b\b\b\b\b";
                ++ count;

                // take a cube from the queue
                tCube c = queue [0];
                queue. removenum (0);

                // clear the neighborbits
                b. clearall (maxneighbors);

                // prepare a set for storing the neighbors of the cube
                hashedset<tCube> neighbors;

                // if the neighborhood of the cube is not acyclic, skip it
                if (!acyclic (c, dim, makesetunion (maincset, cset),
                        &b, maxneighbors, &neighbors))
                {
                        continue;
                }

                // determine the neighbors of this cube (if not done yet)
                // and add the computed neighbors of this cube to the queue
                addcubeneighbors (c, dim, cset, &b, neighbors,
                        queue, maincset);

                // remove the cube from 'cset'
                if (!quiet)
                        sseq << '0' << c << '\n';
                cset. remove (c);
        }

        // erase the temporary progress indicator
        if (!quiet)
                scon << "\b \b";

        // return the number of cubes removed from 'added'
        return prev - cset. size ();
} /* cubreducequiet */

template<class tCube >
int_t chomp::homology::cubreducequiet ( hashedset< tCube > &  cset,
hashedset< tCube > &  other,
mvmap< tCube, tCube > &  map,
const hashedset< tCube > &  keep,
bool  quiet = true 
)

Reduces a pair of sets of cubes for relative homology computation.

Does not remove any cubes from the set 'keep'. Additionally makes sure that the acyclicity of the given map is preserved. If 'quiet' is set to true then suppresses any messages. Returns the number of cubes removed from both sets.

Definition at line 516 of file cubisets.h.

References acyclic(), acyclic_rel(), addcubeneighbors(), getmaxneighbors(), makesetunion(), remainsacyclic(), scon, and sseq.

{
        // determine if the acyclicity of the map should be considered
        bool checkacyclic = !map. getdomain (). empty ();

        // remember the initial number of cubes in both sets
        int_t prev = cset. size () + other. size ();

        // if the case is trivial, return the answer
        if (cset. empty ())
        {
                if (!other. empty ())
                {
                        hashedset<tCube> empty;
                        other = empty;
                }
                return prev;
        }

        // determine the space dimension
        int dim = cset [0]. dim ();

        // compute the maximal number of neighbors of a cube
        int_t maxneighbors = getmaxneighbors (dim);

        // prepare a bitfield and allocate it if necessary
        static BitField b;
        static int_t _maxneighbors = 0;
        if (maxneighbors != _maxneighbors)
        {
                if (_maxneighbors > 0)
                        b. free ();
                _maxneighbors = maxneighbors;
                b. allocate (maxneighbors);
        }

        // prepare a queue for cubes to check
        hashedset<tCube> queue;

        // prepare a counter for displaying the progress of computations
        int_t count = 0;

        // go through the other set, remove cubes which can be removed,
        // and add their neighbors to the queue
        for (int_t i = 0; i < other. size (); ++ i)
        {
                // show the progress indicator
                ++ count;
                if (!quiet && !(count % 373))
                        scon << std::setw (10) << count <<
                                "\b\b\b\b\b\b\b\b\b\b";

                // if the cube should be kept, skip it
                if (keep. check (other [i]))
                        continue;

                // clear the neighborbits
                b. clearall (maxneighbors);

                // prepare a set for storing the neighbors of the cube
                hashedset<tCube> neighbors, *none = 0;

                // if the cube cannot be removed, skip it
                if (!acyclic_rel (other [i], dim, cset, other, &b,
                        maxneighbors, none, &neighbors))
                {
                        continue;
                }

                // make sure that the acyclicity of the map on A is OK
                if (checkacyclic && !remainsacyclic (map, other [i], other))
                        continue;

                // make sure that the acyclicity of the map on X is OK
                if (checkacyclic && !remainsacyclic (map, other [i],
                        other, &cset))
                        continue;

                // remove this cube from the queue
                queue. remove (other [i]);

                // determine the neighbors of this cube (if not done yet)
                // and add the computed neighbors of this cube to the queue
                addcubeneighbors (other [i], dim, other, &b, neighbors,
                        queue, keep);

                // remove this cube from 'other'
                if (!quiet)
                        sseq << '0' << other [i] << '\n';
                other. removenum (i);
                -- i;
        }

        // show a temporary progress indicator and reset the counter
        if (!quiet)
                scon << '.';
        count = 0;

        // go through the main set, remove cubes which can be removed,
        // and add their neighbors to the queue
        for (int_t i = 0; i < cset. size (); ++ i)
        {
                // show progress indicator
                if (!quiet && !(count % 373))
                        scon << std::setw (10) << count <<
                                "\b\b\b\b\b\b\b\b\b\b";
                ++ count;

                // if this cube should be kept, skip it
                if (keep. check (cset [i]))
                        continue;

                // clear the neighborbits
                b. clearall (maxneighbors);

                // prepare a set for storing the neighbors of the cube
                hashedset<tCube> neighbors;

                // if the neighborhood of the cube is not acyclic, skip it
                if (!acyclic (cset [i], dim, makesetunion (cset, other),
                        &b, maxneighbors, &neighbors))
                {
                        continue;
                }

                // make sure that the acyclicity of the map on X is OK
                if (checkacyclic && !remainsacyclic (map, cset [i],
                        cset, &other))
                {
                        continue;
                }

                // remove this cube from the queue
                queue. remove (cset [i]);

                // determine the neighbors of this cube (if not done yet)
                // and add the computed neighbors of this cube to the queue
                addcubeneighbors (cset [i], dim, makesetunion (cset, other),
                        &b, neighbors, queue, keep);

                // remove this cube from 'cset'
                if (!quiet)
                        sseq << '0' << cset [i] << '\n';
                cset. removenum (i);
                -- i;
        }

        // update the temporary progress indicator and reset the counter
        if (!quiet)
                scon << "\b*";
        count = 0;

        // take cubes from the queue and remove them if possible
        while (!queue. empty ())
        {
                // update the progress indicator
                if (!quiet && !(count % 373))
                        scon << std::setw (10) << count <<
                                "\b\b\b\b\b\b\b\b\b\b";
                ++ count;

                // take a cube from the queue and remove it from the queue
                tCube c = queue [0];
                queue. removenum (0);

                // clean the neighborbits
                b. clearall (maxneighbors);

                // if this cube belongs to the other set...
                if (other. check (c))
                {
                        // prepare a set for storing the neighbors
                        hashedset<tCube> neighbors;

                        if (!acyclic_rel (c, dim, cset, other, &b,
                                maxneighbors, &cset, &other))
                        {
                                continue;
                        }

                        // make sure that the map's acyclicity on A is OK
                        if (checkacyclic && !remainsacyclic (map, c, other))
                                continue;

                        // make sure that the map's acyclicity on X is OK
                        if (checkacyclic && !remainsacyclic (map, c,
                                other, &cset))
                                continue;

                        // determine the neighbors of this cube (if not yet)
                        // and add the computed neighbors to the queue
                        addcubeneighbors (c, dim, makesetunion (cset, other),
                                &b, neighbors, queue, keep);

                        // remove the cube from the other set
                        if (!quiet)
                                sseq << '0' << c << '\n';
                        other. remove (c);
                }

                // otherwise, if this cube belongs to 'cset'...
                else
                {
                        // prepare a set for storing the neighbors
                        hashedset<tCube> neighbors;

                        // if the neighborhood of the cube is not acyclic
                        // then skip it
                        if (!acyclic (c, dim, makesetunion (cset, other),
                                &b, maxneighbors, &neighbors))
                        {
                                continue;
                        }

                        // make sure that the acyclicity of the map on X is OK
                        if (checkacyclic && !remainsacyclic (map, c,
                                cset, &other))
                        {
                                continue;
                        }

                        // determine the neighbors of this cube (if not yet)
                        // and add the computed neighbors to the queue
                        addcubeneighbors (c, dim, makesetunion (cset, other),
                                &b, neighbors, queue, keep);

                        // remove the cube from 'cset'
                        if (!quiet)
                                sseq << '0' << c << '\n';
                        cset. remove (c);
                }
        }

        // erase the temporary progress indicator
        if (!quiet)
                scon << "\b \b";

        // return the number of cubes removed from both sets
        return prev - cset. size () - other. size ();
} /* cubreducequiet */

template<class tCube >
int_t chomp::homology::cubreducequiet ( hashedset< tCube > &  cset,
hashedset< tCube > &  other,
const hashedset< tCube > &  keep,
bool  quiet = true 
) [inline]

Reduces a pair of sets of cubes for relative homology computation.

Does not remove any cubes from the set 'keep'. If 'quiet' is set to true, then suppresses any messages. Returns the number of cubes removed from both sets.

Definition at line 775 of file cubisets.h.

References cubreducequiet().

{
        mvmap<tCube,tCube> emptymap;
        return cubreducequiet (cset, other, emptymap, keep, quiet);
} /* cubreducequiet */

const char* chomp::homology::currenttime ( void   )  [inline]

Retrieves the current time as a pointer to a C-style string.

Definition at line 430 of file textfile.h.

Referenced by chomp::multiwork::mwSubCoordinator< dim, coord >::mwSubCoordinator(), and chomp::multiwork::mwSubCoordinator< dim, coord >::~mwSubCoordinator().

{
        std::time_t t;
        std::time (&t);
        return std::asctime (std::localtime (&t));
} /* currenttime */

template<class cell , class euclidom >
void chomp::homology::decreasedimension ( gcomplex< cell, euclidom > &  Acompl,
int  dim,
const char *  name 
)

Decreases the dimension of the geometric complex by adding boundary cells to all the cells on higher dimensions and then removing these cells.

Definition at line 814 of file homtools.h.

References addboundaries(), and sout.

Referenced by Homology(), Homology2l(), and chomp::homology::gcomplex< cell, euclidom >::remove().

{
        if (Acompl. dim () <= dim)
                return;
        if (dim < 0)
                dim = 0;
        sout << "Adding to " << name << " boundaries of high-dim " <<
                cell::pluralname () << "... ";
        int_t howmany = 0;
        for (int i = Acompl. dim (); i > dim; -- i)
        {
                sout << '.';
                howmany += Acompl. addboundaries (i);
                Acompl. removeall (i);
        }
        sout << ' ' << howmany << " added.\n";
        return;
} /* decreasedimension */

template<class coordtype >
void chomp::homology::enhance ( tPointset< coordtype > &  p  ) 

Enhances the set of points by adding to it all the neighbors of all the points in the set.

Definition at line 1939 of file pointset.h.

References enhancepoint().

{
        int_t size = p. size ();
        for (int_t i = 0; i < size; ++ i)
                enhancepoint (p, p [i]);

        return;
} /* enhance */

template<class coordtype >
void chomp::homology::enhancepoint ( tPointset< coordtype > &  p,
coordtype *  c 
)

Enhances the set by adding the neighborhood of the point with given coordinates.

Definition at line 1920 of file pointset.h.

Referenced by enhance(), and enhancepoint().

{
        tNeighbors<coordtype> neigh (c, p. dimension ());

        while ((c = neigh. get ()) != NULL)
                p. add (c);

        return;
} /* enhancepoint */

template<class coordtype >
void chomp::homology::enhancepoint ( tPointset< coordtype > &  p,
int_t  n 
)

Enhances the set by adding the neighborhood of the point with given number.

Definition at line 1931 of file pointset.h.

References enhancepoint().

{
        enhancepoint (p, p [n]);

        return;
} /* enhancepoint */

template<class TSetOfCubes , class TMap >
int chomp::homology::ExitSetM ( const TSetOfCubes &  N,
const TSetOfCubes &  Q1,
const TMap &  F,
TSetOfCubes &  resultQ2 
)

Computes iteratively Q2 := (F (Q1 + Q2) - Q1) * N.

Definition at line 329 of file indxpalg.h.

Referenced by IndexPairM().

{
        // compute Q2 := (F (Q1 \cup Q2) \setminus Q1) \cap N
        int_t countQ1 = Q1. size ();
        int_t n = 0;

        // for all the cubes in Q1 and Q2
        while (n < countQ1 + resultQ2. size ())
        {
                // compute the image of the cube
                const TSetOfCubes &img =
                        F ((n < countQ1) ? Q1 [n] : resultQ2 [n - countQ1]);

                // add those image cubes to Q2 which are in N \setminus Q1
                int_t countImg = img. size ();
                for (int_t i = 0; i < countImg; ++ i)
                {
                        if (!N. check (img [i]))
                                continue;
                        if (Q1. check (img [i]))
                                continue;
                        resultQ2. add (img [i]);
                }
                ++ n;
        }
        return 0;
} /* ExitSetM */

template<class cubsettype >
void chomp::homology::expandAinX ( cubsettype &  Xcubes,
cubsettype &  Acubes,
const char *  Xname,
const char *  Aname 
)

Expands the other element of the pair into the main portion of the set.

Definition at line 581 of file homtools.h.

References cubexpand(), and sout.

Referenced by Homology(), and Homology2l().

{
        if (Xcubes. empty () || Acubes. empty ())
                return;
        sout << "Expanding " << Aname << " in " << Xname << "... ";
        int_t count = cubexpand (Xcubes, Acubes);
        sout << count << " cubes moved to " << Aname << ", " <<
                Xcubes. size () << " left in " << Xname << "\\" << Aname <<
                ".\n";
        return;
} /* expandAinX */

template<class cubsettype , class maptype >
void chomp::homology::expandAinX ( cubsettype &  Xcubes,
cubsettype &  Acubes,
cubsettype &  Ycubes,
cubsettype &  Bcubes,
const maptype &  Fcubmap,
const char *  Xname,
const char *  Aname,
const char *  Bname,
bool  indexmap,
bool  checkacyclic 
)

Expands the other element of the pair into the main portion of the set.

Definition at line 596 of file homtools.h.

References cubexpand(), and sout.

{
        if (Xcubes. empty () || Acubes. empty ())
                return;
        sout << "Expanding " << Aname << " in " << Xname << "... ";
        int_t prevB = Bcubes. size ();
        int_t prevY = Ycubes. size ();
        int_t count = cubexpand (Xcubes, Acubes, Ycubes, Bcubes,
                Fcubmap, indexmap, checkacyclic);
        sout << count << " moved to " << Aname << ", " << Xcubes. size () <<
                " left in " << Xname << "\\" << Aname << ", " <<
                (Bcubes. size () - prevB) << " added to " << Bname << ".\n";
        if (prevY - Ycubes. size () != Bcubes. size () - prevB)
                sout << "WARNING: The image of " << Xname << "\\" << Aname <<
                        " was not contained in Y. "
                        "The result can be wrong!\n";
        return;
} /* expandAinX */

template<class euclidom >
chain<euclidom>** chomp::homology::ExtractGenerators ( const chaincomplex< euclidom > &  cx,
chain< euclidom > *  hom,
int  maxlevel 
)

Extracts homology generators from a chain complex in the simple form.

Returns a pointer to an allocated table of tables of chains each of which defines one generator of the homology module at the specified level. Returns the zero pointer in case of error or if the homology is trivial.

Definition at line 340 of file homology.h.

Referenced by Homology(), and Homology2l().

               : Chain **ExtractGenerators (const ChainComplex cx,
//      Chain *hom, int maxlevel).
{
        // if the maximal level is negative, then there is nothing to do
        if (maxlevel < 0)
                return 0;

        // create a table of tables of chains
        chain<euclidom> **gen = new chain<euclidom> * [maxlevel + 1];

        // extract generators for each homology level separately
        for (int q = 0; q <= maxlevel; ++ q)
        {
                // create a table of chains to hold the generators
                gen [q] = (hom [q]. size ()) ?
                        new chain<euclidom> [hom [q]. size ()] : 0;

                // copy the corresponding chain from internal data of 'cx'
                for (int i = 0; i < hom [q]. size (); ++ i)
                {
                        gen [q] [i] =
                                cx. gethomgen (q, hom [q]. num (i));
                }
        }

        return gen;
} /* ExtractGenerators */

void chomp::homology::fileerror ( const char *  filename,
const char *  what = "open" 
) [inline]

Throws a message about the inability to do something with a file.

By default this is a problem with opening the file, but another name of this action may be provided.

Definition at line 508 of file textfile.h.

References ERRORMSG, and THROW.

Referenced by ReadBitmapFile(), readmapdomain(), readmapimage(), readmaprestriction(), readtheset(), savetheset(), and scancubes().

{
        ERRORMSG << "Cannot " << what << " the file '" <<
                filename << "'." << THROW
        return;
} /* fileerror */

template<class coordtype >
int_t chomp::homology::findboundarypoint ( tPointset< coordtype > &  p,
int_t  n,
int  direction = 1 
)

Finds a boundary point starting at the given one.

Call with n = 0 to find the first boundary point. Direction: 1 - in ascending order, -1 - in descending order. Returns -1 if not found.

Definition at line 1813 of file pointset.h.

References attheborder().

{
        if (direction >= 0)
        {
                if (n >= p. size ())
                        return -1;
                if (n < 0)
                        n = 0;
                int_t size = p. size ();
                while (n < size)
                {
                        if (attheborder (p, p [n]))
                                return n;
                        else
                                ++ n;
                }
                return -1;
        }
        else
        {
                if (n < 0)
                        return -1;
                if (n >= p. size ())
                        n = p. size () - 1;
                while (n >= 0)
                {
                        if (attheborder (p, p [n]))
                                return n;
                        else
                                -- n;
                }
                return -1;
        }
} /* findboundarypoint */

template<class coordtype >
int_t chomp::homology::findboundarypoint ( tPointset< coordtype > &  p,
tPointset< coordtype > &  q,
int_t  n,
int  direction = 1 
)

Finds a point in 'p' at the boundary of the union of 'p' and 'q'.

Definition at line 1849 of file pointset.h.

References countneighbors(), and OUTSIDE.

{
        if (direction >= 0)
        {
                if (n >= p. size ())
                        return -1;
                if (n < 0)
                        n = 0;
                while (n < p. size ())
                {
                        if (countneighbors (p, q, p [n], OUTSIDE, 1))
                                return n;
                        else
                                ++ n;
                }
                return -1;
        }
        else
        {
                if (n < 0)
                        return -1;
                if (n >= p. size ())
                        n = p. size () - 1;
                while (n >= 0)
                {
                        if (countneighbors (p, q, p [n], OUTSIDE, 1))
                                return n;
                        else
                                -- n;
                }
                return -1;
        }
} /* findboundarypoint */

template<class element >
int_t chomp::homology::findelem ( const multitable< element > &  tab,
const element &  e,
int_t  len 
)

Finds the given element in the table of given length.

Return its index or -1 if not found.

Definition at line 706 of file gcomplex.h.

Referenced by chomp::homology::gcomplex< cell, euclidom >::collapse().

{
        if (len <= 0)
                return -1;

        // prepare a random search starting point and step increase
        int_t i = static_cast<int_t> (std::rand ()) % len;
        if (i < 0)
                i = static_cast<int_t> (1) - i;
        int_t step = static_cast<int_t> (std::rand () + 17) % len;
        if (step < 0)
                step = static_cast<int_t> (1) - step;
        if (step < 17)
                step = 17;
        if (step > len)
                step = len >> 1;
        if (step < 1)
                step = 1;

        // jump randomly in the table to find some element if possible
        int_t jumping = len >> 1;
        while (jumping --)
        {
        //      if ((i < 0) || (i >= len))
        //              throw "Wrong random number.";
                if (tab (i) == e)
                        return i;
        //      if ((i + 1 < len) && (tab (i + 1) == e))
        //              return i + 1;
                if (jumping)
                {
                        i += step;
                        if (i >= len)
                                i -= len;
                }
        }

        // if not found, try finding the element thoroughly
        for (int_t i = 0; i < len; ++ i)
        {
                if (tab (i) == e)
                        return i;
        }
        return -1;
} /* findelem */

int_t chomp::homology::getmaxneighbors ( int  dim  )  [inline]

Returns the maximal number of neighbors of a cube: 3^dim - 1.

Definition at line 61 of file neighbor.h.

Referenced by acyclic(), addneighbors(), cubexpand(), cubreducequiet(), getneighbors(), getneighbors_generate(), and remainsacyclic().

{
        if (dim < 0)
                return 0;
        const int maxdim = 17;
        const int neighbors [maxdim] = {0, 2, 8, 26, 80, 242, 728,
                2186, 6560, 19682, 59048, 177146, 531440, 1594322,
                4782968, 14348906, 43046720};
        if (dim < maxdim)
                return neighbors [dim];
        int_t ncount = neighbors [maxdim - 1] + 1;
        for (int i = maxdim - 1; i < dim; ++ i)
                ncount *= 3;
        return (ncount - 1);
} /* getmaxneighbors */

template<class tCube , class tCubeSet1 , class tCubeSet2 >
int_t chomp::homology::getneighbors ( const tCube &  q,
BitField *  bits,
const tCubeSet1 &  theset,
tCubeSet2 *  neighbors,
int_t  limit 
)

Gets neighbors of the given cube from the given set and indicates them in the bit field provided.

Returns the number of neighbors. If the limit is nonzero then quits after having found that many neighbors.

Definition at line 303 of file neighbor.h.

References getmaxneighbors(), getneighbors_generate(), and getneighbors_scan().

Referenced by acyclic(), acyclic_rel(), addcubeneighbors(), cubexpand(), getneighbors(), remainsacyclic(), restrictAtoneighbors(), and chomp::homology::tCube2l< tCube >::setlayers().

{
        // if the answer is trivial, return it
        if (theset. empty ())
                return 0;

        // if the set is small
        if (theset. size () < getmaxneighbors (q. dim ()))
        {
                return getneighbors_scan (q, bits, theset, neighbors, limit);
        }
        else
        {
                return getneighbors_generate (q, bits, theset, neighbors,
                        limit);
        }
} /* getneighbors */

template<class tCube , class tCubeSet >
int_t chomp::homology::getneighbors ( const tCube &  q,
BitField *  bits,
const tCubeSet &  theset,
int_t  limit 
)

Definition at line 327 of file neighbor.h.

References getneighbors().

{
        hashedset<typename tCubeSet::value_type> *none = 0;
        return getneighbors (q, bits, theset, none, limit);
} /* getneighbors */

template<class tCube , class tCubeSet1 , class tCubeSet2 >
int_t chomp::homology::getneighbors_generate ( const tCube2l< tCube > &  q2l,
BitField *  bits,
const tCubeSet1 &  theset,
tCubeSet2 *  neighbors,
int_t  limit 
)

Specialization of the function which gets neighbors of the given cube by generating all the possible neighbors and checking if they are present in the given set.

Definition at line 1047 of file twolayer.h.

References bit2neighbor(), getmaxneighbors(), intersection2l(), chomp::homology::tCube2l< tCube >::layer0(), and chomp::homology::tCube2l< tCube >::layer1().

{
        // decompose the cube into its components
        const tCube &q0 = q2l. cube ();
        typename tCube2l<tCube>::LayerType l0 (q2l. layer ());

        // determine the upper bound for the number of neighbors
        int_t maxneighbors = getmaxneighbors (q0. dim ());

        // determine the set of cubes at layer 0
        const hashedset<tCube> &layer0 = tCube2l<tCube>::layer0 ();

        // determine the set of cubes at layer 1
        const hashedset<tCube> &layer1 = tCube2l<tCube>::layer1 ();

        // prepare a counter for the number of neighbors
        int_t count = 0;

        // go through all possible neighbor numbers
        for (int_t number = 0; number < maxneighbors; ++ number)
        {
                // create a neighbor cube using the generic algorithm
                tCube q1 = bit2neighbor (q0, number, true);

                // determine the layer of the neighbor
                int l1 = layer1. check (q1) ? 1 : 0;

                // create the neighbor cube
                tCube2l<tCube> q1l (q1, l1);

                // if this cube is not in the set then skip it
                if (!theset. check (q1l))
                        continue;

                // if the cubes fully intersect then this is easy
                if ((l0 == l1) ||
                        ((l0 == 0) && (l1 == 1) && (layer0. check (q0))) ||
                        ((l0 == 1) && (l1 == 0) && (layer0. check (q1))))
                {
                        // set the appropriate bit in the bit field
                        if (bits)
                                bits -> set (number);
                }
                // otherwise the correct intersection of the cubes
                // must be determined at the boundary between the layers
                else if (!intersection2l (q0, q1, bits))
                        continue;

                // add the cube to the set of neighbors
                if (neighbors)
                        neighbors -> add (q1l);

                // increase the counter
                ++ count;

                // if this is enough then finish
                if (limit && (count >= limit))
                        return count;
        }

        return count;
} /* getneighbors_generate */

template<class tCube , class tCubeSet1 , class tCubeSet2 >
int_t chomp::homology::getneighbors_generate ( const tCube &  q,
BitField *  bits,
const tCubeSet1 &  theset,
tCubeSet2 *  neighbors,
int_t  limit 
)

Gets neighbors of the given cube from the given set and indicates them in the bit field provided.

Returns the number of neighbors. If the limit is nonzero then quits after having found that many neighbors. Generates all the possible neighbors.

Definition at line 256 of file neighbor.h.

References bit2neighbor(), and getmaxneighbors().

Referenced by getneighbors().

{
        // determine the upper bound for the number of neighbors
        int_t maxneighbors = getmaxneighbors (q. dim ());

        // prepare a counter for the number of neighbors
        int_t count = 0;

        // go through all possible neighbor numbers
        for (int_t number = 0; number < maxneighbors; ++ number)
        {
                // create a neighbor cube
                tCube neighbor = bit2neighbor (q, number);

                // if the neighbor doesn't exist, ignore it
                if (neighbor == q)
                        continue;

                // if this cube is not in the set, ignore it
                if (!theset. check (neighbor))
                        continue;

                // set the appropriate bit in the bit field
                if (bits)
                        bits -> set (number);

                // add the cube to the set of neighbors
                if (neighbors)
                        neighbors -> add (neighbor);

                // increase the counter
                ++ count;

                // if this is enough then finish
                if (limit && (count >= limit))
                        return count;
        }

        return count;
} /* getneighbors_generate */

template<class tCube , class tCubeSet1 , class tCubeSet2 >
int_t chomp::homology::getneighbors_scan ( const tCube2l< tCube > &  q2l,
BitField *  bits,
const tCubeSet1 &  theset,
tCubeSet2 *  neighbors,
int_t  limit 
)

Specialization of the function which gets neighbors of the given cube by scanning the entire set of possible neighbors.

Definition at line 980 of file twolayer.h.

References intersection2l(), chomp::homology::tCube2l< tCube >::layer0(), and neighbor2bit().

{
        // decompose the cube into its components
        const tCube &q0 = q2l. cube ();
        typename tCube2l<tCube>::LayerType l0 (q2l. layer ());

        // determine the set of cubes at layer 0
        const hashedset<tCube> &layer0 = tCube2l<tCube>::layer0 ();

        // prepare a counter for the number of neighbors
        int_t count = 0;

        // go through all the elements in the set
        for (int_t i = 0; i < theset. size (); ++ i)
        {
                // take the cube from the set
                const tCube2l<tCube> &q1l = theset [i];

                // if this is the current cube then ignore it
                if (q1l == q2l)
                        continue;

                // decompose the cube into its components
                const tCube &q1 = q1l. cube ();
                typename tCube2l<tCube>::LayerType l1 (q1l. layer ());

                // determine the number of this neighbor
                int_t number = neighbor2bit (q0, q1);

                // if not neighbor then ignore it
                if (number < 0)
                        continue;

                // if the cubes fully intersect then this is easy
                if ((l0 == l1) ||
                        ((l0 == 0) && (l1 == 1) && (layer0. check (q0))) ||
                        ((l0 == 1) && (l1 == 0) && (layer0. check (q1))))
                {
                        // set the appropriate bit in the bit field
                        if (bits)
                                bits -> set (number);
                }
                // otherwise the correct intersection of the cubes
                // must be determined at the boundary between the layers
                else if (!intersection2l (q0, q1, bits))
                        continue;

                // add the cube to the set of neighbors
                if (neighbors)
                        neighbors -> add (q1l);

                // increase the counter
                ++ count;

                // if this is enough then finish
                if (limit && (count >= limit))
                        return count;
        }

        return count;
} /* getneighbors_scan */

template<class tCube , class tCubeSet1 , class tCubeSet2 >
int_t chomp::homology::getneighbors_scan ( const tCube &  q,
BitField *  bits,
const tCubeSet1 &  theset,
tCubeSet2 *  neighbors,
int_t  limit 
)

Gets neighbors of the given cube from the given set and indicates them in the bit field provided.

Returns the number of neighbors. If the limit is nonzero then quits after having found that many neighbors. Scans through the entire set of cubes.

Definition at line 212 of file neighbor.h.

References neighbor2bit().

Referenced by getneighbors().

{
        // prepare a counter for the number of neighbors
        int_t count = 0;

        // go through all the elements in the set
        for (int_t i = 0; i < theset. size (); ++ i)
        {
                // if this is the current cube, ignore it
                if (theset [i] == q)
                        continue;

                // determine the number of this neighbor
                int_t number = neighbor2bit (q, theset [i]);

                // if not neighbor, ignore it
                if (number < 0)
                        continue;

                // set the corresponding bit in the bit field
                if (bits)
                        bits -> set (number);

                // add the cube to the set of neighbors
                if (neighbors)
                        neighbors -> add (theset [i]);

                // increase the counter
                ++ count;

                // if this is enough then finish
                if (limit && (count >= limit))
                        return count;
        }

        return count;
} /* getneighbors_scan */

template<class wType , class matrix >
void chomp::homology::graph2matrix ( const diGraph< wType > &  g,
matrix &  m 
) [inline]

Creates the adjacency matrix of the given graph.

m [i] [j] is set to 1 if the graph g contains the edge i -> j, using the assignment operator.

Definition at line 3832 of file digraph.h.

Referenced by transitiveReduction().

{
        int_t nVert = g. countVertices ();
        for (int_t v = 0; v < nVert; ++ v)
        {
                int_t nEdges = g. countEdges (v);
                for (int_t e = 0; e < nEdges; ++ e)
                {
                        int_t w = g. getEdge (v, e);
                        m [v] [w] = 1;
                }
        }
        return;
} /* graph2matrix */

int_t chomp::homology::hashkey1 ( const word &  w  )  [inline]

Definition at line 233 of file words.h.

{
        int len = w. length ();
        if (!len)
                return 13;
        const char *txt = w. text ();
        int_t code = (static_cast<int_t> (txt [0]) << 7) ^
                (static_cast<int_t> (txt [len - 1]));
        if (len > 3)
                code ^= static_cast<int_t> (txt [2]) << 15;
        return code;
} /* word::hashkey1 */

int_t chomp::homology::hashkey1 ( const unsigned long &  number  )  [inline]

The first hash key for an unsigned int number.

Definition at line 875 of file hashsets.h.

{
        return static_cast<int_t> (number);
} /* hashkey1 */

int_t chomp::homology::hashkey1 ( const unsigned int &  number  )  [inline]

Definition at line 896 of file hashsets.h.

{

int_t chomp::homology::hashkey1 ( const signed int &  number  )  [inline]

Definition at line 897 of file hashsets.h.

{

int_t chomp::homology::hashkey1 ( const signed long &  number  )  [inline]

Definition at line 899 of file hashsets.h.

{

int_t chomp::homology::hashkey1 ( const unsigned short &  number  )  [inline]

Definition at line 900 of file hashsets.h.

{

int_t chomp::homology::hashkey1 ( const signed short &  number  )  [inline]

Definition at line 901 of file hashsets.h.

{

int_t chomp::homology::hashkey1 ( const unsigned char &  number  )  [inline]

Definition at line 902 of file hashsets.h.

{

int_t chomp::homology::hashkey1 ( const signed char &  number  )  [inline]

Definition at line 903 of file hashsets.h.

{

template<class T >
int_t chomp::homology::hashkey1 ( const T &  x  )  [inline]

A template function that extracts the first hash key from an object which has the method "hashkey1".

Provided for backwards compatibility with some data types.

Definition at line 911 of file hashsets.h.

References hashkey1().

{
        return x. hashkey1 ();
}

template<class Number >
int_t chomp::homology::hashkey1 ( const hashNumber< Number > &  n  )  [inline]

The first hashing key.

Definition at line 1020 of file bincube.h.

Referenced by chomp::homology::hashedset< element >::hashfind(), and hashkey1().

{
        return static_cast<int_t> (static_cast<Number> (n));
} /* hashkey1 */

int_t chomp::homology::hashkey2 ( const unsigned short &  number  )  [inline]

Definition at line 900 of file hashsets.h.

{

int_t chomp::homology::hashkey2 ( const word &  w  )  [inline]

Definition at line 246 of file words.h.

{
        int len = w. length ();
        if (!len)
                return 7;
        const char *txt = w. text ();
        int_t code = (static_cast<int_t> (txt [0])) ^
                (static_cast<int_t> (txt [len - 1] << 17));
        if (len > 4)
                code ^= static_cast<int_t> (txt [3]) << 8;
        return code;
} /* word::hashkey2 */

template<class Number >
int_t chomp::homology::hashkey2 ( const hashNumber< Number > &  n  )  [inline]

The second hashing key.

Definition at line 1027 of file bincube.h.

Referenced by chomp::homology::hashedset< element >::hashfind(), and hashkey2().

{
        return static_cast<int_t> (static_cast<Number> (n) ^
                0xFA5A75A7ul) << 5;
} /* hashkey2 */

int_t chomp::homology::hashkey2 ( const unsigned long &  number  )  [inline]

The second hash key for an unsigned int number.

Definition at line 881 of file hashsets.h.

{
        return static_cast<int_t> (number ^ 0xFA5A75A7ul) << 8;
} /* hashkey2 */

int_t chomp::homology::hashkey2 ( const unsigned int &  number  )  [inline]

Definition at line 896 of file hashsets.h.

{

int_t chomp::homology::hashkey2 ( const signed int &  number  )  [inline]

Definition at line 897 of file hashsets.h.

{

int_t chomp::homology::hashkey2 ( const signed long &  number  )  [inline]

Definition at line 899 of file hashsets.h.

{

int_t chomp::homology::hashkey2 ( const signed short &  number  )  [inline]

Definition at line 901 of file hashsets.h.

{

int_t chomp::homology::hashkey2 ( const unsigned char &  number  )  [inline]

Definition at line 902 of file hashsets.h.

{

int_t chomp::homology::hashkey2 ( const signed char &  number  )  [inline]

Definition at line 903 of file hashsets.h.

{

template<class T >
int_t chomp::homology::hashkey2 ( const T &  x  )  [inline]

A template function that extracts the second hash key from an object which has the method "hashkey2".

Provided for backwards compatibility with some data types.

Definition at line 920 of file hashsets.h.

References hashkey2().

{
        return x. hashkey2 ();
}

template<class euclidom >
int chomp::homology::Homology ( chaincomplex< euclidom > &  cx,
const char *  Xname,
chain< euclidom > *&  hom 
)

Transforms the chain complex into a simple form and compute its homology.

The changes of bases are reflected in all the chain maps whose domain or codomain this chain complex is. If the generators of the chain complex are to be retrieved, the input chain complex must be created with a suitable option, and the function ExtractGenerators can be used to extract them. The table 'hom' is allocated or set to 0 in case of trivial homology. Returns the number of the highest nontrivial homology level or -1 if none.

Definition at line 380 of file homology.h.

References sout.

Referenced by ComputeBettiNumbers(), Homology(), and Homology2l().

               : int Homology (ChainComplex &cx, const char *Xname,
//      Chain *&hom).
{
        // initialize the empty table
        hom = 0;

        // determine the dimension of the chain complex
        int Xdim = cx. dim ();
        if (Xdim < 0)
                return -1;

        // compute the homology of the chain complex of X
        sout << "Computing the homology of " << Xname << " over " <<
                euclidom::ringname () << "...\n";
        cx. simple_form ((int *) 0, false);
        cx. simple_homology (hom);

        // determine the highest non-trivial homology level
        int maxlevel = Xdim;
        while ((maxlevel >= 0) && (hom [maxlevel]. size () <= 0))
                -- maxlevel;

        // if the homology is trivial, delete the allocated table (if any)
        if (hom && (maxlevel < 0))
        {
                delete [] hom;
                hom = 0;
        }

        return maxlevel;
} /* Homology */

template<class cell , class euclidom >
int chomp::homology::Homology ( gcomplex< cell, euclidom > &  Xcompl,
const char *  Xname,
chain< euclidom > *&  hom,
chain< euclidom > ***  gen = 0 
)

Computes the homology of a given cubical complex.

All the boundary cells must be present (use the function for pairs with an empty set A or "X. addboundaries ()" to add boundaries if necessary), because missing cells give rise to missing generators of the corresponding chain complex which indicates a relative cubical complex. Destroy the contents of X before running the algebraic computations. If 'gen' is given, the contents of X is not destroyed, and *gen is set to point to a newly allocated table of tables of chains each of which defines one generator of the homology module at a specified level. Returns the number of the highest nontrivial homology level or -1 if none.

Definition at line 426 of file homology.h.

References createchaincomplex(), ExtractGenerators(), Homology(), and sout.

               : Homology (CubicalComplex &Xcompl, const char *Xname,
//      Chain *&hom, Chain ***gen = 0).
{
        // initialize the empty table
        hom = 0;

        // determine the dimension of the cubical complex
        int Xdim = Xcompl. dim ();
        if (Xdim < 0)
                return -1;

        // create a chain complex from the cubical complex X without adding
        // boundaries, as this might be a relative complex with A removed
        chaincomplex<euclidom> cx (Xdim, !!gen);
        sout << "Creating the chain complex of " << Xname << "... ";
        createchaincomplex (cx, Xcompl);
        sout << "Done.\n";

        // forget the geometric cubical complex to release memory
        if (!gen)
        {
                gcomplex<cell,euclidom> empty;
                Xcompl = empty;
        }

        // compute the homology of this chain complex
        int maxlevel = Homology (cx, Xname, hom);

        // extract the generators of homology ('cx' will be lost on 'return')
        if (gen)
                *gen = ExtractGenerators (cx, hom, maxlevel);

        return maxlevel;
} /* Homology */

template<class euclidom , class cubetype >
int chomp::homology::Homology ( hashedset< cubetype > &  Xcubes,
const char *  Xname,
chain< euclidom > *&  hom,
chain< euclidom > ***  gen = 0,
gcomplex< typename cubetype::CellType, euclidom > **  gcompl = 0 
)

Computes the homology of a given set of cubes.

The set is destroyed. If the generators are to be retrieved, the table 'gen' is allocated as in the Homology function for geometric complexes, and the pointer pointed to by 'gcompl' is set to the cubical complex arising in the computations. Returns the number of the highest nontrivial homology level or -1 if none.

Definition at line 470 of file homology.h.

References collapse(), cubes2cells(), Homology(), knownbits, reducepair(), and sout.

               : Homology (SetOfCubes &Xcubes, const char *Xname,
//      Chain *&hom, Chain ***gen = 0, CubicalComplex **gcompl = 0).
{
        // define the type of a set of cubes
        typedef hashedset<cubetype> cubsettype;

        // define the type of a cubical cell
        typedef typename cubetype::CellType celltype;

        // initialize the empty table
        hom = 0;

        // if the set X is empty, the answer is obvious
        if (Xcubes. empty ())
                return -1;

        // determine the dimension of X (note: X is nonempty!)
        int Xspacedim = Xcubes [0]. dim ();

        // allocate a suitable bit field set for the reduction and show msg
        knownbits [Xspacedim];

        // reduce the cubes in X
        cubsettype emptycubes;
        reducepair (Xcubes, emptycubes, emptycubes, Xname, 0);

        // transform the set of cubes X into a set of cells and forget Xcubes
        gcomplex<celltype,euclidom> *Xcompl =
                new gcomplex<celltype,euclidom>;
        cubes2cells (Xcubes, *Xcompl, Xname);
        Xcubes = emptycubes;

        // collapse the set and add boundaries of cells
        collapse (*Xcompl, Xname);

        // if the complex is empty, the result is trivial
        if (Xcompl -> empty ())
        {
                delete Xcompl;
                return -1;
        }

        // make a correction to the dimension of X
        int Xdim = Xcompl -> dim ();
        if (Xdim != Xspacedim)
        {
                sout << "Note: The dimension of " << Xname <<
                        " decreased from " << Xspacedim <<
                        " to " << Xdim << ".\n";
        }

        // compute the homology of the cubical complex
        int maxlevel = Homology (*Xcompl, Xname, hom, gen);

        // deallocate the cubical complex if necessary
        if (!gcompl)
                delete Xcompl;
        else
                *gcompl = Xcompl;

        return maxlevel;
} /* Homology */

template<class cell , class euclidom >
int chomp::homology::Homology ( gcomplex< cell, euclidom > &  Xcompl,
const char *  Xname,
gcomplex< cell, euclidom > &  Acompl,
const char *  Aname,
chain< euclidom > *&  hom,
chain< euclidom > ***  gen = 0 
)

Computes the relative homology of the given pair of cubical complexes.

Begins with adding boundaries to the cells in A and in X while removing from X all the cells that appear in A to make X a relative cell complex. Destroys the contents of X and A before running the algebraic computations unless homology generators are to be retrieved. Note that if A is empty then all possible boundaries will be added to X. Returns the number of the highest nontrivial homology level or -1 if none.

Definition at line 545 of file homology.h.

References collapse(), Homology(), and sout.

               : Homology (CubicalComplex &Xcompl, const char *Xname,
//      CubicalComplex &Acompl, const char *Aname, Chain *&hom,
//      Chain ***gen = 0).
{
        // initialize the empty table
        hom = 0;

        // determine the dimension of the first cubical complex
        int Xdim = Xcompl. dim ();
        if (Xdim < 0)
                return -1;

        // prepare the right name for the pair (to be used later)
        word pairname;
        if (!Acompl. empty ())
                pairname << '(' << Xname << "," << Aname << ')';
        else
                pairname << Xname;

        // collapse the pair of sets into a relative cubical complex
        // and add boundaries of cells where necessary
        collapse (Xcompl, Acompl, Xname, Aname);

        // forget the remains of the other cubical complex
        gcomplex<cell,euclidom> emptycompl;
        Acompl = emptycompl;

        // make a correction to the dimension of X
        if (Xdim != Xcompl. dim ())
        {
                sout << "Note: The dimension of " << Xname <<
                        " decreased from " << Xdim << " to " <<
                        Xcompl. dim () << ".\n";
        }

        // compute the homology of the relative cubical complex
        int maxlevel = Homology (Xcompl, pairname, hom, gen);

        // release memory used by the name of the pair and exit
        return maxlevel;
} /* Homology */

template<class euclidom , class cubetype >
int chomp::homology::Homology ( hashedset< cubetype > &  Xcubes,
const char *  Xname,
hashedset< cubetype > &  Acubes,
const char *  Aname,
chain< euclidom > *&  hom,
chain< euclidom > ***  gen = 0,
gcomplex< typename cubetype::CellType, euclidom > **  gcompl = 0 
)

Computes the relative homology of a given pair of sets of cubes.

Modifies the sets and then destroy them during the computations. If homology generators are to be retrieved, no expansion of A in X is performed. If the generators are to be retrieved, the table 'gen' is allocated as in the Homology function for geometric complexes, and the pointer pointed to by 'gcompl' is set to the cubical complex arising in the computations. Returns the number of the highest nontrivial homology level or -1 if none.

Definition at line 600 of file homology.h.

References cubes2cells(), expandAinX(), Homology(), knownbits, reducepair(), removeAfromX(), and restrictAtoneighbors().

               : int Homology (SetOfCubes &X, const char *Xname,
//      SetOfCubes &A, const char *Aname, Chain *&hom,
//      Chain ***gen = 0, CubicalComplex **gcompl = 0).
{
        // define the type of a set of cubes
        typedef hashedset<cubetype> cubsettype;

        // define the type of a cubical cell
        typedef typename cubetype::CellType celltype;

        // initialize the empty table
        hom = 0;

        // if the set A is empty, call the other procedure
        if (Acubes. empty ())
                return Homology (Xcubes, Xname, hom, gen, gcompl);

        // remove from X cubes which are in A
        removeAfromX (Xcubes, Acubes, Xname, Aname);

        // if the set X is empty, the answer is obvious
        if (Xcubes. empty ())
                return -1;

        // leave in A only the neighbors of X\\A
        restrictAtoneighbors (Xcubes, Acubes, Xname, Aname);

        // determine the dimension of X (note: X is nonempty!)
        int Xspacedim = Xcubes [0]. dim ();

        // allocate a suitable bit field set for the reduction and show msg
        knownbits [Xspacedim];

        // expand A within X
        if (!gcompl)
                expandAinX (Xcubes, Acubes, Xname, Aname);

        // if everything was moved to A, then the result is trivial
        if (Xcubes. empty ())
                return -1;

        // restrict A to neighbors
        restrictAtoneighbors (Xcubes, Acubes, Xname, Aname);

        // reduce the pair (X,A)
        cubsettype emptycubes;
        reducepair (Xcubes, Acubes, emptycubes, Xname, Aname);

        // if nothing remains in X, then the result is trivial
        if (Xcubes. empty ())
                return -1;

        // prepare the right name for the difference of the two sets
        word diffname;
        diffname << Xname << '\\' << Aname;

        // transform the set of cubes X into a set of cells and forget Xcubes
        gcomplex<celltype,euclidom> *Xcompl =
                new gcomplex<celltype,euclidom>;
        cubes2cells (Xcubes, *Xcompl, diffname);
        Xcubes = emptycubes;

        // transform the set of cubes A into a set of cubical cells
        gcomplex<celltype,euclidom> Acompl;
        cubes2cells (Acubes, Acompl, Aname);
        Acubes = emptycubes;

        // continue the homology computations
        int maxlevel = Homology (*Xcompl, Xname, Acompl, Aname, hom, gen);

        // deallocate the cubical complex if necessary
        if (!gcompl)
                delete Xcompl;
        else
                *gcompl = Xcompl;

        return maxlevel;
} /* Homology */

template<class euclidom , class cubetype >
int chomp::homology::Homology ( mvmap< cubetype, cubetype > &  Fcubmap,
const char *  Fname,
hashedset< cubetype > &  Xcubes,
const char *  Xname,
hashedset< cubetype > &  Acubes,
const char *  Aname,
hashedset< cubetype > &  Ycubes,
const char *  Yname,
hashedset< cubetype > &  Bcubes,
const char *  Bname,
chain< euclidom > *&  hom_cx,
int &  maxlevel_cx,
chain< euclidom > *&  hom_cy,
int &  maxlevel_cy,
chainmap< euclidom > *&  hom_f,
bool  inclusion = false,
int  careful = 0x01,
chain< euclidom > ***  gfgen = 0,
gcomplex< typename cubetype::CellType, euclidom > **  gfcompl = 0,
chain< euclidom > ***  gygen = 0,
gcomplex< typename cubetype::CellType, euclidom > **  gycompl = 0 
)

Computes the homomorphism induced in homology by a combinatorial cubical multivalued map.

Deletes the contents of X, A, Y, B and F when used. Fills in the given data with the computed result. If 'inclusion' is true, then composes the result with the inverse of the homomorphism induced in homology by the inclusion (X,A) -> (Y,B). If the inclusion is not invertible, throws an error message. Note that (X,A) and (Y,B) are modified independently, so you can't just pass the same sets to this procedure; you must clone them first. Set 'careful' bits: 0x01 = basic data verification, 0x02 = preserve the map's acyclicity in reductions (this can be slow!). Displays the computed homology and homomorphisms to the screen. Returns the highest nontrivial homology level for the map or -1 if none.

Definition at line 769 of file homology.h.

References acyclic(), addboundaries(), checkimagecontained(), checkimagedisjoint(), checkinclusion(), collapse(), createcellmap(), createchaincomplex(), creategraph(), createimages(), createprojection(), cubes2cells(), decreasedimension(), expandAinX(), ExtractGenerators(), Homology(), inclusion(), knownbits, project(), reducepair(), removeAfromX(), restrictAtoneighbors(), sbug, and sout.

{
        // define the type of a set of cubes
        typedef hashedset<cubetype> cubsettype;

        // define the type of a cubical cell
        typedef typename cubetype::CellType celltype;

        // define the type of a combinatorial cubical multivalued map
        typedef mvmap<cubetype,cubetype> cubmaptype;

        // transform the 'careful' bits into separate variables
        bool verify = careful & 0x01;
        bool checkacyclic = careful & 0x02;

        // prepare the right names for X\A and Y\B
        word XAname, YBname;
        if (!Acubes. empty ())
                XAname << Xname << '\\' << Aname;
        else
                XAname << Xname;
        if (!Bcubes. empty ())
                YBname << Yname << '\\' << Bname;
        else
                YBname << Yname;

        // ----- prepare the sets of cubes -----

        // if the pointers to both sets are the same, then this is an error
        if (&Xcubes == &Ycubes)
                throw "You must clone the sets passed to Homology.";

        // remove from X cubes which are in A
        removeAfromX (Xcubes, Acubes, Xname, Aname);

        // leave in A only the neighbors of X\\A
        restrictAtoneighbors (Xcubes, Acubes, Xname, Aname);

        // remove from Y cubes which are in B
        removeAfromX (Ycubes, Bcubes, Yname, Bname);

        // if one of the main sets is empty, the answer is trivial
        if (Xcubes. empty () || Ycubes. empty ())
                return -1;

        // remember the original size of the set A and of the set X
        int_t origAsize = Acubes. size ();
        int_t origXsize = Xcubes. size ();

        // determine the dimension of X and Y (both sets are non-empty)
        int Xspacedim = Xcubes [0]. dim ();
        int Yspacedim = Ycubes [0]. dim ();

        // check if F (X\A) \subset Y
        if (verify)
                checkimagecontained (Fcubmap, Xcubes, Ycubes, Bcubes,
                        XAname, Yname);

        // check if F (A) \subset B
        if (verify && !Acubes. empty ())
                checkimagecontained (Fcubmap, Acubes, Bcubes, Aname, Bname);

        // check if F (A) is disjoint from Y
        if (verify && !Acubes. empty ())
                checkimagedisjoint (Fcubmap, Acubes, Ycubes, Aname, YBname);

        // verify if X\A \subset Y and A \subset B if inclusion is considered
        if (verify && inclusion)
                checkinclusion (Xcubes, Ycubes, Bcubes, XAname, Yname);
        if (verify && inclusion)
                checkinclusion (Acubes, Bcubes, Aname, Bname);

        // ----- reduce the sets of cubes -----

        // allocate a suitable bit field set for the reduction and show msg
        knownbits [Xspacedim];
        knownbits [Yspacedim];

        // reduce the pair of sets of cubes (X,A) without acyclicity check
        if (!checkacyclic)
        {
                // reduce the pair (X,A)
                cubsettype empty;
                reducepair (Xcubes, Acubes, empty, Xname, Aname);

                // if nothing remains in X, then the result is trivial
                if (Xcubes. empty ())
                        return -1;
        }

        // expand A towards X and modify (Y,B) accordingly
        if (!Acubes. empty () && !gfgen && !gygen)
        {
                expandAinX (Xcubes, Acubes, Ycubes, Bcubes, Fcubmap,
                        Xname, Aname, Bname, inclusion, checkacyclic);
        }

        // reduce the pair (X,A) or the set X with acyclicity check
        if (checkacyclic && !Acubes. empty ())
        {
                // leave in A only the neighbors of X\\A
                restrictAtoneighbors (Xcubes, Acubes, Xname, Aname);

                // reduce the pair (X,A) with acyclicity check
                cubsettype emptycubes;
                reducepair (Xcubes, Acubes, Fcubmap, emptycubes,
                        Xname, Aname);

                // if nothing remains in X, then the result is trivial
                if (Xcubes. empty ())
                        return -1;
        }

        // reduce the pair (X,A) even further
        if (!checkacyclic && !Acubes. empty ())
        {
                // leave in A only the neighbors of X\\A
                restrictAtoneighbors (Xcubes, Acubes, Xname, Aname);

                // continue the reduction of the pair (X,A)
                cubsettype empty;
                reducepair (Xcubes, Acubes, empty, Xname, Aname);
        }

        // indicate that the acyclicity of the map should be verified
        if (!verify)
        {
                if (!checkacyclic && ((origAsize != Acubes. size ()) ||
                        (origXsize != Xcubes. size ())))
                {
                        sout << "*** Important note: " << Xname << " or " <<
                                Aname << " changed. You must make sure\n"
                                "*** that the restriction of " << Fname <<
                                " to the new sets is acyclic.\n";
                }
                else
                {
                        sout << "*** Note: The program assumes "
                                "that the input map is acyclic.\n";
                }
        }

        // create the set of cubes to keep in Y as the image of the domain
        // and include the domain if the inclusion is considered
        cubsettype Ykeepcubes;
        sout << "Computing the image of the map... ";
        for (int_t i = 0; i < Xcubes. size (); ++ i)
                Ykeepcubes. add (Fcubmap (Xcubes [i]));
        for (int_t i = 0; i < Acubes. size (); ++ i)
                Ykeepcubes. add (Fcubmap (Acubes [i]));
        if (inclusion)
        {
                sout << "and of the inclusion... ";
                Ykeepcubes. add (Xcubes);
                Ykeepcubes. add (Acubes);
        }
        sout << Ykeepcubes. size () << " cubes.\n";

        // reduce the pair of cubical sets (Y,B) towards the image of F
        if (Xspacedim == Yspacedim)
        {
                if (!gygen)
                        expandAinX (Ycubes, Bcubes, Yname, Bname);
                restrictAtoneighbors (Ycubes, Bcubes, Yname, Bname,
                        &Ykeepcubes);
                reducepair (Ycubes, Bcubes, Ykeepcubes, Yname, Bname);
        }

        // forget the cubes to keep in Y as no longer of any use
        if (!Ykeepcubes. empty ())
        {
                cubsettype empty;
                Ykeepcubes = empty;
        }

        // ----- create the cubical complexes -----

        // transform the set of cubes X into a set of cells and forget Xcubes
        gcomplex<celltype,euclidom> Xcompl;
        cubes2cells (Xcubes, Xcompl, XAname, false);

        // transform the set of cubes A into a set of cubical cells
        gcomplex<celltype,euclidom> Acompl;
        cubes2cells (Acubes, Acompl, Aname, false);

        // transform the cubes in Y into cubical cells and forget the cubes
        gcomplex<celltype,euclidom> *Ycompl =
                new gcomplex<celltype,euclidom>;
        cubes2cells (Ycubes, *Ycompl, YBname);

        // transform the cubes in B into cubical cells and forget the cubes
        gcomplex<celltype,euclidom> Bcompl;
        cubes2cells (Bcubes, Bcompl, Bname);

        // determine the dimension of X and Y as cubical complexes
        int Xdim = Xcompl. dim ();
        int Ydim = Ycompl -> dim ();

        // ----- collapse the cubical sets (X,A) -----

        // reduce the pair of sets (Xcompl, Acompl) while adding to them
        // boundaries of all the cells
        gcomplex<celltype,euclidom> emptycompl;
        collapse (Xcompl, Acompl, emptycompl, Xname, Aname,
                true, true, false);

        // if nothing remains in X, then the result is trivial
        if (Xcompl. empty ())
                return -1;

        // make a correction to the dimension of X
        if (Xdim != Xcompl. dim ())
        {
                sout << "Note: The dimension of " << Xname << " decreased "
                        "from " << Xdim << " to " << Xcompl. dim () << ".\n";

                Xdim = Xcompl. dim ();
        }

        // ----- create a reduced graph of F -----

        // create the map F defined on the cells in its domain
        mvcellmap<celltype,euclidom,cubetype> Fcellcubmap (Xcompl);
        sout << "Creating the map " << Fname << " on cells in " <<
                Xname << "... ";
        int_t countimages = createimages (Fcellcubmap, Fcubmap, Fcubmap,
                Xcubes, Acubes);
        sout << countimages << " cubes added.\n";

        // create the map F defined on the cells in its domain subcomplex A
        mvcellmap<celltype,euclidom,cubetype> FcellcubmapA (Acompl);
        if (!Acompl. empty ())
        {
                sout << "Creating the map " << Fname << " on cells in " <<
                        Aname << "... ";
                int_t count = createimages (FcellcubmapA, Fcubmap, Acubes);
                sout << count << " cubes added.\n";
        }

        // get rid of the sets of cubes X and A as no longer needed,
        // as well as the cubical map
        {
                cubsettype emptycubes;
                Acubes = emptycubes;
                Xcubes = emptycubes;
                cubmaptype emptymap;
                Fcubmap = emptymap;
        }

        // create the graph of F as a cubical cell complex
        sout << "Creating a cell map for " << Fname << "... ";
        mvcellmap<celltype,euclidom,celltype> Fcellmap (Xcompl);
        bool acyclic = createcellmap (Fcellcubmap, FcellcubmapA,
                Fcellmap, verify);
        sout << "Done.\n";
        if (verify && !acyclic)
        {
                sout << "*** SERIOUS PROBLEM: The map is not "
                        "acyclic. THE RESULT WILL BE WRONG.\n"
                        "*** You must verify the acyclicity of the "
                        "initial map with 'chkmvmap'\n"
                        "*** and, if successful, set the "
                        "'careful reduction' bit.\n";
        }
        if (verify && acyclic)
        {
                sout << "Note: It has been verified successfully "
                        "that the map is acyclic.\n";
        }

        sout << "Creating the graph of " << Fname << "... ";
        gcomplex<celltype,euclidom> *Fcompl =
                new gcomplex<celltype,euclidom>;
        creategraph (Fcellmap, *Fcompl, false);
        sout << Fcompl -> size () << " cells added.\n";

        // forget the cubical maps on the cells and the cubical complex of X
        mvcellmap<celltype,euclidom,cubetype> emptycellcubmap;
        Fcellcubmap = emptycellcubmap;
        FcellcubmapA = emptycellcubmap;
        mvcellmap<celltype,euclidom,celltype> emptycellmap (emptycompl);
        Fcellmap = emptycellmap;
        Xcompl = emptycompl;

        // ----- collapse the cubical sets (Y,B) -----

        // decrease the dimension of B to the dimension of Y
        decreasedimension (Bcompl, Ydim, Bname);

        // create a full cubical complex (with all the faces) of Y\B
        addboundaries (*Ycompl, Bcompl, 0, false, Yname, Bname);

        // forget the cubical complex of B
        if (!Bcompl. empty ())
        {
                sout << "Forgetting " << Bcompl. size () << " cells from " <<
                        Bname << ".\n";
                gcomplex<celltype,euclidom> empty;
                Bcompl = empty;
        }

        // collapse the codomain of the map towards the image of F
        gcomplex<celltype,euclidom> Ykeepcompl;
        sout << "Computing the image of " << Fname << "... ";
        project (*Fcompl, Ykeepcompl, *Ycompl, Xspacedim, Yspacedim,
                0, 0, false);
        if (inclusion)
        {
                project (*Fcompl, Ykeepcompl, *Ycompl, 0, Xspacedim,
                        Yspacedim, 0, false);
        }
        sout << Ykeepcompl. size () << " cells.\n";

        sout << "Collapsing " << Yname << " to img of " << Xname << "... ";
        int_t countremoved = Ycompl -> collapse (emptycompl, Ykeepcompl,
                0, 0, 0);
        sout << 2 * countremoved << " cells removed, " <<
                Ycompl -> size () << " left.\n";

        // forget the cells to keep in Y
        if (!Ykeepcompl. empty ())
        {
                gcomplex<celltype,euclidom> empty;
                Ykeepcompl = empty;
        }

        // make a correction to the dimension of Y
        if (Ydim != Ycompl -> dim ())
        {
                sout << "Note: The dimension of " << Yname << " decreased "
                        "from " << Ydim << " to " << Ycompl -> dim () <<
                        ".\n";

                Ydim = Ycompl -> dim ();
        }

        // ----- create chain complexes from the cubical sets ------

        // create a chain complex from the graph of F (it is relative)
        chaincomplex<euclidom> cgraph (Fcompl -> dim (), !!gfgen);
        sout << "Creating the chain complex of the graph of " << Fname <<
                "... ";
        createchaincomplex (cgraph, *Fcompl);
        sout << "Done.\n";

        // create the chain complex from Y (this is a relative complex)
        chaincomplex<euclidom> cy (Ydim, !!gygen);
        sout << "Creating the chain complex of " << Yname << "... ";
        createchaincomplex (cy, *Ycompl);
        sout << "Done.\n";

        // create the projection map from the graph of the map to Y
        chainmap<euclidom> cmap (cgraph, cy);
        sout << "Creating the chain map of the projection... ";
        createprojection (*Fcompl, *Ycompl, cmap, Xspacedim, Yspacedim, 0);
        sout << "Done.\n";

        // if this is an index map, create the projection map from the graph
        // of the map to X composed with the inclusion into Y
        chainmap<euclidom> imap (cgraph, cy);
        if (inclusion)
        {
                sout << "Creating the chain map of the inclusion... ";
                createprojection (*Fcompl, *Ycompl, imap, 0, Xspacedim,
                        Yspacedim);
                sout << "Done.\n";
        }

        // forget the graph of F if it is not going to be used anymore
        if (gfcompl)
                (*gfcompl) = Fcompl;
        else
                delete Fcompl;

        // forget the cubical complex Y unless requested to keep it
        if (gycompl)
                (*gycompl) = Ycompl;
        else
                delete Ycompl;

        // ----- compute and show homology, save generators -----

        // prepare the name of the graph of F
        word gFname;
        gFname << "the graph of " << Fname;

        // compute the homology of the chain complex of the graph of the map
        maxlevel_cx = Homology (cgraph, gFname, hom_cx);

        // extract the computed generators of the graph if requested to
        if (gfgen)
                *gfgen = ExtractGenerators (cgraph, hom_cx, maxlevel_cx);

        // compute the homology of the chain complex of Y
        maxlevel_cy = Homology (cy, Yname, hom_cy);

        // extract the computed generators of Y if requested to
        if (gygen)
                *gygen = ExtractGenerators (cy, hom_cy, maxlevel_cy);

        // ----- show the map(s) -----

        // prepare the data structures for the homology
        chaincomplex<euclidom> hgraph (maxlevel_cx);
        chaincomplex<euclidom> hy (maxlevel_cy);
        chainmap<euclidom> *hmap = new chainmap<euclidom> (hgraph, hy);
        chainmap<euclidom> hincl (hgraph, hy);
//      chainmap<euclidom> *hcomp = new chainmap<euclidom> (hgraph, hgraph);
        chainmap<euclidom> *hcomp = new chainmap<euclidom> (hy, hy);

        // show the map induced in homology by the chain map
        sout << "The map induced in homology is as follows:\n";
        hgraph. take_homology (hom_cx);
        hy. take_homology (hom_cy);
        hmap -> take_homology (cmap, hom_cx, hom_cy);
        hmap -> show (sout, "\tf", "x", "y");

        // show the map induced in homology by the inclusion map
        bool invertible = true;
        if (inclusion)
        {
                sout << "The map induced in homology by the inclusion:\n";
                hincl. take_homology (imap, hom_cx, hom_cy);
                hincl. show (sout, "\ti", "x", "y");

                try
                {
                        hincl. invert ();
                }
                catch (...)
                {
                        sout << "Oh, my goodness! This map is apparently "
                                "not invertible.\n";
                        invertible = false;
                }

                if (invertible)
                {
                        sout << "The inverse of the map "
                                "induced by the inclusion:\n";
                        hincl. show (sout, "\tI", "y", "x");

                        // debug: verify if the map was inverted correctly
                        chainmap<euclidom> hincl1 (hgraph, hy);
                        hincl1. take_homology (imap, hom_cx, hom_cy);
                        chainmap<euclidom> hident (hy, hy);
                        hident. compose (hincl1, hincl);
                        sbug << "The composition of the inclusion and "
                                "its inverse (should be the identity):\n";
                        hident. show (sbug, "\tid", "y", "y");
                        for (int i = 0; i <= hident. dim (); ++ i)
                        {
                                const mmatrix<euclidom> &m = hident [i];
                                if (m. getnrows () != m. getncols ())
                                        throw "INV: Inequal rows and cols.";
                                euclidom zero, one;
                                zero = 0;
                                one = 1;
                                for (int c = 0; c < m. getncols (); ++ c)
                                {
                                        for (int r = 0; r < m. getnrows ();
                                                ++ r)
                                        {
                                                if ((r == c) && (m. get
                                                        (r, c) == one))
                                                {
                                                        continue;
                                                }
                                                if (m. get (r, c) == zero)
                                                        continue;
                                                throw "INV: Non-identity.";
                                        }
                                }
                        }
                        // debug: end of the verification

                        sout << "The composition of F and the inverse "
                                "of the map induced by the inclusion:\n";
                //      hcomp -> compose (hincl, *hmap);
                        hcomp -> compose (*hmap, hincl);
                //      hcomp -> show (sout, "\tF", "x", "x");
                        hcomp -> show (sout, "\tF", "y", "y");
                }
        }

        // set the appropriate map
        if (inclusion && invertible)
        {
                hom_f = hcomp;
                delete hmap;
        }
        else
        {
                hom_f = hmap;
                delete hcomp;
        }

        // throw an exception if the map is not invertible
        if (inclusion && !invertible)
                throw "Unable to invert the inclusion map.";

        return ((maxlevel_cx < maxlevel_cy) ? maxlevel_cx : maxlevel_cy);
} /* Homology */

template<class euclidom , class cubetype >
int chomp::homology::Homology ( mvmap< cubetype, cubetype > &  Fcubmap,
hashedset< cubetype > &  Xcubes,
hashedset< cubetype > &  Acubes,
hashedset< cubetype > &  Ycubes,
hashedset< cubetype > &  Bcubes,
chain< euclidom > *&  hom_cx,
int &  maxlevel_cx,
chain< euclidom > *&  hom_cy,
int &  maxlevel_cy,
chainmap< euclidom > *&  hom_f,
bool  inclusion = false,
int  careful = 0x01,
chain< euclidom > ***  gfgen = 0,
gcomplex< typename cubetype::CellType, euclidom > **  gfcompl = 0,
chain< euclidom > ***  gygen = 0,
gcomplex< typename cubetype::CellType, euclidom > **  gycompl = 0 
)

A version of the above procedure with the default names.

Definition at line 1287 of file homology.h.

References Homology(), and inclusion().

{
        return Homology (Fcubmap, "F", Xcubes, "X", Acubes, "A",
                Ycubes, "Y", Bcubes, "B", hom_cx, maxlevel_cx,
                hom_cy, maxlevel_cy, hom_f, inclusion, careful,
                gfgen, gfcompl, gygen, gycompl);
} /* Homology */

template<class euclidom , class cubetype >
int chomp::homology::Homology ( mvmap< cubetype, cubetype > &  Fcubmap,
const char *  Fname,
hashedset< cubetype > &  Xcubes,
const char *  Xname,
hashedset< cubetype > &  Acubes,
const char *  Aname,
chain< euclidom > *&  hom,
int &  maxlevel,
chainmap< euclidom > *&  hom_f,
int  careful = 0x01,
chain< euclidom > ***  gfgen = 0,
gcomplex< typename cubetype::CellType, euclidom > **  gfcompl = 0,
chain< euclidom > ***  gygen = 0,
gcomplex< typename cubetype::CellType, euclidom > **  gycompl = 0 
)

Computes the endomorphism induced in homology by a combinatorial cubical multivalued map.

See the description of the previous function for details.

Definition at line 1309 of file homology.h.

References Homology().

{
        hashedset<cubetype> Ycubes = Xcubes, Bcubes = Acubes;
        chain<euclidom> *hom_cy = 0;
        int maxlevel_cy;
        int result = Homology (Fcubmap, Fname, Xcubes, Xname, Acubes, Aname,
                Ycubes, Xname, Bcubes, Aname, hom, maxlevel,
                hom_cy, maxlevel_cy, hom_f, true, careful,
                gfgen, gfcompl, gygen, gycompl);
        delete [] hom_cy;
        return result;
} /* Homology */

template<class euclidom , class cubetype >
int chomp::homology::Homology ( mvmap< cubetype, cubetype > &  Fcubmap,
hashedset< cubetype > &  Xcubes,
hashedset< cubetype > &  Acubes,
chain< euclidom > *&  hom,
int &  maxlevel,
chainmap< euclidom > *&  hom_f,
int  careful = 0x01,
chain< euclidom > ***  gfgen = 0,
gcomplex< typename cubetype::CellType, euclidom > **  gfcompl = 0,
chain< euclidom > ***  gygen = 0,
gcomplex< typename cubetype::CellType, euclidom > **  gycompl = 0 
)

A version of the above procedure with the default names.

Definition at line 1332 of file homology.h.

References Homology().

{
        return Homology (Fcubmap, "F", Xcubes, "X", Acubes, "A", hom,
                maxlevel, hom_f, careful, gfgen, gfcompl, gygen, gycompl);
} /* Homology */

template<class euclidom , class cubetype >
int chomp::homology::Homology2l ( mvmap< cubetype, cubetype > &  Fcubmap0,
const char *  Fname,
hashedset< cubetype > &  Xcubes0,
const char *  Xname,
hashedset< cubetype > &  Acubes0,
const char *  Aname,
chain< euclidom > *&  hom_cx,
int &  maxlevel,
chainmap< euclidom > *&  hom_f,
int  careful = 0x01,
chain< euclidom > ***  gfgen = 0,
gcomplex< tCell2l< typename cubetype::CellType >, euclidom > **  gfcompl = 0,
chain< euclidom > ***  gygen = 0,
gcomplex< tCell2l< typename cubetype::CellType >, euclidom > **  gycompl = 0 
)

Computes the endomorphism induced in homology by a combinatorial cubical multivalued map using the two-layer construction developped by P.

Pilarczyk and K. Stolot.

Definition at line 1354 of file homology.h.

References acyclic(), addboundaries(), addmapimg(), checkimagecontained(), checkimagedisjoint(), collapse(), createcellmap(), createchaincomplex(), creategraph(), createimages(), createprojection(), cubes2cells(), decreasedimension(), expandAinX(), ExtractGenerators(), Homology(), knownbits, MaxBddDim, project(), reducepair(), removeAfromX(), restrictAtoneighbors(), and sout.

Referenced by Homology2l().

{
        // define the type of a 2-layer cube and 2-layer cell
        typedef tCube2l<cubetype> cube2ltype;
        typedef typename cube2ltype::CellType cell2ltype;

        // turn off locally the usage of binary decision diagrams
        local_var<int> TurnOffMaxBddDim (MaxBddDim, 0);

        // transform the 'careful' bits into separate variables
        bool verify = careful & 0x01;
        bool checkacyclic = careful & 0x02;

        // remove from X cubes which are in A
        removeAfromX (Xcubes0, Acubes0, "X", "A");

        // leave in A only the neighbors of X\\A
        restrictAtoneighbors (Xcubes0, Acubes0, "X", "A");

        // if the set X is empty, the answer is obvious
        if (Xcubes0. empty ())
        {
                sout << "X is a subset of A. The homology of (X,A) "
                        "is trivial and the map is 0.";
                return -1;
        }

        // ----- define the layers ------

        // define the two-layer structure
        sout << "Defining the two-layer structure... ";
        cube2ltype::setlayers (Xcubes0, Acubes0);

        // transform the cubes in X and in A to the two-layer sets
        hashedset<cube2ltype> Xcubes;
        for (int_t i = 0; i < Xcubes0. size (); ++ i)
                Xcubes. add (cube2ltype (Xcubes0 [i], 1));
        hashedset<cube2ltype> Acubes;
        for (int_t i = 0; i < Acubes0. size (); ++ i)
                Acubes. add (cube2ltype (Acubes0 [i], 0));

        // say that defining the two-layer structure is done
        sout << cube2ltype::layer1 (). size () << "+" <<
                cube2ltype::layer0 (). size () << " cubes, " <<
                cell2ltype::identify (). size () << " cells.\n";

        // ----- transform the map ------

        // determine Y and B
        sout << "Creating the sets Y and B... ";
        hashedset<cube2ltype> Ycubes (Xcubes);
        hashedset<cube2ltype> Bcubes (Acubes);
        for (int_t i = 0; i < Xcubes0. size (); ++ i)
        {
                const hashedset<cubetype> &img = Fcubmap0 (Xcubes0 [i]);
                for (int_t j = 0; j < img. size (); ++ j)
                {
                        if (!Xcubes0. check (img [j]))
                                Bcubes. add (cube2ltype (img [j], 0));
                }
        }
        for (int_t i = 0; i < Acubes0. size (); ++ i)
        {
                const hashedset<cubetype> &img = Fcubmap0 (Acubes0 [i]);
                for (int_t j = 0; j < img. size (); ++ j)
                        Bcubes. add (cube2ltype (img [j], 0));
        }
        sout << Ycubes. size () << " cubes in Y\\B, " <<
                Bcubes. size () << " in B.\n";

        // lift the map to the two-layer structure
        mvmap<cube2ltype,cube2ltype> Fcubmap;
        for (int_t i = 0; i < Xcubes0. size (); ++ i)
        {
        //      Fcubmap [Xcubes [i]]. size ();
                const hashedset<cubetype> &img = Fcubmap0 (Xcubes0 [i]);
                if (img. empty ())
                        throw "Empty image of a box in X.\n";
                for (int_t j = 0; j < img. size (); ++ j)
                {
                        int layer = Xcubes0. check (img [j]) ? 1 : 0;
                        Fcubmap [Xcubes [i]]. add
                                (cube2ltype (img [j], layer));
                }
        }
        for (int_t i = 0; i < Acubes0. size (); ++ i)
        {
        //      Fcubmap [Acubes [i]]. size ();
                const hashedset<cubetype> &img = Fcubmap0 (Acubes0 [i]);
                if (img. empty ())
                        throw "Empty image of a box in A.\n";
                for (int_t j = 0; j < img. size (); ++ j)
                        Fcubmap [Acubes [i]]. add
                                (cube2ltype (img [j], 0));
        }

        // forget the initial single-layer sets and the map
        {
                hashedset<cubetype> empty;
                Xcubes0 = empty;
                Acubes0 = empty;
        }
        {
                mvmap<cubetype,cubetype> empty;
                Fcubmap0 = empty;
        }

        // remember the original size of the set A and of the set X
        int_t origAsize = Acubes. size ();
        int_t origXsize = Xcubes. size ();

        // determine the dimension of X and Y if possible
        int Xspacedim = Xcubes. empty () ? -1 : Xcubes [0]. dim ();
        int Yspacedim = Ycubes. empty () ? -1 : Ycubes [0]. dim ();

        // ----- reduce the sets of cubes -----

        // prepare the set of cubes to keep in X (unused in this program)
        hashedset<cube2ltype> Xkeepcubes;

        // allocate a suitable bit field set for the reduction and show msg
        if (Xspacedim > 0)
                knownbits [Xspacedim];

        // reduce the pair of sets of cubes (X,A) without acyclicity check
        if (!Acubes. empty () && !checkacyclic)
        {
                // reduce the pair (X,A)
                reducepair (Xcubes, Acubes, Xkeepcubes, "X", "A");

                // if nothing remains in X, then the result is trivial
                if (Xcubes. empty ())
                {
                        sout << "There are no cubes left "
                                "in X\\A. The homology of (X,A) "
                                "is trivial and the map is 0.";
                        return -1;
                }
        }

        // remember which inclusions have been verified
        bool inclFABchecked = false;
        bool inclFXYchecked = false;

        // do the careful or extended reduction
        if (checkacyclic)
        {
                // check if F (X\A) \subset Y
                if (verify)
                {
                        checkimagecontained (Fcubmap,
                                Xcubes, Ycubes, Bcubes,
                                Acubes. empty () ? "X" : "X\\A", "Y");
                        inclFXYchecked = true;
                }
                // check if F (A) \subset B and if F (A) is disjoint from Y
                if (verify && !Acubes. empty ())
                {
                        checkimagecontained (Fcubmap, Acubes, Bcubes,
                                "A", "B");
                        checkimagedisjoint (Fcubmap, Acubes, Ycubes,
                                "A", "Y\\B");
                        inclFABchecked = true;
                }
        }
        else if (!Acubes. empty ())
        {
                // check if F (X\A) \subset Y
                if (verify)
                {
                        checkimagecontained (Fcubmap,
                                Xcubes, Ycubes, Bcubes,
                                Acubes. empty () ? "X" : "X\\A", "Y");
                        inclFXYchecked = true;
                }
        }

        // expand A within X and modify (Y,B)
        if (!Acubes. empty ())
        {
                // expand A towards X and modify (Y,B) accordingly
                expandAinX (Xcubes, Acubes, Ycubes, Bcubes, Fcubmap,
                        "X", "A", "B", true /*indexmap*/, checkacyclic);
        }

        // reduce the pair (X,A) or the set X with acyclicity check
        if (checkacyclic)
        {
                // leave in A only the neighbors of X\\A
                restrictAtoneighbors (Xcubes, Acubes, "X", "A");

                // reduce the pair (X,A) with acyclicity check
                reducepair (Xcubes, Acubes, Fcubmap, Xkeepcubes, "X", "A");

                // if nothing remains in X, then the result is trivial
                if (Xcubes. empty ())
                {
                        sout << "There are no cubes left "
                                "in X\\A. The homology of (X,A) "
                                "is trivial and the map is 0.";
                        return -1;
                }
        }

        // reduce the pair (X,A) even further
        if (!checkacyclic && !Acubes. empty ())
        {
                // leave in A only the neighbors of X\\A
                restrictAtoneighbors (Xcubes, Acubes, "X", "A");

                // continue the reduction of the pair (X,A)
                reducepair (Xcubes, Acubes, Xkeepcubes, "X", "A");
        }

        // indicate that the acyclicity of the map should be verified
        if (!verify)
        {
                if (!checkacyclic && ((origAsize != Acubes. size ()) ||
                        (origXsize != Xcubes. size ())))
                {
                        sout << "*** Important note: X or A changed. "
                                "You must make sure\n"
                                "*** that the restriction of F "
                                "to the new sets is acyclic.\n";
                }
                else
                {
                        sout << "*** Note: The program assumes "
                                "that the input map is acyclic.\n";
                }
        }

        // check if F (X\A) \subset Y
        if (verify && !inclFXYchecked)
        {
                checkimagecontained (Fcubmap, Xcubes, Ycubes, Bcubes,
                        Acubes. empty () ? "X" : "X\\A", "Y");
                inclFXYchecked = true;
        }

        // check if F (A) \subset B [this should always be satisfied]
        if (verify && !inclFABchecked && !Acubes. empty ())
        {
                checkimagecontained (Fcubmap, Acubes, Bcubes, "A", "B");
                checkimagedisjoint (Fcubmap, Acubes, Ycubes, "A", "Y\\B");
                inclFABchecked = true;
        }

        // set the union of the domain of the map of interest
        // and the image of the map as the cubes to keep in Y
        hashedset<cube2ltype> Ykeepcubes;
        addmapimg (Fcubmap, Xcubes, Acubes, Ykeepcubes,
                true /*indexmap*/);

        // reduce the pair of cubical sets (Y,B) towards the image of F
        if (Xspacedim == Yspacedim)
        {
                expandAinX (Ycubes, Bcubes, "Y", "B");
                restrictAtoneighbors (Ycubes, Bcubes, "Y", "B", &Ykeepcubes);
                reducepair (Ycubes, Bcubes, Ykeepcubes, "Y", "B");
        }

        // ----- create the cubical complexes -----

        // transform the set of cubes X into a set of cells,
        // but do not forget Xcubes yet
        gcomplex<cell2ltype,euclidom> Xcompl;
        cubes2cells (Xcubes, Xcompl, Acubes. size () ? "X\\A" : "X", false);

        // transform the set of cubes A into a set of cubical cells
        // but do not forget Acubes yet
        gcomplex<cell2ltype,euclidom> Acompl;
        cubes2cells (Acubes, Acompl, "A", false);

        // if the set X is empty, no computations are necessary
        if (Xcompl. empty ())
        {
                if (!Acompl. empty ())
                        sout << "The set X is contained in A. "
                                "The homology of (X,A) is trivial.";
                else
                        sout << "The set X is empty. "
                                "The homology of X is trivial.";
                return -1;
        }

        // transform the cubes in Y into cubical cells and forget the cubes
        gcomplex<cell2ltype,euclidom> *Ycompl =
                new gcomplex<cell2ltype,euclidom>;
        cubes2cells (Ycubes, *Ycompl, Bcubes. empty () ? "Y" : "Y\\B");
        if (!Ycubes. empty ())
        {
                hashedset<cube2ltype> empty;
                Ycubes = empty;
        }

        // transform the cubes in B into cubical cells and forget the cubes
        gcomplex<cell2ltype,euclidom> Bcompl;
        cubes2cells (Bcubes, Bcompl, "B");
        if (!Bcubes. empty ())
        {
                hashedset<cube2ltype> empty;
                Bcubes = empty;
        }

        // transform the cubes to keep in Y into cells and forget the cubes
        gcomplex<cell2ltype,euclidom> Ykeepcompl;
        cubes2cells (Ykeepcubes, Ykeepcompl, "Ykeep");
        if (!Ykeepcubes. empty ())
        {
                hashedset<cube2ltype> empty;
                Ykeepcubes = empty;
        }

        // determine the dimension of X and Y as cubical complexes
        int Xdim = Xcompl. dim ();
        if ((Xspacedim < 0) && (Xdim >= 0))
                Xspacedim = Xcompl [Xdim] [0]. spacedim ();
        int Ydim = Ycompl -> dim ();
        if ((Yspacedim < 0) && (Ydim >= 0))
                Yspacedim = (*Ycompl) [Ydim] [0]. spacedim ();

        // ----- collapse the cubical sets (X,A) -----

        // create an empty set of cells to keep in X
        gcomplex<cell2ltype,euclidom> Xkeepcompl;

        // reduce the pair of sets (Xcompl, Acompl) while adding to them
        // boundaries of all the cells
        collapse (Xcompl, Acompl, Xkeepcompl, "X", "A",
                true, true, false);

        // if nothing remains in X, then the result is trivial
        if (Xcompl. empty ())
        {
                sout << "Nothing remains in X. "
                        "The homology of (X,A) is trivial.";
                return -1;
        }

        // forget the cells to keep in X
        if (!Xkeepcompl. empty ())
        {
                gcomplex<cell2ltype,euclidom> empty;
                Xkeepcompl = empty;
        }

        // make a correction to the dimension of X
        if (Xdim != Xcompl. dim ())
        {
                sout << "Note: The dimension of X decreased from " <<
                        Xdim << " to " << Xcompl. dim () << ".\n";

                Xdim = Xcompl. dim ();
        }

        // ----- create a reduced graph of F -----

        // create the map F defined on the cells in its domain
        mvcellmap<cell2ltype,euclidom,cube2ltype> Fcellcubmap (Xcompl);
        sout << "Creating the map F on cells in X... ";
        int_t countimages = createimages (Fcellcubmap, Fcubmap, Fcubmap,
                Xcubes, Acubes);
        sout << countimages << " cubes added.\n";

        // forget the full cubical set X
        if (Xcubes. size ())
        {
                hashedset<cube2ltype> empty;
                Xcubes = empty;
        }

        // create the map F defined on the cells in its domain subcomplex A
        mvcellmap<cell2ltype,euclidom,cube2ltype> FcellcubmapA (Acompl);
        if (!Acompl. empty ())
        {
                sout << "Creating the map F on cells in A... ";
                int_t count = createimages (FcellcubmapA, Fcubmap, Acubes);
                sout << count << " cubes added.\n";
        }

        // forget the full cubical set A
        if (Acubes. size ())
        {
                hashedset<cube2ltype> empty;
                Acubes = empty;
        }

        // create the graph of F as a cubical cell complex
        gcomplex<cell2ltype,euclidom> *Fcompl =
                new gcomplex<cell2ltype,euclidom>;
        sout << "Creating a cell map for F... ";
        mvcellmap<cell2ltype,euclidom,cell2ltype> Fcellmap (Xcompl);
        bool acyclic = createcellmap (Fcellcubmap, FcellcubmapA,
                Fcellmap, verify);
        sout << "Done.\n";
        if (checkacyclic && !acyclic)
        {
                sout << "*** SERIOUS PROBLEM: The map is not "
                        "acyclic. THE RESULT WILL BE WRONG.\n"
                        "*** You must verify the acyclicity of the "
                        "initial map with 'chkmvmap'\n"
                        "*** and, if successful, run this program "
                        "with the '-a' switch.\n";
        }
        if (checkacyclic && acyclic)
        {
                sout << "Note: It has been verified successfully "
                        "that the map is acyclic.\n";
        }

        sout << "Creating the graph of F... ";
        creategraph (Fcellmap, *Fcompl, false);
        sout << Fcompl -> size () << " cells added.\n";

        // forget the cubical map on the cells
        {
                mvcellmap<cell2ltype,euclidom,cube2ltype> empty;
                Fcellcubmap = empty;
                FcellcubmapA = empty;
        }

        // ----- collapse the cubical sets (Y,B) -----

        // decrease the dimension of B to the dimension of Y
        decreasedimension (Bcompl, Ydim, "B");

        // create a full cubical complex (with all the faces) of Y\B
        if (!Ycompl -> empty ())
        {
                addboundaries (*Ycompl, Bcompl, 0, false, "Y", "B");

                // forget the cubical complex of B
                if (!Bcompl. empty ())
                {
                        sout << "Forgetting " << Bcompl. size () <<
                                " cells from B.\n";
                        gcomplex<cell2ltype,euclidom> empty;
                        Bcompl = empty;
                }
        }

        // collapse the codomain of the map towards the image of F
        {
                sout << "Computing the image of F... ";
                int_t prev = Ykeepcompl. size ();
                project (*Fcompl, Ykeepcompl, *Ycompl, Xspacedim, Yspacedim,
                        0, 0, false);
                project (*Fcompl, Ykeepcompl, *Ycompl, 0, Xspacedim,
                        Yspacedim, 0, false);
                sout << (Ykeepcompl. size () - prev) << " cells added.\n";

                sout << "Collapsing Y towards F(X)... ";
                gcomplex<cell2ltype,euclidom> empty;
                int_t count = Ycompl -> collapse (empty, Ykeepcompl,
                        0, 0, 0, 0);
                sout << 2 * count << " cells removed, " <<
                        Ycompl -> size () << " left.\n";
        }

        // forget the cells to keep in Y
        if (!Ykeepcompl. empty ())
        {
                gcomplex<cell2ltype,euclidom> empty;
                Ykeepcompl = empty;
        }

        // make a correction to the dimension of Y
        if (Ydim != Ycompl -> dim ())
        {
                sout << "Note: The dimension of Y decreased from " <<
                        Ydim << " to " << Ycompl -> dim () << ".\n";

                Ydim = Ycompl -> dim ();
        }

        // ----- create chain complexes from the cubical sets ------

        // create a chain complex from X (this is a relative chain complex!)
//      chaincomplex<euclidom> cx (Xcompl. dim (), false /*generators*/);

        // create a chain complex from the graph of F (it is relative)
        chaincomplex<euclidom> cgraph (Fcompl -> dim (), false);
        sout << "Creating the chain complex of the graph of F... ";
        createchaincomplex (cgraph, *Fcompl);
        sout << "Done.\n";

        // create the chain complex from Y (this is a relative complex)
        chaincomplex<euclidom> cy (Ydim, false);
        sout << "Creating the chain complex of Y... ";
        createchaincomplex (cy, *Ycompl);
        sout << "Done.\n";

        // create the projection map from the graph of the map to Y
        chainmap<euclidom> cmap (cgraph, cy);
        sout << "Creating the chain map of the projection... ";
        createprojection (*Fcompl, *Ycompl, cmap, Xspacedim,
                Yspacedim, 0);
        sout << "Done.\n";

        // if this is an index map, create the projection map from the graph
        // of the map to X composed with the inclusion into Y
        chainmap<euclidom> imap (cgraph, cy);
        sout << "Creating the chain map of the inclusion... ";
        createprojection (*Fcompl, *Ycompl, imap, 0, Xspacedim, Yspacedim);
        sout << "Done.\n";

        // forget the graph of F if it is not going to be used anymore
        if (gfcompl)
                (*gfcompl) = Fcompl;
        else
                delete Fcompl;

        // forget the cubical complex Y unless requested to keep it
        if (gycompl)
                (*gycompl) = Ycompl;
        else
                delete Ycompl;

        // ----- compute and show homology, save generators -----

        // prepare the name of the graph of F
        word gFname;
        gFname << "the graph of " << Fname;

        // compute the homology of the chain complex of the graph of the map
        int maxlevel_cx = Homology (cgraph, gFname, hom_cx);

        // extract the computed generators of the graph if requested to
        if (gfgen)
                *gfgen = ExtractGenerators (cgraph, hom_cx, maxlevel_cx);

        // compute the homology of the chain complex of Y
        chain<euclidom> *hom_cy = 0;
        int maxlevel_cy = Homology (cy, Xname, hom_cy);

        // extract the computed generators of Y if requested to
        if (gygen)
                *gygen = ExtractGenerators (cy, hom_cy, maxlevel_cy);

        // ----- show the map(s) -----

        // determine the maximal non-trivial homology level for maps
        int homdimgraph = cgraph. dim ();
        while ((homdimgraph >= 0) && (!hom_cx [homdimgraph]. size ()))
                -- homdimgraph;
        int homdimy = cy. dim ();
        while ((homdimy >= 0) && (!hom_cy [homdimy]. size ()))
                -- homdimy;
//      sout << "Maximal homology level considered for the map "
//              "is " << homdim << ".\n";

        // prepare the data structures for the homology
        chaincomplex<euclidom> hgraph (homdimgraph);
        chaincomplex<euclidom> hy (homdimy);
        chainmap<euclidom> *hmap = new chainmap<euclidom> (hgraph, hy);
        chainmap<euclidom> hincl (hgraph, hy);
        chainmap<euclidom> *hcomp = new chainmap<euclidom> (hgraph, hgraph);

        // show the map induced in homology by the chain map
        sout << "The map induced in homology is as follows:\n";
        hgraph. take_homology (hom_cx);
        hy. take_homology (hom_cy);
        hmap -> take_homology (cmap, hom_cx, hom_cy);
        hmap -> show (sout, "\tf", "x", "y");

        // show the map induced in homology by the inclusion map
        sout << "The map induced in homology by the inclusion:\n";
        hincl. take_homology (imap, hom_cx, hom_cy);
        hincl. show (sout, "\ti", "x", "y");

        sout << "The inverse of the map induced by the inclusion:\n";
        bool invertible = true;
        try
        {
                hincl. invert ();
        }
        catch (...)
        {
                sout << "Oh, my goodness! This map is apparently "
                        "not invertible.\n";
                invertible = false;
        }

        if (invertible)
        {
                hincl. show (sout, "\tI", "y", "x");

                sout << "The composition of F and the inverse "
                        "of the map induced by the inclusion:\n";
                hcomp -> compose (hincl, *hmap);
                hcomp -> show (sout, "\tF", "x", "x");
        }

        // set the appropriate map
        if (invertible)
        {
                hom_f = hcomp;
                delete hmap;
        }
        else
        {
                hom_f = hmap;
                delete hcomp;
        }

        // throw an exception if the map is not invertible
        if (!invertible)
                throw "Unable to invert the inclusion map.";

        maxlevel = (maxlevel_cx < maxlevel_cy) ? maxlevel_cx : maxlevel_cy;
        return maxlevel;
} /* Homology2l */

template<class euclidom , class cubetype >
int chomp::homology::Homology2l ( mvmap< cubetype, cubetype > &  Fcubmap,
hashedset< cubetype > &  Xcubes,
hashedset< cubetype > &  Acubes,
chain< euclidom > *&  hom,
int &  maxlevel,
chainmap< euclidom > *&  hom_f,
int  careful = 0x01,
chain< euclidom > ***  gfgen = 0,
gcomplex< tCell2l< typename cubetype::CellType >, euclidom > **  gfcompl = 0,
chain< euclidom > ***  gygen = 0,
gcomplex< tCell2l< typename cubetype::CellType >, euclidom > **  gycompl = 0 
)

A version of the above procedure with the default names.

Definition at line 1979 of file homology.h.

References Homology2l().

{
        return Homology2l (Fcubmap, "F", Xcubes, "X", Acubes, "A", hom,
                maxlevel, hom_f, careful, gfgen, gfcompl, gygen, gycompl);
} /* Homology2l */

template<class euclidom >
chainmap<euclidom>* chomp::homology::HomologyMap ( const chainmap< euclidom > &  cmap,
const chain< euclidom > *  hom_cx,
const chain< euclidom > *  hom_cy,
int  maxlevel 
)

Extracts the homomorphism induced in homology from the chain map on two chain complexes whose homology has just been computed.

Note that 'maxlevel' must be the MINIMUM of the two maximal nontrivial homology levels encoded in "hom_cx" and "hom_cy". Returns a pointer to the extracted homomorphism.

Explanation: In order to compute the homomorphism induced in homology by a chain map, it is enough to define the chain map between two chain complexes (one can also use the same chain complex for its domain and codomain if the map is an endomorphism), and then compute the homology of both chain complexes. One can use one of the functions below to extract the information obtained in this way into a simpler (and smaller) data structure. The extracted map is exactly the homomorphism induced in homology. Since the returned chain map is allocated with the 'new' operator, one should 'delete' it when finished.

Definition at line 707 of file homology.h.

               : ChainMap *HomologyMap (const ChainMap &cmap,
//      const Chain *hom_cx, const Chain *hom_cy, int maxlevel).
{
        // if the maximal level is wrong, return 0
        if (maxlevel < 0)
                return 0;

        // allocate chain complexes of appropriate dimension and a chain map
        chaincomplex<euclidom> hx (maxlevel);
        chaincomplex<euclidom> hy (maxlevel);
        chainmap<euclidom> *hmap = new chainmap<euclidom> (hx, hy);

        // create the chain complexes reflecting the homology module(s)
        hx. take_homology (hom_cx);
        hy. take_homology (hom_cy);

        // create the chain map accordingly
        hmap -> take_homology (cmap, hom_cx, hom_cy);
        return hmap;
} /* HomologyMap */

template<class euclidom >
chainmap<euclidom>* chomp::homology::HomologyMap ( const chainmap< euclidom > &  cmap,
const chain< euclidom > *  hom_cx,
int  maxlevel 
)

Extracts the endomorphism induced in homology from the chain map on one chain complex whose homology has just been computed.

Returns a pointer to the extracted homomorphism.

Definition at line 735 of file homology.h.

               : ChainMap *HomologyMap (const ChainMap &cmap,
//      const Chain *hom_cx, int maxlevel).
{
        // if the maximal level is wrong, return 0
        if (maxlevel < 0)
                return 0;

        // allocate chain complexes of appropriate dimension and a chain map
        chaincomplex<euclidom> hx (maxlevel);
        chainmap<euclidom> *hmap = new chainmap<euclidom> (hx, hx);

        // create the chain complexes reflecting the homology module(s)
        hx. take_homology (hom_cx);

        // create the chain map accordingly
        hmap -> take_homology (cmap, hom_cx, hom_cx);
        return hmap;
} /* HomologyMap */

void chomp::homology::ignorecomments ( std::istream &  in  )  [inline]

Ignores white characters (spaces, tabulators, CRs and LFs), as well as comments from the input text file.

The comment begins with a semicolon and ends with the end of the line.

Definition at line 361 of file textfile.h.

References ignoreline().

Referenced by operator>>(), read(), readcoordinates(), ReadCubeFix(), readcubeorcell(), ReadCubes(), ReadCubicalCell(), ReadCubicalMap(), readdomain(), readimage(), readrestriction(), chomp::multiwork::mwSubCoordinator< dim, coord >::ReadResults(), readselective(), readtheset(), and scancubes().

{
        int ch = in. peek ();
        while (true)
        {
                switch (ch)
                {
                case ';':
                        ignoreline (in);
                        ch = in. peek ();
                        break;
                case ' ':
                case '\t':
                case '\r':
                case '\n':
                        in. get ();
                        ch = in. peek ();
                        break;
                default:
                        return;
                }
        }       
} /* ignorecomments */

void chomp::homology::ignoreline ( std::istream &  in  )  [inline]

Ignores the input characters until the end of a line, including this end of the line.

Definition at line 352 of file textfile.h.

Referenced by ignorecomments(), read(), readcubeorcell(), ReadCubicalMap(), readdomain(), readimage(), chomp::multiwork::mwSubCoordinator< dim, coord >::ReadResults(), readselective(), readtheset(), and scancubes().

{
        in. ignore (0x7FFFFFFFl, '\n');
        return;
} /* ignoreline */

template<class HSet >
bool chomp::homology::inclusion ( const HSet &  X,
const HSet &  Y 
)

Verifies if X is a subset of Y. Returns true if yes, false if not.

Definition at line 310 of file indxpalg.h.

Referenced by Homology(), and IndexPairM().

{
        int_t countX = X. size ();
        if (countX && Y. empty ())
                return false;

        for (int_t i = 0; i < countX; ++ i)
                if (!Y. check (X [i]))
                        return false;
        return true;
} /* inclusion */

template<class wType >
int_t chomp::homology::inclusionGraph ( const diGraph< wType > &  g,
int_t  nVert,
diGraph< wType > &  result 
) [inline]

Computes the graph that represents flow-induced relations on Morse sets.

The vertices of the result graph are the first "nVert" vertices from the source graph. An edge is added to the new graph iff there exists a path from one vertex to another. Edges that come from the transitive closure are not added.

Definition at line 3490 of file digraph.h.

{
        // remember the number of vertices in the input graph
        int_t nVertG = g. countVertices ();
        if (!nVertG)
                return 0;

        // mark each vertex as non-visited
        BitField visited;
        visited. allocate (nVertG);
        visited. clearall (nVertG);

        // create the sets of vertices reachable from each vertex
        BitSets lists (nVertG, nVert);

        // prepare stacks for the DFS algorithm
        std::stack<int_t> s_vertex;
        std::stack<int_t> s_edge;

        // use DFS to propagate the reachable sets
        int_t startVertex = 0;
        int_t vertex = 0;
        int_t edge = 0;
        visited. set (vertex);
        while (1)
        {
                // go back with the recursion
                // if all the edges have been processed
                if (edge >= g. countEdges (vertex))
                {
                        // if this was the top recursion level,
                        // then find another starting point or quit
                        if (s_vertex. empty ())
                        {
                                while ((startVertex < nVertG) &&
                                        (visited. test (startVertex)))
                                        ++ startVertex;
                                if (startVertex >= nVertG)
                                        break;
                                vertex = startVertex;
                                edge = 0;
                                visited. set (vertex);
                                continue;
                        }

                        // determine the previous vertex (to trace back to)
                        int_t prev = s_vertex. top ();

                        // add the list of the current vertex
                        // to the list of the previous vertex
                        // unless that was one of the first 'nVert' vertices
                        if (vertex >= nVert)
                                lists. addset (prev, vertex);

                        // return from the recursion
                        vertex = prev;
                        s_vertex. pop ();
                        edge = s_edge. top ();
                        s_edge. pop ();
                        continue;
                }

                // take the next vertex
                int_t next = g. getEdge (vertex, edge ++);

                // add the number to the list if appropriate
                if (next < nVert)
                        lists. add (vertex, next);

                // go to the deeper recursion level if vertex not visited
                if (!visited. test (next))
                {
                        // store the previous variables at the stacks
                        s_vertex. push (vertex);
                        s_edge. push (edge);

                        // take the new vertex and mark as visited
                        vertex = next;
                        edge = 0;
                        visited. set (vertex);
                }

                // add the list of the next vertex to the current one
                // if the vertex has already been visited before
                // and the vertex is not one of the first 'nVert' ones
                else if (next >= nVert)
                {
                        lists. addset (vertex, next);
                }
        }

        // create the result graph based on the lists of edges
        for (int_t vertex = 0; vertex < nVert; ++ vertex)
        {
                result. addVertex ();
                int_t edge = lists. get (vertex);
                while (edge >= 0)
                {
                        result. addEdge (edge);
                        edge = lists. get (vertex, edge + 1);
                }
        }

        // free memory and exit
        visited. free ();
        return 0;
} /* inclusionGraph */

template<class wType , class TConn >
int_t chomp::homology::inclusionGraph ( const diGraph< wType > &  g,
int_t  nVert,
diGraph< wType > &  result,
TConn &  connections 
) [inline]

A more complicated version of the 'inclusionGraph' function.

Computes the graph that represents flow-induced relations on Morse sets. The vertices of the result graph are the first "nVert" vertices from the source graph. An edge is added to the new graph iff there exists a path from one vertex to another. Edges that come from the transitive closure are not added. Records vertices along connecting orbits using operator () with the following arguments: source, target, vertex.

Definition at line 3610 of file digraph.h.

{
        // remember the number of vertices in the input graph
        int_t nVertG = g. countVertices ();
        if (!nVertG)
                return 0;

        // mark each vertex as non-visited
        BitField visited;
        visited. allocate (nVertG);
        visited. clearall (nVertG);

        // create the sets of vertices reachable from each vertex
        BitSets forwardlists (nVertG, nVert);

        // prepare stacks for the DFS algorithm
        std::stack<int_t> s_vertex;
        std::stack<int_t> s_edge;

        // use DFS to propagate the reachable sets
        int_t startVertex = 0;
        int_t vertex = 0;
        int_t edge = 0;
        visited. set (vertex);
        while (1)
        {
                // go back with the recursion
                // if all the edges have been processed
                if (edge >= g. countEdges (vertex))
                {
                        // if this was the top recursion level,
                        // then find another starting point or quit
                        if (s_vertex. empty ())
                        {
                                while ((startVertex < nVertG) &&
                                        (visited. test (startVertex)))
                                        ++ startVertex;
                                if (startVertex >= nVertG)
                                        break;
                                vertex = startVertex;
                                edge = 0;
                                visited. set (vertex);
                                continue;
                        }

                        // determine the previous vertex (to trace back to)
                        int_t prev = s_vertex. top ();

                        // add the list of the current vertex
                        // to the list of the previous vertex
                        // unless that was one of the first 'nVert' vertices
                        if (vertex >= nVert)
                                forwardlists. addset (prev, vertex);

                        // return from the recursion
                        vertex = prev;
                        s_vertex. pop ();
                        edge = s_edge. top ();
                        s_edge. pop ();
                        continue;
                }

                // take the next vertex
                int_t next = g. getEdge (vertex, edge ++);

                // add the number to the list if appropriate
                if (next < nVert)
                        forwardlists. add (vertex, next);

                // go to the deeper recursion level if vertex not visited
                if (!visited. test (next))
                {
                        // store the previous variables at the stacks
                        s_vertex. push (vertex);
                        s_edge. push (edge);

                        // take the new vertex and mark as visited
                        vertex = next;
                        edge = 0;
                        visited. set (vertex);
                }

                // add the list of the next vertex to the current one
                // if the vertex has already been visited before
                // and the vertex is not one of the first 'nVert' ones
                else if (next >= nVert)
                {
                        forwardlists. addset (vertex, next);
                }
        }

        // ------------------------------------------

        // create the sets of vertices that can reach each vertex
        BitSets backlists (nVertG, nVert);

        diGraph<wType> gT;
        g. transpose (gT);

        // do a simple test for debugging purposes
        if (!s_vertex. empty () || !s_edge. empty ())
                throw "DEBUG: Nonempty stacks in 'inclusionGraph'.";

        // mark all the vertices as unvisited for the backward run
        visited. clearall (nVertG);

        // use DFS to propagate the reachable sets
        startVertex = 0;
        vertex = 0;
        edge = 0;
        visited. set (vertex);
        while (1)
        {
                // go back with the recursion
                // if all the edges have been processed
                if (edge >= gT. countEdges (vertex))
                {
                        // if this was the top recursion level,
                        // then find another starting point or quit
                        if (s_vertex. empty ())
                        {
                                while ((startVertex < nVertG) &&
                                        (visited. test (startVertex)))
                                        ++ startVertex;
                                if (startVertex >= nVertG)
                                        break;
                                vertex = startVertex;
                                edge = 0;
                                visited. set (vertex);
                                continue;
                        }

                        // determine the previous vertex (to trace back to)
                        int_t prev = s_vertex. top ();

                        // add the list of the current vertex
                        // to the list of the previous vertex
                        // unless that was one of the first 'nVert' vertices
                        if (vertex >= nVert)
                                backlists. addset (prev, vertex);

                        // return from the recursion
                        vertex = prev;
                        s_vertex. pop ();
                        edge = s_edge. top ();
                        s_edge. pop ();
                        continue;
                }

                // take the next vertex
                int_t next = gT. getEdge (vertex, edge ++);

                // add the number to the list if appropriate
                if (next < nVert)
                        backlists. add (vertex, next);

                // go to the deeper recursion level if vertex not visited
                if (!visited. test (next))
                {
                        // store the previous variables at the stacks
                        s_vertex. push (vertex);
                        s_edge. push (edge);

                        // take the new vertex and mark as visited
                        vertex = next;
                        edge = 0;
                        visited. set (vertex);
                }

                // add the list of the next vertex to the current one
                // if the vertex has already been visited before
                // and the vertex is not one of the first 'nVert' ones
                else if (next >= nVert)
                {
                        backlists. addset (vertex, next);
                }
        }

        // ------------------------------------------

        // record the connections to the obtained data structure
        for (int_t v = nVert; v < nVertG; ++ v)
        {
                int_t bvertex = backlists. get (v);
                while (bvertex >= 0)
                {
                        int_t fvertex = forwardlists. get (v);
                        while (fvertex >= 0)
                        {
                                connections (bvertex, fvertex, v);
                                fvertex = forwardlists. get (v, fvertex + 1);
                        }
                        bvertex = backlists. get (v, bvertex + 1);
                }
        }

        // ------------------------------------------
        
        // create the result graph based on the lists of edges
        for (int_t vertex = 0; vertex < nVert; ++ vertex)
        {
                result. addVertex ();
                int_t edge = forwardlists. get (vertex);
                while (edge >= 0)
                {
                        result. addEdge (edge);
                        edge = forwardlists. get (vertex, edge + 1);
                }
        }

        // free memory and exit
        visited. free ();
        return 0;
} /* inclusionGraph */

template<class TSetOfCubes , class TMap >
int chomp::homology::IndexPairM ( const TMap &  F,
const TSetOfCubes &  initialS,
TSetOfCubes &  resultQ1,
TSetOfCubes &  resultQ2 
)

Constructs a combinatorial index pair satisfying Mrozek's definition.

The initial set S must be invariant, or otherwise some of its cubes may not be included in the resulting invariant set.

Definition at line 362 of file indxpalg.h.

References ExitSetM(), inclusion(), invariantpart(), neighborhood(), scon, and sout.

{
        // prepare the initial guess for S and N
        TSetOfCubes S = initialS;
        TSetOfCubes N;
        neighborhood (S, N);

        sout << "Starting with " << S. size () << " cubes in S_0, " <<
                N. size () << " cubes in N.\n";
        while (1)
        {

                // compute S := Inv (N)
                sout << "S := Inv(N)... ";
                scon << "(computing)\b\b\b\b\b\b\b\b\b\b\b";
                TSetOfCubes empty;
                S = empty;
        //      S = initialS;
                invariantpart (N, F, S);
                sout << S. size () << " cubes; o(S) has ";

                // compute N' := o (S)
                TSetOfCubes newN;
                neighborhood (S, newN);
                sout << newN. size () << " cubes.\n";
                
                // if Int (N) contains Inv (N), then exit
                if (inclusion (newN, N))
                        break;
                // otherwise take a larget N and repeat
                else
                {
                        sout << "Set N := o(S). ";
                        N = newN;
                }
        }

        // compute the index pair (Q1 \cup Q2, Q2)
        resultQ1 = S;
        ExitSetM (N, S, F, resultQ2);
        return 0;
} /* IndexPairM */

template<class TSetOfCubes , class TMap >
int chomp::homology::IndexPairP ( const TMap &  F,
const TSetOfCubes &  initialS,
TSetOfCubes &  resultQ1,
TSetOfCubes &  resultQ2 
)

Constructs a combinatorial index pair satisfying Pilarczyk's definition.

The initial set S must be an approximation of the invariant set for the map, for example, a rough covering obtained in numerical simulations.

Definition at line 415 of file indxpalg.h.

References scon, and sout.

{
        resultQ1 = initialS;

        // compute the initial Q2 = f (Q1) - Q1
        sout << "Computing the map on Q1 (" << resultQ1. size () <<
                " cubes)... ";
        for (int_t i = 0; i < resultQ1. size (); ++ i)
        {
                const TSetOfCubes &img = F (resultQ1 [i]);
                for (int_t j = 0; j < img. size (); ++ j)
                {
                        if (!resultQ1. check (img [j]))
                                resultQ2. add (img [j]);
                }
        }
        sout << resultQ2. size () << " cubes added to Q2.\n";

//      sout << "Starting with " << resultQ1. size () <<
//              " cubes in Q1, " << resultQ2. size () <<
//              " cubes in Q2.\n";

        // compute images of cubes in Q2 and if any of them intersects Q1
        // then move this cube from Q2 to Q1
        sout << "Increasing Q1 and Q2 until F(Q2) is disjoint from Q1... ";
        int_t counter = 0;
        int_t countimages = 0;
        int_t cur = 0;
        TSetOfCubes removed;
        while (1)
        {
                // if there are no cubes in Q2, repeat or finish
                if (cur >= resultQ2. size ())
                {
                        if (removed. empty ())
                                break;
                        resultQ2. remove (removed);
                        TSetOfCubes empty;
                        removed = empty;
                        cur = 0;
                        continue;
                }

                // display a counter
                ++ counter;
                if (!(counter % 373))
                        scon << std::setw (12) << counter <<
                                "\b\b\b\b\b\b\b\b\b\b\b\b";

                // verify whether F(q) intersects Q1
                bool intersects = false;
                const TSetOfCubes &img = F (resultQ2 [cur]);
                ++ countimages;
                for (int_t j = 0; j < img. size (); ++ j)
                {
                        if (resultQ1. check (img [j]))
                        {
                                intersects = true;
                                break;
                        }
                }
                
                if (intersects)
                {
                        // add F(q)\Q1 to Q2
                        for (int_t j = 0; j < img. size (); ++ j)
                        {
                                if (!resultQ1. check (img [j]))
                                        resultQ2. add (img [j]);
                        }
                        // move q from Q2 to Q1
                        resultQ1. add (resultQ2 [cur]);
                        removed. add (resultQ2 [cur]);
                }

                // take the next cube from Q2
                ++ cur;
        }
        sout << countimages << " analyzed.\n";
        return 0;
} /* IndexPairP */

void chomp::homology::int2bits ( int  bits,
int_t  length,
BitField &  field 
) [inline]

The length must not exceed the size of the integer.

Definition at line 200 of file bitfield.h.

{
        unsigned char *tab = field. table;
        if (!tab)
                throw "Trying to set values to an undefined bitfield.";
        while (length >= 0)
        {
                *(tab ++) = static_cast<unsigned char> (bits & 0xFF);
                bits >>= 8;
                length -= 8;
        }
        return;
} /* int2bits */

template<class tCube >
bool chomp::homology::intersection2l ( const tCube &  q0,
const tCube &  q1,
BitField *  bits 
)

Computes the intersection between two cubes at different layers.

One cube is at layer 1, and the other is at layer 0, but not in the set on which the identification takes place. The intersection directions are marked in the given bit field. Returns true iff the intersection is nonempty.

Definition at line 945 of file twolayer.h.

References boundarycell(), boundarylength(), chomp::homology::tCell2l< tCell >::identify(), and neighbor2bit().

Referenced by getneighbors_generate(), and getneighbors_scan().

{
        // determine the set of cells at the intersection of layers
        const hashedset<typename tCube::CellType> &ident =
                tCell2l<typename tCube::CellType>::identify ();

        // compute the intersection of the cubes
        typename tCube::CellType intersection (q0, q1);
        hashedset<typename tCube::CellType> faces;
        faces. add (intersection);

        // check all the faces of the cells
        int_t current = 0;
        int_t counter = 0;
        while (current < faces. size ())
        {
                const typename tCube::CellType &face = faces [current ++];
                if (ident. check (face))
                {
                        if (bits)
                                bits -> set (neighbor2bit (q0, face));
                        ++ counter;
                }
                else
                {
                        for (int_t i = 0; i < boundarylength (face); ++ i)
                                faces. add (boundarycell (face, i));
                }
        }
        return (counter > 0);
} /* intersection2l */

template<class TSetOfCubes , class TMap >
void chomp::homology::invariantpart ( TSetOfCubes &  X,
const TMap &  F,
TSetOfCubes &  result 
)

Computes X := Inv (X).

New algorithm by Bill Kalies and Hyunju Ban. If the graph 'gInv' is given, then the resulting graph is created, otherwise only the set X is modified.

Definition at line 239 of file indxpalg.h.

References SCC().

Referenced by IndexPairM().

{
        // do nothing if the set X is empty
        int_t ncount = X. size ();
        if (!ncount)
                return;

        // create a digraph of the map
        diGraph<> g;
        for (int_t n = 0; n < ncount; ++ n)
        {
                g. addVertex ();
                const TSetOfCubes &img = F (X [n]);
                int_t icount = img. size ();
                for (int_t i = 0; i < icount; ++ i)
                {
                        int_t number = X. getnumber (img [i]);
                        if (number < 0)
                                continue;
                        g. addEdge (number);
                }
        }

        // compute the chain recurrent set of the graph
        // and remember the transposed graph
        multitable<int_t> compVertices, compEnds;
        diGraph<> gT;
        int_t count = SCC (g, compVertices, compEnds,
                static_cast<diGraph<> *> (0), &gT);

        // retrieve vertices that can be reached from the chain recurrent set
        int_t nVertices = ncount;
        char *forward = new char [nVertices];
        for (int_t i = 0; i < nVertices; ++ i)
                forward [i] = 0;
        for (int_t cur = 0; cur < count; ++ cur)
        {
                g. DFScolor (forward, '\1',
                        compVertices [cur ? compEnds [cur - 1] :
                        static_cast<int_t> (0)]);
        }

        // retrieve vertices that can reach the chein recurrent set
        char *backward = new char [nVertices];
        for (int_t i = 0; i < nVertices; ++ i)
                backward [i] = 0;
        for (int_t cur = 0; cur < count; ++ cur)
        {
                gT. DFScolor (backward, '\1',
                        compVertices [cur ? compEnds [cur - 1] :
                        static_cast<int_t> (0)]);
        }

        // compute the new set of cubes
        for (int_t i = 0; i < nVertices; ++ i)
                if (forward [i] && backward [i])
                        result. add (X [i]);

        // clean the memory and return
        delete [] backward;
        delete [] forward;
        return;
} /* invariantpart */

template<class set1type , class set2type >
setunion<set1type,set2type> chomp::homology::makesetunion ( const set1type &  set1,
const set2type &  set2 
) [inline]

Creates an object which represents the union of two sets.

Definition at line 226 of file setunion.h.

Referenced by acyclic_rel(), cubreducequiet(), and remainsacyclic().

{
        return setunion<set1type,set2type> (set1, set2);
} /* makesetunion */

template<class wType , class matrix >
void chomp::homology::matrix2graph ( const matrix &  m,
int_t  n,
diGraph< wType > &  g 
) [inline]

Creates a graph based on the given adjacency matrix.

If m [i] [j] is nonzero, then the edge i -> j is added to the graph. It is assumed that the graph g is initially empty. The size of the matrix (the number of vertices), n, must be given.

Definition at line 3852 of file digraph.h.

Referenced by transitiveReduction().

{
        for (int_t v = 0; v < n; ++ v)
        {
                g. addVertex ();
                for (int_t w = 0; w < n; ++ w)
                        if (m [v] [w])
                                g. addEdge (w);
        }
        return;
} /* matrix2graph */

template<typename T >
void chomp::homology::my_swap ( T &  x,
T &  y 
) [inline]

Definition at line 56 of file multitab.h.

Referenced by chomp::homology::multitable< element >::swap(), chomp::homology::hashedset< element >::swap(), and chomp::homology::diGraph< wType >::swap().

{
        T tmp = x;
        x = y;
        y = tmp;
        return;
} /* my_swap */

template<class tCube >
int_t chomp::homology::neighbor2bit ( const tCube2l< tCube > &  q,
const tCube2l< tCube > &  neighbor 
)

Specialization of the "neighbor2bit" function for two-layer cubes.

Throws an exception, because there might be more than one bit which cescribes the intersection.

Definition at line 933 of file twolayer.h.

{
        throw "Trying to use 'neighbor2bit' for a 2-layer cube.";
        return -1;
} /* neighbor2bit */

template<class tCube >
int_t chomp::homology::neighbor2bit ( const tCube &  q,
const tCube &  neighbor 
)

Returns the number of the neighbor bit for the given neighbor of 'q' or -1 if not a neighbor or the same cube as 'q'.

Definition at line 85 of file neighbor.h.

Referenced by getneighbors_scan(), and intersection2l().

{
        // define the type of coordinates
        typedef typename tCube::CoordType coordType;

        coordType c0 [tCube::MaxDim];
        q. coord (c0);
        coordType c1 [tCube::MaxDim];
        neighbor. coord (c1);
        int dim = q. dim ();

        int_t number = 0;
        const coordType *wrap = tCube::PointBase::getwrapping (dim);
        for (int i = 0; i < dim; ++ i)
        {
                if (i)
                        number *= 3;
                switch (c1 [i] - c0 [i])
                {
                        case -1:
                                ++ number;
                        case 1:
                                ++ number;
                                break;
                        case 0:
                                break;
                        default:
                                if (!wrap || !wrap [i])
                                        return -1;
                                if ((c1 [i] - c0 [i]) == (wrap [i] - 1))
                                        number += 2;
                                else if ((c1 [i] - c0 [i]) == (1 - wrap [i]))
                                        ++ number;
                                else
                                        return -1;
                                break;
                }
        }

        return number - 1;
} /* neighbor2bit */

template<class tCube >
int_t chomp::homology::neighbor2bit ( const tCube &  q,
const typename tCube::CellType &  face 
)

Returns the number of the neighbor bit for the neighbor which intersects the given cube at the face provided.

Definition at line 130 of file neighbor.h.

{
        // define the type of coordinates
        typedef typename tCube::CoordType coordType;

        // determine the space dimension and the coordinates of the input
        int dim = q. dim ();
        coordType coord [tCube::MaxDim];
        q. coord (coord);
        coordType cLeft [tCube::MaxDim];
        face. leftcoord (cLeft);
        coordType cRight [tCube::MaxDim];
        face. rightcoord (cRight);

        // compute the number of the neighbor based on the coordinates
        int_t number = 0;
        for (int i = 0; i < dim; ++ i)
        {
                if (i)
                        number *= 3;
                // if the neighbor is shifted upwards
                if (cLeft [i] != coord [i])
                        number += 1;
                // if the neighbor is shifted downwards
                else if (cRight [i] == cLeft [i])
                        number += 2;
                // otherwise the neighbor is at the same level
        }

        return number - 1;
} /* neighbor2bit */

template<class TSetOfCubes >
int chomp::homology::neighborhood ( const TSetOfCubes &  X,
TSetOfCubes &  result 
)

Computes a cubical neighborhood of width 1 around the set.

Definition at line 191 of file indxpalg.h.

Referenced by IndexPairM().

{
        // extract the necessary types and constants
        using namespace chomp::homology;
        typedef typename TSetOfCubes::value_type cubetype;
        typedef typename cubetype::CoordType coordtype;
        typedef tRectangle<coordtype> rectangle;
        const int maxdim = cubetype::MaxDim;

        // create arrays for the corners of a rectangle around each cube
        coordtype mincoord [maxdim], maxcoord [maxdim];

        // for all the cubes in X
        int_t ncount = X. size ();
        for (int_t n = 0; n < ncount; ++ n)
        {
                // get the coordinates of the cube
                int dim = X [n]. dim ();
                X [n]. coord (mincoord);

                // prepare the corners of a rectangle for the cube
                // and its neighbors
                for (int i = 0; i < dim; ++ i)
                {
                        maxcoord [i] = mincoord [i];
                        ++ maxcoord [i];
                        ++ maxcoord [i];
                        -- mincoord [i];
                }

                // add cubes from the rectangle to the resulting set
                rectangle r (mincoord, maxcoord, dim);
                const coordtype *c;
                while ((c = r. get ()) != 0)
                        result. add (cubetype (c, dim));
        }
        return 0;
} /* neighborhood */

bool chomp::homology::numberisprime ( unsigned  n  )  [inline]

Verifies if the given number is a prime number.

Returns: true = Yes, false = No.

Definition at line 141 of file pointset.h.

Referenced by ceilprimenumber().

{
        if (n < 2)
                return false;

        unsigned i = 2;
        while (i * i <= n)
                if (!(n % i ++))
                        return false;

        return true;
} /* numberisprime */

template<class tCube >
int chomp::homology::operator!= ( const tCube2l< tCube > &  c1,
const tCube2l< tCube > &  c2 
) [inline]

The operator != verifies whether two cubes are different.

(Uses the == operator.)

Definition at line 387 of file twolayer.h.

{
        return !(c1 == c2);
} /* operator != */

template<int Dim, int twoPower>
bool chomp::homology::operator!= ( const typename bincube< Dim, twoPower >::neighborhood_iterator &  x1,
const typename bincube< Dim, twoPower >::neighborhood_iterator &  x2 
) [inline]

Definition at line 785 of file bincube.h.

{
//      sout << "DEBUG !=\n";
        return !(x1 == x2);
} /* bincube::neighborhood_iterator::operator != */

template<class tCell >
int chomp::homology::operator!= ( const tCell2l< tCell > &  c1,
const tCell2l< tCell > &  c2 
) [inline]

The operator != verifies whether two cubes are different.

(Uses the == operator.)

Definition at line 820 of file twolayer.h.

{
        return !(c1 == c2);
} /* operator != */

int chomp::homology::operator!= ( const Simplex &  s,
const Simplex &  t 
) [inline]

The operator != verifies if the two simplices are different.

Definition at line 314 of file simplex.h.

{
        return !(s == t);
} /* operator != */

int chomp::homology::operator!= ( const word &  w1,
const word &  w2 
) [inline]

Compares two words. Returns 0 if they are the same, 1 otherwise.

Definition at line 270 of file words.h.

{
        return !(w1 == w2);
} /* operator != */

template<class wType1 , class wType2 >
bool chomp::homology::operator!= ( const diGraph< wType1 > &  g1,
const diGraph< wType2 > &  g2 
) [inline]

Definition at line 606 of file digraph.h.

{
        return !(g1 == g2);
} /* operator != */

int chomp::homology::operator!= ( const char *  c,
const word &  w 
) [inline]

Compares a C-style string with a word.

Definition at line 296 of file words.h.

{
        return (w != c);
} /* operator != */

int chomp::homology::operator!= ( const integer &  n,
const integer &  m 
) [inline]

Definition at line 366 of file integer.h.

{
        return (!(n == m));
} /* operator != */

int chomp::homology::operator!= ( const integer &  n,
int  m 
) [inline]

Definition at line 378 of file integer.h.

{
        return !(n == m);
} /* operator != */

template<class coordtype >
int chomp::homology::operator!= ( const tCellVar< coordtype > &  c1,
const tCellVar< coordtype > &  c2 
) [inline]

Checks if the two cells are different.

Definition at line 490 of file cellvar.h.

{
        return !(c1 == c2);
} /* operator != */

int chomp::homology::operator!= ( const word &  w,
const char *  c 
) [inline]

Compares a word with a C-style string.

Definition at line 284 of file words.h.

{
        return !(w == c);
} /* operator != */

template<int dimfix, class coordtype >
int chomp::homology::operator!= ( const tCellFix< dimfix, coordtype > &  c1,
const tCellFix< dimfix, coordtype > &  c2 
) [inline]

Checks if the two cells are different.

Definition at line 434 of file cellfix.h.

{
        return !(c1 == c2);
} /* operator != */

template<class coordtype >
int chomp::homology::operator!= ( const tCubeBase< coordtype > &  c1,
const tCubeBase< coordtype > &  c2 
) [inline]

The operator != for comparing full cubes.

Definition at line 260 of file cubebase.h.

{
        return !(c1 == c2);
} /* operator != */

template<int dim1, int dim2, class coordtype >
int chomp::homology::operator!= ( const tCubeFix< dim1, coordtype > &  c1,
const tCubeFix< dim2, coordtype > &  c2 
) [inline]

The operator != for comparing full cubes.

Definition at line 252 of file cubefix.h.

{
        return !(c1 == c2);
} /* operator != */

template<class coordtype >
int chomp::homology::operator!= ( const tCellBase< coordtype > &  c1,
const tCellBase< coordtype > &  c2 
) [inline]

Checks if the two cells are different.

Definition at line 416 of file cellbase.h.

{
        return !(c1 == c2);
} /* operator != */

template<class coordtype >
int chomp::homology::operator!= ( const tCubeVar< coordtype > &  c1,
const tCubeVar< coordtype > &  c2 
) [inline]

The operator != for comparing full cubes.

Definition at line 316 of file cubevar.h.

{
        return !(c1 == c2);
} /* operator != */

template<class coordtype >
tCubeVar<coordtype> chomp::homology::operator* ( const tCubeVar< coordtype > &  c1,
const tCubeVar< coordtype > &  c2 
) [inline]

Computes the Cartesian product of two cubes.

Definition at line 326 of file cubevar.h.

{
        int dim1 = c1. dim (), dim2 = c2. dim ();
        if (dim1 + dim2 >= tCubeVar<coordtype>::MaxDim)
                throw "Dimension too high to concatenate coordinates.";
        coordtype coord [tCubeVar<coordtype>::MaxDim];
        c1. coord (coord);
        c2. coord (coord + dim1);
        return tCubeVar<coordtype> (coord, dim1 + dim2);
} /* operator * */

template<class tCell >
tCell2l<tCell> chomp::homology::operator* ( const tCell2l< tCell > &  c1,
const tCell2l< tCell > &  c2 
) [inline]

The operator * computes the Cartesian product of two cells.

Definition at line 828 of file twolayer.h.

{
        tCell q (c1. cell () * c2. cell ());
        typename tCell2l<tCell>::LayerType
                l ((c1. layer () << 2) | c2. layer ());
        return tCell2l<tCell> (q, l);
} /* operator * */

template<int dim1, int dim2, class coordtype >
tCellFix<dim1+dim2,coordtype> chomp::homology::operator* ( const tCellFix< dim1, coordtype > &  c1,
const tCellFix< dim2, coordtype > &  c2 
) [inline]

Computes the Cartesian product of two cells.

Definition at line 445 of file cellfix.h.

{
        // prepare arrays for the coordinates of the cell to create
        coordtype left [dim1 + dim2];
        coordtype right [dim1 + dim2];

        // extract the coordinates of the first cell
        c1. leftcoord (left);
        c1. rightcoord (right);

        // extract the coordinates of the second cell
        c2. leftcoord (left + dim1);
        c2. rightcoord (right + dim1);

        // create the Cartesian product of the cells
        return tCellFix<dim1+dim2,coordtype> (left, right,
                dim1 + dim2, c1. dim () + c2. dim ());
} /* operator * */

template<class coordtype >
tCubeBase<coordtype> chomp::homology::operator* ( const tCubeBase< coordtype > &  c1,
const tCubeBase< coordtype > &  c2 
) [inline]

Computes the Cartesian product of two cubes.

Definition at line 270 of file cubebase.h.

{
        int dim1 = c1. dim (), dim2 = c2. dim ();
        if (dim1 + dim2 >= tCubeBase<coordtype>::MaxDim)
                throw "Dimension too high to concatenate coordinates.";
        coordtype coord [tCubeBase<coordtype>::MaxDim];
        c1. coord (coord);
        c2. coord (coord + dim1);
        return tCubeBase<coordtype> (coord, dim1 + dim2);
} /* operator * */

template<int dim1, int dim2, class coordtype >
tCubeFix<dim1+dim2,coordtype> chomp::homology::operator* ( const tCubeFix< dim1, coordtype > &  c1,
const tCubeFix< dim2, coordtype > &  c2 
) [inline]

Computes the Cartesian product of two cubes.

Definition at line 263 of file cubefix.h.

{
        coordtype coord [dim1 + dim2];
        c1. coord (coord);
        c2. coord (coord + dim1);
        return tCubeFix<dim1+dim2,coordtype> (coord);
} /* operator * */

template<class tCube >
tCube2l<tCube> chomp::homology::operator* ( const tCube2l< tCube > &  c1,
const tCube2l< tCube > &  c2 
) [inline]

The operator * computes the Cartesian product of two cubes.

Definition at line 395 of file twolayer.h.

{
        tCube q (c1. cube () * c2. cube ());
        typename tCube2l<tCube>::LayerType
                l ((c1. layer () << 2) | c2. layer ());
        return tCube2l<tCube> (q, l);
} /* operator * */

template<class coordtype >
tCellVar<coordtype> chomp::homology::operator* ( const tCellVar< coordtype > &  c1,
const tCellVar< coordtype > &  c2 
) [inline]

Computes the Cartesian product of two cells.

Definition at line 501 of file cellvar.h.

{
        // get the underlying space dimensions for both cells
        int d1 = c1. spacedim (), d2 = c2. spacedim ();
        if (d1 + d2 >= tCellVar<coordtype>::MaxDim)
                throw "Too high dimension of a Cartesian product of cells.";

        // prepare arrays for the coordinates of the cell to create
        coordtype left [tCellVar<coordtype>::MaxDim];
        coordtype right [tCellVar<coordtype>::MaxDim];

        // extract the coordinates of the first cell
        c1. leftcoord (left);
        c1. rightcoord (right);

        // extract the coordinates of the second cell
        c2. leftcoord (left + d1);
        c2. rightcoord (right + d1);

        // create the Cartesian product of the cells
        return tCellVar<coordtype> (left, right, d1 + d2,
                c1. dim () + c2. dim ());
} /* operator * */

template<class coordtype >
tCellBase<coordtype> chomp::homology::operator* ( const tCellBase< coordtype > &  c1,
const tCellBase< coordtype > &  c2 
) [inline]

Computes the Cartesian product of two cells.

Definition at line 427 of file cellbase.h.

{
        // get the underlying space dimensions for both cells
        int d1 = c1. spacedim (), d2 = c2. spacedim ();
        if (d1 + d2 >= tCellBase<coordtype>::MaxDim)
                throw "Too high dimension of a Cartesian product of cells.";

        // prepare arrays for the coordinates of the cell to create
        coordtype left [tCellBase<coordtype>::MaxDim];
        coordtype right [tCellBase<coordtype>::MaxDim];

        // extract the coordinates of the first cell
        c1. leftcoord (left);
        c1. rightcoord (right);

        // extract the coordinates of the second cell
        c2. leftcoord (left + d1);
        c2. rightcoord (right + d1);

        // create the Cartesian product of the cells
        return tCellBase<coordtype> (left, right, d1 + d2,
                c1. dim () + c2. dim ());
} /* operator * */

template<class element >
hashedset<element>& chomp::homology::operator+= ( hashedset< element > &  s,
const hashedset< element > &  u 
) [inline]

Operator += adds one hashed set to another.

Definition at line 856 of file hashsets.h.

{
        s. add (u);
        return s;
} /* operator += */

integer chomp::homology::operator- ( const integer &  n,
const integer &  m 
) [inline]

Definition at line 383 of file integer.h.

{
        return (n + -m);
} /* operator - */

template<class element >
hashedset<element>& chomp::homology::operator-= ( hashedset< element > &  s,
const hashedset< element > &  u 
) [inline]

Operator -= removes the contents of one set from another.

Definition at line 865 of file hashsets.h.

{
        s. remove (u);
        return s;
} /* operator -= */

int chomp::homology::operator< ( const word &  w1,
const word &  w2 
) [inline]

Compares two words in an alphabetical way (by ASCII codes).

Returns 1 if the first word precedes the second one, 0 otherwise.

Definition at line 305 of file words.h.

{
        const char *c1 = (const char *) w1;
        const char *c2 = (const char *) w2;

        while (*c1 && *c2 && ((*c1) == (*c2)))
        {
                ++ c1;
                ++ c2;
        }
        return ((*c1) < (*c2));
} /* operator < */

bool chomp::homology::operator< ( const integer &  x,
const integer &  y 
) [inline]

Definition at line 412 of file integer.h.

{
        return (x. num < y. num);
} /* operator < */

template<class coordtype >
std::ostream& chomp::homology::operator<< ( std::ostream &  out,
const tCellBase< coordtype > &  c 
) [inline]

Writes a cell to an output stream.

Definition at line 454 of file cellbase.h.

References WriteCubicalCell().

{
        return WriteCubicalCell (out, c);
} /* operator << */

template<class coordtype >
std::ostream& chomp::homology::operator<< ( std::ostream &  out,
const tCubeVar< coordtype > &  c 
) [inline]

Writes a cube to an output stream in the text mode.

The cube is represented by an n-tuple of integers which are the coordinates of the vertex with minimal coordinates.

Definition at line 344 of file cubevar.h.

References WriteCube().

{
        return WriteCube (out, c);
} /* operator << */

template<class TCube >
std::ostream& chomp::homology::operator<< ( std::ostream &  out,
const BufferedMapClass< TCube > &  map 
)

Definition at line 177 of file indxpalg.h.

{
        out << map. F;
        return out;
} /* operator << */

template<class wType >
std::ostream& chomp::homology::operator<< ( std::ostream &  out,
const diGraph< wType > &  g 
) [inline]

Writes a graph in the text mode to an output stream.

Definition at line 2358 of file digraph.h.

{
        return g. show (out, false);
} /* operator << */

std::ostream& chomp::homology::operator<< ( std::ostream &  out,
const Simplex &  s 
) [inline]

Writes a simplex to the output stream in the text format.

Definition at line 352 of file simplex.h.

{
        out << '(';
        if (s. tab)
        {
                int d = s. dim ();
                out << s. tab [1];
                for (int i = 2; i < d + 2; ++ i)
                        out << ',' << s. tab [i];
        }
        out << ')';
        return out;
} /* operator << */

outputstream& chomp::homology::operator<< ( outputstream &  out,
const char *  object 
) [inline]

A specialization of the operator << for writing a C-style string to the output stream.

Definition at line 224 of file textfile.h.

{
        if (out. flush)
        {
                if (out. show)
                        out. out << object << std::flush;
                if (out. log && out. getlogstream ())
                        (*(out. getlogstream ())) << object << std::flush;
        }
        else
        {
                if (out. show)
                        out. out << object;
                if (out. log && out. getlogstream ())
                        (*(out. getlogstream ())) << object;
        }
        return out;
} /* operator << */

template<class euclidom >
std::ostream& chomp::homology::operator<< ( std::ostream &  out,
const chainmap< euclidom > &  m 
) [inline]

Writes a chain map to an output stream in the text format.

Definition at line 3263 of file chains.h.

{
        out << "chain map" << '\n';
        for (int i = 0; i <= m. dim (); ++ i)
        {
                out << "dimension " << i << '\n';
                for (int j = 0; j < m [i]. getncols (); ++ j)
                {
                        if (m [i]. getcol (j). size ())
                        {
                                out << "\t# " << (j + 1) << " = " <<
                                        m [i]. getcol (j) << '\n';
                        }
                }
        }
        return out;
} /* operator << */

template<class cell , class euclidom >
std::ostream& chomp::homology::operator<< ( std::ostream &  out,
const gcomplex< cell, euclidom > &  c 
)

Writes a geometric complex to the output stream in the text format.

Definition at line 1497 of file gcomplex.h.

{
        out << "; Geometric complex of dimension " << c. dim () <<
                " (" << c. size () << " cells total)." << '\n';
        for (int i = 0; i <= c. dim (); ++ i)
                out << "; Cells of dimension " << i << ':' << '\n' << c [i];
        return out;
} /* operator << */

template<class coordtype >
std::ostream& chomp::homology::operator<< ( std::ostream &  out,
const tCubeBase< coordtype > &  c 
) [inline]

Writes a cube to an output stream in the text mode.

The cube is represented by an n-tuple of integers which are the coordinates of the vertex with minimal coordinates.

Definition at line 288 of file cubebase.h.

References WriteCube().

{
        return WriteCube (out, c);
} /* operator << */

template<class coordtype >
std::ostream& chomp::homology::operator<< ( std::ostream &  out,
const tCellVar< coordtype > &  c 
) [inline]

Writes a cell to an output stream.

Definition at line 528 of file cellvar.h.

References WriteCubicalCell().

{
        return WriteCubicalCell (out, c);
} /* operator << */

template<class element >
std::ostream& chomp::homology::operator<< ( std::ostream &  out,
const hashedset< element > &  s 
)

Writes a hashed set to an output stream as a large one (each element is written on a separate line, with some comments at the beginning).

Definition at line 797 of file hashsets.h.

References LARGE_SIZE, and write().

{
        return write (out, s, LARGE_SIZE);
} /* operator << */

template<class domelement , class imgelement >
std::ostream& chomp::homology::operator<< ( std::ostream &  out,
const mvmap< domelement, imgelement > &  m 
)

Writes a multivalued map to the output stream.

Each assignment is written in such a way that the element of the domain is followed by the space, the arrow "->", another space, and then the image set is written in the small style (in braces, with commas between the elements).

Definition at line 1365 of file hashsets.h.

References SMALL_SIZE, and write().

{
        int_t n = m. getdomain (). size ();
        for (int_t i = 0; i < n; ++ i)
        {
                out << m. get (i) << " -> ";
                write (out, m (i), SMALL_SIZE) << '\n';
        }
        return out;
} /* operator << */

template<int Dim, int twoPower>
std::ostream& chomp::homology::operator<< ( std::ostream &  out,
const bincube< Dim, twoPower > &  b 
) [inline]

Definition at line 898 of file bincube.h.

References write().

{
        return out. write (static_cast<const char *> (b), b. getbufsize ());
} /* operator << */

std::ostream& chomp::homology::operator<< ( std::ostream &  out,
const primeint &  p 
) [inline]

Writes an object of the type "primeint" to an output stream.

Definition at line 100 of file integer.h.

{
        out << static_cast<int_t> (p);
        return out;
} /* operator << */

template<class tCell >
std::ostream& chomp::homology::operator<< ( std::ostream &  out,
const tCell2l< tCell > &  c 
) [inline]

The operator << writes a cubical cell to the text output stream.

Definition at line 839 of file twolayer.h.

References WriteCubicalCell().

{
        // write the cubical cell
        WriteCubicalCell (out, c. cell ());

        // write the layer if any
        if (c. layer ())
                out << '^' << c. layer ();

        return out;
} /* operator << */

template<class euclidom >
std::ostream& chomp::homology::operator<< ( std::ostream &  out,
const chaincomplex< euclidom > &  c 
) [inline]

Writes a chain complex to an output stream in the text format.

Definition at line 2919 of file chains.h.

{
        out << "chain complex" << '\n';
        out << "max dimension " << c. dim () << '\n';
        out << "dimension 0: " << c. getnumgen (0) << '\n';
        for (int i = 1; i <= c. dim (); ++ i)
        {
                out << "dimension " << i << ": " << c. getnumgen (i) << '\n';
                for (int j = 0; j < c. getnumgen (i); ++ j)
                {
                        if (c. getboundary (i). getcol (j). size ())
                        {
                                out << "\t# " << (j + 1) << " = " <<
                                        c. getboundary (i). getcol (j) <<
                                                '\n';
                        }
                }
        }
        return out;
} /* operator << */

std::ostream& chomp::homology::operator<< ( std::ostream &  out,
const word &  w 
) [inline]

Writes the given word to an output stream.

Definition at line 357 of file words.h.

{
        if (w. length ())
                out << (const char *) w;
        return out;
} /* operator << */

std::ostream& chomp::homology::operator<< ( std::ostream &  out,
const integer &  n 
) [inline]

Definition at line 350 of file integer.h.

{
        out << (long) n. num;
        return out;
} /* operator << */

std::ostream& chomp::homology::operator<< ( std::ostream &  out,
const hashstat &  s 
) [inline]

Shows hashing statistics in a concise and readable way to the output stream in the text format.

Definition at line 106 of file hashsets.h.

{
        if (!s. hashhits)
                return out;
        out << "hashing: " << s. hashhits << " hits, avg " <<
                ((s. hashhits + s. hashmisses) / s. hashhits) << "." <<
                ((s. hashhits + s. hashmisses) * 10 / s. hashhits) % 10 <<
                " attempts (" << s. rehashcount << " times rehashed)";
        return out;
} /* operator << */

template<class tCube >
std::ostream& chomp::homology::operator<< ( std::ostream &  out,
const tCube2l< tCube > &  c 
) [inline]

The operator << writes a cube to the output stream in the text mode.

Definition at line 406 of file twolayer.h.

References WriteCube().

{
        // write the cube
        WriteCube (out, c. cube ());

        // write the layer if any
        if (c. layer ())
                out << '^' << c. layer ();

        return out;
} /* operator << */

template<typename type >
outputstream& chomp::homology::operator<< ( outputstream &  out,
const type &  object 
) [inline]

The operator << for writing any kind of object to the output stream.

This object is written using the operator << of the standard stream.

Definition at line 203 of file textfile.h.

{
        if (out. flush)
        {
                if (out. show)
                        out. out << object << std::flush;
                if (out. log && out. getlogstream ())
                        (*(out. getlogstream ())) << object << std::flush;
        }
        else
        {
                if (out. show)
                        out. out << object;
                if (out. log && out. getlogstream ())
                        (*(out. getlogstream ())) << object;
        }
        return out;
} /* operator << */

outputstream& chomp::homology::operator<< ( outputstream &  out,
std::ostream &(*)(std::ostream &)  object 
) [inline]

A specialization of the operator << for putting manipulators (like std::endl, std::flush) to the output stream.

Definition at line 245 of file textfile.h.

{
        if (out. flush)
        {
                if (out. show)
                        out. out << object << std::flush;
                if (out. log && out. getlogstream ())
                        (*(out. getlogstream ())) << object << std::flush;
        }
        else
        {
                if (out. show)
                        out. out << object;
                if (out. log && out. getlogstream ())
                        (*(out. getlogstream ())) << object;
        }
        return out;
} /* operator << */

template<class type >
word& chomp::homology::operator<< ( word &  w,
const type &  elem 
)

Appends the string value of a given element to a word.

The operator << is used to produce this string value.

Definition at line 345 of file words.h.

{
        std::ostringstream s;
        s << elem;
        w += s. str (). c_str ();
        return w;
} /* operator << */

template<class euclidom >
std::ostream& chomp::homology::operator<< ( std::ostream &  out,
const chain< euclidom > &  c 
) [inline]

Outputs the given chain to a standard output stream in the text mode.

Warning: The operators >> and << are not symmetric for chains.

Definition at line 1112 of file chains.h.

{
        c. show (out);
        return out;
} /* operator << */

template<int dimfix, class coordtype >
std::ostream& chomp::homology::operator<< ( std::ostream &  out,
const tCubeFix< dimfix, coordtype > &  c 
) [inline]

Writes a cube to an output stream in the text mode.

The cube is represented by an n-tuple of integers which are the coordinates of the vertex with minimal coordinates.

Definition at line 278 of file cubefix.h.

References WriteCube().

{
        return WriteCube (out, c);
} /* operator << */

template<int dimfix, class coordtype >
std::ostream& chomp::homology::operator<< ( std::ostream &  out,
const tCellFix< dimfix, coordtype > &  c 
) [inline]

Writes a cell to an output stream.

Definition at line 467 of file cellfix.h.

References WriteCubicalCell().

{
        return WriteCubicalCell (out, c);
} /* operator << */

template<class euclidom >
std::ostream& chomp::homology::operator<< ( std::ostream &  out,
const mmatrix< euclidom > &  m 
) [inline]

Writes a matrix to the output stream as a map in terms of columns.

Warning: The operators >> and << are not symmetric for matrices.

Definition at line 2429 of file chains.h.

{
        return m. showcols (out);
} /* operator << */

std::ostream& chomp::homology::operator<< ( std::ostream &  out,
const argelement &  p 
) [inline]

Definition at line 236 of file arg.h.

{
        p. show (out);
        return out;
} /* operator << */

template<class cell , class euclidom , class element >
std::ostream& chomp::homology::operator<< ( std::ostream &  out,
const mvcellmap< cell, euclidom, element > &  m 
)

Writes a multivalued cellular map to the output stream.

Definition at line 2067 of file gcomplex.h.

References SMALL_SIZE, and write().

{
        for (int d = 0; d <= m. dim (); ++ d)
        {
                out << "; Dimension " << d << ':' << '\n';
                const hashedset<cell> &cset = m. get (d);
                for (int_t i = 0; i < cset. size (); ++ i)
                {
                        out << cset [i] << " -> ";
                        write (out, m (cset [i]), SMALL_SIZE) << '\n';
                }
        }
        return out;
} /* operator << */

template<class coordtype >
std::ostream & chomp::homology::operator<< ( std::ostream &  out,
tPointset< coordtype > &  p 
)

Writes a set of points to a file (starting at the point given).

Definition at line 2436 of file pointset.h.

References write().

{
        write (out, p);
        return out;
} /* operator << */

std::ostream& chomp::homology::operator<< ( std::ostream &  out,
const psethashstat &  s 
) [inline]

Writes the information gathered in a hashing statistics collector object to an output stream.

Definition at line 449 of file pointset.h.

{
        if (!s. hashhits)
                return out;
        out << "hashing: " << s. hashhits << " hits, avg " <<
                ((s. hashhits + s. hashmisses) / s. hashhits) << "." <<
                ((s. hashhits + s. hashmisses) * 10 / s. hashhits) % 10 <<
                " attempts (" << s. rehashcount << " times rehashed)";
        return out;
} /* operator << */

int chomp::homology::operator<= ( const word &  w1,
const word &  w2 
) [inline]

Compares two words in an alphabetical way (by ASCII codes).

Returns 1 if the second word does not precede the first one, 0 otherwise.

Definition at line 327 of file words.h.

{
        return !(w1 > w2);
} /* operator <= */

template<class wType1 , class wType2 >
bool chomp::homology::operator== ( const diGraph< wType1 > &  g1,
const diGraph< wType2 > &  g2 
) [inline]

No isomorphism check, just comparing with the same order of vertices. Ignores weights.

Definition at line 584 of file digraph.h.

{
        if (g1. nVertices != g2. nVertices)
                return false;
        if (!g1. nVertices)
                return true;
        for (int_t i = 0; i < g1. nVertices; ++ i)
        {
                if (g1. edgeEnds [i] != g2. edgeEnds [i])
                        return false;
        }
        int_t nEdges = g1. edgeEnds [g1. nVertices - 1];
        for (int_t i = 0; i < nEdges; ++ i)
        {
                if (g1. edges [i] != g2. edges [i])
                        return false;
        }
        return true;
} /* operator == */

template<class tCube >
int chomp::homology::operator== ( const tCube2l< tCube > &  c1,
const tCube2l< tCube > &  c2 
) [inline]

The operator == verifies if two cubes are equal.

Definition at line 377 of file twolayer.h.

{
        return (c1. cube () == c2. cube ()) &&
                (c1. layer () == c2. layer ());
} /* operator == */

int chomp::homology::operator== ( const Simplex &  s,
const Simplex &  t 
) [inline]

The operator == that compares whether the two simplices are the same, that is, have the same vertices in the same order.

Definition at line 301 of file simplex.h.

{
        int sd = s. dim ();
        int td = t. dim ();
        if (sd != td)
                return 0;
        for (int i = 1; i < sd + 2; ++ i)
                if (s. tab [i] != t. tab [i])
                        return 0;
        return 1;
} /* operator == */

int chomp::homology::operator== ( const char *  c,
const word &  w 
) [inline]

Compares a C-style string with a word.

Definition at line 290 of file words.h.

{
        return (w == c);
} /* operator == */

int chomp::homology::operator== ( const word &  w1,
const word &  w2 
) [inline]

Compares two words. Returns 1 if they are the same, 0 otherwise.

Definition at line 260 of file words.h.

{
        if (w1. length () != w2. length ())
                return 0;
        if (!w1. length ())
                return 1;
        return !strcmp ((const char *) w1, (const char *) w2);
} /* operator == */

int chomp::homology::operator== ( const integer &  n,
int  m 
) [inline]

Definition at line 371 of file integer.h.

{
        integer intm;
        intm = m;
        return (n == intm);
} /* operator == */

int chomp::homology::operator== ( const word &  w,
const char *  c 
) [inline]

Compares a word with a C-style string.

Definition at line 276 of file words.h.

{
        if (!w. length ())
                return (!c || !*c);
        return !strcmp ((const char *) w, c);
} /* operator == */

template<class tCell >
int chomp::homology::operator== ( const tCell2l< tCell > &  c1,
const tCell2l< tCell > &  c2 
) [inline]

The operator == verifies if two cells are equal.

Definition at line 810 of file twolayer.h.

{
        return (c1. cell () == c2. cell ()) &&
                (c1. layer () == c2. layer ());
} /* operator == */

template<int Dim, int twoPower>
bool chomp::homology::operator== ( const typename bincube< Dim, twoPower >::neighborhood_iterator &  x1,
const typename bincube< Dim, twoPower >::neighborhood_iterator &  x2 
) [inline]

Definition at line 776 of file bincube.h.

{
//      sout << "DEBUG ==\n";
        return ((x1. b == x2. b) && (x1. cur == x2. cur));
} /* bincube::neighborhood_iterator::operator == */

int chomp::homology::operator> ( const word &  w1,
const word &  w2 
) [inline]

Compares two words in an alphabetical way (by ASCII codes).

Returns 1 if the second word precedes the first one, 0 otherwise.

Definition at line 320 of file words.h.

{
        return (w2 < w1);
} /* operator > */

bool chomp::homology::operator> ( const integer &  x,
const integer &  y 
) [inline]

Definition at line 417 of file integer.h.

{
        return (x. num > y. num);
} /* operator > */

int chomp::homology::operator>= ( const word &  w1,
const word &  w2 
) [inline]

Compares two words in an alphabetical way (by ASCII codes).

Returns 1 if the first word does not precede the second one, 0 otherwise.

Definition at line 334 of file words.h.

{
        return !(w1 < w2);
} /* operator >= */

template<class tCube >
std::istream& chomp::homology::operator>> ( std::istream &  in,
hashedset< tCube2l< tCube > > &  s 
) [inline]

A specialized version of the operator >> for reading a set of cubes and ignores the first line "dimension N".

Definition at line 445 of file twolayer.h.

References ReadCubes().

{
        return ReadCubes (in, s);
} /* operator >> */

template<class tCube >
std::istream& chomp::homology::operator>> ( std::istream &  in,
tCube2l< tCube > &  c 
) [inline]

The operator >> reads a cube from the input stream in the text mode.

Definition at line 420 of file twolayer.h.

References ignorecomments(), and ReadCube().

{
        // read the cube
        tCube q;
        ReadCube (in, q);

        // read the layer if any
        typename tCube2l<tCube>::LayerType l (0);
        ignorecomments (in);
        if (in. peek () == '^')
        {
                in. get ();
                ignorecomments (in);
                in >> l;
        }
        else if (tCube2l<tCube>::layer1 (). check (q))
                l = 1;

        c = tCube2l<tCube> (q, l);
        return in;
} /* operator >> */

template<class domelement , class imgelement >
std::istream& chomp::homology::operator>> ( std::istream &  in,
mvmap< domelement, imgelement > &  m 
)

Reads a multivalued map from an input stream.

Definition at line 1379 of file hashsets.h.

References ignorecomments(), read(), and SMALL_SIZE.

{
        ignorecomments (in);
        while (in. peek () != EOF)
        {
                domelement e;
                in >> e;
        //      if (!in)
        //              throw "Failed to read a domain element of a map.";

                // read the map's arrow
                ignorecomments (in);
                while (in. peek () == '-')
                        in. get ();
                if (in. peek () == '>')
                        in. get ();

                ignorecomments (in);
                read (in, m [e], SMALL_SIZE);

                ignorecomments (in);
        }
        return in;
} /* operator >> */

template<class coordtype >
std::istream& chomp::homology::operator>> ( std::istream &  in,
mvmap< tCubeVar< coordtype >, tCubeVar< coordtype > > &  m 
) [inline]

Reads a cubical map from an input stream in the text mode.

Definition at line 369 of file cubevar.h.

References ReadCubicalMap().

{
        return ReadCubicalMap (in, m);
} /* operator >> */

template<class coordtype >
std::istream& chomp::homology::operator>> ( std::istream &  in,
tCubeBase< coordtype > &  c 
) [inline]

Reads a cube from an input stream in the text mode.

The cube is represented by an n-tuple of integers which are the coordinates of the vertex with minimal coordinates.

Definition at line 298 of file cubebase.h.

References ReadCube().

{
        return ReadCube (in, c);
} /* operator >> */

template<class coordtype >
std::istream& chomp::homology::operator>> ( std::istream &  in,
hashedset< tCubeBase< coordtype > > &  s 
) [inline]

Reads a set of cubes from an input stream in the text mode.

Definition at line 305 of file cubebase.h.

References ReadCubes().

{
        return ReadCubes (in, s);
} /* operator >> */

template<class tCell >
std::istream& chomp::homology::operator>> ( std::istream &  in,
tCell2l< tCell > &  c 
) [inline]

The operator >> reads a cubical cell from the text input stream.

Definition at line 853 of file twolayer.h.

References ignorecomments(), and ReadCubicalCell().

{
        // read the cubical cell
        tCell q;
        ReadCubicalCell (in, q);

        // read the layer if any
        typename tCell2l<tCell>::LayerType l (0);
        ignorecomments (in);
        if (in. peek () == '^')
        {
                in. get ();
                ignorecomments (in);
                in >> l;
        }

        c = tCell2l<tCell> (q, l);
        return in;
} /* operator >> */

std::istream& chomp::homology::operator>> ( std::istream &  in,
primeint &  p 
) [inline]

Reads a prime number from an input stream.

If the actual number that is read is not prime then it is increased as much as necessary to obtain a prime number.

Definition at line 109 of file integer.h.

{
        int_t n;
        in >> n;
        p = n;
        return in;
} /* operator >> */

template<class cell , class euclidom >
std::istream& chomp::homology::operator>> ( std::istream &  in,
gcomplex< cell, euclidom > &  c 
)

Reads a geometric complex from an input stream in the text format.

Definition at line 1509 of file gcomplex.h.

References closingparenthesis(), and ignorecomments().

{
        ignorecomments (in);
        while (closingparenthesis (in. peek ()) != EOF)
        {
                cell x;
                in >> x;
                c. add (x);
                ignorecomments (in);
        }
        return in;
} /* operator >> */

template<class element >
std::istream& chomp::homology::operator>> ( std::istream &  in,
hashedset< element > &  s 
)

Reads a hashed set from an input stream in a large size style (each element occupies one line, any comments are ignored).

Definition at line 849 of file hashsets.h.

References LARGE_SIZE, and read().

{
        return read (in, s, LARGE_SIZE);
} /* operator >> */

template<class coordtype >
std::istream& chomp::homology::operator>> ( std::istream &  in,
tCellVar< coordtype > &  c 
) [inline]

Reads a cell from an input stream.

Definition at line 536 of file cellvar.h.

References ReadCubicalCell().

{
        return ReadCubicalCell (in, c);
} /* operator >> */

template<class tCube >
std::istream& chomp::homology::operator>> ( std::istream &  in,
mvmap< tCube2l< tCube >, tCube2l< tCube > > &  m 
) [inline]

A specialized version of the operator >> that reads a combinatorial cubical multivalued map.

This version allows one to use two formats which are automatically distinguished. The assignments can be either like in a generic multivalued map, or in Jacek and Marcin's format (see the chmap program).

Definition at line 457 of file twolayer.h.

References ReadCubicalMap().

{
        return ReadCubicalMap (in, m);
} /* operator >> */

template<class coordtype >
std::istream& chomp::homology::operator>> ( std::istream &  in,
tCellBase< coordtype > &  c 
) [inline]

Reads a cell from an input stream.

Definition at line 462 of file cellbase.h.

References ReadCubicalCell().

{
        return ReadCubicalCell (in, c);
} /* operator >> */

template<int Dim, int twoPower>
std::istream& chomp::homology::operator>> ( std::istream &  in,
bincube< Dim, twoPower > &  b 
) [inline]

Definition at line 905 of file bincube.h.

References read().

{
        return b. read (in);
} /* operator >> */

template<class coordtype >
std::istream& chomp::homology::operator>> ( std::istream &  in,
mvmap< tCubeBase< coordtype >, tCubeBase< coordtype > > &  m 
) [inline]

Reads a cubical map from an input stream in the text mode.

Definition at line 313 of file cubebase.h.

References ReadCubicalMap().

{
        return ReadCubicalMap (in, m);
} /* operator >> */

template<int dimfix, class coordtype >
std::istream& chomp::homology::operator>> ( std::istream &  in,
tCellFix< dimfix, coordtype > &  c 
) [inline]

Reads a cell from an input stream.

Definition at line 475 of file cellfix.h.

References ReadCubicalCell().

{
        return ReadCubicalCell (in, c);
} /* operator >> */

std::istream& chomp::homology::operator>> ( std::istream &  in,
word &  w 
) [inline]

Reads a word from an input stream.

Definition at line 365 of file words.h.

{
        char buf [256 + 1];
        int pos = 0;
        int ch = in. peek ();
        while ((ch != ' ') && (ch != '\r') && (ch != '\n') && (ch != '\t') &&
                (ch != EOF))
        {
                buf [pos ++] = in. get ();
                ch = in. peek ();
                if (pos >= 256)
                        break;
        }
        buf [pos] = '\0';
        w = word (buf);
        return in;
} /* operator >> */

template<int dimfix, class coordtype >
std::istream& chomp::homology::operator>> ( std::istream &  in,
tCubeFix< dimfix, coordtype > &  c 
) [inline]

Reads a cube from an input stream in the text mode.

The cube is represented by an n-tuple of integers which are the coordinates of the vertex with minimal coordinates.

Definition at line 288 of file cubefix.h.

References ReadCubeFix().

{
        return ReadCubeFix (in, c, dimfix);
} /* operator >> */

template<int dimfix, class coordtype >
std::istream& chomp::homology::operator>> ( std::istream &  in,
hashedset< tCubeFix< dimfix, coordtype > > &  s 
) [inline]

Reads a set of cubes from an input stream in the text mode.

Definition at line 296 of file cubefix.h.

References ReadCubes().

{
        return ReadCubes (in, s);
} /* operator >> */

template<class euclidom >
std::istream& chomp::homology::operator>> ( std::istream &  in,
chain< euclidom > &  c 
) [inline]

Reads a chain from a standard input stream in the text mode.

Warning: The operators >> and << are not symmetric for chains.

Definition at line 1121 of file chains.h.

References ignorecomments(), and readparenthesis().

{
        ignorecomments (in);
        int closing = readparenthesis (in);

        ignorecomments (in);
        while (in. peek () != closing)
        {
                // read the coefficient
                euclidom e (1);
                in >> e;

                // read the multiplication symbol
                ignorecomments (in);
                if (in. peek () != '*')
                        throw "The multiplication sign '*' while reading a chain.";
                in. get ();

                // read the identifier
                ignorecomments (in);
                int n;
                in >> n;
                -- n;

                // if the coefficient is zero, then this is wrong
                if (e == 0)
                        throw "A zero coefficient in a chain detected.";

                // add this element to the chain
                c. add (e, n);

                // prepare for the next pair to read
                ignorecomments (in);

                // read a comma or a plus between two elements of the chain
                if ((in. peek () == ',') || (in. peek () == '+'))
                {
                        in. get ();
                        ignorecomments (in);
                }
        }

        if (closing != EOF)
                in. get ();

        return in;
} /* operator >> */

std::istream& chomp::homology::operator>> ( std::istream &  in,
integer &  n 
) [inline]

Definition at line 356 of file integer.h.

{
        long number;
        in >> number;
        if (!in)
                return in;
        n = number;
        return in;
} /* operator >> */

template<int dimfix, class coordtype >
std::istream& chomp::homology::operator>> ( std::istream &  in,
mvmap< tCubeFix< dimfix, coordtype >, tCubeFix< dimfix, coordtype > > &  m 
) [inline]

Reads a cubical map from an input stream in the text mode.

Definition at line 304 of file cubefix.h.

References ReadCubicalMap().

{
        return ReadCubicalMap (in, m);
} /* operator >> */

std::istream& chomp::homology::operator>> ( std::istream &  in,
Simplex &  s 
) [inline]

Reads a simplex from an imput stream from a text format.

Throws an error message in case of failure.

Definition at line 368 of file simplex.h.

References closingparenthesis(), ignorecomments(), chomp::homology::Simplex::MaxDim, and sortelements().

{
        // check if an opening parenthesis is waiting at the input
        ignorecomments (in);
        int closing = closingparenthesis (in. peek ());
        if (closing == EOF)
                throw "Cannot read a simplex: No opening parenthesis.";

        // read the opening parenthesis
        in. get ();
        ignorecomments (in);

        // read the vertices of the simplex
        int v [Simplex::MaxDim];
        int dim = -1;
        while (in && (in. peek () != closing))
        {
                // read the vertex
                in >> v [++ dim];
                if (!in)
                        throw "Unable to read a vertex of a simplex.";

                // read the separating comma if any
                ignorecomments (in);
                if (in. peek () == ',')
                {
                        in. get ();
                        ignorecomments (in);
                }

                // if there are too many vertices...
                if (dim >= Simplex::MaxDim)
                        throw "Too many vertices of a simplex.";
        }

        // sort the numbers of the vertices of the simplex
        if (sortelements (v, dim + 1) != dim + 1)
                throw "A repeated vertex in a simplex detected.";

        // read the closing parenthesis and define the simplex
        in. get ();
        s = Simplex (v, dim);

        return in;
} /* operator >> */

template<class coordtype >
textfile & chomp::homology::operator>> ( textfile &  f,
tPointset< coordtype > &  p 
)

Reads a set of points from an input stream (starting at the point given).

Definition at line 2347 of file pointset.h.

References read().

{
        read (f, p);
        return f;
} /* operator >> */

template<class coordtype >
std::istream & chomp::homology::operator>> ( std::istream &  in,
tPointset< coordtype > &  p 
)

Reads a set of points from an input stream (starting at the point given).

Definition at line 2354 of file pointset.h.

References read().

{
        textfile f (in);
        read (f, p);
        return in;
} /* operator >> */

template<class coordtype >
std::istream& chomp::homology::operator>> ( std::istream &  in,
tCubeVar< coordtype > &  c 
) [inline]

Reads a cube from an input stream in the text mode.

The cube is represented by an n-tuple of integers which are the coordinates of the vertex with minimal coordinates.

Definition at line 354 of file cubevar.h.

References ReadCube().

{
        return ReadCube (in, c);
} /* operator >> */

template<class coordtype >
std::istream& chomp::homology::operator>> ( std::istream &  in,
hashedset< tCubeVar< coordtype > > &  s 
) [inline]

Reads a set of cubes from an input stream in the text mode.

Definition at line 361 of file cubevar.h.

References ReadCubes().

{
        return ReadCubes (in, s);
} /* operator >> */

template<class coordtype >
int_t chomp::homology::pointhashadd ( const coordtype *  c,
int  dim,
int_t  hashsize 
)

Generates the second hashing key for points.

Definition at line 184 of file pointset.h.

Referenced by chomp::homology::tPointset< coordtype >::hashfindpoint().

{
        int_t add = 1313;
        for (int i = 0; i < dim; ++ i)
                add ^= static_cast<int_t> ((c [i] > 0) ? c [i] : -c [i]) <<
                        (((i << 4) + 3) % 21);
        if (add < 0)
                add = -(add + 1);

        // return the key reduced to the given size
        return (add % (hashsize - 1) + 1);

} /* pointhashadd */

template<class coordtype >
int_t chomp::homology::pointhashkey ( const coordtype *  c,
int  dim,
int_t  hashsize 
)

Generates the main hashing key for points.

Definition at line 166 of file pointset.h.

Referenced by chomp::homology::tPointset< coordtype >::hashfindpoint().

{
        int_t key = 13;
        for (int i = 0; i < dim; ++ i)
        {
                key ^= static_cast<int_t> ((c [i] > 0) ? c [i] : -c [i]) <<
                        ((i << 3) % 19);
        }
        if (key < 0)
                key = -(key + 1);

        // return the key reduced to the given size
        return (key % hashsize);

} /* pointhashkey */

template<class euclidom , class tCell >
void chomp::homology::project ( const gcomplex< tCell, euclidom > &  c,
gcomplex< tCell, euclidom > &  img,
const gcomplex< tCell, euclidom > &  only,
int  offset,
int  outdim,
int  discarddim,
const int *  level,
bool  watchforimages 
)

Creates the image of the projection from the set of cubical cells in the given geometric complex to the subspace of R^n spanned by the 'outdim' subsequent standard vectors with the first number 'offset'.

Only these cells which appear in 'only' are added unless 'only' is empty.

Definition at line 321 of file cubmaps.h.

Referenced by Homology(), and Homology2l().

{
        typedef typename tCell::CoordType coordType;

        // go through the list of all the dimensions which are of concern
        for (int d = 0; d <= c. dim (); ++ d)
        {
                if ((!level || level [d]) && (c. dim () >= d))
                {
                        // take sets of cells of this dimension
                        const hashedset<tCell> &cset = c [d];
                        if (cset. empty ())
                                continue;

                        // go through the list of cells in c of dimension d
                        for (int_t i = 0; i < cset. size (); ++ i)
                        {
                                // get this cell and its coordinates
                                const tCell &thecell = cset [i];
                                coordType left [tCell::MaxDim];
                                thecell. leftcoord (left);
                                coordType right [tCell::MaxDim];
                                thecell. rightcoord (right);

                                // check if this cell has no width in the
                                // directions that are discarded
                                int j;
                                for (j = 0; j < offset; ++ j)
                                        if (left [j] != right [j])
                                        {
                                                j = offset + 33;
                                                break;
                                        }
                                if (j > offset)
                                        continue;
                                for (j = 0; j < discarddim; ++ j)
                                        if (left [offset + outdim + j] !=
                                                right [offset + outdim + j])
                                        {
                                                j = discarddim + 33;
                                                break;
                                        }
                                if (j > discarddim)
                                        continue;

                                // add the projected cell to the complex
                                if (!(tCell::PointBase::check
                                        (left + offset, outdim))
                                        || !(tCell::PointBase::check
                                        (right + offset, outdim)))
                                {
                                        if (watchforimages)
                                                throw "Inclusion undefined!";
                                        else
                                                continue;
                                }
                                tCell projected (left + offset,
                                        right + offset, outdim);
                                if ((only. dim () >= 0) &&
                                        !only. check (projected))
                                {
                                        if (watchforimages)
                                                throw "Inclusion undefined.";
                                        else
                                                continue;
                                }
                                img. add (projected);
                        }
                }
        }
        return;
} /* project */

template<class stream , class element >
stream& chomp::homology::read ( stream &  in,
hashedset< element > &  s,
bool  size 
)

Reads a hashed set from an input stream, either a small size style or a large one.

Definition at line 805 of file hashsets.h.

References ignorecomments(), readparenthesis(), and SMALL_SIZE.

{
        // ignore all the comments at the beginning of the input stream
        ignorecomments (in);

        // determine the closing parenthesis
        // and read the opening one if applicable
        int closing = EOF;
        if (size == SMALL_SIZE)
        {
                closing = readparenthesis (in);
                if (closing == EOF)
                        throw "An opening parenthesis expected in a set.";
                ignorecomments (in);
        }

        // read the elements until the closing parenthesis is found
        while (in. peek () != closing)
        {
                element e;
                in >> e;
        //      if (!in)
        //              throw "Failed to read an element of a set.";
                s. add (e);
                ignorecomments (in);

                // read a comma between the elements if it is there
                if (in. peek () == ',')
                {
                        in. get ();
                        ignorecomments (in);
                }
        }

        // read the closing parenthesis if any
        if (closing != EOF)
                in. get ();

        return in;
} /* read */

template<class coordtype >
int_t chomp::homology::read ( textfile &  f,
tPointset< coordtype > &  p,
coordtype *  wrap,
int  maxdim,
int  quiet = 0,
tPointset< coordtype > *  notthese = NULL 
)

Reads a set of points from an input stream (starting at the point given).

Returns the number of points read or -1 (and show a message) if failed.

Definition at line 2331 of file pointset.h.

References read().

{
        return read (f, p, 0, -1, wrap, maxdim, quiet, notthese);
} /* read */

template<class coordtype >
int chomp::homology::read ( textfile &  f,
coordtype *  c,
int  maxdim 
)

Reads a point from a text file and removes a pair of parentheses, braces or brackets if present.

Returns the number of coordinates read. If the maximal dimension is reached, no more coordinates are read. Note: The first input character should be the opening parenthesis. This is an old version, use "readcoordinates" instead.

Definition at line 1949 of file pointset.h.

References ignoreline().

Referenced by operator>>(), read(), ReadCubes(), ReadCubicalMap(), readimage(), readrestriction(), and readselective().

{
        // ignore lines until you can find an opening parenthesis,
        // brace or bracket and read this character
        int ready = 0;
        while (!ready)
        {
                switch (f. checkchar ())
                {
                        case '(':
                        case '[':
                        case '{':
                        case '"':
                        case '\'':
                                f. readchar ();
                                ready = 1;
                                break;
                        case '+':
                        case '-':
                                break;
                        case EOF:
                                return 0;
                        default:
                                f. ignoreline ();
                                break;
                }
        }

        // read the coordinates
        int n = 0;
        while (1)
        {
                // read the current coordinate of the point
                c [n ++] = (coordtype) f. readnumber ();

                // read a comma between the coordinates
                // or the closing parenthesis, brace or bracket if any
                switch (f. checkchar ())
                {
                        case ')':
                        case ']':
                        case '}':
                        case '"':
                        case '\'':
                                f. readchar ();
                                return n;
                        case ',':
                                f. readchar ();
                                break;
                        case '-':
                        case '+':
                                break;
                        default:
                                if ((f. checkchar () < '0') ||
                                        (f. checkchar () > '9'))
                                        return n;
                }

                // check if the maximal dimension allowed has been reached
                if (n >= maxdim)
                        return n;
        }
} /* read */

template<class coordtype >
int chomp::homology::read ( std::istream &  in,
coordtype *  c,
int  maxdim 
)

Reads a point from a text file and removes a pair of parentheses, braces or brackets if present.

Returns the number of coordinates read. If the maximal dimension is reached, no more coordinates are read. Note: The first input character should be the opening parenthesis. This is an old version, use "readcoordinates" instead.

Definition at line 2014 of file pointset.h.

References read().

{
        textfile f (in);
        return read (f, c, maxdim);
} /* read */

template<class coordtype >
int_t chomp::homology::read ( textfile &  f,
tPointset< coordtype > &  p,
int_t  first = 0,
int_t  howmany = -1,
coordtype *  wrap = NULL,
int  maxdim = 0,
int  quiet = 0,
tPointset< coordtype > *  notthese = NULL 
)

Reads a set of points from an input stream (starting at the point given).

Returns the number of points read or -1 (and show a message) if failed.

Definition at line 2222 of file pointset.h.

References ignoreline(), read(), and sout.

{
        // prepare a temporary point of maximal dimension
        if (maxdim <= 0)
        {
                if (wrap)
                        wrap = NULL;
                maxdim = 100;
        }
        coordtype *temp = allocatepoint<coordtype> (maxdim + 1);

        int_t count = 0;
        int dim = p. empty () ? 0 : p. dimension ();

        if (notthese && !notthese -> empty ())
        {
                if (!dim)
                        dim = notthese -> dimension ();
                else if (dim != notthese -> dimension ())
                {
                        if (!quiet)
                                sout << "Error: Dimensions not the same.\n";
                        return -1;
                }
        }

        while (1)
        {
                // stop reading if it is already enough
                if ((howmany >= 0) && (count >= howmany))
                {
                        delete [] temp;
                        return count;
                }

                // ignore all the lines which do not start
                // with an opening parenthesis
                while ((f. checkchar () != 40) && (f. checkchar () != 91) &&
                        (f. checkchar () != 123) && (f. checkchar () != EOF))
                        f. ignoreline ();

                // if this is the end of the file, finish successfully
                if (f. checkchar () == EOF)
                {
                        delete [] temp;
                        return count;
                }

                // read a point
                int n = read (f, temp, maxdim + 1);
                if (n > maxdim)
                {
                        if (!quiet)
                                sout << "Line " << f. linenumber () <<
                                        ": The point has too many " <<
                                        "coordinates.\n";
                        delete [] temp;
                        return -1;
                }

                // check if the number of coordinates is the same
                // as the dimension of the points in the set
                if (!first && dim && n && (n != dim))
                {
                        if (!quiet)
                                sout << "Line " << f. linenumber () <<
                                        ": Incorrect point dimension.\n";
                        delete [] temp;
                        return -1;
                }

                // set the dimension to be the number of coordinates
                if (!first && !dim)
                {
                        dim = n;
                        if (p. dimension () != dim)
                                p. dimension (dim);
                }

                // add the read point to the set
                if (first)
                        -- first;
                else
                {
                        if (wrap)
                        {
                                p. wrapspace (wrap);
                                wrap = NULL;
                        }
                        if (!notthese || !notthese -> check (temp))
                                p. add (temp);
                        ++ count;
                }
        }
} /* read */

template<class coordtype >
int_t chomp::homology::read ( std::istream &  in,
tPointset< coordtype > &  p,
int_t  first = 0,
int_t  howmany = -1,
coordtype *  wrap = NULL,
int  maxdim = 0,
int  quiet = 0,
tPointset< coordtype > *  notthese = NULL 
)

Reads a set of points from an input stream (starting at the point given).

Returns the number of points read or -1 (and show a message) if failed.

Definition at line 2322 of file pointset.h.

References read().

{
        textfile f (in);
        return read (f, p, first, howmany, wrap, maxdim, quiet, notthese);
} /* read */

template<class coordtype >
int_t chomp::homology::read ( std::istream &  in,
tPointset< coordtype > &  p,
coordtype *  wrap,
int  maxdim,
int  quiet = 0,
tPointset< coordtype > *  notthese = NULL 
)

Reads a set of points from an input stream (starting at the point given).

Returns the number of points read or -1 (and show a message) if failed.

Definition at line 2339 of file pointset.h.

References read().

{
        textfile f (in);
        return read (f, p, wrap, maxdim, quiet, notthese);
} /* read */

template<class tCube >
int chomp::homology::ReadBitmapFile ( const char *  bmpname,
hashedset< tCube > &  cset,
int  mingray = 0,
int  maxgray = 128 
)

Reads the squares from a bitmap file to the set of cubes.

Each pixel whose gray value is within the given range (at least 'mingray', strictly less than 'maxgray') gives raise to one square with the corresponding coordinates. For color bitmaps, a weighted average of RGB is computed as gray. Gray level 0 corresponds to black, gray level 255 is white. Return 0 on success, throw an error message if failed.

Definition at line 892 of file homtools.h.

References fileerror().

{
        // prepare a bitmap file with the vertical axis like in mathematics
        bmpfile bmp;
        bmp. invertedpicture ();

        // open the bitmap file
        if (bmp. open (bmpname) < 0)
                fileerror (bmpname);
        
        // scan the picture and produce the list of hypercubes
        coordinate c [2];
        for (c [1] = 0; c [1] < bmp. picture_height (); ++ (c [1]))
        {
                for (c [0] = 0; c [0] < bmp. picture_width (); ++ (c [0]))
                {
                        long color = bmp. getpixel (c [0], c [1]);
                        long gray = (77 * ((color & 0xFF0000) >> 16) +
                                154 * ((color & 0xFF00) >> 8) +
                                25 * (color & 0xFF)) >> 8;
                        if ((gray >= mingray) && (gray <= maxgray))
                                cset. add (tCube (c, 2));
                }
        }

        return 0;
} /* ReadBitmapFile */

int chomp::homology::readbitpoints ( std::istream &  in,
pointset &  p,
int *  bitcode_depth = NULL 
)

Reads a set of full cubical sets represented as a set of points from a file encoded in the "bitcode" format used by Bill Kalies.

The depth of bit codes is saved to '*bitcode_depth' unless NULL. Returns 0 on success and -1 on error (and displays a message).

template<class cell , class euclidom >
void chomp::homology::readcells ( const char *  name,
gcomplex< cell, euclidom > &  s,
const char *  what 
) [inline]

Uses the general procedure "readtheset" to read a geometric complex.

Definition at line 156 of file homtools.h.

References readtheset().

{
        readtheset (name, s, cell::pluralname (), what);
        return;
} /* readcells */

template<class coordtype >
int chomp::homology::readcoordinates ( std::istream &  in,
coordtype *  coord,
int  maxdim 
) [inline]

Definition at line 2097 of file pointset.h.

References readcoordinates().

{
        return readcoordinates (in, coord, maxdim, EOF);
} /* readcoordinates */

template<class coordtype >
int chomp::homology::readcoordinates ( std::istream &  in,
coordtype *  coord,
int  maxdim,
int  closing 
) [inline]

Reads the coordinates of a point.

The point must begin with an opening parenthesis, brace or bracket (unless a closing parenthesis is different from EOF), then the coordinates must be separated by spaces or commas, and must end with a corresponding closing parenthesis, brace or bracket (or the given one). The closing parenthesis may also be defined as '
'. Interrupts if the number of coordinates reaches the maximal dimension. Returns the number of coordinates read or -1 on error.

Definition at line 2028 of file pointset.h.

References ignorecomments(), and readparenthesis().

Referenced by readcoordinates(), ReadCubeFix(), readcubeorcell(), ReadCubicalCell(), ReadCubicalMap(), and scancubes().

{
        // read the opening parenthesis
        if (closing == EOF)
                closing = readparenthesis (in);
        if (closing == EOF)
                return -1;

        int cur = 0;

        ignorecomments (in);
        while ((in. peek () != closing) && (cur < maxdim))
        {
                // ignore a plus before the number if necessary
                if (in. peek () == '+')
                        in. get ();

                // finish if there is no number at the input
                if ((in. peek () != '-') && !std::isdigit (in. peek ()))
                        break;

                // read the number as 'long' (just in case)
                long number;
                in >> number;
        //      if (!in)
        //              return -1;

                // transform this number to a coordtype
                coord [cur] = (coordtype) number;
                if (coord [cur] != number)
                        return -1;

                // move to the next coordtype position
                ++ cur;
                if (closing == '\n')
                {
                        while ((in. peek () == ' ') ||
                                (in. peek () == '\t') ||
                                (in. peek () == '\r'))
                                in. get ();
                }
                else
                        ignorecomments (in);

                // one more thing: read the following comma if any
                if (in. peek () == ',')
                {
                        in. get ();
                        ignorecomments (in);
                }
        }

        // verify that the coordinates were read successfully
//      if (!in)
//              return -1;

        // read the closing parenthesis
        if (in. peek () == closing)
                in. get ();
        else if ((closing == '\n') && (in. peek () == EOF))
                ;
        else
                return -1;

        return cur;
} /* readcoordinates */

template<class cubetype >
std::istream& chomp::homology::ReadCube ( std::istream &  in,
cubetype &  c 
) [inline]

Reads a cube from the input text stream.

Definition at line 185 of file cubemain.h.

References ReadCubeFix().

Referenced by operator>>().

{
        return ReadCubeFix (in, c, -1);
} /* ReadCube */

template<class cubetype >
std::istream& chomp::homology::ReadCubeFix ( std::istream &  in,
cubetype &  c,
int  dimfix 
)

Reads a cube from the input text stream.

The fixed dimension is forced, unless set to -1.

Definition at line 91 of file cubemain.h.

References ignorecomments(), and readcoordinates().

Referenced by operator>>(), and ReadCube().

{
        // retrieve the type of coordinates of the cube to read
        typedef typename cubetype::CoordType coordtype;

        // ignore any comments, spaces, tabs and new-line characters
        ignorecomments (in);

        // if there is a number in the input, then there are apparently
        // no parentheses used for the coords or the cube is defined
        // by its number (also indicated with '#')
        if (((in. peek () >= '0') && (in. peek () <= '9')) ||
                (in. peek () == '-') || (in. peek () == '+') ||
                (in. peek () == '#'))
        {
                bool cubenumber = false;
                if (in. peek () == '#')
                {
                        in. get ();
                        ignorecomments (in);
                        cubenumber = true;
                }
                if (in. peek () == '+')
                        in. get ();
                int n = -1;
                in >> n;
                while ((in. peek () == ' ') || (in. peek () == '\t'))
                        in. get ();

                // if the next coordinate of the cube follows,
                // read the coordinates until end-of-line is encountered
                if (!cubenumber &&
                        (((in. peek () >= '0') && (in. peek () <= '9')) ||
                        (in. peek () == '-') || (in. peek () == '+')))
                {
                        // read the coords and determine the space dimension
                        coordtype coord [cubetype::MaxDim];
                        coord [0] = n;
                        int dim = -1;
                        if (in. peek () != '\n')
                        {
                                dim = readcoordinates (in, coord + 1,
                                        cubetype::MaxDim - 1, '\n');
                                if (dim < 0)
                                        throw "Unable to read a cube: "
                                                "Dim too high.";
                        }
                        ++ dim;

                        // if could not read the cube, throw an error message
                        if ((dimfix >= 0) && (dim != dimfix))
                                throw "Unable to read a cube: Wrong dim.";

                        // create a cube with the given coordinates
                        c = cubetype (coord, dim);

                        return in;
                }

                // if the cube is given by its number, read it this way
                else
                {
                        int dim = cubetype::PointBase::defaultdimension ();
                        const typename cubetype::CoordType *coord = 0;
                        if ((n > 0) && (dim > 0))
                        {
                                coord = cubetype::PointBase::coord
                                        (n - 1, dim);
                        }
                        if (!coord)
                                throw "Cube no. out of range while reading.";
                        c = cubetype (n - 1, dim);
                        return in;
                }
        }

        // read the coordinates and determine the space dimension
        typename cubetype::CoordType coord [cubetype::MaxDim];
        int dim = readcoordinates (in, coord, cubetype::MaxDim);
        if (dim < 0)
                throw "Unable to read a cube: Dimension too high.";

        // if could not read the cube, throw an error message
        if ((dimfix >= 0) && (dim != dimfix))
                throw "Unable to read a cube: Wrong dimension.";

        // create the cube with the given coordinates
        c = cubetype (coord, dim);

        return in;
} /* ReadCubeFix */

template<class coordtype >
int chomp::homology::readcubeorcell ( std::istream &  in,
coordtype *  left,
coordtype *  right,
int  maxdim,
int *  type = NULL 
)

Reads a cube or a cell from a text file.

Ignores any preceding text lines. Returns the dimension of the object read and sets the type accordingly. Returns 0 in the case of the end of a file or a file error. Throws an error message on failure.

Definition at line 2135 of file pointset.h.

References closingparenthesis(), ignorecomments(), ignoreline(), and readcoordinates().

{
        // ignore all the texts that appear before the actual cell or cube
        int closing;
        while ((closing = closingparenthesis (in. peek ())) == EOF)
        {
                ignoreline (in);
                ignorecomments (in);
                if (!in)
                        return 0;
        }

        // try reading the coordinates of the cube
        int dim = readcoordinates (in, left, maxdim);

        // if successful, then both parentheses are read
        if (dim > 0)
        {
                // check if this is not a product of intervals
                ignorecomments (in);
                if (((in. peek () != 'x') && (in. peek () != 'X')) ||
                        (dim > 2))
                {
                        // set the right coordinates accordingly
                        for (int i = 0; i < dim; ++ i)
                                right [i] = (coordtype) (left [i] + 1);
                        if (type)
                                *type = CUBE;
                        return dim;
                }

                // read the remaining intervals
                right [0] = (dim < 2) ? left [0] : left [1];
                dim = 1;
                coordtype temp [2];
                while ((in. peek () == 'x') || (in. peek () == 'X'))
                {
                        if (dim >= maxdim)
                                throw "Too many intervals in a product.";
                        in. get ();
                        ignorecomments (in);
                        int d = readcoordinates (in, temp, 2);
                        if ((d <= 0) || !in)
                                throw "Can't read a product of intervals.";
                        left [dim] = temp [0];
                        right [dim] = (d < 2) ? temp [0] : temp [1];
                        ++ dim;
                        ignorecomments (in);
                }
                if (type)
                        *type = CELL;
                return dim;
        }

        // otherwise, this is a cubical cell
        else
        {
                // if an error is set for the input stream, clear it
                in. clear (in. rdstate () & ~std::ios::failbit);
                ignorecomments (in);

                // read two points for the cell
                int leftdim = readcoordinates (in, left, maxdim);
                ignorecomments (in);
                int rightdim = readcoordinates (in, right, maxdim);
                ignorecomments (in);

                // compare the dimensions
                if (!leftdim || !rightdim)
                        throw "Can't read a cell.";
                else if (leftdim != rightdim)
                        throw "Different dim of left & right point.";
                else
                        dim = leftdim;

                // read the closing bracket of the cell
                if (in. get () != closing)
                        throw "Can't read the closing bracket of a cell.";
                ignorecomments (in);
                if (type)
                        *type = CELL;
        }
        return dim;
} /* readcubeorcell */

template<class cubsettype >
std::istream& chomp::homology::ReadCubes ( std::istream &  in,
cubsettype &  s 
)

Reads a set of cubes and ignores the line at the beginning of the file which starts with the letter 'd' (like "dimension 2").

For compatibility with previous versions of my software.

Definition at line 194 of file cubemain.h.

References ignorecomments(), LARGE_SIZE, and read().

Referenced by operator>>().

{
        // ignore any comments at the beginning of the file
        ignorecomments (in);

        // if the word "dimension" found, ignore the entire line
        if (in. peek () == 'd')
        {
                in. ignore (20000, '\n');
                ignorecomments (in);
        }

        // read the set of cubes using the standard procedure
        return read (in, s, LARGE_SIZE);
} /* ReadCubes */

template<class celltype >
std::istream& chomp::homology::ReadCubicalCell ( std::istream &  in,
celltype &  c 
) [inline]

Reads a cubical cell form the input text stream.

Allowed formats are: (1) two opposite vertices: with minimal and maximal coordinates, (2) a Cartesian product of intervals (with degenerated intervals allowed), (3) a full-dimensional cubical cell defined by its minimal vertex. For example: [(1,8,-3) (2,9,-2)] = (1,2) x (8,9) x (-3,-2) = (1,8,-3). Another example: [(-4,5,12) (-4,6,12)] = (-4) x (5,6) x (12). Note that the definition of a cubical cell is interpreted as the definition of a full-dimensional cube only if other interpretations fail. As a result, (3,4) will be treated as a 1-dimensional nondegenerated cubical cell in R^1, and not as (3,4) x (4,5). The same applies to 0-dimensional cells in R^1.

Definition at line 236 of file cellmain.h.

References closingparenthesis(), ignorecomments(), and readcoordinates().

Referenced by operator>>().

{
        typedef typename celltype::CoordType coordtype;
        // make sure that an opening parenthesis is waiting in the input
        ignorecomments (in);
        int closing = closingparenthesis (in. peek ());
        if (closing == EOF)
                throw "Opening parenthesis expected while reading a cell.";

        // read the opening parenthesis
        in. get ();
        ignorecomments (in);

        // prepare the two vertices of a cubical cell
        coordtype c1 [celltype::MaxDim], c2 [celltype::MaxDim];

        // if there is another opening parenthesis...
        if (closingparenthesis (in. peek ()) != EOF)
        {
                // read coordinates of both vertices and a comma if any
                int dim1 = readcoordinates (in, c1, celltype::MaxDim);
                ignorecomments (in);
                if (in. peek () == ',')
                {
                        in. get ();
                        ignorecomments (in);
                }
                int dim2 = readcoordinates (in, c2, celltype::MaxDim);

                // read the closing bracket and verify that the data
                ignorecomments (in);
                if ((in. get () != closing) || (dim1 <= 0) || (dim1 != dim2))
                        throw "Failed while reading two vertices of a cell.";

                // verify the distance between the vertices of the cell
                for (int i = 0; i < dim1; ++ i)
                {
                        if ((c1 [i] != c2 [i]) && (c1 [i] + 1 != c2 [i]))
                                throw "Vertices of a read cell are too far.";
                }

                // create the cubical cell with the given vertices and quit
                c = celltype (c1, c2, dim1);
                return in;
        }

        // try reading the first set of coordinates in the cell's definition
        coordtype c0 [celltype::MaxDim];
        int count = readcoordinates (in, c0, celltype::MaxDim, closing);
        if (count <= 0)
                throw "Can't read a cell.";
        ignorecomments (in);

        // if it looks like an interval, then read the cell as a product
        if ((count == 1) || (count == 2))
        {
                int dim = 0;
                c1 [dim] = c0 [0];
                c2 [dim ++] = c0 [count - 1];
                while ((in. peek () == 'x') || (in. peek () == 'X'))
                {
                        in. get ();
                        ignorecomments (in);
                        count = readcoordinates (in, c0, celltype::MaxDim);
                        ignorecomments (in);
                        if ((count < 1) || (count > 2) ||
                                (dim >= celltype::MaxDim))
                                throw "Wrong interval while reading a cell.";
                        if ((count == 2) && (c0 [1] != c0 [0]) &&
                                (c0 [1] - c0 [0] != 1))
                                throw "Too big interval defining a cell.";
                        c1 [dim] = c0 [0];
                        c2 [dim ++] = c0 [count - 1];
                }
                c = celltype (c1, c2, dim);
                return in;
        }

        // if the cell is defined as a full-dim. cube, create it this way
        for (int i = 0; i < count; ++ i)
                c1 [i] = c0 [i] + 1;
        c = celltype (c0, c1, count);
        return in;
} /* operator >> */

template<class tCube >
std::istream& chomp::homology::ReadCubicalMap ( std::istream &  in,
mvmap< tCube, tCube > &  m 
)

Reads a combinatorial cubical multivalued map from an input text stream.

Definition at line 212 of file cubemain.h.

References closingparenthesis(), ignorecomments(), ignoreline(), read(), readcoordinates(), and SMALL_SIZE.

Referenced by operator>>().

{
        // process the entire input file and read the map line-by-line
        ignorecomments (in);
        while (in. peek () != EOF)
        {
                // ignore all the lines which do not define a map assignment
                while ((closingparenthesis (in. peek ()) == EOF) &&
                        ((in. peek () < '0') || (in. peek () > '9')) &&
                        (in. peek () != EOF))
                {
                        ignoreline (in);
                        ignorecomments (in);
                }

                // if the end of the file has been reached, exit the loop
                if (in. peek () == EOF)
                        break;
        
                // determine the closing parenthesis corresp. to this one
                int closing = closingparenthesis (in. peek ());

                // if the opening parenthesis is valid, read it and
                // check the next character to determine the assignment type
                if (closing != EOF)
                {
                        in. get ();
                        ignorecomments (in);
                }

                // if the assignment is in the general form, decode the line
                if ((closing == EOF) ||
                        (closingparenthesis (in. peek ()) == EOF))
                {
                        // read the domain element
                        tCube e;
                        // if it is given as a number, read it directly
                        if (closing == EOF)
                        {
                                in >> e;
                                if (!in)
                                        throw "Can't read cube's number.";
                        }
                        // otherwise read the coordinates of the cube
                        else
                        {
                                typename tCube::CoordType coord
                                        [tCube::MaxDim];
                                int dim = readcoordinates (in, coord,
                                        tCube::MaxDim, closing);
                                if (!in || (dim <= 0))
                                        throw "Unable to read a cube.";
                                e = tCube (coord, dim);
                        }
                        ignorecomments (in);

                        // read the assignment arrow
                        while (in. peek () == '-')
                                in. get ();
                        if (in. peek () == '>')
                                in. get ();
                        ignorecomments (in);

                        // read the image of the cube
                        read (in, m [e], SMALL_SIZE);
                        ignorecomments (in);
                }

                // otherwise read the assignment in the Jacek & Marcin format
                else
                {
                        // read the argument cell
                        typename tCube::CoordType argleft [tCube::MaxDim];
                        typename tCube::CoordType argright [tCube::MaxDim];
                        int dim = readcoordinates (in, argleft,
                                tCube::MaxDim);
                        ignorecomments (in);
                        int d1 = readcoordinates (in, argright,
                                tCube::MaxDim);
                        ignorecomments (in);

                        // read the closing and opening brackets
                        in. get ();
                        ignorecomments (in);
                        in. get ();
                        ignorecomments (in);

                        // read the value cell
                        typename tCube::CoordType vleft [tCube::MaxDim];
                        typename tCube::CoordType vright [tCube::MaxDim];
                        int d2 = readcoordinates (in, vleft, tCube::MaxDim);
                        ignorecomments (in);
                        int d3 = readcoordinates (in, vright, tCube::MaxDim);
                        ignorecomments (in);

                        // if there was an I/O error, interrupt reading here
                        if (!in || (in. peek () == EOF))
                                throw "Cannot read a map assignment line.";

                        // read the closing bracket
                        in. get ();
                        ignorecomments (in);

                        // check that all the dimensions are the same
                        if ((d1 != dim) || (d2 != dim) || (d3 != dim))
                                throw "Wrong dimensions of vertices.";

                        // verify that the argument cube is of the right size
                        for (int i = 0; i < dim; ++ i)
                        {
                                if (argright [i] - argleft [i] != 1)
                                        throw "Wrong size of an argument.";
                        }

                        // add the argument cube to the map's domain
                        hashedset<tCube> &v = m [tCube (argleft, dim)];

                        // form a rectangle from this value cell
                        tRectangle<typename tCube::CoordType> r
                                (vleft, vright, dim);

                        // add all the value cubes to the image of this element
                        const typename tCube::CoordType *c;
                        while ((c = r. get ()) != NULL)
                                v. add (tCube (c, dim));
                }
        }
        
        return in;
} /* ReadCubicalMap */

template<class domelement , class imgelement >
std::istream& chomp::homology::readdomain ( std::istream &  in,
hashedset< domelement > &  dom,
const mvmap< domelement, imgelement > &   
)

Reads the domain of a multivalued map.

Definition at line 1153 of file hashsets.h.

References ignorecomments(), and readparenthesis().

{
        ignorecomments (in);
        while (in. peek () != EOF)
        {
                domelement e;
                in >> e;
        //      if (!in)
        //              throw "Failed to read a domain element of a map.";
                dom. add (e);

                // read the map's arrow
                ignorecomments (in);
                while (in. peek () == '-')
                        in. get ();
                if (in. peek () == '>')
                        in. get ();

                ignorecomments (in);
                int closing = readparenthesis (in);

                ignorecomments (in);
                while (in. peek () != closing)
                {
                        imgelement junk;
                        in >> junk;
                //      if (!in)
                //              throw "Failed to read an image element.";
                        ignorecomments (in);
                        if (in. peek () == ',')
                        {
                                in. get ();
                                ignorecomments (in);
                        }
                }

                if (closing != EOF)
                        in. get ();
                ignorecomments (in);
        }
        return in;
} /* readdomain */

template<class tCube >
std::istream& chomp::homology::readdomain ( std::istream &  in,
hashedset< tCube > &  dom 
)

Reads the domain of a multivalued cubical map.

This is a specialization of the corresponding function for reading the domain of a general multivalued map.

Definition at line 407 of file cubmaps.h.

References ignorecomments(), and ignoreline().

Referenced by readmapdomain().

{
        ignorecomments (in);
        if ((in. peek () != 'S') && (in. peek () != 's'))
        {
                mvmap<tCube,tCube> Fdummy;
                return readdomain (in, dom, Fdummy);
        }

        while (in. peek () != EOF)
        {
                if (in. peek () == '[')
                {
                        in. get ();
                        tCube q;
                        in >> q;
                        if (!in)
                                throw "Can't read the file.";
                        dom. add (q);
                }
                ignoreline (in);
                ignorecomments (in);
        }
        
        return in;
} /* readdomain */

template<class element >
void chomp::homology::readelements ( const char *  name,
hashedset< element > &  s,
const char *  what 
) [inline]

Uses the general procedure "readtheset" to read a set of elements.

Definition at line 165 of file homtools.h.

References readtheset().

{
        readtheset (name, s, element::pluralname (), what);
        return;
} /* readelements */

void chomp::homology::readelements ( const char *  name,
cubes &  cub,
const char *  what 
) [inline]

Reads a set of cubes from the given file.

This function is necessary because cubes need special treatment.

Definition at line 174 of file homtools.h.

References chomp::homology::tCubeBase< coordtype >::pluralname(), and readtheset().

{
        readtheset (name, cub, cube::pluralname (), what);
        return;
} /* readelements */

int chomp::homology::readfromstring ( char *  str,
char *&  t 
) [inline]

A specialization of the above template for interpreting a string as a string (no processing is necessary).

Definition at line 372 of file arg.h.

{
        t = str;
        return 0;
} /* readfromstring */

int chomp::homology::readfromstring ( char *  str,
bool &  t 
) [inline]

A specialization of the above template for reading a bool type.

Definition at line 389 of file arg.h.

{
        switch (*str)
        {
                case 'T':
                case 't':
                case 'Y':
                case 'y':
                case '1':
                        t = true;
                        return 0;
                case 'F':
                case 'f':
                case 'N':
                case 'n':
                case '0':
                        t = false;
                        return 0;
                default:
                        return -1;
        }
} /* readfromstring */

int chomp::homology::readfromstring ( char *  str,
const char *&  t 
) [inline]

A specialization of the above template for interpreting a string as a const string (no processing is necessary).

Definition at line 382 of file arg.h.

{
        t = str;
        return 0;
} /* readfromstring */

template<class type >
int chomp::homology::readfromstring ( char *  str,
type &  t 
) [inline]

A template for reading a variable from a string.

Returns 0 on success, -1 on failure.

Definition at line 354 of file arg.h.

Referenced by chomp::homology::argunit< type >::setvalue().

{
        std::istringstream s (str);
        try
        {
                s >> t;
                if (!s)
                        return -1;
        }
        catch (...)
        {
                return -1;
        }
        return 0;
} /* readfromstring */

template<class domelement , class imgelement >
std::istream& chomp::homology::readimage ( std::istream &  in,
hashedset< imgelement > &  img,
const mvmap< domelement, imgelement > &   
)

Reads the image of a multivalued map.

Definition at line 1199 of file hashsets.h.

References ignorecomments(), read(), and SMALL_SIZE.

{
        ignorecomments (in);
        while (in. peek () != EOF)
        {
                domelement e;
                in >> e;
        //      if (!in)
        //              throw "Failed to read a domain element of a map.";

                // read the map's arrow
                ignorecomments (in);
                while (in. peek () == '-')
                        in. get ();
                if (in. peek () == '>')
                        in. get ();

                ignorecomments (in);
                read (in, img, SMALL_SIZE);

                ignorecomments (in);
        }
        return in;
} /* readimage */

template<class tCube >
std::istream& chomp::homology::readimage ( std::istream &  in,
hashedset< tCube > &  img 
)

Reads the image of a multivalued cubical map.

This is a specialization of the corresponding function for reading the image of a general multivalued map.

Definition at line 438 of file cubmaps.h.

References ignorecomments(), and ignoreline().

Referenced by readmapimage().

{
        ignorecomments (in);
        if ((in. peek () != 'S') && (in. peek () != 's'))
        {
                mvmap<tCube,tCube> Fdummy;
                return readimage (in, img, Fdummy);
        }

        typename tCube::CoordType left [tCube::MaxDim];
        typename tCube::CoordType right [tCube::MaxDim];
        while (in. peek () != EOF)
        {
                if (in. peek () == '[')
                {
                        in. get ();
                        tCube dummy;
                        in >> dummy;
                        in >> dummy;
                        ignorecomments (in);
                        in. get ();
                        ignorecomments (in);
                        in. get ();
                        tCube q1, q2;
                        in >> q1 >> q2;
                        if (!in)
                                throw "Can't read the file.";
                        ignorecomments (in);
                        in. get ();
                        ignorecomments (in);
                        int dim = q1. dim ();
                        q1. coord (left);
                        q2. coord (right);
                        tRectangle<typename tCube::CoordType> r
                                (left, right, dim);
                        const typename tCube::CoordType *c;
                        while ((c = r. get ()) != NULL)
                                img. add (tCube (c, dim));
                }
                else
                        ignoreline (in);
                ignorecomments (in);
        }

        return in;
} /* readimage */

template<class tCube >
std::istream& chomp::homology::readimage ( std::istream &  in,
const hashedset< tCube > &  dom,
hashedset< tCube > &  img 
)

Read the image of a set under a multivalued cubical map.

This is a specialization of the corresponding function for reading the image of a general multivalued map.

Definition at line 489 of file cubmaps.h.

References closingparenthesis(), ignorecomments(), and ignoreline().

{
        ignorecomments (in);
        // the general format: [x,y,z] -> {[a,b,c], [d,e,f]}
        if ((in. peek () != 'S') && (in. peek () != 's'))
        {
                while (in. peek () != EOF)
                {
                        if ((closingparenthesis (in. peek ()) == EOF) &&
                                !std::isdigit (in. peek ()))
                        {
                                ignoreline (in);
                                ignorecomments (in);
                                continue;
                        }
                        tCube q;
                        in >> q;
                        bool ignore = !dom. check (q);
                        ignorecomments (in);
                        while (in. peek () == '-')
                                in. get ();
                        in. get (); // '>'
                        ignorecomments (in);
                        int opening = in. get ();
                        int closing = closingparenthesis (opening);
                        if (closing == EOF)
                                throw "An opening brace '{' expected.";
                        while ((in. peek () != EOF) &&
                                (in. peek () != closing))
                        {
                                if (ignore)
                                {
                                        if (in. get () == opening)
                                        {
                                                while ((in. peek () != EOF) &&
                                                        (in. peek () != closing))
                                                {
                                                        in. get ();
                                                }
                                                in. get (); // '}'
                                        }
                                }
                                else
                                {
                                        in >> q;
                                        img. add (q);
                                        ignorecomments (in);
                                        if (in. peek () == ',')
                                        {
                                                in. get ();
                                                ignorecomments (in);
                                        }
                                }
                        }
                //      in. get (); // '}'
                        ignoreline (in);
                        ignorecomments (in);
                }
        }

        typename tCube::CoordType left [tCube::MaxDim];
        typename tCube::CoordType right [tCube::MaxDim];
        while (in. peek () != EOF)
        {
                if (in. peek () == '[')
                {
                        in. get ();
                        tCube domcube1, domcube2;
                        in >> domcube1;
                        if (!dom. check (domcube1))
                        {
                                ignoreline (in);
                                ignorecomments (in);
                                continue;
                        }
                        in >> domcube2;
                        ignorecomments (in);
                        in. get ();
                        ignorecomments (in);
                        in. get ();
                        tCube q1, q2;
                        in >> q1 >> q2;
                        if (!in)
                                throw "Can't read the file.";
                        ignorecomments (in);
                        in. get ();
                        ignorecomments (in);
                        if (dom. check (domcube1))
                        {
                                int dim = q1. dim ();
                                q1. coord (left);
                                q2. coord (right);
                                tRectangle<typename tCube::CoordType> r
                                        (left, right, dim);
                                const typename tCube::CoordType *c;
                                while ((c = r. get ()) != NULL)
                                        img. add (tCube (c, dim));
                        }
                }
                else
                        ignoreline (in);
                ignorecomments (in);
        }

        return in;
} /* readimage */

template<class element >
void chomp::homology::readmapdomain ( const char *  name,
hashedset< element > &  cub 
) [inline]

Reads the domain of a cubical multivalued map from the given file.

Definition at line 182 of file homtools.h.

References fileerror(), readdomain(), and sout.

{
        if (!name)
                return;
        sout << "Reading the domain of the map from '" << name << "'... ";
        std::ifstream in (name);
        if (!in)
                fileerror (name);
        int_t prev = cub. size ();
        readdomain (in, cub);
        sout << (cub. size () - prev) << " " << element::pluralname () <<
                " read.\n";
        return;
} /* readmapdomain */

template<class element >
void chomp::homology::readmapimage ( const char *  name,
hashedset< element > &  cub 
) [inline]

Reads the domain of a cubical multivalued map from the given file.

Definition at line 199 of file homtools.h.

References fileerror(), readimage(), and sout.

{
        if (!name)
                return;
        sout << "Reading the image of the map from '" << name << "'... ";
        std::ifstream in (name);
        if (!in)
                fileerror (name);
        int_t prev = cub. size ();
        readimage (in, cub);
        sout << (cub. size () - prev) << " " << element::pluralname () <<
                " read.\n";
        return;
} /* readmapimage */

template<class element >
void chomp::homology::readmapimage ( const char *  filename,
const hashedset< element > &  dom,
const char *  domname,
hashedset< element > &  cub 
) [inline]

Reads the image of a set by a cubical multivalued map from the given file.

Definition at line 217 of file homtools.h.

References fileerror(), readimage(), and sout.

{
        if (!filename)
                return;
        sout << "Reading the image of " << domname << " by the map '" <<
                filename << "'... ";
        std::ifstream in (filename);
        if (!in)
                fileerror (filename);
        int_t prev = cub. size ();
        readimage (in, dom, cub);
        sout << (cub. size () - prev) << " " << element::pluralname () <<
                " read.\n";
        return;
} /* readmapimage */

template<class element >
void chomp::homology::readmaprestriction ( mvmap< element, element > &  Fcubmap,
const char *  mapname,
const hashedset< element > &  Xcubes,
const char *  Xname,
const char *  purpose = NULL 
) [inline]

Reads the restriction of a multivalued map to the given set.

Definition at line 266 of file homtools.h.

References readmaprestriction().

{
        hashedset<element> empty;
        readmaprestriction (Fcubmap, mapname, Xcubes, empty, Xname, purpose);
        return;
} /* readmaprestriction */

template<class element >
void chomp::homology::readmaprestriction ( mvmap< element, element > &  Fcubmap,
const char *  mapname,
const hashedset< element > &  Xcubes,
const hashedset< element > &  Acubes,
const char *  Xname,
const char *  purpose = 0 
) [inline]

Reads the restriction of a multivalued map to the union of two sets.

Definition at line 237 of file homtools.h.

References fileerror(), readselective(), and sout.

Referenced by readmaprestriction().

{
        if (!mapname || (Xcubes. empty () && Acubes. empty ()))
                return;
        sout << "Reading the map on " << Xname << " from '" << mapname;
        if (purpose)
                sout << "' " << purpose << "... ";
        else
                sout << "'... ";
        std::ifstream in (mapname);
        if (!in)
                fileerror (mapname);
        readselective (in, Xcubes, Acubes, Fcubmap);
        if (Fcubmap. getdomain (). size () !=
                Xcubes. size () + Acubes. size ())
        {
                sout << "\nWARNING: The map is not defined "
                        "on some cubes in " << Xname << ".\n";
        }
        else
                sout << "Done.\n";
        return;
} /* readmaprestriction */

int chomp::homology::readparenthesis ( std::istream &  in  )  [inline]

Reads an opening parenthesis from the input file.

Return a corresponding closing parenthesis or EOF if none was found.

Definition at line 408 of file textfile.h.

References closingparenthesis().

Referenced by operator>>(), read(), readcoordinates(), readdomain(), readrestriction(), and readselective().

{
        int closing = closingparenthesis (in. peek ());
        if (closing != EOF)
                in. get ();
        return closing;
} /* readparenthesis */

template<class domelement , class imgelement >
std::istream& chomp::homology::readrestriction ( std::istream &  in,
mvmap< domelement, imgelement > &  m,
const hashedset< domelement > &  dom,
const hashedset< imgelement > &  img 
)

Reads a restriction of a multivalued map to the two given sets.

Definition at line 1283 of file hashsets.h.

References ignorecomments(), read(), readparenthesis(), SMALL_SIZE, and sout.

{
        if (dom. empty ())
        {
                sout << "Warning: The domain of the map is empty.\n";
                return in;
        }

        ignorecomments (in);
        while (in. peek () != EOF)
        {
                domelement e;
                in >> e;
        //      if (!in)
        //              throw "Failed to read a domain element of a map.";

                // read the map's arrow
                ignorecomments (in);
                while (in. peek () == '-')
                        in. get ();
                if (in. peek () == '>')
                        in. get ();

                ignorecomments (in);
                if (dom. check (e))
                {
                        hashedset<imgelement> &y = m [e];
                        hashedset<domelement> x;
                        read (in, x, SMALL_SIZE);
                        int_t n = x. size ();
                        for (int_t i = 0; i < n; ++ i)
                        {
                                if (img. check (x [i]))
                                        y. add (x [i]);
                        }
                }
                else
                {
                        int closing = readparenthesis (in);
        
                        ignorecomments (in);
                        while (in. peek () != closing)
                        {
                                imgelement junk;
                                in >> junk;
                        //      if (!in)
                        //              throw "Failed to read an img elem.";
                                ignorecomments (in);
                                if (in. peek () == ',')
                                {
                                        in. get ();
                                        ignorecomments (in);
                                }
                        }
        
                        if (closing != EOF)
                                in. get ();
                }
                ignorecomments (in);
        }
        return in;
} /* readrestriction */

template<class domelement , class imgelement >
std::istream& chomp::homology::readselective ( std::istream &  in,
mvmap< domelement, imgelement > &  m,
const hashedset< domelement > &  dom 
) [inline]

Reads a restriction of a multivalued map to the given set.

Definition at line 1350 of file hashsets.h.

References readselective().

{
        hashedset<domelement> empty;
        return readselective (in, m, dom, empty);
} /* readselective */

template<class tCube >
std::istream& chomp::homology::readselective ( std::istream &  in,
const hashedset< tCube > &  dom,
mvmap< tCube, tCube > &  m 
) [inline]

Reads a restriction of a multivalued cubical map to the given set.

The order of arguments is reversed to distinguish form the template defined for a general multivalued map.

Definition at line 654 of file cubmaps.h.

References readselective().

{
        hashedset<tCube> empty;
        return readselective (in, dom, empty, m);
} /* readselective */

template<class domelement , class imgelement >
std::istream& chomp::homology::readselective ( std::istream &  in,
mvmap< domelement, imgelement > &  m,
const hashedset< domelement > &  dom1,
const hashedset< domelement > &  dom2 
)

Reads a restriction of a multivalued map to the union of the given sets.

Definition at line 1227 of file hashsets.h.

References ignorecomments(), read(), readparenthesis(), SMALL_SIZE, and sout.

{
        if (dom1. empty () && dom2. empty ())
        {
                sout << "Warning: The domain of the map is empty.\n";
                return in;
        }

        ignorecomments (in);
        while (in. peek () != EOF)
        {
                domelement e;
                in >> e;
        //      if (!in)
        //              throw "Failed to read a domain element of a map.";

                // read the map's arrow
                ignorecomments (in);
                while (in. peek () == '-')
                        in. get ();
                if (in. peek () == '>')
                        in. get ();

                ignorecomments (in);
                if (dom1. check (e) || dom2. check (e))
                        read (in, m [e], SMALL_SIZE);
                else
                {
                        int closing = readparenthesis (in);
        
                        ignorecomments (in);
                        while (in. peek () != closing)
                        {
                                imgelement junk;
                                in >> junk;
                        //      if (!in)
                        //              throw "Failed to read an img elem.";
                                ignorecomments (in);
                                if (in. peek () == ',')
                                {
                                        in. get ();
                                        ignorecomments (in);
                                }
                        }
        
                        if (closing != EOF)
                                in. get ();
                }
                ignorecomments (in);
        }
        return in;
} /* readselective */

template<class tCube >
std::istream& chomp::homology::readselective ( std::istream &  in,
const hashedset< tCube > &  dom1,
const hashedset< tCube > &  dom2,
mvmap< tCube, tCube > &  m 
)

Reads the restriction of a multivalued map to the given pair of sets.

Definition at line 599 of file cubmaps.h.

References ignorecomments(), ignoreline(), and sout.

Referenced by readmaprestriction(), and readselective().

{
        if (dom1. empty () && dom2. empty ())
        {
                sout << "Warning: The domain of the map is empty.\n";
                return in;
        }

        ignorecomments (in);
        if ((in. peek () != 'S') && (in. peek () != 's'))
                return readselective (in, m, dom1, dom2);

        typename tCube::CoordType left [tCube::MaxDim];
        typename tCube::CoordType right [tCube::MaxDim];
        while (in. peek () != EOF)
        {
                if (in. peek () == '[')
                {
                        in. get ();
                        tCube domcube;
                        in >> domcube;
                        int dim = domcube. dim ();
                        if (dom1. check (domcube) || dom2. check (domcube))
                        {
                                tCube q1, q2;
                                in >> q1; // (ignored)
                                ignorecomments (in);
                                in. get ();
                                ignorecomments (in);
                                in. get ();
                                in >> q1 >> q2;
                                if (!in)
                                        throw "Can't read the file.";
                                hashedset<tCube> &img = m [domcube];
                                q1. coord (left);
                                q2. coord (right);
                                tRectangle<typename tCube::CoordType> r
                                        (left, right, dim);
                                const typename tCube::CoordType *c;
                                while ((c = r. get ()) != NULL)
                                        img. add (tCube (c, dim));
                        }
                }
                ignoreline (in);
                ignorecomments (in);
        }

        return in;
} /* readselective */

template<class settype >
void chomp::homology::readtheset ( const char *  name,
settype &  s,
const char *  pluralname,
const char *  what 
)

Reads a given set from the file and shows appropriate messages.

Assumes the elements of the set begin with an opening parenthesis-char (or a digit, if "digitOk" == true) and ignores all the preceding data. Uses the given plural name of the elements for the messages. Note: This procedure is suitable for gcomplex<type> or hashedset<type>.

Definition at line 118 of file homtools.h.

References closingparenthesis(), fileerror(), ignorecomments(), ignoreline(), and sout.

Referenced by readcells(), and readelements().

{
        // if no file name is given, do nothing
        if (!name)
                return;

        // show what you are doing
        sout << "Reading " << pluralname;
        if (what)
                sout << " to " << what;
        sout << " from '" << name << "'... ";

        // open the file
        std::ifstream in (name);
        if (!in)
                fileerror (name);

        // ignore all the introductory data
        ignorecomments (in);
        while (!!in && (closingparenthesis (in. peek ()) == EOF) &&
                ((in. peek () < '0') || (in. peek () > '9')) &&
                (in. peek () != '-'))
        {
                ignoreline (in);
                ignorecomments (in);
        }

        // read the set and show how many elements have been read
        int_t prev = s. size ();
        in >> s;
        sout << (s. size () - prev) << " " << pluralname << " read.\n";

        return;
} /* readtheset */

template<class FullCubSet >
int chomp::homology::reduceFullCubes ( FullCubSet &  X,
bool  quiet = false 
) [inline]

Reduces the set of full cubes.

Definition at line 1158 of file bincube.h.

References reduceFullCubesAlg().

Referenced by ComputeBettiNumbers().

{
        switch (X. dimension ())
        {
                case 3:
                        return reduceFullCubesAlg<FullCubSet,
                                Acyclic3d<FullCubSet>,hashIntQueue> (X, quiet);
                case 2:
                        return reduceFullCubesAlg<FullCubSet,
                                Acyclic2d<FullCubSet>,hashIntQueue> (X, quiet);
                case 1:
                        return reduceFullCubesAlg<FullCubSet,
                                Acyclic1d<FullCubSet>,hashIntQueue> (X, quiet);
                default:
                        throw "Binary cube reduction not implemented "
                                "for dimension > 3.";
        }
} /* reduceFullCubes */

template<typename SetT , typename Acyclic , typename QueueT >
int chomp::homology::reduceFullCubesAlg ( SetT &  X,
bool  quiet 
)

Reduces the set of full cubes.

The class 'Acyclic' provides the function for checking if a cube can be removed from a full cubical set (the 'acyclicity' criterion). A queue in which each element should appear only once is used.

Definition at line 1056 of file bincube.h.

References addneighbors(), scon, and sout.

Referenced by reduceFullCubes().

{
        // prepare the set of cubes to consider next time
        QueueT Q;

        // scan the entire set until very few cubes are removed
        int count = 0;
        bool exitloop = false;
        bool lastrun = false;
        while (!exitloop)
        {
                // remember to exit the loop after the last run
                if (lastrun)
                        exitloop = true;

                int countremoved = 0, countleft = 0;
                typename SetT::iterator cur = X. begin (), end = X. end ();
                while (cur != end)
                {
                        if (Acyclic::check (cur, X))
                        {
                                X. remove (cur);
                                ++ countremoved;
                                if (lastrun)
                                        addneighbors (cur, X, Q);
                        }
                        else
                                ++ countleft;
                        ++ cur;
        
                        // show progress indicator
                        if (!quiet && !(count % 5273))
                                scon << std::setw (10) << count <<
                                        "\b\b\b\b\b\b\b\b\b\b";
                        ++ count;
                }
                if (!quiet)
                        sout << ".";

                if (!lastrun && (countremoved - 10 < (countleft >> 2)))
                        lastrun = true;
        }
        
        if (!quiet)
                sout << " ";
        count = 0;
        while (!Q. empty ())
        {
                typename QueueT::value_type elem = Q. front ();
                Q. pop ();
                if (Acyclic::check (elem, X))
                {
                        X. remove (elem);
                        addneighbors (elem, X, Q);
                }

                // show progress indicator
                if (!quiet && !(count % 5273))
                        scon << std::setw (10) << count <<
                                "\b\b\b\b\b\b\b\b\b\b";
                count ++;
        }

        return 0;
} /* reduceFullCubesAlg */

template<class cubsettype >
void chomp::homology::reducepair ( cubsettype &  Xcubes,
cubsettype &  Acubes,
const cubsettype &  Xkeepcubes,
const char *  Xname,
const char *  Aname 
)

Reduces the pair of sets of cubes. Keeps the given cubes untouched.

Definition at line 620 of file homtools.h.

References cubreduce(), and sout.

Referenced by Homology(), and Homology2l().

{
        if (Xcubes. empty ())
                return;
        sout << "Reducing full-dim cubes from ";
        if (!Acubes. empty ())
                sout << '(' << Xname << ',' << Aname << ")... ";
        else
                sout << Xname << "... ";
        int_t count = cubreduce (Xcubes, Acubes, Xkeepcubes);
        sout << count << " removed, " <<
                (Xcubes. size () + Acubes. size ()) << " left.\n";
        return;
} /* reducepair */

template<class maptype , class cubsettype >
void chomp::homology::reducepair ( cubsettype &  Xcubes,
cubsettype &  Acubes,
maptype &  Fcubmap,
const cubsettype &  Xkeepcubes,
const char *  Xname,
const char *  Aname 
)

Reduces the pair of sets of cubes.

Keeps the given cubes untouched. Makes sure that the acyclicity of the given map is not spoiled.

Definition at line 639 of file homtools.h.

References cubreduce(), and sout.

{
        if (Xcubes. empty ())
                return;
        sout << "Reducing cubes from ";
        if (!Acubes. empty ())
                sout << '(' << Xname << ',' << Aname << ") [acyclic]... ";
        else
                sout << Xname << " [acyclic]... ";
        int_t count = cubreduce (Xcubes, Acubes, Fcubmap, Xkeepcubes);
        sout << count << " removed, " <<
                (Xcubes. size () + Acubes. size ()) << " left.\n";
        return;
} /* reducepair */

template<class tCube >
bool chomp::homology::remainsacyclic ( const mvmap< tCube, tCube > &  map,
const tCube &  q,
const hashedset< tCube > &  cset1,
const hashedset< tCube > *  cset2 = 0 
)

Verifies if the map remains acyclic after the addition or removal of the given cube to/from the union of the first and the second set.

Assumes that the map is acyclic before the change. Returns 'true' if yes for sure, 'false' if there is some doubt about it.

Definition at line 282 of file cubisets.h.

References addboundaries(), addneighbors(), computeimage(), cubreducequiet(), getmaxneighbors(), getneighbors(), and makesetunion().

Referenced by cubexpand(), and cubreducequiet().

{
        // compute the maximal number of neighbors of a cube
        int_t maxneighbors = getmaxneighbors (q. dim ());

        // prepare a bitfield and allocate it if necessary
        static BitField b;
        static int_t _maxneighbors = 0;
        if (maxneighbors != _maxneighbors)
        {
                if (_maxneighbors > 0)
                        b. free ();
                _maxneighbors = maxneighbors;
                b. allocate (maxneighbors);
        }

        // clear the neighborbits
        b. clearall (maxneighbors);

        // get the bitfield representing the set of the neighbors of the cube
        if (cset2)
                getneighbors (q, &b, makesetunion (cset1, *cset2), 0);
        else
                getneighbors (q, &b, cset1, 0);

        // create all the faces of the cube
        gcomplex<typename tCube::CellType,integer> faces;
        addneighbors (q, b, faces);
        faces. addboundaries ();

        // compute the new images of all the faces
        // and determine if they are acyclic
        int startdim = faces. dim ();
        for (int d = startdim; d >= 0; -- d)
        {
                for (int_t i = 0; i < faces [d]. size (); ++ i)
                {
                        // compute the image of the face in the first set
                        hashedset<tCube> img;
                        int_t n = computeimage (img, faces [d] [i], map,
                                cset1, q);

                        // add the image of the second set if applicable
                        if (cset2)
                        {
                                n += computeimage (img, faces [d] [i], map,
                                        *cset2, q);
                        }

                        // if this is the image of only one cube, it is Ok
                        if (n == 1)
                                continue;

                        // verify whether the large image (with 'q')
                        // can be reduced towards the small one (without 'q')
                        hashedset<tCube> imgsurplus = map (q);
                        imgsurplus. remove (img);
                        cubreducequiet (img, imgsurplus);
                        if (!imgsurplus. empty ())
                                return false;
                }
        }

        return true;
} /* remainsacyclic */

template<class cubsettype >
void chomp::homology::removeAfromX ( cubsettype &  Xcubes,
const cubsettype &  Acubes,
const char *  Xname,
const char *  Aname 
)

Removes 'Acubes' from 'Xcubes' and shows messages.

Definition at line 549 of file homtools.h.

References sout.

Referenced by Homology(), and Homology2l().

{
        if (Xcubes. empty () || Acubes. empty ())
                return;
        sout << "Computing " << Xname << "\\" << Aname << "... ";
        int_t prev = Xcubes. size ();
        Xcubes. remove (Acubes);
        sout << (prev - Xcubes. size ()) << " cubes removed from " <<
                Xname << ", " << Xcubes. size () << " left.\n";
        return;
} /* removeAfromX */

template<class cell , class euclidom >
void chomp::homology::removeAfromX ( gcomplex< cell, euclidom > &  X,
const gcomplex< cell, euclidom > &  A,
const char *  Xname,
const char *  Aname 
)

Removes from 'X' all the cells that appear in 'A'.

Definition at line 564 of file homtools.h.

References sout.

{
        if (X. empty () || A. empty ())
                return;
        sout << "Computing " << Xname << "\\" << Aname << "... ";
        int_t prev = X. size ();
        X. remove (A);
        sout << (prev - X. size ()) << ' ' << cell::pluralname () <<
                " removed from " << Xname << ", " << X. size () <<
                " left.\n";
        return;
} /* removeAfromX */

template<class cubsettype >
void chomp::homology::restrictAtoneighbors ( const cubsettype &  Xcubes,
cubsettype &  Acubes,
const char *  Xname,
const char *  Aname,
const cubsettype *  keepcubes = 0 
)

Restricts the set of cubes 'Acubes' to these cubes which are neighbors of any of the cubes in 'Xcubes' and displays appropriate messages.

Definition at line 504 of file homtools.h.

References getneighbors(), sout, and sseq.

Referenced by Homology(), and Homology2l().

{
        // if the set 'A' is empty, there is no point in doing anything
        if (Acubes. empty ())
                return;

        // display the message what is being done now
        sout << "Restricting " << Aname << " to the neighbors of " <<
                Xname << "\\" << Aname << "... ";

        // remember the previous number of cubes in 'A'
        int_t prev = Acubes. size ();

        // if the set 'X' is empty, the result is obvious
        if (Xcubes. empty ())
        {
                cubsettype empty;
                Acubes = empty;
        }

        // remove from 'A' these cubes which are not neighbors of 'X'
        sseq << "D 0\n";
        for (int_t i = 0; i < Acubes. size (); ++ i)
        {
                if (keepcubes && keepcubes -> check (Acubes [i]))
                        continue;
                if (getneighbors (Acubes [i], 0, Xcubes, 1))
                        continue;
                sseq << '0' << Acubes [i] << '\n';
                Acubes. removenum (i);
                -- i;
        }
        sseq << "D 100\n";

        // display the result
        sout << (prev - Acubes. size ()) << " cubes removed, " <<
                Acubes. size () << " left.\n";

        return;
} /* restrictAtoneighbors */

template<class domelement , class imgelement >
hashedset<imgelement>& chomp::homology::retrieveimage ( const mvmap< domelement, imgelement > &  m,
hashedset< imgelement > &  img 
)

Adds images of all the elements from the domain of the map to 'img'.

Definition at line 1122 of file hashsets.h.

Referenced by addmapimg().

{
        int_t n = m. getdomain (). size ();
        for (int_t i = 0; i < n; ++ i)
                img. add (m (i));
        return img;
} /* retrieveimage */

template<class coordtype >
coordtype chomp::homology::rounddown ( double  x  )  [inline]

Rounds down the given real number to an integral type.

Definition at line 200 of file pointset.h.

{
        if ((x >= 0) || ((double) (coordtype) x == x))
                return (coordtype) x;
        else
                return -(coordtype) (-x) - 1;
} /* rounddown */

template<class coordtype >
void chomp::homology::roundpoint ( const double *  p,
coordtype *  c,
const double *  grid,
int  dim 
) [inline]

Rounds down the double coordinates of a point to integer ones.

If the grid is provided (not NULL), then uses this grid instead of the integral lattice.

Definition at line 212 of file pointset.h.

Referenced by chomp::homology::tPointset< coordtype >::add(), and chomp::homology::tPointset< coordtype >::getnumber().

{
        if (grid)
        {
                for (int i = 0; i < dim; ++ i)
                        c [i] = rounddown<coordtype> (p [i] / grid [i]);
        }
        else
        {
                for (int i = 0; i < dim; ++ i)
                        c [i] = rounddown<coordtype> (p [i]);
        }
        return;
} /* roundpoint */

template<class cell , class euclidom >
void chomp::homology::savecells ( const char *  name,
const gcomplex< cell, euclidom > &  s,
const char *  what,
const char *  filecomment = 0 
) [inline]

Uses the general procedure "savetheset" to save a geometric complex.

Definition at line 317 of file homtools.h.

References savetheset().

{
        savetheset (name, s, cell::pluralname (), what, filecomment);
        return;
} /* savecells */

template<class element >
void chomp::homology::saveelements ( const char *  name,
const hashedset< element > &  s,
const char *  what,
const char *  filecomment = 0 
) [inline]

Uses the general procedure "savetheset" to save a set of elements.

Definition at line 326 of file homtools.h.

References savetheset().

{
        savetheset (name, s, element::pluralname (), what, filecomment);
        return;
} /* saveelements */

void chomp::homology::saveelements ( const char *  name,
const cubes &  cub,
const char *  what,
const char *  filecomment = 0 
) [inline]

Saves a set of cubes to the given file.

This function is necessary because cubes need special treatment.

Definition at line 335 of file homtools.h.

References chomp::homology::tCubeBase< coordtype >::pluralname(), and savetheset().

{
        savetheset (name, cub, cube::pluralname (), what, filecomment);
        return;
} /* saveelements */

template<class settype >
void chomp::homology::savetheset ( const char *  name,
const settype &  s,
const char *  pluralname,
const char *  what,
const char *  filecomment = 0 
)

Saves a given set to a file and shows appropriate messages.

Note: This procedure is suitable for gcomplex<type> or hashedset<type>.

Definition at line 284 of file homtools.h.

References fileerror(), and sout.

Referenced by savecells(), and saveelements().

{
        // if no file name is given, do nothing
        if (!name)
                return;

        // show what you are doing
        sout << "Saving " << pluralname;
        if (what)
                sout << " in " << what;
        sout << " to '" << name << "'... ";

        // open the file
        std::ofstream out (name);
        if (!out)
                fileerror (name, "create");
                
        // save the data
        if (filecomment)
                out << filecomment;
        out << s;
        if (!out)
                fileerror (name, "save");

        // show how many elements have been written
        sout << s. size () << " " << pluralname << " written.\n";

        return;
} /* writetheset */

template<class settype >
static void chomp::homology::savetheset ( const settype &  c,
const char *  prefix,
const char *  filename,
const char *  name 
) [static]

Writes the given object to a file whose name is a concatenation of the prefix and the given file name.

If the prefix is 0 thenthe prefix is treated as an empty string. Displays a warning if unsuccessful, does not throw any exception. This procedure can be applied to any data type which has the operator << for writing it to a text output stream (std::ostream) defined.

Definition at line 444 of file textfile.h.

References sout.

{
        // if there is no prefix given, do not save the file
        if (!prefix)
                return;

        // prepare the full file name
        std::string str;
        if (prefix)
                str = std::string (prefix) + std::string (filename);
        else
                str = filename;
        const char *s = str. c_str ();

        // create the output file
        std::ofstream out (s);
        if (!out)
        {
                sout << "WARNING: Cannot save the file '" << s << "'.\n";
                return;
        }

        // write the cubes to the output file
        sout << "Saving " << name << " to '" << s << "'... ";
        out << "; This is " << name << ".\n";
        out << c;
        sout << "Done.\n";

        return;
} /* savetheset */

template<class tCube >
void chomp::homology::scancubes ( const char *  name  )  [inline]

Reads all the cubes from the given file and ignores them.

In this way the numbers of cubes are established.

Definition at line 56 of file homtools.h.

References closingparenthesis(), fileerror(), ignorecomments(), ignoreline(), readcoordinates(), and sout.

{
        if (!name || !*name)
                return;
        std::ifstream in (name);
        if (!in)
                fileerror (name);

        // read all the cubes contained in the file,
        // but ignore lines not starting with a parenthesis
        sout << "Scanning the file '" << name << "' for cubes... ";
        int_t count = 0;
        int dim = -19;
        bool warned = false;
        ignorecomments (in);
        while (in)
        {
                typename tCube::CoordType c [tCube::MaxDim];
                if (closingparenthesis (in. peek ()) == EOF)
                        ignoreline (in);
                else
                {
                        // read the point from the file
                        int d = readcoordinates (in, c, tCube::MaxDim);

                        // verify the dimension of the point
                        if (dim < 0)
                                dim = d;
                        else if ((dim != d) && !warned)
                        {
                                sout << "\nWARNING: Not all the cubes have "
                                        "the same dimension.\n";
                                warned = true;
                        }

                        // add the point to the point base
                        // and verify its number
                        int_t n = tCube::PointBase::number (c, d);
                        if ((n != count) && !warned)
                        {
                                cube q (c, d);
                                sout << "\nWARNING: Some cubes are "
                                        "repeated - " << q <<
                                        " for example.\n";
                                warned = true;
                        }

                        // count the point
                        ++ count;
                }
                ignorecomments (in);
        }
        sout << count << " cubes analyzed.\n";
        return;
} /* scancubes */

template<class wType , class Table1 , class Table2 >
int_t chomp::homology::SCC ( const diGraph< wType > &  g,
Table1 &  compVertices,
Table2 &  compEnds,
diGraph< wType > *  scc = 0,
diGraph< wType > *  transposed = 0,
bool  copyweights = false 
) [inline]

Computes strongly connected components of the graph 'g'.

Creates the graph 'scc' in which each vertex corresponds to one component. The graph 'scc' given as an argument must be initially empty. The table 'compVertices' is filled with the numbers of vertices in 'g' which form the components, and the indices that end the listing for each component are stored in the table 'compEnds'. Returns the number of strongly connected components found.

Definition at line 2373 of file digraph.h.

Referenced by invariantpart(), and chomp::homology::diGraph< wType >::minMeanCycleWeight().

{
        // prepare two tables
        int_t nVert = g. countVertices ();
        int_t *ordered = new int_t [nVert];
        int_t *tab = new int_t [nVert];

        // compute the list of vertices in the descending finishing time
        g. DFSfinishTime (tab);
        for (int_t i = 0; i < nVert; ++ i)
                ordered [nVert - tab [i]] = i;
        delete [] tab;

        // create the transposed graph
        diGraph<wType> gT;
        if (!transposed)
                transposed = &gT;
        g. transpose (*transposed, copyweights);

        // extract the DFS forest of gT in the given order of vertices
        int_t n = transposed -> DFSforest (ordered, compVertices, compEnds,
                true, scc);

        // cleanup memory and return the number of components
        delete [] ordered;
        return n;
} /* SCC */

template<class wType , class Table1 , class Table2 >
int_t chomp::homology::SCC_Tarjan ( const diGraph< wType > &  g,
Table1 &  compVertices,
Table2 &  compEnds 
) [inline]

Computes strongly connected components of the graph 'g' using Tarjan's algorithm (as described in the Wikipedia).

Tha advantage of this approach over the one described in Cormen's textbook is that the transposed graph need not be computed. However, this algorithm might be slightly slower than the other one. The table 'compVertices' is filled with the numbers of vertices in 'g' which form the components, and the indices that end the listing for each component are stored in the table 'compEnds'. Returns the number of strongly connected components found.

Definition at line 2415 of file digraph.h.

{
        // return the obvious result if the graph is empty
        int_t nVertices = g. countVertices ();
        if (!nVertices)
                return 0;

        // prepare an array of discovery times for all the vertices
        // (zero == not yet discovered)
        std::vector<int_t> dfsIndex (nVertices, 0);

        // prepare an array of the minimal index of a node reachable
        // from each of the vertices
        std::vector<int_t> lowLink (nVertices, 0);

        // prepare an empty stack of nodes
        std::stack<int_t> s_nodes;

        // prepare an array of bits indicating whether the vertices are
        // in the stack of nodes or not
        BitField inTheStack;
        inTheStack. allocate (nVertices);
        inTheStack. clearall (nVertices);

        // prepare the number of strongly connected components
        int_t nComponents = 0;

        // prepare the current position in the array 'compVertices'
        int_t posVertices = 0;

        // remember the next vertex number in the graph to scan
        // whether this vertex has already been visited or not
        int_t vertexToScan = 0;

        // prepare a variable for storing the discovery time in the DFS
        int_t discoveryTime = 0;

        // prepare stacks for the DFS recursion
        std::stack<int_t> s_vertex;
        std::stack<int_t> s_edge;
        std::stack<int_t> s_maxedge;

        // initialize the number of the currently processed vertex
        int_t vertex = -1;

        // initialize the range of edges to be visited
        int_t edge = 0;
        int_t maxedge = 0;

        while (1)
        {
                // return to the previous recursion level
                // if all the edges have been checked
                if (edge >= maxedge)
                {
                        // extract a strongly connected component
                        if ((vertex >= 0) && (lowLink [vertex] ==
                                dfsIndex [vertex]))
                        {
                                int_t v = 0;
                                do
                                {
                                        v = s_nodes. top ();
                                        s_nodes. pop ();
                                        inTheStack. clear (v);
                                        compVertices [posVertices ++] = v;
                                } while (v != vertex);
                                compEnds [nComponents ++] = posVertices;
                        }

                        // if this is the top level of the recursion
                        // then find another unvisited vertex or return
                        if (s_vertex. empty ())
                        {
                                // find an unvisited vertex in the graph
                                while ((vertexToScan < nVertices) &&
                                        (dfsIndex [vertexToScan] != 0))
                                {
                                        ++ vertexToScan;
                                }

                                // return the result if all visited
                                if (vertexToScan == nVertices)
                                {
                                        inTheStack. free ();
                                        return nComponents;
                                }

                                // set the new vertex
                                vertex = vertexToScan ++;

                                // mark the current vertex as visited
                                // and initialize its low link
                                dfsIndex [vertex] = ++ discoveryTime;
                                lowLink [vertex] = discoveryTime;

                                // push this vertex on the stack
                                s_nodes. push (vertex);
                                inTheStack. set (vertex);

                                // determine the edges to be visited
                                edge = 0;
                                maxedge = g. countEdges (vertex);
                        }

                        // otherwise trace back to the previous level
                        else
                        {
                                // remember the current low link index
                                int_t lowLink2 = lowLink [vertex];

                                // restore the variables
                                vertex = s_vertex. top ();
                                s_vertex. pop ();
                                edge = s_edge. top ();
                                s_edge. pop ();
                                maxedge = s_maxedge. top ();
                                s_maxedge. pop ();

                                // update the current low link index
                                if (lowLink [vertex] > lowLink2)
                                        lowLink [vertex] = lowLink2;
                        }
                }

                // analyse the next edge coming out from the current vertex
                else
                {
                        // determine the next vertex
                        int_t next = g. getEdge (vertex, edge ++);

                        // go to a deeper recursion level if unvisited
                        if (dfsIndex [next] == 0)
                        {
                                // store the variables at the stacks
                                s_vertex. push (vertex);
                                s_edge. push (edge);
                                s_maxedge. push (maxedge);

                                // set the new vertex
                                vertex = next;
                        
                                // mark the new vertex as visited
                                dfsIndex [vertex] = ++ discoveryTime;
                                lowLink [vertex] = discoveryTime;
                        
                                // push this vertex on the stack
                                s_nodes. push (vertex);
                                inTheStack. set (vertex);

                                // determine the edges to be visited
                                edge = 0;
                                maxedge = g. countEdges (vertex);
                        }

                        // update the low link index if the vertex has been
                        // visited and is currently in the stack of nodes
                        else if (inTheStack. test (next))
                        {
                                if (lowLink [vertex] > dfsIndex [next])
                                        lowLink [vertex] = dfsIndex [next];
                        }
                }
        }

        // finalize and return the number of strongly connected components
        inTheStack. free ();
        return nComponents;
} /* SCC_Tarjan */

template<class coordtype >
void chomp::homology::SetSpaceWrapping ( int  dim,
const coordtype *  wrap 
) [inline]

Sets space wrapping in each direction separately.

Parameters:
dim - the dimension of cubes for which the space wrapping is defined
wrap - space wrapping: a nonzero entry indicates a periodic boundary condition in the corresponding direction

Definition at line 2230 of file homology.h.

References chomp::homology::tCubeBase< coordtype >::MaxDim, chomp::homology::tPointBase< coordtype >::setwrapping(), and wrapcoord().

{
        if ((dim < 0) || (dim >= Cube::MaxDim))
                return;

        // set space wrapping if requested to
        coordinate wrapcoord [Cube::MaxDim];
        for (int j = 0; j < dim; ++ j)
                wrapcoord [j] = static_cast <coordtype>
                        ((wrap [j] >= 0) ? wrap [j] : -wrap [j]);
        tPointBase<coordinate>::setwrapping (wrapcoord, dim, dim + 1);
        return;
} /* SetSpaceWrapping */

void chomp::homology::setstreams ( const char *  logfilename,
char *  seqfilename,
bool  quiet,
bool  debug 
) [inline]

Sets the parameters of the output streams depending on the file names acquired from the command line.

This is an internal function used by the macro "algstreamset".

Definition at line 807 of file arg.h.

References program_time, sbug, scon, serr, slog, sout, and sseq.

{
        if (debug)
                sbug. show = true;
        if (quiet)
        {
                sout. show = false;
                scon. show = false;
                sbug. show = false;
        }
        if (logfilename)
        {
                slog. logfile (logfilename);
                slog. keepforever ();
                sout. logfile (slog);
                serr. logfile (slog);
                if (debug)
                        sbug. logfile (slog);
        }
        if (seqfilename)
                sseq. logfile (seqfilename);
#ifdef TIMEUSED
        program_time = sout;
#endif
        return;
} /* setstreams */

template<class euclidom >
std::ostream & chomp::homology::show_homology ( std::ostream &  out,
const chain< euclidom > &  c 
) [inline]

Shows a chain as a list of generators of one level of a homology module.

Definition at line 3329 of file chains.h.

References show_homology().

{
        outputstream tout (out);
        show_homology (tout, c);
        return out;
} /* show_homology */

template<class euclidom >
outputstream & chomp::homology::show_homology ( outputstream &  out,
const chain< euclidom > &  c 
) [inline]

Shows a chain as a list of generators of one level of a homology module.

Definition at line 3290 of file chains.h.

References chomp::homengin::ringsymbol().

Referenced by chomp::homology::chaincomplex< euclidom >::compute_and_show_homology(), show_homology(), and chomp::homology::chaincomplex< euclidom >::show_homology().

{
        int countfree = 0;
        bool writeplus = false;
        for (int i = 0; i < c. size (); ++ i)
        {
                if (c. coef (i). delta () == 1)
                        ++ countfree;
                else
                {
                        out << (writeplus ? " + " : "") <<
                                euclidom::ringsymbol () << "_" <<
                                c. coef (i);
                        writeplus = true;
                }

                if (countfree && ((i == c. size () - 1) ||
                        (c. coef (i + 1). delta () != 1)))
                {
                        out << (writeplus ? " + " : "") <<
                                euclidom::ringsymbol ();
                        if (countfree > 1)
                                out << "^" << countfree;
                        countfree = 0;
                        writeplus = true;
                }
        }

        // if there was nothing to show, then just show zero
        if (!c. size ())
                out << "0";

        return out;
} /* show_homology */

template<class euclidom >
void chomp::homology::ShowGenerator ( const chain< euclidom > &  c  )  [inline]

Shows (that is, writes to 'sout') one generator of the homology module of a chain complex.

The generator is encoded in the given chain. Note: The numbers of generators of the original chain complex are displayed increased by 1 (that is, the first generator is "1", not "0").

Definition at line 209 of file homology.h.

References sout.

Referenced by ShowGenerators().

{
        c. show (sout, "c");
        return;
} /* ShowGenerator */

template<class cell , class euclidom >
void chomp::homology::ShowGenerator ( const chain< euclidom > &  c,
const hashedset< cell > &  s 
)

Shows (that is, writes to 'sout') one generator of the homology module of a geometric complex.

The generator is encoded in the given chain.

Definition at line 273 of file homology.h.

References sout.

{
        if (!c. size ())
                sout << '0';
        for (int i = 0; i < c. size (); ++ i)
        {
                euclidom e = c. coef (i);
                if (e == 1)
                        sout << (i ? " + " : "") << s [c. num (i)];
                else if (-e == 1)
                        sout << (i ? " - " : "-") << s [c. num (i)];
                else
                {
                        sout << (i ? " + " : "") << e << " * " <<
                                s [c. num (i)];
                }
        }
        return;
} /* ShowGenerator */

template<class euclidom >
void chomp::homology::ShowGenerators ( chain< euclidom > const *const *const   gen,
const chain< euclidom > *  hom,
int  maxlevel 
)

Shows (that is, writes to 'sout') all the generators of the entire homology module of a chain complex.

Each level of generators is encoded in one array of chains.

Definition at line 234 of file homology.h.

References ShowGenerators(), and sout.

{
        for (int q = 0; q <= maxlevel; ++ q)
        {
                if (!hom [q]. size ())
                        continue;
                sout << "[H_" << q << "]\n";
                ShowGenerators (gen [q], hom [q]. size ());
                sout << '\n';
        }
        return;
} /* ShowGenerators */

template<class euclidom >
void chomp::homology::ShowGenerators ( const chain< euclidom > *  c,
int  count 
)

Shows (that is, writes to 'sout') all the generators of one level of the homology module of a chain complex.

Each generator is encoded in one chain in the given array.

Definition at line 219 of file homology.h.

References ShowGenerator(), and sout.

Referenced by ShowGenerators().

{
        for (int i = 0; i < count; ++ i)
        {
                sout << 'g' << (i + 1) << " = ";
                ShowGenerator (c [i]);
                sout << '\n';
        }
        return;
} /* ShowGenerators */

template<class cell , class euclidom >
void chomp::homology::ShowGenerators ( const chain< euclidom > *  c,
int  count,
const hashedset< cell > &  s 
)

Shows (that is, writes to 'sout') all the generators of one level of the homology module of a geometric complex.

Each generator is encoded in one chain in the given array.

Definition at line 297 of file homology.h.

References ShowGenerator(), and sout.

{
        for (int i = 0; i < count; ++ i)
        {
                sout << 'g' << (i + 1) << " = ";
                ShowGenerator (c [i], s);
                sout << '\n';
        }
        return;
} /* ShowGenerators */

template<class euclidom , class cell >
void chomp::homology::ShowGenerators ( chain< euclidom > *const *  gen,
const chain< euclidom > *  hom,
int  maxlevel,
const gcomplex< cell, euclidom > &  gcompl 
)

Shows all the generators of the entire homology module of a geometric complex.

Each level of generators is encoded in one array of chains.

Definition at line 312 of file homology.h.

References ShowGenerators(), and sout.

{
        for (int q = 0; q <= maxlevel; ++ q)
        {
                if (!hom [q]. size ())
                        continue;
                sout << "[H_" << q << "]\n";
                ShowGenerators (gen [q], hom [q]. size (), gcompl [q]);
                sout << '\n';
        }
        return;
} /* ShowGenerators */

template<class euclidom >
void chomp::homology::ShowGenerators ( const chaincomplex< euclidom > &  c,
const chain< euclidom > *  hom,
int  maxlevel 
)

Shows (that is, writes to 'sout') all the generators of the entire homology module of a chain complex.

The generators are retrieved from the chain complex itself.

Definition at line 252 of file homology.h.

References ShowGenerator(), and sout.

{
        for (int q = 0; q <= maxlevel; ++ q)
        {
                if (!hom [q]. size ())
                        continue;
                sout << "[H_" << q << "]\n";
                for (int i = 0; i < hom [q]. size (); ++ i)
                {
                        ShowGenerator (c. gethomgen (q, hom [q]. num (i)));
                        sout << '\n';
                }
                sout << '\n';
        }
        return;
} /* ShowGenerators */

template<class euclidom >
void chomp::homology::ShowHomology ( const chainmap< euclidom > &  hmap  )  [inline]

Show (that is, writes to 'sout') the homology map encoded in terms of a chain map.

Definition at line 198 of file homology.h.

References sout.

{
        hmap. show (sout, "\tf", "x", "y");
        return;
} /* ShowHomology */

template<class euclidom >
void chomp::homology::ShowHomology ( const chain< euclidom > &  c  )  [inline]

Shows (that is, writes to 'sout') one level of the homology module encoded in the given chain.

Definition at line 138 of file homology.h.

References chomp::homengin::ringsymbol(), and sout.

Referenced by ComputeBettiNumbers(), and ShowHomology().

{
        int countfree = 0;
        bool writeplus = false;

        // write the homology module exactly in the order it appears in 'c'
        for (int i = 0; i < c. size (); ++ i)
        {
                // if the coefficient is invertible, it will be shown later
                if (c. coef (i). delta () == 1)
                        ++ countfree;
                // otherwise show the corresponding torsion part now
                else
                {
                        sout << (writeplus ? " + " : "") <<
                                euclidom::ringsymbol () << "_" <<
                                c. coef (i);
                        writeplus = true;
                }

                // if there were some free ingredients show them if necessary
                if (countfree && ((i == c. size () - 1) ||
                        (c. coef (i + 1). delta () != 1)))
                {
                        sout << (writeplus ? " + " : "") <<
                                euclidom::ringsymbol ();
                        if (countfree > 1)
                                sout << "^" << countfree;
                        countfree = 0;
                        writeplus = true;
                }
        }

        // if there was nothing to show, then just show zero
        if (!c. size ())
                sout << "0";

        return;
} /* ShowHomology */

template<class euclidom >
void chomp::homology::ShowHomology ( const chain< euclidom > *  hom,
int  maxlevel 
)

Shows (that is, writes to 'sout') the entire homology module encoded in an array of chains.

Definition at line 181 of file homology.h.

References ShowHomology(), and sout.

{
        if (!hom)
                return;

        for (int q = 0; q <= maxlevel; ++ q)
        {
                sout << "H_" << q << " = ";
                ShowHomology (hom [q]);
                sout << '\n';
        }
        return;
} /* ShowHomology */

template<class type >
int chomp::homology::sortelements ( type *  tab,
int  n 
) [inline]

A simple template that sorts an array using the bubble sort method, removes repeated elements and returns the new number of the elements.

Definition at line 316 of file textfile.h.

References swapelements().

Referenced by operator>>().

{
        switch (n)
        {
        case 0:
                return 0;
        case 1:
                return 1;
        case 2:
                if (tab [0] == tab [1])
                        return 1;
                else if (tab [0] > tab [1])
                        swapelements (tab [0], tab [1]);
                return 2;
        default:
                for (int i = 0; i < n - 1; ++ i)
                {
                        for (int j = i + 1; j < n; ++ j)
                                if (tab [i] > tab [j])
                                        swapelements (tab [i],
                                                tab [j]);

                        if (tab [i] == tab [i + 1])
                        {
                                -- n;
                                for (int j = i + 1; j < n; ++ j)
                                        tab [j] = tab [j + 1];
                        }
                }
                break;
        }
        return n;
} /* sortelements */

template<class type >
void chomp::homology::swapelements ( type &  x,
type &  y 
) [inline]

A simple template for swapping two elements with the use of a temporary variable of the same type and the assignment operator.

Definition at line 305 of file textfile.h.

Referenced by sortelements(), chomp::homology::chain< euclidom >::swap(), and chomp::homology::chain< euclidom >::swapnumbers().

{
        type z = x;
        x = y;
        y = z;
        return;
} /* swapelements */

template<class coordtype >
int chomp::homology::thesame ( const coordtype *  c1,
const coordtype *  c2,
int  dim 
) [inline]

Compare two points. Returns true iff they have the same coordinates.

Definition at line 98 of file pointset.h.

Referenced by chomp::homology::tPointset< coordtype >::hashfindpoint().

{
        for (int i = 0; i < dim; ++ i)
                if (c1 [i] != c2 [i])
                        return 0;
        return 1;
} /* thesame */

template<class euclidom >
int chomp::homology::TorsionCoefficient ( const chain< euclidom > &  c,
int  start = 0 
)

Returns the next position in the chain containing a torsion coefficient.

Starts the search at the given position. Returns -1 if not found or the position 'p' of the coefficient. This coefficient can be retrieved as "c. coef (p)".

Definition at line 121 of file homology.h.

{
        if (start < 0)
                return -1;
        while (start < c. size ())
        {
                if (c. coef (start). delta () != 1)
                        return start;
                else
                        ++ start;
        }
        return -1;
} /* TorsionCoefficient */

template<class matrix >
void chomp::homology::transitiveClosure ( matrix &  m,
int_t  n 
) [inline]

Computes the transitive closure of an acyclic graph defined by its adjacency matrix, using the Warshall's algorithm: S.

Warshall, A theorem on Boolean matrices, J. ACM 9 (1962) 11-12.

Definition at line 3870 of file digraph.h.

Referenced by transitiveReduction().

{
        for (int_t k = 0; k < n; ++ k)
        {
                for (int_t i = 0; i < n; ++ i)
                {
                        for (int_t j = 0; j < n; ++ j)
                        {
                                if (m [i] [k] && m [k] [j])
                                        m [i] [j] = 1;
                        }
                }
        }
        return;
} /* transitiveClosure */

template<class wType >
void chomp::homology::transitiveReduction ( const diGraph< wType > &  g,
diGraph< wType > &  gRed 
) [inline]

Computes the transitive reduction of an arbitrary acyclic graph.

The output graph must be initially empty.

Definition at line 3913 of file digraph.h.

References graph2matrix(), matrix2graph(), transitiveClosure(), and transitiveReduction().

{
        int_t nVert = g. countVertices ();
        if (nVert <= 0)
                return;
        flatMatrix<char> m (nVert);
        m. clear (0);
        graph2matrix (g, m);
        transitiveClosure (m, nVert);
        transitiveReduction (m, nVert);
        matrix2graph (m, nVert, gRed);
        return;
} /* transitiveReduction */

template<class matrix >
void chomp::homology::transitiveReduction ( matrix &  m,
int_t  n 
) [inline]

Computes the transitive reduction of a CLOSED acyclic graph defined by its adjacency matrix, using the algorithm by D.

Gries, A.J. Martin, J.L.A. van de Snepscheut and J.T. Udding, An algorithm for transitive reduction of an acyclic graph, Science of Computer Programming 12 (1989), 151-155. WARNING: The input graph MUST BE CLOSED, use the "transitiveClosure" algorithm first if this is not the case.

Definition at line 3894 of file digraph.h.

Referenced by transitiveReduction().

{
        for (int_t k = n - 1; k >= 0; -- k)
        {
                for (int_t i = 0; i < n; ++ i)
                {
                        for (int_t j = 0; j < n; ++ j)
                        {
                                if (m [i] [k] && m [k] [j])
                                        m [i] [j] = 0;
                        }
                }
        }
        return;
} /* transitiveReduction */

template<class coordtype >
void chomp::homology::wrapcoord ( coordtype *  destination,
const coordtype *  source,
const coordtype *  wrap,
int  dim 
) [inline]

Wraps coordinates stored in 'c' accordint to the wrap table 'wrap' and store the result in the table called 'result'.

Definition at line 119 of file pointset.h.

Referenced by chomp::homology::tPointset< coordtype >::add(), chomp::homology::tNeighbors< coordtype >::get(), chomp::homology::tPointset< coordtype >::hashfindpoint(), and SetSpaceWrapping().

{
        if (!destination || !source)
                throw "Trying to wrap NULL coordinates.";

        for (int i = 0; i < dim; ++ i)
                if (wrap [i])
                {
                        destination [i] =
                                (coordtype) (source [i] % wrap [i]);
                        if (destination [i] < 0)
                                destination [i] += wrap [i];
                }
                else
                        destination [i] = source [i];

        return;
} /* wrapcoord */

template<class coordtype >
int chomp::homology::write ( std::ostream &  out,
const coordtype *  c,
int  dim,
char  parenthesis = 40,
char  closing = 0 
)

Definition at line 2103 of file pointset.h.

References closingparenthesis().

Referenced by chomp::multiwork::operator<<(), operator<<(), and write().

{
        // write the opening parenthesis, brace or bracket
        if (parenthesis != 0)
                out << parenthesis;

        // output the point's coordinates
        for (int i = 0; i < dim; ++ i)
        {
                if (i)
                        out << ",";
                out << c [i];
        }

        // write an appropriate closing parenthesis, brace or bracket
        if (closing)
                out << closing;
        else if (parenthesis)
        {
                int ch = closingparenthesis (parenthesis);
                if (ch == EOF)
                        closing = parenthesis;
                else
                        closing = (char) ch;
                out << closing;
        }

        return dim;
} /* write */

template<class coordtype >
int_t chomp::homology::write ( std::ostream &  out,
tPointset< coordtype > &  p,
int_t  first = 0,
int_t  howmany = -1,
int  quiet = 0 
)

Writes a set of points to a file (starting at the point given).

Returns the number of points written or -1 (and show a message) in case of failure.

Definition at line 2362 of file pointset.h.

References write().

{
        int_t count = 0;
        int dim = p. dimension ();

        // write the number of points in the set
        out << "; The set contains " << p. size () << " points.\n";
        if (first)
                out << "; Not writing first " << first << " points.\n";
        if (howmany >= 0)
                out << "; Writing at most " << howmany << " points.\n";

        // write the size of the grid
        if (dim && p. gridsize ())
        {
                for (int i = 0; i < dim; ++ i)
                        out << (i ? ", " : "; Grid size: ") <<
                                p. gridsize () [i];
                out << '\n';
        }

        // write statistical information if it has been gathered
        if (p. gethashsize ())
                out << "; Hashing table size: " <<
                        p. gethashsize () << " entries.\n";

        if (p. stat -> hashhits)
                out << "; Hashing statistics: " <<
                        ((p. stat -> hashhits + p. stat -> hashmisses) /
                        p. stat -> hashhits) << '.' <<
                        ((p. stat -> hashhits + p. stat -> hashmisses) * 10 /
                        p. stat -> hashhits) % 10 << " trials per point, " <<
                        p. stat -> rehashcount << " times rehashed.\n";

        if (p. minimal && p. maximal)
        {
                out << "; The coordinates " <<
                        (p. wereremoved ? "varied" : "vary") << " from ";
                write (out, p. minimal, dim);
                out << " to ";
                write (out, p. maximal, dim);
                out << ".\n";
        }

        std::time_t tm;
        std::time (&tm);
        out << "; Work time: " << (tm - p. stat -> creationtime) <<
                " seconds.\n";

        // add a warning if any points were removed
        if (p. wereremoved)
                out << "; Warning: Points were removed, " <<
                        "so their original order may be distorted.\n";

        // write out the dimension of the points (for compatibility
        // with the older versions of 'pointset')
        out << "dimension " << p. dimension () << '\n';

        // output all the points
        int_t size = p. size ();
        for (int_t i = first; i < size; ++ i)
        {
                if ((howmany >= 0) && (count >= howmany))
                        return count;
                write (out, p [i], dim);
                out << '\n';
                ++ count;
        }

        return count;
} /* write */

template<class stream , class element >
stream& chomp::homology::write ( stream &  out,
const hashedset< element > &  s,
bool  size 
)

Writes the entire hashed set to an output stream in the text mode.

The operator << is used to write each element of the set. The parameter 'size' should be set either to SMALL_SIZE or LARGE_SIZE.

Definition at line 768 of file hashsets.h.

References SMALL_SIZE.

{
        if (size == SMALL_SIZE)
        {
                out << '{';
                int_t n = s. size ();
                for (int_t i = 0; i < n; ++ i)
                        out << (i ? " " : "") << s [i];
                out << '}';
        }
        else
        {
                int_t n = s. size ();
                if (!s. empty ())
                {
                        out << "; " << n << ((n == 1) ? " element." :
                                " elements.") << '\n';
                }
                if (s. stat && s. stat -> hashhits)
                        out << ';' << *(s. stat) << '\n';
                for (int_t i = 0; i < n; ++ i)
                        out << s [i] << '\n';
        }
        return out;
} /* write */

int chomp::homology::writebitpoints ( std::ostream &  out,
pointset &  p,
bool  sorted = true,
int  fixed_depth = 0,
coordinate *  fixed_corner = NULL 
)

Writes a full cubical set represented by a set of points to a file in the "bitcode" format.

If 'sorted', bit codes are sorted as the software by Bill Kalies needs. Otherwise they are saved in the same order as the points in 'p'. The depth of bit fields is determined automatically to the minimal necessary value unless 'fixed_depth' is positive. As the lower left corner, the minimal coordinates of the points are selected unless 'fixed_corner' is NULL. Returns 0 on success and -1 on error (and displays a message).

template<class cell , class euclidom >
std::ostream& chomp::homology::writechaincomplex ( std::ostream &  out,
const gcomplex< cell, euclidom > &  g,
bool  symbolicnames = false,
bool  quiet = false 
)

Writes out a chain complex of the geometric cell complex.

Boundary formulas are restricted to cells which are in the geom. complex. If symbolic names requested, the cells are written directly as generators. This procedure is a slightly modified version of "createchaincomplex".

Definition at line 1181 of file gcomplex.h.

References boundarycell(), boundarycoef(), boundarylength(), and scon.

{
        if (g. dim () < 0)
                return out;
        out << "chaincomplex\n\n";
        out << "maxdimension " << g. dim () << "\n\n";
        out << "dimension 0: " << g [0]. size () << "\n\n";
        for (int d = 1; d <= g. dim (); ++ d)
        {
                out << "dimension " << d << ": " << g [d]. size () << "\n";
                for (int_t i = 0; i < g [d]. size (); ++ i)
                {
                        bool cellwritten = false;
                        int len = boundarylength (g [d] [i]);
                        for (int j = 0; j < len; ++ j)
                        {
                                // take the j-th boundary cell
                                cell thecell = boundarycell (g [d] [i], j);

                                // add it to the chain complex
                                if (g. check (thecell))
                                {
                                        int icoef = boundarycoef
                                                (g [d] [i], j);
                                        euclidom coef;
                                        if (icoef < 0)
                                        {
                                                coef = -icoef;
                                                coef = -coef;
                                        }
                                        else
                                                coef = icoef;
                                        if (!cellwritten)
                                        {
                                                out << "\t# ";
                                                if (symbolicnames)
                                                        out << g [d] [i];
                                                else
                                                        out << (i + 1);
                                                out << " = ";
                                                if (-coef == 1)
                                                        out << "- ";
                                        }
                                        else if (coef == 1)
                                                out << " + ";
                                        else if (-coef == 1)
                                                out << " - ";
                                        else
                                                out << " + " << coef <<
                                                        " * ";
                                        if (symbolicnames)
                                                out << thecell;
                                        else
                                                out << (1 + g [d - 1].
                                                        getnumber (thecell));
                                        cellwritten = true;
                                }
                        }
                        if (cellwritten)
                                out << '\n';
                }
                if (!quiet)
                {
                        if (d < g. dim ())
                                scon << '.';
                        else
                                scon << ". ";
                }
                out << '\n';
        }
        return out;
} /* writechaincomplex */

template<class cubetype >
std::ostream& chomp::homology::WriteCube ( std::ostream &  out,
const cubetype &  c 
) [inline]

Writes a cube to the output stream in the text mode.

Definition at line 70 of file cubemain.h.

Referenced by operator<<().

{
        typename cubetype::CoordType coord [cubetype::MaxDim];
        c. coord (coord);
        int dim = c. dim ();
        out << "(";
        for (int i = 0; i < dim; ++ i)
        {
                if (i)
                        out << ",";
                out << coord [i];
        }
        out << ")";
        return out;
} /* WriteCube */

template<class celltype >
std::ostream& chomp::homology::WriteCubicalCell ( std::ostream &  out,
const celltype &  c 
) [inline]

Writes a cubical cell to the output stream in the text form.

The actual format depends on which OutputBits are set.

Definition at line 174 of file cellmain.h.

Referenced by operator<<().

{
        // determine the data to be written
        typedef typename celltype::CoordType coordtype;
        coordtype lcoord [celltype::MaxDim];
        c. leftcoord (lcoord);
        int dim = c. spacedim ();
        coordtype rcoord [celltype::MaxDim];
        c. rightcoord (rcoord);

        if (celltype::OutputBits & celltype::BitProduct)
        {
                for (int i = 0; i < dim; ++ i)
                {
                        out << '(';
                        out << lcoord [i];
                        if (rcoord [i] != lcoord [i])
                                out << ',' << rcoord [i];
                        out << ')';
                        if (i < dim - 1)
                                out << 'x';
                }
        }
        else
        {
                out << '[' << '(';
                int i;
                for (i = 0; i < dim; ++ i)
                {
                        out << lcoord [i];
                        if (i < dim - 1)
                                out << ',';
                }
                out << ')';
                if (celltype::OutputBits & celltype::BitSpace)
                        out << ' ';
                out << '(';
                for (i = 0; i < dim; ++ i)
                {
                        out << rcoord [i];
                        if (i < dim - 1)
                                out << ',';
                }
                out << ')' << ']';
        }
        return out;
} /* operator << */

template<class cell , class euclidom >
std::ostream& chomp::homology::writegenerators ( std::ostream &  out,
const chain< euclidom > *  hom,
const chaincomplex< euclidom > &  c,
const gcomplex< cell, euclidom > &  g,
const int *  level = NULL 
)

Writes the homology generators of the geometric complex to a file.

Definition at line 1391 of file gcomplex.h.

{
        bool firstlist = true;
        for (int d = 0; d <= c. dim (); ++ d)
        {
                if ((!level || level [d]) && !hom [d]. empty ())
                {
                        if (firstlist)
                                firstlist = false;
                        else
                                out << '\n';
                        if (hom [d]. size () == 1)
                                out << "The generator of H_" << d <<
                                        " follows:" << '\n';
                        else
                                out << "The " << hom [d]. size () <<
                                        " generators of H_" << d <<
                                        " follow:" << '\n';
                        const hashedset<cell> &cset = g [d];
                        for (int_t i = 0; i < hom [d]. size (); ++ i)
                        {
                                if (hom [d]. size () > 1)
                                        out << "generator " << (i + 1) <<
                                                '\n';
                                const chain<euclidom> &lst =
                                        c. gethomgen (d, hom [d]. num (i));
                                for (int_t j = 0; j < lst. size (); ++ j)
                                        out << lst. coef (j) << " * " <<
                                                cset [lst. num (j)] << '\n';
                        }
                }
        }
        return out;
} /* writegenerators */

template<class euclidom , class tCell >
std::ostream& chomp::homology::writegenerators ( std::ostream &  out,
const chain< euclidom > *  hom,
const chaincomplex< euclidom > &  c,
const gcomplex< tCell, euclidom > &  g,
const int *  level,
int  xdim,
int  format = 0 
)

Writes projected homology generators of a cubical complex to a file.

Format: 0 = text format, 1 = chl format.

Definition at line 65 of file cubmaps.h.

{
        typedef typename tCell::CoordType coordType;
        bool firstlist = true;
        for (int d = 0; d <= c. dim (); ++ d)
        {
                if ((level && !level [d]) || hom [d]. empty ())
                        continue;
                if (firstlist)
                        firstlist = false;
                else if (format == 0)
                        out << '\n';
                if (format == 0)
                {
                        if (hom [d]. size () == 1)
                        {
                                out << "The generator of H_" << d <<
                                        " follows:" << '\n';
                        }
                        else
                        {
                                out << "The " << hom [d]. size () <<
                                        " generators of H_" << d <<
                                        " follow:" << '\n';
                        }
                }
                const hashedset<tCell> &cset = g [d];
                for (int_t i = 0; i < hom [d]. size (); ++ i)
                {
                        if (format == 0)
                        {
                                if (hom [d]. size () > 1)
                                        out << "generator " <<
                                                (i + 1) << '\n';
                        }
                        const chain<euclidom> &lst =
                                c. gethomgen (d, hom [d]. num (i));
                        for (int_t j = 0; j < lst. size (); ++ j)
                        {
                                coordType left [tCell::MaxDim];
                                cset [lst. num (j)]. leftcoord (left);
                                coordType right [tCell::MaxDim];
                                cset [lst. num (j)]. rightcoord (right);
                                int projdim = 0;
                                for (int k = 0; k < xdim; ++ k)
                                {
                                        if (left [k] != right [k])
                                                ++ projdim;
                                }
                                if (projdim != d)
                                        continue;
                                if (format == 0)
                                {
                                        out << lst. coef (j) << " * " <<
                                                tCell (left, right, xdim) <<
                                                '\n';
                                }
                                else
                                {
                                        for (int k = 0; k < xdim; ++ k)
                                                out << left [k] << " ";
                                        for (int k = 0; k < xdim; ++ k)
                                                out << right [k] << " ";
                                        out << lst. coef (j) << " " <<
                                                (i + 1) << " " << d << '\n';
                                }
                        }
                }
        }
        return out;
} /* writegenerators */


Variable Documentation

Referenced by bitcountbyte().

const int chomp::homology::DimBits = (sizeof (int_t) > 4) ? 7 : 6

The number of signed bits to store the dimension (i.e., 6: max 31).

The maximal allowed dimension in the program is less than what follows from the number of bits (i.e., max 30 for 6 bits).

Definition at line 68 of file pointbas.h.

The global table of BitFields which store the acyclicity information for reducing full cubical sets.

Referenced by acyclic(), Homology(), and Homology2l().

The maximal dimension that can be used if the high bits of an integer store the value of the dimension, and the number of remaining bits is at least as large as the dimension.

Definition at line 90 of file pointbas.h.

Referenced by chomp::homology::tPointBase< coordtype >::number(), and chomp::homology::tPointBase< coordtype >::setwrapping().

const int chomp::homology::MaxBasDim1 = static_cast<int> (1u << (DimBits - 1))

The maximal dimension that can be represented using 'DimBits' bits.

Definition at line 81 of file pointbas.h.

const int chomp::homology::MaxBasDim2 = static_cast<int> ((sizeof (int_t) << 3) - DimBits)

The maximal dimension which still leaves enough bits in the integer to have one bit for each direction.

Definition at line 85 of file pointbas.h.

The maximal dimension for which binary decision diagrams are used.

This can be decreased by a program if no binary decision diagrams should be used. However, the value of MaxBddDim cannot exceed the value of MaxBddDimPossible.

Referenced by acyclic(), acyclic_rel(), addcubeneighbors(), and Homology2l().

The maximal dimension for which binary decision diagrams are programmed.

Definition at line 1178 of file cubacycl.h.

const int chomp::homology::NumBits = (sizeof (int_t) << 3) - DimBits
const int_t chomp::homology::NumMask = (~(static_cast<int_t> (0) ^ SignBit)) >> (DimBits - 1)

The external variable which measures the time used by the program from its start.

Note that in the destructor of this variable, a message is displayed to std::cout indicating how much time was used by the program in its entire run.

Referenced by chomp::multiwork::mwSubdivMain(), and setstreams().

A wrapper for the standard error stream.

Referenced by setstreams().

const int_t chomp::homology::SignBit = static_cast<int_t> (1) << ((sizeof (int_t) << 3) - 1)

The sign bit of the int_t number.

Definition at line 75 of file pointbas.h.

The output stream to which one can send messages for logging only.

Those messages are not shown to the standard output and are ignored if the log file is not in use.

Referenced by setstreams().

An auxiliary stream which captures sequences of processed data.

This stream is used by some programs in the CHomP package.

Referenced by chomp::homology::gcomplex< cell, euclidom >::collapse(), cubexpand(), cubreducequiet(), restrictAtoneighbors(), and setstreams().

The global instance of this class which stores tabulated configurations to use in the full cube reduction procedures.

Referenced by acyclic().

The variable which controls which binary decision diagrams should be used in dimension 3, either programmed by P.

Pilarczyk (if set to false) or received from G. Malandain (if set to true).

Referenced by bddacyclic().