34 #ifndef _H_HILBERTARRAY
35 #define _H_HILBERTARRAY
48 template<
typename T >
56 virtual void zax(
const T *__restrict__
const &x, T *__restrict__
const &y,
const T *__restrict__ &v,
const T *__restrict__
const &v_end ) = 0;
59 virtual void zxa(
const T *__restrict__
const &x, T *__restrict__
const &y,
const T *__restrict__ &v,
const T *__restrict__
const &v_end ) = 0;
71 virtual void moveToStart(
const T *__restrict__ &x, T *__restrict__ &y,
const T &v ) = 0;
74 virtual void moveToNext(
const T *__restrict__ &x, T *__restrict__ &y,
const T &v ) = 0;
89 template<
typename T,
typename I,
typename hI,
typename mI >
122 void decode(
const hI coor, mI &row, mI &col ) {
127 const unsigned char maxshift = 2 *
sizeof( mI ) >
sizeof( hI ) ? 4 *
sizeof( hI ) : 8 *
sizeof( mI ) ;
133 std::cout <<
"Decoding " << coor <<
"..." << std::endl;
137 mI mask =
static_cast< mI
>( 1 );
138 mask <<= maxshift - 1;
141 hI Imask1 =
static_cast< hI
>( 1ul ) << ( 2 * maxshift - 2 );
142 hI Imask2 =
static_cast< hI
>( 1ul ) << ( 2 * maxshift - 1 );
145 bool R[2][2] = {{
false,
false }, {
true,
true }};
146 bool C[2][2] = {{
false,
true }, {
true,
false }};
149 for( ; mask != 0; mask >>= 1, Imask1 >>= 2, Imask2 >>=2 ) {
152 const bool Imask1_true = (coor & Imask1) > 0;
153 const bool Imask2_true = (coor & Imask2) > 0;
154 const bool r = R[ Imask2_true ? 1 : 0 ][ Imask1_true ? 1 : 0 ];
155 const bool c = C[ Imask2_true ? 1 : 0 ][ Imask1_true ? 1 : 0 ];
158 std::cout << (&coor) <<
"@" << mask <<
", " << (coor & Imask2) << (coor & Imask1) <<
" --> " <<
"(" << r <<
", " << c <<
")" <<
", R={{"
159 << R[0][0] <<
"," << R[0][1] <<
"},{" << R[1][0] <<
"," << R[1][1] <<
"}}, C={{"
160 << C[0][0] <<
"," << C[0][1] <<
"},{" << C[1][0] <<
"," << C[1][1] <<
"}}" << std::endl;
172 if( Imask1_true == Imask2_true ) {
174 std::swap( R[0][0], R[1][0] );
175 std::swap( C[0][0], C[1][0] );
183 std::cout <<
"Decode complete: " << coor <<
" --> (" << row <<
", " << col <<
")" << std::endl;
200 void decode( hI &cur,
const I &inc, mI &row, mI &col ) {
211 const unsigned char maxshift = 2 *
sizeof( mI ) >
sizeof( hI ) ? 4 *
sizeof( hI ) : 8 *
sizeof( mI ) ;
214 mI mask =
static_cast< mI
>( 1 );
215 mask <<= maxshift - 1;
218 hI Imask1 =
static_cast< hI
>( 1ul ) << ( 2 * maxshift - 2 );
219 hI Imask2 =
static_cast< hI
>( 1ul ) << ( 2 * maxshift - 1 );
222 bool R[2][2] = {{
false,
false }, {
true,
true }};
223 bool C[2][2] = {{
false,
true }, {
true,
false }};
226 bool cascade =
false;
229 std::cout <<
"Partial decode: " << cur << std::endl;
233 for( ; mask != 0; mask >>= 1, Imask1 >>= 2, Imask2 >>=2 ) {
235 if( cascade || (cur & Imask1) != (old & Imask1) || (cur & Imask2) != (old & Imask2) ) {
238 const bool Imask1_true = (cur & Imask1) > 0;
239 const bool Imask2_true = (cur & Imask2) > 0;
240 const bool r = R[ Imask2_true ? 1 : 0 ][ Imask1_true ? 1 : 0 ];
241 const bool c = C[ Imask2_true ? 1 : 0 ][ Imask1_true ? 1 : 0 ];
243 std::cout << (cur & Imask2) << (cur & Imask1) <<
" --> " <<
"(" << r <<
", " << c <<
")" <<
", R={{"
244 << R[0][0] <<
"," << R[0][1] <<
"},{" << R[1][0] <<
"," << R[1][1] <<
"}}, C={{"
245 << C[0][0] <<
"," << C[0][1] <<
"},{" << C[1][0] <<
"," << C[1][1] <<
"}}" << std::endl;
256 if( Imask1_true == Imask2_true ) {
263 std::swap( R[0][0], R[1][0] );
264 std::swap( C[0][0], C[1][0] );
272 if( ((old & Imask1) > 0) == ((old & Imask2) > 0) )
276 if( ((cur & Imask1) > 0) == ((cur & Imask2) > 0) ) {
277 if( (cur & Imask1) ) {
278 std::swap( R[0][0], R[1][0] );
279 std::swap( C[0][0], C[1][0] );
294 bytes =
sizeof( hI ) * 2 +
sizeof( mI ) * 2 +
sizeof( I* );
297 if( input.size() == 0 ) {
303 array =
new I[ input.size() - 1 ];
305 bytes +=
sizeof( I ) * ( input.size() - 1 );
309 for(
size_t i = 0; i < input.size() - 1; ++i )
310 array[ i ] = static_cast< I >( input[ i + 1 ] );
323 return static_cast< ULI
>(
currow );
333 return static_cast< ULI
>(
curcol );
345 virtual void zxa(
const T *__restrict__
const &x, T *__restrict__
const &y,
const T *__restrict__ &v,
const T *__restrict__
const &v_end ) {
378 virtual void zax(
const T *__restrict__
const &x, T *__restrict__
const &y,
const T *__restrict__ &v,
const T *__restrict__
const &v_end ) {
401 while( v != v_end ) {
407 assert(
currow == checkR );
408 assert(
curcol == checkC );
409 size_t check1, check2;
432 virtual void moveToStart(
const T *__restrict__ &x, T *__restrict__ &y,
const T &v ) {
449 virtual void moveToNext(
const T *__restrict__ &x, T *__restrict__ &y,
const T &v ) {
467 unsigned char binlog(
unsigned long int x ) {
469 unsigned char ret = 0;
470 bool thereIsARemainder = x > 1 ? x & 1 :
false;
471 while( (x >>= 1) > 0 ) {
472 if( !thereIsARemainder && x > 1 )
473 thereIsARemainder = x & 1;
476 return ret + ( thereIsARemainder ? 1 : 0 );
483 unsigned char binlog(
BigInt x ) {
484 assert( !(x.
high == 0 && x.
low == 0) );
485 unsigned char ret = 0;
486 bool thereIsARemainder = x.
low > 1 ? x.
low & 1 :
false;
487 if( !thereIsARemainder && x.
high > 1 )
488 thereIsARemainder = x.
high & 1;
489 while( (x.
low >>= 1 ) > 0 ) {
490 if( !thereIsARemainder && x.
low > 1 )
491 thereIsARemainder = x.
low & 1;
494 while( (x.
high >>= 1 ) > 0 ) {
495 if( !thereIsARemainder && x.
high > 1 )
496 thereIsARemainder = x.
high & 1;
499 return ret + ( thereIsARemainder ? 1 : 0 );
503 template<
typename T >
504 HilbertArrayInterface< T >* getDiffArray(
const std::vector< BigInt > &values_in,
const unsigned long int m,
const unsigned long int n ) {
506 if( values_in.size() == 0 )
510 const unsigned char mSize = binlog( m ) > binlog( n ) ? binlog( m ) : binlog( n );
513 std::vector< BigInt >::const_iterator it = values_in.begin();
515 for( ++it; it != values_in.end(); ++it ) {
519 const unsigned char logMaxH = binlog( maxH );
523 it = values_in.begin() + 1;
524 unsigned long int curhigh = values_in[ 0 ].high;
525 unsigned long int curlow = values_in[ 0 ].low;
526 unsigned long int maxDiff = it->low;
527 std::vector< unsigned long int > values;
528 values.push_back( curlow );
529 for( ; it != values_in.end(); ++it ) {
530 const unsigned long int diffhigh = it->high - curhigh;
531 const unsigned long int difflow = it->low - curlow;
535 std::cerr <<
"Current implementation assumes increments of 64 bits or less, but a larger increment was found!" << std::endl;
536 exit( EXIT_FAILURE );
538 values.push_back( difflow );
539 if( maxDiff < difflow )
542 const unsigned char logMaxDiff = binlog( maxDiff );
544 std::cout <<
"Matrix index bitlength: " <<
static_cast< unsigned short int >( mSize ) <<
" (" << (m>n?m:n) <<
")" << std::endl;
545 std::cout <<
"Hilbert coordinate bitlength: " <<
static_cast< unsigned short int >( logMaxH ) <<
" (" << maxH.
high << maxH.
low <<
")" << std::endl;
546 std::cout <<
"Hilbert increment bitlength: " << static_cast< unsigned short int >( logMaxDiff ) <<
" (" << maxDiff <<
")" << std::endl;
550 if( logMaxDiff <= 8 ) {
553 }
else if( logMaxH <= 16 ) {
555 }
else if( logMaxH <= 32 ) {
557 }
else if( logMaxH <= 64 ) {
560 }
else if( logMaxDiff <= 16 ) {
563 }
else if( logMaxH <= 16 ) {
565 }
else if( logMaxH <= 32 ) {
567 }
else if( logMaxH <= 64 ) {
570 }
else if( logMaxDiff <= 32 ) {
573 }
else if( logMaxH <= 16 ) {
575 }
else if( logMaxH <= 32 ) {
577 }
else if( logMaxH <= 64 ) {
580 }
else if( logMaxDiff <= 64 ) {
583 }
else if( logMaxH <= 16 ) {
585 }
else if( logMaxH <= 32 ) {
587 }
else if( logMaxH <= 64 ) {
591 }
else if( mSize <= 16 ) {
592 if( logMaxDiff <= 8 ) {
595 }
else if( logMaxH <= 16 ) {
597 }
else if( logMaxH <= 32 ) {
599 }
else if( logMaxH <= 64 ) {
602 }
else if( logMaxDiff <= 16 ) {
605 }
else if( logMaxH <= 16 ) {
607 }
else if( logMaxH <= 32 ) {
609 }
else if( logMaxH <= 64 ) {
612 }
else if( logMaxDiff <= 32 ) {
615 }
else if( logMaxH <= 16 ) {
617 }
else if( logMaxH <= 32 ) {
619 }
else if( logMaxH <= 64 ) {
622 }
else if( logMaxDiff <= 64 ) {
625 }
else if( logMaxH <= 16 ) {
627 }
else if( logMaxH <= 32 ) {
629 }
else if( logMaxH <= 64 ) {
633 }
else if( mSize <= 32 ) {
634 if( logMaxDiff <= 8 ) {
637 }
else if( logMaxH <= 16 ) {
639 }
else if( logMaxH <= 32 ) {
641 }
else if( logMaxH <= 64 ) {
644 }
else if( logMaxDiff <= 16 ) {
647 }
else if( logMaxH <= 16 ) {
649 }
else if( logMaxH <= 32 ) {
651 }
else if( logMaxH <= 64 ) {
654 }
else if( logMaxDiff <= 32 ) {
657 }
else if( logMaxH <= 16 ) {
659 }
else if( logMaxH <= 32 ) {
661 }
else if( logMaxH <= 64 ) {
664 }
else if( logMaxDiff <= 64 ) {
667 }
else if( logMaxH <= 16 ) {
669 }
else if( logMaxH <= 32 ) {
671 }
else if( logMaxH <= 64 ) {
675 }
else if( mSize <= 64 ) {
676 if( logMaxDiff <= 8 ) {
679 }
else if( logMaxH <= 16 ) {
681 }
else if( logMaxH <= 32 ) {
683 }
else if( logMaxH <= 64 ) {
686 }
else if( logMaxDiff <= 16 ) {
689 }
else if( logMaxH <= 16 ) {
691 }
else if( logMaxH <= 32 ) {
693 }
else if( logMaxH <= 64 ) {
696 }
else if( logMaxDiff <= 32 ) {
699 }
else if( logMaxH <= 16 ) {
701 }
else if( logMaxH <= 32 ) {
703 }
else if( logMaxH <= 64 ) {
706 }
else if( logMaxDiff <= 64 ) {
709 }
else if( logMaxH <= 16 ) {
711 }
else if( logMaxH <= 32 ) {
713 }
else if( logMaxH <= 64 ) {
718 std::cerr <<
"Cannot handle matrix indices requiring " << mSize <<
" bits!" << std::endl;
719 exit( EXIT_FAILURE );
virtual void zax(const T *__restrict__ const &x, T *__restrict__ const &y, const T *__restrict__ &v, const T *__restrict__ const &v_end)
Flat implementation of the zax.
Definition: HilbertArray.hpp:378
hI start_coor
Hilbert start coordinate.
Definition: HilbertArray.hpp:95
unsigned long int high
Most significant bits.
Definition: BigInt.hpp:41
virtual void moveToNext(const T *__restrict__ &x, T *__restrict__ &y, const T &v)
Moves this interface and the two given vectors to the next position.
Definition: HilbertArray.hpp:449
Class providing an interface to an efficient storage of a 1D array of Hilbert coordinate increments...
Definition: HilbertArray.hpp:49
mI currow
Current row position.
Definition: HilbertArray.hpp:107
A 128-bit integer, with overloaded comparison operators.
Definition: BigInt.hpp:38
virtual ~HilbertArrayInterface()
Base deconstructor.
Definition: HilbertArray.hpp:77
I *__restrict__ curpos
Current position in the array.
Definition: HilbertArray.hpp:101
virtual void zax(const T *__restrict__ const &x, T *__restrict__ const &y, const T *__restrict__ &v, const T *__restrict__ const &v_end)=0
Does a zax-operation using the moveToStart and moveToNext functionalities.
virtual ULI getFirstRowIndex()
Gets the start-location of the first nonzero in this array.
Definition: HilbertArray.hpp:321
virtual ULI getFirstRowIndex()=0
Gets the first row index.
virtual size_t bytesUsed()=0
Gets the amount of storage used.
static void IntegerToHilbert(const size_t i, const size_t j, size_t &h1, size_t &h2)
New method, October 2010.
Definition: Matrix2HilbertCoordinates.cpp:48
mI curcol
Current column position.
Definition: HilbertArray.hpp:110
void decode(hI &cur, const I &inc, mI &row, mI &col)
Translates a Hilbert coordinate into a row and column index.
Definition: HilbertArray.hpp:200
virtual ~HilbertArray()
Base deconstructor.
Definition: HilbertArray.hpp:457
I * array
Index storage array.
Definition: HilbertArray.hpp:98
virtual void moveToStart(const T *__restrict__ &x, T *__restrict__ &y, const T &v)
Moves this interface to the start location and perform a single multiply-add there.
Definition: HilbertArray.hpp:432
virtual void moveToStart(const T *__restrict__ &x, T *__restrict__ &y, const T &v)=0
Moves this interface and the two given vectors to the start location.
Actual storage implementation.
Definition: HilbertArray.hpp:90
size_t bytes
Keeps track of memory use.
Definition: HilbertArray.hpp:113
virtual size_t bytesUsed()
Definition: HilbertArray.hpp:420
HilbertArray(const std::vector< unsigned long int > &input)
Base constructor.
Definition: HilbertArray.hpp:292
virtual void zxa(const T *__restrict__ const &x, T *__restrict__ const &y, const T *__restrict__ &v, const T *__restrict__ const &v_end)=0
Does a zxa-operation using the moveToStart and moveToNext functionalities.
virtual ULI getFirstColumnIndex()
Gets the start-location of the first nonzero in this array.
Definition: HilbertArray.hpp:331
hI curcoor
Current Hilbert coordinate.
Definition: HilbertArray.hpp:104
virtual void moveToNext(const T *__restrict__ &x, T *__restrict__ &y, const T &v)=0
Moves this interface and the two given vectors to the next position.
virtual ULI getFirstColumnIndex()=0
Gets the first column index.
void decode(const hI coor, mI &row, mI &col)
Translates a Hilbert coordinate into a row and column index.
Definition: HilbertArray.hpp:122
virtual void zxa(const T *__restrict__ const &x, T *__restrict__ const &y, const T *__restrict__ &v, const T *__restrict__ const &v_end)
Flat implementation of the zax.
Definition: HilbertArray.hpp:345
unsigned long int low
Least significant bits.
Definition: BigInt.hpp:44