bernoulli 0.3.1 → 0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +0 -2
- data/LICENSE.md +22 -0
- data/README.md +48 -55
- data/Rakefile +12 -4
- data/bernoulli.gemspec +8 -9
- data/lib/bernoulli.rb +1 -84
- data/lib/bernoulli/distribution.rb +40 -0
- data/lib/bernoulli/distribution/binomial.rb +71 -0
- data/lib/bernoulli/distribution/geometric.rb +56 -0
- data/lib/bernoulli/distribution/hypergeometric.rb +55 -0
- data/lib/bernoulli/distribution/poisson.rb +58 -0
- data/lib/bernoulli/math.rb +8 -7
- data/lib/bernoulli/shorthand.rb +19 -0
- data/lib/bernoulli/version.rb +1 -2
- data/test/distribution/test_binomial.rb +52 -0
- data/test/distribution/test_geometric.rb +43 -0
- data/test/distribution/test_hypergeometric.rb +52 -0
- data/test/distribution/test_poisson.rb +64 -0
- data/test/helper.rb +12 -0
- data/test/test_math.rb +4 -7
- data/test/test_shorthand.rb +26 -0
- metadata +38 -20
- data/test/test_bernoulli.rb +0 -61
data/Gemfile
CHANGED
data/LICENSE.md
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Mikael Konutgan
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,8 +1,11 @@
|
|
1
|
-
# Bernoulli
|
1
|
+
# Bernoulli: Discrete probability distribution library for Ruby
|
2
2
|
|
3
|
-
|
3
|
+
**Bernoulli** implements the four most common discrete probability distributions in an object oriented manner and in pure Ruby.
|
4
4
|
|
5
|
-
|
5
|
+
- The binomial distribution
|
6
|
+
- The geometric distribution
|
7
|
+
- The hypergeometric distribution
|
8
|
+
- The Poisson distribution
|
6
9
|
|
7
10
|
## Installation
|
8
11
|
|
@@ -12,76 +15,66 @@ Use RubyGems to install `bernoulli`
|
|
12
15
|
|
13
16
|
## Tutorial
|
14
17
|
|
15
|
-
|
18
|
+
The classes in `bernoulli` reprsent random variables:
|
16
19
|
|
17
|
-
|
20
|
+
Bernoulli::Distribution::<DistributionName>
|
21
|
+
|
22
|
+
If, for example you wanted to have a geometrically distributed random variable with parameter 0.43, you would do:
|
18
23
|
|
19
|
-
|
24
|
+
y = Bernoulli::Distribution::Geometric.new(0.43)
|
25
|
+
|
26
|
+
Also if you `require 'bernoulli/shorthand'` too, you will get top level shortcut functions to create new instances of all distributions:
|
20
27
|
|
21
|
-
|
28
|
+
- `binomdist`
|
29
|
+
- `geomdist`
|
30
|
+
- `hgeomdist`
|
31
|
+
- `poissondist`
|
22
32
|
|
23
|
-
|
33
|
+
So `y = geomdist(0.43)` would be equivalent to the code shown above.
|
34
|
+
|
35
|
+
After this you call methods on `y`. The methods avalible to all distributions are:
|
24
36
|
|
25
|
-
|
26
|
-
|
27
|
-
|
37
|
+
- `probability`
|
38
|
+
- `probability_range`
|
39
|
+
- `expected_value`
|
40
|
+
- `variance`
|
41
|
+
- `standard_deviation`
|
42
|
+
- `skewness`
|
43
|
+
- `excess`
|
28
44
|
|
29
|
-
|
45
|
+
Again, shortcuts include (but this time included automatically):
|
30
46
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
x[25..36] # => 0.7665588897840108
|
36
|
-
|
37
|
-
x.expected_value # => 30.0
|
38
|
-
x.variance # => 25.0
|
39
|
-
|
40
|
-
We could also calculate the standard deviation, excess or skewness:
|
41
|
-
|
42
|
-
x.standard_deviation # => 5.0
|
43
|
-
x.excess # => 0.006666666666666665
|
44
|
-
x.skewness # => 0.13333333333333336
|
45
|
-
|
46
|
-
`bernoulli` can also do empirical tests. Let's look at a smaller example We can simulate the tossing of 4 fair coins
|
47
|
+
- `ev` for `expected_value`
|
48
|
+
- `v` for `variance`
|
49
|
+
- `sd` for `standard_deviation`
|
50
|
+
- `[]`, which takes a number or a range and then executes `probability` or `probability_range`
|
47
51
|
|
48
|
-
|
49
|
-
# => #<Bernoulli::Distribution @n=4, @p=0.5>
|
52
|
+
### Example
|
50
53
|
|
51
|
-
|
54
|
+
require 'bernoulli'
|
55
|
+
require 'bernoulli/shorthand'
|
56
|
+
|
57
|
+
x = binomdist(180, 1.0/6)
|
58
|
+
# => #<Distribution::Binomial @n=180, @p=0.16666666666666666>
|
59
|
+
|
60
|
+
x.ev # => 30.0
|
61
|
+
x.v # => 25.0
|
62
|
+
x[25..36] # => 0.7665588897840108
|
63
|
+
|
64
|
+
Last, but not least, there are two methods exclusive to the binomial distribution:
|
52
65
|
|
53
|
-
|
54
|
-
y.sample # => [0, 0, 1, 0]
|
55
|
-
y.sample # => [1, 1, 1, 1]
|
66
|
+
The method `sample` returns a random array of length `n`, where each entry is 1 with a probability of `p`. This is esentially modelling a binomial experiment.
|
56
67
|
|
57
|
-
|
58
|
-
y.sample_value # => 1
|
59
|
-
y.sample_value # => 0
|
60
|
-
y.sample_value # => 2
|
61
|
-
|
62
|
-
y.expected_value # => 2.0
|
63
|
-
|
64
|
-
Last, but not least, we can create a full table of all possible values and their probabilitys like so
|
65
|
-
|
66
|
-
puts y.table
|
67
|
-
|
68
|
-
will produce
|
69
|
-
|
70
|
-
0,0.0625
|
71
|
-
1,0.25
|
72
|
-
2,0.375
|
73
|
-
3,0.25
|
74
|
-
4,0.0625
|
68
|
+
The method `sample_value` returns the number of successes in a random binomial expriment that was executed using `sample`. `sv` is a shortcut for `sample_value`.
|
75
69
|
|
76
70
|
## Contributing
|
77
71
|
|
78
|
-
`bernoulli` is a
|
72
|
+
`bernoulli` is a small project. After writing the same code for some project and then losing it two or three times I decided to do it one time and well, so I can just call in the code from here next time.
|
79
73
|
|
80
|
-
Feel free to cantact me about anything I could/should add
|
74
|
+
Feel free to cantact me about anything I could/should add or to contribute in any way to this simple library.
|
81
75
|
|
82
76
|
1. Fork it
|
83
77
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
84
78
|
3. Commit your changes (`git commit -am 'added some feature'`)
|
85
79
|
4. Push to the branch (`git push origin my-new-feature`)
|
86
80
|
5. Create new Pull Request
|
87
|
-
|
data/Rakefile
CHANGED
@@ -1,14 +1,23 @@
|
|
1
|
-
require 'rake/testtask'
|
2
1
|
require 'bundler/gem_tasks'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'yard'
|
3
4
|
|
4
5
|
task :default => :test
|
5
6
|
|
6
|
-
Rake::TestTask.new do |
|
7
|
+
Rake::TestTask.new do |t|
|
8
|
+
t.libs << 'test'
|
9
|
+
t.pattern = 'test/**/test*.rb'
|
7
10
|
end
|
8
11
|
|
9
|
-
|
12
|
+
YARD::Rake::YardocTask.new do |t|
|
13
|
+
t.files = ['lib/**/*.rb']
|
14
|
+
t.options = ['--markup=markdown']
|
15
|
+
end
|
16
|
+
|
17
|
+
desc 'Remove pkg and doc directories'
|
10
18
|
task :clean do
|
11
19
|
rm_rf 'pkg/'
|
20
|
+
rm_rf 'doc/'
|
12
21
|
end
|
13
22
|
|
14
23
|
spec = eval File.read('bernoulli.gemspec')
|
@@ -17,4 +26,3 @@ desc "Remove and uninstall #{spec.name}-#{spec.version}.gem from system gems"
|
|
17
26
|
task :uninstall => :clean do
|
18
27
|
sh 'gem uninstall bernoulli'
|
19
28
|
end
|
20
|
-
|
data/bernoulli.gemspec
CHANGED
@@ -4,22 +4,21 @@ Gem::Specification.new do |spec|
|
|
4
4
|
|
5
5
|
spec.name = 'bernoulli'
|
6
6
|
spec.version = Bernoulli::VERSION
|
7
|
-
spec.summary = '
|
8
|
-
spec.description = '
|
7
|
+
spec.summary = 'Discrete probability distribution library for Ruby'
|
8
|
+
spec.description = 'Bernoulli implements standard methods used for statistcal calculations with discrete probability distributions in an object oriented manner and in pure Ruby'
|
9
9
|
spec.homepage = 'http://mkonutgan.github.com/bernoulli'
|
10
10
|
|
11
11
|
spec.author = 'Mikael Konutgan'
|
12
|
-
spec.email = 'mkonutgan@
|
12
|
+
spec.email = 'mkonutgan@gmail.com'
|
13
13
|
|
14
14
|
spec.required_ruby_version = '>= 1.8.7'
|
15
15
|
spec.required_rubygems_version = '>= 1.3.6'
|
16
16
|
|
17
|
-
spec.files = `git ls-files`.split
|
18
|
-
spec.test_files = spec.files.grep(/
|
17
|
+
spec.files = `git ls-files`.split
|
18
|
+
spec.test_files = spec.files.grep(/test_/)
|
19
19
|
|
20
|
-
spec.add_development_dependency 'minitest', '
|
21
|
-
spec.add_development_dependency 'rake', '
|
22
|
-
spec.add_development_dependency 'bundler', '
|
20
|
+
spec.add_development_dependency 'minitest', '>= 2.5'
|
21
|
+
spec.add_development_dependency 'rake', '>= 0.9'
|
22
|
+
spec.add_development_dependency 'bundler', '>= 1.1'
|
23
23
|
|
24
24
|
end
|
25
|
-
|
data/lib/bernoulli.rb
CHANGED
@@ -1,85 +1,2 @@
|
|
1
|
-
require 'bernoulli/math'
|
2
1
|
require 'bernoulli/version'
|
3
|
-
|
4
|
-
module Bernoulli
|
5
|
-
class Distribution
|
6
|
-
|
7
|
-
def initialize(n, p)
|
8
|
-
if n < 0 or p > 1.0 or p < 0.0 or not n.is_a? Integer
|
9
|
-
raise 'Could not initialize Bernoulli experiment'
|
10
|
-
end
|
11
|
-
@n = n
|
12
|
-
@p = p
|
13
|
-
end
|
14
|
-
|
15
|
-
def to_s
|
16
|
-
"#<Bernoulli::Distribution @n=#@n, @p=#@p>"
|
17
|
-
end
|
18
|
-
|
19
|
-
def probability(k)
|
20
|
-
Math.binomial(@n, k) * @p**k * (1 - @p)**(@n - k)
|
21
|
-
end
|
22
|
-
|
23
|
-
def [](k)
|
24
|
-
if k.is_a? Integer
|
25
|
-
raise Math::DomainError if not (k <= @n and k >= 0)
|
26
|
-
probability(k).to_f
|
27
|
-
elsif k.is_a? Range
|
28
|
-
raise Math::DomainError if not (k.begin >= 0 and k.end <= @n)
|
29
|
-
sum = 0
|
30
|
-
k.each do |i|
|
31
|
-
sum += probability(i)
|
32
|
-
end
|
33
|
-
sum.to_f
|
34
|
-
else
|
35
|
-
raise TypeError
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def sample
|
40
|
-
s = []
|
41
|
-
@n.times do
|
42
|
-
s << (rand < @p ? 1 : 0)
|
43
|
-
end
|
44
|
-
s
|
45
|
-
end
|
46
|
-
|
47
|
-
def sample_value
|
48
|
-
sample.count(1)
|
49
|
-
end
|
50
|
-
alias :sv :sample_value
|
51
|
-
|
52
|
-
def expected_value
|
53
|
-
@n * @p
|
54
|
-
end
|
55
|
-
alias :ev :expected_value
|
56
|
-
|
57
|
-
def variance
|
58
|
-
@n * @p * (1 - @p)
|
59
|
-
end
|
60
|
-
alias :v :variance
|
61
|
-
|
62
|
-
def standard_deviation
|
63
|
-
Math.sqrt(variance)
|
64
|
-
end
|
65
|
-
alias :sd :standard_deviation
|
66
|
-
|
67
|
-
def skewness
|
68
|
-
(1 - 2 * @p) / (Math.sqrt(@n * @p * (1 - @p)))
|
69
|
-
end
|
70
|
-
|
71
|
-
def excess
|
72
|
-
(1 - 6 * @p * (1 - @p)) / (@n * @p * (1 - @p))
|
73
|
-
end
|
74
|
-
|
75
|
-
def table
|
76
|
-
csv = ""
|
77
|
-
(0..@n).each do |n|
|
78
|
-
csv << n.to_s << "," << probability(n).to_s << "\n"
|
79
|
-
end
|
80
|
-
csv
|
81
|
-
end
|
82
|
-
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
2
|
+
require 'bernoulli/distribution'
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'bernoulli/distribution/binomial'
|
2
|
+
require 'bernoulli/distribution/hypergeometric'
|
3
|
+
require 'bernoulli/distribution/geometric'
|
4
|
+
require 'bernoulli/distribution/poisson'
|
5
|
+
|
6
|
+
module Bernoulli
|
7
|
+
|
8
|
+
# Top level Module for all the probability distributions
|
9
|
+
# Also provides convinience methods and `#standard_deviation`, which
|
10
|
+
# is calculated the same way independent of the distribution
|
11
|
+
module Distribution
|
12
|
+
|
13
|
+
# Calculate the sum of the probabilities across a range
|
14
|
+
# @param r [Range]
|
15
|
+
def probability_range(r)
|
16
|
+
r.inject(0) { |s, k| s + probability(k) }
|
17
|
+
end
|
18
|
+
|
19
|
+
# A shortcut to the `#probability` and `#probability_range`
|
20
|
+
# methods
|
21
|
+
# @param k [Integer, Range]
|
22
|
+
def [](k)
|
23
|
+
if k.is_a? Integer
|
24
|
+
probability(k).to_f
|
25
|
+
elsif k.is_a? Range
|
26
|
+
probability_range(k).to_f
|
27
|
+
else
|
28
|
+
raise TypeError, 'Expecting Integer or Range - "[]"'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# The standard deviation of a random variable
|
33
|
+
# is the square root of its variance.
|
34
|
+
def standard_deviation
|
35
|
+
Math.sqrt(variance)
|
36
|
+
end
|
37
|
+
alias :sd :standard_deviation
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'bernoulli/math'
|
2
|
+
|
3
|
+
module Bernoulli
|
4
|
+
|
5
|
+
module Distribution
|
6
|
+
|
7
|
+
# Implements binomially distributed random variable
|
8
|
+
# See http://en.wikipedia.org/wiki/Binomial_distribution
|
9
|
+
# for more information
|
10
|
+
class Binomial
|
11
|
+
|
12
|
+
include Distribution
|
13
|
+
|
14
|
+
# @param n [Integer] the number of trials (>= 0)
|
15
|
+
# @param p [Float] success probability in each trial
|
16
|
+
def initialize(n, p)
|
17
|
+
if n < 0 or p > 1.0 or p < 0.0
|
18
|
+
raise 'Expecting n >= 0 and 0.0 <= p <= 1.0'
|
19
|
+
end
|
20
|
+
@n = n.to_i
|
21
|
+
@p = p.to_f
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_s
|
25
|
+
"#<Distribution::Binomial @n=#@n, @p=#@p>"
|
26
|
+
end
|
27
|
+
|
28
|
+
# @param k [Integer] the number of successes (>= 0)
|
29
|
+
# @return [Float] the probability of `k` successes
|
30
|
+
def probability(k)
|
31
|
+
Math.binomial(@n, k) * @p**k * (1 - @p)**(@n - k)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Preform a binomial experiment of length `@n` and probability `@p`
|
35
|
+
# @return [Array<0, 1>] the resulting random array
|
36
|
+
def sample
|
37
|
+
s = []
|
38
|
+
@n.times do
|
39
|
+
s << (rand < @p ? 1 : 0)
|
40
|
+
end
|
41
|
+
s
|
42
|
+
end
|
43
|
+
|
44
|
+
# @return [Integer] number of 1's in a run of `#sample`
|
45
|
+
def sample_value
|
46
|
+
sample.count(1)
|
47
|
+
end
|
48
|
+
alias :sv :sample_value
|
49
|
+
|
50
|
+
def expected_value
|
51
|
+
@n * @p
|
52
|
+
end
|
53
|
+
alias :ev :expected_value
|
54
|
+
|
55
|
+
def variance
|
56
|
+
@n * @p * (1 - @p)
|
57
|
+
end
|
58
|
+
alias :v :variance
|
59
|
+
|
60
|
+
def skewness
|
61
|
+
(1 - 2 * @p) / (Math.sqrt(@n * @p * (1 - @p)))
|
62
|
+
end
|
63
|
+
|
64
|
+
def excess
|
65
|
+
(1 - 6 * @p * (1 - @p)) / (@n * @p * (1 - @p))
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Bernoulli
|
2
|
+
|
3
|
+
module Distribution
|
4
|
+
|
5
|
+
# Implements geometrically distributed random variable
|
6
|
+
# See http://en.wikipedia.org/wiki/Geometric_distribution
|
7
|
+
# for more information
|
8
|
+
class Geometric
|
9
|
+
|
10
|
+
include Distribution
|
11
|
+
|
12
|
+
# @param p [Float] the success probability (>= 0, <= 1)
|
13
|
+
def initialize(p)
|
14
|
+
if p > 1.0 or p < 0.0
|
15
|
+
raise 'Expecting 0.0 <= p <= 1.0'
|
16
|
+
end
|
17
|
+
@p = p.to_f
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_s
|
21
|
+
"#<Distribution::Geometric @p=#@p>"
|
22
|
+
end
|
23
|
+
|
24
|
+
# @param k [Integer] number of independent trials (> 0)
|
25
|
+
# @return [Float] the probability that the first occurrence
|
26
|
+
# of success require `k` independent trials
|
27
|
+
def probability(k)
|
28
|
+
if k == 0
|
29
|
+
0
|
30
|
+
else
|
31
|
+
(1 - @p)**(k - 1) * @p
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def expected_value
|
36
|
+
1 / @p
|
37
|
+
end
|
38
|
+
alias :ev :expected_value
|
39
|
+
|
40
|
+
def variance
|
41
|
+
(1 - @p) / @p**2
|
42
|
+
end
|
43
|
+
alias :v :variance
|
44
|
+
|
45
|
+
def skewness
|
46
|
+
(2 - @p) / Math.sqrt(1 - @p)
|
47
|
+
end
|
48
|
+
|
49
|
+
def excess
|
50
|
+
6 + @p**2 / (1 - @p)
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'bernoulli/math'
|
2
|
+
|
3
|
+
module Bernoulli
|
4
|
+
|
5
|
+
module Distribution
|
6
|
+
|
7
|
+
# Implements hypergeometrically distributed random variable
|
8
|
+
# See http://en.wikipedia.org/wiki/Hypergeometric_distribution
|
9
|
+
# for more information
|
10
|
+
class Hypergeometric
|
11
|
+
|
12
|
+
include Distribution
|
13
|
+
|
14
|
+
# @param bn [Integer] the size of the population (big n) (> 0)
|
15
|
+
# @param m [Integer] the number of successes (>= 0, <= bn)
|
16
|
+
# @param n [Integer] the number of draws (>= 1, <= bn)
|
17
|
+
def initialize(bn, m, n)
|
18
|
+
if bn < 1 or m < 0 or m > bn or n < 1 or n > bn
|
19
|
+
raise 'Expecting bn > 1, 0 < m < bn, 0 < n < bn'
|
20
|
+
end
|
21
|
+
@bn, @m, @n = bn.to_i, m.to_i, n.to_i
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_s
|
25
|
+
"#<Distribution::Hypergeometric @bn=#@bn, @m=#@m, @n=#@n>"
|
26
|
+
end
|
27
|
+
|
28
|
+
# @param k [Integer] number of successes (>= 0)
|
29
|
+
# @return [Float] the probability of `k` successes
|
30
|
+
def probability(k)
|
31
|
+
(Math.binomial(@m, k) * Math.binomial(@bn - @m, @n - k)).to_f / Math.binomial(@bn, @n)
|
32
|
+
end
|
33
|
+
|
34
|
+
def expected_value
|
35
|
+
@n * (@m.to_f / @bn)
|
36
|
+
end
|
37
|
+
alias :ev :expected_value
|
38
|
+
|
39
|
+
def variance
|
40
|
+
(@n * @m * (@bn - @m) *(@bn - @n)).to_f / (@bn * @bn * (@bn - 1))
|
41
|
+
end
|
42
|
+
alias :v :variance
|
43
|
+
|
44
|
+
def skewness
|
45
|
+
((@bn - 2 * @m) * Math.sqrt(@bn - 1) * (@bn - 2 * @n)) / (Math.sqrt(@n * @m * (@bn - @m) * (@bn - @n)) * (@bn - 2))
|
46
|
+
end
|
47
|
+
|
48
|
+
def excess
|
49
|
+
((@bn - 1) * @bn * @bn * (@bn * (@bn + 1) - 6 * @m * (@bn - @m) - 6 * @n * (@bn - @n)) + 6 * @n * @m * (@bn - @m) * (@bn - @n) * (5 * @bn - 6)).to_f / (@n * @m * (@bn - @m) * (@bn - @n) * (@bn - 2) * (@bn - 3))
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'bernoulli/math'
|
2
|
+
|
3
|
+
module Bernoulli
|
4
|
+
|
5
|
+
module Distribution
|
6
|
+
|
7
|
+
# Implements Poisson distributed random variable
|
8
|
+
# See http://en.wikipedia.org/wiki/Poisson_distribution
|
9
|
+
# for more information
|
10
|
+
class Poisson
|
11
|
+
|
12
|
+
include Distribution
|
13
|
+
|
14
|
+
# @param l [Float] the avarage rate of success in a time period
|
15
|
+
def initialize(l)
|
16
|
+
if l <= 0.0
|
17
|
+
raise 'Expecting l > 0.0'
|
18
|
+
end
|
19
|
+
@l = l.to_f
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_s
|
23
|
+
"#<Distribution::Poisson @l=#@l>"
|
24
|
+
end
|
25
|
+
|
26
|
+
# @param k [Integer] number of successes (>= 0)
|
27
|
+
# @return [Float] the probability of `k` successes
|
28
|
+
# in the time period
|
29
|
+
def probability(k)
|
30
|
+
(@l**k / Math.factorial(k)) * Math.exp(-@l)
|
31
|
+
end
|
32
|
+
|
33
|
+
def probability_range(r)
|
34
|
+
Math.exp(-@l) * r.inject(0) { |s, k| s + (@l**k / Math.factorial(k)) }
|
35
|
+
end
|
36
|
+
|
37
|
+
def expected_value
|
38
|
+
@l
|
39
|
+
end
|
40
|
+
alias :ev :expected_value
|
41
|
+
|
42
|
+
def variance
|
43
|
+
@l
|
44
|
+
end
|
45
|
+
alias :v :variance
|
46
|
+
|
47
|
+
def skewness
|
48
|
+
1 / Math.sqrt(@l)
|
49
|
+
end
|
50
|
+
|
51
|
+
def excess
|
52
|
+
1 / @l
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
data/lib/bernoulli/math.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
+
# Extend the Ruby Math module with common functions used in
|
2
|
+
# statstical distributions
|
1
3
|
module Math
|
2
|
-
|
4
|
+
|
3
5
|
def self.factorial(n)
|
4
|
-
|
5
|
-
if n < 0 or not n.is_a? Integer
|
6
|
+
if n < 0
|
6
7
|
raise Math::DomainError, 'Numerical argument is out of domain - "factorial"'
|
7
8
|
end
|
8
9
|
if n == 0
|
@@ -13,11 +14,11 @@ module Math
|
|
13
14
|
end
|
14
15
|
|
15
16
|
def self.binomial(n, k)
|
16
|
-
if n < 0 or
|
17
|
-
|
17
|
+
if n < 0 or k < 0 or n < k
|
18
|
+
0
|
19
|
+
else
|
20
|
+
factorial(n)/(factorial(k) * factorial(n - k))
|
18
21
|
end
|
19
|
-
factorial(n)/(factorial(k) * factorial(n - k))
|
20
22
|
end
|
21
23
|
|
22
24
|
end
|
23
|
-
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# shorthand that returns new instance of `Distribution::Binomial`
|
2
|
+
def binomdist(n, p)
|
3
|
+
Bernoulli::Distribution::Binomial.new(n, p)
|
4
|
+
end
|
5
|
+
|
6
|
+
# shorthand that returns new instance of `Distribution::Geometric`
|
7
|
+
def geomdist(p)
|
8
|
+
Bernoulli::Distribution::Geometric.new(p)
|
9
|
+
end
|
10
|
+
|
11
|
+
# shorthand that returns new instance of `Distribution::Hypergeometric`
|
12
|
+
def hgeomdist(bn, m, n)
|
13
|
+
Bernoulli::Distribution::Hypergeometric.new(bn, m, n)
|
14
|
+
end
|
15
|
+
|
16
|
+
# shorthand that returns new instance of `Distribution::Poisson`
|
17
|
+
def poissondist(l)
|
18
|
+
Bernoulli::Distribution::Poisson.new(l)
|
19
|
+
end
|
data/lib/bernoulli/version.rb
CHANGED
@@ -0,0 +1,52 @@
|
|
1
|
+
require File.expand_path('../../helper', __FILE__)
|
2
|
+
|
3
|
+
class BinomialTest < MiniTest::Unit::TestCase
|
4
|
+
|
5
|
+
def test_new_experiment
|
6
|
+
assert_raises RuntimeError do
|
7
|
+
Bernoulli::Distribution::Binomial.new(10, 1.1)
|
8
|
+
end
|
9
|
+
assert_raises RuntimeError do
|
10
|
+
Bernoulli::Distribution::Binomial.new(-10, 0.7)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def setup
|
15
|
+
@x = Bernoulli::Distribution::Binomial.new(180, 1.0/6)
|
16
|
+
@y = Bernoulli::Distribution::Binomial.new(2, 0.5)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_to_s
|
20
|
+
assert_equal "#<Distribution::Binomial @n=2, @p=0.5>", @y.to_s
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_coin_toss
|
24
|
+
assert_equal 0.25, @y[0]
|
25
|
+
assert_equal 0.5, @y[1]
|
26
|
+
assert_equal 0.25, @y[2]
|
27
|
+
assert_equal 0.75, @y[0..1]
|
28
|
+
assert_equal 0.75, @y[1..2]
|
29
|
+
assert_equal 1.0, @y[0..2]
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_expected_value
|
33
|
+
assert_equal 30, @x.expected_value
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_variance
|
37
|
+
assert_equal 25, @x.variance
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_standard_deviation
|
41
|
+
assert_equal 5, @x.standard_deviation
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_skewness
|
45
|
+
assert_in_eps 0.1333333333333333, @x.skewness
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_excess
|
49
|
+
assert_in_eps 0.0066666666666667, @x.excess
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require File.expand_path('../../helper', __FILE__)
|
2
|
+
|
3
|
+
class GeometricTest < MiniTest::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@x = Bernoulli::Distribution::Geometric.new(0.5)
|
7
|
+
@y = Bernoulli::Distribution::Geometric.new(0.87)
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_to_s
|
11
|
+
assert_equal "#<Distribution::Geometric @p=0.5>", @x.to_s
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_probabilities
|
15
|
+
assert_in_eps 1.0, @x[1..100]
|
16
|
+
assert_in_eps 0.5, @x[1]
|
17
|
+
assert_in_eps 0.25, @x[2]
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_expected_value
|
21
|
+
assert_in_eps 2, @x.expected_value
|
22
|
+
assert_in_eps 1.149425287, @y.expected_value
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_variance
|
26
|
+
assert_in_eps 2, @x.variance
|
27
|
+
assert_in_eps 0.171753204, @y.variance
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_standard_deviation
|
31
|
+
assert_in_eps 1.4142135623730951, @x.standard_deviation
|
32
|
+
assert_in_eps 0.414431181, @y.standard_deviation
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_skewness
|
36
|
+
assert_in_eps 3.134056109, @y.skewness
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_excess
|
40
|
+
assert_in_eps 11.822307692, @y.excess
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require File.expand_path('../../helper', __FILE__)
|
2
|
+
|
3
|
+
class HypergeometricTest < MiniTest::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@x = Bernoulli::Distribution::Hypergeometric.new(5, 3, 2)
|
7
|
+
@y = Bernoulli::Distribution::Hypergeometric.new(50, 17, 9)
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_to_s
|
11
|
+
assert_equal "#<Distribution::Hypergeometric @bn=5, @m=3, @n=2>", @x.to_s
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_probabilities
|
15
|
+
assert_in_eps 0.1, @x[0]
|
16
|
+
assert_in_eps 0.6, @x[1]
|
17
|
+
assert_in_eps 0.3, @x[2]
|
18
|
+
assert_in_eps 1.0, @x[0..2]
|
19
|
+
assert_in_eps 0.9, @x[1..2]
|
20
|
+
assert_in_eps 0.0, @x[3]
|
21
|
+
assert_in_eps 0.0, @x[4]
|
22
|
+
|
23
|
+
assert_in_eps 1.0, @y[0..9]
|
24
|
+
assert_in_eps 0.0, @y[10]
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_expected_value
|
28
|
+
assert_in_eps 1.2, @x.expected_value
|
29
|
+
assert_in_eps 3.06, @y.expected_value
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_variance
|
33
|
+
assert_in_eps 0.36, @x.variance
|
34
|
+
assert_in_eps 1.689869388, @y.variance
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_standard_deviation
|
38
|
+
assert_in_eps 0.6, @x.standard_deviation
|
39
|
+
assert_in_eps 1.299949764, @y.standard_deviation
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_skewness
|
43
|
+
assert_in_eps -0.111111111, @x.skewness
|
44
|
+
assert_in_eps 0.164108906, @y.skewness
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_excess
|
48
|
+
assert_in_eps -0.444444444, @x.excess
|
49
|
+
assert_in_eps -0.14585017, @y.excess
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require File.expand_path('../../helper', __FILE__)
|
2
|
+
|
3
|
+
class PoissonTest < MiniTest::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@x = Bernoulli::Distribution::Poisson.new(1)
|
7
|
+
@y = Bernoulli::Distribution::Poisson.new(112)
|
8
|
+
@z = Bernoulli::Distribution::Poisson.new(54)
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_to_s
|
12
|
+
assert_equal "#<Distribution::Poisson @l=1.0>", @x.to_s
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_probabilities_1
|
16
|
+
p = [
|
17
|
+
0.36787944117144233,
|
18
|
+
0.36787944117144233,
|
19
|
+
0.18393972058572117,
|
20
|
+
0.061313240195240384,
|
21
|
+
0.015328310048810096,
|
22
|
+
0.0030656620097620196,
|
23
|
+
0.0005109436682936699
|
24
|
+
]
|
25
|
+
(0..6).each { |v| assert_in_eps p[v], @x[v] }
|
26
|
+
assert_in_eps 1, @x[0..10]
|
27
|
+
assert_in_eps 0.9810118431238463, @x[0..3]
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_probabilities_2
|
31
|
+
assert_in_eps 0.003324518575716, @y[89]
|
32
|
+
assert_in_eps 0.0143492278868432, @y[0..89]
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_probabilities_3
|
36
|
+
assert_in_eps 0.0483850390510616, @z[50]
|
37
|
+
assert_in_eps 0.32326350500948, @z[0..50]
|
38
|
+
assert_in_eps 1.0, @z[0..100]
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_expected_value
|
42
|
+
assert_equal 1, @x.expected_value
|
43
|
+
assert_equal 112, @y.expected_value
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_variance
|
47
|
+
assert_equal 1, @x.variance
|
48
|
+
assert_equal 112, @y.variance
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_standard_deviation
|
52
|
+
assert_in_eps 1, @x.standard_deviation
|
53
|
+
assert_in_eps Math.sqrt(112), @y.standard_deviation
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_skewness
|
57
|
+
assert_in_eps 0.094491118, @y.skewness
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_excess
|
61
|
+
assert_in_eps 0.008928571, @y.excess
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
data/test/helper.rb
ADDED
data/test/test_math.rb
CHANGED
@@ -1,24 +1,22 @@
|
|
1
1
|
require 'minitest/autorun'
|
2
2
|
require 'minitest/pride'
|
3
|
-
require 'bernoulli'
|
3
|
+
require 'bernoulli/math'
|
4
4
|
|
5
5
|
class MathTest < MiniTest::Unit::TestCase
|
6
6
|
|
7
7
|
def test_factorial
|
8
8
|
assert_raises(Math::DomainError) { Math.factorial(-1) }
|
9
|
-
assert_raises(Math::DomainError) { Math.factorial(2.4) }
|
10
9
|
assert_equal 1, Math.factorial(0)
|
11
10
|
assert_equal 1, Math.factorial(1)
|
11
|
+
assert_equal 2, Math.factorial(2)
|
12
12
|
assert_equal 120, Math.factorial(5)
|
13
13
|
assert_equal 263130836933693530167218012160000000, Math.factorial(32)
|
14
14
|
end
|
15
15
|
|
16
16
|
def test_binomial
|
17
|
-
pairs = [[-1, 0], [2, 4], [-2, -1], [
|
17
|
+
pairs = [[-1, 0], [2, 4], [-2, -1], [6, -3], [12, 50]]
|
18
18
|
pairs.each do |pair|
|
19
|
-
|
20
|
-
Math.binomial *pair
|
21
|
-
end
|
19
|
+
assert_equal 0, Math.binomial(*pair)
|
22
20
|
end
|
23
21
|
assert_equal 1, Math.binomial(0, 0)
|
24
22
|
(1..20).each do |k|
|
@@ -36,4 +34,3 @@ class MathTest < MiniTest::Unit::TestCase
|
|
36
34
|
end
|
37
35
|
|
38
36
|
end
|
39
|
-
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'bernoulli/distribution'
|
2
|
+
require 'bernoulli/shorthand'
|
3
|
+
|
4
|
+
class ShorthandTest < MiniTest::Unit::TestCase
|
5
|
+
|
6
|
+
def test_binomdist
|
7
|
+
x = Bernoulli::Distribution::Binomial.new(10, 0.71)
|
8
|
+
assert_equal x.to_s, binomdist(10, 0.71).to_s
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_geomdist
|
12
|
+
x = Bernoulli::Distribution::Geometric.new(0.53)
|
13
|
+
assert_equal x.to_s, geomdist(0.53).to_s
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_hgeomdist
|
17
|
+
x = Bernoulli::Distribution::Hypergeometric.new(20, 14, 5)
|
18
|
+
assert_equal x.to_s, hgeomdist(20, 14, 5).to_s
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_poissondist
|
22
|
+
x = Bernoulli::Distribution::Poisson.new(13.3)
|
23
|
+
assert_equal x.to_s, poissondist(13.3).to_s
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bernoulli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: '0.4'
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,72 +9,85 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-07-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: minitest
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
|
-
- -
|
19
|
+
- - ! '>='
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
21
|
+
version: '2.5'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
none: false
|
26
26
|
requirements:
|
27
|
-
- -
|
27
|
+
- - ! '>='
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
29
|
+
version: '2.5'
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
31
|
name: rake
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
33
33
|
none: false
|
34
34
|
requirements:
|
35
|
-
- -
|
35
|
+
- - ! '>='
|
36
36
|
- !ruby/object:Gem::Version
|
37
|
-
version: 0.9
|
37
|
+
version: '0.9'
|
38
38
|
type: :development
|
39
39
|
prerelease: false
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
41
|
none: false
|
42
42
|
requirements:
|
43
|
-
- -
|
43
|
+
- - ! '>='
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
version: 0.9
|
45
|
+
version: '0.9'
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
47
|
name: bundler
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
49
49
|
none: false
|
50
50
|
requirements:
|
51
|
-
- -
|
51
|
+
- - ! '>='
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: 1.1
|
53
|
+
version: '1.1'
|
54
54
|
type: :development
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
57
|
none: false
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ! '>='
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 1.1
|
62
|
-
description:
|
63
|
-
|
64
|
-
|
61
|
+
version: '1.1'
|
62
|
+
description: Bernoulli implements standard methods used for statistcal calculations
|
63
|
+
with discrete probability distributions in an object oriented manner and in pure
|
64
|
+
Ruby
|
65
|
+
email: mkonutgan@gmail.com
|
65
66
|
executables: []
|
66
67
|
extensions: []
|
67
68
|
extra_rdoc_files: []
|
68
69
|
files:
|
69
70
|
- Gemfile
|
71
|
+
- LICENSE.md
|
70
72
|
- README.md
|
71
73
|
- Rakefile
|
72
74
|
- bernoulli.gemspec
|
73
75
|
- lib/bernoulli.rb
|
76
|
+
- lib/bernoulli/distribution.rb
|
77
|
+
- lib/bernoulli/distribution/binomial.rb
|
78
|
+
- lib/bernoulli/distribution/geometric.rb
|
79
|
+
- lib/bernoulli/distribution/hypergeometric.rb
|
80
|
+
- lib/bernoulli/distribution/poisson.rb
|
74
81
|
- lib/bernoulli/math.rb
|
82
|
+
- lib/bernoulli/shorthand.rb
|
75
83
|
- lib/bernoulli/version.rb
|
76
|
-
- test/
|
84
|
+
- test/distribution/test_binomial.rb
|
85
|
+
- test/distribution/test_geometric.rb
|
86
|
+
- test/distribution/test_hypergeometric.rb
|
87
|
+
- test/distribution/test_poisson.rb
|
88
|
+
- test/helper.rb
|
77
89
|
- test/test_math.rb
|
90
|
+
- test/test_shorthand.rb
|
78
91
|
homepage: http://mkonutgan.github.com/bernoulli
|
79
92
|
licenses: []
|
80
93
|
post_install_message:
|
@@ -98,7 +111,12 @@ rubyforge_project:
|
|
98
111
|
rubygems_version: 1.8.24
|
99
112
|
signing_key:
|
100
113
|
specification_version: 3
|
101
|
-
summary:
|
114
|
+
summary: Discrete probability distribution library for Ruby
|
102
115
|
test_files:
|
103
|
-
- test/
|
116
|
+
- test/distribution/test_binomial.rb
|
117
|
+
- test/distribution/test_geometric.rb
|
118
|
+
- test/distribution/test_hypergeometric.rb
|
119
|
+
- test/distribution/test_poisson.rb
|
104
120
|
- test/test_math.rb
|
121
|
+
- test/test_shorthand.rb
|
122
|
+
has_rdoc:
|
data/test/test_bernoulli.rb
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
require 'minitest/autorun'
|
2
|
-
require 'minitest/pride'
|
3
|
-
require 'bernoulli'
|
4
|
-
|
5
|
-
class DistributionTest < MiniTest::Unit::TestCase
|
6
|
-
|
7
|
-
def test_new_experiment
|
8
|
-
assert_raises RuntimeError do
|
9
|
-
Bernoulli::Distribution.new(10, 1.1)
|
10
|
-
end
|
11
|
-
assert_raises RuntimeError do
|
12
|
-
Bernoulli::Distribution.new(-10, 0.7)
|
13
|
-
end
|
14
|
-
assert_raises RuntimeError do
|
15
|
-
Bernoulli::Distribution.new(4.5, 0.2)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def setup
|
20
|
-
@x = Bernoulli::Distribution.new(180, 1.0/6)
|
21
|
-
@y = Bernoulli::Distribution.new(2, 0.5)
|
22
|
-
@z = Bernoulli::Distribution.new(4, 0.5)
|
23
|
-
end
|
24
|
-
|
25
|
-
def test_to_s
|
26
|
-
assert_equal "#<Bernoulli::Distribution @n=2, @p=0.5>", @y.to_s
|
27
|
-
end
|
28
|
-
|
29
|
-
def test_coin_toss
|
30
|
-
assert_equal 0.5, @y[1]
|
31
|
-
assert_equal 0.25, @y[2]
|
32
|
-
assert_equal 1.0, @y[0..2]
|
33
|
-
end
|
34
|
-
|
35
|
-
def test_expected_value
|
36
|
-
assert_equal 30, @x.expected_value
|
37
|
-
end
|
38
|
-
|
39
|
-
def test_variance
|
40
|
-
assert_equal 25, @x.variance
|
41
|
-
end
|
42
|
-
|
43
|
-
def test_standard_deviation
|
44
|
-
assert_equal 5, @x.standard_deviation
|
45
|
-
end
|
46
|
-
|
47
|
-
def test_skewness
|
48
|
-
assert_in_delta 0.1333333333333333, @x.skewness, 1.0e-7
|
49
|
-
end
|
50
|
-
|
51
|
-
def test_excess
|
52
|
-
assert_in_delta 0.0066666666666667, @x.excess, 1.0e-7
|
53
|
-
end
|
54
|
-
|
55
|
-
def test_table
|
56
|
-
str = "0,0.0625\n1,0.25\n2,0.375\n3,0.25\n4,0.0625\n"
|
57
|
-
assert_equal str, @z.table
|
58
|
-
end
|
59
|
-
|
60
|
-
end
|
61
|
-
|