The Original CHomP Software
homtools.h
Go to the documentation of this file.
1
3
16
17// Copyright (C) 1997-2020 by Pawel Pilarczyk.
18//
19// This file is part of my research software package. This is free software:
20// you can redistribute it and/or modify it under the terms of the GNU
21// General Public License as published by the Free Software Foundation,
22// either version 3 of the License, or (at your option) any later version.
23//
24// This software is distributed in the hope that it will be useful,
25// but WITHOUT ANY WARRANTY; without even the implied warranty of
26// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27// GNU General Public License for more details.
28//
29// You should have received a copy of the GNU General Public License
30// along with this software; see the file "license.txt". If not,
31// please, see <https://www.gnu.org/licenses/>.
32
33// Started on April 16, 2003. Last revision: June 30, 2007.
34
35
36#ifndef _CHOMP_HOMOLOGY_HOMTOOLS_H_
37#define _CHOMP_HOMOLOGY_HOMTOOLS_H_
38
40#include "chomp/cubes/cubmaps.h"
43
44namespace chomp {
45namespace homology {
46
47
48// --------------------------------------------------
49// ---------------------- READ ----------------------
50// --------------------------------------------------
51
54template <class tCube>
55inline void scancubes (const char *name)
56{
57 if (!name || !*name)
58 return;
59 std::ifstream in (name);
60 if (!in)
61 fileerror (name);
62
63 // read all the cubes contained in the file,
64 // but ignore lines not starting with a parenthesis
65 sout << "Scanning the file '" << name << "' for cubes... ";
66 int_t count = 0;
67 int dim = -19;
68 bool warned = false;
69 ignorecomments (in);
70 while (in)
71 {
72 typename tCube::CoordType c [tCube::MaxDim];
73 if (closingparenthesis (in. peek ()) == EOF)
74 ignoreline (in);
75 else
76 {
77 // read the point from the file
78 int d = readcoordinates (in, c, tCube::MaxDim);
79
80 // verify the dimension of the point
81 if (dim < 0)
82 dim = d;
83 else if ((dim != d) && !warned)
84 {
85 sout << "\nWARNING: Not all the cubes have "
86 "the same dimension.\n";
87 warned = true;
88 }
89
90 // add the point to the point base
91 // and verify its number
92 int_t n = tCube::PointBase::number (c, d);
93 if ((n != count) && !warned)
94 {
95 cube q (c, d);
96 sout << "\nWARNING: Some cubes are "
97 "repeated - " << q <<
98 " for example.\n";
99 warned = true;
100 }
101
102 // count the point
103 ++ count;
104 }
105 ignorecomments (in);
106 }
107 sout << count << " cubes analyzed.\n";
108 return;
109} /* scancubes */
110
116template <class settype>
117void readtheset (const char *name, settype &s, const char *pluralname,
118 const char *what/*, bool digitOk = false*/)
119{
120 // if no file name is given, do nothing
121 if (!name)
122 return;
123
124 // show what you are doing
125 sout << "Reading " << pluralname;
126 if (what)
127 sout << " to " << what;
128 sout << " from '" << name << "'... ";
129
130 // open the file
131 std::ifstream in (name);
132 if (!in)
133 fileerror (name);
134
135 // ignore all the introductory data
136 ignorecomments (in);
137 while (!!in && (closingparenthesis (in. peek ()) == EOF) &&
138 ((in. peek () < '0') || (in. peek () > '9')) &&
139 (in. peek () != '-'))
140 {
141 ignoreline (in);
142 ignorecomments (in);
143 }
144
145 // read the set and show how many elements have been read
146 int_t prev = s. size ();
147 in >> s;
148 sout << (s. size () - prev) << " " << pluralname << " read.\n";
149
150 return;
151} /* readtheset */
152
154template <class cell, class euclidom>
155inline void readcells (const char *name, gcomplex<cell,euclidom> &s,
156 const char *what)
157{
158 readtheset (name, s, cell::pluralname (), what);
159 return;
160} /* readcells */
161
163template <class element>
164inline void readelements (const char *name, hashedset<element> &s,
165 const char *what)
166{
167 readtheset (name, s, element::pluralname (), what);
168 return;
169} /* readelements */
170
173inline void readelements (const char *name, cubes &cub, const char *what)
174{
175 readtheset (name, cub, cube::pluralname (), what);
176 return;
177} /* readelements */
178
180template <class element>
181inline void readmapdomain (const char *name, hashedset<element> &cub)
182{
183 if (!name)
184 return;
185 sout << "Reading the domain of the map from '" << name << "'... ";
186 std::ifstream in (name);
187 if (!in)
188 fileerror (name);
189 int_t prev = cub. size ();
190 readdomain (in, cub);
191 sout << (cub. size () - prev) << " " << element::pluralname () <<
192 " read.\n";
193 return;
194} /* readmapdomain */
195
197template <class element>
198inline void readmapimage (const char *name, hashedset<element> &cub)
199{
200 if (!name)
201 return;
202 sout << "Reading the image of the map from '" << name << "'... ";
203 std::ifstream in (name);
204 if (!in)
205 fileerror (name);
206 int_t prev = cub. size ();
207 readimage (in, cub);
208 sout << (cub. size () - prev) << " " << element::pluralname () <<
209 " read.\n";
210 return;
211} /* readmapimage */
212
215template<class element>
216inline void readmapimage (const char *filename,
217 const hashedset<element> &dom, const char *domname,
219{
220 if (!filename)
221 return;
222 sout << "Reading the image of " << domname << " by the map '" <<
223 filename << "'... ";
224 std::ifstream in (filename);
225 if (!in)
226 fileerror (filename);
227 int_t prev = cub. size ();
228 readimage (in, dom, cub);
229 sout << (cub. size () - prev) << " " << element::pluralname () <<
230 " read.\n";
231 return;
232} /* readmapimage */
233
235template <class element>
237 const char *mapname,
238 const hashedset<element> &Xcubes, const hashedset<element> &Acubes,
239 const char *Xname, const char *purpose = 0)
240{
241 if (!mapname || (Xcubes. empty () && Acubes. empty ()))
242 return;
243 sout << "Reading the map on " << Xname << " from '" << mapname;
244 if (purpose)
245 sout << "' " << purpose << "... ";
246 else
247 sout << "'... ";
248 std::ifstream in (mapname);
249 if (!in)
250 fileerror (mapname);
251 readselective (in, Xcubes, Acubes, Fcubmap);
252 if (Fcubmap. getdomain (). size () !=
253 Xcubes. size () + Acubes. size ())
254 {
255 sout << "\nWARNING: The map is not defined "
256 "on some cubes in " << Xname << ".\n";
257 }
258 else
259 sout << "Done.\n";
260 return;
261} /* readmaprestriction */
262
264template <class element>
266 const char *mapname,
267 const hashedset<element> &Xcubes, const char *Xname,
268 const char *purpose = NULL)
269{
270 hashedset<element> empty;
271 readmaprestriction (Fcubmap, mapname, Xcubes, empty, Xname, purpose);
272 return;
273} /* readmaprestriction */
274
275
276// --------------------------------------------------
277// ---------------------- SAVE ----------------------
278// --------------------------------------------------
279
282template <class settype>
283void savetheset (const char *name, const settype &s, const char *pluralname,
284 const char *what, const char *filecomment = 0)
285{
286 // if no file name is given, do nothing
287 if (!name)
288 return;
289
290 // show what you are doing
291 sout << "Saving " << pluralname;
292 if (what)
293 sout << " in " << what;
294 sout << " to '" << name << "'... ";
295
296 // open the file
297 std::ofstream out (name);
298 if (!out)
299 fileerror (name, "create");
300
301 // save the data
302 if (filecomment)
303 out << filecomment;
304 out << s;
305 if (!out)
306 fileerror (name, "save");
307
308 // show how many elements have been written
309 sout << s. size () << " " << pluralname << " written.\n";
310
311 return;
312} /* writetheset */
313
315template <class cell, class euclidom>
316inline void savecells (const char *name, const gcomplex<cell,euclidom> &s,
317 const char *what, const char *filecomment = 0)
318{
319 savetheset (name, s, cell::pluralname (), what, filecomment);
320 return;
321} /* savecells */
322
324template <class element>
325inline void saveelements (const char *name, const hashedset<element> &s,
326 const char *what, const char *filecomment = 0)
327{
328 savetheset (name, s, element::pluralname (), what, filecomment);
329 return;
330} /* saveelements */
331
334inline void saveelements (const char *name, const cubes &cub,
335 const char *what, const char *filecomment = 0)
336{
337 savetheset (name, cub, cube::pluralname (), what, filecomment);
338 return;
339} /* saveelements */
340
341
342// --------------------------------------------------
343// --------------------- VERIFY ---------------------
344// --------------------------------------------------
345
348template <class cubsettype>
349bool checkinclusion (const cubsettype &Xcubes, const cubsettype &Ycubes,
350 const cubsettype &Bcubes, const char *Xname, const char *YBname)
351{
352 sout << "Verifying if " << Xname << " is contained in " <<
353 YBname << "... ";
354 bool failed = false;
355 for (int_t i = 0; !failed && (i < Xcubes. size ()); ++ i)
356 {
357 if (!Ycubes. check (Xcubes [i]) &&
358 !Bcubes. check (Xcubes [i]))
359 {
360 failed = true;
361 }
362 }
363 if (failed)
364 sout << "Failed.\nWARNING: The set " << Xname <<
365 " is NOT contained in " << YBname << ".\n";
366 else
367 sout << "Passed.\n";
368 return !failed;
369} /* checkinclusion */
370
373template <class cubsettype>
374inline bool checkinclusion (const cubsettype &Xcubes,
375 const cubsettype &Ycubes, const char *Xname, const char *Yname)
376{
377 cubsettype empty;
378 return checkinclusion (Xcubes, Ycubes, empty, Xname, Yname);
379} /* checkinclusion */
380
383template <class maptype, class cubsettype>
384bool checkimagecontained (const maptype &Fcubmap, const cubsettype &Xcubes,
385 const cubsettype &Ycubes, const cubsettype &Bcubes,
386 const char *Xname, const char *Yname)
387{
388 sout << "Verifying if the image of " << Xname <<
389 " is contained in " << Yname << "... ";
390 bool failed = false;
391 for (int_t i = 0; !failed && (i < Xcubes. size ()); ++ i)
392 {
393 if (!Fcubmap. getdomain (). check (Xcubes [i]))
394 continue;
395 const cubsettype &cset = Fcubmap (Xcubes [i]);
396 for (int_t j = 0; !failed && (j < cset. size ()); ++ j)
397 {
398 if (!Ycubes. check (cset [j]) &&
399 !Bcubes. check (cset [j]))
400 {
401 failed = true;
402 }
403 }
404 }
405 if (failed)
406 sout << "Failed.\nWARNING: The image of " << Xname <<
407 " is NOT contained in " << Yname << ".\n";
408 else
409 sout << "Passed.\n";
410 return !failed;
411} /* checkimagecontained */
412
415template <class maptype, class cubsettype>
416inline bool checkimagecontained (const maptype &Fcubmap,
417 const cubsettype &Xcubes, const cubsettype &Ycubes,
418 const char *Xname, const char *Yname)
419{
420 cubsettype empty;
421 return checkimagecontained (Fcubmap, Xcubes, Ycubes, empty,
422 Xname, Yname);
423} /* checkimagecontained */
424
427template <class maptype, class cubsettype>
428bool checkimagedisjoint (const maptype &Fcubmap, const cubsettype &Acubes,
429 const cubsettype &Ycubes, const char *Aname, const char *Yname)
430{
431 sout << "Verifying if the image of " << Aname <<
432 " is disjoint from " << Yname << "... ";
433 bool failed = false;
434 for (int_t i = 0; !failed && (i < Acubes. size ()); ++ i)
435 {
436 if (!Fcubmap. getdomain (). check (Acubes [i]))
437 continue;
438 const cubsettype &cset = Fcubmap (Acubes [i]);
439 for (int_t j = 0; !failed && (j < cset. size ()); ++ j)
440 if (Ycubes. check (cset [j]))
441 failed = true;
442 }
443 if (failed)
444 sout << "Failed.\nSERIOUS WARNING: The image of " << Aname <<
445 " is NOT disjoint from " << Yname << ".\n";
446 else
447 sout << "Passed.\n";
448 return !failed;
449} /* checkimagedisjoint */
450
453template <class tCell, class tCube, class tCoef>
455 const char *Xname)
456{
457 sout << "Verifying if the map on " << Xname << " is acyclic... ";
458
459 // retrieve the domain cell complex and analyze each dimension
460 const gcomplex<tCell,tCoef> &dom = Fcellcubmap. getdomain ();
461 int_t counter = 0;
462 bool failed = false;
463 for (int_t d = 0; !failed && (d <= dom. dim ()); ++ d)
464 {
465 // retrieve the set of cells in this dimension and analyze it
466 const hashedset<tCell> &qset = dom [d];
467 for (int_t i = 0; !failed && (i < qset. size ()); ++ i)
468 {
469 // show progress indicator
470 if (counter && !(counter % 373))
471 scon << std::setw (10) << counter <<
472 "\b\b\b\b\b\b\b\b\b\b";
473 ++ counter;
474
475 // reduce the image of this cell
476 const hashedset<tCube> &img = Fcellcubmap (qset [i]);
477 if (img. size () == 1)
478 continue;
479
480 // if could not be reduced, compute the homology
481 if (!acyclic (img))
482 failed = true;
483 }
484 }
485 if (failed)
486 sout << "Failed.\n*** WARNING: The map on " << Xname <<
487 " is NOT acyclic. ***\n"
488 "*** The result of the computations "
489 "may be totally wrong. ***\n";
490 else
491 sout << "Passed. \n";
492 return !failed;
493} /* checkacyclicmap */
494
495
496// --------------------------------------------------
497// --------------------- REDUCE ---------------------
498// --------------------------------------------------
499
502template <class cubsettype>
503void restrictAtoneighbors (const cubsettype &Xcubes, cubsettype &Acubes,
504 const char *Xname, const char *Aname,
505 const cubsettype *keepcubes = 0)
506{
507 // if the set 'A' is empty, there is no point in doing anything
508 if (Acubes. empty ())
509 return;
510
511 // display the message what is being done now
512 sout << "Restricting " << Aname << " to the neighbors of " <<
513 Xname << "\\" << Aname << "... ";
514
515 // remember the previous number of cubes in 'A'
516 int_t prev = Acubes. size ();
517
518 // if the set 'X' is empty, the result is obvious
519 if (Xcubes. empty ())
520 {
521 cubsettype empty;
522 Acubes = empty;
523 }
524
525 // remove from 'A' these cubes which are not neighbors of 'X'
526 sseq << "D 0\n";
527 for (int_t i = 0; i < Acubes. size (); ++ i)
528 {
529 if (keepcubes && keepcubes -> check (Acubes [i]))
530 continue;
531 if (getneighbors (Acubes [i], 0, Xcubes, 1))
532 continue;
533 sseq << '0' << Acubes [i] << '\n';
534 Acubes. removenum (i);
535 -- i;
536 }
537 sseq << "D 100\n";
538
539 // display the result
540 sout << (prev - Acubes. size ()) << " cubes removed, " <<
541 Acubes. size () << " left.\n";
542
543 return;
544} /* restrictAtoneighbors */
545
547template <class cubsettype>
548void removeAfromX (cubsettype &Xcubes, const cubsettype &Acubes,
549 const char *Xname, const char *Aname)
550{
551 if (Xcubes. empty () || Acubes. empty ())
552 return;
553 sout << "Computing " << Xname << "\\" << Aname << "... ";
554 int_t prev = Xcubes. size ();
555 Xcubes. remove (Acubes);
556 sout << (prev - Xcubes. size ()) << " cubes removed from " <<
557 Xname << ", " << Xcubes. size () << " left.\n";
558 return;
559} /* removeAfromX */
560
562template <class cell, class euclidom>
565 const char *Xname, const char *Aname)
566{
567 if (X. empty () || A. empty ())
568 return;
569 sout << "Computing " << Xname << "\\" << Aname << "... ";
570 int_t prev = X. size ();
571 X. remove (A);
572 sout << (prev - X. size ()) << ' ' << cell::pluralname () <<
573 " removed from " << Xname << ", " << X. size () <<
574 " left.\n";
575 return;
576} /* removeAfromX */
577
579template <class cubsettype>
580void expandAinX (cubsettype &Xcubes, cubsettype &Acubes,
581 const char *Xname, const char *Aname)
582{
583 if (Xcubes. empty () || Acubes. empty ())
584 return;
585 sout << "Expanding " << Aname << " in " << Xname << "... ";
586 int_t count = cubexpand (Xcubes, Acubes);
587 sout << count << " cubes moved to " << Aname << ", " <<
588 Xcubes. size () << " left in " << Xname << "\\" << Aname <<
589 ".\n";
590 return;
591} /* expandAinX */
592
594template <class cubsettype, class maptype>
595void expandAinX (cubsettype &Xcubes, cubsettype &Acubes, cubsettype &Ycubes,
596 cubsettype &Bcubes, const maptype &Fcubmap,
597 const char *Xname, const char *Aname, const char *Bname,
598 bool indexmap, bool checkacyclic)
599{
600 if (Xcubes. empty () || Acubes. empty ())
601 return;
602 sout << "Expanding " << Aname << " in " << Xname << "... ";
603 int_t prevB = Bcubes. size ();
604 int_t prevY = Ycubes. size ();
605 int_t count = cubexpand (Xcubes, Acubes, Ycubes, Bcubes,
606 Fcubmap, indexmap, checkacyclic);
607 sout << count << " moved to " << Aname << ", " << Xcubes. size () <<
608 " left in " << Xname << "\\" << Aname << ", " <<
609 (Bcubes. size () - prevB) << " added to " << Bname << ".\n";
610 if (prevY - Ycubes. size () != Bcubes. size () - prevB)
611 sout << "WARNING: The image of " << Xname << "\\" << Aname <<
612 " was not contained in Y. "
613 "The result can be wrong!\n";
614 return;
615} /* expandAinX */
616
618template <class cubsettype>
619void reducepair (cubsettype &Xcubes, cubsettype &Acubes,
620 const cubsettype &Xkeepcubes, const char *Xname, const char *Aname)
621{
622 if (Xcubes. empty ())
623 return;
624 sout << "Reducing full-dim cubes from ";
625 if (!Acubes. empty ())
626 sout << '(' << Xname << ',' << Aname << ")... ";
627 else
628 sout << Xname << "... ";
629 int_t count = cubreduce (Xcubes, Acubes, Xkeepcubes);
630 sout << count << " removed, " <<
631 (Xcubes. size () + Acubes. size ()) << " left.\n";
632 return;
633} /* reducepair */
634
637template <class maptype, class cubsettype>
638void reducepair (cubsettype &Xcubes, cubsettype &Acubes, maptype &Fcubmap,
639 const cubsettype &Xkeepcubes, const char *Xname, const char *Aname)
640{
641 if (Xcubes. empty ())
642 return;
643 sout << "Reducing cubes from ";
644 if (!Acubes. empty ())
645 sout << '(' << Xname << ',' << Aname << ") [acyclic]... ";
646 else
647 sout << Xname << " [acyclic]... ";
648 int_t count = cubreduce (Xcubes, Acubes, Fcubmap, Xkeepcubes);
649 sout << count << " removed, " <<
650 (Xcubes. size () + Acubes. size ()) << " left.\n";
651 return;
652} /* reducepair */
653
657template <class maptype, class cubsettype>
658void addmapimg (const maptype &Fcubmap, const maptype &FcubmapA,
659 const cubsettype &Xcubes, const cubsettype &Acubes,
660 cubsettype &Ykeepcubes, bool indexmap)
661{
662 if (Fcubmap. getdomain (). empty () &&
663 FcubmapA. getdomain (). empty ())
664 {
665 return;
666 }
667 sout << "Computing the image of the map... ";
668 int_t prev = Ykeepcubes. size ();
669 const cubsettype &Fdomain = Fcubmap. getdomain ();
670 if (!Fdomain. empty ())
671 {
672 if (Fdomain. size () == Xcubes. size ())
673 retrieveimage (Fcubmap, Ykeepcubes);
674 else
675 {
676 int_t n = Xcubes. size ();
677 for (int_t i = 0; i < n; ++ i)
678 Ykeepcubes. add (Fcubmap (Xcubes [i]));
679 }
680 }
681 const cubsettype &FdomainA = FcubmapA. getdomain ();
682 if (!FdomainA. empty ())
683 {
684 if (FdomainA. size () == Acubes. size ())
685 retrieveimage (FcubmapA, Ykeepcubes);
686 else
687 {
688 int_t n = Acubes. size ();
689 for (int_t i = 0; i < n; ++ i)
690 Ykeepcubes. add (FcubmapA (Acubes [i]));
691 }
692 }
693 if (indexmap)
694 {
695 sout << "and of the inclusion... ";
696 Ykeepcubes. add (Xcubes);
697 Ykeepcubes. add (Acubes);
698 }
699 sout << (Ykeepcubes. size () - prev) << " cubes.\n";
700 return;
701} /* addmapimg */
702
705template <class maptype, class cubsettype>
706inline void addmapimg (const maptype &Fcubmap,
707 const cubsettype &Xcubes, const cubsettype &Acubes,
708 cubsettype &Ykeepcubes, bool indexmap)
709{
710 addmapimg (Fcubmap, Fcubmap, Xcubes, Acubes, Ykeepcubes, indexmap);
711 return;
712} /* addmapimg */
713
715template <class tCubes, class tCell, class tCoef>
716void cubes2cells (tCubes &Xcubes, gcomplex<tCell,tCoef> &Xcompl,
717 const char *Xname, bool deletecubes = true)
718{
719 // if there are no cubes to transform, do nothing
720 if (Xcubes. empty ())
721 return;
722
723 // transform cubes into the cells of the same dimension
724 int_t prev = Xcompl. size ();
725 sout << "Transforming " << Xname << " into cells... ";
726 for (int_t i = 0; i < Xcubes. size (); ++ i)
727 Xcompl. add (tCell (Xcubes [i]));
728 sout << (Xcompl. size () - prev) << " cells added.\n";
729
730 // forget the set of cubes if requested to
731 if (deletecubes)
732 {
733 tCubes empty;
734 Xcubes = empty;
735 }
736
737 return;
738} /* cubes2cells */
739
741template <class cell, class euclidom>
744 const char *Xname, const char *Aname, bool addbd = true,
745 bool addcob = false, bool disjoint = true, const int *level = NULL)
746{
747 // say what you are about to do
748 sout << "Collapsing faces in " << Xname;
749 if (!Acompl. empty ())
750 sout << " and " << Aname;
751 sout << "... ";
752
753 // collapse the faces as requested to
754 int_t count = Xcompl. collapse (Acompl, Xkeepcompl,
755 addbd, addcob, disjoint, level);
756
757 // say something about the result
758 sout << (count << 1) << " removed, " <<
759 Xcompl. size () << " left.\n";
760
761 // if something remains in A, say it
762 if (!Acompl. empty ())
763 sout << "There are " << Acompl. size () << " faces "
764 "of dimension up to " << Acompl. dim () <<
765 " left in " << Aname << ".\n";
766
767 return;
768} /* collapse */
769
772template <class cell, class euclidom>
775 const char *Xname, const char *Aname, bool addbd = true,
776 bool addcob = false, bool disjoint = true, const int *level = NULL)
777{
779 collapse (Xcompl, Acompl, empty, Xname, Aname,
780 addbd, addcob, disjoint, level);
781 return;
782} /* collapse */
783
785template <class cell, class euclidom>
787 gcomplex<cell,euclidom> &Xkeepcompl,
788 const char *Xname, bool addbd = true, bool addcob = false,
789 bool disjoint = true, const int *level = NULL)
790{
792 collapse (Xcompl, empty, Xkeepcompl, Xname, "",
793 addbd, addcob, disjoint, level);
794 return;
795} /* collapse */
796
799template <class cell, class euclidom>
801 const char *Xname, bool addbd = true, bool addcob = false,
802 bool disjoint = true, const int *level = NULL)
803{
805 collapse (Xcompl, empty, empty, Xname, "",
806 addbd, addcob, disjoint, level);
807 return;
808} /* collapse */
809
812template <class cell, class euclidom>
814 int dim, const char *name)
815{
816 if (Acompl. dim () <= dim)
817 return;
818 if (dim < 0)
819 dim = 0;
820 sout << "Adding to " << name << " boundaries of high-dim " <<
821 cell::pluralname () << "... ";
822 int_t howmany = 0;
823 for (int i = Acompl. dim (); i > dim; -- i)
824 {
825 sout << '.';
826 howmany += Acompl. addboundaries (i);
827 Acompl. removeall (i);
828 }
829 sout << ' ' << howmany << " added.\n";
830 return;
831} /* decreasedimension */
832
834template <class cell, class euclidom>
837 int minlevel, bool bothsets, const char *Xname, const char *Aname)
838{
839 // if there are no cells in the complex, there is nothing to do
840 if (Xcompl. empty ())
841 return;
842
843 // say what you are doing
844 sout << "Adding boundaries of " << cell::pluralname () << " in ";
845 if (!Acompl. empty ())
846 sout << Xname << " and " << Aname << "... ";
847 else
848 sout << Xname << "... ";
849
850 // add the boundaries and count the number of added cells
851 int_t howmany = 0;
852 for (int i = Xcompl. dim (); (i >= minlevel) && i; -- i)
853 {
854 if (bothsets)
855 {
856 howmany += Xcompl. addboundaries (i, true);
857 if (Acompl. dim () >= i)
858 howmany += Acompl. addboundaries (i,
859 true);
860 }
861 else
862 howmany += Xcompl. addboundaries (i, Acompl);
863 }
864
865 // show the total number of added cells
866 sout << howmany << ' ' << cell::pluralname () << " added.\n";
867 return;
868} /* addboundaries */
869
870// Add boundaries to X or to X and A.
871//void addboundaries (cubicalcomplex &Xcompl, cubicalcomplex &Acompl,
872// int minlevel, bool bothsets, const char *Xname, const char *Aname);
873
874// Add boundaries to X or to X and A.
875//void addboundaries (simplicialcomplex &Xcompl, simplicialcomplex &Acompl,
876// int minlevel, bool bothsets, const char *Xname, const char *Aname);
877
878
879// --------------------------------------------------
880// ---------------- READ BITMAP FILE ----------------
881// --------------------------------------------------
882
890template <class tCube>
891int ReadBitmapFile (const char *bmpname, hashedset<tCube> &cset,
892 int mingray = 0, int maxgray = 128)
893{
894 // prepare a bitmap file with the vertical axis like in mathematics
895 bmpfile bmp;
896 bmp. invertedpicture ();
897
898 // open the bitmap file
899 if (bmp. open (bmpname) < 0)
900 fileerror (bmpname);
901
902 // scan the picture and produce the list of hypercubes
903 coordinate c [2];
904 for (c [1] = 0; c [1] < bmp. picture_height (); ++ (c [1]))
905 {
906 for (c [0] = 0; c [0] < bmp. picture_width (); ++ (c [0]))
907 {
908 long color = bmp. getpixel (c [0], c [1]);
909 long gray = (77 * ((color & 0xFF0000) >> 16) +
910 154 * ((color & 0xFF00) >> 8) +
911 25 * (color & 0xFF)) >> 8;
912 if ((gray >= mingray) && (gray <= maxgray))
913 cset. add (tCube (c, 2));
914 }
915 }
916
917 return 0;
918} /* ReadBitmapFile */
919
920
921} // namespace homology
922} // namespace chomp
923
924#endif // _CHOMP_HOMOLOGY_HOMTOOLS_H
925
927
This file contains the definition of a class which can be used as a simple interface to read and writ...
The class 'bmpfile' is an elementary interface that can be used to read or create and write images in...
Definition: bitmaps.h:67
The class that defines a geometric complex - a set of cells (cubes, simplices, etc).
Definition: gcomplex.h:85
This is a template for a set of objects of the given type.
Definition: hashsets.h:185
This class represents a multivalued map whose domain is a geometric complex.
Definition: gcomplex.h:1530
This class defines a multivalued map.
Definition: hashsets.h:945
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
static const char * pluralname()
Returns the plural name of the objects represented by this class.
Definition: cubebase.h:262
This file contains an interface to procedures for full cubical reduction.
This file contains some procedures defined for cubical maps.
int int_t
Index type for indexing arrays, counting cubes, etc.
Definition: config.h:115
outputstream sseq
An auxiliary stream which captures sequences of processed data.
void readmapdomain(const char *name, hashedset< element > &cub)
Reads the domain of a cubical multivalued map from the given file.
Definition: homtools.h:181
void saveelements(const char *name, const hashedset< element > &s, const char *what, const char *filecomment=0)
Uses the general procedure "savetheset" to save a set of elements.
Definition: homtools.h:325
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 checkimagecontained(const maptype &Fcubmap, const cubsettype &Xcubes, const cubsettype &Ycubes, const cubsettype &Bcubes, const char *Xname, const char *Yname)
Checks if the image of X by F is contained in the union of Y and B.
Definition: homtools.h:384
void ignoreline(std::istream &in)
Ignores the input characters until the end of a line, including this end of the line.
Definition: textfile.h:376
outputstream sout
A replacement for standard output stream, with optional logging and other features provided by the cl...
int closingparenthesis(int ch)
Returns the matching closing parenthesis for the given opening one or EOF if none.
Definition: textfile.h:411
void readmaprestriction(mvmap< element, element > &Fcubmap, const char *mapname, const hashedset< element > &Xcubes, const hashedset< element > &Acubes, const char *Xname, const char *purpose=0)
Reads the restriction of a multivalued map to the union of two sets.
Definition: homtools.h:236
void fileerror(const char *filename, const char *what="open")
Throws a message about the inability to do something with a file.
Definition: textfile.h:532
void reducepair(cubsettype &Xcubes, cubsettype &Acubes, const cubsettype &Xkeepcubes, const char *Xname, const char *Aname)
Reduces the pair of sets of cubes. Keeps the given cubes untouched.
Definition: homtools.h:619
int ReadBitmapFile(const char *bmpname, hashedset< tCube > &cset, int mingray=0, int maxgray=128)
Reads the squares from a bitmap file to the set of cubes.
Definition: homtools.h:891
void cubes2cells(tCubes &Xcubes, gcomplex< tCell, tCoef > &Xcompl, const char *Xname, bool deletecubes=true)
Transforms cubes to full-dimensional cells.
Definition: homtools.h:716
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
bool checkinclusion(const cubsettype &Xcubes, const cubsettype &Ycubes, const cubsettype &Bcubes, const char *Xname, const char *YBname)
Checks if X is a subset of the union of Y and B.
Definition: homtools.h:349
std::istream & readimage(std::istream &in, hashedset< tCube > &img)
Reads the image of a multivalued cubical map.
Definition: cubmaps.h:437
void readtheset(const char *name, settype &s, const char *pluralname, const char *what)
Reads a given set from the file and shows appropriate messages.
Definition: homtools.h:117
void collapse(gcomplex< cell, euclidom > &Xcompl, gcomplex< cell, euclidom > &Acompl, gcomplex< cell, euclidom > &Xkeepcompl, const char *Xname, const char *Aname, bool addbd=true, bool addcob=false, bool disjoint=true, const int *level=NULL)
Collapses a pair of geometric complexes.
Definition: homtools.h:742
int_t cubexpand(hashedset< tCube > &cset, hashedset< tCube > &other, bool quiet=false)
Expands the set 'other' towards 'cset' without changing the homology of (cset + other,...
Definition: cubisets.h:153
bool checkacyclicmap(const mvcellmap< tCell, tCoef, tCube > &Fcellcubmap, const char *Xname)
Checks if the image of each element of the domain of this map is acyclic.
Definition: homtools.h:454
void savetheset(const char *name, const settype &s, const char *pluralname, const char *what, const char *filecomment=0)
Saves a given set to a file and shows appropriate messages.
Definition: homtools.h:283
short int coordinate
The default type of coordinates.
Definition: pointset.h:63
int readcoordinates(std::istream &in, coordtype *coord, int maxdim, int closing)
Reads the coordinates of a point.
Definition: pointset.h:2073
void readcells(const char *name, gcomplex< cell, euclidom > &s, const char *what)
Uses the general procedure "readtheset" to read a geometric complex.
Definition: homtools.h:155
void expandAinX(cubsettype &Xcubes, cubsettype &Acubes, const char *Xname, const char *Aname)
Expands the other element of the pair into the main portion of the set.
Definition: homtools.h:580
std::istream & readselective(std::istream &in, const hashedset< tCube > &dom1, const hashedset< tCube > &dom2, mvmap< tCube, tCube > &m)
Reads the restriction of a multivalued map to the given pair of sets.
Definition: cubmaps.h:598
void readmapimage(const char *name, hashedset< element > &cub)
Reads the domain of a cubical multivalued map from the given file.
Definition: homtools.h:198
hashedset< imgelement > & retrieveimage(const mvmap< domelement, imgelement > &m, hashedset< imgelement > &img)
Adds images of all the elements from the domain of the map to 'img'.
Definition: hashsets.h:1128
bool checkimagedisjoint(const maptype &Fcubmap, const cubsettype &Acubes, const cubsettype &Ycubes, const char *Aname, const char *Yname)
Checks if the image of A by F is disjoint from Y (actually, from Y\B).
Definition: homtools.h:428
void decreasedimension(gcomplex< cell, euclidom > &Acompl, int dim, const char *name)
Decreases the dimension of the geometric complex by adding boundary cells to all the cells on higher ...
Definition: homtools.h:813
outputstream scon
The console output stream to which one should put all the junk that spoils the log file,...
void readelements(const char *name, hashedset< element > &s, const char *what)
Uses the general procedure "readtheset" to read a set of elements.
Definition: homtools.h:164
void ignorecomments(std::istream &in)
Ignores white characters (spaces, tabulators, CRs and LFs), as well as comments from the input text f...
Definition: textfile.h:385
void restrictAtoneighbors(const cubsettype &Xcubes, cubsettype &Acubes, const char *Xname, const char *Aname, const cubsettype *keepcubes=0)
Restricts the set of cubes 'Acubes' to these cubes which are neighbors of any of the cubes in 'Xcubes...
Definition: homtools.h:503
void removeAfromX(cubsettype &Xcubes, const cubsettype &Acubes, const char *Xname, const char *Aname)
Removes 'Acubes' from 'Xcubes' and shows messages.
Definition: homtools.h:548
void addmapimg(const maptype &Fcubmap, const maptype &FcubmapA, const cubsettype &Xcubes, const cubsettype &Acubes, cubsettype &Ykeepcubes, bool indexmap)
Adds the images of both maps to the set of cubes to be kept.
Definition: homtools.h:658
void savecells(const char *name, const gcomplex< cell, euclidom > &s, const char *what, const char *filecomment=0)
Uses the general procedure "savetheset" to save a geometric complex.
Definition: homtools.h:316
std::istream & readdomain(std::istream &in, hashedset< tCube > &dom)
Reads the domain of a multivalued cubical map.
Definition: cubmaps.h:406
int_t cubreduce(hashedset< tCube > &cset, hashedset< tCube > &other, mvmap< tCube, tCube > &cubmap, const hashedset< tCube > &keep)
Reduces a pair of sets of cubes for relative homology computation.
Definition: cubisets.h:91
void scancubes(const char *name)
Reads all the cubes from the given file and ignores them.
Definition: homtools.h:55
This namespace contains the entire CHomP library interface.
Definition: bitmaps.h:51
This file contains the definition of a class which represents a simplex.