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