| [221] | 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
 | 
|---|