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.
Files changed (100) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +4 -6
  3. data/.yardopts +5 -0
  4. data/History.txt +3 -0
  5. data/README.md +87 -44
  6. data/benchmark/binomial_coefficient.rb +19 -23
  7. data/benchmark/binomial_coefficient/experiment.rb +33 -36
  8. data/benchmark/factorial_hash.rb +7 -8
  9. data/benchmark/factorial_method.rb +4 -6
  10. data/benchmark/odd.rb +6 -7
  11. data/benchmark/power.rb +11 -11
  12. data/bin/distribution +26 -26
  13. data/distribution.gemspec +3 -4
  14. data/lib/distribution.rb +55 -96
  15. data/lib/distribution/beta/gsl.rb +10 -5
  16. data/lib/distribution/beta/ruby.rb +3 -1
  17. data/lib/distribution/binomial/ruby.rb +5 -2
  18. data/lib/distribution/bivariatenormal.rb +4 -5
  19. data/lib/distribution/bivariatenormal/gsl.rb +2 -2
  20. data/lib/distribution/bivariatenormal/java.rb +1 -1
  21. data/lib/distribution/bivariatenormal/ruby.rb +245 -254
  22. data/lib/distribution/chisquare.rb +8 -10
  23. data/lib/distribution/chisquare/gsl.rb +24 -19
  24. data/lib/distribution/chisquare/java.rb +1 -1
  25. data/lib/distribution/chisquare/ruby.rb +25 -25
  26. data/lib/distribution/chisquare/statistics2.rb +16 -13
  27. data/lib/distribution/distributable.rb +40 -0
  28. data/lib/distribution/exponential.rb +4 -5
  29. data/lib/distribution/exponential/gsl.rb +13 -9
  30. data/lib/distribution/exponential/ruby.rb +14 -9
  31. data/lib/distribution/f.rb +1 -1
  32. data/lib/distribution/f/gsl.rb +26 -22
  33. data/lib/distribution/f/java.rb +1 -1
  34. data/lib/distribution/f/ruby.rb +16 -19
  35. data/lib/distribution/f/statistics2.rb +22 -19
  36. data/lib/distribution/gamma.rb +5 -7
  37. data/lib/distribution/gamma/gsl.rb +13 -9
  38. data/lib/distribution/gamma/java.rb +1 -1
  39. data/lib/distribution/gamma/ruby.rb +5 -11
  40. data/lib/distribution/hypergeometric.rb +5 -8
  41. data/lib/distribution/hypergeometric/gsl.rb +4 -5
  42. data/lib/distribution/hypergeometric/java.rb +1 -1
  43. data/lib/distribution/hypergeometric/ruby.rb +34 -35
  44. data/lib/distribution/logistic.rb +5 -8
  45. data/lib/distribution/logistic/ruby.rb +13 -8
  46. data/lib/distribution/lognormal.rb +5 -7
  47. data/lib/distribution/lognormal/gsl.rb +8 -6
  48. data/lib/distribution/lognormal/ruby.rb +5 -9
  49. data/lib/distribution/math_extension.rb +6 -15
  50. data/lib/distribution/math_extension/chebyshev_series.rb +281 -272
  51. data/lib/distribution/math_extension/erfc.rb +26 -29
  52. data/lib/distribution/math_extension/exponential_integral.rb +17 -17
  53. data/lib/distribution/math_extension/gammastar.rb +19 -20
  54. data/lib/distribution/math_extension/gsl_utilities.rb +12 -12
  55. data/lib/distribution/math_extension/incomplete_beta.rb +52 -61
  56. data/lib/distribution/math_extension/incomplete_gamma.rb +166 -168
  57. data/lib/distribution/math_extension/log_utilities.rb +20 -22
  58. data/lib/distribution/normal.rb +11 -13
  59. data/lib/distribution/normal/gsl.rb +13 -10
  60. data/lib/distribution/normal/java.rb +14 -13
  61. data/lib/distribution/normal/ruby.rb +68 -58
  62. data/lib/distribution/normal/statistics2.rb +5 -2
  63. data/lib/distribution/normalmultivariate.rb +64 -64
  64. data/lib/distribution/poisson.rb +11 -13
  65. data/lib/distribution/poisson/gsl.rb +7 -7
  66. data/lib/distribution/poisson/java.rb +19 -24
  67. data/lib/distribution/poisson/ruby.rb +38 -9
  68. data/lib/distribution/shorthand.rb +17 -0
  69. data/lib/distribution/t.rb +13 -15
  70. data/lib/distribution/t/gsl.rb +27 -24
  71. data/lib/distribution/t/java.rb +1 -1
  72. data/lib/distribution/t/ruby.rb +99 -100
  73. data/lib/distribution/t/statistics2.rb +19 -19
  74. data/lib/distribution/uniform.rb +26 -0
  75. data/lib/distribution/uniform/gsl.rb +36 -0
  76. data/lib/distribution/uniform/ruby.rb +91 -0
  77. data/lib/distribution/version.rb +1 -1
  78. data/lib/distribution/weibull.rb +6 -7
  79. data/lib/distribution/weibull/gsl.rb +16 -16
  80. data/lib/distribution/weibull/ruby.rb +30 -23
  81. data/spec/beta_spec.rb +45 -47
  82. data/spec/binomial_spec.rb +77 -85
  83. data/spec/bivariatenormal_spec.rb +28 -35
  84. data/spec/chisquare_spec.rb +48 -52
  85. data/spec/distribution_spec.rb +10 -10
  86. data/spec/exponential_spec.rb +44 -49
  87. data/spec/f_spec.rb +4 -4
  88. data/spec/gamma_spec.rb +50 -53
  89. data/spec/hypergeometric_spec.rb +63 -69
  90. data/spec/logistic_spec.rb +32 -37
  91. data/spec/lognormal_spec.rb +25 -31
  92. data/spec/math_extension_spec.rb +192 -210
  93. data/spec/normal_spec.rb +80 -73
  94. data/spec/poisson_spec.rb +63 -41
  95. data/spec/shorthand_spec.rb +19 -22
  96. data/spec/spec_helper.rb +8 -9
  97. data/spec/t_spec.rb +63 -77
  98. data/spec/uniform_spec.rb +154 -0
  99. data/spec/weibull_spec.rb +13 -14
  100. 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 x
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
- raise(ArgumentError, "Range error: x must be > -1") if x <= -1
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
- C5 + x*(C6 + x*(C7 + x*(C8 + x*C9))) # formerly t = this
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 x, with_error = false
51
- raise(ArgumentError, "Range error: x must be > -1") if x <= -1
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
- C5 + x*(C6 + x*(C7 + x*(C8 + x*C9))) # formerly t = this
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
- protected
67
+ protected
70
68
 
71
69
  # Abstracted from other log helper functions in GSL-1.9.
72
- def x_less_than_root_epsilon x, with_error
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
@@ -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 isbell”-shaped
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
- lambda { mean+rng.gaussian(sigma)}
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::ugaussian_P(x)
12
+ GSL::Cdf.ugaussian_P(x)
12
13
  end
14
+
13
15
  def pdf(x) # :nodoc:
14
- GSL::Ran::gaussian_pdf(x)
16
+ GSL::Ran.gaussian_pdf(x)
15
17
  end
16
- def p_value(qn)
17
- GSL::Cdf::ugaussian_Pinv(qn)
18
- end
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,seed=nil)
8
+ def rng(mean = 0, sigma = 1, _seed = nil)
9
9
  dist = NormalDistributionImpl.new(mean, sigma)
10
- lambda { dist.sample }
10
+ -> { dist.sample }
11
11
  end
12
-
12
+
13
13
  #==
14
- # Get the inverse cumulative density function (p-value) for qn
15
- def p_value(qn)
14
+ # Return the probability density function at x
15
+ def pdf(x)
16
16
  dist = NormalDistributionImpl.new
17
- dist.inverseCumulativeProbability(qn)
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
- # Return the probability density function at x
29
- def pdf(x)
28
+ # Get the inverse cumulative density function (p-value) for qn
29
+ def quantile(qn)
30
30
  dist = NormalDistributionImpl.new
31
- dist.density(x)
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
- # random number within a gaussian distribution X ~ N(0,1)
7
- def rngu
8
- rng(0,1,nil)
9
- end
10
- # Return a proc which return a random number within a
11
- # gaussian distribution X ~ N(+mean+,+sigma+^2)
12
- # +seed+ feed the
13
- # == Reference:
14
- # * http://www.taygeta.com/random/gaussian.html
15
- def rng(mean=0,sigma=1,seed=nil)
16
- returned,y1,y2=0,0,0
17
- lambda {
18
- if returned==0
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 ( w >= 1.0 )
24
- w = Math::sqrt( (-2.0 * Math::log( w ) ) / w )
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
- qn == 0.5 and return 0.0
40
+ end
48
41
 
49
- w1 = qn
50
- qn > 0.5 and w1 = 1.0 - w1
51
- w3 = -Math.log(4.0 * w1 * (1.0 - w1))
52
- w1 = b[0]
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
- # Normal probability density function (pdf)
92
- # With x=0 and sigma=1
93
- def pdf(x)
94
- (1.0 / SQ2PI)*Math::exp(-(x**2/2.0))
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
@@ -5,9 +5,12 @@ module Distribution
5
5
  def cdf(x)
6
6
  Statistics2.normaldist(x)
7
7
  end
8
- def p_value(pr)
9
- Statistics2.pnormaldist(pr)
8
+
9
+ def quantile(pr)
10
+ Statistics2.pnormaldist(pr)
10
11
  end
12
+
13
+ alias_method :p_value, :quantile
11
14
  end
12
15
  end
13
16
  end
@@ -1,73 +1,73 @@
1
1
  module Distribution
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
- raise "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
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
- error=1000
33
- begin
34
- w=(m+1).times.collect {|i| rand*epsilon}
35
- y=[]
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
- if a[i]!=nil
44
- d[i]=uPhi((a[i]-sumc).quo(c[i-1,i-1]))
45
- end
46
- # puts "sumc:#{sumc}"
47
-
48
- if b[i]!=nil
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=varsum+f[m]**2
56
- n+=1
57
- error=alpha*Math::sqrt((varsum.quo(n) - (intsum.quo(n))**2).quo(n))
58
- end while(error>epsilon and n<max_iterations)
59
-
60
- f=intsum.quo(n)
61
- #p intsum
62
- #puts "f:#{f}, n:#{n}, error:#{error}"
63
- f
64
- end
65
- def iPhi(pr)
66
- Distribution::Normal.p_value(pr)
67
- end
68
- def uPhi(x)
69
- Distribution::Normal.cdf(x)
70
- end
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