ruby-statistics 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1c58bc877eb893a77eacc586ddbc2cfca7e3655d
4
+ data.tar.gz: e61823ec3df43e872d451668ad8148b29b3749b8
5
+ SHA512:
6
+ metadata.gz: 7fe62c3c65d455fdc40c3dca386c0bce4672025c56638cadea586720b7c10ea57b6d6cf91379772f5c41c080fa4a1cb3e4b7894fe328bde45f03e616dadf0c8d
7
+ data.tar.gz: 5de5004f6ff87991dc41d273a05db3ab2dbe1c87c001ec5ef3b6e93d5145ac5f7168b64ec55c6049de715b7aa82ac1cdd3dec0a771c2c9f31794067734ddb125
data/.gitignore ADDED
@@ -0,0 +1,65 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /test/tmp/
10
+ /test/version_tmp/
11
+ /tmp/
12
+
13
+ # Used by dotenv library to load environment variables.
14
+ # .env
15
+
16
+ ## Specific to RubyMotion:
17
+ .dat*
18
+ .repl_history
19
+ build/
20
+ *.bridgesupport
21
+ build-iPhoneOS/
22
+ build-iPhoneSimulator/
23
+
24
+ ## Specific to RubyMotion (use of CocoaPods):
25
+ #
26
+ # We recommend against adding the Pods directory to your .gitignore. However
27
+ # you should judge for yourself, the pros and cons are mentioned at:
28
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
29
+ #
30
+ # vendor/Pods/
31
+
32
+ ## Documentation cache and generated files:
33
+ /.yardoc/
34
+ /_yardoc/
35
+ /doc/
36
+ /rdoc/
37
+
38
+ ## Environment normalization:
39
+ /.bundle/
40
+ /vendor/bundle
41
+ /lib/bundler/man/
42
+
43
+ # for a library or gem, you might want to ignore these files since the code is
44
+ # intended to run in multiple environments; otherwise, check them in:
45
+ # Gemfile.lock
46
+ .ruby-version
47
+ .ruby-gemset
48
+
49
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
50
+ .rvmrc
51
+ /.bundle/
52
+ /.yardoc
53
+ /Gemfile.lock
54
+ /_yardoc/
55
+ /coverage/
56
+ /doc/
57
+ /pkg/
58
+ /spec/reports/
59
+ /tmp/
60
+
61
+ # rspec failure tracking
62
+ .rspec_status
63
+
64
+ # byebug
65
+ .byebug_history
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.2
5
+ - 2.3.1
6
+ before_install: gem install bundler
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at ezapata@altavistaed.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in statistics.gemspec
6
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2017 Esteban Zapata Rojas
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 esteban zapata
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,59 @@
1
+ # Statistics
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/statistics`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'ruby-statistics'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install ruby-statistics
22
+
23
+ ## Basic Usage
24
+
25
+ just require the `statistics` gem in order to load it. If you don't have defined the `Distribution` namespace, the gem will assign an alias, reducing the number of namespaces needed to use a class.
26
+
27
+ Right know you can load:
28
+
29
+ * The whole statistics gem. `require 'statistics'`
30
+ * A namespace. `require 'statistics/distribution'`
31
+ * A class. `require 'statistics/distribution/normal'`
32
+
33
+ Feel free to use the one that is more convenient to you.
34
+
35
+ ### Hello-World Example
36
+ ```ruby
37
+ require 'statistics'
38
+
39
+ poisson = Distribution::Poisson.new(l) # Using Distribution alias.
40
+ normal = Statistics::Distribution::StandardNormal.new # Using all namespaces.
41
+ ```
42
+
43
+ ## Development
44
+
45
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
46
+
47
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
48
+
49
+ ## Contributing
50
+
51
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/statistics. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
52
+
53
+ ## License
54
+
55
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
56
+
57
+ ## Code of Conduct
58
+
59
+ Everyone interacting in the Statistics project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/statistics/blob/master/CODE_OF_CONDUCT.md).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "statistics"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/lib/math.rb ADDED
@@ -0,0 +1,120 @@
1
+ module Math
2
+ def self.factorial(n)
3
+ return if n < 0
4
+
5
+ n = n.to_i # Only integers.
6
+
7
+ return 1 if n == 0 || n == 1
8
+ Math.gamma(n + 1) # Math.gamma(x) == (n - 1)! for integer values
9
+ end
10
+
11
+ def self.combination(n, r)
12
+ self.factorial(n)/(self.factorial(r) * self.factorial(n - r)).to_f # n!/(r! * [n - r]!)
13
+ end
14
+
15
+ def self.permutation(n, k)
16
+ self.factorial(n)/self.factorial(n - k).to_f
17
+ end
18
+
19
+ # Function adapted from the python implementation that exists in https://en.wikipedia.org/wiki/Simpson%27s_rule#Sample_implementation
20
+ # Finite integral in the interval [a, b] split up in n-intervals
21
+ def self.simpson_rule(a, b, n, &block)
22
+ unless n.even?
23
+ puts "The composite simpson's rule needs even intervals!"
24
+ return
25
+ end
26
+
27
+ h = (b - a)/n.to_f
28
+ resA = yield(a)
29
+ resB = yield(b)
30
+
31
+ sum = resA + resB
32
+
33
+ (1..n).step(2).each do |number|
34
+ res = yield(a + number * h)
35
+ sum += 4 * res
36
+ end
37
+
38
+ (1..(n-1)).step(2).each do |number|
39
+ res = yield(a + number * h)
40
+ sum += 2 * res
41
+ end
42
+
43
+ return sum * h / 3.0
44
+ end
45
+
46
+ def self.lower_incomplete_gamma_function(s, x)
47
+ # The greater the iterations, the better. That's why we are iterating 10_000 * x times
48
+ self.simpson_rule(0, x, (10_000 * x).round) do |t|
49
+ (t ** (s - 1)) * Math.exp(-t)
50
+ end
51
+ end
52
+
53
+ def self.beta_function(x, y)
54
+ return 1 if x == 1 && y == 1
55
+
56
+ (Math.gamma(x) * Math.gamma(y))/Math.gamma(x + y)
57
+ end
58
+
59
+ ### This implementation is an adaptation of the incomplete beta function made in C by
60
+ ### Lewis Van Winkle, which released the code under the zlib license.
61
+ ### The whole math behind this code is described in the following post: https://codeplea.com/incomplete-beta-function-c
62
+ def self.incomplete_beta_function(x, alp, bet)
63
+ return if x < 0.0
64
+ return 1.0 if x > 1.0
65
+
66
+ tiny = 1.0E-50
67
+
68
+ if x > ((alp + 1.0)/(alp + bet + 2.0))
69
+ return 1.0 - self.incomplete_beta_function(1.0 - x, bet, alp)
70
+ end
71
+
72
+ # To avoid overflow problems, the implementation applies the logarithm properties
73
+ # to calculate in a faster and safer way the values.
74
+ lbet_ab = (Math.lgamma(alp)[0] + Math.lgamma(bet)[0] - Math.lgamma(alp + bet)[0]).freeze
75
+ front = (Math.exp(Math.log(x) * alp + Math.log(1.0 - x) * bet - lbet_ab) / alp.to_f).freeze
76
+
77
+ # This is the non-log version of the left part of the formula (before the continuous fraction)
78
+ # down_left = alp * self.beta_function(alp, bet)
79
+ # upper_left = (x ** alp) * ((1.0 - x) ** bet)
80
+ # front = upper_left/down_left
81
+
82
+ f, c, d = 1.0, 1.0, 0.0
83
+
84
+ returned_value = nil
85
+
86
+ # Let's do more iterations than the proposed implementation (200 iters)
87
+ (0..500).each do |number|
88
+ m = number/2
89
+
90
+ numerator = if number == 0
91
+ 1.0
92
+ elsif number % 2 == 0
93
+ (m * (bet - m) * x)/((alp + 2.0 * m - 1.0)* (alp + 2.0 * m))
94
+ else
95
+ top = -((alp + m) * (alp + bet + m) * x)
96
+ down = ((alp + 2.0 * m) * (alp + 2.0 * m + 1.0))
97
+
98
+ top/down
99
+ end
100
+
101
+ d = 1.0 + numerator * d
102
+ d = tiny if d.abs < tiny
103
+ d = 1.0 / d
104
+
105
+ c = 1.0 + numerator / c
106
+ c = tiny if c.abs < tiny
107
+
108
+ cd = (c*d).freeze
109
+ f = f * cd
110
+
111
+
112
+ if (1.0 - cd).abs < 1.0E-10
113
+ returned_value = front * (f - 1.0)
114
+ break
115
+ end
116
+ end
117
+
118
+ returned_value
119
+ end
120
+ end
@@ -0,0 +1,35 @@
1
+ module Statistics
2
+ module Distribution
3
+ class Beta
4
+ attr_accessor :alpha, :beta
5
+
6
+ def initialize(alp, bet)
7
+ self.alpha = alp.to_f
8
+ self.beta = bet.to_f
9
+ end
10
+
11
+ def cumulative_function(value)
12
+ Math.incomplete_beta_function(value, alpha, beta)
13
+ end
14
+
15
+ def density_function(value)
16
+ return 0 if value < 0 || value > 1 # Density function defined in the [0,1] interval
17
+
18
+ num = (value**(alpha - 1)) * ((1 - value)**(beta - 1))
19
+ den = Math.beta_function(alpha, beta)
20
+
21
+ num/den
22
+ end
23
+
24
+ def mode
25
+ return unless alpha > 1 && beta > 1
26
+
27
+ (alpha - 1)/(alpha + beta - 2)
28
+ end
29
+
30
+ def mean
31
+ alpha / (alpha + beta)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,49 @@
1
+ module Statistics
2
+ module Distribution
3
+ class Binomial
4
+ attr_accessor :number_of_trials, :probability_per_trial
5
+ def initialize(n, p)
6
+ self.number_of_trials = n.to_i
7
+ self.probability_per_trial = p
8
+ end
9
+
10
+ def probability_mass_function(k)
11
+ return if k < 0 || k > number_of_trials
12
+ k = k.to_i
13
+
14
+ Math.combination(number_of_trials, k) *
15
+ (probability_per_trial ** k) * ((1 - probability_per_trial) ** (number_of_trials - k))
16
+ end
17
+
18
+ def cumulative_function(k)
19
+ return if k < 0 || k > number_of_trials
20
+ k = k.to_i
21
+
22
+ p = 1 - probability_per_trial
23
+ Math.incomplete_beta_function(p, number_of_trials - k, 1 + k)
24
+ end
25
+
26
+ def mean
27
+ number_of_trials * probability_per_trial
28
+ end
29
+
30
+ def variance
31
+ mean * (1 - probability_per_trial)
32
+ end
33
+
34
+ def mode
35
+ test = (number_of_trials + 1) * probability_per_trial
36
+
37
+ returned = if test == 0 || (test % 1 != 0)
38
+ test.floor
39
+ elsif (test % 1 == 0) && (test >= 1 && test <= number_of_trials)
40
+ [test, test - 1]
41
+ elsif test == number_of_trials + 1
42
+ number_of_trials
43
+ end
44
+
45
+ returned
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,37 @@
1
+ module Statistics
2
+ module Distribution
3
+ class ChiSquared
4
+ attr_accessor :degrees_of_freedom
5
+
6
+ alias_method :mean, :degrees_of_freedom
7
+
8
+ def initialize(k)
9
+ self.degrees_of_freedom = k
10
+ end
11
+
12
+ def cumulative_function(value)
13
+ k = degrees_of_freedom/2.0
14
+ Math.lower_incomplete_gamma_function(k, value/2.0)/Math.gamma(k)
15
+ end
16
+
17
+ def density_function(value)
18
+ return 0 if value < 0
19
+
20
+ common = degrees_of_freedom/2.0
21
+
22
+ left_down = (2 ** common) * Math.gamma(common)
23
+ right = (value ** (common - 1)) * Math.exp(-(value/2.0))
24
+
25
+ (1.0/left_down) * right
26
+ end
27
+
28
+ def mode
29
+ [degrees_of_freedom - 2, 0].max
30
+ end
31
+
32
+ def variance
33
+ degrees_of_freedom * 2
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,46 @@
1
+ module Statistics
2
+ module Distribution
3
+ class F
4
+ attr_accessor :d1, :d2 # Degrees of freedom #1 and #2
5
+
6
+ def initialize(k, j)
7
+ self.d1 = k
8
+ self.d2 = j
9
+ end
10
+
11
+ # Formula extracted from http://www.itl.nist.gov/div898/handbook/eda/section3/eda3665.htm#CDF
12
+ def cumulative_function(value)
13
+ k = d2/(d2 + d1 * value.to_f)
14
+
15
+ 1 - Math.incomplete_beta_function(k, d2/2.0, d1/2.0)
16
+ end
17
+
18
+ def density_function(value)
19
+ return if d1 < 0 || d2 < 0 # F-pdf is well defined for the [0, +infinity) interval.
20
+
21
+ val = value.to_f
22
+ upper = ((d1 * val) ** d1) * (d2**d2)
23
+ lower = (d1 * val + d2) ** (d1 + d2)
24
+ up = Math.sqrt(upper/lower.to_f)
25
+ down = val * Math.beta_function(d1/2.0, d2/2.0)
26
+
27
+ up/down.to_f
28
+ end
29
+
30
+ def mean
31
+ return if d2 <= 2
32
+
33
+ d2/(d2 - 2).to_f
34
+ end
35
+
36
+ def mode
37
+ return if d1 <= 2
38
+
39
+ left = (d1 - 2)/d1.to_f
40
+ right = d2/(d2 + 2).to_f
41
+
42
+ left * right
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,43 @@
1
+ module Statistics
2
+ module Distribution
3
+ class Normal
4
+ attr_accessor :mean, :standard_deviation, :variance
5
+ alias_method :mode, :mean
6
+
7
+ def initialize(avg, std)
8
+ self.mean = avg.to_f
9
+ self.standard_deviation = std.to_f
10
+ self.variance = std.to_f**2
11
+ end
12
+
13
+ def cumulative_function(value)
14
+ (1/2.0) * (1.0 + Math.erf((value - mean)/(standard_deviation * Math.sqrt(2.0))))
15
+ end
16
+
17
+ def density_function(value)
18
+ return 0 if standard_deviation <= 0
19
+
20
+ up_right = (value - mean)**2.0
21
+ down_right = 2.0 * variance
22
+ right = Math.exp(-(up_right/down_right))
23
+ left_down = Math.sqrt(2.0 * Math::PI * variance)
24
+ left_up = 1.0
25
+
26
+ (left_up/(left_down) * right)
27
+ end
28
+ end
29
+
30
+ class StandardNormal < Normal
31
+ def initialize
32
+ super(0, 1) # Mean = 0, Std = 1
33
+ end
34
+
35
+ def density_function(value)
36
+ pow = (value**2)/2.0
37
+ euler = Math.exp(-pow)
38
+
39
+ euler/Math.sqrt(2 * Math::PI)
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,38 @@
1
+ module Statistics
2
+ module Distribution
3
+ class Poisson
4
+ attr_accessor :expected_number_of_occurrences
5
+
6
+ alias_method :mean, :expected_number_of_occurrences
7
+ alias_method :variance, :expected_number_of_occurrences
8
+
9
+ def initialize(l)
10
+ self.expected_number_of_occurrences = l
11
+ end
12
+
13
+ def probability_mass_function(k)
14
+ return if k < 0 || expected_number_of_occurrences < 0
15
+
16
+ k = k.to_i
17
+
18
+ upper = (expected_number_of_occurrences ** k) * Math.exp(-expected_number_of_occurrences)
19
+ lower = Math.factorial(k)
20
+
21
+ upper/lower.to_f
22
+ end
23
+
24
+ def cumulative_function(k)
25
+ return if k < 0 || expected_number_of_occurrences < 0
26
+
27
+ k = k.to_i
28
+
29
+ upper = Math.lower_incomplete_gamma_function((k + 1).floor, expected_number_of_occurrences)
30
+ lower = Math.factorial(k.floor)
31
+
32
+ # We need the right tail, i.e.: The upper incomplete gamma function. This can be
33
+ # achieved by doing a substraction between 1 and the lower incomplete gamma function.
34
+ 1 - (upper/lower.to_f)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,50 @@
1
+ module Statistics
2
+ module Distribution
3
+ class TStudent
4
+ attr_accessor :degrees_of_freedom
5
+ attr_reader :mode
6
+
7
+ def initialize(v)
8
+ self.degrees_of_freedom = v
9
+ @mode = 0
10
+ end
11
+
12
+ ### Extracted from https://codeplea.com/incomplete-beta-function-c
13
+ ### This function is shared under zlib license and the author is Lewis Van Winkle
14
+ def cumulative_function(value)
15
+ upper = (value + Math.sqrt(value * value + degrees_of_freedom))
16
+ lower = (2.0 * Math.sqrt(value * value + degrees_of_freedom))
17
+
18
+ x = upper/lower
19
+
20
+ alpha = degrees_of_freedom/2.0
21
+ beta = degrees_of_freedom/2.0
22
+
23
+ Math.incomplete_beta_function(x, alpha, beta)
24
+ end
25
+
26
+ def density_function(value)
27
+ return if degrees_of_freedom <= 0
28
+
29
+ upper = Math.gamma((degrees_of_freedom + 1)/2.0)
30
+ lower = Math.sqrt(degrees_of_freedom * Math::PI) * Math.gamma(degrees_of_freedom/2.0)
31
+ left = upper/lower
32
+ right = (1 + ((value ** 2)/degrees_of_freedom.to_f)) ** -((degrees_of_freedom + 1)/2.0)
33
+
34
+ left * right
35
+ end
36
+
37
+ def mean
38
+ 0 if degrees_of_freedom > 1
39
+ end
40
+
41
+ def variance
42
+ if degrees_of_freedom > 1 && degrees_of_freedom <= 2
43
+ Float::INFINITY
44
+ elsif degrees_of_freedom > 2
45
+ degrees_of_freedom/(degrees_of_freedom - 2.0)
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,40 @@
1
+ module Statistics
2
+ module Distribution
3
+ class Uniform
4
+ attr_accessor :left, :right
5
+
6
+ def initialize(a, b)
7
+ self.left = a.to_f
8
+ self.right = b.to_f
9
+ end
10
+
11
+ def density_function(value)
12
+ if value >= left && value <= right
13
+ 1/(right - left)
14
+ else
15
+ 0
16
+ end
17
+ end
18
+
19
+ def cumulative_function(value)
20
+ if value < left
21
+ 0
22
+ elsif value >= left && value <= right
23
+ (value - left)/(right - left)
24
+ else
25
+ 1
26
+ end
27
+ end
28
+
29
+ def mean
30
+ (1/2.0) * ( left + right )
31
+ end
32
+ alias_method :median, :mean
33
+
34
+
35
+ def variance
36
+ (1/12.0) * ( right - left ) ** 2
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,46 @@
1
+ module Statistics
2
+ module Distribution
3
+ class Weibull
4
+ attr_accessor :shape, :scale # k and lambda
5
+
6
+ def initialize(k, lamb)
7
+ self.shape = k.to_f
8
+ self.scale = lamb.to_f
9
+ end
10
+
11
+ def cumulative_function(random_value)
12
+ return 0 if random_value < 0
13
+
14
+ 1 - Math.exp(-((random_value/scale) ** shape))
15
+ end
16
+
17
+ def density_function(value)
18
+ return if shape <= 0 || scale <= 0
19
+ return 0 if value < 0
20
+
21
+ left = shape/scale
22
+ center = (value/scale)**(shape - 1)
23
+ right = Math.exp(-((value/scale)**shape))
24
+
25
+ left * center * right
26
+ end
27
+
28
+ def mean
29
+ scale * Math.gamma(1 + (1/shape))
30
+ end
31
+
32
+ def mode
33
+ return 0 if shape <= 1
34
+
35
+ scale * (((shape - 1)/shape) ** (1/shape))
36
+ end
37
+
38
+ def variance
39
+ left = Math.gamma(1 + (2/shape))
40
+ right = Math.gamma(1 + (1/shape)) ** 2
41
+
42
+ (scale ** 2) * (left - right)
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,11 @@
1
+ Dir['./lib/statistics/distribution/**/*.rb'].each {|file| require file }
2
+
3
+ module Statistics
4
+ module Distribution
5
+ end
6
+ end
7
+
8
+ # If Distribution is not defined, setup alias.
9
+ if defined?(Statistics) && !(defined?(Distribution))
10
+ Distribution = Statistics::Distribution
11
+ end
@@ -0,0 +1,3 @@
1
+ module Statistics
2
+ VERSION = "0.5.0"
3
+ end
data/lib/statistics.rb ADDED
@@ -0,0 +1,8 @@
1
+ require 'descriptive_statistics'
2
+
3
+ Dir['./lib/statistics/**/*.rb'].each {|file| require file }
4
+ require_relative './math'
5
+
6
+ module Statistics
7
+ # Your code goes here...
8
+ end
@@ -0,0 +1,36 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "statistics/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "ruby-statistics"
8
+ spec.version = Statistics::VERSION
9
+ spec.authors = ["esteban zapata"]
10
+ spec.email = ["estebanz01@outlook.com"]
11
+
12
+ spec.summary = %q{A ruby gem for som specific statistics. Inspired by the jStat js library.}
13
+ spec.description = %q{This gem is intended to accomplish the same purpose as jStat js library:
14
+ to provide ruby with statistical capabilities without the need
15
+ of a statistical programming language like R or Octave. Some functions
16
+ and capabilities are an implementation from other authors and are
17
+ referenced properly in the class/method.}
18
+ spec.homepage = "https://github.com/estebanz01/ruby-statistics"
19
+ spec.license = "MIT"
20
+
21
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
22
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
23
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
24
+ f.match(%r{^(test|spec|features)/})
25
+ end
26
+ spec.bindir = "exe"
27
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
+ spec.require_paths = ["lib"]
29
+
30
+ spec.add_development_dependency "bundler", '>= 1.15.4'
31
+ spec.add_development_dependency "rake", '>= 12.0.0'
32
+ spec.add_development_dependency "rspec", '>= 3.6.0'
33
+ spec.add_development_dependency "grb", '0.4.1'
34
+ spec.add_development_dependency 'byebug', '9.1.0'
35
+ spec.add_dependency 'descriptive_statistics', '2.5.1'
36
+ end
metadata ADDED
@@ -0,0 +1,158 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby-statistics
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.0
5
+ platform: ruby
6
+ authors:
7
+ - esteban zapata
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-09-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 1.15.4
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 1.15.4
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 12.0.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 12.0.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: 3.6.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 3.6.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: grb
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '='
60
+ - !ruby/object:Gem::Version
61
+ version: 0.4.1
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '='
67
+ - !ruby/object:Gem::Version
68
+ version: 0.4.1
69
+ - !ruby/object:Gem::Dependency
70
+ name: byebug
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '='
74
+ - !ruby/object:Gem::Version
75
+ version: 9.1.0
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '='
81
+ - !ruby/object:Gem::Version
82
+ version: 9.1.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: descriptive_statistics
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '='
88
+ - !ruby/object:Gem::Version
89
+ version: 2.5.1
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '='
95
+ - !ruby/object:Gem::Version
96
+ version: 2.5.1
97
+ description: |-
98
+ This gem is intended to accomplish the same purpose as jStat js library:
99
+ to provide ruby with statistical capabilities without the need
100
+ of a statistical programming language like R or Octave. Some functions
101
+ and capabilities are an implementation from other authors and are
102
+ referenced properly in the class/method.
103
+ email:
104
+ - estebanz01@outlook.com
105
+ executables: []
106
+ extensions: []
107
+ extra_rdoc_files: []
108
+ files:
109
+ - ".gitignore"
110
+ - ".rspec"
111
+ - ".travis.yml"
112
+ - CODE_OF_CONDUCT.md
113
+ - Gemfile
114
+ - LICENSE
115
+ - LICENSE.txt
116
+ - README.md
117
+ - Rakefile
118
+ - bin/console
119
+ - bin/setup
120
+ - lib/math.rb
121
+ - lib/statistics.rb
122
+ - lib/statistics/distribution.rb
123
+ - lib/statistics/distribution/beta.rb
124
+ - lib/statistics/distribution/binomial.rb
125
+ - lib/statistics/distribution/chi_squared.rb
126
+ - lib/statistics/distribution/f.rb
127
+ - lib/statistics/distribution/normal.rb
128
+ - lib/statistics/distribution/poisson.rb
129
+ - lib/statistics/distribution/t_student.rb
130
+ - lib/statistics/distribution/uniform.rb
131
+ - lib/statistics/distribution/weibull.rb
132
+ - lib/statistics/version.rb
133
+ - ruby-statistics.gemspec
134
+ homepage: https://github.com/estebanz01/ruby-statistics
135
+ licenses:
136
+ - MIT
137
+ metadata: {}
138
+ post_install_message:
139
+ rdoc_options: []
140
+ require_paths:
141
+ - lib
142
+ required_ruby_version: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ required_rubygems_version: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ requirements: []
153
+ rubyforge_project:
154
+ rubygems_version: 2.6.13
155
+ signing_key:
156
+ specification_version: 4
157
+ summary: A ruby gem for som specific statistics. Inspired by the jStat js library.
158
+ test_files: []