more_math 0.3.3 → 1.0.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/Gemfile +0 -1
- data/{README.rdoc → README.md} +7 -6
- data/Rakefile +5 -2
- data/lib/more_math/continued_fraction.rb +51 -4
- data/lib/more_math/functions.rb +32 -11
- data/lib/more_math/histogram.rb +30 -11
- data/lib/more_math/linear_regression.rb +11 -3
- data/lib/more_math/sequence.rb +7 -1
- data/lib/more_math/version.rb +1 -1
- data/more_math.gemspec +21 -27
- data/tests/histogram_test.rb +23 -6
- data/tests/sequence/refinement_test.rb +13 -0
- data/tests/sequence_test.rb +30 -12
- metadata +28 -18
- data/.codeclimate.yml +0 -16
- data/.gitignore +0 -9
- data/.rubocop.yml +0 -1158
- data/.travis.yml +0 -6
- data/VERSION +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 1a9d46106c13337d7b3b949a3984d57de664ba0f8f7931a4ac8aa91139e36a2b
|
4
|
+
data.tar.gz: ce02a111f04c4bc8aab30603d172e47bae8f62bd500484a5ea9b20d2438cb5cd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 44864c937a9f957f6aaf9a7fad4d5a300c75e4db9e69f882f1fc42ff07c9f811b405c70d7c0a8b312e698053aef63f787d26bb66a7b37f86c58c22e8bfcafdd2
|
7
|
+
data.tar.gz: 9a0dfb7c53d2c1487cb2f8597268b921dfdb0898e3130ca894cb0222dad2a1ee2ee54d466c56ae51ddc17063d35a7b05dde4e3a3c6fa080e720eba0ae9a00d44
|
data/Gemfile
CHANGED
data/{README.rdoc → README.md}
RENAMED
@@ -1,20 +1,21 @@
|
|
1
|
-
|
1
|
+
# MoreMath - More mathematics in Ruby
|
2
2
|
|
3
|
-
|
3
|
+
## Description
|
4
4
|
|
5
5
|
Ruby library that contains various mathematical functions and algorithms.
|
6
6
|
|
7
|
-
|
7
|
+
## Download
|
8
8
|
|
9
9
|
The homepage of this library is located at
|
10
10
|
|
11
|
-
*
|
11
|
+
* http://github.com/flori/more_math
|
12
12
|
|
13
|
-
|
13
|
+
|
14
|
+
## Author
|
14
15
|
|
15
16
|
Florian Frank mailto:flori@ping.de
|
16
17
|
|
17
|
-
|
18
|
+
## License
|
18
19
|
|
19
20
|
This software is licensed under the X11 (or MIT) license:
|
20
21
|
http://www.xfree86.org/3.3.6/COPYRIGHT2.html#3
|
data/Rakefile
CHANGED
@@ -12,8 +12,10 @@ GemHadar do
|
|
12
12
|
test_dir 'tests'
|
13
13
|
ignore '.*.sw[pon]', 'pkg', 'Gemfile.lock', 'coverage', '.rvmrc',
|
14
14
|
'.AppleDouble', 'tags', '.byebug_history', '.DS_Store'
|
15
|
-
readme 'README.
|
15
|
+
readme 'README.md'
|
16
16
|
title "#{name.camelize} -- More Math in Ruby"
|
17
|
+
package_ignore '.all_images.yml', '.gitignore', 'VERSION',
|
18
|
+
*Dir.glob('.github/**/*', File::FNM_DOTMATCH)
|
17
19
|
|
18
20
|
required_ruby_version '>= 2.0'
|
19
21
|
dependency 'tins', '~>1.0'
|
@@ -21,6 +23,7 @@ GemHadar do
|
|
21
23
|
development_dependency 'rake'
|
22
24
|
development_dependency 'simplecov'
|
23
25
|
development_dependency 'test-unit'
|
24
|
-
development_dependency
|
26
|
+
development_dependency 'debug'
|
27
|
+
development_dependency 'all_images'
|
25
28
|
licenses << 'MIT'
|
26
29
|
end
|
@@ -14,11 +14,13 @@ module MoreMath
|
|
14
14
|
# ...
|
15
15
|
#
|
16
16
|
class ContinuedFraction
|
17
|
+
SIMPLE_B = proc { 1 }
|
18
|
+
|
17
19
|
# Creates a continued fraction instance. With the defaults for_a { 1 } and
|
18
20
|
# for_b { 1 } it approximates the golden ration phi if evaluated.
|
19
21
|
def initialize
|
20
|
-
@a = proc { 1
|
21
|
-
@b =
|
22
|
+
@a = proc { 1 }
|
23
|
+
@b = SIMPLE_B
|
22
24
|
end
|
23
25
|
|
24
26
|
# Creates a ContinuedFraction instances and passes its arguments to a call
|
@@ -35,7 +37,7 @@ module MoreMath
|
|
35
37
|
|
36
38
|
def for_arg(arg = nil, &block)
|
37
39
|
if arg and !block
|
38
|
-
arg
|
40
|
+
arg.freeze
|
39
41
|
elsif block and !arg
|
40
42
|
block
|
41
43
|
else
|
@@ -44,6 +46,17 @@ module MoreMath
|
|
44
46
|
end
|
45
47
|
private :for_arg
|
46
48
|
|
49
|
+
def self.from(number)
|
50
|
+
number = number.to_r
|
51
|
+
n, d = number.numerator, number.denominator
|
52
|
+
as = []
|
53
|
+
while d > 0
|
54
|
+
n, (a, d) = d, n.divmod(d)
|
55
|
+
as << a
|
56
|
+
end
|
57
|
+
for_a(as)
|
58
|
+
end
|
59
|
+
|
47
60
|
# This method either takes a block or an argument +arg+. The argument +arg+
|
48
61
|
# has to respond to an integer index n >= 0 and return the value a_n. The
|
49
62
|
# block has to return the value for a_n when +n+ is passed as the first
|
@@ -64,6 +77,30 @@ module MoreMath
|
|
64
77
|
self
|
65
78
|
end
|
66
79
|
|
80
|
+
def simple?
|
81
|
+
@b == SIMPLE_B
|
82
|
+
end
|
83
|
+
|
84
|
+
def inspect
|
85
|
+
"#<#{self.class} #{to_s}>"
|
86
|
+
end
|
87
|
+
|
88
|
+
include Enumerable
|
89
|
+
def each(&block)
|
90
|
+
if simple?
|
91
|
+
(0..Float::INFINITY).lazy.map { |i| @a[i] }.take_while { |x| x }.each(&block)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def to_s(length: 10)
|
96
|
+
if simple?
|
97
|
+
convergents = take(length)
|
98
|
+
"[#{convergents[0]}; #{convergents[1..-1] * ', '}#{",…" if convergents.size >= length}]"
|
99
|
+
else
|
100
|
+
"CF(a=#@a, b=#@b)"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
67
104
|
def value(v, n, x = nil)
|
68
105
|
result = if x
|
69
106
|
v[n, x]
|
@@ -86,7 +123,7 @@ module MoreMath
|
|
86
123
|
# Evaluates the continued fraction for the value +x+ (if any) with the
|
87
124
|
# accuracy +epsilon+ and +max_iterations+ as the maximum number of
|
88
125
|
# iterations using the Wallis-method with scaling.
|
89
|
-
def call(x = nil, epsilon
|
126
|
+
def call(x = nil, epsilon: 1E-16, max_iterations: 1 << 31)
|
90
127
|
c_0, c_1 = 1.0, a(0, x)
|
91
128
|
c_1 == nil and return 0 / 0.0
|
92
129
|
d_0, d_1 = 0.0, 1.0
|
@@ -127,8 +164,18 @@ module MoreMath
|
|
127
164
|
result
|
128
165
|
end
|
129
166
|
|
167
|
+
def reciprocal
|
168
|
+
if @a[0] > 0
|
169
|
+
dup.for_a { |i| i == 0 ? 0 : @a[i - 1] }
|
170
|
+
else
|
171
|
+
dup.for_a { |i| @a[i + 1] }
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
130
175
|
alias [] call
|
131
176
|
|
177
|
+
alias to_f call
|
178
|
+
|
132
179
|
# Returns this continued fraction as a Proc object which takes the same
|
133
180
|
# arguments like its call method does.
|
134
181
|
def to_proc
|
data/lib/more_math/functions.rb
CHANGED
@@ -15,6 +15,7 @@ module MoreMath
|
|
15
15
|
end
|
16
16
|
else
|
17
17
|
def log_gamma(x)
|
18
|
+
x = x.to_f
|
18
19
|
if x.nan? || x <= 0
|
19
20
|
0 / 0.0
|
20
21
|
else
|
@@ -33,6 +34,15 @@ module MoreMath
|
|
33
34
|
end
|
34
35
|
end
|
35
36
|
|
37
|
+
# Returns the value of the gamma function, extended to a negative domain.
|
38
|
+
def gamma(x)
|
39
|
+
if x < 0.0
|
40
|
+
return PI / (sin(PI * x) * exp(log_gamma(1 - x)))
|
41
|
+
else
|
42
|
+
exp(log_gamma(x))
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
36
46
|
# Returns the natural logarithm of the beta function value for +(a, b)+.
|
37
47
|
def log_beta(a, b)
|
38
48
|
log_gamma(a) + log_gamma(b) - log_gamma(a + b)
|
@@ -40,16 +50,25 @@ module MoreMath
|
|
40
50
|
0 / 0.0
|
41
51
|
end
|
42
52
|
|
53
|
+
# Returns the value of the beta function for +(a, b)+, +a > 0, b > 0'.
|
54
|
+
def beta(a, b)
|
55
|
+
if a > 0 && b > 0
|
56
|
+
exp(log_beta(a, b))
|
57
|
+
else
|
58
|
+
0.0 / 0
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
43
62
|
# Return an approximation value of Euler's regularized beta function for
|
44
63
|
# +x+, +a+, and +b+ with an error <= +epsilon+, but only iterate
|
45
64
|
# +max_iterations+-times.
|
46
|
-
def beta_regularized(x, a, b, epsilon
|
65
|
+
def beta_regularized(x, a, b, epsilon: 1E-16, max_iterations: 1 << 16)
|
47
66
|
x, a, b = x.to_f, a.to_f, b.to_f
|
48
67
|
case
|
49
68
|
when a.nan? || b.nan? || x.nan? || a <= 0 || b <= 0 || x < 0 || x > 1
|
50
69
|
0 / 0.0
|
51
70
|
when x > (a + 1) / (a + b + 2)
|
52
|
-
1 - beta_regularized(1 - x, b, a, epsilon, max_iterations)
|
71
|
+
1 - beta_regularized(1 - x, b, a, epsilon: epsilon, max_iterations: max_iterations)
|
53
72
|
else
|
54
73
|
fraction = ContinuedFraction.for_b do |n, y|
|
55
74
|
if n % 2 == 0
|
@@ -61,7 +80,7 @@ module MoreMath
|
|
61
80
|
end
|
62
81
|
end
|
63
82
|
exp(a * log(x) + b * log(1.0 - x) - log(a) - log_beta(a, b)) /
|
64
|
-
fraction[x, epsilon, max_iterations]
|
83
|
+
fraction[x, epsilon: epsilon, max_iterations: max_iterations]
|
65
84
|
end
|
66
85
|
rescue Errno::ERANGE, Errno::EDOM
|
67
86
|
0 / 0.0
|
@@ -70,7 +89,7 @@ module MoreMath
|
|
70
89
|
# Return an approximation of the regularized gammaP function for +x+ and
|
71
90
|
# +a+ with an error of <= +epsilon+, but only iterate
|
72
91
|
# +max_iterations+-times.
|
73
|
-
def gammaP_regularized(x, a, epsilon
|
92
|
+
def gammaP_regularized(x, a, epsilon: 1E-16, max_iterations: 1 << 16)
|
74
93
|
x, a = x.to_f, a.to_f
|
75
94
|
case
|
76
95
|
when a.nan? || x.nan? || a <= 0 || x < 0
|
@@ -78,7 +97,7 @@ module MoreMath
|
|
78
97
|
when x == 0
|
79
98
|
0.0
|
80
99
|
when 1 <= a && a < x
|
81
|
-
1 - gammaQ_regularized(x, a, epsilon, max_iterations)
|
100
|
+
1 - gammaQ_regularized(x, a, epsilon: epsilon, max_iterations: max_iterations)
|
82
101
|
else
|
83
102
|
n = 0
|
84
103
|
an = 1 / a
|
@@ -101,7 +120,7 @@ module MoreMath
|
|
101
120
|
# Return an approximation of the regularized gammaQ function for +x+ and
|
102
121
|
# +a+ with an error of <= +epsilon+, but only iterate
|
103
122
|
# +max_iterations+-times.
|
104
|
-
def gammaQ_regularized(x, a, epsilon
|
123
|
+
def gammaQ_regularized(x, a, epsilon: 1E-16, max_iterations: 1 << 16)
|
105
124
|
x, a = x.to_f, a.to_f
|
106
125
|
case
|
107
126
|
when a.nan? || x.nan? || a <= 0 || x < 0
|
@@ -109,7 +128,7 @@ module MoreMath
|
|
109
128
|
when x == 0
|
110
129
|
1.0
|
111
130
|
when a > x || a < 1
|
112
|
-
1 - gammaP_regularized(x, a, epsilon, max_iterations)
|
131
|
+
1 - gammaP_regularized(x, a, epsilon: epsilon, max_iterations: max_iterations)
|
113
132
|
else
|
114
133
|
fraction = ContinuedFraction.for_a do |n, y|
|
115
134
|
(2 * n + 1) - a + y
|
@@ -117,7 +136,7 @@ module MoreMath
|
|
117
136
|
n * (a - n)
|
118
137
|
end
|
119
138
|
exp(-x + a * log(x) - log_gamma(a)) *
|
120
|
-
fraction[x, epsilon, max_iterations] ** -1
|
139
|
+
fraction[x, epsilon: epsilon, max_iterations: max_iterations] ** -1
|
121
140
|
end
|
122
141
|
rescue Errno::ERANGE, Errno::EDOM
|
123
142
|
0 / 0.0
|
@@ -130,9 +149,11 @@ module MoreMath
|
|
130
149
|
r = sqrt(1 - exp(-x ** 2 * (4 / Math::PI + erf_a * x ** 2) / (1 + erf_a * x ** 2)))
|
131
150
|
x < 0 ? -r : r
|
132
151
|
end
|
133
|
-
|
134
|
-
|
135
|
-
|
152
|
+
end
|
153
|
+
|
154
|
+
unless Math.respond_to?(:erfc)
|
155
|
+
def erfc(x)
|
156
|
+
1.0 - erf(x)
|
136
157
|
end
|
137
158
|
end
|
138
159
|
|
data/lib/more_math/histogram.rb
CHANGED
@@ -4,7 +4,14 @@ module MoreMath
|
|
4
4
|
Bin = Struct.new(:left, :right, :count)
|
5
5
|
|
6
6
|
# Create a Histogram for the elements of +sequence+ with +bins+ bins.
|
7
|
-
def initialize(sequence,
|
7
|
+
def initialize(sequence, arg = 10)
|
8
|
+
@with_counts = false
|
9
|
+
if arg.is_a?(Hash)
|
10
|
+
bins = arg.fetch(:bins, 10)
|
11
|
+
wc = arg[:with_counts] and @with_counts = wc
|
12
|
+
else
|
13
|
+
bins = arg
|
14
|
+
end
|
8
15
|
@sequence = sequence
|
9
16
|
@bins = bins
|
10
17
|
@result = compute
|
@@ -29,9 +36,8 @@ module MoreMath
|
|
29
36
|
# Display this histogram to +output+, +width+ is the parameter for
|
30
37
|
# +prepare_display+
|
31
38
|
def display(output = $stdout, width = 50)
|
32
|
-
|
33
|
-
|
34
|
-
output << "%11.5f -|%s\n" % [ (l + r) / 2.0, "*" * bar ]
|
39
|
+
for r in rows
|
40
|
+
output << output_row(r, width)
|
35
41
|
end
|
36
42
|
output << "max_count=#{max_count}\n"
|
37
43
|
self
|
@@ -43,13 +49,26 @@ module MoreMath
|
|
43
49
|
|
44
50
|
private
|
45
51
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
52
|
+
def output_row(row, width)
|
53
|
+
left, right, count = row
|
54
|
+
if @with_counts
|
55
|
+
left_width = width - (counts.map { |x| x.to_s.size }.max + 1)
|
56
|
+
else
|
57
|
+
left_width = width
|
58
|
+
end
|
59
|
+
factor = left_width.to_f / max_count
|
60
|
+
bar_width = (count * factor).ceil
|
61
|
+
bar = ?* * bar_width
|
62
|
+
if @with_counts
|
63
|
+
bar += count.to_s.rjust(width - bar_width)
|
64
|
+
end
|
65
|
+
"%11.5f -|%s\n" % [ (left + right) / 2.0, bar ]
|
66
|
+
end
|
67
|
+
|
68
|
+
def rows
|
69
|
+
@result.reverse_each.map { |bin|
|
70
|
+
[ bin.left, bin.right, bin.count ]
|
71
|
+
}
|
53
72
|
end
|
54
73
|
|
55
74
|
# Computes the histogram and returns it as an array of tuples (l, c, r).
|
@@ -32,9 +32,9 @@ module MoreMath
|
|
32
32
|
t.abs <= td.inverse_probability(1 - alpha.abs / 2.0).abs
|
33
33
|
end
|
34
34
|
|
35
|
-
# Returns the
|
35
|
+
# Returns the residuals of this linear regression in relation to the given
|
36
36
|
# domain and image.
|
37
|
-
def
|
37
|
+
def residuals
|
38
38
|
result = []
|
39
39
|
@domain.zip(@image) do |x, y|
|
40
40
|
result << y - (@a * x + @b)
|
@@ -42,13 +42,21 @@ module MoreMath
|
|
42
42
|
result
|
43
43
|
end
|
44
44
|
|
45
|
+
def r2
|
46
|
+
image_seq = MoreMath::Sequence.new(@image)
|
47
|
+
sum_res = residuals.inject(0.0) { |s, r| s + r ** 2 }
|
48
|
+
[
|
49
|
+
1.0 - sum_res / image_seq.sum_of_squares,
|
50
|
+
0.0,
|
51
|
+
].max
|
52
|
+
end
|
53
|
+
|
45
54
|
private
|
46
55
|
|
47
56
|
def compute
|
48
57
|
size = @image.size
|
49
58
|
sum_xx = sum_xy = sum_x = sum_y = 0.0
|
50
59
|
@domain.zip(@image) do |x, y|
|
51
|
-
x += 1
|
52
60
|
sum_xx += x ** 2
|
53
61
|
sum_xy += x * y
|
54
62
|
sum_x += x
|
data/lib/more_math/sequence.rb
CHANGED
@@ -74,6 +74,12 @@ module MoreMath
|
|
74
74
|
Math.sqrt(variance)
|
75
75
|
end
|
76
76
|
|
77
|
+
# Returns the Z-score sequence derived from the current sequence.
|
78
|
+
memoize method:
|
79
|
+
def z_score
|
80
|
+
self.class.new(elements.map { |t| t.to_f - mean / standard_deviation })
|
81
|
+
end
|
82
|
+
|
77
83
|
# Returns the standard deviation of the elements in percentage of the
|
78
84
|
# arithmetic mean.
|
79
85
|
memoize method:
|
@@ -289,7 +295,7 @@ module MoreMath
|
|
289
295
|
# Returns the d-value for the Durbin-Watson statistic. The value is d << 2
|
290
296
|
# for positive, d >> 2 for negative and d around 2 for no autocorrelation.
|
291
297
|
def durbin_watson_statistic
|
292
|
-
e = linear_regression.
|
298
|
+
e = linear_regression.residuals
|
293
299
|
e.size <= 1 and return 2.0
|
294
300
|
(1...e.size).inject(0.0) { |s, i| s + (e[i] - e[i - 1]) ** 2 } /
|
295
301
|
e.inject(0.0) { |s, x| s + x ** 2 }
|
data/lib/more_math/version.rb
CHANGED
data/more_math.gemspec
CHANGED
@@ -1,52 +1,46 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
# stub: more_math 0.
|
2
|
+
# stub: more_math 1.0.0 ruby lib
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = "more_math".freeze
|
6
|
-
s.version = "0.
|
6
|
+
s.version = "1.0.0"
|
7
7
|
|
8
8
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
9
9
|
s.require_paths = ["lib".freeze]
|
10
10
|
s.authors = ["Florian Frank".freeze]
|
11
|
-
s.date = "
|
11
|
+
s.date = "2023-05-26"
|
12
12
|
s.description = "Library that provides more mathematical functions/algorithms than standard Ruby.".freeze
|
13
13
|
s.email = "flori@ping.de".freeze
|
14
|
-
s.extra_rdoc_files = ["README.
|
15
|
-
s.files = ["
|
14
|
+
s.extra_rdoc_files = ["README.md".freeze, "lib/more_math.rb".freeze, "lib/more_math/cantor_pairing_function.rb".freeze, "lib/more_math/constants/functions_constants.rb".freeze, "lib/more_math/continued_fraction.rb".freeze, "lib/more_math/distributions.rb".freeze, "lib/more_math/entropy.rb".freeze, "lib/more_math/exceptions.rb".freeze, "lib/more_math/functions.rb".freeze, "lib/more_math/histogram.rb".freeze, "lib/more_math/linear_regression.rb".freeze, "lib/more_math/newton_bisection.rb".freeze, "lib/more_math/numberify_string_function.rb".freeze, "lib/more_math/permutation.rb".freeze, "lib/more_math/ranking_common.rb".freeze, "lib/more_math/sequence.rb".freeze, "lib/more_math/sequence/moving_average.rb".freeze, "lib/more_math/sequence/refinement.rb".freeze, "lib/more_math/string_numeral.rb".freeze, "lib/more_math/subset.rb".freeze, "lib/more_math/version.rb".freeze]
|
15
|
+
s.files = ["CHANGES".freeze, "Gemfile".freeze, "LICENSE".freeze, "README.md".freeze, "Rakefile".freeze, "lib/more_math.rb".freeze, "lib/more_math/cantor_pairing_function.rb".freeze, "lib/more_math/constants/functions_constants.rb".freeze, "lib/more_math/continued_fraction.rb".freeze, "lib/more_math/distributions.rb".freeze, "lib/more_math/entropy.rb".freeze, "lib/more_math/exceptions.rb".freeze, "lib/more_math/functions.rb".freeze, "lib/more_math/histogram.rb".freeze, "lib/more_math/linear_regression.rb".freeze, "lib/more_math/newton_bisection.rb".freeze, "lib/more_math/numberify_string_function.rb".freeze, "lib/more_math/permutation.rb".freeze, "lib/more_math/ranking_common.rb".freeze, "lib/more_math/sequence.rb".freeze, "lib/more_math/sequence/moving_average.rb".freeze, "lib/more_math/sequence/refinement.rb".freeze, "lib/more_math/string_numeral.rb".freeze, "lib/more_math/subset.rb".freeze, "lib/more_math/version.rb".freeze, "more_math.gemspec".freeze, "tests/cantor_pairing_function_test.rb".freeze, "tests/continued_fraction_test.rb".freeze, "tests/distribution_test.rb".freeze, "tests/entropy_test.rb".freeze, "tests/functions_test.rb".freeze, "tests/histogram_test.rb".freeze, "tests/newton_bisection_test.rb".freeze, "tests/numberify_string_function_test.rb".freeze, "tests/permutation_test.rb".freeze, "tests/sequence/refinement_test.rb".freeze, "tests/sequence_moving_average_test.rb".freeze, "tests/sequence_test.rb".freeze, "tests/string_numeral_test.rb".freeze, "tests/subset_test.rb".freeze, "tests/test_helper.rb".freeze]
|
16
16
|
s.homepage = "http://flori.github.com/more_math".freeze
|
17
17
|
s.licenses = ["MIT".freeze]
|
18
|
-
s.rdoc_options = ["--title".freeze, "MoreMath -- More Math in Ruby".freeze, "--main".freeze, "README.
|
18
|
+
s.rdoc_options = ["--title".freeze, "MoreMath -- More Math in Ruby".freeze, "--main".freeze, "README.md".freeze]
|
19
19
|
s.required_ruby_version = Gem::Requirement.new(">= 2.0".freeze)
|
20
|
-
s.rubygems_version = "
|
20
|
+
s.rubygems_version = "3.3.26".freeze
|
21
21
|
s.summary = "Library that provides more mathematics.".freeze
|
22
|
-
s.test_files = ["tests/cantor_pairing_function_test.rb".freeze, "tests/continued_fraction_test.rb".freeze, "tests/distribution_test.rb".freeze, "tests/entropy_test.rb".freeze, "tests/functions_test.rb".freeze, "tests/histogram_test.rb".freeze, "tests/newton_bisection_test.rb".freeze, "tests/numberify_string_function_test.rb".freeze, "tests/permutation_test.rb".freeze, "tests/sequence_moving_average_test.rb".freeze, "tests/sequence_test.rb".freeze, "tests/string_numeral_test.rb".freeze, "tests/subset_test.rb".freeze, "tests/test_helper.rb".freeze]
|
22
|
+
s.test_files = ["tests/cantor_pairing_function_test.rb".freeze, "tests/continued_fraction_test.rb".freeze, "tests/distribution_test.rb".freeze, "tests/entropy_test.rb".freeze, "tests/functions_test.rb".freeze, "tests/histogram_test.rb".freeze, "tests/newton_bisection_test.rb".freeze, "tests/numberify_string_function_test.rb".freeze, "tests/permutation_test.rb".freeze, "tests/sequence/refinement_test.rb".freeze, "tests/sequence_moving_average_test.rb".freeze, "tests/sequence_test.rb".freeze, "tests/string_numeral_test.rb".freeze, "tests/subset_test.rb".freeze, "tests/test_helper.rb".freeze]
|
23
23
|
|
24
24
|
if s.respond_to? :specification_version then
|
25
25
|
s.specification_version = 4
|
26
|
+
end
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
s.add_dependency(%q<gem_hadar>.freeze, ["~> 1.9.1"])
|
37
|
-
s.add_dependency(%q<rake>.freeze, [">= 0"])
|
38
|
-
s.add_dependency(%q<simplecov>.freeze, [">= 0"])
|
39
|
-
s.add_dependency(%q<test-unit>.freeze, [">= 0"])
|
40
|
-
s.add_dependency(%q<codeclimate-test-reporter>.freeze, [">= 0"])
|
41
|
-
s.add_dependency(%q<tins>.freeze, ["~> 1.0"])
|
42
|
-
s.add_dependency(%q<mize>.freeze, [">= 0"])
|
43
|
-
end
|
28
|
+
if s.respond_to? :add_runtime_dependency then
|
29
|
+
s.add_development_dependency(%q<gem_hadar>.freeze, ["~> 1.12.0"])
|
30
|
+
s.add_development_dependency(%q<rake>.freeze, [">= 0"])
|
31
|
+
s.add_development_dependency(%q<simplecov>.freeze, [">= 0"])
|
32
|
+
s.add_development_dependency(%q<test-unit>.freeze, [">= 0"])
|
33
|
+
s.add_development_dependency(%q<debug>.freeze, [">= 0"])
|
34
|
+
s.add_development_dependency(%q<all_images>.freeze, [">= 0"])
|
35
|
+
s.add_runtime_dependency(%q<tins>.freeze, ["~> 1.0"])
|
36
|
+
s.add_runtime_dependency(%q<mize>.freeze, [">= 0"])
|
44
37
|
else
|
45
|
-
s.add_dependency(%q<gem_hadar>.freeze, ["~> 1.
|
38
|
+
s.add_dependency(%q<gem_hadar>.freeze, ["~> 1.12.0"])
|
46
39
|
s.add_dependency(%q<rake>.freeze, [">= 0"])
|
47
40
|
s.add_dependency(%q<simplecov>.freeze, [">= 0"])
|
48
41
|
s.add_dependency(%q<test-unit>.freeze, [">= 0"])
|
49
|
-
s.add_dependency(%q<
|
42
|
+
s.add_dependency(%q<debug>.freeze, [">= 0"])
|
43
|
+
s.add_dependency(%q<all_images>.freeze, [">= 0"])
|
50
44
|
s.add_dependency(%q<tins>.freeze, ["~> 1.0"])
|
51
45
|
s.add_dependency(%q<mize>.freeze, [">= 0"])
|
52
46
|
end
|
data/tests/histogram_test.rb
CHANGED
@@ -17,13 +17,30 @@ class HistogramTest < Test::Unit::TestCase
|
|
17
17
|
def test_histogram_display
|
18
18
|
sequence = Sequence.new [ 1, 2, 3, 0, 2 ]
|
19
19
|
histogram = Histogram.new sequence, 3
|
20
|
-
assert_equal [[2.0,
|
21
|
-
histogram.instance_eval {
|
20
|
+
assert_equal [[2.0, 3.0, 1], [1.0, 2.0, 2], [0.0, 1.0, 2]],
|
21
|
+
histogram.instance_eval { rows }
|
22
22
|
output = StringIO.new
|
23
23
|
histogram.display output
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
24
|
+
assert_equal <<~end, output.string
|
25
|
+
2.50000 -|*************************
|
26
|
+
1.50000 -|**************************************************
|
27
|
+
0.50000 -|**************************************************
|
28
|
+
max_count=2
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_histogram_display_with_counts
|
33
|
+
sequence = Sequence.new [ 1, 2, 3, 0, 2 ]
|
34
|
+
histogram = Histogram.new sequence, with_counts: true, bins: 3
|
35
|
+
assert_equal [[2.0, 3.0, 1], [1.0, 2.0, 2], [0.0, 1.0, 2]],
|
36
|
+
histogram.instance_eval { rows }
|
37
|
+
output = StringIO.new
|
38
|
+
histogram.display output
|
39
|
+
assert_equal <<~end, output.string
|
40
|
+
2.50000 -|************************ 1
|
41
|
+
1.50000 -|************************************************ 2
|
42
|
+
0.50000 -|************************************************ 2
|
43
|
+
max_count=2
|
44
|
+
end
|
28
45
|
end
|
29
46
|
end
|
data/tests/sequence_test.rb
CHANGED
@@ -126,8 +126,8 @@ class SequenceTest < Test::Unit::TestCase
|
|
126
126
|
3, 94, 5, 79, 11, 16, 0, 90, 81, 42, 64, 76, 92, 25,
|
127
127
|
3, 90, 51, 15, 0, 74, 98, 93, 90, 14, 81, 85, 28, 30,
|
128
128
|
73, 32, 88])
|
129
|
-
@rand_up = Sequence.new(Array.new(rand.size) { |i| rand[i]
|
130
|
-
@rand_down = Sequence.new(Array.new(rand.size) { |i| rand[i]
|
129
|
+
@rand_up = Sequence.new(Array.new(rand.size) { |i| rand[i] + 10 * i })
|
130
|
+
@rand_down = Sequence.new(Array.new(rand.size) { |i| rand[i] - 10 * i })
|
131
131
|
@rasi = Sequence.new(
|
132
132
|
[ 0.0, 11.7813239550446, 23.8742291678261, 0.368124552684678,
|
133
133
|
20.233654312272, 7.64120827980215, 61.609239533582, 69.346191849821,
|
@@ -186,7 +186,8 @@ class SequenceTest < Test::Unit::TestCase
|
|
186
186
|
assert_in_delta 0.3, @flat.median, 1E-8
|
187
187
|
assert_in_delta 0.3, @flat.percentile(75), 1E-8
|
188
188
|
assert_equal 100, @flat.histogram(10).each_bin.first.count
|
189
|
-
assert @flat.linear_regression.
|
189
|
+
assert @flat.linear_regression.residuals.all? { |r| r.abs <= 1E-6 }
|
190
|
+
assert_in_delta 0.0, @flat.linear_regression.r2, 1E-8
|
190
191
|
end
|
191
192
|
|
192
193
|
def test_half
|
@@ -207,7 +208,8 @@ class SequenceTest < Test::Unit::TestCase
|
|
207
208
|
assert_in_delta 37.375, @half.percentile(75), 1E-8
|
208
209
|
assert_equal [10] * 10, counts = @half.histogram(10).counts
|
209
210
|
assert_equal 100, counts.inject { |s, x| s + x }
|
210
|
-
assert @half.linear_regression.
|
211
|
+
assert @half.linear_regression.residuals.all? { |r| r.abs <= 0.5 }
|
212
|
+
assert_in_delta 1.0, @half.linear_regression.r2, 1E-8
|
211
213
|
end
|
212
214
|
|
213
215
|
def test_rand
|
@@ -227,13 +229,15 @@ class SequenceTest < Test::Unit::TestCase
|
|
227
229
|
assert_in_delta 50.0, @rand.median, 1E-8
|
228
230
|
assert_in_delta 81, @rand.percentile(75), 1E-8
|
229
231
|
assert_in_delta 0.05660, @rand.linear_regression.a, 1E-4
|
230
|
-
assert_in_delta
|
232
|
+
assert_in_delta 48.0378, @rand.linear_regression.b, 1E-4
|
231
233
|
assert @rand.linear_regression.slope_zero?
|
232
|
-
assert_in_delta(-
|
233
|
-
assert_in_delta
|
234
|
+
assert_in_delta(-9.9433, @rand_down.linear_regression.a, 1E-4)
|
235
|
+
assert_in_delta 48.0378, @rand_down.linear_regression.b, 1E-4
|
236
|
+
assert_in_delta 0.9883, @rand_down.linear_regression.r2, 1E-4
|
234
237
|
assert !@rand_down.linear_regression.slope_zero?
|
235
|
-
assert_in_delta
|
236
|
-
assert_in_delta
|
238
|
+
assert_in_delta 10.0566, @rand_up.linear_regression.a, 1E-4
|
239
|
+
assert_in_delta 48.0378, @rand_up.linear_regression.b, 1E-4
|
240
|
+
assert_in_delta 0.98857, @rand_up.linear_regression.r2, 1E-4
|
237
241
|
assert !@rand_up.linear_regression.slope_zero?
|
238
242
|
assert_nil @rand.detect_outliers
|
239
243
|
assert !@rand.detect_autocorrelation[:detected]
|
@@ -258,7 +262,8 @@ class SequenceTest < Test::Unit::TestCase
|
|
258
262
|
assert_in_delta 0.0, @rasi.median, 1E-2
|
259
263
|
assert_in_delta 30.58, @rasi.percentile(75), 1E-2
|
260
264
|
assert_in_delta(-0.41, @rasi.linear_regression.a, 1E-2)
|
261
|
-
assert_in_delta(
|
265
|
+
assert_in_delta(23.94, @rasi.linear_regression.b, 1E-2)
|
266
|
+
assert_in_delta 0.0887, @rasi.linear_regression.r2, 1E-4
|
262
267
|
assert !@rasi.linear_regression.slope_zero?
|
263
268
|
assert_equal 13, @rasi.detect_outliers[:high]
|
264
269
|
assert @rasi.detect_autocorrelation[:detected]
|
@@ -284,8 +289,9 @@ class SequenceTest < Test::Unit::TestCase
|
|
284
289
|
assert_in_delta 51.5, @book.median, 1E-2
|
285
290
|
assert_in_delta 58.25, @book.percentile(75), 1E-2
|
286
291
|
assert_in_delta(-0.0952, @book.linear_regression.a, 1E-4)
|
287
|
-
assert_in_delta(54.
|
292
|
+
assert_in_delta(54.5420, @book.linear_regression.b, 1E-4)
|
288
293
|
assert @book.linear_regression.slope_zero?
|
294
|
+
assert_in_delta 0.0249, @book.linear_regression.r2, 1E-4
|
289
295
|
assert_equal 7, @book.detect_outliers[:high]
|
290
296
|
ought = [1.0, -0.39, 0.3, -0.17, 0.07, -0.10, 0.05, 0.04, -0.04, -0.01,
|
291
297
|
0.01, 0.11, -0.07, 0.15, 0.04, -0.01
|
@@ -297,7 +303,7 @@ class SequenceTest < Test::Unit::TestCase
|
|
297
303
|
assert_equal [3, 4, 9, 12, 18, 14, 4, 5, 0, 1],
|
298
304
|
counts = @book.histogram(10).counts
|
299
305
|
assert_equal 70, counts.inject { |s, x| s + x }
|
300
|
-
assert @flat.linear_regression.
|
306
|
+
assert @flat.linear_regression.residuals.all? { |r| r.abs <= 1E-6 }
|
301
307
|
end
|
302
308
|
|
303
309
|
def test_cover
|
@@ -338,4 +344,16 @@ class SequenceTest < Test::Unit::TestCase
|
|
338
344
|
assert_not_same seq2, seq
|
339
345
|
assert_equal [ 1, 2, 3 ], seq2.elements
|
340
346
|
end
|
347
|
+
|
348
|
+
def test_z_score
|
349
|
+
s = MoreMath::Sequence.new(
|
350
|
+
[
|
351
|
+
697.195, 913.583, 793.187, 363.926, 111.559, 296.687, 500.225,
|
352
|
+
303.019, 4.702, 378.132,
|
353
|
+
]
|
354
|
+
)
|
355
|
+
assert_equal s.size, s.z_score.size
|
356
|
+
assert_in_delta 276.57, s.z_score.standard_deviation, 1E-2
|
357
|
+
assert_in_delta 434.64, s.z_score.mean, 1E-2
|
358
|
+
end
|
341
359
|
end
|