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