Class: Rust::RandomVariable

Inherits:
RandomVariableSlice show all
Defined in:
lib/rust/stats/probabilities.rb

Overview

Represents a random variable. The cumulative probability of the values must equal 1.

Direct Known Subclasses

UniformRandomVariable

Constant Summary collapse

EPSILON =
1e-7

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from RandomVariableSlice

#<, #<=, #==, #>, #>=, #between, #expected, #ml, #so_that

Constructor Details

#initialize(values = {0 => 1.0}, exact = false) ⇒ RandomVariable

Creates a new random variable. values is a hash of values associated with their probabilities. exact indicates whether this variable, when combined with others, should force to keep all the values, even the most unlikely ones. If this is false (default), the most improbable values (lower than EPSILON) are removed for efficiency reasons.



152
153
154
155
156
157
158
159
160
# File 'lib/rust/stats/probabilities.rb', line 152

def initialize(values = {0 => 1.0}, exact = false)
    @values = values
    @exact = exact
    
    raise "All the probabilities should be in the range [0, 1]" unless @values.values.all? { |v| v.between? 0, 1 }
    raise "The cumulative probability must be exactly 1 (#{@values.values.sum} instead)"        unless @values.values.sum.between? 1-EPSILON, 1+EPSILON
    
    approx!
end

Instance Attribute Details

#valuesObject (readonly)

Returns the value of attribute values.



144
145
146
# File 'lib/rust/stats/probabilities.rb', line 144

def values
  @values
end

Class Method Details

.complete(hash, key = 0) ⇒ Object

Creates a random variable by partially specifying the values through hash. The remaining probability is attributed to key (0, by default).



271
272
273
274
# File 'lib/rust/stats/probabilities.rb', line 271

def self.complete(hash, key=0)
    hash[key] = 1 - hash.values.sum
    return RandomVariable.new(hash)
end

Instance Method Details

#*(arg) ⇒ Object

Based on the type of arg, either mul (product with another random variable) or rep (repeated sum) is called.



189
190
191
192
193
194
195
196
197
# File 'lib/rust/stats/probabilities.rb', line 189

def *(arg)
    if arg.is_a? Integer
        return rep(arg)
    elsif arg.is_a? RandomVariable
        return mul(arg)
    else
        raise "The argument must be an Integer or a RandomVariable"
    end
end

#+(other) ⇒ Object

Returns a new random variable which represents the sum of this and the other random variable.



172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/rust/stats/probabilities.rb', line 172

def +(other)
    new_hash = {}
    
    @values.each do |my_key, my_value|
        other.values.each do |other_key, other_value|
            sum_key = my_key + other_key
            
            new_hash[sum_key] = new_hash[sum_key].to_f + (my_value * other_value)
        end
    end
    
    return RandomVariable.new(new_hash, @exact)
end

#approx!Object

If this variable is not exact, the values with probability lower than EPSLION are removed.



238
239
240
241
242
243
244
245
246
247
248
249
250
251
# File 'lib/rust/stats/probabilities.rb', line 238

def approx!
    return if @exact
    
    to_delete = []
    @values.each do |v, probability|
        to_delete.push v if probability <= EPSILON
    end
    
    to_delete.each do |v| 
        probability = @values.delete v
        nearest = @values.keys.min_by { |k| k._rust_prob_distance v }
        @values[nearest] += probability
    end
end

#exact!Object

Makes sure that the operations yield all the values, even the most unlikely ones.



231
232
233
# File 'lib/rust/stats/probabilities.rb', line 231

def exact!
    @exact = true
end

#extractObject

Returns a random value, according to the data distribution.



256
257
258
259
260
261
262
263
264
265
# File 'lib/rust/stats/probabilities.rb', line 256

def extract
    v = rand
    
    cumulative = 0
    @values.sort_by { |k, v| k }.each do |key, prob|
        cumulative += prob
        
        return key if cumulative >= v
    end
end

#mul(other) ⇒ Object

Returns a new random variable which represents the product of this and the other random variable.



202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/rust/stats/probabilities.rb', line 202

def mul(other)
    new_hash = {}

    @values.each do |my_key, my_value|
        other.values.each do |other_key, other_value|
            mul_key = my_key * other_key
            
            new_hash[mul_key] = new_hash[mul_key].to_f + (my_value * other_value)
        end
    end

    return RandomVariable.new(new_hash, @exact)
end

#probability(v) ⇒ Object

Returns the probability of value v.



165
166
167
# File 'lib/rust/stats/probabilities.rb', line 165

def probability(v)
    return @values[v].to_f
end

#rep(times) ⇒ Object

Returns a new random variable which represents the sum of this random variable with itself n times.



219
220
221
222
223
224
225
226
# File 'lib/rust/stats/probabilities.rb', line 219

def rep(times)
    rv = self
    (times-1).times do
        rv += self
    end
    
    return rv
end