| 1 | #ifndef BZ_TRAVERSAL_CC
 | 
|---|
| 2 | #define BZ_TRAVERSAL_CC
 | 
|---|
| 3 | 
 | 
|---|
| 4 | #ifndef BZ_TRAVERSAL_H
 | 
|---|
| 5 |  #error <blitz/traversal.cc> must be included via <blitz/traversal.h>
 | 
|---|
| 6 | #endif
 | 
|---|
| 7 | 
 | 
|---|
| 8 | BZ_NAMESPACE(blitz)
 | 
|---|
| 9 | 
 | 
|---|
| 10 | template<int N_dimensions>
 | 
|---|
| 11 | _bz_typename TraversalOrderCollection<N_dimensions>::T_set
 | 
|---|
| 12 |     TraversalOrderCollection<N_dimensions>::traversals_;
 | 
|---|
| 13 | 
 | 
|---|
| 14 | template<int N>
 | 
|---|
| 15 | void makeHilbert(Vector<TinyVector<int,N> >& coord, 
 | 
|---|
| 16 |     int x0, int y0, int xis, int xjs,
 | 
|---|
| 17 |     int yis, int yjs, int n, int& i)
 | 
|---|
| 18 | {
 | 
|---|
| 19 |     // N != 2 is not yet implemented.
 | 
|---|
| 20 |     BZPRECONDITION(N == 2);
 | 
|---|
| 21 | 
 | 
|---|
| 22 |     if (!n)
 | 
|---|
| 23 |     {
 | 
|---|
| 24 |         if (i > coord.length())
 | 
|---|
| 25 |         {
 | 
|---|
| 26 |             cerr << "makeHilbert: vector not long enough" << endl;
 | 
|---|
| 27 |             exit(1);
 | 
|---|
| 28 |         }
 | 
|---|
| 29 |         coord[i][0] = x0 + (xis+yis)/2;
 | 
|---|
| 30 |         coord[i][1] = y0 + (xjs+yjs)/2;
 | 
|---|
| 31 |         ++i;
 | 
|---|
| 32 |     }
 | 
|---|
| 33 |     else {
 | 
|---|
| 34 |         makeHilbert(coord,x0,y0,yis/2, yjs/2, xis/2, xjs/2, n-1, i);
 | 
|---|
| 35 |         makeHilbert(coord,x0+xis/2,y0+xjs/2,xis/2,xjs/2,yis/2,yjs/2,n-1,i);
 | 
|---|
| 36 |         makeHilbert(coord,x0+xis/2+yis/2,y0+xjs/2+yjs/2,xis/2,xjs/2,yis/2,
 | 
|---|
| 37 |             yjs/2,n-1,i);
 | 
|---|
| 38 |         makeHilbert(coord,x0+xis/2+yis, y0+xjs/2+yjs, -yis/2,-yjs/2,-xis/2,
 | 
|---|
| 39 |             -xjs/2,n-1,i);
 | 
|---|
| 40 |     }
 | 
|---|
| 41 | }
 | 
|---|
| 42 | 
 | 
|---|
| 43 | template<int N_dimensions>
 | 
|---|
| 44 | void MakeHilbertTraversal(Vector<TinyVector<int,N_dimensions> >& coord, 
 | 
|---|
| 45 |     int length)
 | 
|---|
| 46 | {
 | 
|---|
| 47 |     // N_dimensions != 2 not yet implemented
 | 
|---|
| 48 |     BZPRECONDITION(N_dimensions == 2);
 | 
|---|
| 49 | 
 | 
|---|
| 50 |     // The constant on the next line is ln(2)
 | 
|---|
| 51 |     int d = (int)(::ceil(::log((double)length) / 0.693147180559945309417));  
 | 
|---|
| 52 | 
 | 
|---|
| 53 |     int N = 1 << d;
 | 
|---|
| 54 |     const int Npoints = N*N;
 | 
|---|
| 55 |     Vector<TinyVector<int,2> > coord2(Npoints);
 | 
|---|
| 56 | 
 | 
|---|
| 57 |     int i=0;
 | 
|---|
| 58 |     makeHilbert(coord2,0,0,32768,0,0,32768,d,i);
 | 
|---|
| 59 | 
 | 
|---|
| 60 |     int xp0 = coord2[0][0];
 | 
|---|
| 61 |     int yp0 = coord2[0][1];
 | 
|---|
| 62 | 
 | 
|---|
| 63 |     int j=0;
 | 
|---|
| 64 | 
 | 
|---|
| 65 |     coord.resize(length * length);
 | 
|---|
| 66 | 
 | 
|---|
| 67 |     for (int i=0; i < Npoints; ++i)
 | 
|---|
| 68 |     {
 | 
|---|
| 69 |         coord2[i][0] = (coord2[i][0]-xp0)/(2*xp0);
 | 
|---|
| 70 |         coord2[i][1] = (coord2[i][1]-yp0)/(2*yp0);
 | 
|---|
| 71 | 
 | 
|---|
| 72 |         if ((coord2[i][0] < length) && (coord2[i][1] < length) 
 | 
|---|
| 73 |             && (coord2[i][0] >= 0) && (coord2[i][1] >= 0))
 | 
|---|
| 74 |         {
 | 
|---|
| 75 |             coord[j][0] = coord2[i][0];
 | 
|---|
| 76 |             coord[j][1] = coord2[i][1];
 | 
|---|
| 77 |             ++j;
 | 
|---|
| 78 |         }
 | 
|---|
| 79 |     }
 | 
|---|
| 80 | }
 | 
|---|
| 81 | 
 | 
|---|
| 82 | template<int N_dimensions>
 | 
|---|
| 83 | void generateFastTraversalOrder(const TinyVector<int,N_dimensions>& size)
 | 
|---|
| 84 | {
 | 
|---|
| 85 |     BZPRECONDITION(N_dimensions == 2);
 | 
|---|
| 86 |     BZPRECONDITION(size[0] == size[1]);
 | 
|---|
| 87 | 
 | 
|---|
| 88 |     TraversalOrderCollection<2> travCol;
 | 
|---|
| 89 |     if (travCol.find(size))
 | 
|---|
| 90 |         return;
 | 
|---|
| 91 | 
 | 
|---|
| 92 |     Vector<TinyVector<int,2> > ordering(size[0]);
 | 
|---|
| 93 | 
 | 
|---|
| 94 |     MakeHilbertTraversal(ordering, size[0]);
 | 
|---|
| 95 |     travCol.insert(TraversalOrder<2>(size, ordering));
 | 
|---|
| 96 | }
 | 
|---|
| 97 | 
 | 
|---|
| 98 | BZ_NAMESPACE_END
 | 
|---|
| 99 | 
 | 
|---|
| 100 | #endif // BZ_TRAVERSAL_CC
 | 
|---|