cmsingle.cpp

Go to the documentation of this file.
00001 /////////////////////////////////////////////////////////////////////////////
00002 ///
00003 /// @file cmsingle.cpp
00004 ///
00005 /// Computing a single Conley-Morse graph.
00006 /// This program constitutes an interface to computing a Conley-Morse graph
00007 /// for a single parameter box the same way it would be computed by the
00008 /// program "cmgraphs". Its purpose is to extract specific data
00009 /// for a single parameter box after having located it with the aid
00010 /// of the results obtained by the program "cmgraphs", in particular,
00011 /// by having analyzed the continuation diagram.
00012 /// Please, use the program "cmgraphs" to run computations for a range
00013 /// of parameters and to do continuation matching
00014 /// between the Morse decompositions.
00015 ///
00016 /// @author Pawel Pilarczyk
00017 ///
00018 /////////////////////////////////////////////////////////////////////////////
00019 
00020 // Copyright (C) 1997-2008 by Pawel Pilarczyk.
00021 //
00022 // This file is part of my research software package.  This is free software;
00023 // you can redistribute it and/or modify it under the terms of the GNU
00024 // General Public License as published by the Free Software Foundation;
00025 // either version 2 of the License, or (at your option) any later version.
00026 //
00027 // This software is distributed in the hope that it will be useful,
00028 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00029 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00030 // GNU General Public License for more details.
00031 //
00032 // You should have received a copy of the GNU General Public License along
00033 // with this software; see the file "license.txt".  If not, write to the
00034 // Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00035 // MA 02111-1307, USA.
00036 
00037 // Started on February 26, 2008. Last revision: April 10, 2008.
00038 
00039 
00040 // include some standard C++ header files
00041 #include <exception>
00042 #include <sstream>
00043 #include <fstream>
00044 #include <algorithm>
00045 #include <new>
00046 
00047 // include selected header files from the CHomP library
00048 #include "chomp/system/config.h"
00049 #include "chomp/system/textfile.h"
00050 #include "chomp/system/timeused.h"
00051 #include "chomp/system/arg.h"
00052 
00053 // include local header files
00054 #include "config.h"
00055 #include "confinfo.h"
00056 #include "typedefs.h"
00057 #include "utils.h"
00058 #include "compmdec.h"
00059 #include "plotmdec.h"
00060 #include "eigenval.h"
00061 #include "dotgraph.h"
00062 
00063 
00064 // --------------------------------------------------
00065 // -------------------- OVERTURE --------------------
00066 // --------------------------------------------------
00067 
00068 /// The title of the program which is displayed every time
00069 /// the program is launcued.
00070 const char *title = "\
00071 This is a program which computes a single Conley-Morse graph.\n\
00072 Ver. 0.01, April 19, 2008. Copyright (C) 2005-2008 by Pawel Pilarczyk.\n\
00073 This is free software. No warranty. Consult 'license.txt' for details.";
00074 
00075 /// The help information about the program which is displayed
00076 /// if the program is launched without command-line arguments
00077 /// or with incorrect arguments.
00078 const char *helpinfo = "\
00079 This is the front-end program for the computation of a Conley-Morse graph\n\
00080 for a single parameter box. It is a supplementary program to 'cmgraphs',\n\
00081 and it capable of saving the results of all its computations to files.\n\
00082 The parameter box is identified by the integer coordinates of its minimal\n\
00083 vertex and corresponds to a box in the subdivision of the parameter area,\n\
00084 for example, if the entire parameter range [-1,1]x[-1,1] is divided into\n\
00085 20x20 boxes then '-b 0,19' corresponds to [-1.0,-0.9]x[0.9,1.0].\n\
00086 Command line arguments (the argument '-b' is mandatory):\n\
00087 -b x1,x2,...,xN - the integer coordinates of a parameter box to process,\n\
00088 -g file.txt - file name to save the text code for the Conley-Morse graph,\n\
00089 -s file.ind - file name to save/load cached Conley index information,\n\
00090 -p file.png - file name to save a PNG picture of the Morse decomposition,\n\
00091 -c prefix - prefix for file names to save Morse sets to as lists of boxes,\n\
00092 --conn - compute connecting orbits between Morse sets (memory-consuming),\n\
00093 --full - use the full range of the phase space to plot Morse sets,\n\
00094 --log filename - file name to save all the text output of the program to,\n\
00095 --quiet - suppress any output written to the terminal,\n\
00096 --debug - display additional information useful for debugging,\n\
00097 --help - make the program show this brief help information and exit.\n\
00098 For more information ask the author at http://www.pawelpilarczyk.com/.";
00099 
00100 
00101 // --------------------------------------------------
00102 // --------------- Single Computation ---------------
00103 // --------------------------------------------------
00104 
00105 int runSingeComp (const char *boxCoordinates,
00106         const char *graphName, const char *shareName,
00107         const char *phaseSpaceName, bool fullPhaseSpace,
00108         const char *cubesName, bool connOrbits, int skipIndices)
00109 {
00110         using chomp::homology::sout;
00111 
00112         // show the global configuration information
00113         std::ostringstream info;
00114         showConfigInfo (info, 0, 0);
00115         sout << "\n" << info. str () << "\n";
00116 
00117         // reset the variables for computing max image diameter and volume
00118         theCubMapType::maxImgDiam = 0;
00119         theCubMapType::maxImgVol = 0;
00120 
00121         // decode the parameter box
00122         parCube paramBox;
00123         std::string boxCoordStr ("(" + std::string (boxCoordinates) + ")");
00124         std::istringstream boxCoordStream (boxCoordStr);
00125         boxCoordStream >> paramBox;
00126         sout << "Computing Morse decomposition for " << paramBox << ".\n";
00127 
00128         // prepare the offset and the width of the phase space region
00129         double offset [spaceDim];
00130         for (int i = 0; i < spaceDim; ++ i)
00131                 offset [i] = spaceOffset [i];
00132         double width [spaceDim];
00133         for (int i = 0; i < spaceDim; ++ i)
00134                 width [i] = spaceWidth [i];
00135 
00136         // set up an array of coordinates of the box
00137         parCoord curCoord [paramDim];
00138         paramBox. coord (curCoord);
00139 
00140         // prepare the actual parameters for the map
00141         double leftMapParam [paramCount];
00142         double rightMapParam [paramCount];
00143         computeParam (curCoord, leftMapParam, rightMapParam);
00144         sout << "Parameter values:";
00145         for (int i = 0; i < paramCount; ++ i)
00146         {
00147                 sout << " [" << leftMapParam [i] << "," <<
00148                         rightMapParam [i] << "]";
00149         }
00150         sout << "\n";
00151 
00152         // create the map object and set its parameters
00153         theMapType theMap;
00154         theMap. setParam (leftMapParam, rightMapParam, paramCount);
00155 
00156         // prepare an object of the cubical map
00157         // at the highest subdivision level to be used
00158         // in the definition of the Morse decomposition
00159         theCubMapType theCubMap0 (offset, width, 1 << finalDepth, theMap);
00160         theCubMap0. cache = true;
00161         theCubMapType theCubMap1 (offset, width, 1 << (finalDepth + 1),
00162                 theMap);
00163         theCubMap1. cache = true;
00164 
00165         // prepare a boolean value to store the information on whether
00166         // the Conley indices in the Morse decomposition were computed
00167         // or read from cache
00168         bool morseDecComputed (false);
00169 
00170         // prepare an array in which wrong Conley indices will be recorded
00171         std::vector<int> wrongIndices;
00172 
00173         // prepare an array in which skipped Conley indices will be recorded
00174         std::vector<int> skippedIndices;
00175 
00176         // prepare an array in which attractors will be recorded
00177         std::vector<int> attractors;
00178 
00179         // compute the Morse decomposition
00180         theMorseDecompositionType *morseDec = computeMorseDecomposition
00181                 (theMap, theCubMap0, theCubMap1, offset, width, skipIndices,
00182                 shareName ? shareName : "", morseDecComputed, wrongIndices,
00183                 skippedIndices, attractors, connOrbits,
00184                 leftMapParam, rightMapParam, paramCount);
00185 
00186         // show computed max image diameter and volume
00187         sout << "Max img diam = " << theCubMapType::maxImgDiam <<
00188                 ", max img vol = " << theCubMapType::maxImgVol << ".\n";
00189 
00190         // compute the min and max coordinates of Morse sets
00191         spcCoord coordLeftMin [spaceDim];
00192         spcCoord coordRightMax [spaceDim];
00193         for (int i = 0; i < spaceDim; ++ i)
00194         {
00195                 coordLeftMin [i] = 1 << finalDepth;
00196                 coordRightMax [i] = 0;
00197         }
00198         coordMinMax (*morseDec, coordLeftMin, coordRightMax);
00199 
00200         // save a picture of the computed Morse decomposition
00201         if ((spaceDim == 2) && phaseSpaceName && *phaseSpaceName)
00202         {
00203                 sout << "Saving a picture of Morse sets to '" <<
00204                         phaseSpaceName << "'...\n";
00205                 plotMorseDecompositionPNG (*morseDec, phaseSpaceName,
00206                         fullPhaseSpace ? (1 << finalDepth) : 0);
00207         }
00208 
00209         // save the computed Conley-Morse graph for the "dot" program
00210         if (graphName && *graphName)
00211         {
00212                 // create the Morse graph from the Morse decomposition
00213                 chomp::homology::diGraph<> connGraph;
00214                 morseDec -> makegraph (connGraph);
00215                 chomp::homology::diGraph<> morseGraph;
00216                 transitiveReduction (connGraph, morseGraph);
00217 
00218                 // gather the sizes of each Morse set into a vector
00219                 int nSets = morseGraph. countVertices ();
00220                 std::vector<int> sizes (nSets);
00221                 for (int n = 0; n < nSets; ++ n)
00222                         sizes [n] = (*morseDec) [n]. size ();
00223 
00224                 // gather the Conley indices and the eigenvalues
00225                 std::vector<theConleyIndexType> indices (nSets);
00226                 std::vector<IndexEigenValues> eigenValues (nSets);
00227                 for (int n = 0; n < nSets; ++ n)
00228                 {
00229                         indices [n] = morseDec -> index (n);
00230                         eigenValues [n] = IndexEigenValues (indices [n]);
00231                 }
00232 
00233                 sout << "Saving the Conley-Morse graph to '" <<
00234                         graphName << "'...\n";
00235                 std::ofstream graphFile (graphName);
00236                 writeDotGraph (graphFile, morseGraph, sizes,
00237                         indices, eigenValues,
00238                         wrongIndices, skippedIndices, attractors);
00239                 graphFile << "\n";
00240         }
00241 
00242         // save the computed Morse sets to separate text files
00243         if (cubesName && *cubesName)
00244         {
00245                 sout << "Saving the Morse decomposition to '" <<
00246                         cubesName << "*'...\n";
00247                 morseDec -> savetofiles (cubesName);
00248         }
00249 
00250         delete morseDec;
00251         return 0;
00252 } /* runSingleComp */
00253 
00254 
00255 // --------------------------------------------------
00256 // ---------------------- MAIN ----------------------
00257 // --------------------------------------------------
00258 
00259 /// The main procedure of the program.
00260 /// Returns: 0 = Ok, -1 = Error, 1 = Help displayed, 2 = Wrong arguments.
00261 int main (int argc, char *argv [])
00262 {
00263         using namespace chomp::homology;
00264 
00265         // prepare user-configurable data
00266         int skipIndices = 0;
00267         char *boxCoordinates = 0;
00268         char *graphName = 0;
00269         char *shareName = 0;
00270         char *phaseSpaceName = 0;
00271         char *cubesName = 0;
00272         bool fullPhaseSpace = false;
00273         bool connOrbits = false;
00274 
00275         // interprete the command-line arguments
00276         arguments a;
00277         arg (a, "b", boxCoordinates);
00278         arg (a, "g", graphName);
00279         arg (a, "s", shareName);
00280         arg (a, "p", phaseSpaceName);
00281         arg (a, "c", cubesName);
00282         arg (a, "-skip-indices", skipIndices, 1);
00283         argswitch (a, "-full", fullPhaseSpace, true);
00284         argswitch (a, "-conn", connOrbits, true);
00285         arghelp (a);
00286 
00287         argstreamprepare (a);
00288         int argresult = a. analyze (argc, argv);
00289         argstreamset ();
00290 
00291         // if no box coordinates defined then show the help message
00292         if (!boxCoordinates)
00293                 argresult = 1;
00294 
00295         // show the program's main title
00296         if (argresult >= 0)
00297                 sout << title << '\n';
00298 
00299         // if something was incorrect, show an additional message and exit
00300         if (argresult < 0)
00301         {
00302                 sout << "Call with '--help' for help.\n";
00303                 return 2;
00304         }
00305 
00306         // if help requested, show help information
00307         if (argresult > 0)
00308         {
00309                 sout << helpinfo << '\n';
00310                 return 1;
00311         }
00312 
00313         // try running the main function and catch an error message if thrown
00314         try
00315         {
00316                 // set an appropriate program time message
00317                 program_time = "Aborted after:";
00318                 program_time = 1;
00319 
00320                 // run the computations for a single parameter box
00321                 runSingeComp (boxCoordinates, graphName, shareName,
00322                         phaseSpaceName, fullPhaseSpace, cubesName,
00323                         connOrbits, skipIndices);
00324 
00325                 // set an appropriate program time message
00326                 program_time = "Total time used:";
00327 
00328                 // finalize
00329                 return 0;
00330         }
00331         catch (const char *msg)
00332         {
00333                 sout << "ERROR: " << msg << '\n';
00334                 return -1;
00335         }
00336         catch (const std::exception &e)
00337         {
00338                 sout << "ERROR: " << e. what () << '\n';
00339                 return -1;
00340         }
00341         catch (...)
00342         {
00343                 sout << "ABORT: An unknown error occurred.\n";
00344                 return -1;
00345         }
00346 } /* main */
00347 

Generated on Sun Mar 28 17:47:57 2010 for The Conley-Morse Graphs Software by  doxygen 1.5.3