aboutsummaryrefslogtreecommitdiffstats
path: root/chilbert/Algorithm.hpp
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2018-08-07 19:47:16 +0200
committerDavid Robillard <d@drobilla.net>2018-09-29 14:46:18 +0200
commit9fde28df12c6f9d45e9fcb60d6a609e416a1371a (patch)
tree8c2a24a7a344e15bd9b740202ae06f81dafe69f6 /chilbert/Algorithm.hpp
parent12a5b1aa57976b6a2be04efd224b7109df702f52 (diff)
downloadchilbert-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.hpp403
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