simplex.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 on March 12, 2003. Last revision: May 24, 2010.
00035 
00036 
00037 #ifndef _CHOMP_SIMPLICES_SIMPLEX_H_
00038 #define _CHOMP_SIMPLICES_SIMPLEX_H_
00039 
00040 #include "chomp/system/config.h"
00041 #include "chomp/system/textfile.h"
00042 #include "chomp/struct/integer.h"
00043 #include "chomp/homology/gcomplex.h"
00044 
00045 #include <iostream>
00046 #include <fstream>
00047 #include <cstdlib>
00048 
00049 namespace chomp {
00050 namespace homology {
00051 
00052 
00053 // classes defined within this header file (in this order)
00054 class Simplex;
00055 
00057 typedef gcomplex<Simplex,integer> SimplicialComplex;
00058 
00060 typedef hashedset<Simplex> SetOfSimplices;
00061 
00063 typedef Simplex simplex;
00064 
00066 typedef gcomplex<simplex,integer> simplicialcomplex;
00067 
00069 typedef hashedset<simplex> simplices;
00070 
00071 
00072 // --------------------------------------------------
00073 // -------------------- Simplex ---------------------
00074 // --------------------------------------------------
00075 
00078 class Simplex
00079 {
00080 public:
00083         static const int MaxDim = 2048;
00084 
00086         Simplex ();
00087 
00089         Simplex (const int *v, int dim);
00090 
00092         Simplex (const Simplex &s, int n);
00093 
00095         ~Simplex ();
00096 
00098         Simplex (const Simplex &s);
00099 
00101         Simplex &operator = (const Simplex &s);
00102 
00105         int dim () const;
00106 
00108         void vertices (int *table) const;
00109 
00111         int_t hashkey1 () const;
00112 
00114         int_t hashkey2 () const;
00115 
00117         static const char *name ();
00118 
00120         static const char *pluralname ();
00121 
00122         // friends
00123         friend int operator == (const Simplex &s, const Simplex &t);
00124         friend std::ostream &operator << (std::ostream &out, const Simplex &s);
00125 
00126 private:
00129         int *tab;
00130 
00131 }; /* class Simplex */
00132 
00133 // --------------------------------------------------
00134 
00135 inline Simplex::Simplex ()
00136 {
00137         tab = NULL;
00138         return;
00139 } /* Simplex::Simplex */
00140 
00141 inline Simplex::~Simplex ()
00142 {
00143         if (tab)
00144                 delete [] tab;
00145         return;
00146 } /* Simplex::~Simplex */
00147 
00148 inline const char *simplex::name ()
00149 {
00150         return "simplex";
00151 } /* simplex::name */
00152 
00153 inline const char *simplex::pluralname ()
00154 {
00155         return "simplices";
00156 } /* simplex::pluralname */
00157 
00158 inline int Simplex::dim () const
00159 {
00160         if (!tab)
00161                 return -1;
00162         else
00163                 return (*tab);
00164 } /* Simplex::dim */
00165 
00166 inline void Simplex::vertices (int *table) const
00167 {
00168         int d = dim ();
00169         for (int i = 0; i <= d; ++ i)
00170                 table [i] = tab [i + 1];
00171         return;
00172 } /* Simplex::dim */
00173 
00174 inline Simplex::Simplex (const int *v, int d)
00175 {
00176         if (d < 0)
00177                 throw "Negative dimension of a simplex.";
00178         tab = new int [d + 2];
00179         if (!tab)
00180                 throw "Not enough memory for a simplex.";
00181         tab [0] = d;
00182         for (int i = 0; i <= d; ++ i)
00183                 tab [i + 1] = v [i];
00184         return;
00185 } /* Simplex::Simplex */
00186 
00187 inline Simplex::Simplex (const Simplex &s, int n)
00188 {
00189         int d = s. dim () - 1;
00190         if (d < 0)
00191                 throw "Undefined boundary simplex.";
00192         tab = new int [d + 2];
00193         if (!tab)
00194                 throw "Not enough memory for a boundary simplex.";
00195         tab [0] = d;
00196         int i;
00197         for (i = 1; i <= n; ++ i)
00198                 tab [i] = s. tab [i];
00199         for (i = n + 1; i < d + 2; ++ i)
00200                 tab [i] = s. tab [i + 1];
00201         return;
00202 } /* Simplex::Simplex */
00203 
00204 inline Simplex::Simplex (const Simplex &s)
00205 {
00206         int d = s. dim ();
00207         if (d < 0)
00208                 tab = NULL;
00209         else
00210         {
00211                 tab = new int [d + 2];
00212                 if (!tab)
00213                         throw "Not enough memory to copy a simplex.";
00214                 for (int i = 0; i < d + 2; ++ i)
00215                         tab [i] = s. tab [i];
00216         }
00217         return;
00218 } /* Simplex::Simplex */
00219 
00220 inline Simplex &Simplex::operator = (const Simplex &s)
00221 {
00222         int d = s. dim ();
00223         if (d < 0)
00224         {
00225                 if (tab)
00226                         delete [] tab;
00227                 tab = NULL;
00228         }
00229         else if (d == dim ())
00230         {
00231                 for (int i = 0; i < d + 2; ++ i)
00232                         tab [i] = s. tab [i];
00233         }
00234         else
00235         {
00236                 if (tab)
00237                         delete [] tab;
00238                 tab = new int [d + 2];
00239                 if (!tab)
00240                         throw "Not enough memory to assign a simplex.";
00241                 for (int i = 0; i < d + 2; ++ i)
00242                         tab [i] = s. tab [i];
00243         }
00244         return *this;
00245 } /* Simplex::operator = */
00246 
00247 inline int_t Simplex::hashkey1 () const
00248 {
00249         int d = dim ();
00250         if (d < 0)
00251                 return 0;
00252         else if (d == 0)
00253                 return static_cast<int_t> (tab [1]) << 2;
00254         else if (d == 1)
00255         {
00256                 return ((static_cast<int_t> (tab [1])
00257                         ^ 0x55555555u) << 16) ^
00258                         ((static_cast<int_t> (tab [2])
00259                         ^ 0xAAAA00AAu) << 4);
00260         }
00261         else
00262         {
00263                 return ((static_cast<int_t> (tab [1]) ^
00264                         0x55555555u) << 16) ^
00265                         ((static_cast<int_t> (tab [2]) ^
00266                         0xAA00AAAAu) << 4) ^
00267                         ((static_cast<int_t> (tab [3]) ^
00268                         0xAA55AA55u) >> 6);
00269         }
00270 } /* Simplex::hashkey1 */
00271 
00272 inline int_t Simplex::hashkey2 () const
00273 {
00274         int d = dim ();
00275         if (d < 0)
00276                 return 0;
00277         else if (d == 0)
00278                 return static_cast<int_t> (tab [1]) << 2;
00279         else if (d == 1)
00280         {
00281                 return ((static_cast<int_t> (tab [1]) ^
00282                         0xAAAAAAAAu) >> 1) ^
00283                         ((static_cast<int_t> (tab [2]) ^
00284                         0x55555555u) << 13);
00285         }
00286         else
00287         {
00288                 return ((static_cast<int_t> (tab [d + 1]) ^
00289                         0x55555555u) << 13) ^
00290                         ((static_cast<int_t> (tab [d]) ^
00291                         0xAA00AA00u) >> 1) ^
00292                         ((static_cast<int_t> (tab [d - 1]) ^
00293                         0xAA0055AAu) << 7);
00294         }
00295 } /* Simplex::hashkey2 */
00296 
00297 // --------------------------------------------------
00298 
00301 inline int operator == (const Simplex &s, const Simplex &t)
00302 {
00303         int sd = s. dim ();
00304         int td = t. dim ();
00305         if (sd != td)
00306                 return 0;
00307         for (int i = 1; i < sd + 2; ++ i)
00308                 if (s. tab [i] != t. tab [i])
00309                         return 0;
00310         return 1;
00311 } /* operator == */
00312 
00314 inline int operator != (const Simplex &s, const Simplex &t)
00315 {
00316         return !(s == t);
00317 } /* operator != */
00318 
00319 // --------------------------------------------------
00320 
00322 inline int boundarylength (const Simplex &s)
00323 {
00324         int d = s. dim ();
00325         return (d ? (d + 1) : 0);
00326 } /* boundarylength */
00327 
00329 inline int boundarycoef (const Simplex &, int i)
00330 {
00331         if (i & 1)
00332                 return -1;
00333         else
00334                 return 1;
00335 } /* boundarycoef */
00336 
00338 inline Simplex boundarycell (const Simplex &s, int i)
00339 {
00340         return Simplex (s, i);
00341 } /* boundarycell */
00342 
00344 inline Simplex boundarycell (const Simplex &s, int i, bool)
00345 {
00346         return boundarycell (s, i);
00347 } /* boundarycell */
00348 
00349 // --------------------------------------------------
00350 
00352 inline std::ostream &operator << (std::ostream &out, const Simplex &s)
00353 {
00354         out << '(';
00355         if (s. tab)
00356         {
00357                 int d = s. dim ();
00358                 out << s. tab [1];
00359                 for (int i = 2; i < d + 2; ++ i)
00360                         out << ',' << s. tab [i];
00361         }
00362         out << ')';
00363         return out;
00364 } /* operator << */
00365 
00368 inline std::istream &operator >> (std::istream &in, Simplex &s)
00369 {
00370         // check if an opening parenthesis is waiting at the input
00371         ignorecomments (in);
00372         int closing = closingparenthesis (in. peek ());
00373         if (closing == EOF)
00374                 throw "Cannot read a simplex: No opening parenthesis.";
00375 
00376         // read the opening parenthesis
00377         in. get ();
00378         ignorecomments (in);
00379 
00380         // read the vertices of the simplex
00381         int v [Simplex::MaxDim];
00382         int dim = -1;
00383         while (in && (in. peek () != closing))
00384         {
00385                 // read the vertex
00386                 in >> v [++ dim];
00387                 if (!in)
00388                         throw "Unable to read a vertex of a simplex.";
00389 
00390                 // read the separating comma if any
00391                 ignorecomments (in);
00392                 if (in. peek () == ',')
00393                 {
00394                         in. get ();
00395                         ignorecomments (in);
00396                 }
00397 
00398                 // if there are too many vertices...
00399                 if (dim >= Simplex::MaxDim)
00400                         throw "Too many vertices of a simplex.";
00401         }
00402 
00403         // sort the numbers of the vertices of the simplex
00404         if (sortelements (v, dim + 1) != dim + 1)
00405                 throw "A repeated vertex in a simplex detected.";
00406 
00407         // read the closing parenthesis and define the simplex
00408         in. get ();
00409         s = Simplex (v, dim);
00410 
00411         return in;
00412 } /* operator >> */
00413 
00414 
00415 } // namespace homology
00416 } // namespace chomp
00417 
00418 #endif // _CHOMP_SIMPLICES_SIMPLEX_H_
00419 
00421