class StdRandom

Public Class Methods

bernoulli(p=0.5) click to toggle source

Returns a random boolean from a Bernoulli distribution with success probability p

# 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() click to toggle source

return a random real number from the Cauchy distribution.

# 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) click to toggle source
  • Returns a random real number from a standard Gaussian distribution.

# 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) click to toggle source

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

# 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) click to toggle source

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

# 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) click to toggle source

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

# 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) click to toggle source

Returns a random integer uniformly in [a, b). Returns a random long integer uniformly in [0, n).

# 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

Private Class Methods

uniform_int(n) click to toggle source
# File lib/princeton_standard_libs/std_random.rb, line 105
def self.uniform_int(n)
  throw "argument must be positive: #{n}" if n <= 0

  r = srand
  m = n - 1

  # power of two
  return r & m if (n & m) == 0

  # reject over-represented candidates
  u = unsigned_shift(r, 1)
  while u + m - (r = u % n) < 0
    u = unsigned_shift(srand, 1)
  end

  r
end
unsigned_shift(val, amt) click to toggle source
# File lib/princeton_standard_libs/std_random.rb, line 123
def self.unsigned_shift(val, amt)
  mask = (1 << (32 - amt)) - 1
  (val >> amt) & mask
end