cubemain.h

Go to the documentation of this file.
00001 
00002 
00003 
00015 
00016 // Copyright (C) 1997-2010 by Pawel Pilarczyk.
00017 //
00018 // This file is part of the Homology Library.  This library is free software;
00019 // you can redistribute it and/or modify it under the terms of the GNU
00020 // General Public License as published by the Free Software Foundation;
00021 // either version 2 of the License, or (at your option) any later version.
00022 //
00023 // This library is distributed in the hope that it will be useful,
00024 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00025 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00026 // GNU General Public License for more details.
00027 //
00028 // You should have received a copy of the GNU General Public License along
00029 // with this software; see the file "license.txt".  If not, write to the
00030 // Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00031 // MA 02111-1307, USA.
00032 
00033 // Started in January 2002. Last revision: June 4, 2007.
00034 
00035 
00036 #ifndef _CHOMP_CUBES_CUBEMAIN_H_
00037 #define _CHOMP_CUBES_CUBEMAIN_H_
00038 
00039 
00040 #include "chomp/system/config.h"
00041 #include "chomp/system/textfile.h"
00042 #include "chomp/cubes/pointset.h"
00043 #include "chomp/struct/bitfield.h"
00044 #include "chomp/struct/integer.h"
00045 #include "chomp/struct/hashsets.h"
00046 
00047 #include <iostream>
00048 #include <fstream>
00049 #include <cstdlib>
00050 #include <cstring>
00051 
00052 
00053 namespace chomp {
00054 namespace homology {
00055 
00056 
00058 template <class dest_cube, class src_cube>
00059 inline dest_cube cube_cast (const src_cube &src)
00060 {
00061         typename dest_cube::CoordType tab [src_cube::MaxDim];
00062         src. coord (tab);
00063         return dest_cube (tab, src. dim ());
00064 } /* cube_cast */
00065 
00066 // --------------------------------------------------
00067 
00069 template <class cubetype>
00070 inline std::ostream &WriteCube (std::ostream &out, const cubetype &c)
00071 {
00072         typename cubetype::CoordType coord [cubetype::MaxDim];
00073         c. coord (coord);
00074         int dim = c. dim ();
00075         out << "(";
00076         for (int i = 0; i < dim; ++ i)
00077         {
00078                 if (i)
00079                         out << ",";
00080                 out << coord [i];
00081         }
00082         out << ")";
00083         return out;
00084 } /* WriteCube */
00085 
00086 // --------------------------------------------------
00087 
00090 template <class cubetype>
00091 std::istream &ReadCubeFix (std::istream &in, cubetype &c, int dimfix)
00092 {
00093         // retrieve the type of coordinates of the cube to read
00094         typedef typename cubetype::CoordType coordtype;
00095 
00096         // ignore any comments, spaces, tabs and new-line characters
00097         ignorecomments (in);
00098 
00099         // if there is a number in the input, then there are apparently
00100         // no parentheses used for the coords or the cube is defined
00101         // by its number (also indicated with '#')
00102         if (((in. peek () >= '0') && (in. peek () <= '9')) ||
00103                 (in. peek () == '-') || (in. peek () == '+') ||
00104                 (in. peek () == '#'))
00105         {
00106                 bool cubenumber = false;
00107                 if (in. peek () == '#')
00108                 {
00109                         in. get ();
00110                         ignorecomments (in);
00111                         cubenumber = true;
00112                 }
00113                 if (in. peek () == '+')
00114                         in. get ();
00115                 int n = -1;
00116                 in >> n;
00117                 while ((in. peek () == ' ') || (in. peek () == '\t'))
00118                         in. get ();
00119 
00120                 // if the next coordinate of the cube follows,
00121                 // read the coordinates until end-of-line is encountered
00122                 if (!cubenumber &&
00123                         (((in. peek () >= '0') && (in. peek () <= '9')) ||
00124                         (in. peek () == '-') || (in. peek () == '+')))
00125                 {
00126                         // read the coords and determine the space dimension
00127                         coordtype coord [cubetype::MaxDim];
00128                         coord [0] = n;
00129                         int dim = -1;
00130                         if (in. peek () != '\n')
00131                         {
00132                                 dim = readcoordinates (in, coord + 1,
00133                                         cubetype::MaxDim - 1, '\n');
00134                                 if (dim < 0)
00135                                         throw "Unable to read a cube: "
00136                                                 "Dim too high.";
00137                         }
00138                         ++ dim;
00139 
00140                         // if could not read the cube, throw an error message
00141                         if ((dimfix >= 0) && (dim != dimfix))
00142                                 throw "Unable to read a cube: Wrong dim.";
00143 
00144                         // create a cube with the given coordinates
00145                         c = cubetype (coord, dim);
00146 
00147                         return in;
00148                 }
00149 
00150                 // if the cube is given by its number, read it this way
00151                 else
00152                 {
00153                         int dim = cubetype::PointBase::defaultdimension ();
00154                         const typename cubetype::CoordType *coord = 0;
00155                         if ((n > 0) && (dim > 0))
00156                         {
00157                                 coord = cubetype::PointBase::coord
00158                                         (n - 1, dim);
00159                         }
00160                         if (!coord)
00161                                 throw "Cube no. out of range while reading.";
00162                         c = cubetype (n - 1, dim);
00163                         return in;
00164                 }
00165         }
00166 
00167         // read the coordinates and determine the space dimension
00168         typename cubetype::CoordType coord [cubetype::MaxDim];
00169         int dim = readcoordinates (in, coord, cubetype::MaxDim);
00170         if (dim < 0)
00171                 throw "Unable to read a cube: Dimension too high.";
00172 
00173         // if could not read the cube, throw an error message
00174         if ((dimfix >= 0) && (dim != dimfix))
00175                 throw "Unable to read a cube: Wrong dimension.";
00176 
00177         // create the cube with the given coordinates
00178         c = cubetype (coord, dim);
00179 
00180         return in;
00181 } /* ReadCubeFix */
00182 
00184 template <class cubetype>
00185 inline std::istream &ReadCube (std::istream &in, cubetype &c)
00186 {
00187         return ReadCubeFix (in, c, -1);
00188 } /* ReadCube */
00189 
00193 template <class cubsettype>
00194 std::istream &ReadCubes (std::istream &in, cubsettype &s)
00195 {
00196         // ignore any comments at the beginning of the file
00197         ignorecomments (in);
00198 
00199         // if the word "dimension" found, ignore the entire line
00200         if (in. peek () == 'd')
00201         {
00202                 in. ignore (20000, '\n');
00203                 ignorecomments (in);
00204         }
00205 
00206         // read the set of cubes using the standard procedure
00207         return read (in, s, LARGE_SIZE);
00208 } /* ReadCubes */
00209 
00211 template <class tCube>
00212 std::istream &ReadCubicalMap (std::istream &in, mvmap<tCube,tCube> &m)
00213 {
00214         // process the entire input file and read the map line-by-line
00215         ignorecomments (in);
00216         while (in. peek () != EOF)
00217         {
00218                 // ignore all the lines which do not define a map assignment
00219                 while ((closingparenthesis (in. peek ()) == EOF) &&
00220                         ((in. peek () < '0') || (in. peek () > '9')) &&
00221                         (in. peek () != EOF))
00222                 {
00223                         ignoreline (in);
00224                         ignorecomments (in);
00225                 }
00226 
00227                 // if the end of the file has been reached, exit the loop
00228                 if (in. peek () == EOF)
00229                         break;
00230         
00231                 // determine the closing parenthesis corresp. to this one
00232                 int closing = closingparenthesis (in. peek ());
00233 
00234                 // if the opening parenthesis is valid, read it and
00235                 // check the next character to determine the assignment type
00236                 if (closing != EOF)
00237                 {
00238                         in. get ();
00239                         ignorecomments (in);
00240                 }
00241 
00242                 // if the assignment is in the general form, decode the line
00243                 if ((closing == EOF) ||
00244                         (closingparenthesis (in. peek ()) == EOF))
00245                 {
00246                         // read the domain element
00247                         tCube e;
00248                         // if it is given as a number, read it directly
00249                         if (closing == EOF)
00250                         {
00251                                 in >> e;
00252                                 if (!in)
00253                                         throw "Can't read cube's number.";
00254                         }
00255                         // otherwise read the coordinates of the cube
00256                         else
00257                         {
00258                                 typename tCube::CoordType coord
00259                                         [tCube::MaxDim];
00260                                 int dim = readcoordinates (in, coord,
00261                                         tCube::MaxDim, closing);
00262                                 if (!in || (dim <= 0))
00263                                         throw "Unable to read a cube.";
00264                                 e = tCube (coord, dim);
00265                         }
00266                         ignorecomments (in);
00267 
00268                         // read the assignment arrow
00269                         while (in. peek () == '-')
00270                                 in. get ();
00271                         if (in. peek () == '>')
00272                                 in. get ();
00273                         ignorecomments (in);
00274 
00275                         // read the image of the cube
00276                         read (in, m [e], SMALL_SIZE);
00277                         ignorecomments (in);
00278                 }
00279 
00280                 // otherwise read the assignment in the Jacek & Marcin format
00281                 else
00282                 {
00283                         // read the argument cell
00284                         typename tCube::CoordType argleft [tCube::MaxDim];
00285                         typename tCube::CoordType argright [tCube::MaxDim];
00286                         int dim = readcoordinates (in, argleft,
00287                                 tCube::MaxDim);
00288                         ignorecomments (in);
00289                         int d1 = readcoordinates (in, argright,
00290                                 tCube::MaxDim);
00291                         ignorecomments (in);
00292 
00293                         // read the closing and opening brackets
00294                         in. get ();
00295                         ignorecomments (in);
00296                         in. get ();
00297                         ignorecomments (in);
00298 
00299                         // read the value cell
00300                         typename tCube::CoordType vleft [tCube::MaxDim];
00301                         typename tCube::CoordType vright [tCube::MaxDim];
00302                         int d2 = readcoordinates (in, vleft, tCube::MaxDim);
00303                         ignorecomments (in);
00304                         int d3 = readcoordinates (in, vright, tCube::MaxDim);
00305                         ignorecomments (in);
00306 
00307                         // if there was an I/O error, interrupt reading here
00308                         if (!in || (in. peek () == EOF))
00309                                 throw "Cannot read a map assignment line.";
00310 
00311                         // read the closing bracket
00312                         in. get ();
00313                         ignorecomments (in);
00314 
00315                         // check that all the dimensions are the same
00316                         if ((d1 != dim) || (d2 != dim) || (d3 != dim))
00317                                 throw "Wrong dimensions of vertices.";
00318 
00319                         // verify that the argument cube is of the right size
00320                         for (int i = 0; i < dim; ++ i)
00321                         {
00322                                 if (argright [i] - argleft [i] != 1)
00323                                         throw "Wrong size of an argument.";
00324                         }
00325 
00326                         // add the argument cube to the map's domain
00327                         hashedset<tCube> &v = m [tCube (argleft, dim)];
00328 
00329                         // form a rectangle from this value cell
00330                         tRectangle<typename tCube::CoordType> r
00331                                 (vleft, vright, dim);
00332 
00333                         // add all the value cubes to the image of this element
00334                         const typename tCube::CoordType *c;
00335                         while ((c = r. get ()) != NULL)
00336                                 v. add (tCube (c, dim));
00337                 }
00338         }
00339         
00340         return in;
00341 } /* ReadCubicalMap */
00342 
00343 
00344 } // namespace homology
00345 } // namespace chomp
00346 
00347 #endif // _CHOMP_CUBES_CUBEMAIN_H_
00348 
00350