| //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| // Filename: hilbert.c |
| // |
| // Purpose: Hilbert and Linked-list utility procedures for BayeSys3. |
| // |
| // History: TreeSys.c 17 Apr 1996 - 31 Dec 2002 |
| // Peano.c 10 Apr 2001 - 11 Jan 2003 |
| // merged 1 Feb 2003 |
| // Arith debug 28 Aug 2003 |
| // Hilbert.c 14 Oct 2003 |
| // 2 Dec 2003 |
| //----------------------------------------------------------------------------- |
| /* |
| Copyright (c) 1996-2003 Maximum Entropy Data Consultants Ltd, |
| 114c Milton Road, Cambridge CB4 1XE, England |
| |
| This library is free software; you can redistribute it and/or |
| modify it under the terms of the GNU Lesser General Public |
| License as published by the Free Software Foundation; either |
| version 2.1 of the License, or (at your option) any later version. |
| |
| This library is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| Lesser General Public License for more details. |
| |
| You should have received a copy of the GNU Lesser General Public |
| License along with this library; if not, write to the Free Software |
| Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| |
| #include "license.txt" |
| */ |
| |
| #include <stdio.h> |
| typedef unsigned int coord_t; // char,short,int for up to 8,16,32 bits per word |
| |
| static void TransposetoAxes( |
| coord_t* X, // I O position [n] |
| int b, // I # bits |
| int n) // I dimension |
| { |
| coord_t M, P, Q, t; |
| int i; |
| |
| // Gray decode by H ^ (H/2) |
| t = X[n-1] >> 1; |
| for( i = n-1; i; i-- ) |
| X[i] ^= X[i-1]; |
| X[0] ^= t; |
| |
| // Undo excess work |
| M = 2 << (b - 1); |
| for( Q = 2; Q != M; Q <<= 1 ) |
| { |
| P = Q - 1; |
| for( i = n-1; i; i-- ) |
| if( X[i] & Q ) X[0] ^= P; // invert |
| else{ t = (X[0] ^ X[i]) & P; X[0] ^= t; X[i] ^= t; } // exchange |
| if( X[0] & Q ) X[0] ^= P; // invert |
| } |
| } |
| static void AxestoTranspose( |
| coord_t* X, // I O position [n] |
| int b, // I # bits |
| int n) // I dimension |
| { |
| coord_t P, Q, t; |
| int i; |
| |
| // Inverse undo |
| for( Q = 1 << (b - 1); Q > 1; Q >>= 1 ) |
| { |
| P = Q - 1; |
| if( X[0] & Q ) X[0] ^= P; // invert |
| for( i = 1; i < n; i++ ) |
| if( X[i] & Q ) X[0] ^= P; // invert |
| else{ t = (X[0] ^ X[i]) & P; X[0] ^= t; X[i] ^= t; } // exchange |
| } |
| |
| // Gray encode (inverse of decode) |
| for( i = 1; i < n; i++ ) |
| X[i] ^= X[i-1]; |
| t = X[n-1]; |
| for( i = 1; i < b; i <<= 1 ) |
| X[n-1] ^= X[n-1] >> i; |
| t ^= X[n-1]; |
| for( i = n-2; i >= 0; i-- ) |
| X[i] ^= t; |
| } |
| |
| /* This is an sample use of Skilling's functions above. |
| * You will need to modify the code if the value of BITS or DIMS is changed. |
| * The the output of this can be used to order the node name entries in slurm.conf */ |
| #define BITS 5 /* number of bits used to store the axis values, size of Hilbert space */ |
| #define DIMS 3 /* number of dimensions in the Hilbert space */ |
| main(int argc, char **argv) |
| { |
| int i, H; |
| coord_t X[DIMS]; // any position in 32x32x32 cube for BITS=5 |
| if (argc != (DIMS + 1)) { |
| printf("Usage %s X Y Z\n", argv[0]); |
| exit(1); |
| } |
| for (i=0; i<DIMS; i++) |
| X[i] = atoi(argv[i+1]); |
| printf("Axis coordinates = %d %d %d\n", X[0], X[1], X[2]); |
| |
| AxestoTranspose(X, BITS, DIMS); // Hilbert transpose for 5 bits and 3 dimensions |
| H = ((X[2]>>0 & 1) << 0) + ((X[1]>>0 & 1) << 1) + ((X[0]>>0 & 1) << 2) + |
| ((X[2]>>1 & 1) << 3) + ((X[1]>>1 & 1) << 4) + ((X[0]>>1 & 1) << 5) + |
| ((X[2]>>2 & 1) << 6) + ((X[1]>>2 & 1) << 7) + ((X[0]>>2 & 1) << 8) + |
| ((X[2]>>3 & 1) << 9) + ((X[1]>>3 & 1) << 10) + ((X[0]>>3 & 1) << 11) + |
| ((X[2]>>4 & 1) << 12) + ((X[1]>>4 & 1) << 13) + ((X[0]>>4 & 1) << 14); |
| printf("Hilbert integer = %d (%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d)\n", H, |
| X[0]>>4 & 1, X[1]>>4 & 1, X[2]>>4 & 1, X[0]>>3 & 1, X[1]>>3 & 1, |
| X[2]>>3 & 1, X[0]>>2 & 1, X[1]>>2 & 1, X[2]>>2 & 1, X[0]>>1 & 1, |
| X[1]>>1 & 1, X[2]>>1 & 1, X[0]>>0 & 1, X[1]>>0 & 1, X[2]>>0 & 1); |
| |
| #if 0 |
| /* Used for validation purposes */ |
| TransposetoAxes(X, BITS, DIMS); // Hilbert transpose for 5 bits and 3 dimensions |
| printf("Axis coordinates = %d %d %d\n", X[0], X[1], X[2]); |
| #endif |
| } |