Mercurial > repos > lsong10 > psiclass
comparison PsiCLASS-1.0.2/BitTable.hpp @ 0:903fc43d6227 draft default tip
Uploaded
| author | lsong10 |
|---|---|
| date | Fri, 26 Mar 2021 16:52:45 +0000 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:903fc43d6227 |
|---|---|
| 1 /** | |
| 2 Use an 64bit integer to represent bit table. | |
| 3 | |
| 4 Li Song | |
| 5 July 24, 2012 | |
| 6 | |
| 7 - Modified again from May 27, 2017. | |
| 8 */ | |
| 9 | |
| 10 | |
| 11 #ifndef _BIT_TABLE_HEADER | |
| 12 #define _BIT_TABLE_HEADER | |
| 13 | |
| 14 #include <stdio.h> | |
| 15 | |
| 16 typedef unsigned long long int UINT64 ; | |
| 17 #define UNIT_SIZE (sizeof( UINT64 ) * 8 ) | |
| 18 #define UNIT_MASK ((UINT64)63) | |
| 19 | |
| 20 class BitTable | |
| 21 { | |
| 22 private: | |
| 23 UINT64 *tab ; // The bits | |
| 24 int size ; // The size of the table | |
| 25 int asize ; // The size of the array (size/64). | |
| 26 public: | |
| 27 BitTable() // Intialize a bit table. | |
| 28 { | |
| 29 //tab = new UINT64[1] ; | |
| 30 //size = UNIT_SIZE ; | |
| 31 tab = NULL ; | |
| 32 size = 0 ; | |
| 33 } | |
| 34 | |
| 35 BitTable( int s ) // Initalize a bit table with size s. | |
| 36 { | |
| 37 if ( s == 0 ) | |
| 38 s = UNIT_SIZE ; | |
| 39 | |
| 40 if ( s & UNIT_MASK ) | |
| 41 { | |
| 42 asize = s / UNIT_SIZE + 1 ; | |
| 43 tab = new UINT64[ asize ] ; | |
| 44 } | |
| 45 else | |
| 46 { | |
| 47 asize = s / UNIT_SIZE ; | |
| 48 tab = new UINT64[ asize ] ; | |
| 49 } | |
| 50 | |
| 51 size = s ; | |
| 52 Reset() ; | |
| 53 } | |
| 54 | |
| 55 ~BitTable() | |
| 56 { | |
| 57 //printf( "hi %d\n", size ) ; | |
| 58 //printf( "%s\n", __func__ ) ; | |
| 59 //if ( tab != NULL ) | |
| 60 // delete [] tab ; | |
| 61 //size = -1 ; | |
| 62 | |
| 63 // Manually release the memory. | |
| 64 } | |
| 65 | |
| 66 void Init( int s ) // Initialize a bit table with size s. | |
| 67 { | |
| 68 if ( tab != NULL ) | |
| 69 delete [] tab ; | |
| 70 | |
| 71 if ( s == 0 ) | |
| 72 s = UNIT_SIZE ; | |
| 73 | |
| 74 if ( s & UNIT_MASK ) | |
| 75 { | |
| 76 asize = s / UNIT_SIZE + 1 ; | |
| 77 tab = new UINT64[ asize ] ; | |
| 78 } | |
| 79 else | |
| 80 { | |
| 81 asize = s / UNIT_SIZE ; | |
| 82 tab = new UINT64[ asize ] ; | |
| 83 } | |
| 84 | |
| 85 size = s ; | |
| 86 Reset() ; | |
| 87 } | |
| 88 | |
| 89 void Release() | |
| 90 { | |
| 91 if ( tab != NULL ) | |
| 92 delete[] tab ; | |
| 93 tab = NULL ; | |
| 94 } | |
| 95 | |
| 96 void Reset() // Make every value 0. | |
| 97 { | |
| 98 for ( int i = 0 ; i < asize ; ++i ) | |
| 99 tab[i] = 0 ; | |
| 100 } | |
| 101 | |
| 102 void Set( int i ) // Set the ith bit. | |
| 103 { | |
| 104 int ind, offset ; | |
| 105 ind = i / UNIT_SIZE ; | |
| 106 offset = i & UNIT_MASK ; | |
| 107 //printf( "%d,%d %d,%d: %llx", 311 / UNIT_SIZE, 311 & UNIT_MASK, 279 / UNIT_SIZE, 279 & UNIT_MASK, tab[ind] ) ; | |
| 108 tab[ind] |= ( (UINT64)1 << offset ) ; | |
| 109 //printf( " %llx %d\n", tab[ind], UNIT_SIZE ) ; | |
| 110 } | |
| 111 | |
| 112 void Unset( int i ) // Unset the ith bit | |
| 113 { | |
| 114 int ind, offset ; | |
| 115 ind = i / UNIT_SIZE ; | |
| 116 offset = i & UNIT_MASK ; | |
| 117 | |
| 118 tab[ind] &= ( (UINT64)-1 ^ ( (UINT64)1 << offset ) ) ; | |
| 119 } | |
| 120 | |
| 121 void Flip( int i ) // Flip the ith bit. Same as xor 1. | |
| 122 { | |
| 123 int ind, offset ; | |
| 124 ind = i / UNIT_SIZE ; | |
| 125 offset = i & UNIT_MASK ; | |
| 126 | |
| 127 tab[ind] ^= ( (UINT64)1 << offset ) ; | |
| 128 } | |
| 129 | |
| 130 bool Test( unsigned int i ) const // Test the ith bit. | |
| 131 { | |
| 132 if ( i >= (unsigned int)size ) | |
| 133 return false ; | |
| 134 | |
| 135 unsigned int ind, offset ; | |
| 136 ind = i / UNIT_SIZE ; | |
| 137 offset = i & UNIT_MASK ; | |
| 138 | |
| 139 if ( tab[ind] & ( (UINT64)1 << offset ) ) | |
| 140 return true ; | |
| 141 else | |
| 142 return false ; | |
| 143 } | |
| 144 | |
| 145 void Not() // Not all the bits. | |
| 146 { | |
| 147 int i ; | |
| 148 for ( i = 0 ; i < asize ; ++i ) | |
| 149 { | |
| 150 tab[i] = ~tab[i] ; | |
| 151 } | |
| 152 } | |
| 153 | |
| 154 void And( const BitTable &in ) // Do the "and" on each bits. | |
| 155 { | |
| 156 if ( asize != in.asize ) | |
| 157 return ; | |
| 158 int i ; | |
| 159 for ( i = 0 ; i < asize ; ++i ) | |
| 160 tab[i] &= in.tab[i] ; | |
| 161 } | |
| 162 | |
| 163 void Or( const BitTable &in ) // Do the "or" on each bits. | |
| 164 { | |
| 165 if ( asize != in.asize ) | |
| 166 return ; | |
| 167 int i ; | |
| 168 for ( i = 0 ; i < asize ; ++i ) | |
| 169 tab[i] |= in.tab[i] ; | |
| 170 } | |
| 171 | |
| 172 void Xor( const BitTable &in ) | |
| 173 { | |
| 174 if ( asize != in.asize ) | |
| 175 return ; | |
| 176 int i ; | |
| 177 for ( i = 0 ; i < asize ; ++i ) | |
| 178 tab[i] ^= in.tab[i] ; | |
| 179 } | |
| 180 | |
| 181 // Unset all the bits outside [s,e] | |
| 182 void MaskRegionOutside( unsigned int s, unsigned int e ) | |
| 183 { | |
| 184 int i ; | |
| 185 // mask out [0, s-1]. | |
| 186 int ind, offset ; | |
| 187 if ( s > 0 ) | |
| 188 { | |
| 189 ind = (s - 1) / UNIT_SIZE ; | |
| 190 offset = ( s - 1 ) & UNIT_MASK ; | |
| 191 for ( i = 0 ; i <= ind - 1 ; ++i ) | |
| 192 tab[i] = 0 ; | |
| 193 if ( offset + 1 >= 64 ) | |
| 194 tab[i] = 0 ; | |
| 195 else | |
| 196 tab[i] = ( tab[i] >> (UINT64)( offset + 1 ) ) << (UINT64)( offset + 1 ) ; | |
| 197 } | |
| 198 | |
| 199 // mask out [e+1, size-1] | |
| 200 if ( e < ( (unsigned int)size - 1 ) ) | |
| 201 { | |
| 202 ind = ( e + 1 ) / UNIT_SIZE ; | |
| 203 offset = ( e + 1 ) & UNIT_MASK ; | |
| 204 for ( i = ind + 1 ; i < asize ; ++i ) | |
| 205 tab[i] = 0 ; | |
| 206 | |
| 207 if ( UNIT_SIZE - offset >= 64 ) | |
| 208 tab[ind] = 0 ; | |
| 209 else | |
| 210 tab[ind] = ( tab[ind] << (UINT64)( UNIT_SIZE - offset ) ) >> (UINT64)( UNIT_SIZE - offset ) ; | |
| 211 } | |
| 212 } | |
| 213 | |
| 214 // Given further information about the position of first and last 1's | |
| 215 void MaskRegionOutsideInRange( int s, int e, int first, int last ) | |
| 216 { | |
| 217 int i ; | |
| 218 int start, to ; | |
| 219 start = first / UNIT_SIZE ; | |
| 220 to = last / UNIT_SIZE ; | |
| 221 // mask out [0, s-1]. | |
| 222 int ind, offset ; | |
| 223 if ( s > 0 ) | |
| 224 { | |
| 225 ind = (s - 1) / UNIT_SIZE ; | |
| 226 offset = ( s - 1 ) & UNIT_MASK ; | |
| 227 for ( i = start ; i <= ind - 1 ; ++i ) | |
| 228 tab[i] = 0 ; | |
| 229 if ( offset + 1 >= 64 ) | |
| 230 tab[i] = 0 ; | |
| 231 else | |
| 232 tab[i] = ( tab[i] >> (UINT64)( offset + 1 ) ) << (UINT64)( offset + 1 ) ; | |
| 233 } | |
| 234 | |
| 235 // mask out [e+1, size-1] | |
| 236 if ( e < size - 1 ) | |
| 237 { | |
| 238 ind = ( e + 1 ) / UNIT_SIZE ; | |
| 239 offset = ( e + 1 ) & UNIT_MASK ; | |
| 240 for ( i = ind + 1 ; i <= to ; ++i ) | |
| 241 tab[i] = 0 ; | |
| 242 | |
| 243 if ( UNIT_SIZE - offset >= 64 ) | |
| 244 tab[ind] = 0 ; | |
| 245 else | |
| 246 tab[ind] = ( tab[ind] << (UINT64)( UNIT_SIZE - offset ) ) >> (UINT64)( UNIT_SIZE - offset ) ; | |
| 247 } | |
| 248 } | |
| 249 void ShiftOneLeft() | |
| 250 { | |
| 251 int i ; | |
| 252 UINT64 carry = 0 ; | |
| 253 UINT64 lastTabMask ; | |
| 254 if ( ( size & UNIT_MASK ) == 0 ) | |
| 255 lastTabMask = (UINT64)(-1) ; | |
| 256 else | |
| 257 lastTabMask = ( 1 << ( size & UNIT_MASK ) ) - 1 ; | |
| 258 | |
| 259 for ( i = 0 ; i < asize - 1 ; ++i ) | |
| 260 { | |
| 261 UINT64 tmp = ( tab[i] >> ( UNIT_SIZE - 1 ) ) & 1 ; | |
| 262 tab[i] = ( tab[i] << 1 ) | carry ; | |
| 263 carry = tmp ; | |
| 264 } | |
| 265 tab[i] = ( ( tab[i] << 1 ) | carry ) & lastTabMask ; | |
| 266 } | |
| 267 | |
| 268 void ShiftOneRight() | |
| 269 { | |
| 270 int i ; | |
| 271 UINT64 carry = ( tab[ asize - 1 ] & 1 ) ; | |
| 272 tab[ asize - 1 ] >>= 1 ; | |
| 273 for ( i = asize - 2 ; i >= 0 ; --i ) | |
| 274 { | |
| 275 UINT64 tmp = ( tab[i] & 1 ) ; | |
| 276 tab[i] = ( tab[i] >> 1 ) | ( carry << ( UNIT_SIZE - 1 ) ) ; | |
| 277 carry = tmp ; | |
| 278 } | |
| 279 } | |
| 280 | |
| 281 bool IsAllZero() | |
| 282 { | |
| 283 int i ; | |
| 284 for ( i = 0 ; i < asize ; ++i ) | |
| 285 if ( tab[i] != 0 ) | |
| 286 return false ; | |
| 287 return true ; | |
| 288 } | |
| 289 | |
| 290 int Count() const // Count how many 1. | |
| 291 { | |
| 292 if ( size <= 0 ) | |
| 293 return 0 ; | |
| 294 UINT64 k ; | |
| 295 int i, ret = 0 ; | |
| 296 for ( i = 0 ; i < asize - 1 ; ++i ) | |
| 297 { | |
| 298 k = tab[i] ; | |
| 299 while ( k ) | |
| 300 //for ( j = 0 ; j < UNIT_SIZE ; ++j ) | |
| 301 { | |
| 302 if ( k & 1 ) | |
| 303 ++ret ; | |
| 304 //printf( "### %d %d %d %d\n", ret, asize, size, k ) ; | |
| 305 k /= 2 ; | |
| 306 } | |
| 307 } | |
| 308 //printf( "(%d) ", ret ) ; | |
| 309 k = tab[ asize - 1 ] ; | |
| 310 for ( i = 0 ; i <= (int)( ( size - 1 ) & UNIT_MASK ) ; ++i ) | |
| 311 { | |
| 312 if ( k & 1 ) | |
| 313 ++ret ; | |
| 314 k /= 2 ; | |
| 315 } | |
| 316 //for ( i = 0 ; i < asize ; ++i ) | |
| 317 // printf( "%llu ", tab[i] ) ; | |
| 318 //printf( "(%d)\n", ret ) ; | |
| 319 return ret ; | |
| 320 } | |
| 321 | |
| 322 void GetOnesIndices( std::vector<int> &indices ) | |
| 323 { | |
| 324 if ( size <= 0 ) | |
| 325 return ; | |
| 326 UINT64 k ; | |
| 327 int i ; | |
| 328 int ind = 0 ; | |
| 329 for ( i = 0 ; i < asize - 1 ; ++i ) | |
| 330 { | |
| 331 k = tab[i] ; | |
| 332 ind = i * UNIT_SIZE ; | |
| 333 while ( k ) | |
| 334 //for ( j = 0 ; j < UNIT_SIZE ; ++j ) | |
| 335 { | |
| 336 if ( k & 1 ) | |
| 337 indices.push_back( ind ) ; | |
| 338 //printf( "### %d %d %d %d\n", ret, asize, size, k ) ; | |
| 339 k /= 2 ; | |
| 340 ++ind ; | |
| 341 } | |
| 342 } | |
| 343 //printf( "(%d) ", ret ) ; | |
| 344 k = tab[ asize - 1 ] ; | |
| 345 ind = i * UNIT_SIZE ; | |
| 346 for ( i = 0 ; i <= (int)( ( size - 1 ) & UNIT_MASK ) ; ++i ) | |
| 347 { | |
| 348 if ( k & 1ull ) | |
| 349 indices.push_back( ind ) ; | |
| 350 k /= 2ull ; | |
| 351 ++ind ; | |
| 352 } | |
| 353 } | |
| 354 | |
| 355 bool IsEqual( const BitTable &in ) const// Test wether two bit tables equal. | |
| 356 { | |
| 357 int i ; | |
| 358 if ( in.size != size ) | |
| 359 return false ; | |
| 360 //printf( "== %d %d\n", in.size, size ) ; | |
| 361 //if ( size & UNIT_MASK ) | |
| 362 // k = size / UNIT_SIZE + 1 ; | |
| 363 //else | |
| 364 // k = size / UNIT_SIZE ; | |
| 365 | |
| 366 for ( i = 0 ; i < asize ; ++i ) | |
| 367 if ( tab[i] != in.tab[i] ) | |
| 368 return false ; | |
| 369 return true ; | |
| 370 } | |
| 371 | |
| 372 // Return the location of the first difference. -1 if the same. | |
| 373 int GetFirstDifference( const BitTable &in ) const | |
| 374 { | |
| 375 int as = asize < in.asize ? asize : in.asize ; | |
| 376 //int s = size < in.size ? size : in.size ; | |
| 377 int i, j ; | |
| 378 | |
| 379 for ( i = 0 ; i < as ; ++i ) | |
| 380 { | |
| 381 if ( tab[i] != in.tab[i] ) | |
| 382 { | |
| 383 UINT64 k1 = tab[i] ; | |
| 384 UINT64 k2 = in.tab[i] ; | |
| 385 for ( j = 0 ; j < (int)UNIT_SIZE ; ++j ) | |
| 386 { | |
| 387 if ( ( k1 & 1 ) != ( k2 & 1 ) ) | |
| 388 { | |
| 389 return j + UNIT_SIZE * i ; | |
| 390 } | |
| 391 k1 >>= 1 ; | |
| 392 k2 >>= 1 ; | |
| 393 } | |
| 394 } | |
| 395 } | |
| 396 | |
| 397 for ( ; i < asize ; ++i ) | |
| 398 { | |
| 399 if ( tab[i] != 0 ) | |
| 400 { | |
| 401 UINT64 k = tab[i] ; | |
| 402 for ( j = 0 ; j < (int)UNIT_SIZE ; ++j ) | |
| 403 { | |
| 404 if ( k & 1 ) | |
| 405 return j + UNIT_SIZE * i ; | |
| 406 k >>= 1 ; | |
| 407 } | |
| 408 } | |
| 409 } | |
| 410 | |
| 411 for ( ; i < in.asize ; ++i ) | |
| 412 { | |
| 413 if ( in.tab[i] != 0 ) | |
| 414 { | |
| 415 UINT64 k = in.tab[i] ; | |
| 416 for ( j = 0 ; j < (int)UNIT_SIZE ; ++j ) | |
| 417 { | |
| 418 if ( k & 1 ) | |
| 419 return j + UNIT_SIZE * i ; | |
| 420 k >>= 1 ; | |
| 421 } | |
| 422 } | |
| 423 } | |
| 424 return -1 ; | |
| 425 } | |
| 426 | |
| 427 void Duplicate( BitTable &in ) | |
| 428 { | |
| 429 if ( tab != NULL ) | |
| 430 delete [] tab ; | |
| 431 int i ; | |
| 432 size = in.size ; | |
| 433 asize = in.asize ; | |
| 434 tab = new UINT64[ asize ] ; | |
| 435 for ( i = 0 ; i < asize ; ++i ) | |
| 436 tab[i] = in.tab[i] ; | |
| 437 } | |
| 438 | |
| 439 /*void SetBulk( int ind, uint64_t val ) | |
| 440 { | |
| 441 tab[ind] = val ; | |
| 442 }*/ | |
| 443 | |
| 444 void Assign( BitTable &in ) | |
| 445 { | |
| 446 int i ; | |
| 447 for ( i = 0 ; i < asize ; ++i ) | |
| 448 tab[i] = in.tab[i] ; | |
| 449 } | |
| 450 | |
| 451 void Nullify() | |
| 452 { | |
| 453 tab = NULL ; | |
| 454 } | |
| 455 | |
| 456 int GetSize() | |
| 457 { | |
| 458 return size ; | |
| 459 } | |
| 460 | |
| 461 void Print() | |
| 462 { | |
| 463 int i ; | |
| 464 for ( i = 0 ; i < asize; ++i ) | |
| 465 printf( "%llu ", tab[i] ) ; | |
| 466 printf( "\n" ) ; | |
| 467 } | |
| 468 } ; | |
| 469 | |
| 470 | |
| 471 #endif |
