ruby-numo / numo-narray

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

The behavior of NArray#dot is weird #56

Closed tamuratak closed 7 years ago

tamuratak commented 7 years ago

Hi, the current behavior of NArray#dot seems weird. Given NArray with a vector-like shape, NArray#dot returns a certain result, never raise exception. I think, in case (b) and case (c-2), exception should be raised.

require "numo/narray"
include Numo

x = SFloat[1,2,3]
y = SFloat[1,1,1]
# case (a)
p x.dot(y)  #=> 6.0

x1 = x.reshape(1,3)
y1 = y.reshape(1,3)
# case (b)
p x1.dot(y1)  #=> SFloat[[6, 6, 6]]
p y1.dot(x1)  #=> SFloat[[3, 6, 9]]

z = SFloat[[1,2,3],[4,5,6]]
# case (c-1)
p z.dot(x)  #=> SFloat[14, 32]
# case (c-2)
p z.dot(x1) #=> SFloat[[6, 12, 18],  [15, 30, 45]]

Numpy example.

import numpy as np
print(np.version.version) #=> 1.12.0

x = np.asarray([1.0, 2.0, 3.0])
y = np.asarray([1.0, 1.0, 1.0])
# case (a)
print(x.dot(y)) #=> 6.0

x1 = x.reshape([1,3])
y1 = y.reshape([1,3])
# case (b)
print(x1.dot(y1)) #=> error!
print(y1.dot(x1)) #=> error!

z = np.asarray([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
# case (c-1)
print(z.dot(x))  #=> [ 14.  32.]
# case (c-2)
print(z.dot(x1)) #=> error!

Versions.

$ gem2.3 list --local numo-narray

*** LOCAL GEMS ***

numo-narray (0.9.0.4)

$ ruby2.3 -v
ruby 2.3.3p222 (2016-11-21 revision 56859) [x86_64-darwin13]

$ python2.7 --version
Python 2.7.13

I want to emphasize that I am not saying NArray should behave in the same way as numpy. I don't know much about python and numpy. I am just saying the current behavior of NArray#dot is unreasonable.

Regards.

masa16 commented 7 years ago

This is because dot method is implemented as

( x[false,:new,true] * y.transpose[false,:new] ).sum(-1)

and broadcast rule is applied to axes with shape[axis]==1. Shape check is added in the latest commit. Thank you for reporting.

tamuratak commented 7 years ago

Thank you too.