cubiset.h

Go to the documentation of this file.
00001 
00002 
00003 
00014 
00015 // Copyright (C) 1997-2010 by Pawel Pilarczyk.
00016 //
00017 // This file constitutes a part of the Homology Library, 
00018 // distributed under the terms of the GNU General Public License.
00019 // Consult  http://capd.wsb-nlu.edu.pl/ for details. 
00020 
00021 // Started on March 19, 2006. Last revision: July 27, 2007.
00022 
00023 
00024 #ifndef _CAPD_HOMENGIN_CUBISET_H_ 
00025 #define _CAPD_HOMENGIN_CUBISET_H_ 
00026 
00027 #include <string>
00028 #include <cstring>
00029 #include "capd/homengin/homology.h"
00030 
00031 
00032 // --------------------------------------------------
00033 // ------------------ CUBICAL SET -------------------
00034 // --------------------------------------------------
00035 
00039 class CubicalSet
00040 {
00041 public:
00044         CubicalSet (const int *left_coords, const int *right_coords,
00045                 int dim = EMBEDDING_DIM, const int *space_wrapping = 0);
00046 
00048         ~CubicalSet ();
00049 
00051         CubicalSet (const CubicalSet &c);
00052 
00054         CubicalSet &operator = (const CubicalSet &c);
00055 
00058         void ComputeBettiNumbers (int *result, const char *engine = 0,
00059                 bool quiet = false) const;
00060 
00063         int Add (const int *coords);
00064 
00067         int Delete (const int *coords);
00068 
00071         bool Contains (const int *coords) const;
00072 
00074         void Clear ();
00075 
00076 private:
00078         int ByteOffset (const int *coords) const;
00079 
00081         int BitMask (const int *coords) const;
00082 
00084         bool Inside (const int *coords);
00085 
00087         unsigned char *buffer;
00088 
00090         int bufsize;
00091 
00093         int dim;
00094 
00096         int *sizes;
00097 
00099         int *minimal;
00100 
00102         int *wrapping;
00103 
00104 }; /* class CubicalComples */
00105 
00106 // --------------------------------------------------
00107 
00108 inline CubicalSet::CubicalSet (const int *left_coords,
00109         const int *right_coords, int dim, const int *space_wrapping)
00110 {
00111         if (dim <= 0)
00112                 throw "Non-positive dimension of a cubical complex.";
00113         this -> dim = dim;
00114         this -> sizes = new int [dim];
00115         this -> minimal = new int [dim];
00116         this -> wrapping = space_wrapping ? new int [dim] : 0;
00117         this -> bufsize = 0;
00118         for (int i = 0; i < dim; ++ i)
00119         {
00120                 minimal [i] = left_coords [i];
00121                 sizes [i] = right_coords [i] - left_coords [i];
00122                 if (sizes [i] <= 0)
00123                         throw "Non-positive size of a cubical complex.";
00124                 if (!i)
00125                 {
00126                         sizes [0] = (sizes [0] + 63) & ~63;
00127                         bufsize = sizes [0] >> 3;
00128                 }
00129                 else
00130                         bufsize *= sizes [i];
00131         }
00132         if (space_wrapping)
00133         {
00134                 for (int i = 0; i < dim; ++ i)
00135                 {
00136                         wrapping [i] = space_wrapping [i];
00137                         if (wrapping [i] < 0)
00138                                 wrapping [i] = -space_wrapping [i];
00139                 }
00140         }
00141         if (bufsize <= 0)
00142                 throw "Wrong buffer size in a cubical complex.";
00143         buffer = new unsigned char [bufsize];
00144         std::memset (buffer, 0, bufsize);
00145         return;
00146 } /* CubicalSet::CubicalSet */
00147 
00148 inline CubicalSet::~CubicalSet ()
00149 {
00150         delete [] sizes;
00151         delete [] minimal;
00152         delete [] buffer;
00153         if (wrapping)
00154                 delete [] wrapping;
00155         return;
00156 } /* CubicalSet::~CubicalSet */
00157 
00158 inline CubicalSet::CubicalSet (const CubicalSet &c)
00159 {
00160         dim = c. dim;
00161         bufsize = c. bufsize;
00162         sizes = new int [dim];
00163         minimal = new int [dim];
00164         for (int i = 0; i < dim; ++ i)
00165         {
00166                 minimal [i] = c. minimal [i];
00167                 sizes [i] = c. sizes [i];
00168         }
00169         buffer = new unsigned char [bufsize];
00170         std::memcpy (buffer, c. buffer, bufsize);
00171         return;
00172 } /* CubicalSet::CubicalSet */
00173 
00174 inline CubicalSet &CubicalSet::operator = (const CubicalSet &c)
00175 {
00176         delete [] sizes;
00177         delete [] minimal;
00178         delete [] buffer;
00179 
00180         dim = c. dim;
00181         bufsize = c. bufsize;
00182         sizes = new int [dim];
00183         minimal = new int [dim];
00184         for (int i = 0; i < dim; ++ i)
00185         {
00186                 minimal [i] = c. minimal [i];
00187                 sizes [i] = c. sizes [i];
00188                 if (i > 0)
00189                         bufsize *= sizes [i];
00190         }
00191         buffer = new unsigned char [bufsize];
00192         std::memcpy (buffer, c. buffer, bufsize);
00193         return *this;
00194 } /* CubicalSet::operator = */
00195 
00196 inline int CubicalSet::ByteOffset (const int *coords) const
00197 {
00198         int offset = (coords [0] - minimal [0]) >> 3;
00199         int multiply = ((sizes [0] + 31) >> 5) << 2;
00200         for (int i = 1; i < dim; ++ i)
00201         {
00202                 offset += multiply * (coords [i] - minimal [i]);
00203                 multiply *= sizes [i];
00204         }
00205         return offset;
00206 } /* CubicalSet::ByteOffset */
00207 
00208 inline int CubicalSet::BitMask (const int *coords) const
00209 {
00210         return 1 << ((coords [0] - minimal [0]) & 0x07);
00211 } /* CubicalSet::BitMask */
00212 
00213 inline bool CubicalSet::Inside (const int *coords)
00214 {
00215         for (int i = 0; i < dim; ++ i)
00216         {
00217                 if (coords [i] < minimal [i])
00218                         return false;
00219                 if (coords [i] >= minimal [i] + sizes [i])
00220                         return false;
00221         }
00222         return true;
00223 } /* CubicalSet::Inside */
00224 
00225 inline int CubicalSet::Add (const int *coords)
00226 {
00227         if (!Inside (coords))
00228                 return -1;
00229         buffer [ByteOffset (coords)] |= BitMask (coords);
00230         return 0;
00231 } /* CubicalSet::Add */
00232 
00233 inline int CubicalSet::Delete (const int *coords)
00234 {
00235         if (!Inside (coords))
00236                 return -1;
00237         buffer [ByteOffset (coords)] &= ~(BitMask (coords));
00238         return 0;
00239 } /* CubicalSet::Delete */
00240 
00241 inline bool CubicalSet::Contains (const int *coords) const
00242 {
00243         return buffer [ByteOffset (coords)] & BitMask (coords);
00244 } /* CubicalSet::Contains */
00245 
00246 inline void CubicalSet::Clear ()
00247 {
00248         std::memset (buffer, 0, bufsize);
00249         return;
00250 } /* CubicalSet::Clear */
00251 
00252 inline void CubicalSet::ComputeBettiNumbers (int *result,
00253         const char *engine, bool quiet) const
00254 {
00255 	::ComputeBettiNumbers (buffer, sizes, dim, result, engine,
00256                 wrapping, quiet);
00257         return;
00258 } /* CubicalSet::ComputeBettiNumbers */
00259 
00262 inline void ComputeBettiNumbers (const CubicalSet &s, int *result,
00263         const char *engine = 0, bool quiet = false)
00264 {
00265         s. ComputeBettiNumbers (result, engine, quiet);
00266         return;
00267 } /* ComputeBettiNumbers */
00268 
00269 
00270 #endif // _CAPD_HOMENGIN_CUBISET_H_ 
00271 
00273