source: GTP/trunk/Lib/Vis/Preprocessing/src/Halton.h @ 2076

Revision 2076, 3.6 KB checked in by bittner, 17 years ago (diff)

merge

Line 
1#ifndef __HALTON_H
2#define __HALTON_H
3
4#include <iostream>
5using namespace std;
6
7namespace GtpVisibilityPreprocessor {
8
9inline float halton(float baseRec, float prev) {
10  //  float r = 1 - prev - 1e-10f;
11  float r = 1.0f - prev;
12  //float r = 1.0f - prev;
13  if (baseRec < r)
14        return prev + baseRec;
15  float h = baseRec;
16  float hh;
17  do {
18        hh = h;
19        h *= baseRec;
20  } while (h > r);
21  return prev + hh + h - 1.0f;
22}
23
24template<int T>
25struct Halton {
26  static float _invBases[T];
27  float _prev[T];
28 
29public:
30 
31  void Reset() {
32        for (int i=0; i < T; i++)
33          _prev[i] = 0;
34  }
35
36  Halton(const bool initializeBases) {
37        for (int i=0; i < T; i++) {
38          int base = FindPrime(i+1);
39          if (base == 1)
40                base++;
41          _invBases[i] = 1.0f/base;
42        }
43  }
44
45  Halton() {
46        Reset();
47  }
48 
49  void
50  GetNext(float *a) {
51        for (int i=0; i < T; i++) {
52          a[i] = halton(_invBases[i], _prev[i]);
53          _prev[i] = a[i];
54        }
55  }
56 
57};
58
59struct Halton2 {
60  static float _invBases[2];
61  float _prev[2];
62 
63public:
64 
65  void Reset() {
66        _prev[0] =_prev[1] = 0;
67  }
68 
69  Halton2() {
70        _invBases[0] = 1.0f/2;
71        _invBases[1] = 1.0f/3;
72        Reset();
73  }
74 
75  void
76  GetNext(float &a, float &b) {
77        a = halton(_invBases[0], _prev[0]);
78        b = halton(_invBases[1], _prev[1]);
79        _prev[0] = a;
80        _prev[1] = b;
81  }
82};
83
84
85/**
86 * Assert whether the argument is a prime number.
87 * @param number the number to be checked
88 */
89inline bool IsPrime(const int number) {
90  bool isIt = true;
91  for(int i = 2; i < number; i++) {
92        if(number % i == 0) {
93          isIt = false;
94          break;
95        }
96  }
97        if(number == 2) {
98          isIt = false;
99        }
100        return isIt;
101}
102
103 
104  /**
105 * Find the nth prime number.
106 * @param index the ordinal position in the sequence
107 */
108inline int FindPrime(const int index) {
109  //  if (index < 1) {
110  //    cerr<<"FindPrime: The argument must be non-negative."<<endl;
111  //    return -1;
112  //  }
113
114  const int primes[] = {-1, 1, 3, 5, 7, 11, 13};
115  if (index <= 6)
116        return primes[index];
117
118  int prime = 1;
119  int found = 1;
120  while(found != index) {
121        prime += 2;
122          if(IsPrime(prime) == true) {
123                found++;
124          }
125  }
126  return prime;
127}
128
129struct HaltonSequence {
130public:
131  int index;
132
133  HaltonSequence():index(1) {}
134
135  void Reset() {
136        index = 1;
137  }
138
139  void
140  GetNext(const int dimensions, float *p);
141 
142  void GenerateNext() {
143        index++;
144  }
145 
146  double GetNumber(const int dimension)  {
147        int base = FindPrime(dimension);
148        if(base == 1) {
149          base++;  //The first dimension uses base 2.
150        }
151       
152        int _p1 = base;
153        float _ip1 = 1.0f/base;
154        float p, u=0.0f;
155    int kk, a;
156       
157    // the first coordinate
158    for (p = _ip1, kk = index ; kk ;  p *= _ip1, kk /= _p1)   
159      if ((a = kk % _p1))
160                u += a * p;
161       
162        return u;
163  }
164 
165  /**
166   * Returns the nth number in the sequence, taken from a specified dimension.
167   * @param index the ordinal position in the sequence
168   * @param dimension the dimension
169   */
170
171  double GetNumberOld(const int dimension)  {
172        int base = FindPrime(dimension);
173        if(base == 1) {
174          base++;  //The first dimension uses base 2.
175        }
176        double remainder;
177        double output = 0.0;
178        double fraction = 1.0 / (double)base;
179        int N1 = 0;
180        int copyOfIndex = index;
181        if((base >= 2) && (index >= 1)) {
182          while(copyOfIndex > 0) {
183                N1 = (copyOfIndex / base);
184                remainder = copyOfIndex % base;
185                output += fraction * remainder;
186                copyOfIndex = (int)(copyOfIndex / base);
187                fraction /= (double)base;
188          }
189          return output;
190        }
191        else {
192          cerr<<"Error generating Halton sequence."<<endl;
193          exit(1);
194        }
195  }
196};
197
198extern Halton2 halton2;
199}
200
201#endif
Note: See TracBrowser for help on using the repository browser.