Commit 962abebbf215337ffe4ec227d58b9e8b458f12c5

Authored by Charles Otto
1 parent d56eb4f2

Replace use of rand() in RandSample, this was resulting in poor results from RndSubspace on windows

openbr/core/common.cpp
... ... @@ -16,21 +16,32 @@
16 16  
17 17 #include "common.h"
18 18 #include <QMutex>
  19 +#include <RandomLib\Random.hpp>
19 20  
20 21 using namespace std;
21 22  
  23 +static RandomLib::Random g_rand;
  24 +static QMutex rngLock;
  25 +
22 26 /**** GLOBAL ****/
23 27 void Common::seedRNG() {
24   - static QMutex seedControl;
25   - QMutexLocker lock(&seedControl);
  28 + QMutexLocker lock(&rngLock);
26 29  
27 30 static bool seeded = false;
28 31 if (!seeded) {
29 32 srand(0); // We seed with 0 instead of time(NULL) to have reproducible randomness
30 33 seeded = true;
  34 + g_rand.Reseed(0);
31 35 }
32 36 }
33 37  
  38 +double Common::randN()
  39 +{
  40 + QMutexLocker lock(&rngLock);
  41 +
  42 + return g_rand.FloatN();
  43 +}
  44 +
34 45 QList<int> Common::RandSample(int n, int max, int min, bool unique)
35 46 {
36 47 QList<int> samples; samples.reserve(n);
... ...
openbr/core/common.h
... ... @@ -220,6 +220,9 @@ double KernelDensityEstimation(const V&lt;T&gt; &amp;vals, double x, double h)
220 220 return y / (vals.size() * h);
221 221 }
222 222  
  223 +// Return a random number, uniformly distributed over 0,1
  224 +double randN();
  225 +
223 226 /*!
224 227 * \brief Returns a vector of n integers sampled in the range <min, max].
225 228 *
... ... @@ -236,19 +239,14 @@ QList&lt;int&gt; RandSample(int n, const QSet&lt;int&gt; &amp;values, bool unique = false);
236 239 template <typename T>
237 240 QList<int> RandSample(int n, const QList<T> &weights, bool unique = false)
238 241 {
239   - static bool seeded = false;
240   - if (!seeded) {
241   - srand(time(NULL));
242   - seeded = true;
243   - }
244   -
245 242 QList<T> cdf = CumSum(weights);
246 243 for (int i=0; i<cdf.size(); i++) // Normalize cdf
247 244 cdf[i] = cdf[i] / cdf.last();
248 245  
249 246 QList<int> samples; samples.reserve(n);
250 247 while (samples.size() < n) {
251   - T r = (T)rand() / (T)RAND_MAX;
  248 + T r = randN();
  249 +
252 250 for (int j=0; j<weights.size(); j++) {
253 251 if ((r >= cdf[j]) && (r <= cdf[j+1])) {
254 252 if (!unique || !samples.contains(j))
... ...