The ChainCon Software (Release 0.03)
boundary.h
Go to the documentation of this file.
1 /////////////////////////////////////////////////////////////////////////////
2 ///
3 /// \file
4 ///
5 /// Boundary computation at the level of chains of cells.
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: February 5, 2016.
26 
27 
28 #ifndef _CHAINCON_BOUNDARY_H_
29 #define _CHAINCON_BOUNDARY_H_
30 
31 
32 // include some standard C++ header files
33 #include <vector>
34 
35 // include relevant local header files
36 #include "chaincon/combchain.h"
37 #include "chaincon/chain.h"
38 #include "chaincon/combtensor.h"
39 #include "chaincon/tensor.h"
40 #include "chaincon/comblinmap.h"
41 #include "chaincon/linmap.h"
42 #include "chaincon/filtcomplex.h"
43 
44 // include selected header files from the CHomP library
45 #include "chomp/system/config.h"
46 #include "chomp/struct/multitab.h"
47 //#include "chomp/system/textfile.h"
48 
49 
50 // --------------------------------------------------
51 // ----------------- helper classes -----------------
52 // --------------------------------------------------
53 
54 /// A template of a simple class for unrestricted cell selection
55 /// in the boundary computation procedures.
57 {
58 public:
59  /// Checks whether the given cell satisfies the restriction.
60  /// In this class, always returns true.
61  template <class CellT>
62  bool check (const CellT &c) const;
63 
64 }; /* class Unrestricted */
65 
66 template <class CellT>
67 inline bool Unrestricted::check (const CellT &c) const
68 {
69  return true;
70 } /* Unrestricted::check */
71 
72 // --------------------------------------------------
73 
74 /// A template of a simple class for negating the cell restriction
75 /// given by another object for the boundary computation procedures.
76 template <class CellRestrT>
78 {
79 public:
80  /// Creates an object of the class based on another object
81  /// whose decisions will be negated.
82  NegateRestr (const CellRestrT &p);
83 
84  /// Checks whether the given cell satisfies the negation
85  /// of the restriction given by the parent object.
86  template <class CellT>
87  bool check (const CellT &c) const;
88 
89 private:
90  /// The parent object whose decisions will be negated.
91  const CellRestrT &parent;
92 
93 }; /* class NegateRestr */
94 
95 template <class CellRestrT>
96 inline NegateRestr<CellRestrT>::NegateRestr (const CellRestrT &p):
97  parent (p)
98 {
99  return;
100 } /* NegateRestr::NegateRestr */
101 
102 template <class CellRestrT>
103 template <class CellT>
104 inline bool NegateRestr<CellRestrT>::check (const CellT &c) const
105 {
106  return !parent. check (c);
107 } /* NegateRestr::check */
108 
109 
110 // --------------------------------------------------
111 // ------- boundary of a combinatorial chain --------
112 // --------------------------------------------------
113 
114 /// Adds the boundary of a given cell to the provided chain
115 /// (takes boundary cells restricted by the given object,
116 /// preferably of the type hashedset<CellT>).
117 template <class CellT, class CellRestrT>
118 inline void computeBoundary (const CellT &c, tCombChain<CellT> &b,
119  const CellRestrT &restr)
120 {
121  // determine the length of the boundary of this cell
122  int length = c. boundaryLength ();
123 
124  // process all the cells in its boundary
125  for (int i = 0; i < length; ++ i)
126  {
127  // create the subsequent boundary cell
128  CellT bc (c, i);
129 
130  // if the cell is not in the restriction then skip it
131  if (!restr. check (bc))
132  continue;
133 
134  // add the boundary cell to the given chain
135  b. add (bc);
136  }
137  return;
138 } /* computeBoundary */
139 
140 /// Adds the boundary of a given chain to the provided chain
141 /// (takes boundary cells restricted by the given object,
142 /// preferably of the type hashedset<CellT>).
143 template <class CellT, class CellRestrT>
144 inline void computeBoundary (const tCombChain<CellT> &c,
145  tCombChain<CellT> &b, const CellRestrT &restr)
146 {
147  int_t size = c. size ();
148  for (int_t i = 0; i < size; ++ i)
149  computeBoundary (c. getCell (i), b, restr);
150  return;
151 } /* computeBoundary */
152 
153 /// Returns the boundary of a given chain (takes boundary cells restricted
154 /// by the given object, preferably of the type hashedset<CellT>).
155 template <class CellT, class CellRestrT>
157  const CellRestrT &restr)
158 {
159  // prepare a chain that is going to contain the boundary of c
161 
162  // add the boundary of each cell in the chain to b
163  computeBoundary (c, b, restr);
164 
165  // return the computed boundary chain
166  return b;
167 } /* boundary */
168 
169 
170 // --------------------------------------------------
171 // -------------- boundary of a chain ---------------
172 // --------------------------------------------------
173 
174 /// Adds the boundary of a given cell to the provided chain
175 /// with the given coefficient (takes boundary cells restricted
176 /// by the given object, preferably of the type hashedset<CellT>).
177 template <class CellT, class CoefT, class CellRestrT>
178 inline void computeBoundary (const CellT &c, tChain<CellT,CoefT> &b,
179  const CoefT &coef, const CellRestrT &restr)
180 {
181  // determine the length of the boundary of this cell
182  int length = c. boundaryLength ();
183 
184  // process all the cells in its boundary
185  for (int i = 0; i < length; ++ i)
186  {
187  // create the subsequent boundary cell
188  CellT bc (c, i);
189 
190  // if the cell is not in the restriction then skip it
191  if (!restr. check (bc))
192  continue;
193 
194  // determine the coefficient to use
195  CoefT bcoef (c. boundaryCoef (i));
196  bcoef *= coef;
197 
198  // add the boundary cell to the given chain
199  b. add (bc, bcoef);
200  }
201  return;
202 } /* computeBoundary */
203 
204 /// Adds the boundary of a given chain to the provided chain
205 /// (takes boundary cells restricted by the given object,
206 /// preferably of the type hashedset<CellT>).
207 template <class CellT, class CoefT, class CellRestrT>
208 inline void computeBoundary (const tChain<CellT,CoefT> &c,
209  tChain<CellT,CoefT> &b, const CellRestrT &restr)
210 {
211  int_t size = c. size ();
212  for (int_t i = 0; i < size; ++ i)
213  computeBoundary (c. getCell (i), b, c. getCoef (i), restr);
214  return;
215 } /* computeBoundary */
216 
217 /// Returns the boundary of a given chain (takes boundary cells restricted
218 /// by the given object, preferably of the type hashedset<CellT>).
219 template <class CellT, class CoefT, class CellRestrT>
221  const CellRestrT &restr)
222 {
223  // prepare a chain that is going to contain the boundary of c
225 
226  // add the boundary of each cell in the chain to b
227  computeBoundary (c, b, restr);
228 
229  // return the computed boundary chain
230  return b;
231 } /* boundary */
232 
233 // Returns the boundary of a given chain (no restriction on boundary cells).
234 //template <class CellT, class CoefT>
235 //inline tChain<CellT,CoefT> boundary (const tChain<CellT,CoefT> &c)
236 //{
237 // return boundary (c, Unrestricted<CellT> ());
238 //} /* boundary */
239 
240 
241 // --------------------------------------------------
242 // ------- boundary of a combinatorial tensor -------
243 // --------------------------------------------------
244 
245 /// Adds the boundary of a given tensor to the provided tensor.
246 template <class Cell1T, class Cell2T, class CellRestrT>
248  tCombTensor<Cell1T,Cell2T> &b, const CellRestrT &restr)
249 {
250  int_t size = c. size ();
251  for (int_t i = 0; i < size; ++ i)
252  {
253  tCombChain<Cell1T> left;
254  computeBoundary (c. left (i), left, restr);
255  tCombChain<Cell2T> right;
256  computeBoundary (c. right (i), right, restr);
257  b. add (left, right);
258  }
259  return;
260 } /* computeBoundary */
261 
262 /// Returns the boundary of a given tensor.
263 template <class Cell1T, class Cell2T, class CellRestrT>
265  (const tCombTensor<Cell1T,Cell2T> &c, const CellRestrT &restr)
266 {
267  // prepare a tensor that is going to contain the boundary of c
269 
270  // add the boundary of each pair in the tensor c to the tensor b
271  computeBoundary (c, b, restr);
272 
273  // return the computed boundary tensor
274  return b;
275 } /* boundary */
276 
277 
278 // --------------------------------------------------
279 // -------------- boundary of a tensor --------------
280 // --------------------------------------------------
281 
282 /// Adds the boundary of a given tensor to the provided tensor.
283 template <class Cell1T, class Cell2T, class CoefT, class CellRestrT>
285  tTensor<Cell1T,Cell2T,CoefT> &b, const CellRestrT &restr)
286 {
287  int_t size = c. size ();
288  for (int_t i = 0; i < size; ++ i)
289  {
291  computeBoundary (c. left (i), left, restr);
292  tChain<Cell2T,CoefT> right;
293  computeBoundary (c. right (i), right, restr);
294  b. add (left, right);
295  }
296  return;
297 } /* computeBoundary */
298 
299 /// Returns the boundary of a given tensor.
300 template <class Cell1T, class Cell2T, class CoefT, class CellRestrT>
302  (const tTensor<Cell1T,Cell2T,CoefT> &c, const CellRestrT &restr)
303 {
304  // prepare a tensor that is going to contain the boundary of c
306 
307  // add the boundary of each pair in the tensor c to the tensor b
308  computeBoundary (c, b, restr);
309 
310  // return the computed boundary tensor
311  return b;
312 } /* boundary */
313 
314 
315 // --------------------------------------------------
316 // ----- boundary of a combinatorial linear map -----
317 // --------------------------------------------------
318 
319 /// Computes the full boundary map for a cellular complex that contains
320 /// the cells in a provided set and all their boundary cells.
321 /// The map is assumed to be initially zero.
322 template <class CellArray, class CellT, class CellRestrT>
323 inline void computeBoundaryMap (const CellArray &cells,
324  tCombLinMap<CellT,CellT> &f, const CellRestrT &restr)
325 {
326  // prepare a set of cells whose boundaries yet have to be computed
327  chomp::homology::hashedset<CellT> waiting;
328 
329  // process all the cells in the domain of the map
330  // (note that the domain may increase during this process)
331  int_t inputCellNumber = 0;
332  const int_t inputCellCount = cells. size ();
333  while (1)
334  {
335  // determine whether a cell from the array should be used
336  bool useInput = (inputCellNumber < inputCellCount);
337 
338  // if the input array has been used and the set
339  // of wating cells as well then exit the loop
340  if (!useInput && waiting. empty ())
341  break;
342 
343  // take a cell for processing
344  int_t waitingPosition = waiting. size () - 1;
345  const CellT &c = useInput ? cells [inputCellNumber] :
346  waiting [waitingPosition];
347 
348  // determine the length of the boundary of this cell
349  int length = c. boundaryLength ();
350 
351  // process all the cells in its boundary
352  for (int b = 0; b < length; ++ b)
353  {
354  // create the subsequent boundary cell
355  CellT bc (c, b);
356 
357  // if the cell is not in the restriction then skip it
358  if (!restr. check (bc))
359  continue;
360 
361  // add the boundary cell to the waiting list
362  if (bc. boundaryLength () &&
363  f. getImage (bc). empty ())
364  {
365  waiting. add (bc);
366  }
367 
368  // add the boundary cell to the image of 'c'
369  f. add (c, bc);
370  }
371 
372  // increase the counter of cells in the input array
373  if (useInput)
374  ++ inputCellNumber;
375 
376  // or remove the waiting cell which was taken
377  else
378  waiting. removenum (waitingPosition);
379  }
380  return;
381 } /* computeBoundaryMap */
382 
383 
384 // --------------------------------------------------
385 // ------------ boundary of a linear map ------------
386 // --------------------------------------------------
387 
388 /// Computes the full boundary map for a cellular complex that contains
389 /// the cells in a provided set and all their boundary cells.
390 /// The map is assumed to be initially zero.
391 template <class CellArray, class CellT, class CoefT, class CellRestrT>
392 inline void computeBoundaryMap (const CellArray &cells,
393  tLinMap<CellT,CellT,CoefT> &f, const CellRestrT &restr)
394 {
395  // prepare a set of cells whose boundaries yet have to be computed
396  chomp::homology::hashedset<CellT> waiting;
397 
398  // process all the cells in the domain of the map
399  // (note that the domain may increase during this process)
400  int_t inputCellNumber = 0;
401  const int_t inputCellCount = cells. size ();
402  while (1)
403  {
404  // determine whether a cell from the array should be used
405  bool useInput = (inputCellNumber < inputCellCount);
406 
407  // if the input array has been used and the set
408  // of wating cells as well then exit the loop
409  if (!useInput && waiting. empty ())
410  break;
411 
412  // take a cell for processing
413  int_t waitingPosition = waiting. size () - 1;
414  const CellT &c = useInput ? cells [inputCellNumber] :
415  waiting [waitingPosition];
416 
417  // determine the length of the boundary of this cell
418  int length = c. boundaryLength ();
419 
420  // process all the cells in its boundary
421  for (int b = 0; b < length; ++ b)
422  {
423  // create the subsequent boundary cell
424  CellT bc (c, b);
425 
426  // if the cell is not in the restriction then skip it
427  if (!restr. check (bc))
428  continue;
429 
430  // add the boundary cell to the waiting list
431  if (bc. boundaryLength () &&
432  f. getImage (bc). empty ())
433  {
434  waiting. add (bc);
435  }
436 
437  // add the boundary cell to the image of 'c'
438  f. add (c, bc, CoefT (c. boundaryCoef (b)));
439  }
440 
441  // increase the counter of cells in the input array
442  if (useInput)
443  ++ inputCellNumber;
444 
445  // or remove the waiting cell which was taken
446  else
447  waiting. removenum (waitingPosition);
448  }
449  return;
450 } /* computeBoundaryMap */
451 
452 
453 // --------------------------------------------------
454 // -------- boundaries in a filtered complex --------
455 // --------------------------------------------------
456 
457 /// Adds boundaries to all the cells in the given filtered complex.
458 template <class CellT, class CellRestrT>
460  const CellRestrT &restr)
461 {
462 // using chomp::homology::sbug;
463  using chomp::homology::scon;
464 
465  // if the complex is empty then there is no work to do
466  if (K. empty ())
467  return;
468 
469  // determine the dimensions of all the cells in the input complex
470  chomp::homology::multitable<std::vector<int_t> > cellsByDim (32);
471  int topDim (-1);
472  int_t Ksize = K. size ();
473  for (int_t i = 0; i < Ksize; ++ i)
474  {
475  int dim (K [i]. dim ());
476  if (dim >= 0)
477  {
478  cellsByDim [dim]. push_back (i);
479  if (topDim < dim)
480  topDim = dim;
481  }
482  }
483 
484  // prepare another complex for the result and swap it with the input
486  L. swap (K);
487  int_t Lsize (L. size ());
488  int_t Lused (0);
489 
490  // prepare the current dimension of cells (starting with top dim)
491  int curDim (topDim);
492 
493  // process all the cells in the filter (its size may be changing)
494  int_t counter (0);
495  for (int_t n = 0; (n < K. size ()) || (Lused < Lsize); ++ n)
496  {
497  // sbug << "DEBUG: n = " << n << ", K. size () = " <<
498  // K. size () << ".\n";
499  // add appropriate cells from L if the dimension
500  // of the next cell to be processed allows for that
501  if ((curDim >= 0) && ((n >= K. size ()) ||
502  (K [K. size () - n - 1]. dim () - 1 <= curDim)))
503  {
504  size_t curDimSize (cellsByDim [curDim]. size ());
505  // sbug << "DEBUG: Adding " << curDimSize <<
506  // " cell(s) from L of dim " << curDim << ".\n";
507  for (size_t i = 0; i < curDimSize; ++ i)
508  {
509  K. add (L [cellsByDim [curDim] [i]]);
510  ++ counter;
511  if (!(counter % 5347))
512  scon << std::setw (15) << counter <<
513  "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b";
514  }
515  Lused += curDimSize;
516  -- curDim;
517  -- n;
518  continue;
519  }
520 
521  // take the cell
522  const CellT &c = K [K. size () - n - 1];
523  // sbug << "DEBUG: Computing bounary of " << c << ".\n";
524 
525  // process the boundary cells of the cell
526  int len = c. boundaryLength ();
527  for (int i = 0; i < len; ++ i)
528  {
529  // create the subsequent boundary cell
530  CellT bc (c, i);
531 
532  // if the cell is not in the restriction then skip it
533  if (!restr. check (bc))
534  continue;
535 
536  // add the boundary cell to the filtered complex
537  int_t cn = K. add (bc);
538  ++ counter;
539  if (!(counter % 5347))
540  scon << std::setw (15) << counter <<
541  "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b";
542 
543  // make sure that the parent cell appears earlier
544  if (cn < n)
545  {
546  throw "A boundary cell appears too early "
547  "in the filter.";
548  }
549  }
550  }
551 
552  return;
553 } /* addBoundaries */
554 
555 
556 #endif // _CHAINCON_BOUNDARY_H_
557 
A linear map for coefficients in an arbitrary commutative ring.
A combinatorial chain, that is, a chain with Z_2 coefficients.
tCombChain< CellT > boundary(const tCombChain< CellT > &c, const CellRestrT &restr)
Returns the boundary of a given chain (takes boundary cells restricted by the given object...
Definition: boundary.h:156
A chain with coefficients in an arbitrary ring.
Definition: chain.h:50
A combinatorial linear map (for coefficients in Z_2).
NegateRestr(const CellRestrT &p)
Creates an object of the class based on another object whose decisions will be negated.
Definition: boundary.h:96
A tensor of chains with coefficients in an arbitrary commutative ring.
void computeBoundaryMap(const CellArray &cells, tCombLinMap< CellT, CellT > &f, const CellRestrT &restr)
Computes the full boundary map for a cellular complex that contains the cells in a provided set and a...
Definition: boundary.h:323
A filtered cell complex.
A linear map.
Definition: linmap.h:55
A template of a simple class for negating the cell restriction given by another object for the bounda...
Definition: boundary.h:77
A filtered complex.
Definition: filtcomplex.h:53
bool check(const CellT &c) const
Checks whether the given cell satisfies the negation of the restriction given by the parent object...
Definition: boundary.h:104
const CellRestrT & parent
The parent object whose decisions will be negated.
Definition: boundary.h:91
Tensor of chains.
Definition: tensor.h:52
Combinatorial tensor of cells.
Definition: combtensor.h:53
void computeBoundary(const CellT &c, tCombChain< CellT > &b, const CellRestrT &restr)
Adds the boundary of a given cell to the provided chain (takes boundary cells restricted by the given...
Definition: boundary.h:118
A combinatorial chain.
Definition: combchain.h:49
A combinatorial tensor (for coefficients in Z_2).
void addBoundaries(tFilteredComplex< CellT > &K, const CellRestrT &restr)
Adds boundaries to all the cells in the given filtered complex.
Definition: boundary.h:459
A chain with coefficients in an arbitrary commutative ring.
bool check(const CellT &c) const
Checks whether the given cell satisfies the restriction.
Definition: boundary.h:67
A template of a simple class for unrestricted cell selection in the boundary computation procedures...
Definition: boundary.h:56
A combinatorial linear map.
Definition: comblinmap.h:56