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_CUBES_CELLMAIN_H_
00038 #define _CHOMP_CUBES_CELLMAIN_H_
00039
00040 #include "chomp/system/config.h"
00041 #include "chomp/system/textfile.h"
00042 #include "chomp/cubes/pointset.h"
00043 #include "chomp/homology/chains.h"
00044 #include "chomp/struct/bitfield.h"
00045 #include "chomp/struct/integer.h"
00046 #include "chomp/struct/hashsets.h"
00047 #include "chomp/homology/gcomplex.h"
00048 #include "chomp/cubes/pointbas.h"
00049
00050 #include <iostream>
00051 #include <fstream>
00052 #include <cstdlib>
00053
00054 namespace chomp {
00055 namespace homology {
00056
00057
00058
00059
00060
00061
00072 template <class celltype>
00073 inline celltype CubicalBoundaryCell (const celltype &q, int i,
00074 bool onlyexisting)
00075 {
00076 typedef typename celltype::CoordType coordtype;
00077 coordtype origleft [celltype::MaxDim];
00078 q. leftcoord (origleft);
00079 coordtype origright [celltype::MaxDim];
00080 q. rightcoord (origright);
00081 coordtype newcoord [celltype::MaxDim];
00082 int sd = q. spacedim ();
00083 int d = q. dim ();
00084 int count = 0;
00085
00086
00087 if (i < d)
00088 {
00089 for (int j = 0; j < sd; ++ j)
00090 {
00091
00092 newcoord [j] = origleft [j];
00093
00094
00095 if (origleft [j] != origright [j])
00096 {
00097 if (i == count ++)
00098 {
00099 newcoord [j] = origright [j];
00100 for (j = j + 1; j < sd; ++ j)
00101 newcoord [j] = origleft [j];
00102 if (onlyexisting &&
00103 !celltype::PointBase::check
00104 (newcoord, sd))
00105 return q;
00106 return celltype (newcoord,
00107 origright, sd);
00108 }
00109 }
00110 }
00111 throw "False cubical cell's dimension.";
00112 }
00113 else
00114 {
00115 i -= d;
00116 for (int j = 0; j < sd; ++ j)
00117 {
00118
00119 newcoord [j] = origright [j];
00120
00121
00122 if (origleft [j] != origright [j])
00123 {
00124 if (i == count ++)
00125 {
00126 newcoord [j] = origleft [j];
00127 for (j = j + 1; j < sd; j ++)
00128 newcoord [j] = origright [j];
00129 if (onlyexisting &&
00130 !celltype::PointBase::check
00131 (newcoord, sd))
00132 return q;
00133 return celltype (origleft,
00134 newcoord, sd);
00135 }
00136 }
00137 }
00138 throw "False dimension of a cubical cell.";
00139 }
00140 }
00141
00143 template <class celltype>
00144 inline celltype CubicalBoundaryCell (const celltype &q, int i)
00145 {
00146 return CubicalBoundaryCell (q, i, false);
00147 }
00148
00150 template <class celltype>
00151 inline int CubicalBoundaryLength (const celltype &q)
00152 {
00153 return q. dim () << 1;
00154 }
00155
00157 template <class celltype>
00158 inline int CubicalBoundaryCoef (const celltype &q, int i)
00159 {
00160 int d = q. dim ();
00161 if (i >= d)
00162 i -= d - 1;
00163 return (i & 1) ? 1 : -1;
00164 }
00165
00166
00167
00168
00169
00170
00173 template <class celltype>
00174 inline std::ostream &WriteCubicalCell (std::ostream &out, const celltype &c)
00175 {
00176
00177 typedef typename celltype::CoordType coordtype;
00178 coordtype lcoord [celltype::MaxDim];
00179 c. leftcoord (lcoord);
00180 int dim = c. spacedim ();
00181 coordtype rcoord [celltype::MaxDim];
00182 c. rightcoord (rcoord);
00183
00184 if (celltype::OutputBits & celltype::BitProduct)
00185 {
00186 for (int i = 0; i < dim; ++ i)
00187 {
00188 out << '(';
00189 out << lcoord [i];
00190 if (rcoord [i] != lcoord [i])
00191 out << ',' << rcoord [i];
00192 out << ')';
00193 if (i < dim - 1)
00194 out << 'x';
00195 }
00196 }
00197 else
00198 {
00199 out << '[' << '(';
00200 int i;
00201 for (i = 0; i < dim; ++ i)
00202 {
00203 out << lcoord [i];
00204 if (i < dim - 1)
00205 out << ',';
00206 }
00207 out << ')';
00208 if (celltype::OutputBits & celltype::BitSpace)
00209 out << ' ';
00210 out << '(';
00211 for (i = 0; i < dim; ++ i)
00212 {
00213 out << rcoord [i];
00214 if (i < dim - 1)
00215 out << ',';
00216 }
00217 out << ')' << ']';
00218 }
00219 return out;
00220 }
00221
00235 template <class celltype>
00236 inline std::istream &ReadCubicalCell (std::istream &in, celltype &c)
00237 {
00238 typedef typename celltype::CoordType coordtype;
00239
00240 ignorecomments (in);
00241 int closing = closingparenthesis (in. peek ());
00242 if (closing == EOF)
00243 throw "Opening parenthesis expected while reading a cell.";
00244
00245
00246 in. get ();
00247 ignorecomments (in);
00248
00249
00250 coordtype c1 [celltype::MaxDim], c2 [celltype::MaxDim];
00251
00252
00253 if (closingparenthesis (in. peek ()) != EOF)
00254 {
00255
00256 int dim1 = readcoordinates (in, c1, celltype::MaxDim);
00257 ignorecomments (in);
00258 if (in. peek () == ',')
00259 {
00260 in. get ();
00261 ignorecomments (in);
00262 }
00263 int dim2 = readcoordinates (in, c2, celltype::MaxDim);
00264
00265
00266 ignorecomments (in);
00267 if ((in. get () != closing) || (dim1 <= 0) || (dim1 != dim2))
00268 throw "Failed while reading two vertices of a cell.";
00269
00270
00271 for (int i = 0; i < dim1; ++ i)
00272 {
00273 if ((c1 [i] != c2 [i]) && (c1 [i] + 1 != c2 [i]))
00274 throw "Vertices of a read cell are too far.";
00275 }
00276
00277
00278 c = celltype (c1, c2, dim1);
00279 return in;
00280 }
00281
00282
00283 coordtype c0 [celltype::MaxDim];
00284 int count = readcoordinates (in, c0, celltype::MaxDim, closing);
00285 if (count <= 0)
00286 throw "Can't read a cell.";
00287 ignorecomments (in);
00288
00289
00290 if ((count == 1) || (count == 2))
00291 {
00292 int dim = 0;
00293 c1 [dim] = c0 [0];
00294 c2 [dim ++] = c0 [count - 1];
00295 while ((in. peek () == 'x') || (in. peek () == 'X'))
00296 {
00297 in. get ();
00298 ignorecomments (in);
00299 count = readcoordinates (in, c0, celltype::MaxDim);
00300 ignorecomments (in);
00301 if ((count < 1) || (count > 2) ||
00302 (dim >= celltype::MaxDim))
00303 throw "Wrong interval while reading a cell.";
00304 if ((count == 2) && (c0 [1] != c0 [0]) &&
00305 (c0 [1] - c0 [0] != 1))
00306 throw "Too big interval defining a cell.";
00307 c1 [dim] = c0 [0];
00308 c2 [dim ++] = c0 [count - 1];
00309 }
00310 c = celltype (c1, c2, dim);
00311 return in;
00312 }
00313
00314
00315 for (int i = 0; i < count; ++ i)
00316 c1 [i] = c0 [i] + 1;
00317 c = celltype (c0, c1, count);
00318 return in;
00319 }
00320
00321
00322
00323
00324
00325
00328 template<class coordtype>
00329 inline int CommonCell (coordtype *left, coordtype *right,
00330 const coordtype *c1, const coordtype *c2, int spcdim,
00331 const coordtype *wrap = 0)
00332 {
00333
00334
00335 int celldim = 0;
00336 for (int i = 0; i < spcdim; ++ i)
00337 {
00338 if (c1 [i] == c2 [i])
00339 {
00340 left [i] = c1 [i];
00341 right [i] = c1 [i];
00342 ++ (right [i]);
00343 ++ celldim;
00344 }
00345 else if ((c1 [i] - c2 [i] == -1) || (wrap && wrap [i] &&
00346 (c1 [i] - c2 [i] == wrap [i] - 1)))
00347 {
00348 left [i] = c2 [i];
00349 right [i] = c2 [i];
00350 }
00351 else if ((c1 [i] - c2 [i] == 1) || (wrap && wrap [i] &&
00352 (c1 [i] - c2 [i] == -wrap [i] + 1)))
00353 {
00354 left [i] = c1 [i];
00355 right [i] = c1 [i];
00356 }
00357 else
00358 throw "The cubes do not intersect.";
00359 }
00360
00361 return celldim;
00362 }
00363
00364
00365 }
00366 }
00367
00368 #endif // _CHOMP_CUBES_CELLMAIN_H_
00369
00371