The Conley-Morse Graphs Software
mapcomp.h
Go to the documentation of this file.
1/////////////////////////////////////////////////////////////////////////////
2///
3/// @file mapcomp.h
4///
5/// Map computation routines.
6/// This file contains the definition of routines for the computation
7/// of combinatorial cubical multivalued maps.
8///
9/// @author Pawel Pilarczyk
10///
11/////////////////////////////////////////////////////////////////////////////
12
13// Copyright (C) 1997-2014 by Pawel Pilarczyk.
14//
15// This file is part of my research software package. This is free software:
16// you can redistribute it and/or modify it under the terms of the GNU
17// General Public License as published by the Free Software Foundation,
18// either version 3 of the License, or (at your option) any later version.
19//
20// This software is distributed in the hope that it will be useful,
21// but WITHOUT ANY WARRANTY; without even the implied warranty of
22// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23// GNU General Public License for more details.
24//
25// You should have received a copy of the GNU General Public License
26// along with this software; see the file "license.txt". If not,
27// please, see <https://www.gnu.org/licenses/>.
28
29// Started on July 19, 2006. Last revision: March 16, 2016.
30
31
32#ifndef _CMGRAPHS_MAPCOMP_H_
33#define _CMGRAPHS_MAPCOMP_H_
34
35
36// include some standard C++ header files
37#include <iostream>
38#include <fstream>
39#include <algorithm>
40#include <memory>
41#include <new>
42
43// include selected header files from the CHomP library
44#include "chomp/system/textfile.h"
45#include "chomp/system/timeused.h"
46#include "chomp/struct/autoarray.h"
47#include "chomp/struct/digraph.h"
48
49// include local header files
50#include "config.h"
51#include "typedefs.h"
52#include "typeintv.h"
53#include "mapdist.h"
54#include "utils.h"
55
56
57// --------------------------------------------------
58// ----------------- MapComputation -----------------
59// --------------------------------------------------
60
61/// A generic map computation routine that computes a rigorous
62/// cubical multivalued map based on a function that computes the image
63/// of intervals using interval arithmetic. The "mapcomp" class must have
64/// a method called "compute" which is used to compute the map
65/// in interval arithmetic.
66template <class mapcomp, class cubetype,
67 class cubsettype = chomp::homology::hashedset<cubetype> >
69{
70public:
71 /// The type of the underlying interval map.
72 typedef mapcomp MapCompType;
73
74 /// The type of the graph used in the computation of the image.
75 typedef chomp::homology::diGraph<> GraphType;
76
77 /// The map used to compute an interval enclosure of the image
78 /// of an interval box.
79 const mapcomp &M;
80
81 /// The default constructor.
82 /// Remembers the offset and width of the phase space,
83 /// and the width (the same in each direction) in integers.
84 /// Note: 'intwidth' does not have to be a power of 2.
85 /// Note: The arrays of the offset and width of the phase space
86 /// must exist until the object is deleted; the same for the map.
87 MapComputation (const double *_offset, const double *_width,
88 int _intwidth, int _subdivdepth,
89 const mapcomp &_M);
90
91 /// The destructor.
93
94 /// The operator for computing the image of a box as a set of boxes,
95 /// as it is in a combinatorial cubical multivalued map.
96 /// The image is restricted to the given codomain (if provided).
97 /// The integral coefficients of cubes are transformed to real
98 /// numbers according to the rectangular area defined by offset
99 /// from the origin and its width, as well as the width
100 /// of this area in terms of integral coordinates.
101 int operator () (const cubetype &q, cubsettype *img,
102 chomp::homology::diGraph<> *g, const cubsettype *codomain,
103 const cubsettype *disjoint, bool throwIfCropped) const;
104
105 /// Using cache for the map.
106 bool cache;
107
108 /// Is cropping of images to the designated box in effect?
109 mutable bool cropping;
110
111 /// Was the image cropped at least once? Reset this variable
112 /// to "false" in order to detect image cropping again.
113 mutable bool cropped;
114
115 /// The maximal image diameter encountered so far.
116 /// Set this variable to zero to gather meaningful information.
117 static int maxImgDiam;
118
119 /// The maximal image volume encountered so far.
120 /// Set this variable to zero to gather meaningful information.
121 static int maxImgVol;
122
123 /// Returns the width of the phase space in terms of
124 /// the number of boxes.
125 int intWidth () const;
126
127 /// Returns the subdivision depth at which the computations are done.
128 int subdivDepth () const;
129
130 /// A helper function that encloses an interval box
131 /// in the interior of a box with integer coordinates.
132 template <class IntervalArray>
133 static void encloseIntervalInt (const IntervalArray &box, int dim,
134 typename cubetype::CoordType *left,
135 typename cubetype::CoordType *right);
136
137 /// Cleans the cache of the cubical map, e.g., if the underlying
138 /// interval map has changed.
139 void cleanCache () const;
140
141 /// Sets new (more or less restrictive) limits for the maximal
142 /// allowed image diameter and volume.
143 static void setAllowedImgSize (int diameter, int volume);
144
145protected:
146 /// The offset of the cubical rectangle.
147 const double *offset;
148
149 /// The width of the rectangle in each direction.
150 const double *width;
151
152 /// The width of the rectangle in terms of the number of cubes.
154
155 /// The binary subdivision depth.
157
158 /// Use interval arithmetic to compute the coordinate scope.
159 /// The image scaled to the interval grid may be saved
160 /// if an array of intervals is provided.
161 /// Note: 'coord' may point to the same location
162 /// as 'left' or 'right'.
163 int compute (const typename cubetype::CoordType *coord, int dim,
164 typename cubetype::CoordType *left,
165 typename cubetype::CoordType *right,
166 IntervalType *scaledImage) const;
167
168 /// The maximal allowed image diameter.
170
171 /// The maximal allowed image volume.
173
174private:
175 /// The number of times the cache was used successfully.
176 mutable int_t cacheused;
177
178 /// The cache domain.
179 mutable cubsettype computed;
180
181 /// The cache left vertex.
182 mutable chomp::homology::multitable<cubetype> leftcache;
183
184 /// The cache right vertex.
185 mutable chomp::homology::multitable<cubetype> rightcache;
186
187 /// The cached interval vectors for images.
188 mutable chomp::homology::multitable<IntervalType *> imagecache;
189
190 /// Map distance measuring object.
191 /// This is an auxiliary object for gathering information
192 /// on the distance of a cube from certain subspaces
193 /// in comparison to the distance of its image.
194 /// Please, see the definition of this class
195 /// for more details.
197
198}; /* class MapComputation */
199
200// --------------------------------------------------
201
202template <class mapcomp, class cubetype, class cubsettype>
204
205template <class mapcomp, class cubetype, class cubsettype>
207
208template <class mapcomp, class cubetype, class cubsettype>
211
212template <class mapcomp, class cubetype, class cubsettype>
215
216// --------------------------------------------------
217
218template <class mapcomp, class cubetype, class cubsettype>
220 (const double *_offset, const double *_width,
221 int _intwidth, int _subdivdepth, const mapcomp &_M):
222 M (_M), cache (false), cropping (false), cropped (false),
223 offset (_offset), width (_width),
224 intwidth (_intwidth), subdivdepth (_subdivdepth),
225 cacheused (0), leftcache (8192), rightcache (8192)
226{
227 testIntervals ();
228 return;
229} /* MapComputation::MapComputation */
230
231template <class mapcomp, class cubetype, class cubsettype>
233{
234 // DEBUG
235// if (cache && !computed. empty ())
236// chomp::homology::sbug << "MAP: " << computed. size () <<
237// " images cached, used " << cacheused << " times.\n";
238
239 // DEBUG: Save the map.
240 if (cache && false)
241 {
242 std::ofstream f ("f.map");
243 for (int_t i = 0; i < computed. size (); ++ i)
244 {
245 typename cubetype::CoordType c [cubetype::MaxDim];
246 f << "[" << computed [i];
247 computed [i]. coord (c);
248 for (int j = 0; j < computed [i]. dim (); ++ j)
249 ++ c [j];
250 f << cubetype (c, computed [i]. dim ()) << "] ";
251 f << "[" << leftcache [i] << rightcache [i] << "]\n";
252 }
253 }
254
255 // delete the cached scaled images
256#ifdef CONFIG_IFRACTION
257 for (int_t i = 0; i < computed. size (); ++ i)
258 delete [] (imagecache [i]);
259#endif
260
261 return;
262} /* MapComputation::~MapComputation */
263
264// --------------------------------------------------
265
266template <class mapcomp, class cubetype, class cubsettype>
267template <class IntervalArray>
269 (const IntervalArray &box, int dim,
270 typename cubetype::CoordType *left,
271 typename cubetype::CoordType *right)
272{
273 typedef typename cubetype::CoordType CoordType;
274
275 // make sure that the actual image is contained
276 // in the INTERIOR of the box with integer coordinates
277 for (int i = 0; i < dim; ++ i)
278 {
279 double left_b = box [i]. leftBound ();
280 left [i] = static_cast<CoordType> (left_b);
281 for (int j = 0; (j < 4) && (left [i] >= left_b); ++ j)
282 -- left [i];
283 if ((left [i] >= left_b) || (left_b - left [i] > 2))
284 {
285 throw "Interval enclosure: Left bound out of range.";
286 }
287
288 double right_b = box [i]. rightBound ();
289 right [i] = static_cast<CoordType> (right_b);
290 for (int j = 0; (j < 4) && (right [i] <= right_b); ++ j)
291 ++ right [i];
292 if ((right [i] <= right_b) || (right [i] - right_b > 2))
293 {
294 throw "Interval enclosure: "
295 "Right bound out of range.";
296 }
297 }
298 return;
299} /* MapComputation::encloseIntervalInt */
300
301template <class mapcomp, class cubetype, class cubsettype>
303 (const typename cubetype::CoordType *coord, int dim,
304 typename cubetype::CoordType *left,
305 typename cubetype::CoordType *right,
306 IntervalType *scaledImage) const
307{
308 using chomp::homology::auto_array;
309
310 // compute the actual box corresponding to the cube
311 auto_array<IntervalType> xPtr (new IntervalType [dim]);
312 IntervalType *x = xPtr. get ();
313 for (int i = 0; i < dim; ++ i)
314 {
315 x [i] = IntervalType (coord [i], coord [i] + 1);
316 x [i] /= intwidth;
317 x [i] *= width [i];
318 x [i] += offset [i];
319 }
320 // swich the rounding direction to the neutral one
321 resetRounding ();
322
323 // compute the image of this box
324 auto_array<IntervalType> yPtr
325 (scaledImage ? 0 : new IntervalType [dim]);
326 IntervalType *y = scaledImage ? scaledImage : yPtr. get ();
327 M (x, y, dim, coord, subdivdepth);
328 checkDistance (coord, dim, x, y);
329
330 // measure the expansion of the map and output it to the screen
331 // (temporary code for the "plasma" model, Dec 7, 2010)
332 if (false)
333 {
334 using chomp::homology::slog;
335 slog << "Exp " << cubetype (coord, dim) << ": (";
336 for (int i = 0; i < dim; ++ i)
337 {
338 double expansion = (y [i]. rightBound () -
339 y [i]. leftBound ()) /
340 (x [i]. rightBound () - x [i]. leftBound ());
341 slog << (i ? "," : "") << expansion;
342 }
343 slog << ")\n";
344 }
345
346 // rescale the image box (towards the integer coordinates)
347 for (int i = 0; i < dim; ++ i)
348 {
349 y [i] -= offset [i];
350 y [i] /= width [i];
351 y [i] *= intwidth;
352 }
353 // swich the rounding direction to the neutral one
354 resetRounding ();
355
356 encloseIntervalInt (y, dim, left, right);
357
358 return 0;
359} /* MapComputation::compute */
360
361template <class mapcomp, class cubetype, class cubsettype>
363 (const cubetype &q, cubsettype *img,
364 chomp::homology::diGraph<> *g, const cubsettype *codomain,
365 const cubsettype *disjoint, bool throwIfCropped) const
366{
367 using chomp::homology::auto_array;
368
369 typedef typename cubetype::CoordType coordType;
370
371 // prepare arrays for the range of the image box
372 int dim = q. dim ();
373 auto_array<coordType> leftPtr (new coordType [dim]);
374 coordType *left = leftPtr. get ();
375 auto_array<coordType> rightPtr (new coordType [dim]);
376 coordType *right = rightPtr. get ();
377
378 // check if the image of this cube has already been computed
379 int_t number = cache ? computed. getnumber (q) :
380 static_cast<int_t> (-1);
381
382 // prepare an interval vector for scaled image (if necessary)
383#ifdef CONFIG_IFRACTION
384 auto_array<IntervalType> scaledImagePtr (new IntervalType [dim]);
385 IntervalType *scaledImage (scaledImagePtr. get ());
386#else
387 IntervalType *scaledImage (0);
388#endif
389
390 // compute the image of this box if necessary
391 if (number < 0)
392 {
393 // determine the cordinates of the lower left vertex
394 q. coord (left);
395
396 // compute the image of the box
397 compute (left, dim, left, right, scaledImage);
398
399 // store this image in the cache if requested to
400 if (cache)
401 {
402 leftcache [computed. size ()] = cubetype (left, dim);
403 rightcache [computed. size ()] =
404 cubetype (right, dim);
405#ifdef CONFIG_IFRACTION
406 imagecache [computed. size ()] =
407 scaledImagePtr. release ();
408#endif
409 computed. add (q);
410 }
411 }
412
413 // use the cached values for the image of this box
414 else
415 {
416 // retrieve the coordinates of the left and right ends
417 leftcache [number]. coord (left);
418 rightcache [number]. coord (right);
419#ifdef CONFIG_IFRACTION
420 scaledImage = imagecache [number];
421#endif
422
423 // increase the right coorinates in case of wrapping
424 for (int i = 0; i < dim; ++ i)
425 {
426 if (right [i] <= left [i])
427 right [i] += intwidth;
428 }
429
430 // make a note that the cached value has been used
431 ++ cacheused;
432 }
433
434 // crop the image of this box to the given area if necessary
435 if (cropping)
436 {
437 cropRanges (left, right, dim,
438 intwidth, throwIfCropped, cropped);
439 }
440
441 // make sure that the size of the image is reasonably small
442 long volume = checkImageSize (left, right, dim,
443 maxImgDiam, maxImgVol, maxImgDiamAllowed, maxImgVolAllowed);
444
445 // compute the set of cubes that is the image of the given box;
446 // if codomain is defined then compute the restriction of the box
447 if (codomain)
448 {
449 // if the size of codomain is smaller than the volume of the
450 // image box then check all the cubes if they are in the box
451 if (codomain && (codomain -> size () < volume + 8))
452 {
453 // prepare an array for the coordinates of cubes
454 auto_array<coordType> coordPtr (new coordType [dim]);
455 coordType *c = coordPtr. get ();
456 int_t codomSize = codomain -> size ();
457
458 // check all the cubes in the codomain
459 for (int_t i = 0; i < codomSize; ++ i)
460 {
461 // retrieve the coordinates of the cube
462 const cubetype &q = (*codomain) [i];
463 if (disjoint && disjoint -> check (q))
464 continue;
465 q. coord (c);
466
467#ifdef CONFIG_IFRACTION
468 // check the percentage of intersection
469 if (intersectionVolume (c, scaledImage,
470 dim) < CONFIG_IFRACTION)
471 {
472 continue;
473 }
474#else
475 // check if the cube is inside the rectangle
476 bool inside = true;
477 for (int j = 0; j < dim; ++ j)
478 {
479 if ((c [j] < left [j]) ||
480 (c [j] >= right [j]))
481 {
482 inside = false;
483 break;
484 }
485 }
486 if (!inside)
487 continue;
488#endif
489 // add the cube to the image being computed
490 if (img)
491 img -> add (q);
492 if (g)
493 g -> addEdge (i);
494 }
495 }
496
497 // otherwise, process all the cubes in the image rectangle
498 else
499 {
500 chomp::homology::tRectangle<typename
501 cubetype::CoordType> r (left, right, dim);
502 const typename cubetype::CoordType *c;
503 while ((c = r. get ()) != 0)
504 {
505 cubetype q (c, dim);
506 if (disjoint && disjoint -> check (q))
507 continue;
508 int_t n = codomain ?
509 codomain -> getnumber (q) : -1;
510 if (n < 0)
511 continue;
512#ifdef CONFIG_IFRACTION
513 // check the percentage of intersection
514 if (intersectionVolume (c, scaledImage,
515 dim) < CONFIG_IFRACTION)
516 {
517 continue;
518 }
519#endif
520 if (img)
521 img -> add (q);
522 if (g)
523 g -> addEdge (n);
524 }
525 }
526 }
527
528 // otherwise, add all the cubes in the entire rectangular box
529 else if (img)
530 {
531 chomp::homology::tRectangle<typename cubetype::CoordType>
532 r (left, right, dim);
533 const typename cubetype::CoordType *c;
534 while ((c = r. get ()) != 0)
535 {
536 cubetype q (c, dim);
537 if (disjoint && disjoint -> check (q))
538 continue;
539#ifdef CONFIG_IFRACTION
540 // check the percentage of intersection
541 if (intersectionVolume (c, scaledImage,
542 dim) < CONFIG_IFRACTION)
543 {
544 continue;
545 }
546#endif
547 img -> add (q);
548 }
549 }
550
551 return 0;
552} /* MapComputation::operator () */
553
554template <class mapcomp, class cubetype, class cubsettype>
556 const
557{
558 return intwidth;
559} /* MapComputation::intWidth */
560
561template <class mapcomp, class cubetype, class cubsettype>
563 const
564{
565 return subdivdepth;
566} /* MapComputation::subdivDepth */
567
568template <class mapcomp, class cubetype, class cubsettype>
570{
571 cubsettype empty;
572 computed = empty;
573 return;
574} /* MapComputation::cleanCache */
575
576template <class mapcomp, class cubetype, class cubsettype>
578 (int diameter, int volume)
579{
580// chomp::homology::sbug << "Setting max img diam & vol to " <<
581// diameter << " and " << volume << ".\n";
582 maxImgDiamAllowed = diameter;
583 maxImgVolAllowed = volume;
584 return;
585} /* MapComputation::setAllowedImgSize */
586
587
588#endif // _CMGRAPHS_MAPCOMP_H_
589
A generic map computation routine that computes a rigorous cubical multivalued map based on a functio...
Definition: mapcomp.h:69
static void setAllowedImgSize(int diameter, int volume)
Sets new (more or less restrictive) limits for the maximal allowed image diameter and volume.
Definition: mapcomp.h:578
bool cache
Using cache for the map.
Definition: mapcomp.h:106
bool cropping
Is cropping of images to the designated box in effect?
Definition: mapcomp.h:109
int_t cacheused
The number of times the cache was used successfully.
Definition: mapcomp.h:176
int subdivdepth
The binary subdivision depth.
Definition: mapcomp.h:156
const mapcomp & M
The map used to compute an interval enclosure of the image of an interval box.
Definition: mapcomp.h:79
int subdivDepth() const
Returns the subdivision depth at which the computations are done.
Definition: mapcomp.h:562
static void encloseIntervalInt(const IntervalArray &box, int dim, typename cubetype::CoordType *left, typename cubetype::CoordType *right)
A helper function that encloses an interval box in the interior of a box with integer coordinates.
Definition: mapcomp.h:269
MapDistance< cubetype, cubsettype > checkDistance
Map distance measuring object.
Definition: mapcomp.h:196
~MapComputation()
The destructor.
Definition: mapcomp.h:232
MapComputation(const double *_offset, const double *_width, int _intwidth, int _subdivdepth, const mapcomp &_M)
The default constructor.
Definition: mapcomp.h:220
chomp::homology::multitable< cubetype > leftcache
The cache left vertex.
Definition: mapcomp.h:182
const double * width
The width of the rectangle in each direction.
Definition: mapcomp.h:150
const double * offset
The offset of the cubical rectangle.
Definition: mapcomp.h:147
chomp::homology::multitable< IntervalType * > imagecache
The cached interval vectors for images.
Definition: mapcomp.h:188
chomp::homology::multitable< cubetype > rightcache
The cache right vertex.
Definition: mapcomp.h:185
void cleanCache() const
Cleans the cache of the cubical map, e.g., if the underlying interval map has changed.
Definition: mapcomp.h:569
static int maxImgDiam
The maximal image diameter encountered so far.
Definition: mapcomp.h:117
int intWidth() const
Returns the width of the phase space in terms of the number of boxes.
Definition: mapcomp.h:555
static int maxImgDiamAllowed
The maximal allowed image diameter.
Definition: mapcomp.h:169
mapcomp MapCompType
The type of the underlying interval map.
Definition: mapcomp.h:72
chomp::homology::diGraph GraphType
The type of the graph used in the computation of the image.
Definition: mapcomp.h:75
int intwidth
The width of the rectangle in terms of the number of cubes.
Definition: mapcomp.h:153
int compute(const typename cubetype::CoordType *coord, int dim, typename cubetype::CoordType *left, typename cubetype::CoordType *right, IntervalType *scaledImage) const
Use interval arithmetic to compute the coordinate scope.
Definition: mapcomp.h:303
static int maxImgVol
The maximal image volume encountered so far.
Definition: mapcomp.h:121
int operator()(const cubetype &q, cubsettype *img, chomp::homology::diGraph<> *g, const cubsettype *codomain, const cubsettype *disjoint, bool throwIfCropped) const
The operator for computing the image of a box as a set of boxes, as it is in a combinatorial cubical ...
Definition: mapcomp.h:363
bool cropped
Was the image cropped at least once? Reset this variable to "false" in order to detect image cropping...
Definition: mapcomp.h:113
static int maxImgVolAllowed
The maximal allowed image volume.
Definition: mapcomp.h:172
cubsettype computed
The cache domain.
Definition: mapcomp.h:179
The map distance change tracker.
Definition: mapdist.h:70
Choice of configuration settings.
bool disjoint(const pointset &p, const pointset &q)
Definition: psetjoin.cpp:139
Map computation distance checker.
const int maxImageVolume
The maximal allowed volume of the cubical image of a single box.
Definition: p_differ.h:164
const int maxImageDiameter
The maximal allowed diameter of the cubical image of a signle box.
Definition: p_differ.h:159
Customizable data types for the Conley-Morse graphs computation program.
Data types for interval arithmetic.
void resetRounding()
This function resets rounding switches of the processor and sets rounding to the nearest.
Definition: typeintv.h:65
bool testIntervals(bool throwException=false)
Testing interval arithmetic.
Definition: typeintv.h:82
capd::DInterval IntervalType
The type of an interval (from the CAPD library 2.9/3.0 beta).
Definition: typeintv.h:49
Utilites and helper functions.
double intersectionVolume(const CoordType *c, const IntervalType *intervalBox, int dim)
Computes the volume of the intersection of the unitary cube with the provided coordinates with the gi...
Definition: utils.h:844
void cropRanges(CoordType *left, CoordType *right, int dim, int intwidth, bool throwIfCropped, bool &cropped)
Crops the ranges, marks this fact if it occurred, and throws an exception if requested to.
Definition: utils.h:724
long checkImageSize(const CoordType *left, const CoordType *right, int dim, int &maxImgDiam, int &maxImgVol, int maxImgDiamAllowed, int maxImgVolAllowed)
Checks if the size of the image does not exceed the globally defined maximal diameter and maximal vol...
Definition: utils.h:755