class DiscreteDistribution

Convenience wrapper around DiscreteDistribution::AliasTable

  1. Provides same interface as Array to obtain random element (i.e.,

‘#sample`)

  1. Normalizes observation counts into set of probabilities. I.e.,

allows user to specify

instead of

  1. Initializer takes a hash of ‘observed_object => num_observation`

pairs instead of separate arrays of objects and associated probabilities

Constants

VERSION

Public Class Methods

new(hash) click to toggle source

@param hash [Hash{Object => Numeric}]

Map of observed objects to the number of observations
# File lib/discrete_distribution.rb, line 28
def initialize(hash)
  @original_observations = hash.dup

  probabilities = self.class.normalize(original_observations.values)
  @alias_table = AliasTable.new(original_observations.keys, probabilities)
end
normalize(observations) click to toggle source

@param observations [Array<Numeric>]

@return [Array<Rational>]

# File lib/discrete_distribution.rb, line 66
def self.normalize(observations)
  rationals = observations.map(&:to_r)
  divisor = rationals.inject(:+)
  rationals.map { |r| r / divisor }
end

Public Instance Methods

merge(sample_set) click to toggle source

@param sample_set [Hash{Object=>Numeric},DiscreteDistribution]

@return [DiscreteDistribution]

# File lib/discrete_distribution.rb, line 50
def merge(sample_set)
  hash = sample_set.kind_of?(self.class) ? sample_set.original_observations : sample_set
  self.class.new(@original_observations.merge(hash))
end
sample(*args) click to toggle source

TODO: Add the separate argument cases mimicking Array#sample TODO: Add ability to provide own random number generator

# File lib/discrete_distribution.rb, line 38
def sample(*args)
  if args.empty?
    @alias_table.generate
  else
    Array.new(args.first) { @alias_table.generate }
  end
end

Protected Instance Methods

original_observations() click to toggle source

@return [Hash]

# File lib/discrete_distribution.rb, line 57
def original_observations
  @original_observations
end