bernoulli 0.3.1 → 0.4
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.
- 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
|
-
|