distribution 0.6.0 → 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 +7 -0
- data/.gitignore +7 -0
- data/.travis.yml +13 -0
- data/.yardopts +5 -0
- data/Gemfile +5 -0
- data/History.txt +24 -8
- data/LICENCE.md +26 -0
- data/README.md +155 -0
- data/Rakefile +15 -19
- 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/data/template/spec.erb +7 -6
- data/distribution.gemspec +25 -0
- data/lib/distribution.rb +79 -124
- data/lib/distribution/beta.rb +6 -8
- data/lib/distribution/beta/gsl.rb +14 -9
- data/lib/distribution/beta/java.rb +1 -1
- data/lib/distribution/beta/ruby.rb +41 -7
- data/lib/distribution/binomial.rb +10 -11
- data/lib/distribution/binomial/gsl.rb +6 -5
- data/lib/distribution/binomial/java.rb +1 -1
- data/lib/distribution/binomial/ruby.rb +22 -15
- 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 +60 -55
- 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 +17 -11
- data/lib/distribution/f.rb +10 -11
- data/lib/distribution/f/gsl.rb +26 -22
- data/lib/distribution/f/java.rb +1 -1
- data/lib/distribution/f/ruby.rb +104 -105
- 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 +5 -6
- data/lib/distribution/hypergeometric/java.rb +1 -1
- data/lib/distribution/hypergeometric/ruby.rb +34 -35
- data/lib/distribution/logistic.rb +6 -9
- data/lib/distribution/logistic/ruby.rb +14 -9
- data/lib/distribution/lognormal.rb +37 -0
- data/lib/distribution/lognormal/gsl.rb +21 -0
- data/lib/distribution/lognormal/ruby.rb +16 -0
- data/lib/distribution/math_extension.rb +187 -231
- data/lib/distribution/math_extension/chebyshev_series.rb +281 -272
- data/lib/distribution/math_extension/erfc.rb +28 -31
- 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 +30 -1
- data/lib/distribution/normal/ruby.rb +69 -59
- data/lib/distribution/normal/statistics2.rb +5 -2
- data/lib/distribution/normalmultivariate.rb +64 -64
- data/lib/distribution/poisson.rb +12 -14
- data/lib/distribution/poisson/gsl.rb +7 -7
- data/lib/distribution/poisson/java.rb +26 -0
- data/lib/distribution/poisson/ruby.rb +38 -9
- data/lib/distribution/shorthand.rb +17 -0
- data/lib/distribution/t.rb +16 -16
- 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 +3 -0
- data/lib/distribution/weibull.rb +10 -0
- data/lib/distribution/weibull/gsl.rb +21 -0
- data/lib/distribution/weibull/ruby.rb +34 -0
- data/spec/beta_spec.rb +48 -50
- data/spec/binomial_spec.rb +80 -84
- data/spec/bivariatenormal_spec.rb +28 -35
- data/spec/chisquare_spec.rb +49 -52
- data/spec/distribution_spec.rb +11 -11
- data/spec/exponential_spec.rb +48 -39
- data/spec/f_spec.rb +73 -71
- data/spec/gamma_spec.rb +50 -53
- data/spec/hypergeometric_spec.rb +63 -69
- data/spec/logistic_spec.rb +31 -37
- data/spec/lognormal_spec.rb +54 -0
- data/spec/math_extension_spec.rb +192 -209
- data/spec/normal_spec.rb +80 -73
- data/spec/poisson_spec.rb +78 -36
- data/spec/shorthand_spec.rb +19 -22
- data/spec/spec_helper.rb +31 -6
- data/spec/t_spec.rb +63 -77
- data/spec/uniform_spec.rb +154 -0
- data/spec/weibull_spec.rb +17 -0
- data/vendor/java/commons-math-2.2.jar +0 -0
- metadata +91 -111
- data.tar.gz.sig +0 -0
- data/.autotest +0 -23
- data/.gemtest +0 -0
- data/Manifest.txt +0 -95
- data/README.txt +0 -100
- metadata.gz.sig +0 -0
data/lib/distribution/beta.rb
CHANGED
|
@@ -5,22 +5,21 @@ require 'distribution/beta/java'
|
|
|
5
5
|
|
|
6
6
|
module Distribution
|
|
7
7
|
# From Wikipedia:
|
|
8
|
-
# In probability theory and statistics, the beta distribution
|
|
9
|
-
# is a family of continuous probability distributions defined
|
|
10
|
-
# on the interval (0, 1) parameterized by two positive shape
|
|
11
|
-
# parameters, typically denoted by alpha and beta.
|
|
8
|
+
# In probability theory and statistics, the beta distribution
|
|
9
|
+
# is a family of continuous probability distributions defined
|
|
10
|
+
# on the interval (0, 1) parameterized by two positive shape
|
|
11
|
+
# parameters, typically denoted by alpha and beta.
|
|
12
12
|
# This module calculate cdf and inverse cdf for Beta Distribution.
|
|
13
13
|
#
|
|
14
14
|
module Beta
|
|
15
15
|
extend Distributable
|
|
16
|
-
SHORTHAND='beta'
|
|
16
|
+
SHORTHAND = 'beta'
|
|
17
17
|
create_distribution_methods
|
|
18
18
|
|
|
19
19
|
##
|
|
20
20
|
# :singleton-method: pdf(x,a,b)
|
|
21
21
|
# Returns PDF of of Beta distribution with parameters a and b
|
|
22
22
|
|
|
23
|
-
|
|
24
23
|
##
|
|
25
24
|
# :singleton-method: cdf(x,a,b)
|
|
26
25
|
# Returns the integral of Beta distribution with parameters a and b
|
|
@@ -28,7 +27,6 @@ module Distribution
|
|
|
28
27
|
##
|
|
29
28
|
# :singleton-method: p_value(qn,a,b)
|
|
30
29
|
# Return the quantile of the corresponding integral +qn+
|
|
31
|
-
# on a beta distribution's cdf with parameters a and b
|
|
32
|
-
|
|
30
|
+
# on a beta distribution's cdf with parameters a and b
|
|
33
31
|
end
|
|
34
32
|
end
|
|
@@ -2,22 +2,27 @@ module Distribution
|
|
|
2
2
|
module Beta
|
|
3
3
|
module GSL_
|
|
4
4
|
class << self
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
# Return the P-value of the corresponding integral with
|
|
9
|
-
# k degrees of freedom
|
|
10
|
-
def p_value(pr,a,b)
|
|
11
|
-
GSL::Cdf::beta_Pinv(pr.to_f, a.to_f, b.to_f)
|
|
5
|
+
# PDF.
|
|
6
|
+
def pdf(x, a, b)
|
|
7
|
+
GSL::Ran.beta_pdf(x.to_f, a.to_f, b.to_f)
|
|
12
8
|
end
|
|
9
|
+
|
|
13
10
|
# Beta cumulative distribution function (cdf).
|
|
14
11
|
#
|
|
15
12
|
# Returns the integral of Beta distribution
|
|
16
13
|
# with parameters +a+ and +b+ over [0, x]
|
|
17
14
|
#
|
|
18
|
-
def cdf(x,a,b)
|
|
19
|
-
GSL::Cdf
|
|
15
|
+
def cdf(x, a, b)
|
|
16
|
+
GSL::Cdf.beta_P(x.to_f, a.to_f, b.to_f)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Return the P-value of the corresponding integral with
|
|
20
|
+
# k degrees of freedom
|
|
21
|
+
def quantile(pr, a, b)
|
|
22
|
+
GSL::Cdf.beta_Pinv(pr.to_f, a.to_f, b.to_f)
|
|
20
23
|
end
|
|
24
|
+
|
|
25
|
+
alias_method :p_value, :quantile
|
|
21
26
|
end
|
|
22
27
|
end
|
|
23
28
|
end
|
|
@@ -3,7 +3,6 @@ module Distribution
|
|
|
3
3
|
module Beta
|
|
4
4
|
module Ruby_
|
|
5
5
|
class << self
|
|
6
|
-
|
|
7
6
|
include Math
|
|
8
7
|
# Beta distribution probability density function
|
|
9
8
|
#
|
|
@@ -13,29 +12,64 @@ module Distribution
|
|
|
13
12
|
#
|
|
14
13
|
# == References
|
|
15
14
|
# * http://www.gnu.org/s/gsl/manual/html_node/The-Gamma-Distribution.html
|
|
16
|
-
def pdf(x,a,b)
|
|
15
|
+
def pdf(x, a, b)
|
|
17
16
|
return 0 if x < 0 || x > 1
|
|
18
17
|
|
|
19
|
-
gab = Math.lgamma(a+b).first
|
|
18
|
+
gab = Math.lgamma(a + b).first
|
|
20
19
|
ga = Math.lgamma(a).first
|
|
21
20
|
gb = Math.lgamma(b).first
|
|
22
21
|
|
|
23
22
|
if x == 0.0 || x == 1.0
|
|
24
|
-
Math.exp(gab - ga - gb) * x**(a-1) * (1-x)**(b-1)
|
|
23
|
+
Math.exp(gab - ga - gb) * x**(a - 1) * (1 - x)**(b - 1)
|
|
25
24
|
else
|
|
26
|
-
Math.exp(gab - ga - gb + Math.log(x)*(a-1) + Math::Log.log1p(-x)*(b-1))
|
|
25
|
+
Math.exp(gab - ga - gb + Math.log(x) * (a - 1) + Math::Log.log1p(-x) * (b - 1))
|
|
27
26
|
end
|
|
28
27
|
end
|
|
29
28
|
|
|
30
29
|
# Gamma cumulative distribution function
|
|
31
30
|
# Translated from GSL-1.9: cdf/beta.c gsl_cdf_beta_P
|
|
32
|
-
def cdf(x,a,b)
|
|
31
|
+
def cdf(x, a, b)
|
|
33
32
|
return 0.0 if x <= 0.0
|
|
34
33
|
return 1.0 if x >= 1.0
|
|
35
|
-
Math::IncompleteBeta.axpy(1.0, 0.0, a,b,x)
|
|
34
|
+
Math::IncompleteBeta.axpy(1.0, 0.0, a, b, x)
|
|
36
35
|
end
|
|
37
36
|
|
|
37
|
+
# Inverse of the beta distribution function
|
|
38
|
+
def quantile(p, a, b, rmin = 0, rmax = 1)
|
|
39
|
+
fail 'a <= 0' if a <= 0
|
|
40
|
+
fail 'b <= 0' if b <= 0
|
|
41
|
+
fail 'rmin == rmax' if rmin == rmax
|
|
42
|
+
fail 'p <= 0' if p <= 0
|
|
43
|
+
fail 'p > 1' if p > 1
|
|
44
|
+
|
|
45
|
+
precision = 8.88e-016
|
|
46
|
+
max_iterations = 256
|
|
47
|
+
|
|
48
|
+
ga = 0
|
|
49
|
+
gb = 2
|
|
50
|
+
|
|
51
|
+
i = 1
|
|
52
|
+
while ((gb - ga) > precision) && (i < max_iterations)
|
|
53
|
+
guess = (ga + gb) / 2.0
|
|
54
|
+
result = cdf(guess, a, b)
|
|
55
|
+
|
|
56
|
+
if (result == p) || (result == 0)
|
|
57
|
+
gb = ga
|
|
58
|
+
elsif result > p
|
|
59
|
+
gb = guess
|
|
60
|
+
else
|
|
61
|
+
ga = guess
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
fail 'No value' if i == max_iterations
|
|
65
|
+
|
|
66
|
+
i += 1
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
rmin + guess * (rmax - rmin)
|
|
70
|
+
end
|
|
38
71
|
|
|
72
|
+
alias_method :p_value, :quantile
|
|
39
73
|
end
|
|
40
74
|
end
|
|
41
75
|
end
|
|
@@ -2,27 +2,26 @@ require 'distribution/binomial/ruby'
|
|
|
2
2
|
require 'distribution/binomial/gsl'
|
|
3
3
|
require 'distribution/binomial/java'
|
|
4
4
|
module Distribution
|
|
5
|
-
|
|
6
5
|
# Calculate statisticals for Binomial Distribution.
|
|
7
6
|
module Binomial
|
|
8
|
-
SHORTHAND = 'bino'
|
|
9
|
-
|
|
7
|
+
SHORTHAND = 'bino'
|
|
8
|
+
|
|
10
9
|
extend Distributable
|
|
11
10
|
create_distribution_methods
|
|
12
|
-
|
|
11
|
+
|
|
13
12
|
##
|
|
14
13
|
# :singleton-method: pdf(x,k)
|
|
15
|
-
# Returns the integral of T distribution
|
|
16
|
-
# with +k+ degrees of freedom over [0, +x+]
|
|
14
|
+
# Returns the integral of T distribution
|
|
15
|
+
# with +k+ degrees of freedom over [0, +x+]
|
|
17
16
|
|
|
18
17
|
##
|
|
19
18
|
# :singleton-method: p_value(qn, k)
|
|
20
|
-
# Return the P-value of the corresponding integral +qn+ with
|
|
21
|
-
# +k+ degrees of freedom
|
|
22
|
-
|
|
19
|
+
# Return the P-value of the corresponding integral +qn+ with
|
|
20
|
+
# +k+ degrees of freedom
|
|
21
|
+
|
|
23
22
|
##
|
|
24
23
|
# :singleton-method: cdf(x,k)
|
|
25
|
-
# Returns the integral of T distribution
|
|
26
|
-
# with +k+ degrees of freedom over [0, +x+]
|
|
24
|
+
# Returns the integral of T distribution
|
|
25
|
+
# with +k+ degrees of freedom over [0, +x+]
|
|
27
26
|
end
|
|
28
27
|
end
|
|
@@ -2,13 +2,14 @@ module Distribution
|
|
|
2
2
|
module Binomial
|
|
3
3
|
module GSL_
|
|
4
4
|
class << self
|
|
5
|
-
def pdf(k,n,prob)
|
|
6
|
-
GSL::Ran.binomial_pdf(k,prob,n)
|
|
5
|
+
def pdf(k, n, prob)
|
|
6
|
+
GSL::Ran.binomial_pdf(k, prob, n)
|
|
7
7
|
end
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
|
|
9
|
+
def cdf(k, n, prob)
|
|
10
|
+
GSL::Cdf.binomial_P(k, prob, n)
|
|
10
11
|
end
|
|
11
12
|
end
|
|
12
13
|
end
|
|
13
14
|
end
|
|
14
|
-
end
|
|
15
|
+
end
|
|
@@ -2,28 +2,35 @@ module Distribution
|
|
|
2
2
|
module Binomial
|
|
3
3
|
module Ruby_
|
|
4
4
|
class << self
|
|
5
|
-
def pdf(k,n,pr)
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
def pdf(k, n, pr)
|
|
6
|
+
fail 'k>n' if k > n
|
|
7
|
+
Math.binomial_coefficient(n, k) * (pr**k) * (1 - pr)**(n - k)
|
|
8
8
|
end
|
|
9
|
-
|
|
9
|
+
|
|
10
|
+
alias_method :exact_pdf, :pdf
|
|
11
|
+
|
|
12
|
+
# TODO: Use exact_regularized_beta for
|
|
10
13
|
# small values and regularized_beta for bigger ones.
|
|
11
|
-
def cdf(k,n,pr)
|
|
12
|
-
#(0..x.floor).inject(0) {|ac,i| ac+pdf(i,n,pr)}
|
|
13
|
-
Math.regularized_beta(1-pr,n - k,k+1)
|
|
14
|
+
def cdf(k, n, pr)
|
|
15
|
+
# (0..x.floor).inject(0) {|ac,i| ac+pdf(i,n,pr)}
|
|
16
|
+
Math.regularized_beta(1 - pr, n - k, k + 1)
|
|
14
17
|
end
|
|
15
|
-
|
|
16
|
-
|
|
18
|
+
|
|
19
|
+
def exact_cdf(k, n, pr)
|
|
20
|
+
out = (0..k).inject(0) { |ac, i| ac + pdf(i, n, pr) }
|
|
21
|
+
out = 1 if out > 1.0
|
|
22
|
+
out
|
|
17
23
|
end
|
|
18
|
-
|
|
19
|
-
|
|
24
|
+
|
|
25
|
+
def quantile(prob, n, pr)
|
|
26
|
+
ac = 0
|
|
20
27
|
(0..n).each do |i|
|
|
21
|
-
ac+=pdf(i,n,pr)
|
|
22
|
-
return i if prob<=ac
|
|
28
|
+
ac += pdf(i, n, pr)
|
|
29
|
+
return i if prob <= ac
|
|
23
30
|
end
|
|
24
31
|
end
|
|
25
|
-
|
|
26
|
-
|
|
32
|
+
|
|
33
|
+
alias_method :p_value, :quantile
|
|
27
34
|
end
|
|
28
35
|
end
|
|
29
36
|
end
|
|
@@ -7,21 +7,20 @@ module Distribution
|
|
|
7
7
|
# Pdf if easy to calculate, but CDF is not trivial. Several papers
|
|
8
8
|
# describe methods to calculate the integral.
|
|
9
9
|
module BivariateNormal
|
|
10
|
-
SHORTHAND='bnor'
|
|
10
|
+
SHORTHAND = 'bnor'
|
|
11
11
|
|
|
12
12
|
extend Distributable
|
|
13
13
|
create_distribution_methods
|
|
14
|
-
|
|
14
|
+
|
|
15
15
|
##
|
|
16
16
|
# :singleton-method: pdf(k,n,prob)
|
|
17
17
|
# Probability density function for exactly +k+ successes in +n+ trials
|
|
18
18
|
# with success probability +prob+
|
|
19
|
-
#
|
|
20
|
-
|
|
19
|
+
#
|
|
20
|
+
|
|
21
21
|
##
|
|
22
22
|
# :singleton-method: cdf(k,n,prob)
|
|
23
23
|
# Cumulative density function for +k+ or less successes in +n+ trials
|
|
24
24
|
# with success probability +prob+
|
|
25
|
-
|
|
26
25
|
end
|
|
27
26
|
end
|
|
@@ -2,8 +2,8 @@ module Distribution
|
|
|
2
2
|
module BivariateNormal
|
|
3
3
|
module GSL_
|
|
4
4
|
class <<self
|
|
5
|
-
def pdf(x,y,rho,s1=1.0,s2=1.0)
|
|
6
|
-
GSL::Ran
|
|
5
|
+
def pdf(x, y, rho, s1 = 1.0, s2 = 1.0)
|
|
6
|
+
GSL::Ran.bivariate_gaussian_pdf(x, y, s1, s2, rho)
|
|
7
7
|
end
|
|
8
8
|
end
|
|
9
9
|
end
|
|
@@ -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
|