The Conley-Morse Graphs Software
cmsingle.cpp
Go to the documentation of this file.
1/////////////////////////////////////////////////////////////////////////////
2///
3/// @file cmsingle.cpp
4///
5/// Computing a single Conley-Morse graph.
6/// This program constitutes an interface to computing a Conley-Morse graph
7/// for a single parameter box the same way it would be computed by the
8/// program "cmgraphs". Its purpose is to extract specific data
9/// for a single parameter box after having located it with the aid
10/// of the results obtained by the program "cmgraphs", in particular,
11/// by having analyzed the continuation diagram.
12/// Please, use the program "cmgraphs" to run computations for a range
13/// of parameters and to do continuation matching
14/// between the Morse decompositions.
15///
16/// @author Pawel Pilarczyk
17///
18/////////////////////////////////////////////////////////////////////////////
19
20// Copyright (C) 1997-2014 by Pawel Pilarczyk.
21//
22// This file is part of my research software package. This is free software:
23// you can redistribute it and/or modify it under the terms of the GNU
24// General Public License as published by the Free Software Foundation,
25// either version 3 of the License, or (at your option) any later version.
26//
27// This software is distributed in the hope that it will be useful,
28// but WITHOUT ANY WARRANTY; without even the implied warranty of
29// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30// GNU General Public License for more details.
31//
32// You should have received a copy of the GNU General Public License
33// along with this software; see the file "license.txt". If not,
34// please, see <https://www.gnu.org/licenses/>.
35
36// Started on February 26, 2008. Last revision: July 15, 2014.
37
38
39// include some standard C++ header files
40#include <exception>
41#include <sstream>
42#include <fstream>
43#include <algorithm>
44#include <new>
45
46// include selected header files from the CHomP library
47#include "chomp/system/config.h"
48#include "chomp/system/textfile.h"
49#include "chomp/system/timeused.h"
50#include "chomp/system/arg.h"
51
52// include local header files
53#include "config.h"
54#include "confinfo.h"
55#include "typedefs.h"
56#include "typedyns.h"
57#include "utils.h"
58#include "compmdec.h"
59#include "plotmdec.h"
60#include "eigenval.h"
61#include "dotgraph.h"
62#include "mapopt.h"
63
64
65// --------------------------------------------------
66// -------------------- OVERTURE --------------------
67// --------------------------------------------------
68
69/// The title of the program which is displayed every time
70/// the program is launcued.
71const char *title = "\
72This is a program which computes a single Conley-Morse graph.\n\
73Ver. 0.06, August 22, 2014. Copyright (C) 2005-2014 by Pawel Pilarczyk.\n\
74This is free software. No warranty. Consult 'license.txt' for details.";
75
76/// The help information about the program which is displayed
77/// if the program is launched without command-line arguments
78/// or with incorrect arguments.
79const char *helpinfo = "\
80This is the front-end program for the computation of a Conley-Morse graph\n\
81for a single parameter box. It is a supplementary program to 'cmgraphs',\n\
82and is capable of saving the results of all its computations to files.\n\
83The parameter box is identified by the integer coordinates of its minimal\n\
84vertex and corresponds to a box in the subdivision of the parameter area,\n\
85for example, if the entire parameter range [-1,1]x[-1,1] is divided into\n\
8620x20 boxes then '-b 0,19' corresponds to [-1.0,-0.9]x[0.9,1.0].\n\
87Command line arguments (the argument '-b' is mandatory):\n\
88-b x1,x2,...,xN - the integer coordinates of a parameter box to process,\n\
89-g file.txt - file name to save the text code for the Conley-Morse graph,\n\
90-s file.ind - file name to save/load cached Conley index information,\n\
91-p file.png - file name to save a PNG picture of the Morse decomposition,\n\
92-q prefix - prefix for file names to save Morse sets to as lists of cubes,\n\
93-o prefix - file name prefix for post-processing Morse sets information,\n\
94-t filename - file name with optimization information (read & append),\n\
95-u prefix - file name prefix for ODE integration optimization information,\n\
96-z file.bz2 - name of a temporary file with Morse decomposition cache,\n\
97--conn - compute connecting orbits between Morse sets (memory-consuming),\n\
98--full - use the full range of the phase space to plot Morse sets,\n\
99--log filename - file name to save all the text output of the program to,\n\
100--quiet - suppress any output written to the terminal,\n\
101--debug - display additional information useful for debugging,\n\
102--help - make the program show this brief help information and exit.\n\
103For more information ask the author at http://www.pawelpilarczyk.com/.";
104
105
106// --------------------------------------------------
107// --------------- Single Computation ---------------
108// --------------------------------------------------
109
110int runSingleComp (const char *boxCoordinates,
111 const char *mapOptFileName, const char *mapOptFileLocal,
112 const char *graphName, const char *shareName,
113 const char *phaseSpaceName, bool fullPhaseSpace,
114 const char *cubesFilePrefix, const char *morseDecName,
115 const char *procFilePrefix,
116 bool connOrbits, int skipIndices)
117{
118 using chomp::homology::sout;
119 using chomp::homology::sbug;
120
121 // show the global configuration information
122 std::ostringstream info;
123 showConfigInfo (info, 0, 0);
124 sout << "\n" << info. str () << "\n";
125
126 // reset the variables for computing max image diameter and volume
129
130 // decode the parameter box
131 parCube paramBox;
132 std::string boxCoordStr ("(" + std::string (boxCoordinates) + ")");
133 std::istringstream boxCoordStream (boxCoordStr);
134 boxCoordStream >> paramBox;
135 sout << "Computing Morse decomposition for " << paramBox << ".\n";
136
137 // prepare the offset and the width of the phase space region
138 double offset [spaceDim];
139 for (int i = 0; i < spaceDim; ++ i)
140 offset [i] = spaceOffset [i];
141 double width [spaceDim];
142 for (int i = 0; i < spaceDim; ++ i)
143 width [i] = spaceWidth [i];
144
145 // set up an array of coordinates of the box
146 parCoord curCoord [paramDim];
147 paramBox. coord (curCoord);
148
149 // prepare the actual parameters for the map
150 double leftMapParam [paramCount];
151 double rightMapParam [paramCount];
152 computeParam (curCoord, leftMapParam, rightMapParam);
153 sout << "Parameter values:";
154 for (int i = 0; i < paramCount; ++ i)
155 {
156 sout << " [" << leftMapParam [i] << "," <<
157 rightMapParam [i] << "]";
158 }
159 sout << "\n";
160
161 // create the map object and set its parameters
162 theMapType theMap;
163 theMap. setParam (leftMapParam, rightMapParam, paramCount);
164
165 // read map optimization data and apply it to the map
166 MapOptimization mapOptimization;
167 size_t prevSize (mapOptimization. size ());
168 if (mapOptFileName && *mapOptFileName)
169 {
170 std::ifstream in (mapOptFileName);
171 if (in)
172 {
173 sout << "Reading map optimization data... ";
174 mapOptimization. loadData (in);
175 sout << (mapOptimization. size () - prevSize) <<
176 " items added.\n";
177
178 sout << "Optimizing the map... ";
179 std::vector<std::string> data;
180 mapOptimization. prepareData (data,
181 leftMapParam, rightMapParam, paramCount);
182 sout << data. size () << " hints... ";
183 for (std::vector<std::string>::const_iterator it =
184 data. begin (); it != data. end (); ++ it)
185 {
186 theMap. useOptInfo (*it);
187 }
188 sout << "Done.\n";
189 }
190 }
191
192 // prepare an object of the cubical map
193 // at the highest subdivision level to be used
194 // in the definition of the Morse decomposition
195 theCubMapType theCubMap0 (offset, width, 1 << finalDepth,
196 finalDepth, theMap);
197 theCubMap0. cache = false;
198 theCubMapType theCubMap1 (offset, width, 1 << (finalDepth + 1),
199 finalDepth + 1, theMap);
200 theCubMap1. cache = false;
201
202 // prepare a boolean value to store the information on whether
203 // the Conley indices in the Morse decomposition were computed
204 // or read from cache
205 bool morseDecComputed (false);
206
207 // prepare an array in which wrong Conley indices will be recorded
208 std::vector<int> wrongIndices;
209
210 // prepare an array in which skipped Conley indices will be recorded
211 std::vector<int> skippedIndices;
212
213 // prepare an array in which attractors will be recorded
214 std::vector<int> attractors;
215
216 // compute the Morse decomposition
218 (theMap, theCubMap0, theCubMap1, offset, width, skipIndices,
219 shareName ? shareName : "",
220 phaseSpaceName ? phaseSpaceName : "",
221 cubesFilePrefix ? cubesFilePrefix : "",
222 morseDecName ? morseDecName : "",
223 graphName ? graphName : "",
224 procFilePrefix ? procFilePrefix : "",
225 mapOptFileLocal ? mapOptFileLocal : "",
226 morseDecComputed, wrongIndices,
227 skippedIndices, attractors, connOrbits,
228 leftMapParam, rightMapParam, paramCount);
229
230 // compute the min and max coordinates of Morse sets
231 if (!sbug. show)
232 {
233 CoordMinMax coordMinMax;
234 int_t nMorseSets = morseDec -> count ();
235 for (int_t nSet = 0; nSet < nMorseSets; ++ nSet)
236 coordMinMax ((*morseDec) [nSet]);
237 if (coordMinMax. defined ())
238 {
239 sout << "The computed Morse sets are in " <<
240 coordMinMax << ".\n";
241 sout << "Real coordinates: ";
242 showRealCoords (sout, coordMinMax) << ".\n";
243 }
244 }
245
246 // show computed max image diameter and volume
247 sout << "Max img diam = " << theCubMapType::maxImgDiam <<
248 ", max img vol = " << theCubMapType::maxImgVol << ".\n";
249
250 // save a picture of the computed Morse decomposition
251 if (
252#if (!defined (PLOT_X_COORD) && !defined (PLOT_Y_COORD))
253 (spaceDim == 2) &&
254#endif
255 phaseSpaceName && *phaseSpaceName)
256 {
257 sout << "Saving a picture of Morse sets to '" <<
258 phaseSpaceName << "'...\n";
259#ifdef PLOT_X_COORD
260 const int xCoord (PLOT_X_COORD);
261#else
262 const int xCoord (0);
263#endif
264#ifdef PLOT_Y_COORD
265 const int yCoord (PLOT_Y_COORD);
266#else
267 const int yCoord (1);
268#endif
269 plotMorseDecompositionPNG (*morseDec, phaseSpaceName,
270 xCoord, yCoord,
271 fullPhaseSpace ? (1 << finalDepth) : 0);
272 }
273
274 // save the computed Conley-Morse graph for the "dot" program
275 // NOTE: This procedure is contained in "computeMorseDecomposition".
276 if (false && (graphName && *graphName))
277 {
278 // create the Morse graph from the Morse decomposition
279 chomp::homology::diGraph<> connGraph;
280 morseDec -> makegraph (connGraph);
281 chomp::homology::diGraph<> morseGraph;
282 transitiveReduction (connGraph, morseGraph);
283
284 // gather the sizes of each Morse set into a vector
285 int nSets = morseGraph. countVertices ();
286 std::vector<int_t> sizes (nSets);
287 for (int n = 0; n < nSets; ++ n)
288 sizes [n] = (*morseDec) [n]. size ();
289
290 // gather the Conley indices and the eigenvalues
291 std::vector<theConleyIndexType> indices (nSets);
292 std::vector<IndexEigenValues> eigenValues (nSets);
293 for (int n = 0; n < nSets; ++ n)
294 {
295 indices [n] = morseDec -> index (n);
296 eigenValues [n] = IndexEigenValues (indices [n]);
297 }
298
299 sout << "Saving the Conley-Morse graph to '" <<
300 graphName << "'...\n";
301 std::ofstream graphFile (graphName);
302 writeDotGraph (graphFile, morseGraph, sizes,
303 indices, eigenValues,
304 wrongIndices, skippedIndices, attractors);
305 graphFile << "\n";
306 graphFile. close ();
307 }
308
309 // save the computed Morse sets to separate text files
310 // NOTE: This procedure is contained in "computeMorseDecomposition".
311// if (cubesFilePrefix && *cubesFilePrefix)
312// {
313// sout << "Saving the Morse decomposition to '" <<
314// cubesFilePrefix << "*'...\n";
315// morseDec -> savetofiles (cubesFilePrefix);
316// }
317
318 // delete the Morse deocmposition
319 delete morseDec;
320
321 // save new map optimization data if any
322 if (mapOptFileName && *mapOptFileName)
323 {
324 std::string line = theMap. getOptInfo ();
325 if (!line. empty ())
326 {
327 mapOptimization. addData (line, true);
328 std::ofstream mapOptFile;
329 mapOptFile. open (mapOptFileName,
330 std::ios::out | std::ios::app);
331 mapOptimization. saveData (mapOptFile, true);
332 }
333 }
334
335 // release pointset data to make fewer valgrind complaints
336 sbug << "(Releasing the pointset data.)\n";
337 parCube::PointBase::reset ();
338 spcCube::PointBase::reset ();
339 chomp::homology::Cube::PointBase::reset ();
340
341 return 0;
342} /* runSingleComp */
343
344
345// --------------------------------------------------
346// ---------------------- MAIN ----------------------
347// --------------------------------------------------
348
349/// The main procedure of the program.
350/// Returns: 0 = Ok, -1 = Error, 1 = Help displayed, 2 = Wrong arguments.
351int main (int argc, char *argv [])
352{
353 using namespace chomp::homology;
354
355 // prepare user-configurable data
356 int skipIndices = 0;
357 char *boxCoordinates = 0;
358 char *mapOptFileName = 0;
359 char *mapOptFileLocal = 0;
360 char *graphName = 0;
361 char *shareName = 0;
362 char *phaseSpaceName = 0;
363 char *cubesFilePrefix = 0;
364 char *morseDecName = 0;
365 char *procFilePrefix = 0;
366 bool fullPhaseSpace = false;
367 bool connOrbits = false;
368 const int maxComments = 16;
369 int nComments = 0;
370 char *comments [maxComments];
371
372 // interprete the command-line arguments
373 arguments a;
374 arg (a, "b", boxCoordinates);
375 arg (a, "t", mapOptFileName);
376 arg (a, "u", mapOptFileLocal);
377 arg (a, "g", graphName);
378 arg (a, "s", shareName);
379 arg (a, "p", phaseSpaceName);
380 arg (a, "z", morseDecName);
381 arg (a, "c", cubesFilePrefix);//deprecated
382 arg (a, "q", cubesFilePrefix);
383 arg (a, "o", procFilePrefix);
384 arg (a, "-comment", comments, nComments, maxComments);
385 arg (a, "-skip-indices", skipIndices, 1);
386 argswitch (a, "-full", fullPhaseSpace, true);
387 argswitch (a, "-conn", connOrbits, true);
388 arghelp (a);
389
390 argstreamprepare (a);
391 int argresult = a. analyze (argc, argv);
392 argstreamset ();
393
394 // if no box coordinates defined then show the help message
395 if (!boxCoordinates)
396 argresult = 1;
397
398 // show the program's main title
399 if (argresult >= 0)
400 sout << title << '\n';
401
402 // if something was incorrect, show an additional message and exit
403 if (argresult < 0)
404 {
405 sout << "Call with '--help' for help.\n";
406 return 2;
407 }
408
409 // if help requested, show help information
410 if (argresult > 0)
411 {
412 sout << helpinfo << '\n';
413 return 1;
414 }
415
416 // try running the main function and catch an error message if thrown
417 try
418 {
419 // set an appropriate program time message
420 program_time = "Aborted after:";
421 program_time = 1;
422
423 // run the computations for a single parameter box
424 runSingleComp (boxCoordinates,
425 mapOptFileName, mapOptFileLocal,
426 graphName, shareName,
427 phaseSpaceName, fullPhaseSpace, cubesFilePrefix,
428 morseDecName, procFilePrefix,
429 connOrbits, skipIndices);
430
431 // set an appropriate program time message
432 program_time = "Total time used:";
433
434 // finalize
435 return 0;
436 }
437 catch (const char *msg)
438 {
439 sout << "ERROR: " << msg << '\n';
440 return -1;
441 }
442 catch (const std::exception &e)
443 {
444 sout << "ERROR: " << e. what () << '\n';
445 return -1;
446 }
447 catch (...)
448 {
449 sout << "ABORT: An unknown error occurred.\n";
450 return -1;
451 }
452} /* main */
453
#define PLOT_Y_COORD
Definition: c_inf_t.h:82
#define PLOT_X_COORD
Definition: c_inf_t.h:78
A class whose objects store, update and show coordinate ranges.
Definition: utils.h:444
Eigenvalues of the Conley index map gathered by levels.
Definition: eigenval.h:63
A generic map computation routine that computes a rigorous cubical multivalued map based on a functio...
Definition: mapcomp.h:69
static int maxImgDiam
The maximal image diameter encountered so far.
Definition: mapcomp.h:117
static int maxImgVol
The maximal image volume encountered so far.
Definition: mapcomp.h:121
This class defines a map derived from a sample difference equation.
Definition: m_differ.h:47
A class whose objects are responsible for adjusting the integration parameters such as step size and ...
Definition: mapopt.h:59
The Morse decoposition class.
Definition: morsedec.h:65
int main(int argc, char *argv[])
The main procedure of the program.
Definition: cmsingle.cpp:351
const char * helpinfo
The help information about the program which is displayed if the program is launched without command-...
Definition: cmsingle.cpp:79
const char * title
The title of the program which is displayed every time the program is launcued.
Definition: cmsingle.cpp:71
int runSingleComp(const char *boxCoordinates, const char *mapOptFileName, const char *mapOptFileLocal, const char *graphName, const char *shareName, const char *phaseSpaceName, bool fullPhaseSpace, const char *cubesFilePrefix, const char *morseDecName, const char *procFilePrefix, bool connOrbits, int skipIndices)
Definition: cmsingle.cpp:110
Computation of Morse decompositions.
theMorseDecompositionType * computeMorseDecomposition(theMapType &theMap, const theCubMapType theCubMap0, const theCubMapType theCubMap1, const double *offset, const double *width, int_t skipIndices, const std::string &cacheFileName, const std::string &pictureFileName, const std::string &cubesFilePrefix, const std::string &morseDecFileName, const std::string &graphFileName, const std::string &procFilePrefix, const std::string &mapOptFileName, bool &morseDecComputed, std::vector< int > &wrongIndices, std::vector< int > &skippedIndices, std::vector< int > &attractors, bool connOrbits, const double *leftMapParam, const double *rightMapParam, int paramCount)
Computes the Morse decomposition using all the pre- and postprocessing.
Definition: compmdec.h:997
Choice of configuration settings.
Writing configuration settings to an output stream.
void showConfigInfo(std::ostream &f, const char *prefix, const parCoord *maxIter)
Writes the configuration information to the given output stream.
Definition: confinfo.h:53
Writing a graph in the "dot" format.
std::ostream & writeDotGraph(std::ostream &out, const chomp::homology::diGraph<> &g, const std::vector< int_t > &sizes, const std::vector< theConleyIndexType > &indices, const std::vector< IndexEigenValues > &eigenValues, const std::vector< int > &wrongIndices, const std::vector< int > &skippedIndices, const std::vector< int > &attractors)
Writes the given Conley-Morse graph to the output stream in the format for the 'dot' program.
Definition: dotgraph.h:61
Eigenvalues of the Conley index map.
Map optimization data saving, retrieving, and sending.
const SpaceOffsetType spaceOffset
An imitation of an array which returns the offset of the rectangular area in the phase space which co...
Definition: p_differ.h:108
const int paramDim
The dimension of the parameter space to iterate.
Definition: p_differ.h:67
const int spaceDim
The dimension of the phase space.
Definition: p_differ.h:48
const int paramCount
The number of all the parameters, both varying and fixed.
Definition: p_differ.h:82
const SpaceWidthType spaceWidth
An imitation of an array which returns the width of the rectangular area in the phase space which con...
Definition: p_differ.h:128
const int finalDepth
The final depth of subdivisions in the phase space.
Definition: p_differ.h:58
Plotting a Morse decomposition in a PNG picture.
void plotMorseDecompositionPNG(const MorseDecType &m, const char *filename, int xCoord, int yCoord, int size=0, bool colorBar=true)
Saves all the Morse sets in the provided Morse decomposition to a PNG file.
Definition: plotmdec.h:51
Customizable data types for the Conley-Morse graphs computation program.
Data types for the dynamical systems data structures.
chomp::homology::tCubeFix< paramDim, parCoord > parCube
The type of a cube in the set of parameters.
Definition: typeparam.h:58
short int parCoord
The type of coordinates of cubes in the set of parameters.
Definition: typeparam.h:53
Utilites and helper functions.
OutStream & showRealCoords(OutStream &out, const CoordMinMax &range)
Shows the real coordinates of the coordinate range.
Definition: utils.h:543
void computeParam(const intType *curCoord, double *leftMapParam, double *rightMapParam)
Computes the real coordinates of the parameter cube which corresponds to the given box.
Definition: utils.h:160