more_math 1.5.0 → 1.6.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 +4 -4
- data/CHANGES.md +28 -1
- data/README.md +25 -54
- data/Rakefile +8 -2
- data/lib/more_math/cantor_pairing_function.rb +59 -0
- data/lib/more_math/constants/functions_constants.rb +37 -0
- data/lib/more_math/continued_fraction.rb +170 -60
- data/lib/more_math/distributions.rb +98 -9
- data/lib/more_math/entropy.rb +74 -2
- data/lib/more_math/exceptions.rb +26 -0
- data/lib/more_math/functions.rb +140 -4
- data/lib/more_math/histogram.rb +86 -3
- data/lib/more_math/linear_regression.rb +108 -7
- data/lib/more_math/newton_bisection.rb +71 -8
- data/lib/more_math/numberify_string_function.rb +96 -20
- data/lib/more_math/permutation.rb +132 -27
- data/lib/more_math/ranking_common.rb +38 -10
- data/lib/more_math/sequence/moving_average.rb +27 -0
- data/lib/more_math/sequence/refinement.rb +26 -0
- data/lib/more_math/sequence.rb +177 -66
- data/lib/more_math/string_numeral.rb +172 -4
- data/lib/more_math/subset.rb +49 -5
- data/lib/more_math/version.rb +1 -1
- data/lib/more_math.rb +1 -0
- data/more_math.gemspec +4 -3
- metadata +17 -3
@@ -1,13 +1,38 @@
|
|
1
1
|
require 'more_math/ranking_common'
|
2
2
|
|
3
3
|
module MoreMath
|
4
|
+
# A permutation represents a rearrangement of elements in a set. Permutations
|
5
|
+
# are ranked in lexicographic order, allowing efficient enumeration and
|
6
|
+
# indexing.
|
7
|
+
#
|
8
|
+
# @example Create a permutation of size 3
|
9
|
+
# perm = Permutation.new(3)
|
10
|
+
# # => #<Permutation:0x6ae34 @last=5, @rank=0, @size=3>
|
11
|
+
#
|
12
|
+
# @example Create a permutation with specific rank
|
13
|
+
# perm = Permutation.new(3, 5)
|
14
|
+
# # => #<Permutation:0x6ae34 @last=5, @rank=5, @size=3>
|
15
|
+
#
|
16
|
+
# @example Get the permutation as an array of indices
|
17
|
+
# perm = Permutation.new(3, 5)
|
18
|
+
# perm.value
|
19
|
+
# # => [2, 1, 0]
|
20
|
+
#
|
21
|
+
# @example Project onto actual data
|
22
|
+
# perm = Permutation.new(3, 5)
|
23
|
+
# perm.project(['a', 'b', 'c'])
|
24
|
+
# # => ['c', 'b', 'a']
|
4
25
|
class Permutation
|
5
26
|
include Enumerable
|
6
27
|
include Comparable
|
7
28
|
include RankingCommon
|
8
29
|
|
9
|
-
# Creates a new Permutation instance of <code>size</code>
|
10
|
-
#
|
30
|
+
# Creates a new Permutation instance of <code>size</code> (and ranked with
|
31
|
+
# <code>rank</code>). Creates a new Permutation instance of size (and
|
32
|
+
# ranked with rank).
|
33
|
+
#
|
34
|
+
# @param size [Integer] The size of the permutation
|
35
|
+
# @param rank [Integer] The rank of the permutation (default: 0)
|
11
36
|
def initialize(size, rank = 0)
|
12
37
|
@size, self.rank = size, rank
|
13
38
|
@last = factorial(size) - 1
|
@@ -17,6 +42,9 @@ module MoreMath
|
|
17
42
|
# <code>indices</code>, that should consist of a permutation of Fixnums
|
18
43
|
# in the range of <code>0</code> and <code>indices.size - 1</code>. This is
|
19
44
|
# for example the result of a call to the Permutation#value method.
|
45
|
+
#
|
46
|
+
# @param indices [Array<Integer>] array of indices representing a permutation
|
47
|
+
# @return [Permutation] new permutation instance
|
20
48
|
def self.from_value(indices)
|
21
49
|
indices = indices.clone
|
22
50
|
obj = new(indices.size)
|
@@ -29,6 +57,10 @@ module MoreMath
|
|
29
57
|
# Creates a new Permutation instance from the Array of Arrays
|
30
58
|
# <code>cycles</code>. This is for example the result of a
|
31
59
|
# call to the Permutation#cycles method .
|
60
|
+
#
|
61
|
+
# @param cycles [Array<Array<Integer>>] array of cycles
|
62
|
+
# @param max [Integer] maximum element index (default: 0)
|
63
|
+
# @return [Permutation] new permutation instance
|
32
64
|
def self.from_cycles(cycles, max = 0)
|
33
65
|
indices = Array.new(max)
|
34
66
|
cycles.each do |cycle|
|
@@ -45,6 +77,10 @@ module MoreMath
|
|
45
77
|
# collection as the default Permutation#project data object. A
|
46
78
|
# collection should respond to size, [], and []=. The Permutation
|
47
79
|
# instance will default to rank 0 if none is given.
|
80
|
+
#
|
81
|
+
# @param collection [Object] collection to use for projection
|
82
|
+
# @param rank [Integer] the rank of this permutation (default: 0)
|
83
|
+
# @return [Permutation] new permutation instance
|
48
84
|
def self.for(collection, rank = 0)
|
49
85
|
perm = new(collection.size, rank)
|
50
86
|
perm.instance_variable_set(:@collection, collection)
|
@@ -53,12 +89,17 @@ module MoreMath
|
|
53
89
|
|
54
90
|
# Shortcut to generate the identity permutation that has
|
55
91
|
# Permutation#size <code>n</code>.
|
92
|
+
#
|
93
|
+
# @param n [Integer] size of identity permutation
|
94
|
+
# @return [Permutation] identity permutation of size n
|
56
95
|
def self.identity(n)
|
57
96
|
new(n)
|
58
97
|
end
|
59
98
|
|
60
99
|
# Returns the identity permutation that has the same Permutation#size as this
|
61
100
|
# instance.
|
101
|
+
#
|
102
|
+
# @return [Permutation] identity permutation of same size
|
62
103
|
def identity
|
63
104
|
self.class.new(size)
|
64
105
|
end
|
@@ -67,6 +108,10 @@ module MoreMath
|
|
67
108
|
# Both arguments must be the same length and must contain the same
|
68
109
|
# elements. If these arrays contain duplicate elements, the solution
|
69
110
|
# will not be unique.
|
111
|
+
#
|
112
|
+
# @param a [Array] initial array of elements
|
113
|
+
# @param b [Array] target array of elements
|
114
|
+
# @return [Permutation] permutation that maps a to b
|
70
115
|
def self.for_mapping(a, b)
|
71
116
|
a.size == b.size or
|
72
117
|
raise ArgumentError, "Initial and final lists must be the same length"
|
@@ -83,6 +128,9 @@ module MoreMath
|
|
83
128
|
|
84
129
|
# Computes the nth power (ie the nth repeated permutation) of this instance.
|
85
130
|
# Negative powers are taken to be powers of the inverse.
|
131
|
+
#
|
132
|
+
# @param n [Integer] power to raise permutation to
|
133
|
+
# @return [Permutation] result of permutation raised to power n
|
86
134
|
def power(n)
|
87
135
|
if n.respond_to?(:to_int)
|
88
136
|
n = n.to_int
|
@@ -102,6 +150,9 @@ module MoreMath
|
|
102
150
|
# instance. That implies that the indices produced by a call to the
|
103
151
|
# Permutation#value method of this instance is the permutation ranked with
|
104
152
|
# this new <code>rank</code>.
|
153
|
+
#
|
154
|
+
# @param m [Integer] new rank value
|
155
|
+
# @return [Integer] assigned rank
|
105
156
|
def rank=(m)
|
106
157
|
@rank = m % factorial(size)
|
107
158
|
end
|
@@ -114,6 +165,8 @@ module MoreMath
|
|
114
165
|
# # => #<Permutation:0x6ae34 @last=719, @rank=312, @size=6>
|
115
166
|
# perm.value
|
116
167
|
# # => [2, 4, 0, 1, 3, 5]
|
168
|
+
#
|
169
|
+
# @return [Array<Integer>] array of indices representing this permutation
|
117
170
|
def value
|
118
171
|
unrank_indices(@rank)
|
119
172
|
end
|
@@ -124,30 +177,47 @@ module MoreMath
|
|
124
177
|
# with Permutation.for the collection used to create
|
125
178
|
# it is used as a data object.
|
126
179
|
#
|
127
|
-
#
|
128
|
-
#
|
129
|
-
#
|
130
|
-
#
|
131
|
-
#
|
180
|
+
# @example
|
181
|
+
# perm = Permutation.new(6, 312)
|
182
|
+
# # => #<Permutation:0x6ae34 @last=719, @rank=312, @size=6>
|
183
|
+
# perm.project("abcdef")
|
184
|
+
# # => "ceabdf"
|
185
|
+
#
|
186
|
+
# @param data [Object] data to project onto (optional)
|
187
|
+
# @return [Object] projected result
|
132
188
|
def project(data = (@collection if defined? @collection))
|
133
189
|
data or raise ArgumentError, "a collection is required to project"
|
134
190
|
raise ArgumentError, "data size is != #{size}!" if data.size != size
|
135
|
-
projection = data.
|
191
|
+
projection = data.dup
|
136
192
|
value.each_with_index { |i, j| projection[j] = data[i] }
|
137
193
|
projection
|
138
194
|
end
|
139
195
|
|
140
|
-
#
|
141
|
-
#
|
196
|
+
# Compare this permutation with another based on size and rank.
|
197
|
+
#
|
198
|
+
# This method implements the comparison operator for Permutation objects,
|
199
|
+
# allowing them to be sorted and compared using standard Ruby comparison
|
200
|
+
# operators. The comparison is first done by size, then by rank for permutations
|
201
|
+
# of the same size.
|
142
202
|
#
|
143
|
-
#
|
203
|
+
# @param other [Object] the other permutation to compare with
|
204
|
+
# @return [Integer] -1 if this permutation should be ordered before the other,
|
205
|
+
# 0 if they are equal, 1 if this permutation should be ordered after the other
|
144
206
|
def <=>(other)
|
145
|
-
|
207
|
+
sc = size <=> other.size
|
208
|
+
if sc.zero?
|
209
|
+
rank <=> other.rank
|
210
|
+
else
|
211
|
+
sc
|
212
|
+
end
|
146
213
|
end
|
147
214
|
|
148
215
|
# Returns true if this Permutation instance and the other have the same
|
149
216
|
# value, that is both Permutation instances have the same Permutation#size
|
150
217
|
# and the same Permutation#rank.
|
218
|
+
#
|
219
|
+
# @param other [Object] object to compare with
|
220
|
+
# @return [Boolean] true if equal
|
151
221
|
def eql?(other)
|
152
222
|
self.class == other.class && size == other.size && rank == other.rank
|
153
223
|
end
|
@@ -155,12 +225,16 @@ module MoreMath
|
|
155
225
|
alias == eql?
|
156
226
|
|
157
227
|
# Computes a unique hash value for this Permutation instance.
|
228
|
+
#
|
229
|
+
# @return [Integer] hash value
|
158
230
|
def hash
|
159
231
|
size.hash ^ rank.hash
|
160
232
|
end
|
161
233
|
|
162
|
-
#
|
234
|
+
# Switches this Permutation instance to the inverted permutation.
|
163
235
|
# (See Permutation#compose for an example.)
|
236
|
+
#
|
237
|
+
# @return [Permutation] self after inversion
|
164
238
|
def invert!
|
165
239
|
indices = unrank_indices(rank)
|
166
240
|
inverted = Array.new(size)
|
@@ -173,6 +247,8 @@ module MoreMath
|
|
173
247
|
|
174
248
|
# Returns the inverted Permutation of this Permutation instance.
|
175
249
|
# (See Permutation#compose for an example.)
|
250
|
+
#
|
251
|
+
# @return [Permutation] inverted permutation
|
176
252
|
def invert
|
177
253
|
clone.invert!
|
178
254
|
end
|
@@ -184,16 +260,20 @@ module MoreMath
|
|
184
260
|
# composed with it's inverted permutation yields
|
185
261
|
# the identity permutation, the permutation with rank 0.
|
186
262
|
#
|
187
|
-
#
|
188
|
-
#
|
189
|
-
#
|
190
|
-
#
|
191
|
-
#
|
192
|
-
#
|
193
|
-
#
|
194
|
-
#
|
195
|
-
#
|
196
|
-
#
|
263
|
+
# @example
|
264
|
+
# p1 = Permutation.new(5, 42)
|
265
|
+
# # => #<Permutation:0x75370 @last=119, @rank=42, @size=5>
|
266
|
+
# p2 = p1.invert
|
267
|
+
# # => #<Permutation:0x653d0 @last=119, @rank=51, @size=5>
|
268
|
+
# p1.compose(p2)
|
269
|
+
# => #<Permutation:0x639a4 @last=119, @rank=0, @size=5>
|
270
|
+
#
|
271
|
+
# # Or a little nicer to look at:
|
272
|
+
# p1 * -p1
|
273
|
+
# # => #<Permutation:0x62004 @last=119, @rank=0, @size=5>
|
274
|
+
#
|
275
|
+
# @param other [Permutation] permutation to compose with
|
276
|
+
# @return [Permutation] composed permutation
|
197
277
|
def compose(other)
|
198
278
|
size == other.size or raise ArgumentError,
|
199
279
|
"permutations of unequal sizes cannot be composed!"
|
@@ -210,11 +290,13 @@ module MoreMath
|
|
210
290
|
# The return value of this method can be used to create a
|
211
291
|
# new Permutation instance with the Permutation.from_cycles method.
|
212
292
|
#
|
213
|
-
#
|
293
|
+
# @example
|
214
294
|
# perm = Permutation.new(7, 23)
|
215
295
|
# # => #<Permutation:0x58541c @last=5039, @rank=23, @size=7>
|
216
296
|
# perm.cycles
|
217
297
|
# # => [[3, 6], [4, 5]]
|
298
|
+
#
|
299
|
+
# @return [Array<Array<Integer>>] array of cycles
|
218
300
|
def cycles
|
219
301
|
perm = value
|
220
302
|
result = [[]]
|
@@ -246,6 +328,8 @@ module MoreMath
|
|
246
328
|
# A permutation is odd if it can be represented by an odd number of
|
247
329
|
# transpositions (cycles of length 2), or even if it can be represented of
|
248
330
|
# an even number of transpositions.
|
331
|
+
#
|
332
|
+
# @return [Integer] 1 for even, -1 for odd
|
249
333
|
def signum
|
250
334
|
s = 1
|
251
335
|
cycles.each do |c|
|
@@ -257,11 +341,15 @@ module MoreMath
|
|
257
341
|
alias sgn signum
|
258
342
|
|
259
343
|
# Returns true if this permutation is even, false otherwise.
|
344
|
+
#
|
345
|
+
# @return [Boolean] true if even permutation
|
260
346
|
def even?
|
261
347
|
signum == 1
|
262
348
|
end
|
263
349
|
|
264
350
|
# Returns true if this permutation is odd, false otherwise.
|
351
|
+
#
|
352
|
+
# @return [Boolean] true if odd permutation
|
265
353
|
def odd?
|
266
354
|
signum == -1
|
267
355
|
end
|
@@ -270,13 +358,23 @@ module MoreMath
|
|
270
358
|
|
271
359
|
@@fcache = [ 1 ]
|
272
360
|
|
361
|
+
# Computes the factorial of a number using memoization for efficiency. This
|
362
|
+
# method is used internally by the permutation ranking system to calculate
|
363
|
+
# the total number of permutations for a given size.
|
364
|
+
#
|
365
|
+
# @param n [Integer] the number to calculate factorial for
|
366
|
+
# @return [Integer] the factorial of n
|
273
367
|
def factorial(n)
|
274
368
|
@@fcache.size.upto(n) { |i| @@fcache[i] = i * @@fcache[i - 1] }
|
275
369
|
@@fcache[n]
|
276
370
|
end
|
277
371
|
|
278
372
|
# Rank the indices of the permutation +p+. Beware that this method may
|
279
|
-
# change its argument +p+.
|
373
|
+
# change its argument +p+. Rank the indices of the permutation p. Beware
|
374
|
+
# that this method may change its argument p.
|
375
|
+
#
|
376
|
+
# @param p [Array<Integer>] the permutation indices to rank
|
377
|
+
# @return [Integer] the rank of the permutation indices
|
280
378
|
def rank_indices(p)
|
281
379
|
result = 0
|
282
380
|
for i in 0...size
|
@@ -288,8 +386,15 @@ module MoreMath
|
|
288
386
|
result
|
289
387
|
end
|
290
388
|
|
291
|
-
#
|
292
|
-
#
|
389
|
+
# Unranks the given index value into an array of permutation indices.
|
390
|
+
#
|
391
|
+
# This method converts a rank value back into its corresponding permutation
|
392
|
+
# indices representation. It's the inverse operation of the rank_indices
|
393
|
+
# method and is used internally by the permutation ranking system to
|
394
|
+
# reconstruct permutation arrays from their rank values.
|
395
|
+
#
|
396
|
+
# @param m [Integer] The rank value to unrank
|
397
|
+
# @return [Array<Integer>] Array of indices representing the permutation
|
293
398
|
def unrank_indices(m)
|
294
399
|
result = Array.new(size, 0)
|
295
400
|
for i in 0...size
|
@@ -1,21 +1,34 @@
|
|
1
1
|
module MoreMath
|
2
|
+
# Common functionality for ranking systems. This module provides basic
|
3
|
+
# ranking operations that are shared across different ranking implementations
|
4
|
+
# in the MoreMath library, including permutations and subsets.
|
2
5
|
module RankingCommon
|
3
6
|
# Returns the size of this instance's collection, a Fixnum.
|
7
|
+
#
|
8
|
+
# @return [Integer] the size of the collection
|
4
9
|
attr_reader :size
|
5
10
|
|
6
11
|
# Returns the rank of this instance, a Fixnum in the range
|
7
12
|
# of 0 and #last.
|
13
|
+
#
|
14
|
+
# @return [Integer] the current rank
|
8
15
|
attr_reader :rank
|
9
16
|
|
10
17
|
# Returns the rank of the last ranked instance.
|
18
|
+
#
|
19
|
+
# @return [Integer] the maximum rank value for this size
|
11
20
|
attr_reader :last
|
12
21
|
|
13
22
|
# Returns the collection the #rank applies to if any was set, otherwise
|
14
|
-
#
|
23
|
+
# returns nil.
|
24
|
+
#
|
25
|
+
# @return [Object, nil] the associated collection or nil
|
15
26
|
attr_reader :collection
|
16
27
|
|
17
28
|
# Switches this instance to the next ranked instance. If this was the #last
|
18
|
-
# instance it wraps around the first (<code>rank == 0</code>) instance.
|
29
|
+
# instance it wraps around to the first (<code>rank == 0</code>) instance.
|
30
|
+
#
|
31
|
+
# @return [self] returns self after incrementing rank
|
19
32
|
def next!
|
20
33
|
self.rank += 1
|
21
34
|
self
|
@@ -25,6 +38,8 @@ module MoreMath
|
|
25
38
|
|
26
39
|
# Returns the next ranked instance. If this instance is the #last instance
|
27
40
|
# it returns the first (<code>rank == 0</code>) instance again.
|
41
|
+
#
|
42
|
+
# @return [self] a new instance with incremented rank
|
28
43
|
def next
|
29
44
|
clone.next!
|
30
45
|
end
|
@@ -33,6 +48,8 @@ module MoreMath
|
|
33
48
|
|
34
49
|
# Switches this instance to the previously ranked instance. If this was the
|
35
50
|
# first instance it returns the last (<code>rank == #last</code>) instance.
|
51
|
+
#
|
52
|
+
# @return [self] returns self after decrementing rank
|
36
53
|
def pred!
|
37
54
|
self.rank -= 1
|
38
55
|
self
|
@@ -40,11 +57,15 @@ module MoreMath
|
|
40
57
|
|
41
58
|
# Returns the previously ranked instance. If this was the first instance it
|
42
59
|
# returns the last (<code>rank == #last</code>) instance.
|
60
|
+
#
|
61
|
+
# @return [self] a new instance with decremented rank
|
43
62
|
def pred
|
44
63
|
clone.pred!
|
45
64
|
end
|
46
65
|
|
47
66
|
# Switches this instance to a randomly ranked instance.
|
67
|
+
#
|
68
|
+
# @return [self] returns self after setting random rank
|
48
69
|
def random!
|
49
70
|
new_rank = rand(last + 1).to_i
|
50
71
|
self.rank = new_rank
|
@@ -52,6 +73,8 @@ module MoreMath
|
|
52
73
|
end
|
53
74
|
|
54
75
|
# Returns a randomly ranked instance.
|
76
|
+
#
|
77
|
+
# @return [self] a new instance with random rank
|
55
78
|
def random
|
56
79
|
clone.random!
|
57
80
|
end
|
@@ -63,7 +86,10 @@ module MoreMath
|
|
63
86
|
# step.
|
64
87
|
#
|
65
88
|
# The mixed in methods from the Enumerable module rely on this method.
|
66
|
-
|
89
|
+
#
|
90
|
+
# @yield [instance] yields each instance in sequence
|
91
|
+
# @return [self] returns self after iteration
|
92
|
+
def each
|
67
93
|
0.upto(last) do |r|
|
68
94
|
klon = clone
|
69
95
|
klon.rank = r
|
@@ -72,13 +98,15 @@ module MoreMath
|
|
72
98
|
self
|
73
99
|
end
|
74
100
|
|
75
|
-
# Does something similar to #each. It doesn't create new
|
76
|
-
#
|
77
|
-
#
|
78
|
-
#
|
79
|
-
#
|
80
|
-
#
|
81
|
-
#
|
101
|
+
# Does something similar to #each. It doesn't create new instances (less
|
102
|
+
# overhead) for every iteration step, but yields to a modified self
|
103
|
+
# instead. This is useful if one only wants to call a method on the yielded
|
104
|
+
# value and work with the result of this call. It's not a good idea to put
|
105
|
+
# the yielded values in a data structure because all of them will reference
|
106
|
+
# the same (this!) instance. If you want to do this use #each.
|
107
|
+
#
|
108
|
+
# @yield [instance] yields the current instance
|
109
|
+
# @return [self] returns self after iteration
|
82
110
|
def each!
|
83
111
|
old_rank = rank
|
84
112
|
0.upto(last) do |r|
|
@@ -1,6 +1,31 @@
|
|
1
1
|
module MoreMath
|
2
2
|
class Sequence
|
3
|
+
# Module containing moving average calculation methods
|
4
|
+
#
|
5
|
+
# Provides simple moving average functionality for sequence analysis and
|
6
|
+
# time series data.
|
3
7
|
module MovingAverage
|
8
|
+
# Calculates a simple moving average for the sequence
|
9
|
+
#
|
10
|
+
# A simple moving average is calculated by taking the arithmetic mean of
|
11
|
+
# a specified number of consecutive elements in the sequence.
|
12
|
+
#
|
13
|
+
# @example Basic usage
|
14
|
+
# sequence = Sequence.new([1, 2, 3, 4, 5])
|
15
|
+
# sequence.simple_moving_average(3) # => [2.0, 3.0, 4.0]
|
16
|
+
#
|
17
|
+
# @example With alias usage
|
18
|
+
# sequence = Sequence.new([1, 2, 3, 4, 5])
|
19
|
+
# sequence.moving_average(2) # => [1.5, 2.5, 3.5, 4.5]
|
20
|
+
#
|
21
|
+
# @param n [Integer] The window size for the moving average (must be >= 1)
|
22
|
+
# @return [Array<Float>] Array of moving averages, where each element is
|
23
|
+
# the mean of n consecutive elements from the original sequence
|
24
|
+
# @raise [ArgumentError] If n < 1 or n > number of elements in the sequence
|
25
|
+
#
|
26
|
+
# @note The result array will contain (elements.size - n + 1) elements
|
27
|
+
# @note Each moving average is calculated as the arithmetic mean of n
|
28
|
+
# consecutive elements
|
4
29
|
def simple_moving_average(n)
|
5
30
|
n < 1 and raise ArgumentError, 'n < 1, has to be >= 1'
|
6
31
|
n <= @elements.size or raise ArgumentError,
|
@@ -15,6 +40,8 @@ module MoreMath
|
|
15
40
|
end
|
16
41
|
avg
|
17
42
|
end
|
43
|
+
|
44
|
+
# Alias for {simple_moving_average}
|
18
45
|
alias moving_average simple_moving_average
|
19
46
|
end
|
20
47
|
end
|
@@ -1,5 +1,31 @@
|
|
1
|
+
# Refinement module that adds sequence conversion capabilities to Object.
|
2
|
+
#
|
3
|
+
# This refinement extends the Object class with a +to_seq+ method that
|
4
|
+
# converts any enumerable object into a MoreMath::Sequence.
|
5
|
+
#
|
6
|
+
# @example Converting an array to a sequence
|
7
|
+
# using MoreMath::Sequence::Refinement
|
8
|
+
# [1, 2, 3, 4, 5].to_seq
|
9
|
+
# # => #<MoreMath::Sequence:0x00007f8b8c0b8a00>
|
10
|
+
#
|
11
|
+
# @example Converting other enumerables
|
12
|
+
# using MoreMath::Sequence::Refinement
|
13
|
+
# (1..5).to_seq
|
14
|
+
# # => #<MoreMath::Sequence:0x00007f8b8c0b8a00>
|
15
|
+
#
|
16
|
+
# @note This refinement must be activated with +using
|
17
|
+
# MoreMath::Sequence::Refinement+ before it can be used
|
18
|
+
# @note The resulting sequence is frozen and cannot be modified
|
1
19
|
module MoreMath::Sequence::Refinement
|
2
20
|
refine ::Object do
|
21
|
+
# Converts this object into a MoreMath::Sequence.
|
22
|
+
#
|
23
|
+
# This method iterates over the object (assuming it's enumerable) and
|
24
|
+
# creates a new Sequence instance containing all elements.
|
25
|
+
#
|
26
|
+
# @return [MoreMath::Sequence] A new sequence containing all elements
|
27
|
+
# @note This method works with any enumerable object
|
28
|
+
# @note The resulting sequence is frozen and cannot be modified
|
3
29
|
def to_seq
|
4
30
|
ary = []
|
5
31
|
each { |x| ary << x }
|