00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef _CMGRAPHS_WORKER_H_
00034 #define _CMGRAPHS_WORKER_H_
00035
00036
00037
00038 #include <string>
00039 #include <sstream>
00040 #include <cstdio>
00041
00042
00043 #include "chomp/system/config.h"
00044 #include "chomp/system/textfile.h"
00045 #include "chomp/system/timeused.h"
00046 #include "chomp/cubes/cube.h"
00047 #include "chomp/multiwork/mw.h"
00048 #include "chomp/struct/digraph.h"
00049
00050
00051 #include "config.h"
00052 #include "typedefs.h"
00053 #include "utils.h"
00054 #include "compmdec.h"
00055 #include "plotmdec.h"
00056 #include "eigenval.h"
00057 #include "dataconv.h"
00058 #include "matchdec.h"
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 class Worker: public chomp::multiwork::mwWorker
00069 {
00070 public:
00071
00072 Worker (bool _local = false);
00073
00074 private:
00075
00076 int Initialize (chomp::multiwork::mwData &data);
00077
00078
00079 int Process (chomp::multiwork::mwData &data);
00080
00081
00082 Worker (const Worker &) {return;}
00083
00084
00085 Worker &operator = (const Worker &) {return *this;}
00086
00087 private:
00088
00089
00090
00091
00092 bool local;
00093
00094 };
00095
00096
00097
00098 inline Worker::Worker (bool _local): local (_local)
00099 {
00100 return;
00101 }
00102
00103
00104
00105 inline int Worker::Initialize (chomp::multiwork::mwData &data)
00106 {
00107
00108 return chomp::multiwork::mwOk;
00109 }
00110
00111 inline int Worker::Process (chomp::multiwork::mwData &data)
00112 {
00113 using namespace chomp::homology;
00114 using namespace chomp::multiwork;
00115
00116
00117 timeused processingTime;
00118
00119
00120 theCubMapType::maxImgDiam = 0;
00121 theCubMapType::maxImgVol = 0;
00122
00123
00124 int dataNumber = 0;
00125 data >> dataNumber;
00126
00127
00128 int dim = 0;
00129 data >> dim;
00130 if (dim != paramDim)
00131 {
00132 sout << "! Wrong parameter space dimension (" << dim <<
00133 "). Rejecting the data.\n";
00134 data. Reset ();
00135 return mwReject;
00136 }
00137
00138
00139 parCoord parLeft [paramDim];
00140 parCoord parRight [paramDim];
00141 for (int i = 0; i < paramDim; ++ i)
00142 {
00143 int n = 0;
00144 data >> n;
00145 parLeft [i] = static_cast<parCoord> (n);
00146 data >> n;
00147 parRight [i] = static_cast<parCoord> (n);
00148 }
00149
00150
00151 int skipIndices = 0;
00152 data >> skipIndices;
00153
00154
00155 std::string sharePrefix;
00156 data >> sharePrefix;
00157
00158
00159 std::string phaseSpacePrefix;
00160 data >> phaseSpacePrefix;
00161
00162
00163 bool fullPhaseSpace (false);
00164 data >> fullPhaseSpace;
00165
00166
00167 int ctrl = 0;
00168 data >> ctrl;
00169 if (ctrl != controlNumber)
00170 {
00171 data. Reset ();
00172 sout << "! Data incomplete. Rejecting it.\n";
00173 return mwReject;
00174 }
00175
00176
00177 int volume = 1;
00178 for (int i = 0; i < paramDim; ++ i)
00179 {
00180 int prevVolume = volume;
00181 volume *= parRight [i] - parLeft [i];
00182 if (volume < prevVolume)
00183 throw "Too many boxes for processing by a worker.";
00184 }
00185
00186
00187 if (volume > 1)
00188 {
00189 sout << "Processing " << dataNumber << ": " << volume <<
00190 " boxes in ";
00191 for (int i = 0; i < paramDim; ++ i)
00192 {
00193 sout << (i ? "x" : "") << "[" << parLeft [i] <<
00194 "," << parRight [i] << "]";
00195 }
00196 sout << "...\n";
00197 }
00198
00199 else
00200 {
00201 sout << "Processing " << dataNumber << ": the box " <<
00202 parCube (parLeft, paramDim) << "...\n";
00203 }
00204
00205
00206
00207 double offset [spaceDim];
00208 for (int i = 0; i < spaceDim; ++ i)
00209 offset [i] = spaceOffset [i];
00210 double width [spaceDim];
00211 for (int i = 0; i < spaceDim; ++ i)
00212 width [i] = spaceWidth [i];
00213
00214
00215
00216 spcCoord coordLeftMin [spaceDim];
00217 spcCoord coordRightMax [spaceDim];
00218 for (int i = 0; i < spaceDim; ++ i)
00219 {
00220 coordLeftMin [i] = 1 << finalDepth;
00221 coordRightMax [i] = 0;
00222 }
00223
00224
00225
00226 parCubes paramBoxes;
00227 std::vector<theMapType *> theMap (volume);
00228 std::vector<theCubMapType *> theCubMap0 (volume);
00229 std::vector<theCubMapType *> theCubMap1 (volume);
00230 std::vector<theMorseDecompositionType *> morseDec (volume);
00231 std::vector<bool> morseDecComputed (volume, false);
00232 std::vector<double> timeUsed (volume, 0);
00233 std::vector<std::vector<int> > wrongIndices (volume);
00234 std::vector<std::vector<int> > skippedIndices (volume);
00235 std::vector<std::vector<int> > attractors (volume);
00236
00237
00238 int countRead = 0, countWritten = 0, countComputed = 0;
00239 parRect rect (parLeft, parRight, paramDim);
00240 const parCoord *curCoord;
00241 while ((curCoord = rect. get ()) != 0)
00242 {
00243
00244 chomp::homology::timeused stopwatch;
00245
00246
00247 bool intBoundaryPoint = internalBoundaryPoint
00248 (curCoord, parLeft, parRight, paramSubdiv, paramDim);
00249
00250
00251 intBoundaryPoint = true;
00252
00253
00254 std::string pictureFileName = phaseSpacePrefix +
00255 coord2str (curCoord, paramDim) + ".png";
00256 std::string cacheFileName ((intBoundaryPoint &&
00257 !sharePrefix. empty ()) ? (sharePrefix +
00258 coord2str (curCoord, paramDim) + ".ind") : "");
00259
00260
00261
00262 if ((volume == 1) &&
00263 (cacheFileName. empty () ||
00264 fileExists (cacheFileName. c_str ())) &&
00265 (phaseSpacePrefix. empty () ||
00266 fileExists (pictureFileName. c_str ())))
00267 {
00268 if (cacheFileName. empty ())
00269 sout << "No Conley index cache to compute.";
00270 else if (fileExists (cacheFileName. c_str ()))
00271 sout << "Conley index cache already exists.";
00272 sout << " Skipping the box.\n";
00273 break;
00274 }
00275
00276
00277 int curNumber = paramBoxes. size ();
00278 parCube paramBox (curCoord, paramDim);
00279 paramBoxes. add (paramBox);
00280 if (paramBoxes. size () == curNumber)
00281 throw "A repeated box found in the iterations.";
00282
00283
00284 double leftMapParam [paramCount];
00285 double rightMapParam [paramCount];
00286 computeParam (curCoord, leftMapParam, rightMapParam);
00287 sbug << "Box " << paramBox << ":";
00288 for (int i = 0; i < paramCount; ++ i)
00289 {
00290 sbug << " [" << leftMapParam [i] << "," <<
00291 rightMapParam [i] << "]";
00292 }
00293 sbug << ".\n";
00294
00295
00296 theMap [curNumber] = new theMapType ();
00297 theMap [curNumber] -> setParam (leftMapParam, rightMapParam,
00298 paramCount);
00299
00300
00301
00302
00303 theCubMap0 [curNumber] = new theCubMapType (offset, width,
00304 1 << finalDepth, *(theMap [curNumber]));
00305 theCubMap0 [curNumber] -> cache = true;
00306 theCubMap1 [curNumber] = new theCubMapType (offset, width,
00307 1 << (finalDepth + 1), *(theMap [curNumber]));
00308 theCubMap1 [curNumber] -> cache = true;
00309
00310
00311 sbug << "Computing Morse decomposition for " <<
00312 paramBox << "...\n";
00313 bool computed = false;
00314 morseDec [curNumber] = computeMorseDecomposition
00315 (*(theMap [curNumber]),
00316 *(theCubMap0 [curNumber]), *(theCubMap1 [curNumber]),
00317 offset, width, skipIndices, cacheFileName,
00318 computed, wrongIndices [curNumber],
00319 skippedIndices [curNumber], attractors [curNumber],
00320 false, leftMapParam, rightMapParam, paramCount);
00321 morseDecComputed [curNumber] = computed;
00322
00323
00324 if (computed)
00325 {
00326 ++ countComputed;
00327 if (intBoundaryPoint)
00328 ++ countWritten;
00329 }
00330 else
00331 ++ countRead;
00332
00333
00334 coordMinMax (*(morseDec [curNumber]),
00335 coordLeftMin, coordRightMax);
00336
00337
00338 if ((spaceDim == 2) && !phaseSpacePrefix. empty () &&
00339 !fileExists (pictureFileName. c_str ()))
00340 {
00341 sbug << "Saving '" << pictureFileName << "'...\n";
00342 plotMorseDecompositionPNG (*(morseDec [curNumber]),
00343 pictureFileName. c_str (),
00344 fullPhaseSpace ? (1 << finalDepth) : 0);
00345 }
00346
00347
00348 timeUsed [curNumber] = stopwatch;
00349
00350
00351 sbug << timeUsed [curNumber] << " sec, " <<
00352 ((curNumber + 1) * 100 / volume) << "% done.\n";
00353 sbug << "--------------------------------\n";
00354 }
00355
00356
00357 if (volume > 1)
00358 {
00359 sout << countRead << " sets of Conley indices read, " <<
00360 countComputed << " computed (" <<
00361 countWritten << " written).\n";
00362 }
00363
00364
00365
00366 std::vector<std::vector<parCube> > matchClasses;
00367 if (volume > 1)
00368 {
00369 sbug << "Matching " << volume <<
00370 " Morse decompositions...\n";
00371 std::vector<std::vector<int> > noWrongIndices (volume);
00372 matchMorseDecompositions (paramBoxes, morseDec,
00373
00374 theCubMap1,
00375 ignoreIsolationForContinuation ? noWrongIndices :
00376 wrongIndices, parLeft, parRight, matchClasses);
00377
00378
00379 int nClasses = matchClasses. size ();
00380 if (nClasses == 1)
00381 sbug << "There is only one nontrivial class";
00382 else
00383 sbug << "There are " << nClasses << " nontrivial classes";
00384 sbug << " of equivalent Morse decompositions:\n";
00385 if (nClasses == 0)
00386 sbug << 0;
00387 for (int n = 0; n < nClasses; ++ n)
00388 sbug << (n ? "+" : "") << matchClasses [n]. size ();
00389 sbug << " elements.\n";
00390 }
00391
00392
00393 sbug << "Max img diam = " << theCubMapType::maxImgDiam <<
00394 ", max img vol = " << theCubMapType::maxImgVol << ".\n";
00395
00396
00397 data. Reset ();
00398 data << dataNumber;
00399
00400
00401 data << static_cast<double> (processingTime);
00402 processingTime = 0;
00403
00404
00405 data << wrongIndices;
00406
00407
00408 data << skippedIndices;
00409
00410
00411 data << attractors;
00412
00413
00414 data << spcCube (coordLeftMin, spaceDim);
00415 data << spcCube (coordRightMax, spaceDim);
00416
00417
00418 int countBoxes = paramBoxes. size ();
00419 data << countBoxes;
00420
00421
00422 for (int curNumber = 0; curNumber < countBoxes; ++ curNumber)
00423 {
00424
00425 data << paramBoxes [curNumber];
00426
00427
00428 data << timeUsed [curNumber];
00429
00430
00431
00432 data << morseDecComputed [curNumber];
00433
00434
00435 diGraph<> connGraph;
00436 morseDec [curNumber] -> makegraph (connGraph);
00437 diGraph<> morseGraph;
00438 transitiveReduction (connGraph, morseGraph);
00439 data << morseGraph;
00440
00441
00442 int nSets = morseDec [curNumber] -> count ();
00443 for (int n = 0; n < nSets; ++ n)
00444 data << (*(morseDec [curNumber])) [n]. size ();
00445
00446
00447
00448 if (nSets != morseGraph. countVertices ())
00449 throw "Wrong number of Morse sets encountered.";
00450 for (int n = 0; n < nSets; ++ n)
00451 {
00452 const theConleyIndexType &index =
00453 morseDec [curNumber] -> index (n);
00454 data << index;
00455 IndexEigenValues eigenValues (index);
00456 data << eigenValues;
00457 }
00458 }
00459
00460
00461 data << matchClasses;
00462
00463
00464 data << theCubMapType::maxImgDiam;
00465 data << theCubMapType::maxImgVol;
00466
00467
00468 for (int i = 0; i < countBoxes; ++ i)
00469 {
00470 delete morseDec [i];
00471 delete theCubMap1 [i];
00472 delete theCubMap0 [i];
00473 delete theMap [i];
00474 }
00475
00476
00477
00478 if (!local)
00479 {
00480 sbug << "(Resetting the pointset data.)\n";
00481 parCube::PointBase::reset ();
00482 spcCube::PointBase::reset ();
00483 Cube::PointBase::reset ();
00484 }
00485
00486
00487 sout << "================================\n";
00488
00489
00490 return mwOk;
00491 }
00492
00493
00494 #endif // _CMGRAPHS_WORKER_H_
00495