Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef _CHAINCON_SIMPLEX_H_
00029 #define _CHAINCON_SIMPLEX_H_
00030
00031
00032
00033 #include <istream>
00034 #include <ostream>
00035 #include <algorithm>
00036 #include <vector>
00037
00038
00039 #include "chomp/system/config.h"
00040
00041
00042 #include "chaincon/emptycell.h"
00043
00044
00045
00046
00047
00048
00049
00050 template <class VertexT>
00051 class tSimplex
00052 {
00053 public:
00054
00055 typedef VertexT VertexType;
00056
00057
00058 tSimplex ();
00059
00060
00061 template <class VertexArray>
00062 tSimplex (int dimension, const VertexArray &vertices);
00063
00064
00065 tSimplex (const tSimplex<VertexT> &s);
00066
00067
00068 tSimplex (const tSimplex<VertexT> &s, int n);
00069
00070
00071 tSimplex<VertexT> &operator = (const tSimplex<VertexT> &s);
00072
00073
00074 ~tSimplex ();
00075
00076
00077 int dim () const;
00078
00079
00080 const VertexT &operator [] (int n) const;
00081
00082
00083 int boundaryLength () const;
00084
00085
00086 int boundaryCoef (int n) const;
00087
00088
00089 bool operator == (const tSimplex<VertexT> &s) const;
00090
00091
00092 void swap (tSimplex<VertexT> &s);
00093
00094 private:
00095
00096 int dimension;
00097
00098
00099 VertexT *vertices;
00100 };
00101
00102
00103
00104 template <class VertexT>
00105 inline tSimplex<VertexT>::tSimplex ():
00106 dimension (-1), vertices (0)
00107 {
00108 return;
00109 }
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 }
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 }
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 }
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 }
00161
00162 template <class VertexT>
00163 inline tSimplex<VertexT>::~tSimplex ()
00164 {
00165 if (vertices)
00166 delete [] vertices;
00167 return;
00168 }
00169
00170 template <class VertexT>
00171 inline int tSimplex<VertexT>::dim () const
00172 {
00173 return dimension;
00174 }
00175
00176 template <class VertexT>
00177 inline const VertexT &tSimplex<VertexT>::operator [] (int n) const
00178 {
00179 return vertices [n];
00180 }
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 }
00191
00192 template <class VertexT>
00193 inline int tSimplex<VertexT>::boundaryCoef (int n) const
00194 {
00195 return (n & 1) ? -1 : 1;
00196 }
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 }
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 }
00219
00220
00221
00222
00223
00224
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 }
00247
00248
00249
00250
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 }
00273
00274
00275
00276
00277
00278
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 }
00293
00294
00295
00296
00297
00298
00299
00300
00301 template <class VertexT>
00302 std::istream &operator >> (std::istream &in, tSimplex<VertexT> &s)
00303 {
00304
00305 chomp::homology::ignorecomments (in);
00306
00307
00308 int ch = in. get ();
00309 if (ch != '(')
00310 return in;
00311
00312
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
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
00336 s = tSimplex<VertexT> (vertices. size () - 1, vertices);
00337
00338 return in;
00339 }
00340
00341
00342 #endif // _CHAINCON_SIMPLEX_H_
00343