-
Notifications
You must be signed in to change notification settings - Fork 0
NArray Redesign
Rough documentation of the behavior of Masahiro Tanaka's redesign of NArray. Right now, this code is highly experimental and expected to change.
NArray is now housed under the Num module. The rest of this document will refer to the Num library rather than NArray so there is no confusion as to which version I am referring to. Focus will be on new features, but also how Num differs from NArray.
ATTRIBUTION: most code examples are copied or modified from Masahiro Tanaka's test suite.
By default, Num follows the indexing order convention of Matlab, Numpy, C, Ruby Matrix and Ruby multidimensional arrays (opposite NArray, PDL, and Fortran). This is a good thing for consistency.
>> x = Num::Int32.new([2,3]).seq
=> Num::Int32#shape=[2,3]:
[[0, 1, 2],
[3, 4, 5]]
>> x[0,2]
=> 2
>> x[1,2]
=> 5
# same order as a ruby multidimensional array:
a = [[0,1,2],
[3,4,5]]
a[1][2] # => 5
# same order as a ruby Matrix
require 'matrix'
b = Matrix[[0,1,2],[3,4,5]] ;
b[1,2] # => 5
The format is simple, 'start:stop:step'
>> a = Num::DFloat.new([5,5]).seq
=> Num::DFloat#shape=[5,5]:
[[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9],
[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19],
[20, 21, 22, 23, 24]]
>> a['1:3,::2']
=> Num::DFloat#shape=[3,3]:
[[5, 7, 9],
[10, 12, 14],
[15, 17, 19]]
>> a['1:3,1::2']
=> Num::DFloat#shape=[3,2]:
[[6, 8],
[11, 13],
[16, 18]]
>> a['1:3,:']
=> Num::DFloat#shape=[3,5]:
[[5, 6, 7, 8, 9],
[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19]]
NArray makes a deep copy upon indexing, but Num makes a shallow copy (like Numpy) when indexing:
>> a = Num::DFloat.new([5,5]).seq
=> Num::DFloat#shape=[5,5]:
[[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9],
[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19],
[20, 21, 22, 23, 24]]
>> b = a['1:3,::2']
=> Num::DFloat#shape=[3,3]:
[[5, 7, 9],
[10, 12, 14],
[15, 17, 19]]
>> b.fill(10000)
=> Num::DFloat#shape=[3,3]:
[[10000, 10000, 10000],
[10000, 10000, 10000],
[10000, 10000, 10000]]
>> a
=> Num::DFloat#shape=[5,5]:
[[0, 1, 2, 3, 4],
[10000, 6, 10000, 8, 10000],
[10000, 11, 10000, 13, 10000],
[10000, 16, 10000, 18, 10000],
[20, 21, 22, 23, 24]]
Num allows the definition of custom types. A serious feature.
Hoge = Num::NStruct.new() do |m|
add_type(Num::DFloat, :f64)
add_type(Num::Int32, :i32)
end
Hoge.byte_size # => 12
x = Hoge.new([3,4])
x.byte_size # => 144
>> x.definition(0)
=> [:f64, Num::DFloat, 0, 8]
>> x.definition(:f64)
=> [:f64, Num::DFloat, 0, 8]
>> x.definition(1)
=> [:i32, Num::Int32, 8, 4]
>> x.definitions
=> [[:f64, Num::DFloat, 0, 8], [:i32, Num::Int32, 8, 4]]
>> x.field(:f64).seq.inplace * 2.4 + 0.5
=> Num::DFloat#shape=[3,4]:
[[0.5, 2.9, 5.3, 7.7],
[10.1, 12.5, 14.9, 17.3],
[19.7, 22.1, 24.5, 26.9]]
>> x.field(:i32).seq.inplace * 2 + 3
=> Num::Int32#shape=[3,4]:
[[3, 5, 7, 9],
[11, 13, 15, 17],
[19, 21, 23, 25]]
>> x[0,1].field(:f64)
=> Num::DFloat#shape=[]:
(scalar)2.9
>> x[0,1].field(:i32)
=> Num::Int32#shape=[]:
(scalar)5