Tesseract
3.02
|
00001 00002 // File: qrsequence.h 00003 // Description: Quasi-random sequence generator class. 00004 // Author: Ranjith Unnikrishnan 00005 // Created: Wed May 20 2009 00006 // 00007 // Class to generate a (deterministic) quasi-random Van der Corput sequence that 00008 // covers the interval [0,N) without repetition. 00009 // 00010 // The sequence is generated by reversing the base-2 representation of the 00011 // sequence of natural numbers {0, 1,... M-1}, where M is 2^{num_bits_} and 00012 // num_bits is the minimum number of bits required to represent N. If a reversed 00013 // numbers is >= N it is rejected and the next natural number is considered 00014 // until a valid output number is found. 00015 // 00016 // (C) Copyright 2009, Google Inc. 00017 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 00018 // use this file except in compliance with the License. You may obtain a copy 00019 // of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required 00020 // by applicable law or agreed to in writing, software distributed under the 00021 // License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 00022 // OF ANY KIND, either express or implied. See the License for the specific 00023 // language governing permissions and limitations under the License. 00024 // 00026 00027 #ifndef TESSERACT_CCUTIL_QRSEQUENCE_H_ 00028 #define TESSERACT_CCUTIL_QRSEQUENCE_H_ 00029 00030 #include <math.h> 00031 00032 class QRSequenceGenerator { 00033 public: 00034 // Object is initalized with the size of the output range. 00035 explicit QRSequenceGenerator(int N) : N_(N), next_num_(0) { 00036 num_bits_ = static_cast<int>(ceil(log(static_cast<double>(N)) / log(2.0))); 00037 } 00038 00039 // Main worker method that retrieves the next number in the sequence. 00040 // Returns kInvalidVal if called more than N times after object initialization 00041 int GetVal() { 00042 const int kInvalidVal = -1; 00043 const int kMaxNaturalNumberValue = 1 << num_bits_; 00044 if (next_num_ >= kMaxNaturalNumberValue) 00045 return kInvalidVal; 00046 int n = next_num_; 00047 00048 while (next_num_ < kMaxNaturalNumberValue) { 00049 n = GetBinaryReversedInteger(next_num_++); 00050 if (n < N_) break; 00051 } 00052 return (next_num_ > kMaxNaturalNumberValue) ? kInvalidVal : n; 00053 } 00054 00055 protected: 00056 // Outputs the integer formed by reversing the bits of the input integer. Only 00057 // the lowest num_bits_ bits of the input integer are reversed. 00058 int GetBinaryReversedInteger(int in_val) const { 00059 int bit_pos = num_bits_; 00060 int out_val = 0; 00061 while(bit_pos--) { 00062 // Set the value of the last bit. 00063 out_val |= (in_val & 0x1); 00064 if (bit_pos > 0) { 00065 // Left-shift output value to prepare for storing the next bit. 00066 out_val <<= 1; 00067 } 00068 // Right-shift input value to prepare for retrieving the next bit. 00069 in_val >>= 1; 00070 } 00071 return out_val; 00072 } 00073 int N_; 00074 // Next number to be considered for reversal and output. 00075 int next_num_; 00076 // number of bits required to represent the numbers of the sequence 00077 int num_bits_; 00078 }; 00079 00080 #endif // TESSERACT_CCUTIL_QRSEQUENCE_H_