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

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

merge

RevLine 
[355]1#ifndef __HALTON_H
2#define __HALTON_H
3
[492]4#include <iostream>
5using namespace std;
6
[860]7namespace GtpVisibilityPreprocessor {
8
[1867]9inline float halton(float baseRec, float prev) {
[1876]10  //  float r = 1 - prev - 1e-10f;
11  float r = 1.0f - prev;
[2076]12  //float r = 1.0f - prev;
[1867]13  if (baseRec < r)
14        return prev + baseRec;
[1876]15  float h = baseRec;
16  float hh;
17  do {
18        hh = h;
19        h *= baseRec;
[2076]20  } while (h > r);
[1876]21  return prev + hh + h - 1.0f;
[1867]22}
23
24template<int T>
[2076]25struct Halton {
26  static float _invBases[T];
[1867]27  float _prev[T];
28 
29public:
30 
31  void Reset() {
32        for (int i=0; i < T; i++)
33          _prev[i] = 0;
[492]34  }
[2076]35
36  Halton(const bool initializeBases) {
[1867]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        }
[2076]43  }
44
45  Halton() {
[1867]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
[2076]59struct Halton2 {
[1867]60  static float _invBases[2];
61  float _prev[2];
62 
[492]63public:
64 
65  void Reset() {
66        _prev[0] =_prev[1] = 0;
67  }
68 
69  Halton2() {
[497]70        _invBases[0] = 1.0f/2;
71        _invBases[1] = 1.0f/3;
[492]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};
[355]83
[492]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;
[355]95        }
[492]96  }
97        if(number == 2) {
98          isIt = false;
99        }
100        return isIt;
101}
102
[2076]103 
104  /**
[492]105 * Find the nth prime number.
106 * @param index the ordinal position in the sequence
107 */
108inline int FindPrime(const int index) {
[1867]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
[492]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 {
[355]130public:
[492]131  int index;
[355]132
[492]133  HaltonSequence():index(1) {}
[355]134
[492]135  void Reset() {
136        index = 1;
137  }
138
[1876]139  void
[2076]140  GetNext(const int dimensions, float *p);
[1876]141 
[492]142  void GenerateNext() {
143        index++;
144  }
145 
[2076]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 
[492]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
[2076]171  double GetNumberOld(const int dimension)  {
[492]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;
[497]181        if((base >= 2) && (index >= 1)) {
[492]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;
[355]190        }
[492]191        else {
192          cerr<<"Error generating Halton sequence."<<endl;
193          exit(1);
[355]194        }
[492]195  }
[355]196};
197
198extern Halton2 halton2;
[860]199}
[355]200
201#endif
Note: See TracBrowser for help on using the repository browser.