The Original CHomP Software
cubacycl.h
Go to the documentation of this file.
1
3
14
15// Copyright (C) 1997-2020 by Pawel Pilarczyk.
16//
17// This file is part of my research software package. This is free software:
18// you can redistribute it and/or modify it under the terms of the GNU
19// General Public License as published by the Free Software Foundation,
20// either version 3 of the License, or (at your option) any later version.
21//
22// This software is distributed in the hope that it will be useful,
23// but WITHOUT ANY WARRANTY; without even the implied warranty of
24// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25// GNU General Public License for more details.
26//
27// You should have received a copy of the GNU General Public License
28// along with this software; see the file "license.txt". If not,
29// please, see <https://www.gnu.org/licenses/>.
30
31// Started in January 2002. Last revision: February 2, 2018.
32
33
34#ifndef _CHOMP_HOMOLOGY_CUBACYCL_H_
35#define _CHOMP_HOMOLOGY_CUBACYCL_H_
36
37#include "chomp/system/config.h"
48#include "chomp/cubes/cube.h"
49#include "chomp/cubes/cell.h"
50#include "chomp/cubes/cubmaps.h"
55
56#include <iostream>
57#include <fstream>
58#include <cstdlib>
59
60namespace chomp {
61namespace homology {
62
63// --------------------------------------------------
64// ---------- acyclicity of neighborhoods -----------
65// --------------------------------------------------
66
70inline bool acyclic (int dim, BitField &b)
71{
72 // look for the answer in the tabulated data
73 const char *table = tabulated [dim];
74 if (table)
75 {
76 return Tabulated::get (table,
77 bits2int (b, getmaxneighbors (dim)));
78 }
79
80 // look for the answer among the known combinations
81 SetOfBitFields *known = knownbits [dim];
82 int answerKnown = known ? known -> check (b) : -1;
83
84 // if the answer is known then return it
85 if (answerKnown >= 0)
86 return (!!answerKnown);
87
88 // create a model cube for building the neighborhood
89 typedef tCubeBase<short> tCube;
90 if (dim > tCube::MaxDim)
91 throw "Cube dimension too high for acyclicity verification.";
92 short c [tCube::MaxDim];
93 for (int i = 0; i < dim; ++ i)
94 c [i] = 0;
95 tCube qzero (c, dim);
96
97 // find out whether the set of neighbors is acyclic or not
98 typedef tCube::CellType tCell;
100 addneighbors (qzero, b, neighbors, true);
101 bool answerBool (acyclic (neighbors));
102
103 // add the answer to the list of known ones
104 if (known)
105 known -> add (b, answerBool);
106
107 return answerBool;
108} /* acyclic */
109
112template <class tCube>
113inline bool acyclic (const hashedset<tCube> &cset)
114{
115 // the empty set is not acyclic
116 if (cset. empty ())
117 return false;
118
119 // a singleton is acyclic
120 if (cset. size () == 1)
121 return true;
122
123 // reduce the set and see if there is only one cube remaining
124 hashedset<tCube> emptycubes;
125 hashedset<tCube> theset (cset);
126 cubreducequiet (emptycubes, theset, emptycubes); // !!!
127 if (theset. size () == 1)
128 return true;
129
130 // create a cubical complex from this set of cubes
132 int_t size = cset. size ();
133 for (int_t i = 0; i < size; ++ i)
134 ccompl. add (typename tCube::CellType (cset [i]));
135
136 // check whether this geometric complex is acyclic or not
137 return acyclic (ccompl);
138} /* acyclic */
139
150template <class tCube, class tCubeSet1, class tCubeSet2>
151inline bool acyclic (const tCube &q, int dim, const tCubeSet1 &cset,
152 BitField *b, int_t maxneighbors, tCubeSet2 *neighbors)
153{
154 // use a binary decision diagram code if possible
155 if (dim <= MaxBddDim)
156 return bddacyclic (q, dim, cset, *b);
157
158 // get the neighbors of the cube
159 int_t n = getneighbors (q, b, cset, neighbors, 0);
160
161 // if the answer is obvious from the number of neighbors, return it
162 if ((n == 0) || (n == maxneighbors))
163 return false;
164 if (n == 1)
165 return true;
166
167 // return the information on whether this set of neighbors is acyclic
168 return acyclic (dim, *b);
169} /* acyclic */
170
173template <class tCube, class tCubeSet>
174inline bool acyclic (const tCube &q, int dim, const tCubeSet &cset,
175 BitField *b, int_t maxneighbors)
176{
178 return acyclic (q, dim, cset, b, maxneighbors, neighbors);
179} /* acyclic */
180
182template <class tCube, class tSet1, class tSet2>
183bool acyclic_rel (const tCube &q, int dim, const tSet1 &cset,
184 const tSet2 &other, BitField *b, int_t maxneighbors,
185 hashedset<tCube> *neighbors_main, hashedset<tCube> *neighbors_other)
186{
187 // use a binary decision diagram code if possible
188 if (dim <= MaxBddDim)
189 {
190 if (!getneighbors (q, b, cset, 1))
191 return true;
192 if (!bddacyclic (q, dim, other, *b))
193 return false;
194 return bddacyclic (q, dim, makesetunion (cset, other), *b);
195 }
196
197 // get the neighbors from the other set
198 int_t nother = getneighbors (q, b, other, neighbors_other, 0);
199
200 // verify if this set of neighbors is acyclic
201 bool otheracyclic = (nother < maxneighbors) &&
202 ((nother == 1) || (nother && acyclic (dim, *b)));
203
204 // add the neighbors from 'cset'
205 int_t ncset = getneighbors (q, b, cset, neighbors_main, 0);
206
207 // if there are no cubes in 'cset', then this cube is ok
208 if (!ncset)
209 return true;
210
211 // if there are neighbors in 'cset' and the neighbors
212 // from 'other' are not acyclic, the cube canot be removed
213 if (!otheracyclic)
214 return false;
215
216 // if there are neighbors from 'cset' then check if the neighbors
217 // from both 'cset' and 'other' taken together form an acyclic set
218 if ((ncset + nother > 1) && ((ncset + nother == maxneighbors) ||
219 !acyclic (dim, *b)))
220 {
221 return false;
222 }
223 return true;
224} /* acyclic_rel */
225
226
227// --------------------------------------------------
228// -------------- acyclicity for maps ---------------
229// --------------------------------------------------
230
234template <class tCube, class tCell, class tSet>
235int_t computeimage (hashedset<tCube> &img, const tCell &face,
236 const mvmap<tCube,tCube> &map, const tSet &cset,
237 const tCube &ignore)
238{
239 // get the coordinates of the cubical cell
240 typename tCell::CoordType left [tCell::MaxDim];
241 face. leftcoord (left);
242 typename tCell::CoordType right [tCell::MaxDim];
243 face. rightcoord (right);
244
245 // find the images of all the cubes containing this cell
246 int spacedim = face. spacedim ();
247 typename tCell::CoordType leftb [tCell::MaxDim];
248 typename tCell::CoordType rightb [tCell::MaxDim];
249 for (int j = 0; j < spacedim; ++ j)
250 {
251 typename tCell::CoordType diff =
252 (left [j] == right [j]) ? 1 : 0;
253 leftb [j] = (left [j] - diff);
254 rightb [j] = (right [j] + diff);
255 }
256 tRectangle<typename tCell::CoordType> r (leftb, rightb, spacedim);
257 const typename tCell::CoordType *c;
258 int_t countimages = 0;
259 while ((c = r. get ()) != NULL)
260 {
261 if (!tCube::PointBase::check (c, spacedim))
262 continue;
263 tCube q (c, spacedim);
264 if (q == ignore)
265 continue;
266 if (!cset. check (q))
267 continue;
268 img. add (map (q));
269 ++ countimages;
270 }
271
272 return countimages;
273} /* computeimage */
274
279template <class tCube, class tSet>
280bool remainsacyclic (const mvmap<tCube,tCube> &map, const tCube &q,
281 const tSet &cset)
282{
283 // if the map is trivial then the answer is obvious
284 if (map. getdomain (). empty ())
285 return true;
286
287 // compute the maximal number of neighbors of a cube
288 int_t maxneighbors = getmaxneighbors (q. dim ());
289
290 // prepare a bitfield and allocate it if necessary
291 static BitField b;
292 static int_t _maxneighbors = 0;
293 static auto_array<unsigned char> buffer;
294 if (maxneighbors != _maxneighbors)
295 {
296 _maxneighbors = maxneighbors;
297 buffer. reset (new unsigned char [(maxneighbors + 7) >> 3]);
298 b. define (buffer. get (), maxneighbors);
299 }
300
301 // clear the neighborbits
302 b. clearall (maxneighbors);
303
304 // get the bitfield representing the set of the neighbors of the cube
305 getneighbors (q, &b, cset, 0);
306
307 // create all the faces of the cube
309 addneighbors (q, b, faces);
310 faces. addboundaries ();
311
312 // compute the new images of all the faces
313 // and determine if they are acyclic
314 int startdim = faces. dim ();
315 for (int d = startdim; d >= 0; -- d)
316 {
317 for (int_t i = 0; i < faces [d]. size (); ++ i)
318 {
319 // compute the image of the face in the set
321 int_t n = computeimage (img, faces [d] [i], map,
322 cset, q);
323
324 // if this is the image of only one cube, it is Ok
325 if (n == 1)
326 continue;
327
328 // verify whether the large image (with 'q')
329 // can be reduced towards the small one (without 'q')
330 hashedset<tCube> imgsurplus = map (q);
331 imgsurplus. remove (img);
332 cubreducequiet (img, imgsurplus);
333 if (!imgsurplus. empty ())
334 return false;
335 }
336 }
337
338 return true;
339} /* remainsacyclic */
340
344template <class tCube>
346{
347public:
349 MapRemainsAcyclic (const mvmap<tCube,tCube> &the_map);
350
355 template <class tSet>
356 bool operator () (const tCube &q, const tSet &cset) const;
357
358protected:
361
362}; /* class MapRemainsAcyclic */
363
364template <class tCube>
366 map (the_map)
367{
368 // determine if the acyclicity of the map should be considered
369// bool checkacyclic = !map. getdomain (). empty ();
370
371 return;
372} /* MapRemainsAcyclic<tCube>::MapRemainsAcyclic */
373
374template <class tCube>
375template <class tSet>
376inline bool MapRemainsAcyclic<tCube>::operator () (const tCube &q,
377 const tSet &cset) const
378{
379 return remainsacyclic (map, q, cset);
380} /* MapRemainsAcyclic<tCube>::operator () */
381
382// --------------------------------------------------
383
390template <class tCube>
392{
393public:
395 MapCanExpand (const mvmap<tCube,tCube> &_map,
396 hashedset<tCube> &_imgsrc, hashedset<tCube> &_img,
397 bool _indexmap, bool _checkacyclic, bool _quiet);
398
403 template <class tSet1, class tSet2>
404 bool operator () (const tCube &c, const tSet1 &cset,
405 const tSet2 &other) const;
406
407protected:
410
413
416
419
422
424 bool quiet;
425
426}; /* class MapCanExpand */
427
428template <class tCube>
430 hashedset<tCube> &_imgsrc, hashedset<tCube> &_img,
431 bool _indexmap, bool _checkacyclic, bool _quiet):
432 map (_map), imgsrc (_imgsrc), img (_img),
433 indexmap (_indexmap), checkacyclic (_checkacyclic),
434 quiet (_quiet)
435{
436 return;
437} /* MapCanExpand<tCube>::MapCanExpand */
438
439template <class tCube>
440template <class tSet1, class tSet2>
441inline bool MapCanExpand<tCube>::operator () (const tCube &c,
442 const tSet1 &cset, const tSet2 &other) const
443{
444 // take the image and reduce what is outside 'img'
445 const hashedset<tCube> &cubimage = map (c);
446 hashedset<tCube> ximage = cubimage;
447 if (indexmap)
448 ximage. add (c);
449 ximage. remove (img);
450 cubreducequiet (img, ximage);
451
452 // if the image could not be reduced, skip the cube
453 if (!ximage. empty ())
454 return false;
455
456 // make sure that the acyclicity of the map is not spoiled
457 if (checkacyclic && !remainsacyclic (map, c, other))
458 return false;
459
460 // add the image of this cube to the image of the map
461 if (!quiet && !cubimage. empty ())
462 {
463 sseq << "R\n";
464 for (int_t j = 0; j < cubimage. size (); ++ j)
465 sseq << '2' << cubimage [j] << '\n';
466 if (indexmap)
467 sseq << '2' << c << '\n';
468 }
469 img. add (cubimage);
470 if (indexmap)
471 img. add (c);
472
473 // remove from 'imgsrc' all the cubes added to 'img'
474 imgsrc. remove (cubimage);
475 if (indexmap)
476 imgsrc. remove (c);
477
478 return true;
479} /* MapCanExpand<tCube>::operator () */
480
481// --------------------------------------------------
482
485template <class tCube>
487{
488public:
491
493 template <class tSet1, class tSet2>
494 bool operator () (const tCube &q, const tSet1 &cset,
495 const tSet2 &other) const;
496
497}; /* class MapCanExpandDummy */
498
499template <class tCube>
501{
502 return;
503} /* MapCanExpandDummy<tCube>::MapCanExpandDummy */
504
505template <class tCube>
506template <class tSet1, class tSet2>
508 const tSet1 &, const tSet2 &) const
509{
510 return true;
511} /* MapCanExpandDummy<tCube>::operator () */
512
513
514} // namespace homology
515} // namespace chomp
516
517#endif // _CHOMP_HOMOLOGY_CUBACYCL_H_
518
520
An auto_array template that mimics selected behaviors of the std::auto_ptr template,...
This file contains functions generated using Binary Decision Diagrams for checking the acyclicity of ...
This file contains the definition of a bitfield class which works an array of bits.
This file includes header files with various definitions of cubical cells and defines the standard ty...
This file contains classes and functions related to algebraic chain complexes and chain maps,...
This class defines a bit field that is part of some larger array or that uses an allocated piece of m...
Definition: bitfield.h:73
A dummy class that substitutes MapCanExpand if there is no map to check, so the verification always r...
Definition: cubacycl.h:487
bool operator()(const tCube &q, const tSet1 &cset, const tSet2 &other) const
Dummy verification. Always returns 'true'.
Definition: cubacycl.h:507
MapCanExpandDummy()
The only allowed constructor.
Definition: cubacycl.h:500
A class for the procecure checking if the image of a given map can be expanded without any harm to th...
Definition: cubacycl.h:392
bool checkacyclic
Should it be checked that the map acyclicity is preserved?
Definition: cubacycl.h:421
const mvmap< tCube, tCube > & map
A reference to the map being verified.
Definition: cubacycl.h:409
bool indexmap
Is theis the index map?
Definition: cubacycl.h:418
bool quiet
Should any messages be suppressed?
Definition: cubacycl.h:424
MapCanExpand(const mvmap< tCube, tCube > &_map, hashedset< tCube > &_imgsrc, hashedset< tCube > &_img, bool _indexmap, bool _checkacyclic, bool _quiet)
The only allowed constructor.
Definition: cubacycl.h:429
bool operator()(const tCube &c, const tSet1 &cset, const tSet2 &other) const
Verifies if the map remains acyclic after the addition or removal of the given cube to/from the given...
Definition: cubacycl.h:441
hashedset< tCube > & img
A reference to image of the map, previously computed, modified.
Definition: cubacycl.h:415
hashedset< tCube > & imgsrc
A reference to the source of image cubes. (?)
Definition: cubacycl.h:412
A wrapper class for the procecure checking if a given map remains acyclic when a given full cube is r...
Definition: cubacycl.h:346
const mvmap< tCube, tCube > & map
A reference to the map being verified.
Definition: cubacycl.h:360
bool operator()(const tCube &q, const tSet &cset) const
Verifies if the map remains acyclic after the addition or removal of the given cube to/from the given...
Definition: cubacycl.h:376
MapRemainsAcyclic(const mvmap< tCube, tCube > &the_map)
The only allowed constructor.
Definition: cubacycl.h:365
This class defines a set of bit fields of the same length which are to be stored in a contiguous piec...
Definition: bitfield.h:245
static int get(const char *table, int_t bitnumber)
Retrieve the given bit from the given table.
Definition: tabulate.h:121
An auto_array template that mimics selected behaviors of the std::auto_ptr template,...
Definition: autoarray.h:54
The class that defines a geometric complex - a set of cells (cubes, simplices, etc).
Definition: gcomplex.h:85
This class defines a hypercube in R^n with edges parallel to the axes and with size 1 in each directi...
Definition: cubebase.h:72
This class can be used for iterating point's neighbors.
Definition: pointset.h:1450
This class can be used for iterating a rectangular set of points, given its left and right bound.
Definition: pointset.h:1627
This file contains some precompiler definitions which indicate the operating system and/or compiler u...
This file includes header files with various definitions of full cubes and defines the standard types...
This file contains some procedures defined for cubical maps.
This file contains a definition of a general geometric complex which represents a polyhedron.
int int_t
Index type for indexing arrays, counting cubes, etc.
Definition: config.h:115
This file contains the definition of the container "hashedset" which can be used to represent a set o...
This file defines a class "integer" which represents the ring of integers or the field of integers mo...
This file contains the definition of a tabulated set of configurations of full cubical neighborhood u...
outputstream sseq
An auxiliary stream which captures sequences of processed data.
int MaxBddDim
The maximal dimension for which binary decision diagrams are used.
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.
Definition: neighbor.h:302
bool acyclic(int dim, BitField &b)
Checks whether this cube's nieghbors form an acyclic set.
Definition: cubacycl.h:70
bool acyclic_rel(const tCube &q, int dim, const tSet1 &cset, const tSet2 &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: cubacycl.h:183
setunion< set1type, set2type > makesetunion(const set1type &set1, const set2type &set2)
Creates an object which represents the union of two sets.
Definition: setunion.h:225
int_t computeimage(hashedset< tCube > &img, const tCell &face, const mvmap< tCube, tCube > &map, const tSet &cset, const tCube &ignore)
Computes the image of the face under the combinatorial cubical multivalued map, but doesn't take the ...
Definition: cubacycl.h:235
int bits2int(const BitField &field, int_t length)
Definition: bitfield.h:215
int_t getmaxneighbors(int dim)
Returns the maximal number of neighbors of a cube: 3^dim - 1.
Definition: neighbor.h:60
int_t cubreducequiet(hashedset< tCube > &cset, hashedset< tCube > &other, mvmap< tCube, tCube > &cubmap, const hashedset< tCube > &keep, bool quiet=true)
Reduces a pair of sets of cubes for relative homology computation.
Definition: cubisets.h:76
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'.
Definition: bincube.h:1048
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 reduc...
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.
Definition: homtools.h:835
tNeighbors< coordinate > neighbors
The neighbors class with the default type of coordinates.
Definition: pointset.h:84
bool remainsacyclic(const mvmap< tCube, tCube > &map, const tCube &q, const tSet &cset)
Verifies if the map remains acyclic after the addition or removal of the given cube to/from the union...
Definition: cubacycl.h:280
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 i...
Definition: bddacycl.h:1198
This namespace contains the entire CHomP library interface.
Definition: bitmaps.h:51
This file contains various procedures relating to neighborhoods of cubes in full cubical sets.
This file contains the definition of a point base class which is used for indexing all the points (n-...
This file contains the definition of a set of n-dimensional points with integer coordinates and sever...
This file contains the definition of the container "setunion".
This file contains the definition of a class which stores tabulated configuration of full cubical nei...
This file contains some useful functions related to the text input/output procedures.