annotate hilbert.cpp @ 34:94df2cd72d7b

New hilbert code - does rotations!
author Robert Tubb <rt300@eecs.qmul.ac.uk>
date Mon, 08 Apr 2013 12:58:21 +0100
parents
children 790939017078
rev   line source
rt300@34 1 //
rt300@34 2 // hilbert.cpp
rt300@34 3 // sonicZoom
rt300@34 4 //
rt300@34 5 // Created by Robert Tubb on 04/04/2013.
rt300@34 6 //
rt300@34 7 //
rt300@34 8
rt300@34 9 #include "hilbert.h"
rt300@34 10 Hilbert hilbert;
rt300@34 11
rt300@34 12 //--------------------------------------------------------------------
rt300@34 13 unsigned int rotl(unsigned int value, int shift, int digits) {
rt300@34 14 unsigned int ones = (1 << digits) - 1;
rt300@34 15 if(shift >= digits)
rt300@34 16 shift -= digits;
rt300@34 17
rt300@34 18 unsigned int out = (value << shift) | (value >> (digits - shift));
rt300@34 19 return out & ones;
rt300@34 20 }
rt300@34 21 //--------------------------------------------------------------------
rt300@34 22 unsigned int rotr(unsigned int value, int shift, int digits) {
rt300@34 23 int ones = (1 << digits) - 1;
rt300@34 24 // can only handle -digits to 2*digits-1
rt300@34 25 if(shift >= digits) shift = shift - digits;
rt300@34 26 if(shift < 0) shift = digits + shift;
rt300@34 27 unsigned int out = (value >> shift) | (value << (digits - shift));
rt300@34 28 return out & ones;
rt300@34 29 }
rt300@34 30 //--------------------------------------------------------------------
rt300@34 31 unsigned int bin2dec(vector<bool> binary){
rt300@34 32 // takes in a vector of booleans. we assume that the leftmost bool (highest index) is the MSB
rt300@34 33 unsigned int dec = 0;
rt300@34 34 int i,pwr;
rt300@34 35 int N = binary.size();
rt300@34 36
rt300@34 37 for (i = 0; i<N; i++){
rt300@34 38 pwr = N-i-1;
rt300@34 39 dec += binary[i]*(1 << pwr);
rt300@34 40
rt300@34 41 }
rt300@34 42
rt300@34 43 return dec;
rt300@34 44 }
rt300@34 45 //--------------------------------------------------------------------
rt300@34 46 vector<bool> dec2bin(unsigned int number, unsigned int size){
rt300@34 47 vector<bool> bin;
rt300@34 48 int i, pwr;
rt300@34 49 for(i=0;i<size;i++){
rt300@34 50 bin.push_back(0);
rt300@34 51 }
rt300@34 52 if(number >= (1 << size)){
rt300@34 53 cout << " bad size for Hilbert::dec2bin" << "\n";
rt300@34 54 return bin;
rt300@34 55 }
rt300@34 56 for(i=0;i<size;i++){
rt300@34 57 pwr = size-i;
rt300@34 58 bin[i] = (number/(1 << pwr)) % 2;
rt300@34 59 bin.push_back(0);
rt300@34 60 }
rt300@34 61
rt300@34 62
rt300@34 63
rt300@34 64 }
rt300@34 65 void printBool(vector <bool> vcode){
rt300@34 66 vector<bool>::iterator bit;
rt300@34 67
rt300@34 68 for(bit=vcode.begin(); bit!=vcode.end() ; bit++){
rt300@34 69
rt300@34 70 cout << *bit;
rt300@34 71 }
rt300@34 72 cout << "\n";
rt300@34 73
rt300@34 74 }
rt300@34 75 //--------------------------------------------------------------------
rt300@34 76 void Hilbert::init(int aN, int aP){
rt300@34 77 N = aN;
rt300@34 78 P = aP;
rt300@34 79 codeLength = (int)pow(2.0,P);
rt300@34 80 makeCode();
rt300@34 81 makeRotationRules();
rt300@34 82
rt300@34 83
rt300@34 84 // whole process unit test(?)
rt300@34 85
rt300@34 86 unsigned long long inCoord = 888999777;
rt300@34 87 vector<int> checkParam;
rt300@34 88 checkParam = calculateParamsFromIndex(inCoord);
rt300@34 89 cout << "PARAMS: ";
rt300@34 90 for(int i=0; i<P;i++){
rt300@34 91 cout << checkParam[i] << " ";
rt300@34 92 }
rt300@34 93 cout << '\n';
rt300@34 94 unsigned long long outCoord = calculateIndexFromParams(checkParam);
rt300@34 95 cout << "Unit TEst coord = " << outCoord << "\n";
rt300@34 96
rt300@34 97
rt300@34 98 }
rt300@34 99 //--------------------------------------------------------------
rt300@34 100 void Hilbert::makeRotationRules(){
rt300@34 101
rt300@34 102
rt300@34 103 }
rt300@34 104 //--------------------------------------------------------------
rt300@34 105 void Hilbert::makeCode(){
rt300@34 106
rt300@34 107 ////////////////////////////////~~~,,,,,,,,.........
rt300@34 108 ////////// gray code generation
rt300@34 109 //////
rt300@34 110 ///
rt300@34 111 // TODO 5bit specific
rt300@34 112 // transition sequence.... what a palaver! only need to do once though.
rt300@34 113
rt300@34 114 // ALL SEQUENCES SHOULD END WITH 1 0 0 ... i.e. MSB changes
rt300@34 115
rt300@34 116 // max MRL 5 digit
rt300@34 117 int trans[] = {2,3,4,0,2,1,4,3,2,0,4,3,2,1,4,0,2,3,4,0,2,1,4,3,2,0,4,3,2,1,4,0};
rt300@34 118
rt300@34 119 // other ones
rt300@34 120 int trans4[] = {1,2,0,3,0,2,1,2,3,0,3,2,1,3,1,0};
rt300@34 121 int trans3[] = {1,2,1,0,1,2,1,0};
rt300@34 122 int trans2[] = {1,0,1,0};
rt300@34 123 // balanced 5
rt300@34 124 int transB5[] = {1,2,3,4,5,1,5,2,3,5,2,4,2,3,4,1,4,3,2,3,1,5,3,4,1,5,2,5,3,4,1,3};
rt300@34 125
rt300@34 126
rt300@34 127 if(P == 5){
rt300@34 128
rt300@34 129 }else{
rt300@34 130 cout << "Only 5 digit supported now\n";
rt300@34 131 return;
rt300@34 132 }
rt300@34 133
rt300@34 134
rt300@34 135 int code[codeLength][P]; // start with normal array
rt300@34 136 for(int j=0; j<P; j++){
rt300@34 137 code[0][j] = 0;
rt300@34 138 }
rt300@34 139
rt300@34 140 for(int i=0; i < codeLength-1; i++){ // don't need last 3
rt300@34 141 for(int j=0; j<P; j++){
rt300@34 142 if (j == abs(trans[i])){
rt300@34 143 code[i+1][j] = !code[i][j];
rt300@34 144 }else{
rt300@34 145 code[i+1][j] = code[i][j];
rt300@34 146 }
rt300@34 147 }
rt300@34 148
rt300@34 149 }
rt300@34 150
rt300@34 151 for(int i=0; i < codeLength; i++){ // fill vector
rt300@34 152
rt300@34 153 theGrayCode.push_back(vector<bool>());
rt300@34 154
rt300@34 155 for(int j=0; j<P; j++){
rt300@34 156 theGrayCode[i].push_back(code[i][j]);
rt300@34 157
rt300@34 158 }
rt300@34 159
rt300@34 160 }
rt300@34 161
rt300@34 162 for(int i=0;i<codeLength;i++){
rt300@34 163 theGrayCodeD.push_back(bin2dec(theGrayCode[i]));
rt300@34 164 //cout << bin2dec(theGrayCode[i]) << "\n";
rt300@34 165 //cout << theGrayCodeD[i] << "\n";
rt300@34 166 }
rt300@34 167
rt300@34 168 }
rt300@34 169
rt300@34 170 //--------------------------------------------------------------------
rt300@34 171 //--------------------------------------------------------------------
rt300@34 172 vector<int> Hilbert::calculateParamsFromIndex(unsigned long long index){
rt300@34 173 // set %set start and direction of biggest cube
rt300@34 174 unsigned int i;
rt300@34 175 unsigned int mask = (1 << P) - 1;
rt300@34 176 unsigned int entryPoint = 0;
rt300@34 177 int direction = P - 1, directionInv = P-1;
rt300@34 178 unsigned int vertex=0, subindex=0, newe=0, newd=0, entryPointInv = 0;
rt300@34 179
rt300@34 180 unsigned int pbin[N];
rt300@34 181
rt300@34 182 vector<int> params;
rt300@34 183 for(i=0; i<P;i++){
rt300@34 184 params.push_back(0);
rt300@34 185 }
rt300@34 186 for(i=0;i<N;i++){
rt300@34 187 pbin[i] = 0;
rt300@34 188
rt300@34 189 }
rt300@34 190
rt300@34 191 // for loop thru bit levels
rt300@34 192 i=0;
rt300@34 193 for(int blev = N-1; blev >= 0; blev--){
rt300@34 194 // get next highest bits of index
rt300@34 195
rt300@34 196 subindex = index >> blev*P;
rt300@34 197 subindex = mask & subindex;
rt300@34 198
rt300@34 199 cout << "subindex: " << subindex << "\n";
rt300@34 200 // which vertex corresponds to this index?
rt300@34 201 if(subindex < theGrayCode.size()) vertex = theGrayCodeD[subindex];
rt300@34 202
rt300@34 203 cout << "rotated: " << vertex << "\n";
rt300@34 204
rt300@34 205
rt300@34 206 //% inverse rotate this T_e,d
rt300@34 207 entryPointInv = rotr(entryPoint, direction+1,P);
rt300@34 208 directionInv = (P - direction - 2);
rt300@34 209 vertex = rotate(vertex,entryPointInv,directionInv);
rt300@34 210
rt300@34 211 cout << "vertex: " << vertex << "\n";
rt300@34 212
rt300@34 213 //% build up bits of params
rt300@34 214
rt300@34 215 for(int j=0;j<P;j++){
rt300@34 216
rt300@34 217 params[j] += ((vertex >> P-j-1) & 1)*(1<<blev);
rt300@34 218 }
rt300@34 219 if(P==5){
rt300@34 220 newe = entryVertices5[subindex];
rt300@34 221 newd = rotations5[subindex];
rt300@34 222 }
rt300@34 223 // next rotations...
rt300@34 224 int lse2 = rotr(newe, P-direction-1,P);
rt300@34 225 entryPoint = entryPoint ^ lse2;
rt300@34 226 direction = (direction + newd + 1) % P;
rt300@34 227 cout << "------------\n";
rt300@34 228 }
rt300@34 229
rt300@34 230 return params;
rt300@34 231 }
rt300@34 232 //--------------------------------------------------------------------
rt300@34 233 int Hilbert::rotate(int vertex, int entryPoint, int direction){
rt300@34 234 vertex = vertex ^ entryPoint;
rt300@34 235 vertex = rotr(vertex,direction+1,P);
rt300@34 236 return vertex;
rt300@34 237 }
rt300@34 238 //--------------------------------------------------------------------
rt300@34 239
rt300@34 240
rt300@34 241 //--------------------------------------------------------------------
rt300@34 242 long long Hilbert::calculateIndexFromParams(vector<int> params){
rt300@34 243 // set %set start and direction of biggest cube
rt300@34 244
rt300@34 245 long long h = 0;
rt300@34 246
rt300@34 247 unsigned int i;
rt300@34 248 unsigned int entryPoint = 0;
rt300@34 249 int direction = P - 1;
rt300@34 250 unsigned int vertex=0, subindex=0, newe=0, newd=0;
rt300@34 251
rt300@34 252 vector<int> subindices;
rt300@34 253
rt300@34 254
rt300@34 255 // for loop thru bit levels
rt300@34 256 i=0;
rt300@34 257 for(int blev = N-1; blev >= 0; blev--){
rt300@34 258 //% get next highest bit of param
rt300@34 259
rt300@34 260 vector<bool> vertexb;
rt300@34 261 for(i=0;i<P;i++){
rt300@34 262 vertexb.push_back((params[i]/(1 << blev)) % 2);
rt300@34 263
rt300@34 264 }
rt300@34 265 printBool(vertexb);
rt300@34 266 vertex = bin2dec(vertexb);
rt300@34 267 cout << "INV vertex: " << vertex << "\n";
rt300@34 268 // rotate it
rt300@34 269 vertex = rotate(vertex,entryPoint,direction);
rt300@34 270
rt300@34 271 // % get new index of thisun
rt300@34 272 cout << "INV rotated: " << vertex << "\n";
rt300@34 273
rt300@34 274
rt300@34 275 for(i=0;i<codeLength;i++){
rt300@34 276 if(vertex == theGrayCodeD[i]){
rt300@34 277 subindex = i;
rt300@34 278 }
rt300@34 279 }
rt300@34 280 cout << "INV subindex: " << subindex << "\n";
rt300@34 281 // work out next rotations
rt300@34 282 newe = entryVertices5[subindex];
rt300@34 283 newd = rotations5[subindex];
rt300@34 284
rt300@34 285 // next rotations...
rt300@34 286 int lse2 = rotr(newe, P-direction-1,P);
rt300@34 287 entryPoint = entryPoint ^ lse2;
rt300@34 288 direction = (direction + newd + 1) % P;
rt300@34 289
rt300@34 290 // now build up h from subindices
rt300@34 291 h += subindex << (blev*P);
rt300@34 292 cout << "------------\n";
rt300@34 293 }
rt300@34 294
rt300@34 295 return h;
rt300@34 296 }
rt300@34 297 //--------------------------------------------------------------------