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.
@@ -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
@@ -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
- raise "Can't calculate not integer df"
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);
@@ -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
@@ -1,5 +1,5 @@
1
1
  require File.expand_path(File.dirname(__FILE__)+"/spec_helper.rb")
2
-
2
+ include ExampleWithGSL
3
3
  describe Distribution::Binomial do
4
4
 
5
5
  shared_examples_for "binomial engine" do
@@ -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
@@ -9,12 +9,12 @@ describe Distribution::Logistic do
9
9
  u=rand()
10
10
  s=rand()+1
11
11
  x=rand()*100-50
12
- exp=Math.exp(-(x-u)/s)/(s*(1+Math.exp(-(x-u)/s)**2))
13
- @engine.pdf(x,u,s).should eq(exp)
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
- end
17
+ end
18
18
  end
19
19
 
20
20
  it "should return correct cdf" do
@@ -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
- it "incomplete beta function should return similar results to R" do
34
- pending("Not working yet")
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.regularized_beta_function(0.5,5,5).should eq 0.5
41
- Math.regularized_beta_function(0.5,5,6).should be_within(1e-6).of(0.6230469)
42
- Math.regularized_beta_function(0.5,5,7).should be_within(1e-6).of(0.725586)
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.regularized_beta_function(0,a,b).should eq 0
47
- Math.regularized_beta_function(1,a,b).should eq 1
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.regularized_beta_function(x,a,b).should be_within(1e-6). of(1-Math.regularized_beta_function(1-x,b,a))
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