cellfix.h

Go to the documentation of this file.
00001 
00002 
00003 
00016 
00017 // Copyright (C) 1997-2010 by Pawel Pilarczyk.
00018 //
00019 // This file is part of the Homology Library.  This library is free software;
00020 // you can redistribute it and/or modify it under the terms of the GNU
00021 // General Public License as published by the Free Software Foundation;
00022 // either version 2 of the License, or (at your option) any later version.
00023 //
00024 // This library is distributed in the hope that it will be useful,
00025 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00026 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00027 // GNU General Public License for more details.
00028 //
00029 // You should have received a copy of the GNU General Public License along
00030 // with this software; see the file "license.txt".  If not, write to the
00031 // Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00032 // MA 02111-1307, USA.
00033 
00034 // Started in January 2002. Last revision: August 4, 2010.
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 // ----------- CubicalCell with fixed dim -----------
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,      // unset => two vertices
00148                 BitSpace = 0x02
00149         };
00150 
00152         static int OutputBits;
00153 
00154         // --- friends: ---
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         } /* operator == */
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 }; /* class tCellFix */
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         // copy the left corner coordinates to the cell
00193         PointBase::wrapcopy (tab, c1, dimfix);
00194 
00195         // prepare wrapped right coordinates for the detection of cell bits
00196         coordtype r [dimfix];
00197         PointBase::wrapcopy (r, c2, dimfix);
00198 
00199         // if the dimension of the cell is known, then compute the bits only
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         // set the bits of the cell and compute its actual dimension
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 } /* tCellFix::initialize */
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 } /* tCellFix::tCellFix */
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         // test the validity of the dimension
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         // initialize the cell
00253         initialize (c1, c2, celldim);
00254         return;
00255 } /* tCellFix::tCellFix */
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         // get the coordinates of minimal vertices of both cubes
00266         coordtype c1 [dimfix];
00267         q1. coord (c1);
00268         coordtype c2 [dimfix];
00269         q2. coord (c2);
00270 
00271         // prepare tables for the new coordinates of the cubical cell
00272         coordinate left [dimfix];
00273         coordinate right [dimfix];
00274 
00275         // compute the new coordinates of the cubical cell
00276         int celldim = CommonCell (left, right, c1, c2, dimfix,
00277                 PointBase::getwrapping (dimfix));
00278         
00279         // create the cell as computed
00280         initialize (left, right, celldim);
00281 
00282         return;
00283 } /* tCellFix::tCellFix */
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 } /* tCellFix::tCellFix */
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 } /* tCellFix::tCellFix */
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         // note: the following can be done in a slightly more efficient way,
00322         // without creating the right coordinates and calling "initialize"
00323         coordtype right [dimhigh];
00324         q. rightcoord (right);
00325         initialize (q. tab + offset, right + offset);
00326         return;
00327 } /* tCellFix::tCellFix */
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 } /* tCellFix::tCellFix */
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 } /* tCellFix::operator = */
00346 
00347 template <int dimfix, class coordtype>
00348 inline int tCellFix<dimfix,coordtype>::dim () const
00349 {
00350         return static_cast<int> (n >> NumBits);
00351 } /* tCellFix::dim */
00352 
00353 template <int dimfix, class coordtype>
00354 inline int tCellFix<dimfix,coordtype>::spacedim () const
00355 {
00356         return dimfix;
00357 } /* tCellFix::spacedim */
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 } /* tCellFix::leftcoord */
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 } /* tCellFix::rightcoord */
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 } /* tCellFix::hashkey1 */
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 } /* tCellFix::hashkey2 */
00417 
00418 template <int dimfix, class coordtype>
00419 const char *tCellFix<dimfix,coordtype>::name ()
00420 {
00421         return "cubical cell";
00422 } /* tCellFix::name */
00423 
00424 template <int dimfix, class coordtype>
00425 const char *tCellFix<dimfix,coordtype>::pluralname ()
00426 {
00427         return "cubical cells";
00428 } /* tCellFix::pluralname */
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 } /* operator != */
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         // prepare arrays for the coordinates of the cell to create
00449         coordtype left [dim1 + dim2];
00450         coordtype right [dim1 + dim2];
00451 
00452         // extract the coordinates of the first cell
00453         c1. leftcoord (left);
00454         c1. rightcoord (right);
00455 
00456         // extract the coordinates of the second cell
00457         c2. leftcoord (left + dim1);
00458         c2. rightcoord (right + dim1);
00459 
00460         // create the Cartesian product of the cells
00461         return tCellFix<dim1+dim2,coordtype> (left, right,
00462                 dim1 + dim2, c1. dim () + c2. dim ());
00463 } /* operator * */
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 } /* operator << */
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 } /* operator >> */
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 } /* boundarycell */
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 } /* boundarycell */
00498         
00500 template <int dimfix, class coordtype>
00501 inline int boundarylength (const tCellFix<dimfix,coordtype> &q)
00502 {
00503         return CubicalBoundaryLength (q);
00504 } /* boundarylength */
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 } /* boundarycoef */
00512 
00513 
00514 } // namespace homology
00515 } // namespace chomp
00516 
00517 #endif // _CHOMP_CUBES_CELLFIX_H_
00518 
00520