invpart.h

Go to the documentation of this file.
00001 /////////////////////////////////////////////////////////////////////////////
00002 ///
00003 /// @file invpart.h
00004 ///
00005 /// Computation of the invariant part of a set of cubes.
00006 /// This file contains the definition of a function
00007 /// for the computation of the invariant part of a set of cubes
00008 /// with respect to a given multivalued map.
00009 /// It also contains the procedure for verifying whether the invariant part
00010 /// is nonempty after subdividing the set of cubes a few times.
00011 ///
00012 /// @author Pawel Pilarczyk
00013 ///
00014 /////////////////////////////////////////////////////////////////////////////
00015 
00016 // Copyright (C) 1997-2008 by Pawel Pilarczyk.
00017 //
00018 // This file is part of my research software package.  This is free software;
00019 // you can redistribute it and/or modify it under the terms of the GNU
00020 // General Public License as published by the Free Software Foundation;
00021 // either version 2 of the License, or (at your option) any later version.
00022 //
00023 // This software is distributed in the hope that it will be useful,
00024 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00025 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00026 // GNU General Public License for more details.
00027 //
00028 // You should have received a copy of the GNU General Public License along
00029 // with this software; see the file "license.txt".  If not, write to the
00030 // Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00031 // MA 02111-1307, USA.
00032 
00033 // Started on February 12, 2007. Last revision: March 6, 2008.
00034 
00035 
00036 #ifndef _CMGRAPHS_INVPART_H_
00037 #define _CMGRAPHS_INVPART_H_
00038 
00039 
00040 // include selected header files from the CHomP library
00041 #include "chomp/system/textfile.h"
00042 #include "chomp/cubes/cube.h"
00043 #include "chomp/struct/digraph.h"
00044 #include "chomp/struct/multitab.h"
00045 
00046 // include local header files
00047 #include "config.h"
00048 #include "typedefs.h"
00049 #include "mapgraph.h"
00050 
00051 
00052 // --------------------------------------------------
00053 // ----------------- invariant part -----------------
00054 // --------------------------------------------------
00055 
00056 /// Computes X := Inv (X) using the algorithm by Bill Kalies and Hyunju Ban.
00057 /// If the graph 'gInv' is given, then the resulting graph is created,
00058 /// otherwise only the set X is modified.
00059 template <class typeCubes>
00060 inline void invariantPart (typeCubes &X, const chomp::homology::diGraph<> &g,
00061         chomp::homology::diGraph<> *gInv = 0)
00062 {
00063         // do nothing if the set X is empty
00064         if (X. empty ())
00065                 return;
00066 
00067         // compute the chain recurrent set of the graph
00068         // and remember the transposed graph
00069         chomp::homology::multitable<int> compVertices, compEnds;
00070         chomp::homology::diGraph<> gT;
00071         int count = chomp::homology::SCC (g, compVertices, compEnds,
00072                 static_cast<chomp::homology::diGraph<> *> (0), &gT);
00073 
00074         // retrieve vertices that can be reached from the chain recurrent set
00075         int nVertices = X. size ();
00076         char *forward = new char [nVertices];
00077         for (int i = 0; i < nVertices; ++ i)
00078                 forward [i] = 0;
00079         for (int cur = 0; cur < count; ++ cur)
00080                 g. DFScolor (forward, '\1',
00081                         compVertices [cur ? compEnds [cur - 1] : 0]);
00082 
00083         // retrieve vertices that can reach the chain recurrent set
00084         char *backward = new char [nVertices];
00085         for (int i = 0; i < nVertices; ++ i)
00086                 backward [i] = 0;
00087         for (int cur = 0; cur < count; ++ cur)
00088                 gT. DFScolor (backward, '\1',
00089                         compVertices [cur ? compEnds [cur - 1] : 0]);
00090 
00091         // compute the new set of cubes and exit if gInv is null
00092         typeCubes invX;
00093         if (!gInv)
00094         {
00095                 for (int i = 0; i < nVertices; ++ i)
00096                         if (forward [i] && backward [i])
00097                                 invX. add (X [i]);
00098         }
00099         else
00100         {
00101                 // join both tables and compute the new set of cubes
00102                 for (int i = 0; i < nVertices; ++ i)
00103                 {
00104                         forward [i] &= backward [i];
00105                         if (forward [i])
00106                                 invX. add (X [i]);
00107                 }
00108 
00109                 // restrict the graph to the colored vertices
00110                 g. subgraph (*gInv, forward);
00111         }
00112 
00113         // swap the set of cubes and the corresponding graph
00114         X. swap (invX);
00115 
00116         // clean the memory and return
00117         delete [] backward;
00118         delete [] forward;
00119         return;
00120 } /* invariantPart */
00121 
00122 
00123 /// Computes X := Inv (X) using the algorithm by Bill Kalies and Hyunju Ban.
00124 /// Uses the combinatorial cubical multivalued map provided.
00125 /// Returns 0 on success or -1 if failed. Shows messages to 'sbug'.
00126 template <class typeCubes, class theCubMapType>
00127 inline int invariantPart (typeCubes &X, const theCubMapType &theCubMap)
00128 {
00129         using chomp::homology::sbug;
00130 
00131         // compute the graph representation of the cubical map
00132         sbug << "F ";
00133         chomp::homology::diGraph<> g;
00134         try
00135         {
00136                 // compute the graph that represents the map restricted to X
00137                 computeMapGraph (X, g, theCubMap);
00138 
00139                 // show the average size of the image of a cube
00140                 int avgImgSize = g. countEdges () /
00141                         (X. size () ? X. size () : 1);
00142                 sbug << "[avg " << avgImgSize << "] ";
00143 
00144         }
00145         catch (const char *msg)
00146         {
00147                 // return -1 in case of failure
00148                 sbug << "Failed: " << msg << "\n";
00149                 return -1;
00150         }
00151 
00152         // compute the invariant part of X in case of success
00153         sbug << "Inv... ";
00154         invariantPart (X, g);
00155         sbug << X. size () << " left.\n";
00156 
00157         return 0;
00158 } /* invariantPart */
00159 
00160 
00161 /// Verifies whether the invariant part of the given set is empty
00162 /// by applying a limited number of refinements until the set is empty
00163 /// or the number of cubes becomes too large.
00164 /// Returns "true" if it is empty, "false" if this could not be proved.
00165 inline bool checkEmptyInv (const spcCubes &X, int subdivDepth,
00166         const double *offset, const double *width, const theMapType &theMap,
00167         const theCubMapType &theCubMap0, const theCubMapType &theCubMap1)
00168 {
00169         using chomp::homology::sbug;
00170         using chomp::homology::diGraph;
00171 
00172         if (X. empty () || (X. size () > maxRefineSize0))
00173                 return false;
00174         spcCubes Z;
00175         int subdivisions = 0;
00176         while (++ subdivisions <= refineDepth)
00177         {
00178                 // subdivide X or Z to Y
00179                 spcCubes Y;
00180                 const spcCubes &source = Z. empty () ? X : Z;
00181                 sbug << "* Subdiv " << source. size () << " -> ";
00182                 subdivideCubes (source, Y);
00183                 sbug << Y. size () << ". ";
00184                 spcCubes emptySet;
00185                 Z = emptySet;
00186 
00187                 // compute the invariant part of Y
00188                 theCubMapType subdivCubMap (offset, width,
00189                         1 << (subdivDepth + subdivisions), theMap);
00190                 subdivCubMap. cache = false;
00191                 const theCubMapType &theCubMap =
00192                         (subdivisions > 1) ? subdivCubMap :
00193                         (subdivisions ? theCubMap1 : theCubMap0);
00194                 int result = invariantPart (Y, theCubMap);
00195 
00196                 // if the computation failed then return the negative result
00197                 if (result < 0)
00198                         return false;
00199 
00200                 // return the positive result if the invariant part is empty
00201                 if (Y. empty ())
00202                 {
00203                         sbug << "* Empty after " << subdivisions <<
00204                                 " subdivisions).\n";
00205                         return true;
00206                 }
00207 
00208                 // remember the current set of cubes as Z
00209                 Z. swap (Y);
00210 
00211                 // exit the loop if there are too many cubes
00212                 if (Z. size () > maxRefineSize1)
00213                         break;
00214         }
00215         sbug << "* Nonempty after " << subdivisions << " subdivisions (" <<
00216                 Z. size () << " cubes left).\n";
00217         return false;
00218 } /* checkEmptyInv */
00219 
00220 
00221 #endif // _CMGRAPHS_INVPART_H_
00222 

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