Class: Statfeed

Inherits:
Object
  • Object
show all
Defined in:
lib/statfeed.rb

Constant Summary collapse

VERSION =
"1.0.1"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(decisions, options, heterogeneity: 0.1, accent: 1.0) ⇒ Statfeed

Returns a new instance of Statfeed.



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/statfeed.rb', line 5

def initialize decisions, options, heterogeneity: 0.1, accent: 1.0
  @decisions = decisions
  @options = options

  # This will eventually be the result of applying statistical feedback
  @choices = Array.new(@decisions.size, nil)

  # Vector of heterogeneity values for each decision
  @heterogeneities = Array.new(decisions.size, heterogeneity)
  # Vector of accent values for each decision
  @accents = Array.new(decisions.size, accent)
  # Vector of statistic for each option
  reset_statistics

  # Fill matrix of random values
  populate_randoms
  # Fill matrix of weights
  populate_weights
end

Instance Attribute Details

#accentsObject

Returns the value of attribute accents.



3
4
5
# File 'lib/statfeed.rb', line 3

def accents
  @accents
end

#choicesObject

Returns the value of attribute choices.



3
4
5
# File 'lib/statfeed.rb', line 3

def choices
  @choices
end

#decisionsObject

Returns the value of attribute decisions.



3
4
5
# File 'lib/statfeed.rb', line 3

def decisions
  @decisions
end

#heterogeneitiesObject

Returns the value of attribute heterogeneities.



3
4
5
# File 'lib/statfeed.rb', line 3

def heterogeneities
  @heterogeneities
end

#optionsObject

Returns the value of attribute options.



3
4
5
# File 'lib/statfeed.rb', line 3

def options
  @options
end

#randomsObject

Returns the value of attribute randoms.



3
4
5
# File 'lib/statfeed.rb', line 3

def randoms
  @randoms
end

#sizeObject

Returns the value of attribute size.



3
4
5
# File 'lib/statfeed.rb', line 3

def size
  @size
end

#statisticsObject

Returns the value of attribute statistics.



3
4
5
# File 'lib/statfeed.rb', line 3

def statistics
  @statistics
end

#weightsObject

Returns the value of attribute weights.



3
4
5
# File 'lib/statfeed.rb', line 3

def weights
  @weights
end

Instance Method Details

#expected_increment(decision, option) ⇒ Object



55
56
57
# File 'lib/statfeed.rb', line 55

def expected_increment decision, option
  (@accents[decision] + (@heterogeneities[decision] * @randoms[decision][option])).to_f / @weights[decision][option]
end

#increment_statistics(decision, option) ⇒ Object



83
84
85
# File 'lib/statfeed.rb', line 83

def increment_statistics decision, option
  @statistics[option] += true_increment(decision, option)
end

#normalization_value(decision) ⇒ Object



63
64
65
# File 'lib/statfeed.rb', line 63

def normalization_value decision
  @accents[decision].to_f / @weights[decision].inject(0.0, :+)
end

#normalize_statistics(decision) ⇒ Object



87
88
89
90
91
92
93
94
95
# File 'lib/statfeed.rb', line 87

def normalize_statistics decision
  @statistics.each_with_index.map do |statistic, m|
    if @weights[decision][m] > 0.0
      statistic - normalization_value(decision)
    else
      statistic
    end
  end
end

#normalize_statistics!(decision) ⇒ Object



97
98
99
# File 'lib/statfeed.rb', line 97

def normalize_statistics! decision
  @statistics = normalize_statistics decision
end

#populate_choicesObject



29
30
31
32
33
34
35
36
37
# File 'lib/statfeed.rb', line 29

def populate_choices
  @decisions.each_index do |decision|
    vals = scheduling_values(decision)
    @choices[decision] = sort_options(vals).first
    increment_statistics decision, sort_option_indices(vals).first
    normalize_statistics! decision
  end
  @choices
end

#populate_randomsObject



39
40
41
42
43
44
45
# File 'lib/statfeed.rb', line 39

def populate_randoms
  @randoms = Array.new @decisions.size do
    Array.new @options.size do
      rand
    end
  end
end

#populate_weightsObject



47
48
49
50
51
52
53
# File 'lib/statfeed.rb', line 47

def populate_weights
  @weights = Array.new @decisions.size do
    Array.new @options.size do
      1.0 / @options.size
    end
  end
end

#reset_statisticsObject



25
26
27
# File 'lib/statfeed.rb', line 25

def reset_statistics
  @statistics = Array.new(options.size, 0.0)
end

#sampleObject



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/statfeed.rb', line 101

def sample
  # Accumulator value
  acc = 0.0
  # Map the cumulative weights
  cdf = @weights.map { |w| acc += w }
  # Get a random number between 0.0 and the last value
  r = rand(cdf.last)
  # Gets the first number that's less than the random number
  index = cdf.find_index { |c| c > r }
  
  @weights = @weights.map { |w|
    # Increment the full thing by a total of 1.0
    w += (@weights[index].to_f / (@weights.size-1.0))
  }
  @weights[index] = 0

  if block_given?
    yield index
  else
    index
  end
end

#scheduling_values(decision) ⇒ Object



67
68
69
70
71
# File 'lib/statfeed.rb', line 67

def scheduling_values decision
  (0...@options.size).map do |m|
    @statistics[m] + expected_increment(decision, m)
  end
end

#sort_option_indices(vals) ⇒ Object

Feed the scheduling values into this (step 2)



79
80
81
# File 'lib/statfeed.rb', line 79

def sort_option_indices vals
  (0...@options.size).to_a.zip(vals).sort_by(&:last).map(&:first)
end

#sort_options(vals) ⇒ Object

Feed the scheduling values into this (step 2)



74
75
76
# File 'lib/statfeed.rb', line 74

def sort_options vals
  @options.zip(vals).sort_by(&:last).map(&:first)
end

#true_increment(decision, option) ⇒ Object



59
60
61
# File 'lib/statfeed.rb', line 59

def true_increment decision, option
  @accents[decision].to_f / @weights[decision][option]
end