distribution 0.6.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +7 -0
  3. data/.travis.yml +13 -0
  4. data/.yardopts +5 -0
  5. data/Gemfile +5 -0
  6. data/History.txt +24 -8
  7. data/LICENCE.md +26 -0
  8. data/README.md +155 -0
  9. data/Rakefile +15 -19
  10. data/benchmark/binomial_coefficient.rb +19 -23
  11. data/benchmark/binomial_coefficient/experiment.rb +33 -36
  12. data/benchmark/factorial_hash.rb +7 -8
  13. data/benchmark/factorial_method.rb +4 -6
  14. data/benchmark/odd.rb +6 -7
  15. data/benchmark/power.rb +11 -11
  16. data/bin/distribution +26 -26
  17. data/data/template/spec.erb +7 -6
  18. data/distribution.gemspec +25 -0
  19. data/lib/distribution.rb +79 -124
  20. data/lib/distribution/beta.rb +6 -8
  21. data/lib/distribution/beta/gsl.rb +14 -9
  22. data/lib/distribution/beta/java.rb +1 -1
  23. data/lib/distribution/beta/ruby.rb +41 -7
  24. data/lib/distribution/binomial.rb +10 -11
  25. data/lib/distribution/binomial/gsl.rb +6 -5
  26. data/lib/distribution/binomial/java.rb +1 -1
  27. data/lib/distribution/binomial/ruby.rb +22 -15
  28. data/lib/distribution/bivariatenormal.rb +4 -5
  29. data/lib/distribution/bivariatenormal/gsl.rb +2 -2
  30. data/lib/distribution/bivariatenormal/java.rb +1 -1
  31. data/lib/distribution/bivariatenormal/ruby.rb +245 -254
  32. data/lib/distribution/chisquare.rb +8 -10
  33. data/lib/distribution/chisquare/gsl.rb +24 -19
  34. data/lib/distribution/chisquare/java.rb +1 -1
  35. data/lib/distribution/chisquare/ruby.rb +60 -55
  36. data/lib/distribution/chisquare/statistics2.rb +16 -13
  37. data/lib/distribution/distributable.rb +40 -0
  38. data/lib/distribution/exponential.rb +4 -5
  39. data/lib/distribution/exponential/gsl.rb +13 -9
  40. data/lib/distribution/exponential/ruby.rb +17 -11
  41. data/lib/distribution/f.rb +10 -11
  42. data/lib/distribution/f/gsl.rb +26 -22
  43. data/lib/distribution/f/java.rb +1 -1
  44. data/lib/distribution/f/ruby.rb +104 -105
  45. data/lib/distribution/f/statistics2.rb +22 -19
  46. data/lib/distribution/gamma.rb +5 -7
  47. data/lib/distribution/gamma/gsl.rb +13 -9
  48. data/lib/distribution/gamma/java.rb +1 -1
  49. data/lib/distribution/gamma/ruby.rb +5 -11
  50. data/lib/distribution/hypergeometric.rb +5 -8
  51. data/lib/distribution/hypergeometric/gsl.rb +5 -6
  52. data/lib/distribution/hypergeometric/java.rb +1 -1
  53. data/lib/distribution/hypergeometric/ruby.rb +34 -35
  54. data/lib/distribution/logistic.rb +6 -9
  55. data/lib/distribution/logistic/ruby.rb +14 -9
  56. data/lib/distribution/lognormal.rb +37 -0
  57. data/lib/distribution/lognormal/gsl.rb +21 -0
  58. data/lib/distribution/lognormal/ruby.rb +16 -0
  59. data/lib/distribution/math_extension.rb +187 -231
  60. data/lib/distribution/math_extension/chebyshev_series.rb +281 -272
  61. data/lib/distribution/math_extension/erfc.rb +28 -31
  62. data/lib/distribution/math_extension/exponential_integral.rb +17 -17
  63. data/lib/distribution/math_extension/gammastar.rb +19 -20
  64. data/lib/distribution/math_extension/gsl_utilities.rb +12 -12
  65. data/lib/distribution/math_extension/incomplete_beta.rb +52 -61
  66. data/lib/distribution/math_extension/incomplete_gamma.rb +166 -168
  67. data/lib/distribution/math_extension/log_utilities.rb +20 -22
  68. data/lib/distribution/normal.rb +11 -13
  69. data/lib/distribution/normal/gsl.rb +13 -10
  70. data/lib/distribution/normal/java.rb +30 -1
  71. data/lib/distribution/normal/ruby.rb +69 -59
  72. data/lib/distribution/normal/statistics2.rb +5 -2
  73. data/lib/distribution/normalmultivariate.rb +64 -64
  74. data/lib/distribution/poisson.rb +12 -14
  75. data/lib/distribution/poisson/gsl.rb +7 -7
  76. data/lib/distribution/poisson/java.rb +26 -0
  77. data/lib/distribution/poisson/ruby.rb +38 -9
  78. data/lib/distribution/shorthand.rb +17 -0
  79. data/lib/distribution/t.rb +16 -16
  80. data/lib/distribution/t/gsl.rb +27 -24
  81. data/lib/distribution/t/java.rb +1 -1
  82. data/lib/distribution/t/ruby.rb +99 -100
  83. data/lib/distribution/t/statistics2.rb +19 -19
  84. data/lib/distribution/uniform.rb +26 -0
  85. data/lib/distribution/uniform/gsl.rb +36 -0
  86. data/lib/distribution/uniform/ruby.rb +91 -0
  87. data/lib/distribution/version.rb +3 -0
  88. data/lib/distribution/weibull.rb +10 -0
  89. data/lib/distribution/weibull/gsl.rb +21 -0
  90. data/lib/distribution/weibull/ruby.rb +34 -0
  91. data/spec/beta_spec.rb +48 -50
  92. data/spec/binomial_spec.rb +80 -84
  93. data/spec/bivariatenormal_spec.rb +28 -35
  94. data/spec/chisquare_spec.rb +49 -52
  95. data/spec/distribution_spec.rb +11 -11
  96. data/spec/exponential_spec.rb +48 -39
  97. data/spec/f_spec.rb +73 -71
  98. data/spec/gamma_spec.rb +50 -53
  99. data/spec/hypergeometric_spec.rb +63 -69
  100. data/spec/logistic_spec.rb +31 -37
  101. data/spec/lognormal_spec.rb +54 -0
  102. data/spec/math_extension_spec.rb +192 -209
  103. data/spec/normal_spec.rb +80 -73
  104. data/spec/poisson_spec.rb +78 -36
  105. data/spec/shorthand_spec.rb +19 -22
  106. data/spec/spec_helper.rb +31 -6
  107. data/spec/t_spec.rb +63 -77
  108. data/spec/uniform_spec.rb +154 -0
  109. data/spec/weibull_spec.rb +17 -0
  110. data/vendor/java/commons-math-2.2.jar +0 -0
  111. metadata +91 -111
  112. data.tar.gz.sig +0 -0
  113. data/.autotest +0 -23
  114. data/.gemtest +0 -0
  115. data/Manifest.txt +0 -95
  116. data/README.txt +0 -100
  117. metadata.gz.sig +0 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: b3c0292d160b0f59129c73e352855422d7f1d35cbc8eac916419a7146c5ee4eb
4
+ data.tar.gz: 63f7693122a361948ad79f60e26d5ab060fe69982477cf96e0eb7815dcf29d29
5
+ SHA512:
6
+ metadata.gz: aa9d6ccb96e181214325ad90a1bba142bb46b2b23c2826c314ece10e55de139e613999a63e0477ea9ba595158a4544fa9758ff6f0ea4eff04ac2c2a568502e67
7
+ data.tar.gz: 5730f217be13735748570c0b45d56c3a04dc6f0dffeee39b97addb64e4eadd6a03d3d731f25a99903a9624a999be58308116b494e46342ef0ecd9b36293a4f1a
@@ -0,0 +1,7 @@
1
+ *~
2
+ *.rbc
3
+ doc/*
4
+ pkg/*
5
+ coverage
6
+ Gemfile.lock
7
+ .autotest
@@ -0,0 +1,13 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.5
4
+ - 2.6
5
+ - 2.7
6
+
7
+ script:
8
+ bundle exec rake
9
+
10
+ before_install:
11
+ - sudo apt-get update -qq
12
+ - sudo apt-get install -y libgsl0-dev
13
+ - gem update && gem install bundler
@@ -0,0 +1,5 @@
1
+ --title "Distribution"
2
+ --markup markdown
3
+ lib/**/*.rb
4
+ README.md History.txt
5
+
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem 'rb-gsl', '~> 1.16'
4
+
5
+ gemspec
@@ -1,5 +1,21 @@
1
+ === 0.7.4 / 2018-04-11
2
+ * Removed reference to deprecated Fixnum class.
3
+
4
+ === 0.7.3 / 2015-05-28
5
+ * Fixed F::Ruby_.p_value.
6
+
7
+ === 0.7.2 / 2015-04-03
8
+ * Formatting files according to the community's best practices.
9
+ * Other minor improvements in gemspec, Rakefile, etc.
10
+
11
+ === 0.7.0 / 2011-11-30
12
+ + Basic log-normal distribution support, with pdf and cdf for ruby [dennyabraham and clbustos]
13
+ * Matthew Peterson add Java support for Poisson and Normal distributions.
14
+ * Updated Logistic, Normal spec. Added LogNormal spec [clbustos]
15
+ * Updated template for new distributions
16
+
1
17
  === 0.6.0 / 2011-09-23
2
- * Incomplete Beta functions on math renamed to Regularized beta, because MathExtension::IncompleteBeta calculates regularized beta function, not Incomplete Beta.
18
+ * Incomplete Beta functions on math renamed to Regularized beta, because MathExtension::IncompleteBeta calculates regularized beta function, not Incomplete Beta.
3
19
  * Corrected documention on F distribution and added comments on gamma and beta[Claudio Bustos]
4
20
  * Moved ported methods from GSL to lib/math_extension. Updated spec for gamma and beta distributions[Claudio Bustos]
5
21
  * Added beta distribution functions. p_value does not seem to work yet.[John Woods]
@@ -13,15 +29,15 @@
13
29
  === 0.5.0 / 2011-05-03
14
30
 
15
31
  * Exception raises on calculation of T's cdf with ruby engine. For now, stick to gsl implementation
16
- * Added logistic distribution.
17
- * Raises an error on binomial if k>n.
32
+ * Added logistic distribution.
33
+ * Raises an error on binomial if k>n.
18
34
  * New rng for exponential distribution, based on F^-1 [clbustos]
19
35
  * Added power benchmark
20
36
 
21
37
  === 0.4.0 / 2011-02-01
22
38
 
23
39
  * Poisson and exponential distributions implemented. Implementation of inverse cdf for poisson is not perfect, yet.
24
- * +distribution+ executable can create template files for new distributions.
40
+ * +distribution+ executable can create template files for new distributions.
25
41
  * MathExtension should work fine with Ruby 1.8. Fixed shadowed variable on MathExtension.naive_factorial
26
42
  * Added factorial lookup table for n<20.
27
43
  * Added exact cdf for Binomial
@@ -32,19 +48,19 @@
32
48
 
33
49
  * Included support for binomial distribution. p_value is not accurate
34
50
  * Included alias for ruby exact methods on discrete distributions, when they are available
35
- * Works on Jruby and Ruby 1.8.7
51
+ * Works on Jruby and Ruby 1.8.7
36
52
  * Binomial coefficient optimized. Falling factorial method with Swing Prime on factorial provides a 10x improvement over naive version.
37
53
  * Working on binomial coefficient using gamma. The same problem as using Sterling: faster than exact version, but when it requires BigDecimal, is 2-3x slower
38
54
  * Deleted Fixnum extension on Hypergeometric
39
55
 
40
56
  === 0.2.0 / 2011-01-27
41
- * Shorthands for F and T are 'fdist' and 'tdist' now, to avoid confussions
57
+ * Shorthands for F and T are 'fdist' and 'tdist' now, to avoid confussions
42
58
  * Added Hypergeometric distribution with pdf, cdf, p_value. The Ruby version uses a very slow factorial process, but also has pdf_with_stirling if you don't care about accuracy at all. This latter method needs to be improved, actually, in terms of which choose function it calls for the numerator and denominator. Once that's done, it can replace the slower pdf function. [John Woods]
43
- * Spec for cdf and p_value of Hypergeometric
59
+ * Spec for cdf and p_value of Hypergeometric
44
60
  * New cdf and p_value on Hypergeometric[clbustos]
45
61
  * Hypergeometric#pdf returns 0 on max(0,n+m-t)<=k<=min(m,n)
46
62
  * Improved factorial calculation, using Luschny algorithms
47
63
 
48
64
  === 0.1.0 / 2011-01-26
49
65
 
50
- * Basic set (pdf, cdf, p_value) for Normal, Chi Square, F and T distributions
66
+ * Basic set (pdf, cdf, p_value) for Normal, Chi Square, F and T distributions
@@ -0,0 +1,26 @@
1
+ ## LICENSE:
2
+
3
+ Copyright (c) 2011-2012, Claudio Bustos
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+ * Redistributions of source code must retain the above copyright
9
+ notice, this list of conditions and the following disclaimer.
10
+ * Redistributions in binary form must reproduce the above copyright
11
+ notice, this list of conditions and the following disclaimer in the
12
+ documentation and/or other materials provided with the distribution.
13
+ * Neither the name of the copyright holder nor the
14
+ names of its contributors may be used to endorse or promote products
15
+ derived from this software without specific prior written permission.
16
+
17
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
+ DISCLAIMED. IN NO EVENT SHALL Claudio Bustos BE LIABLE FOR ANY
21
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,155 @@
1
+ # [Distribution](https://github.com/sciruby/distribution)
2
+
3
+ [![Build Status](https://travis-ci.org/SciRuby/distribution.svg?branch=master)](https://travis-ci.org/SciRuby/distribution)
4
+ [![Code Climate](https://codeclimate.com/github/SciRuby/distribution/badges/gpa.svg)](https://codeclimate.com/github/SciRuby/distribution)
5
+
6
+ Distribution is a gem with several probabilistic distributions. Pure Ruby is used by default, C (GSL) or Java extensions are used if available. Some facts:
7
+
8
+ - Very fast ruby 1.9.3+ implementation, with improved method to calculate factorials and other common functions.
9
+ - All methods tested on several ranges. See `spec/`.
10
+ - Code for normal, Student's t and chi square is lifted from the [statistics2 gem](https://rubygems.org/gems/statistics2). Originally at [this site](http://blade.nagaokaut.ac.jp/~sinara/ruby/math/statistics2).
11
+ - The code for some functions and RNGs was lifted from Julia's [Rmath-julia](https://github.com/JuliaLang/Rmath-julia), a patched version of R's standalone math library.
12
+
13
+ The following table lists the available distributions and the methods available for each one. If a field is marked with an *x*, that distribution doesn't have that method implemented.
14
+
15
+ | Distribution | PDF | CDF | Quantile | RNG | Mean | Mode | Variance | Skewness | Kurtosis | Entropy |
16
+ | :--------------- | :-: | :-: | :------: | :-: | :--: | :--: | :------: | :------: | :------: | :-----: |
17
+ | Uniform | | | | | x | x | x | x | x | x |
18
+ | Normal | | | | | x | x | x | x | x | x |
19
+ | Lognormal | | | x | x | x | x | x | x | x | x |
20
+ | Bivariate Normal | | | x | x | x | x | x | x | x | x |
21
+ | Exponential | | | | | x | x | x | x | x | x |
22
+ | Logistic | | | | | x | x | x | x | x | x |
23
+ | Student's T | | | | x | x | x | x | x | x | x |
24
+ | Chi Square | | | | | x | x | x | x | x | x |
25
+ | Fisher-Snedecor | | | | x | x | x | x | x | x | x |
26
+ | Beta | | | | x | x | x | x | x | x | x |
27
+ | Gamma | | | x | x | x | x | x | x | x | x |
28
+ | Weibull | | | | x | x | x | x | x | x | x |
29
+ | Binomial | | | | x | x | x | x | x | x | x |
30
+ | Poisson | | | | | x | x | x | x | x | x |
31
+ | Hypergeometric | | | | x | x | x | x | x | x | x |
32
+
33
+ ## Installation
34
+
35
+ ```
36
+ $ gem install distribution
37
+ ```
38
+
39
+ You can install GSL for better performance:
40
+
41
+ * For Mac OS X: `brew install gsl`
42
+ * For Ubuntu / Debian: `sudo apt-get install libgsl0-dev`
43
+
44
+ After successfully installing the library:
45
+
46
+ ```bash
47
+ $ gem install rb-gsl
48
+ ```
49
+
50
+ ## Examples
51
+
52
+ You can find automatically generated documentation on [RubyDoc](http://www.rubydoc.info/github/sciruby/distribution/master).
53
+
54
+ ```
55
+ # Returns Gaussian PDF for x.
56
+ pdf = Distribution::Normal.pdf(x)
57
+
58
+ # Returns Gaussian CDF for x.
59
+ cdf = Distribution::Normal.cdf(x)
60
+
61
+ # Returns inverse CDF (or p-value) for x.
62
+ pv = Distribution::Normal.p_value(x)
63
+
64
+ # API.
65
+
66
+ # You would normally use the following
67
+ p = Distribution::T.cdf(x)
68
+
69
+ # to get the cumulative probability of `x`. However, you can also:
70
+
71
+ include Distribution::Shorthand
72
+ tdist_cdf(x)
73
+ ```
74
+
75
+ ## API Structure
76
+
77
+ ```ruby
78
+ Distribution::<name>.(cdf|pdf|p_value|rng)
79
+ ```
80
+
81
+ On discrete distributions, exact Ruby implementations of pdf, cdf and p_value could be provided, using
82
+
83
+ ```
84
+ Distribution::<name>.exact_(cdf|pdf|p_value)
85
+ ```
86
+
87
+ module Distribution::Shorthand provides (you guess?) shortands method to call all methods
88
+
89
+ ```
90
+ <Distribution shortname>_(cdf|pdf|p|r)
91
+ ```
92
+
93
+ On discrete distributions, exact cdf, pdf and p_value are
94
+
95
+ ```
96
+ <Distribution shortname>_(ecdf|epdf|ep)
97
+ ```
98
+
99
+ Shortnames for distributions:
100
+
101
+ * Normal: norm
102
+ * Bivariate Normal: bnor
103
+ * T: tdist
104
+ * F: fdist
105
+ * Chi Square: chisq
106
+ * Binomial: bino
107
+ * Hypergeometric: hypg
108
+ * Exponential: expo
109
+ * Poisson: pois
110
+ * Beta: beta
111
+ * Gamma: gamma
112
+ * LogNormal: lognormal
113
+ * Uniform: unif
114
+
115
+ ## Roadmap
116
+
117
+ This gem wasn't updated for a long time before I started working on it, so there are a lot of work to do. The first priority is cleaning the interface and removing cruft whenever possible. After that, I want to implement more distributions and make sure that each one has a RNG.
118
+
119
+ ### Short-term
120
+
121
+ - Define a minimal interface for continuous and discrete distributions (e.g. mean, variance, mode, skewness, kurtosis, pdf, cdf, quantile, cquantile).
122
+ - Implement `Distribution::Uniform` with the default Ruby `Random`.
123
+ - Clean up the implementation of normal distribution. Implement the necessary functions.
124
+ - The same for Student's t, chi square, Fisher-Snedecor, beta, gamma, lognormal, logistic.
125
+ - The same for discrete distributions: binomial, hypergeometric, bernoulli (still missing), etc.
126
+
127
+ ### Medium-term
128
+
129
+ - Implement [DSFMT](http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/) for the uniform random generator.
130
+ - Cauchy distribution.
131
+
132
+ ### Long-term
133
+
134
+ - Implementing everything in the distributions x functions table above.
135
+
136
+ ## Issues
137
+
138
+ * On JRuby and Rubinius, BivariateNormal returns incorrect pdf
139
+
140
+ For current issues see the [issue tracker pages](https://github.com/sciruby/distribution/issues).
141
+
142
+ ## OMG! I want to help!
143
+
144
+ Everyone is welcome to help! Please, test these distributions with your own use
145
+ cases and give a shout on the issue tracker if you find a problem or something
146
+ is strange or hard to use. Documentation pull requests are totally welcome.
147
+ More generally, any ideas or suggestions are welcome -- even by private e-mail.
148
+
149
+ If you want to provide a new distribution, run `lib/distribution`:
150
+
151
+ ```
152
+ $ distribution --new your_distribution
153
+ ```
154
+
155
+ This should create the main distribution file, the directory with Ruby and GSL engines and specs on the spec/ directory.
data/Rakefile CHANGED
@@ -1,26 +1,22 @@
1
- # -*- ruby -*-
2
- $:.unshift(File.expand_path(File.dirname(__FILE__)+"/lib/"))
3
- require 'rubygems'
4
- require 'hoe'
5
- require 'distribution'
6
- require 'rubyforge'
7
- # Hoe.plugin :compiler
8
- # Hoe.plugin :gem_prelude_sucks
9
- Hoe.plugin :git
10
- # Hoe.plugin :inline
11
- # Hoe.plugin :racc
12
- Hoe.plugin :rubyforge
13
-
14
- Hoe.spec 'distribution' do
15
- self.developer('Claudio Bustos', 'clbustos_at_gmail.com')
16
- self.version=Distribution::VERSION
17
- self.extra_dev_deps << ["rspec",">=2.0"] << ["rubyforge",">=0"]
1
+ require 'bundler'
2
+ require 'bundler/gem_tasks'
3
+ require 'rake'
4
+ require 'rspec/core/rake_task'
18
5
 
6
+ # Setup the necessary gems, specified in the gemspec.
7
+ begin
8
+ Bundler.setup(:default, :development)
9
+ rescue Bundler::BundlerError => e
10
+ $stderr.puts e.message
11
+ $stderr.puts "Run `bundle install` to install missing gems"
12
+ exit e.status_code
19
13
  end
20
- # git log --pretty=format:"*%s[%cn]" v0.5.0..HEAD >> History.txt
14
+
21
15
  desc "Open an irb session preloaded with distribution"
22
16
  task :console do
23
17
  sh "irb -rubygems -I lib -r distribution.rb"
24
18
  end
25
19
 
26
- # vim: syntax=ruby
20
+ RSpec::Core::RakeTask.new(:spec)
21
+
22
+ task :default => :spec
@@ -1,56 +1,52 @@
1
- $:.unshift(File.expand_path(File.dirname(__FILE__)+"/../lib"))
1
+ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + '/../lib'))
2
2
  require 'distribution'
3
3
  require 'bench_press'
4
4
 
5
5
  extend BenchPress
6
6
 
7
-
8
-
9
- samples=10.times.map {|i| 2**(i+1)}
7
+ samples = 10.times.map { |i| 2**(i + 1) }
10
8
 
11
9
  name 'binomial coefficient: multiplicative, factorial and optimized factorial methods'
12
10
  author 'Claudio Bustos'
13
11
  date '2011-01-27'
14
- summary "Exact calculation of Binomial Coefficient could be obtained using multiplicative, pure factorial or optimized factorial algorithm (failing + factorial).
12
+ summary "Exact calculation of Binomial Coefficient could be obtained using multiplicative, pure factorial or optimized factorial algorithm (failing + factorial).
15
13
  Which one is faster?
16
14
 
17
- Lower k is the best for all
15
+ Lower k is the best for all
18
16
  k=n/2 is the worst case.
19
17
 
20
18
  The factorial method uses the fastest Swing Prime Algorithm."
21
19
 
22
- reps 10 #number of repetitions
23
-
24
- x=100
25
-
26
- n=100
27
- k=50
20
+ reps 10 # number of repetitions
28
21
 
22
+ x = 100
29
23
 
24
+ n = 100
25
+ k = 50
30
26
 
31
- measure "Multiplicative" do
27
+ measure 'Multiplicative' do
32
28
  samples.each do |n|
33
- [5,n/2].each do |k|
34
- k=[k,n-k].min
35
- (1..k).inject(1) {|ac, i| (ac*(n-k+i).quo(i))}
29
+ [5, n / 2].each do |k|
30
+ k = [k, n - k].min
31
+ (1..k).inject(1) { |ac, i| (ac * (n - k + i).quo(i)) }
36
32
  end
37
33
  end
38
34
  end
39
35
 
40
- measure "Pure Factorial" do
36
+ measure 'Pure Factorial' do
41
37
  samples.each do |n|
42
- [5,n/2].each do |k|
43
- k=[k,n-k].min
38
+ [5, n / 2].each do |k|
39
+ k = [k, n - k].min
44
40
  Math.factorial(n).quo(Math.factorial(k) * Math.factorial(n - k))
45
41
  end
46
42
  end
47
43
  end
48
44
 
49
- measure "Failing factorial + factorial" do
45
+ measure 'Failing factorial + factorial' do
50
46
  samples.each do |n|
51
- [5,n/2].each do |k|
52
- k=[k,n-k].min
53
- (((n-k+1)..n).inject(1) {|ac,v| ac * v}).quo(Math.factorial(k))
47
+ [5, n / 2].each do |k|
48
+ k = [k, n - k].min
49
+ (((n - k + 1)..n).inject(1) { |ac, v| ac * v }).quo(Math.factorial(k))
54
50
  end
55
51
  end
56
52
  end
@@ -1,54 +1,51 @@
1
1
  # This test create a database to adjust the best algorithm
2
2
  # to use on correlation matrix
3
- $:.unshift(File.expand_path(File.dirname(__FILE__)+"/../../lib"))
3
+ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + '/../../lib'))
4
4
  require 'distribution'
5
5
  require 'statsample'
6
6
  require 'benchmark'
7
7
 
8
- if !File.exists?("binomial_coefficient.ds") or File.mtime(__FILE__) > File.mtime("binomial_coefficient.ds")
9
- reps=100 #number of repetitions
10
- ns={
11
- 5=> [1,3],
12
- 10=> [1,3,5],
13
- 50=> [1,3,5,10,25],
14
- 100=> [1,3,5,10,25,50],
15
- 500=> [1,3,5,10,25,50,100,250],
16
- 1000=> [1,3,5,10,25,50,100,250,500],
17
- 5000=> [1,3,5,10,25,50,100,250,500,1000,2500],
18
- 10000=>[1,3,5,10,25,50,100,250,500,1000,2500,5000]
19
- }
20
-
21
- rs=Statsample::Dataset.new(%w{n k mixed_factorial multiplicative})
22
-
23
- ns.each do |n,ks|
24
- ks.each do |k|
25
-
26
- time_factorial= Benchmark.realtime do
27
- reps.times {
28
- (((n-k+1)..n).inject(1) {|ac,v| ac * v}).quo(Math.factorial(k))
8
+ if !File.exist?('binomial_coefficient.ds') or File.mtime(__FILE__) > File.mtime('binomial_coefficient.ds')
9
+ reps = 100 # number of repetitions
10
+ ns = {
11
+ 5 => [1, 3],
12
+ 10 => [1, 3, 5],
13
+ 50 => [1, 3, 5, 10, 25],
14
+ 100 => [1, 3, 5, 10, 25, 50],
15
+ 500 => [1, 3, 5, 10, 25, 50, 100, 250],
16
+ 1000 => [1, 3, 5, 10, 25, 50, 100, 250, 500],
17
+ 5000 => [1, 3, 5, 10, 25, 50, 100, 250, 500, 1000, 2500],
18
+ 10_000 => [1, 3, 5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000]
19
+ }
20
+
21
+ rs = Statsample::Dataset.new(%w(n k mixed_factorial multiplicative))
22
+
23
+ ns.each do |n, ks|
24
+ ks.each do |k|
25
+ time_factorial = Benchmark.realtime do
26
+ reps.times {
27
+ (((n - k + 1)..n).inject(1) { |ac, v| ac * v }).quo(Math.factorial(k))
29
28
  }
30
29
  end
31
-
32
- time_multiplicative= Benchmark.realtime do
33
- reps.times {
34
- (1..k).inject(1) {|ac, i| (ac*(n-k+i).quo(i))}
30
+
31
+ time_multiplicative = Benchmark.realtime do
32
+ reps.times {
33
+ (1..k).inject(1) { |ac, i| (ac * (n - k + i).quo(i)) }
35
34
  }
36
35
  end
37
-
36
+
38
37
  puts "n:#{n}, k:#{k} -> factorial:%0.3f | multiplicative: %0.3f " % [time_factorial, time_multiplicative]
39
-
40
- rs.add_case({'n'=>n,'k'=>k,'mixed_factorial'=>time_factorial, 'multiplicative'=>time_multiplicative})
38
+
39
+ rs.add_case('n' => n, 'k' => k, 'mixed_factorial' => time_factorial, 'multiplicative' => time_multiplicative)
41
40
  end
42
41
  end
43
-
42
+
44
43
  else
45
- rs=Statsample.load("binomial_coefficient.ds")
44
+ rs = Statsample.load('binomial_coefficient.ds')
46
45
  end
47
46
 
48
-
49
- rs.fields.each {|f| rs[f].type=:scale}
50
-
47
+ rs.fields.each { |f| rs[f].type = :scale }
51
48
 
52
49
  rs.update_valid_data
53
- rs.save("binomial_coefficient.ds")
54
- Statsample::Excel.write(rs,"binomial_coefficient.xls")
50
+ rs.save('binomial_coefficient.ds')
51
+ Statsample::Excel.write(rs, 'binomial_coefficient.xls')