The Original CHomP Software
cubired1.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_CUBIRED1_H_
35#define _CHOMP_HOMOLOGY_CUBIRED1_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"
56
57#include <iostream>
58#include <fstream>
59#include <cstdlib>
60
61namespace chomp {
62namespace homology {
63namespace reduction1 {
64
65
66// --------------------------------------------------
67// ----------------- add neighbors ------------------
68// --------------------------------------------------
69
77template <class tCube, class tCubeSet>
78inline void addcubeneighbors (const tCube &q, int dim,
79 const tCubeSet &cubset, bitfield *b, hashedset<tCube> &neighbors,
80 hashedset<tCube> &queue, const hashedset<tCube> &notthese)
81{
82 // determine the neighbors of this cube (if not done yet)
83 if (dim <= MaxBddDim)
84 getneighbors (q, b, cubset, &neighbors, 0);
85
86 // add the computed neighbors of this cube to the queue
87 for (int_t j = 0; j < neighbors. size (); ++ j)
88 {
89 if (!notthese. check (neighbors [j]))
90 queue. add (neighbors [j]);
91 }
92
93 return;
94} /* addcubeneighbors */
95
96
97// --------------------------------------------------
98// ------------------ reduce cubes ------------------
99// --------------------------------------------------
100
113template <class tCube, class tVerify>
116 const hashedset<tCube> &keep, const tVerify &verify,
117 bool quiet = true)
118{
119 // remember the initial number of cubes in both sets
120 int_t prev = cset. size () + other. size ();
121
122 // if the case is trivial, return the answer
123 if (maincset. empty () && cset. empty ())
124 {
125 if (!other. empty ())
126 {
127 hashedset<tCube> empty;
128 other = empty;
129 }
130 return prev;
131 }
132
133 // determine the space dimension
134 int dim = (cset. empty ()) ? maincset [0]. dim () :
135 cset [0]. dim ();
136
137 // compute the maximal number of neighbors of a cube
138 int_t maxneighbors = getmaxneighbors (dim);
139
140 // prepare a bitfield for storing neighborhood configurations
141 // and allocate it if necessary (this is a static variable)
142 static BitField b;
143 static int_t _maxneighbors = 0;
144 static auto_array<unsigned char> buffer;
145 if (maxneighbors != _maxneighbors)
146 {
147 _maxneighbors = maxneighbors;
148 buffer. reset (new unsigned char [(maxneighbors + 7) >> 3]);
149 b. define (buffer. get (), maxneighbors);
150 }
151
152 // prepare a queue for cubes to check
153 hashedset<tCube> queue;
154
155 // prepare a counter for displaying the progress of computations
156 int_t count = 0;
157
158 // go through the other set, remove cubes which can be removed,
159 // and add their neighbors (only in the other set) to the queue
160 for (int_t i = 0; i < other. size (); ++ i)
161 {
162 // show the progress indicator
163 ++ count;
164 if (!quiet && !(count % 373))
165 scon << std::setw (10) << count <<
166 "\b\b\b\b\b\b\b\b\b\b";
167
168 // if the cube should be kept, skip it
169 if (keep. check (other [i]))
170 continue;
171
172 // clear the neighborbits
173 b. clearall (maxneighbors);
174
175 // prepare a set for storing the neighbors of the cube
177 hashedset<tCube> *none (0);
178
179 // if the cube cannot be removed, skip it
180 if (!acyclic_rel (other [i], dim,
181 makesetunion (maincset, cset), other, &b,
182 maxneighbors, none, &neighbors))
183 {
184 continue;
185 }
186
187 // verify if the removal of the cube from A is OK
188 if (!verify (other [i], other))
189 continue;
190
191 // verify if the removal of the cube from X is OK
192 if (!verify (other [i], makesetunion (maincset,
193 makesetunion (other, cset))))
194 {
195 continue;
196 }
197
198 // remove this cube from the queue
199 queue. remove (other [i]);
200
201 // determine the neighbors of this cube (if not done yet)
202 // and add the computed neighbors of this cube to the queue
203 addcubeneighbors (other [i], dim, other, &b, neighbors,
204 queue, keep);
205
206 // remove this cube from 'other'
207 if (!quiet)
208 sseq << '0' << other [i] << '\n';
209 other. removenum (i);
210 -- i;
211 }
212
213 // show a temporary progress indicator and reset the counter
214 if (!quiet)
215 scon << '.';
216 count = 0;
217
218 // go through the main set (scan those cubes only that should
219 // be considered for removal), remove cubes which can be removed,
220 // and add their neighbors to the queue
221 for (int_t i = 0; i < cset. size (); ++ i)
222 {
223 // show progress indicator
224 if (!quiet && !(count % 373))
225 scon << std::setw (10) << count <<
226 "\b\b\b\b\b\b\b\b\b\b";
227 ++ count;
228
229 // if this cube should be kept, skip it
230 if (keep. check (cset [i]))
231 continue;
232
233 // clear the neighborbits
234 b. clearall (maxneighbors);
235
236 // prepare a set for storing the neighbors of the cube
238
239 // if the neighborhood of the cube is not acyclic, skip it
240 if (!acyclic (cset [i], dim, makesetunion (maincset,
241 makesetunion (cset, other)),
242 &b, maxneighbors, &neighbors))
243 {
244 continue;
245 }
246
247 // verify if the removal of the cube from X is OK
248 if (!verify (cset [i], makesetunion (maincset,
249 makesetunion (cset, other))))
250 {
251 continue;
252 }
253
254 // remove this cube from the queue
255 queue. remove (cset [i]);
256
257 // determine the neighbors of this cube (if not done yet)
258 // and add the computed neighbors of this cube to the queue;
259 // neighbors in 'maincset' should be skipped, because
260 // they are not considered for reduction anyway
261 addcubeneighbors (cset [i], dim,
262 makesetunion (cset, other),
263 &b, neighbors, queue, keep);
264
265 // remove this cube from 'cset'
266 if (!quiet)
267 sseq << '0' << cset [i] << '\n';
268 cset. removenum (i);
269 -- i;
270 }
271
272 // update the temporary progress indicator and reset the counter
273 if (!quiet)
274 scon << "\b*";
275 count = 0;
276
277 // take cubes from the queue and remove them if possible
278 while (!queue. empty ())
279 {
280 // update the progress indicator
281 if (!quiet && !(count % 373))
282 scon << std::setw (10) << count <<
283 "\b\b\b\b\b\b\b\b\b\b";
284 ++ count;
285
286 // take a cube from the queue and remove it from the queue
287 tCube c = queue [0];
288 queue. removenum (0);
289
290 // clean the neighborbits
291 b. clearall (maxneighbors);
292
293 // debug check: the cube must not be in 'keep' nor 'maincset'
294 if (keep. check (c))
295 throw "A cube from 'keep' found in a reduction queue!";
296 if (maincset. check (c))
297 throw "A cube from 'maincset' found in a reduction queue!";
298
299 // if this cube belongs to the other set...
300 if (other. check (c))
301 {
302 // prepare a set for storing the neighbors
304
305 if (!acyclic_rel (c, dim,
306 makesetunion (maincset, cset), other, &b,
307 maxneighbors, &neighbors, &neighbors))
308 {
309 continue;
310 }
311
312 // verify if the removal of the cube from A is OK
313 if (!verify (c, other))
314 continue;
315
316 // verify if the removal of the cube from X is OK
317 if (!verify (c, makesetunion (maincset,
318 makesetunion (other, cset))))
319 {
320 continue;
321 }
322
323 // determine the neighbors of this cube (if not yet)
324 // and add the computed neighbors to the queue
325 addcubeneighbors (c, dim,
326 makesetunion (cset, other),
327 &b, neighbors, queue, keep);
328
329 // remove the cube from the other set
330 if (!quiet)
331 sseq << '0' << c << '\n';
332 other. remove (c);
333 }
334
335 // otherwise, if this cube belongs to 'cset'...
336 else
337 {
338 // prepare a set for storing the neighbors
340
341 // if the neighborhood of the cube is not acyclic
342 // then skip it
343 if (!acyclic (c, dim, makesetunion (maincset,
344 makesetunion (cset, other)),
345 &b, maxneighbors, &neighbors))
346 {
347 continue;
348 }
349
350 // verify if the removal of the cube from X is OK
351 if (!verify (c, makesetunion (maincset,
352 makesetunion (cset, other))))
353 {
354 continue;
355 }
356
357 // determine the neighbors of this cube (if not yet)
358 // and add the computed neighbors to the queue
359 addcubeneighbors (c, dim,
360 makesetunion (cset, other),
361 &b, neighbors, queue, keep);
362
363 // remove the cube from 'cset'
364 if (!quiet)
365 sseq << '0' << c << '\n';
366 cset. remove (c);
367 }
368 }
369
370 // erase the temporary progress indicator
371 if (!quiet)
372 scon << "\b \b";
373
374 // return the number of cubes removed from both sets
375 return prev - cset. size () - other. size ();
376} /* cubreducequiet */
377
378
379// --------------------------------------------------
380// ------------------ expand cubes ------------------
381// --------------------------------------------------
382
389template <class tCube, class tVerify>
391 const tVerify &verify, bool quiet = false)
392{
393 // if the case is trivial, return the answer
394 if (cset. empty () || other. empty ())
395 return 0;
396
397 // remember the initial number of cubes in the main set
398 int_t prev = cset. size ();
399
400 // determine the space dimension
401 int dim = cset [0]. dim ();
402
403 // compute the maximal number of neighbors of a cube
404 int_t maxneighbors = getmaxneighbors (dim);
405
406 // prepare a bitfield and allocate it if necessary
407 static BitField b;
408 static int_t _maxneighbors = 0;
409 static auto_array<unsigned char> buffer;
410 if (maxneighbors != _maxneighbors)
411 {
412 _maxneighbors = maxneighbors;
413 buffer. reset (new unsigned char [(maxneighbors + 7) >> 3]);
414 b. define (buffer. get (), maxneighbors);
415 }
416
417 // prepare a queue for cubes to check
418 hashedset<tCube> queue;
419
420 // prepare a counter for displaying the progress of computations
421 int_t count = 0;
422
423 // go through the main set, move cubes to the other set
424 // if possible, and add their neighbors to the queue
425 for (int_t i = 0; i < cset. size (); ++ i)
426 {
427 // show progress indicator
428 ++ count;
429 if (!quiet && !(count % 373))
430 scon << std::setw (10) << count <<
431 "\b\b\b\b\b\b\b\b\b\b";
432
433 // take a cube from 'cset'
434 const tCube &c = cset [i];
435
436 // clear the neighborbits
437 b. clearall (maxneighbors);
438
439 // if the neighborhood of the cube is not acyclic, skip it
440 if (!acyclic (c, dim, other, &b, maxneighbors))
441 continue;
442
443 // verify if moving this cube to 'other' is allowed
444 if (!verify (c, cset, other))
445 continue;
446
447 // remove this cube from the queue
448 queue. remove (c);
449
450 // add neighbors from 'cset' to the queue
451 b. clearall (maxneighbors);
452 getneighbors (c, &b, cset, &queue, 0);
453
454 // move the cube to the other set
455 if (!quiet)
456 sseq << "L\n" << '2' << c << '\n';
457 other. add (c);
458 cset. removenum (i);
459 -- i;
460 }
461
462 // show a temporary progress indicator and reset the counter
463 if (!quiet)
464 scon << '*';
465 count = 0;
466
467 // take cubes from the queue and move them from 'cset' to 'other'
468 while (!queue. empty ())
469 {
470 // show progress indicator
471 if (!quiet && !(count % 373))
472 scon << std::setw (10) << count <<
473 "\b\b\b\b\b\b\b\b\b\b";
474 ++ count;
475
476 // take a cube from the queue
477 const tCube c = queue [0];
478 queue. removenum (0);
479
480 // clear the neighborbits
481 b. clearall (maxneighbors);
482
483 // if the neighborhood of the cube is not acyclic, skip it
484 if (!acyclic (c, dim, other, &b, maxneighbors))
485 continue;
486
487 // verify if moving this cube to 'other' is allowed
488 if (!verify (c, cset, other))
489 continue;
490
491 // add the neighbors from 'cset' to the queue
492 b. clearall (maxneighbors);
493 getneighbors (c, &b, cset, &queue, 0);
494
495 // move this cube from 'cset' to 'other'
496 if (!quiet)
497 sseq << "L\n" << '2' << c << '\n';
498 cset. remove (c);
499 other. add (c);
500 }
501
502 // erase the temporary progress indicator
503 if (!quiet)
504 scon << "\b \b";
505
506 // return the number of cubes removed from 'cset'
507 return prev - cset. size ();
508} /* cubexpand */
509
510
511} // namespace reduction1
512} // namespace homology
513} // namespace chomp
514
515#endif // _CHOMP_HOMOLOGY_CUBIRED1_H_
516
518
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
An auto_array template that mimics selected behaviors of the std::auto_ptr template,...
Definition: autoarray.h:54
This class can be used for iterating point's neighbors.
Definition: pointset.h:1450
This file contains some precompiler definitions which indicate the operating system and/or compiler u...
This file contains procedures for the verification of acyclicity of full cubical sets,...
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...
int_t cubexpand(hashedset< tCube > &cset, hashedset< tCube > &other, const tVerify &verify, bool quiet=false)
Expands the set 'other' towards 'cset' without changing the homology of (cset + other,...
Definition: cubired1.h:390
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.
Definition: cubired1.h:78
int_t cubreducequiet(const hashedset< tCube > &maincset, hashedset< tCube > &cset, hashedset< tCube > &other, const hashedset< tCube > &keep, const tVerify &verify, bool quiet=true)
Reduces a pair of sets of cubes for relative homology computation.
Definition: cubired1.h:114
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 getmaxneighbors(int dim)
Returns the maximal number of neighbors of a cube: 3^dim - 1.
Definition: neighbor.h:60
tNeighbors< coordinate > neighbors
The neighbors class with the default type of coordinates.
Definition: pointset.h:84
outputstream scon
The console output stream to which one should put all the junk that spoils the log file,...
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.