• Main Page
  • Classes
  • Files
  • File List
  • File Members

chaincon/simplex.h

Go to the documentation of this file.
00001 /////////////////////////////////////////////////////////////////////////////
00002 ///
00003 /// \file
00004 ///
00005 /// A simplex class with arbitrary vertices.
00006 ///
00007 /////////////////////////////////////////////////////////////////////////////
00008 
00009 // Copyright (C) 2009-2011 by Pawel Pilarczyk.
00010 //
00011 // This file is part of my research software package. This is free software:
00012 // you can redistribute it and/or modify it under the terms of the GNU
00013 // General Public License as published by the Free Software Foundation,
00014 // either version 3 of the License, or (at your option) any later version.
00015 //
00016 // This software is distributed in the hope that it will be useful,
00017 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00019 // GNU General Public License for more details.
00020 //
00021 // You should have received a copy of the GNU General Public License
00022 // along with this software; see the file "license.txt". If not,
00023 // please, see <http://www.gnu.org/licenses/>.
00024 
00025 // Started on March 24, 2009. Last revision: March 4, 2011.
00026 
00027 
00028 #ifndef _CHAINCON_SIMPLEX_H_
00029 #define _CHAINCON_SIMPLEX_H_
00030 
00031 
00032 // include some standard C++ header files
00033 #include <istream>
00034 #include <ostream>
00035 #include <algorithm>
00036 #include <vector>
00037 
00038 // include selected header files from the CHomP library
00039 #include "chomp/system/config.h"
00040 
00041 // include relevant local header files
00042 #include "chaincon/emptycell.h"
00043 
00044 
00045 // --------------------------------------------------
00046 // --------------------- simplex --------------------
00047 // --------------------------------------------------
00048 
00049 /// A simplex with vertices of arbitrary type.
00050 template <class VertexT>
00051 class tSimplex
00052 {
00053 public:
00054         /// The type of the vertex.
00055         typedef VertexT VertexType;
00056 
00057         /// The default constructor of an empty simplex.
00058         tSimplex ();
00059 
00060         /// The constructor of a simplex from an array of vertices.
00061         template <class VertexArray>
00062         tSimplex (int dimension, const VertexArray &vertices);
00063 
00064         /// The copy constructor.
00065         tSimplex (const tSimplex<VertexT> &s);
00066 
00067         /// The constructor of the n-th boundary simplex.
00068         tSimplex (const tSimplex<VertexT> &s, int n);
00069 
00070         /// The assignment operator.
00071         tSimplex<VertexT> &operator = (const tSimplex<VertexT> &s);
00072 
00073         /// The destructor.
00074         ~tSimplex ();
00075 
00076         /// Returns the dimension of the simplex.
00077         int dim () const;
00078 
00079         /// Returns the n-th vertex of the simplex.
00080         const VertexT &operator [] (int n) const;
00081 
00082         /// Returns the length of the boundary of the simplex.
00083         int boundaryLength () const;
00084 
00085         /// Returns the n-th coefficient in the boundary of the simplex.
00086         int boundaryCoef (int n) const;
00087 
00088         /// The equality operator.
00089         bool operator == (const tSimplex<VertexT> &s) const;
00090 
00091         /// Swaps the data between two simplices.
00092         void swap (tSimplex<VertexT> &s);
00093 
00094 private:
00095         /// The dimension of the simplex.
00096         int dimension;
00097 
00098         /// An array of vertices of the simplex.
00099         VertexT *vertices;
00100 }; /* class tSimplex */
00101 
00102 // --------------------------------------------------
00103 
00104 template <class VertexT>
00105 inline tSimplex<VertexT>::tSimplex ():
00106         dimension (-1), vertices (0)
00107 {
00108         return;
00109 } /* tSimplex::tSimplex */
00110 
00111 template <class VertexT>
00112 template <class VertexArray>
00113 inline tSimplex<VertexT>::tSimplex (int dimension,
00114         const VertexArray &vertices)
00115 {
00116         this -> dimension = (dimension >= 0) ? dimension : -1;
00117         this -> vertices = (dimension >= 0) ? new VertexT [dimension + 1] : 0;
00118         for (int i = 0; i <= dimension; ++ i)
00119                 this -> vertices [i] = vertices [i];
00120         return;
00121 } /* tSimplex::tSimplex */
00122 
00123 template <class VertexT>
00124 inline tSimplex<VertexT>::tSimplex (const tSimplex<VertexT> &s)
00125 {
00126         dimension = s. dimension;
00127         vertices = (dimension >= 0) ? new VertexT [dimension + 1] : 0;
00128         for (int i = 0; i <= dimension; ++ i)
00129                 vertices [i] = s. vertices [i];
00130         return;
00131 } /* tSimplex::tSimplex */
00132 
00133 template <class VertexT>
00134 inline tSimplex<VertexT>::tSimplex (const tSimplex<VertexT> &s, int n)
00135 {
00136         dimension = (s. dimension >= 0) ? (s. dimension - 1) : -1;
00137         vertices = (dimension >= 0) ? new VertexT [dimension + 1] : 0;
00138         for (int i = 0; i < n; ++ i)
00139                 vertices [i] = s. vertices [i];
00140         for (int i = n; i <= dimension; ++ i)
00141                 vertices [i] = s. vertices [i + 1];
00142         return;
00143 } /* tSimplex::tSimplex */
00144 
00145 template <class VertexT>
00146 inline tSimplex<VertexT> &tSimplex<VertexT>::operator =
00147         (const tSimplex<VertexT> &s)
00148 {
00149         if (dimension != s. dimension)
00150         {
00151                 if (vertices)
00152                         delete [] vertices;
00153                 dimension = s. dimension;
00154                 vertices = (dimension >= 0) ?
00155                         new VertexT [dimension + 1] : 0;
00156         }
00157         for (int i = 0; i <= dimension; ++ i)
00158                 this -> vertices [i] = s. vertices [i];
00159         return *this;
00160 } /* tSimplex::operator = */
00161 
00162 template <class VertexT>
00163 inline tSimplex<VertexT>::~tSimplex ()
00164 {
00165         if (vertices)
00166                 delete [] vertices;
00167         return;
00168 } /* tSimplex::~tSimplex */
00169 
00170 template <class VertexT>
00171 inline int tSimplex<VertexT>::dim () const
00172 {
00173         return dimension;
00174 } /* tSimplex::dim */
00175 
00176 template <class VertexT>
00177 inline const VertexT &tSimplex<VertexT>::operator [] (int n) const
00178 {
00179         return vertices [n];
00180 } /* tSimplex::operator [] */
00181 
00182 template <class VertexT>
00183 inline int tSimplex<VertexT>::boundaryLength () const
00184 {
00185 #ifdef NO_EMPTY_CELL
00186         return (dimension > 0) ? (dimension + 1) : 0;
00187 #else
00188         return dimension + 1;
00189 #endif
00190 } /* tSimplex::boundaryLength */
00191 
00192 template <class VertexT>
00193 inline int tSimplex<VertexT>::boundaryCoef (int n) const
00194 {
00195         return (n & 1) ? -1 : 1;
00196 } /* tSimplex::boundaryCoef */
00197 
00198 template <class VertexT>
00199 inline bool tSimplex<VertexT>::operator ==
00200         (const tSimplex<VertexT> &s) const
00201 {
00202         if (dimension != s. dimension)
00203                 return false;
00204         for (int i = 0; i <= dimension; ++ i)
00205         {
00206                 if (!(vertices [i] == s. vertices [i]))
00207                         return false;
00208         }
00209         return true;
00210 } /* tSimplex::operator == */
00211 
00212 template <class VertexT>
00213 inline void tSimplex<VertexT>::swap (tSimplex<VertexT> &s)
00214 {
00215         std::swap (dimension, s. dimension);
00216         std::swap (vertices, s. vertices);
00217         return;
00218 } /* tSimplex::swap */
00219 
00220 // --------------------------------------------------
00221 
00222 /// Generates a hashing key no. 1 for a simplex,
00223 /// composed of hashing keys for the vertices.
00224 /// This key is to be used in a hashed set.
00225 template <class VertexT>
00226 inline int_t hashkey1 (const tSimplex<VertexT> &s)
00227 {
00228         using chomp::homology::hashkey1;
00229         using ::hashkey1;
00230         int d = s. dim ();
00231         if (d < 0)
00232                 return 0;
00233         else if (d == 0)
00234                 return hashkey1 (s [0]) << 2;
00235         else if (d == 1)
00236         {
00237                 return ((hashkey1 (s [0]) & 0x655555u) << 11) ^
00238                         ((hashkey1 (s [1]) & 0xAA00AAu) >> 1);
00239         }
00240         else
00241         {
00242                 return ((hashkey1 (s [0]) & 0x655555u) << 15) ^
00243                         ((hashkey1 (s [d >> 1]) & 0xAA00AAu) << 1) ^
00244                         ((hashkey1 (s [d]) & 0xAAAAAAu) >> 7);
00245         }
00246 } /* hashkey1 */
00247 
00248 /// Generates a hashing key no. 2 for a simplex,
00249 /// composed of hashing keys for the vertices.
00250 /// This key is to be used in a hashed set.
00251 template <class VertexT>
00252 inline int_t hashkey2 (const tSimplex<VertexT> &s)
00253 {
00254         using chomp::homology::hashkey2;
00255         using ::hashkey2;
00256         int d = s. dim ();
00257         if (d < 0)
00258                 return 0;
00259         else if (d == 0)
00260                 return hashkey2 (s [0]) << 4;
00261         else if (d == 1)
00262         {
00263                 return ((hashkey2 (s [0]) & 0xAAAAAAu) >> 2) ^
00264                         ((hashkey2 (s [1]) & 0x555555u) << 8);
00265         }
00266         else
00267         {
00268                 return ((hashkey2 (s [d]) & 0x555555u) << 7) ^
00269                         ((hashkey2 (s [0]) & 0xAA00AAu) << 5) ^
00270                         ((hashkey2 (s [d >> 1]) & 0xAAAAu) >> 5);
00271         }
00272 } /* hashkey2 */
00273 
00274 // --------------------------------------------------
00275 
00276 /// Writes a simplex in the text mode to an output stream.
00277 /// All the vertices are written using their operator <<,
00278 /// and are enclosed in parentheses in a comma-separated list.
00279 template <class VertexT>
00280 std::ostream &operator << (std::ostream &out, const tSimplex<VertexT> &s)
00281 {
00282         int dim = s. dim ();
00283         out << "(";
00284         for (int i = 0; i <= dim; ++ i)
00285         {
00286                 if (i)
00287                         out << ',';
00288                 out << s [i];
00289         }
00290         out << ")";
00291         return out;
00292 } /* operator << */
00293 
00294 /// Reads a simplex from the input stream in the text format.
00295 /// Skips all the characters in the input stream until
00296 /// an opening parenthesis is found. Then reads the vertices
00297 /// of the simplex using their operator >> as a comma-separated list.
00298 /// The closing parenthesis indicates the end of the simplex definition.
00299 /// If the closing parenthesis is not found then an exception is thrown.
00300 /// If no simplex is found in the input then the simplex is not modified.
00301 template <class VertexT>
00302 std::istream &operator >> (std::istream &in, tSimplex<VertexT> &s)
00303 {
00304         // ignore any comments, spaces, tabs and new-line characters
00305         chomp::homology::ignorecomments (in);
00306 
00307         // read the opening parenthesis
00308         int ch = in. get ();
00309         if (ch != '(')
00310                 return in;
00311 
00312         // read a comma-separated list of vertices of the simplex
00313         std::vector<VertexT> vertices;
00314         ch = in. peek ();
00315         while ((ch != EOF) && (ch != ')'))
00316         {
00317                 VertexT vertex;
00318                 in >> vertex;
00319                 vertices. push_back (vertex);
00320                 while ((in. peek () == ' ') || (in. peek () == ','))
00321                         ch = in. get ();
00322                 if (in. peek () == ')')
00323                         ch = in. get ();
00324         }
00325         if (ch != ')')
00326                 throw "Simplex reading error: ')' expected.\n";
00327 
00328         // make sure that the vertices are in the ascending order
00329         for (unsigned i = 1; i < vertices. size (); ++ i)
00330         {
00331                 if (vertices [i - 1] >= vertices [i])
00332                         throw "Simplex reading error: wrong vertices.\n";
00333         }
00334 
00335         // define the simplex
00336         s = tSimplex<VertexT> (vertices. size () - 1, vertices);
00337 
00338         return in;
00339 } /* operator >> */
00340 
00341 
00342 #endif // _CHAINCON_SIMPLEX_H_
00343 

Generated on Tue Apr 5 2011 00:06:32 for Chain Contraction Software by  doxygen 1.7.2