pointbas.h

Go to the documentation of this file.
00001 
00002 
00003 
00018 
00019 // Copyright (C) 1997-2010 by Pawel Pilarczyk.
00020 //
00021 // This file is part of the Homology Library.  This library is free software;
00022 // you can redistribute it and/or modify it under the terms of the GNU
00023 // General Public License as published by the Free Software Foundation;
00024 // either version 2 of the License, or (at your option) any later version.
00025 //
00026 // This library is distributed in the hope that it will be useful,
00027 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00028 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00029 // GNU General Public License for more details.
00030 //
00031 // You should have received a copy of the GNU General Public License along
00032 // with this software; see the file "license.txt".  If not, write to the
00033 // Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00034 // MA 02111-1307, USA.
00035 
00036 // Started in January 2002. Last revision: January 23, 2010.
00037 
00038 
00039 #ifndef _CHOMP_CUBES_POINTBAS_H_
00040 #define _CHOMP_CUBES_POINTBAS_H_
00041 
00042 #include "chomp/system/config.h"
00043 #include "chomp/system/textfile.h"
00044 #include "chomp/cubes/pointset.h"
00045 
00046 #include <iostream>
00047 #include <fstream>
00048 #include <cstdlib>
00049 
00050 
00051 namespace chomp {
00052 namespace homology {
00053 
00054 
00055 // classes defined within this header file (in this order):
00056 template <class coordtype>
00057 class tPointBase;
00058 
00059 template <class coordtype>
00060 class tPointBaseInitializer;
00061 
00063 typedef tPointBase<coordinate> PointBase;
00064 
00068 const int DimBits = (sizeof (int_t) > 4) ? 7 : 6;
00069 
00072 const int NumBits = (sizeof (int_t) << 3) - DimBits;
00073 
00075 const int_t SignBit = static_cast<int_t> (1) << ((sizeof (int_t) << 3) - 1);
00076 
00078 const int_t NumMask = (~(static_cast<int_t> (0) ^ SignBit)) >> (DimBits - 1);
00079 
00081 const int MaxBasDim1 = static_cast<int> (1u << (DimBits - 1));
00082 
00085 const int MaxBasDim2 = static_cast<int> ((sizeof (int_t) << 3) - DimBits);
00086 
00090 const int MaxBasDim = (MaxBasDim1 < MaxBasDim2) ? MaxBasDim1 : MaxBasDim2;
00091 
00092 
00093 // --------------------------------------------------
00094 // ------------------- Point Base -------------------
00095 // --------------------------------------------------
00096 
00101 template <class coordtype>
00102 class tPointBase
00103 {
00104 public:
00107         static int_t number (const coordtype *c, int d);
00108 
00112         static bool check (const coordtype *c, int d);
00113 
00115         static const coordtype *coord (int_t number, int d);
00116 
00118         static int defaultdimension (void);
00119 
00122         static void quiet (bool what = true);
00123         
00127         static void setwrapping (const coordtype *c,
00128                 int mindim = 1, int maxdim = MaxBasDim);
00129 
00133         static void setwrapping (coordtype c,
00134                 int mindim = 1, int maxdim = MaxBasDim);
00135 
00137         static const coordtype *getwrapping (int d);
00138 
00140         static void wrapcoord (coordtype *c, int dim);
00141 
00143         static void wrapcopy (coordtype *dest, const coordtype *src,
00144                 int dim);
00145 
00148         static void reset (void);
00149 
00152         static void forget (void);
00153 
00155         static outputstream &showused (outputstream &out);
00156 
00158         static std::ostream &showused (std::ostream &out);
00159 
00161         friend class tPointBaseInitializer<coordtype>;
00162 
00163 protected:
00165         static tPointset<coordtype> **p;
00166 
00168         static int n;
00169 
00171         static bool show;
00172 
00174         static bool forgotten;
00175 
00177         static tPointBaseInitializer<coordtype> pointBaseInitializer;
00178 
00179 }; /* class tPointBase */
00180 
00181 // --------------------------------------------------
00182 
00183 template <class coordtype>
00184 inline const coordtype *tPointBase<coordtype>::coord (int_t nr, int d)
00185 {
00186         if (forgotten)
00187                 throw "Trying to retrieve forgotten coordinates.";
00188         if ((d > n) || (d <= 0) || (p [d - 1] == NULL))
00189                 return NULL;
00190         else
00191                 return (*(p [d - 1])) [nr];
00192 } /* tPointBase::coord */
00193 
00194 template <class coordtype>
00195 inline bool tPointBase<coordtype>::check (const coordtype *c, int d)
00196 {
00197         if (forgotten)
00198                 throw "Trying to check forgotten coordinates.";
00199         if ((d > n) || (d <= 0) || (p [d - 1] == NULL))
00200                 return 0;
00201         return p [d - 1] -> check (c);
00202 } /* tPointBase::check */
00203 
00204 template <class coordtype>
00205 inline void tPointBase<coordtype>::quiet (bool what)
00206 {
00207         show = !what;
00208         return;
00209 } /* tPointBase::quiet */
00210 
00211 template <class coordtype>
00212 inline int_t tPointBase<coordtype>::number (const coordtype *c, int d)
00213 {
00214         if (forgotten)
00215                 throw "Trying to find the number of forgotten coordinates.";
00216 
00217         if (d < 0)
00218                 return -1;
00219         if (d >= MaxBasDim)
00220                 throw "Dimension too high.";
00221 
00222         // enhance the table of sets of points if necessary
00223         if (d > n)
00224         {
00225                 tPointset<coordtype> **newtable =
00226                         new tPointset<coordtype> * [d];
00227                 for (int i = 0; i < d; ++ i)
00228                         newtable [i] = (i < n) ? p [i] : NULL;
00229                 if (p)
00230                         delete [] p;
00231                 p = newtable;
00232                 n = d;
00233         }
00234 
00235         if (!p [d - 1])
00236         {
00237                 p [d - 1] = new tPointset<coordtype> (1024);
00238                 p [d - 1] -> dimension (d);
00239         }
00240 
00241         int_t number = p [d - 1] -> add (c);
00242         if (number > NumMask)
00243                 throw "Too many points.";
00244 
00245         return number;
00246 } /* tPointBase::number */
00247 
00248 template <class coordtype>
00249 inline void tPointBase<coordtype>::setwrapping (const coordtype *c,
00250         int mindim, int maxdim)
00251 {
00252         if (forgotten)
00253                 throw "Trying to wrap forgotten coordinates.";
00254 
00255         // correct the left and right bound for dimensions
00256         if (mindim < 1)
00257                 mindim = 1;
00258         if (maxdim > MaxBasDim)
00259                 maxdim = MaxBasDim;
00260 
00261         // enhance the table of sets of points if necessary
00262         if (maxdim > n)
00263         {
00264                 tPointset<coordtype> **newtable =
00265                         new tPointset<coordtype> * [maxdim];
00266                 for (int i = 0; i < maxdim; ++ i)
00267                         newtable [i] = (i < n) ? p [i] : NULL;
00268                 if (p)
00269                         delete [] p;
00270                 p = newtable;
00271                 n = maxdim;
00272         }
00273 
00274         // set wrapping coordinates and allocate sets of points if needed
00275         for (int d = mindim; d < maxdim; ++ d)
00276         {
00277                 if (!p [d - 1])
00278                 {
00279                         p [d - 1] = new tPointset<coordtype>;
00280                         p [d - 1] -> dimension (d);
00281                 }
00282                 p [d - 1] -> wrapspace (c);
00283         }
00284 
00285         return;
00286 } /* tPointBase::setwrapping */
00287 
00288 template <class coordtype>
00289 inline void tPointBase<coordtype>::setwrapping (coordtype c,
00290         int mindim, int maxdim)
00291 {
00292         coordtype wraptable [MaxBasDim];
00293         for (int i = 0; i < MaxBasDim; ++ i)
00294                 wraptable [i] = c;
00295         setwrapping (wraptable, mindim, maxdim);
00296         return;
00297 } /* tPointBase::setwrapping */
00298 
00299 template <class coordtype>
00300 inline const coordtype *tPointBase<coordtype>::getwrapping (int d)
00301 {
00302         if (forgotten)
00303                 throw "Trying to get wrapping of forgotten coordinates.";
00304 
00305         if ((d <= 0) || (d - 1 >= n) || !p [d - 1])
00306                 return NULL;
00307         else
00308                 return p [d - 1] -> wrapspace ();
00309 } /* tPointBase::getwrapping */
00310 
00311 template <class coordtype>
00312 inline void tPointBase<coordtype>::wrapcoord (coordtype *c, int dim)
00313 {
00314         if ((dim > n) || (dim <= 0) || (p [dim - 1] == NULL))
00315                 return;
00316         const coordtype *cw = p [dim - 1] -> wrapspace ();
00317         if (cw)
00318                 chomp::homology::wrapcoord (c, c, cw, dim);
00319         return;
00320 } /* tPointBase::wrapcoord */
00321 
00322 template <class coordtype>
00323 inline void tPointBase<coordtype>::wrapcopy (coordtype *dest,
00324         const coordtype *src, int dim)
00325 {
00326         const coordtype *cw;
00327         if ((dim > n) || (dim <= 0) || (p [dim - 1] == 0))
00328                 cw = 0;
00329         else
00330                 cw = p [dim - 1] -> wrapspace ();
00331         if (cw)
00332                 chomp::homology::wrapcoord (dest, src, cw, dim);
00333         else
00334                 copycoord (dest, src, dim);
00335         return;
00336 } /* tPointBase::wrapcopy */
00337 
00338 template <class coordtype>
00339 inline void tPointBase<coordtype>::reset (void)
00340 {
00341         for (int i = 0; i < n; ++ i)
00342         {
00343                 if (p [i])
00344                 {
00345                         delete p [i];
00346                         p [i] = NULL;
00347                 }
00348         }
00349         delete [] p;
00350         p = NULL;
00351         n = 0;
00352         forgotten = false;
00353         return;
00354 } /* tPointBase::reset */
00355 
00356 template <class coordtype>
00357 inline void tPointBase<coordtype>::forget (void)
00358 {
00359         if (forgotten)
00360                 throw "Trying to forget already forgotten coordinates.";
00361 
00362         reset ();
00363         forgotten = true;
00364         return;
00365 } /* tPointBase::forget */
00366 
00367 // --------------------------------------------------
00368 
00369 template <class coordtype>
00370 tPointset<coordtype> **tPointBase<coordtype>::p = NULL;
00371 
00372 template <class coordtype>
00373 int tPointBase<coordtype>::n = 0;
00374 
00375 template <class coordtype>
00376 bool tPointBase<coordtype>::show = true;
00377 
00378 template <class coordtype>
00379 bool tPointBase<coordtype>::forgotten = false;
00380 
00381 template <class coordtype>
00382 int tPointBase<coordtype>::defaultdimension (void)
00383 {
00384         static int dim = 0;
00385         if (dim)
00386                 return dim;
00387         for (int d = 1; d <= n; ++ d)
00388         {
00389                 if (!p [d - 1])
00390                         continue;
00391                 if (p [d - 1] -> empty ())
00392                         continue;
00393                 return d;
00394         }
00395         return 0;
00396 } /* tPointBase::defaultdimension */
00397 
00398 template <class coordtype>
00399 outputstream &tPointBase<coordtype>::showused (outputstream &out)
00400 {
00401         if (forgotten)
00402                 throw "Trying to show forgotten coordinates.";
00403 
00404         bool shown = false;
00405         for (int i = 0; i < n; ++ i)
00406         {
00407                 if (!p [i])
00408                         continue;
00409                 const tPointset<coordtype> &pset = *(p [i]);
00410                 if (pset. empty ())
00411                         continue;
00412                 out << (shown ? ", " : "Vertices used: ") <<
00413                         pset. size () << " of dim " << (i + 1);
00414                 shown = true;
00415         }
00416         if (shown)
00417                 out << ".\n";
00418         return out;
00419 } /* tPointBase::showused */
00420 
00421 template <class coordtype>
00422 std::ostream &tPointBase<coordtype>::showused (std::ostream &out)
00423 {
00424         outputstream tout (out);
00425         showused (tout);
00426         return out;
00427 } /* tPointBase::showused */
00428 
00429 
00430 // --------------------------------------------------
00431 // ------------- Point Base Initializer -------------
00432 // --------------------------------------------------
00433 
00437 template <class coordtype>
00438 class tPointBaseInitializer
00439 {
00440 public:
00444         ~tPointBaseInitializer ();
00445 
00446 }; /* PointBaseInitializer */
00447 
00448 template <class coordtype>
00449 tPointBaseInitializer<coordtype> tPointBase<coordtype>::pointBaseInitializer;
00450 
00451 template <class coordtype>
00452 tPointBaseInitializer<coordtype>::~tPointBaseInitializer<coordtype> ()
00453 {
00454         if (tPointBase<coordtype>::forgotten)
00455                 return;
00456         if (tPointBase<coordtype>::show && tPointBase<coordtype>::n)
00457                 tPointBase<coordtype>::showused (sout);
00458         tPointBase<coordtype>::forget ();
00459         return;
00460 } /* PointBaseInitializer::~PointBaseInitializer */
00461 
00462 
00463 // --------------------------------------------------
00464 // ------------------- Wrap Base --------------------
00465 // --------------------------------------------------
00466 
00469 template <class coordtype>
00470 class tWrapBase: public tPointBase<coordtype>
00471 {
00472 public:
00474         static int_t number (const coordtype *, int)
00475                 {throw "Trying to get a point number.";}
00476 
00478         static bool check (const coordtype *, int)
00479                 {return true;}
00480 
00482         static const coordtype *coord (int_t, int)
00483                 {throw "Trying to get the coordinates of a point.";}
00484 
00485         static void quiet (bool = true) {return;}
00486 
00487         static void reset (void) {return;}
00488 
00489         static void forget (void) {return;}
00490 
00491         static outputstream &showused (outputstream &out) {return out;}
00492 
00493         static std::ostream &showused (std::ostream &out) {return out;}
00494 
00495 }; /* class tWrapBase */
00496 
00497 // --------------------------------------------------
00498 
00499 
00500 } // namespace homology
00501 } // namespace chomp
00502 
00503 #endif // _CHOMP_CUBES_POINTBAS_H_
00504 
00506