statfeed 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9c60df28cfbe507a544ecbdd58cd0c24f1d8ac87
4
+ data.tar.gz: 81da8653f2970b5295fd2c84410725e9fc4e86a9
5
+ SHA512:
6
+ metadata.gz: 2411be809e795c59c8d6f9208449d03af3f756a7ed72d508852d21c2d250789a13c01734f485c6a31758bfdf0af1acc76137846a8c653bf8ab294764ceda9d84
7
+ data.tar.gz: cd055760f586d4f00734623e32adbe2d3987c8ff4eda5e2ec26b92c4de2121b90236430a6ef838287c958bf7ffd68610812b2e5f29472f7c23ee0211e4a5adc6
@@ -0,0 +1,25 @@
1
+ # -*- ruby -*-
2
+
3
+ require "autotest/restart"
4
+
5
+ # Autotest.add_hook :initialize do |at|
6
+ # at.testlib = "minitest/unit"
7
+ #
8
+ # at.extra_files << "../some/external/dependency.rb"
9
+ #
10
+ # at.libs << ":../some/external"
11
+ #
12
+ # at.add_exception "vendor"
13
+ #
14
+ # at.add_mapping(/dependency.rb/) do |f, _|
15
+ # at.files_matching(/test_.*rb$/)
16
+ # end
17
+ #
18
+ # %w(TestA TestB).each do |klass|
19
+ # at.extra_class_map[klass] = "test/test_misc.rb"
20
+ # end
21
+ # end
22
+
23
+ # Autotest.add_hook :run_command do |at|
24
+ # system "rake build"
25
+ # end
File without changes
@@ -0,0 +1,6 @@
1
+ === 1.0.0 / 2015-04-23
2
+
3
+ * 1 major enhancement
4
+
5
+ * Birthday!
6
+
@@ -0,0 +1,8 @@
1
+ .autotest
2
+ History.txt
3
+ Manifest.txt
4
+ README.txt
5
+ Rakefile
6
+ bin/statfeed
7
+ lib/statfeed.rb
8
+ test/test_statfeed.rb
@@ -0,0 +1,58 @@
1
+ = statfeed
2
+
3
+ * http://www.github.com/andrewcsmith/statfeed
4
+
5
+ == DESCRIPTION:
6
+
7
+ Statistical feedback algorithm in Ruby. Taken from Charles Ames' paper
8
+ "Statistics and Compositional Balance," in Perspectives of New Music.
9
+
10
+ == FEATURES/PROBLEMS:
11
+
12
+ * keeps track of statistics and gives you a balanced distrubtion
13
+
14
+ == SYNOPSIS:
15
+
16
+ FIX (code sample of usage)
17
+
18
+ == REQUIREMENTS:
19
+
20
+ * ruby
21
+
22
+ == INSTALL:
23
+
24
+ gem install statfeed
25
+
26
+ == DEVELOPERS:
27
+
28
+ After checking out the source, run:
29
+
30
+ $ rake newb
31
+
32
+ This task will install any missing dependencies, run the tests/specs,
33
+ and generate the RDoc.
34
+
35
+ == LICENSE:
36
+
37
+ (The MIT License)
38
+
39
+ Copyright (c) 2015 FIX
40
+
41
+ Permission is hereby granted, free of charge, to any person obtaining
42
+ a copy of this software and associated documentation files (the
43
+ 'Software'), to deal in the Software without restriction, including
44
+ without limitation the rights to use, copy, modify, merge, publish,
45
+ distribute, sublicense, and/or sell copies of the Software, and to
46
+ permit persons to whom the Software is furnished to do so, subject to
47
+ the following conditions:
48
+
49
+ The above copyright notice and this permission notice shall be
50
+ included in all copies or substantial portions of the Software.
51
+
52
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
53
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
54
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
55
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
56
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
57
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
58
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,22 @@
1
+ # -*- ruby -*-
2
+
3
+ require "rubygems"
4
+ require "hoe"
5
+
6
+ # Hoe.plugin :compiler
7
+ # Hoe.plugin :gem_prelude_sucks
8
+ # Hoe.plugin :inline
9
+ # Hoe.plugin :minitest
10
+ # Hoe.plugin :racc
11
+ # Hoe.plugin :rcov
12
+ # Hoe.plugin :rdoc
13
+
14
+ Hoe.spec "statfeed" do
15
+ developer("Andrew Smith", "andrewchristophersmith@gmail.com")
16
+
17
+ # self.group_name = "statfeed" # if part of an organization/group
18
+
19
+ # license "MIT" # this should match the license in the README
20
+ end
21
+
22
+ # vim: syntax=ruby
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ abort "you need to write me"
@@ -0,0 +1,123 @@
1
+ class Statfeed
2
+ VERSION = "1.0.1"
3
+ attr_accessor :weights, :choices, :randoms, :heterogeneities, :accents, :statistics, :size, :decisions, :options
4
+
5
+ def initialize decisions, options, heterogeneity: 0.1, accent: 1.0
6
+ @decisions = decisions
7
+ @options = options
8
+
9
+ # This will eventually be the result of applying statistical feedback
10
+ @choices = Array.new(@decisions.size, nil)
11
+
12
+ # Vector of heterogeneity values for each decision
13
+ @heterogeneities = Array.new(decisions.size, heterogeneity)
14
+ # Vector of accent values for each decision
15
+ @accents = Array.new(decisions.size, accent)
16
+ # Vector of statistic for each option
17
+ reset_statistics
18
+
19
+ # Fill matrix of random values
20
+ populate_randoms
21
+ # Fill matrix of weights
22
+ populate_weights
23
+ end
24
+
25
+ def reset_statistics
26
+ @statistics = Array.new(options.size, 0.0)
27
+ end
28
+
29
+ def populate_choices
30
+ @decisions.each_index do |decision|
31
+ vals = scheduling_values(decision)
32
+ @choices[decision] = sort_options(vals).first
33
+ increment_statistics decision, sort_option_indices(vals).first
34
+ normalize_statistics! decision
35
+ end
36
+ @choices
37
+ end
38
+
39
+ def populate_randoms
40
+ @randoms = Array.new @decisions.size do
41
+ Array.new @options.size do
42
+ rand
43
+ end
44
+ end
45
+ end
46
+
47
+ def populate_weights
48
+ @weights = Array.new @decisions.size do
49
+ Array.new @options.size do
50
+ 1.0 / @options.size
51
+ end
52
+ end
53
+ end
54
+
55
+ def expected_increment decision, option
56
+ (@accents[decision] + (@heterogeneities[decision] * @randoms[decision][option])).to_f / @weights[decision][option]
57
+ end
58
+
59
+ def true_increment decision, option
60
+ @accents[decision].to_f / @weights[decision][option]
61
+ end
62
+
63
+ def normalization_value decision
64
+ @accents[decision].to_f / @weights[decision].inject(0.0, :+)
65
+ end
66
+
67
+ def scheduling_values decision
68
+ (0...@options.size).map do |m|
69
+ @statistics[m] + expected_increment(decision, m)
70
+ end
71
+ end
72
+
73
+ # Feed the scheduling values into this (step 2)
74
+ def sort_options vals
75
+ @options.zip(vals).sort_by(&:last).map(&:first)
76
+ end
77
+
78
+ # Feed the scheduling values into this (step 2)
79
+ def sort_option_indices vals
80
+ (0...@options.size).to_a.zip(vals).sort_by(&:last).map(&:first)
81
+ end
82
+
83
+ def increment_statistics decision, option
84
+ @statistics[option] += true_increment(decision, option)
85
+ end
86
+
87
+ def normalize_statistics decision
88
+ @statistics.each_with_index.map do |statistic, m|
89
+ if @weights[decision][m] > 0.0
90
+ statistic - normalization_value(decision)
91
+ else
92
+ statistic
93
+ end
94
+ end
95
+ end
96
+
97
+ def normalize_statistics! decision
98
+ @statistics = normalize_statistics decision
99
+ end
100
+
101
+ def sample
102
+ # Accumulator value
103
+ acc = 0.0
104
+ # Map the cumulative weights
105
+ cdf = @weights.map { |w| acc += w }
106
+ # Get a random number between 0.0 and the last value
107
+ r = rand(cdf.last)
108
+ # Gets the first number that's less than the random number
109
+ index = cdf.find_index { |c| c > r }
110
+
111
+ @weights = @weights.map { |w|
112
+ # Increment the full thing by a total of 1.0
113
+ w += (@weights[index].to_f / (@weights.size-1.0))
114
+ }
115
+ @weights[index] = 0
116
+
117
+ if block_given?
118
+ yield index
119
+ else
120
+ index
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,69 @@
1
+ require "minitest/autorun"
2
+ require "statfeed"
3
+
4
+ class TestStatfeed < Minitest::Test
5
+ def setup
6
+ @sf = Statfeed.new([0, 1, 2], %w(a b c))
7
+ # Need to control the "random" numbers in order to assert answers
8
+ @sf.randoms = [[0.1, 0.2, 0.3], [0.4, 0.5, 0.6], [0.7, 0.8, 0.9]]
9
+ end
10
+
11
+ def test_true_increment
12
+ assert_in_delta 3.0, @sf.true_increment(0, 0)
13
+ end
14
+
15
+ def test_expected_increment
16
+ actual = @sf.expected_increment(0, 0)
17
+ assert_in_delta 3.03, actual
18
+ end
19
+
20
+ def test_scheduling_values
21
+ actual = @sf.scheduling_values(0)
22
+ assert_each_in_delta [3.03, 3.06, 3.09], actual
23
+ end
24
+
25
+ def test_sort_options
26
+ actual = @sf.sort_options([0.3, 0.5, 0.4])
27
+ assert_each_equal %w(a c b), actual
28
+ end
29
+
30
+ def test_n_decisions
31
+ # Should have N possible decisions
32
+ end
33
+
34
+ def test_m_options
35
+ # Should have a common pool of M possible options
36
+ end
37
+
38
+ def test_s_sub_m
39
+ # Should have a statistic S_m for the statistic associated with option m
40
+ end
41
+
42
+ def test_a_sub_n
43
+ # Accent (stress) associated with the decision n
44
+ end
45
+
46
+ def test_h_sub_n
47
+ # Heterogeneity associated with decision n
48
+ end
49
+
50
+ def test_w_sub_m_n
51
+ # Weight associated with option m during decision n
52
+ end
53
+
54
+ def test_u_sub_m_n
55
+ # Uniformly distributed random number for each option of each decision
56
+ end
57
+
58
+ def assert_each_in_delta exp, act, delta = 0.001
59
+ exp.zip(act).each do |e, a|
60
+ assert_in_delta e, a, delta
61
+ end
62
+ end
63
+
64
+ def assert_each_equal exp, act
65
+ exp.zip(act).each do |e, a|
66
+ assert_equal e, a
67
+ end
68
+ end
69
+ end
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: statfeed
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Andrew Smith
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-05-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rdoc
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: hoe
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.13'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.13'
41
+ description: |-
42
+ Statistical feedback algorithm in Ruby. Taken from Charles Ames' paper
43
+ "Statistics and Compositional Balance," in Perspectives of New Music.
44
+ email:
45
+ - andrewchristophersmith@gmail.com
46
+ executables:
47
+ - statfeed
48
+ extensions: []
49
+ extra_rdoc_files:
50
+ - History.txt
51
+ - Manifest.txt
52
+ - README.txt
53
+ files:
54
+ - ".autotest"
55
+ - ".gemtest"
56
+ - History.txt
57
+ - Manifest.txt
58
+ - README.txt
59
+ - Rakefile
60
+ - bin/statfeed
61
+ - lib/statfeed.rb
62
+ - test/test_statfeed.rb
63
+ homepage: http://www.github.com/andrewcsmith/statfeed
64
+ licenses:
65
+ - MIT
66
+ metadata: {}
67
+ post_install_message:
68
+ rdoc_options:
69
+ - "--main"
70
+ - README.txt
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ requirements: []
84
+ rubyforge_project:
85
+ rubygems_version: 2.4.5
86
+ signing_key:
87
+ specification_version: 4
88
+ summary: Statistical feedback algorithm in Ruby
89
+ test_files: []