dotgraph.h

Go to the documentation of this file.
00001 /////////////////////////////////////////////////////////////////////////////
00002 ///
00003 /// @file dotgraph.h
00004 ///
00005 /// Writing a graph in the "dot" format.
00006 /// This file contains the definition of a function
00007 /// which writes a Conley-Morse graph to an output stream
00008 /// in the format suitable for plotting by the "dot" program.
00009 ///
00010 /// @author Pawel Pilarczyk
00011 ///
00012 /////////////////////////////////////////////////////////////////////////////
00013 
00014 // Copyright (C) 1997-2008 by Pawel Pilarczyk.
00015 //
00016 // This file is part of my research software package.  This is free software;
00017 // you can redistribute it and/or modify it under the terms of the GNU
00018 // General Public License as published by the Free Software Foundation;
00019 // either version 2 of the License, or (at your option) any later version.
00020 //
00021 // This software is distributed in the hope that it will be useful,
00022 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00023 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00024 // GNU General Public License for more details.
00025 //
00026 // You should have received a copy of the GNU General Public License along
00027 // with this software; see the file "license.txt".  If not, write to the
00028 // Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00029 // MA 02111-1307, USA.
00030 
00031 // Started on February 11, 2008. Last revision: March 8, 2008.
00032 
00033 
00034 #ifndef _CMGRAPHS_DOTGRAPH_H_
00035 #define _CMGRAPHS_DOTGRAPH_H_
00036 
00037 
00038 // include some standard C++ header files
00039 #include <string>
00040 #include <ostream>
00041 #include <cmath>
00042 #include <vector>
00043 
00044 // include selected header files from the CHomP library
00045 #include "chomp/system/config.h"
00046 #include "chomp/system/textfile.h"
00047 #include "chomp/cubes/cube.h"
00048 
00049 // include local header files
00050 #include "config.h"
00051 #include "typedefs.h"
00052 #include "eigenval.h"
00053 
00054 
00055 // --------------------------------------------------
00056 // ------ encoding graphs for the dot program -------
00057 // --------------------------------------------------
00058 
00059 /// Writes the given Conley-Morse graph to the output stream
00060 /// in the format for the 'dot' program.
00061 inline std::ostream &writeDotGraph (std::ostream &out,
00062         const chomp::homology::diGraph<> &g,
00063         const std::vector<int> &sizes,
00064         const std::vector<theConleyIndexType> &indices,
00065         const std::vector<IndexEigenValues> &eigenValues,
00066         const std::vector<int> &wrongIndices,
00067         const std::vector<int> &skippedIndices,
00068         const std::vector<int> &attractors)
00069 {
00070         // determine the number of vertices in the graph
00071         int nVert = g. countVertices ();
00072 
00073         // prepare a vector of bits indicating which indices are wrong
00074         std::vector<bool> wrong (nVert, false);
00075         for (std::vector<int>::const_iterator it = wrongIndices. begin ();
00076                 it != wrongIndices. end (); ++ it)
00077         {
00078                 if (*it < 0)
00079                         continue;
00080                 else if (*it >= nVert)
00081                         throw "Too large Morse set number with wrong index.";
00082                 wrong [*it] = true;
00083         }
00084 
00085         // prepare a vector of bits indicating which indices were skipped
00086         std::vector<bool> skipped (nVert, false);
00087         for (std::vector<int>::const_iterator it = skippedIndices. begin ();
00088                 it != skippedIndices. end (); ++ it)
00089         {
00090                 if (*it < 0)
00091                         continue;
00092                 else if (*it >= nVert)
00093                         throw "Too large number of a skipped index.";
00094                 skipped [*it] = true;
00095         }
00096 
00097         // prepare a vector of bits indicating which sets are attractors
00098         std::vector<bool> attr (nVert, false);
00099         for (std::vector<int>::const_iterator it = attractors. begin ();
00100                 it != attractors. end (); ++ it)
00101         {
00102                 if (*it < 0)
00103                         continue;
00104                 else if (*it >= nVert)
00105                         throw "Too large attractor number.";
00106                 attr [*it] = true;
00107         }
00108 
00109         // count the number of incoming edges
00110         std::vector<int> incomingEdgesCount (nVert, 0);
00111         for (int v = 0; v < nVert; ++ v)
00112         {
00113                 int nEdges = g. countEdges (v);
00114                 for (int e = 0; e < nEdges; ++ e)
00115                 {
00116                         int target = g. getEdge (v, e);
00117                         if ((target < 0) || (target >= nVert))
00118                                 throw "Wrong edge while writing dot graph.";
00119                         ++ (incomingEdgesCount [target]);
00120                 }
00121         }
00122 
00123         // write the graph for the 'dot' program
00124         out << "digraph G {";
00125         bool first = true;
00126         for (int v = 0; v < nVert; ++ v)
00127         {
00128                 // begin the definition of the vertex of the C-M graph
00129                 out << (first ? "" : " ") << "v" << v << " [label=\"";
00130 
00131                 // show the number of the Morse set and its size in cubes
00132                 out << v << ": " << sizes [v] << "\\n";
00133 
00134                 // check if there is anything nonzero to show
00135                 bool showindex = !eigenValues [v]. trivial ();
00136                 int dim = indices [v]. dim ();
00137                 for (int d = 0; !showindex && (d <= dim); ++ d)
00138                 {
00139                         if (indices [v]. BettiNumber (d) ||
00140                                 (indices [v]. Coefficient (d, 0) != 0) ||
00141                                 indices [v]. Map (d) -> getncols ())
00142                         {
00143                                 showindex = true;
00144                         }
00145                 }
00146 
00147                 // show the Conley index
00148                 if (wrong [v])
00149                 {
00150                         out << "[no isolation]\\n";
00151                 }
00152                 else if (skipped [v])
00153                 {
00154                         out << "[index skipped]\\n";
00155                 }
00156                 else if (showindex)
00157                 {
00158                         // show the homology groups
00159                         out << "H = (" << indices [v]. HomString () <<
00160                                 ")\\n";
00161 
00162                         // show the homomorphism in homology
00163                         for (int d = 0; d <= indices [v]. dim (); ++ d)
00164                         {
00165                                 if (indices [v]. Map (d) -> getncols ())
00166                                 {
00167                                         out << indices [v].
00168                                                 MapString (d, "\\n");
00169                                 }
00170                         }
00171 
00172                         // show the eigenvalues
00173                         eigenValues [v]. write (out, ", ", "\\n");
00174                 }
00175 
00176                 // finish writing the label of the vertex
00177                 out << "\"";
00178 
00179                 // add necessary features of the boxes
00180                 if (attr [v])
00181                 {
00182                         out << " shape=box style=filled color=" <<
00183                                 (wrong [v] ? "red" : "yellow");
00184                 }
00185         //      else if (g. countEdges (v) == 0)
00186         //      {
00187         //      }
00188                 else if (incomingEdgesCount [v] == 0)
00189                 {
00190                         out << " shape=box style=filled color=" <<
00191                                 (wrong [v] ? "red" : "greenyellow");
00192                 }
00193                 else if (!eigenValues [v]. trivial ())
00194                 {
00195                         out << " style=filled color=" <<
00196                                 (wrong [v] ? "red" : "lightblue");
00197                 }
00198                 else if (wrong [v])
00199                 {
00200                         out << " style=filled color=red";
00201                 }
00202                 out << "]";
00203 
00204                 // make a note that this is no longer the first vertex
00205                 first = false;
00206         }
00207 
00208         // make sure all the attractors are at the same level
00209         if (attractors. size () > 1)
00210         {
00211                 out << " {rank=same;";
00212                 for (std::vector<int>::const_iterator it =
00213                         attractors. begin ();
00214                         it != attractors. end (); ++ it)
00215                 {
00216                         out << " v" << *it;
00217                 }
00218                 out << "}";
00219         }
00220 
00221         // the edges emanating from each vertex
00222         for (int v = 0; v < nVert; ++ v)
00223         {
00224                 int nEdges = g. countEdges (v);
00225                 for (int e = 0; e < nEdges; ++ e)
00226                 {
00227                         int target = g. getEdge (v, e);
00228                         out << " v" << v << "->v" << target;
00229                 }
00230         }
00231         out << "}";
00232 
00233         return out;
00234 } /* writeDotGraph */
00235 
00236 
00237 #endif // _CMGRAPHS_DOTGRAPH_H_
00238 

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