[SciPy-user] vectorizing methods?

Gael Varoquaux gael.varoquaux@normalesup....
Sun Jul 15 04:32:44 CDT 2007


On Sat, Jul 14, 2007 at 04:31:59PM -0700, Greg Novak wrote:
> Is there a preferred way to vectorize methods, rather than functions?
> The obvious thing doesn't work:

> class foo:
>     def bar(self, x): pass
>     bar = vectorize(bar)

This cannot work, as you are applying "vectorize" before the class is
built, so the function is still unbound. The binding process, which
happens during the building of the class, will not like what you have
done to the function to vectorize it, mainly the fact that it is no
longer a plain function.


> class foo:
>     __vectorMethods = ('bar', )

>     def __init__(self, n):
>         for name in self.__vectorMethods:
>             setattr(self, name, vectorize(getattr(self, name)))

>     def bar(self, x): pass

There you are vectorizing after the construction of the instance, so the
method is already bound.

> which works fine but it doesn't seem like it should be necessary to do
> it in the initialization of every instance.

Well, if your methods don't really refer to the object (they don't use
self at all in the body of the function), you could do something like:

class Foo(object):
    @staticmethod
    @vectorize
    def bar(x):
        return x


In the static method there is no reference to the object. The problem is
that when the class is binding the method (making a call in which the
first argument is already assigned to the instance) it is really
modifying it. If you could apply vectorize to only part of the argument,
and get a curry of the original function you could than transform 
bar(self, *args) in baz(self, *args), where *args can be vectors, and
this might work.

Is can see two ways out of this:

   1) Do some heavy magic with a metaclass and modify the binding process
      (I am talking about things I don't know, so it may not be
      feasible).

 2.a) Use a static method that you vectorize, and pass it the instance as
      the first argument using a convention bound method:

	class Foo(object):
	    @staticmethod
	    @vectorize
	    def bar(self, x):
		return self.a + x
		
	    def baz(self, x):
		return self.bar(self, x)

	    a = 1

 2.b) IMHO it would be even cleaner to only pass interesting vectors to
      the vectorize staticmethod, as it has been vectorized relatively to
      "self", but self cannot be a vector:

	class Foo(object):
	    @staticmethod
	    @vectorize
	    def bar(a, x):
		return a + x
		
	    def baz(self, x):
		return self.bar(self.a, x)

	    a = 1

      Basically this is similar to using a standard function instead of a
      method, but lets face it, the notions of bound method and
      vectorized function seem mutually incompatible as they both want to
      modify a function.

It might be possible to implement a decorator similar to staticmethod
that does the proces presented in 2.a) but hiddes it from the user, but
to do this, you would need to understand how staticmethod works, and I
suspect there is some cooperation of the class building mechanisme (so we
are back to 1), I think).

I hope 2.a) or 2.b) suit you, elsewhere maybe some one has a better idea ?

Cheers,

Gaël


More information about the SciPy-user mailing list