distribution 0.7.3 → 0.8.0

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.
Files changed (100) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +4 -6
  3. data/.yardopts +5 -0
  4. data/History.txt +3 -0
  5. data/README.md +87 -44
  6. data/benchmark/binomial_coefficient.rb +19 -23
  7. data/benchmark/binomial_coefficient/experiment.rb +33 -36
  8. data/benchmark/factorial_hash.rb +7 -8
  9. data/benchmark/factorial_method.rb +4 -6
  10. data/benchmark/odd.rb +6 -7
  11. data/benchmark/power.rb +11 -11
  12. data/bin/distribution +26 -26
  13. data/distribution.gemspec +3 -4
  14. data/lib/distribution.rb +55 -96
  15. data/lib/distribution/beta/gsl.rb +10 -5
  16. data/lib/distribution/beta/ruby.rb +3 -1
  17. data/lib/distribution/binomial/ruby.rb +5 -2
  18. data/lib/distribution/bivariatenormal.rb +4 -5
  19. data/lib/distribution/bivariatenormal/gsl.rb +2 -2
  20. data/lib/distribution/bivariatenormal/java.rb +1 -1
  21. data/lib/distribution/bivariatenormal/ruby.rb +245 -254
  22. data/lib/distribution/chisquare.rb +8 -10
  23. data/lib/distribution/chisquare/gsl.rb +24 -19
  24. data/lib/distribution/chisquare/java.rb +1 -1
  25. data/lib/distribution/chisquare/ruby.rb +25 -25
  26. data/lib/distribution/chisquare/statistics2.rb +16 -13
  27. data/lib/distribution/distributable.rb +40 -0
  28. data/lib/distribution/exponential.rb +4 -5
  29. data/lib/distribution/exponential/gsl.rb +13 -9
  30. data/lib/distribution/exponential/ruby.rb +14 -9
  31. data/lib/distribution/f.rb +1 -1
  32. data/lib/distribution/f/gsl.rb +26 -22
  33. data/lib/distribution/f/java.rb +1 -1
  34. data/lib/distribution/f/ruby.rb +16 -19
  35. data/lib/distribution/f/statistics2.rb +22 -19
  36. data/lib/distribution/gamma.rb +5 -7
  37. data/lib/distribution/gamma/gsl.rb +13 -9
  38. data/lib/distribution/gamma/java.rb +1 -1
  39. data/lib/distribution/gamma/ruby.rb +5 -11
  40. data/lib/distribution/hypergeometric.rb +5 -8
  41. data/lib/distribution/hypergeometric/gsl.rb +4 -5
  42. data/lib/distribution/hypergeometric/java.rb +1 -1
  43. data/lib/distribution/hypergeometric/ruby.rb +34 -35
  44. data/lib/distribution/logistic.rb +5 -8
  45. data/lib/distribution/logistic/ruby.rb +13 -8
  46. data/lib/distribution/lognormal.rb +5 -7
  47. data/lib/distribution/lognormal/gsl.rb +8 -6
  48. data/lib/distribution/lognormal/ruby.rb +5 -9
  49. data/lib/distribution/math_extension.rb +6 -15
  50. data/lib/distribution/math_extension/chebyshev_series.rb +281 -272
  51. data/lib/distribution/math_extension/erfc.rb +26 -29
  52. data/lib/distribution/math_extension/exponential_integral.rb +17 -17
  53. data/lib/distribution/math_extension/gammastar.rb +19 -20
  54. data/lib/distribution/math_extension/gsl_utilities.rb +12 -12
  55. data/lib/distribution/math_extension/incomplete_beta.rb +52 -61
  56. data/lib/distribution/math_extension/incomplete_gamma.rb +166 -168
  57. data/lib/distribution/math_extension/log_utilities.rb +20 -22
  58. data/lib/distribution/normal.rb +11 -13
  59. data/lib/distribution/normal/gsl.rb +13 -10
  60. data/lib/distribution/normal/java.rb +14 -13
  61. data/lib/distribution/normal/ruby.rb +68 -58
  62. data/lib/distribution/normal/statistics2.rb +5 -2
  63. data/lib/distribution/normalmultivariate.rb +64 -64
  64. data/lib/distribution/poisson.rb +11 -13
  65. data/lib/distribution/poisson/gsl.rb +7 -7
  66. data/lib/distribution/poisson/java.rb +19 -24
  67. data/lib/distribution/poisson/ruby.rb +38 -9
  68. data/lib/distribution/shorthand.rb +17 -0
  69. data/lib/distribution/t.rb +13 -15
  70. data/lib/distribution/t/gsl.rb +27 -24
  71. data/lib/distribution/t/java.rb +1 -1
  72. data/lib/distribution/t/ruby.rb +99 -100
  73. data/lib/distribution/t/statistics2.rb +19 -19
  74. data/lib/distribution/uniform.rb +26 -0
  75. data/lib/distribution/uniform/gsl.rb +36 -0
  76. data/lib/distribution/uniform/ruby.rb +91 -0
  77. data/lib/distribution/version.rb +1 -1
  78. data/lib/distribution/weibull.rb +6 -7
  79. data/lib/distribution/weibull/gsl.rb +16 -16
  80. data/lib/distribution/weibull/ruby.rb +30 -23
  81. data/spec/beta_spec.rb +45 -47
  82. data/spec/binomial_spec.rb +77 -85
  83. data/spec/bivariatenormal_spec.rb +28 -35
  84. data/spec/chisquare_spec.rb +48 -52
  85. data/spec/distribution_spec.rb +10 -10
  86. data/spec/exponential_spec.rb +44 -49
  87. data/spec/f_spec.rb +4 -4
  88. data/spec/gamma_spec.rb +50 -53
  89. data/spec/hypergeometric_spec.rb +63 -69
  90. data/spec/logistic_spec.rb +32 -37
  91. data/spec/lognormal_spec.rb +25 -31
  92. data/spec/math_extension_spec.rb +192 -210
  93. data/spec/normal_spec.rb +80 -73
  94. data/spec/poisson_spec.rb +63 -41
  95. data/spec/shorthand_spec.rb +19 -22
  96. data/spec/spec_helper.rb +8 -9
  97. data/spec/t_spec.rb +63 -77
  98. data/spec/uniform_spec.rb +154 -0
  99. data/spec/weibull_spec.rb +13 -14
  100. metadata +17 -8
@@ -7,13 +7,12 @@ module Distribution
7
7
  module MathExtension
8
8
  module IncompleteGamma
9
9
  NMAX = 5000
10
- SMALL = Float::EPSILON ** 3
10
+ SMALL = Float::EPSILON**3
11
11
  PG21 = -2.404113806319188570799476 # PolyGamma[2,1]
12
12
 
13
13
  class << self
14
-
15
14
  # Helper function for plot
16
- #def range_to_array r
15
+ # def range_to_array r
17
16
  # r << (r.last - r.first)/100.0 if r.size == 2 # set dr as Dr/100.0
18
17
  # arr = []
19
18
  # pos = r[0]
@@ -22,9 +21,9 @@ module Distribution
22
21
  # pos += r[2]
23
22
  # end
24
23
  # arr
25
- #end
24
+ # end
26
25
  #
27
- #def plot a, x_range, fun = :p
26
+ # def plot a, x_range, fun = :p
28
27
  # x_range = range_to_array(x_range) if x_range.is_a?(Array)
29
28
  # y_range = x_range.collect { |x| self.send(fun, a, x) }
30
29
  # graph = Statsample::Graph::Scatterplot.new x_range.to_scale, y_range.to_scale
@@ -32,96 +31,96 @@ module Distribution
32
31
  # f.puts(graph.to_svg)
33
32
  # f.close
34
33
  # `google-chrome test.svg`
35
- #end
34
+ # end
36
35
 
37
36
  # The dominant part, D(a,x) := x^a e^(-x) / Gamma(a+1)
38
37
  # gamma_inc_D in GSL-1.9.
39
38
  def d(a, x, with_error = false)
40
39
  error = nil
41
40
  if a < 10.0
42
- ln_a = Math.lgamma(a+1.0).first
41
+ ln_a = Math.lgamma(a + 1.0).first
43
42
  lnr = a * Math.log(x) - x - ln_a
44
43
  result = Math.exp(lnr)
45
44
  error = 2.0 * Float::EPSILON * (lnr.abs + 1.0) + result.abs if with_error
46
- with_error ? [result,error] : result
45
+ with_error ? [result, error] : result
47
46
  else
48
47
  ln_term = ln_term_error = nil
49
- if x < 0.5*a
50
- u = x/a.to_f
48
+ if x < 0.5 * a
49
+ u = x / a.to_f
51
50
  ln_u = Math.log(u)
52
51
  ln_term = ln_u - u + 1.0
53
52
  ln_term_error = (ln_u.abs + u.abs + 1.0) * Float::EPSILON if with_error
54
53
  else
55
- mu = (x-a)/a.to_f
56
- ln_term = Log::log_1plusx_minusx(mu, with_error)
54
+ mu = (x - a) / a.to_f
55
+ ln_term = Log.log_1plusx_minusx(mu, with_error)
57
56
  ln_term, ln_term_error = ln_term if with_error
58
57
  end
59
58
  gstar = Gammastar.evaluate(a, with_error)
60
- gstar,gstar_error = gstar if with_error
61
- term1 = Math.exp(a*ln_term) / Math.sqrt(2.0*Math::PI*a)
62
- result = term1/gstar
63
- error = 2.0*Float::EPSILON*((a*ln_term).abs+1.0) * result.abs + gstar_error/gstar.abs * result.abs if with_error
64
- with_error ? [result,error] : result
59
+ gstar, gstar_error = gstar if with_error
60
+ term1 = Math.exp(a * ln_term) / Math.sqrt(2.0 * Math::PI * a)
61
+ result = term1 / gstar
62
+ error = 2.0 * Float::EPSILON * ((a * ln_term).abs + 1.0) * result.abs + gstar_error / gstar.abs * result.abs if with_error
63
+ with_error ? [result, error] : result
65
64
  end
66
65
  end
67
66
 
68
67
  # gamma_inc_P_series
69
- def p_series(a,x,with_error=false)
70
- d = d(a,x,with_error)
68
+ def p_series(a, x, with_error = false)
69
+ d = d(a, x, with_error)
71
70
  d, d_err = d if with_error
72
71
  sum = 1.0
73
72
  term = 1.0
74
73
  n = 1
75
- 1.upto(NMAX-1) do |n|
76
- term *= x / (a+n).to_f
77
- sum += term
78
- break if (term/sum).abs < Float::EPSILON
74
+ 1.upto(NMAX - 1) do |n|
75
+ term *= x / (a + n).to_f
76
+ sum += term
77
+ break if (term / sum).abs < Float::EPSILON
79
78
  end
80
79
 
81
80
  result = d * sum
82
81
 
83
82
  if n == NMAX
84
- STDERR.puts("Error: n reached NMAX in p series")
83
+ STDERR.puts('Error: n reached NMAX in p series')
85
84
  else
86
- return with_error ? [result,d_err * sum.abs + (1.0+n)*Float::EPSILON * result.abs] : result
85
+ return with_error ? [result, d_err * sum.abs + (1.0 + n) * Float::EPSILON * result.abs] : result
87
86
  end
88
87
  end
89
88
 
90
89
  # This function does not exist in GSL, but is nonetheless GSL code. It's for calculating two specific ranges of p.
91
- def q_asymptotic_uniform_complement a,x,with_error=false
90
+ def q_asymptotic_uniform_complement(a, x, with_error = false)
92
91
  q = q_asymptotic_uniform(a, x, with_error)
93
- q,q_err = q if with_error
92
+ q, q_err = q if with_error
94
93
  result = 1.0 - q
95
- return with_error ? [result, q_err + 2.0*Float::EPSILON*result.abs] : result
94
+ with_error ? [result, q_err + 2.0 * Float::EPSILON * result.abs] : result
96
95
  end
97
96
 
98
- def q_continued_fraction_complement a,x,with_error=false
99
- q = q_continued_fraction(a,x,with_error)
100
- return with_error ? [1.0 - q.first, q.last + 2.0*Float::EPSILON*(1.0-q.first).abs] : 1.0 - q
97
+ def q_continued_fraction_complement(a, x, with_error = false)
98
+ q = q_continued_fraction(a, x, with_error)
99
+ with_error ? [1.0 - q.first, q.last + 2.0 * Float::EPSILON * (1.0 - q.first).abs] : 1.0 - q
101
100
  end
102
101
 
103
- def q_large_x_complement a,x,with_error=false
104
- q = q_large_x(a,x,with_error)
105
- return with_error ? [1.0 - q.first, q.last + 2.0*Float::EPSILON*(1.0-q.first).abs] : 1.0 - q
102
+ def q_large_x_complement(a, x, with_error = false)
103
+ q = q_large_x(a, x, with_error)
104
+ with_error ? [1.0 - q.first, q.last + 2.0 * Float::EPSILON * (1.0 - q.first).abs] : 1.0 - q
106
105
  end
107
106
 
108
107
  # The incomplete gamma function.
109
108
  # gsl_sf_gamma_inc_P_e
110
- def p a,x,with_error=false
111
- raise(ArgumentError, "Range Error: a must be positive, x must be non-negative") if a <= 0.0 || x < 0.0
109
+ def p(a, x, with_error = false)
110
+ fail(ArgumentError, 'Range Error: a must be positive, x must be non-negative') if a <= 0.0 || x < 0.0
112
111
  if x == 0.0
113
112
  return with_error ? [0.0, 0.0] : 0.0
114
- elsif x < 20.0 || x < 0.5*a
113
+ elsif x < 20.0 || x < 0.5 * a
115
114
  return p_series(a, x, with_error)
116
- elsif a > 1e6 && (x-a)*(x-a) < a
115
+ elsif a > 1e6 && (x - a) * (x - a) < a
117
116
  return q_asymptotic_uniform_complement a, x, with_error
118
117
  elsif a <= x
119
- if a > 0.2*x
118
+ if a > 0.2 * x
120
119
  return q_continued_fraction_complement(a, x, with_error)
121
120
  else
122
121
  return q_large_x_complement(a, x, with_error)
123
122
  end
124
- elsif (x-a)*(x-a) < a
123
+ elsif (x - a) * (x - a) < a
125
124
  return q_asymptotic_uniform_complement a, x, with_error
126
125
  else
127
126
  return p_series(a, x, with_error)
@@ -129,71 +128,71 @@ module Distribution
129
128
  end
130
129
 
131
130
  # gamma_inc_Q_e
132
- def q a,x,with_error=false
133
- raise(ArgumentError, "Range Error: a and x must be non-negative") if (a < 0.0 || x < 0.0)
131
+ def q(a, x, with_error = false)
132
+ fail(ArgumentError, 'Range Error: a and x must be non-negative') if a < 0.0 || x < 0.0
134
133
  if x == 0.0
135
134
  return with_error ? [1.0, 0.0] : 1.0
136
135
  elsif a == 0.0
137
136
  return with_error ? [0.0, 0.0] : 0.0
138
- elsif x <= 0.5*a
137
+ elsif x <= 0.5 * a
139
138
  # If series is quick, do that.
140
- p = p_series(a,x, with_error)
141
- p,p_err = p if with_error
139
+ p = p_series(a, x, with_error)
140
+ p, p_err = p if with_error
142
141
  result = 1.0 - p
143
- return with_error ? [result, p_err + 2.0*Float::EPSILON*result.abs] : result
144
- elsif a >= 1.0e+06 && (x-a)*(x-a) < a # difficult asymptotic regime, only way to do this region
142
+ return with_error ? [result, p_err + 2.0 * Float::EPSILON * result.abs] : result
143
+ elsif a >= 1.0e+06 && (x - a) * (x - a) < a # difficult asymptotic regime, only way to do this region
145
144
  return q_asymptotic_uniform(a, x, with_error)
146
145
  elsif a < 0.2 && x < 5.0
147
- return q_series(a,x, with_error)
146
+ return q_series(a, x, with_error)
148
147
  elsif a <= x
149
148
  return x <= 1.0e+06 ? q_continued_fraction(a, x, with_error) : q_large_x(a, x, with_error)
150
149
  else
151
- if x > a-Math.sqrt(a)
150
+ if x > a - Math.sqrt(a)
152
151
  return q_continued_fraction(a, x, with_error)
153
152
  else
154
153
  p = p_series(a, x, with_error)
155
154
  p, p_err = p if with_error
156
155
  result = 1.0 - p
157
- return with_error ? [result, p_err + 2.0*Float::EPSILON*result.abs] : result
156
+ return with_error ? [result, p_err + 2.0 * Float::EPSILON * result.abs] : result
158
157
  end
159
158
  end
160
159
  end
161
160
 
162
161
  # gamma_inc_Q_CF
163
- def q_continued_fraction a, x, with_error=false
162
+ def q_continued_fraction(a, x, with_error = false)
164
163
  d = d(a, x, with_error)
165
164
  f = f_continued_fraction(a, x, with_error)
166
165
 
167
166
  if with_error
168
- [d.first*(a/x).to_f*f.first, d.last * ((a/x).to_f*f.first).abs + (d.first*a/x*f.last).abs]
167
+ [d.first * (a / x).to_f * f.first, d.last * ((a / x).to_f * f.first).abs + (d.first * a / x * f.last).abs]
169
168
  else
170
- d * (a/x).to_f * f
169
+ d * (a / x).to_f * f
171
170
  end
172
171
  end
173
172
 
174
173
  # gamma_inc_Q_large_x in GSL-1.9
175
- def q_large_x a,x,with_error=false
176
- d = d(a,x,with_error)
177
- d,d_err = d if with_error
174
+ def q_large_x(a, x, with_error = false)
175
+ d = d(a, x, with_error)
176
+ d, d_err = d if with_error
178
177
  sum = 1.0
179
178
  term = 1.0
180
179
  last = 1.0
181
180
  n = 1
182
- 1.upto(NMAX-1).each do |n|
183
- term *= (a-n)/x
184
- break if (term/last).abs > 1.0
185
- break if (term/sum).abs < Float::EPSILON
186
- sum += term
181
+ 1.upto(NMAX - 1).each do |n|
182
+ term *= (a - n) / x
183
+ break if (term / last).abs > 1.0
184
+ break if (term / sum).abs < Float::EPSILON
185
+ sum += term
187
186
  last = term
188
187
  end
189
188
 
190
- result = d*(a/x)*sum
191
- error = d_err * (a/x).abs * sum if with_error
189
+ result = d * (a / x) * sum
190
+ error = d_err * (a / x).abs * sum if with_error
192
191
 
193
192
  if n == NMAX
194
- STDERR.puts("Error: n reached NMAX in q_large_x")
193
+ STDERR.puts('Error: n reached NMAX in q_large_x')
195
194
  else
196
- return with_error ? [result,error] : result
195
+ return with_error ? [result, error] : result
197
196
  end
198
197
  end
199
198
 
@@ -201,41 +200,41 @@ module Distribution
201
200
  # gamma_inc_Q_asymp_unif
202
201
  def q_asymptotic_uniform(a, x, with_error = false)
203
202
  rta = Math.sqrt(a)
204
- eps = (x-a).quo(a)
203
+ eps = (x - a).quo(a)
205
204
 
206
- ln_term = Log::log_1plusx_minusx(eps, with_error)
205
+ ln_term = Log.log_1plusx_minusx(eps, with_error)
207
206
  ln_term, ln_term_err = ln_term if with_error
208
207
 
209
- eta = (eps >= 0 ? 1 : -1) * Math.sqrt(-2*ln_term)
208
+ eta = (eps >= 0 ? 1 : -1) * Math.sqrt(-2 * ln_term)
210
209
 
211
- erfc = Math.erfc_e(eta*rta/SQRT2, with_error)
210
+ erfc = Math.erfc_e(eta * rta / SQRT2, with_error)
212
211
  erfc, erfc_err = erfc if with_error
213
212
 
214
213
  c0 = c1 = nil
215
214
  if eps.abs < ROOT5_FLOAT_EPSILON
216
- c0 = -1.quo(3) + eps*(1.quo(12) - eps*(23.quo(540) - eps*(353.quo(12960) - eps*589.quo(30240))))
215
+ c0 = -1.quo(3) + eps * (1.quo(12) - eps * (23.quo(540) - eps * (353.quo(12_960) - eps * 589.quo(30_240))))
217
216
  c1 = -1.quo(540) - eps.quo(288)
218
217
  else
219
- rt_term = Math.sqrt(-2 * ln_term.quo(eps*eps))
218
+ rt_term = Math.sqrt(-2 * ln_term.quo(eps * eps))
220
219
  lam = x.quo(a)
221
- c0 = (1 - 1/rt_term)/eps
222
- c1 = -(eta**3 * (lam*lam + 10*lam + 1) - 12*eps**3).quo(12 * eta**3 * eps**3)
220
+ c0 = (1 - 1 / rt_term) / eps
221
+ c1 = -(eta**3 * (lam * lam + 10 * lam + 1) - 12 * eps**3).quo(12 * eta**3 * eps**3)
223
222
  end
224
223
 
225
- r = Math.exp(-0.5*a*eta*eta) / (SQRT2*SQRTPI*rta) * (c0 + c1.quo(a))
224
+ r = Math.exp(-0.5 * a * eta * eta) / (SQRT2 * SQRTPI * rta) * (c0 + c1.quo(a))
226
225
 
227
226
  result = 0.5 * erfc + r
228
- with_error ? [result, Float::EPSILON + (r*0.5*a*eta*eta).abs + 0.5*erfc_err + 2.0*Float::EPSILON + result.abs] : result
227
+ with_error ? [result, Float::EPSILON + (r * 0.5 * a * eta * eta).abs + 0.5 * erfc_err + 2.0 * Float::EPSILON + result.abs] : result
229
228
  end
230
229
 
231
230
  # gamma_inc_F_CF
232
- def f_continued_fraction a, x, with_error = false
231
+ def f_continued_fraction(a, x, with_error = false)
233
232
  hn = 1.0 # convergent
234
233
  cn = 1.0 / SMALL
235
234
  dn = 1.0
236
235
  n = 2
237
- 2.upto(NMAX-1).each do |n|
238
- an = n.odd? ? 0.5*(n-1)/x : (0.5*n-a)/x
236
+ 2.upto(NMAX - 1).each do |n|
237
+ an = n.odd? ? 0.5 * (n - 1) / x : (0.5 * n - a) / x
239
238
  dn = 1.0 + an * dn
240
239
  dn = SMALL if dn.abs < SMALL
241
240
  cn = 1.0 + an / cn
@@ -243,17 +242,17 @@ module Distribution
243
242
  dn = 1.0 / dn
244
243
  delta = cn * dn
245
244
  hn *= delta
246
- break if (delta-1.0).abs < Float::EPSILON
245
+ break if (delta - 1.0).abs < Float::EPSILON
247
246
  end
248
247
 
249
248
  if n == NMAX
250
- STDERR.puts("Error: n reached NMAX in f continued fraction")
249
+ STDERR.puts('Error: n reached NMAX in f continued fraction')
251
250
  else
252
- with_error ? [hn,2.0*Float::EPSILON * hn.abs + Float::EPSILON*(2.0+0.5*n) * hn.abs] : hn
251
+ with_error ? [hn, 2.0 * Float::EPSILON * hn.abs + Float::EPSILON * (2.0 + 0.5 * n) * hn.abs] : hn
253
252
  end
254
253
  end
255
254
 
256
- def q_series(a,x,with_error=false)
255
+ def q_series(a, x, with_error = false)
257
256
  term1 = nil
258
257
  sum = nil
259
258
  term2 = nil
@@ -261,120 +260,120 @@ module Distribution
261
260
  lnx = Math.log(x)
262
261
  el = EULER + lnx
263
262
  c1 = -el
264
- c2 = Math::PI * Math::PI / 12.0 - 0.5*el*el
265
- c3 = el*(Math::PI*Math::PI/12.0 - el*el/6.0) + PG21/6.0
263
+ c2 = Math::PI * Math::PI / 12.0 - 0.5 * el * el
264
+ c3 = el * (Math::PI * Math::PI / 12.0 - el * el / 6.0) + PG21 / 6.0
266
265
  c4 = -0.04166666666666666667 *
267
- (-1.758243446661483480 + lnx) *
268
- (-0.764428657272716373 + lnx) *
269
- ( 0.723980571623507657 + lnx) *
270
- ( 4.107554191916823640 + lnx)
266
+ (-1.758243446661483480 + lnx) *
267
+ (-0.764428657272716373 + lnx) *
268
+ (0.723980571623507657 + lnx) *
269
+ (4.107554191916823640 + lnx)
271
270
  c5 = -0.0083333333333333333 *
272
- (-2.06563396085715900 + lnx) *
273
- (-1.28459889470864700 + lnx) *
274
- (-0.27583535756454143 + lnx) *
275
- ( 1.33677371336239618 + lnx) *
276
- ( 5.17537282427561550 + lnx)
271
+ (-2.06563396085715900 + lnx) *
272
+ (-1.28459889470864700 + lnx) *
273
+ (-0.27583535756454143 + lnx) *
274
+ (1.33677371336239618 + lnx) *
275
+ (5.17537282427561550 + lnx)
277
276
  c6 = -0.0013888888888888889 *
278
- (-2.30814336454783200 + lnx) *
279
- (-1.65846557706987300 + lnx) *
280
- (-0.88768082560020400 + lnx) *
281
- ( 0.17043847751371778 + lnx) *
282
- ( 1.92135970115863890 + lnx) *
283
- ( 6.22578557795474900 + lnx)
277
+ (-2.30814336454783200 + lnx) *
278
+ (-1.65846557706987300 + lnx) *
279
+ (-0.88768082560020400 + lnx) *
280
+ (0.17043847751371778 + lnx) *
281
+ (1.92135970115863890 + lnx) *
282
+ (6.22578557795474900 + lnx)
284
283
  c7 = -0.00019841269841269841
285
- (-2.5078657901291800 + lnx) *
286
- (-1.9478900888958200 + lnx) *
287
- (-1.3194837322612730 + lnx) *
288
- (-0.5281322700249279 + lnx) *
289
- ( 0.5913834939078759 + lnx) *
290
- ( 2.4876819633378140 + lnx) *
291
- ( 7.2648160783762400 + lnx)
284
+ (-2.5078657901291800 + lnx) *
285
+ (-1.9478900888958200 + lnx) *
286
+ (-1.3194837322612730 + lnx) *
287
+ (-0.5281322700249279 + lnx) *
288
+ (0.5913834939078759 + lnx) *
289
+ (2.4876819633378140 + lnx) *
290
+ (7.2648160783762400 + lnx)
292
291
  c8 = -0.00002480158730158730 *
293
- (-2.677341544966400 + lnx) *
294
- (-2.182810448271700 + lnx) *
295
- (-1.649350342277400 + lnx) *
296
- (-1.014099048290790 + lnx) *
297
- (-0.191366955370652 + lnx) *
298
- ( 0.995403817918724 + lnx) *
299
- ( 3.041323283529310 + lnx) *
300
- ( 8.295966556941250 + lnx) *
301
- c9 = -2.75573192239859e-6 *
302
- (-2.8243487670469080 + lnx) *
303
- (-2.3798494322701120 + lnx) *
304
- (-1.9143674728689960 + lnx) *
305
- (-1.3814529102920370 + lnx) *
306
- (-0.7294312810261694 + lnx) *
307
- ( 0.1299079285269565 + lnx) *
308
- ( 1.3873333251885240 + lnx) *
309
- ( 3.5857258865210760 + lnx) *
310
- ( 9.3214237073814600 + lnx) *
311
- c10 = -2.75573192239859e-7 *
312
- (-2.9540329644556910 + lnx) *
313
- (-2.5491366926991850 + lnx) *
314
- (-2.1348279229279880 + lnx) *
315
- (-1.6741881076349450 + lnx) *
316
- (-1.1325949616098420 + lnx) *
317
- (-0.4590034650618494 + lnx) *
318
- ( 0.4399352987435699 + lnx) *
319
- ( 1.7702236517651670 + lnx) *
320
- ( 4.1231539047474080 + lnx) *
321
- ( 10.342627908148680 + lnx)
322
- term1 = a*(c1+a*(c2+a*(c3+a*(c4+a*(c5+a*(c6+a*(c7+a*(c8+a*(c9+a*c10)))))))))
292
+ (-2.677341544966400 + lnx) *
293
+ (-2.182810448271700 + lnx) *
294
+ (-1.649350342277400 + lnx) *
295
+ (-1.014099048290790 + lnx) *
296
+ (-0.191366955370652 + lnx) *
297
+ (0.995403817918724 + lnx) *
298
+ (3.041323283529310 + lnx) *
299
+ (8.295966556941250 + lnx) *
300
+ c9 = -2.75573192239859e-6 *
301
+ (-2.8243487670469080 + lnx) *
302
+ (-2.3798494322701120 + lnx) *
303
+ (-1.9143674728689960 + lnx) *
304
+ (-1.3814529102920370 + lnx) *
305
+ (-0.7294312810261694 + lnx) *
306
+ (0.1299079285269565 + lnx) *
307
+ (1.3873333251885240 + lnx) *
308
+ (3.5857258865210760 + lnx) *
309
+ (9.3214237073814600 + lnx) *
310
+ c10 = -2.75573192239859e-7 *
311
+ (-2.9540329644556910 + lnx) *
312
+ (-2.5491366926991850 + lnx) *
313
+ (-2.1348279229279880 + lnx) *
314
+ (-1.6741881076349450 + lnx) *
315
+ (-1.1325949616098420 + lnx) *
316
+ (-0.4590034650618494 + lnx) *
317
+ (0.4399352987435699 + lnx) *
318
+ (1.7702236517651670 + lnx) *
319
+ (4.1231539047474080 + lnx) *
320
+ (10.342627908148680 + lnx)
321
+ term1 = a * (c1 + a * (c2 + a * (c3 + a * (c4 + a * (c5 + a * (c6 + a * (c7 + a * (c8 + a * (c9 + a * c10)))))))))
323
322
  end
324
323
 
325
324
  n = 1
326
325
  begin
327
326
  t = 1.0
328
327
  sum = 1.0
329
- 1.upto(NMAX-1).each do |n|
330
- t *= -x/(n+1.0)
331
- sum += (a+1.0) / (a+n+1.0) * t
332
- break if (t/sum).abs < Float::EPSILON
328
+ 1.upto(NMAX - 1).each do |n|
329
+ t *= -x / (n + 1.0)
330
+ sum += (a + 1.0) / (a + n + 1.0) * t
331
+ break if (t / sum).abs < Float::EPSILON
333
332
  end
334
333
  end
335
334
 
336
335
  if n == NMAX
337
- STDERR.puts("Error: n reached NMAX in q_series")
336
+ STDERR.puts('Error: n reached NMAX in q_series')
338
337
  else
339
- term2 = (1.0 - term1) * a/(a+1.0) * x * sum
340
- result = term1+term2
341
- with_error ? [result, Float::EPSILON*term1.abs + 2.0*term2.abs + 2.0*Float::EPSILON*result.abs] : result
338
+ term2 = (1.0 - term1) * a / (a + 1.0) * x * sum
339
+ result = term1 + term2
340
+ with_error ? [result, Float::EPSILON * term1.abs + 2.0 * term2.abs + 2.0 * Float::EPSILON * result.abs] : result
342
341
  end
343
342
  end
344
343
 
345
344
  # gamma_inc_series
346
- def series a,x,with_error = false
347
- q = q_series(a,x,with_error)
345
+ def series(a, x, with_error = false)
346
+ q = q_series(a, x, with_error)
348
347
  g = Math.gamma(a)
349
348
  STDERR.puts("Warning: Don't know error for Math.gamma. Error will be incorrect") if with_error
350
349
  # When we get the error from Gamma, switch the comment on the next to lines
351
350
  # with_error ? [q.first*g.first, (q.first*g.last).abs + (q.last*g.first).abs + 2.0*Float::EPSILON*(q.first*g.first).abs] : q*g
352
- with_error ? [q.first*g, (q.first*Float::EPSILON).abs + (q.last*g.first).abs + 2.0*Float::EPSILON(q.first*g).abs] : q*g
351
+ with_error ? [q.first * g, (q.first * Float::EPSILON).abs + (q.last * g.first).abs + 2.0 * Float::EPSILON(q.first * g).abs] : q * g
353
352
  end
354
353
 
355
354
  # gamma_inc_a_gt_0
356
- def a_greater_than_0 a, x, with_error = false
357
- q = q(a,x,with_error)
358
- q,q_err = q if with_error
355
+ def a_greater_than_0(a, x, with_error = false)
356
+ q = q(a, x, with_error)
357
+ q, q_err = q if with_error
359
358
  g = Math.gamma(a)
360
359
  STDERR.puts("Warning: Don't know error for Math.gamma. Error will be incorrect") if with_error
361
360
  g_err = Float::EPSILON
362
- result = g*q
363
- error = (g*q_err).abs + (g_err*q).abs if with_error
364
- with_error ? [result,error] : result
361
+ result = g * q
362
+ error = (g * q_err).abs + (g_err * q).abs if with_error
363
+ with_error ? [result, error] : result
365
364
  end
366
365
 
367
366
  # gamma_inc_CF
368
- def continued_fraction a,x, with_error=false
369
- f = f_continued_fraction(a,x,with_error)
370
- f,f_error = f if with_error
371
- pre = Math.exp((a-1.0)*Math.log(x) - x)
367
+ def continued_fraction(a, x, with_error = false)
368
+ f = f_continued_fraction(a, x, with_error)
369
+ f, f_error = f if with_error
370
+ pre = Math.exp((a - 1.0) * Math.log(x) - x)
372
371
  STDERR.puts("Warning: Don't know error for Math.exp. Error will be incorrect") if with_error
373
372
  pre_error = Float::EPSILON
374
- result = f*pre
373
+ result = f * pre
375
374
  if with_error
376
- error = (f_error*pre).abs + (f*pre_error) + (2.0+a.abs)*Float::EPSILON*result.abs
377
- [result,error]
375
+ error = (f_error * pre).abs + (f * pre_error) + (2.0 + a.abs) * Float::EPSILON * result.abs
376
+ [result, error]
378
377
  else
379
378
  result
380
379
  end
@@ -382,8 +381,8 @@ module Distribution
382
381
 
383
382
  # Unnormalized incomplete gamma function.
384
383
  # gsl_sf_gamma_inc_e
385
- def unnormalized a,x,with_error = false
386
- raise(ArgumentError, "x cannot be negative") if x < 0.0
384
+ def unnormalized(a, x, with_error = false)
385
+ fail(ArgumentError, 'x cannot be negative') if x < 0.0
387
386
 
388
387
  if x == 0.0
389
388
  result = Math.gamma(a.to_f)
@@ -397,7 +396,7 @@ module Distribution
397
396
  # continued fraction seems to fail for x too small
398
397
  return continued_fraction(a.to_f, x.to_f, with_error)
399
398
  elsif a.abs < 0.5
400
- return series(a.to_f,x.to_f,with_error)
399
+ return series(a.to_f, x.to_f, with_error)
401
400
  else
402
401
  fa = a.floor.to_f
403
402
  da = a - fa
@@ -408,17 +407,16 @@ module Distribution
408
407
 
409
408
  # Gamma(alpha-1,x) = 1/(alpha-1) (Gamma(a,x) - x^(alpha-1) e^-x)
410
409
  begin
411
- shift = Math.exp(-x + (alpha-1.0)*Math.log(x))
412
- gax = (gax-shift) / (alpha-1.0)
410
+ shift = Math.exp(-x + (alpha - 1.0) * Math.log(x))
411
+ gax = (gax - shift) / (alpha - 1.0)
413
412
  alpha -= 1.0
414
413
  end while alpha > a
415
414
 
416
415
  result = gax
417
- return with_error ? [result, 2.0*(1.0 + a.abs) * Float::EPSILON*gax.abs] : result
416
+ return with_error ? [result, 2.0 * (1.0 + a.abs) * Float::EPSILON * gax.abs] : result
418
417
  end
419
418
  end
420
-
421
419
  end
422
420
  end
423
421
  end
424
- end
422
+ end