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
@@ -15,62 +15,60 @@ module Distribution
|
|
15
15
|
C8 = 1.quo(9)
|
16
16
|
C9 = -1.quo(10)
|
17
17
|
class << self
|
18
|
-
|
19
18
|
# gsl_log1p from GSL-1.9 sys/log1p.c
|
20
19
|
# log for very small x
|
21
|
-
def log1p
|
20
|
+
def log1p(x)
|
22
21
|
# in C, this is volatile double y.
|
23
22
|
# 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
|
23
|
+
y = 1 + x
|
24
|
+
Math.log(y) - ((y - 1) - x).quo(y) # cancel errors with IEEE arithmetic
|
26
25
|
end
|
27
26
|
|
28
27
|
# \log(1+x) for x > -1
|
29
28
|
# gsl_sf_log_1plusx_e
|
30
29
|
def log_1plusx(x, with_error = false)
|
31
|
-
|
30
|
+
fail(ArgumentError, 'Range error: x must be > -1') if x <= -1
|
32
31
|
|
33
32
|
if x.abs < Math::ROOT6_FLOAT_EPSILON
|
34
|
-
result = x * (1.0 + x * (C1 + x*(C2 + x*(C3 + x*(C4 + x*begin
|
35
|
-
|
33
|
+
result = x * (1.0 + x * (C1 + x * (C2 + x * (C3 + x * (C4 + x * begin
|
34
|
+
C5 + x * (C6 + x * (C7 + x * (C8 + x * C9))) # formerly t = this
|
36
35
|
end)))))
|
37
36
|
return with_error ? [result, Float::EPSILON * result.abs] : result
|
38
37
|
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
|
38
|
+
c = ChebyshevSeries.evaluate(:lopx, (8 * x + 1).quo(2 * x + 4), with_error)
|
39
|
+
return with_error ? [x * c.first, x * c.last] : x * c
|
41
40
|
else
|
42
|
-
result = Math.log(1+x)
|
43
|
-
return with_error ? [result, Float::EPSILON*result.abs] : result
|
41
|
+
result = Math.log(1 + x)
|
42
|
+
return with_error ? [result, Float::EPSILON * result.abs] : result
|
44
43
|
end
|
45
44
|
end
|
46
45
|
|
47
|
-
|
48
46
|
# \log(1+x)-x for x > -1
|
49
47
|
# gsl_sf_log_1plusx_mx_e
|
50
|
-
def log_1plusx_minusx
|
51
|
-
|
48
|
+
def log_1plusx_minusx(x, with_error = false)
|
49
|
+
fail(ArgumentError, 'Range error: x must be > -1') if x <= -1
|
52
50
|
|
53
51
|
if x.abs < Math::ROOT5_FLOAT_EPSILON
|
54
|
-
result = x*x * (C1 + x*(C2 + x*(C3 + x*(C4 + x*begin
|
55
|
-
|
52
|
+
result = x * x * (C1 + x * (C2 + x * (C3 + x * (C4 + x * begin
|
53
|
+
C5 + x * (C6 + x * (C7 + x * (C8 + x * C9))) # formerly t = this
|
56
54
|
end))))
|
57
55
|
return with_error ? [result, Float::EPSILON * result.abs] : result
|
58
56
|
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
|
57
|
+
c = ChebyshevSeries.evaluate(:lopxmx, (8 * x + 1).quo(2 * x + 4), with_error)
|
58
|
+
return with_error ? [x * x * c.first, x * x * c.last] : x * x * c
|
61
59
|
else
|
62
|
-
lterm = Math.log(1.0+x)
|
60
|
+
lterm = Math.log(1.0 + x)
|
63
61
|
error = Float::EPSILON * (lterm.abs + x.abs) if with_error
|
64
62
|
result = lterm - x
|
65
63
|
return with_error ? [result, error] : result
|
66
64
|
end
|
67
65
|
end
|
68
66
|
|
69
|
-
|
67
|
+
protected
|
70
68
|
|
71
69
|
# Abstracted from other log helper functions in GSL-1.9.
|
72
|
-
def x_less_than_root_epsilon
|
73
|
-
result = square_x ? x*x : x
|
70
|
+
def x_less_than_root_epsilon(x, with_error)
|
71
|
+
result = square_x ? x * x : x
|
74
72
|
|
75
73
|
with_error ? [result, Float::EPSILON * result.abs] : result
|
76
74
|
end
|
data/lib/distribution/normal.rb
CHANGED
@@ -4,34 +4,32 @@ require 'distribution/normal/statistics2'
|
|
4
4
|
require 'distribution/normal/java'
|
5
5
|
|
6
6
|
module Distribution
|
7
|
-
# From Wikipedia:
|
8
|
-
# Continuous probability distribution that is often used as
|
9
|
-
# a first approximation to describe real-valued random variables
|
10
|
-
# that tend to cluster around a single mean value.
|
11
|
-
# The graph of the associated probability density function is
|
7
|
+
# From Wikipedia:
|
8
|
+
# Continuous probability distribution that is often used as
|
9
|
+
# a first approximation to describe real-valued random variables
|
10
|
+
# that tend to cluster around a single mean value.
|
11
|
+
# The graph of the associated probability density function is "bell-shaped.
|
12
12
|
module Normal
|
13
|
-
SHORTHAND='norm'
|
13
|
+
SHORTHAND = 'norm'
|
14
14
|
extend Distributable
|
15
|
-
|
15
|
+
|
16
16
|
create_distribution_methods
|
17
|
-
|
17
|
+
|
18
18
|
##
|
19
19
|
# :singleton-method: pdf(x)
|
20
|
-
# Returns PDF of Normal distribution
|
20
|
+
# Returns PDF of Normal distribution
|
21
21
|
|
22
22
|
##
|
23
23
|
# :singleton-method: p_value(qn)
|
24
24
|
# Return the P-value of the corresponding integral +qn+
|
25
|
-
|
25
|
+
|
26
26
|
##
|
27
27
|
# :singleton-method: cdf(x)
|
28
28
|
# Returns the integral of Normal distribution over [0, +x+]
|
29
|
-
|
29
|
+
|
30
30
|
##
|
31
31
|
# :singleton-method: rng
|
32
32
|
# Returns a lambda which returns a random number from
|
33
33
|
# X ~ N(0,1)
|
34
|
-
|
35
|
-
|
36
34
|
end
|
37
35
|
end
|
@@ -2,22 +2,25 @@ module Distribution
|
|
2
2
|
module Normal
|
3
3
|
module GSL_
|
4
4
|
class << self
|
5
|
-
def rng(mean=0,sigma=1,seed=nil)
|
6
|
-
seed||=rand(10e8)
|
7
|
-
rng=GSL::Rng.alloc(GSL::Rng::MT19937,seed)
|
8
|
-
|
5
|
+
def rng(mean = 0, sigma = 1, seed = nil)
|
6
|
+
seed ||= rand(10e8)
|
7
|
+
rng = GSL::Rng.alloc(GSL::Rng::MT19937, seed)
|
8
|
+
-> { mean + rng.gaussian(sigma) }
|
9
9
|
end
|
10
|
+
|
10
11
|
def cdf(x) # :nodoc:
|
11
|
-
GSL::Cdf
|
12
|
+
GSL::Cdf.ugaussian_P(x)
|
12
13
|
end
|
14
|
+
|
13
15
|
def pdf(x) # :nodoc:
|
14
|
-
GSL::Ran
|
16
|
+
GSL::Ran.gaussian_pdf(x)
|
15
17
|
end
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
def gsl
|
18
|
+
|
19
|
+
def quantile(qn)
|
20
|
+
GSL::Cdf.ugaussian_Pinv(qn)
|
20
21
|
end
|
22
|
+
|
23
|
+
alias_method :p_value, :quantile
|
21
24
|
end
|
22
25
|
end
|
23
26
|
end
|
@@ -5,33 +5,34 @@ module Distribution
|
|
5
5
|
class << self
|
6
6
|
#==
|
7
7
|
# Generate random variables from the provided distribution
|
8
|
-
def rng(mean=0,sigma=1,
|
8
|
+
def rng(mean = 0, sigma = 1, _seed = nil)
|
9
9
|
dist = NormalDistributionImpl.new(mean, sigma)
|
10
|
-
|
10
|
+
-> { dist.sample }
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
#==
|
14
|
-
#
|
15
|
-
def
|
14
|
+
# Return the probability density function at x
|
15
|
+
def pdf(x)
|
16
16
|
dist = NormalDistributionImpl.new
|
17
|
-
dist.
|
17
|
+
dist.density(x)
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
#==
|
21
21
|
# Return the cumulative density function at x
|
22
22
|
def cdf(x)
|
23
23
|
dist = NormalDistributionImpl.new
|
24
24
|
dist.cumulativeProbability(x)
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
#==
|
28
|
-
#
|
29
|
-
def
|
28
|
+
# Get the inverse cumulative density function (p-value) for qn
|
29
|
+
def quantile(qn)
|
30
30
|
dist = NormalDistributionImpl.new
|
31
|
-
dist.
|
31
|
+
dist.inverseCumulativeProbability(qn)
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
|
+
alias_method :p_value, :quantile
|
34
35
|
end
|
35
36
|
end
|
36
37
|
end
|
37
|
-
end
|
38
|
+
end
|
@@ -1,71 +1,64 @@
|
|
1
|
-
module Distribution
|
1
|
+
module Distribution
|
2
2
|
module Normal
|
3
3
|
module Ruby_
|
4
4
|
class << self
|
5
|
-
|
6
|
-
#
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
#
|
11
|
-
#
|
12
|
-
# +seed+
|
13
|
-
#
|
14
|
-
#
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
5
|
+
# Return a Proc object which returns a random number drawn
|
6
|
+
# from the normal distribution with mean +mean+ and
|
7
|
+
# standard deviation +sigma+, i.e. from N(+mean+,+sigma+^2).
|
8
|
+
#
|
9
|
+
# == Arguments
|
10
|
+
# * +mean+ - mean of the normal distribution
|
11
|
+
# * +sigma+ - standard deviation, a strictly positive number
|
12
|
+
# * +seed+ - seed, an integer value to set the initial state
|
13
|
+
#
|
14
|
+
# == Reference
|
15
|
+
# * http://www.taygeta.com/random/gaussian.html
|
16
|
+
#
|
17
|
+
def rng(mean = 0, sigma = 1, seed = nil)
|
18
|
+
seed = Random.new_seed if seed.nil?
|
19
|
+
r = Random.new(seed)
|
20
|
+
returned = 0
|
21
|
+
y1 = 0
|
22
|
+
y2 = 0
|
23
|
+
lambda do
|
24
|
+
if returned == 0
|
19
25
|
begin
|
20
|
-
x1 = 2.0 * rand - 1.0
|
21
|
-
x2 = 2.0 * rand - 1.0
|
26
|
+
x1 = 2.0 * r.rand - 1.0
|
27
|
+
x2 = 2.0 * r.rand - 1.0
|
22
28
|
w = x1 * x1 + x2 * x2
|
23
|
-
end while (
|
24
|
-
w = Math
|
29
|
+
end while (w >= 1.0)
|
30
|
+
w = Math.sqrt((-2.0 * Math.log(w)) / w)
|
25
31
|
y1 = x1 * w
|
26
32
|
y2 = x2 * w
|
27
|
-
returned=1
|
28
|
-
y1*sigma + mean
|
33
|
+
returned = 1
|
34
|
+
y1 * sigma + mean
|
29
35
|
else
|
30
|
-
returned=0
|
36
|
+
returned = 0
|
31
37
|
y2 * sigma + mean
|
32
38
|
end
|
33
|
-
}
|
34
|
-
|
35
|
-
end
|
36
|
-
# Return the inverse CDF or P-value of the corresponding integral
|
37
|
-
def p_value(qn)
|
38
|
-
b = [1.570796288, 0.03706987906, -0.8364353589e-3,
|
39
|
-
-0.2250947176e-3, 0.6841218299e-5, 0.5824238515e-5,
|
40
|
-
-0.104527497e-5, 0.8360937017e-7, -0.3231081277e-8,
|
41
|
-
0.3657763036e-10, 0.6936233982e-12]
|
42
|
-
|
43
|
-
if(qn < 0.0 || 1.0 < qn)
|
44
|
-
$stderr.printf("Error : qn <= 0 or qn >= 1 in pnorm()!\n")
|
45
|
-
return 0.0;
|
46
39
|
end
|
47
|
-
|
40
|
+
end
|
48
41
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
1.upto 10 do |i|
|
54
|
-
w1 += b[i] * w3**i;
|
55
|
-
end
|
56
|
-
qn > 0.5 and return Math.sqrt(w1 * w3)
|
57
|
-
-Math.sqrt(w1 * w3)
|
42
|
+
# random number within a gaussian distribution X ~ N(0,1)
|
43
|
+
def rngu
|
44
|
+
rng(0, 1, nil)
|
45
|
+
end
|
58
46
|
|
47
|
+
# Normal probability density function (pdf)
|
48
|
+
# With x=0 and sigma=1
|
49
|
+
def pdf(x)
|
50
|
+
(1.0 / SQ2PI) * Math.exp(-(x**2 / 2.0))
|
59
51
|
end
|
52
|
+
|
60
53
|
# Normal cumulative distribution function (cdf).
|
61
|
-
#
|
62
|
-
# Returns the integral of normal distribution
|
54
|
+
#
|
55
|
+
# Returns the integral of normal distribution
|
63
56
|
# over (-Infty, z].
|
64
|
-
#
|
57
|
+
#
|
65
58
|
def cdf(z)
|
66
|
-
return 0.0 if z < -12
|
59
|
+
return 0.0 if z < -12
|
67
60
|
return 1.0 if z > 12
|
68
|
-
return 0.5 if z == 0.0
|
61
|
+
return 0.5 if z == 0.0
|
69
62
|
|
70
63
|
if z > 0.0
|
71
64
|
e = true
|
@@ -81,18 +74,35 @@ module Distribution
|
|
81
74
|
prev = q
|
82
75
|
t *= z2 / i
|
83
76
|
q += t
|
84
|
-
if q <= prev
|
85
|
-
return(e ? 0.5 + q : 0.5 - q)
|
86
|
-
end
|
77
|
+
return(e ? 0.5 + q : 0.5 - q) if q <= prev
|
87
78
|
end
|
88
79
|
e ? 1.0 : 0.0
|
89
80
|
end
|
90
|
-
|
91
|
-
#
|
92
|
-
|
93
|
-
|
94
|
-
|
81
|
+
|
82
|
+
# Return the inverse CDF or P-value of the corresponding integral
|
83
|
+
def quantile(qn)
|
84
|
+
b = [1.570796288, 0.03706987906, -0.8364353589e-3,
|
85
|
+
-0.2250947176e-3, 0.6841218299e-5, 0.5824238515e-5,
|
86
|
+
-0.104527497e-5, 0.8360937017e-7, -0.3231081277e-8,
|
87
|
+
0.3657763036e-10, 0.6936233982e-12]
|
88
|
+
|
89
|
+
if qn < 0.0 || 1.0 < qn
|
90
|
+
$stderr.printf("Error : qn <= 0 or qn >= 1 in pnorm()!\n")
|
91
|
+
return 0.0
|
92
|
+
end
|
93
|
+
qn == 0.5 and return 0.0
|
94
|
+
|
95
|
+
w1 = qn
|
96
|
+
w3 = -Math.log(4.0 * w1 * (1.0 - w1))
|
97
|
+
w1 = b[0]
|
98
|
+
1.upto 10 do |i|
|
99
|
+
w1 += b[i] * w3**i
|
100
|
+
end
|
101
|
+
qn > 0.5 and return Math.sqrt(w1 * w3)
|
102
|
+
-Math.sqrt(w1 * w3)
|
95
103
|
end
|
104
|
+
|
105
|
+
alias_method :p_value, :quantile
|
96
106
|
end
|
97
107
|
end
|
98
108
|
end
|
@@ -1,73 +1,73 @@
|
|
1
1
|
module Distribution
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
cc=GSL::Linalg::Cholesky.decomp(sigma)
|
17
|
-
c=cc.lower
|
18
|
-
intsum=0
|
19
|
-
varsum=0
|
20
|
-
n=0
|
21
|
-
d=Array.new(m+1,nil)
|
22
|
-
e=Array.new(m+1,nil)
|
23
|
-
f=Array.new(m+1,nil)
|
24
|
-
(1..m).each {|i|
|
25
|
-
d[i]=0.0 if a[i].nil?
|
26
|
-
e[i]=1.0 if b[i].nil?
|
27
|
-
}
|
28
|
-
d[1]=uPhi(a[1].quo( c[0,0])) unless d[1]==0
|
29
|
-
e[1]=uPhi(b[1].quo( c[0,0])) unless e[1]==1
|
30
|
-
f[1]=e[1]-d[1]
|
2
|
+
# Calculate cdf and inverse cdf for Multivariate Distribution.
|
3
|
+
module NormalMultivariate
|
4
|
+
class << self
|
5
|
+
# Returns multivariate cdf distribution
|
6
|
+
# * a is the array of lower values
|
7
|
+
# * b is the array of higher values
|
8
|
+
# * s is an symmetric positive definite covariance matrix
|
9
|
+
def cdf(aa, bb, sigma, epsilon = 0.0001, alpha = 2.5, max_iterations = 100) # :nodoc:
|
10
|
+
fail "Doesn't work yet"
|
11
|
+
a = [nil] + aa
|
12
|
+
b = [nil] + bb
|
13
|
+
m = aa.size
|
14
|
+
sigma = sigma.to_gsl if sigma.respond_to? :to_gsl
|
31
15
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
16
|
+
cc = GSL::Linalg::Cholesky.decomp(sigma)
|
17
|
+
c = cc.lower
|
18
|
+
intsum = 0
|
19
|
+
varsum = 0
|
20
|
+
n = 0
|
21
|
+
d = Array.new(m + 1, nil)
|
22
|
+
e = Array.new(m + 1, nil)
|
23
|
+
f = Array.new(m + 1, nil)
|
24
|
+
(1..m).each do|i|
|
25
|
+
d[i] = 0.0 if a[i].nil?
|
26
|
+
e[i] = 1.0 if b[i].nil?
|
27
|
+
end
|
28
|
+
d[1] = uPhi(a[1].quo(c[0, 0])) unless d[1] == 0
|
29
|
+
e[1] = uPhi(b[1].quo(c[0, 0])) unless e[1] == 1
|
30
|
+
f[1] = e[1] - d[1]
|
31
|
+
|
32
|
+
error = 1000
|
33
|
+
begin
|
34
|
+
w = (m + 1).times.collect { |_i| rand * epsilon }
|
35
|
+
y = []
|
36
36
|
(2..m).each do |i|
|
37
|
-
y[i-1]=iPhi(d[i-1] + w[i-1] * (e[i-1] - d[i-1]))
|
38
|
-
sumc=0
|
39
|
-
(1..(i-1)).each do |j|
|
40
|
-
sumc+=c[i-1, j-1]*y[j]
|
37
|
+
y[i - 1] = iPhi(d[i - 1] + w[i - 1] * (e[i - 1] - d[i - 1]))
|
38
|
+
sumc = 0
|
39
|
+
(1..(i - 1)).each do |j|
|
40
|
+
sumc += c[i - 1, j - 1] * y[j]
|
41
41
|
end
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
#puts "e[#{i}] :#{c[i-1,i-1]}"
|
50
|
-
e[i]=uPhi((b[i]-sumc).quo(c[i-1, i-1]))
|
42
|
+
|
43
|
+
d[i] = uPhi((a[i] - sumc).quo(c[i - 1, i - 1])) unless a[i].nil?
|
44
|
+
# puts "sumc:#{sumc}"
|
45
|
+
|
46
|
+
unless b[i].nil?
|
47
|
+
# puts "e[#{i}] :#{c[i-1,i-1]}"
|
48
|
+
e[i] = uPhi((b[i] - sumc).quo(c[i - 1, i - 1]))
|
51
49
|
end
|
52
|
-
f[i]=(e[i]-d[i])*f[i-1]
|
50
|
+
f[i] = (e[i] - d[i]) * f[i - 1]
|
53
51
|
end
|
54
|
-
intsum+=intsum+f[m]
|
55
|
-
varsum
|
56
|
-
n+=1
|
57
|
-
error=alpha*Math
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
52
|
+
intsum += intsum + f[m]
|
53
|
+
varsum += f[m]**2
|
54
|
+
n += 1
|
55
|
+
error = alpha * Math.sqrt((varsum.quo(n) - (intsum.quo(n))**2).quo(n))
|
56
|
+
end while(error > epsilon && n < max_iterations)
|
57
|
+
|
58
|
+
f = intsum.quo(n)
|
59
|
+
# p intsum
|
60
|
+
# puts "f:#{f}, n:#{n}, error:#{error}"
|
61
|
+
f
|
62
|
+
end
|
63
|
+
|
64
|
+
def iPhi(pr)
|
65
|
+
Distribution::Normal.p_value(pr)
|
66
|
+
end
|
67
|
+
|
68
|
+
def uPhi(x)
|
69
|
+
Distribution::Normal.cdf(x)
|
71
70
|
end
|
72
71
|
end
|
72
|
+
end
|
73
73
|
end
|