00001
00002
00003
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef _CHOMP_HOMOLOGY_INDXPALG_H_
00036 #define _CHOMP_HOMOLOGY_INDXPALG_H_
00037
00038 #include "chomp/homology/cubisets.h"
00039 #include "chomp/cubes/cube.h"
00040 #include "chomp/cubes/cell.h"
00041 #include "chomp/struct/digraph.h"
00042
00043 #include <iostream>
00044 #include <fstream>
00045 #include <cstdlib>
00046
00047 namespace chomp {
00048 namespace homology {
00049
00050
00051
00052
00053
00054
00057 template <class TCube, class TSetOfCubes>
00058 class MapClass
00059 {
00060 public:
00063 const TSetOfCubes &operator () (const TCube &q) const
00064 {
00065 throw "The map has not been defined.";
00066 }
00067
00068 };
00069
00070
00075 template <class TCube = Cube>
00076 class BufferedMapClass: public MapClass<TCube,hashedset<TCube> >
00077 {
00078 public:
00080 typedef hashedset<TCube> TSetOfCubes;
00081
00083 typedef typename TCube::CoordType TCoordType;
00084
00086 typedef int (*map) (const TCoordType *coord,
00087 double *left, double *right);
00088
00090 BufferedMapClass (map _f): f (_f) {}
00091
00094 const TSetOfCubes &operator () (const TCube &q) const;
00095
00097 mutable mvmap<TCube,TCube> F;
00098
00099 private:
00101 map f;
00102
00103 };
00104
00105 template <class TCube>
00106 const typename BufferedMapClass<TCube>::TSetOfCubes &
00107 BufferedMapClass<TCube>::operator () (const TCube &q) const
00108 {
00109
00110 const TSetOfCubes &dom = F. getdomain ();
00111 if (dom. check (q))
00112 return F (q);
00113
00114
00115 const int dim = q. dim ();
00116
00117
00118 TCoordType *coord = new TCoordType [dim];
00119 q. coord (coord);
00120 double *left = new double [dim];
00121 double *right = new double [dim];
00122 f (coord, left, right);
00123 delete [] coord;
00124
00125
00126
00127 TCoordType *ileft = new TCoordType [dim];
00128 TCoordType *iright = new TCoordType [dim];
00129 for (int i = 0; i < dim; ++ i)
00130 {
00131 ileft [i] = static_cast<TCoordType> (left [i]);
00132 if ((ileft [i] + 1 < left [i]) ||
00133 (ileft [i] - 1 > left [i]))
00134 throw "Conversion error: double to coord - "
00135 "out of range.";
00136 for (int j = 0; j < 10; ++ j)
00137 {
00138 if (ileft [i] >= left [i])
00139 -- ileft [i];
00140 else
00141 break;
00142 }
00143 if (ileft [i] >= left [i])
00144 throw "Outer approximation failure (left).";
00145 iright [i] = static_cast<TCoordType> (right [i]);
00146 if ((iright [i] + 1 < right [i]) ||
00147 (iright [i] - 1 > right [i]))
00148 throw "Conversion error: double to coord - "
00149 "out of range.";
00150 for (int j = 0; j < 10; ++ j)
00151 {
00152 if (iright [i] <= right [i])
00153 ++ iright [i];
00154 else
00155 break;
00156 }
00157 if (iright [i] <= right [i])
00158 throw "Outer approximation failure (right).";
00159 }
00160 delete [] right;
00161 delete [] left;
00162
00163
00164 hashedset<TCube> &img = F [q];
00165 tRectangle<TCoordType> r (ileft, iright, dim);
00166 const TCoordType *c;
00167 while ((c = r. get ()) != 0)
00168 img. add (TCube (c, dim));
00169 delete [] iright;
00170 delete [] ileft;
00171
00172
00173 return F (q);
00174 }
00175
00176 template <class TCube>
00177 std::ostream &operator << (std::ostream &out,
00178 const BufferedMapClass<TCube> &map)
00179 {
00180 out << map. F;
00181 return out;
00182 }
00183
00184
00185
00186
00187
00188
00190 template <class TSetOfCubes>
00191 int neighborhood (const TSetOfCubes &X, TSetOfCubes &result)
00192 {
00193
00194 using namespace chomp::homology;
00195 typedef typename TSetOfCubes::value_type cubetype;
00196 typedef typename cubetype::CoordType coordtype;
00197 typedef tRectangle<coordtype> rectangle;
00198 const int maxdim = cubetype::MaxDim;
00199
00200
00201 coordtype mincoord [maxdim], maxcoord [maxdim];
00202
00203
00204 int_t ncount = X. size ();
00205 for (int_t n = 0; n < ncount; ++ n)
00206 {
00207
00208 int dim = X [n]. dim ();
00209 X [n]. coord (mincoord);
00210
00211
00212
00213 for (int i = 0; i < dim; ++ i)
00214 {
00215 maxcoord [i] = mincoord [i];
00216 ++ maxcoord [i];
00217 ++ maxcoord [i];
00218 -- mincoord [i];
00219 }
00220
00221
00222 rectangle r (mincoord, maxcoord, dim);
00223 const coordtype *c;
00224 while ((c = r. get ()) != 0)
00225 result. add (cubetype (c, dim));
00226 }
00227 return 0;
00228 }
00229
00230
00231
00232
00233
00234
00238 template <class TSetOfCubes, class TMap>
00239 void invariantpart (TSetOfCubes &X, const TMap &F, TSetOfCubes &result)
00240 {
00241
00242 int_t ncount = X. size ();
00243 if (!ncount)
00244 return;
00245
00246
00247 diGraph<> g;
00248 for (int_t n = 0; n < ncount; ++ n)
00249 {
00250 g. addVertex ();
00251 const TSetOfCubes &img = F (X [n]);
00252 int_t icount = img. size ();
00253 for (int_t i = 0; i < icount; ++ i)
00254 {
00255 int_t number = X. getnumber (img [i]);
00256 if (number < 0)
00257 continue;
00258 g. addEdge (number);
00259 }
00260 }
00261
00262
00263
00264 multitable<int_t> compVertices, compEnds;
00265 diGraph<> gT;
00266 int_t count = SCC (g, compVertices, compEnds,
00267 static_cast<diGraph<> *> (0), &gT);
00268
00269
00270 int_t nVertices = ncount;
00271 char *forward = new char [nVertices];
00272 for (int_t i = 0; i < nVertices; ++ i)
00273 forward [i] = 0;
00274 for (int_t cur = 0; cur < count; ++ cur)
00275 {
00276 g. DFScolor (forward, '\1',
00277 compVertices [cur ? compEnds [cur - 1] :
00278 static_cast<int_t> (0)]);
00279 }
00280
00281
00282 char *backward = new char [nVertices];
00283 for (int_t i = 0; i < nVertices; ++ i)
00284 backward [i] = 0;
00285 for (int_t cur = 0; cur < count; ++ cur)
00286 {
00287 gT. DFScolor (backward, '\1',
00288 compVertices [cur ? compEnds [cur - 1] :
00289 static_cast<int_t> (0)]);
00290 }
00291
00292
00293 for (int_t i = 0; i < nVertices; ++ i)
00294 if (forward [i] && backward [i])
00295 result. add (X [i]);
00296
00297
00298 delete [] backward;
00299 delete [] forward;
00300 return;
00301 }
00302
00303
00304
00305
00306
00307
00309 template <class HSet>
00310 bool inclusion (const HSet &X, const HSet &Y)
00311 {
00312 int_t countX = X. size ();
00313 if (countX && Y. empty ())
00314 return false;
00315
00316 for (int_t i = 0; i < countX; ++ i)
00317 if (!Y. check (X [i]))
00318 return false;
00319 return true;
00320 }
00321
00322
00323
00324
00325
00326
00328 template <class TSetOfCubes, class TMap>
00329 int ExitSetM (const TSetOfCubes &N, const TSetOfCubes &Q1,
00330 const TMap &F, TSetOfCubes &resultQ2)
00331 {
00332
00333 int_t countQ1 = Q1. size ();
00334 int_t n = 0;
00335
00336
00337 while (n < countQ1 + resultQ2. size ())
00338 {
00339
00340 const TSetOfCubes &img =
00341 F ((n < countQ1) ? Q1 [n] : resultQ2 [n - countQ1]);
00342
00343
00344 int_t countImg = img. size ();
00345 for (int_t i = 0; i < countImg; ++ i)
00346 {
00347 if (!N. check (img [i]))
00348 continue;
00349 if (Q1. check (img [i]))
00350 continue;
00351 resultQ2. add (img [i]);
00352 }
00353 ++ n;
00354 }
00355 return 0;
00356 }
00357
00361 template <class TSetOfCubes, class TMap>
00362 int IndexPairM (const TMap &F, const TSetOfCubes &initialS,
00363 TSetOfCubes &resultQ1, TSetOfCubes &resultQ2)
00364 {
00365
00366 TSetOfCubes S = initialS;
00367 TSetOfCubes N;
00368 neighborhood (S, N);
00369
00370 sout << "Starting with " << S. size () << " cubes in S_0, " <<
00371 N. size () << " cubes in N.\n";
00372 while (1)
00373 {
00374
00375
00376 sout << "S := Inv(N)... ";
00377 scon << "(computing)\b\b\b\b\b\b\b\b\b\b\b";
00378 TSetOfCubes empty;
00379 S = empty;
00380
00381 invariantpart (N, F, S);
00382 sout << S. size () << " cubes; o(S) has ";
00383
00384
00385 TSetOfCubes newN;
00386 neighborhood (S, newN);
00387 sout << newN. size () << " cubes.\n";
00388
00389
00390 if (inclusion (newN, N))
00391 break;
00392
00393 else
00394 {
00395 sout << "Set N := o(S). ";
00396 N = newN;
00397 }
00398 }
00399
00400
00401 resultQ1 = S;
00402 ExitSetM (N, S, F, resultQ2);
00403 return 0;
00404 }
00405
00406
00407
00408
00409
00410
00414 template <class TSetOfCubes, class TMap>
00415 int IndexPairP (const TMap &F, const TSetOfCubes &initialS,
00416 TSetOfCubes &resultQ1, TSetOfCubes &resultQ2)
00417 {
00418 resultQ1 = initialS;
00419
00420
00421 sout << "Computing the map on Q1 (" << resultQ1. size () <<
00422 " cubes)... ";
00423 for (int_t i = 0; i < resultQ1. size (); ++ i)
00424 {
00425 const TSetOfCubes &img = F (resultQ1 [i]);
00426 for (int_t j = 0; j < img. size (); ++ j)
00427 {
00428 if (!resultQ1. check (img [j]))
00429 resultQ2. add (img [j]);
00430 }
00431 }
00432 sout << resultQ2. size () << " cubes added to Q2.\n";
00433
00434
00435
00436
00437
00438
00439
00440 sout << "Increasing Q1 and Q2 until F(Q2) is disjoint from Q1... ";
00441 int_t counter = 0;
00442 int_t countimages = 0;
00443 int_t cur = 0;
00444 TSetOfCubes removed;
00445 while (1)
00446 {
00447
00448 if (cur >= resultQ2. size ())
00449 {
00450 if (removed. empty ())
00451 break;
00452 resultQ2. remove (removed);
00453 TSetOfCubes empty;
00454 removed = empty;
00455 cur = 0;
00456 continue;
00457 }
00458
00459
00460 ++ counter;
00461 if (!(counter % 373))
00462 scon << std::setw (12) << counter <<
00463 "\b\b\b\b\b\b\b\b\b\b\b\b";
00464
00465
00466 bool intersects = false;
00467 const TSetOfCubes &img = F (resultQ2 [cur]);
00468 ++ countimages;
00469 for (int_t j = 0; j < img. size (); ++ j)
00470 {
00471 if (resultQ1. check (img [j]))
00472 {
00473 intersects = true;
00474 break;
00475 }
00476 }
00477
00478 if (intersects)
00479 {
00480
00481 for (int_t j = 0; j < img. size (); ++ j)
00482 {
00483 if (!resultQ1. check (img [j]))
00484 resultQ2. add (img [j]);
00485 }
00486
00487 resultQ1. add (resultQ2 [cur]);
00488 removed. add (resultQ2 [cur]);
00489 }
00490
00491
00492 ++ cur;
00493 }
00494 sout << countimages << " analyzed.\n";
00495 return 0;
00496 }
00497
00498
00499 }
00500 }
00501
00502 #endif // _CHOMP_HOMOLOGY_INDXPALG_H_
00503
00505