1 /* hilbert.c -
2 $Id$
3 Author - Eric Bylaska
4
5 This file contains 2d hilbert mapping routines
6
7 */
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <math.h>
12 #include "typesf2c.h"
13 #include "olist.h"
14
15 #if defined(WIN32) && !defined(__MINGW32__)
16 #define hilbert2d_map_ HILBERT2D_MAP
17 #endif
18
19
20 #define bottom_left 0
21 #define bottom_right 1
22 #define top_left 2
23 #define top_right 3
24
25 #define right 0
26 #define left 1
27 #define up 2
28 #define down 3
29
30 int hilbert2d(int i, int j, int level);
31 int hilbert_dir(int i, int j, int level, int high, int* start);
32
33 #if (defined(CRAY) || defined(WIN32)) && !defined(__crayx1) &&!defined(__MINGW32__)
34 #define pspsolve_ PSPSOLVE
35 #endif
36
hilbert2d_map_(sizex_ptr,sizey_ptr,map)37 void FATR hilbert2d_map_(sizex_ptr,sizey_ptr,map)
38 Integer *sizex_ptr,*sizey_ptr;
39 Integer map[];
40 {
41 int i,j,size,sizex,sizey;
42 int ii,jj,iii,jjj;
43 int level,count;
44 double dx,dy,x2,y2,dx2,dy2;
45 OList_Type olist2;
46 int *map2,*mapii,*mapjj;
47
48 sizex = *sizex_ptr;
49 sizey = *sizey_ptr;
50
51
52 size = sizex;
53 if (sizey>size) size = sizey;
54
55 /* get the level of map */
56 count = 1;
57 level = 0;
58 while (count < size)
59 {
60 ++level;
61 count = count*2;
62 }
63
64 map2 = (int *) malloc(count*count*sizeof(int));
65 mapii = (int *) malloc(count*count*sizeof(int));
66 mapjj = (int *) malloc(count*count*sizeof(int));
67
68
69 //create_olist(&olist2,count*count);
70 //for (jj=0; jj<count; ++jj)
71 //for (ii=0; ii<count; ++ii)
72 //{
73 //
74 // map2[ii+jj*count] = hilbert2d(ii,jj,level);
75 // insert_olist(&olist2,map2[ii+jj*count]);
76 //}
77
78 for (jj=0; jj<count; ++jj)
79 for (ii=0; ii<count; ++ii)
80 map2[ii+jj*count] = hilbert2d(ii,jj,level);
81
82 create_olist(&olist2,count*count);
83 for (jj=0; jj<count; ++jj)
84 for (ii=0; ii<count; ++ii)
85 insert_olist(&olist2,map2[ii+jj*count]);
86
87
88 for (jj=0; jj<count; ++jj)
89 for (ii=0; ii<count; ++ii)
90 map2[ii+jj*count] = index_olist(&olist2,map2[ii+jj*count]);
91
92 destroy_olist(&olist2);
93
94 for (jj=0; jj<count; ++jj)
95 for (ii=0; ii<count; ++ii)
96 {
97 mapii[map2[ii+jj*count]] = ii;
98 mapjj[map2[ii+jj*count]] = jj;
99 }
100
101
102 dx2 = 1.0/((double) count);
103 dy2 = 1.0/((double) count);
104 dx = 1.0/((double) sizex);
105 dy = 1.0/((double) sizey);
106
107 for (j=0; j<sizex*sizey; ++j) map[j] = -9;
108
109 iii = 0;
110 for (jjj=0; jjj<count*count; ++jjj)
111 {
112 ii = mapii[jjj];
113 jj = mapjj[jjj];
114
115 x2 = dx2*(ii+0.5);
116 y2 = dy2*(jj+0.5);
117 i = rint((x2/dx) - 0.5);
118 j = rint((y2/dy) - 0.5);
119
120 if (map[i+j*sizex] == -9)
121 {
122 map[i+j*sizex] = iii;
123 ++iii;
124 }
125 }
126 free(mapii);
127 free(mapjj);
128 free(map2);
129
130 }
131
132
hilbert2d(i,j,level)133 int hilbert2d(i,j,level)
134 int i,j;
135 int level;
136 {
137 int start,direction;
138
139 direction = hilbert_dir(i,j,level,level,&start);
140
141 return start;
142 }
143
144
parent(i)145 int parent(i)
146 int i;
147 {
148 return(i/2);
149 }
150
corner(i,j)151 int corner(i,j)
152 int i,j;
153 {
154 return(2*(j%2) + (i%2));
155 }
156
hilbert_dir(i,j,level,high,start)157 int hilbert_dir(i,j,level,high,start)
158 int i,j;
159 int level,high;
160 int *start;
161 {
162 int direction,parent_direction,
163 crnr,length,
164 count;
165
166 length = 1;
167 for (count=0; count<(high-level); ++count)
168 length = length*4;
169
170 if (level == 0)
171 {
172 direction = right;
173 *start = 0;
174 }
175 else
176 {
177 parent_direction = hilbert_dir(parent(i),parent(j),
178 level-1,high,
179 start);
180 crnr = corner(i,j);
181
182
183 if (parent_direction == right)
184 {
185 if (crnr == bottom_left)
186 {
187 direction = up;
188 *start = *start + 0*length;
189 }
190 if (crnr == bottom_right)
191 {
192 direction = down;
193 *start = *start + 3*length;
194 }
195 if (crnr == top_left)
196 {
197 direction = right;
198 *start = *start + 1*length;
199 }
200 if (crnr == top_right)
201 {
202 direction = right;
203 *start = *start + 2*length;
204 }
205 }
206
207 if (parent_direction == left)
208 {
209 if (crnr == bottom_left)
210 {
211 direction = left;
212 *start = *start + 2*length;
213 }
214 if (crnr == bottom_right)
215 {
216 direction = left;
217 *start = *start + 1*length;
218 }
219 if (crnr == top_left)
220 {
221 direction = up;
222 *start = *start + 3*length;
223 }
224 if (crnr == top_right)
225 {
226 direction = down;
227 *start = *start + 0*length;
228 }
229 }
230
231 if (parent_direction == up)
232 {
233 if (crnr == bottom_left)
234 {
235 direction = right;
236 *start = *start + 0*length;
237 }
238 if (crnr == bottom_right)
239 {
240 direction = up;
241 *start = *start + 1*length;
242 }
243 if (crnr == top_left)
244 {
245 direction = left;
246 *start = *start + 3*length;
247 }
248 if (crnr == top_right)
249 {
250 direction = up;
251 *start = *start + 2*length;
252 }
253 }
254
255 if (parent_direction == down)
256 {
257 if (crnr == bottom_left)
258 {
259 direction = down;
260 *start = *start + 2*length;
261 }
262 if (crnr == bottom_right)
263 {
264 direction = right;
265 *start = *start + 3*length;
266 }
267 if (crnr == top_left)
268 {
269 direction = down;
270 *start = *start + 1*length;
271 }
272 if (crnr == top_right)
273 {
274 direction = left;
275 *start = *start + 0*length;
276 }
277 }
278 }
279
280 return direction;
281 }
282