diff options
author | David Robillard <d@drobilla.net> | 2018-08-07 19:47:16 +0200 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2018-09-29 14:46:18 +0200 |
commit | 9fde28df12c6f9d45e9fcb60d6a609e416a1371a (patch) | |
tree | 8c2a24a7a344e15bd9b740202ae06f81dafe69f6 /chilbert/Algorithm.hpp | |
parent | 12a5b1aa57976b6a2be04efd224b7109df702f52 (diff) | |
download | chilbert-9fde28df12c6f9d45e9fcb60d6a609e416a1371a.tar.gz chilbert-9fde28df12c6f9d45e9fcb60d6a609e416a1371a.tar.bz2 chilbert-9fde28df12c6f9d45e9fcb60d6a609e416a1371a.zip |
Clean up remaining code and format consistently with clang-format
Diffstat (limited to 'chilbert/Algorithm.hpp')
-rw-r--r-- | chilbert/Algorithm.hpp | 403 |
1 files changed, 175 insertions, 228 deletions
diff --git a/chilbert/Algorithm.hpp b/chilbert/Algorithm.hpp index cdf76a8..d4896ec 100644 --- a/chilbert/Algorithm.hpp +++ b/chilbert/Algorithm.hpp @@ -19,9 +19,8 @@ #ifndef CHILBERT_ALGORITHM_HPP #define CHILBERT_ALGORITHM_HPP - -#include "chilbert/FixBitVec.hpp" #include "chilbert/BigBitVec.hpp" +#include "chilbert/FixBitVec.hpp" #include "chilbert/GetBits.hpp" #include "chilbert/GetLocation.hpp" #include "chilbert/GrayCodeRank.hpp" @@ -30,7 +29,6 @@ #include <cassert> - // Templated Hilbert functions. // P - is the class used to represent each dimension // of a multidimensional point. @@ -44,146 +42,125 @@ // Whatever you use, they must all be of consistent underlying // storage types. - // The dimension across which the Hilbert curve travels // principally. // D0 is d + 1, where d is the actual dimension you want to // walk across. // MUST HAVE 0 <= D0 < n -#define D0 1 +#define D0 1 + +namespace chilbert { -namespace chilbert -{ // 'Transforms' a point. -template<class I> -inline -void -transform( - const I &e, - int d, - int n, - I &a - ) +template <class I> +inline void +transform(const I& e, int d, int n, I& a) { a ^= e; - a.rotr( d, n );//#D d+1, n ); + a.rotr(d, n); //#D d+1, n ); } // Inverse 'transforms' a point. -template<class I> -inline -void -transformInv( - const I &e, - int d, - int n, - I &a - ) +template <class I> +inline void +transformInv(const I& e, int d, int n, I& a) { - a.rotl( d, n );//#D d+1, n ); + a.rotl(d, n); //#D d+1, n ); a ^= e; } // Update for method 1 (GrayCodeInv in the loop) -template<class I> -inline -void -update1( - const I &l, - const I &t, - const I &w, - int n, - I &e, - int &d - ) +template <class I> +inline void +update1(const I& l, const I& t, const I& w, int n, I& e, int& d) { - assert( 0 <= d && d < n ); + assert(0 <= d && d < n); e = l; - e.toggle( d ); //#D d == n-1 ? 0 : d+1 ); - + e.toggle(d); //#D d == n-1 ? 0 : d+1 ); + // Update direction d += 1 + t.fsb(); - if ( d >= n ) d -= n; - if ( d >= n ) d -= n; - assert( 0 <= d && d < n ); + if (d >= n) { + d -= n; + } + if (d >= n) { + d -= n; + } + assert(0 <= d && d < n); - if ( ! (w.rack() & 1) ) - e.toggle( d == 0 ? n-1 : d-1 ); //#D d ); + if (!(w.rack() & 1)) { + e.toggle(d == 0 ? n - 1 : d - 1); //#D d ); + } } // Update for method 2 (GrayCodeInv out of loop) -template<class I> -inline -void -update2( - const I &l, - const I &t, - const I &w, - int n, - I &e, - int &d - ) +template <class I> +inline void +update2(const I& l, const I& t, const I& w, int n, I& e, int& d) { - assert( 0 <= d && d < n ); + assert(0 <= d && d < n); e = l; - e.toggle( d );//#D d == n-1 ? 0 : d+1 ); - + e.toggle(d); //#D d == n-1 ? 0 : d+1 ); + // Update direction d += 1 + t.fsb(); - if ( d >= n ) d -= n; - if ( d >= n ) d -= n; - assert( 0 <= d && d < n ); + if (d >= n) { + d -= n; + } + if (d >= n) { + d -= n; + } + assert(0 <= d && d < n); } -template <class P,class H,class I> -inline -void -_coordsToIndex( - const P *p, - int m, - int n, - H &h, - I&& scratch, - int *ds = nullptr // #HACK - ) +template <class P, class H, class I> +inline void +_coordsToIndex(const P* p, + int m, + int n, + H& h, + I&& scratch, + int* ds = nullptr // #HACK +) { I e{std::move(scratch)}; I l{e}; I t{e}; I w{e}; - int d, i; - int ho = m*n; // Initialize e.reset(); - d = D0; l.reset(); h = 0U; // Work from MSB to LSB - for ( i = m-1; i >= 0; i-- ) - { + int d = D0; + int ho = m * n; + for (int i = m - 1; i >= 0; i--) { // #HACK - if ( ds ) ds[i] = d; - + if (ds) { + ds[i] = d; + } + // Get corner of sub-hypercube where point lies. - getLocation<P,I>(p,n,i,l); + getLocation<P, I>(p, n, i, l); // Mirror and reflect the location. // t = T_{(e,d)}(l) t = l; - transform<I>(e,d,n,t); + transform<I>(e, d, n, t); w = t; - if ( i < m-1 ) + if (i < m - 1) { w.toggle(n - 1); + } // Concatenate to the index. ho -= n; - setBits<H,I>(h,n,ho,w); + setBits<H, I>(h, n, ho, w); // Update the entry point and direction. - update2<I>(l,t,w,n,e,d); + update2<I>(l, t, w, n, e, d); } grayCodeInv(h); @@ -195,58 +172,46 @@ _coordsToIndex( // number of dimensions, it will use the most efficient // representation for interim variables. // Assumes h is big enough for the output (n*m bits!) -template<class P,class H> -inline -void -coordsToIndex( - const P *p, // [in ] point - int m, // [in ] precision of each dimension in bits - int n, // [in ] number of dimensions - H &h // [out] Hilbert index - ) +template <class P, class H> +inline void +coordsToIndex(const P* p, // [in ] point + int m, // [in ] precision of each dimension in bits + int n, // [in ] number of dimensions + H& h // [out] Hilbert index +) { - if ( n <= FBV_BITS ) { + if (n <= FBV_BITS) { // Intermediate variables will fit in fixed width - _coordsToIndex<P,H,CFixBitVec>(p,m,n,h, CFixBitVec{}); + _coordsToIndex<P, H, CFixBitVec>(p, m, n, h, CFixBitVec{}); } else { // Otherwise, they must be BigBitVecs - _coordsToIndex<P,H,CBigBitVec>(p,m,n,h, CBigBitVec(n)); + _coordsToIndex<P, H, CBigBitVec>(p, m, n, h, CBigBitVec(n)); } } - -template <class P,class H,class I> -inline -void -_indexToCoords( - P *p, - int m, - int n, - const H &h, - I&& scratch - ) +template <class P, class H, class I> +inline void +_indexToCoords(P* p, int m, int n, const H& h, I&& scratch) { I e{std::move(scratch)}; I l{e}; I t{e}; I w{e}; - int d, i, j, ho; // Initialize e.reset(); - d = D0; l.reset(); - for ( j = 0; j < n; j++ ) + for (int j = 0; j < n; j++) { p[j] = 0U; + } - ho = m*n; - // Work from MSB to LSB - for ( i = m-1; i >= 0; i-- ) - { + int d = D0; + int ho = m * n; + for (int i = m - 1; i >= 0; i--) { // Get the Hilbert index bits ho -= n; - getBits<H,I>(h,n,ho,w); + getBits<H, I>(h, n, ho, w); // t = GrayCode(w) t = w; @@ -255,14 +220,14 @@ _indexToCoords( // Reverse the transform // l = T^{-1}_{(e,d)}(t) l = t; - transformInv<I>(e,d,n,l); + transformInv<I>(e, d, n, l); // Distribute these bits // to the coordinates. - setLocation<P,I>(p,n,i,l); + setLocation<P, I>(p, n, i, l); // Update the entry point and direction. - update1<I>(l,t,w,n,e,d); + update1<I>(l, t, w, n, e, d); } } @@ -273,74 +238,62 @@ _indexToCoords( // representation for interim variables. // Assumes each entry of p is big enough to hold the // appropriate variable. -template<class P,class H> -inline -void -indexToCoords( - P *p, // [out] point - int m, // [in ] precision of each dimension in bits - int n, // [in ] number of dimensions - const H &h // [out] Hilbert index - ) +template <class P, class H> +inline void +indexToCoords(P* p, // [out] point + int m, // [in ] precision of each dimension in bits + int n, // [in ] number of dimensions + const H& h // [out] Hilbert index +) { - if ( n <= FBV_BITS ) { + if (n <= FBV_BITS) { // Intermediate variables will fit in fixed width - _indexToCoords<P,H,CFixBitVec>(p,m,n,h,CFixBitVec{}); + _indexToCoords<P, H, CFixBitVec>(p, m, n, h, CFixBitVec{}); } else { // Otherwise, they must be BigBitVecs - _indexToCoords<P,H,CBigBitVec>(p,m,n,h,CBigBitVec(n)); + _indexToCoords<P, H, CBigBitVec>(p, m, n, h, CBigBitVec(n)); } } -template <class P,class HC,class I> -inline -void -_coordsToCompactIndex( - const P *p, - const int *ms, - int n, - HC &hc, - I&& scratch, - int M = 0, - int m = 0 - ) +template <class P, class HC, class I> +inline void +_coordsToCompactIndex(const P* p, + const int* ms, + int n, + HC& hc, + I&& scratch, + int M = 0, + int m = 0) { - int i, mn; - int *ds; - - // Get total precision and max precision - // if not supplied - if ( M == 0 || m == 0 ) - { + // Get total precision and max precision if not supplied + if (M == 0 || m == 0) { M = m = 0; - for ( i = 0; i < n; i++ ) - { - if ( ms[i] > m ) m = ms[i]; + for (int i = 0; i < n; i++) { + if (ms[i] > m) { + m = ms[i]; + } M += ms[i]; } } - mn = m*n; + const int mn = m * n; // If we could avoid allocation altogether (ie: have a // fixed buffer allocated on the stack) then this increases // speed by a bit (4% when n=4, m=20) - ds = new int [ m ]; + int* const ds = new int[m]; - if ( mn > FBV_BITS ) - { + if (mn > FBV_BITS) { CBigBitVec h(mn); - _coordsToIndex<P,CBigBitVec,I>(p,m,n,h,std::move(scratch),ds); - compactIndex<CBigBitVec,HC>(ms,ds,n,m,h,hc); - } - else - { + _coordsToIndex<P, CBigBitVec, I>(p, m, n, h, std::move(scratch), ds); + compactIndex<CBigBitVec, HC>(ms, ds, n, m, h, hc); + } else { CFixBitVec h; - _coordsToIndex<P,CFixBitVec,I>(p,m,n,h,std::move(scratch),ds); - compactIndex<CFixBitVec,HC>(ms,ds,n,m,h,hc); + _coordsToIndex<P, CFixBitVec, I>(p, m, n, h, std::move(scratch), ds); + compactIndex<CFixBitVec, HC>(ms, ds, n, m, h, hc); } - delete [] ds; + delete[] ds; } // This is wrapper to the basic Hilbert curve index @@ -349,39 +302,35 @@ _coordsToCompactIndex( // number of dimensions, it will use the most efficient // representation for interim variables. // Assumes h is big enough for the output (n*m bits!) -template<class P,class HC> -inline -void -coordsToCompactIndex( - const P *p, // [in ] point - const int *ms,// [in ] precision of each dimension in bits - int n, // [in ] number of dimensions - HC &hc, // [out] Hilbert index - int M = 0, - int m = 0 - ) +template <class P, class HC> +inline void +coordsToCompactIndex(const P* p, // [in ] point + const int* ms, // [in ] precision of each dimension in bits + int n, // [in ] number of dimensions + HC& hc, // [out] Hilbert index + int M = 0, + int m = 0) { - if ( n <= FBV_BITS ) { + if (n <= FBV_BITS) { // Intermediate variables will fit in fixed width? - _coordsToCompactIndex<P,HC,CFixBitVec>(p,ms,n,hc,CFixBitVec{},M,m); + _coordsToCompactIndex<P, HC, CFixBitVec>( + p, ms, n, hc, CFixBitVec{}, M, m); } else { // Otherwise, they must be BigBitVecs. - _coordsToCompactIndex<P,HC,CBigBitVec>(p,ms,n,hc,CBigBitVec(n),M,m); + _coordsToCompactIndex<P, HC, CBigBitVec>( + p, ms, n, hc, CBigBitVec(n), M, m); } } -template <class P,class HC,class I> -inline -void -_compactIndexToCoords( - P *p, - const int *ms, - int n, - const HC &hc, - I&& scratch, - int M = 0, - int m = 0 - ) +template <class P, class HC, class I> +inline void +_compactIndexToCoords(P* p, + const int* ms, + int n, + const HC& hc, + I&& scratch, + int M = 0, + int m = 0) { I e{std::move(scratch)}; I l{e}; @@ -391,55 +340,55 @@ _compactIndexToCoords( I mask{e}; I ptrn{e}; - int d, i, j, b; - // Get total precision and max precision // if not supplied - if ( M == 0 || m == 0 ) - { + if (M == 0 || m == 0) { M = m = 0; - for ( i = 0; i < n; i++ ) - { - if ( ms[i] > m ) m = ms[i]; + for (int i = 0; i < n; i++) { + if (ms[i] > m) { + m = ms[i]; + } M += ms[i]; } } - + // Initialize e.reset(); - d = D0; l.reset(); - for ( j = 0; j < n; j++ ) + for (int j = 0; j < n; j++) { p[j] = 0; - + } + // Work from MSB to LSB - for ( i = m-1; i >= 0; i-- ) - { + int d = D0; + + for (int i = m - 1; i >= 0; i--) { // Get the mask and ptrn - extractMask<I>(ms,n,d,i,mask,b); + int b = 0; + extractMask<I>(ms, n, d, i, mask, b); ptrn = e; - ptrn.rotr(d,n);//#D ptrn.Rotr(d+1,n); + ptrn.rotr(d, n); //#D ptrn.Rotr(d+1,n); // Get the Hilbert index bits M -= b; r.reset(); // GetBits doesn't do this - getBits<HC,I>(hc,b,M,r); + getBits<HC, I>(hc, b, M, r); // w = GrayCodeRankInv(r) // t = GrayCode(w) - grayCodeRankInv<I>(mask,ptrn,r,n,b,t,w); + grayCodeRankInv<I>(mask, ptrn, r, n, b, t, w); // Reverse the transform // l = T^{-1}_{(e,d)}(t) l = t; - transformInv<I>(e,d,n,l); + transformInv<I>(e, d, n, l); // Distribute these bits // to the coordinates. - setLocation<P,I>(p,n,i,l); + setLocation<P, I>(p, n, i, l); // Update the entry point and direction. - update1<I>(l,t,w,n,e,d); + update1<I>(l, t, w, n, e, d); } } @@ -450,30 +399,28 @@ _compactIndexToCoords( // representation for interim variables. // Assumes each entry of p is big enough to hold the // appropriate variable. -template<class P,class HC> -inline -void -compactIndexToCoords( - P *p, // [out] point - const int *ms,// [in ] precision of each dimension in bits - int n, // [in ] number of dimensions - const HC &hc, // [out] Hilbert index - int M = 0, - int m = 0 - ) +template <class P, class HC> +inline void +compactIndexToCoords(P* p, // [out] point + const int* ms, // [in ] precision of each dimension in bits + int n, // [in ] number of dimensions + const HC& hc, // [out] Hilbert index + int M = 0, + int m = 0) { - if ( n <= FBV_BITS ) { + if (n <= FBV_BITS) { // Intermediate variables will fit in fixed width CFixBitVec scratch; - _compactIndexToCoords<P,HC,CFixBitVec>(p,ms,n,hc,CFixBitVec{},M,m); + _compactIndexToCoords<P, HC, CFixBitVec>( + p, ms, n, hc, CFixBitVec{}, M, m); } else { // Otherwise, they must be BigBitVecs CBigBitVec scratch(n); - _compactIndexToCoords<P,HC,CBigBitVec>(p,ms,n,hc,std::move(scratch),M,m); + _compactIndexToCoords<P, HC, CBigBitVec>( + p, ms, n, hc, std::move(scratch), M, m); } } -} - +} // namespace chilbert #endif |