distribution 0.5.0 → 0.6.0

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