Module hilbert_mod


Uses:
    module kinds_mod
Types:
    private type hilbert_table
    public type hilbert_iter
Variables:
    integer (kind=i_k), private, parameter :: SFC_MAX_LEV = 12
    integer (kind=i_k), private, parameter :: SFC_DIMS = 3
    type (hilbert_table), private, parameter, dimension (0:23) :: tab = (/ hilbert_table ((/ 1, 3, -1, 2, 1, -3, -1 /), (/ 1, 2, 2, 20, 20, 4, 4, 5 /), (/ 0, 1, 5, 4, 6, 7, 3, 2 /), (/ 0, 1, 7, 6, 3, 2, 4, 5 /)), hilbert_table ((/ 3, 2, -3, 1, 3, -2, -3 /), (/ 6, 7, 7, 19, 19, 9, 9, 10 /), (/ 0, 4, 6, 2, 3, 7, 5, 1 /), (/ 0, 7, 3, 4, 1, 6, 2, 5 /)), hilbert_table ((/ 1, 2, -1, 3, 1, -2, -1 /), (/ 11, 0, 0, 23, 23, 14, 14, 15 /), (/ 0, 1, 3, 2, 6, 7, 5, 4 /), (/ 0, 1, 3, 2, 7, 6, 4, 5 /)), hilbert_table ((/ -1, -3, 1, 2, -1, 3, 1 /), (/ 16, 17, 17, 7, 7, 13, 13, 8 /), (/ 5, 4, 0, 1, 3, 2, 6, 7 /), (/ 2, 3, 5, 4, 1, 0, 6, 7 /)), hilbert_table ((/ 1, -2, -1, -3, 1, 2, -1 /), (/ 19, 14, 14, 10, 10, 0, 0, 22 /), (/ 6, 7, 5, 4, 0, 1, 3, 2 /), (/ 4, 5, 7, 6, 3, 2, 0, 1 /)), hilbert_table ((/ 3, -2, -3, -1, 3, 2, -3 /), (/ 23, 9, 9, 15, 15, 7, 7, 21 /), (/ 3, 7, 5, 1, 0, 4, 6, 2 /), (/ 4, 3, 7, 0, 5, 2, 6, 1 /)), hilbert_table ((/ 2, 1, -2, 3, 2, -1, -2 /), (/ 0, 11, 11, 13, 13, 15, 15, 14 /), (/ 0, 2, 3, 1, 5, 7, 6, 4 /), (/ 0, 3, 1, 2, 7, 4, 6, 5 /)), hilbert_table ((/ 3, 1, -3, 2, 3, -1, -3 /), (/ 2, 1, 1, 3, 3, 5, 5, 4 /), (/ 0, 4, 5, 1, 3, 7, 6, 2 /), (/ 0, 3, 7, 4, 1, 2, 6, 5 /)), hilbert_table ((/ -3, -2, 3, 1, -3, 2, 3 /), (/ 21, 18, 18, 11, 11, 20, 20, 23 /), (/ 6, 2, 0, 4, 5, 1, 3, 7 /), (/ 2, 5, 1, 6, 3, 4, 0, 7 /)), hilbert_table ((/ 3, -1, -3, -2, 3, 1, -3 /), (/ 13, 5, 5, 14, 14, 1, 1, 17 /), (/ 3, 7, 6, 2, 0, 4, 5, 1 /), (/ 4, 7, 3, 0, 5, 6, 2, 1 /)), hilbert_table ((/ 2, -1, -2, -3, 2, 1, -2 /), (/ 3, 15, 15, 4, 4, 11, 11, 12 /), (/ 5, 7, 6, 4, 0, 2, 3, 1 /), (/ 4, 7, 5, 6, 3, 0, 2, 1 /)), hilbert_table ((/ 2, 3, -2, 1, 2, -3, -2 /), (/ 7, 6, 6, 8, 8, 10, 10, 9 /), (/ 0, 2, 6, 4, 5, 7, 3, 1 /), (/ 0, 7, 1, 6, 3, 4, 2, 5 /)), hilbert_table ((/ -1, 3, 1, -2, -1, -3, 1 /), (/ 5, 13, 13, 18, 18, 17, 17, 1 /), (/ 3, 2, 6, 7, 5, 4, 0, 1 /), (/ 6, 7, 1, 0, 5, 4, 2, 3 /)), hilbert_table ((/ -1, -2, 1, 3, -1, 2, 1 /), (/ 22, 12, 12, 6, 6, 3, 3, 19 /), (/ 3, 2, 0, 1, 5, 4, 6, 7 /), (/ 2, 3, 1, 0, 5, 4, 6, 7 /)), hilbert_table ((/ 1, -3, -1, -2, 1, 3, -1 /), (/ 8, 4, 4, 9, 9, 2, 2, 16 /), (/ 6, 7, 3, 2, 0, 1, 5, 4 /), (/ 4, 5, 3, 2, 7, 6, 0, 1 /)), hilbert_table ((/ 2, -3, -2, -1, 2, 3, -2 /), (/ 20, 10, 10, 5, 5, 6, 6, 18 /), (/ 5, 7, 3, 1, 0, 2, 6, 4 /), (/ 4, 3, 5, 2, 7, 0, 6, 1 /)), hilbert_table ((/ -3, 2, 3, -1, -3, -2, 3 /), (/ 10, 20, 20, 22, 22, 18, 18, 6 /), (/ 5, 1, 3, 7, 6, 2, 0, 4 /), (/ 6, 1, 5, 2, 7, 0, 4, 3 /)), hilbert_table ((/ -1, 2, 1, -3, -1, -2, 1 /), (/ 15, 3, 3, 21, 21, 12, 12, 11 /), (/ 5, 4, 6, 7, 3, 2, 0, 1 /), (/ 6, 7, 5, 4, 1, 0, 2, 3 /)), hilbert_table ((/ -3, 1, 3, -2, -3, -1, 3 /), (/ 4, 8, 8, 12, 12, 16, 16, 2 /), (/ 6, 2, 3, 7, 5, 1, 0, 4 /), (/ 6, 5, 1, 2, 7, 4, 0, 3 /)), hilbert_table ((/ -2, -3, 2, 1, -2, 3, 2 /), (/ 18, 21, 21, 1, 1, 23, 23, 20 /), (/ 6, 4, 0, 2, 3, 1, 5, 7 /), (/ 2, 5, 3, 4, 1, 6, 0, 7 /)), hilbert_table ((/ -3, -1, 3, 2, -3, 1, 3 /), (/ 17, 16, 16, 0, 0, 8, 8, 13 /), (/ 5, 1, 0, 4, 6, 2, 3, 7 /), (/ 2, 1, 5, 6, 3, 0, 4, 7 /)), hilbert_table ((/ -2, 1, 2, -3, -2, -1, 2 /), (/ 14, 19, 19, 17, 17, 22, 22, 0 /), (/ 6, 4, 5, 7, 3, 1, 0, 2 /), (/ 6, 5, 7, 4, 1, 2, 0, 3 /)), hilbert_table ((/ -2, 3, 2, -1, -2, -3, 2 /), (/ 9, 23, 23, 16, 16, 21, 21, 7 /), (/ 3, 1, 5, 7, 6, 4, 0, 2 /), (/ 6, 1, 7, 0, 5, 2, 4, 3 /)), hilbert_table ((/ -2, -1, 2, 3, -2, 1, 2 /), (/ 12, 22, 22, 2, 2, 19, 19, 3 /), (/ 3, 1, 0, 2, 6, 4, 5, 7 /), (/ 2, 1, 3, 0, 5, 6, 4, 7 /)) /)
Subroutines and functions:
    public pure subroutine hilbert_c2i (lev, p, idx)
    public pure subroutine hilbert_i2c (lev, idx, p)
    public pure subroutine hilbert_c2i_qsz (lev, qsz, p, idx)
    public pure subroutine hilbert_i2c_qsz (lev, qsz, idx, p, iter)
    public pure subroutine hilbert_iter_init (iter, lev, opt_qsz)
    public pure subroutine hilbert_iter_set (iter, idx)
    public pure subroutine hilbert_iter_next (iter)

Simple 3D Hilbert curve subroutines. Based on a table description of the curve. Parts of the table came from http://wiki.tcl.tk/8723.

Routines accept position and hilbert-index starting at 1 (instead of 0 in hilbert.F90)

Author: Matthias Lieber


Description of Types

hilbert_table

private type hilbert_table
    integer (kind=i_k), dimension (0:6) :: mv
    integer (kind=i_k), dimension (0:7) :: next
    integer (kind=i_k), dimension (0:7) :: num2ref
    integer (kind=i_k), dimension (0:7) :: ref2num
end type hilbert_table
Components:
mv spatial moves of the curve
next next states when refinining (octant is sequence number)
num2ref sequence number on curve primitve to reference (spatial) octant
ref2num reference (spatial) octant to sequence number on curve primitve
Type for one entry in the 3D Hilbert curve description table.

Values of the mv item are:


hilbert_iter

public type hilbert_iter
    integer (kind=i_k) :: idx = -1
    integer (kind=i_k), dimension (SFC_DIMS) :: p = -1
    integer (kind=i_k) :: lev = -1
    integer (kind=i_k), dimension (SFC_DIMS) :: qsz = -1
    integer (kind=i_k) :: len = -1
    integer (kind=i_k) :: clev = -1
    integer (kind=i_k), dimension (SFC_MAX_LEV) :: s = -1
    integer (kind=i_k), dimension (SFC_MAX_LEV) :: c = -1
    integer (kind=i_K) :: jump_level = SFC_MAX_LEV + 1
end type hilbert_iter
Iterator to traverse the 3D Hilbert curve

Description of Subroutines and Functions

hilbert_c2i

public pure subroutine hilbert_c2i (lev, p, idx)
    integer (kind=i_k), intent(in) :: lev
    integer (kind=i_k), intent(in), dimension (3) :: p
    integer (kind=i_k), intent(out) :: idx
end subroutine hilbert_c2i
Parameters:
lev level of the hilbert curve (1=2x2x2, 2=4x4x4, 3=8x8x8, etc)
p 3D coordinates [1 ... 2^lev]
idx index on the 3D hilbert curve [1 ... (2^lev)^3]
Get index on curve at given 3D coordinate (coordinates-to-index).

Has logarithmic complexity: number of loop iterations = lev. Due to performance reasons, no checking of arguments is performend!


hilbert_i2c

public pure subroutine hilbert_i2c (lev, idx, p)
    integer (kind=i_k), intent(in) :: lev
    integer (kind=i_k), intent(in) :: idx
    integer (kind=i_k), intent(out), dimension (3) :: p
end subroutine hilbert_i2c
Parameters:
lev level of the hilbert curve (1=2x2x2, 2=4x4x4, 3=8x8x8, etc)
idx index on the 3D hilbert curve [1 ... (2^lev)^3 ]
p 3D coordinates [1 ... 2^lev]
Get 3D coordinate at given index on curve (index-to-coordinates).

Has logarithmic complexity: number of loop iterations = lev. Due to performance reasons, no checking of arguments is performend!


hilbert_c2i_qsz

public pure subroutine hilbert_c2i_qsz (lev, qsz, p, idx)
    integer (kind=i_k), intent(in) :: lev
    integer (kind=i_k), intent(in), dimension (3) :: qsz
    integer (kind=i_k), intent(in), dimension (3) :: p
    integer (kind=i_k), intent(out) :: idx
end subroutine hilbert_c2i_qsz
Parameters:
lev level of the hilbert curve (1=2x2x2, 2=4x4x4, 3=8x8x8, etc)
qsz query region size
p 3D coordinates [1 ... 2^lev]
idx index on the 3D hilbert curve [1 ... (2^lev)^3]
Get index on curve at given 3D coordinate (coordinates-to-index).

The size of the query region is restricted by qsz for each dimension. qsz must be <= lev**2 and pos must be <= qsz.

Has logarithmic complexity: number of loop iterations = lev. Due to performance reasons, no checking of arguments is performend!


hilbert_i2c_qsz

public pure subroutine hilbert_i2c_qsz (lev, qsz, idx, p, iter)
    integer (kind=i_k), intent(in) :: lev
    integer (kind=i_k), intent(in), dimension (3) :: qsz
    integer (kind=i_k), intent(in) :: idx
    integer (kind=i_k), intent(out), dimension (3) :: p
    type (hilbert_iter), optional, intent(inout) :: iter
end subroutine hilbert_i2c_qsz
Parameters:
lev level of the hilbert curve (1=2x2x2, 2=4x4x4, 3=8x8x8, etc)
qsz query region size
idx index on the 3D hilbert curve [1 ... (2^lev)^3 ]
p 3D coordinates [1 ... 2^lev]
iter for internal use only
Get 3D coordinate at given index on curve (index-to-coordinates).

The size of the query region is restricted by qsz for each dimension. qsz must be <= lev**2 and pos must be <= qsz.

Has logarithmic complexity: number of loop iterations = lev. Due to performance reasons, no checking of arguments is performend!


hilbert_iter_init

public pure subroutine hilbert_iter_init (iter, lev, opt_qsz)
    type (hilbert_iter), intent(inout) :: iter
    integer (kind=i_k), intent(in) :: lev
    integer (kind=i_k), optional, intent(in), dimension (SFC_DIMS) :: opt_qsz
end subroutine hilbert_iter_init
Initialize the iterator.

The current index is iter%idx and the current 3D position iter%p.

  call hilbert_iter_init(iter, lev, qsz)
  do while(iter%idx > 0)
    array(iter%p(1),iter%p(2),iter%p(3)) = iter%idx
    call hilbert_iter_next(iter)
  end do
  

hilbert_iter_set

public pure subroutine hilbert_iter_set (iter, idx)
    type (hilbert_iter), intent(inout) :: iter
    integer (kind=i_k), intent(in) :: idx
end subroutine hilbert_iter_set
Set the iterator to given index

hilbert_iter_next

public pure subroutine hilbert_iter_next (iter)
    type (hilbert_iter), intent(inout) :: iter
end subroutine hilbert_iter_next
Iterate to next point on the hilbert curve

After reaching the end of the curve, iter%idx is set to 0.