+++ /dev/null
-/* Tests for multidimensional Hilbert curves */
-
-#define LOCAL_DEBUG
-
-#include "lib/lib.h"
-#include "lib/mempool.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <math.h>
-
-static struct mempool *pool;
-
-static uns dim;
-static uns order;
-
-static inline void
-rand_vec(uns *vec)
-{
- for (uns i = 0; i < dim; i++)
- vec[i] = (uns)rand() >> (32 - order);
-}
-
-static byte *
-print_vec(uns *vec)
-{
- byte *s = mp_alloc(pool, dim * 16), *res = s;
- *s++ = '(';
- for (uns i = 0; i < dim; i++)
- {
- if (i)
- *s++ = ' ';
- s += sprintf(s, "%x", vec[i]);
- }
- *s++ = ')';
- *s = 0;
- return res;
-}
-
-static inline int
-cmp_vec(uns *vec1, uns *vec2)
-{
- for (uns i = dim; i--; )
- if (vec1[i] < vec2[i])
- return -1;
- else if (vec1[i] > vec2[i])
- return 1;
- return 0;
-}
-
-#if 0
-static long double
-param_dist(uns *vec1, uns *vec2)
-{
- long double d1 = 0, d2 = 0;
- for (uns i = 0; i < dim; i++)
- {
- d1 = (d1 + vec1[i]) / ((u64)1 << order);
- d2 = (d2 + vec2[i]) / ((u64)1 << order);
- }
- return fabsl(d1 - d2);
-}
-
-static long double
-vec_dist(uns *vec1, uns *vec2)
-{
- long double d = 0;
- for (uns i = 0; i < dim; i++)
- {
- long double x = fabsl(vec1[i] - vec2[i]) / ((u64)1 << order);
- d += x * x;
- }
- return sqrtl(d);
-}
-#endif
-
-#define HILBERT_PREFIX(x) test1_##x
-#define HILBERT_DIM dim
-#define HILBERT_ORDER order
-#define HILBERT_WANT_DECODE
-#define HILBERT_WANT_ENCODE
-#include "images/hilbert.h"
-
-static void
-test1(void)
-{
- uns a[32], b[32], c[32];
- for (dim = 2; dim <= 8; dim++)
- for (order = 8; order <= 32; order++)
- for (uns i = 0; i < 1000; i++)
- {
- rand_vec(a);
- test1_encode(b, a);
- test1_decode(c, b);
- if (cmp_vec(a, c))
- die("Error... dim=%d order=%d testnum=%d ... %s -> %s -> %s",
- dim, order, i, print_vec(a), print_vec(b), print_vec(c));
- }
-}
-
-#if 0
-#include "images/hilbert-origin.h"
-static void
-test_origin(void)
-{
- Hcode code;
- Point pt, pt2;
- pt.hcode[0] = 0x12345678;
- pt.hcode[1] = 0x654321;
- pt.hcode[2] = 0x11122233;
- code = H_encode(pt);
- pt2 = H_decode(code);
- DBG("origin: [%08x, %08x, %08x] --> [%08x, %08x %08x] --> [%08x, %08x %08x]",
- pt.hcode[0], pt.hcode[1], pt.hcode[2], code.hcode[0], code.hcode[1], code.hcode[2], pt2.hcode[0], pt2.hcode[1], pt2.hcode[2]);
-}
-#endif
-
-int
-main(int argc UNUSED, char **argv UNUSED)
-{
- pool = mp_new(1 << 16);
- test1();
- //test_origin();
- return 0;
-}
+++ /dev/null
-/*
- * Image Library -- multidimensional Hilbert curves
- *
- * (c) 2006 Pavel Charvat <pchar@ucw.cz>
- *
- * This software may be freely distributed and used according to the terms
- * of the GNU Lesser General Public License.
- *
- *
- * References:
- * - http://www.dcs.bbk.ac.uk/~jkl/mapping.c
- * (c) 2002 J.K.Lawder
- * - J.K. Lawder. Calculation of Mappings between One and n-dimensional Values
- * Using the Hilbert Space-Filling Curve. Technical Report JL1/00, Birkbeck
- * College, University of London, 2000.
- *
- * FIXME:
- * - the algorithm fails for some combinations of HILBERT_DIM and HILBERT_ORDER,
- * but it should be safe for HILBERT_DIM = 2..8, HILBERT_ORDER = 8..32
- * - clean and optimize the code
- */
-
-#ifndef HILBERT_PREFIX
-# error Undefined HILBERT_PREFIX
-#endif
-
-#define P(x) HILBERT_PREFIX(x)
-
-/*
- * HILBERT_DIM is the number of dimensions in space through which the
- * Hilbert Curve passes.
- * Don't use this implementation with values for HILBERT_DIM of > 31!
- * Also, make sure you use a 32 bit compiler!
- */
-#ifndef HILBERT_DIM
-# define HILBERT_DIM 2
-#endif
-
-#ifndef HILBERT_TYPE
-# define HILBERT_TYPE u32
-#endif
-
-#ifndef HILBERT_ORDER
-# define HILBERT_ORDER (8 * sizeof(HILBERT_TYPE))
-#endif
-
-typedef HILBERT_TYPE P(t);
-
-/*
- * retained for historical reasons: the number of bits in an attribute value:
- * effectively the order of a curve
- */
-#define NUMBITS HILBERT_ORDER
-
-/*
- * the number of bits in a word used to store an hcode (or in an element of
- * an array that's used)
- */
-#define WORDBITS HILBERT_ORDER
-
-#ifdef HILBERT_WANT_ENCODE
-/*
- * given the coordinates of a point, it finds the sequence number of the point
- * on the Hilbert Curve
- */
-static void
-P(encode) (P(t) *dest, P(t) *src)
-{
- P(t) mask = (P(t))1 << WORDBITS - 1, element, temp1, temp2,
- A, W = 0, S, tS, T, tT, J, P = 0, xJ;
- uns i = NUMBITS * HILBERT_DIM - HILBERT_DIM, j;
-
- for (j = 0; j < HILBERT_DIM; j++)
- dest[j] = 0;
- for (j = A = 0; j < HILBERT_DIM; j++)
- if (src[j] & mask)
- A |= (1 << HILBERT_DIM - 1 - j);
-
- S = tS = A;
-
- P |= S & (1 << HILBERT_DIM - 1);
- for (j = 1; j < HILBERT_DIM; j++)
- if( S & (1 << HILBERT_DIM - 1 - j) ^ (P >> 1) & (1 << HILBERT_DIM - 1 - j))
- P |= (1 << HILBERT_DIM - 1 - j);
-
- /* add in HILBERT_DIM bits to hcode */
- element = i / WORDBITS;
- if (i % WORDBITS > WORDBITS - HILBERT_DIM)
- {
- dest[element] |= P << i % WORDBITS;
- dest[element + 1] |= P >> WORDBITS - i % WORDBITS;
- }
- else
- dest[element] |= P << i - element * WORDBITS;
-
- J = HILBERT_DIM;
- for (j = 1; j < HILBERT_DIM; j++)
- if ((P >> j & 1) == (P & 1))
- continue;
- else
- break;
- if (j != HILBERT_DIM)
- J -= j;
- xJ = J - 1;
-
- if (P < 3)
- T = 0;
- else
- if (P % 2)
- T = (P - 1) ^ (P - 1) / 2;
- else
- T = (P - 2) ^ (P - 2) / 2;
- tT = T;
-
- for (i -= HILBERT_DIM, mask >>= 1; (int)i >= 0; i -= HILBERT_DIM, mask >>= 1)
- {
- for (j = A = 0; j < HILBERT_DIM; j++)
- if (src[j] & mask)
- A |= (1 << HILBERT_DIM - 1 - j);
-
- W ^= tT;
- tS = A ^ W;
- if (xJ % HILBERT_DIM != 0)
- {
- temp1 = tS << xJ % HILBERT_DIM;
- temp2 = tS >> HILBERT_DIM - xJ % HILBERT_DIM;
- S = temp1 | temp2;
- S &= ((P(t))1 << HILBERT_DIM) - 1;
- }
- else
- S = tS;
-
- P = S & (1 << HILBERT_DIM - 1);
- for (j = 1; j < HILBERT_DIM; j++)
- if( S & (1 << HILBERT_DIM - 1 - j) ^ (P >> 1) & (1 << HILBERT_DIM - 1 - j))
- P |= (1 << HILBERT_DIM - 1 - j);
-
- /* add in HILBERT_DIM bits to hcode */
- element = i / WORDBITS;
- if (i % WORDBITS > WORDBITS - HILBERT_DIM)
- {
- dest[element] |= P << i % WORDBITS;
- dest[element + 1] |= P >> WORDBITS - i % WORDBITS;
- }
- else
- dest[element] |= P << i - element * WORDBITS;
-
- if (i > 0)
- {
- if (P < 3)
- T = 0;
- else
- if (P % 2)
- T = (P - 1) ^ (P - 1) / 2;
- else
- T = (P - 2) ^ (P - 2) / 2;
-
- if (xJ % HILBERT_DIM != 0)
- {
- temp1 = T >> xJ % HILBERT_DIM;
- temp2 = T << HILBERT_DIM - xJ % HILBERT_DIM;
- tT = temp1 | temp2;
- tT &= ((P(t))1 << HILBERT_DIM) - 1;
- }
- else
- tT = T;
-
- J = HILBERT_DIM;
- for (j = 1; j < HILBERT_DIM; j++)
- if ((P >> j & 1) == (P & 1))
- continue;
- else
- break;
- if (j != HILBERT_DIM)
- J -= j;
-
- xJ += J - 1;
- /* J %= HILBERT_DIM; */
- }
- }
- for (j = 0; j < HILBERT_DIM; j++)
- dest[j] &= ~(P(t))0 >> (8 * sizeof(P(t)) - WORDBITS);
-}
-#endif
-
-#ifdef HILBERT_WANT_DECODE
-/*
- * given the sequence number of a point, it finds the coordinates of the point
- * on the Hilbert Curve
- */
-static void
-P(decode) (P(t) *dest, P(t) *src)
-{
- P(t) mask = (P(t))1 << WORDBITS - 1, element, temp1, temp2,
- A, W = 0, S, tS, T, tT, J, P = 0, xJ;
- uns i = NUMBITS * HILBERT_DIM - HILBERT_DIM, j;
-
- for (j = 0; j < HILBERT_DIM; j++)
- dest[j] = 0;
-
- /*--- P ---*/
- element = i / WORDBITS;
- P = src[element];
- if (i % WORDBITS > WORDBITS - HILBERT_DIM)
- {
- temp1 = src[element + 1];
- P >>= i % WORDBITS;
- temp1 <<= WORDBITS - i % WORDBITS;
- P |= temp1;
- }
- else
- P >>= i % WORDBITS; /* P is a HILBERT_DIM bit hcode */
-
- /* the & masks out spurious highbit values */
- if (HILBERT_DIM < WORDBITS)
- P &= (1 << HILBERT_DIM) -1;
-
- /*--- xJ ---*/
- J = HILBERT_DIM;
- for (j = 1; j < HILBERT_DIM; j++)
- if ((P >> j & 1) == (P & 1))
- continue;
- else
- break;
- if (j != HILBERT_DIM)
- J -= j;
- xJ = J - 1;
-
- /*--- S, tS, A ---*/
- A = S = tS = P ^ P / 2;
-
-
- /*--- T ---*/
- if (P < 3)
- T = 0;
- else
- if (P % 2)
- T = (P - 1) ^ (P - 1) / 2;
- else
- T = (P - 2) ^ (P - 2) / 2;
-
- /*--- tT ---*/
- tT = T;
-
- /*--- distrib bits to coords ---*/
- for (j = HILBERT_DIM - 1; P > 0; P >>=1, j--)
- if (P & 1)
- dest[j] |= mask;
-
-
- for (i -= HILBERT_DIM, mask >>= 1; (int)i >= 0; i -= HILBERT_DIM, mask >>= 1)
- {
- /*--- P ---*/
- element = i / WORDBITS;
- P = src[element];
- if (i % WORDBITS > WORDBITS - HILBERT_DIM)
- {
- temp1 = src[element + 1];
- P >>= i % WORDBITS;
- temp1 <<= WORDBITS - i % WORDBITS;
- P |= temp1;
- }
- else
- P >>= i % WORDBITS; /* P is a HILBERT_DIM bit hcode */
-
- /* the & masks out spurious highbit values */
- if (HILBERT_DIM < WORDBITS)
- P &= (1 << HILBERT_DIM) -1;
-
- /*--- S ---*/
- S = P ^ P / 2;
-
- /*--- tS ---*/
- if (xJ % HILBERT_DIM != 0)
- {
- temp1 = S >> xJ % HILBERT_DIM;
- temp2 = S << HILBERT_DIM - xJ % HILBERT_DIM;
- tS = temp1 | temp2;
- tS &= ((P(t))1 << HILBERT_DIM) - 1;
- }
- else
- tS = S;
-
- /*--- W ---*/
- W ^= tT;
-
- /*--- A ---*/
- A = W ^ tS;
-
- /*--- distrib bits to coords ---*/
- for (j = HILBERT_DIM - 1; A > 0; A >>=1, j--)
- if (A & 1)
- dest[j] |= mask;
-
- if (i > 0)
- {
- /*--- T ---*/
- if (P < 3)
- T = 0;
- else
- if (P % 2)
- T = (P - 1) ^ (P - 1) / 2;
- else
- T = (P - 2) ^ (P - 2) / 2;
-
- /*--- tT ---*/
- if (xJ % HILBERT_DIM != 0)
- {
- temp1 = T >> xJ % HILBERT_DIM;
- temp2 = T << HILBERT_DIM - xJ % HILBERT_DIM;
- tT = temp1 | temp2;
- tT &= ((P(t))1 << HILBERT_DIM) - 1;
- }
- else
- tT = T;
-
- /*--- xJ ---*/
- J = HILBERT_DIM;
- for (j = 1; j < HILBERT_DIM; j++)
- if ((P >> j & 1) == (P & 1))
- continue;
- else
- break;
- if (j != HILBERT_DIM)
- J -= j;
- xJ += J - 1;
- }
- }
-}
-#endif
-
-#undef P
-#undef HILBERT_PREFIX
-#undef HILBERT_DIM
-#undef HILBERT_TYPE
-#undef HILBERT_ORDER
-#undef HILBERT_WANT_DECODE
-#undef HILBERT_WANT_ENCODE
-#undef NUMBITS
-#undef WORDBITS