-
Notifications
You must be signed in to change notification settings - Fork 7
Views
Rodrigo Botafogo edited this page May 20, 2013
·
1 revision
setup do
# creates an array from a function (actually a block). The name fromfunction
# is preserved to maintain API compatibility with NumPy (is it necessary?)
# simulating financial data: 1 year, 20 days, 10 securities, 7 values (open,
# close, high, low, volume, e1, e2)
@a = MDArray.fromfunction("double", [1, 20, 10, 7]) do |x, y, z, k|
0.5 * x + y + 10 * (z + 1) + Math.sin(k + x)
end
@b = MDArray.int([2, 2])
@c = MDArray.fromfunction("double", [2, 3, 4]) do |x, y, z|
x + y + z
end
end
#-------------------------------------------------------------------------------------
# Create a new Array using same backing store as this Array, by fixing the specified
# dimension at the specified index value. This reduces rank by 1.
#-------------------------------------------------------------------------------------
should "slice an array" do
# @c rank is [2, 3, 4]. @c is the following array
# [[[0.00 1.00 2.00 3.00]
# [1.00 2.00 3.00 4.00]
# [2.00 3.00 4.00 5.00]]
#
# [[1.00 2.00 3.00 4.00]
# [2.00 3.00 4.00 5.00]
# [3.00 4.00 5.00 6.00]]]
# take a slice of c on the first dimension (0) and taking only the first (0) index,
# we should get the following array:
# [[0.00 1.00 2.00 3.00]
# [1.00 2.00 3.00 4.00]
# [2.00 3.00 4.00 5.00]]
arr = @c.slice(0, 0)
assert_equal(1, arr[0, 1])
assert_equal(4, arr[2, 2])
assert_equal(5, arr[2, 3])
# take a slice of c on the first dimension (0) and taking only the second (1) index,
# we should get the following array:
# [[1.00 2.00 3.00 4.00]
# [2.00 3.00 4.00 5.00]
# [3.00 4.00 5.00 6.00]]
arr = @c.slice(0, 1)
assert_equal(2, arr[0, 1])
assert_equal(4, arr[0, 3])
assert_equal(5, arr[1, 3])
# take a slice of c on the second dimension (1) and taking only the second (1) index,
# we should get the following array:
# [[1.00 2.00 3.00 4.00]
# [2.00 3.00 4.00 5.00]]
arr = @c.slice(1, 1)
assert_equal(2, arr[0, 1])
assert_equal(2, arr[1, 0])
# take a slice of c on the third dimension (2) and taking only the third (2) index,
# we should get the following array:
# [[2.00 3.00 4.00]
# [3.00 4.00 5.00]]
arr = @c.slice(2, 2)
assert_equal(3, arr[0, 1])
assert_equal(5, arr[1, 2])
end
#-------------------------------------------------------------------------------------
#
#-------------------------------------------------------------------------------------
should "get array section" do
# 1 -> first year (only 1 year)
# 20 -> 20 days
# 10 -> number os secs
# 7 - > number of values
# b is a section of @a, starting at position (0) and taking only the first two
# elements of the first dimension. Getting all values, for all secs for the first
# 2 days
b = @a.section([0, 0, 0, 0], [1, 2, 10, 7])
assert_equal(true, b.section?)
assert_equal([1, 2, 10, 7], b.shape)
ind = b.get_index
ind.each do |elmt|
assert_equal(@a.get(elmt), b.get(elmt))
end
# getting "open" for the first 2 days of the 2nd sec. Values are organized
# as follows:
# (open, close, high, low, volume, e1, e2).
# Start at: [0, 0, 3, 0] =>
# 0 -> first year, 0 -> first day, 3 -> 2nd sec, 0 -> first value
# Specification: [1, 2, 1, 1] =>
# 1 -> get only first year, 2 -> take 2 days from day 0 to day 1,
# 1 -> take one security, already selected the 2nd one, 1 -> only one value
# in this case the first one was selected.
b = @a.section([0, 0, 3, 0], [1, 2, 1, 1])
assert_equal(40.00, b[0, 0, 0, 0])
assert_equal(41.00, b[0, 1, 0, 0])
# getting "close" (2nd) value of the 3rd sec for the second day with
# shape reduction. Note that in this case, with shape reduction, b is a
# number and not an array any more
b = @a.section([0, 1, 2, 1], [1, 1, 1, 1], true)
assert_equal(@a[0, 1, 2, 1], b)
# getting the "close" (2nd) value of the 3rd sec for the second day without
# shape reduction
b = @a.section([0, 1, 2, 1], [1, 1, 1, 1])
assert_equal([1, 1, 1, 1], b.shape)
assert_equal(@a[0, 1, 2, 1], b[0, 0, 0, 0])
# getting the "open" (1rst) value of the second secs for two days
b = @a.section([0, 0, 0, 0], [1, 2, 1, 1])
assert_equal([1, 2, 1, 1], b.shape)
assert_equal(@a[0, 0, 0, 0], b[0, 0, 0, 0])
assert_equal(@a[0, 1, 0, 0], b[0, 1, 0, 0])
# getting the "open" (1rst) value of the second secs for two days with rank
# reduction
b = @a.section([0, 0, 0, 0], [1, 2, 1, 1], true)
assert_equal([2], b.shape)
assert_equal(@a[0, 0, 0, 0], b[0])
assert_equal(@a[0, 1, 0, 0], b[1])
# getting the first security, all values
b = @a.section([0, 0, 0, 0], [1, 1, 1, 7])
# b.print
# getting the 2 security, all values
b = @a.section([0, 0, 1, 0], [1, 1, 1, 7])
# b.print
# getting the 1 day, all then secs
b = @a.section([0, 0, 0, 0], [1, 1, 10, 7])
# b.print
# getting the "open" (1st) value of all secs for the first day
b = @a.section([0, 0, 0, 0], [1, 1, 10, 1])
# b.print
end
#-------------------------------------------------------------------------------------
# each_along_axes returns sub-arrays (sections) of the original array. Each section
# is taken by walking along the given axis and getting all elements of the
# axis that were not given.
#-------------------------------------------------------------------------------------
should "split array in subarrays with or without reduction" do
# 1 -> first year (only 1 year)
# 20 -> 20 days
# 10 -> number os secs
# 7 - > number of values
# Should generate 1 array with all elements, since the first dimension has only
# one element. For this test cannot reduce the array as this would have @a and
# slice have different dimensions
@a.each_slice([0], false) do |slice|
slice.each_with_counter do |value, counter|
assert_equal(value, @a.get(counter))
end
end
# Should generate 20 arrays one for each day. Since slice uses the same backing
# store as @a, there isn't much of memory waist.
arrays = Array.new
@a.each_slice([1]) do |slice|
arrays << slice
end
arrays[0].reset_traversal
@a.slice(1, 0).each do |val|
assert_equal(val, arrays[0].get_next)
end
# Should generate 10 arrays one for each security
arrays.clear
@a.each_slice([2]) do |slice|
arrays << slice
end
arrays[6].reset_traversal
@a.slice(2, 6).each do |val|
assert_equal(val, arrays[6].get_next)
end
# For instance, array @a shape is [1, 20, 10, 7]. Slicing along the fourth axes
# (index 3) will get the following sections of @a:
# section([0, 0, 0, 0], [1, 20, 10, 1], true),
# section([0, 0, 0, 1], [1, 20, 10, 1], true),
# section([0, 0, 0, 2], [1, 20, 10, 1], true),
# ...
# section([0, 0, 0, 6], [1, 20, 10, 1], true),
# In this case, we get 7 arrays. First for all opens, sencond for all closes,
# third for all highs, fourth for all closes, etc.
arrays.clear
@a.each_slice([3]) do |slice|
arrays << slice
end
assert_equal(7, arrays.size)
# Although method slice only slices on one dimension, we can each_slice on multiple
# dimensions
# For instance, array @a shape is [1, 20, 10, 7]. Slicing
# along axes [1, 2] will generate 200 arrays = 20 * 10. 20 days times 10 secs. In this
# case we will have one array for every day and every securities quote (open, close, etc.)
arrays.clear
@a.each_slice([1, 2]) do |slice|
arrays << slice
end
# We can get the equivalent of arrays[0] above by doing the following set of operations
# @a.slice(1,0);
# now slice it again at (1, 0), since now the second dimension has become the first
# reduce the array so that only 1 dimension is left
assert_equal(arrays[0].to_string, @a.slice(1, 0).slice(1, 0).reduce.to_string)
# Changing the order of axis in the parameter list does change the final result as
# each_slice moves first the last axis in the array given. In this example, it will
# first increment axis 1 and then axis 2. On the prvious example, axis 2 was
# incremented prior to axis 1.
arr2 = Array.new
@a.each_slice([2, 1]) do |slice|
arr2 << slice
end
end
#-------------------------------------------------------------------------------------
#-------------------------------------------------------------------------------------
should "permute array indices" do
# c shape is [2, 3, 4]
# b is the same array as c... no permutation was done.
# b shape still is [2, 3, 4]. Both b and @c point to the same backing store
b = @c.permute([0, 1, 2])
assert_equal([2, 3, 4], b.shape)
# b shape is now [3, 2, 4]
b = @c.permute([1, 0, 2])
assert_equal([3, 2, 4], b.shape)
# b shape is now [3, 4, 2]
b = @c.permute([1, 2, 0])
assert_equal([3, 4, 2], b.shape)
end
#-------------------------------------------------------------------------------------
# Creates views of an array by transposing original arrays dimensions. Uses the same
# backing store as the original array.
#-------------------------------------------------------------------------------------
should "permute array indices" do
# c shape is [2, 3, 4]
# b shape is now [3, 2, 4] by transposing the first two dimensions
b = @c.transpose(0, 1)
assert_equal([3, 2, 4], b.shape)
# b shape is now [2, 4, 3]
b = @c.transpose(1, 2)
assert_equal([2, 4, 3], b.shape)
end