distribution 0.5.0 → 0.6.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.
- 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
|