0.9.8.10
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
DiscreteRandomGenerator.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2007-2015 Hypertable, Inc.
3  *
4  * This file is part of Hypertable.
5  *
6  * Hypertable is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 3
9  * of the License, or any later version.
10  *
11  * Hypertable is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19  * 02110-1301, USA.
20  */
21 
27 #include "Common/Compat.h"
28 #include "Common/Logger.h"
29 
31 
32 using namespace Hypertable;
33 
35 {
36  if (m_cmf == 0) {
38  if (m_value_count == 0)
40  else if (m_pool_max == 0)
42  m_numbers = new uint64_t [ m_value_count ];
43  m_cmf = new double [ m_value_count + 1 ];
44  generate_cmf();
45  }
46 
47  uint64_t upper = m_value_count;
48  uint64_t lower = 0;
49  uint64_t ii;
50 
51  double rand = std::uniform_real_distribution<>()(m_random_engine);
52 
53  assert(rand >= 0.0 && rand <= 1.0);
54 
55  // do a binary search through cmf to figure out which index in cmf
56  // rand lies in. this will transform the uniform[0,1] distribution into
57  // the distribution specified in m_cmf
58  while (true) {
59 
60  assert(upper >= lower);
61  ii = (upper + lower) / 2;
62  if (m_cmf[ii] >= rand) {
63  if (ii == 0 || m_cmf[ii - 1] <= rand)
64  break;
65  else {
66  upper = ii - 1;
67  continue;
68  }
69  }
70  else {
71  lower = ii + 1;
72  continue;
73  }
74  }
75 
76  return m_numbers[ii];
77 }
78 
80 {
81  uint64_t ii;
82  double norm_const;
83 
84  if (m_value_count == m_pool_max) {
85  uint64_t temp_num, index;
86  for (uint64_t i = 0; i < m_value_count; i++)
87  m_numbers[i] = i;
88  // randomize the array of numbers
89  for (uint64_t i = 0; i < m_value_count; i++) {
90  index = std::uniform_int_distribution<uint64_t>(0, m_value_count-1)(m_random_engine);
91  temp_num = m_numbers[0];
92  m_numbers[0] = m_numbers[index];
93  m_numbers[index] = temp_num;
94  }
95  }
96  else {
97  uint64_t pool_diff = m_pool_max - m_pool_min;
98  for (uint64_t i = 0; i < m_value_count; i++)
99  m_numbers[i] = m_pool_min + std::uniform_int_distribution<uint64_t>(0, pool_diff-1)(m_random_engine);
100  }
101 
102  m_cmf[0] = pmf(0);
103  for (ii = 1; ii < m_value_count + 1; ++ii) {
104  m_cmf[ii] = m_cmf[ii - 1] + pmf(ii);
105  }
106  norm_const = m_cmf[m_value_count];
107  // renormalize cmf
108  for (ii = 0; ii < m_value_count + 1 ;++ii) {
109  m_cmf[ii] /= norm_const;
110  }
111 }
112 
uint64_t m_pool_min
Lower bound of the range.
uint64_t * m_numbers
Array with the random samples.
#define HT_ASSERT(_e_)
Definition: Logger.h:396
Discrete Random Generator.
uint64_t m_pool_max
Upper bound of the range.
std::mt19937 m_random_engine
The random number generator.
uint64_t m_value_count
Number of values in the range.
Logging routines and macros.
Compatibility Macros for C/C++.
Hypertable definitions
virtual double pmf(uint64_t val)
Returns the probability of drawing a specific value from the distribution.
virtual uint64_t get_sample()
Returns a random sample from the distribution.
virtual void generate_cmf()
Generate the cumulative mass function for the distribution.
double * m_cmf
The cumulative mass of the distribution.