distribution 0.7.3 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.travis.yml +4 -6
- data/.yardopts +5 -0
- data/History.txt +3 -0
- data/README.md +87 -44
- data/benchmark/binomial_coefficient.rb +19 -23
- data/benchmark/binomial_coefficient/experiment.rb +33 -36
- data/benchmark/factorial_hash.rb +7 -8
- data/benchmark/factorial_method.rb +4 -6
- data/benchmark/odd.rb +6 -7
- data/benchmark/power.rb +11 -11
- data/bin/distribution +26 -26
- data/distribution.gemspec +3 -4
- data/lib/distribution.rb +55 -96
- data/lib/distribution/beta/gsl.rb +10 -5
- data/lib/distribution/beta/ruby.rb +3 -1
- data/lib/distribution/binomial/ruby.rb +5 -2
- data/lib/distribution/bivariatenormal.rb +4 -5
- data/lib/distribution/bivariatenormal/gsl.rb +2 -2
- data/lib/distribution/bivariatenormal/java.rb +1 -1
- data/lib/distribution/bivariatenormal/ruby.rb +245 -254
- data/lib/distribution/chisquare.rb +8 -10
- data/lib/distribution/chisquare/gsl.rb +24 -19
- data/lib/distribution/chisquare/java.rb +1 -1
- data/lib/distribution/chisquare/ruby.rb +25 -25
- data/lib/distribution/chisquare/statistics2.rb +16 -13
- data/lib/distribution/distributable.rb +40 -0
- data/lib/distribution/exponential.rb +4 -5
- data/lib/distribution/exponential/gsl.rb +13 -9
- data/lib/distribution/exponential/ruby.rb +14 -9
- data/lib/distribution/f.rb +1 -1
- data/lib/distribution/f/gsl.rb +26 -22
- data/lib/distribution/f/java.rb +1 -1
- data/lib/distribution/f/ruby.rb +16 -19
- data/lib/distribution/f/statistics2.rb +22 -19
- data/lib/distribution/gamma.rb +5 -7
- data/lib/distribution/gamma/gsl.rb +13 -9
- data/lib/distribution/gamma/java.rb +1 -1
- data/lib/distribution/gamma/ruby.rb +5 -11
- data/lib/distribution/hypergeometric.rb +5 -8
- data/lib/distribution/hypergeometric/gsl.rb +4 -5
- data/lib/distribution/hypergeometric/java.rb +1 -1
- data/lib/distribution/hypergeometric/ruby.rb +34 -35
- data/lib/distribution/logistic.rb +5 -8
- data/lib/distribution/logistic/ruby.rb +13 -8
- data/lib/distribution/lognormal.rb +5 -7
- data/lib/distribution/lognormal/gsl.rb +8 -6
- data/lib/distribution/lognormal/ruby.rb +5 -9
- data/lib/distribution/math_extension.rb +6 -15
- data/lib/distribution/math_extension/chebyshev_series.rb +281 -272
- data/lib/distribution/math_extension/erfc.rb +26 -29
- data/lib/distribution/math_extension/exponential_integral.rb +17 -17
- data/lib/distribution/math_extension/gammastar.rb +19 -20
- data/lib/distribution/math_extension/gsl_utilities.rb +12 -12
- data/lib/distribution/math_extension/incomplete_beta.rb +52 -61
- data/lib/distribution/math_extension/incomplete_gamma.rb +166 -168
- data/lib/distribution/math_extension/log_utilities.rb +20 -22
- data/lib/distribution/normal.rb +11 -13
- data/lib/distribution/normal/gsl.rb +13 -10
- data/lib/distribution/normal/java.rb +14 -13
- data/lib/distribution/normal/ruby.rb +68 -58
- data/lib/distribution/normal/statistics2.rb +5 -2
- data/lib/distribution/normalmultivariate.rb +64 -64
- data/lib/distribution/poisson.rb +11 -13
- data/lib/distribution/poisson/gsl.rb +7 -7
- data/lib/distribution/poisson/java.rb +19 -24
- data/lib/distribution/poisson/ruby.rb +38 -9
- data/lib/distribution/shorthand.rb +17 -0
- data/lib/distribution/t.rb +13 -15
- data/lib/distribution/t/gsl.rb +27 -24
- data/lib/distribution/t/java.rb +1 -1
- data/lib/distribution/t/ruby.rb +99 -100
- data/lib/distribution/t/statistics2.rb +19 -19
- data/lib/distribution/uniform.rb +26 -0
- data/lib/distribution/uniform/gsl.rb +36 -0
- data/lib/distribution/uniform/ruby.rb +91 -0
- data/lib/distribution/version.rb +1 -1
- data/lib/distribution/weibull.rb +6 -7
- data/lib/distribution/weibull/gsl.rb +16 -16
- data/lib/distribution/weibull/ruby.rb +30 -23
- data/spec/beta_spec.rb +45 -47
- data/spec/binomial_spec.rb +77 -85
- data/spec/bivariatenormal_spec.rb +28 -35
- data/spec/chisquare_spec.rb +48 -52
- data/spec/distribution_spec.rb +10 -10
- data/spec/exponential_spec.rb +44 -49
- data/spec/f_spec.rb +4 -4
- data/spec/gamma_spec.rb +50 -53
- data/spec/hypergeometric_spec.rb +63 -69
- data/spec/logistic_spec.rb +32 -37
- data/spec/lognormal_spec.rb +25 -31
- data/spec/math_extension_spec.rb +192 -210
- data/spec/normal_spec.rb +80 -73
- data/spec/poisson_spec.rb +63 -41
- data/spec/shorthand_spec.rb +19 -22
- data/spec/spec_helper.rb +8 -9
- data/spec/t_spec.rb +63 -77
- data/spec/uniform_spec.rb +154 -0
- data/spec/weibull_spec.rb +13 -14
- metadata +17 -8
@@ -1,281 +1,272 @@
|
|
1
1
|
module Distribution
|
2
|
-
#
|
2
|
+
#
|
3
3
|
# Ruby version implements three methods on this module:
|
4
4
|
# * Genz:: Used by default, with improvement to calculate p on rho > 0.95
|
5
5
|
# * Hull:: Port from a C++ code
|
6
6
|
# * Jantaravareerat:: Iterative (slow and buggy)
|
7
|
-
#
|
8
|
-
|
7
|
+
#
|
8
|
+
|
9
9
|
module BivariateNormal
|
10
10
|
module Ruby_
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
# Normal cumulative distribution function (cdf) for a given x, y and rho.
|
50
|
-
# Based on Hull (1993, cited by Arne, 2003)
|
51
|
-
#
|
52
|
-
# References:
|
53
|
-
# * Arne, B.(2003). Financial Numerical Recipes in C ++. Available on http://finance.bi.no/~bernt/gcc_prog/recipes/recipes/node23.html
|
54
|
-
def cdf_hull(a,b,rho)
|
55
|
-
#puts "a:#{a} - b:#{b} - rho:#{rho}"
|
56
|
-
if (a<=0 and b<=0 and rho<=0)
|
57
|
-
# puts "ruta 1"
|
58
|
-
aprime=a.quo(Math::sqrt(2.0*(1.0-rho**2)))
|
59
|
-
bprime=b.quo(Math::sqrt(2.0*(1.0-rho**2)))
|
60
|
-
aa=[0.3253030, 0.4211071, 0.1334425, 0.006374323]
|
61
|
-
bb=[0.1337764, 0.6243247, 1.3425378, 2.2626645]
|
62
|
-
sum=0
|
63
|
-
4.times do |i|
|
64
|
-
4.times do |j|
|
65
|
-
sum+=aa[i]*aa[j] * f(bb[i], bb[j], aprime, bprime,rho)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
sum=sum*(Math::sqrt(1.0-rho**2).quo(Math::PI))
|
69
|
-
return sum
|
70
|
-
elsif(a*b*rho<=0.0)
|
71
|
-
|
72
|
-
#puts "ruta 2"
|
73
|
-
if(a<=0 and b>=0 and rho>=0)
|
74
|
-
return Distribution::Normal.cdf(a) - cdf(a,-b,-rho)
|
75
|
-
elsif (a>=0.0 and b<=0.0 and rho>=0)
|
76
|
-
return Distribution::Normal.cdf(b) - cdf(-a,b,-rho)
|
77
|
-
elsif (a>=0.0 and b>=0.0 and rho<=0)
|
78
|
-
return Distribution::Normal.cdf(a) + Distribution::Normal.cdf(b) - 1.0 + cdf(-a,-b,rho)
|
11
|
+
class << self
|
12
|
+
SIDE = 0.1 # :nodoc:
|
13
|
+
LIMIT = 5 # :nodoc:
|
14
|
+
# Return the partial derivative of cdf over x, with y and rho constant
|
15
|
+
# Reference:
|
16
|
+
# * Tallis, 1962, p.346, cited by Olsson, 1979
|
17
|
+
def partial_derivative_cdf_x(x, y, rho)
|
18
|
+
Distribution::Normal.pdf(x) * Distribution::Normal.cdf((y - rho * x).quo(Math.sqrt(1 - rho**2)))
|
19
|
+
end
|
20
|
+
alias_method :pd_cdf_x, :partial_derivative_cdf_x
|
21
|
+
# Probability density function for a given x, y and rho value.
|
22
|
+
#
|
23
|
+
# Source: http://en.wikipedia.org/wiki/Multivariate_normal_distribution
|
24
|
+
def pdf(x, y, rho, s1 = 1.0, s2 = 1.0)
|
25
|
+
1.quo(2 * Math::PI * s1 * s2 * Math.sqrt(1 - rho**2)) * (Math.exp(-(1.quo(2 * (1 - rho**2))) *
|
26
|
+
((x**2.quo(s1)) + (y**2.quo(s2)) - (2 * rho * x * y).quo(s1 * s2))))
|
27
|
+
end
|
28
|
+
|
29
|
+
def f(x, y, aprime, bprime, rho)
|
30
|
+
r = aprime * (2 * x - aprime) + bprime * (2 * y - bprime) + 2 * rho * (x - aprime) * (y - bprime)
|
31
|
+
Math.exp(r)
|
32
|
+
end
|
33
|
+
|
34
|
+
# CDF for a given x, y and rho value.
|
35
|
+
# Uses Genz algorithm (cdf_genz method).
|
36
|
+
#
|
37
|
+
def cdf(a, b, rho)
|
38
|
+
cdf_genz(a, b, rho)
|
39
|
+
end
|
40
|
+
|
41
|
+
def sgn(x)
|
42
|
+
if (x >= 0)
|
43
|
+
1
|
44
|
+
else
|
45
|
+
-1
|
79
46
|
end
|
80
|
-
elsif (a*b*rho>=0.0)
|
81
|
-
#puts "ruta 3"
|
82
|
-
denum=Math::sqrt(a**2 - 2*rho*a*b + b**2)
|
83
|
-
rho1=((rho*a-b)*sgn(a)).quo(denum)
|
84
|
-
rho2=((rho*b-a)*sgn(b)).quo(denum)
|
85
|
-
delta=(1.0-sgn(a)*sgn(b)).quo(4)
|
86
|
-
#puts "#{rho1} - #{rho2}"
|
87
|
-
return cdf(a, 0.0, rho1) + cdf(b, 0.0, rho2) - delta
|
88
47
|
end
|
89
|
-
raise "Should'nt be here! #{a} - #{b} #{rho}"
|
90
|
-
end
|
91
|
-
|
92
|
-
# CDF. Iterative method by Jantaravareerat (n/d)
|
93
|
-
#
|
94
|
-
# Reference:
|
95
|
-
# * Jantaravareerat, M. & Thomopoulos, N. (n/d). Tables for standard bivariate normal distribution
|
96
|
-
|
97
|
-
def cdf_jantaravareerat(x,y,rho,s1=1,s2=1)
|
98
|
-
# Special cases
|
99
|
-
return 1 if x>LIMIT and y>LIMIT
|
100
|
-
return 0 if x<-LIMIT or y<-LIMIT
|
101
|
-
return Distribution::Normal.cdf(y) if x>LIMIT
|
102
|
-
return Distribution::Normal.cdf(x) if y>LIMIT
|
103
|
-
|
104
|
-
#puts "x:#{x} - y:#{y}"
|
105
|
-
x=-LIMIT if x<-LIMIT
|
106
|
-
x=LIMIT if x>LIMIT
|
107
|
-
y=-LIMIT if y<-LIMIT
|
108
|
-
y=LIMIT if y>LIMIT
|
109
48
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
49
|
+
# Normal cumulative distribution function (cdf) for a given x, y and rho.
|
50
|
+
# Based on Hull (1993, cited by Arne, 2003)
|
51
|
+
#
|
52
|
+
# References:
|
53
|
+
# * Arne, B.(2003). Financial Numerical Recipes in C ++. Available on http://finance.bi.no/~bernt/gcc_prog/recipes/recipes/node23.html
|
54
|
+
def cdf_hull(a, b, rho)
|
55
|
+
# puts "a:#{a} - b:#{b} - rho:#{rho}"
|
56
|
+
if a <= 0 && b <= 0 && rho <= 0
|
57
|
+
# puts "ruta 1"
|
58
|
+
aprime = a.quo(Math.sqrt(2.0 * (1.0 - rho**2)))
|
59
|
+
bprime = b.quo(Math.sqrt(2.0 * (1.0 - rho**2)))
|
60
|
+
aa = [0.3253030, 0.4211071, 0.1334425, 0.006374323]
|
61
|
+
bb = [0.1337764, 0.6243247, 1.3425378, 2.2626645]
|
62
|
+
sum = 0
|
63
|
+
4.times do |i|
|
64
|
+
4.times do |j|
|
65
|
+
sum += aa[i] * aa[j] * f(bb[i], bb[j], aprime, bprime, rho)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
sum *= (Math.sqrt(1.0 - rho**2).quo(Math::PI))
|
69
|
+
return sum
|
70
|
+
elsif (a * b * rho <= 0.0)
|
71
|
+
|
72
|
+
# puts "ruta 2"
|
73
|
+
if a <= 0 && b >= 0 && rho >= 0
|
74
|
+
return Distribution::Normal.cdf(a) - cdf(a, -b, -rho)
|
75
|
+
elsif a >= 0.0 && b <= 0.0 && rho >= 0
|
76
|
+
return Distribution::Normal.cdf(b) - cdf(-a, b, -rho)
|
77
|
+
elsif a >= 0.0 && b >= 0.0 && rho <= 0
|
78
|
+
return Distribution::Normal.cdf(a) + Distribution::Normal.cdf(b) - 1.0 + cdf(-a, -b, rho)
|
79
|
+
end
|
80
|
+
elsif (a * b * rho >= 0.0)
|
81
|
+
# puts "ruta 3"
|
82
|
+
denum = Math.sqrt(a**2 - 2 * rho * a * b + b**2)
|
83
|
+
rho1 = ((rho * a - b) * sgn(a)).quo(denum)
|
84
|
+
rho2 = ((rho * b - a) * sgn(b)).quo(denum)
|
85
|
+
delta = (1.0 - sgn(a) * sgn(b)).quo(4)
|
86
|
+
# puts "#{rho1} - #{rho2}"
|
87
|
+
return cdf(a, 0.0, rho1) + cdf(b, 0.0, rho2) - delta
|
120
88
|
end
|
89
|
+
fail "Should'nt be here! #{a} - #{b} #{rho}"
|
121
90
|
end
|
122
|
-
sum
|
123
|
-
end
|
124
|
-
# Normal cumulative distribution function (cdf) for a given x, y and rho.
|
125
|
-
# Ported from Fortran code by Alan Genz
|
126
|
-
#
|
127
|
-
# Original documentation
|
128
|
-
# DOUBLE PRECISION FUNCTION BVND( DH, DK, R )
|
129
|
-
# A function for computing bivariate normal probabilities.
|
130
|
-
#
|
131
|
-
# Alan Genz
|
132
|
-
# Department of Mathematics
|
133
|
-
# Washington State University
|
134
|
-
# Pullman, WA 99164-3113
|
135
|
-
# Email : alangenz_AT_wsu.edu
|
136
|
-
#
|
137
|
-
# This function is based on the method described by
|
138
|
-
# Drezner, Z and G.O. Wesolowsky, (1989),
|
139
|
-
# On the computation of the bivariate normal integral,
|
140
|
-
# Journal of Statist. Comput. Simul. 35, pp. 101-107,
|
141
|
-
# with major modifications for double precision, and for |R| close to 1.
|
142
|
-
#
|
143
|
-
# Original location:
|
144
|
-
# * http://www.math.wsu.edu/faculty/genz/software/fort77/tvpack.f
|
145
|
-
def cdf_genz(x,y,rho)
|
146
|
-
dh=-x
|
147
|
-
dk=-y
|
148
|
-
r=rho
|
149
|
-
twopi = 6.283185307179586
|
150
|
-
|
151
|
-
w=11.times.collect {[nil]*4};
|
152
|
-
x=11.times.collect {[nil]*4}
|
153
|
-
|
154
|
-
data=[
|
155
|
-
0.1713244923791705E+00, -0.9324695142031522E+00,
|
156
|
-
0.3607615730481384E+00, -0.6612093864662647E+00,
|
157
|
-
0.4679139345726904E+00, -0.2386191860831970E+00]
|
158
|
-
|
159
|
-
(1..3).each {|i|
|
160
|
-
w[i][1]=data[(i-1)*2]
|
161
|
-
x[i][1]=data[(i-1)*2+1]
|
162
|
-
|
163
|
-
}
|
164
|
-
data=[
|
165
|
-
0.4717533638651177E-01,-0.9815606342467191E+00,
|
166
|
-
0.1069393259953183E+00,-0.9041172563704750E+00,
|
167
|
-
0.1600783285433464E+00,-0.7699026741943050E+00,
|
168
|
-
0.2031674267230659E+00,-0.5873179542866171E+00,
|
169
|
-
0.2334925365383547E+00,-0.3678314989981802E+00,
|
170
|
-
0.2491470458134029E+00,-0.1252334085114692E+00]
|
171
|
-
(1..6).each {|i|
|
172
|
-
w[i][2]=data[(i-1)*2]
|
173
|
-
x[i][2]=data[(i-1)*2+1]
|
174
91
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
0.4060142980038694E-01,-0.9639719272779138E+00,
|
180
|
-
0.6267204833410906E-01,-0.9122344282513259E+00,
|
181
|
-
0.8327674157670475E-01,-0.8391169718222188E+00,
|
182
|
-
0.1019301198172404E+00,-0.7463319064601508E+00,
|
183
|
-
0.1181945319615184E+00,-0.6360536807265150E+00,
|
184
|
-
0.1316886384491766E+00,-0.5108670019508271E+00,
|
185
|
-
0.1420961093183821E+00,-0.3737060887154196E+00,
|
186
|
-
0.1491729864726037E+00,-0.2277858511416451E+00,
|
187
|
-
0.1527533871307259E+00,-0.7652652113349733E-01]
|
188
|
-
|
189
|
-
(1..10).each {|i|
|
190
|
-
w[i][3]=data[(i-1)*2]
|
191
|
-
x[i][3]=data[(i-1)*2+1]
|
92
|
+
# CDF. Iterative method by Jantaravareerat (n/d)
|
93
|
+
#
|
94
|
+
# Reference:
|
95
|
+
# * Jantaravareerat, M. & Thomopoulos, N. (n/d). Tables for standard bivariate normal distribution
|
192
96
|
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
97
|
+
def cdf_jantaravareerat(x, y, rho, s1 = 1, s2 = 1)
|
98
|
+
# Special cases
|
99
|
+
return 1 if x > LIMIT && y > LIMIT
|
100
|
+
return 0 if x < -LIMIT || y < -LIMIT
|
101
|
+
return Distribution::Normal.cdf(y) if x > LIMIT
|
102
|
+
return Distribution::Normal.cdf(x) if y > LIMIT
|
103
|
+
|
104
|
+
# puts "x:#{x} - y:#{y}"
|
105
|
+
x = -LIMIT if x < -LIMIT
|
106
|
+
x = LIMIT if x > LIMIT
|
107
|
+
y = -LIMIT if y < -LIMIT
|
108
|
+
y = LIMIT if y > LIMIT
|
109
|
+
|
110
|
+
x_squares = ((LIMIT + x) / SIDE).to_i
|
111
|
+
y_squares = ((LIMIT + y) / SIDE).to_i
|
112
|
+
sum = 0
|
113
|
+
x_squares.times do |i|
|
114
|
+
y_squares.times do |j|
|
115
|
+
z1 = -LIMIT + (i + 1) * SIDE
|
116
|
+
z2 = -LIMIT + (j + 1) * SIDE
|
117
|
+
# puts " #{z1}-#{z2}"
|
118
|
+
h = (pdf(z1, z2, rho, s1, s2) + pdf(z1 - SIDE, z2, rho, s1, s2) + pdf(z1, z2 - SIDE, rho, s1, s2) + pdf(z1 - SIDE, z2 - SIDE, rho, s1, s2)).quo(4)
|
119
|
+
sum += (SIDE**2) * h # area
|
120
|
+
end
|
121
|
+
end
|
122
|
+
sum
|
206
123
|
end
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
124
|
+
# Normal cumulative distribution function (cdf) for a given x, y and rho.
|
125
|
+
# Ported from Fortran code by Alan Genz
|
126
|
+
#
|
127
|
+
# Original documentation
|
128
|
+
# DOUBLE PRECISION FUNCTION BVND( DH, DK, R )
|
129
|
+
# A function for computing bivariate normal probabilities.
|
130
|
+
#
|
131
|
+
# Alan Genz
|
132
|
+
# Department of Mathematics
|
133
|
+
# Washington State University
|
134
|
+
# Pullman, WA 99164-3113
|
135
|
+
# Email : alangenz_AT_wsu.edu
|
136
|
+
#
|
137
|
+
# This function is based on the method described by
|
138
|
+
# Drezner, Z and G.O. Wesolowsky, (1989),
|
139
|
+
# On the computation of the bivariate normal integral,
|
140
|
+
# Journal of Statist. Comput. Simul. 35, pp. 101-107,
|
141
|
+
# with major modifications for double precision, and for |R| close to 1.
|
142
|
+
#
|
143
|
+
# Original location:
|
144
|
+
# * http://www.math.wsu.edu/faculty/genz/software/fort77/tvpack.f
|
145
|
+
def cdf_genz(x, y, rho)
|
146
|
+
dh = -x
|
147
|
+
dk = -y
|
148
|
+
r = rho
|
149
|
+
twopi = 6.283185307179586
|
150
|
+
|
151
|
+
w = 11.times.collect { [nil] * 4 }
|
152
|
+
x = 11.times.collect { [nil] * 4 }
|
153
|
+
|
154
|
+
data = [
|
155
|
+
0.1713244923791705E+00, -0.9324695142031522E+00,
|
156
|
+
0.3607615730481384E+00, -0.6612093864662647E+00,
|
157
|
+
0.4679139345726904E+00, -0.2386191860831970E+00]
|
158
|
+
|
159
|
+
(1..3).each do|i|
|
160
|
+
w[i][1] = data[(i - 1) * 2]
|
161
|
+
x[i][1] = data[(i - 1) * 2 + 1]
|
232
162
|
end
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
163
|
+
data = [
|
164
|
+
0.4717533638651177E-01, -0.9815606342467191E+00,
|
165
|
+
0.1069393259953183E+00, -0.9041172563704750E+00,
|
166
|
+
0.1600783285433464E+00, -0.7699026741943050E+00,
|
167
|
+
0.2031674267230659E+00, -0.5873179542866171E+00,
|
168
|
+
0.2334925365383547E+00, -0.3678314989981802E+00,
|
169
|
+
0.2491470458134029E+00, -0.1252334085114692E+00]
|
170
|
+
(1..6).each do|i|
|
171
|
+
w[i][2] = data[(i - 1) * 2]
|
172
|
+
x[i][2] = data[(i - 1) * 2 + 1]
|
173
|
+
end
|
174
|
+
data = [
|
175
|
+
0.1761400713915212E-01, -0.9931285991850949E+00,
|
176
|
+
0.4060142980038694E-01, -0.9639719272779138E+00,
|
177
|
+
0.6267204833410906E-01, -0.9122344282513259E+00,
|
178
|
+
0.8327674157670475E-01, -0.8391169718222188E+00,
|
179
|
+
0.1019301198172404E+00, -0.7463319064601508E+00,
|
180
|
+
0.1181945319615184E+00, -0.6360536807265150E+00,
|
181
|
+
0.1316886384491766E+00, -0.5108670019508271E+00,
|
182
|
+
0.1420961093183821E+00, -0.3737060887154196E+00,
|
183
|
+
0.1491729864726037E+00, -0.2277858511416451E+00,
|
184
|
+
0.1527533871307259E+00, -0.7652652113349733E-01]
|
185
|
+
|
186
|
+
(1..10).each do|i|
|
187
|
+
w[i][3] = data[(i - 1) * 2]
|
188
|
+
x[i][3] = data[(i - 1) * 2 + 1]
|
189
|
+
end
|
190
|
+
|
191
|
+
if r.abs < 0.3
|
192
|
+
ng = 1
|
193
|
+
lg = 3
|
194
|
+
elsif r.abs < 0.75
|
195
|
+
ng = 2
|
196
|
+
lg = 6
|
197
|
+
else
|
198
|
+
ng = 3
|
199
|
+
lg = 10
|
200
|
+
end
|
201
|
+
|
202
|
+
h = dh
|
203
|
+
k = dk
|
204
|
+
hk = h * k
|
205
|
+
bvn = 0
|
206
|
+
if r.abs < 0.925
|
207
|
+
if r.abs > 0
|
208
|
+
hs = (h * h + k * k).quo(2)
|
209
|
+
asr = Math.asin(r)
|
210
|
+
(1..lg).each do |i|
|
211
|
+
[-1, 1].each do |is|
|
212
|
+
sn = Math.sin(asr * (is * x[i][ng] + 1).quo(2))
|
213
|
+
bvn += w[i][ng] * Math.exp((sn * hk - hs).quo(1 - sn * sn))
|
214
|
+
end # do
|
215
|
+
end # do
|
216
|
+
bvn *= asr.quo(2 * twopi)
|
217
|
+
end # if
|
218
|
+
bvn += Distribution::Normal.cdf(-h) * Distribution::Normal.cdf(-k)
|
219
|
+
|
220
|
+
else # r.abs
|
221
|
+
if r < 0
|
222
|
+
k = -k
|
223
|
+
hk = -hk
|
248
224
|
end
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
225
|
+
|
226
|
+
if r.abs < 1
|
227
|
+
as = (1 - r) * (1 + r)
|
228
|
+
a = Math.sqrt(as)
|
229
|
+
bs = (h - k)**2
|
230
|
+
c = (4 - hk).quo(8)
|
231
|
+
d = (12 - hk).quo(16)
|
232
|
+
asr = -(bs.quo(as) + hk).quo(2)
|
233
|
+
if asr > -100
|
234
|
+
bvn = a * Math.exp(asr) * (1 - c * (bs - as) * (1 - d * bs.quo(5)).quo(3) + c * d * as * as.quo(5))
|
235
|
+
end
|
236
|
+
if -hk < 100
|
237
|
+
b = Math.sqrt(bs)
|
238
|
+
bvn -= Math.exp(-hk.quo(2)) * Math.sqrt(twopi) * Distribution::Normal.cdf(-b.quo(a)) * b *
|
239
|
+
(1 - c * bs * (1 - d * bs.quo(5)).quo(3))
|
240
|
+
end
|
241
|
+
|
242
|
+
a = a.quo(2)
|
243
|
+
(1..lg).each do |i|
|
244
|
+
[-1, 1].each do |is|
|
245
|
+
xs = (a * (is * x[i][ng] + 1))**2
|
246
|
+
rs = Math.sqrt(1 - xs)
|
247
|
+
asr = -(bs / xs + hk).quo(2)
|
248
|
+
if asr > -100
|
249
|
+
bvn += a * w[i][ng] * Math.exp(asr) *
|
250
|
+
(Math.exp(-hk * (1 - rs).quo(2 * (1 + rs))) .quo(rs) - (1 + c * xs * (1 + d * xs)))
|
251
|
+
end
|
260
252
|
end
|
261
253
|
end
|
254
|
+
bvn = -bvn / twopi
|
262
255
|
end
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
bvn = bvn + Distribution::Normal.cdf(k) - Distribution::Normal.cdf(h)
|
256
|
+
|
257
|
+
if r > 0
|
258
|
+
bvn += Distribution::Normal.cdf(-[h, k].max)
|
259
|
+
else
|
260
|
+
bvn = -bvn
|
261
|
+
if k > h
|
262
|
+
bvn = bvn + Distribution::Normal.cdf(k) - Distribution::Normal.cdf(h)
|
263
|
+
end
|
272
264
|
end
|
273
265
|
end
|
266
|
+
bvn
|
274
267
|
end
|
275
|
-
|
268
|
+
private :f, :sgn
|
276
269
|
end
|
277
|
-
private :f, :sgn
|
278
|
-
end
|
279
270
|
end
|
280
271
|
end
|
281
272
|
end
|