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_CUBES_NEIGHBOR_H_
00036 #define _CHOMP_CUBES_NEIGHBOR_H_
00037
00038 #include "chomp/system/config.h"
00039 #include "chomp/system/textfile.h"
00040 #include "chomp/cubes/pointset.h"
00041 #include "chomp/struct/hashsets.h"
00042 #include "chomp/cubes/pointbas.h"
00043 #include "chomp/cubes/cube.h"
00044 #include "chomp/cubes/cell.h"
00045 #include "chomp/homology/cubacycl.h"
00046 #include "chomp/homology/tabulate.h"
00047 #include "chomp/homology/known.h"
00048
00049 #include <iostream>
00050 #include <fstream>
00051 #include <cstdlib>
00052
00053 namespace chomp {
00054 namespace homology {
00055
00056
00057
00058
00059
00061 inline int_t getmaxneighbors (int dim)
00062 {
00063 if (dim < 0)
00064 return 0;
00065 const int maxdim = 17;
00066 const int neighbors [maxdim] = {0, 2, 8, 26, 80, 242, 728,
00067 2186, 6560, 19682, 59048, 177146, 531440, 1594322,
00068 4782968, 14348906, 43046720};
00069 if (dim < maxdim)
00070 return neighbors [dim];
00071 int_t ncount = neighbors [maxdim - 1] + 1;
00072 for (int i = maxdim - 1; i < dim; ++ i)
00073 ncount *= 3;
00074 return (ncount - 1);
00075 }
00076
00077
00078
00079
00080
00081
00084 template <class tCube>
00085 int_t neighbor2bit (const tCube &q, const tCube &neighbor)
00086 {
00087
00088 typedef typename tCube::CoordType coordType;
00089
00090 coordType c0 [tCube::MaxDim];
00091 q. coord (c0);
00092 coordType c1 [tCube::MaxDim];
00093 neighbor. coord (c1);
00094 int dim = q. dim ();
00095
00096 int_t number = 0;
00097 const coordType *wrap = tCube::PointBase::getwrapping (dim);
00098 for (int i = 0; i < dim; ++ i)
00099 {
00100 if (i)
00101 number *= 3;
00102 switch (c1 [i] - c0 [i])
00103 {
00104 case -1:
00105 ++ number;
00106 case 1:
00107 ++ number;
00108 break;
00109 case 0:
00110 break;
00111 default:
00112 if (!wrap || !wrap [i])
00113 return -1;
00114 if ((c1 [i] - c0 [i]) == (wrap [i] - 1))
00115 number += 2;
00116 else if ((c1 [i] - c0 [i]) == (1 - wrap [i]))
00117 ++ number;
00118 else
00119 return -1;
00120 break;
00121 }
00122 }
00123
00124 return number - 1;
00125 }
00126
00129 template <class tCube>
00130 int_t neighbor2bit (const tCube &q, const typename tCube::CellType &face)
00131 {
00132
00133 typedef typename tCube::CoordType coordType;
00134
00135
00136 int dim = q. dim ();
00137 coordType coord [tCube::MaxDim];
00138 q. coord (coord);
00139 coordType cLeft [tCube::MaxDim];
00140 face. leftcoord (cLeft);
00141 coordType cRight [tCube::MaxDim];
00142 face. rightcoord (cRight);
00143
00144
00145 int_t number = 0;
00146 for (int i = 0; i < dim; ++ i)
00147 {
00148 if (i)
00149 number *= 3;
00150
00151 if (cLeft [i] != coord [i])
00152 number += 1;
00153
00154 else if (cRight [i] == cLeft [i])
00155 number += 2;
00156
00157 }
00158
00159 return number - 1;
00160 }
00161
00165 template <class tCube>
00166 tCube bit2neighbor (const tCube &q, int_t number, bool unconditional = false)
00167 {
00168
00169 typedef typename tCube::CoordType coordType;
00170
00171 coordType c0 [tCube::MaxDim];
00172 q. coord (c0);
00173 coordType c1 [tCube::MaxDim];
00174 int dim = q. dim ();
00175
00176 ++ number;
00177 for (int i = dim - 1; i >= 0; -- i)
00178 {
00179 switch (number % 3)
00180 {
00181 case 2:
00182 c1 [i] = c0 [i] - 1;
00183 break;
00184 case 1:
00185 c1 [i] = c0 [i] + 1;
00186 break;
00187 case 0:
00188 c1 [i] = c0 [i];
00189 break;
00190 default:
00191 throw "Erratic neighbor.";
00192 }
00193 number /= 3;
00194 }
00195
00196 if (unconditional || tCube::PointBase::check (c1, dim))
00197 return tCube (c1, dim);
00198 else
00199 return q;
00200 }
00201
00202
00203
00204
00205
00206
00211 template <class tCube, class tCubeSet1, class tCubeSet2>
00212 int_t getneighbors_scan (const tCube &q, BitField *bits,
00213 const tCubeSet1 &theset, tCubeSet2 *neighbors, int_t limit)
00214 {
00215
00216 int_t count = 0;
00217
00218
00219 for (int_t i = 0; i < theset. size (); ++ i)
00220 {
00221
00222 if (theset [i] == q)
00223 continue;
00224
00225
00226 int_t number = neighbor2bit (q, theset [i]);
00227
00228
00229 if (number < 0)
00230 continue;
00231
00232
00233 if (bits)
00234 bits -> set (number);
00235
00236
00237 if (neighbors)
00238 neighbors -> add (theset [i]);
00239
00240
00241 ++ count;
00242
00243
00244 if (limit && (count >= limit))
00245 return count;
00246 }
00247
00248 return count;
00249 }
00250
00255 template <class tCube, class tCubeSet1, class tCubeSet2>
00256 int_t getneighbors_generate (const tCube &q, BitField *bits,
00257 const tCubeSet1 &theset, tCubeSet2 *neighbors, int_t limit)
00258 {
00259
00260 int_t maxneighbors = getmaxneighbors (q. dim ());
00261
00262
00263 int_t count = 0;
00264
00265
00266 for (int_t number = 0; number < maxneighbors; ++ number)
00267 {
00268
00269 tCube neighbor = bit2neighbor (q, number);
00270
00271
00272 if (neighbor == q)
00273 continue;
00274
00275
00276 if (!theset. check (neighbor))
00277 continue;
00278
00279
00280 if (bits)
00281 bits -> set (number);
00282
00283
00284 if (neighbors)
00285 neighbors -> add (neighbor);
00286
00287
00288 ++ count;
00289
00290
00291 if (limit && (count >= limit))
00292 return count;
00293 }
00294
00295 return count;
00296 }
00297
00302 template <class tCube, class tCubeSet1, class tCubeSet2>
00303 int_t getneighbors (const tCube &q, BitField *bits,
00304 const tCubeSet1 &theset, tCubeSet2 *neighbors, int_t limit)
00305 {
00306
00307 if (theset. empty ())
00308 return 0;
00309
00310
00311 if (theset. size () < getmaxneighbors (q. dim ()))
00312 {
00313 return getneighbors_scan (q, bits, theset, neighbors, limit);
00314 }
00315 else
00316 {
00317 return getneighbors_generate (q, bits, theset, neighbors,
00318 limit);
00319 }
00320 }
00321
00322
00323
00324
00325
00326 template <class tCube, class tCubeSet>
00327 int_t getneighbors (const tCube &q, BitField *bits,
00328 const tCubeSet &theset, int_t limit)
00329 {
00330 hashedset<typename tCubeSet::value_type> *none = 0;
00331 return getneighbors (q, bits, theset, none, limit);
00332 }
00333
00334
00335
00336
00337
00338
00342 template <class tCube, class tCubeSet>
00343 int_t addneighbors (const tCube &q, const BitField &bits, tCubeSet &set,
00344 const tCubeSet ¬these)
00345 {
00346 int_t maxneighbors = getmaxneighbors (q. dim ());
00347
00348 int_t count = 0;
00349 int_t number = bits. find (0, maxneighbors);
00350 while (number >= 0)
00351 {
00352 tCube neighbor = bit2neighbor (q, number);
00353 if (!notthese. check (neighbor))
00354 set. add (neighbor);
00355 number = bits. find (number + 1, maxneighbors);
00356 ++ count;
00357 }
00358
00359 return count;
00360 }
00361
00364 template <class tCube, class tCubeSet>
00365 int_t addneighbors (const tCube &q, const BitField &bits, tCubeSet &set,
00366 bool unconditional = false)
00367 {
00368 int_t maxneighbors = getmaxneighbors (q. dim ());
00369 int_t count = 0;
00370
00371 int_t number = bits. find (0, maxneighbors);
00372 while (number >= 0)
00373 {
00374 tCube neighbor = bit2neighbor (q, number, unconditional);
00375 set. add (neighbor);
00376 number = bits. find (number + 1, maxneighbors);
00377 ++ count;
00378 }
00379
00380 return count;
00381 }
00382
00386 template <class tCube, class tCell>
00387 int_t addneighbors (const tCube &q, const BitField &bits,
00388 gcomplex<tCell,integer> &c, bool unconditional = false)
00389 {
00390
00391 typedef typename tCube::CoordType coordType;
00392
00393
00394 int dim = q. dim ();
00395
00396
00397 int_t maxneighbors = getmaxneighbors (dim);
00398
00399
00400 coordType coord [tCube::MaxDim];
00401 q. coord (coord);
00402
00403
00404 coordType cLeft [tCube::MaxDim];
00405 coordType cRight [tCube::MaxDim];
00406
00407
00408 int_t count = 0;
00409
00410
00411 int_t number = bits. find (0, maxneighbors);
00412
00413
00414 while (number >= 0)
00415 {
00416
00417 int_t n = number + 1;
00418 for (int i = dim - 1; i >= 0; -- i)
00419 {
00420 switch (n % 3)
00421 {
00422 case 2:
00423 cLeft [i] = coord [i];
00424 cRight [i] = coord [i];
00425 break;
00426 case 1:
00427 cLeft [i] = coord [i] + 1;
00428 cRight [i] = coord [i] + 1;
00429 break;
00430 case 0:
00431 cLeft [i] = coord [i];
00432 cRight [i] = coord [i] + 1;
00433 break;
00434 }
00435 n /= 3;
00436 }
00437
00438
00439 c. add (tCell (cLeft, cRight, dim));
00440
00441
00442 ++ count;
00443
00444
00445 number = bits. find (number + 1, maxneighbors);
00446 }
00447
00448 return count;
00449 }
00450
00451
00452 }
00453 }
00454
00455 #endif // _CHOMP_CUBES_NEIGHBOR_H_
00456
00458