[SciPy-User] idiom for iterators, expr(T) if isscalar(T) else array([expr(t) for t in T])

Yosef Meller yosefmel@post.tau.ac...
Thu Oct 15 02:30:43 CDT 2009


On יום רביעי 14 אוקטובר 2009 19:23:47 denis wrote:
> On Oct 14, 2:02 pm, Yosef Meller <yosef...@post.tau.ac.il> wrote:
> > v_expr = numpy.vectorize(expr)
> > v_expr(T)
> >
> > Is that what you wanted?
> 
> Yosef,
>   thanks, the right direction -- there must be a numpy primitive for
> this.
> But 2 problems with vectorize:
> 1) an optional arg => TypeError: __call__() got an unexpected keyword
> argument 'h'
> 2) vectorize => broadcasting => ValueError
> Here's a test case: ugly, but funciter() is at least correct :)
> 
> 
> """ funciter, vectorize ?  14oct """
> import numpy as np
> 
> def spline_2p2s( t, p0, p1, m0, m1, h=1 ):
>     """ Hermite 2-point, 2-slope spline
>         t: a scalar / range / iterator
>         p0 p1 m0 m1: scalars or arrays
>         Beware: t and p0 both vecs => broadcasting =>
>             ValueError: shape mismatch: objects cannot be broadcast to
> a single shape
>         (need guidelines, axioms on broadcasting)
>     """
>     def f(t):
>         t2 = t*t
>         t3 = t2*t
>         return (
>               p0 * (2*t3 - 3*t2 + 1)
>             + p1 * (-2*t3 + 3*t2)
>             + m0 * h * (t3 - 2*t2 + t)
>             + m1 * h * (t3 - t2) )
>     return funciter( f, t )
> 
> def funciter( f, T ):
>     return f(T) if np.isscalar(T) \
>         else np.array([ f(t) for t in T ])
> 
> #..........................................................................
> ..... if __name__ == "__main__":
>     t = np.arange( 0, 1.01, .1 )
>     p0 = np.array(( 0, 0 ))
>     p1 = np.array(( 1, 0 ))
>     m0 = np.array(( 1, 1 ))
>     m1 = np.array(( 1, -1 ))
> 
>     s = spline_2p2s( t, p0, p1, m0, m1 )
>     print "spline_2p2s", s.T
> 
>     spline_2p2s_vec = np.vectorize( spline_2p2s )
>     s = spline_2p2s_vec( t, p0, p1, m0, m1 )
>     print "spline_2p2s_vec", s.T

First of all, the candidate for vectorization is f(t) inside spline_2p2s, not 
spline_2p2s itself. Second, since for each t you may get multiple results 
based on the size of pi, mi, you might want to check frompyfunc() instead of 
vectorize().

Most important, if broadcasting is hard for you, you might still save a lot of 
time by using np.multiply.outer() instead of vectorizing an inner function. 
outer() returns the operation's result on each possible pair of its two 
arguments. 
See if that works for you.

Yours,
yosef.


More information about the SciPy-User mailing list