00001
00002
00003
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #ifndef _CHOMP_CUBES_CELLFIX_H_
00038 #define _CHOMP_CUBES_CELLFIX_H_
00039
00040 #include "chomp/system/config.h"
00041 #include "chomp/system/textfile.h"
00042 #include "chomp/cubes/pointset.h"
00043 #include "chomp/homology/chains.h"
00044 #include "chomp/struct/bitfield.h"
00045 #include "chomp/struct/integer.h"
00046 #include "chomp/struct/hashsets.h"
00047 #include "chomp/homology/gcomplex.h"
00048 #include "chomp/cubes/pointbas.h"
00049 #include "chomp/cubes/cubefix.h"
00050 #include "chomp/cubes/cellmain.h"
00051
00052 #include <iostream>
00053 #include <fstream>
00054 #include <cstdlib>
00055
00056 namespace chomp {
00057 namespace homology {
00058
00059
00060
00061
00062
00063
00068 template <int dimfix, class coordtype>
00069 class tCellFix
00070 {
00071 public:
00073 typedef coordtype CoordType;
00074
00076 static const int MaxDim =
00077 (tCubeFix<dimfix,coordtype>::MaxDim < MaxBasDim) ?
00078 tCubeFix<dimfix,coordtype>::MaxDim : MaxBasDim;
00079
00081 static const int MaxSpaceDim = dimfix;
00082
00084 typedef typename tCubeFix<dimfix,coordtype>::PointBase PointBase;
00085
00087 tCellFix ();
00088
00090 tCellFix (const coordtype *c1, const coordtype *c2,
00091 int spcdim = 0, int celldim = -1);
00092
00094 tCellFix (const tCubeFix<dimfix,coordtype> &q1,
00095 const tCubeFix<dimfix,coordtype> &q2);
00096
00099 tCellFix (const tCubeFix<dimfix,coordtype> &q, int facedim);
00100
00102 explicit tCellFix (const tCubeFix<dimfix,coordtype> &q);
00103
00106 template <int dimhigh>
00107 tCellFix (const tCellFix<dimhigh,coordtype> &q,
00108 int offset, int ncoords);
00109
00111 tCellFix (const tCellFix<dimfix,coordtype> &c);
00112
00114 tCellFix<dimfix,coordtype> &operator =
00115 (const tCellFix<dimfix,coordtype> &c);
00116
00118 int dim () const;
00119
00121 int spacedim () const;
00122
00124 coordtype *leftcoord (coordtype *c) const;
00125
00127 coordtype *rightcoord (coordtype *c) const;
00128
00130 int_t hashkey1 () const;
00131
00133 int_t hashkey2 () const;
00134
00136 static const char *name ();
00137
00139 static const char *pluralname ();
00140
00145 enum OutputBitValues
00146 {
00147 BitProduct = 0x01,
00148 BitSpace = 0x02
00149 };
00150
00152 static int OutputBits;
00153
00154
00155
00157 template <int _dimfix, class _coordtype>
00158 friend inline int operator ==
00159 (const tCellFix<_dimfix,_coordtype> &c1,
00160 const tCellFix<_dimfix,_coordtype> &c2)
00161 {
00162 return ((c1. n == c2. n) && (!memcmp (c1. tab, c2. tab,
00163 dimfix * sizeof (coordtype))));
00164 }
00165
00166 private:
00168 coordtype tab [dimfix];
00169
00173 int_t n;
00174
00176 void initialize (const coordtype *c1, const coordtype *c2,
00177 int celldim = -1);
00178
00179 };
00180
00181
00182
00183 template <int dimfix, class coordtype>
00184 int tCellFix<dimfix,coordtype>::OutputBits = 0;
00185
00186
00187
00188 template <int dimfix, class coordtype>
00189 inline void tCellFix<dimfix,coordtype>::initialize (const coordtype *c1,
00190 const coordtype *c2, int celldim)
00191 {
00192
00193 PointBase::wrapcopy (tab, c1, dimfix);
00194
00195
00196 coordtype r [dimfix];
00197 PointBase::wrapcopy (r, c2, dimfix);
00198
00199
00200 if (celldim >= 0)
00201 {
00202 n = static_cast<int_t> (celldim) << NumBits;
00203 if (!celldim)
00204 return;
00205 for (int i = 0; i < dimfix; ++ i)
00206 {
00207 if (tab [i] != r [i])
00208 n |= (static_cast<int_t> (1) << i);
00209 }
00210 return;
00211 }
00212
00213
00214 n = 0;
00215 int dim = 0;
00216 for (int i = 0; i < dimfix; ++ i)
00217 {
00218 if (tab [i] != r [i])
00219 {
00220 n |= (static_cast<int_t> (1) << i);
00221 ++ dim;
00222 }
00223 }
00224 n |= static_cast<int_t> (dim) << NumBits;
00225
00226 return;
00227 }
00228
00229
00230
00231 template <int dimfix, class coordtype>
00232 inline tCellFix<dimfix,coordtype>::tCellFix ()
00233 :n (0)
00234 {
00235 if (dimfix > MaxDim)
00236 throw "Too high fixed-dim cell dimension.";
00237 return;
00238 }
00239
00240 template <int dimfix, class coordtype>
00241 inline tCellFix<dimfix,coordtype>::tCellFix
00242 (const coordtype *c1, const coordtype *c2, int spcdim, int celldim)
00243 {
00244
00245 if (spcdim < 0)
00246 throw "Negative dimension of the space.";
00247 else if ((spcdim > 0) && (spcdim != dimfix))
00248 throw "Wrong dimension of a cell.";
00249 if (dimfix > MaxDim)
00250 throw "Too high fixed-dim cell dimension.";
00251
00252
00253 initialize (c1, c2, celldim);
00254 return;
00255 }
00256
00257 template <int dimfix, class coordtype>
00258 inline tCellFix<dimfix,coordtype>::tCellFix
00259 (const tCubeFix<dimfix,coordtype> &q1,
00260 const tCubeFix<dimfix,coordtype> &q2)
00261 {
00262 if (dimfix > MaxDim)
00263 throw "Too high fixed-dim cell dimension.";
00264
00265
00266 coordtype c1 [dimfix];
00267 q1. coord (c1);
00268 coordtype c2 [dimfix];
00269 q2. coord (c2);
00270
00271
00272 coordinate left [dimfix];
00273 coordinate right [dimfix];
00274
00275
00276 int celldim = CommonCell (left, right, c1, c2, dimfix,
00277 PointBase::getwrapping (dimfix));
00278
00279
00280 initialize (left, right, celldim);
00281
00282 return;
00283 }
00284
00285 template <int dimfix, class coordtype>
00286 inline tCellFix<dimfix,coordtype>::tCellFix
00287 (const tCubeFix<dimfix,coordtype> &q, int facedim)
00288 {
00289 if (facedim < 0)
00290 throw "Negative dimension of a face requested.";
00291 if (facedim > dimfix)
00292 throw "Too high dimension of a face requested.";
00293 if (dimfix > MaxDim)
00294 throw "Too high fixed-dim cell dimension.";
00295 copycoord (tab, q. tab, dimfix);
00296 n = static_cast<int_t> (facedim) << NumBits;
00297 for (int i = 0; i < facedim; ++ i)
00298 n |= static_cast<int_t> (1) << i;
00299 return;
00300 }
00301
00302 template <int dimfix, class coordtype>
00303 inline tCellFix<dimfix,coordtype>::tCellFix
00304 (const tCubeFix<dimfix,coordtype> &q)
00305 : n ((static_cast<int_t> (dimfix) << NumBits) | NumMask)
00306 {
00307 if (dimfix > MaxDim)
00308 throw "Too high fixed-dim cell dimension.";
00309 copycoord (tab, q. tab, dimfix);
00310 return;
00311 }
00312
00313 template <int dimfix, class coordtype>
00314 template <int dimhigh>
00315 inline tCellFix<dimfix,coordtype>::tCellFix
00316 (const tCellFix<dimhigh,coordtype> &q, int offset, int ncoords)
00317 {
00318 if ((offset < 0) || (ncoords <= 0) || (ncoords != dimfix) ||
00319 (offset + ncoords > dimhigh))
00320 throw "Wrong cell projection requested.";
00321
00322
00323 coordtype right [dimhigh];
00324 q. rightcoord (right);
00325 initialize (q. tab + offset, right + offset);
00326 return;
00327 }
00328
00329 template <int dimfix, class coordtype>
00330 inline tCellFix<dimfix,coordtype>::tCellFix
00331 (const tCellFix<dimfix,coordtype> &q)
00332 : n (q. n)
00333 {
00334 copycoord (tab, q. tab, dimfix);
00335 return;
00336 }
00337
00338 template <int dimfix, class coordtype>
00339 inline tCellFix<dimfix,coordtype> &tCellFix<dimfix,coordtype>::operator =
00340 (const tCellFix<dimfix,coordtype> &q)
00341 {
00342 memcpy (tab, q. tab, dimfix * sizeof (coordtype));
00343 n = q. n;
00344 return *this;
00345 }
00346
00347 template <int dimfix, class coordtype>
00348 inline int tCellFix<dimfix,coordtype>::dim () const
00349 {
00350 return static_cast<int> (n >> NumBits);
00351 }
00352
00353 template <int dimfix, class coordtype>
00354 inline int tCellFix<dimfix,coordtype>::spacedim () const
00355 {
00356 return dimfix;
00357 }
00358
00359 template <int dimfix, class coordtype>
00360 inline coordtype *tCellFix<dimfix,coordtype>::leftcoord (coordtype *c) const
00361 {
00362 if (!c)
00363 throw "Null pointer to save left coordinates.";
00364 for (int i = 0; i < dimfix; ++ i)
00365 c [i] = tab [i];
00366 return c;
00367 }
00368
00369 template <int dimfix, class coordtype>
00370 inline coordtype *tCellFix<dimfix,coordtype>::rightcoord (coordtype *c) const
00371 {
00372 if (!c)
00373 throw "Null pointer to save right coordinates.";
00374 for (int i = 0; i < dimfix; ++ i)
00375 {
00376 c [i] = tab [i] +
00377 ((n & (static_cast<int_t> (1) << i)) ? 1 : 0);
00378 }
00379 PointBase::wrapcoord (c, spacedim ());
00380 return c;
00381 }
00382
00383 template <int dimfix, class coordtype>
00384 inline int_t tCellFix<dimfix,coordtype>::hashkey1 () const
00385 {
00386 switch (dimfix)
00387 {
00388 case 1:
00389 return (static_cast<int_t> (tab [0]) << 12) ^ n;
00390 case 2:
00391 return (((static_cast<int_t> (tab [0])) << 18) +
00392 ((static_cast<int_t> (tab [1])) << 6)) ^ n;
00393 default:
00394 return (((static_cast<int_t> (tab [0])) << 18) +
00395 ((static_cast<int_t> (tab [1])) << 6) +
00396 ((static_cast<int_t> (tab [2])) >> 6)) ^ n;
00397 }
00398 }
00399
00400 template <int dimfix, class coordtype>
00401 inline int_t tCellFix<dimfix,coordtype>::hashkey2 () const
00402 {
00403 switch (dimfix)
00404 {
00405 case 1:
00406 return (static_cast<int_t> (tab [0]) << 3) ^ (n << 5);
00407 case 2:
00408 return ((static_cast<int_t> (tab [0]) >> 1) +
00409 (static_cast<int_t> (tab [1]) << 13)) ^ (n << 5);
00410 default:
00411 return (((static_cast<int_t> (tab [dimfix - 1])) << 20) +
00412 ((static_cast<int_t> (tab [dimfix - 2])) << 9) +
00413 ((static_cast<int_t> (tab [dimfix - 3])) >> 1)) ^
00414 (n << 5);
00415 }
00416 }
00417
00418 template <int dimfix, class coordtype>
00419 const char *tCellFix<dimfix,coordtype>::name ()
00420 {
00421 return "cubical cell";
00422 }
00423
00424 template <int dimfix, class coordtype>
00425 const char *tCellFix<dimfix,coordtype>::pluralname ()
00426 {
00427 return "cubical cells";
00428 }
00429
00430
00431
00433 template <int dimfix, class coordtype>
00434 inline int operator != (const tCellFix<dimfix,coordtype> &c1,
00435 const tCellFix<dimfix,coordtype> &c2)
00436 {
00437 return !(c1 == c2);
00438 }
00439
00440
00441
00443 template <int dim1, int dim2, class coordtype>
00444 inline tCellFix<dim1+dim2,coordtype> operator *
00445 (const tCellFix<dim1,coordtype> &c1,
00446 const tCellFix<dim2,coordtype> &c2)
00447 {
00448
00449 coordtype left [dim1 + dim2];
00450 coordtype right [dim1 + dim2];
00451
00452
00453 c1. leftcoord (left);
00454 c1. rightcoord (right);
00455
00456
00457 c2. leftcoord (left + dim1);
00458 c2. rightcoord (right + dim1);
00459
00460
00461 return tCellFix<dim1+dim2,coordtype> (left, right,
00462 dim1 + dim2, c1. dim () + c2. dim ());
00463 }
00464
00466 template <int dimfix, class coordtype>
00467 inline std::ostream &operator << (std::ostream &out,
00468 const tCellFix<dimfix,coordtype> &c)
00469 {
00470 return WriteCubicalCell (out, c);
00471 }
00472
00474 template <int dimfix, class coordtype>
00475 inline std::istream &operator >> (std::istream &in,
00476 tCellFix<dimfix,coordtype> &c)
00477 {
00478 return ReadCubicalCell (in, c);
00479 }
00480
00481
00482
00484 template <int dimfix, class coordtype>
00485 inline tCellFix<dimfix,coordtype> boundarycell
00486 (const tCellFix<dimfix,coordtype> &q, int i, bool onlyexisting)
00487 {
00488 return CubicalBoundaryCell (q, i, onlyexisting);
00489 }
00490
00492 template <int dimfix, class coordtype>
00493 inline tCellFix<dimfix,coordtype> boundarycell
00494 (const tCellFix<dimfix,coordtype> &q, int i)
00495 {
00496 return CubicalBoundaryCell (q, i);
00497 }
00498
00500 template <int dimfix, class coordtype>
00501 inline int boundarylength (const tCellFix<dimfix,coordtype> &q)
00502 {
00503 return CubicalBoundaryLength (q);
00504 }
00505
00507 template <int dimfix, class coordtype>
00508 inline int boundarycoef (const tCellFix<dimfix,coordtype> &q, int i)
00509 {
00510 return CubicalBoundaryCoef (q, i);
00511 }
00512
00513
00514 }
00515 }
00516
00517 #endif // _CHOMP_CUBES_CELLFIX_H_
00518
00520