Class: StdRandom
- Inherits:
-
Object
- Object
- StdRandom
- Defined in:
- lib/princeton_standard_libs/std_random.rb
Class Method Summary collapse
-
.bernoulli(p = 0.5) ⇒ Object
Returns a random boolean from a Bernoulli distribution with success probability p.
-
.cauchy ⇒ Object
return a random real number from the Cauchy distribution.
-
.gaussian(mu = nil, sigma = nil) ⇒ Object
-
Returns a random real number from a standard Gaussian distribution.
-
-
.geometric(p) ⇒ Object
Returns a random integer from a geometric distribution with success probability p.
-
.pareto(alpha = nil) ⇒ Object
Returns a random real number from a Pareto distribution with shape parameter alpha.
-
.poisson(lmbda) ⇒ Object
Returns a random integer from a Poisson distribution with mean & lambda.
-
.uniform(a = 0, b = nil) ⇒ Object
Returns a random integer uniformly in [a, b).
Class Method Details
.bernoulli(p = 0.5) ⇒ Object
Returns a random boolean from a Bernoulli distribution with success probability p
23 24 25 26 |
# File 'lib/princeton_standard_libs/std_random.rb', line 23 def self.bernoulli(p=0.5) throw "probability p must be between 0.0 and 1.0: #{p}" if !(p >= 0.0 && p <= 1.0) uniform < p end |
.cauchy ⇒ Object
return a random real number from the Cauchy distribution.
99 100 101 |
# File 'lib/princeton_standard_libs/std_random.rb', line 99 def self.cauchy Math.tan(Math::PI * (uniform - 0.5)) end |
.gaussian(mu = nil, sigma = nil) ⇒ Object
-
Returns a random real number from a standard Gaussian distribution.
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/princeton_standard_libs/std_random.rb', line 29 def self.gaussian(mu=nil, sigma=nil) return mu + sigma * gaussian if mu && sigma #x use the polar form of the Box-Muller transform r, x, y = nil loop do x = uniform(-1.0, 1.0) y = uniform(-1.0, 1.0) r = (x*x) + (y*y) break unless r >= 1 || r == 0 end # Remark: y * Math.sqrt(-2 * Math.log(r) / r) # is an independent random gaussian input = -2 * (Math.log(r) / r) x * Math.sqrt(input) end |
.geometric(p) ⇒ Object
Returns a random integer from a geometric distribution with success
probability p.
The integer represents the number of independent trials
before the first success.
throws IllegalArgumentException unless p >= 0.0 and p <= 1.0
53 54 55 56 57 58 59 |
# File 'lib/princeton_standard_libs/std_random.rb', line 53 def self.geometric(p) throw "probability p must be greater than 0: #{p}" if !(p >= 0) throw "probability p must not be larger than 1: #{p}" if !(p <= 1.0) # using algorithm given by Knuth (Math.log(uniform) / Math.log(1.0 - p)).ceil end |
.pareto(alpha = nil) ⇒ Object
Returns a random real number from a Pareto distribution with shape parameter alpha
param alpha shape parameter return a random real number from a Pareto distribution with shape
parameter alpha
throws Exception unless alpha > 0.0
91 92 93 94 95 96 |
# File 'lib/princeton_standard_libs/std_random.rb', line 91 def self.pareto(alpha=nil) return pareto(1.0) if alpha.nil? throw "alpha must be positive: #{alpha}" if !(alpha > 0.0) ((1 - uniform) ** (-1.0/alpha)) - 1.0 end |
.poisson(lmbda) ⇒ Object
Returns a random integer from a Poisson distribution with mean & lambda.
param lambda the mean of the Poisson distribution return a random integer from a Poisson distribution with mean lambda throws Exception unless lambda > 0.0 and not infinite
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/princeton_standard_libs/std_random.rb', line 67 def self.poisson(lmbda) throw "lambda must be positive: #{lmbda}" if !(lmbda > 0.0) throw "lambda must not be infinite: #{lmbda}" if lmbda == Float::INFINITY # using algorithm given by Knuth # see http://en.wikipedia.org/wiki/Poisson_distribution k = 0 p = 1.0 expLambda = Math.exp(-lmbda) loop do k += 1 p *= uniform break unless p >= expLambda end k-1 end |
.uniform(a = 0, b = nil) ⇒ Object
Returns a random integer uniformly in [a, b). Returns a random long integer uniformly in [0, n).
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# File 'lib/princeton_standard_libs/std_random.rb', line 5 def self.uniform(a=0, b=nil) return rand if a == 0 && b.nil? if !a.zero? && b.nil? b = a a = 0 end throw "Invalid range: [#{a},#{b})" if b <= a if b.is_a?(Float) return a + rand * (b-a) else a + uniform_int(b - a) end end |