[Numpy-discussion] forwarded article (embracing tensors)
I thought the topic of this article might be of interest here: https://groups.google.com/forum/?fromgroups#!topic/julia-dev/GAdcYzmibyo ___ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
Re: [Numpy-discussion] forwarded article (embracing tensors)
On 30 May 2013 13:44, Neal Becker ndbeck...@gmail.com wrote: I thought the topic of this article might be of interest here: https://groups.google.com/forum/?fromgroups#!topic/julia-dev/GAdcYzmibyo I think Julia has great potential, and can, unlike Matlab, rid itself of its tunnel vision on matrices and embrace tensors from the ground up Trying to discredit Matlab for tensors? I appreciate the enthusiasm but consider that there are high quality extensions before trying to discredit other people's work: http://www.sandia.gov/~tgkolda/TensorToolbox/index-2.5.html ___ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
Re: [Numpy-discussion] __array_priority__ ignored if __array__ is present
Hi Frederic, On 16 May 2013 15:58, Frédéric Bastien no...@nouiz.org wrote: I looked yesterday rapidly in the code and didn't find the reason (I don't know it well, that is probably why). But last night I think of one possible cause. I found this code 2 times in the file core/src/umath/ufunc_object.c: if (nin == 2 nout == 1 dtypes[1]-type_num == NPY_OBJECT) { PyObject *_obj = PyTuple_GET_ITEM(args, 1); if (!PyArray_CheckExact(_obj)) { double self_prio, other_prio; self_prio = PyArray_GetPriority(PyTuple_GET_ITEM(args, 0), NPY_SCALAR_PRIORITY); other_prio = PyArray_GetPriority(_obj, NPY_SCALAR_PRIORITY); if (self_prio other_prio _has_reflected_op(_obj, ufunc_name)) { retval = -2; goto fail; } } } It is this code that will call _has_reflected_op() function. The if condition is: dtypes[1]-type_num == NPY_OBJECT I wouldn't be surprised if dtypes[1] isn't NPY_OBJECT when you implement __array__. dtypes is set with those line: retval = ufunc-type_resolver(ufunc, casting, op, type_tup, dtypes); Thanks for looking into this - should this be considered a bug? Tom HTH Fred On Thu, May 16, 2013 at 9:19 AM, Thomas Robitaille thomas.robitai...@gmail.com wrote: Hi everyone, (this was posted as part of another topic, but since it was unrelated, I'm reposting as a separate thread) I've also been having issues with __array_priority__ - the following code behaves differently for __mul__ and __rmul__: import numpy as np class TestClass(object): def __init__(self, input_array): self.array = input_array def __mul__(self, other): print Called __mul__ def __rmul__(self, other): print Called __rmul__ def __array_wrap__(self, out_arr, context=None): print Called __array_wrap__ return TestClass(out_arr) def __array__(self): print Called __array__ return np.array(self.array) with output: In [7]: a = TestClass([1,2,3]) In [8]: print type(np.array([1,2,3]) * a) Called __array__ Called __array_wrap__ class '__main__.TestClass' In [9]: print type(a * np.array([1,2,3])) Called __mul__ type 'NoneType' Is this also an oversight? I opened a ticket for it a little while ago: https://github.com/numpy/numpy/issues/3164 Any ideas? Thanks! Tom ___ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion ___ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion ___ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
[Numpy-discussion] __getitem__ and creating an array of objects
I'm seeing some behavior that I can't understand when creating a numpy array of Python objects. Basically it seems that np.array() is calling the object __getitem__ method for one object class but not another class, and I can't understand the difference. Here is an example, starting with a simple class where __getitem__ does NOT get called: class Foo(object): ... def __getitem__(self, item): ... return 1/0 ... def __len__(self, item): ... return 1 ... f = Foo() x = np.array([f]) x array([__main__.Foo object at 0x11a1ff10], dtype=object) Now move to the complicated class (astropy.time.Time) which has a lot of stuff in it (including __new__, __init__, and __len__ methods, but initially no __getitem__), but is otherwise an ordinary class derived from object. This works as expected: from astropy.time import Time t = Time('2001-01-01', scale='utc') x = np.array([t]) x array([2001-01-01 00:00:00.000], dtype=object) Now inject a __getitem__ that will fail and try again: Time.__getitem__ = lambda self, item: 1 / 0 x = np.array([t]) ERROR: ZeroDivisionError: integer division or modulo by zero Any ideas on what is driving this difference in behavior? BTW, the value of item in the latter case is 0. Thanks, Tom ___ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
Re: [Numpy-discussion] __array_priority__ ignored if __array__ is present
I think so. Changing the order between np.array([1,2,3]) * a and a * np.array([1,2,3]) should return the same type I think, specificaly when array_priority is defined. Fred On Thu, May 30, 2013 at 3:28 PM, Thomas Robitaille thomas.robitai...@gmail.com wrote: Hi Frederic, On 16 May 2013 15:58, Frédéric Bastien no...@nouiz.org wrote: I looked yesterday rapidly in the code and didn't find the reason (I don't know it well, that is probably why). But last night I think of one possible cause. I found this code 2 times in the file core/src/umath/ufunc_object.c: if (nin == 2 nout == 1 dtypes[1]-type_num == NPY_OBJECT) { PyObject *_obj = PyTuple_GET_ITEM(args, 1); if (!PyArray_CheckExact(_obj)) { double self_prio, other_prio; self_prio = PyArray_GetPriority(PyTuple_GET_ITEM(args, 0), NPY_SCALAR_PRIORITY); other_prio = PyArray_GetPriority(_obj, NPY_SCALAR_PRIORITY); if (self_prio other_prio _has_reflected_op(_obj, ufunc_name)) { retval = -2; goto fail; } } } It is this code that will call _has_reflected_op() function. The if condition is: dtypes[1]-type_num == NPY_OBJECT I wouldn't be surprised if dtypes[1] isn't NPY_OBJECT when you implement __array__. dtypes is set with those line: retval = ufunc-type_resolver(ufunc, casting, op, type_tup, dtypes); Thanks for looking into this - should this be considered a bug? Tom HTH Fred On Thu, May 16, 2013 at 9:19 AM, Thomas Robitaille thomas.robitai...@gmail.com wrote: Hi everyone, (this was posted as part of another topic, but since it was unrelated, I'm reposting as a separate thread) I've also been having issues with __array_priority__ - the following code behaves differently for __mul__ and __rmul__: import numpy as np class TestClass(object): def __init__(self, input_array): self.array = input_array def __mul__(self, other): print Called __mul__ def __rmul__(self, other): print Called __rmul__ def __array_wrap__(self, out_arr, context=None): print Called __array_wrap__ return TestClass(out_arr) def __array__(self): print Called __array__ return np.array(self.array) with output: In [7]: a = TestClass([1,2,3]) In [8]: print type(np.array([1,2,3]) * a) Called __array__ Called __array_wrap__ class '__main__.TestClass' In [9]: print type(a * np.array([1,2,3])) Called __mul__ type 'NoneType' Is this also an oversight? I opened a ticket for it a little while ago: https://github.com/numpy/numpy/issues/3164 Any ideas? Thanks! Tom ___ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion ___ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion ___ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion ___ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
Re: [Numpy-discussion] __getitem__ and creating an array of objects
On Thu, May 30, 2013 at 9:21 PM, Aldcroft, Thomas aldcr...@head.cfa.harvard.edu wrote: I'm seeing some behavior that I can't understand when creating a numpy array of Python objects. Basically it seems that np.array() is calling the object __getitem__ method for one object class but not another class, and I can't understand the difference. Here is an example, starting with a simple class where __getitem__ does NOT get called: class Foo(object): ... def __getitem__(self, item): ... return 1/0 ... def __len__(self, item): ... return 1 ... f = Foo() x = np.array([f]) x array([__main__.Foo object at 0x11a1ff10], dtype=object) Now move to the complicated class (astropy.time.Time) which has a lot of stuff in it (including __new__, __init__, and __len__ methods, but initially no __getitem__), but is otherwise an ordinary class derived from object. This works as expected: from astropy.time import Time t = Time('2001-01-01', scale='utc') x = np.array([t]) x array([2001-01-01 00:00:00.000], dtype=object) Now inject a __getitem__ that will fail and try again: Time.__getitem__ = lambda self, item: 1 / 0 x = np.array([t]) ERROR: ZeroDivisionError: integer division or modulo by zero Any ideas on what is driving this difference in behavior? BTW, the value of item in the latter case is 0. What is len(t) in the latter case? -- Robert Kern ___ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
Re: [Numpy-discussion] __getitem__ and creating an array of objects
On Thu, May 30, 2013 at 4:27 PM, Robert Kern robert.k...@gmail.com wrote: On Thu, May 30, 2013 at 9:21 PM, Aldcroft, Thomas aldcr...@head.cfa.harvard.edu wrote: I'm seeing some behavior that I can't understand when creating a numpy array of Python objects. Basically it seems that np.array() is calling the object __getitem__ method for one object class but not another class, and I can't understand the difference. Here is an example, starting with a simple class where __getitem__ does NOT get called: class Foo(object): ... def __getitem__(self, item): ... return 1/0 ... def __len__(self, item): ... return 1 ... f = Foo() x = np.array([f]) x array([__main__.Foo object at 0x11a1ff10], dtype=object) Now move to the complicated class (astropy.time.Time) which has a lot of stuff in it (including __new__, __init__, and __len__ methods, but initially no __getitem__), but is otherwise an ordinary class derived from object. This works as expected: from astropy.time import Time t = Time('2001-01-01', scale='utc') x = np.array([t]) x array([2001-01-01 00:00:00.000], dtype=object) Now inject a __getitem__ that will fail and try again: Time.__getitem__ = lambda self, item: 1 / 0 x = np.array([t]) ERROR: ZeroDivisionError: integer division or modulo by zero Any ideas on what is driving this difference in behavior? BTW, the value of item in the latter case is 0. What is len(t) in the latter case? len(t) 1 Prompted by this question I looked again at the Foo() definition and see that I had copy/pasted the definition of __len__ from __getitem__ and forgot to remove the `item` arg. As written `len(Foo())` would fail. Interestingly, once `Foo.__len__` is valid and succeeds, then `f.__getitem__` does indeed get called and `np.array([f])` fails in the same way. Sorry for the noise, though this is still just slightly curious to me. I guess internally maybe there is try/except block that is trying to get a len and if that fails then it moves on. - Tom -- Robert Kern ___ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion ___ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
Re: [Numpy-discussion] __getitem__ and creating an array of objects
On Thu, May 30, 2013 at 4:58 PM, Aldcroft, Thomas aldcr...@head.cfa.harvard.edu wrote: On Thu, May 30, 2013 at 4:27 PM, Robert Kern robert.k...@gmail.comwrote: On Thu, May 30, 2013 at 9:21 PM, Aldcroft, Thomas aldcr...@head.cfa.harvard.edu wrote: I'm seeing some behavior that I can't understand when creating a numpy array of Python objects. Basically it seems that np.array() is calling the object __getitem__ method for one object class but not another class, and I can't understand the difference. Here is an example, starting with a simple class where __getitem__ does NOT get called: class Foo(object): ... def __getitem__(self, item): ... return 1/0 ... def __len__(self, item): ... return 1 ... f = Foo() x = np.array([f]) x array([__main__.Foo object at 0x11a1ff10], dtype=object) Now move to the complicated class (astropy.time.Time) which has a lot of stuff in it (including __new__, __init__, and __len__ methods, but initially no __getitem__), but is otherwise an ordinary class derived from object. This works as expected: from astropy.time import Time t = Time('2001-01-01', scale='utc') x = np.array([t]) x array([2001-01-01 00:00:00.000], dtype=object) Now inject a __getitem__ that will fail and try again: Time.__getitem__ = lambda self, item: 1 / 0 x = np.array([t]) ERROR: ZeroDivisionError: integer division or modulo by zero Any ideas on what is driving this difference in behavior? BTW, the value of item in the latter case is 0. What is len(t) in the latter case? len(t) 1 Prompted by this question I looked again at the Foo() definition and see that I had copy/pasted the definition of __len__ from __getitem__ and forgot to remove the `item` arg. As written `len(Foo())` would fail. Interestingly, once `Foo.__len__` is valid and succeeds, then `f.__getitem__` does indeed get called and `np.array([f])` fails in the same way. Sorry for the noise, though this is still just slightly curious to me. I guess internally maybe there is try/except block that is trying to get a len and if that fails then it moves on. Now I realize what seemed curious. Here is a related example which shows that when initializing a numpy array of objects where __getitem__ and __len__ exist, np.array introspects the object item values for item in range(len(object)) and appears to replace the input object with an ndarray of the object values. class Foo(object): ... attr = 'hello' ... def __getitem__(self, item): ... return item ... def __len__(self): ... return 5 f = Foo() f.attr 'hello' x = np.array([f, f], dtype=object) x array([[0, 1, 2, 3, 4], [0, 1, 2, 3, 4]], dtype=object) x[0] array([0, 1, 2, 3, 4], dtype=object) type(x[0]) type 'numpy.ndarray' x[0].attr Traceback (most recent call last): File ipython-input-16-7b865674a0b6, line 1, in module x[0].attr AttributeError: 'numpy.ndarray' object has no attribute 'attr' The actual objects that I passed in seem to be lost, which is not the behavior I expected. Thanks, Tom - Tom -- Robert Kern ___ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion ___ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
Re: [Numpy-discussion] __getitem__ and creating an array of objects
On Thu, May 30, 2013 at 10:31 PM, Aldcroft, Thomas aldcr...@head.cfa.harvard.edu wrote: Now I realize what seemed curious. Here is a related example which shows that when initializing a numpy array of objects where __getitem__ and __len__ exist, np.array introspects the object item values for item in range(len(object)) and appears to replace the input object with an ndarray of the object values. class Foo(object): ... attr = 'hello' ... def __getitem__(self, item): ... return item ... def __len__(self): ... return 5 f = Foo() f.attr 'hello' x = np.array([f, f], dtype=object) x array([[0, 1, 2, 3, 4], [0, 1, 2, 3, 4]], dtype=object) x[0] array([0, 1, 2, 3, 4], dtype=object) type(x[0]) type 'numpy.ndarray' x[0].attr Traceback (most recent call last): File ipython-input-16-7b865674a0b6, line 1, in module x[0].attr AttributeError: 'numpy.ndarray' object has no attribute 'attr' The actual objects that I passed in seem to be lost, which is not the behavior I expected. By defining __len__ and __getitem__, you are making your objects look like containers that array() should traverse down into, like a list, rather than atomic items like a float. array() has to do a lot of magic to determine what shape of an array you actually want. If you have objects that look like containers but you don't want them to be the atomic items, then you should first construct an empty object array of the right shape, then populate it using slice assignment. -- Robert Kern ___ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion