From: David M. C. <co...@ph...> - 2006-06-05 21:10:35
|
I just ran into the fact that the power function for integer types isn't handled in scalarmath yet. I'm going to add it, but I'm wondering what people want when power overflows the integer type? Taking the concrete example of a = uint8(3), b = uint8(10), then should a ** b return 1) the maximum integer for the type (255 here) 2) 0 3) upcast to the largest type that will hold it (but what if it's larger than our largest type? Return a Python long?) 4) do the power using "long" like Python does, then downcast it to the type (that would return 169 for the above example) 5) something else? I'm leaning towards #3; if you do a ** 10, you get the right answer (59049 as an int64scalar), because 'a' is upcasted to int64scalar, since '10', a Python int, is converted to that type. Otherwise, I would choose #1. -- |>|\/|< /----------------------------------------------------------------------\ |David M. Cooke http://arbutus.physics.mcmaster.ca/dmc/ |co...@ph... |
From: David D. <dav...@lo...> - 2006-06-06 08:44:38
|
On Mon, Jun 05, 2006 at 05:10:23PM -0400, David M. Cooke wrote: > I just ran into the fact that the power function for integer types > isn't handled in scalarmath yet. I'm going to add it, but I'm wondering > what people want when power overflows the integer type? >=20 > Taking the concrete example of a =3D uint8(3), b =3D uint8(10), then shou= ld > a ** b return >=20 > 1) the maximum integer for the type (255 here) > 2) 0 > 3) upcast to the largest type that will hold it (but what if it's > larger than our largest type? Return a Python long?) > 4) do the power using "long" like Python does, then downcast it to the > type (that would return 169 for the above example) > 5) something else? >=20 > I'm leaning towards #3; if you do a ** 10, you get the right > answer (59049 as an int64scalar), because 'a' is upcasted to > int64scalar, since '10', a Python int, is converted to that type. > Otherwise, I would choose #1. I agree, #1 seems the better solution for me. BTW, I'm quite new on this list, and I don't know is this has already been discussed (I guess I has): why does uint_n arithmetics are done in the Z/(2**n)Z field (not sure about the maths correctness here)? I mean: >>> a =3D numpy.uint8(10) >>> a*a 100 >>> a*a*a # I'd like to have 255 here 232 >>> 1000%256 232 It would be really a nice feature to be able (by the mean of a numpy flag o= r so) to have bound limited uint operations (especially when doing image processi= ng...). David --=20 David Douard LOGILAB, Paris (France) Formations Python, Zope, Plone, Debian : http://www.logilab.fr/formations D=E9veloppement logiciel sur mesure : http://www.logilab.fr/services Informatique scientifique : http://www.logilab.fr/science |
From: David M. C. <co...@ph...> - 2006-06-06 20:02:52
|
On Tue, 6 Jun 2006 10:44:20 +0200 David Douard <dav...@lo...> wrote: > On Mon, Jun 05, 2006 at 05:10:23PM -0400, David M. Cooke wrote: > > I just ran into the fact that the power function for integer types > > isn't handled in scalarmath yet. I'm going to add it, but I'm > > wondering what people want when power overflows the integer type? > > > > Taking the concrete example of a = uint8(3), b = uint8(10), then > > should a ** b return > > > > 1) the maximum integer for the type (255 here) > > 2) 0 > > 3) upcast to the largest type that will hold it (but what if it's > > larger than our largest type? Return a Python long?) > > 4) do the power using "long" like Python does, then downcast it to > > the type (that would return 169 for the above example) > > 5) something else? > > > > I'm leaning towards #3; if you do a ** 10, you get the right > > answer (59049 as an int64scalar), because 'a' is upcasted to > > int64scalar, since '10', a Python int, is converted to that type. > > Otherwise, I would choose #1. > > I agree, #1 seems the better solution for me. > > BTW, I'm quite new on this list, and I don't know is this has already > been discussed (I guess I has): why does uint_n arithmetics are done > in the Z/(2**n)Z field (not sure about the maths correctness here)? > I mean: > >>> a = numpy.uint8(10) > >>> a*a > 100 > >>> a*a*a # I'd like to have 255 here > 232 > >>> 1000%256 > 232 > History, and efficiency. Detecting integer overflow in C portably requires doing a division afterwards, or splitting the multiplication up into parts that won't overflow, so you can see if the sum would. Both of those options are pretty slow compared with multiplication. Now, mind you, our scalar types *do* check for overflow: they use a larger integer type for the result (or by splitting it up for the largest type). So you can check for overflow by setting the overflow handler: >>> seterr(over='raise') {'over': 'ignore', 'divide': 'ignore', 'invalid': 'ignore', 'under': 'ignore'} >>> int16(32000) * int16(3) Traceback (most recent call last): File "<stdin>", line 1, in ? FloatingPointError: overflow encountered in short_scalars Note that the integer array types don't check, though (huh, maybe they should). It's easy enough to use the multiply routine for the power, so you'll get overflow checking for free. > It would be really a nice feature to be able (by the mean of a numpy > flag or so) to have bound limited uint operations (especially when > doing image processing...). If you want to supply a patch ... :-) -- |>|\/|< /--------------------------------------------------------------------------\ |David M. Cooke http://arbutus.physics.mcmaster.ca/dmc/ |co...@ph... |
From: Charles R H. <cha...@gm...> - 2006-06-08 00:24:46
|
You could use the C approach and use modular arithmetic where the product simply wraps around. The Python approach would be nice if feasible, but what are you going to do for integers larger than the largest numpy data type? So I vote for modular arithetic because numpy is sorta C. On 6/5/06, David M. Cooke <co...@ph...> wrote: > > I just ran into the fact that the power function for integer types > isn't handled in scalarmath yet. I'm going to add it, but I'm wondering > what people want when power overflows the integer type? > > Taking the concrete example of a = uint8(3), b = uint8(10), then should > a ** b return > > 1) the maximum integer for the type (255 here) > 2) 0 > 3) upcast to the largest type that will hold it (but what if it's > larger than our largest type? Return a Python long?) > 4) do the power using "long" like Python does, then downcast it to the > type (that would return 169 for the above example) > 5) something else? > > I'm leaning towards #3; if you do a ** 10, you get the right > answer (59049 as an int64scalar), because 'a' is upcasted to > int64scalar, since '10', a Python int, is converted to that type. > Otherwise, I would choose #1. > > -- > |>|\/|< > /----------------------------------------------------------------------\ > |David M. Cooke http://arbutus.physics.mcmaster.ca/dmc/ > |co...@ph... > > > _______________________________________________ > Numpy-discussion mailing list > Num...@li... > https://lists.sourceforge.net/lists/listinfo/numpy-discussion > |