distribution 0.6.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- 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/f/gsl.rb
CHANGED
@@ -1,27 +1,31 @@
|
|
1
1
|
module Distribution
|
2
2
|
module F
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
3
|
+
module GSL_
|
4
|
+
class << self
|
5
|
+
def pdf(x, k1, k2)
|
6
|
+
GSL::Ran.fdist_pdf(x.to_f, k1, k2)
|
7
|
+
end
|
8
|
+
|
9
|
+
# F cumulative distribution function (cdf).
|
10
|
+
#
|
11
|
+
# Returns the integral of F-distribution
|
12
|
+
# with k1 and k2 degrees of freedom
|
13
|
+
# over [0, x].
|
14
|
+
# Distribution::F.cdf(20,3,2)
|
15
|
+
#
|
16
|
+
def cdf(x, k1, k2)
|
17
|
+
GSL::Cdf.fdist_P(x.to_f.to_f, k1, k2)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Return the P-value of the corresponding integral with
|
21
|
+
# k degrees of freedom
|
22
|
+
#
|
23
|
+
# Distribution::F.p_value(0.95,1,2)
|
24
|
+
def quantile(pr, k1, k2)
|
25
|
+
GSL::Cdf.fdist_Pinv(pr.to_f, k1, k2)
|
26
|
+
end
|
27
|
+
|
28
|
+
alias_method :p_value, :quantile
|
25
29
|
end
|
26
30
|
end
|
27
31
|
end
|
data/lib/distribution/f/java.rb
CHANGED
data/lib/distribution/f/ruby.rb
CHANGED
@@ -1,116 +1,115 @@
|
|
1
1
|
module Distribution
|
2
2
|
module F
|
3
|
+
# Continuous random number distributions are defined by a probability density function, p(x), such that the probability of x occurring in the infinitesimal range x to x+dx is p dx.
|
4
|
+
|
5
|
+
# The cumulative distribution function for the lower tail P(x) is defined by the integral,
|
6
|
+
|
7
|
+
# P(x) = \int_{-\infty}^{x} dx' p(x')
|
8
|
+
# and gives the probability of a variate taking a value less than x.
|
9
|
+
|
10
|
+
# The cumulative distribution function for the upper tail Q(x) is defined by the integral,
|
11
|
+
|
12
|
+
# Q(x) = \int_{x}^{+\infty} dx' p(x')
|
13
|
+
# and gives the probability of a variate taking a value greater than x.
|
14
|
+
|
15
|
+
# The upper and lower cumulative distribution functions are related by P(x) + Q(x) = 1 and satisfy 0 <= P(x) <= 1, 0 <= Q(x).
|
3
16
|
module Ruby_
|
4
|
-
|
17
|
+
extend Distribution::MathExtension
|
5
18
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
#
|
13
|
-
#
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
cos2 = 1.0 / (1.0 + df1.to_f * f / df2.to_f)
|
20
|
-
sin2 = 1.0 - cos2
|
21
|
-
|
22
|
-
if (df1 % 2 == 0)
|
23
|
-
prob = cos2 ** (df2.to_f / 2.0)
|
24
|
-
temp = prob
|
25
|
-
i = 2
|
26
|
-
while i < df1
|
27
|
-
temp *= (df2.to_f + i - 2) * sin2 / i
|
28
|
-
prob += temp
|
29
|
-
i += 2
|
30
|
-
end
|
31
|
-
return prob
|
32
|
-
end
|
33
|
-
prob = Math.atan(Math.sqrt(df2.to_f / (df1.to_f * f)))
|
34
|
-
temp = Math.sqrt(sin2 * cos2)
|
35
|
-
i = 3
|
36
|
-
while i <= df1
|
37
|
-
prob += temp
|
38
|
-
temp *= (i - 1).to_f * sin2 / i.to_f;
|
39
|
-
i += 2.0
|
40
|
-
end
|
41
|
-
temp *= df1.to_f
|
42
|
-
i = 3
|
43
|
-
while i <= df2
|
44
|
-
prob -= temp
|
45
|
-
temp *= (df1.to_f + i - 2) * cos2 / i.to_f
|
46
|
-
i += 2
|
47
|
-
end
|
48
|
-
prob * 2.0 / Math::PI
|
49
|
-
end
|
19
|
+
# functions needed:
|
20
|
+
# - pdf
|
21
|
+
# - cdf (lower cumulative function, P(x))
|
22
|
+
# - Q(x), upper cumulative function
|
23
|
+
# - mean
|
24
|
+
# - mode
|
25
|
+
# - kurtosis
|
26
|
+
# - skewness
|
27
|
+
# - entropy
|
28
|
+
# - "fit" (maximum likelihood?)
|
29
|
+
# - expected value (given a function)
|
30
|
+
# - lower-tail quantile -> P
|
31
|
+
# - upper tail quantile -> Q
|
50
32
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
33
|
+
class << self
|
34
|
+
# F Distribution (Ruby) -- Probability Density Function
|
35
|
+
def pdf(x, n, m)
|
36
|
+
x = x.to_f
|
37
|
+
numerator = ((n * x)**n * (m**m)) / (n * x + m)**(n + m)
|
38
|
+
denominator = x * Math.beta(n / 2.0, m / 2.0)
|
55
39
|
|
56
|
-
|
57
|
-
|
58
|
-
def pf(q, n1, n2)
|
59
|
-
if(q < 0.0 || q > 1.0 || n1 < 1 || n2 < 1)
|
60
|
-
$stderr.printf("Error : Illegal parameter in pf()!\n")
|
61
|
-
return 0.0
|
62
|
-
end
|
40
|
+
Math.sqrt(numerator) / denominator
|
41
|
+
end
|
63
42
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
fw += s
|
71
|
-
if s <= eps then return fw end
|
72
|
-
if (qe = q_f(n1, n2, fw) - q) == 0.0 then return fw end
|
73
|
-
if qe < 0.0
|
74
|
-
fw -= s
|
75
|
-
s /= 10.0 #/
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
43
|
+
# Cumulative Distribution Function.
|
44
|
+
def cdf(x, n, m)
|
45
|
+
x = x.to_f
|
46
|
+
xx = (x * n).to_f / (x * n + m).to_f
|
47
|
+
regularized_beta(xx, n / 2.0, m / 2.0)
|
48
|
+
end
|
79
49
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
50
|
+
# Upper cumulative function.
|
51
|
+
#
|
52
|
+
# If cdf(x, n, m) = p, then q(x, n, m) = 1 - p
|
53
|
+
def q(x, n, m)
|
54
|
+
1.0 - cdf(x, n, m)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Return the F value corresponding to `probability` with degrees of
|
58
|
+
# freedom `n` and `m`.
|
59
|
+
#
|
60
|
+
# If x = quantile(p, n, m), then cdf(x, n, m) = p.
|
61
|
+
#
|
62
|
+
# Taken from:
|
63
|
+
# https://github.com/JuliaLang/Rmath-julia/blob/master/src/qf.c
|
64
|
+
def quantile(probability, n, m)
|
65
|
+
return Float::NAN if n <= 0.0 || m <= 0.0
|
66
|
+
|
67
|
+
if n == Float::INFINITY || n == -Float::INFINITY || m == Float::INFINITY || m == -Float::INFINITY
|
68
|
+
return 1.0
|
69
|
+
end
|
70
|
+
|
71
|
+
if n <= m && m > 4e5
|
72
|
+
return Distribution::ChiSquare.p_value(probability, n) / n.to_f
|
73
|
+
elsif n > 4e5 # thus n > m
|
74
|
+
return m.to_f / Distribution::ChiSquare.p_value(1.0 - probability, m)
|
75
|
+
else
|
76
|
+
# O problema está aqui.
|
77
|
+
tmp = Distribution::Beta.p_value(1.0 - probability, m.to_f / 2, n.to_f / 2)
|
78
|
+
value = (1.0 / tmp - 1.0) * (m.to_f / n.to_f)
|
79
|
+
return value.nan? ? Float::NAN : value
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
alias_method :p_value, :quantile
|
84
|
+
|
85
|
+
# Complementary quantile function.
|
86
|
+
#
|
87
|
+
# def cquantile(prob, n, m)
|
88
|
+
# quantile(1.0 - probability, n, m)
|
89
|
+
# end
|
90
|
+
|
91
|
+
# Return the corresponding F value for a p-value `y` with `n` and `m`
|
92
|
+
# degrees of freedom.
|
93
|
+
#
|
94
|
+
# @param y [Float] Value corresponding to the desired p-value. Between 0 and 1.
|
95
|
+
# @param n [Float] Degree of freedom of the first random variable.
|
96
|
+
# @param m [Float] Degree of freedom of the second random variable.
|
97
|
+
# @return [Float] Value of the F distribution that gives a p-value of `y`.
|
98
|
+
|
99
|
+
def mean
|
100
|
+
end
|
101
|
+
|
102
|
+
def mode
|
103
|
+
end
|
104
|
+
|
105
|
+
def skewness
|
106
|
+
end
|
107
|
+
|
108
|
+
def kurtosis
|
109
|
+
end
|
110
|
+
|
111
|
+
def entropy
|
112
|
+
end
|
114
113
|
end
|
115
114
|
end
|
116
115
|
end
|
@@ -1,26 +1,29 @@
|
|
1
1
|
module Distribution
|
2
2
|
module F
|
3
3
|
module Statistics2_
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
4
|
+
class << self
|
5
|
+
# F cumulative distribution function (cdf).
|
6
|
+
#
|
7
|
+
# Returns the integral of F-distribution
|
8
|
+
# with k1 and k2 degrees of freedom
|
9
|
+
# over [0, x].
|
10
|
+
# Distribution::F.cdf(20,3,2)
|
11
|
+
#
|
12
|
+
def cdf(x, k1, k2)
|
13
|
+
Statistics2.fdist(k1, k2, x)
|
14
|
+
end
|
15
|
+
|
16
|
+
# Return the P-value of the corresponding integral with
|
17
|
+
# k degrees of freedom
|
18
|
+
#
|
19
|
+
# Distribution::F.p_value(0.95,1,2)
|
20
|
+
# Statistics2 have some problem with extreme values
|
21
|
+
def quantile(pr, k1, k2)
|
22
|
+
Statistics2.pfdist(k1, k2, pr)
|
23
|
+
end
|
24
|
+
|
25
|
+
alias_method :p_value, :quantile
|
12
26
|
end
|
13
|
-
# F cumulative distribution function (cdf).
|
14
|
-
#
|
15
|
-
# Returns the integral of F-distribution
|
16
|
-
# with k1 and k2 degrees of freedom
|
17
|
-
# over [0, x].
|
18
|
-
# Distribution::F.cdf(20,3,2)
|
19
|
-
#
|
20
|
-
def cdf(x, k1, k2)
|
21
|
-
Statistics2.fdist(k1, k2,x)
|
22
|
-
end
|
23
|
-
end
|
24
27
|
end
|
25
28
|
end
|
26
29
|
end
|
data/lib/distribution/gamma.rb
CHANGED
@@ -5,15 +5,15 @@ require 'distribution/gamma/java'
|
|
5
5
|
|
6
6
|
module Distribution
|
7
7
|
# From Wikipedia:
|
8
|
-
# The gamma distribution is a two-parameter family of
|
8
|
+
# The gamma distribution is a two-parameter family of
|
9
9
|
# continuous probability distributions. It has a scale parameter a
|
10
10
|
# and a shape parameter b.
|
11
|
-
#
|
11
|
+
#
|
12
12
|
# Calculate pdf, cdf and inverse cdf for Gamma Distribution.
|
13
13
|
#
|
14
14
|
module Gamma
|
15
15
|
extend Distributable
|
16
|
-
SHORTHAND='gamma'
|
16
|
+
SHORTHAND = 'gamma'
|
17
17
|
create_distribution_methods
|
18
18
|
|
19
19
|
##
|
@@ -21,7 +21,6 @@ module Distribution
|
|
21
21
|
# Returns PDF of of Gamma distribution with +a+ as scale
|
22
22
|
# parameter and +b+ as shape parameter
|
23
23
|
|
24
|
-
|
25
24
|
##
|
26
25
|
# :singleton-method: cdf(x,a,b)
|
27
26
|
# Returns the integral of Gamma distribution with +a+ as scale
|
@@ -29,9 +28,8 @@ module Distribution
|
|
29
28
|
|
30
29
|
##
|
31
30
|
# :singleton-method: p_value(qn,a,b)
|
32
|
-
# Return the upper limit for the integral of a
|
33
|
-
# gamma distribution which returns +qn+
|
31
|
+
# Return the upper limit for the integral of a
|
32
|
+
# gamma distribution which returns +qn+
|
34
33
|
# with scale +a+ and shape +b+
|
35
|
-
|
36
34
|
end
|
37
35
|
end
|
@@ -2,22 +2,26 @@ module Distribution
|
|
2
2
|
module Gamma
|
3
3
|
module GSL_
|
4
4
|
class << self
|
5
|
-
def pdf(x,a,b)
|
6
|
-
GSL::Ran
|
7
|
-
end
|
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::gamma_Pinv(pr.to_f, a.to_f, b.to_f)
|
5
|
+
def pdf(x, a, b)
|
6
|
+
GSL::Ran.gamma_pdf(x.to_f, a.to_f, b.to_f)
|
12
7
|
end
|
8
|
+
|
13
9
|
# Chi-square cumulative distribution function (cdf).
|
14
10
|
#
|
15
11
|
# Returns the integral of Chi-squared distribution
|
16
12
|
# with k degrees of freedom over [0, x]
|
17
13
|
#
|
18
|
-
def cdf(x,a,b)
|
19
|
-
GSL::Cdf
|
14
|
+
def cdf(x, a, b)
|
15
|
+
GSL::Cdf.gamma_P(x.to_f, a.to_f, b.to_f)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Return the P-value of the corresponding integral with
|
19
|
+
# k degrees of freedom
|
20
|
+
def quantile(pr, a, b)
|
21
|
+
GSL::Cdf.gamma_Pinv(pr.to_f, a.to_f, b.to_f)
|
20
22
|
end
|
23
|
+
|
24
|
+
alias_method :p_value, :quantile
|
21
25
|
end
|
22
26
|
end
|
23
27
|
end
|
@@ -3,7 +3,6 @@ module Distribution
|
|
3
3
|
module Gamma
|
4
4
|
module Ruby_
|
5
5
|
class << self
|
6
|
-
|
7
6
|
include Math
|
8
7
|
# Gamma distribution probability density function
|
9
8
|
#
|
@@ -22,7 +21,7 @@ module Distribution
|
|
22
21
|
# ==References
|
23
22
|
# * http://www.gnu.org/software/gsl/manual/html_node/The-Gamma-Distribution.html
|
24
23
|
# * http://en.wikipedia.org/wiki/Gamma_distribution
|
25
|
-
def pdf(x,a,b)
|
24
|
+
def pdf(x, a, b)
|
26
25
|
return 0 if x < 0
|
27
26
|
if x == 0
|
28
27
|
return 1.quo(b) if a == 1
|
@@ -30,23 +29,18 @@ module Distribution
|
|
30
29
|
elsif a == 1
|
31
30
|
Math.exp(-x.quo(b)).quo(b)
|
32
31
|
else
|
33
|
-
Math.exp((a-1)*Math.log(x.quo(b)) - x.quo(b) - Math.lgamma(a).first).quo(b)
|
32
|
+
Math.exp((a - 1) * Math.log(x.quo(b)) - x.quo(b) - Math.lgamma(a).first).quo(b)
|
34
33
|
end
|
35
34
|
end
|
36
35
|
|
37
36
|
# Gamma cumulative distribution function
|
38
|
-
def cdf(x,a,b)
|
37
|
+
def cdf(x, a, b)
|
39
38
|
return 0.0 if x <= 0.0
|
40
39
|
|
41
40
|
y = x.quo(b)
|
42
|
-
return (1-Math::IncompleteGamma.q(a, y)) if y > a
|
43
|
-
|
41
|
+
return (1 - Math::IncompleteGamma.q(a, y)) if y > a
|
42
|
+
(Math::IncompleteGamma.p(a, y))
|
44
43
|
end
|
45
|
-
|
46
|
-
#def p_value(pr,a,b)
|
47
|
-
# cdf(1.0-pr,a,b)
|
48
|
-
#end
|
49
|
-
|
50
44
|
end
|
51
45
|
end
|
52
46
|
end
|