mdarray 0.4.0-java → 0.4.2-java
Sign up to get free protection for your applications and to get access to all the features.
- 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
|