nChooseKSampleSelector.h
Go to the documentation of this file.00001
00016 #ifndef DLR_COMPUTERVISION_NCHOOSEKSAMPLESELECTOR_H
00017 #define DLR_COMPUTERVISION_NCHOOSEKSAMPLESELECTOR_H
00018
00019 #include <vector>
00020
00021 namespace dlr {
00022
00023 namespace computerVision {
00024
00033 template <class Sample>
00034 class NChooseKSampleSelector {
00035 public:
00036
00037
00038
00042 typedef Sample SampleType;
00043
00049 typedef std::pair<typename std::vector<SampleType>::const_iterator,
00050 typename std::vector<SampleType>::const_iterator>
00051 SampleSequenceType;
00052
00053
00054
00055
00071 template <class IterType>
00072 NChooseKSampleSelector(size_t sampleSize,
00073 IterType beginIter,
00074 IterType endIter);
00075
00076
00086 size_t
00087 getNumberOfSamples();
00088
00089
00097 SampleSequenceType
00098 getPool() {
00099 return std::make_pair(m_poolVector.begin(), m_poolVector.end());
00100 }
00101
00102
00110 size_t
00111 getPoolSize() {return m_poolVector.size();}
00112
00113
00128 SampleSequenceType
00129 getSample(size_t sampleNumber);
00130
00131 private:
00132
00133 size_t
00134 getFactorial(size_t argument);
00135
00136 void
00137 incrementSampleIndices();
00138
00139 SampleSequenceType
00140 statelessGetSample(size_t sampleNumber);
00141
00142 size_t m_numberOfSamples;
00143 std::vector<SampleType> m_poolVector;
00144 size_t m_previousSampleNumber;
00145 std::vector<size_t> m_sampleIndices;
00146 std::vector<SampleType> m_sampleVector;
00147
00148 };
00149
00150 }
00151
00152 }
00153
00154
00155
00156
00157 #include <limits>
00158 #include <dlrCommon/exception.h>
00159
00160 namespace dlr {
00161
00162 namespace computerVision {
00163
00164 template <class Sample>
00165 template <class IterType>
00166 NChooseKSampleSelector<Sample>::
00167 NChooseKSampleSelector(size_t sampleSize,
00168 IterType beginIter,
00169 IterType endIter)
00170 : m_numberOfSamples(0),
00171 m_poolVector(beginIter, endIter),
00172 m_previousSampleNumber(std::numeric_limits<size_t>::max() - 1),
00173 m_sampleIndices(sampleSize),
00174 m_sampleVector(sampleSize)
00175 {
00176 if(m_sampleIndices.size() == 0) {
00177 DLR_THROW(ValueException,
00178 "NChooseKSampleSelector::NChooseKSampleSelector()",
00179 "Argument sampleSize must be nonzero.");
00180 }
00181 if(m_sampleIndices.size() > m_poolVector.size()) {
00182 DLR_THROW(ValueException,
00183 "NChooseKSampleSelector::NChooseKSampleSelector()",
00184 "Argument sampleSize must be less than or equal to "
00185 "the number of elements in the input sequence.");
00186 }
00187 }
00188
00189
00190 template <class Sample>
00191 size_t
00192 NChooseKSampleSelector<Sample>::
00193 getNumberOfSamples()
00194 {
00195 if(m_numberOfSamples == 0) {
00196
00197 size_t nFactorial = this->getFactorial(m_poolVector.size());
00198 size_t kFactorial = this->getFactorial(m_sampleIndices.size());
00199 size_t nMinusKFactorial = this->getFactorial(
00200 m_poolVector.size() - m_sampleIndices.size());
00201 m_numberOfSamples = nFactorial / (kFactorial * nMinusKFactorial);
00202 }
00203 return m_numberOfSamples;
00204 }
00205
00206
00207 template <class Sample>
00208 typename NChooseKSampleSelector<Sample>::SampleSequenceType
00209 NChooseKSampleSelector<Sample>::
00210 getSample(size_t sampleNumber)
00211 {
00212 if(sampleNumber != m_previousSampleNumber + 1) {
00213 m_previousSampleNumber = sampleNumber;
00214 return this->statelessGetSample(sampleNumber);
00215 }
00216
00217
00218 this->incrementSampleIndices();
00219 for(size_t kk = 0; kk < m_sampleIndices.size(); ++kk) {
00220 m_sampleVector[kk] = m_poolVector[m_sampleIndices[kk]];
00221 }
00222 ++m_previousSampleNumber;
00223 return std::make_pair(m_sampleVector.begin(), m_sampleVector.end());
00224 }
00225
00226
00227 template <class Sample>
00228 size_t
00229 NChooseKSampleSelector<Sample>::
00230 getFactorial(size_t argument)
00231 {
00232 size_t result = 1;
00233 for(size_t ii = 2; ii <= argument; ++ii) {
00234 result *= ii;
00235 }
00236 return result;
00237 }
00238
00239
00240 template <class Sample>
00241 void
00242 NChooseKSampleSelector<Sample>::
00243 incrementSampleIndices()
00244 {
00245 size_t const finalIndex = m_sampleIndices.size() - 1;
00246
00247
00248 ++(m_sampleIndices[finalIndex]);
00249
00250
00251 size_t ii = finalIndex;
00252 while(m_sampleIndices[finalIndex] >= m_poolVector.size()) {
00253
00254 if((--ii) > m_sampleIndices.size()) {
00255 DLR_THROW(IndexException,
00256 "NChooseKSampleSelector::incrementSampleIndices()",
00257 "No more samples available.");
00258 }
00259 ++(m_sampleIndices[ii]);
00260 for(size_t jj = ii + 1; jj < m_sampleIndices.size(); ++jj) {
00261 m_sampleIndices[jj] = m_sampleIndices[jj - 1] + 1;
00262 }
00263 }
00264 }
00265
00266
00267 template <class Sample>
00268 typename NChooseKSampleSelector<Sample>::SampleSequenceType
00269 NChooseKSampleSelector<Sample>::
00270 statelessGetSample(size_t sampleNumber)
00271 {
00272 for(size_t ii = 0; ii < m_sampleIndices.size(); ++ii) {
00273 m_sampleIndices[ii] = ii;
00274 }
00275 for(size_t jj = 0; jj < sampleNumber; ++jj) {
00276 this->incrementSampleIndices();
00277 }
00278 for(size_t kk = 0; kk < m_sampleIndices.size(); ++kk) {
00279 m_sampleVector[kk] = m_poolVector[m_sampleIndices[kk]];
00280 }
00281 return std::make_pair(m_sampleVector.begin(), m_sampleVector.end());
00282 }
00283
00284 }
00285
00286 }
00287
00288 #endif