distribution 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/.gemtest +0 -0
- data/History.txt +13 -1
- data/Manifest.txt +18 -0
- data/README.txt +3 -1
- data/Rakefile +5 -0
- data/lib/distribution.rb +6 -3
- data/lib/distribution/beta.rb +34 -0
- data/lib/distribution/beta/gsl.rb +24 -0
- data/lib/distribution/beta/java.rb +9 -0
- data/lib/distribution/beta/ruby.rb +42 -0
- data/lib/distribution/binomial.rb +1 -1
- data/lib/distribution/binomial/ruby.rb +3 -1
- data/lib/distribution/f.rb +1 -1
- data/lib/distribution/gamma.rb +37 -0
- data/lib/distribution/gamma/gsl.rb +24 -0
- data/lib/distribution/gamma/java.rb +9 -0
- data/lib/distribution/gamma/ruby.rb +53 -0
- data/lib/distribution/math_extension.rb +59 -13
- data/lib/distribution/math_extension/chebyshev_series.rb +411 -0
- data/lib/distribution/math_extension/erfc.rb +79 -0
- data/lib/distribution/math_extension/exponential_integral.rb +63 -0
- data/lib/distribution/math_extension/gammastar.rb +64 -0
- data/lib/distribution/math_extension/gsl_utilities.rb +31 -0
- data/lib/distribution/math_extension/incomplete_beta.rb +213 -0
- data/lib/distribution/math_extension/incomplete_gamma.rb +424 -0
- data/lib/distribution/math_extension/log_utilities.rb +80 -0
- data/lib/distribution/t/ruby.rb +2 -1
- data/spec/beta_spec.rb +82 -0
- data/spec/binomial_spec.rb +1 -1
- data/spec/gamma_spec.rb +85 -0
- data/spec/logistic_spec.rb +3 -3
- data/spec/math_extension_spec.rb +188 -13
- data/spec/t_spec.rb +13 -18
- metadata +24 -5
- metadata.gz.sig +0 -0
@@ -0,0 +1,80 @@
|
|
1
|
+
# Added by John O. Woods, SciRuby project.
|
2
|
+
# Derived from GSL-1.9 source files in the specfunc/ dir.
|
3
|
+
|
4
|
+
module Distribution
|
5
|
+
module MathExtension
|
6
|
+
# Various logarithm shortcuts, adapted from GSL-1.9.
|
7
|
+
module Log
|
8
|
+
C1 = -1.quo(2)
|
9
|
+
C2 = 1.quo(3)
|
10
|
+
C3 = -1.quo(4)
|
11
|
+
C4 = 1.quo(5)
|
12
|
+
C5 = -1.quo(6)
|
13
|
+
C6 = 1.quo(7)
|
14
|
+
C7 = -1.quo(8)
|
15
|
+
C8 = 1.quo(9)
|
16
|
+
C9 = -1.quo(10)
|
17
|
+
class << self
|
18
|
+
|
19
|
+
# gsl_log1p from GSL-1.9 sys/log1p.c
|
20
|
+
# log for very small x
|
21
|
+
def log1p x
|
22
|
+
# in C, this is volatile double y.
|
23
|
+
# Not sure how to reproduce that in Ruby.
|
24
|
+
y = 1+x
|
25
|
+
Math.log(y) - ((y-1)-x).quo(y) # cancel errors with IEEE arithmetic
|
26
|
+
end
|
27
|
+
|
28
|
+
# \log(1+x) for x > -1
|
29
|
+
# gsl_sf_log_1plusx_e
|
30
|
+
def log_1plusx(x, with_error = false)
|
31
|
+
raise(ArgumentError, "Range error: x must be > -1") if x <= -1
|
32
|
+
|
33
|
+
if x.abs < Math::ROOT6_FLOAT_EPSILON
|
34
|
+
result = x * (1.0 + x * (C1 + x*(C2 + x*(C3 + x*(C4 + x*begin
|
35
|
+
C5 + x*(C6 + x*(C7 + x*(C8 + x*C9))) # formerly t = this
|
36
|
+
end)))))
|
37
|
+
return with_error ? [result, Float::EPSILON * result.abs] : result
|
38
|
+
elsif x.abs < 0.5
|
39
|
+
c = ChebyshevSeries.evaluate(:lopx, (8*x + 1).quo(2*x+4), with_error)
|
40
|
+
return with_error ? [x * c.first, x * c.last] : x*c
|
41
|
+
else
|
42
|
+
result = Math.log(1+x)
|
43
|
+
return with_error ? [result, Float::EPSILON*result.abs] : result
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
# \log(1+x)-x for x > -1
|
49
|
+
# gsl_sf_log_1plusx_mx_e
|
50
|
+
def log_1plusx_minusx x, with_error = false
|
51
|
+
raise(ArgumentError, "Range error: x must be > -1") if x <= -1
|
52
|
+
|
53
|
+
if x.abs < Math::ROOT5_FLOAT_EPSILON
|
54
|
+
result = x*x * (C1 + x*(C2 + x*(C3 + x*(C4 + x*begin
|
55
|
+
C5 + x*(C6 + x*(C7 + x*(C8 + x*C9))) # formerly t = this
|
56
|
+
end))))
|
57
|
+
return with_error ? [result, Float::EPSILON * result.abs] : result
|
58
|
+
elsif x.abs < 0.5
|
59
|
+
c = ChebyshevSeries.evaluate(:lopxmx, (8*x + 1).quo(2*x+4), with_error)
|
60
|
+
return with_error ? [x*x * c.first, x*x * c.last] : x*x*c
|
61
|
+
else
|
62
|
+
lterm = Math.log(1.0+x)
|
63
|
+
error = Float::EPSILON * (lterm.abs + x.abs) if with_error
|
64
|
+
result = lterm - x
|
65
|
+
return with_error ? [result, error] : result
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
protected
|
70
|
+
|
71
|
+
# Abstracted from other log helper functions in GSL-1.9.
|
72
|
+
def x_less_than_root_epsilon x, with_error
|
73
|
+
result = square_x ? x*x : x
|
74
|
+
|
75
|
+
with_error ? [result, Float::EPSILON * result.abs] : result
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
data/lib/distribution/t/ruby.rb
CHANGED
@@ -15,7 +15,8 @@ module Distribution
|
|
15
15
|
# (-\infty, x]
|
16
16
|
def p_t(df, t)
|
17
17
|
if df.to_i!=df
|
18
|
-
|
18
|
+
x=(t+Math.sqrt(t**2+df)) / (2*Math.sqrt(t**2+df))
|
19
|
+
return Math.regularized_beta(x,df/2.0,df/2.0)
|
19
20
|
end
|
20
21
|
df=df.to_i
|
21
22
|
c2 = df.to_f / (df + t * t);
|
data/spec/beta_spec.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__)+"/spec_helper.rb")
|
2
|
+
include ExampleWithGSL
|
3
|
+
describe Distribution::Beta do
|
4
|
+
|
5
|
+
shared_examples_for "Beta engine" do
|
6
|
+
it_only_with_gsl "should return correct pdf" do
|
7
|
+
if @engine.respond_to? :pdf
|
8
|
+
1.upto(101) do |x|
|
9
|
+
a=rand * x
|
10
|
+
b=1 + rand * 5
|
11
|
+
g=GSL::Ran.beta_pdf(x,a,b)
|
12
|
+
@engine.pdf(x,a,b).should be_within(1e-10).of(g)
|
13
|
+
end
|
14
|
+
else
|
15
|
+
pending("No #{@engine}.pdf")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
it_only_with_gsl "should return correct cdf" do
|
20
|
+
if @engine.respond_to? :cdf
|
21
|
+
# From GSL-1.9.
|
22
|
+
TOL = 1048576.0*Float::EPSILON
|
23
|
+
@engine.cdf(0.0, 1.2, 1.3).should eq(0.0)
|
24
|
+
@engine.cdf(1e-100, 1.2, 1.3).should be_within(TOL).of(1.34434944656489596e-120)
|
25
|
+
@engine.cdf(0.001, 1.2, 1.3).should be_within(TOL).of(3.37630042504535813e-4)
|
26
|
+
@engine.cdf(0.01, 1.2, 1.3).should be_within(TOL).of(5.34317264038929473e-3)
|
27
|
+
@engine.cdf(0.1, 1.2, 1.3).should be_within(TOL).of(8.33997828306748346e-2)
|
28
|
+
@engine.cdf(0.325, 1.2, 1.3).should be_within(TOL).of(3.28698654180583916e-1)
|
29
|
+
@engine.cdf(0.5, 1.2, 1.3).should be_within(TOL).of(5.29781429451299081e-1)
|
30
|
+
@engine.cdf(0.9, 1.2, 1.3).should be_within(TOL).of(9.38529397224430659e-1)
|
31
|
+
@engine.cdf(0.99, 1.2, 1.3).should be_within(TOL).of(9.96886438341254380e-1)
|
32
|
+
@engine.cdf(0.999, 1.2, 1.3).should be_within(TOL).of(9.99843792833067634e-1)
|
33
|
+
@engine.cdf(1.0, 1.2, 1.3).should be_within(TOL).of(1.0)
|
34
|
+
else
|
35
|
+
pending("No #{@engine}.cdf")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
it "should return correct p_value" do
|
39
|
+
if @engine.respond_to? :p_value
|
40
|
+
2.upto(99) do |x|
|
41
|
+
a=rand() * x
|
42
|
+
b=1 + rand() * 5
|
43
|
+
pr=@engine.cdf(x/100.0,a,b)
|
44
|
+
@engine.p_value(pr,a, b).should be_within(1e-10).of(x/100.0)
|
45
|
+
end
|
46
|
+
else
|
47
|
+
pending("No #{@engine}.p_value")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "singleton" do
|
53
|
+
before do
|
54
|
+
@engine=Distribution::Beta
|
55
|
+
end
|
56
|
+
it_should_behave_like "Beta engine"
|
57
|
+
end
|
58
|
+
|
59
|
+
describe Distribution::Beta::Ruby_ do
|
60
|
+
before do
|
61
|
+
@engine=Distribution::Beta::Ruby_
|
62
|
+
end
|
63
|
+
it_should_behave_like "Beta engine"
|
64
|
+
end
|
65
|
+
if Distribution.has_gsl?
|
66
|
+
describe Distribution::Beta::GSL_ do
|
67
|
+
before do
|
68
|
+
@engine=Distribution::Beta::GSL_
|
69
|
+
end
|
70
|
+
it_should_behave_like "Beta engine"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
if Distribution.has_java?
|
74
|
+
describe Distribution::Beta::Java_ do
|
75
|
+
before do
|
76
|
+
@engine=Distribution::Beta::Java_
|
77
|
+
end
|
78
|
+
it_should_behave_like "Beta engine"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
data/spec/binomial_spec.rb
CHANGED
data/spec/gamma_spec.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__)+"/spec_helper.rb")
|
2
|
+
include ExampleWithGSL
|
3
|
+
describe Distribution::Gamma do
|
4
|
+
|
5
|
+
|
6
|
+
shared_examples_for "Gamma engine" do
|
7
|
+
it_only_with_gsl "should return correct pdf" do
|
8
|
+
if @engine.respond_to? :pdf
|
9
|
+
1.upto(101) do |x|
|
10
|
+
a=rand * x
|
11
|
+
b=1 + rand * 5
|
12
|
+
g=GSL::Ran.gamma_pdf(x,a,b)
|
13
|
+
@engine.pdf(x,a,b).should be_within(1e-10).of(g)
|
14
|
+
end
|
15
|
+
else
|
16
|
+
pending("No #{@engine}.pdf")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
it_only_with_gsl "should return correct cdf" do
|
20
|
+
if @engine.respond_to? :cdf
|
21
|
+
# From GSL-1.9.
|
22
|
+
TOL = 1048576.0*Float::EPSILON
|
23
|
+
@engine.cdf(0.0, 1.0, 1.0).should eq(0.0)
|
24
|
+
@engine.cdf(1e-100, 1.0, 1.0).should be_within(TOL).of(1e-100)
|
25
|
+
@engine.cdf(0.001, 1.0, 1.0).should be_within(TOL).of(9.99500166625008332e-4)
|
26
|
+
@engine.cdf(0.01, 1.0, 1.0).should be_within(TOL).of(9.95016625083194643e-3)
|
27
|
+
@engine.cdf(0.1, 1.0, 1.0).should be_within(TOL).of(9.51625819640404268e-2)
|
28
|
+
@engine.cdf(0.325, 1.0, 1.0).should be_within(TOL).of(2.77472646357927811e-1)
|
29
|
+
@engine.cdf(1.0, 1.0, 1.0).should be_within(TOL).of(6.32120558828557678e-1)
|
30
|
+
@engine.cdf(1.5, 1.0, 1.0).should be_within(TOL).of(7.76869839851570171e-1)
|
31
|
+
@engine.cdf(2.0, 1.0, 1.0).should be_within(TOL).of(8.64664716763387308e-1)
|
32
|
+
@engine.cdf(10.0, 1.0, 1.0).should be_within(TOL).of(9.99954600070237515e-1)
|
33
|
+
@engine.cdf(20.0, 1.0, 1.0).should be_within(TOL).of(9.99999997938846378e-1)
|
34
|
+
@engine.cdf(100.0, 1.0, 1.0).should be_within(TOL).of(1e0)
|
35
|
+
@engine.cdf(1000.0, 1.0, 1.0).should be_within(TOL).of(1e0)
|
36
|
+
@engine.cdf(10000.0, 1.0, 1.0).should be_within(TOL).of(1e0)
|
37
|
+
else
|
38
|
+
pending("No #{@engine}.cdf")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
it "should return correct p_value" do
|
42
|
+
if @engine.respond_to? :p_value
|
43
|
+
1.upto(20) do |x|
|
44
|
+
a=rand()*0.5
|
45
|
+
b=1 + rand() * 5
|
46
|
+
pr=@engine.cdf(x,a,b)
|
47
|
+
@engine.p_value(pr,a,b).should be_within(1e-3).of(x)
|
48
|
+
end
|
49
|
+
else
|
50
|
+
pending("No #{@engine}.p_value")
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "singleton" do
|
56
|
+
before do
|
57
|
+
@engine=Distribution::Gamma
|
58
|
+
end
|
59
|
+
it_should_behave_like "Gamma engine"
|
60
|
+
end
|
61
|
+
|
62
|
+
describe Distribution::Gamma::Ruby_ do
|
63
|
+
before do
|
64
|
+
@engine=Distribution::Gamma::Ruby_
|
65
|
+
end
|
66
|
+
it_should_behave_like "Gamma engine"
|
67
|
+
end
|
68
|
+
if Distribution.has_gsl?
|
69
|
+
describe Distribution::Gamma::GSL_ do
|
70
|
+
before do
|
71
|
+
@engine=Distribution::Gamma::GSL_
|
72
|
+
end
|
73
|
+
it_should_behave_like "Gamma engine"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
if Distribution.has_java?
|
77
|
+
describe Distribution::Gamma::Java_ do
|
78
|
+
before do
|
79
|
+
@engine=Distribution::Gamma::Java_
|
80
|
+
end
|
81
|
+
it_should_behave_like "Gamma engine"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
data/spec/logistic_spec.rb
CHANGED
@@ -9,12 +9,12 @@ describe Distribution::Logistic do
|
|
9
9
|
u=rand()
|
10
10
|
s=rand()+1
|
11
11
|
x=rand()*100-50
|
12
|
-
|
13
|
-
|
12
|
+
exp=Math.exp(-(x-u) / s) / (s*(1+Math.exp(-(x-u) / s)**2))
|
13
|
+
@engine.pdf(x,u,s).should eq(exp)
|
14
14
|
}
|
15
15
|
else
|
16
16
|
pending("No #{@engine}.pdf")
|
17
|
-
|
17
|
+
end
|
18
18
|
end
|
19
19
|
|
20
20
|
it "should return correct cdf" do
|
data/spec/math_extension_spec.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__)+"/spec_helper.rb")
|
2
|
+
include ExampleWithGSL
|
2
3
|
describe Distribution::MathExtension do
|
3
4
|
it "binomial coefficient should be correctly calculated" do
|
4
5
|
|
@@ -7,8 +8,186 @@ describe Distribution::MathExtension do
|
|
7
8
|
Math.binomial_coefficient(n,k).should eq(Math.factorial(n).quo(Math.factorial(k)*Math.factorial(n-k)))
|
8
9
|
end
|
9
10
|
end
|
11
|
+
|
12
|
+
it "ChebyshevSeries for :sin should return correct values" do
|
13
|
+
#Math::SIN_CS.evaluate()
|
14
|
+
end
|
15
|
+
|
16
|
+
it "log_1plusx_minusx should return correct values" do
|
17
|
+
# Tests from GSL-1.9
|
18
|
+
Math::Log.log_1plusx_minusx(1.0e-10).should be_within(1e-10).of(-4.999999999666666667e-21)
|
19
|
+
Math::Log.log_1plusx_minusx(1.0e-8).should be_within(1e-10).of(-4.999999966666666917e-17)
|
20
|
+
Math::Log.log_1plusx_minusx(1.0e-4).should be_within(1e-10).of(-4.999666691664666833e-09)
|
21
|
+
Math::Log.log_1plusx_minusx(0.1).should be_within(1e-10).of(-0.004689820195675139956)
|
22
|
+
Math::Log.log_1plusx_minusx(0.49).should be_within(1e-10).of(-0.09122388004263222704)
|
23
|
+
|
24
|
+
Math::Log.log_1plusx_minusx(-0.49).should be_within(1e-10).of(-0.18334455326376559639)
|
25
|
+
Math::Log.log_1plusx_minusx(1.0).should be_within(1e-10).of(Math::LN2 - 1.0)
|
26
|
+
Math::Log.log_1plusx_minusx(-0.99).should be_within(1e-10).of(-3.615170185988091368)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "log_1plusx should return correct values" do
|
30
|
+
# Tests from GSL-1.9
|
31
|
+
Math::Log.log_1plusx(1.0e-10).should be_within(1e-10).of(9.999999999500000000e-11)
|
32
|
+
Math::Log.log_1plusx(1.0e-8).should be_within(1e-10).of(9.999999950000000333e-09)
|
33
|
+
Math::Log.log_1plusx(1.0e-4).should be_within(1e-10).of(0.00009999500033330833533)
|
34
|
+
Math::Log.log_1plusx(0.1).should be_within(1e-10).of(0.09531017980432486004)
|
35
|
+
Math::Log.log_1plusx(0.49).should be_within(1e-10).of(0.3987761199573677730)
|
36
|
+
|
37
|
+
Math::Log.log_1plusx(-0.49).should be_within(1e-10).of(-0.6733445532637655964)
|
38
|
+
Math::Log.log_1plusx(1.0).should be_within(1e-10).of(Math::LN2)
|
39
|
+
Math::Log.log_1plusx(-0.99).should be_within(1e-10).of(-4.605170185988091368)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "log_beta should return correct values" do
|
43
|
+
Math::Beta.log_beta(1.0e-8, 1.0e-8).first.should be_within(1e-10).of(19.113827924512310617)
|
44
|
+
Math::Beta.log_beta(1.0e-8, 0.01).first.should be_within(1e-10).of(18.420681743788563403)
|
45
|
+
Math::Beta.log_beta(1.0e-8, 1.0).first.should be_within(1e-10).of(18.420680743952365472)
|
46
|
+
Math::Beta.log_beta(1.0e-8, 10.0).first.should be_within(1e-10).of(18.420680715662683009)
|
47
|
+
Math::Beta.log_beta(1.0e-8, 1000.0).first.should be_within(1e-10).of(18.420680669107656949)
|
48
|
+
Math::Beta.log_beta(0.1, 0.1).first.should be_within(1e-10).of(2.9813614810376273949)
|
49
|
+
Math::Beta.log_beta(0.1, 1.0).first.should be_within(1e-10).of(2.3025850929940456840)
|
50
|
+
Math::Beta.log_beta(0.1, 100.0).first.should be_within(1e-10).of(1.7926462324527931217)
|
51
|
+
Math::Beta.log_beta(0.1, 1000).first.should be_within(1e-10).of(1.5619821298353164928)
|
52
|
+
Math::Beta.log_beta(1.0, 1.00025).first.should be_within(1e-10).of(-0.0002499687552073570)
|
53
|
+
Math::Beta.log_beta(1.0, 1.01).first.should be_within(1e-10).of(-0.009950330853168082848)
|
54
|
+
Math::Beta.log_beta(1.0, 1000.0).first.should be_within(1e-10).of(-6.907755278982137052)
|
55
|
+
Math::Beta.log_beta(100.0, 100.0).first.should be_within(1e-10).of(-139.66525908670663927)
|
56
|
+
Math::Beta.log_beta(100.0, 1000.0).first.should be_within(1e-10).of(-336.4348576477366051)
|
57
|
+
Math::Beta.log_beta(100.0, 1.0e+8).first.should be_within(1e-10).of(-1482.9339185256447309)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "regularized_beta should return correct values" do
|
61
|
+
Math.regularized_beta(0.0,1.0, 1.0).should be_within(1e-10).of(0.0)
|
62
|
+
Math.regularized_beta(1.0, 1.0, 1.0).should be_within(1e-10).of(1.0)
|
63
|
+
Math.regularized_beta(1.0, 0.1, 0.1).should be_within(1e-10).of(1.0)
|
64
|
+
Math.regularized_beta(0.5, 1.0, 1.0).should be_within(1e-10).of(0.5)
|
65
|
+
Math.regularized_beta(0.5, 0.1, 1.0).should be_within(1e-10).of(0.9330329915368074160)
|
66
|
+
Math.regularized_beta(0.5, 10.0, 1.0).should be_within(1e-10).of(0.0009765625000000000000)
|
67
|
+
Math.regularized_beta(0.5, 50.0, 1.0).should be_within(1e-10).of(8.881784197001252323e-16)
|
68
|
+
Math.regularized_beta(0.5, 1.0, 0.1).should be_within(1e-10).of(0.06696700846319258402)
|
69
|
+
Math.regularized_beta(0.5, 1.0, 10.0).should be_within(1e-10).of(0.99902343750000000000)
|
70
|
+
Math.regularized_beta(0.5, 1.0, 50.0).should be_within(1e-10).of(0.99999999999999911180)
|
71
|
+
Math.regularized_beta(0.1, 1.0, 1.0).should be_within(1e-10).of(0.10)
|
72
|
+
Math.regularized_beta(0.1, 1.0, 2.0).should be_within(1e-10).of(0.19)
|
73
|
+
Math.regularized_beta(0.9, 1.0, 2.0).should be_within(1e-10).of(0.99)
|
74
|
+
Math.regularized_beta(0.5, 50.0, 60.0).should be_within(1e-10).of(0.8309072939016694143)
|
75
|
+
Math.regularized_beta(0.5, 90.0, 90.0).should be_within(1e-10).of(0.5)
|
76
|
+
Math.regularized_beta(0.5, 500.0, 500.0).should be_within(1e-10).of(0.5)
|
77
|
+
Math.regularized_beta(0.4, 5000.0, 5000.0).should be_within(1e-10).of(4.518543727260666383e-91)
|
78
|
+
Math.regularized_beta(0.6, 5000.0, 5000.0).should be_within(1e-10).of(1.0)
|
79
|
+
Math.regularized_beta(0.6, 5000.0, 2000.0).should be_within(1e-10).of(8.445388773903332659e-89)
|
80
|
+
end
|
81
|
+
it_only_with_gsl "incomplete_beta should return correct values" do
|
82
|
+
|
83
|
+
a=rand()*10+1
|
84
|
+
b=rand()*10+1
|
85
|
+
ib = GSL::Function.alloc { |t| t**(a-1)*(1-t)**(b-1)}
|
86
|
+
w = GSL::Integration::Workspace.alloc(1000)
|
87
|
+
1.upto(10) {|x|
|
88
|
+
inte=ib.qag([0,x / 10.0],w)
|
89
|
+
Math.incomplete_beta(x/10.0, a ,b).should be_within(1e-10).of(inte[0])
|
90
|
+
}
|
91
|
+
end
|
92
|
+
|
93
|
+
it "gammastar should return correct values" do
|
94
|
+
# Tests from GSL-1.9
|
95
|
+
Math::Gammastar.evaluate(1.0e-08).should be_within(1e-10).of(3989.423555759890865)
|
96
|
+
Math::Gammastar.evaluate(1.0e-05).should be_within(1e-10).of(126.17168469882690233)
|
97
|
+
Math::Gammastar.evaluate(0.001).should be_within(1e-10).of(12.708492464364073506)
|
98
|
+
Math::Gammastar.evaluate(1.5).should be_within(1e-10).of(1.0563442442685598666)
|
99
|
+
Math::Gammastar.evaluate(3.0).should be_within(1e-10).of(1.0280645179187893045)
|
100
|
+
Math::Gammastar.evaluate(9.0).should be_within(1e-10).of(1.0092984264218189715)
|
101
|
+
Math::Gammastar.evaluate(11.0).should be_within(1e-10).of(1.0076024283104962850)
|
102
|
+
Math::Gammastar.evaluate(100.0).should be_within(1e-10).of(1.0008336778720121418)
|
103
|
+
Math::Gammastar.evaluate(1.0e+05).should be_within(1e-10).of(1.0000008333336805529)
|
104
|
+
Math::Gammastar.evaluate(1.0e+20).should be_within(1e-10).of(1.0)
|
105
|
+
end
|
106
|
+
|
107
|
+
it "erfc_e should return correct values" do
|
108
|
+
# From GSL-1.9. For troubleshooting gammq.
|
109
|
+
Math::erfc_e(-10.0).should be_within(1e-10).of(2.0)
|
110
|
+
Math::erfc_e(-5.0000002).should be_within(1e-10).of(1.9999999999984625433)
|
111
|
+
Math::erfc_e(-5.0).should be_within(1e-10).of(1.9999999999984625402)
|
112
|
+
Math::erfc_e(-1.0).should be_within(1e-10).of(1.8427007929497148693)
|
113
|
+
Math::erfc_e(-0.5).should be_within(1e-10).of(1.5204998778130465377)
|
114
|
+
Math::erfc_e(1.0).should be_within(1e-10).of(0.15729920705028513066)
|
115
|
+
Math::erfc_e(3.0).should be_within(1e-10).of(0.000022090496998585441373)
|
116
|
+
Math::erfc_e(7.0).should be_within(1e-10).of(4.183825607779414399e-23)
|
117
|
+
Math::erfc_e(10.0).should be_within(1e-10).of(2.0884875837625447570e-45)
|
118
|
+
end
|
119
|
+
|
120
|
+
|
121
|
+
it "unnormalized_incomplete_gamma with x=0 should return correct values" do
|
122
|
+
Math.unnormalized_incomplete_gamma(-1.5, 0).should be_within(1e-10).of(4.0*Math.sqrt(Math::PI)/3.0)
|
123
|
+
Math.unnormalized_incomplete_gamma(-0.5, 0).should be_within(1e-10).of(-2*Math.sqrt(Math::PI))
|
124
|
+
Math.unnormalized_incomplete_gamma(0.5, 0).should be_within(1e-10).of(Math.sqrt(Math::PI))
|
125
|
+
Math.unnormalized_incomplete_gamma(1.0, 0).should eq 1.0
|
126
|
+
Math.unnormalized_incomplete_gamma(1.5, 0).should be_within(1e-10).of(Math.sqrt(Math::PI)/2.0)
|
127
|
+
Math.unnormalized_incomplete_gamma(2.0, 0).should eq 1.0
|
128
|
+
Math.unnormalized_incomplete_gamma(2.5, 0).should be_within(1e-10).of(0.75*Math.sqrt(Math::PI))
|
129
|
+
Math.unnormalized_incomplete_gamma(3.0, 0).should eq 2.0
|
130
|
+
Math.unnormalized_incomplete_gamma(3.5, 0).should be_within(1e-10).of(15.0*Math.sqrt(Math::PI) / 8.0)
|
131
|
+
Math.unnormalized_incomplete_gamma(4.0, 0).should eq 6.0
|
132
|
+
end
|
133
|
+
|
134
|
+
it "incomplete_gamma should return correct values" do
|
135
|
+
# Tests from GSL-1.9
|
136
|
+
Math.incomplete_gamma(1e-100, 0.001).should be_within(1e-10).of(1.0)
|
137
|
+
Math.incomplete_gamma(0.001, 0.001).should be_within(1e-10).of(0.9936876467088602902)
|
138
|
+
Math.incomplete_gamma(0.001, 1.0).should be_within(1e-10).of(0.9997803916424144436)
|
139
|
+
Math.incomplete_gamma(0.001, 10.0).should be_within(1e-10).of(0.9999999958306921828)
|
140
|
+
Math.incomplete_gamma(1.0, 0.001).should be_within(1e-10).of(0.0009995001666250083319)
|
141
|
+
Math.incomplete_gamma(1.0, 1.01).should be_within(1e-10).of(0.6357810204284766802)
|
142
|
+
Math.incomplete_gamma(1.0, 10.0).should be_within(1e-10).of(0.9999546000702375151)
|
143
|
+
Math.incomplete_gamma(10.0, 10.01).should be_within(1e-10).of(0.5433207586693410570)
|
144
|
+
Math.incomplete_gamma(10.0, 20.0).should be_within(1e-10).of(0.9950045876916924128)
|
145
|
+
Math.incomplete_gamma(1000.0, 1000.1).should be_within(1e-10).of(0.5054666401440661753)
|
146
|
+
Math.incomplete_gamma(1000.0, 2000.0).should be_within(1e-10).of(1.0)
|
147
|
+
|
148
|
+
# designed to trap the a-x=1 problem
|
149
|
+
# These next two are 1e-7 because they give the same output as GSL, but GSL is apparently not totally accurate here.
|
150
|
+
# It's a problem with log_1plusx_mx (log_1plusx_minusx in my code)
|
151
|
+
Math.incomplete_gamma(100, 99.0).should be_within(1e-7).of(0.4733043303994607)
|
152
|
+
Math.incomplete_gamma(200, 199.0).should be_within(1e-7).of(0.4811585880878718)
|
153
|
+
|
154
|
+
# Test for x86 cancellation problems
|
155
|
+
Math.incomplete_gamma(5670, 4574).should be_within(1e-10).of(3.063972328743934e-55)
|
156
|
+
end
|
157
|
+
|
158
|
+
it "gammq should return correct values" do
|
159
|
+
# Tests from GSL-1.9
|
160
|
+
Math.gammq(0.0, 0.001).should be_within(1e-10).of(0.0)
|
161
|
+
Math.gammq(0.001, 0.001).should be_within(1e-10).of(0.006312353291139709793)
|
162
|
+
Math.gammq(0.001, 1.0).should be_within(1e-10).of(0.00021960835758555639171)
|
163
|
+
Math.gammq(0.001, 2.0).should be_within(1e-10).of(0.00004897691783098147880)
|
164
|
+
Math.gammq(0.001, 5.0).should be_within(1e-10).of(1.1509813397308608541e-06)
|
165
|
+
Math.gammq(1.0, 0.001).should be_within(1e-10).of(0.9990004998333749917)
|
166
|
+
Math.gammq(1.0, 1.01).should be_within(1e-10).of(0.3642189795715233198)
|
167
|
+
Math.gammq(1.0, 10.0).should be_within(1e-10).of(0.00004539992976248485154)
|
168
|
+
Math.gammq(10.0, 10.01).should be_within(1e-10).of(0.4566792413306589430)
|
169
|
+
Math.gammq(10.0, 100.0).should be_within(1e-10).of(1.1253473960842733885e-31)
|
170
|
+
Math.gammq(1000.0, 1000.1).should be_within(1e-10).of(0.4945333598559338247)
|
171
|
+
Math.gammq(1000.0, 2000.0).should be_within(1e-10).of(6.847349459614753180e-136)
|
172
|
+
|
173
|
+
# designed to trap the a-x=1 problem
|
174
|
+
Math.gammq(100, 99.0).should be_within(1e-10).of(0.5266956696005394)
|
175
|
+
Math.gammq(200, 199.0).should be_within(1e-10).of(0.5188414119121281)
|
10
176
|
|
11
|
-
|
177
|
+
# Test for x86 cancellation problems
|
178
|
+
Math.gammq(5670, 4574).should be_within(1e-10).of(1.0000000000000000)
|
179
|
+
|
180
|
+
|
181
|
+
# test suggested by Michel Lespinasse [gsl-discuss Sat, 13 Nov 2004]
|
182
|
+
Math.gammq(1.0e+06-1.0, 1.0e+06-2.0).should be_within(1e-10).of(0.50026596175224547004)
|
183
|
+
|
184
|
+
# tests in asymptotic regime related to Lespinasse test
|
185
|
+
Math.gammq(1.0e+06+2.0, 1.0e+06+1.0).should be_within(1e-10).of(0.50026596135330304336)
|
186
|
+
Math.gammq(1.0e+06, 1.0e+06-2.0).should be_within(1e-10).of(0.50066490399940144811)
|
187
|
+
Math.gammq(1.0e+07, 1.0e+07-2.0).should be_within(1e-10).of(0.50021026104978614908)
|
188
|
+
end
|
189
|
+
|
190
|
+
|
12
191
|
it "rising_factorial should return correct values" do
|
13
192
|
|
14
193
|
x=rand(10)+1
|
@@ -30,24 +209,20 @@ describe Distribution::MathExtension do
|
|
30
209
|
Math.permutations(n,n).should eq(Math.factorial(n) / Math.factorial(n-n))
|
31
210
|
end
|
32
211
|
|
33
|
-
|
34
|
-
|
35
|
-
Math.incomplete_beta(0.5,5,6).should be_within(1e-6).of(Math.beta(5,6)*0.6230469)
|
36
|
-
Math.incomplete_beta(0.6,5,6).should be_within(1e-6).of(Math.beta(5,6)*0.0006617154)
|
37
|
-
end
|
38
|
-
it "regularized incomplete beta should behave properly" do
|
212
|
+
|
213
|
+
it "exact regularized incomplete beta should behave properly" do
|
39
214
|
|
40
|
-
Math.
|
41
|
-
Math.
|
42
|
-
Math.
|
215
|
+
Math.exact_regularized_beta(0.5,5,5).should be_within(1e-6).of(0.5)
|
216
|
+
Math.exact_regularized_beta(0.5,5,6).should be_within(1e-6).of(0.6230469)
|
217
|
+
Math.exact_regularized_beta(0.5,5,7).should be_within(1e-6).of(0.725586)
|
43
218
|
|
44
219
|
a=5
|
45
220
|
b=5
|
46
|
-
Math.
|
47
|
-
Math.
|
221
|
+
Math.exact_regularized_beta(0,a,b).should eq 0
|
222
|
+
Math.exact_regularized_beta(1,a,b).should eq 1
|
48
223
|
x=rand()
|
49
224
|
|
50
|
-
Math.
|
225
|
+
Math.exact_regularized_beta(x,a,b).should be_within(1e-6). of(1-Math.regularized_beta(1-x,b,a))
|
51
226
|
|
52
227
|
|
53
228
|
end
|