00001 #ifndef BMTRANS__H__INCLUDED__
00002 #define BMTRANS__H__INCLUDED__
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 namespace bm
00031 {
00032
00033
00034
00035
00036
00037 template<typename T, unsigned ROWS, unsigned COLS>
00038 struct tmatrix
00039 {
00040 typedef T value_type;
00041
00042 T BM_ALIGN16 value[ROWS][COLS] BM_ALIGN16ATTR;
00043
00044 enum params
00045 {
00046 n_rows = ROWS,
00047 n_columns = COLS
00048 };
00049
00050
00051
00052 struct rstat
00053 {
00054 unsigned bit_count;
00055 unsigned gap_count;
00056 bm::set_representation best_rep;
00057 };
00058
00059 static unsigned rows() { return ROWS; }
00060 static unsigned cols() { return COLS; }
00061
00062 const T* row(unsigned row_idx) const { return value[row_idx]; }
00063 T* row(unsigned row_idx) { return value[row_idx]; }
00064 };
00065
00066
00067
00068
00069
00070
00071 template<typename T, unsigned BPC>
00072 struct bit_grabber
00073 {
00074 static
00075 unsigned get(const T*, unsigned)
00076 {
00077 BM_ASSERT(0); return 0;
00078 }
00079 };
00080
00081 template<>
00082 struct bit_grabber<unsigned, 32>
00083 {
00084 static
00085 unsigned get(const unsigned* arr, unsigned j)
00086 {
00087 return (((arr[0] >> j) & 1) << 0) |
00088 (((arr[1] >> j) & 1) << 1) |
00089 (((arr[2] >> j) & 1) << 2) |
00090 (((arr[3] >> j) & 1) << 3) |
00091 (((arr[4] >> j) & 1) << 4) |
00092 (((arr[5] >> j) & 1) << 5) |
00093 (((arr[6] >> j) & 1) << 6) |
00094 (((arr[7] >> j) & 1) << 7) |
00095 (((arr[8] >> j) & 1) << 8) |
00096 (((arr[9] >> j) & 1) << 9) |
00097 (((arr[10]>> j) & 1) << 10)|
00098 (((arr[11]>> j) & 1) << 11)|
00099 (((arr[12]>> j) & 1) << 12)|
00100 (((arr[13]>> j) & 1) << 13)|
00101 (((arr[14]>> j) & 1) << 14)|
00102 (((arr[15]>> j) & 1) << 15)|
00103 (((arr[16]>> j) & 1) << 16)|
00104 (((arr[17]>> j) & 1) << 17)|
00105 (((arr[18]>> j) & 1) << 18)|
00106 (((arr[19]>> j) & 1) << 19)|
00107 (((arr[20]>> j) & 1) << 20)|
00108 (((arr[21]>> j) & 1) << 21)|
00109 (((arr[22]>> j) & 1) << 22)|
00110 (((arr[23]>> j) & 1) << 23)|
00111 (((arr[24]>> j) & 1) << 24)|
00112 (((arr[25]>> j) & 1) << 25)|
00113 (((arr[26]>> j) & 1) << 26)|
00114 (((arr[27]>> j) & 1) << 27)|
00115 (((arr[28]>> j) & 1) << 28)|
00116 (((arr[29]>> j) & 1) << 29)|
00117 (((arr[30]>> j) & 1) << 30)|
00118 (((arr[31]>> j) & 1) << 31);
00119 }
00120 };
00121
00122 template<>
00123 struct bit_grabber<unsigned short, 16>
00124 {
00125 static
00126 unsigned get(const unsigned short* arr, unsigned j)
00127 {
00128 return (((arr[0] >> j) & 1) << 0) |
00129 (((arr[1] >> j) & 1) << 1) |
00130 (((arr[2] >> j) & 1) << 2) |
00131 (((arr[3] >> j) & 1) << 3) |
00132 (((arr[4] >> j) & 1) << 4) |
00133 (((arr[5] >> j) & 1) << 5) |
00134 (((arr[6] >> j) & 1) << 6) |
00135 (((arr[7] >> j) & 1) << 7) |
00136 (((arr[8] >> j) & 1) << 8) |
00137 (((arr[9] >> j) & 1) << 9) |
00138 (((arr[10]>> j) & 1) << 10)|
00139 (((arr[11]>> j) & 1) << 11)|
00140 (((arr[12]>> j) & 1) << 12)|
00141 (((arr[13]>> j) & 1) << 13)|
00142 (((arr[14]>> j) & 1) << 14)|
00143 (((arr[15]>> j) & 1) << 15);
00144 }
00145 };
00146
00147
00148 template<>
00149 struct bit_grabber<unsigned char, 8>
00150 {
00151 static
00152 unsigned get(const unsigned char* arr, unsigned j)
00153 {
00154 return (((arr[0] >> j) & 1) << 0) |
00155 (((arr[1] >> j) & 1) << 1) |
00156 (((arr[2] >> j) & 1) << 2) |
00157 (((arr[3] >> j) & 1) << 3) |
00158 (((arr[4] >> j) & 1) << 4) |
00159 (((arr[5] >> j) & 1) << 5) |
00160 (((arr[6] >> j) & 1) << 6) |
00161 (((arr[7] >> j) & 1) << 7);
00162 }
00163 };
00164
00165
00166
00167
00168
00169
00170 template<typename T, unsigned BPC, unsigned BPS>
00171 struct bit_trans_grabber
00172 {
00173 static
00174 T get(const T tmatrix[BPC][BPS], unsigned i, unsigned j)
00175 {
00176 T w = 0;
00177
00178
00179
00180
00181
00182
00183 w |=
00184 (((tmatrix[0][i] >> j) & 1) << 0) |
00185 (((tmatrix[1][i] >> j) & 1) << 1) |
00186 (((tmatrix[2][i] >> j) & 1) << 2) |
00187 (((tmatrix[3][i] >> j) & 1) << 3) |
00188 (((tmatrix[4][i] >> j) & 1) << 4) |
00189 (((tmatrix[5][i] >> j) & 1) << 5) |
00190 (((tmatrix[6][i] >> j) & 1) << 6) |
00191 (((tmatrix[7][i] >> j) & 1) << 7);
00192
00193
00194 if (BPC > 8)
00195 {
00196 w |=
00197 (((tmatrix[8][i] >> j) & 1) << 8) |
00198 (((tmatrix[9][i] >> j) & 1) << 9) |
00199 (((tmatrix[10][i] >> j) & 1) << 10) |
00200 (((tmatrix[11][i] >> j) & 1) << 11) |
00201 (((tmatrix[12][i] >> j) & 1) << 12) |
00202 (((tmatrix[13][i] >> j) & 1) << 13) |
00203 (((tmatrix[14][i] >> j) & 1) << 14) |
00204 (((tmatrix[15][i] >> j) & 1) << 15);
00205 }
00206
00207
00208 if (BPC > 16)
00209 {
00210 w |=
00211 (((tmatrix[16][i] >> j) & 1) << 16) |
00212 (((tmatrix[17][i] >> j) & 1) << 17) |
00213 (((tmatrix[18][i] >> j) & 1) << 18) |
00214 (((tmatrix[19][i] >> j) & 1) << 19) |
00215 (((tmatrix[20][i] >> j) & 1) << 20) |
00216 (((tmatrix[21][i] >> j) & 1) << 21) |
00217 (((tmatrix[22][i] >> j) & 1) << 22) |
00218 (((tmatrix[23][i] >> j) & 1) << 23) |
00219 (((tmatrix[24][i] >> j) & 1) << 24) |
00220 (((tmatrix[25][i] >> j) & 1) << 25) |
00221 (((tmatrix[26][i] >> j) & 1) << 26) |
00222 (((tmatrix[27][i] >> j) & 1) << 27) |
00223 (((tmatrix[28][i] >> j) & 1) << 28) |
00224 (((tmatrix[29][i] >> j) & 1) << 29) |
00225 (((tmatrix[30][i] >> j) & 1) << 30) |
00226 (((tmatrix[31][i] >> j) & 1) << 31);
00227 }
00228 return w;
00229 }
00230 };
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289 template<typename T, unsigned BPC, unsigned BPS>
00290 void vect_bit_transpose(const T* arr,
00291 unsigned arr_size,
00292 T tmatrix[BPC][BPS])
00293 {
00294 BM_ASSERT(sizeof(T)*8 == BPC);
00295
00296 unsigned col = 0;
00297 for (unsigned i = 0; i < arr_size;
00298 i+=BPC, arr+=BPC,
00299 ++col)
00300 {
00301 for (unsigned j = 0; j < BPC; ++j)
00302 {
00303 unsigned w =
00304 bm::bit_grabber<T, BPC>::get(arr, j);
00305 T* row = tmatrix[j];
00306 row[col] = (T)w;
00307 }
00308 }
00309 }
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322 template<typename T, unsigned BPC, unsigned BPS>
00323 void vect_bit_trestore(const T tmatrix[BPC][BPS],
00324 T* arr)
00325 {
00326 unsigned col = 0;
00327 for (unsigned i = 0; i < BPS; ++i)
00328 {
00329 for (unsigned j = 0; j < BPC; ++j, ++col)
00330 {
00331 arr[col] =
00332 bm::bit_trans_grabber<T, BPC, BPS>::get(tmatrix, i, j);
00333 }
00334 }
00335 }
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347 template<typename T, unsigned BPC, unsigned BPS>
00348 void tmatrix_distance(const T tmatrix[BPC][BPS],
00349 unsigned distance[BPC][BPC])
00350 {
00351 for (unsigned i = 0; i < BPC; ++i)
00352 {
00353 const T* r1 = tmatrix[i];
00354 const T* r1_end = r1 + BPS;
00355 distance[i][i] =
00356 bm::bit_block_calc_count((bm::word_t*)r1, (bm::word_t*)r1_end);
00357
00358 for (unsigned j = i + 1; j < BPC; ++j)
00359 {
00360 r1 = tmatrix[i];
00361 r1_end = r1 + BPS;
00362 unsigned count = 0;
00363
00364 {
00365 const T* r2 = tmatrix[i];
00366 const T* r2_end = r2 + BPS;
00367 const bm::word_t* r3 = (bm::word_t*)(tmatrix[j]);
00368 do {
00369 BM_INCWORD_BITCOUNT(count, r2[0] ^ r3[0]);
00370 BM_INCWORD_BITCOUNT(count, r2[1] ^ r3[1]);
00371 BM_INCWORD_BITCOUNT(count, r2[2] ^ r3[2]);
00372 BM_INCWORD_BITCOUNT(count, r2[3] ^ r3[3]);
00373 r2 += 4;
00374 r3 += 4;
00375 } while (r2 < r2_end);
00376 }
00377 distance[i][j] = count;
00378 }
00379 }
00380 }
00381
00382
00383
00384 const unsigned char ibpc_uncompr = 0;
00385 const unsigned char ibpc_all_zero= 1;
00386 const unsigned char ibpc_all_one = 2;
00387 const unsigned char ibpc_equiv = 3;
00388 const unsigned char ibpc_close = 4;
00389
00390 const unsigned char ibpc_end = 8;
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413 template<typename T, unsigned BPC, unsigned BPS>
00414 void bit_iblock_make_pcv(
00415 const unsigned distance[BPC][BPC],
00416 unsigned char* pc_vector)
00417 {
00418 BM_ASSERT(pc_vector);
00419
00420 for (unsigned i = 0; i < BPC; ++i)
00421 {
00422 unsigned char pc = ibpc_uncompr;
00423 unsigned row_bitcount = distance[i][i];
00424
00425 const unsigned total_possible_max = sizeof(T)*8*BPS;
00426 switch (row_bitcount)
00427 {
00428 case 0:
00429 pc_vector[i] = ibpc_all_zero;
00430 continue;
00431 case total_possible_max:
00432 pc_vector[i] = ibpc_all_one;
00433 continue;
00434 }
00435
00436
00437 if (row_bitcount > total_possible_max/2)
00438 {
00439 pc_vector[i] = ibpc_uncompr;
00440 continue;
00441 }
00442
00443
00444
00445 unsigned rmin = ~0;
00446 unsigned rmin_idx = 0;
00447 for (unsigned j = i + 1; j < BPC; ++j)
00448 {
00449 unsigned d = distance[i][j];
00450 if (d < rmin)
00451 {
00452 if (d == 0)
00453 {
00454 pc = ibpc_equiv | (j << 3);
00455 break;
00456 }
00457 rmin = d; rmin_idx = j;
00458 }
00459 }
00460
00461 if ((pc == 0) && rmin_idx && (rmin < row_bitcount))
00462 {
00463 pc = ibpc_close | (rmin_idx << 3);
00464 }
00465 pc_vector[i] = pc;
00466 }
00467 }
00468
00469
00470
00471
00472
00473 inline
00474 void bit_iblock_pcv_stat(const unsigned char* BMRESTRICT pc_vector,
00475 const unsigned char* BMRESTRICT pc_vector_end,
00476 unsigned* BMRESTRICT pc_vector_stat
00477 )
00478 {
00479 BM_ASSERT(pc_vector_stat);
00480
00481 do
00482 {
00483 unsigned ibpc = *pc_vector & 7;
00484 ++(pc_vector_stat[ibpc]);
00485 } while (++pc_vector < pc_vector_end);
00486 }
00487
00488
00489
00490
00491
00492
00493 inline
00494 void bit_iblock_reduce(
00495 const unsigned tmatrix[bm::set_block_plain_cnt][bm::set_block_plain_size],
00496 const unsigned char* BMRESTRICT pc_vector,
00497 const unsigned char* BMRESTRICT pc_vector_end,
00498 unsigned tmatrix_out[bm::set_block_plain_cnt][bm::set_block_plain_size])
00499 {
00500 ::memset(tmatrix_out, 0, sizeof(tmatrix_out));
00501
00502 unsigned row = 0;
00503 do
00504 {
00505 unsigned ibpc = *pc_vector & 7;
00506 unsigned n_row = *pc_vector >> 3;
00507
00508 switch(ibpc)
00509 {
00510 case bm::ibpc_uncompr:
00511 {
00512 const unsigned* r1 = tmatrix[row];
00513 unsigned* r_out = tmatrix_out[row];
00514 for (unsigned i = 0; i < bm::set_block_plain_size; ++i)
00515 {
00516 r_out[i] = r1[i];
00517 }
00518 }
00519 break;
00520 case bm::ibpc_all_zero:
00521 break;
00522 case bm::ibpc_all_one:
00523 break;
00524 case bm::ibpc_equiv:
00525 break;
00526 case bm::ibpc_close:
00527 {
00528 const unsigned* r1 = tmatrix[row];
00529 const unsigned* r2 = tmatrix[n_row];
00530 unsigned* r_out = tmatrix_out[row];
00531 for (unsigned i = 0; i < bm::set_block_plain_size; ++i)
00532 {
00533 r_out[i] = r1[i] ^ r2[i];
00534 }
00535 }
00536 break;
00537 default:
00538 BM_ASSERT(0);
00539 break;
00540 }
00541 ++row;
00542 } while (++pc_vector < pc_vector_end);
00543
00544 }
00545
00546
00547
00548
00549 template<class TMatrix>
00550 void tmatrix_reduce(TMatrix& tmatrix,
00551 const unsigned char* pc_vector,
00552 const unsigned effective_cols)
00553 {
00554 BM_ASSERT(pc_vector);
00555
00556 typedef typename TMatrix::value_type value_type;
00557
00558 const unsigned char* pc_vector_end = pc_vector + tmatrix.rows();
00559 unsigned row = 0;
00560 unsigned cols = effective_cols ? effective_cols : tmatrix.cols();
00561
00562 do
00563 {
00564 unsigned ibpc = *pc_vector & 7;
00565 switch(ibpc)
00566 {
00567 case bm::ibpc_uncompr:
00568 case bm::ibpc_all_zero:
00569 case bm::ibpc_all_one:
00570 case bm::ibpc_equiv:
00571 break;
00572 case bm::ibpc_close:
00573 {
00574 unsigned n_row = *pc_vector >> 3;
00575 BM_ASSERT(n_row > row);
00576
00577 value_type* r1 = tmatrix.row(row);
00578 const value_type* r2 = tmatrix.row(n_row);
00579 for (unsigned i = 0; i < cols; ++i)
00580 {
00581 r1[i] ^= r2[i];
00582 }
00583 }
00584 break;
00585 default:
00586 BM_ASSERT(0);
00587 break;
00588 }
00589 ++row;
00590 } while (++pc_vector < pc_vector_end);
00591 }
00592
00593
00594
00595
00596 template<class TMatrix>
00597 void tmatrix_restore(TMatrix& tmatrix,
00598 const unsigned char* pc_vector,
00599 const unsigned effective_cols)
00600 {
00601 BM_ASSERT(pc_vector);
00602
00603 typedef typename TMatrix::value_type value_type;
00604
00605 unsigned cols = effective_cols ? effective_cols : tmatrix.cols();
00606 for (int row = tmatrix.rows()-1; row >= 0; --row)
00607 {
00608 unsigned ibpc = pc_vector[row] & 7;
00609 int n_row = pc_vector[row] >> 3;
00610
00611 value_type* r1 = tmatrix.row(row);
00612
00613 switch(ibpc)
00614 {
00615 case bm::ibpc_uncompr:
00616 break;
00617 case bm::ibpc_all_zero:
00618 for (unsigned i = 0; i < cols; ++i)
00619 r1[i] = 0;
00620 break;
00621 case bm::ibpc_all_one:
00622 for (unsigned i = 0; i < cols; ++i)
00623 r1[i] = ~0;
00624 break;
00625 case bm::ibpc_equiv:
00626 {
00627 BM_ASSERT(n_row > row);
00628 const value_type* r2 = tmatrix.row(n_row);
00629 for (unsigned i = 0; i < cols; ++i)
00630 r1[i] = r2[i];
00631 }
00632 break;
00633 case bm::ibpc_close:
00634 {
00635 BM_ASSERT(n_row > row);
00636 const value_type* r2 = tmatrix.row(n_row);
00637 for (unsigned i = 0; i < cols; ++i)
00638 r1[i] ^= r2[i];
00639 }
00640 break;
00641 default:
00642 BM_ASSERT(0);
00643 break;
00644 }
00645 }
00646
00647 }
00648
00649
00650
00651
00652
00653
00654
00655 template<typename GT, typename BT>
00656 void gap_2_bitblock(const GT* BMRESTRICT gap_buf,
00657 BT* BMRESTRICT block,
00658 unsigned block_size)
00659 {
00660 GT* dgap_buf = (GT*) block;
00661 BT* block_end = block + block_size;
00662
00663 GT* dgap_end = gap_2_dgap<GT>(gap_buf, dgap_buf, false);
00664 GT* block_end2 = (GT*) block_end;
00665
00666
00667 for ( ;dgap_end < block_end2; ++dgap_end)
00668 {
00669 *dgap_end = 0;
00670 }
00671 }
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682 template<class TMatrix>
00683 void compute_tmatrix_rstat(const TMatrix& tmatrix,
00684 const unsigned char* pc_vector,
00685 typename TMatrix::rstat* rstat,
00686 unsigned effective_cols)
00687 {
00688 BM_ASSERT(rstat);
00689 typedef typename TMatrix::value_type value_type;
00690
00691 unsigned cols = effective_cols ? effective_cols : tmatrix.cols();
00692
00693 unsigned rows = tmatrix.rows();
00694
00695 for (unsigned i = 0; i < rows; ++i)
00696 {
00697 unsigned ibpc = pc_vector[i] & 7;
00698 switch(ibpc)
00699 {
00700 case bm::ibpc_all_zero:
00701 case bm::ibpc_all_one:
00702 case bm::ibpc_equiv:
00703 rstat[i].bit_count = rstat[i].gap_count = 0;
00704 rstat[i].best_rep = bm::set_bitset;
00705 break;
00706 case bm::ibpc_uncompr:
00707 case bm::ibpc_close:
00708 {
00709 const value_type* r1 = tmatrix.row(i);
00710 const value_type* r1_end = r1 + cols;
00711
00712 bm::bit_count_change32((bm::word_t*)r1, (bm::word_t*)r1_end,
00713 &rstat[i].bit_count, &rstat[i].gap_count);
00714
00715 const unsigned bitset_size = sizeof(value_type) * cols;
00716 const unsigned total_possible_max_bits = sizeof(value_type)*8*cols;
00717
00718 rstat[i].best_rep =
00719 bm::best_representation(rstat[i].bit_count,
00720 total_possible_max_bits,
00721 rstat[i].gap_count,
00722 bitset_size);
00723
00724 }
00725 break;
00726 default:
00727 BM_ASSERT(0);
00728 break;
00729 }
00730
00731 }
00732 }
00733
00734
00735
00736
00737
00738
00739
00740 template<typename TM>
00741 unsigned find_effective_columns(const TM& tmatrix)
00742 {
00743
00744 unsigned col = 1;
00745 for (unsigned i = 0; i < tmatrix.rows(); ++i)
00746 {
00747 const typename TM::value_type* row = tmatrix.value[i];
00748 for (unsigned j = 0; j < tmatrix.cols(); ++j)
00749 {
00750 if (row[j] != 0 && j > col)
00751 {
00752 col = j;
00753 }
00754 }
00755 }
00756 return col;
00757 }
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769 template<typename GT, typename BT, unsigned BLOCK_SIZE>
00770 class gap_transpose_engine
00771 {
00772 public:
00773
00774
00775
00776
00777 typedef
00778 tmatrix<GT, sizeof(GT)*8,
00779 (((BLOCK_SIZE * sizeof(unsigned)) / (sizeof(GT))) / (sizeof(GT) * 8))>
00780 tmatrix_type;
00781
00782 gap_transpose_engine() : eff_cols_(0)
00783 {}
00784
00785
00786
00787 void transpose(const GT* BMRESTRICT gap_buf,
00788 BT* BMRESTRICT tmp_block)
00789 {
00790 const unsigned arr_size = BLOCK_SIZE * sizeof(unsigned) / sizeof(GT);
00791
00792 BM_ASSERT(sizeof(tmatrix_.value) == tmatrix_type::n_columns *
00793 tmatrix_type::n_rows * sizeof(GT));
00794
00795
00796 gap_2_bitblock(gap_buf, tmp_block, BLOCK_SIZE);
00797
00798
00799 vect_bit_transpose<GT, tmatrix_type::n_rows, tmatrix_type::n_columns>
00800 ((GT*)tmp_block, arr_size, tmatrix_.value);
00801
00802
00803 eff_cols_ = find_effective_columns(tmatrix_);
00804 }
00805
00806
00807
00808 void transpose(const GT* BMRESTRICT garr,
00809 unsigned garr_size,
00810 BT* BMRESTRICT tmp_block)
00811 {
00812 BM_ASSERT(garr_size);
00813
00814 bit_block_set(tmp_block, 0);
00815 ::memcpy(tmp_block, garr, sizeof(GT)*garr_size);
00816
00817 const unsigned arr_size = BLOCK_SIZE * sizeof(unsigned) / sizeof(GT);
00818 BM_ASSERT(sizeof(tmatrix_.value) == tmatrix_type::n_columns *
00819 tmatrix_type::n_rows * sizeof(GT));
00820
00821 vect_bit_transpose<GT, tmatrix_type::n_rows, tmatrix_type::n_columns>
00822 ((GT*)tmp_block, arr_size, tmatrix_.value);
00823
00824
00825 eff_cols_ = find_effective_columns(tmatrix_);
00826
00827 }
00828
00829 void compute_distance_matrix()
00830 {
00831 tmatrix_distance<typename tmatrix_type::value_type,
00832 tmatrix_type::n_rows, tmatrix_type::n_columns>
00833 (tmatrix_.value, distance_);
00834
00835
00836 bit_iblock_make_pcv<unsigned char,
00837 tmatrix_type::n_rows, tmatrix_type::n_columns>
00838 (distance_, pc_vector_);
00839
00840 bit_iblock_pcv_stat(pc_vector_,
00841 pc_vector_ + tmatrix_type::n_rows,
00842 pc_vector_stat_);
00843 }
00844
00845 void reduce()
00846 {
00847 tmatrix_reduce(tmatrix_, pc_vector_, eff_cols_);
00848 compute_tmatrix_rstat(tmatrix_, pc_vector_, rstat_vector_, eff_cols_);
00849 }
00850
00851 void restore()
00852 {
00853 tmatrix_restore(tmatrix_, pc_vector_, eff_cols_);
00854 }
00855
00856
00857
00858
00859 void trestore(GT gap_head,
00860 GT* BMRESTRICT gap_buf,
00861 BT* BMRESTRICT tmp_block)
00862 {
00863 BM_ASSERT(sizeof(tmatrix_.value) == tmatrix_type::n_columns *
00864 tmatrix_type::n_rows * sizeof(GT));
00865
00866
00867 GT* gap_tmp = (GT*)tmp_block;
00868
00869
00870 vect_bit_trestore<GT, tmatrix_type::n_rows, tmatrix_type::n_columns>(tmatrix_.value, gap_tmp);
00871
00872
00873 gap_tmp = (GT*)tmp_block;
00874 dgap_2_gap<GT>(gap_tmp, gap_buf, gap_head);
00875 }
00876
00877 public:
00878
00879 tmatrix_type tmatrix_;
00880 unsigned eff_cols_;
00881 unsigned distance_[tmatrix_type::n_rows][tmatrix_type::n_rows];
00882 unsigned char pc_vector_[tmatrix_type::n_rows];
00883 unsigned pc_vector_stat_[bm::ibpc_end];
00884 typename tmatrix_type::rstat rstat_vector_[tmatrix_type::n_rows];
00885 };
00886
00887
00888 }
00889
00890 #endif