Decode an array of Hilbert integers into locations in a hypercube. This is a vectorized-ish version of the Hilbert curve implementation by John Skilling as described in: Skilling, J. (2004, April). Programming the Hilbert curve. In AIP Conference Proceedings (Vol. 707, No.
(hilberts, num_dims, num_bits)
| 199 | |
| 200 | |
| 201 | def decode(hilberts, num_dims, num_bits): |
| 202 | """Decode an array of Hilbert integers into locations in a hypercube. |
| 203 | |
| 204 | This is a vectorized-ish version of the Hilbert curve implementation by John |
| 205 | Skilling as described in: |
| 206 | |
| 207 | Skilling, J. (2004, April). Programming the Hilbert curve. In AIP Conference |
| 208 | Proceedings (Vol. 707, No. 1, pp. 381-387). American Institute of Physics. |
| 209 | |
| 210 | Params: |
| 211 | ------- |
| 212 | hilberts - An ndarray of Hilbert integers. Must be an integer dtype and |
| 213 | cannot have fewer bits than num_dims * num_bits. |
| 214 | |
| 215 | num_dims - The dimensionality of the hypercube. Integer. |
| 216 | |
| 217 | num_bits - The number of bits for each dimension. Integer. |
| 218 | |
| 219 | Returns: |
| 220 | -------- |
| 221 | The output is an ndarray of unsigned integers with the same shape as hilberts |
| 222 | but with an additional dimension of size num_dims. |
| 223 | """ |
| 224 | |
| 225 | if num_dims * num_bits > 64: |
| 226 | raise ValueError( |
| 227 | """ |
| 228 | num_dims=%d and num_bits=%d for %d bits total, which can't be encoded |
| 229 | into a uint64. Are you sure you need that many points on your Hilbert |
| 230 | curve? |
| 231 | """ |
| 232 | % (num_dims, num_bits) |
| 233 | ) |
| 234 | |
| 235 | # Handle the case where we got handed a naked integer. |
| 236 | hilberts = torch.atleast_1d(hilberts) |
| 237 | |
| 238 | # Keep around the shape for later. |
| 239 | orig_shape = hilberts.shape |
| 240 | bitpack_mask = 2 ** torch.arange(0, 8).to(hilberts.device) |
| 241 | bitpack_mask_rev = bitpack_mask.flip(-1) |
| 242 | |
| 243 | # Treat each of the hilberts as a s equence of eight uint8. |
| 244 | # This treats all of the inputs as uint64 and makes things uniform. |
| 245 | hh_uint8 = ( |
| 246 | hilberts.ravel().type(torch.int64).view(torch.uint8).reshape((-1, 8)).flip(-1) |
| 247 | ) |
| 248 | |
| 249 | # Turn these lists of uints into lists of bits and then truncate to the size |
| 250 | # we actually need for using Skilling's procedure. |
| 251 | hh_bits = ( |
| 252 | hh_uint8.unsqueeze(-1) |
| 253 | .bitwise_and(bitpack_mask_rev) |
| 254 | .ne(0) |
| 255 | .byte() |
| 256 | .flatten(-2, -1)[:, -num_dims * num_bits :] |
| 257 | ) |
| 258 |
nothing calls this directly
no test coverage detected