The Conley-Morse Graphs Software
invpart.h
Go to the documentation of this file.
1/////////////////////////////////////////////////////////////////////////////
2///
3/// @file invpart.h
4///
5/// Computation of the invariant part of a set of cubes.
6/// This file contains the definition of a function
7/// for the computation of the invariant part of a set of cubes
8/// with respect to a given multivalued map.
9/// It also contains the procedure for verifying whether the invariant part
10/// is nonempty after subdividing the set of cubes a few times.
11///
12/// @author Pawel Pilarczyk
13///
14/////////////////////////////////////////////////////////////////////////////
15
16// Copyright (C) 1997-2014 by Pawel Pilarczyk.
17//
18// This file is part of my research software package. This is free software:
19// you can redistribute it and/or modify it under the terms of the GNU
20// General Public License as published by the Free Software Foundation,
21// either version 3 of the License, or (at your option) any later version.
22//
23// This software is distributed in the hope that it will be useful,
24// but WITHOUT ANY WARRANTY; without even the implied warranty of
25// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26// GNU General Public License for more details.
27//
28// You should have received a copy of the GNU General Public License
29// along with this software; see the file "license.txt". If not,
30// please, see <https://www.gnu.org/licenses/>.
31
32// Started on February 12, 2007. Last revision: October 9, 2022.
33
34
35#ifndef _CMGRAPHS_INVPART_H_
36#define _CMGRAPHS_INVPART_H_
37
38
39// include selected header files from the CHomP library
40#include "chomp/system/textfile.h"
41#include "chomp/cubes/cube.h"
42#include "chomp/struct/digraph.h"
43#include "chomp/struct/multitab.h"
44
45// include local header files
46#include "config.h"
47#include "typedefs.h"
48#include "mapgraph.h"
49#include "typedyns.h"
50
51
52// --------------------------------------------------
53// ----------------- invariant part -----------------
54// --------------------------------------------------
55
56/// Computes X := Inv (X) using the algorithm by Bill Kalies and Hyunju Ban.
57/// If the graph 'gInv' is given, then the resulting graph is created,
58/// otherwise only the set X is modified.
59template <class typeCubes>
60inline void invariantPart (typeCubes &X, const chomp::homology::diGraph<> &g,
61 chomp::homology::diGraph<> *gInv = 0)
62{
63 // do nothing if the set X is empty
64 if (X. empty ())
65 return;
66
67 // compute the chain recurrent set of the graph
68 // and remember the transposed graph
69 chomp::homology::multitable<int_t> compVertices (8192);
70 chomp::homology::multitable<int_t> compEnds (8192);
71 chomp::homology::diGraph<> gT;
72 int_t count = chomp::homology::SCC (g, compVertices, compEnds,
73 static_cast<chomp::homology::diGraph<> *> (0), &gT);
74
75 // retrieve vertices that can be reached from the chain recurrent set
76 int_t nVertices = X. size ();
77 char *forward = new char [nVertices];
78 for (int_t i = 0; i < nVertices; ++ i)
79 forward [i] = 0;
80 for (int_t cur = 0; cur < count; ++ cur)
81 {
82 g. DFScolor (forward, '\1',
83 compVertices [cur ? compEnds [cur - 1] :
84 static_cast<int_t> (0)]);
85 }
86
87 // retrieve vertices that can reach the chain recurrent set
88 char *backward = new char [nVertices];
89 for (int_t i = 0; i < nVertices; ++ i)
90 backward [i] = 0;
91 for (int_t cur = 0; cur < count; ++ cur)
92 {
93 gT. DFScolor (backward, '\1',
94 compVertices [cur ? compEnds [cur - 1] :
95 static_cast<int_t> (0)]);
96 }
97
98 // compute the new set of cubes and exit if gInv is null
99 typeCubes invX;
100 if (!gInv)
101 {
102 for (int_t i = 0; i < nVertices; ++ i)
103 if (forward [i] && backward [i])
104 invX. add (X [i]);
105 }
106 else
107 {
108 // join both tables and compute the new set of cubes
109 for (int_t i = 0; i < nVertices; ++ i)
110 {
111 forward [i] &= backward [i];
112 if (forward [i])
113 invX. add (X [i]);
114 }
115
116 // restrict the graph to the colored vertices
117 g. subgraph (*gInv, forward);
118 }
119
120 // swap the set of cubes and the corresponding graph
121 X. swap (invX);
122
123 // clean the memory and return
124 delete [] backward;
125 delete [] forward;
126 return;
127} /* invariantPart */
128
129/// Computes X := Inv (X) using the algorithm by Bill Kalies and Hyunju Ban.
130/// Uses the combinatorial cubical multivalued map provided.
131/// Returns 0 on success or -1 if failed. Shows messages to 'sbug'.
132template <class typeCubes, class theCubMapType>
133inline int invariantPart (typeCubes &X, const theCubMapType &theCubMap,
134 bool cropping = true)
135{
136 using chomp::homology::sbug;
137
138 // compute the graph representation of the cubical map
139 sbug << "F ";
140 chomp::homology::diGraph<> g;
141 try
142 {
143 // compute the graph that represents the map restricted to X
144 computeMapGraph (X, g, theCubMap, cropping);
145
146 // show the average size of the image of a cube
147 int_t avgImgSize = g. countEdges () /
148 (X. size () ? X. size () : static_cast<int_t> (1));
149 sbug << "[avg " << avgImgSize << "] ";
150
151 }
152 catch (const char *msg)
153 {
154 // return -1 in case of failure
155 sbug << "Failed: " << msg << "\n";
156 return -1;
157 }
158
159 // compute the invariant part of X in case of success
160 sbug << "Inv... ";
161 invariantPart (X, g);
162 sbug << X. size () << " left.\n";
163
164 return 0;
165} /* invariantPart */
166
167/// Verifies whether the invariant part of the given set is empty
168/// by applying a limited number of refinements until the set is empty
169/// or the number of cubes becomes too large.
170/// Returns "true" if it is empty, "false" if this could not be proved.
171inline bool checkEmptyInv (const spcCubes &X, int subdivDepth,
172 const double *offset, const double *width, const theMapType &theMap,
173 const theCubMapType &theCubMap0, const theCubMapType &theCubMap1)
174{
175 using chomp::homology::sbug;
176 using chomp::homology::diGraph;
177
178 if (X. empty () || (X. size () > maxRefineSize0))
179 return false;
180 spcCubes Z;
181 int subdivisions = 0;
182 while (subdivisions < refineDepth)
183 {
184 // subdivide X or Z to Y
185 spcCubes Y;
186 const spcCubes &source = Z. empty () ? X : Z;
187 sbug << "* Subdiv " << source. size () << " -> ";
188 subdivideCubes (source, Y);
189 sbug << Y. size () << ". ";
190 spcCubes emptySet;
191 Z = emptySet;
192 ++ subdivisions;
193
194 // compute the invariant part of Y
195 theCubMapType subdivCubMap (offset, width,
196 1 << (subdivDepth + subdivisions),
197 subdivDepth + subdivisions, theMap);
198 subdivCubMap. cache = false;
199 if (subdivisions > 1)
200 {
201 subdivCubMap. setAllowedImgSize
202 (maxImageDiameter << 3, maxImageVolume << 3);
203 }
204 const theCubMapType &theCubMap =
205 (subdivisions > 1) ? subdivCubMap :
206 (subdivisions ? theCubMap1 : theCubMap0);
207 int result = invariantPart (Y, theCubMap);
208
209 // if the computation failed then return the negative result
210 if (result < 0)
211 return false;
212
213 // return the positive result if the invariant part is empty
214 if (Y. empty ())
215 {
216 sbug << "* Empty after " << subdivisions <<
217 ((subdivisions == 1) ? " subdivision.\n" :
218 " subdivisions.\n");
219 return true;
220 }
221
222 // remember the current set of cubes as Z
223 Z. swap (Y);
224
225 // exit the loop if there are too many cubes
226 if (Z. size () > maxRefineSize1)
227 break;
228 }
229 sbug << "* Nonempty after " << subdivisions <<
230 ((subdivisions == 1) ? " subdivision (" :
231 " subdivisions (") << Z. size () << " cubes left).\n";
232 return false;
233} /* checkEmptyInv */
234
235/// Computes the strongly connected path components
236/// of the graph representation of the multivalued map on the given set.
237/// Returns the number of components and fills in the array provided
238/// or returns -1 in case of failure.
239/// Shows messages to 'sbug'.
240template <class CubSetType, class CubSetArrayType, class CubMapType>
241inline int_t findSCCs (const CubSetType &X, const CubMapType &theCubMap,
242 CubSetArrayType &components)
243{
244 using chomp::homology::sbug;
245
246 // compute the graph representation of the cubical map
247 sbug << "F ";
248 chomp::homology::diGraph<> g;
249 try
250 {
251 // compute the graph that represents the map restricted to X
252 computeMapGraph (X, g, theCubMap);
253
254 // show the average size of the image of a cube
255 int_t avgImgSize = g. countEdges () /
256 (X. size () ? X. size () : static_cast<int_t> (1));
257 sbug << "[avg " << avgImgSize << "] ";
258
259 }
260 catch (const char *msg)
261 {
262 // return -1 in case of failure
263 sbug << "Failed: " << msg << "\n";
264 return -1;
265 }
266
267 // compute the components of the chain recurrent set of the graph
268 sbug << "SCC... ";
269 chomp::homology::multitable<int_t> compVertices (8192);
270 chomp::homology::multitable<int_t> compEnds (8192);
271 chomp::homology::diGraph<> *sccAddr = 0;
272 chomp::homology::diGraph<> *transpAddr = 0;
273 int_t nSets = chomp::homology::SCC (g, compVertices, compEnds,
274 sccAddr, transpAddr);
275 sbug << nSets << ".\n";
276
277 // put the corresponding cubes into the array of sets of cubes
278 int_t cur = 0;
279 for (int_t n = 0; n < nSets; ++ n)
280 {
281 int_t end = compEnds [n];
282 while (cur < end)
283 {
284 components [n]. add (X [compVertices [cur]]);
285 ++ cur;
286 }
287 }
288
289 return nSets;
290} /* findSCCs */
291
292
293
294#endif // _CMGRAPHS_INVPART_H_
295
A generic map computation routine that computes a rigorous cubical multivalued map based on a functio...
Definition: mapcomp.h:69
This class defines a map derived from a sample difference equation.
Definition: m_differ.h:47
Choice of configuration settings.
void invariantPart(typeCubes &X, const chomp::homology::diGraph<> &g, chomp::homology::diGraph<> *gInv=0)
Computes X := Inv (X) using the algorithm by Bill Kalies and Hyunju Ban.
Definition: invpart.h:60
bool checkEmptyInv(const spcCubes &X, int subdivDepth, const double *offset, const double *width, const theMapType &theMap, const theCubMapType &theCubMap0, const theCubMapType &theCubMap1)
Verifies whether the invariant part of the given set is empty by applying a limited number of refinem...
Definition: invpart.h:171
int_t findSCCs(const CubSetType &X, const CubMapType &theCubMap, CubSetArrayType &components)
Computes the strongly connected path components of the graph representation of the multivalued map on...
Definition: invpart.h:241
Computation of the graph representation of a combinatorial map.
void computeMapGraph(const typeCubes &X, typeGraph &g, const typeCubMap &theCubMap, bool cropping=true)
Computes the cubical map on 'X' and fills out the graph 'g'.
Definition: mapgraph.h:56
const int refineDepth
The number of refinements that should be done if a Morse set with the trivial index is encountered or...
Definition: p_differ.h:139
const int maxRefineSize0
The maximal allowed size of a set of cubes in the phase space which can be refined at the initial sub...
Definition: p_differ.h:144
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
const int maxRefineSize1
The maximal allowed size of a set of cubes in the phase space which can be refined at the subsequent ...
Definition: p_differ.h:149
Customizable data types for the Conley-Morse graphs computation program.
Data types for the dynamical systems data structures.
chomp::homology::hashedset< spcCube > spcCubes
The type of a set of cubes in the phase space.
Definition: typespace.h:58
void subdivideCubes(const typeCubes &X, typeCubes &result)
Subdivides one set of cubes to another set of cubes with respect to twice finer grid.
Definition: utils.h:590