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
@@ -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
|