Octopus
hilbert.c
Go to the documentation of this file.
1/*
2 Copyright (C) 2013 X. Andrade
3 Copyright (C) 2021 S. Ohlmann
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
8 any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 02110-1301, USA.
19
20*/
21
22#include <config.h>
23
24#include <assert.h>
25
26/* This code is based on the implementation of the Hilbert curves
27 presented in:
28
29 J. Skilling, Programming the Hilbert curve, AIP Conf. Proc. 707, 381 (2004);
30 http://dx.doi.org/10.1063/1.1751381
31
32*/
33
34void Int4toTranspose(const int dim, const int h, int bits, int *x) {
35 /* the code uses some funny way of storing the bits */
36
37 int idir, ibit, ifbit;
38
39 for (idir = 0; idir < dim; idir++)
40 x[idir] = 0;
41
42 ifbit = 0;
43 for (ibit = 0; ibit < bits; ibit++) {
44 for (idir = dim - 1; idir >= 0; idir--) {
45 x[idir] += (((h >> ifbit) & 1) << ibit);
46 ifbit++;
47 }
48 }
49}
50
51void InttoTranspose(const int dim, const long long int h, int bits, int *x) {
52 /* the code uses some funny way of storing the bits */
53
54 int idir, ibit, ifbit;
55
56 for (idir = 0; idir < dim; idir++)
57 x[idir] = 0;
59 ifbit = 0;
60 for (ibit = 0; ibit < bits; ibit++) {
61 for (idir = dim - 1; idir >= 0; idir--) {
62 x[idir] += (((h >> ifbit) & 1) << ibit);
63 ifbit++;
64 }
65 }
66}
68void TransposetoAxes(int *X, int b, int n) { /* position, #bits, dimension */
69
70 int N = 2 << (b - 1), P, Q, t;
71 int i;
72
73 /* Gray decode by H ^ (H/2) */
74 t = X[n - 1] >> 1;
75 for (i = n - 1; i > 0; i--)
76 X[i] ^= X[i - 1];
77 X[0] ^= t;
78
79 /* Undo excess work */
80 for (Q = 2; Q != N; Q <<= 1) {
81 P = Q - 1;
82 for (i = n - 1; i >= 0; i--) {
83 if (X[i] & Q) {
84 X[0] ^= P; /* invert */
85 } else {
86 t = (X[0] ^ X[i]) & P;
87 X[0] ^= t;
88 X[i] ^= t; /* exchange */
89 }
90 }
91 }
92}
93
94void TransposetoInt(const int dim, long long int *h, int bits, int *x) {
95 /* the code uses some funny way of storing the bits */
96
97 int idir, ibit, ifbit;
98
99 *h = 0;
100
101 ifbit = 0;
102 for (ibit = 0; ibit < bits; ibit++) {
103 for (idir = dim - 1; idir >= 0; idir--) {
104 *h += (((x[idir] >> ibit) & 1) << ifbit);
105 ifbit++;
106 }
107 }
108}
109
110void TransposetoInt4(const int dim, int *h, int bits, int *x) {
111 /* the code uses some funny way of storing the bits */
112
113 int idir, ibit, ifbit;
114
115 *h = 0;
116
117 ifbit = 0;
118 for (ibit = 0; ibit < bits; ibit++) {
119 for (idir = dim - 1; idir >= 0; idir--) {
120 *h += (((x[idir] >> ibit) & 1) << ifbit);
121 ifbit++;
122 }
123 }
124}
125
126void AxestoTranspose(int *X, int b, int n) { /* position, #bits, dimension */
127 int M = 1 << (b - 1), P, Q, t;
128 int i;
129 /* Inverse undo */
130 for (Q = M; Q > 1; Q >>= 1) {
131 P = Q - 1;
132 for (i = 0; i < n; i++) {
133 if (X[i] & Q)
134 X[0] ^= P; /* invert */
135 else { /* exchange */
136 t = (X[0] ^ X[i]) & P;
137 X[0] ^= t;
138 X[i] ^= t;
139 }
140 }
141 }
142
143 /* Gray encode */
144 for (i = 1; i < n; i++)
145 X[i] ^= X[i - 1];
146 t = 0;
147 for (Q = M; Q > 1; Q >>= 1)
148 if (X[n - 1] & Q)
149 t ^= Q - 1;
150 for (i = 0; i < n; i++)
151 X[i] ^= t;
152}
153
154/* 64 bit integer versions */
155void FC_FUNC_(hilbert_index_to_point,
156 HILBERT_INDEX_TO_POINT)(const int *dim, const int *nbits,
157 const long long int *index, int *point) {
158 InttoTranspose(*dim, *index, *nbits, point);
159 TransposetoAxes(point, *nbits, *dim);
160}
161
162void FC_FUNC_(hilbert_point_to_index,
163 HILBERT_POINT_TO_INDEX)(const int *dim, const int *nbits,
164 long long int *index, const int *point) {
165 /* copy point to not overwrite original data */
166 int point_copy[*dim];
167 for (int i = 0; i < *dim; i++)
168 point_copy[i] = point[i];
169 AxestoTranspose(point_copy, *nbits, *dim);
170 TransposetoInt(*dim, index, *nbits, point_copy);
171}
172
173/* 32 bit integer versions */
174void FC_FUNC_(hilbert_index_to_point_int,
175 HILBERT_INDEX_TO_POINT_INT)(const int *dim, const int *nbits,
176 const int *index, int *point) {
177 Int4toTranspose(*dim, *index, *nbits, point);
178 TransposetoAxes(point, *nbits, *dim);
179}
180
181void FC_FUNC_(hilbert_point_to_index_int,
182 HILBERT_POINT_TO_INDEX_INT)(const int *dim, const int *nbits,
183 int *index, const int *point) {
184 /* copy point to not overwrite original data */
185 int point_copy[*dim];
186 for (int i = 0; i < *dim; i++)
187 point_copy[i] = point[i];
188 AxestoTranspose(point_copy, *nbits, *dim);
189 TransposetoInt4(*dim, index, *nbits, point_copy);
190}
void InttoTranspose(const int dim, const long long int h, int bits, int *x)
Definition: hilbert.c:84
void TransposetoInt4(const int dim, int *h, int bits, int *x)
Definition: hilbert.c:143
void AxestoTranspose(int *X, int b, int n)
Definition: hilbert.c:159
void TransposetoAxes(int *X, int b, int n)
Definition: hilbert.c:101
void Int4toTranspose(const int dim, const int h, int bits, int *x)
Definition: hilbert.c:67
void TransposetoInt(const int dim, long long int *h, int bits, int *x)
Definition: hilbert.c:127
ptrdiff_t i
Definition: operate_inc.c:12
const int *restrict index
Definition: operate_inc.c:13