33#ifndef _CMGRAPHS_COORD_H_
34#define _CMGRAPHS_COORD_H_
46#include "chomp/system/config.h"
47#include "chomp/system/textfile.h"
48#include "chomp/system/timeused.h"
49#include "chomp/cubes/cube.h"
50#include "chomp/multiwork/mw.h"
78 const char *_mapOptFileName,
const char *_mapOptPrefix,
79 const char *_graphsFileName,
const char *_graphsPrefix,
80 const char *_finalPrefix,
const char *_sharePrefix,
81 const char *_phaseSpacePrefix,
const char *_cubesPrefix,
82 const char *_morseDecPrefix,
83 const char *_procPrefix,
bool _fullPhaseSpace,
84 int _skipIndices,
int _nPatches);
91 int Prepare (chomp::multiwork::mwData &data);
94 int Accept (chomp::multiwork::mwData &data);
97 int Reject (chomp::multiwork::mwData &data);
169 chomp::homology::multitable<datapack>
sent;
269 const char *_mapOptFileName,
const char *_mapOptPrefix,
270 const char *_graphsFileName,
const char *_graphsPrefix,
271 const char *_finalPrefix,
const char *_sharePrefix,
272 const char *_phaseSpacePrefix,
const char *_cubesPrefix,
273 const char *_morseDecPrefix,
274 const char *_procPrefix,
bool _fullPhaseSpace,
275 int _skipIndices,
int _nPatches):
276 usingGraphsFile (false),
277 currentCache (0), maxCache (0), waitingCache (0),
278 current (0), maxCurrent (0), sentlen (0),
279 skipIndices (_skipIndices), fullPhaseSpace (_fullPhaseSpace),
280 rectIterator (0), allSent (false),
282 morseDecComputed (0), morseDecReused (0),
283 maxImgDiam (0), maxImgVol (0)
285 using chomp::homology::sout;
288 if (_mapOptPrefix && *_mapOptPrefix)
292 if (_sharePrefix && *_sharePrefix)
296 if (_phaseSpacePrefix && *_phaseSpacePrefix)
300 if (_cubesPrefix && *_cubesPrefix)
304 if (_morseDecPrefix && *_morseDecPrefix)
308 if (_procPrefix && *_procPrefix)
312 if (!_interFileName || !*_interFileName)
314 sout <<
"WARNING: No file name for intermediate results "
315 "has been provided.\n"
316 " It will not be possible to restart "
317 "the computations if they are interrupted.\n";
321 if ((!_graphsFileName || !*_graphsFileName) &&
322 (!_graphsPrefix || !*_graphsPrefix))
324 sout <<
"WARNING: No file name for saving the Conley-Morse "
325 "graphs has been provided.\n"
326 " The computed Conley-Morse graphs "
327 "Will be discarded.\n";
332 if (_finalPrefix && *_finalPrefix)
335 throw "No file name prefix provided for the results.";
338 if (_interFileName && *_interFileName)
342 if (_mapOptFileName && *_mapOptFileName)
345 std::ifstream in (_mapOptFileName);
349 sout <<
"Reading map optimization data... ";
370 if (_graphsFileName && *_graphsFileName)
373 std::ios::out | std::ios::app);
374 graphsFile <<
"; --- Conley-Morse graphs ---\n";
380 if (_graphsPrefix && *_graphsPrefix)
384 if (_interFileName && *_interFileName)
387 std::ios::out | std::ios::app);
389 chomp::homology::currenttime () <<
";\n";
397 sout <<
"Serious problem: finalDepth (" <<
400 sout <<
"However, the space coordinates are " <<
401 (8 *
sizeof(
spcCoord)) <<
"-bit integers.\n";
402 sout <<
"Please, modify 'typespace.h': the 'spcCoord' type "
403 "must have at least " <<
405 throw "Not enough bits available in spcCoord.";
416#ifndef CONFIG_ONLYPREPROCESSING
422#ifndef CONFIG_NOPREPROCESSING
435 using chomp::homology::sout;
436 using chomp::homology::ignoreline;
437 using chomp::homology::ignorecomments;
439 std::ifstream in (filename);
442 sout <<
"Note: Could not open the results file. "
443 "Any previous results will be ignored.\n";
447 int countClasses = 0;
453 if (in. peek () ==
'E')
460 if (std::isdigit (in. peek ()))
471 firstCube. coord (firstCoord);
475 while (in. peek () ==
'(')
480 otherCube. coord (otherCoord);
490 else if (in. peek () ==
'*')
497 if (std::isdigit (in. peek ()))
522 chomp::homology::sout << countBoxes <<
" previously computed "
523 "parameter ranges read from a file.\n";
525 chomp::homology::sout << countClasses <<
" previously computed "
526 "equivalence classes processed.\n";
539 std::ofstream mapOptFile;
541 std::ios::out | std::ios::app);
546 interFile <<
"; Finished on " << chomp::homology::currenttime ();
554 using chomp::homology::sout;
555 using chomp::homology::sbug;
556 using chomp::homology::timeused;
559 timeused workingTime;
564 std::ifstream in (
"_badboxes.cub");
566 if (!badBoxes. empty ())
567 sbug << badBoxes. size () <<
" bad boxes will be skipped.\n";
572 sout <<
"=== PHASE 1: Computation of Conley indices ===\n";
580 if (!badBoxes. empty ())
583 if (badBoxes. check (p))
586 sbug <<
"Skipping bad parameter box " << p <<
".\n";
620#ifdef CONFIG_ONLYPREPROCESSING
637 sout <<
"=== PHASE 2: Continuation of Morse "
638 "decompositions ===\n";
642#ifdef CONFIG_SEPARATEPHASES
646 sbug <<
"[Note: waiting for " <<
waitingCache <<
" indices to be cached.]\n";
647 return chomp::multiwork::mwNoData;
656#ifndef CONFIG_ONLYPREPROCESSING
657 while (!cacheToSend && !
allSent)
685 bool parityOk =
true;
710#ifndef CONFIG_ONLYPREPROCESSING
716 sout <<
"================================\n";
721 sout <<
"\n*** WARNING: Some Conley indices at " <<
723 " parameters were not computed\n"
724 "*** because of lack of isolation.\n\n";
729 bad <<
"; Parameter boxes for which "
730 "at least one Conley index "
731 "could not be computed:\n";
740 int percent =
static_cast<int>
743 volume <<
" Morse decomps computed (" <<
749 sout <<
"The computed Morse sets are in " <<
750 coordMinMax <<
".\n";
751 sout <<
"Real coordinates: ";
756 ", max img vol = " <<
maxImgVol <<
".\n";
759 sout <<
"Saving the continuation classes...\n";
767 if (
static_cast<double> (workingTime) > 1.0)
769 sbug <<
"It took " << workingTime <<
" to "
770 "see that there is no data to send.\n";
773 return chomp::multiwork::mwNoData;
776#ifdef CONFIG_ONLYPREPROCESSING
779 return chomp::multiwork::mwNoData;
802 int right =
subCoords [i] [coord [i] + 1];
805 leftCoords [i] = left;
806 rightCoords [i] = right;
815 parLeft [i] =
static_cast<parCoord> (leftCoords [i]);
816 parRight [i] =
static_cast<parCoord> (rightCoords [i]);
818 std::vector<std::vector<std::string> > mapOptLines;
822 while ((curCoord = rect. get ()) != 0)
830 std::vector<std::string> data;
831 mapOptLines. push_back (data);
844 data << leftCoords [i] << rightCoords [i];
860 interFile <<
"+ " << dataNumber <<
" " << dataBox <<
"\n" <<
866 sout <<
"Sending " << dataNumber <<
" " << dataBox;
871 sout << (i ?
" x [" :
": [") << leftCoords [i] <<
872 "," << rightCoords [i] <<
"]";
877 sout <<
", " << (100 * (countSent + 1) /
878 (maxToSend ? maxToSend : 1)) <<
"% sent.\n";
894 sout <<
"=== PHASE 2: Continuation of Morse "
895 "decompositions ===\n";
904 if (
static_cast<double> (workingTime) > 1.0)
906 sbug <<
"It took " << workingTime <<
907 " to prepare new data.\n";
909 return chomp::multiwork::mwOk;
914 using chomp::homology::sout;
915 using chomp::homology::sbug;
916 using chomp::homology::timeused;
919 timeused workingTime;
931 for (
int i = 0; i <
sentlen; ++ i)
933 if ((dataNumber >= 0) && (
sent [i]. num < 0))
935 else if ((dataNumber < 0) && (
sent [i]. num >= 0))
938 sout <<
"Receiving " << dataNumber <<
", " <<
939 (100 * (countPrepared - countSent + 1) /
940 (maxPrepared ? maxPrepared : 1)) <<
"% completed.\n";
948 while ((pos <
sentlen) && (
sent [pos]. num != dataNumber))
951 throw "Wrong data chunk number returned by a worker.";
956 interFile <<
"* " << dataNumber <<
" " <<
957 sent [pos]. box <<
"\n";
961 double processingTime = 0;
962 data >> processingTime;
965 std::vector<std::vector<int> > localWrongIndices;
966 data >> localWrongIndices;
970 std::vector<std::vector<int> > skippedIndices;
971 data >> skippedIndices;
974 std::vector<std::vector<int> > attractors;
981 data >> cubeRightMax;
984 cubeLeftMin. coord (localLeftMin);
985 cubeRightMax. coord (localRightMax);
999 bool graphsOutput =
false;
1001 for (
int curNumber = 0; curNumber < countBoxes; ++ curNumber)
1006 paramBoxes. add (paramBox);
1007 if (paramBoxes. size () <= curNumber)
1008 throw "Repeated box found in the results.";
1011 double timeUsed = 0;
1015 bool wasComputed =
false;
1016 data >> wasComputed;
1023 chomp::homology::diGraph<> morseGraph;
1027 int nSets = morseGraph. countVertices ();
1028 std::vector<int_t> sizes (nSets);
1029 for (
int n = 0; n < nSets; ++ n)
1033 if (!localWrongIndices [curNumber]. empty ())
1036 localWrongIndices [curNumber];
1041 std::vector<theConleyIndexType> indices (nSets);
1042 std::vector<IndexEigenValues> eigenValues (nSets);
1043 for (
int n = 0; n < nSets; ++ n)
1046 data >> indices [n];
1049 data >> eigenValues [n];
1057 std::ostringstream dotGraphStream;
1059 indices, eigenValues,
1060 localWrongIndices [curNumber],
1061 skippedIndices [curNumber],
1062 attractors [curNumber]);
1063 std::string dotGraph (dotGraphStream. str ());
1070 graphsOutput =
true;
1082 std::ofstream graphFile
1083 (graphFileName. c_str ());
1084 graphFile << dotGraph <<
"\n";
1085 graphFile. close ();
1093 if (paramBoxes. empty ())
1095 sbug <<
"Results for no boxes accepted.\n";
1097 else if (paramBoxes. size () == 1)
1099 sbug <<
"Results for one box (processed in " <<
1100 processingTime <<
" sec) accepted.\n";
1104 sbug <<
"Results for " << paramBoxes. size () <<
" boxes "
1105 "(processed in " << processingTime <<
1106 " sec) accepted.\n";
1110 std::vector<std::vector<parCube> > matchClasses;
1111 data >> matchClasses;
1112 int nClasses = matchClasses. size ();
1113 for (
int n = 0; n < nClasses; ++ n)
1116 const std::vector<parCube> &theClass = matchClasses [n];
1117 int nBoxes = theClass. size ();
1124 theClass [0]. coord (coordZero);
1128 for (
int i = 1; i < nBoxes; ++ i)
1132 theClass [i]. coord (coordBox);
1139 int localMaxImgDiam = 0;
1140 int localMaxImgVol = 0;
1141 data >> localMaxImgDiam;
1142 data >> localMaxImgVol;
1149 std::vector<std::string> mapOptLines;
1150 data >> mapOptLines;
1151 if (!mapOptLines. empty ())
1154 for (
size_t n = 0; n < mapOptLines. size (); ++ n)
1156 if (!mapOptLines [n]. empty ())
1166 std::ofstream mapOptFile;
1168 std::ios::out | std::ios::app);
1183 if (dataNumber >= 0)
1189 if (
static_cast<double> (workingTime) > 1.0)
1191 sbug <<
"It took " << workingTime <<
1192 " to accept the data.\n";
1195 return chomp::multiwork::mwOk;
1200 using chomp::homology::sout;
1201 sout <<
"WARNING: Data rejected by a worker.\n";
1202 return chomp::multiwork::mwError;
const int controlNumber
The control number that is used to confirm the compatibility between the coordinator and workers.
A class whose objects store, update and show coordinate ranges.
The coordinator class which prepares chunks of parameter space to be processed by workers,...
int current
The current number of data pack to prepare by the coordinator.
int maxCache
The number of indices to pre-cache.
std::string morseDecPrefix
The file name prefix for cached compressed Morse decompositions.
std::string sharePrefix
The file name prefix for saving Morse sets by workers.
std::string finalPrefix
The file name prefix for saving the final result.
int sentlen
The number of data packs currently being processed by workers.
std::ofstream interFile
A file to append the results to.
MapOptimization mapOptimization
Map optimization data for all the parameters.
parCoord zeroIter[paramDim]
The minimal corner of the rectangle to iterate (zero coords).
parCubes previousBoxes
The boxes representing parameter ranges which have already been processed in the previous run of the ...
chomp::homology::multitable< datapack > sent
The data packs sent for processing to workers.
int waitingCache
The number of pre-cached indices waiting to complete.
int Accept(chomp::multiwork::mwData &data)
A function for accepting results by the coordinator.
int maxImgDiam
The maximal image diameter encountered by the workers.
int maxCurrent
The number of parameter regions which are to be processed in this run of the program.
int maxImgVol
The maximal image volume encountered by the workers.
int currentCache
The current number of data pack sent for pre-caching indices.
void readPreviousResults(const char *filename)
A procedure for reading the previously computed results.
std::string phaseSpacePrefix
The file name prefix for saving the phase space pictures of Morse decompositions.
chomp::homology::multitable< std::vector< int > > wrongIndices
The lists of Morse set numbers for which the wrong Conley indices appeared.
int morseDecComputed
The total number of computed Morse decopositions.
bool allSent
Have all the rectangular regions already been sent?
parCubes wrongIndexBoxes
The parameter boxes for which wrong Conley indices were computed by workers.
std::string cubesPrefix
The file name prefix for saving the actual cubes of Morse sets and possibly also additional sets (whi...
parCoord cacheCoord[paramDim]
The coordinates of a box to send for pre-caching indices.
MatchArray< parCoord, int > matchArray
The array of matching between parameter boxes.
parCoord parityBits[paramDim]
Parity bits of which rectangles are to be sent to workers.
std::string graphsPrefix
The file name prefix for saving the text Conley-Morse graphs.
std::ofstream graphsFile
A file to append the computed Conley-Morse graphs to.
std::string mapOptPrefix
A file name prefix for optimization data for each parameter.
std::string procPrefix
The file name prefix for saving post-processing information.
int Prepare(chomp::multiwork::mwData &data)
A function for preparing data by the coordinator.
std::string mapOptFileName
A file to append the optimization results to.
bool fullPhaseSpace
Should the full phase space be taken for plotting the pictures of Morse sets?
bool usingGraphsFile
Is the graphs file in use?
Coordinator(const char *_interFileName, const char *_mapOptFileName, const char *_mapOptPrefix, const char *_graphsFileName, const char *_graphsPrefix, const char *_finalPrefix, const char *_sharePrefix, const char *_phaseSpacePrefix, const char *_cubesPrefix, const char *_morseDecPrefix, const char *_procPrefix, bool _fullPhaseSpace, int _skipIndices, int _nPatches)
The complete constructor of a coordinator.
parCubes graphsWritten
The parameter boxes for which the Conley-Morse graph has already been written to the corresponding fi...
~Coordinator()
The destructor.
spcCoord coordRightMax[spaceDim]
The right coordinates of a box that contains all the Morse sets.
int morseDecReused
The total number of re-used Morse decompositions.
parCoord maxIter[paramDim]
The numbers of rectangular regions in each direction to iterate.
std::vector< parCoord > subCoords[paramDim]
The coordinates for lower (and upper) ends of rectangular regions in each direction.
int Reject(chomp::multiwork::mwData &data)
A function for taking rejected data by the coordinator.
spcCoord coordLeftMin[spaceDim]
The left coordinates of a box that contains all the Morse sets.
int skipIndices
The minimal size of a Morse set for which the indices should not be computed.
parRect * rectIterator
A rectangle which iterates the rectangular sets to send.
A class whose objects are responsible for adjusting the integration parameters such as step size and ...
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.
Data conversion for sending/receiving.
Data conversion for sending/receiving: std::vectors and hashed sets of any objects.
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.
Map optimization data saving, retrieving, and sending.
Array for matching Morse decompositions.
const int refineDepth
The number of refinements that should be done if a Morse set with the trivial index is encountered or...
const int paramDim
The dimension of the parameter space to iterate.
const int spaceDim
The dimension of the phase space.
const int paramCount
The number of all the parameters, both varying and fixed.
const int finalDepth
The final depth of subdivisions in the phase space.
const short int paramSubdiv[paramDim]
The numbers of subintervals in each direction of the parameter space.
This is an auxiliary class whose objects store the information on the data chunks sent to workers.
int num
The number of the data pack.
parCube box
The cube (with respect to the iterator) sent to a worker.
datapack(int _num, const parCube &_box)
A nice constructor which initializes all the data.
datapack()
The default constructor of an uninitialized data pack.
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.
short int parCoord
The type of coordinates of cubes in the set of parameters.
chomp::homology::tRectangle< parCoord > parRect
The type of a rectangle used to iterate sets of cubes of parameters.
chomp::homology::hashedset< parCube > parCubes
The type of a set of cubes in the set of parameters.
int spcCoord
The type of coordinates of cubes in the phase space.
chomp::homology::tCubeBase< spcCoord > spcCube
The type of a cube in the phase space.
Utilites and helper functions.
OutStream & showRealCoords(OutStream &out, const CoordMinMax &range)
Shows the real coordinates of the coordinate range.
bool fileExists(const char *filename)
Returns 'true' iff the given file exists and it is allowed to read it.
parRect * subRectangles(parCoord *zeroIter, parCoord *maxIter, std::vector< parCoord > *subCoords, int minCount)
Determines heuristically an optimal subdivision of a large parameter region into the given minimal nu...
std::string coord2str(const intType1 *coords, const intType2 *maxCoords, int dim)
Generates an underscore-separated list of non-negative coordinates padded with zeros to the same widt...
void computeParam(const intType *curCoord, double *leftMapParam, double *rightMapParam)
Computes the real coordinates of the parameter cube which corresponds to the given box.