[SciPy-User] idiom for iterators, expr(T) if isscalar(T) else array([expr(t) for t in T])
josef.pktd at gmail.com
josef.pktd at gmail.com
Thu Oct 15 12:13:34 EDT 2009
On Thu, Oct 15, 2009 at 11:56 AM, <josef.pktd at gmail.com> wrote:
> On Wed, Oct 14, 2009 at 1:23 PM, denis <denis-bz-gg at t-online.de> wrote:
>> On Oct 14, 2:02 pm, Yosef Meller <yosef... at 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 :)
>
>
> broadcasting is nice, two changes below and it produces an output
> without exception.
> I didn't check whether the output makes sense. I guess vectorize still
> needs to have compatible array dimension in its arguments for
> broadcasting. But in your function, vectorize doesn't seem necessary.
>
> Josef
>
>>
>>
>> """ 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) )
>
> change number 1
>
> - return funciter( f, t )
> + return f(t) #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__":
>
> change number two:
>
> - t = np.arange( 0, 1.01, .1 )
> + t = np.arange( 0, 1.01, .1 )[:,None]
>
>> 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
>> _______________________________________________
>> SciPy-User mailing list
>> SciPy-User at scipy.org
>> http://mail.scipy.org/mailman/listinfo/scipy-user
>>
>
here's a minimum on broadcasting:
>>> p = np.array(( 1, -1 ))
>>> p.shape
(2,)
>>>
>>> t = np.arange(3)
>>> t.shape
(3,)
>>> t*p0
Traceback (most recent call last):
ValueError: shape mismatch: objects cannot be broadcast to a single shape
cannot multiply elementwise two arrays that have different length in
the same dimension
solution: add a new dimension, turn t into a "column vector"
then each (one element) row of `t` is multiplied with each (one
element) column of `p`
t[:,None] or t[:, np.newaxis] add a new axis and increase dimension of array
more explanation in docs
>>> np.atleast_2d(t).T
array([[0],
[1],
[2]])
>>> np.atleast_2d(t).T * p
array([[ 0, 0],
[ 1, -1],
[ 2, -2]])
>>> t[:,None].shape
(3, 1)
>>> t[:,None] * p
array([[ 0, 0],
[ 1, -1],
[ 2, -2]])
Josef
More information about the SciPy-User
mailing list