-
-
Notifications
You must be signed in to change notification settings - Fork 11.1k
API: Add outer
to numpy.linalg
[Array API]
#25101
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
``outer`` for `numpy.linalg` | ||
---------------------------- | ||
|
||
`numpy.linalg.outer` has been added. It computes the outer product of two vectors. | ||
It differs from `numpy.outer` by accepting one-dimensional arrays only. | ||
This function is compatible with Array API. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,6 +34,7 @@ | |
-------------- | ||
|
||
cholesky | ||
outer | ||
qr | ||
svd | ||
svdvals | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,7 @@ AR_c16: npt.NDArray[np.complex128] | |
AR_O: npt.NDArray[np.object_] | ||
AR_m: npt.NDArray[np.timedelta64] | ||
AR_S: npt.NDArray[np.str_] | ||
AR_b: npt.NDArray[np.bool] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unrelated, but @BvB93, is there a way to make the error you get from
But both There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Unfortunately not yet, no. There is PEP 702: Marking deprecations using the type system in the works which might help with this in the future, but even then both numpy and mypy will have to add some support for it before seeing the actual benefits. |
||
|
||
assert_type(np.linalg.tensorsolve(AR_i8, AR_i8), npt.NDArray[np.float64]) | ||
assert_type(np.linalg.tensorsolve(AR_i8, AR_f8), npt.NDArray[np.floating[Any]]) | ||
|
@@ -44,6 +45,13 @@ assert_type(np.linalg.cholesky(AR_i8), npt.NDArray[np.float64]) | |
assert_type(np.linalg.cholesky(AR_f8), npt.NDArray[np.floating[Any]]) | ||
assert_type(np.linalg.cholesky(AR_c16), npt.NDArray[np.complexfloating[Any, Any]]) | ||
|
||
assert_type(np.linalg.outer(AR_i8, AR_i8), npt.NDArray[np.signedinteger[Any]]) | ||
assert_type(np.linalg.outer(AR_f8, AR_f8), npt.NDArray[np.floating[Any]]) | ||
assert_type(np.linalg.outer(AR_c16, AR_c16), npt.NDArray[np.complexfloating[Any, Any]]) | ||
assert_type(np.linalg.outer(AR_b, AR_b), npt.NDArray[np.bool]) | ||
assert_type(np.linalg.outer(AR_O, AR_O), npt.NDArray[np.object_]) | ||
assert_type(np.linalg.outer(AR_i8, AR_m), npt.NDArray[np.timedelta64]) | ||
|
||
assert_type(np.linalg.qr(AR_i8), QRResult) | ||
assert_type(np.linalg.qr(AR_f8), QRResult) | ||
assert_type(np.linalg.qr(AR_c16), QRResult) | ||
|
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.
@mtsokol - only seeing this now since it entered nightly and hence caused astropy to notice it is missing coverage: is there any reason this is not
asanyarray
? It means we have to cover this function even though we already covernp.outer
, so withnp.asanyarray
this would just have worked. I think for new code we should just assume subclasses are OK and able to deal with standard numpy code.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.
It indeed seems reasonable to accept subclasses in new functions. However, as long as
np.matrix
and masked arrays are still around, I think it'd be a lot safe to have a new validation function that does whatasanyarray
does plus explicitly rejects instances of those two problematic subclasses. And in order to do so, we need a faster check thanisinstance
calls (perhaps adding a private._invalid_subclass
and checking for that attribute?). WDYT @mhvk?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.
Let's just ignore those? Concretely:
asarray()
is guaranteed to give bad results, whileasanyarray()
at least has a chance to do the right thing (and in fact, it looks like it does something pretty reasonable here).The question is what pattern we want, which is the
_invalid_subclass
thought. I think the answer is: it's the subclasses problem, especially for new functions. We just always useasanyarray()
, the subclass should/must implement__array_function__
and deal with it if that doesn't work out.Using
asanyarray()
gives the subclass a chance at gambling it can usesuper().__array_function__
or callfunc._implementation()
(and a bit of a gamble it is, as we may change the implementation; astropy is happy with that gamble).The main thing I do not quite like about the pattern is that it would be nice if we could open this up more clearly to non-subclasses but...
PS: I actually do wonder if rather than trying to implement a proper
__array_function__
for masked arrays, it may be plausible to implement one that does nothing but reject clearly broken ones.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.
Agreed. For non-subclasses, in this case all that is needed is the dimension of the array, so one could do
np.ndim(x1)
which would be fast for anything except list input. But just changing toasanyarray
here would seem sensible!