Class: DiscreteDistribution

Inherits:
Object
  • Object
show all
Defined in:
lib/discrete_distribution.rb,
lib/discrete_distribution/version.rb,
lib/discrete_distribution/alias_table.rb

Overview

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

  • US: 50

  • CA: 20

  • FR: 15

  • RU: 10

instead of

  • US: Rational(10, 19)

  • CA: Rational( 4, 19)

  • FR: Rational( 3, 19)

  • RU: Rational( 2, 19)

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

pairs instead of separate arrays of objects and associated probabilities

Defined Under Namespace

Classes: AliasTable

Constant Summary collapse

VERSION =
'1.0.1'

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(hash) ⇒ DiscreteDistribution

Returns a new instance of DiscreteDistribution.

Parameters:

  • hash (Hash{Object => Numeric})

    Map of observed objects to the number of observations



28
29
30
31
32
33
# 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

Class Method Details

.normalize(observations) ⇒ Array<Rational>

Parameters:

  • observations (Array<Numeric>)

Returns:

  • (Array<Rational>)


66
67
68
69
70
# 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

Instance Method Details

#merge(sample_set) ⇒ DiscreteDistribution

Parameters:

Returns:



50
51
52
53
# 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) ⇒ Object

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



38
39
40
41
42
43
44
# 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