Skip to main content

Construct Hilbert Curves.

Project description

https://travis-ci.com/galtay/hilbertcurve.svg?branch=develop

Updates

Version 2.0

Version 2.0 introduces some breaking changes.

API Changes

Previous versions transformed a single distance to a vector or a single vector to a distance.

  • coordinates_from_distance(self, h: int) -> List[int]

  • distance_from_coordinates(self, x_in: List[int]) -> int

In version 2.0 coordinates -> point(s) and we add methods to handle multiple distances or multiple points. The match_type kwarg forces the output type to match the input type and all functions can handle tuples, lists, and ndarrays.

  • point_from_distance(self, distance: int) -> Iterable[int]

  • points_from_distances(self, distances: Iterable[int], match_type: bool=False) -> Iterable[Iterable[int]]

  • distance_from_point(self, point: Iterable[int]) -> int

  • distances_from_points(self, points: Iterable[Iterable[int]], match_type: bool=False) -> Iterable[int]

Multiprocessing

The methods that handle multiple distances or multiple points can take advantage of multiple cores. You can control this behavior using the n_procs kwarg when you create an instance of HilbertCurve.

n_procs (int): number of processes to use
    0 = dont use multiprocessing
   -1 = use all available processes
    any other positive integer = number of processes to use

Introduction

This is a package to convert between one dimensional distance along a Hilbert curve, h, and n-dimensional points, (x_0, x_1, ... x_n-1). There are two important parameters,

  • n – the number of dimensions (must be > 0)

  • p – the number of iterations used in constructing the Hilbert curve (must be > 0)

We consider an n-dimensional hypercube of side length 2^p. This hypercube contains 2^{n p} unit hypercubes (2^p along each dimension). The number of unit hypercubes determine the possible discrete distances along the Hilbert curve (indexed from 0 to 2^{n p} - 1).

Quickstart

Install the package with pip,

pip install hilbertcurve

You can calculate points given distances along a hilbert curve,

>>> from hilbertcurve.hilbertcurve import HilbertCurve
>>> p=1; n=2
>>> hilbert_curve = HilbertCurve(p, n)
>>> distances = list(range(4))
>>> points = hilbert_curve.points_from_distances(distances)
>>> for point, dist in zip(points, distances):
>>>     print(f'point(h={dist}) = {point}')

point(h=0) = [0, 0]
point(h=1) = [0, 1]
point(h=2) = [1, 1]
point(h=3) = [1, 0]

You can also calculate distances along a hilbert curve given points,

>>> points = [[0,0], [0,1], [1,1], [1,0]]
>>> distances = hilbert_curve.distances_from_points(points)
>>> for point, dist in zip(points, distances):
>>>     print(f'distance(x={point}) = {dist}')

distance(x=[0, 0]) = 0
distance(x=[0, 1]) = 1
distance(x=[1, 1]) = 2
distance(x=[1, 0]) = 3

(Absurdly) Large Integers

Due to the magic of arbitrarily large integers in Python, these calculations can be done with … well … arbitrarily large integers!

>>> p = 512; n = 10
>>> hilbert_curve = HilbertCurve(p, n)
>>> ii = 123456789101112131415161718192021222324252627282930
>>> point = hilbert_curve.points_from_distances([ii])[0]
>>> print(f'point = {point}')

point = [121075, 67332, 67326, 108879, 26637, 43346, 23848, 1551, 68130, 84004]

The calculations above represent the 512th iteration of the Hilbert curve in 10 dimensions. The maximum value along any coordinate axis is an integer with 155 digits and the maximum distance along the curve is an integer with 1542 digits. For comparison, an estimate of the number of atoms in the observable universe is 10^{82} (i.e. an integer with 83 digits).

Visuals

https://raw.githubusercontent.com/galtay/hilbertcurve/main/n2_p3.png

The figure above shows the first three iterations of the Hilbert curve in two (n=2) dimensions. The p=1 iteration is shown in red, p=2 in blue, and p=3 in black. For the p=3 iteration, distances, h, along the curve are labeled from 0 to 63 (i.e. from 0 to 2^{n p}-1). This package provides methods to translate between n-dimensional points and one dimensional distance. For example, between (x_0=4, x_1=6) and h=36. Note that the p=1 and p=2 iterations have been scaled and translated to the coordinate system of the p=3 iteration.

An animation of the same case in 3-D is available on YouTube. To watch the video, click the link below. Once the YouTube video loads, you can right click on it and turn “Loop” on to watch the curve rotate continuously.

https://img.youtube.com/vi/TfJEJidwkBQ/0.jpg

3-D Hilbert Curve Animation https://www.youtube.com/watch?v=TfJEJidwkBQ

Reference

This module is based on the C code provided in the 2004 article “Programming the Hilbert Curve” by John Skilling,

I was also helped by the discussion in the following stackoverflow post,

which points out a typo in the source code of the paper. The Skilling code provides two functions TransposetoAxes and AxestoTranspose. In this case, Transpose refers to a specific packing of the integer that represents distance along the Hilbert curve (see below for details) and Axes refer to the n-dimensional coordinates. Below is an excerpt from the documentation of Skilling’s code,

//+++++++++++++++++++++++++++ PUBLIC-DOMAIN SOFTWARE ++++++++++++++++++++++++++
// Functions: TransposetoAxes  AxestoTranspose
// Purpose:   Transform in-place between Hilbert transpose and geometrical axes
// Example:   b=5 bits for each of n=3 coordinates.
//            15-bit Hilbert integer = A B C D E F G H I J K L M N O is stored
//            as its Transpose
//                   X[0] = A D G J M                X[2]|
//                   X[1] = B E H K N    <------->       | /X[1]
//                   X[2] = C F I L O               axes |/
//                          high  low                    0------ X[0]
//            Axes are stored conveniently as b-bit integers.
// Author:    John Skilling  20 Apr 2001 to 11 Oct 2003

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hilbertcurve-2.0.3.tar.gz (56.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

hilbertcurve-2.0.3-py3-none-any.whl (7.9 kB view details)

Uploaded Python 3

File details

Details for the file hilbertcurve-2.0.3.tar.gz.

File metadata

  • Download URL: hilbertcurve-2.0.3.tar.gz
  • Upload date:
  • Size: 56.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/45.2.0.post20200210 requests-toolbelt/0.9.1 tqdm/4.42.1 CPython/3.7.6

File hashes

Hashes for hilbertcurve-2.0.3.tar.gz
Algorithm Hash digest
SHA256 735e2302d19546ad92300b04a8e2e0b04d5b48230a083b1ddc9f0f080679da11
MD5 91eea255bb6bb0469556b814540bf6f2
BLAKE2b-256 720cde79df4902859dda5ce167eec6fa5d721cf26696b71751320ff5e0a485bc

See more details on using hashes here.

File details

Details for the file hilbertcurve-2.0.3-py3-none-any.whl.

File metadata

  • Download URL: hilbertcurve-2.0.3-py3-none-any.whl
  • Upload date:
  • Size: 7.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/45.2.0.post20200210 requests-toolbelt/0.9.1 tqdm/4.42.1 CPython/3.7.6

File hashes

Hashes for hilbertcurve-2.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 95f5a468ec2b9c1d40697038935e008edda42395ad9453c3eaeb937fd2075062
MD5 3625ab2419b7404687ad47f44e4d4fcc
BLAKE2b-256 4f766fb21a1d3f492c794024eadb468c2bc27f0585efbe46d11f86f2865494db

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page