RMPCDMD
hilbert.f90
Go to the documentation of this file.
1 ! This file is part of RMPCDMD
2 ! Copyright (c) 2015-2016 Pierre de Buyl and contributors
3 ! License: BSD 3-clause (see file LICENSE)
4 
8 
9 module hilbert
10  implicit none
11  private
12 
14 
15  integer, parameter :: dim = 3
16  integer, parameter :: mask=2**dim-1
17 
18 contains
19 
20  pure function rotate_right(x, d)
21  integer, intent(in) :: x
22  integer, intent(in) :: d
23  integer :: rotate_right
24  integer :: tmp
25 
26  rotate_right = shiftr(x, d)
27  tmp = shiftl(x, dim-d)
28  rotate_right = iand(ior(rotate_right, tmp), mask)
29 
30  end function rotate_right
31 
32  pure function rotate_left(x, d)
33  integer, intent(in) :: x
34  integer, intent(in) :: d
35  integer :: rotate_left
36  integer :: tmp
37 
38  rotate_left = shiftl(x, d)
39  tmp = shiftr(x, dim-d)
40  rotate_left = iand(ior(rotate_left, tmp), mask)
41 
42  end function rotate_left
43 
44  pure function bin_str(x)
45  integer, intent(in) :: x
46 
47  character(len=dim) :: bin_str
48  integer :: i, j, total_size
49 
50  total_size = bit_size(x)
51 
52  do i=1, dim
53  j = dim-(i-1)
54  if (ibits(x, i-1, 1).eq.1) then
55  bin_str(j:j) = '1'
56  else
57  bin_str(j:j) = '0'
58  end if
59  end do
60 
61  end function bin_str
62 
63  pure function gc(i)
64  integer, intent(in) :: i
65  integer gc
66 
67  gc = ieor(i, shiftr(i, 1))
68 
69  end function gc
70 
71  pure function entry_point(i)
72  integer, intent(in) :: i
73  integer :: entry_point
74 
75  if (i .eq. 0) then
76  entry_point = 0
77  else
78  entry_point = gc(2*((i-1)/2))
79  end if
80 
81  end function entry_point
82 
83  pure function exit_point(i)
84  integer, intent(in) :: i
85  integer :: exit_point
86 
87  exit_point = ieor(entry_point(mask-i), 2**(dim-1))
88 
89  end function exit_point
90 
91  pure function inverse_gc(g)
92  integer, intent(in) :: g
93  integer :: inverse_gc
94  integer :: j
95 
96  inverse_gc = g
97  j = 1
98  do while ( j .lt. dim )
99  inverse_gc = ieor(inverse_gc, shiftr(g, j))
100  j = j + 1
101  end do
102 
103  end function inverse_gc
104 
105  pure function intercube_g(i) result(g)
106  integer, intent(in) :: i
107  integer :: g
108 
109  g = trailz(ieor(gc(i), gc(i+1)))
110 
111  end function intercube_g
112 
113  pure function intracube_d(i) result(d)
114  integer, intent(in) :: i
115  integer :: d
116 
117  if (i .eq. 0) then
118  d = 0
119  else if ( modulo(i, 2) .eq. 0 ) then
120  d = modulo(intercube_g(i-1), dim)
121  else
122  d = modulo(intercube_g(i), dim)
123  end if
124  end function intracube_d
125 
126  pure function transform(e, d, b) result(t)
127  integer, intent(in) :: e, d, b
128  integer :: t
129 
130  t = rotate_right( ieor(b, e), d+1)
131  end function transform
132 
133  pure function inverse_transform(e, d, b) result(t)
134  integer, intent(in) :: e, d, b
135  integer :: t
136 
137  t = transform(rotate_right(e, d+1), dim-d-2, b)
138 
139  end function inverse_transform
140 
141  pure function p_to_h(p, m) result(h)
142  integer, intent(in) :: p(dim), m
143  integer :: h
144 
145  integer :: e, d, i, j, l, w
146 
147  h = 0
148  e = 0
149  d = 2
150  do i = m-1, 0, -1
151  l = 0
152  do j=1, dim
153  l = l + 2**(j-1)*ibits(p(j), i, 1)
154  end do
155  l = transform(e, d, l)
156  w = inverse_gc(l)
157  e = ieor(e, rotate_left(entry_point(w), d+1))
158  d = modulo(d + intracube_d(w) + 1, dim)
159  h = ior(shiftl(h, dim), w)
160  end do
161  end function p_to_h
162 
163  pure function h_to_p(h, m) result(p)
164  integer, intent(in) :: h, m
165  integer :: p(dim)
166 
167  integer :: e, d, i, j, l, w
168 
169  e = 0
170  d = 2
171  p = 0
172  do i=m-1, 0, -1
173  w = 0
174  do j=0, dim-1
175  w = w + 2**j*ibits(h, i*dim+j, 1)
176  end do
177  l = gc(w)
178  l = inverse_transform(e, d, l)
179  do j=1, dim
180  p(j) = p(j) + shiftl(ibits(l, j-1, 1) , i)
181  end do
182  e = ieor( e, rotate_left(entry_point(w), d+1))
183  d = modulo(d + intracube_d(w) + 1, dim)
184  end do
185 
186  end function h_to_p
187 
188  pure function gcr(i, mu) result(r)
189  integer, intent(in) :: i, mu
190  integer :: r
191 
192  integer :: k
193  r = 0
194  do k=dim-1, 0, -1
195  if (ibits(mu, k, 1) .eq. 1) then
196  r = ior( shiftl(r, 1), ibits(i, k, 1))
197  end if
198  end do
199 
200  end function gcr
201 
202  pure function inverse_gcr(r, mu, pi) result(i)
203  integer, intent(in) :: r, mu, pi
204  integer :: i
205 
206  integer :: g, j, k
207  i = 0
208  g = 0
209  j = -1
210  do k=0, dim - 1
211  j = j + ibits(mu, k, 1)
212  end do
213  do k=dim-1, 0, -1
214  if (ibits(mu, k, 1) .eq. 1) then
215  i = ior(i, shiftl( ibits(r, j, 1), k))
216  g = ior(g, shiftl( modulo( ibits(i, k, 1)+ibits(i, k+1, 1), 2), k) )
217  j = j-1
218  else
219  g = ior(g, shiftl( ibits(pi, k, 1), k))
220  i = ior(i, shiftl( modulo( ibits(g, k, 1)+ibits(i, k+1, 1), 2), k) )
221  end if
222  end do
223  end function inverse_gcr
224 
225  pure function extract_mask(i, m) result(mu)
226  integer, intent(in) :: i, m(dim)
227  integer :: mu
228 
229  integer :: j
230 
231  mu = 0
232  do j=dim, 1, -1
233  mu = shiftl(mu, 1)
234  if ( m(j) .gt. i ) then
235  mu = ior(mu, 1)
236  end if
237  end do
238 
239  end function extract_mask
240 
241  pure function compact_p_to_h(p, m) result(h)
242  integer, intent(in) :: p(dim), m(dim)
243  integer :: h
244 
245  integer :: e, d, max_m, i, j, l, mu, mu_norm, pi, r, w
246 
247  h = 0
248  e = 0
249  d = 2
250  max_m = maxval(m)
251  do i=max_m-1, 0, -1
252  mu = extract_mask(i, m)
253  mu_norm = 0
254  do j=0, dim-1
255  mu_norm = mu_norm + ibits(mu, j, 1)
256  end do
257  mu = rotate_right(mu, d+1)
258  pi = iand(rotate_right(e, d+1), iand(not(mu), mask))
259  l = 0
260  do j=1, dim
261  l = l + 2**(j-1)*ibits(p(j), i, 1)
262  end do
263  l = transform(e, d, l)
264  w = inverse_gc(l)
265  r = gcr(w, mu)
266  e = ieor(e, rotate_left(entry_point(w), d+1))
267  d = modulo(d + intracube_d(w) + 1, dim)
268  h = ior( shiftl(h, mu_norm), r)
269  end do
270 
271  end function compact_p_to_h
272 
273  pure function compact_h_to_p(h, m) result(p)
274  integer, intent(in) :: h, m(dim)
275  integer :: p(dim)
276 
277  integer :: e, d, i, j, k, max_m, sum_m, mu_norm, mu, pi, r, l, w
278 
279  e = 0
280  d = 2
281  k = 0
282  p = 0
283  max_m = maxval(m)
284  sum_m = sum(m)
285  do i=max_m-1, 0, -1
286  mu = extract_mask(i, m)
287  mu_norm = 0
288  do j=0, dim-1
289  mu_norm = mu_norm + ibits(mu, j, 1)
290  end do
291  mu = rotate_right(mu, d+1)
292  pi = iand(rotate_right(e, d+1), iand(not(mu), mask))
293  r = 0
294  do j=0, mu_norm-1
295  r = r + 2**j*ibits(h, sum_m - k - mu_norm + j, 1)
296  end do
297  k = k + mu_norm
298  w = inverse_gcr(r, mu, pi)
299  l = gc(w)
300  l = inverse_transform(e, d, l)
301  do j=1, dim
302  p(j) = p(j) + shiftl(ibits(l, j-1, 1), i)
303  end do
304  e = ieor(e, rotate_left(entry_point(w), d+1))
305  d = modulo(d + intracube_d(w) + 1, dim)
306  end do
307  end function compact_h_to_p
308 
309 end module hilbert
pure integer function, dimension(dim), public compact_h_to_p(h, m)
Definition: hilbert.f90:274
pure integer function, public compact_p_to_h(p, m)
Definition: hilbert.f90:242
pure integer function, dimension(dim), public h_to_p(h, m)
Definition: hilbert.f90:164
pure integer function extract_mask(i, m)
Definition: hilbert.f90:226
pure integer function rotate_left(x, d)
Definition: hilbert.f90:33
pure integer function inverse_gcr(r, mu, pi)
Definition: hilbert.f90:203
pure integer function, public p_to_h(p, m)
Definition: hilbert.f90:142
pure integer function entry_point(i)
Definition: hilbert.f90:72
pure integer function intercube_g(i)
Definition: hilbert.f90:106
pure integer function rotate_right(x, d)
Definition: hilbert.f90:21
pure character(len=dim) function bin_str(x)
Definition: hilbert.f90:45
pure integer function inverse_transform(e, d, b)
Definition: hilbert.f90:134
pure integer function inverse_gc(g)
Definition: hilbert.f90:92
Compute compact Hilbert indices.
Definition: hilbert.f90:9
pure integer function exit_point(i)
Definition: hilbert.f90:84
pure integer function intracube_d(i)
Definition: hilbert.f90:114
integer, parameter dim
Definition: hilbert.f90:15
pure integer function gc(i)
Definition: hilbert.f90:64
pure integer function transform(e, d, b)
Definition: hilbert.f90:127
pure integer function gcr(i, mu)
Definition: hilbert.f90:189
integer, parameter mask
Definition: hilbert.f90:16