The ChainCon Software (Release 0.03)
prodcell.h
Go to the documentation of this file.
1 /////////////////////////////////////////////////////////////////////////////
2 ///
3 /// \file
4 ///
5 /// A Cartesian product of simplicial cells of arbitrary type.
6 ///
7 /////////////////////////////////////////////////////////////////////////////
8 
9 // Copyright (C) 2009-2016 by Pawel Pilarczyk.
10 //
11 // This file is part of my research software package. This is free software:
12 // you can redistribute it and/or modify it under the terms of the GNU
13 // General Public License as published by the Free Software Foundation,
14 // either version 3 of the License, or (at your option) any later version.
15 //
16 // This software is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this software; see the file "license.txt". If not,
23 // please, see <http://www.gnu.org/licenses/>.
24 
25 // Started on March 24, 2009. Last revision: August 20, 2013.
26 
27 
28 #ifndef _CHAINCON_PRODCELL_H_
29 #define _CHAINCON_PRODCELL_H_
30 
31 
32 // include some standard C++ header files
33 #include <istream>
34 #include <ostream>
35 #include <algorithm>
36 #include <vector>
37 
38 // include selected header files from the CHomP library
39 #include "chomp/system/config.h"
40 
41 
42 // --------------------------------------------------
43 // ------------------ product cell ------------------
44 // --------------------------------------------------
45 
46 /// A Cartesian product of simplicial cells as a simplicial cell.
47 template <class CellT>
48 class tProdCell
49 {
50 public:
51  /// The type of the cells whose product is stored here.
52  typedef CellT CellType;
53 
54  /// The type of the empty cell existence decision class.
55  typedef typename CellT::EmptyType EmptyType;
56 
57  /// The default constructor of an undefined product cell.
58  tProdCell ();
59 
60  /// The constructor of a product cell from a simplicial cell.
61  tProdCell (const CellT &c);
62 
63  /// The constructor of a product of two product cells.
64  tProdCell (const tProdCell<CellT> &s1, const tProdCell<CellT> &s2);
65 
66  /// The copy constructor.
67  tProdCell (const tProdCell<CellT> &s);
68 
69  /// The constructor of the n-th face of a cell (if n >= 0)
70  /// or the k-th degeneracy operator (if n = -1 - k < 0).
71  tProdCell (const tProdCell<CellT> &s, int n);
72 
73  /// The assignment operator.
75 
76  /// The destructor.
77  ~tProdCell ();
78 
79  /// Checks if the two cells are equal.
80  bool operator == (const tProdCell<CellT> &s) const;
81 
82  /// Swaps the data between two cells.
83  void swap (tProdCell<CellT> &s);
84 
85  /// Returns the dimension of the cell.
86  int dim () const;
87 
88  /// Checks if the product cell is degenerate, that is,
89  /// if its (i-1)st face equals ith face.
90  /// Returns the first such number i > 0 if this is the case.
91  /// Returns 0 if the cell is not degenerate.
92  /// Note that this verification may be a bit time-consuming,
93  /// because it involves creation of all these faces.
94  int degenerate () const;
95 
96  /// Checks if the cell is defined.
97  bool defined () const;
98 
99  /// Checks if the cell is really a product of two other cells.
100  /// Returns true if yes, or false otherwise.
101  bool product () const;
102 
103  /// Returns the left-hand side part of the product.
104  const tProdCell &getLeft () const;
105 
106  /// Returns the right-hand side part of the product.
107  const tProdCell &getRight () const;
108 
109  /// Returns the actual cell in case this is not a product.
110  const CellT &getCell () const;
111 
112  /// Returns the length of the boundary of the simplicial product,
113  /// which equals the dimension of the cell + 1.
114  int boundaryLength () const;
115 
116  /// Returns the n-th coefficient in the boundary
117  /// of the simplicial product, which is (-1)^n.
118  int boundaryCoef (int n) const;
119 
120 private:
121  /// The dimension of the cell.
123 
124  /// A pointer to the left-hand side part of the product.
126 
127  /// A pointer to the right-hand side part of the product.
129 
130  /// A pointer to the actual cell if this is not a product.
131  CellT *cell;
132 
133 }; /* class tProdCell */
134 
135 // --------------------------------------------------
136 
137 template <class CellT>
139  dimension (-1), left (0), right (0), cell (0)
140 {
141  return;
142 } /* tProdCell::tProdCell */
143 
144 template <class CellT>
145 inline tProdCell<CellT>::tProdCell (const CellT &c):
146  dimension (c. dim ()), left (0), right (0), cell (new CellT (c))
147 {
148  return;
149 } /* tProdCell::tProdCell */
150 
151 template <class CellT>
153  const tProdCell<CellT> &s2): dimension (s1. dimension),
154  left (new tProdCell<CellT> (s1)), right (new tProdCell<CellT> (s2)),
155  cell (0)
156 {
157  if (dimension != s2. dimension)
158  {
159  throw "Constructing a simplicial product of cells "
160  "of different dim.";
161  }
162  return;
163 } /* tProdCell::tProdCell */
164 
165 template <class CellT>
167  dimension (s. dimension),
168  left (s. left ? new tProdCell<CellT> (*s. left) : 0),
169  right (s. right ? new tProdCell<CellT> (*s. right) : 0),
170  cell (s. cell ? new CellT (*s. cell) : 0)
171 {
172  return;
173 } /* tProdCell::tProdCell */
174 
175 template <class CellT>
177  dimension (-1),
178  left (s. left ? new tProdCell<CellT> (*s. left, n) : 0),
179  right (s. right ? new tProdCell<CellT> (*s. right, n) : 0),
180  cell (s. cell ? new CellT (*s. cell, n) : 0)
181 {
182  if (left)
183  dimension = left -> dim ();
184  else if (cell)
185  dimension = cell -> dim ();
186  return;
187 } /* tProdCell::tProdCell */
188 
189 template <class CellT>
191  (const tProdCell<CellT> &s)
192 {
193  // if this is a statement like "x = x" then do nothing
194  if (this == &s)
195  return *this;
196 
197  // release the pointed-to cells
198  if (left)
199  {
200  delete left;
201  left = 0;
202  }
203  if (right)
204  {
205  delete right;
206  right = 0;
207  }
208  if (cell)
209  {
210  delete cell;
211  cell = 0;
212  }
213 
214  // create new cells, copies of the other cells
215  dimension = s. dimension;
216  left = s. left ? new tProdCell<CellT> (*s. left) : 0;
217  right = s. right ? new tProdCell<CellT> (*s. right) : 0;
218  cell = s. cell ? new CellT (*s. cell) : 0;
219 
220  return *this;
221 } /* tProdCell::operator = */
222 
223 template <class CellT>
225 {
226  if (left)
227  delete left;
228  if (right)
229  delete right;
230  if (cell)
231  delete cell;
232  return;
233 } /* tProdCell::~tProdCell */
234 
235 template <class CellT>
236 inline bool tProdCell<CellT>::operator ==
237  (const tProdCell<CellT> &s) const
238 {
239  if (dimension != s. dimension)
240  return false;
241  if ((left && !s. left) || (!left && s. left))
242  return false;
243  if (left && !(*left == *s. left))
244  return false;
245  if ((right && !s. right) || (!right && s. right))
246  return false;
247  if (right && !(*right == *s. right))
248  return false;
249  if ((cell && !s. cell) || (!cell && s. cell))
250  return false;
251  if (cell && !(*cell == *s. cell))
252  return false;
253  return true;
254 } /* tProdCell::operator == */
255 
256 template <class CellT>
258 {
259  std::swap (dimension, s. dimension);
260  std::swap (left, s. left);
261  std::swap (right, s. right);
262  std::swap (cell, s. cell);
263  return;
264 } /* tProdCell::swap */
265 
266 template <class CellT>
267 inline int tProdCell<CellT>::dim () const
268 {
269  return dimension;
270 } /* tProdCell::dim */
271 
272 template <class CellT>
273 inline int tProdCell<CellT>::degenerate () const
274 {
275  if (dimension < 1)
276  return 0;
277  tProdCell<CellT> bd1 (*this, 0);
278  for (int i = 1; i <= dimension; ++ i)
279  {
280  tProdCell<CellT> bd2 (*this, i);
281  if (bd1 == bd2)
282  return i;
283  bd1. swap (bd2);
284  }
285  return 0;
286 } /* tProdCell::degenerate */
287 
288 template <class CellT>
289 inline bool tProdCell<CellT>::defined () const
290 {
291  return (left || cell);
292 } /* tProdCell::defined */
293 
294 template <class CellT>
295 inline bool tProdCell<CellT>::product () const
296 {
297  return !!left;
298 } /* tProdCell::product */
299 
300 template <class CellT>
302 {
303  if (!left)
304  throw "Trying to get a non-existent left cell from a product.";
305  return *left;
306 } /* tProdCell::getLeft */
307 
308 template <class CellT>
310 {
311  if (!right)
312  throw "Trying to get a non-existent right cell from a product.";
313  return *right;
314 } /* tProdCell::getRight */
315 
316 template <class CellT>
317 inline const CellT &tProdCell<CellT>::getCell () const
318 {
319  if (!cell)
320  throw "Trying to get a non-existent cell from a product.";
321  return *cell;
322 } /* tProdCell::getCell */
323 
324 template <class CellT>
326 {
327  return (dimension > 0) ? (dimension + 1) : 0;
328 } /* tProdCell::boundaryLength */
329 
330 template <class CellT>
331 inline int tProdCell<CellT>::boundaryCoef (int n) const
332 {
333  return (n & 1) ? -1 : 1;
334 } /* tProdCell::boundaryCoef */
335 
336 // --------------------------------------------------
337 
338 /// Generates a hashing key no. 1 for a product cell,
339 /// composed of hashing keys for the cells in the product.
340 /// This key is to be used in a hashed set.
341 template <class CellT>
342 inline int_t hashkey1 (const tProdCell<CellT> &s)
343 {
344 // using chomp::homology::hashkey1;
346 
347  if (!s. defined ())
348  return 0;
349  if (s. product ())
350  {
351  return (hashkey1 (s. getLeft ()) << 11) ^
352  hashkey1 (s. getRight ());
353  }
354  return hashkey1 (s. getCell ());
355 } /* hashkey1 */
356 
357 /// Generates a hashing key no. 2 for a product cell,
358 /// composed of hashing keys for the cells in the product.
359 /// This key is to be used in a hashed set.
360 template <class CellT>
361 inline int_t hashkey2 (const tProdCell<CellT> &s)
362 {
363 // using chomp::homology::hashkey2;
365 
366  if (!s. defined ())
367  return 0;
368  if (s. product ())
369  {
370  return hashkey2 (s. getLeft ()) ^
371  (hashkey2 (s. getRight ()) << 13);
372  }
373  return hashkey2 (s. getCell ());
374 } /* hashkey2 */
375 
376 // --------------------------------------------------
377 
378 /// Writes a product cell in the text mode to an output stream.
379 template <class CellT>
380 std::ostream &operator << (std::ostream &out, const tProdCell<CellT> &s)
381 {
382  if (!s. defined ())
383  out << "[undef]";
384  else if (s. product ())
385  {
386  out << "(" << s. getLeft () << " X " <<
387  s. getRight () << ")";
388  }
389  else
390  out << s. getCell ();
391 
392  return out;
393 } /* operator << */
394 
395 /// Reading a product cell is not well defined (too much effort, sorry!).
396 template <class CellT>
397 std::istream &operator >> (std::istream &in, tProdCell<CellT> &s)
398 {
399  throw "Reading a product cell not programmed. Sorry!";
400  return in;
401 } /* operator >> */
402 
403 
404 #endif // _CHAINCON_PRODCELL_H_
405 
tProdCell< CellT > & operator=(const tProdCell< CellT > &s)
The assignment operator.
Definition: prodcell.h:191
const tProdCell & getLeft() const
Returns the left-hand side part of the product.
Definition: prodcell.h:301
int_t hashkey2(const tProdCell< CellT > &s)
Generates a hashing key no.
Definition: prodcell.h:361
const CellT & getCell() const
Returns the actual cell in case this is not a product.
Definition: prodcell.h:317
tProdCell< CellT > * left
A pointer to the left-hand side part of the product.
Definition: prodcell.h:125
int dimension
The dimension of the cell.
Definition: prodcell.h:122
int boundaryLength() const
Returns the length of the boundary of the simplicial product, which equals the dimension of the cell ...
Definition: prodcell.h:325
CellT * cell
A pointer to the actual cell if this is not a product.
Definition: prodcell.h:131
int dim() const
Returns the dimension of the cell.
Definition: prodcell.h:267
void swap(tProdCell< CellT > &s)
Swaps the data between two cells.
Definition: prodcell.h:257
bool defined() const
Checks if the cell is defined.
Definition: prodcell.h:289
bool operator==(const tProdCell< CellT > &s) const
Checks if the two cells are equal.
Definition: prodcell.h:237
~tProdCell()
The destructor.
Definition: prodcell.h:224
int boundaryCoef(int n) const
Returns the n-th coefficient in the boundary of the simplicial product, which is (-1)^n.
Definition: prodcell.h:331
std::istream & operator>>(std::istream &in, tProdCell< CellT > &s)
Reading a product cell is not well defined (too much effort, sorry!).
Definition: prodcell.h:397
int_t hashkey1(const tProdCell< CellT > &s)
Generates a hashing key no.
Definition: prodcell.h:342
A Cartesian product of simplicial cells as a simplicial cell.
Definition: prodcell.h:48
tProdCell< CellT > * right
A pointer to the right-hand side part of the product.
Definition: prodcell.h:128
tProdCell()
The default constructor of an undefined product cell.
Definition: prodcell.h:138
CellT CellType
The type of the cells whose product is stored here.
Definition: prodcell.h:52
const tProdCell & getRight() const
Returns the right-hand side part of the product.
Definition: prodcell.h:309
bool product() const
Checks if the cell is really a product of two other cells.
Definition: prodcell.h:295
int degenerate() const
Checks if the product cell is degenerate, that is, if its (i-1)st face equals ith face...
Definition: prodcell.h:273
CellT::EmptyType EmptyType
The type of the empty cell existence decision class.
Definition: prodcell.h:55