distribution 0.7.3 → 0.8.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.
- 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
|