4.3 More Advanced Array Computing
4.3.7 Functionality in the Numpyutils Module
Thenumpyutilsmodule in thescitoolspackage provides some useful add on functions to what is found in NumPy:
– seq: Theseqfunction is similar toarangeandlinspace. It does the same asarange, but guarantees to include the upper limit of the array. Contrary tolinspace,seqrequires the increment between two elements and not the total number of elements as argument.
seq(0, 1, 0.2) # 0., 0.2, 0.4, 0.6, 0.8, 1.0 seq(min=0, max=1, inc=0.2) # same as previous line seq(0, 6, 2, int) # 0, 2, 4, 6 (integers)
seq(3) # 0., 1., 2., 3.
The signature of the function reads
def seq(min=0.0, max=None, inc=1.0, type=float, return_type=’NumPyArray’):
The return_type string argument specifies the returned data structure holding the generated numbers:’NumPyArray’orndarrayimplies a NumPy array,’list’returns a standard Python list, and’tuple’returns a tuple.
Basically, the function creates a NumPy array using r = arange(min, max + inc/2.0, inc, type) and covertsrto list or tuple if necessary.
A warning is demanded regarding the standard use ofarange: This func- tion claims to not include the upper limit, but sometimes the upper limit is included due to round-off errors. Try out the following code segment on your computer to see how often the last element inacontains the upper limit 1.0 or not:
N = 1001
for n in range(1, N):
a = arange(0, 1, 1.0/n) last = a[-1]
print a.size-n, n, last
On my computer, the upper limit was included in 58 out 1001 cases, and a then contained an extra element. Therefore, I suggest to avoidarange for floating-point numbers and stick tolinspaceor seq.
– iseq: The fact that range and xrange do not include the upper limit in integer sequences can be confusing or misleading sometimes when im- plementing mathematical algorithms. The numpyutils module therefore offers a function for generating integers fromstart up to and including stop in increments ofinc:
def iseq(start=0, stop=None, inc=1):
if stop is None: # simulate xrange(start+1) behavior stop = start; start = 0; inc = 1
return xrange(start, stop+inc, inc) A relevant example may be coding of a formula like
xk = (ck−Ak,2xk+1)/dk, i=n−2, n−3, . . . ,0, which translates into
4.3. More Advanced Array Computing 167 for k in iseq(n-2, 0, -1):
x[k] = (c[k] - A[k,2]*x[k+1])/d[k]
Many find this more readable and easier to debug than a loop built with range(n-2,-1,-1).
The iseq function is in general recommended when you need to iterate over a part of an array, because it is easy to control that the arguments to iseq correspond exactly to the loop limits used in the mathematical specification of the algorithm. Such details are often important to quickly get a correct implementation of an algorithm.
– float_eq:float_eq(a, b, rtol, atol)returns a true value if aandbare equal within a relative tolerancertol(default 1014) and an absolute tol- eranceatol(default 1014). More precisely, thefloat_eqfunction returns a true value if
abs(a-b) < atol + rtol*abs(b)
The argumentsa andbcan be floatvariables or NumPy arrays. In the latter case,float_eqjust callsallclose innumpy.
– ndgrid: This function extends one-dimensional coordinate arrays with extra dimensions, which is required for vectorized operations for com- puting scalar and vector fields over 2D and 3D grids, as explained in Chapter 4.3.5. For example,
>>> x = linspace(0, 1, 3) # coordinates along x axis
>>> y = linspace(0, 1, 2) # coordinates along y axis
>>> xv, yv = ndgrid(x, y)
>>> xv
array([[ 0. ], [ 0.5], [ 1. ]])
>>> yv
array([[ 0., 1.]])
Thendgridfunction also handles boundary grids, i.e., 1D/2D slices of 3D grids with one/two of the coordinates kept constant, see the documenta- tion of the function for further details.
(Remark. There are severalndgrid-like functions innumpy:meshgrid,mgrid, andogrid, butscitoolshas its ownndgridfunction becausemeshgridin numpy is limited to 2D grids only and it always returns a full 2D array and not the “sparse” extensions used in Chapter 4.3.5 (unit length in the added dimensions). Theogridfunction can produce “sparse” extensions, but neither ogrid nor mgrid allow for non-uniform grid spacings. The ndgridinscitools.numpyutilsalso allow for both “matrix” indexing and
“grid” indexing of the coordinate arrays. All of these additional features are important when working with 2D and 3D grids.)
– wrap2callable: This is a function for turning integers, real numbers, func- tions, user-defined objects (with a__call__method), string formulas, and
discrete grid data into some object that can be called as an ordinary func- tion (see Chapters 12.2.1 and 12.2.2). You can write a function
def df(f, x, h):
f = wrap2callable(f) # ensure f is a function: f(x) return (f(x+h) - f(x-h))/(2.0*h)
and calldfwith a variety of arguments:
x = 2; h = 0.01
print df(4.2, x, h) # constant 4.2
print df(’sin(x)’, x, h) # string function, sin(x) def q(x):
return sin(x)
print df(q, x, h) # user-defined function q xc = seq(0, 4, 0.05); yc = sin(xc)
print df((xc,yc), x, h) # discrete data xc, yc
The constant 4.2, user-defined function q, discrete data (xc,yc), and string formula’sin(x)’ will all be turned, bywrap2callable, into an ob- jectf, which can be used as an ordinary function inside thedffunction.
Chapter 12.2.2 explains how to construct thewrap2callable tool.
– arr: This function provides a unified short-hand notation for creating arrays in many different ways:
a = arr(100) # as zeros(100) a = arr((M,N)) # as zeros((M,N))
a = arr((M,N), element_type=complex) # Complex elements a = arr(N, interval=[1,10]) # as linspace(1,10,N) a = arr(data=mylist) # as asarray(mylist) a = arr(data=myarr, copy=True) # as array(myarr, copy=1) a = arr(file_=’tmp.dat’) # load tabular data from file Thearrfunction is just a simple, unified interface to thezerosandarray function in NumPy, plus some file reading statements. The file format is a table with a fixed number of columns and rows where whitespace is the delimiter between numbers in a row. One- and two-dimensional arrays can be read this way. The arr function makes several consistency and error checks that are handy to have automated and hidden.