Mercurial > hg > soniczoomios
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 //-------------------------------------------------------------------- |