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
00034
00035
00036 #ifndef _CMGRAPHS_INVPART_H_
00037 #define _CMGRAPHS_INVPART_H_
00038
00039
00040
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
00047 #include "config.h"
00048 #include "typedefs.h"
00049 #include "mapgraph.h"
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 template <class typeCubes>
00060 inline void invariantPart (typeCubes &X, const chomp::homology::diGraph<> &g,
00061 chomp::homology::diGraph<> *gInv = 0)
00062 {
00063
00064 if (X. empty ())
00065 return;
00066
00067
00068
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
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
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
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
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
00110 g. subgraph (*gInv, forward);
00111 }
00112
00113
00114 X. swap (invX);
00115
00116
00117 delete [] backward;
00118 delete [] forward;
00119 return;
00120 }
00121
00122
00123
00124
00125
00126 template <class typeCubes, class theCubMapType>
00127 inline int invariantPart (typeCubes &X, const theCubMapType &theCubMap)
00128 {
00129 using chomp::homology::sbug;
00130
00131
00132 sbug << "F ";
00133 chomp::homology::diGraph<> g;
00134 try
00135 {
00136
00137 computeMapGraph (X, g, theCubMap);
00138
00139
00140 int avgImgSize = g. countEdges () /
00141 (X. size () ? X. size () : 1);
00142 sbug << "[avg " << avgImgSize << "] ";
00143
00144 }
00145 catch (const char *msg)
00146 {
00147
00148 sbug << "Failed: " << msg << "\n";
00149 return -1;
00150 }
00151
00152
00153 sbug << "Inv... ";
00154 invariantPart (X, g);
00155 sbug << X. size () << " left.\n";
00156
00157 return 0;
00158 }
00159
00160
00161
00162
00163
00164
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
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
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
00197 if (result < 0)
00198 return false;
00199
00200
00201 if (Y. empty ())
00202 {
00203 sbug << "* Empty after " << subdivisions <<
00204 " subdivisions).\n";
00205 return true;
00206 }
00207
00208
00209 Z. swap (Y);
00210
00211
00212 if (Z. size () > maxRefineSize1)
00213 break;
00214 }
00215 sbug << "* Nonempty after " << subdivisions << " subdivisions (" <<
00216 Z. size () << " cubes left).\n";
00217 return false;
00218 }
00219
00220
00221 #endif // _CMGRAPHS_INVPART_H_
00222