Module: Distribution::MathExtension
- Defined in:
- lib/distribution/math_extension.rb,
lib/distribution/math_extension/erfc.rb,
lib/distribution/math_extension/gammastar.rb,
lib/distribution/math_extension/gsl_utilities.rb,
lib/distribution/math_extension/log_utilities.rb,
lib/distribution/math_extension/incomplete_beta.rb,
lib/distribution/math_extension/chebyshev_series.rb,
lib/distribution/math_extension/incomplete_gamma.rb,
lib/distribution/math_extension/exponential_integral.rb
Overview
Useful additions to Math
Defined Under Namespace
Modules: ApproxFactorial, Beta, Erfc, ExponentialIntegral, Gammastar, IncompleteBeta, IncompleteGamma, Log Classes: ChebyshevSeries, SwingFactorial
Constant Summary collapse
- LNPI =
1.14472988584940017414342735135
- LN2 =
0.69314718055994530941723212146
- SQRT2 =
1.41421356237309504880168872421
- SQRTPI =
1.77245385090551602729816748334
- ROOT3_FLOAT_MIN =
Float::MIN ** (1/3.0)
- ROOT3_FLOAT_EPSILON =
Float::EPSILON ** (1/3.0)
- ROOT4_FLOAT_MIN =
Float::MIN ** (1/4.0)
- ROOT4_FLOAT_EPSILON =
Float::EPSILON ** (1/4.0)
- ROOT5_FLOAT_MIN =
Float::MIN ** (1/5.0)
- ROOT5_FLOAT_EPSILON =
Float::EPSILON ** (1/5.0)
- ROOT6_FLOAT_MIN =
Float::MIN ** (1/6.0)
- ROOT6_FLOAT_EPSILON =
Float::EPSILON ** (1/6.0)
- LOG_FLOAT_MIN =
Math.log(Float::MIN)
- EULER =
0.57721566490153286060651209008
Instance Method Summary collapse
-
#beta(x, y) ⇒ Object
Beta function.
-
#binomial_coefficient(n, k) ⇒ Object
(also: #combinations)
Binomial coeffients, or: ( n ) ( k ).
-
#binomial_coefficient_gamma(n, k) ⇒ Object
Approximate binomial coefficient, using gamma function.
-
#binomial_coefficient_multiplicative(n, k) ⇒ Object
Binomial coefficient using multiplicative algorithm On benchmarks, is faster that raising factorial method when k is little.
-
#erfc_e(x, with_error = false) ⇒ Object
Not the same as erfc.
-
#exact_regularized_beta(x, a, b) ⇒ Object
I_x(a,b): Regularized incomplete beta function TODO: Find a faster version.
-
#exp_err(x, dx) ⇒ Object
e^x taking into account the error thus far (I think) gsl_sf_exp_err_e.
-
#factorial(n) ⇒ Object
Exact factorial.
-
#fast_factorial(n) ⇒ Object
Approximate factorial, up to 16 digits Based of Luschy algorithm.
- #gammq(a, x, with_error = false) ⇒ Object
-
#incomplete_beta(x, a, b) ⇒ Object
Incomplete beta function: B(x;a,b)
a
andb
are parameters andx
is integration upper limit. - #incomplete_gamma(a, x = 0, with_error = false) ⇒ Object (also: #gammp)
-
#lbeta(x, y) ⇒ Object
Log beta function conforming to style of lgamma (returns sign in second array index).
-
#logbeta(x, y) ⇒ Object
Get pure-Ruby logbeta.
-
#loggamma(x) ⇒ Object
Ln of gamma.
-
#permutations(n, k) ⇒ Object
Sequences without repetition.
-
#regularized_beta(x, a, b) ⇒ Object
I_x(a,b): Regularized incomplete beta function Fast version.
-
#rising_factorial(x, n) ⇒ Object
Rising factorial.
- #unnormalized_incomplete_gamma(a, x, with_error = false) ⇒ Object
Instance Method Details
#beta(x, y) ⇒ Object
Beta function. Source:
220 221 222 |
# File 'lib/distribution/math_extension.rb', line 220 def beta(x,y) (gamma(x)*gamma(y)).quo(gamma(x+y)) end |
#binomial_coefficient(n, k) ⇒ Object Also known as: combinations
Binomial coeffients, or: ( n ) ( k )
Gives the number of different k size subsets of a set size n
Uses:
(n) n^k' (n)..(n-k+1)
( ) = ---- = ------------
(k) k! k!
313 314 315 316 317 318 319 320 321 |
# File 'lib/distribution/math_extension.rb', line 313 def binomial_coefficient(n,k) return 1 if (k==0 or k==n) k=[k, n-k].min permutations(n,k).quo(factorial(k)) # The factorial way is # factorial(n).quo(factorial(k)*(factorial(n-k))) # The multiplicative way is # (1..k).inject(1) {|ac, i| (ac*(n-k+i).quo(i))} end |
#binomial_coefficient_gamma(n, k) ⇒ Object
Approximate binomial coefficient, using gamma function. The fastest method, until we fall on BigDecimal!
333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 |
# File 'lib/distribution/math_extension.rb', line 333 def binomial_coefficient_gamma(n,k) return 1 if (k==0 or k==n) k=[k, n-k].min # First, we try direct gamma calculation for max precission val=gamma(n + 1).quo(gamma(k+1)*gamma(n-k+1)) # Ups. Outside float point range. We try with logs if (val.nan?) #puts "nan" lg=loggamma( n + 1 ) - (loggamma(k+1)+ loggamma(n-k+1)) val=Math.exp(lg) # Crash again! We require BigDecimals if val.infinite? #puts "infinite" val=BigMath.exp(BigDecimal(lg.to_s),16) end end val end |
#binomial_coefficient_multiplicative(n, k) ⇒ Object
Binomial coefficient using multiplicative algorithm On benchmarks, is faster that raising factorial method when k is little. Use only when you’re sure of that.
325 326 327 328 329 |
# File 'lib/distribution/math_extension.rb', line 325 def binomial_coefficient_multiplicative(n,k) return 1 if (k==0 or k==n) k=[k, n-k].min (1..k).inject(1) {|ac, i| (ac*(n-k+i).quo(i))} end |
#erfc_e(x, with_error = false) ⇒ Object
Not the same as erfc. This is the GSL version, which may have slightly different results.
287 288 289 |
# File 'lib/distribution/math_extension.rb', line 287 def erfc_e(x, with_error = false) Erfc.evaluate(x, with_error) end |
#exact_regularized_beta(x, a, b) ⇒ Object
I_x(a,b): Regularized incomplete beta function TODO: Find a faster version. Source:
245 246 247 248 249 250 251 252 253 |
# File 'lib/distribution/math_extension.rb', line 245 def exact_regularized_beta(x,a,b) return 1 if x==1 m=a.to_i n=(b+a-1).to_i (m..n).inject(0) {|sum,j| sum+(binomial_coefficient(n,j)* x**j * (1-x)**(n-j)) } end |
#exp_err(x, dx) ⇒ Object
e^x taking into account the error thus far (I think) gsl_sf_exp_err_e
24 25 26 27 28 29 |
# File 'lib/distribution/math_extension/gsl_utilities.rb', line 24 def exp_err(x, dx) adx = dx.abs raise("Overflow Error in exp_err: x + adx > LOG_FLOAT_MAX") if x + adx > LOG_FLOAT_MAX raise("Underflow Error in exp_err: x - adx < LOG_FLOAT_MIN") if x - adx < LOG_FLOAT_MIN [Math.exp(x), Math.exp(x) * [Float::EPSILON, Math.exp(adx) - 1.0/Math.exp(adx)] + 2.0 * Float::EPSILON * Math.exp(x).abs] end |
#factorial(n) ⇒ Object
Exact factorial. Use lookup on a Hash table on n<20 and Prime Swing algorithm for higher values.
208 209 210 |
# File 'lib/distribution/math_extension.rb', line 208 def factorial(n) SwingFactorial.new(n).result end |
#fast_factorial(n) ⇒ Object
Approximate factorial, up to 16 digits Based of Luschy algorithm
213 214 215 |
# File 'lib/distribution/math_extension.rb', line 213 def fast_factorial(n) ApproxFactorial.stieltjes_factorial(n) end |
#gammq(a, x, with_error = false) ⇒ Object
278 279 280 |
# File 'lib/distribution/math_extension.rb', line 278 def gammq(a, x, with_error = false) IncompleteGamma.q(a,x,with_error) end |
#incomplete_beta(x, a, b) ⇒ Object
Incomplete beta function: B(x;a,b) a
and b
are parameters and x
is integration upper limit.
258 259 260 261 |
# File 'lib/distribution/math_extension.rb', line 258 def incomplete_beta(x,a,b) IncompleteBeta.evaluate(a,b,x)*beta(a,b) #Math::IncompleteBeta.axpy(1.0, 0.0, a,b,x) end |
#incomplete_gamma(a, x = 0, with_error = false) ⇒ Object Also known as: gammp
273 274 275 |
# File 'lib/distribution/math_extension.rb', line 273 def incomplete_gamma(a, x = 0, with_error = false) IncompleteGamma.p(a,x, with_error) end |
#lbeta(x, y) ⇒ Object
Log beta function conforming to style of lgamma (returns sign in second array index)
230 231 232 |
# File 'lib/distribution/math_extension.rb', line 230 def lbeta(x,y) Beta.log_beta(x,y) end |
#logbeta(x, y) ⇒ Object
Get pure-Ruby logbeta
225 226 227 |
# File 'lib/distribution/math_extension.rb', line 225 def logbeta(x,y) Beta.log_beta(x,y).first end |
#loggamma(x) ⇒ Object
Ln of gamma
269 270 271 |
# File 'lib/distribution/math_extension.rb', line 269 def loggamma(x) Math.lgamma(x).first end |
#permutations(n, k) ⇒ Object
Sequences without repetition. n^k’ Also called ‘failing factorial’
293 294 295 296 297 298 299 |
# File 'lib/distribution/math_extension.rb', line 293 def permutations(n,k) return 1 if k==0 return n if k==1 return factorial(n) if k==n (((n-k+1)..n).inject(1) {|ac,v| ac * v}) #factorial(x).quo(factorial(x-n)) end |
#regularized_beta(x, a, b) ⇒ Object
I_x(a,b): Regularized incomplete beta function Fast version. For a exact calculation, based on factorial use exact_regularized_beta_function
237 238 239 240 |
# File 'lib/distribution/math_extension.rb', line 237 def regularized_beta(x,a,b) return 1 if x==1 IncompleteBeta.evaluate(a,b,x) end |
#rising_factorial(x, n) ⇒ Object
Rising factorial
264 265 266 |
# File 'lib/distribution/math_extension.rb', line 264 def rising_factorial(x,n) factorial(x+n-1).quo(factorial(x-1)) end |
#unnormalized_incomplete_gamma(a, x, with_error = false) ⇒ Object
282 283 284 |
# File 'lib/distribution/math_extension.rb', line 282 def unnormalized_incomplete_gamma(a, x, with_error = false) IncompleteGamma.unnormalized(a, x, with_error) end |