00001
00002
00003
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #ifndef _CHOMP_HOMOLOGY_HOMTOOLS_H_
00038 #define _CHOMP_HOMOLOGY_HOMTOOLS_H_
00039
00040 #include "chomp/homology/cubisets.h"
00041 #include "chomp/cubes/cubmaps.h"
00042 #include "chomp/simplices/simplex.h"
00043 #include "chomp/bitmaps/bitmaps.h"
00044
00045 namespace chomp {
00046 namespace homology {
00047
00048
00049
00050
00051
00052
00055 template <class tCube>
00056 inline void scancubes (const char *name)
00057 {
00058 if (!name || !*name)
00059 return;
00060 std::ifstream in (name);
00061 if (!in)
00062 fileerror (name);
00063
00064
00065
00066 sout << "Scanning the file '" << name << "' for cubes... ";
00067 int_t count = 0;
00068 int dim = -19;
00069 bool warned = false;
00070 ignorecomments (in);
00071 while (in)
00072 {
00073 typename tCube::CoordType c [tCube::MaxDim];
00074 if (closingparenthesis (in. peek ()) == EOF)
00075 ignoreline (in);
00076 else
00077 {
00078
00079 int d = readcoordinates (in, c, tCube::MaxDim);
00080
00081
00082 if (dim < 0)
00083 dim = d;
00084 else if ((dim != d) && !warned)
00085 {
00086 sout << "\nWARNING: Not all the cubes have "
00087 "the same dimension.\n";
00088 warned = true;
00089 }
00090
00091
00092
00093 int_t n = tCube::PointBase::number (c, d);
00094 if ((n != count) && !warned)
00095 {
00096 cube q (c, d);
00097 sout << "\nWARNING: Some cubes are "
00098 "repeated - " << q <<
00099 " for example.\n";
00100 warned = true;
00101 }
00102
00103
00104 ++ count;
00105 }
00106 ignorecomments (in);
00107 }
00108 sout << count << " cubes analyzed.\n";
00109 return;
00110 }
00111
00117 template <class settype>
00118 void readtheset (const char *name, settype &s, const char *pluralname,
00119 const char *what)
00120 {
00121
00122 if (!name)
00123 return;
00124
00125
00126 sout << "Reading " << pluralname;
00127 if (what)
00128 sout << " to " << what;
00129 sout << " from '" << name << "'... ";
00130
00131
00132 std::ifstream in (name);
00133 if (!in)
00134 fileerror (name);
00135
00136
00137 ignorecomments (in);
00138 while (!!in && (closingparenthesis (in. peek ()) == EOF) &&
00139 ((in. peek () < '0') || (in. peek () > '9')) &&
00140 (in. peek () != '-'))
00141 {
00142 ignoreline (in);
00143 ignorecomments (in);
00144 }
00145
00146
00147 int_t prev = s. size ();
00148 in >> s;
00149 sout << (s. size () - prev) << " " << pluralname << " read.\n";
00150
00151 return;
00152 }
00153
00155 template <class cell, class euclidom>
00156 inline void readcells (const char *name, gcomplex<cell,euclidom> &s,
00157 const char *what)
00158 {
00159 readtheset (name, s, cell::pluralname (), what);
00160 return;
00161 }
00162
00164 template <class element>
00165 inline void readelements (const char *name, hashedset<element> &s,
00166 const char *what)
00167 {
00168 readtheset (name, s, element::pluralname (), what);
00169 return;
00170 }
00171
00174 inline void readelements (const char *name, cubes &cub, const char *what)
00175 {
00176 readtheset (name, cub, cube::pluralname (), what);
00177 return;
00178 }
00179
00181 template <class element>
00182 inline void readmapdomain (const char *name, hashedset<element> &cub)
00183 {
00184 if (!name)
00185 return;
00186 sout << "Reading the domain of the map from '" << name << "'... ";
00187 std::ifstream in (name);
00188 if (!in)
00189 fileerror (name);
00190 int_t prev = cub. size ();
00191 readdomain (in, cub);
00192 sout << (cub. size () - prev) << " " << element::pluralname () <<
00193 " read.\n";
00194 return;
00195 }
00196
00198 template <class element>
00199 inline void readmapimage (const char *name, hashedset<element> &cub)
00200 {
00201 if (!name)
00202 return;
00203 sout << "Reading the image of the map from '" << name << "'... ";
00204 std::ifstream in (name);
00205 if (!in)
00206 fileerror (name);
00207 int_t prev = cub. size ();
00208 readimage (in, cub);
00209 sout << (cub. size () - prev) << " " << element::pluralname () <<
00210 " read.\n";
00211 return;
00212 }
00213
00216 template<class element>
00217 inline void readmapimage (const char *filename,
00218 const hashedset<element> &dom, const char *domname,
00219 hashedset<element> &cub)
00220 {
00221 if (!filename)
00222 return;
00223 sout << "Reading the image of " << domname << " by the map '" <<
00224 filename << "'... ";
00225 std::ifstream in (filename);
00226 if (!in)
00227 fileerror (filename);
00228 int_t prev = cub. size ();
00229 readimage (in, dom, cub);
00230 sout << (cub. size () - prev) << " " << element::pluralname () <<
00231 " read.\n";
00232 return;
00233 }
00234
00236 template <class element>
00237 inline void readmaprestriction (mvmap<element,element> &Fcubmap,
00238 const char *mapname,
00239 const hashedset<element> &Xcubes, const hashedset<element> &Acubes,
00240 const char *Xname, const char *purpose = 0)
00241 {
00242 if (!mapname || (Xcubes. empty () && Acubes. empty ()))
00243 return;
00244 sout << "Reading the map on " << Xname << " from '" << mapname;
00245 if (purpose)
00246 sout << "' " << purpose << "... ";
00247 else
00248 sout << "'... ";
00249 std::ifstream in (mapname);
00250 if (!in)
00251 fileerror (mapname);
00252 readselective (in, Xcubes, Acubes, Fcubmap);
00253 if (Fcubmap. getdomain (). size () !=
00254 Xcubes. size () + Acubes. size ())
00255 {
00256 sout << "\nWARNING: The map is not defined "
00257 "on some cubes in " << Xname << ".\n";
00258 }
00259 else
00260 sout << "Done.\n";
00261 return;
00262 }
00263
00265 template <class element>
00266 inline void readmaprestriction (mvmap<element,element> &Fcubmap,
00267 const char *mapname,
00268 const hashedset<element> &Xcubes, const char *Xname,
00269 const char *purpose = NULL)
00270 {
00271 hashedset<element> empty;
00272 readmaprestriction (Fcubmap, mapname, Xcubes, empty, Xname, purpose);
00273 return;
00274 }
00275
00276
00277
00278
00279
00280
00283 template <class settype>
00284 void savetheset (const char *name, const settype &s, const char *pluralname,
00285 const char *what, const char *filecomment = 0)
00286 {
00287
00288 if (!name)
00289 return;
00290
00291
00292 sout << "Saving " << pluralname;
00293 if (what)
00294 sout << " in " << what;
00295 sout << " to '" << name << "'... ";
00296
00297
00298 std::ofstream out (name);
00299 if (!out)
00300 fileerror (name, "create");
00301
00302
00303 if (filecomment)
00304 out << filecomment;
00305 out << s;
00306 if (!out)
00307 fileerror (name, "save");
00308
00309
00310 sout << s. size () << " " << pluralname << " written.\n";
00311
00312 return;
00313 }
00314
00316 template <class cell, class euclidom>
00317 inline void savecells (const char *name, const gcomplex<cell,euclidom> &s,
00318 const char *what, const char *filecomment = 0)
00319 {
00320 savetheset (name, s, cell::pluralname (), what, filecomment);
00321 return;
00322 }
00323
00325 template <class element>
00326 inline void saveelements (const char *name, const hashedset<element> &s,
00327 const char *what, const char *filecomment = 0)
00328 {
00329 savetheset (name, s, element::pluralname (), what, filecomment);
00330 return;
00331 }
00332
00335 inline void saveelements (const char *name, const cubes &cub,
00336 const char *what, const char *filecomment = 0)
00337 {
00338 savetheset (name, cub, cube::pluralname (), what, filecomment);
00339 return;
00340 }
00341
00342
00343
00344
00345
00346
00349 template <class cubsettype>
00350 bool checkinclusion (const cubsettype &Xcubes, const cubsettype &Ycubes,
00351 const cubsettype &Bcubes, const char *Xname, const char *YBname)
00352 {
00353 sout << "Verifying if " << Xname << " is contained in " <<
00354 YBname << "... ";
00355 bool failed = false;
00356 for (int_t i = 0; !failed && (i < Xcubes. size ()); ++ i)
00357 {
00358 if (!Ycubes. check (Xcubes [i]) &&
00359 !Bcubes. check (Xcubes [i]))
00360 {
00361 failed = true;
00362 }
00363 }
00364 if (failed)
00365 sout << "Failed.\nWARNING: The set " << Xname <<
00366 " is NOT contained in " << YBname << ".\n";
00367 else
00368 sout << "Passed.\n";
00369 return !failed;
00370 }
00371
00374 template <class cubsettype>
00375 inline bool checkinclusion (const cubsettype &Xcubes,
00376 const cubsettype &Ycubes, const char *Xname, const char *Yname)
00377 {
00378 cubsettype empty;
00379 return checkinclusion (Xcubes, Ycubes, empty, Xname, Yname);
00380 }
00381
00384 template <class maptype, class cubsettype>
00385 bool checkimagecontained (const maptype &Fcubmap, const cubsettype &Xcubes,
00386 const cubsettype &Ycubes, const cubsettype &Bcubes,
00387 const char *Xname, const char *Yname)
00388 {
00389 sout << "Verifying if the image of " << Xname <<
00390 " is contained in " << Yname << "... ";
00391 bool failed = false;
00392 for (int_t i = 0; !failed && (i < Xcubes. size ()); ++ i)
00393 {
00394 if (!Fcubmap. getdomain (). check (Xcubes [i]))
00395 continue;
00396 const cubsettype &cset = Fcubmap (Xcubes [i]);
00397 for (int_t j = 0; !failed && (j < cset. size ()); ++ j)
00398 {
00399 if (!Ycubes. check (cset [j]) &&
00400 !Bcubes. check (cset [j]))
00401 {
00402 failed = true;
00403 }
00404 }
00405 }
00406 if (failed)
00407 sout << "Failed.\nWARNING: The image of " << Xname <<
00408 " is NOT contained in " << Yname << ".\n";
00409 else
00410 sout << "Passed.\n";
00411 return !failed;
00412 }
00413
00416 template <class maptype, class cubsettype>
00417 inline bool checkimagecontained (const maptype &Fcubmap,
00418 const cubsettype &Xcubes, const cubsettype &Ycubes,
00419 const char *Xname, const char *Yname)
00420 {
00421 cubsettype empty;
00422 return checkimagecontained (Fcubmap, Xcubes, Ycubes, empty,
00423 Xname, Yname);
00424 }
00425
00428 template <class maptype, class cubsettype>
00429 bool checkimagedisjoint (const maptype &Fcubmap, const cubsettype &Acubes,
00430 const cubsettype &Ycubes, const char *Aname, const char *Yname)
00431 {
00432 sout << "Verifying if the image of " << Aname <<
00433 " is disjoint from " << Yname << "... ";
00434 bool failed = false;
00435 for (int_t i = 0; !failed && (i < Acubes. size ()); ++ i)
00436 {
00437 if (!Fcubmap. getdomain (). check (Acubes [i]))
00438 continue;
00439 const cubsettype &cset = Fcubmap (Acubes [i]);
00440 for (int_t j = 0; !failed && (j < cset. size ()); ++ j)
00441 if (Ycubes. check (cset [j]))
00442 failed = true;
00443 }
00444 if (failed)
00445 sout << "Failed.\nSERIOUS WARNING: The image of " << Aname <<
00446 " is NOT disjoint from " << Yname << ".\n";
00447 else
00448 sout << "Passed.\n";
00449 return !failed;
00450 }
00451
00454 template <class tCell, class tCube, class tCoef>
00455 bool checkacyclicmap (const mvcellmap<tCell,tCoef,tCube> &Fcellcubmap,
00456 const char *Xname)
00457 {
00458 sout << "Verifying if the map on " << Xname << " is acyclic... ";
00459
00460
00461 const gcomplex<tCell,tCoef> &dom = Fcellcubmap. getdomain ();
00462 int_t counter = 0;
00463 bool failed = false;
00464 for (int_t d = 0; !failed && (d <= dom. dim ()); ++ d)
00465 {
00466
00467 const hashedset<tCell> &qset = dom [d];
00468 for (int_t i = 0; !failed && (i < qset. size ()); ++ i)
00469 {
00470
00471 if (counter && !(counter % 373))
00472 scon << std::setw (10) << counter <<
00473 "\b\b\b\b\b\b\b\b\b\b";
00474 ++ counter;
00475
00476
00477 const hashedset<tCube> &img = Fcellcubmap (qset [i]);
00478 if (img. size () == 1)
00479 continue;
00480
00481
00482 if (!acyclic (img))
00483 failed = true;
00484 }
00485 }
00486 if (failed)
00487 sout << "Failed.\n*** WARNING: The map on " << Xname <<
00488 " is NOT acyclic. ***\n"
00489 "*** The result of the computations "
00490 "may be totally wrong. ***\n";
00491 else
00492 sout << "Passed. \n";
00493 return !failed;
00494 }
00495
00496
00497
00498
00499
00500
00503 template <class cubsettype>
00504 void restrictAtoneighbors (const cubsettype &Xcubes, cubsettype &Acubes,
00505 const char *Xname, const char *Aname,
00506 const cubsettype *keepcubes = 0)
00507 {
00508
00509 if (Acubes. empty ())
00510 return;
00511
00512
00513 sout << "Restricting " << Aname << " to the neighbors of " <<
00514 Xname << "\\" << Aname << "... ";
00515
00516
00517 int_t prev = Acubes. size ();
00518
00519
00520 if (Xcubes. empty ())
00521 {
00522 cubsettype empty;
00523 Acubes = empty;
00524 }
00525
00526
00527 sseq << "D 0\n";
00528 for (int_t i = 0; i < Acubes. size (); ++ i)
00529 {
00530 if (keepcubes && keepcubes -> check (Acubes [i]))
00531 continue;
00532 if (getneighbors (Acubes [i], 0, Xcubes, 1))
00533 continue;
00534 sseq << '0' << Acubes [i] << '\n';
00535 Acubes. removenum (i);
00536 -- i;
00537 }
00538 sseq << "D 100\n";
00539
00540
00541 sout << (prev - Acubes. size ()) << " cubes removed, " <<
00542 Acubes. size () << " left.\n";
00543
00544 return;
00545 }
00546
00548 template <class cubsettype>
00549 void removeAfromX (cubsettype &Xcubes, const cubsettype &Acubes,
00550 const char *Xname, const char *Aname)
00551 {
00552 if (Xcubes. empty () || Acubes. empty ())
00553 return;
00554 sout << "Computing " << Xname << "\\" << Aname << "... ";
00555 int_t prev = Xcubes. size ();
00556 Xcubes. remove (Acubes);
00557 sout << (prev - Xcubes. size ()) << " cubes removed from " <<
00558 Xname << ", " << Xcubes. size () << " left.\n";
00559 return;
00560 }
00561
00563 template <class cell, class euclidom>
00564 void removeAfromX (gcomplex<cell,euclidom> &X,
00565 const gcomplex<cell,euclidom> &A,
00566 const char *Xname, const char *Aname)
00567 {
00568 if (X. empty () || A. empty ())
00569 return;
00570 sout << "Computing " << Xname << "\\" << Aname << "... ";
00571 int_t prev = X. size ();
00572 X. remove (A);
00573 sout << (prev - X. size ()) << ' ' << cell::pluralname () <<
00574 " removed from " << Xname << ", " << X. size () <<
00575 " left.\n";
00576 return;
00577 }
00578
00580 template <class cubsettype>
00581 void expandAinX (cubsettype &Xcubes, cubsettype &Acubes,
00582 const char *Xname, const char *Aname)
00583 {
00584 if (Xcubes. empty () || Acubes. empty ())
00585 return;
00586 sout << "Expanding " << Aname << " in " << Xname << "... ";
00587 int_t count = cubexpand (Xcubes, Acubes);
00588 sout << count << " cubes moved to " << Aname << ", " <<
00589 Xcubes. size () << " left in " << Xname << "\\" << Aname <<
00590 ".\n";
00591 return;
00592 }
00593
00595 template <class cubsettype, class maptype>
00596 void expandAinX (cubsettype &Xcubes, cubsettype &Acubes, cubsettype &Ycubes,
00597 cubsettype &Bcubes, const maptype &Fcubmap,
00598 const char *Xname, const char *Aname, const char *Bname,
00599 bool indexmap, bool checkacyclic)
00600 {
00601 if (Xcubes. empty () || Acubes. empty ())
00602 return;
00603 sout << "Expanding " << Aname << " in " << Xname << "... ";
00604 int_t prevB = Bcubes. size ();
00605 int_t prevY = Ycubes. size ();
00606 int_t count = cubexpand (Xcubes, Acubes, Ycubes, Bcubes,
00607 Fcubmap, indexmap, checkacyclic);
00608 sout << count << " moved to " << Aname << ", " << Xcubes. size () <<
00609 " left in " << Xname << "\\" << Aname << ", " <<
00610 (Bcubes. size () - prevB) << " added to " << Bname << ".\n";
00611 if (prevY - Ycubes. size () != Bcubes. size () - prevB)
00612 sout << "WARNING: The image of " << Xname << "\\" << Aname <<
00613 " was not contained in Y. "
00614 "The result can be wrong!\n";
00615 return;
00616 }
00617
00619 template <class cubsettype>
00620 void reducepair (cubsettype &Xcubes, cubsettype &Acubes,
00621 const cubsettype &Xkeepcubes, const char *Xname, const char *Aname)
00622 {
00623 if (Xcubes. empty ())
00624 return;
00625 sout << "Reducing full-dim cubes from ";
00626 if (!Acubes. empty ())
00627 sout << '(' << Xname << ',' << Aname << ")... ";
00628 else
00629 sout << Xname << "... ";
00630 int_t count = cubreduce (Xcubes, Acubes, Xkeepcubes);
00631 sout << count << " removed, " <<
00632 (Xcubes. size () + Acubes. size ()) << " left.\n";
00633 return;
00634 }
00635
00638 template <class maptype, class cubsettype>
00639 void reducepair (cubsettype &Xcubes, cubsettype &Acubes, maptype &Fcubmap,
00640 const cubsettype &Xkeepcubes, const char *Xname, const char *Aname)
00641 {
00642 if (Xcubes. empty ())
00643 return;
00644 sout << "Reducing cubes from ";
00645 if (!Acubes. empty ())
00646 sout << '(' << Xname << ',' << Aname << ") [acyclic]... ";
00647 else
00648 sout << Xname << " [acyclic]... ";
00649 int_t count = cubreduce (Xcubes, Acubes, Fcubmap, Xkeepcubes);
00650 sout << count << " removed, " <<
00651 (Xcubes. size () + Acubes. size ()) << " left.\n";
00652 return;
00653 }
00654
00658 template <class maptype, class cubsettype>
00659 void addmapimg (const maptype &Fcubmap, const maptype &FcubmapA,
00660 const cubsettype &Xcubes, const cubsettype &Acubes,
00661 cubsettype &Ykeepcubes, bool indexmap)
00662 {
00663 if (Fcubmap. getdomain (). empty () &&
00664 FcubmapA. getdomain (). empty ())
00665 {
00666 return;
00667 }
00668 sout << "Computing the image of the map... ";
00669 int_t prev = Ykeepcubes. size ();
00670 const cubsettype &Fdomain = Fcubmap. getdomain ();
00671 if (!Fdomain. empty ())
00672 {
00673 if (Fdomain. size () == Xcubes. size ())
00674 retrieveimage (Fcubmap, Ykeepcubes);
00675 else
00676 {
00677 int_t n = Xcubes. size ();
00678 for (int_t i = 0; i < n; ++ i)
00679 Ykeepcubes. add (Fcubmap (Xcubes [i]));
00680 }
00681 }
00682 const cubsettype &FdomainA = FcubmapA. getdomain ();
00683 if (!FdomainA. empty ())
00684 {
00685 if (FdomainA. size () == Acubes. size ())
00686 retrieveimage (FcubmapA, Ykeepcubes);
00687 else
00688 {
00689 int_t n = Acubes. size ();
00690 for (int_t i = 0; i < n; ++ i)
00691 Ykeepcubes. add (FcubmapA (Acubes [i]));
00692 }
00693 }
00694 if (indexmap)
00695 {
00696 sout << "and of the inclusion... ";
00697 Ykeepcubes. add (Xcubes);
00698 Ykeepcubes. add (Acubes);
00699 }
00700 sout << (Ykeepcubes. size () - prev) << " cubes.\n";
00701 return;
00702 }
00703
00706 template <class maptype, class cubsettype>
00707 inline void addmapimg (const maptype &Fcubmap,
00708 const cubsettype &Xcubes, const cubsettype &Acubes,
00709 cubsettype &Ykeepcubes, bool indexmap)
00710 {
00711 addmapimg (Fcubmap, Fcubmap, Xcubes, Acubes, Ykeepcubes, indexmap);
00712 return;
00713 }
00714
00716 template <class tCubes, class tCell, class tCoef>
00717 void cubes2cells (tCubes &Xcubes, gcomplex<tCell,tCoef> &Xcompl,
00718 const char *Xname, bool deletecubes = true)
00719 {
00720
00721 if (Xcubes. empty ())
00722 return;
00723
00724
00725 int_t prev = Xcompl. size ();
00726 sout << "Transforming " << Xname << " into cells... ";
00727 for (int_t i = 0; i < Xcubes. size (); ++ i)
00728 Xcompl. add (tCell (Xcubes [i]));
00729 sout << (Xcompl. size () - prev) << " cells added.\n";
00730
00731
00732 if (deletecubes)
00733 {
00734 tCubes empty;
00735 Xcubes = empty;
00736 }
00737
00738 return;
00739 }
00740
00742 template <class cell, class euclidom>
00743 void collapse (gcomplex<cell,euclidom> &Xcompl,
00744 gcomplex<cell,euclidom> &Acompl, gcomplex<cell,euclidom> &Xkeepcompl,
00745 const char *Xname, const char *Aname, bool addbd = true,
00746 bool addcob = false, bool disjoint = true, const int *level = NULL)
00747 {
00748
00749 sout << "Collapsing faces in " << Xname;
00750 if (!Acompl. empty ())
00751 sout << " and " << Aname;
00752 sout << "... ";
00753
00754
00755 int_t count = Xcompl. collapse (Acompl, Xkeepcompl,
00756 addbd, addcob, disjoint, level);
00757
00758
00759 sout << (count << 1) << " removed, " <<
00760 Xcompl. size () << " left.\n";
00761
00762
00763 if (!Acompl. empty ())
00764 sout << "There are " << Acompl. size () << " faces "
00765 "of dimension up to " << Acompl. dim () <<
00766 " left in " << Aname << ".\n";
00767
00768 return;
00769 }
00770
00773 template <class cell, class euclidom>
00774 inline void collapse (gcomplex<cell,euclidom> &Xcompl,
00775 gcomplex<cell,euclidom> &Acompl,
00776 const char *Xname, const char *Aname, bool addbd = true,
00777 bool addcob = false, bool disjoint = true, const int *level = NULL)
00778 {
00779 gcomplex<cell,euclidom> empty;
00780 collapse (Xcompl, Acompl, empty, Xname, Aname,
00781 addbd, addcob, disjoint, level);
00782 return;
00783 }
00784
00786 template <class cell, class euclidom>
00787 inline void collapse (gcomplex<cell,euclidom> &Xcompl,
00788 gcomplex<cell,euclidom> &Xkeepcompl,
00789 const char *Xname, bool addbd = true, bool addcob = false,
00790 bool disjoint = true, const int *level = NULL)
00791 {
00792 gcomplex<cell,euclidom> empty;
00793 collapse (Xcompl, empty, Xkeepcompl, Xname, "",
00794 addbd, addcob, disjoint, level);
00795 return;
00796 }
00797
00800 template <class cell, class euclidom>
00801 inline void collapse (gcomplex<cell,euclidom> &Xcompl,
00802 const char *Xname, bool addbd = true, bool addcob = false,
00803 bool disjoint = true, const int *level = NULL)
00804 {
00805 gcomplex<cell,euclidom> empty;
00806 collapse (Xcompl, empty, empty, Xname, "",
00807 addbd, addcob, disjoint, level);
00808 return;
00809 }
00810
00813 template <class cell, class euclidom>
00814 void decreasedimension (gcomplex<cell,euclidom> &Acompl,
00815 int dim, const char *name)
00816 {
00817 if (Acompl. dim () <= dim)
00818 return;
00819 if (dim < 0)
00820 dim = 0;
00821 sout << "Adding to " << name << " boundaries of high-dim " <<
00822 cell::pluralname () << "... ";
00823 int_t howmany = 0;
00824 for (int i = Acompl. dim (); i > dim; -- i)
00825 {
00826 sout << '.';
00827 howmany += Acompl. addboundaries (i);
00828 Acompl. removeall (i);
00829 }
00830 sout << ' ' << howmany << " added.\n";
00831 return;
00832 }
00833
00835 template <class cell, class euclidom>
00836 void addboundaries (gcomplex<cell,euclidom> &Xcompl,
00837 gcomplex<cell,euclidom> &Acompl,
00838 int minlevel, bool bothsets, const char *Xname, const char *Aname)
00839 {
00840
00841 if (Xcompl. empty ())
00842 return;
00843
00844
00845 sout << "Adding boundaries of " << cell::pluralname () << " in ";
00846 if (!Acompl. empty ())
00847 sout << Xname << " and " << Aname << "... ";
00848 else
00849 sout << Xname << "... ";
00850
00851
00852 int_t howmany = 0;
00853 for (int i = Xcompl. dim (); (i >= minlevel) && i; -- i)
00854 {
00855 if (bothsets)
00856 {
00857 howmany += Xcompl. addboundaries (i, true);
00858 if (Acompl. dim () >= i)
00859 howmany += Acompl. addboundaries (i,
00860 true);
00861 }
00862 else
00863 howmany += Xcompl. addboundaries (i, Acompl);
00864 }
00865
00866
00867 sout << howmany << ' ' << cell::pluralname () << " added.\n";
00868 return;
00869 }
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00891 template <class tCube>
00892 int ReadBitmapFile (const char *bmpname, hashedset<tCube> &cset,
00893 int mingray = 0, int maxgray = 128)
00894 {
00895
00896 bmpfile bmp;
00897 bmp. invertedpicture ();
00898
00899
00900 if (bmp. open (bmpname) < 0)
00901 fileerror (bmpname);
00902
00903
00904 coordinate c [2];
00905 for (c [1] = 0; c [1] < bmp. picture_height (); ++ (c [1]))
00906 {
00907 for (c [0] = 0; c [0] < bmp. picture_width (); ++ (c [0]))
00908 {
00909 long color = bmp. getpixel (c [0], c [1]);
00910 long gray = (77 * ((color & 0xFF0000) >> 16) +
00911 154 * ((color & 0xFF00) >> 8) +
00912 25 * (color & 0xFF)) >> 8;
00913 if ((gray >= mingray) && (gray <= maxgray))
00914 cset. add (tCube (c, 2));
00915 }
00916 }
00917
00918 return 0;
00919 }
00920
00921
00922 }
00923 }
00924
00925 #endif // _CHOMP_HOMOLOGY_HOMTOOLS_H
00926
00928