I am not sure I follow : is the problem the coerce-sequences-to-ndarrays behavior, or is it the fact that it applies to division and not multiplication? I thought the second situation is the more problematic. Anyway, you seem to take it as a bug, should I file a ticket somewhere? thanks, johann
On 08/30/2011 08:17 PM, Robert Kern wrote: > On Tue, Aug 30, 2011 at 09:52, Charles R Harris > <[email protected]> wrote: >> On Tue, Aug 30, 2011 at 8:33 AM, Johann Cohen-Tanugi >> <[email protected]> wrote: >>> I have numpy version 1.6.1 and I see the following behavior : >>> >>> In [380]: X >>> Out[380]: 1.0476157527896641 >>> >>> In [381]: X.__class__ >>> Out[381]: numpy.float64 >>> >>> In [382]: (2,3)*X >>> Out[382]: (2, 3) >>> >>> In [383]: (2,3)/X >>> Out[383]: array([ 1.90909691, 2.86364537]) >>> >>> In [384]: X=float(X) >>> >>> In [385]: (2,3)/X >>> >>> --------------------------------------------------------------------------- >>> TypeError Traceback (most recent call >>> last) >>> /home/cohen/<ipython-input-385-cafbe080bfd5> in<module>() >>> ----> 1 (2,3)/X >>> >>> TypeError: unsupported operand type(s) for /: 'tuple' and 'float' >>> >>> >>> So it appears that X being a numpy float allows numpy to play some trick >>> on the tuple so that division becomes possible, which regular built-in >>> float does not allow arithmetics with tuples. >>> But why is multiplication with "*" not following the same prescription? >>> >> That's strange. >> >> In [16]: x = float64(2.1) >> >> In [17]: (2,3)*x >> Out[17]: (2, 3, 2, 3) >> >> In [18]: (2,3)/x >> Out[18]: array([ 0.95238095, 1.42857143]) >> >> Note that in the first case x is treated like an integer. In the second the >> tuple is turned into an array. I think both of these cases should raise >> exceptions. > In scalartypes.c.src: > > tatic PyObject * > gentype_multiply(PyObject *m1, PyObject *m2) > { > PyObject *ret = NULL; > long repeat; > > if (!PyArray_IsScalar(m1, Generic)&& > ((Py_TYPE(m1)->tp_as_number == NULL) || > (Py_TYPE(m1)->tp_as_number->nb_multiply == NULL))) { > /* Try to convert m2 to an int and try sequence repeat */ > repeat = PyInt_AsLong(m2); > if (repeat == -1&& PyErr_Occurred()) { > return NULL; > } > ret = PySequence_Repeat(m1, (int) repeat); > } > else if (!PyArray_IsScalar(m2, Generic)&& > ((Py_TYPE(m2)->tp_as_number == NULL) || > (Py_TYPE(m2)->tp_as_number->nb_multiply == NULL))) { > /* Try to convert m1 to an int and try sequence repeat */ > repeat = PyInt_AsLong(m1); > if (repeat == -1&& PyErr_Occurred()) { > return NULL; > } > ret = PySequence_Repeat(m2, (int) repeat); > } > if (ret == NULL) { > PyErr_Clear(); /* no effect if not set */ > ret = PyArray_Type.tp_as_number->nb_multiply(m1, m2); > } > return ret; > } > > The PyInt_AsLong() calls should be changed to check for > __index__ability, instead. Not sure about the other operators. Some > people *may* be relying on the coerce-sequences-to-ndarray behavior > with numpy scalars just like they do so with ndarrays. On the other > hand, the repeat behavior with * should have thrown a monkey wrench to > them if they were, so the number of people who do this is probably > small. > _______________________________________________ NumPy-Discussion mailing list [email protected] http://mail.scipy.org/mailman/listinfo/numpy-discussion
