Go to the documentation of this file.00001
00002
00003
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
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
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
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
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 };
00132
00133
00134
00135 inline Simplex::Simplex ()
00136 {
00137 tab = NULL;
00138 return;
00139 }
00140
00141 inline Simplex::~Simplex ()
00142 {
00143 if (tab)
00144 delete [] tab;
00145 return;
00146 }
00147
00148 inline const char *simplex::name ()
00149 {
00150 return "simplex";
00151 }
00152
00153 inline const char *simplex::pluralname ()
00154 {
00155 return "simplices";
00156 }
00157
00158 inline int Simplex::dim () const
00159 {
00160 if (!tab)
00161 return -1;
00162 else
00163 return (*tab);
00164 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
00312
00314 inline int operator != (const Simplex &s, const Simplex &t)
00315 {
00316 return !(s == t);
00317 }
00318
00319
00320
00322 inline int boundarylength (const Simplex &s)
00323 {
00324 int d = s. dim ();
00325 return (d ? (d + 1) : 0);
00326 }
00327
00329 inline int boundarycoef (const Simplex &, int i)
00330 {
00331 if (i & 1)
00332 return -1;
00333 else
00334 return 1;
00335 }
00336
00338 inline Simplex boundarycell (const Simplex &s, int i)
00339 {
00340 return Simplex (s, i);
00341 }
00342
00344 inline Simplex boundarycell (const Simplex &s, int i, bool)
00345 {
00346 return boundarycell (s, i);
00347 }
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 }
00365
00368 inline std::istream &operator >> (std::istream &in, Simplex &s)
00369 {
00370
00371 ignorecomments (in);
00372 int closing = closingparenthesis (in. peek ());
00373 if (closing == EOF)
00374 throw "Cannot read a simplex: No opening parenthesis.";
00375
00376
00377 in. get ();
00378 ignorecomments (in);
00379
00380
00381 int v [Simplex::MaxDim];
00382 int dim = -1;
00383 while (in && (in. peek () != closing))
00384 {
00385
00386 in >> v [++ dim];
00387 if (!in)
00388 throw "Unable to read a vertex of a simplex.";
00389
00390
00391 ignorecomments (in);
00392 if (in. peek () == ',')
00393 {
00394 in. get ();
00395 ignorecomments (in);
00396 }
00397
00398
00399 if (dim >= Simplex::MaxDim)
00400 throw "Too many vertices of a simplex.";
00401 }
00402
00403
00404 if (sortelements (v, dim + 1) != dim + 1)
00405 throw "A repeated vertex in a simplex detected.";
00406
00407
00408 in. get ();
00409 s = Simplex (v, dim);
00410
00411 return in;
00412 }
00413
00414
00415 }
00416 }
00417
00418 #endif // _CHOMP_SIMPLICES_SIMPLEX_H_
00419
00421