-
-
Notifications
You must be signed in to change notification settings - Fork 10.8k
BUG: ndarray.conjugate broken for custom dtypes (unlike np.conjugate) #9003
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
As explained here, I can verify that this patch does fix the problem in the quaternion library. Thanks! |
Note that this "breaks" the following:
It also means that |
To make this not break (bad) old code, I think the test should become:
and then the else branch should have a |
I can verify that using the original code with if (PyArray_ISCOMPLEX(self) || PyArray_ISOBJECT(self)) { replaced by if (PyArray_ISNUMBER(self) || PyArray_ISOBJECT(self) || PyArray_ISUSERDEF(self)) { also solves my problem. |
8260ac9
to
8254690
Compare
Sounds good, I've updated the patch as suggested. |
Can you split this into a BUG commit and a DEP commit? It's nice to have deprecation commits stand alone. Also needs:
But otherwise looks good |
aa240fd
to
76ab732
Compare
Okay, I've done as you say. Let me know if you'd prefer separate TST and DOC commits instead of putting those changes in the DEP commit. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All looks good to me. My only concern is whether no longer returning a view is an ok change - It'd be nice if another maintainer could weigh in.
Obviously there's a consistency benefit here, but there's also a performance cost.
doc/release/1.13.0-notes.rst
Outdated
@@ -100,6 +102,14 @@ invokes``ndarray.__getslice__`` (e.g. through ``super(...).__getslice__``) will | |||
now issue a DeprecationWarning - ``.__getitem__(slice(start, end))`` should be | |||
used instead. | |||
|
|||
``ndarray.conjugate`` no longer returns a view of real data | |||
----------------------------------------------------------- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick - belongs in previous commit, but I don't think that's worth your time to fix
☔ The latest upstream changes (presumably #8948) made this pull request unmergeable. Please resolve the merge conflicts. |
Rebased and moved release notes into correct commits. Re: performance cost, I count five conjugations in this repo (outside tests) which are guarded by a complex check, and one which is not at https://github.com/numpy/numpy/blob/master/numpy/lib/function_base.py#L3087 in I could change this so that a view is still returned when |
Since I find the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very thorough patch - thanks! Just some minor style nits, and this is good to merge
@@ -1173,7 +1173,8 @@ PyArray_Clip(PyArrayObject *self, PyObject *min, PyObject *max, PyArrayObject *o | |||
NPY_NO_EXPORT PyObject * | |||
PyArray_Conjugate(PyArrayObject *self, PyArrayObject *out) | |||
{ | |||
if (PyArray_ISCOMPLEX(self) || PyArray_ISOBJECT(self)) { | |||
if (PyArray_ISCOMPLEX(self) || PyArray_ISOBJECT(self) || | |||
PyArray_ISUSERDEF(self)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Convention would be to indent this twice, (doc\C_STYLE_GUIDE.rst.txt
)
if (!PyArray_ISNUMBER(self)) { | ||
if (DEPRECATE("attempting to conjugate non-numeric dtype; " | ||
"this will error in the future to match the behavior " | ||
"of np.conjugate") < 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indentation is weird here - should probably either be column aligned, or 8 spaces - currently, it's neither
Indentation updated. |
@@ -1186,6 +1186,13 @@ PyArray_Conjugate(PyArrayObject *self, PyArrayObject *out) | |||
} | |||
else { | |||
PyArrayObject *ret; | |||
if (!PyArray_ISNUMBER(self)) { | |||
if (DEPRECATE("attempting to conjugate non-numeric dtype; this " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One last thing - this needs a comment like NumPy 1.13, 2017-05-04
by the deprecation. Sorry for not spotting that in the last review
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment added, following the format of other such comments.
types This behavior is contrary to np.conjugate (which will error on non-numeric types), even though documentation claims they are identical. This deprecation favors failing fast.
This is especially relevant to moble's numpy quaternion library, which will silently fail to conjugate when using ndarray.conjugate.
Travis is correctly testing the final commit (see, e.g., https://github.com/longjon/numpy/commits/d4257335fc515aff9cda64d57cd3ec72841b9720/numpy/core/src/multiarray/calculation.c). GitHub lists commits in chronological rather than topological order, because GitHub is designed around a concatenative rather than a rewriting workflow. (The other UI issues just sound broken though!) |
☔ The latest upstream changes (presumably #8918) made this pull request unmergeable. Please resolve the merge conflicts. |
In the interest of leaving this around as a testcase for the support thread I started with github about the UI, can I get you to make a new PR for rebasing this? |
Thanks @longjon |
In #4730, @andyjost noted that
ndarray.conjugate
was broken for arrays of objects. This was fixed in #4887 by @juliantaylor by extending the conditions guarding a no-op fall-through to exclude both complex- and object-typed arrays. Unfortunately this solution is not complete, because custom dtypes may be conjugateable without being objects. This patch simply removes the fall-through, which actually makes the behaviors of thenp.conjugate
ufunc andndarray.conjugate
the same as documented.This will be slower if
ndarray.conjugate
is used (needlessly) on real data; but then, it's now the same speed asnp.conjugate
. (Is numpy exploiting the specific no-op behavior ofndarray.conjugate
anywhere?)This is especially relevant to @moble's https://github.com/moble/quaternion library, which will silently no-op when using
ndarray.conjugate
on non-zero-dim arrays.