distribution 0.7.3 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
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