[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 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 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 > 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__ >> >> >> In [9]: print type(a * np.array([1,2,3])) >> Called __mul__ >> >> """ >> >> 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 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 > > 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__ > >> > >> > >> In [9]: print type(a * np.array([1,2,3])) > >> Called __mul__ > >> > >> """ > >> > >> 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 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 wrote: > On Thu, May 30, 2013 at 9:21 PM, Aldcroft, Thomas > 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 wrote: > >> On Thu, May 30, 2013 at 9:21 PM, Aldcroft, Thomas >> 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]) >>> x[0].attr Traceback (most recent call last): File "", line 1, in 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 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]) > x[0].attr > Traceback (most recent call last): > File "", line 1, in > 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