[Matrix-SIG] Casts and slices

jhauser@ifm.uni-kiel.de jhauser@ifm.uni-kiel.de
Mon, 15 Mar 1999 11:43:43 +0100 (CET)


Christos Siopis writes:
 > Greetings, fellow NumPyers
 > 
 > First off, thanks to all the noble souls who created NumPy and
 > then shared it with the rest of us :) Having just changed from
 > an environment where unlimited IDL (in fact, PV WAVE) licenses
 > were available to a place where no IDL is available, I did
 > appreciate NumPy's availability :)
 > 
 > I have a question about what might be a possible inconsistency:
 > 
 > >>> b = reshape(ones(20, 'f'), (10,2))
 > 
 > >>> b[:,0] = b[:,1]   # This works fine: both sides are of the same type.
 > 
 > >>> b[:,0] = sqrt(b[:,1])  # This also works fine.
 > 
 > >>> b[:,0] = b[:,1]**3     # Should this not also work if sqrt works?
 > Traceback (innermost last):
 >   File "<stdin>", line 1, in ?
 > TypeError: Array can not be safely cast to required type
 > 

I don't know, if this is an error, but to be on the save side use:
b[:,0] = (b[:,1]**3).astype('f')

Not sure if this generates an copy in between, but it's probably
faster than map().

 > If the previous does not work because it attempts to cast a
 > double (right hand side) into a float, then should the following
 > not also produce an error, since each element of the list is
 > a Python double:
 > 
 > >>> b[:,0] = (b[:,1]**3).tolist()    # It works.
 > 
 > >>> b[:,0] = map(float, b[:,1]**3)   # It also works.
 > 
 > Since many operations have right hand sides which are doubles,
 > I was wondering if there is an easier way to assign results to
 > float array elements than using the tolist() method or map().

See above...

 > ====
 > 
 > A second question: using take() one can access noncontiguous
 > elements of an array. Is there a way to also assign values to
 > noncontiguous elements? I mean something like:
 > 
 > b[(0,1,4)] = [1.2, 3.4, 5.3]
 > 

Use the arrayfns module from the graphics package. Althoug it works
only on 1-d arrays.

>>> from arrayfns import array_set
>>> array_set(ravel(b),[0,1,4],[1.2, 3.4, 5.3])
>>> b # now the indices were wrong
>>> array([[ 1.20000005,  3.4000001 ],
           [ 1.        ,  1.        ],
           [ 5.30000019,  1.        ],
           [ 1.        ,  1.        ],
           [ 1.        ,  1.        ],
           [ 1.        ,  1.        ],
           [ 1.        ,  1.        ],
           [ 1.        ,  1.        ],
           [ 1.        ,  1.        ],
           [ 1.        ,  1.        ]],'f')

There was a discussion in the SIG and a proposal by David Ascher for a
more general solution.

Hope this helps,

__Janko