BitMagic-C++
bmtrans.h
Go to the documentation of this file.
1#ifndef BMTRANS__H__INCLUDED__
2#define BMTRANS__H__INCLUDED__
3/*
4Copyright(c) 2002-2017 Anatoliy Kuznetsov(anatoliy_kuznetsov at yahoo.com)
5
6Licensed under the Apache License, Version 2.0 (the "License");
7you may not use this file except in compliance with the License.
8You may obtain a copy of the License at
9
10 http://www.apache.org/licenses/LICENSE-2.0
11
12Unless required by applicable law or agreed to in writing, software
13distributed under the License is distributed on an "AS IS" BASIS,
14WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15See the License for the specific language governing permissions and
16limitations under the License.
17
18For more information please visit: http://bitmagic.io
19*/
20
21/*! \file bmtrans.h
22 \brief Utilities for bit transposition (internal) (experimental!)
23*/
24
25#ifdef _MSC_VER
26#pragma warning( push )
27#pragma warning( disable : 4311 4312 4127)
28#endif
29
30#include "bmdef.h"
31
32namespace bm
33{
34
35/**
36 Mini-matrix for bit transposition purposes
37 @internal
38*/
39template<typename T, unsigned ROWS, unsigned COLS>
40struct tmatrix
41{
42 typedef T value_type;
43
44 T BM_VECT_ALIGN value[ROWS][COLS] BM_VECT_ALIGN_ATTR;
45
46 enum params
47 {
48 n_rows = ROWS,
49 n_columns = COLS
50 };
51
52
53 /// Row characteristics for transposed matrix
54 struct rstat
55 {
56 unsigned bit_count;
57 unsigned gap_count;
59 };
60
61 static unsigned rows() BMNOEXCEPT { return ROWS; }
62 static unsigned cols() BMNOEXCEPT { return COLS; }
63
64 const T* row(unsigned row_idx) const BMNOEXCEPT
65 {
66 BM_ASSERT(row_idx < ROWS);
67 return value[row_idx];
68 }
69 T* row(unsigned row_idx) BMNOEXCEPT
70 {
71 BM_ASSERT(row_idx < ROWS);
72 return value[row_idx];
73 }
74};
75
76
77/*!
78 Bit array grabber - template specitialization for various basic types
79 @internal
80*/
81template<typename T, unsigned BPC>
83{
84 static
85 unsigned get(const T*, unsigned)
86 {
87 BM_ASSERT(0); return 0;
88 }
89};
90
91template<>
92struct bit_grabber<unsigned, 32>
93{
94 static
95 unsigned get(const unsigned* arr, unsigned j)
96 {
97 return (((arr[0] >> j) & 1) << 0) |
98 (((arr[1] >> j) & 1) << 1) |
99 (((arr[2] >> j) & 1) << 2) |
100 (((arr[3] >> j) & 1) << 3) |
101 (((arr[4] >> j) & 1) << 4) |
102 (((arr[5] >> j) & 1) << 5) |
103 (((arr[6] >> j) & 1) << 6) |
104 (((arr[7] >> j) & 1) << 7) |
105 (((arr[8] >> j) & 1) << 8) |
106 (((arr[9] >> j) & 1) << 9) |
107 (((arr[10]>> j) & 1) << 10)|
108 (((arr[11]>> j) & 1) << 11)|
109 (((arr[12]>> j) & 1) << 12)|
110 (((arr[13]>> j) & 1) << 13)|
111 (((arr[14]>> j) & 1) << 14)|
112 (((arr[15]>> j) & 1) << 15)|
113 (((arr[16]>> j) & 1) << 16)|
114 (((arr[17]>> j) & 1) << 17)|
115 (((arr[18]>> j) & 1) << 18)|
116 (((arr[19]>> j) & 1) << 19)|
117 (((arr[20]>> j) & 1) << 20)|
118 (((arr[21]>> j) & 1) << 21)|
119 (((arr[22]>> j) & 1) << 22)|
120 (((arr[23]>> j) & 1) << 23)|
121 (((arr[24]>> j) & 1) << 24)|
122 (((arr[25]>> j) & 1) << 25)|
123 (((arr[26]>> j) & 1) << 26)|
124 (((arr[27]>> j) & 1) << 27)|
125 (((arr[28]>> j) & 1) << 28)|
126 (((arr[29]>> j) & 1) << 29)|
127 (((arr[30]>> j) & 1) << 30)|
128 (((arr[31]>> j) & 1) << 31);
129 }
130};
131
132template<>
133struct bit_grabber<unsigned short, 16>
134{
135 static
136 unsigned get(const unsigned short* arr, unsigned j)
137 {
138 return (((arr[0] >> j) & 1u) << 0u) |
139 (((arr[1] >> j) & 1u) << 1u) |
140 (((arr[2] >> j) & 1u) << 2u) |
141 (((arr[3] >> j) & 1u) << 3u) |
142 (((arr[4] >> j) & 1u) << 4u) |
143 (((arr[5] >> j) & 1u) << 5u) |
144 (((arr[6] >> j) & 1u) << 6u) |
145 (((arr[7] >> j) & 1u) << 7u) |
146 (((arr[8] >> j) & 1u) << 8u) |
147 (((arr[9] >> j) & 1u) << 9u) |
148 (((arr[10]>> j) & 1u) << 10u)|
149 (((arr[11]>> j) & 1u) << 11u)|
150 (((arr[12]>> j) & 1u) << 12u)|
151 (((arr[13]>> j) & 1u) << 13u)|
152 (((arr[14]>> j) & 1u) << 14u)|
153 (((arr[15]>> j) & 1u) << 15u);
154 }
155};
156
157
158template<>
159struct bit_grabber<unsigned char, 8>
160{
161 static
162 unsigned get(const unsigned char* arr, unsigned j)
163 {
164 return unsigned(
165 (((arr[0] >> j) & 1) << 0) |
166 (((arr[1] >> j) & 1) << 1) |
167 (((arr[2] >> j) & 1) << 2) |
168 (((arr[3] >> j) & 1) << 3) |
169 (((arr[4] >> j) & 1) << 4) |
170 (((arr[5] >> j) & 1) << 5) |
171 (((arr[6] >> j) & 1) << 6) |
172 (((arr[7] >> j) & 1) << 7));
173 }
174};
175
176
177/*!
178 Bit transpose matrix grabber - template specitialization for various basic types
179 @internal
180*/
181template<typename T, unsigned BPC, unsigned BPS>
183{
184 static
185 T get(const T tmatrix[BPC][BPS], unsigned i, unsigned j)
186 {
187 T w = 0;
188
189 // Next code hopes that compiler will completely
190 // eliminate ifs (all conditions are known at compile time)
191 // ( typically C++ compilers are smart to do that)
192
193 // 8-bit (minimum)
194 w |=
195 (((tmatrix[0][i] >> j) & 1) << 0) |
196 (((tmatrix[1][i] >> j) & 1) << 1) |
197 (((tmatrix[2][i] >> j) & 1) << 2) |
198 (((tmatrix[3][i] >> j) & 1) << 3) |
199 (((tmatrix[4][i] >> j) & 1) << 4) |
200 (((tmatrix[5][i] >> j) & 1) << 5) |
201 (((tmatrix[6][i] >> j) & 1) << 6) |
202 (((tmatrix[7][i] >> j) & 1) << 7);
203
204 // 16-bit
205 if (BPC > 8)
206 {
207 w |=
208 (((tmatrix[8][i] >> j) & 1) << 8) |
209 (((tmatrix[9][i] >> j) & 1) << 9) |
210 (((tmatrix[10][i] >> j) & 1) << 10) |
211 (((tmatrix[11][i] >> j) & 1) << 11) |
212 (((tmatrix[12][i] >> j) & 1) << 12) |
213 (((tmatrix[13][i] >> j) & 1) << 13) |
214 (((tmatrix[14][i] >> j) & 1) << 14) |
215 (((tmatrix[15][i] >> j) & 1) << 15);
216 }
217
218 // 32-bit
219 if (BPC > 16)
220 {
221 w |=
222 (((tmatrix[16][i] >> j) & 1) << 16) |
223 (((tmatrix[17][i] >> j) & 1) << 17) |
224 (((tmatrix[18][i] >> j) & 1) << 18) |
225 (((tmatrix[19][i] >> j) & 1) << 19) |
226 (((tmatrix[20][i] >> j) & 1) << 20) |
227 (((tmatrix[21][i] >> j) & 1) << 21) |
228 (((tmatrix[22][i] >> j) & 1) << 22) |
229 (((tmatrix[23][i] >> j) & 1) << 23) |
230 (((tmatrix[24][i] >> j) & 1) << 24) |
231 (((tmatrix[25][i] >> j) & 1) << 25) |
232 (((tmatrix[26][i] >> j) & 1) << 26) |
233 (((tmatrix[27][i] >> j) & 1) << 27) |
234 (((tmatrix[28][i] >> j) & 1) << 28) |
235 (((tmatrix[29][i] >> j) & 1) << 29) |
236 (((tmatrix[30][i] >> j) & 1) << 30) |
237 (((tmatrix[31][i] >> j) & 1) << 31);
238 }
239 return w;
240 }
241};
242
243
244
245/**
246 Generic bit-array transposition function
247 T - array type (any int)
248 BPC - bit plane count
249 BPS - bit plane size
250
251 \param arr - source array start
252 \param arr_size - source array size
253 \param tmatrix - destination bit matrix
254
255*/
256template<typename T, unsigned BPC, unsigned BPS>
257void vect_bit_transpose(const T* arr,
258 unsigned arr_size,
259 T tmatrix[BPC][BPS])
260{
261 BM_ASSERT(sizeof(T)*8 == BPC);
262
263 unsigned col = 0;
264 for (unsigned i = 0; i < arr_size;
265 i+=BPC, arr+=BPC,
266 ++col)
267 {
268 for (unsigned j = 0; j < BPC; ++j)
269 {
270 unsigned w =
272 T* row = tmatrix[j];
273 row[col] = (T)w;
274 } // for j
275 } // for i
276}
277
278
279/**
280 Restore bit array from the transposition matrix
281 T - array type (any int)
282 BPC - bit plane count
283 BPS - bit plane size
284
285 \param arr - dest array
286 \param tmatrix - source bit-slice matrix
287
288*/
289template<typename T, unsigned BPC, unsigned BPS>
290void vect_bit_trestore(const T tmatrix[BPC][BPS],
291 T* arr)
292{
293 unsigned col = 0;
294 for (unsigned i = 0; i < BPS; ++i)
295 {
296 for (unsigned j = 0; j < BPC; ++j, ++col)
297 {
298 arr[col] =
300 } // for j
301 } // for i
302}
303
304
305
306/*!
307 \brief Compute pairwise Row x Row Humming distances on planes(rows) of
308 the transposed bit block
309 \param tmatrix - bit-block transposition matrix (bit-planes)
310 \param distance - pairwise NxN Humming distance matrix (diagonal is popcnt)
311
312 @ingroup bitfunc
313*/
314template<typename T, unsigned BPC, unsigned BPS>
315void tmatrix_distance(const T tmatrix[BPC][BPS],
316 unsigned distance[BPC][BPC])
317{
318 for (unsigned i = 0; i < BPC; ++i)
319 {
320 const T* r1 = tmatrix[i];
321 distance[i][i] =
323
324 for (unsigned j = i + 1; j < BPC; ++j)
325 {
326 r1 = tmatrix[i];
327 unsigned count = 0;
328
329 {
330 const T* r2 = tmatrix[i];
331 const T* r2_end = r2 + BPS;
332 const bm::word_t* r3 = (bm::word_t*)(tmatrix[j]);
333 do {
334 count += bm::word_bitcount(r2[0] ^ r3[0]);
335 count += bm::word_bitcount(r2[1] ^ r3[1]);
336 count += bm::word_bitcount(r2[2] ^ r3[2]);
337 count += bm::word_bitcount(r2[3] ^ r3[3]);
338 r2 += 4;
339 r3 += 4;
340 } while (r2 < r2_end);
341 }
342 distance[i][j] = count;
343 } // for j
344 } // for i
345}
346
347
348
349const unsigned char ibpc_uncompr = 0; ///!< plane uncompressed
350const unsigned char ibpc_all_zero= 1; ///!< plane ALL ZERO
351const unsigned char ibpc_all_one = 2; ///!< plane ALL ONE
352const unsigned char ibpc_equiv = 3; ///!< plane is equal to plane M
353const unsigned char ibpc_close = 4; ///!< plane is close to plane M
354
355const unsigned char ibpc_end = 8; ///!< ibpc limiter
356
357
358/*!
359 \brief Make a compression descriptor vector for bit-planes
360
361 \param distance - pairwise distance matrix
362 \param pc_vector - OUT compression descriptor vector
363 <pre>
364 pc_vector[] format:
365 each element (pc_vector[i]) describes the plane compression:
366 first 3 bits - compression code:
367 0 - plane uncompressed
368 1 - plane is ALL ZERO (000000...)
369 2 - plane is ALL ONE (111111...)
370 3 - plane is equal to another plane J (5 high bits (max 31))
371 4 - plane is close (but not equal) to plane J
372 next 5 bits - number of plane used as a XOR expression
373 ( compression codes: 3,4 )
374 </pre>
375
376 @ingroup bitfunc
377*/
378template<typename T, unsigned BPC, unsigned BPS>
380 const unsigned distance[BPC][BPC],
381 unsigned char* pc_vector)
382{
383 BM_ASSERT(pc_vector);
384
385 for (unsigned i = 0; i < BPC; ++i)
386 {
387 unsigned char pc = ibpc_uncompr;
388 unsigned row_bitcount = distance[i][i];
389
390 const unsigned total_possible_max = sizeof(T)*8*BPS;
391 switch (row_bitcount)
392 {
393 case 0:
394 pc_vector[i] = ibpc_all_zero;
395 continue;
396 case total_possible_max:
397 pc_vector[i] = ibpc_all_one;
398 continue;
399 default:
400 break;
401 }
402
403 // Dense-populated set, leave it as is
404 if (row_bitcount > total_possible_max/2)
405 {
406 pc_vector[i] = ibpc_uncompr;
407 continue;
408 }
409
410 // scan for the closest neighbor
411 //
412 unsigned rmin = ~0u;
413 unsigned rmin_idx = 0;
414 for (unsigned j = i + 1; j < BPC; ++j)
415 {
416 unsigned d = distance[i][j];
417 if (d < rmin) // new minimum - closest plane
418 {
419 if (d == 0) // plane is complete duplicate of j
420 {
421 pc = (unsigned char)(ibpc_equiv | (j << 3));
422 break;
423 }
424 rmin = d; rmin_idx = j;
425 }
426 } // for j
427
428 if ((pc == 0) && rmin_idx && (rmin < row_bitcount)) // neighbor found
429 {
430 pc = (unsigned char)(ibpc_close | (rmin_idx << 3));
431 }
432 pc_vector[i] = pc;
433 } // for i
434}
435
436
437/*!
438 \brief Compute number of ibpc codes in pc_vector
439*/
440inline
441void bit_iblock_pcv_stat(const unsigned char* BMRESTRICT pc_vector,
442 const unsigned char* BMRESTRICT pc_vector_end,
443 unsigned* BMRESTRICT pc_vector_stat
444 )
445{
446 BM_ASSERT(pc_vector_stat);
447 // pc_vector_stat MUST be assigned to 0 before
448 do
449 {
450 unsigned ibpc = *pc_vector & 7;
451 ++(pc_vector_stat[ibpc]);
452 } while (++pc_vector < pc_vector_end);
453}
454
455
456
457/**
458 \brief Matrix reduction based on transformation pc vector
459*/
460inline
463 const unsigned char* BMRESTRICT pc_vector,
464 const unsigned char* BMRESTRICT pc_vector_end,
466{
467 ::memset(tmatrix_out, 0, bm::set_block_plane_cnt * sizeof(*tmatrix_out));
468 unsigned row = 0;
469 do
470 {
471 unsigned ibpc = *pc_vector & 7;
472 unsigned n_row = *pc_vector >> 3;
473
474 switch(ibpc)
475 {
476 case bm::ibpc_uncompr:
477 {
478 const unsigned* r1 = tmatrix[row];
479 unsigned* r_out = tmatrix_out[row];
480 for (unsigned i = 0; i < bm::set_block_plane_size; ++i)
481 {
482 r_out[i] = r1[i];
483 }
484 }
485 break;
487 break;
488 case bm::ibpc_all_one:
489 break;
490 case bm::ibpc_equiv:
491 break;
492 case bm::ibpc_close:
493 {
494 const unsigned* r1 = tmatrix[row];
495 const unsigned* r2 = tmatrix[n_row];
496 unsigned* r_out = tmatrix_out[row];
497 for (unsigned i = 0; i < bm::set_block_plane_size; ++i)
498 {
499 r_out[i] = r1[i] ^ r2[i];
500 } // for
501 }
502 break;
503 default:
504 BM_ASSERT(0);
505 break;
506 } // switch
507 ++row;
508 } while (++pc_vector < pc_vector_end);
509
510}
511
512/**
513 \brief Transposed Matrix reduction based on transformation pc vector
514*/
515template<class TMatrix>
516void tmatrix_reduce(TMatrix& tmatrix,
517 const unsigned char* pc_vector,
518 const unsigned effective_cols)
519{
520 BM_ASSERT(pc_vector);
521
522 typedef typename TMatrix::value_type value_type;
523
524 const unsigned char* pc_vector_end = pc_vector + tmatrix.rows();
525 unsigned row = 0;
526 unsigned cols = effective_cols ? effective_cols : tmatrix.cols();
527
528 do
529 {
530 unsigned ibpc = *pc_vector & 7;
531 switch(ibpc)
532 {
533 case bm::ibpc_uncompr:
535 case bm::ibpc_all_one:
536 case bm::ibpc_equiv:
537 break;
538 case bm::ibpc_close:
539 {
540 unsigned n_row = *pc_vector >> 3;
541 BM_ASSERT(n_row > row);
542
543 value_type* r1 = tmatrix.row(row);
544 const value_type* r2 = tmatrix.row(n_row);
545 for (unsigned i = 0; i < cols; ++i)
546 {
547 r1[i] ^= r2[i];
548 } // for
549 }
550 break;
551 default:
552 BM_ASSERT(0);
553 break;
554 } // switch
555 ++row;
556 } while (++pc_vector < pc_vector_end);
557}
558
559/**
560 \brief Transposed Matrix restore based on transformation pc vector
561*/
562template<class TMatrix>
564 const unsigned char* pc_vector,
565 const unsigned effective_cols)
566{
567 BM_ASSERT(pc_vector);
568
569 typedef typename TMatrix::value_type value_type;
570
571 unsigned cols = effective_cols ? effective_cols : tmatrix.cols();
572 for (unsigned row = tmatrix.rows()-1u; 1; --row)
573 {
574 unsigned ibpc = pc_vector[row] & 7u;
575 unsigned n_row = pc_vector[row] >> 3u;
576
577 value_type* r1 = tmatrix.row(unsigned(row));
578
579 switch(ibpc)
580 {
581 case bm::ibpc_uncompr:
582 break;
584 for (unsigned i = 0; i < cols; ++i)
585 r1[i] = 0;
586 break;
587 case bm::ibpc_all_one:
588 for (unsigned i = 0; i < cols; ++i)
589 r1[i] = (value_type)(~0);
590 break;
591 case bm::ibpc_equiv:
592 {
593 BM_ASSERT(n_row > row);
594 const value_type* r2 = tmatrix.row(n_row);
595 for (unsigned i = 0; i < cols; ++i)
596 r1[i] = r2[i];
597 }
598 break;
599 case bm::ibpc_close:
600 {
601 BM_ASSERT(n_row > row);
602 const value_type* r2 = tmatrix.row(n_row);
603 for (unsigned i = 0; i < cols; ++i)
604 r1[i] ^= r2[i];
605 }
606 break;
607 default:
608 BM_ASSERT(0);
609 break;
610 } // switch
611
612 if (row == 0)
613 break;
614 } // for
615
616}
617
618
619
620/**
621 \brief Copy GAP block body to bit block with DGap transformation
622 \internal
623*/
624template<typename GT, typename BT>
625void gap_2_bitblock(const GT* BMRESTRICT gap_buf,
626 BT* BMRESTRICT block,
627 unsigned block_size)
628{
629 GT* dgap_buf = (GT*) block;
630 BT* block_end = block + block_size;
631
632 GT* dgap_end = gap_2_dgap<GT>(gap_buf, dgap_buf, false);
633 GT* block_end2 = (GT*) block_end;
634
635 // zero the tail memory
636 for ( ;dgap_end < block_end2; ++dgap_end)
637 {
638 *dgap_end = 0;
639 }
640}
641
642#if 0
643/**
644 @brief Compute t-matrix rows statistics used for compression
645
646 @param tmatrix - transposed matrix
647 @param pc_vector - row content vector
648 @param rstat - output row vector
649 @param effective_cols - effective columns
650
651 @internal
652*/
653template<class TMatrix>
654void compute_tmatrix_rstat(const TMatrix& tmatrix,
655 const unsigned char* pc_vector,
656 typename TMatrix::rstat* rstat,
657 unsigned effective_cols)
658{
659 BM_ASSERT(rstat);
660 typedef typename TMatrix::value_type value_type;
661
662 unsigned cols = effective_cols ? effective_cols : tmatrix.cols();
663 //unsigned cols = tmatrix.cols();
664 unsigned rows = tmatrix.rows();
665
666 for (unsigned i = 0; i < rows; ++i)
667 {
668 unsigned ibpc = pc_vector[i] & 7;
669 switch(ibpc)
670 {
672 case bm::ibpc_all_one:
673 case bm::ibpc_equiv:
674 rstat[i].bit_count = rstat[i].gap_count = 0;
675 rstat[i].best_rep = bm::set_bitset;
676 break;
677 case bm::ibpc_uncompr:
678 case bm::ibpc_close:
679 {
680 const value_type* r1 = tmatrix.row(i);
681 const value_type* r1_end = r1 + cols;
682 // TODO: find how to deal with the potentially incorrect type-cast
683 bm::bit_count_change32((bm::word_t*)r1, (bm::word_t*)r1_end,
684 &rstat[i].bit_count, &rstat[i].gap_count);
685
686 const unsigned bitset_size = unsigned(sizeof(value_type) * cols);
687 const unsigned total_possible_max_bits = unsigned(sizeof(value_type)*8*cols);
688
689 rstat[i].best_rep =
690 bm::best_representation(rstat[i].bit_count,
691 total_possible_max_bits,
692 rstat[i].gap_count,
693 bitset_size);
694
695 }
696 break;
697 default:
698 BM_ASSERT(0);
699 break;
700 } // switch
701
702 } // for
703}
704#endif
705
706
707/**
708 \brief Compute effective right column border of the t-matrix
709 \internal
710*/
711template<typename TM>
713{
714 // TODO: need optimization in order not to scan the whole space
715 unsigned col = 1;
716 for (unsigned i = 0; i < tmatrix.rows(); ++i)
717 {
718 const typename TM::value_type* row = tmatrix.value[i];
719 for (unsigned j = 0; j < tmatrix.cols(); ++j)
720 {
721 if (row[j] != 0 && j > col)
722 {
723 col = j;
724 }
725 }
726 }
727 return col;
728}
729
730
731/**
732 \brief Bit-plane splicing of a GAP block
733
734 GT - gap word type
735 BT - block word type
736 BLOCK_SIZE - bit block size in words (works as a transposition basis)
737
738 @internal
739*/
740template<typename GT, typename BT, unsigned BLOCK_SIZE>
742{
743public:
744 /// cryptic calculation of equivalent size for the transpose matrix
745 /// based on BLOCK_SIZE and sizeof(GT)(16)
746 ///
747 /// matrix[size_of_gap*8][(Size_block_in_bytes / size_of_gap) / number_of_planes)]
748 typedef
750 static_cast<unsigned>(((BLOCK_SIZE * sizeof(unsigned)) / (sizeof(GT)))
751 / (sizeof(GT) * 8))>
753
755 {}
756
757 /// Transpose GAP block through a temp. block of aligned(!) memory
758 ///
759 void transpose(const GT* BMRESTRICT gap_buf,
760 BT* BMRESTRICT tmp_block)
761 {
762 const unsigned arr_size = BLOCK_SIZE * sizeof(unsigned) / sizeof(GT);
763
764 BM_ASSERT(sizeof(tmatrix_.value) == tmatrix_type::n_columns *
765 tmatrix_type::n_rows * sizeof(GT));
766
767 // load all GAP as D-GAP(but not head word) into aligned bit-block
768 gap_2_bitblock(gap_buf, tmp_block, BLOCK_SIZE);
769
770 // transpose
771 vect_bit_transpose<GT, tmatrix_type::n_rows, tmatrix_type::n_columns>
772 ((GT*)tmp_block, arr_size, tmatrix_.value);
773
774 // calculate number of non-zero columns
776 }
777
778 /// Transpose array of shorts
779 ///
780 void transpose(const GT* BMRESTRICT garr,
781 unsigned garr_size,
782 BT* BMRESTRICT tmp_block)
783 {
784 BM_ASSERT(garr_size);
785
786 bit_block_set(tmp_block, 0);
787 ::memcpy(tmp_block, garr, sizeof(GT)*garr_size);
788
789 const unsigned arr_size = BLOCK_SIZE * sizeof(unsigned) / sizeof(GT);
790 BM_ASSERT(sizeof(tmatrix_.value) == tmatrix_type::n_columns *
791 tmatrix_type::n_rows * sizeof(GT));
792 // transpose
793 vect_bit_transpose<GT, tmatrix_type::n_rows, tmatrix_type::n_columns>
794 ((GT*)tmp_block, arr_size, tmatrix_.value);
795
796 // calculate number of non-zero columns
798
799 }
800
802 {
805 (tmatrix_.value, distance_);
806
807 // make compression descriptor vector and statistics vector
808 bit_iblock_make_pcv<unsigned char,
811
815 }
816
817 void reduce()
818 {
820 //compute_tmatrix_rstat(tmatrix_, pc_vector_, rstat_vector_, eff_cols_);
821 }
822
823 void restore()
824 {
826 }
827
828
829 /// Restore GAP block from the transposed matrix
830 ///
831 void trestore(GT gap_head,
832 GT* BMRESTRICT gap_buf,
833 BT* BMRESTRICT tmp_block)
834 {
835 BM_ASSERT(sizeof(tmatrix_.value) == tmatrix_type::n_columns *
836 tmatrix_type::n_rows * sizeof(GT));
837
838 // restore into a temp buffer
839 GT* gap_tmp = (GT*)tmp_block;
840 //*gap_tmp++ = gap_head;
841
842 vect_bit_trestore<GT, tmatrix_type::n_rows, tmatrix_type::n_columns>(tmatrix_.value, gap_tmp);
843
844 // D-Gap to GAP block recalculation
845 gap_tmp = (GT*)tmp_block;
846 dgap_2_gap<GT>(gap_tmp, gap_buf, gap_head);
847 }
848
849public:
850// GT gap_head_;
852 unsigned eff_cols_;
856 typename tmatrix_type::rstat rstat_vector_[tmatrix_type::n_rows];
857};
858
859
860} // namespace bm
861
862
863#ifdef _MSC_VER
864#pragma warning( pop )
865#endif
866
867
868#endif
Definitions(internal)
#define BMRESTRICT
Definition: bmdef.h:203
#define BMNOEXCEPT
Definition: bmdef.h:82
#define BM_ASSERT
Definition: bmdef.h:139
#define BM_VECT_ALIGN
Definition: bmdef.h:320
Bit-plane splicing of a GAP block.
Definition: bmtrans.h:742
void compute_distance_matrix()
Definition: bmtrans.h:801
void transpose(const GT *BMRESTRICT garr, unsigned garr_size, BT *BMRESTRICT tmp_block)
Transpose array of shorts.
Definition: bmtrans.h:780
unsigned pc_vector_stat_[bm::ibpc_end]
Definition: bmtrans.h:855
tmatrix< GT, static_cast< unsigned >(sizeof(GT) *8), static_cast< unsigned >(((BLOCK_SIZE *sizeof(unsigned))/(sizeof(GT)))/(sizeof(GT) *8))> tmatrix_type
cryptic calculation of equivalent size for the transpose matrix based on BLOCK_SIZE and sizeof(GT)(16...
Definition: bmtrans.h:752
void trestore(GT gap_head, GT *BMRESTRICT gap_buf, BT *BMRESTRICT tmp_block)
Restore GAP block from the transposed matrix.
Definition: bmtrans.h:831
unsigned char pc_vector_[tmatrix_type::n_rows]
Definition: bmtrans.h:854
tmatrix_type tmatrix_
Definition: bmtrans.h:851
void transpose(const GT *BMRESTRICT gap_buf, BT *BMRESTRICT tmp_block)
Transpose GAP block through a temp.
Definition: bmtrans.h:759
tmatrix_type::rstat rstat_vector_[tmatrix_type::n_rows]
Definition: bmtrans.h:856
unsigned distance_[tmatrix_type::n_rows][tmatrix_type::n_rows]
Definition: bmtrans.h:853
BMFORCEINLINE bm::id_t word_bitcount(bm::id_t w) BMNOEXCEPT
Definition: bmutil.h:573
bm::id_t bit_block_count(const bm::word_t *block) BMNOEXCEPT
Bitcount for bit block.
Definition: bmfunc.h:5017
bm::set_representation best_representation(unsigned bit_count, unsigned total_possible_bitcount, unsigned gap_count, unsigned block_size) BMNOEXCEPT
Choose best representation for a bit-block.
Definition: bmfunc.h:8706
void tmatrix_distance(const T tmatrix[BPC][BPS], unsigned distance[BPC][BPC])
Compute pairwise Row x Row Humming distances on planes(rows) of the transposed bit block.
Definition: bmtrans.h:315
void bit_block_set(bm::word_t *BMRESTRICT dst, bm::word_t value) BMNOEXCEPT
Bitblock memset operation.
Definition: bmfunc.h:4422
void bit_iblock_make_pcv(const unsigned distance[BPC][BPC], unsigned char *pc_vector)
!< ibpc limiter
Definition: bmtrans.h:379
Definition: bm.h:78
const unsigned set_block_plane_cnt
Definition: bmconst.h:64
unsigned int word_t
Definition: bmconst.h:39
void gap_2_bitblock(const GT *BMRESTRICT gap_buf, BT *BMRESTRICT block, unsigned block_size)
Copy GAP block body to bit block with DGap transformation.
Definition: bmtrans.h:625
void tmatrix_reduce(TMatrix &tmatrix, const unsigned char *pc_vector, const unsigned effective_cols)
Transposed Matrix reduction based on transformation pc vector.
Definition: bmtrans.h:516
set_representation
set representation variants
Definition: bmconst.h:216
@ set_bitset
Simple bitset.
Definition: bmconst.h:217
unsigned find_effective_columns(const TM &tmatrix)
Compute effective right column border of the t-matrix.
Definition: bmtrans.h:712
const unsigned char ibpc_equiv
!< plane ALL ONE
Definition: bmtrans.h:352
void bit_iblock_reduce(const unsigned tmatrix[bm::set_block_plane_cnt][bm::set_block_plane_size], const unsigned char *BMRESTRICT pc_vector, const unsigned char *BMRESTRICT pc_vector_end, unsigned tmatrix_out[bm::set_block_plane_cnt][bm::set_block_plane_size])
Matrix reduction based on transformation pc vector.
Definition: bmtrans.h:461
void vect_bit_transpose(const T *arr, unsigned arr_size, T tmatrix[BPC][BPS])
Generic bit-array transposition function T - array type (any int) BPC - bit plane count BPS - bit pla...
Definition: bmtrans.h:257
void tmatrix_restore(TMatrix &tmatrix, const unsigned char *pc_vector, const unsigned effective_cols)
Transposed Matrix restore based on transformation pc vector.
Definition: bmtrans.h:563
void vect_bit_trestore(const T tmatrix[BPC][BPS], T *arr)
Restore bit array from the transposition matrix T - array type (any int) BPC - bit plane count BPS - ...
Definition: bmtrans.h:290
const unsigned char ibpc_close
!< plane is equal to plane M
Definition: bmtrans.h:353
const unsigned char ibpc_all_one
!< plane ALL ZERO
Definition: bmtrans.h:351
const unsigned char ibpc_all_zero
!< plane uncompressed
Definition: bmtrans.h:350
const unsigned set_block_plane_size
Definition: bmconst.h:63
void bit_iblock_pcv_stat(const unsigned char *BMRESTRICT pc_vector, const unsigned char *BMRESTRICT pc_vector_end, unsigned *BMRESTRICT pc_vector_stat)
Compute number of ibpc codes in pc_vector.
Definition: bmtrans.h:441
const unsigned char ibpc_uncompr
Definition: bmtrans.h:349
const unsigned char ibpc_end
!< plane is close to plane M
Definition: bmtrans.h:355
static unsigned get(const unsigned *arr, unsigned j)
Definition: bmtrans.h:95
static unsigned get(const unsigned char *arr, unsigned j)
Definition: bmtrans.h:162
static unsigned get(const unsigned short *arr, unsigned j)
Definition: bmtrans.h:136
static unsigned get(const T *, unsigned)
Definition: bmtrans.h:85
static T get(const T tmatrix[BPC][BPS], unsigned i, unsigned j)
Definition: bmtrans.h:185
Row characteristics for transposed matrix.
Definition: bmtrans.h:55
unsigned gap_count
Definition: bmtrans.h:57
unsigned bit_count
Definition: bmtrans.h:56
bm::set_representation best_rep
Definition: bmtrans.h:58
Mini-matrix for bit transposition purposes.
Definition: bmtrans.h:41
static unsigned rows() BMNOEXCEPT
Definition: bmtrans.h:61
static unsigned cols() BMNOEXCEPT
Definition: bmtrans.h:62
T * row(unsigned row_idx) BMNOEXCEPT
Definition: bmtrans.h:69
T value_type
Definition: bmtrans.h:42
T BM_VECT_ALIGN value[ROWS][COLS] BM_VECT_ALIGN_ATTR
Definition: bmtrans.h:44
@ n_columns
Definition: bmtrans.h:49
const T * row(unsigned row_idx) const BMNOEXCEPT
Definition: bmtrans.h:64