On Tue, Oct 25, 2016 at 10:14 AM, Stephan Hoyer <sho...@gmail.com> wrote:
> I am also concerned about adding more special cases for NumPy scalars vs > arrays. These cases are already confusing (e.g., making no distinction > between 0d arrays and scalars) and poorly documented. > > On Mon, Oct 24, 2016 at 4:30 PM, Nathaniel Smith <n...@pobox.com> wrote: > >> On Mon, Oct 24, 2016 at 3:41 PM, Charles R Harris >> <charlesr.har...@gmail.com> wrote: >> > Hi All, >> > >> > I've been thinking about this some (a lot) more and have an alternate >> > proposal for the behavior of the `**` operator >> > >> > if both base and power are numpy/python scalar integers, convert to >> python >> > integers and call the `**` operator. That would solve both the >> precision and >> > compatibility problems and I think is the option of least surprise. For >> > those who need type preservation and modular arithmetic, the np.power >> > function remains, although the type conversions can be surpirising as it >> > seems that the base and power should play different roles in >> determining >> > the type, at least to me. >> > Array, 0-d or not, are treated differently from scalars and integers >> raised >> > to negative integer powers always raise an error. >> > >> > I think this solves most problems and would not be difficult to >> implement. >> > >> > Thoughts? >> >> My main concern about this is that it adds more special cases to numpy >> scalars, and a new behavioral deviation between 0d arrays and scalars, >> when ideally we should be trying to reduce the >> duplication/discrepancies between these. It's also inconsistent with >> how other operations on integer scalars work, e.g. regular addition >> overflows rather than promoting to Python int: >> >> In [8]: np.int64(2 ** 63 - 1) + 1 >> /home/njs/.user-python3.5-64bit/bin/ipython:1: RuntimeWarning: >> overflow encountered in long_scalars >> #!/home/njs/.user-python3.5-64bit/bin/python3.5 >> Out[8]: -9223372036854775808 >> >> So I'm inclined to try and keep it simple, like in your previous >> proposal... theoretically of course it would be nice to have the >> perfect solution here, but at this point it feels like we might be >> overthinking this trying to get that last 1% of improvement. The thing >> where 2 ** -1 returns 0 is just broken and bites people so we should >> definitely fix it, but beyond that I'm not sure it really matters >> *that* much what we do, and "special cases aren't special enough to >> break the rules" and all that. >> >> What I have been concerned about are the follow combinations that currently return floats num: <type 'numpy.int8'>, exp: <type 'numpy.int8'>, res: <type 'numpy.float32'> num: <type 'numpy.int16'>, exp: <type 'numpy.int8'>, res: <type 'numpy.float32'> num: <type 'numpy.int16'>, exp: <type 'numpy.int16'>, res: <type 'numpy.float32'> num: <type 'numpy.int32'>, exp: <type 'numpy.int8'>, res: <type 'numpy.float64'> num: <type 'numpy.int32'>, exp: <type 'numpy.int16'>, res: <type 'numpy.float64'> num: <type 'numpy.int32'>, exp: <type 'numpy.int32'>, res: <type 'numpy.float64'> num: <type 'numpy.int64'>, exp: <type 'numpy.int8'>, res: <type 'numpy.float64'> num: <type 'numpy.int64'>, exp: <type 'numpy.int16'>, res: <type 'numpy.float64'> num: <type 'numpy.int64'>, exp: <type 'numpy.int32'>, res: <type 'numpy.float64'> num: <type 'numpy.int64'>, exp: <type 'numpy.int64'>, res: <type 'numpy.float64'> num: <type 'numpy.int64'>, exp: <type 'numpy.int64'>, res: <type 'numpy.float64'> num: <type 'numpy.uint64'>, exp: <type 'numpy.int8'>, res: <type 'numpy.float64'> num: <type 'numpy.uint64'>, exp: <type 'numpy.int16'>, res: <type 'numpy.float64'> num: <type 'numpy.uint64'>, exp: <type 'numpy.int32'>, res: <type 'numpy.float64'> num: <type 'numpy.uint64'>, exp: <type 'numpy.int64'>, res: <type 'numpy.float64'> num: <type 'numpy.uint64'>, exp: <type 'numpy.int64'>, res: <type 'numpy.float64'> The other combinations of signed and unsigned integers to signed powers currently raise ValueError due to the change to the power ufunc. The exceptions that aren't covered by uint64 + signed (which won't change) seem to occur when the exponent can be safely cast to the base type. I suspect that people have already come to depend on that, especially as python integers on 64 bit linux convert to int64. So in those cases we should perhaps raise a FutureWarning instead of an error. Chuck
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org https://mail.scipy.org/mailman/listinfo/numpy-discussion