source: XMLIO_V2/external/include/blitz/traversal.cc @ 73

Last change on this file since 73 was 73, checked in by ymipsl, 14 years ago
File size: 3.7 KB
Line 
1/***************************************************************************
2 * blitz/traversal.cc  Space-filling curve based traversal orders
3 *
4 * $Id: traversal.cc,v 1.4 2003/01/14 11:29:18 patricg Exp $
5 *
6 * Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * Suggestions:          blitz-dev@oonumerics.org
19 * Bugs:                 blitz-bugs@oonumerics.org
20 *
21 * For more information, please see the Blitz++ Home Page:
22 *    http://oonumerics.org/blitz/
23 *
24 ***************************************************************************/
25
26#ifndef BZ_TRAVERSAL_CC
27#define BZ_TRAVERSAL_CC
28
29#ifndef BZ_TRAVERSAL_H
30 #error <blitz/traversal.cc> must be included via <blitz/traversal.h>
31#endif
32
33BZ_NAMESPACE(blitz)
34
35// Next line is a workaround for Intel C++ V4.0 oddity, due
36// to Allan Stokes.
37static set<TraversalOrder<2> > *_bz_intel_kludge;
38
39//template<int N_dimensions>
40//_bz_typename TraversalOrderCollection<N_dimensions>::T_set
41//    TraversalOrderCollection<N_dimensions>::traversals_;
42
43template<int N>
44void makeHilbert(Vector<TinyVector<int,N> >& coord, 
45    int x0, int y0, int xis, int xjs,
46    int yis, int yjs, int n, int& i)
47{
48    // N != 2 is not yet implemented.
49    BZPRECONDITION(N == 2);
50
51    if (!n)
52    {
53        if (i > coord.length())
54        {
55            cerr << "makeHilbert: vector not long enough" << endl;
56            exit(1);
57        }
58        coord[i][0] = x0 + (xis+yis)/2;
59        coord[i][1] = y0 + (xjs+yjs)/2;
60        ++i;
61    }
62    else {
63        makeHilbert(coord,x0,y0,yis/2, yjs/2, xis/2, xjs/2, n-1, i);
64        makeHilbert(coord,x0+xis/2,y0+xjs/2,xis/2,xjs/2,yis/2,yjs/2,n-1,i);
65        makeHilbert(coord,x0+xis/2+yis/2,y0+xjs/2+yjs/2,xis/2,xjs/2,yis/2,
66            yjs/2,n-1,i);
67        makeHilbert(coord,x0+xis/2+yis, y0+xjs/2+yjs, -yis/2,-yjs/2,-xis/2,
68            -xjs/2,n-1,i);
69    }
70}
71
72template<int N_dimensions>
73void MakeHilbertTraversal(Vector<TinyVector<int,N_dimensions> >& coord, 
74    int length)
75{
76    // N_dimensions != 2 not yet implemented
77    BZPRECONDITION(N_dimensions == 2);
78
79    // The constant on the next line is ln(2)
80    int d = (int)(::ceil(::log((double)length) / 0.693147180559945309417)); 
81
82    int N = 1 << d;
83    const int Npoints = N*N;
84    Vector<TinyVector<int,2> > coord2(Npoints);
85
86    int i=0;
87    makeHilbert(coord2,0,0,32768,0,0,32768,d,i);
88
89    int xp0 = coord2[0][0];
90    int yp0 = coord2[0][1];
91
92    int j=0;
93
94    coord.resize(length * length);
95
96    for (int i=0; i < Npoints; ++i)
97    {
98        coord2[i][0] = (coord2[i][0]-xp0)/(2*xp0);
99        coord2[i][1] = (coord2[i][1]-yp0)/(2*yp0);
100
101        if ((coord2[i][0] < length) && (coord2[i][1] < length) 
102            && (coord2[i][0] >= 0) && (coord2[i][1] >= 0))
103        {
104            coord[j][0] = coord2[i][0];
105            coord[j][1] = coord2[i][1];
106            ++j;
107        }
108    }
109}
110
111template<int N_dimensions>
112void generateFastTraversalOrder(const TinyVector<int,N_dimensions>& size)
113{
114    BZPRECONDITION(N_dimensions == 2);
115    BZPRECONDITION(size[0] == size[1]);
116
117    TraversalOrderCollection<2> travCol;
118    if (travCol.find(size))
119        return;
120
121    Vector<TinyVector<int,2> > ordering(size[0]);
122
123    MakeHilbertTraversal(ordering, size[0]);
124    travCol.insert(TraversalOrder<2>(size, ordering));
125}
126
127BZ_NAMESPACE_END
128
129#endif // BZ_TRAVERSAL_CC
Note: See TracBrowser for help on using the repository browser.