class Probably::Distribution

The Discrete Distribution representation class

Public Class Methods

new(init_type, *data) click to toggle source

Creates a new Discrete Distribution with said constructor type (init_type) and initial data upon construction the data are automatically normalized if init_type is:

  • :MAP then the given map use used directly and should not

    be used anymore by someone else but the current 
    distribution class
  • :MAPCOPY then the given map is copied for further use

  • :LISTS then the second parameter is the list of keys and the

    third parameter the corresponding list of probabilities
    
# File lib/prob.rb, line 68
def initialize(init_type, *data)
    case init_type
        when :MAP 
            @map = data[0]
        when :MAPCOPY
            init_map(data[0])
        when :LISTS
            init_lsts(data[0], data[1])
        else
            raise "unable to create probability distribution"
    end
    self.normalize_probabilities
end

Public Instance Methods

*(other) click to toggle source
# File lib/prob.rb, line 202
def * (other)
    self.mult other
end
adjust_min(new_min = 0.01) click to toggle source
# File lib/prob.rb, line 241
def adjust_min(new_min = 0.01)
    tmp = Hash.new(0)
    self.each do |prob, value|
        tmp[value] = if prob > new_min then prob else new_min end
    end
    self.class.new :MAP, tmp
end
dep() { |key| ... } click to toggle source
# File lib/prob.rb, line 167
def dep
    self.class.new :MAP, block1(Hash.new(0)) {|m|
        @map.each do |key, p1|
            tmp = yield key
            if tmp != nil
                tmp.each do |p2, value|
                    m[value] += p1 * p2
                end
            else
                m[nil] += p1
            end
        end
        }
end
distance(other) click to toggle source
# File lib/prob.rb, line 234
def distance(other)
    (self.keys | other.keys).reduce(0) {|sum, value|
        tmp = self.probability(value) - other.probability(value)
        sum + tmp * tmp
    }
end
each() { |prob, value| ... } click to toggle source
# File lib/prob.rb, line 125
def each
    @map.each { |value, prob| yield prob, value }
end
event_dep(pred) { |value| ... } click to toggle source
# File lib/prob.rb, line 182
def event_dep(pred)
    self.dep {|value|
        if !pred.call value 
            nil
        else 
            yield value
        end
    }
end
expectation() click to toggle source

computes expectation given that keys in distribution are numeric

# File lib/prob.rb, line 208
def expectation
    @map.reduce(0) {|sum, (value, p)| sum + value.to_f * p }
end
filter() { |value)| ... } click to toggle source
# File lib/prob.rb, line 137
def filter
    self.class.new :MAP, @map.reject { |value,prob|
        !(yield value)
    }
end
join() click to toggle source
# File lib/prob.rb, line 156
def join
    tmp = Hash.new(0)

    @map.each do |dist, p1|
        dist.each do |p2, value|
            tmp[value] += p1 * p2 
        end
    end
    self.class.new(:MAP, tmp)
end
keys() click to toggle source

set of keys in distribution

# File lib/prob.rb, line 83
def keys
    @map.keys
end
map() { |value| ... } click to toggle source
# File lib/prob.rb, line 129
def map
    tmp = Hash.new(0)
    @map.each do |value, prob|
        tmp[yield(value)] += prob
    end
    self.class.new(:MAP, tmp)
end
most_probable() click to toggle source

use most_probable to retrieve most probable event and its probability from given distribution

# File lib/prob.rb, line 107
def most_probable
    @map.reduce { |best, value|
        if best[1] < value[1] then value else best end
    }
end
mult(dist2) { |k, k2| ... } click to toggle source
# File lib/prob.rb, line 192
def mult(dist2)
    self.dep do |k|
        if block_given? 
            dist2.map { |k2| yield(k, k2) }
        else      
            dist2.map { |k2| [k, k2] }
        end
    end
end
normalize() click to toggle source

returns normalized distribution removing all nil values. In combination with condition, normalize must be used to compute normalization of bayes theorem

# File lib/prob.rb, line 91
def normalize
    if @map[nil] > 0.0
        self.filter { |value| value != nil }
    else
        self
    end
end
pick() click to toggle source

randomly pick a key-value with respect to its probability in given distribution

# File lib/prob.rb, line 115
def pick
    tst = rand
    sum = 0
    @map.each do |value, prob|
        sum += prob
        return value,prob if tst < sum
    end
    return nil
end
probability(val) click to toggle source

returns probability of event val from distribution

# File lib/prob.rb, line 101
def probability(val)
    @map[val] 
end
query?() { |dat then probability + dp| ... } click to toggle source
# File lib/prob.rb, line 149
def query?
    @map.reduce(0) {|probability, (dat,dp)|
        if yield dat then probability + dp
        else probability end
    }
end
reject() { |value| ... } click to toggle source
# File lib/prob.rb, line 143
def reject
    self.class.new :MAP, @map.reject { |value, prob|
        yield value
    }
end
std_dev() click to toggle source

computes standard deviation given that keys in distribution are numeric

# File lib/prob.rb, line 224
def std_dev
    Math.sqrt( self.variance )
end
to_s() click to toggle source
# File lib/prob.rb, line 228
def to_s
    @map.reduce("") { |str,(value, prob)|
        str + "#{value} : #{prob * 100} %\n"
    }
end
variance() click to toggle source

computes variance given that keys in distribution are numeric

# File lib/prob.rb, line 214
def variance
    expected = self.expectation
    @map.reduce(0) {|sum, (value,p)| 
        tmp = (value.to_f - expectation)
        sum + tmp * tmp * p 
    }
end

Protected Instance Methods

init_lsts(data, shape) click to toggle source
# File lib/prob.rb, line 37
def init_lsts(data, shape)
    @map = Hash.new(0)
    count = data.length
    data.each_with_index { |value, index| 
        @map[value] += shape.call( Float(index + 1) / count  )
    }
end
init_map(map) click to toggle source
# File lib/prob.rb, line 45
def init_map(map)
    @map = Hash.new(0)
    map.each { |value, prob| @map[value] = prob }
    self.normalize_probabilities
end
normalize_probabilities() click to toggle source
# File lib/prob.rb, line 51
def normalize_probabilities
    sum = Float( @map.values.inject(:+) )
    @map.keys.each { |value| @map[value] /= sum } if sum != 1.0
end