The Original CHomP Software
cellmain.h
Go to the documentation of this file.
1
3
16
17// Copyright (C) 1997-2020 by Pawel Pilarczyk.
18//
19// This file is part of my research software package. This is free software:
20// you can redistribute it and/or modify it under the terms of the GNU
21// General Public License as published by the Free Software Foundation,
22// either version 3 of the License, or (at your option) any later version.
23//
24// This software is distributed in the hope that it will be useful,
25// but WITHOUT ANY WARRANTY; without even the implied warranty of
26// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27// GNU General Public License for more details.
28//
29// You should have received a copy of the GNU General Public License
30// along with this software; see the file "license.txt". If not,
31// please, see <https://www.gnu.org/licenses/>.
32
33// Started in January 2002. Last revision: July 15, 2007.
34
35
36#ifndef _CHOMP_CUBES_CELLMAIN_H_
37#define _CHOMP_CUBES_CELLMAIN_H_
38
39#include "chomp/system/config.h"
48
49#include <iostream>
50#include <fstream>
51#include <cstdlib>
52
53namespace chomp {
54namespace homology {
55
56
57// --------------------------------------------------
58// ------------- CUBICAL CELL BOUNDARY --------------
59// --------------------------------------------------
60
71template <class celltype>
72inline celltype CubicalBoundaryCell (const celltype &q, int i,
73 bool onlyexisting)
74{
75 typedef typename celltype::CoordType coordtype;
76 coordtype origleft [celltype::MaxDim];
77 q. leftcoord (origleft);
78 coordtype origright [celltype::MaxDim];
79 q. rightcoord (origright);
80 coordtype newcoord [celltype::MaxDim];
81 int sd = q. spacedim ();
82 int d = q. dim ();
83 int count = 0;
84
85 // if this is the first set of cells
86 if (i < d)
87 {
88 for (int j = 0; j < sd; ++ j)
89 {
90 // copy the coordinates of the right vertex
91 newcoord [j] = origleft [j];
92
93 // modify the desired coordinate and finalize
94 if (origleft [j] != origright [j])
95 {
96 if (i == count ++)
97 {
98 newcoord [j] = origright [j];
99 for (j = j + 1; j < sd; ++ j)
100 newcoord [j] = origleft [j];
101 if (onlyexisting &&
102 !celltype::PointBase::check
103 (newcoord, sd))
104 return q;
105 return celltype (newcoord,
106 origright, sd);
107 }
108 }
109 }
110 throw "False cubical cell's dimension.";
111 }
112 else
113 {
114 i -= d;
115 for (int j = 0; j < sd; ++ j)
116 {
117 // copy the coordinates of the right vertex
118 newcoord [j] = origright [j];
119
120 // modify the desired coordinate and finalize
121 if (origleft [j] != origright [j])
122 {
123 if (i == count ++)
124 {
125 newcoord [j] = origleft [j];
126 for (j = j + 1; j < sd; j ++)
127 newcoord [j] = origright [j];
128 if (onlyexisting &&
129 !celltype::PointBase::check
130 (newcoord, sd))
131 return q;
132 return celltype (origleft,
133 newcoord, sd);
134 }
135 }
136 }
137 throw "False dimension of a cubical cell.";
138 }
139} /* boundarycell */
140
142template <class celltype>
143inline celltype CubicalBoundaryCell (const celltype &q, int i)
144{
145 return CubicalBoundaryCell (q, i, false);
146} /* boundarycell */
147
149template <class celltype>
150inline int CubicalBoundaryLength (const celltype &q)
151{
152 return q. dim () << 1;
153} /* boundarylength */
154
156template <class celltype>
157inline int CubicalBoundaryCoef (const celltype &q, int i)
158{
159 int d = q. dim ();
160 if (i >= d)
161 i -= d - 1;
162 return (i & 1) ? 1 : -1;
163} /* boundarycoef */
164
165
166// --------------------------------------------------
167// ---------------- CUBICAL CELL I/O ----------------
168// --------------------------------------------------
169
172template <class celltype>
173inline std::ostream &WriteCubicalCell (std::ostream &out, const celltype &c)
174{
175 // determine the data to be written
176 typedef typename celltype::CoordType coordtype;
177 coordtype lcoord [celltype::MaxDim];
178 c. leftcoord (lcoord);
179 int dim = c. spacedim ();
180 coordtype rcoord [celltype::MaxDim];
181 c. rightcoord (rcoord);
182
183 if (celltype::OutputBits & celltype::BitProduct)
184 {
185 for (int i = 0; i < dim; ++ i)
186 {
187 out << '(';
188 out << lcoord [i];
189 if (rcoord [i] != lcoord [i])
190 out << ',' << rcoord [i];
191 out << ')';
192 if (i < dim - 1)
193 out << 'x';
194 }
195 }
196 else
197 {
198 out << '[' << '(';
199 int i;
200 for (i = 0; i < dim; ++ i)
201 {
202 out << lcoord [i];
203 if (i < dim - 1)
204 out << ',';
205 }
206 out << ')';
207 if (celltype::OutputBits & celltype::BitSpace)
208 out << ' ';
209 out << '(';
210 for (i = 0; i < dim; ++ i)
211 {
212 out << rcoord [i];
213 if (i < dim - 1)
214 out << ',';
215 }
216 out << ')' << ']';
217 }
218 return out;
219} /* operator << */
220
234template <class celltype>
235inline std::istream &ReadCubicalCell (std::istream &in, celltype &c)
236{
237 typedef typename celltype::CoordType coordtype;
238 // make sure that an opening parenthesis is waiting in the input
239 ignorecomments (in);
240 int closing = closingparenthesis (in. peek ());
241 if (closing == EOF)
242 throw "Opening parenthesis expected while reading a cell.";
243
244 // read the opening parenthesis
245 in. get ();
246 ignorecomments (in);
247
248 // prepare the two vertices of a cubical cell
249 coordtype c1 [celltype::MaxDim], c2 [celltype::MaxDim];
250
251 // if there is another opening parenthesis...
252 if (closingparenthesis (in. peek ()) != EOF)
253 {
254 // read coordinates of both vertices and a comma if any
255 int dim1 = readcoordinates (in, c1, celltype::MaxDim);
256 ignorecomments (in);
257 if (in. peek () == ',')
258 {
259 in. get ();
260 ignorecomments (in);
261 }
262 int dim2 = readcoordinates (in, c2, celltype::MaxDim);
263
264 // read the closing bracket and verify that the data
265 ignorecomments (in);
266 if ((in. get () != closing) || (dim1 <= 0) || (dim1 != dim2))
267 throw "Failed while reading two vertices of a cell.";
268
269 // verify the distance between the vertices of the cell
270 for (int i = 0; i < dim1; ++ i)
271 {
272 if ((c1 [i] != c2 [i]) && (c1 [i] + 1 != c2 [i]))
273 throw "Vertices of a read cell are too far.";
274 }
275
276 // create the cubical cell with the given vertices and quit
277 c = celltype (c1, c2, dim1);
278 return in;
279 }
280
281 // try reading the first set of coordinates in the cell's definition
282 coordtype c0 [celltype::MaxDim];
283 int count = readcoordinates (in, c0, celltype::MaxDim, closing);
284 if (count <= 0)
285 throw "Can't read a cell.";
286 ignorecomments (in);
287
288 // if it looks like an interval, then read the cell as a product
289 if ((count == 1) || (count == 2))
290 {
291 int dim = 0;
292 c1 [dim] = c0 [0];
293 c2 [dim ++] = c0 [count - 1];
294 while ((in. peek () == 'x') || (in. peek () == 'X'))
295 {
296 in. get ();
297 ignorecomments (in);
298 count = readcoordinates (in, c0, celltype::MaxDim);
299 ignorecomments (in);
300 if ((count < 1) || (count > 2) ||
301 (dim >= celltype::MaxDim))
302 throw "Wrong interval while reading a cell.";
303 if ((count == 2) && (c0 [1] != c0 [0]) &&
304 (c0 [1] - c0 [0] != 1))
305 throw "Too big interval defining a cell.";
306 c1 [dim] = c0 [0];
307 c2 [dim ++] = c0 [count - 1];
308 }
309 c = celltype (c1, c2, dim);
310 return in;
311 }
312
313 // if the cell is defined as a full-dim. cube, create it this way
314 for (int i = 0; i < count; ++ i)
315 c1 [i] = c0 [i] + 1;
316 c = celltype (c0, c1, count);
317 return in;
318} /* operator >> */
319
320
321// --------------------------------------------------
322// ----------- INTERSECTION OF TWO CUBES ------------
323// --------------------------------------------------
324
327template<class coordtype>
328inline int CommonCell (coordtype *left, coordtype *right,
329 const coordtype *c1, const coordtype *c2, int spcdim,
330 const coordtype *wrap = 0)
331{
332 // calculate the coordinates of both vertices of the cubical cell
333 // and the dimension of the cubical cell
334 int celldim = 0;
335 for (int i = 0; i < spcdim; ++ i)
336 {
337 if (c1 [i] == c2 [i])
338 {
339 left [i] = c1 [i];
340 right [i] = c1 [i];
341 ++ (right [i]);
342 ++ celldim;
343 }
344 else if ((c1 [i] - c2 [i] == -1) || (wrap && wrap [i] &&
345 (c1 [i] - c2 [i] == wrap [i] - 1)))
346 {
347 left [i] = c2 [i];
348 right [i] = c2 [i];
349 }
350 else if ((c1 [i] - c2 [i] == 1) || (wrap && wrap [i] &&
351 (c1 [i] - c2 [i] == -wrap [i] + 1)))
352 {
353 left [i] = c1 [i];
354 right [i] = c1 [i];
355 }
356 else
357 throw "The cubes do not intersect.";
358 }
359
360 return celldim;
361} /* CommonCell */
362
363
364} // namespace homology
365} // namespace chomp
366
367#endif // _CHOMP_CUBES_CELLMAIN_H_
368
370
This file contains the definition of a bitfield class which works an array of bits.
This file contains classes and functions related to algebraic chain complexes and chain maps,...
This file contains some precompiler definitions which indicate the operating system and/or compiler u...
This file contains a definition of a general geometric complex which represents a polyhedron.
This file contains the definition of the container "hashedset" which can be used to represent a set o...
This file defines a class "integer" which represents the ring of integers or the field of integers mo...
int CubicalBoundaryCoef(const celltype &q, int i)
Returns the i-th coefficient in the boundary of a cubical cell.
Definition: cellmain.h:157
int closingparenthesis(int ch)
Returns the matching closing parenthesis for the given opening one or EOF if none.
Definition: textfile.h:411
celltype CubicalBoundaryCell(const celltype &q, int i, bool onlyexisting)
Returns the i-th boundary element of a cell.
Definition: cellmain.h:72
std::ostream & WriteCubicalCell(std::ostream &out, const celltype &c)
Writes a cubical cell to the output stream in the text form.
Definition: cellmain.h:173
int CommonCell(coordtype *left, coordtype *right, const coordtype *c1, const coordtype *c2, int spcdim, const coordtype *wrap=0)
Computes the left and right corner of a cell which is the intersection of the two given cubes.
Definition: cellmain.h:328
int readcoordinates(std::istream &in, coordtype *coord, int maxdim, int closing)
Reads the coordinates of a point.
Definition: pointset.h:2073
void ignorecomments(std::istream &in)
Ignores white characters (spaces, tabulators, CRs and LFs), as well as comments from the input text f...
Definition: textfile.h:385
std::istream & ReadCubicalCell(std::istream &in, celltype &c)
Reads a cubical cell form the input text stream.
Definition: cellmain.h:235
int CubicalBoundaryLength(const celltype &q)
Returns the length of the boundary of a cubical cell.
Definition: cellmain.h:150
This namespace contains the entire CHomP library interface.
Definition: bitmaps.h:51
This file contains the definition of a point base class which is used for indexing all the points (n-...
This file contains the definition of a set of n-dimensional points with integer coordinates and sever...
This file contains some useful functions related to the text input/output procedures.