28 #ifndef _CHAINCON_CUBCELL_H_ 29 #define _CHAINCON_CUBCELL_H_ 37 #include "chomp/system/config.h" 38 #include "chomp/struct/hashsets.h" 39 #include "chomp/cubes/pointbas.h" 40 #include "chomp/system/textfile.h" 62 template <
class CoordT,
class WrapT,
class EmptyT>
79 template <
class CoordArray>
80 tCubCell (
int dimension,
const CoordArray &coordinates);
83 template <
class CoordArray>
85 const CoordArray &
right);
112 const CoordT
left (
int n)
const;
115 const CoordT
right (
int n)
const;
155 template <
class CoordT,
class WrapT,
class EmptyT>
161 template <
class CoordT,
class WrapT,
class EmptyT>
162 template <
class CoordArray>
164 const CoordArray &coordinates):
n1 (0),
n2 (0)
172 if (dimension >= chomp::homology::MaxBasDim)
173 throw "Too high cubical cell dimension requested.";
176 CoordT c [chomp::homology::MaxBasDim];
177 for (
int i = 0; i < dimension; ++ i)
178 c [i] = coordinates [i];
179 WrapT::wrap (c, dimension);
180 n1 = chomp::homology::tPointBase<CoordT>::number (c, dimension);
181 n1 |= dimension << chomp::homology::NumBits;
184 for (
int i = 0; i < dimension; ++ i)
186 WrapT::wrap (c, dimension);
187 n2 = chomp::homology::tPointBase<CoordT>::number (c, dimension);
188 n2 |= dimension << chomp::homology::NumBits;
193 template <
class CoordT,
class WrapT,
class EmptyT>
194 template <
class CoordArray>
196 const CoordArray &
left,
const CoordArray &
right):
n1 (0),
n2 (0)
204 if (dimension >= chomp::homology::MaxBasDim)
205 throw "Too high cubical cell dimension requested.";
208 int cellDimension = 0;
209 for (
int i = 0; i < dimension; ++ i)
211 if (left [i] != right [i])
216 CoordT c [chomp::homology::MaxBasDim];
217 for (
int i = 0; i < dimension; ++ i)
219 WrapT::wrap (c, dimension);
220 n1 = chomp::homology::tPointBase<CoordT>::number (c, dimension);
221 n1 |= dimension << chomp::homology::NumBits;
224 for (
int i = 0; i < dimension; ++ i)
226 WrapT::wrap (c, dimension);
227 n2 = chomp::homology::tPointBase<CoordT>::number (c, dimension);
228 n2 |= cellDimension << chomp::homology::NumBits;
233 template <
class CoordT,
class WrapT,
class EmptyT>
241 template <
class CoordT,
class WrapT,
class EmptyT>
245 using chomp::homology::sbug;
248 int cellDimension = c.
dim ();
259 int spaceDimension = c.
spaceDim ();
262 CoordT newLeft [chomp::homology::MaxBasDim];
263 CoordT newRight [chomp::homology::MaxBasDim];
264 for (
int i = 0; i < spaceDimension; ++ i)
266 newLeft [i] = c.
left (i);
267 newRight [i] = c.
right (i);
271 bool squeezeRight = (n < cellDimension);
272 int nn ((n >= cellDimension) ? (n - cellDimension) : n);
274 bool squeezed =
false;
275 for (
int i = 0; i < spaceDimension; ++ i)
277 if (newLeft [i] != newRight [i])
282 newLeft [i] = newRight [i];
284 newRight [i] = newLeft [i];
293 sbug <<
"DEBUG: c = " << c <<
".\n";
294 sbug <<
"DEBUG: cellDimension = " << cellDimension <<
".\n";
295 sbug <<
"DEBUG: spaceDimension = " << spaceDimension <<
".\n";
296 sbug <<
"DEBUG: squeezeRight = " <<
297 (squeezeRight ?
"true" :
"false") <<
".\n";
298 sbug <<
"DEBUG: n = " << n <<
".\n";
299 sbug <<
"DEBUG: nn = " << nn <<
".\n";
300 throw "Wrong boundary element requested.";
302 n1 = chomp::homology::tPointBase<CoordT>::number
303 (newLeft, spaceDimension);
304 n1 |= spaceDimension << chomp::homology::NumBits;
305 n2 = chomp::homology::tPointBase<CoordT>::number
306 (newRight, spaceDimension);
307 n2 |= (cellDimension - 1) << chomp::homology::NumBits;
314 template <
class CoordT,
class WrapT,
class EmptyT>
318 int cellDimension = c.
dim ();
319 if (cellDimension != 2)
320 throw "AW diagonal supported for cubes only in dim 2.";
321 CoordT newLeft [chomp::homology::MaxBasDim];
322 CoordT newRight [chomp::homology::MaxBasDim];
323 int spaceDimension = c.
spaceDim ();
326 for (
int i = 0; i < spaceDimension; ++ i)
328 newLeft [i] = c.
left (i);
329 newRight [i] = c.
right (i);
330 if (newLeft [i] != newRight [i])
331 indices [index ++] = i;
334 if (diagVersion == 1)
342 newRight [indices [0]] = newLeft [indices [0]];
343 newLeft [indices [1]] = newRight [indices [1]];
349 newLeft [indices [0]] = newRight [indices [0]];
352 newLeft [indices [1]] = newRight [indices [1]];
355 newRight [indices [0]] = newLeft [indices [0]];
366 newRight [indices [0]] = newLeft [indices [0]];
367 newRight [indices [1]] = newLeft [indices [1]];
370 newLeft [indices [1]] = newRight [indices [1]];
373 newRight [indices [0]] = newLeft [indices [0]];
380 else if (diagVersion == 2)
388 newRight [indices [1]] = newLeft [indices [1]];
391 newLeft [indices [0]] = newRight [indices [0]];
394 newRight [indices [0]] = newLeft [indices [0]];
404 newLeft [indices [0]] = newRight [indices [0]];
407 newLeft [indices [1]] = newRight [indices [1]];
414 else if (diagVersion == 3)
423 newRight [indices [1]] = newLeft [indices [1]];
426 newLeft [indices [0]] = newRight [indices [0]];
435 newLeft [indices [0]] = newRight [indices [0]];
439 newLeft [indices [1]] = newRight [indices [1]];
447 throw "Undefined version of A-W diagonal requested.\n";
449 int newDimension = 0;
450 for (
int i = 0; i < spaceDimension; ++ i)
452 if (newLeft [i] != newRight [i])
455 n1 = chomp::homology::tPointBase<CoordT>::number
456 (newLeft, spaceDimension);
457 n1 |= spaceDimension << chomp::homology::NumBits;
458 n2 = chomp::homology::tPointBase<CoordT>::number
459 (newRight, spaceDimension);
460 n2 |= newDimension << chomp::homology::NumBits;
464 template <
class CoordT,
class WrapT,
class EmptyT>
474 template <
class CoordT,
class WrapT,
class EmptyT>
480 template <
class CoordT,
class WrapT,
class EmptyT>
483 return (
n1 >> chomp::homology::NumBits);
486 template <
class CoordT,
class WrapT,
class EmptyT>
489 if ((
n1 == 0) && (
n2 == 0))
491 return (
n2 >> chomp::homology::NumBits);
494 template <
class CoordT,
class WrapT,
class EmptyT>
497 return chomp::homology::tPointBase<CoordT>::coord
498 (
n1 & chomp::homology::NumMask,
spaceDim ()) [n];
501 template <
class CoordT,
class WrapT,
class EmptyT>
504 return chomp::homology::tPointBase<CoordT>::coord
505 (
n2 & chomp::homology::NumMask,
spaceDim ()) [n];
508 template <
class CoordT,
class WrapT,
class EmptyT>
511 int dimension =
dim ();
512 if (EmptyT::exists ())
513 return (dimension > 0) ? (dimension << 1) : (dimension + 1);
515 return dimension << 1;
518 template <
class CoordT,
class WrapT,
class EmptyT>
523 int dimension =
dim ();
526 return (n & 1) ? -1 : 1;
529 template <
class CoordT,
class WrapT,
class EmptyT>
533 throw "A-W diagonal supported only in dim 2.";
537 template <
class CoordT,
class WrapT,
class EmptyT>
540 return ((
n1 ^ 0x55555555u) << 21) ^ ((
n1 ^ 0xAAAAAAAAu) << 9) ^
541 ((
n2 ^ 0xAAAAAAAAu) >> 1);
544 template <
class CoordT,
class WrapT,
class EmptyT>
547 return ((
n2 ^ 0xAAAAAAAAu) << 22) ^ ((
n2 ^ 0x55555555u) << 10) ^
551 template <
class CoordT,
class WrapT,
class EmptyT>
552 inline bool tCubCell<CoordT,WrapT,EmptyT>::operator ==
555 return (
n1 == s.
n1) && (
n2 == s.
n2);
558 template <
class CoordT,
class WrapT,
class EmptyT>
562 std::swap (
n1, s.
n1);
563 std::swap (
n2, s.
n2);
572 template <
class CoordT,
class WrapT,
class EmptyT>
608 template <
class CoordT,
class WrapT,
class EmptyT>
645 template <
class CoordT,
class WrapT,
class EmptyT>
651 for (
int i = 0; i <
dim; ++ i)
671 template <
class CoordT,
class WrapT,
class EmptyT>
675 using chomp::homology::ignorecomments;
681 if ((in. peek () !=
'[') && (in. peek () !=
'('))
689 if ((in. peek () ==
']') || (in. peek () ==
')'))
692 const CoordT *null = 0;
702 CoordT coordinates [chomp::homology::MaxBasDim];
706 CoordT &coordinate = coordinates [
spaceDim];
713 if (in. peek () ==
',')
720 if (in. peek () ==
')')
730 CoordT leftArray [chomp::homology::MaxBasDim];
731 CoordT rightArray [chomp::homology::MaxBasDim];
742 if (in. peek () ==
']')
744 else if (in. get () ==
',')
750 throw "Can't read a cubical cell.";
754 if (in. peek () !=
'x')
758 if (in. get () !=
'[')
759 throw "An interval expected for a cubical cell.";
760 if (spaceDim >= chomp::homology::MaxBasDim)
761 throw "Too high dimension of a cubical cell.";
771 #endif // _CHAINCON_CUBCELL_H_ WrapT WrapType
The type of the coord wrapping class.
std::ostream & operator<<(std::ostream &out, const tCubCell< CoordT, WrapT, EmptyT > &c)
Writes an elementary cube in the text mode to an output stream as the cartesian product of elementary...
int boundaryCoef(int n) const
Returns the n-th coefficient in the boundary of the cube.
int_t n1
The number that defines the left corner of the elementary cube.
bool operator==(const tCubCell< CoordT, WrapT, EmptyT > &s) const
Returns true if and only if the cubes are the same.
int dim() const
Returns the dimension of the elementary cube.
int boundaryLength() const
Returns the length of the boundary of the elementary cube.
tCubCell()
The default constructor of an empty cube.
int spaceDim() const
Returns the dimension of the embedding space.
const CoordT left(int n) const
Returns the n-th left coordinate of the elementary cube.
int_t hashkey2() const
Return shashing key no. 2, based on the internal data.
void swap(tCubCell< CoordT, WrapT, EmptyT > &s)
Swaps the data between two cubical cells.
int_t n2
The number that defines the right corner of the elementary cube.
static int diagVersion
The version of the AW diagonal. For testing only.
const CoordT right(int n) const
Returns the n-th right coordinate of the elementary cube.
EmptyT EmptyType
The type of the empty cell existence decision class.
int diagonalLength() const
Returns the number of terms in the Alexander-Whitneney diagonal.
An elementary cubical cell with vertex coordinates of integer type.
~tCubCell()
The destructor.
std::istream & operator>>(std::istream &in, tCubCell< CoordT, WrapT, EmptyT > &c)
Reads an elementary cube from the input stream in the text format.
CoordT CoordType
The type of coordinates.
int_t hashkey1() const
Returns hashing key no. 1, based on the internal data.