mdarray 0.4.0-java → 0.4.2-java
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.
- data/README.md +1 -0
- data/Rakefile +1 -1
- data/lib/mdarray.rb +3 -33
- data/lib/mdarray/access.rb +0 -24
- data/lib/mdarray/hierarchy.rb +0 -56
- data/lib/mdarray/operators.rb +62 -17
- data/lib/mdarray/ruby_boolean_functions.rb +43 -0
- data/lib/mdarray/ruby_functions.rb +1 -0
- data/lib/mdarray/ruby_operators.rb +1 -0
- data/lib/mdarray/ruby_stats.rb +32 -19
- data/lib/mdarray/{slices.rb → views.rb} +76 -9
- data/test/test_boolean.rb +4 -3
- data/test/test_complete.rb +19 -13
- data/test/test_counter.rb +2 -19
- data/test/test_creation.rb +0 -1
- data/test/test_operator.rb +22 -9
- data/test/test_printing.rb +8 -9
- data/test/test_statistics.rb +1 -8
- data/test/test_views.rb +291 -0
- data/version.rb +1 -1
- metadata +16 -41
- data/lib/mdarray/fast_non_numerical.rb +0 -102
- data/lib/mdarray/statistics.rb +0 -86
- data/test/test_slices.rb +0 -146
@@ -101,16 +101,15 @@ class MDArray
|
|
101
101
|
|
102
102
|
end
|
103
103
|
|
104
|
-
|
104
|
+
#---------------------------------------------------------------------------------------
|
105
105
|
# Create a new Array as a subsection of this Array, without rank reduction. No data
|
106
106
|
# is moved, so the new Array references the same backing store as the original.
|
107
|
-
#
|
108
|
-
#
|
109
|
-
# shape
|
110
|
-
# of the returned Array. Must be same rank as original Array.
|
111
|
-
#
|
112
|
-
#
|
113
|
-
# the new Array
|
107
|
+
# @param origin ruby array specifying the starting index. Must be same rank as original
|
108
|
+
# Array.
|
109
|
+
# @param shape ruby array specifying the extents in each dimension. This becomes the
|
110
|
+
# shape of the returned Array. Must be same rank as original Array.
|
111
|
+
# @param reduce true if the array should be reduced by removing dimensions of size 1
|
112
|
+
# @returns new Array
|
114
113
|
# Throws:
|
115
114
|
# InvalidRangeException - if ranges is invalid
|
116
115
|
#------------------------------------------------------------------------------------
|
@@ -138,7 +137,18 @@ class MDArray
|
|
138
137
|
end
|
139
138
|
|
140
139
|
#------------------------------------------------------------------------------------
|
141
|
-
#
|
140
|
+
# Create a new Array as a subsection of this Array, without rank reduction. No data
|
141
|
+
# is moved, so the new Array references the same backing store as the original.
|
142
|
+
# @param origin ruby array specifying the starting index. Must be same rank as
|
143
|
+
# original Array.
|
144
|
+
# @param shape ruby array specifying the extents in each dimension. This becomes the
|
145
|
+
# shape of the returned Array. Must be same rank as original Array.
|
146
|
+
# @param stride array specifying the strides in each dimension. If null, assume all
|
147
|
+
# ones.
|
148
|
+
# @param reduce true if the array should be reduced by removing dimensions of size 1
|
149
|
+
# @returns new Array
|
150
|
+
# Throws:
|
151
|
+
# InvalidRangeException - if ranges is invalid
|
142
152
|
#------------------------------------------------------------------------------------
|
143
153
|
|
144
154
|
def section_with_stride(origin, shape, stride, reduce = false)
|
@@ -168,6 +178,63 @@ class MDArray
|
|
168
178
|
@section
|
169
179
|
end
|
170
180
|
|
181
|
+
#------------------------------------------------------------------------------------
|
182
|
+
# Create a new Array using same backing store as this Array, by fixing the specified
|
183
|
+
# dimension at the specified index value. This reduces rank by 1.
|
184
|
+
# @param dim dimension to fix
|
185
|
+
# @param val value in which to fix the dimension
|
186
|
+
# @return new array sliced at the given dimension on the specified value
|
187
|
+
#------------------------------------------------------------------------------------
|
188
|
+
|
189
|
+
def slice(dim, val)
|
190
|
+
|
191
|
+
arr = @nc_array.slice(dim, val)
|
192
|
+
slice = MDArray.new(@type, arr, true)
|
193
|
+
copy_print_parameters(slice)
|
194
|
+
return slice
|
195
|
+
|
196
|
+
end
|
197
|
+
|
198
|
+
#------------------------------------------------------------------------------------
|
199
|
+
#
|
200
|
+
#------------------------------------------------------------------------------------
|
201
|
+
|
202
|
+
def each_slice(axes, reduce = true)
|
203
|
+
|
204
|
+
counter = Counter.new(self)
|
205
|
+
|
206
|
+
sizes = Array.new
|
207
|
+
(0..rank - 1).each do |axis|
|
208
|
+
if (axes.include?(axis))
|
209
|
+
sizes[axis] = 1
|
210
|
+
else
|
211
|
+
sizes[axis] = shape[axis]
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
counter.each_along_axes(axes) do |ct|
|
216
|
+
yield section(ct, sizes, reduce) if block_given?
|
217
|
+
end
|
218
|
+
|
219
|
+
end
|
220
|
+
|
221
|
+
#------------------------------------------------------------------------------------
|
222
|
+
# Create a new Array using same backing store as this Array, by transposing two of
|
223
|
+
# the indices.
|
224
|
+
# @param dim1 first dimension index
|
225
|
+
# @param dim2 second dimension index
|
226
|
+
# @return new array with dimensions transposed
|
227
|
+
#------------------------------------------------------------------------------------
|
228
|
+
|
229
|
+
def transpose(dim1, dim2)
|
230
|
+
|
231
|
+
arr = @nc_array.transpose(dim1, dim2)
|
232
|
+
transpose = MDArray.new(@type, arr, true)
|
233
|
+
copy_print_parameters(transpose)
|
234
|
+
return transpose
|
235
|
+
|
236
|
+
end
|
237
|
+
|
171
238
|
#------------------------------------------------------------------------------------
|
172
239
|
#
|
173
240
|
#------------------------------------------------------------------------------------
|
data/test/test_boolean.rb
CHANGED
@@ -2,9 +2,10 @@ require 'rubygems'
|
|
2
2
|
require "test/unit"
|
3
3
|
require 'shoulda'
|
4
4
|
|
5
|
-
require 'env'
|
6
5
|
require 'mdarray'
|
7
6
|
|
7
|
+
require_relative 'env'
|
8
|
+
|
8
9
|
class MDArrayTest < Test::Unit::TestCase
|
9
10
|
|
10
11
|
context "Arithmetic Tests" do
|
@@ -57,8 +58,8 @@ class MDArrayTest < Test::Unit::TestCase
|
|
57
58
|
result = @bool2 | @bool1
|
58
59
|
assert_equal("true false true true ", result.to_string)
|
59
60
|
|
60
|
-
|
61
|
-
|
61
|
+
result = @bool1.not
|
62
|
+
assert_equal("false true false true ", result.to_string)
|
62
63
|
|
63
64
|
end
|
64
65
|
|
data/test/test_complete.rb
CHANGED
@@ -21,10 +21,12 @@
|
|
21
21
|
|
22
22
|
require 'simplecov'
|
23
23
|
|
24
|
+
#require_relative 'env'
|
25
|
+
|
24
26
|
#=begin
|
25
27
|
SimpleCov.start do
|
26
28
|
@filters = []
|
27
|
-
add_group "MDArray", "F:/rbotafogo/cygwin/home/zxb3/Desenv/MDArray/
|
29
|
+
add_group "MDArray", "F:/rbotafogo/cygwin/home/zxb3/Desenv/MDArray/lib"
|
28
30
|
end
|
29
31
|
#=end
|
30
32
|
|
@@ -54,16 +56,20 @@ end
|
|
54
56
|
# * itemsize: ??
|
55
57
|
# Differently from NumPy, it is not possible to get the internal buffer
|
56
58
|
|
59
|
+
#=begin
|
60
|
+
require_relative 'test_creation'
|
61
|
+
require_relative 'test_access'
|
62
|
+
require_relative 'test_operator'
|
63
|
+
require_relative 'arithmetic_casting'
|
64
|
+
require_relative 'test_comparison'
|
65
|
+
require_relative 'test_boolean'
|
66
|
+
require_relative 'test_shape'
|
67
|
+
require_relative 'test_counter'
|
68
|
+
require_relative 'test_trigonometry'
|
69
|
+
require_relative 'test_views'
|
70
|
+
require_relative 'test_printing'
|
71
|
+
require_relative 'test_statistics'
|
72
|
+
#=end
|
73
|
+
|
74
|
+
# require_relative 'test_speed'
|
57
75
|
|
58
|
-
require 'test_creation'
|
59
|
-
require 'test_access'
|
60
|
-
require 'test_operator' # Fix user's operators contruction
|
61
|
-
require 'arithmetic_casting'
|
62
|
-
require 'test_comparison'
|
63
|
-
# require 'test_boolean'
|
64
|
-
require 'test_shape'
|
65
|
-
require 'test_counter'
|
66
|
-
require 'test_trigonometry'
|
67
|
-
# require 'test_statistics'
|
68
|
-
# require 'test_slices'
|
69
|
-
# require 'test_speed'
|
data/test/test_counter.rb
CHANGED
@@ -119,13 +119,11 @@ class MDArrayTest < Test::Unit::TestCase
|
|
119
119
|
|
120
120
|
counter = MDArray::Counter.new(@a)
|
121
121
|
counter.each_along_axes([0, 2]) do |counter|
|
122
|
-
|
122
|
+
counter
|
123
123
|
end
|
124
124
|
|
125
|
-
printf "\n"
|
126
|
-
|
127
125
|
counter.each_along_axes([0, 1, 2]) do |counter|
|
128
|
-
|
126
|
+
counter
|
129
127
|
end
|
130
128
|
|
131
129
|
end
|
@@ -138,21 +136,6 @@ class MDArrayTest < Test::Unit::TestCase
|
|
138
136
|
|
139
137
|
end
|
140
138
|
|
141
|
-
=begin
|
142
|
-
#-------------------------------------------------------------------------------------
|
143
|
-
#
|
144
|
-
#-------------------------------------------------------------------------------------
|
145
|
-
|
146
|
-
should "issue errors if range is used as index" do
|
147
|
-
|
148
|
-
index = MDArray::Index.new(@a)
|
149
|
-
index.set_start([/1:1/, /0:2/, 1, 1])
|
150
|
-
|
151
|
-
end
|
152
|
-
|
153
|
-
=end
|
154
|
-
|
155
|
-
|
156
139
|
=begin
|
157
140
|
should "allow partial access to the array" do
|
158
141
|
|
data/test/test_creation.rb
CHANGED
data/test/test_operator.rb
CHANGED
@@ -51,6 +51,9 @@ class MDArrayTest < Test::Unit::TestCase
|
|
51
51
|
@h = MDArray.byte([1], [13])
|
52
52
|
@i = MDArray.double([4], [2.0, 6.0, 5.0, 9.0])
|
53
53
|
|
54
|
+
@bool1 = MDArray.boolean([4], [true, false, true, false])
|
55
|
+
@bool2 = MDArray.boolean([4], [false, false, true, true])
|
56
|
+
|
54
57
|
end # setup
|
55
58
|
|
56
59
|
#-------------------------------------------------------------------------------------
|
@@ -242,6 +245,17 @@ class MDArrayTest < Test::Unit::TestCase
|
|
242
245
|
|
243
246
|
end
|
244
247
|
|
248
|
+
#-------------------------------------------------------------------------------------
|
249
|
+
#
|
250
|
+
#-------------------------------------------------------------------------------------
|
251
|
+
|
252
|
+
should "not allow operation between numeric and non-numeric types" do
|
253
|
+
|
254
|
+
assert_raise (RuntimeError) { result = @c + @bool1 }
|
255
|
+
assert_raise (RuntimeError) { result = @c + "this is a test" }
|
256
|
+
|
257
|
+
end
|
258
|
+
|
245
259
|
#------------------------------------------------------------------------------------
|
246
260
|
#
|
247
261
|
#------------------------------------------------------------------------------------
|
@@ -306,29 +320,28 @@ class MDArrayTest < Test::Unit::TestCase
|
|
306
320
|
# array will be double
|
307
321
|
c = @a.addd(@b)
|
308
322
|
assert_equal("double", c.type)
|
309
|
-
c.print
|
310
323
|
|
311
324
|
# request that resulting array of type int is ignored when using addd
|
312
325
|
c = @a.addd(@b, "int")
|
313
326
|
assert_equal("double", c.type)
|
314
327
|
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
328
|
+
# Crete method perc_inc and add it into the double MDArray.
|
329
|
+
UserFunction.binary_operator("perc_inc", :default,
|
330
|
+
Proc.new { |val1, val2| (val2 - val1) / val1 },
|
331
|
+
"double")
|
319
332
|
|
320
333
|
result = @c.perc_inc @i
|
321
334
|
assert_equal("0.06951871657754005 0.12359550561797755 -0.3036211699164345 0.018099547511312233 ", result.to_string)
|
322
335
|
|
323
336
|
# do it in place
|
324
|
-
|
337
|
+
UserFunction.binary_operator("perc_inc!", :in_place,
|
338
|
+
Proc.new { |val1, val2| (val2 - val1) / val1 },
|
339
|
+
"double")
|
325
340
|
|
326
|
-
#
|
327
|
-
# @c.binary_operator = BinaryOperator
|
341
|
+
# "0.06951871514320374 0.1235954761505127 -0.3036211431026459 0.018099529668688774 "
|
328
342
|
|
329
343
|
@c.perc_inc! @i
|
330
344
|
assert_equal("0.06951871657754005 0.12359550561797755 -0.3036211699164345 0.018099547511312233 ", @c.to_string)
|
331
|
-
=end
|
332
345
|
|
333
346
|
end
|
334
347
|
|
data/test/test_printing.rb
CHANGED
@@ -37,18 +37,13 @@ class MDArrayTest < Test::Unit::TestCase
|
|
37
37
|
#
|
38
38
|
#-------------------------------------------------------------------------------------
|
39
39
|
|
40
|
-
|
41
|
-
should "apply a method over axes" do
|
42
|
-
@e.apply_over_axes([0, 2])
|
43
|
-
# @e.section([0, 0, 0], [1, 5, 1])
|
44
|
-
# @e.print
|
45
|
-
end
|
46
|
-
|
47
|
-
#=begin
|
48
40
|
should "print 1D array" do
|
49
41
|
@a.print
|
50
42
|
end
|
51
|
-
|
43
|
+
|
44
|
+
#-------------------------------------------------------------------------------------
|
45
|
+
#
|
46
|
+
#-------------------------------------------------------------------------------------
|
52
47
|
|
53
48
|
should "print nD array" do
|
54
49
|
@d.print
|
@@ -57,6 +52,10 @@ class MDArrayTest < Test::Unit::TestCase
|
|
57
52
|
@g.print
|
58
53
|
end
|
59
54
|
|
55
|
+
#-------------------------------------------------------------------------------------
|
56
|
+
#
|
57
|
+
#-------------------------------------------------------------------------------------
|
58
|
+
|
60
59
|
should "print output to csv" do
|
61
60
|
@e.to_csv
|
62
61
|
end
|
data/test/test_statistics.rb
CHANGED
@@ -2,9 +2,7 @@ require 'rubygems'
|
|
2
2
|
require "test/unit"
|
3
3
|
require 'shoulda'
|
4
4
|
|
5
|
-
require 'env'
|
6
5
|
require 'mdarray'
|
7
|
-
require 'benchmark'
|
8
6
|
|
9
7
|
class MDArrayTest < Test::Unit::TestCase
|
10
8
|
|
@@ -27,16 +25,11 @@ class MDArrayTest < Test::Unit::TestCase
|
|
27
25
|
|
28
26
|
should "do stats operations" do
|
29
27
|
|
30
|
-
# @a.unary_operator = FastUnaryOperator
|
31
28
|
assert_equal(49995000, @a.sum)
|
32
29
|
assert_equal(0, @a.min)
|
33
30
|
assert_equal(9999, @a.max)
|
34
31
|
assert_equal(4999.5, @a.mean)
|
35
|
-
|
36
|
-
# @a.binary_operator = BinaryOperator
|
37
|
-
puts Benchmark.measure {
|
38
|
-
assert_equal(6666.333333333333, @a.weighted_mean(@weight)[0])
|
39
|
-
}
|
32
|
+
assert_equal(6666.333333333333, @a.weighted_mean(@weight)[0])
|
40
33
|
|
41
34
|
end
|
42
35
|
|
data/test/test_views.rb
ADDED
@@ -0,0 +1,291 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require "test/unit"
|
3
|
+
require 'shoulda'
|
4
|
+
|
5
|
+
require 'mdarray'
|
6
|
+
|
7
|
+
class MDArrayTest < Test::Unit::TestCase
|
8
|
+
|
9
|
+
context "Slice Tests" do
|
10
|
+
|
11
|
+
setup do
|
12
|
+
|
13
|
+
# creates an array from a function (actually a block). The name fromfunction
|
14
|
+
# is preserved to maintain API compatibility with NumPy (is it necessary?)
|
15
|
+
|
16
|
+
# simulating financial data: 1 year, 20 days, 10 securities, 7 values (open,
|
17
|
+
# close, high, low, volume, e1, e2)
|
18
|
+
@a = MDArray.fromfunction("double", [1, 20, 10, 7]) do |x, y, z, k|
|
19
|
+
0.5 * x + y + 10 * (z + 1) + Math.sin(k + x)
|
20
|
+
end
|
21
|
+
|
22
|
+
@b = MDArray.int([2, 2])
|
23
|
+
@c = MDArray.fromfunction("double", [2, 3, 4]) do |x, y, z|
|
24
|
+
x + y + z
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
#-------------------------------------------------------------------------------------
|
30
|
+
# Create a new Array using same backing store as this Array, by fixing the specified
|
31
|
+
# dimension at the specified index value. This reduces rank by 1.
|
32
|
+
#-------------------------------------------------------------------------------------
|
33
|
+
|
34
|
+
should "slice an array" do
|
35
|
+
|
36
|
+
# @c rank is [2, 3, 4]. @c is the following array
|
37
|
+
# [[[0.00 1.00 2.00 3.00]
|
38
|
+
# [1.00 2.00 3.00 4.00]
|
39
|
+
# [2.00 3.00 4.00 5.00]]
|
40
|
+
#
|
41
|
+
# [[1.00 2.00 3.00 4.00]
|
42
|
+
# [2.00 3.00 4.00 5.00]
|
43
|
+
# [3.00 4.00 5.00 6.00]]]
|
44
|
+
|
45
|
+
# take a slice of c on the first dimension (0) and taking only the first (0) index,
|
46
|
+
# we should get the following array:
|
47
|
+
# [[0.00 1.00 2.00 3.00]
|
48
|
+
# [1.00 2.00 3.00 4.00]
|
49
|
+
# [2.00 3.00 4.00 5.00]]
|
50
|
+
arr = @c.slice(0, 0)
|
51
|
+
assert_equal(1, arr[0, 1])
|
52
|
+
assert_equal(4, arr[2, 2])
|
53
|
+
assert_equal(5, arr[2, 3])
|
54
|
+
|
55
|
+
# take a slice of c on the first dimension (0) and taking only the second (1) index,
|
56
|
+
# we should get the following array:
|
57
|
+
# [[1.00 2.00 3.00 4.00]
|
58
|
+
# [2.00 3.00 4.00 5.00]
|
59
|
+
# [3.00 4.00 5.00 6.00]]
|
60
|
+
arr = @c.slice(0, 1)
|
61
|
+
assert_equal(2, arr[0, 1])
|
62
|
+
assert_equal(4, arr[0, 3])
|
63
|
+
assert_equal(5, arr[1, 3])
|
64
|
+
|
65
|
+
# take a slice of c on the second dimension (1) and taking only the second (1) index,
|
66
|
+
# we should get the following array:
|
67
|
+
# [[1.00 2.00 3.00 4.00]
|
68
|
+
# [2.00 3.00 4.00 5.00]]
|
69
|
+
arr = @c.slice(1, 1)
|
70
|
+
assert_equal(2, arr[0, 1])
|
71
|
+
assert_equal(2, arr[1, 0])
|
72
|
+
|
73
|
+
# take a slice of c on the third dimension (2) and taking only the third (2) index,
|
74
|
+
# we should get the following array:
|
75
|
+
# [[2.00 3.00 4.00]
|
76
|
+
# [3.00 4.00 5.00]]
|
77
|
+
arr = @c.slice(2, 2)
|
78
|
+
assert_equal(3, arr[0, 1])
|
79
|
+
assert_equal(5, arr[1, 2])
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
#-------------------------------------------------------------------------------------
|
84
|
+
#
|
85
|
+
#-------------------------------------------------------------------------------------
|
86
|
+
|
87
|
+
should "get array section" do
|
88
|
+
|
89
|
+
# 1 -> first year (only 1 year)
|
90
|
+
# 20 -> 20 days
|
91
|
+
# 10 -> number os secs
|
92
|
+
# 7 - > number of values
|
93
|
+
|
94
|
+
# b is a section of @a, starting at position (0) and taking only the first two
|
95
|
+
# elements of the first dimension. Getting all values, for all secs for the first
|
96
|
+
# 2 days
|
97
|
+
b = @a.section([0, 0, 0, 0], [1, 2, 10, 7])
|
98
|
+
assert_equal(true, b.section?)
|
99
|
+
assert_equal([1, 2, 10, 7], b.shape)
|
100
|
+
ind = b.get_index
|
101
|
+
ind.each do |elmt|
|
102
|
+
assert_equal(@a.get(elmt), b.get(elmt))
|
103
|
+
end
|
104
|
+
|
105
|
+
# getting "open" for the first 2 days of the 2nd sec. Values are organized
|
106
|
+
# as follows:
|
107
|
+
# (open, close, high, low, volume, e1, e2).
|
108
|
+
# Start at: [0, 0, 3, 0] =>
|
109
|
+
# 0 -> first year, 0 -> first day, 3 -> 2nd sec, 0 -> first value
|
110
|
+
# Specification: [1, 2, 1, 1] =>
|
111
|
+
# 1 -> get only first year, 2 -> take 2 days from day 0 to day 1,
|
112
|
+
# 1 -> take one security, already selected the 2nd one, 1 -> only one value
|
113
|
+
# in this case the first one was selected.
|
114
|
+
b = @a.section([0, 0, 3, 0], [1, 2, 1, 1])
|
115
|
+
assert_equal(40.00, b[0, 0, 0, 0])
|
116
|
+
assert_equal(41.00, b[0, 1, 0, 0])
|
117
|
+
|
118
|
+
# getting "close" (2nd) value of the 3rd sec for the second day with
|
119
|
+
# shape reduction. Note that in this case, with shape reduction, b is a
|
120
|
+
# number and not an array any more
|
121
|
+
b = @a.section([0, 1, 2, 1], [1, 1, 1, 1], true)
|
122
|
+
assert_equal(@a[0, 1, 2, 1], b)
|
123
|
+
|
124
|
+
# getting the "close" (2nd) value of the 3rd sec for the second day without
|
125
|
+
# shape reduction
|
126
|
+
b = @a.section([0, 1, 2, 1], [1, 1, 1, 1])
|
127
|
+
assert_equal([1, 1, 1, 1], b.shape)
|
128
|
+
assert_equal(@a[0, 1, 2, 1], b[0, 0, 0, 0])
|
129
|
+
|
130
|
+
# getting the "open" (1rst) value of the second secs for two days
|
131
|
+
b = @a.section([0, 0, 0, 0], [1, 2, 1, 1])
|
132
|
+
assert_equal([1, 2, 1, 1], b.shape)
|
133
|
+
assert_equal(@a[0, 0, 0, 0], b[0, 0, 0, 0])
|
134
|
+
assert_equal(@a[0, 1, 0, 0], b[0, 1, 0, 0])
|
135
|
+
|
136
|
+
# getting the "open" (1rst) value of the second secs for two days with rank
|
137
|
+
# reduction
|
138
|
+
b = @a.section([0, 0, 0, 0], [1, 2, 1, 1], true)
|
139
|
+
assert_equal([2], b.shape)
|
140
|
+
assert_equal(@a[0, 0, 0, 0], b[0])
|
141
|
+
assert_equal(@a[0, 1, 0, 0], b[1])
|
142
|
+
|
143
|
+
# getting the first security, all values
|
144
|
+
b = @a.section([0, 0, 0, 0], [1, 1, 1, 7])
|
145
|
+
# b.print
|
146
|
+
|
147
|
+
# getting the 2 security, all values
|
148
|
+
b = @a.section([0, 0, 1, 0], [1, 1, 1, 7])
|
149
|
+
# b.print
|
150
|
+
|
151
|
+
# getting the 1 day, all then secs
|
152
|
+
b = @a.section([0, 0, 0, 0], [1, 1, 10, 7])
|
153
|
+
# b.print
|
154
|
+
|
155
|
+
# getting the "open" (1st) value of all secs for the first day
|
156
|
+
b = @a.section([0, 0, 0, 0], [1, 1, 10, 1])
|
157
|
+
# b.print
|
158
|
+
|
159
|
+
end
|
160
|
+
|
161
|
+
#-------------------------------------------------------------------------------------
|
162
|
+
# each_along_axes returns sub-arrays (sections) of the original array. Each section
|
163
|
+
# is taken by walking along the given axis and getting all elements of the
|
164
|
+
# axis that were not given.
|
165
|
+
#-------------------------------------------------------------------------------------
|
166
|
+
|
167
|
+
should "split array in subarrays with or without reduction" do
|
168
|
+
|
169
|
+
# 1 -> first year (only 1 year)
|
170
|
+
# 20 -> 20 days
|
171
|
+
# 10 -> number os secs
|
172
|
+
# 7 - > number of values
|
173
|
+
|
174
|
+
# Should generate 1 array with all elements, since the first dimension has only
|
175
|
+
# one element. For this test cannot reduce the array as this would have @a and
|
176
|
+
# slice have different dimensions
|
177
|
+
@a.each_slice([0], false) do |slice|
|
178
|
+
slice.each_with_counter do |value, counter|
|
179
|
+
assert_equal(value, @a.get(counter))
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
# Should generate 20 arrays one for each day. Since slice uses the same backing
|
184
|
+
# store as @a, there isn't much of memory waist.
|
185
|
+
arrays = Array.new
|
186
|
+
@a.each_slice([1]) do |slice|
|
187
|
+
arrays << slice
|
188
|
+
end
|
189
|
+
|
190
|
+
arrays[0].reset_traversal
|
191
|
+
@a.slice(1, 0).each do |val|
|
192
|
+
assert_equal(val, arrays[0].get_next)
|
193
|
+
end
|
194
|
+
|
195
|
+
# Should generate 10 arrays one for each security
|
196
|
+
arrays.clear
|
197
|
+
@a.each_slice([2]) do |slice|
|
198
|
+
arrays << slice
|
199
|
+
end
|
200
|
+
|
201
|
+
arrays[6].reset_traversal
|
202
|
+
@a.slice(2, 6).each do |val|
|
203
|
+
assert_equal(val, arrays[6].get_next)
|
204
|
+
end
|
205
|
+
|
206
|
+
# For instance, array @a shape is [1, 20, 10, 7]. Slicing along the fourth axes
|
207
|
+
# (index 3) will get the following sections of @a:
|
208
|
+
# section([0, 0, 0, 0], [1, 20, 10, 1], true),
|
209
|
+
# section([0, 0, 0, 1], [1, 20, 10, 1], true),
|
210
|
+
# section([0, 0, 0, 2], [1, 20, 10, 1], true),
|
211
|
+
# ...
|
212
|
+
# section([0, 0, 0, 6], [1, 20, 10, 1], true),
|
213
|
+
|
214
|
+
# In this case, we get 7 arrays. First for all opens, sencond for all closes,
|
215
|
+
# third for all highs, fourth for all closes, etc.
|
216
|
+
arrays.clear
|
217
|
+
@a.each_slice([3]) do |slice|
|
218
|
+
arrays << slice
|
219
|
+
end
|
220
|
+
assert_equal(7, arrays.size)
|
221
|
+
|
222
|
+
|
223
|
+
# Although method slice only slices on one dimension, we can each_slice on multiple
|
224
|
+
# dimensions
|
225
|
+
|
226
|
+
# For instance, array @a shape is [1, 20, 10, 7]. Slicing
|
227
|
+
# along axes [1, 2] will generate 200 arrays = 20 * 10. 20 days times 10 secs. In this
|
228
|
+
# case we will have one array for every day and every securities quote (open, close, etc.)
|
229
|
+
arrays.clear
|
230
|
+
@a.each_slice([1, 2]) do |slice|
|
231
|
+
arrays << slice
|
232
|
+
end
|
233
|
+
|
234
|
+
# We can get the equivalent of arrays[0] above by doing the following set of operations
|
235
|
+
# @a.slice(1,0);
|
236
|
+
# now slice it again at (1, 0), since now the second dimension has become the first
|
237
|
+
# reduce the array so that only 1 dimension is left
|
238
|
+
assert_equal(arrays[0].to_string, @a.slice(1, 0).slice(1, 0).reduce.to_string)
|
239
|
+
|
240
|
+
|
241
|
+
# Changing the order of axis in the parameter list does change the final result as
|
242
|
+
# each_slice moves first the last axis in the array given. In this example, it will
|
243
|
+
# first increment axis 1 and then axis 2. On the prvious example, axis 2 was
|
244
|
+
# incremented prior to axis 1.
|
245
|
+
arr2 = Array.new
|
246
|
+
@a.each_slice([2, 1]) do |slice|
|
247
|
+
arr2 << slice
|
248
|
+
end
|
249
|
+
|
250
|
+
end
|
251
|
+
|
252
|
+
#-------------------------------------------------------------------------------------
|
253
|
+
#-------------------------------------------------------------------------------------
|
254
|
+
|
255
|
+
should "permute array indices" do
|
256
|
+
|
257
|
+
# c shape is [2, 3, 4]
|
258
|
+
# b is the same array as c... no permutation was done.
|
259
|
+
# b shape still is [2, 3, 4]. Both b and @c point to the same backing store
|
260
|
+
b = @c.permute([0, 1, 2])
|
261
|
+
assert_equal([2, 3, 4], b.shape)
|
262
|
+
# b shape is now [3, 2, 4]
|
263
|
+
b = @c.permute([1, 0, 2])
|
264
|
+
assert_equal([3, 2, 4], b.shape)
|
265
|
+
# b shape is now [3, 4, 2]
|
266
|
+
b = @c.permute([1, 2, 0])
|
267
|
+
assert_equal([3, 4, 2], b.shape)
|
268
|
+
|
269
|
+
end
|
270
|
+
|
271
|
+
#-------------------------------------------------------------------------------------
|
272
|
+
# Creates views of an array by transposing original arrays dimensions. Uses the same
|
273
|
+
# backing store as the original array.
|
274
|
+
#-------------------------------------------------------------------------------------
|
275
|
+
|
276
|
+
should "permute array indices" do
|
277
|
+
|
278
|
+
# c shape is [2, 3, 4]
|
279
|
+
# b shape is now [3, 2, 4] by transposing the first two dimensions
|
280
|
+
b = @c.transpose(0, 1)
|
281
|
+
assert_equal([3, 2, 4], b.shape)
|
282
|
+
|
283
|
+
# b shape is now [2, 4, 3]
|
284
|
+
b = @c.transpose(1, 2)
|
285
|
+
assert_equal([2, 4, 3], b.shape)
|
286
|
+
|
287
|
+
end
|
288
|
+
|
289
|
+
end
|
290
|
+
|
291
|
+
end
|