def point(self, idx): idx = utils.graycode(idx) p = [0]*self.dimension iwidth = self.bits * self.dimension for i in range(iwidth): b = utils.bitrange(idx, iwidth, i, i+1) << (iwidth-i-1)/self.dimension p[i%self.dimension] |= b return p
def hilbert_point(dimension, order, h): """ Convert an index on the Hilbert curve of the specified dimension and order to a set of point coordinates. """ # The bit widths in this function are: # p[*] - order # h - order*dimension # l - dimension # e - dimension hwidth = order*dimension e, d = 0, 0 p = [0]*dimension for i in range(order): w = utils.bitrange(h, hwidth, i*dimension, i*dimension+dimension) l = utils.graycode(w) l = itransform(e, d, dimension, l) for j in range(dimension): b = utils.bitrange(l, dimension, j, j+1) p[j] = utils.setbit(p[j], order, i, b) e = e ^ utils.lrot(entry(w), d+1, dimension) d = (d + direction(w, dimension) + 1)%dimension return p
def hilbert_point(dimension, order, h): """ Convert an index on the Hilbert curve of the specified dimension and order to a set of point coordinates. """ # The bit widths in this function are: # p[*] - order # h - order*dimension # l - dimension # e - dimension hwidth = order * dimension e, d = 0, 0 p = [0] * dimension for i in range(order): w = utils.bitrange(h, hwidth, i * dimension, i * dimension + dimension) l = utils.graycode(w) l = itransform(e, d, dimension, l) for j in range(dimension): b = utils.bitrange(l, dimension, j, j + 1) p[j] = utils.setbit(p[j], order, i, b) e = e ^ utils.lrot(entry(w), d + 1, dimension) d = (d + direction(w, dimension) + 1) % dimension return p
def test_transform(self): for width in range(2, 5): g = [utils.graycode(i) for i in range(2**width)] # Sanity: the gray sequence should be a Hilbert cube too self.is_hilbertcube(g) for e in range(2**width): for d in range(width): x = [hilbert.transform(e, d, width, i) for i in g] # From Lemma 2.11 of Hamilton assert hilbert.transform(e, d, width, e) == 0 assert hilbert.itransform(e, d, width, 0) == e # The base gray code starts at 0, and has a direction of width-1: if e == 0 and d == width-1: assert x == g self.is_hilbertcube(x) assert [hilbert.itransform(e, d, width, i) for i in x] == g # These values are from the example on p 18 of Hamilton assert hilbert.transform(0, 1, 2, 3) == 3 assert hilbert.transform(3, 0, 2, 2) == 2 assert hilbert.transform(3, 0, 2, 1) == 1
def test_transform(self): for width in range(2, 5): g = [utils.graycode(i) for i in range(2**width)] # Sanity: the gray sequence should be a Hilbert cube too self.is_hilbertcube(g) for e in range(2**width): for d in range(width): x = [hilbert.transform(e, d, width, i) for i in g] # From Lemma 2.11 of Hamilton assert hilbert.transform(e, d, width, e) == 0 assert hilbert.itransform(e, d, width, 0) == e # The base gray code starts at 0, and has a direction of width-1: if e == 0 and d == width - 1: assert x == g self.is_hilbertcube(x) assert [hilbert.itransform(e, d, width, i) for i in x] == g # These values are from the example on p 18 of Hamilton assert hilbert.transform(0, 1, 2, 3) == 3 assert hilbert.transform(3, 0, 2, 2) == 2 assert hilbert.transform(3, 0, 2, 1) == 1
def entry(x): if x == 0: return 0 else: return utils.graycode(2 * ((x - 1) / 2))
def test_igraycode(self): for i in range(10): assert utils.igraycode(utils.graycode(i)) == i assert utils.graycode(utils.igraycode(i)) == i
def test_graycode(self): assert utils.graycode(3) == 2 assert utils.graycode(4) == 6