Go to the documentation of this file.00001
00002
00003
00014
00015
00016
00017
00018
00019
00020
00021
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
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 };
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 }
00147
00148 inline CubicalSet::~CubicalSet ()
00149 {
00150 delete [] sizes;
00151 delete [] minimal;
00152 delete [] buffer;
00153 if (wrapping)
00154 delete [] wrapping;
00155 return;
00156 }
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 }
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 }
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 }
00207
00208 inline int CubicalSet::BitMask (const int *coords) const
00209 {
00210 return 1 << ((coords [0] - minimal [0]) & 0x07);
00211 }
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 }
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 }
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 }
00240
00241 inline bool CubicalSet::Contains (const int *coords) const
00242 {
00243 return buffer [ByteOffset (coords)] & BitMask (coords);
00244 }
00245
00246 inline void CubicalSet::Clear ()
00247 {
00248 std::memset (buffer, 0, bufsize);
00249 return;
00250 }
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 }
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 }
00268
00269
00270 #endif // _CAPD_HOMENGIN_CUBISET_H_
00271
00273