ruby-numo / numo-narray

Ruby/Numo::NArray - New NArray class library
http://ruby-numo.github.io/narray/
BSD 3-Clause "New" or "Revised" License
415 stars 41 forks source link

How to access by multiple coordinate? #120

Closed naitoh closed 5 years ago

naitoh commented 5 years ago

How to access in coordinates like numpy?

numpy (Examples of expected results.)

>>> a = numpy.arange(20).reshape(4,5)
>>> a
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19]])
>>> a[[0,1,2],[0,2,3]] 
array([ 0,  7, 13])
>>> a[[0,1,2],[0,2,3]] -= 10
>>> a
array([[-10,   1,   2,   3,   4],
       [  5,   6,  -3,   8,   9],
       [ 10,  11,  12,   3,  14],
       [ 15,  16,  17,  18,  19]])

In Numpy, coordinate access can be done by giving an x, y coordinate array (or ndarray) as an argument.

Numo::NArray (Examples of unexpected results.)

>  a = Numo::DFloat.new(4,5).seq
=> Numo::DFloat#shape=[4,5]
[[0, 1, 2, 3, 4], 
 [5, 6, 7, 8, 9], 
 [10, 11, 12, 13, 14], 
 [15, 16, 17, 18, 19]]
> a[[0,1,2],[0,2,3]] 
=> Numo::DFloat(view)#shape=[3,3]
[[0, 2, 3], 
 [5, 7, 8], 
 [10, 12, 13]]
> a[[0,1,2],[0,2,3]] -= 10
=> Numo::DFloat#shape=[3,3]
[[-10, -8, -7], 
 [-5, -3, -2], 
 [0, 2, 3]]
> a
=> Numo::DFloat#shape=[4,5]
[[-10, 1, -8, -7, 4], 
 [-5, 6, -3, -2, 9], 
 [0, 11, 2, 3, 14], 
 [15, 16, 17, 18, 19]]

If Numo::NArray is written in the same way as numpy, it will be the row / column unit specification. That is not the result I want.

Numo::NArray (Examples of expected results.)

>  a = Numo::DFloat.new(4,5).seq
=> Numo::DFloat#shape=[4,5]
[[0, 1, 2, 3, 4], 
 [5, 6, 7, 8, 9], 
 [10, 11, 12, 13, 14], 
 [15, 16, 17, 18, 19]]
> a[[0 * a.shape[1] + 0, 1 * a.shape[1] + 2, 2 * a.shape[1] + 3]]
=> Numo::DFloat(view)#shape=[3]
[0, 7, 13]
> a[[0 * a.shape[1] + 0, 1 * a.shape[1] + 2, 2 * a.shape[1] + 3]] -= 10
=> Numo::DFloat#shape=[3]
[-10, -3, 3]
> a
=> Numo::DFloat#shape=[4,5]
[[-10, 1, 2, 3, 4], 
 [5, 6, -3, 8, 9], 
 [10, 11, 12, 3, 14], 
 [15, 16, 17, 18, 19]]

I got the same result as numpy, but the calculation of coordinates is complicated.

Can you easily specify multiple coordinate specifications?

masa16 commented 5 years ago
> a = Numo::DFloat.new(4,5).seq
=> Numo::DFloat#shape=[4,5]
[[0, 1, 2, 3, 4], 
 [5, 6, 7, 8, 9], 
 [10, 11, 12, 13, 14], 
 [15, 16, 17, 18, 19]]

> a.at([0,1,2],[0,2,3]).inplace - 10
=> Numo::DFloat(view)#shape=[3]
[-10, -3, 3]

> a
=> Numo::DFloat#shape=[4,5]
[[-10, 1, 2, 3, 4], 
 [5, 6, -3, 8, 9], 
 [10, 11, 12, 3, 14], 
 [15, 16, 17, 18, 19]]
naitoh commented 5 years ago

Thank you for your reply! In this way, I can do what I want to do.