calculating on matrix indices

Robert Kern robert.kern at gmail.com
Thu Feb 16 21:54:02 EST 2006


Brian Blais wrote:
> Hello,
> 
> In my attempt to learn python, migrating from matlab, I have the following problem. 
> Here is what I want to do, (with the wrong syntax):
> 
> from numpy import *
> 
> t=arange(0,20,.1)
> x=zeros(len(t),'f')
> 
> idx=(t>5)
> tau=5
> x[idx]=exp(-t[idx]/tau)  # <---this line is wrong (gives a TypeError)
> 
> #------------------
> 
> what is the best way to replace the wrong line with something that works: replace all 
> of the values of x at the indices idx with exp(-t/tau) for values of t at indices idx?

The traceback tells you exactly what's wrong:

In [7]: x[idx] = exp(-t[idx]/tau)
---------------------------------------------------------------------------
exceptions.TypeError                                 Traceback (most recent call
last)

/Users/kern/<ipython console>

TypeError: array cannot be safely cast to required type

In [8]: t.dtype
Out[8]: dtype('>f8')

In [9]: x.dtype
Out[9]: dtype('>f4')

In [10]: exp(-t[idx]/tau).dtype
Out[10]: dtype('>f8')

The righthand-side is in double precision, but you are trying to stuff it into a
single-precision array. numpy can't do that conversion without losing precision,
so it raises a TypeError. If you really wanted x to be single precision, then
you would explicitly do the conversion on the righthand-side.

In [11]: x[idx] = exp(-t[idx]/tau).astype(float32)

In [12]: x
Out[12]:
array([ 0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
        0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
        0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
        0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
        0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
        0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
        0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
        0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
        0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
        0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
        0.        ,  0.36059493,  0.35345468,  0.34645581,  0.33959553,
...
        0.02024191,  0.0198411 ,  0.01944822,  0.01906312,  0.01868564],
dtype=float32)

However, I suspect that you wanted x to be the same precision as t, which
defaults to double precision just like Python.

In [13]: x = zeros(len(t), float)

In [14]: x[idx] = exp(-t[idx]/tau)

In [15]: x
Out[15]:
array([ 0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
        0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
        0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
        0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
        0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
        0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
        0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
        0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
        0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
        0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
        0.        ,  0.36059494,  0.35345468,  0.34645581,  0.33959553,
...
        0.02024191,  0.01984109,  0.01944821,  0.01906311,  0.01868564])

BTW, because using arange with floating point steps is somewhat unreliable
because it's floating point. You may want to use linspace() instead.

In [16]: linspace?
Type:           function
Base Class:     <type 'function'>
String Form:    <function linspace at 0x6e21f0>
Namespace:      Interactive
File:
/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/numpy-0.9.5.2085-py2.4-macosx-10.4-ppc.egg/numpy/lib/function_base.py
Definition:     linspace(start, stop, num=50, endpoint=True, retstep=False)
Docstring:
    Return evenly spaced numbers.

    Return 'num' evenly spaced samples from 'start' to 'stop'.  If
    'endpoint' is True, the last sample is 'stop'. If 'retstep' is
    True then return the step value used.

-- 
Robert Kern
robert.kern at gmail.com

"In the fields of hell where the grass grows high
 Are the graves of dreams allowed to die."
  -- Richard Harter




More information about the Python-list mailing list