The Original CHomP Software
twolayer.h
Go to the documentation of this file.
1
3
21
22// Copyright (C) 1997-2020 by Pawel Pilarczyk.
23//
24// This file is part of my research software package. This is free software:
25// you can redistribute it and/or modify it under the terms of the GNU
26// General Public License as published by the Free Software Foundation,
27// either version 3 of the License, or (at your option) any later version.
28//
29// This software is distributed in the hope that it will be useful,
30// but WITHOUT ANY WARRANTY; without even the implied warranty of
31// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32// GNU General Public License for more details.
33//
34// You should have received a copy of the GNU General Public License
35// along with this software; see the file "license.txt". If not,
36// please, see <https://www.gnu.org/licenses/>.
37
38// Started in May 2006. Last revision: October 24, 2013.
39
40
41#ifndef _CHOMP_CUBES_TWOLAYER_H_
42#define _CHOMP_CUBES_TWOLAYER_H_
43
44#include "chomp/cubes/cube.h"
45#include "chomp/cubes/cell.h"
47#include "chomp/cubes/cubmaps.h"
50
51#include <iostream>
52#include <fstream>
53#include <cstdlib>
54#include <cstring>
55#include <exception>
56
57namespace chomp {
58namespace homology {
59
60
66typedef short int theLayerType;
67
68
69// --------------------------------------------------
70// ---------------- two-layer cubes -----------------
71// --------------------------------------------------
72
73template <class tCell>
74class tCell2l;
75
78template <class tCube>
80{
81public:
84
86 typedef tCube CubeType;
87
89 typedef typename tCube::CoordType CoordType;
90
93
95 static const int MaxDim = tCube::MaxDim;
96
98 typedef typename tCube::PointBase PointBase;
99
101 tCube2l ();
102
104 tCube2l (const tCube &_q, const LayerType &_l);
105
107 tCube2l (const CoordType *coord, int dim);
108
110 tCube2l (const CoordType *coord, int dim, const LayerType &_l);
111
113 tCube2l (int_t number, int dim);
114
116 tCube2l (const tCube2l &c);
117
119 tCube2l &operator = (const tCube2l &c);
120
122 int dim () const;
123
125 template <class intType>
126 intType *coord (intType *c) const;
127
129 int_t hashkey1 () const;
130
132 int_t hashkey2 () const;
133
135 static const char *name ();
136
138 static const char *pluralname ();
139
141 const LayerType &layer () const;
142
144 const tCube &cube () const;
145
147 void layer (const typename tCube2l<tCube>::LayerType &newlayer);
148
154 static void setlayers (const hashedset<tCube> &X,
155 const hashedset<tCube> &A);
156
158 static const hashedset<tCube> &layer1 ();
159
161 static const hashedset<tCube> &layer1b ();
162
165 static const hashedset<tCube> &layer0 ();
166
167private:
169 tCube q;
170
173
178
182
186
187}; /* class tCube2l */
188
189// --------------------------------------------------
190
191template <class tCube>
193
194template <class tCube>
196
197template <class tCube>
199
200// --------------------------------------------------
201
202template <class tCube>
203inline tCube2l<tCube>::tCube2l (): q (), l (0)
204{
205 return;
206} /* tCube2l */
207
208template <class tCube>
209inline tCube2l<tCube>::tCube2l (const tCube &_q, const LayerType &_l)
210: q (_q), l (_l)
211{
212 return;
213} /* tCube2l */
214
215template <class tCube>
216inline tCube2l<tCube>::tCube2l (const CoordType *coord, int dim):
217 q (coord, dim), l (layer1set. check (q) ? 1 : 0)
218{
219 return;
220} /* tCube2l */
221
222template <class tCube>
223inline tCube2l<tCube>::tCube2l (const CoordType *coord, int dim,
224 const LayerType &_l): q (coord, dim), l (_l)
225{
226 return;
227} /* tCube2l */
228
229template <class tCube>
230inline tCube2l<tCube>::tCube2l (int_t number, int dim)
231: q (number, dim), l (layer1set. check (q) ? 1 : 0)
232{
233 return;
234} /* tCube2l */
235
236template <class tCube>
237inline tCube2l<tCube>::tCube2l (const tCube2l &c): q (c. q), l (c. l)
238{
239 return;
240} /* tCube2l */
241
242template <class tCube>
244{
245 q = c. q;
246 l = c. l;
247 return *this;
248} /* tCube2l */
249
250template <class tCube>
251inline int tCube2l<tCube>::dim () const
252{
253 return q. dim ();
254} /* dim */
255
256template <class tCube>
257template <class intType>
258inline intType *tCube2l<tCube>::coord (intType *c) const
259{
260 return q. coord (c);
261} /* coord */
262
263template <class tCube>
265{
266 return q. hashkey1 ();
267} /* hashkey1 */
268
269template <class tCube>
271{
272 return c. hashkey1 ();
273} /* hashkey1 */
274
275template <class tCube>
277{
278 return q. hashkey2 () ^ l;
279} /* hashkey2 */
280
281template <class tCube>
283{
284 return c. hashkey2 ();
285} /* hashkey2 */
286
287template <class tCube>
288inline const char *tCube2l<tCube>::name ()
289{
290 return tCube::name ();
291} /* name */
292
293template <class tCube>
294inline const char *tCube2l<tCube>::pluralname ()
295{
296 return tCube::pluralname ();
297} /* pluralname */
298
299template <class tCube>
300inline const tCube &tCube2l<tCube>::cube () const
301{
302 return q;
303} /* cube */
304
305template <class tCube>
307 const
308{
309 return l;
310} /* layer */
311
312template <class tCube>
314 (const typename tCube2l<tCube>::LayerType &newlayer)
315{
316 l = newlayer;
317 return;
318} /* layer */
319
320template <class tCube>
322 const hashedset<tCube> &A)
323{
324 // remember the sets at the layers' boundary
325 layer0set = A;
326 layer1set = X;
327 hashedset<tCube> empty;
328 layer1boundary = empty;
329
330 // if the set X is empty, then there is no problem at all
331 if (X. empty ())
332 return;
333
334 // determine the set at Layer 1 as neighbors of A in X,
335 // and create cells at the layers' boundary for identification
337 for (int_t i = 0; i < X. size (); ++ i)
338 {
339 const tCube &q = X [i];
341 int_t ncount = getneighbors (q, 0, layer0set, &neighbors, 0);
342 if (!ncount)
343 continue;
344 layer1boundary. add (q);
345 for (int_t j = 0; j < ncount; ++ j)
346 {
347 idcells. add (typename tCube::CellType
348 (q, neighbors [j]));
349 }
350 }
351
352 // add boundaries of all the cells
353 for (int_t i = 0; i < idcells. size (); ++ i)
354 {
355 const typename tCube::CellType &c = idcells [i];
356 int bsize = boundarylength (c);
357 for (int j = 0; j < bsize; ++ j)
358 idcells. add (boundarycell (c, j));
359 }
360
361 // define the identification set
362 CellType::identify (idcells, layer1set [0]. dim ());
363 return;
364} /* setlayers */
365
366template <class tCube>
368{
369 return layer1set;
370} /* layer1 */
371
372template <class tCube>
374{
375 return layer1boundary;
376} /* layer1b */
377
378template <class tCube>
380{
381 return layer0set;
382} /* layer0 */
383
384// --------------------------------------------------
385
387template <class tCube>
388inline int operator == (const tCube2l<tCube> &c1,
389 const tCube2l<tCube> &c2)
390{
391 return (c1. cube () == c2. cube ()) &&
392 (c1. layer () == c2. layer ());
393} /* operator == */
394
397template <class tCube>
398inline int operator != (const tCube2l<tCube> &c1,
399 const tCube2l<tCube> &c2)
400{
401 return !(c1 == c2);
402} /* operator != */
403
405template <class tCube>
407 const tCube2l<tCube> &c2)
408{
409 tCube q (c1. cube () * c2. cube ());
411 l ((c1. layer () << 2) | c2. layer ());
412 return tCube2l<tCube> (q, l);
413} /* operator * */
414
416template <class tCube>
417inline std::ostream &operator << (std::ostream &out, const tCube2l<tCube> &c)
418{
419 // write the cube
420 WriteCube (out, c. cube ());
421
422 // write the layer if any
423 if (c. layer ())
424 out << '^' << c. layer ();
425
426 return out;
427} /* operator << */
428
430template <class tCube>
431inline std::istream &operator >> (std::istream &in, tCube2l<tCube> &c)
432{
433 // read the cube
434 tCube q;
435 ReadCube (in, q);
436
437 // read the layer if any
438 typename tCube2l<tCube>::LayerType l (0);
439 ignorecomments (in);
440 if (in. peek () == '^')
441 {
442 in. get ();
443 ignorecomments (in);
444 in >> l;
445 }
446 else if (tCube2l<tCube>::layer1 (). check (q))
447 l = 1;
448
449 c = tCube2l<tCube> (q, l);
450 return in;
451} /* operator >> */
452
455template <class tCube>
456inline std::istream &operator >> (std::istream &in,
458{
459 return ReadCubes (in, s);
460} /* operator >> */
461
467template <class tCube>
468inline std::istream &operator >> (std::istream &in,
470{
471 return ReadCubicalMap (in, m);
472} /* operator >> */
473
474
475// --------------------------------------------------
476// ---------------- two-layer cells -----------------
477// --------------------------------------------------
478
481template <class tCell>
483{
484public:
487
489 typedef tCell CellType;
490
492 typedef typename tCell::CoordType CoordType;
493
495 static const int MaxDim = tCell::MaxDim;
496
498 typedef typename tCell::PointBase PointBase;
499
501 tCell2l ();
502
504 tCell2l (const tCell &_q, const LayerType &_l);
505
507 tCell2l (const CoordType *c1, const CoordType *c2,
508 int spcdim, int celldim = -1, int layer = 0);
509
511 template <class tCube>
512 tCell2l (const tCube2l<tCube> &q1, const tCube2l<tCube> &q2);
513
516 template <class tCube>
517 tCell2l (const tCube2l<tCube> &c, int facedim);
518
520 template <class tCube>
521 explicit tCell2l (const tCube2l<tCube> &c);
522
526 template <class tCellSrc>
527 tCell2l (const tCell2l<tCellSrc> &q, int offset, int ncoords);
528
530 tCell2l (const tCell2l &c);
531
533 tCell2l &operator = (const tCell2l &c);
534
536 int dim () const;
537
539 int spacedim () const;
540
542 template <class intType>
543 intType *leftcoord (intType *c) const;
544
546 template <class intType>
547 intType *rightcoord (intType *c) const;
548
550 int_t hashkey1 () const;
551
553 int_t hashkey2 () const;
554
556 static const char *name ();
557
559 static const char *pluralname ();
560
564 {
565 BitProduct = 0x01, // unset => two vertices
566 BitSpace = 0x02
567 };
568 static int OutputBits;
569
571 const LayerType &layer () const;
572
574 const tCell &cell () const;
575
577 void layer (const typename tCell2l<tCell>::LayerType &newlayer);
578
580 static void identify (const hashedset<tCell> &s, int dim);
581
583 static const hashedset<tCell> &identify ();
584
586 static LayerType droplayer (const tCell &q, const LayerType &layer);
587
588private:
591
595 static int iddim;
596
598 tCell q;
599
602
603}; /* class tCell2l */
604
605// --------------------------------------------------
606
607template <class tCell>
609
610template <class tCell>
612
613template <class tCell>
615
616// --------------------------------------------------
617
618template <class tCell>
619inline tCell2l<tCell>::tCell2l (): q (), l (0)
620{
621 return;
622} /* tCell2l */
623
624template <class tCell>
625inline tCell2l<tCell>::tCell2l (const tCell &_q, const LayerType &_l)
626: q (_q), l (_l)
627{
628 if ((l == 1) && idset. check (q))
629 l = 0;
630 return;
631} /* tCell2l */
632
633template <class tCell>
635 const typename tCell2l<tCell>::CoordType *c2,
636 int spcdim, int celldim, int layer)
637: q (c1, c2, spcdim, celldim), l (layer)
638{
639 if ((l == 1) && idset. check (q))
640 l = 0;
641 return;
642} /* tCell2l */
643
644template <class tCell>
645template <class tCube>
647 const tCube2l<tCube> &q2)
648: q (q1. cube (), q2. cube ()), l ((q1. layer () < q2. layer ()) ?
649 q1. layer () : q2. layer ())
650{
651 if ((l == 1) && idset. check (q))
652 l = 0;
653 return;
654} /* tCell2l */
655
656template <class tCell>
657template <class tCube>
658inline tCell2l<tCell>::tCell2l (const tCube2l<tCube> &c, int facedim)
659: q (c. cube (), facedim), l (c. layer ())
660{
662 return;
663} /* tCell2l */
664
665template <class tCell>
666template <class tCube>
668: q (c. cube ()), l (c. layer ())
669{
670 if ((l == 1) && idset. check (q))
671 l = 0;
672 return;
673} /* tCell2l */
674
675template <class tCell>
676template <class tCellSrc>
678 int offset, int ncoords)
679: q (c. cell (), offset, ncoords), l (c. layer ())
680{
681 if (offset > 0)
682 l &= 0x03;
683 else
684 {
685 l >>= 2;
686 l &= 0x03;
687 }
688 if ((l == 1) && idset. check (q))
689 l = 0;
690 return;
691} /* tCell2l */
692
693template <class tCell>
694inline tCell2l<tCell>::tCell2l (const tCell2l &c): q (c. q), l (c. l)
695{
696 return;
697} /* tCell2l */
698
699template <class tCell>
701{
702 q = c. q;
703 l = c. l;
704 return *this;
705} /* tCell2l */
706
707template <class tCell>
708inline int tCell2l<tCell>::dim () const
709{
710 return q. dim ();
711} /* dim */
712
713template <class tCell>
714inline int tCell2l<tCell>::spacedim () const
715{
716 return q. spacedim ();
717} /* spacedim */
718
719template <class tCell>
720template <class intType>
721inline intType *tCell2l<tCell>::leftcoord (intType *c) const
722{
723 return q. leftcoord (c);
724} /* leftcoord */
725
726template <class tCell>
727template <class intType>
728inline intType *tCell2l<tCell>::rightcoord (intType *c) const
729{
730 return q. rightcoord (c);
731} /* rightcoord */
732
733template <class tCell>
735{
736 return q. hashkey1 ();
737} /* hashkey1 */
738
739template <class tCell>
741{
742 return c. hashkey1 ();
743} /* hashkey1 */
744
745template <class tCell>
747{
748 return q. hashkey2 () ^ l;
749} /* hashkey2 */
750
751template <class tCell>
753{
754 return c. hashkey2 ();
755} /* hashkey2 */
756
757template <class tCell>
758inline const char *tCell2l<tCell>::name ()
759{
760 return tCell::name ();
761} /* name */
762
763template <class tCell>
764inline const char *tCell2l<tCell>::pluralname ()
765{
766 return tCell::pluralname ();
767} /* pluralname */
768
769template <class tCell>
771 const
772{
773 return l;
774} /* layer */
775
776template <class tCell>
777inline const tCell &tCell2l<tCell>::cell () const
778{
779 return q;
780} /* cell */
781
782template <class tCell>
784 (const typename tCell2l<tCell>::LayerType &newlayer)
785{
786 l = newlayer;
787 return;
788} /* layer */
789
790template <class tCell>
791inline void tCell2l<tCell>::identify (const hashedset<tCell> &s, int dim)
792{
793 idset = s;
794 iddim = dim;
795 return;
796} /* identify */
797
798template <class tCell>
800{
801 return idset;
802} /* identify */
803
804template <class tCell>
806 (const tCell &q, const LayerType &layer)
807{
808 if (!layer)
809 return layer;
810 int dim = q. spacedim ();
811 if (dim <= iddim)
812 {
813 if (idset. check (q))
814 return 0;
815 else
816 return layer;
817 }
818 if (dim != iddim + iddim)
819 throw "Unknown cells for layer analysis.";
820 typename tCell2l<tCell>::LayerType layer1 (layer >> 2);
821 typename tCell2l<tCell>::LayerType layer2 (layer & 0x03);
822 if ((layer1) && idset. check (tCell (q, 0, iddim)))
823 layer1 = 0;
824 if ((layer2) && idset. check (tCell (q, iddim, iddim)))
825 layer2 = 0;
826 return (layer1 << 2) | layer2;
827} /* droplayer */
828
829// --------------------------------------------------
830
832template <class tCell>
833inline int operator == (const tCell2l<tCell> &c1,
834 const tCell2l<tCell> &c2)
835{
836 return (c1. cell () == c2. cell ()) &&
837 (c1. layer () == c2. layer ());
838} /* operator == */
839
842template <class tCell>
843inline int operator != (const tCell2l<tCell> &c1,
844 const tCell2l<tCell> &c2)
845{
846 return !(c1 == c2);
847} /* operator != */
848
850template <class tCell>
852 const tCell2l<tCell> &c2)
853{
854 tCell q (c1. cell () * c2. cell ());
856 l ((c1. layer () << 2) | c2. layer ());
857 return tCell2l<tCell> (q, l);
858} /* operator * */
859
861template <class tCell>
862inline std::ostream &operator << (std::ostream &out, const tCell2l<tCell> &c)
863{
864 // write the cubical cell
865 WriteCubicalCell (out, c. cell ());
866
867 // write the layer if any
868 if (c. layer ())
869 out << '^' << c. layer ();
870
871 return out;
872} /* operator << */
873
875template <class tCell>
876inline std::istream &operator >> (std::istream &in, tCell2l<tCell> &c)
877{
878 // read the cubical cell
879 tCell q;
880 ReadCubicalCell (in, q);
881
882 // read the layer if any
883 typename tCell2l<tCell>::LayerType l (0);
884 ignorecomments (in);
885 if (in. peek () == '^')
886 {
887 in. get ();
888 ignorecomments (in);
889 in >> l;
890 }
891
892 c = tCell2l<tCell> (q, l);
893 return in;
894} /* operator >> */
895
896// --------------------------------------------------
897
900template <class tCell>
902 bool onlyexisting)
903{
904 tCell c = CubicalBoundaryCell (q. cell (), i, onlyexisting);
905 if (c == q. cell ())
906 return q;
908 (tCell2l<tCell>::droplayer (c, q. layer ()));
909 return tCell2l<tCell> (c, l);
910} /* boundarycell */
911
913template <class tCell>
915{
916 tCell c = CubicalBoundaryCell (q. cell (), i);
918 (tCell2l<tCell>::droplayer (c, q. layer ()));
919 return tCell2l<tCell> (c, l);
920} /* boundarycell */
921
923template <class tCell>
924inline int boundarylength (const tCell2l<tCell> &q)
925{
926 return CubicalBoundaryLength (q. cell ());
927} /* boundarylength */
928
930template <class tCell>
931inline int boundarycoef (const tCell2l<tCell> &q, int i)
932{
933 return CubicalBoundaryCoef (q. cell (), i);
934} /* boundarycoef */
935
936
937// --------------------------------------------------
938// ---------------- specializations -----------------
939// --------------------------------------------------
940
944template <class tCube>
946 bool unconditional = false)
947{
948 throw "Trying to use 'bit2neighbor' for a 2-layer cube.";
949 return q;
950} /* bit2neighbor */
951
955template <class tCube>
957{
958 throw "Trying to use 'neighbor2bit' for a 2-layer cube.";
959 return -1;
960} /* neighbor2bit */
961
967template <class tCube>
968bool intersection2l (const tCube &q0, const tCube &q1, BitField *bits)
969{
970 // determine the set of cells at the intersection of layers
973
974 // compute the intersection of the cubes
975 typename tCube::CellType intersection (q0, q1);
977 faces. add (intersection);
978
979 // check all the faces of the cells
980 int_t current = 0;
981 int_t counter = 0;
982 while (current < faces. size ())
983 {
984 const typename tCube::CellType &face = faces [current ++];
985 if (ident. check (face))
986 {
987 if (bits)
988 bits -> set (neighbor2bit (q0, face));
989 ++ counter;
990 }
991 else
992 {
993 for (int_t i = 0; i < boundarylength (face); ++ i)
994 faces. add (boundarycell (face, i));
995 }
996 }
997 return (counter > 0);
998} /* intersection2l */
999
1002template <class tCube, class tCubeSet1, class tCubeSet2>
1004 const tCubeSet1 &theset, tCubeSet2 *neighbors, int_t limit)
1005{
1006 // decompose the cube into its components
1007 const tCube &q0 = q2l. cube ();
1008 typename tCube2l<tCube>::LayerType l0 (q2l. layer ());
1009
1010 // determine the set of cubes at layer 0
1011 const hashedset<tCube> &layer0 = tCube2l<tCube>::layer0 ();
1012
1013 // prepare a counter for the number of neighbors
1014 int_t count = 0;
1015
1016 // go through all the elements in the set
1017 for (int_t i = 0; i < theset. size (); ++ i)
1018 {
1019 // take the cube from the set
1020 const tCube2l<tCube> &q1l = theset [i];
1021
1022 // if this is the current cube then ignore it
1023 if (q1l == q2l)
1024 continue;
1025
1026 // decompose the cube into its components
1027 const tCube &q1 = q1l. cube ();
1028 typename tCube2l<tCube>::LayerType l1 (q1l. layer ());
1029
1030 // determine the number of this neighbor
1031 int_t number = neighbor2bit (q0, q1);
1032
1033 // if not neighbor then ignore it
1034 if (number < 0)
1035 continue;
1036
1037 // if the cubes fully intersect then this is easy
1038 if ((l0 == l1) ||
1039 ((l0 == 0) && (l1 == 1) && (layer0. check (q0))) ||
1040 ((l0 == 1) && (l1 == 0) && (layer0. check (q1))))
1041 {
1042 // set the appropriate bit in the bit field
1043 if (bits)
1044 bits -> set (number);
1045 }
1046 // otherwise the correct intersection of the cubes
1047 // must be determined at the boundary between the layers
1048 else if (!intersection2l (q0, q1, bits))
1049 continue;
1050
1051 // add the cube to the set of neighbors
1052 if (neighbors)
1053 neighbors -> add (q1l);
1054
1055 // increase the counter
1056 ++ count;
1057
1058 // if this is enough then finish
1059 if (limit && (count >= limit))
1060 return count;
1061 }
1062
1063 return count;
1064} /* getneighbors_scan */
1065
1069template <class tCube, class tCubeSet1, class tCubeSet2>
1071 const tCubeSet1 &theset, tCubeSet2 *neighbors, int_t limit)
1072{
1073 // decompose the cube into its components
1074 const tCube &q0 = q2l. cube ();
1075 typename tCube2l<tCube>::LayerType l0 (q2l. layer ());
1076
1077 // determine the upper bound for the number of neighbors
1078 int_t maxneighbors = getmaxneighbors (q0. dim ());
1079
1080 // determine the set of cubes at layer 0
1081 const hashedset<tCube> &layer0 = tCube2l<tCube>::layer0 ();
1082
1083 // determine the set of cubes at layer 1
1084 const hashedset<tCube> &layer1 = tCube2l<tCube>::layer1 ();
1085
1086 // prepare a counter for the number of neighbors
1087 int_t count = 0;
1088
1089 // go through all possible neighbor numbers
1090 for (int_t number = 0; number < maxneighbors; ++ number)
1091 {
1092 // create a neighbor cube using the generic algorithm
1093 tCube q1 = bit2neighbor (q0, number, true);
1094
1095 // determine the layer of the neighbor
1096 int l1 = layer1. check (q1) ? 1 : 0;
1097
1098 // create the neighbor cube
1099 tCube2l<tCube> q1l (q1, l1);
1100
1101 // if this cube is not in the set then skip it
1102 if (!theset. check (q1l))
1103 continue;
1104
1105 // if the cubes fully intersect then this is easy
1106 if ((l0 == l1) ||
1107 ((l0 == 0) && (l1 == 1) && (layer0. check (q0))) ||
1108 ((l0 == 1) && (l1 == 0) && (layer0. check (q1))))
1109 {
1110 // set the appropriate bit in the bit field
1111 if (bits)
1112 bits -> set (number);
1113 }
1114 // otherwise the correct intersection of the cubes
1115 // must be determined at the boundary between the layers
1116 else if (!intersection2l (q0, q1, bits))
1117 continue;
1118
1119 // add the cube to the set of neighbors
1120 if (neighbors)
1121 neighbors -> add (q1l);
1122
1123 // increase the counter
1124 ++ count;
1125
1126 // if this is enough then finish
1127 if (limit && (count >= limit))
1128 return count;
1129 }
1130
1131 return count;
1132} /* getneighbors_generate */
1133
1139template <class euclidom, class tCell, class tCube>
1143 const hashedset<tCube2l<tCube> > &dom1,
1144 const hashedset<tCube2l<tCube> > &dom2)
1145{
1146 typedef typename tCube::CoordType coordType;
1147 int_t countimages = 0;
1148 coordType leftbound [tCell::MaxDim];
1149 coordType rightbound [tCell::MaxDim];
1150 coordType left [tCell::MaxDim];
1151 coordType right [tCell::MaxDim];
1152
1153 // go through all the dimensions of the cellular complex separtely
1154 for (int d = 0; d <= m. dim (); ++ d)
1155 {
1156 const hashedset<tCell2l<tCell> > &cset = m. get (d);
1157 if (cset. empty ())
1158 continue;
1159 const int spacedim = cset [0]. spacedim ();
1160
1161 // go through the cells of the specified dimension
1162 for (int_t i = 0; i < cset. size (); ++ i)
1163 {
1164 // remember the cell whose image is computed
1165 const tCell2l<tCell> &thecell = cset [i];
1166
1167 // determine tha layer of the cell
1168 const typename tCube2l<tCube>::LayerType layer =
1169 thecell. layer ();
1170
1171 // check if the layers are identified at the cell
1172 bool idlayers = tCell2l<tCell>::identify ().
1173 check (thecell. cell ());
1174
1175 // get the coordinates of the corners of the cell
1176 thecell. leftcoord (left);
1177 thecell. rightcoord (right);
1178
1179 // compute the bounds for full cubes to get imgs of
1180 for (int j = 0; j < spacedim; ++ j)
1181 {
1182 // compensate for space wrapping
1183 if (right [j] < left [j])
1184 right [j] = left [j] + 1;
1185
1186 // compute the bounds for full cubes
1187 leftbound [j] = static_cast<coordType>
1188 (left [j] - (left [j] == right [j]));
1189 rightbound [j] = static_cast<coordType>
1190 (right [j] +
1191 (left [j] == right [j]));
1192 }
1193
1194 // go through the full cubes in the computed range
1195 tRectangle<coordType> r (leftbound, rightbound,
1196 spacedim);
1197 const coordType *c;
1198 while ((c = r. get ()) != NULL)
1199 {
1200 // determine the core cube
1201 if (!tCube::PointBase::check (c, spacedim))
1202 continue;
1203 tCube q0 (c, spacedim);
1204
1205 // add the images of the 2-layer cube
1206 tCube2l<tCube> q (q0, layer);
1207 if (dom1. check (q))
1208 m. add (d, i, f1 (q));
1209 if (dom2. check (q))
1210 m. add (d, i, f2 (q));
1211
1212 // determine if the cubes at the other
1213 // layer must also be considered
1214 typename tCube2l<tCube>::LayerType l = layer;
1215 if (idlayers && !layer &&
1217 check (q0))
1218 {
1219 l = 1;
1220 }
1221 else if (idlayers && layer &&
1223 check (q0))
1224 {
1225 l = 0;
1226 }
1227 if (l != layer)
1228 {
1229 tCube2l<tCube> ql (q0, l);
1230 if (dom1. check (ql))
1231 m. add (d, i, f1 (ql));
1232 if (dom2. check (ql))
1233 m. add (d, i, f2 (ql));
1234 }
1235 }
1236 countimages += m (thecell). size ();
1237 }
1238 }
1239 return countimages;
1240} /* createimages */
1241
1242
1243// --------------------------------------------------
1244// ----------------- standard types -----------------
1245// --------------------------------------------------
1246
1249
1252
1255
1258
1261
1264
1268
1269
1270} // namespace homology
1271} // namespace chomp
1272
1273#endif // _CHOMP_CUBES_TWOLAYER_H_
1274
1276
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 class defines a bit field that is part of some larger array or that uses an allocated piece of m...
Definition: bitfield.h:73
The class that defines a geometric complex - a set of cells (cubes, simplices, etc).
Definition: gcomplex.h:85
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
A general cubical cell with additional information about the layer number.
Definition: twolayer.h:483
static LayerType droplayer(const tCell &q, const LayerType &layer)
Drops the layer of the cell if necessary by the identification.
Definition: twolayer.h:806
const LayerType & layer() const
Returns the layer number.
Definition: twolayer.h:770
static int iddim
The space dimension of cells for which the identification takes place.
Definition: twolayer.h:595
int dim() const
Returns the dimension of the cubical cell.
Definition: twolayer.h:708
tCell::PointBase PointBase
The point base (for wrapping and tabulating coordinates).
Definition: twolayer.h:498
LayerType l
The layer to which the cell belongs.
Definition: twolayer.h:601
static const char * name()
Returns the name of the objects represented by this class.
Definition: twolayer.h:758
int_t hashkey1() const
Returns the hash key no. 1 required by the hashing set template.
Definition: twolayer.h:734
static const char * pluralname()
Returns the plural name of the objects represented by this class.
Definition: twolayer.h:764
tCell CellType
The type for keeping the cell at the given layer.
Definition: twolayer.h:489
static const hashedset< tCell > & identify()
Returns the set of cells for the identification of layers.
Definition: twolayer.h:799
tCell2l()
The default constructor.
Definition: twolayer.h:619
tCell q
The actual cubical cell at the given layer.
Definition: twolayer.h:598
static hashedset< tCell > idset
The set of cells at which the identification takes place.
Definition: twolayer.h:590
intType * rightcoord(intType *c) const
Fills the given table with the right corner coordinates.
Definition: twolayer.h:728
const tCell & cell() const
Returns the cell without the layer.
Definition: twolayer.h:777
tCell2l & operator=(const tCell2l &c)
The assignment operator.
Definition: twolayer.h:700
int_t hashkey2() const
Returns the hash key no. 2 required by the hashing set template.
Definition: twolayer.h:746
int spacedim() const
Returns the dimension of the embedding space.
Definition: twolayer.h:714
OutputBitValues
How to output the cell: As a cartesian product or by two opposite vertices? Also, should ' ' be inser...
Definition: twolayer.h:564
tCell2l(const CoordType *c1, const CoordType *c2, int spcdim, int celldim=-1, int layer=0)
The constructor of a cell spanning from one point to another.
static const int MaxDim
The maximal dimension of a cube.
Definition: twolayer.h:495
intType * leftcoord(intType *c) const
Fills the given table with the left corner coordinates.
Definition: twolayer.h:721
theLayerType LayerType
The type for keeping the layer number.
Definition: twolayer.h:486
tCell::CoordType CoordType
The type of the coordinates.
Definition: twolayer.h:492
A (hyper)cube with additional information about the layer number.
Definition: twolayer.h:80
tCell2l< typename tCube::CellType > CellType
The type of a cell related to this cube type.
Definition: twolayer.h:92
LayerType l
The layer to which the cube belongs.
Definition: twolayer.h:172
int dim() const
Returns the dimension of the cube.
Definition: twolayer.h:251
tCube::PointBase PointBase
The point base (for wrapping and tabulating coordinates).
Definition: twolayer.h:98
tCube q
The actual cube at the given layer.
Definition: twolayer.h:169
tCube CubeType
The type for keeping the cube at the given layer.
Definition: twolayer.h:86
tCube::CoordType CoordType
The type of the coordinates.
Definition: twolayer.h:89
static const int MaxDim
The maximal dimension of a cube.
Definition: twolayer.h:95
static void setlayers(const hashedset< tCube > &X, const hashedset< tCube > &A)
Defines the set of cubes at layer 1 (X).
Definition: twolayer.h:321
static const hashedset< tCube > & layer1b()
Returns the set of cubes at the boundary of layer 1.
Definition: twolayer.h:373
static hashedset< tCube > layer0set
The set of full-dimensional cubes at layer 0 which are adjacent to the cubes at layer 1.
Definition: twolayer.h:185
static const char * name()
Returns the name of the objects represented by this class.
Definition: twolayer.h:288
const tCube & cube() const
Returns the cube without the layer.
Definition: twolayer.h:300
int_t hashkey1() const
Returns the hash key no. 1 required by the hashing set template.
Definition: twolayer.h:264
static const hashedset< tCube > & layer1()
Returns the set of cubes at layer 1.
Definition: twolayer.h:367
const LayerType & layer() const
Returns the layer number.
Definition: twolayer.h:306
static const char * pluralname()
Returns the plural name of the objects represented by this class.
Definition: twolayer.h:294
int_t hashkey2() const
Returns the hash key no. 2 required by the hashing set template.
Definition: twolayer.h:276
static const hashedset< tCube > & layer0()
Returns the set of cubes at layer 0 which are neighbors of cubes at layer 1 by the identification of ...
Definition: twolayer.h:379
theLayerType LayerType
The type for keeping the layer number.
Definition: twolayer.h:83
static hashedset< tCube > layer1set
The set of full-dimensional cubes at layer 1.
Definition: twolayer.h:177
tCube2l & operator=(const tCube2l &c)
The assignment operator.
Definition: twolayer.h:243
intType * coord(intType *c) const
Fills out the coordinate table with the cube's coordinates.
Definition: twolayer.h:258
tCube2l()
The default constructor.
Definition: twolayer.h:203
static hashedset< tCube > layer1boundary
The set of full-dimensional cubes at layer 1 adjacent to cubes at layer 0.
Definition: twolayer.h:181
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 includes header files with various definitions of full cubes and defines the standard types...
This file contains some procedures defined for cubical maps.
int int_t
Index type for indexing arrays, counting cubes, etc.
Definition: config.h:115
tCube bit2neighbor(const tCube &q, int_t number, bool unconditional=false)
Creates the neighbor of the given cube with the specified number.
Definition: neighbor.h:165
int_t neighbor2bit(const tCube &q, const tCube &neighbor)
Returns the number of the neighbor bit for the given neighbor of 'q' or -1 if not a neighbor or the s...
Definition: neighbor.h:84
short int theLayerType
The type of the layer variable.
Definition: twolayer.h:66
std::ostream & WriteCube(std::ostream &out, const cubetype &c)
Writes a cube to the output stream in the text mode.
Definition: cubemain.h:69
int CubicalBoundaryCoef(const celltype &q, int i)
Returns the i-th coefficient in the boundary of a cubical cell.
Definition: cellmain.h:157
gcomplex< CubicalCell2l, integer > CubicalComplex2l
A typical cubical complex in the two-layer setting.
Definition: twolayer.h:1263
hashedset< Cube2l > SetOfCubes2l
A typical set of full cubes in the two-layer setting.
Definition: twolayer.h:1257
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
tCube2l< tCubeBase< coordinate > > Cube2l
A typical full cube in the two-layer setting.
Definition: twolayer.h:1248
int_t getneighbors_scan(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:211
std::ostream & operator<<(std::ostream &out, const bincube< Dim, twoPower > &b)
Definition: bincube.h:907
std::istream & ReadCubes(std::istream &in, cubsettype &s)
Reads a set of cubes and ignores the line at the beginning of the file which starts with the letter '...
Definition: cubemain.h:193
tCell2l< tCellBase< coordinate > > CubicalCell2l
A typical cubical cell in the two-layer setting.
Definition: twolayer.h:1251
int_t hashkey2(const hashNumber< Number > &n)
The second hashing key.
Definition: bincube.h:1036
celltype CubicalBoundaryCell(const celltype &q, int i, bool onlyexisting)
Returns the i-th boundary element of a cell.
Definition: cellmain.h:72
int_t getmaxneighbors(int dim)
Returns the maximal number of neighbors of a cube: 3^dim - 1.
Definition: neighbor.h:60
tCellBase< coordtype > operator*(const tCellBase< coordtype > &c1, const tCellBase< coordtype > &c2)
Computes the Cartesian product of two cells.
Definition: cellbase.h:438
Cube cube
A lower-case name of a cube [deprecated].
Definition: cube.h:77
hashedset< CubicalCell2l > SetOfCubicalCells2l
A typical set of cubical cells in the two-layer setting.
Definition: twolayer.h:1260
tNeighbors< coordinate > neighbors
The neighbors class with the default type of coordinates.
Definition: pointset.h:84
int boundarylength(const tCellBase< coordtype > &q)
Returns the length of the boundary of a cell.
Definition: cellbase.h:501
tPointBase< coordinate > PointBase
The default type of the point base class.
Definition: pointbas.h:62
int_t createimages(mvcellmap< tCell, euclidom, tCube > &m, const mvmap< tCube, tCube > &f1, const mvmap< tCube, tCube > &f2, const hashedset< tCube > &dom1, const hashedset< tCube > &dom2)
Creates images of cells in 'm' as unions of cubes determined by f1 and f2.
Definition: cubmaps.h:147
std::ostream & WriteCubicalCell(std::ostream &out, const celltype &c)
Writes a cubical cell to the output stream in the text form.
Definition: cellmain.h:173
tCellBase< coordtype > boundarycell(const tCellBase< coordtype > &q, int i, bool onlyexisting)
Computes the i-th boundary element of a cell.
Definition: cellbase.h:485
std::istream & ReadCube(std::istream &in, cubetype &c)
Reads a cube from the input text stream.
Definition: cubemain.h:184
bool operator!=(const typename bincube< Dim, twoPower >::neighborhood_iterator &x1, const typename bincube< Dim, twoPower >::neighborhood_iterator &x2)
Definition: bincube.h:794
std::istream & operator>>(std::istream &in, bincube< Dim, twoPower > &b)
Definition: bincube.h:914
int_t hashkey1(const hashNumber< Number > &n)
The first hashing key.
Definition: bincube.h:1029
bool intersection2l(const tCube &q0, const tCube &q1, BitField *bits)
Computes the intersection between two cubes at different layers.
Definition: twolayer.h:968
bool operator==(const typename bincube< Dim, twoPower >::neighborhood_iterator &x1, const typename bincube< Dim, twoPower >::neighborhood_iterator &x2)
Definition: bincube.h:785
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
int_t getneighbors_generate(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:255
std::istream & ReadCubicalCell(std::istream &in, celltype &c)
Reads a cubical cell form the input text stream.
Definition: cellmain.h:235
std::istream & ReadCubicalMap(std::istream &in, mvmap< tCube, tCube > &m)
Reads a combinatorial cubical multivalued map from an input text stream.
Definition: cubemain.h:211
mvmap< Cube2l, Cube2l > CombinatorialMultivaluedMap2l
A typical multivalued map on full cubes in the two-layer setting.
Definition: twolayer.h:1254
mvcellmap< CubicalCell2l, integer, CubicalCell2l > CubicalMultivaluedMap2l
A typical multivalued cubical-cellular map in the two-layer setting.
Definition: twolayer.h:1267
int CubicalBoundaryLength(const celltype &q)
Returns the length of the boundary of a cubical cell.
Definition: cellmain.h:150
int boundarycoef(const tCellBase< coordtype > &q, int i)
Returns the i-th coefficient in the boundary of a cell.
Definition: cellbase.h:508
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 some useful functions related to the text input/output procedures.