Hi, I have a question about the vectorize function. I'd like to use it to create a vectorized version of a class method. I've tried the following code: from numpy import * class X: def func(self, n): return 2 * n # example func = vectorize(func) Now, when I declare an instance of the class X and invoke func() as an unbound method, it works: x = X() print X.func(x, [1, 2]) # output: [2 4] But an attempt to invoke it "normally", i.e. like print x.func([1, 2]) fails with the message Traceback (most recent call last): File "<stdin>", line 1, in ? File "/usr/lib/python2.4/site-packages/numpy/lib/function_base.py", line 823, in __call__ raise ValueError, "mismatch between python function inputs"\ ValueError: mismatch between python function inputs and received arguments It seems that in this case the class instance (x) isn't passed to the vectorize.__call__() method, and as a result the number of arguments does not agree with what this method expects. Does anybody have an idea of how to do it correctly? As a workaround, I can write a wrapper function on the module level, which can be vectorized without problems, and call it from inside the class---but it looks ugly and is tedious given that I have multiple functions to be handled in this way. Thanks in advance for any help, Wojciech Smigaj
On 2/14/07, Wojciech Śmigaj <puddleglum@o2.pl> wrote:
Hi,
I have a question about the vectorize function. I'd like to use it to create a vectorized version of a class method. I've tried the following code:
from numpy import *
class X: def func(self, n): return 2 * n # example func = vectorize(func)
Now, when I declare an instance of the class X and invoke func() as an unbound method, it works:
x = X() print X.func(x, [1, 2]) # output: [2 4]
But an attempt to invoke it "normally", i.e. like
print x.func([1, 2])
fails with the message
Traceback (most recent call last): File "<stdin>", line 1, in ? File "/usr/lib/python2.4/site-packages/numpy/lib/function_base.py", line 823, in __call__ raise ValueError, "mismatch between python function inputs"\ ValueError: mismatch between python function inputs and received arguments
It seems that in this case the class instance (x) isn't passed to the vectorize.__call__() method, and as a result the number of arguments does not agree with what this method expects.
Does anybody have an idea of how to do it correctly? As a workaround, I can write a wrapper function on the module level, which can be vectorized without problems, and call it from inside the class---but it looks ugly and is tedious given that I have multiple functions to be handled in this way.
I think you want staticmethod. Something like: class X: def f(x): return 2*x f = staticmethod(vectorize(x)) However, I don't have a Python distribution available here to check that. If that doesn't work, as search on staticmethod should get you to the correct syntax. I'll just note in passing that if your function is composed of completely of things that will operate on arrays as is (as your example is), then vectorizing the function is counter productive. However, your real code may well need vectorize to work. Thanks in advance for any help,
Wojciech Smigaj _______________________________________________ Numpy-discussion mailing list Numpy-discussion@scipy.org http://projects.scipy.org/mailman/listinfo/numpy-discussion
-- //=][=\\ tim.hochberg@ieee.org
Timothy Hochberg wrote:
On 2/14/07, *Wojciech Śmigaj* <puddleglum@o2.pl <mailto:puddleglum@o2.pl>> wrote:
I have a question about the vectorize function. I'd like to use it to create a vectorized version of a class method. I've tried the following code:
from numpy import *
class X: def func(self, n): return 2 * n # example func = vectorize(func)
[...]
I think you want staticmethod. Something like:
class X: def f(x): return 2*x f = staticmethod(vectorize(x))
However, I don't have a Python distribution available here to check that. If that doesn't work, as search on staticmethod should get you to the correct syntax.
I'll just note in passing that if your function is composed of completely of things that will operate on arrays as is (as your example is), then vectorizing the function is counter productive. However, your real code may well need vectorize to work.
Thank you for your answer. I see now that my example was oversimplified. In reality, the method func() accesses internal data of the object, so it cannot be made a staticmethod. In addition, it does not operate on the array as a whole: basically, it does calculations according to some formula if n != 0, and to another one otherwise. Perhaps both parts could be merged in some intelligent way, but right now I want to make the program work, and optimization will be done later. And vectorize is a very nice and quick way of making functions accept arrays, even if it is not super-efficient. Best regards, Wojciech Smigaj
I don't know if this helps but you could use where to do the dispatch between the two different formulas. I don't know the answer to your original question however. On 2/14/07, Wojciech Śmigaj <puddleglum@o2.pl> wrote:
Timothy Hochberg wrote:
On 2/14/07, *Wojciech Śmigaj* <puddleglum@o2.pl <mailto:puddleglum@o2.pl>> wrote:
I have a question about the vectorize function. I'd like to use it to create a vectorized version of a class method. I've tried the following code:
from numpy import *
class X: def func(self, n): return 2 * n # example func = vectorize(func)
[...]
I think you want staticmethod. Something like:
class X: def f(x): return 2*x f = staticmethod(vectorize(x))
However, I don't have a Python distribution available here to check that. If that doesn't work, as search on staticmethod should get you to the correct syntax.
I'll just note in passing that if your function is composed of completely of things that will operate on arrays as is (as your example is), then vectorizing the function is counter productive. However, your real code may well need vectorize to work.
Thank you for your answer. I see now that my example was oversimplified. In reality, the method func() accesses internal data of the object, so it cannot be made a staticmethod. In addition, it does not operate on the array as a whole: basically, it does calculations according to some formula if n != 0, and to another one otherwise. Perhaps both parts could be merged in some intelligent way, but right now I want to make the program work, and optimization will be done later. And vectorize is a very nice and quick way of making functions accept arrays, even if it is not super-efficient.
Best regards, Wojciech Smigaj
_______________________________________________ Numpy-discussion mailing list Numpy-discussion@scipy.org http://projects.scipy.org/mailman/listinfo/numpy-discussion
On 14/02/07, Wojciech Śmigaj <puddleglum@o2.pl> wrote:
Timothy Hochberg wrote:
On 2/14/07, *Wojciech Śmigaj* <puddleglum@o2.pl <mailto:puddleglum@o2.pl>> wrote:
I have a question about the vectorize function. I'd like to use it to create a vectorized version of a class method. I've tried the following code:
from numpy import *
class X: def func(self, n): return 2 * n # example func = vectorize(func)
The appropriate spelling for this, in modern pythons, is class X: @vectorize def func(self, n): return 2*n Not that it makes it work any better. There's no reason vectorize couldn't be made to do the Right Thing when handed (bound and unbound) methods, for example by examining X.func.im_self, X.func.im_class and X.func.im_func attributes. I can't imagine a situation where a method would want to be vectorized over its self parameter, or at least, not by default. Anne
Anne Archibald wrote:
The appropriate spelling for this, in modern pythons, is
class X: @vectorize def func(self, n): return 2*n
Not that it makes it work any better.
There's no reason vectorize couldn't be made to do the Right Thing when handed (bound and unbound) methods, for example by examining X.func.im_self, X.func.im_class and X.func.im_func attributes.
This magic is well above my current level of expertise in Python, but perhaps one day I'll try to do it. Thanks for pointing me in this direction.
I can't imagine a situation where a method would want to be vectorized over its self parameter, or at least, not by default.
Yes, I agree. I thought it would be harmless, though. Anyway, since it seems it is not possible to vectorize() a method with today's NumPy, I think the class' docstring, which says "[...] somefunction -- a Python function or method" is rather misleading. Perhaps it ought to be changed? Best regards, Wojciech Smigaj
participants (4)
-
Anne Archibald -
Timothy Hochberg -
Tom Denniston -
Wojciech Śmigaj