33#ifndef _CMGRAPHS_PROCRECUR_H_
34#define _CMGRAPHS_PROCRECUR_H_
43#include "chomp/system/config.h"
44#include "chomp/system/textfile.h"
45#include "chomp/system/timeused.h"
46#include "chomp/struct/digraph.h"
47#include "chomp/struct/flatmatr.h"
48#include "chomp/struct/multitab.h"
62namespace procRecurrence {
70template <
class GraphType>
71inline void graph2dot (
const GraphType &g, std::ostream &out)
73 int_t nVertices = g. countVertices ();
77 for (int_t vertex = 0; vertex < nVertices; ++ vertex)
79 out << (vertex ?
" " :
"") <<
"v" << vertex <<
80 " [label=\"" << vertex <<
"\"]";
84 for (int_t vertex = 0; vertex < nVertices; ++ vertex)
86 int_t nEdges = g. countEdges (vertex);
87 for (int_t edge = 0; edge < nEdges; ++ edge)
89 int_t target = g. getEdge (vertex, edge);
90 out <<
" v" << vertex <<
"->v" << target;
103template <
class ArrayType,
class GraphType>
106 using chomp::homology::sbug;
109 const int maxVertices = 30000;
110 if (g. countVertices () > maxVertices)
112 sbug <<
"The number of cubes exceeds " << maxVertices <<
113 ". Skipping the analysis.\n";
119 sbug <<
"Copying the graph...\n";
120 typedef chomp::homology::diGraph<int_t> WGraphType;
122 int_t nVertices = g. countVertices ();
123 std::vector<bool> selfEdges (nVertices,
false);
124 for (int_t vertex = 0; vertex < nVertices; ++ vertex)
127 int_t nEdges = g. countEdges (vertex);
128 for (int_t edge = 0; edge < nEdges; ++ edge)
130 int_t target = g. getEdge (vertex, edge);
131 wg. addEdge (target, 1);
132 if (vertex == target)
133 selfEdges [vertex] =
true;
139 sbug <<
"Preparing a " << nVertices <<
"x" << nVertices <<
140 " matrix (" << (nVertices * nVertices *
sizeof(int_t) /
141 1024 / 1024) <<
" MB)...\n";
142 std::vector<std::vector<signed char> > D (nVertices,
143 std::vector<signed char> (nVertices));
145 sbug <<
"Running Dijkstra " << nVertices <<
" times...\n";
146 std::vector<int_t> tempResults (nVertices);
147 for (int_t source = 0; source < nVertices; ++ source)
149 if (source && !(source % 17))
152 wg. Dijkstra (source, tempResults);
154 for (int_t i = 0; i < nVertices; ++ i)
156 if (tempResults [i] < -128)
157 D [source] [i] = -128;
158 else if (tempResults [i] > 127)
159 D [source] [i] = 127;
161 D [source] [i] = tempResults [i];
166 sbug <<
"Computing minimum loop lengths...\n";
167 for (int_t source = 0; source < nVertices; ++ source)
170 if (selfEdges [source])
172 recurrence [source] = 1;
178 for (int_t other = 0; other < nVertices; ++ other)
183 int_t len1 = D [source] [other];
184 int_t len2 = D [other] [source];
185 if ((len1 <= 0) || (len2 <= 0))
187 if ((minLoop == 0) || (len1 + len2 < minLoop))
188 minLoop = len1 + len2;
190 recurrence [source] = minLoop;
198template <
class CubSetType,
class Vector>
200 const Vector &recurrence,
long &counter)
203 if (morseCubes.empty() || (morseCubes[0].dim() != 2))
207 typedef typename CubSetType::value_type cubeT;
208 typedef typename cubeT::CoordType coordT;
210 morseCubes[0].coord (coord);
211 coordT xMin(coord[0]), xMax(coord[0]+1), yMin(coord[1]), yMax(coord[1]+1);
212 for (int_t n = 1; n < morseCubes.size(); ++ n)
214 morseCubes[n].coord (coord);
217 if (xMax <= coord[0])
221 if (yMax <= coord[1])
226 typedef typename Vector::value_type recT;
227 std::vector<recT> row (yMax - yMin, -1);
228 std::vector<std::vector<recT> > R (xMax - xMin, row);
229 for (int_t n = 0; n < morseCubes.size(); ++ n)
231 morseCubes[n].coord (coord);
232 (R[coord[0]-xMin])[coord[1]-yMin] = recurrence [n];
238 for (int_t x = 0; x < xMax - xMin - 1; ++ x)
240 for (int_t y = 0; y < yMax - yMin - 1; ++ y)
244 if (((R[x+1])[y] > 0) && ((R[x])[y+1] > 0) &&
247 double v = (R[x])[y] + (R[x+1])[y+1] -
248 (R[x+1])[y] - (R[x])[y+1];
249 vvar += (v > 0) ? v : -v;
259template <
class CubSetType,
class GraphType,
class CubMapType>
261 const CubSetType &allCubes,
const GraphType &g,
262 const CubMapType &theCubMap,
const std::string &baseSetFileName)
264 using namespace chomp::homology;
265 using chomp::homology::timeused;
268 timeused workingTime;
276 int_t graphPeriod = computePeriod (gm);
277 sbug <<
"Graph period of this Morse set: " << graphPeriod <<
".\n";
280 std::vector<int_t> recurrence (morseCubes.size (), 0);
284 int_t recMin (0), recMax (0);
285 size_t countZero (0);
286 for (std::vector<int_t>::const_iterator it = recurrence.begin();
287 it != recurrence.end(); ++ it)
291 if ((*it > 0) && ((recMin == 0) || (*it < recMin)))
296 sbug <<
"Recurrence between " << recMin <<
" and " << recMax <<
297 " found.\n" << countZero <<
298 " non-recurrent cubes were encountered.\n";
303 sbug <<
"Vitali variation of the recurrence computed on " << counter <<
304 " quadruples: " << vvar <<
".\n";
307 std::string recFileName (baseSetFileName +
".rec");
308 sbug <<
"Saving '" << recFileName <<
"'...\n";
309 std::ofstream f (recFileName. c_str ());
310 for (
size_t i = 0; i < recurrence.size (); ++ i)
312 f << morseCubes [i] <<
" " << recurrence [i] <<
"\n";
317 sbug <<
"Recurrence processing completed in " << workingTime <<
".\n";
324template <
class CubSetType,
class MorseDecType,
class GraphType,
327 const CubSetType &allCubes,
const GraphType &g,
328 const CubMapType &theCubMap,
const CubMapType &,
329 const std::string &cubesFilePrefix,
330 const std::string &procFilePrefix)
332 using namespace chomp::homology;
334 if (procFilePrefix.empty() && cubesFilePrefix.empty())
336 sbug <<
"WARNING: Skipping recurrence analysis, "
337 "because its results would not be saved.\n";
341 std::string prefix = (procFilePrefix.size() ?
342 procFilePrefix : cubesFilePrefix) +
"r";
345 sbug <<
"\n=================================\n";
346 sbug <<
"====== RECURRENCE ANALYSIS ======\n";
347 sbug <<
"=================================\n";
348 sbug <<
"Analyzing the Morse sets and saving results to '" <<
350 sbug <<
"Note: cubesFilePrefix = '" << cubesFilePrefix <<
351 "', procFilePrefix = '" << procFilePrefix <<
"'.\n";
354 int nSets = morseDec. count ();
355 for (
int n = 0; n < nSets; ++ n)
358 sbug <<
"\nMorse set no. " << n <<
" (" <<
359 morseDec [n]. size () <<
" cubes).\n";
362 std::ostringstream s;
364 const std::string baseSetFileName = s. str ();
368 theCubMap, baseSetFileName);
370 sbug <<
"============== END ==============\n\n";
Choice of configuration settings.
Conley index computation routines.
void processMorseDec(const MorseDecType &morseDec, const CubSetType &allCubes, const GraphType &g, const CubMapType &theCubMap, const CubMapType &, const std::string &cubesFilePrefix, const std::string &procFilePrefix)
Post-processes a Morse decomposition by computing a decomposition of each Morse set into cycle sets a...
double computeVitaliVariation(const CubSetType &morseCubes, const Vector &recurrence, long &counter)
Computes Vitali variation of the values on the cubical set.
void processMorseSet(const CubSetType &morseCubes, const CubSetType &allCubes, const GraphType &g, const CubMapType &theCubMap, const std::string &baseSetFileName)
Processes a single Morse set by applying the cycle decomposition method.
void graph2dot(const GraphType &g, std::ostream &out)
Writes a directed graph in the "dot" format.
void computeRecurrence(ArrayType &recurrence, const GraphType &g)
Computes minimum recurrence of vertices in the graph.
Customizable settings that are supposed to be modified and/or chosen by the user of the software.
Customizable data types for the Conley-Morse graphs computation program.
Data types for the dynamical systems data structures.
Utilites and helper functions.
void showProgress(int n, char c)
Shows a progress indicator to the screen as an integer number followed by an additional character (e....
void computeRestrictedGraph(GraphType &restr, const GraphType &g, const SetType &full, const SetType &subset)
Computes the graph corresponding to the restriction of the combinatorial map to the provided subset.