<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Oct 26, 2016 at 3:57 PM, Charles R Harris <span dir="ltr"><<a href="mailto:charlesr.harris@gmail.com" target="_blank">charlesr.harris@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote"><div><div class="m_6149973495221092996h5">On Wed, Oct 26, 2016 at 1:39 PM,  <span dir="ltr"><<a href="mailto:josef.pktd@gmail.com" target="_blank">josef.pktd@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote"><div><div class="m_6149973495221092996m_5524754786806464554h5">On Wed, Oct 26, 2016 at 3:23 PM, Charles R Harris <span dir="ltr"><<a href="mailto:charlesr.harris@gmail.com" target="_blank">charlesr.harris@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote"><div><div class="m_6149973495221092996m_5524754786806464554m_-5298903815263724592gmail-h5">On Tue, Oct 25, 2016 at 10:14 AM, Stephan Hoyer <span dir="ltr"><<a href="mailto:shoyer@gmail.com" target="_blank">shoyer@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">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.</div><div class="m_6149973495221092996m_5524754786806464554m_-5298903815263724592gmail-m_-8894435250639677267gmail-HOEnZb"><div class="m_6149973495221092996m_5524754786806464554m_-5298903815263724592gmail-m_-8894435250639677267gmail-h5"><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Oct 24, 2016 at 4:30 PM, Nathaniel Smith <span dir="ltr"><<a href="mailto:njs@pobox.com" target="_blank">njs@pobox.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span>On Mon, Oct 24, 2016 at 3:41 PM, Charles R Harris<br>
<<a href="mailto:charlesr.harris@gmail.com" target="_blank">charlesr.harris@gmail.com</a>> wrote:<br>
> Hi All,<br>
><br>
> I've been thinking about this some (a lot) more and have an alternate<br>
> proposal for the behavior of the `**` operator<br>
><br>
> if both base and power are numpy/python scalar integers, convert to python<br>
> integers and call the `**` operator. That would solve both the precision and<br>
> compatibility problems and I think is the option of least surprise. For<br>
> those who need type preservation and modular arithmetic, the np.power<br>
> function remains, although the type conversions can be surpirising as it<br>
> seems that the base and power should  play different roles in determining<br>
> the type, at least to me.<br>
> Array, 0-d or not, are treated differently from scalars and integers raised<br>
> to negative integer powers always raise an error.<br>
><br>
> I think this solves most problems and would not be difficult to implement.<br>
><br>
> Thoughts?<br>
<br>
</span>My main concern about this is that it adds more special cases to numpy<br>
scalars, and a new behavioral deviation between 0d arrays and scalars,<br>
when ideally we should be trying to reduce the<br>
duplication/discrepancies between these. It's also inconsistent with<br>
how other operations on integer scalars work, e.g. regular addition<br>
overflows rather than promoting to Python int:<br>
<br>
In [8]: np.int64(2 ** 63 - 1) + 1<br>
/home/njs/.user-python3.5-64bi<wbr>t/bin/ipython:1: RuntimeWarning:<br>
overflow encountered in long_scalars<br>
  #!/home/njs/.user-python3.5-64<wbr>bit/bin/python3.5<br>
Out[8]: -9223372036854775808<br>
<br>
So I'm inclined to try and keep it simple, like in your previous<br>
proposal... theoretically of course it would be nice to have the<br>
perfect solution here, but at this point it feels like we might be<br>
overthinking this trying to get that last 1% of improvement. The thing<br>
where 2 ** -1 returns 0 is just broken and bites people so we should<br>
definitely fix it, but beyond that I'm not sure it really matters<br>
*that* much what we do, and "special cases aren't special enough to<br>
break the rules" and all that.<br>
<span class="m_6149973495221092996m_5524754786806464554m_-5298903815263724592gmail-m_-8894435250639677267gmail-m_3313378286959386415HOEnZb"><font color="#888888"><br></font></span></blockquote></div></div></div></div></blockquote><div><br></div></div></div><div>What I have been concerned about are the follow combinations that currently return floats<br><br>num: <type 'numpy.int8'>, exp: <type 'numpy.int8'>, res: <type 'numpy.float32'><br>num: <type 'numpy.int16'>, exp: <type 'numpy.int8'>, res: <type 'numpy.float32'><br>num: <type 'numpy.int16'>, exp: <type 'numpy.int16'>, res: <type 'numpy.float32'><br>num: <type 'numpy.int32'>, exp: <type 'numpy.int8'>, res: <type 'numpy.float64'><br>num: <type 'numpy.int32'>, exp: <type 'numpy.int16'>, res: <type 'numpy.float64'><br>num: <type 'numpy.int32'>, exp: <type 'numpy.int32'>, res: <type 'numpy.float64'><br>num: <type 'numpy.int64'>, exp: <type 'numpy.int8'>, res: <type 'numpy.float64'><br>num: <type 'numpy.int64'>, exp: <type 'numpy.int16'>, res: <type 'numpy.float64'><br>num: <type 'numpy.int64'>, exp: <type 'numpy.int32'>, res: <type 'numpy.float64'><br>num: <type 'numpy.int64'>, exp: <type 'numpy.int64'>, res: <type 'numpy.float64'><br>num: <type 'numpy.int64'>, exp: <type 'numpy.int64'>, res: <type 'numpy.float64'><br>num: <type 'numpy.uint64'>, exp: <type 'numpy.int8'>, res: <type 'numpy.float64'><br>num: <type 'numpy.uint64'>, exp: <type 'numpy.int16'>, res: <type 'numpy.float64'><br>num: <type 'numpy.uint64'>, exp: <type 'numpy.int32'>, res: <type 'numpy.float64'><br>num: <type 'numpy.uint64'>, exp: <type 'numpy.int64'>, res: <type 'numpy.float64'><br>num: <type 'numpy.uint64'>, exp: <type 'numpy.int64'>, res: <type 'numpy.float64'><br><br></div><div>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.<br></div></div></div></div></blockquote><div><br></div><div><br></div></div></div><div><div>>>> np.int64(2)**np.array(-1, np.int64)</div><div>0.5</div><div>>>> np.__version__</div><div>'1.10.4'</div><div>>>> np.int64(2)**np.array([-1, 2], np.int64)</div><div>array([0, 4], dtype=int64)</div></div><div><div>>>> np.array(2, np.uint64)**np.array([-1, 2], np.int64)</div><div>array([0, 4], dtype=int64)</div><div>>>> np.array([2], np.uint64)**np.array([-1, 2], np.int64)</div><div>array([ 0.5,  4. ])</div></div><div><div>>>> np.array([2], np.uint64).squeeze()**np.array<wbr>([-1, 2], np.int64)</div><div>array([0, 4], dtype=int64)</div></div><div><br></div><div><br></div><div>(IMO: If you have to break backwards compatibility, break forwards not backwards.)</div></div></div></div></blockquote><div><br></div></div></div><div>Current master is different. I'm not too worried in the array cases as the results for negative exponents were zero except then raising -1 to a power. Since that result is incorrect raising an error  falls on the fine line between bug fix and compatibility break. If the pre-releases cause too much trouble. <br></div></div></div></div></blockquote><div><br></div><div><br></div><div>naive question: if cleaning up the inconsistencies already (kind of) breaks backwards compatibility and didn't result in a big outcry, why can we not go with a Future warning all the way to float. (i.e. use the power function with specified dtype instead of ** if you insist on int return)</div><div><br></div><div>Josef</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><br></div><div>Chuck <br></div></div><br></div></div>
<br>______________________________<wbr>_________________<br>
NumPy-Discussion mailing list<br>
<a href="mailto:NumPy-Discussion@scipy.org" target="_blank">NumPy-Discussion@scipy.org</a><br>
<a href="https://mail.scipy.org/mailman/listinfo/numpy-discussion" rel="noreferrer" target="_blank">https://mail.scipy.org/mailman<wbr>/listinfo/numpy-discussion</a><br>
<br></blockquote></div><br></div></div>