The Original CHomP Software
indxpalg.h
Go to the documentation of this file.
1
3
14
15// Copyright (C) 1997-2020 by Pawel Pilarczyk.
16//
17// This file is part of my research software package. This is free software:
18// you can redistribute it and/or modify it under the terms of the GNU
19// General Public License as published by the Free Software Foundation,
20// either version 3 of the License, or (at your option) any later version.
21//
22// This software is distributed in the hope that it will be useful,
23// but WITHOUT ANY WARRANTY; without even the implied warranty of
24// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25// GNU General Public License for more details.
26//
27// You should have received a copy of the GNU General Public License
28// along with this software; see the file "license.txt". If not,
29// please, see <https://www.gnu.org/licenses/>.
30
31// Started on May 17, 2006. Last revision: August 30, 2006.
32
33
34#ifndef _CHOMP_HOMOLOGY_INDXPALG_H_
35#define _CHOMP_HOMOLOGY_INDXPALG_H_
36
38#include "chomp/cubes/cube.h"
39#include "chomp/cubes/cell.h"
41
42#include <iostream>
43#include <fstream>
44#include <cstdlib>
45
46namespace chomp {
47namespace homology {
48
49
50// --------------------------------------------------
51// ------------------- Map Class --------------------
52// --------------------------------------------------
53
56template <class TCube, class TSetOfCubes>
58{
59public:
62 const TSetOfCubes &operator () (const TCube &q) const
63 {
64 throw "The map has not been defined.";
65 }
66
67}; /* class MapClass */
68
69
74template <class TCube = Cube>
75class BufferedMapClass: public MapClass<TCube,hashedset<TCube> >
76{
77public:
80
82 typedef typename TCube::CoordType TCoordType;
83
85 typedef int (*map) (const TCoordType *coord,
86 double *left, double *right);
87
89 BufferedMapClass (map _f): f (_f) {}
90
93 const TSetOfCubes &operator () (const TCube &q) const;
94
97
98private:
101
102}; /* class BufferedMapClass */
103
104template <class TCube>
107{
108 // if the image of the cube is already known, then return it
109 const TSetOfCubes &dom = F. getdomain ();
110 if (dom. check (q))
111 return F (q);
112
113 // determine the dimension
114 const int dim = q. dim ();
115
116 // compute the image of the cube
117 TCoordType *coord = new TCoordType [dim];
118 q. coord (coord);
119 double *left = new double [dim];
120 double *right = new double [dim];
121 f (coord, left, right);
122 delete [] coord;
123
124 // compute the minimal and maximal corner of the rectangular
125 // cubical set that covers the computed image of the cube
126 TCoordType *ileft = new TCoordType [dim];
127 TCoordType *iright = new TCoordType [dim];
128 for (int i = 0; i < dim; ++ i)
129 {
130 ileft [i] = static_cast<TCoordType> (left [i]);
131 if ((ileft [i] + 1 < left [i]) ||
132 (ileft [i] - 1 > left [i]))
133 throw "Conversion error: double to coord - "
134 "out of range.";
135 for (int j = 0; j < 10; ++ j)
136 {
137 if (ileft [i] >= left [i])
138 -- ileft [i];
139 else
140 break;
141 }
142 if (ileft [i] >= left [i])
143 throw "Outer approximation failure (left).";
144 iright [i] = static_cast<TCoordType> (right [i]);
145 if ((iright [i] + 1 < right [i]) ||
146 (iright [i] - 1 > right [i]))
147 throw "Conversion error: double to coord - "
148 "out of range.";
149 for (int j = 0; j < 10; ++ j)
150 {
151 if (iright [i] <= right [i])
152 ++ iright [i];
153 else
154 break;
155 }
156 if (iright [i] <= right [i])
157 throw "Outer approximation failure (right).";
158 }
159 delete [] right;
160 delete [] left;
161
162 // create the image of the cube and add all the cubes to it
163 hashedset<TCube> &img = F [q];
164 tRectangle<TCoordType> r (ileft, iright, dim);
165 const TCoordType *c;
166 while ((c = r. get ()) != 0)
167 img. add (TCube (c, dim));
168 delete [] iright;
169 delete [] ileft;
170
171 // return the image of the cube
172 return F (q);
173} /* operator () */
174
175template <class TCube>
176std::ostream &operator << (std::ostream &out,
177 const BufferedMapClass<TCube> &map)
178{
179 out << map. F;
180 return out;
181} /* operator << */
182
183
184// --------------------------------------------------
185// ------------------ Neighborhood ------------------
186// --------------------------------------------------
187
189template <class TSetOfCubes>
190int neighborhood (const TSetOfCubes &X, TSetOfCubes &result)
191{
192 // extract the necessary types and constants
193 using namespace chomp::homology;
194 typedef typename TSetOfCubes::value_type cubetype;
195 typedef typename cubetype::CoordType coordtype;
197 const int maxdim = cubetype::MaxDim;
198
199 // create arrays for the corners of a rectangle around each cube
200 coordtype mincoord [maxdim], maxcoord [maxdim];
201
202 // for all the cubes in X
203 int_t ncount = X. size ();
204 for (int_t n = 0; n < ncount; ++ n)
205 {
206 // get the coordinates of the cube
207 int dim = X [n]. dim ();
208 X [n]. coord (mincoord);
209
210 // prepare the corners of a rectangle for the cube
211 // and its neighbors
212 for (int i = 0; i < dim; ++ i)
213 {
214 maxcoord [i] = mincoord [i];
215 ++ maxcoord [i];
216 ++ maxcoord [i];
217 -- mincoord [i];
218 }
219
220 // add cubes from the rectangle to the resulting set
221 rectangle r (mincoord, maxcoord, dim);
222 const coordtype *c;
223 while ((c = r. get ()) != 0)
224 result. add (cubetype (c, dim));
225 }
226 return 0;
227} /* neighborhood */
228
229
230// --------------------------------------------------
231// ----------------- Invariant Part -----------------
232// --------------------------------------------------
233
237template <class TSetOfCubes, class TMap>
238void invariantpart (TSetOfCubes &X, const TMap &F, TSetOfCubes &result)
239{
240 // do nothing if the set X is empty
241 int_t ncount = X. size ();
242 if (!ncount)
243 return;
244
245 // create a digraph of the map
246 diGraph<> g;
247 for (int_t n = 0; n < ncount; ++ n)
248 {
249 g. addVertex ();
250 const TSetOfCubes &img = F (X [n]);
251 int_t icount = img. size ();
252 for (int_t i = 0; i < icount; ++ i)
253 {
254 int_t number = X. getnumber (img [i]);
255 if (number < 0)
256 continue;
257 g. addEdge (number);
258 }
259 }
260
261 // compute the chain recurrent set of the graph
262 // and remember the transposed graph
263 multitable<int_t> compVertices, compEnds;
264 diGraph<> gT;
265 int_t count = SCC (g, compVertices, compEnds,
266 static_cast<diGraph<> *> (0), &gT);
267
268 // retrieve vertices that can be reached from the chain recurrent set
269 int_t nVertices = ncount;
270 char *forward = new char [nVertices];
271 for (int_t i = 0; i < nVertices; ++ i)
272 forward [i] = 0;
273 for (int_t cur = 0; cur < count; ++ cur)
274 {
275 g. DFScolor (forward, '\1',
276 compVertices [cur ? compEnds [cur - 1] :
277 static_cast<int_t> (0)]);
278 }
279
280 // retrieve vertices that can reach the chein recurrent set
281 char *backward = new char [nVertices];
282 for (int_t i = 0; i < nVertices; ++ i)
283 backward [i] = 0;
284 for (int_t cur = 0; cur < count; ++ cur)
285 {
286 gT. DFScolor (backward, '\1',
287 compVertices [cur ? compEnds [cur - 1] :
288 static_cast<int_t> (0)]);
289 }
290
291 // compute the new set of cubes
292 for (int_t i = 0; i < nVertices; ++ i)
293 if (forward [i] && backward [i])
294 result. add (X [i]);
295
296 // clean the memory and return
297 delete [] backward;
298 delete [] forward;
299 return;
300} /* invariantpart */
301
302
303// --------------------------------------------------
304// ------------------- inclusion --------------------
305// --------------------------------------------------
306
308template <class HSet>
309bool inclusion (const HSet &X, const HSet &Y)
310{
311 int_t countX = X. size ();
312 if (countX && Y. empty ())
313 return false;
314
315 for (int_t i = 0; i < countX; ++ i)
316 if (!Y. check (X [i]))
317 return false;
318 return true;
319} /* inclusion */
320
321
322// --------------------------------------------------
323// ------------------ Index Pair M ------------------
324// --------------------------------------------------
325
327template <class TSetOfCubes, class TMap>
328int ExitSetM (const TSetOfCubes &N, const TSetOfCubes &Q1,
329 const TMap &F, TSetOfCubes &resultQ2)
330{
331 // compute Q2 := (F (Q1 \cup Q2) \setminus Q1) \cap N
332 int_t countQ1 = Q1. size ();
333 int_t n = 0;
334
335 // for all the cubes in Q1 and Q2
336 while (n < countQ1 + resultQ2. size ())
337 {
338 // compute the image of the cube
339 const TSetOfCubes &img =
340 F ((n < countQ1) ? Q1 [n] : resultQ2 [n - countQ1]);
341
342 // add those image cubes to Q2 which are in N \setminus Q1
343 int_t countImg = img. size ();
344 for (int_t i = 0; i < countImg; ++ i)
345 {
346 if (!N. check (img [i]))
347 continue;
348 if (Q1. check (img [i]))
349 continue;
350 resultQ2. add (img [i]);
351 }
352 ++ n;
353 }
354 return 0;
355} /* ExitSetM */
356
360template <class TSetOfCubes, class TMap>
361int IndexPairM (const TMap &F, const TSetOfCubes &initialS,
362 TSetOfCubes &resultQ1, TSetOfCubes &resultQ2)
363{
364 // prepare the initial guess for S and N
365 TSetOfCubes S = initialS;
366 TSetOfCubes N;
367 neighborhood (S, N);
368
369 sout << "Starting with " << S. size () << " cubes in S_0, " <<
370 N. size () << " cubes in N.\n";
371 while (1)
372 {
373
374 // compute S := Inv (N)
375 sout << "S := Inv(N)... ";
376 scon << "(computing)\b\b\b\b\b\b\b\b\b\b\b";
377 TSetOfCubes empty;
378 S = empty;
379 // S = initialS;
380 invariantpart (N, F, S);
381 sout << S. size () << " cubes; o(S) has ";
382
383 // compute N' := o (S)
384 TSetOfCubes newN;
385 neighborhood (S, newN);
386 sout << newN. size () << " cubes.\n";
387
388 // if Int (N) contains Inv (N), then exit
389 if (inclusion (newN, N))
390 break;
391 // otherwise take a larget N and repeat
392 else
393 {
394 sout << "Set N := o(S). ";
395 N = newN;
396 }
397 }
398
399 // compute the index pair (Q1 \cup Q2, Q2)
400 resultQ1 = S;
401 ExitSetM (N, S, F, resultQ2);
402 return 0;
403} /* IndexPairM */
404
405
406// --------------------------------------------------
407// ------------------ Index Pair P ------------------
408// --------------------------------------------------
409
413template <class TSetOfCubes, class TMap>
414int IndexPairP (const TMap &F, const TSetOfCubes &initialS,
415 TSetOfCubes &resultQ1, TSetOfCubes &resultQ2)
416{
417 resultQ1 = initialS;
418
419 // compute the initial Q2 = f (Q1) - Q1
420 sout << "Computing the map on Q1 (" << resultQ1. size () <<
421 " cubes)... ";
422 for (int_t i = 0; i < resultQ1. size (); ++ i)
423 {
424 const TSetOfCubes &img = F (resultQ1 [i]);
425 for (int_t j = 0; j < img. size (); ++ j)
426 {
427 if (!resultQ1. check (img [j]))
428 resultQ2. add (img [j]);
429 }
430 }
431 sout << resultQ2. size () << " cubes added to Q2.\n";
432
433// sout << "Starting with " << resultQ1. size () <<
434// " cubes in Q1, " << resultQ2. size () <<
435// " cubes in Q2.\n";
436
437 // compute images of cubes in Q2 and if any of them intersects Q1
438 // then move this cube from Q2 to Q1
439 sout << "Increasing Q1 and Q2 until F(Q2) is disjoint from Q1... ";
440 int_t counter = 0;
441 int_t countimages = 0;
442 int_t cur = 0;
443 TSetOfCubes removed;
444 while (1)
445 {
446 // if there are no cubes in Q2, repeat or finish
447 if (cur >= resultQ2. size ())
448 {
449 if (removed. empty ())
450 break;
451 resultQ2. remove (removed);
452 TSetOfCubes empty;
453 removed = empty;
454 cur = 0;
455 continue;
456 }
457
458 // display a counter
459 ++ counter;
460 if (!(counter % 373))
461 scon << std::setw (12) << counter <<
462 "\b\b\b\b\b\b\b\b\b\b\b\b";
463
464 // verify whether F(q) intersects Q1
465 bool intersects = false;
466 const TSetOfCubes &img = F (resultQ2 [cur]);
467 ++ countimages;
468 for (int_t j = 0; j < img. size (); ++ j)
469 {
470 if (resultQ1. check (img [j]))
471 {
472 intersects = true;
473 break;
474 }
475 }
476
477 if (intersects)
478 {
479 // add F(q)\Q1 to Q2
480 for (int_t j = 0; j < img. size (); ++ j)
481 {
482 if (!resultQ1. check (img [j]))
483 resultQ2. add (img [j]);
484 }
485 // move q from Q2 to Q1
486 resultQ1. add (resultQ2 [cur]);
487 removed. add (resultQ2 [cur]);
488 }
489
490 // take the next cube from Q2
491 ++ cur;
492 }
493 sout << countimages << " analyzed.\n";
494 return 0;
495} /* IndexPairP */
496
497
498} // namespace homology
499} // namespace chomp
500
501#endif // _CHOMP_HOMOLOGY_INDXPALG_H_
502
504
This file includes header files with various definitions of cubical cells and defines the standard ty...
This class is a wrapper for a map that computes the image of a cube as a rectangular box (i....
Definition: indxpalg.h:76
int(* map)(const TCoordType *coord, double *left, double *right)
The class of a map that computes the image of a unitary cube.
Definition: indxpalg.h:85
TCube::CoordType TCoordType
The type of coordinates of a cube.
Definition: indxpalg.h:82
BufferedMapClass(map _f)
The constructor.
Definition: indxpalg.h:89
hashedset< TCube > TSetOfCubes
The type of the set of cubes.
Definition: indxpalg.h:79
mvmap< TCube, TCube > F
The multivalued cubical map computed so far.
Definition: indxpalg.h:96
map f
A pointer to the map which computes images of cubes.
Definition: indxpalg.h:100
const TSetOfCubes & operator()(const TCube &q) const
Computes the image of a cube under the map and adds the image cubes to the given set.
Definition: indxpalg.h:106
This is a general map class that may be inherited by your particular class that computes a map.
Definition: indxpalg.h:58
const TSetOfCubes & operator()(const TCube &q) const
Computes the image of a cube under the map and adds the image cubes to the given set.
Definition: indxpalg.h:62
This class defines a directed graph with very limited number of operations, and a few specific algori...
Definition: digraph.h:143
This is a template for a set of objects of the given type.
Definition: hashsets.h:185
This class defines a multivalued map.
Definition: hashsets.h:945
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 an interface to procedures for full cubical reduction.
This header file contains the definition of a weighted directed graph class and several algorithms on...
int int_t
Index type for indexing arrays, counting cubes, etc.
Definition: config.h:115
This namespace contains the core of the homology computation procedures and related classes and templ...
Definition: bitmaps.h:52
int ExitSetM(const TSetOfCubes &N, const TSetOfCubes &Q1, const TMap &F, TSetOfCubes &resultQ2)
Computes iteratively Q2 := (F (Q1 + Q2) - Q1) * N.
Definition: indxpalg.h:328
outputstream sout
A replacement for standard output stream, with optional logging and other features provided by the cl...
tRectangle< coordinate > rectangle
The rectangle class with the default type of coordinates.
Definition: pointset.h:87
std::ostream & operator<<(std::ostream &out, const bincube< Dim, twoPower > &b)
Definition: bincube.h:907
bool inclusion(const HSet &X, const HSet &Y)
Verifies if X is a subset of Y. Returns true if yes, false if not.
Definition: indxpalg.h:309
int neighborhood(const TSetOfCubes &X, TSetOfCubes &result)
Computes a cubical neighborhood of width 1 around the set.
Definition: indxpalg.h:190
int IndexPairM(const TMap &F, const TSetOfCubes &initialS, TSetOfCubes &resultQ1, TSetOfCubes &resultQ2)
Constructs a combinatorial index pair satisfying Mrozek's definition.
Definition: indxpalg.h:361
outputstream scon
The console output stream to which one should put all the junk that spoils the log file,...
void invariantpart(TSetOfCubes &X, const TMap &F, TSetOfCubes &result)
Computes X := Inv (X).
Definition: indxpalg.h:238
int_t SCC(const diGraph< wType > &g, Table1 &compVertices, Table2 &compEnds, diGraph< wType > *scc=0, diGraph< wType > *transposed=0, bool copyweights=false)
Computes strongly connected components of the graph 'g'.
Definition: digraph.h:2392
int IndexPairP(const TMap &F, const TSetOfCubes &initialS, TSetOfCubes &resultQ1, TSetOfCubes &resultQ2)
Constructs a combinatorial index pair satisfying Pilarczyk's definition.
Definition: indxpalg.h:414
This namespace contains the entire CHomP library interface.
Definition: bitmaps.h:51