-
Notifications
You must be signed in to change notification settings - Fork 2.2k
vectorizing functions with multiple return values? #763
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
Comments
I also would like to do this! I think it would make most sense to return a I tried this with: py::array_t<double> return_array(double t) {
py::array_t<double> a({2});
a.mutable_at(0) = a.mutable_at(1) = t;
return a;
} ... and: m.def("return_array", py::vectorize(&return_array)); ... but this created a very long compiler error, boiling down to pybind11/include/pybind11/numpy.h Lines 1497 to 1502 in 2d0507d
So it looks like this isn't supported (but it would be great if it would be supported!). I tried if this works in NumPy ... >>> import numpy as np
>>> def myfunc(x):
... return np.array([x, x])
...
>>> v = np.vectorize(myfunc)
>>> v([2, 3])
Traceback (most recent call last):
...
ValueError: setting an array element with a sequence. ... and it turns out that it doesn't! But then I had a look at the vectorize docs and found out that there is a quite new (version 1.12, released about a year ago) argument called >>> v = np.vectorize(myfunc, signature='()->(n)')
>>> v([2, 3])
array([[2, 2],
[3, 3]]) To implement this in pybind11, it wouldn't even be necessary to add a separate argument, because the compiler would know that the return type of the function is a Sadly, I don't understand enough about the internals of pybind11 to tackle an implementation myself. It seems that this is part of a grander scheme called Generalized Universal Functions. This may or may not be related to this comment by @JohanMabille. BTW, this is related to a more complicated problem I asked about on stackoverflow: https://stackoverflow.com/q/48736838/. |
I just realized that there is another way to handle multiple outputs in >>> import numpy as np
>>> def return_multiple_values(x):
... return x, x + x, x * x
...
>>> v = np.vectorize(return_multiple_values)
>>> v(1)
(array(1), array(2), array(1))
>>> v([2, 3])
(array([2, 3]), array([4, 6]), array([4, 9])) This could probably also be implemented in pybind11, using |
My goal is to provide a vectorized Python binding to C++ functions that return more than a single value, like
py::vectorize(ang2vec)
does not work, producing error messages like"pybind11/numpy.h:732:5: error: forming pointer to reference type ‘double&’".
I tried to translate this into a more Python-like interface:
but unfortunately vectorizing this fails as well.
Are there fundamental obstacles to supporting this scenario, or am I just the first one trying to do this? :)
The text was updated successfully, but these errors were encountered: