SciPy Reference Guide
User Manual:
Open the PDF directly: View PDF .
Page Count: 1229
Download | |
Open PDF In Browser | View PDF |
SciPy Reference Guide Release 0.13.0 Written by the SciPy community October 21, 2013 CONTENTS 1 2 SciPy Tutorial 1.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2 Basic functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3 Special functions (scipy.special) . . . . . . . . . . . . . . . 1.4 Integration (scipy.integrate) . . . . . . . . . . . . . . . . . 1.5 Optimization (scipy.optimize) . . . . . . . . . . . . . . . . . 1.6 Interpolation (scipy.interpolate) . . . . . . . . . . . . . . 1.7 Fourier Transforms (scipy.fftpack) . . . . . . . . . . . . . . 1.8 Signal Processing (scipy.signal) . . . . . . . . . . . . . . . . 1.9 Linear Algebra (scipy.linalg) . . . . . . . . . . . . . . . . . 1.10 Sparse Eigenvalue Problems with ARPACK . . . . . . . . . . . . . 1.11 Compressed Sparse Graph Routines scipy.sparse.csgraph 1.12 Spatial data structures and algorithms (scipy.spatial) . . . . 1.13 Statistics (scipy.stats) . . . . . . . . . . . . . . . . . . . . . 1.14 Multidimensional image processing (scipy.ndimage) . . . . . 1.15 File IO (scipy.io) . . . . . . . . . . . . . . . . . . . . . . . . . 1.16 Weave (scipy.weave) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 . 3 . 5 . 9 . 11 . 16 . 29 . 41 . 44 . 52 . 65 . 68 . 71 . 77 . 96 . 117 . 123 Contributing to SciPy 2.1 Contributing new code . . . . . . . . . . . . . 2.2 Contributing by helping maintain existing code 2.3 Other ways to contribute . . . . . . . . . . . . 2.4 Recommended development setup . . . . . . . 2.5 SciPy structure . . . . . . . . . . . . . . . . . 2.6 Useful links, FAQ, checklist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159 159 160 161 161 162 162 3 API - importing from Scipy 165 3.1 Guidelines for importing functions from Scipy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 3.2 API definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166 4 Release Notes 4.1 SciPy 0.13.0 Release Notes 4.2 SciPy 0.12.0 Release Notes 4.3 SciPy 0.11.0 Release Notes 4.4 SciPy 0.10.0 Release Notes 4.5 SciPy 0.9.0 Release Notes . 4.6 SciPy 0.8.0 Release Notes . 4.7 SciPy 0.7.2 Release Notes . 4.8 SciPy 0.7.1 Release Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169 169 176 181 187 191 195 199 199 i 4.9 5 SciPy 0.7.0 Release Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201 Reference 5.1 Clustering package (scipy.cluster) . . . . . . . . . . . . . . . . . . . 5.2 K-means clustering and vector quantization (scipy.cluster.vq) . . . . 5.3 Hierarchical clustering (scipy.cluster.hierarchy) . . . . . . . . . 5.4 Constants (scipy.constants) . . . . . . . . . . . . . . . . . . . . . . . 5.5 Discrete Fourier transforms (scipy.fftpack) . . . . . . . . . . . . . . . 5.6 Integration and ODEs (scipy.integrate) . . . . . . . . . . . . . . . . 5.7 Interpolation (scipy.interpolate) . . . . . . . . . . . . . . . . . . . 5.8 Input and output (scipy.io) . . . . . . . . . . . . . . . . . . . . . . . . . 5.9 Linear algebra (scipy.linalg) . . . . . . . . . . . . . . . . . . . . . . 5.10 Low-level BLAS functions . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.11 Finding functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.12 All functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.13 Low-level LAPACK functions . . . . . . . . . . . . . . . . . . . . . . . . . 5.14 Finding functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.15 All functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.16 Interpolative matrix decomposition (scipy.linalg.interpolative) 5.17 Miscellaneous routines (scipy.misc) . . . . . . . . . . . . . . . . . . . 5.18 Multi-dimensional image processing (scipy.ndimage) . . . . . . . . . . 5.19 Orthogonal distance regression (scipy.odr) . . . . . . . . . . . . . . . . 5.20 Optimization and root finding (scipy.optimize) . . . . . . . . . . . . . 5.21 Nonlinear solvers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.22 Signal processing (scipy.signal) . . . . . . . . . . . . . . . . . . . . . 5.23 Sparse matrices (scipy.sparse) . . . . . . . . . . . . . . . . . . . . . . 5.24 Sparse linear algebra (scipy.sparse.linalg) . . . . . . . . . . . . . 5.25 Compressed Sparse Graph Routines (scipy.sparse.csgraph) . . . . . 5.26 Spatial algorithms and data structures (scipy.spatial) . . . . . . . . . 5.27 Distance computations (scipy.spatial.distance) . . . . . . . . . . 5.28 Special functions (scipy.special) . . . . . . . . . . . . . . . . . . . . 5.29 Statistical functions (scipy.stats) . . . . . . . . . . . . . . . . . . . . 5.30 Statistical functions for masked arrays (scipy.stats.mstats) . . . . . 5.31 C/C++ integration (scipy.weave) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207 207 207 211 226 241 255 273 320 331 373 373 373 398 398 398 448 457 466 520 530 593 595 692 784 809 819 853 867 897 1162 1188 Bibliography 1193 Index 1205 ii SciPy Reference Guide, Release 0.13.0 Release Date 0.13.0 October 21, 2013 SciPy (pronounced “Sigh Pie”) is open-source software for mathematics, science, and engineering. CONTENTS 1 SciPy Reference Guide, Release 0.13.0 2 CONTENTS CHAPTER ONE SCIPY TUTORIAL 1.1 Introduction Contents • Introduction – SciPy Organization – Finding Documentation SciPy is a collection of mathematical algorithms and convenience functions built on the Numpy extension of Python. It adds significant power to the interactive Python session by providing the user with high-level commands and classes for manipulating and visualizing data. With SciPy an interactive Python session becomes a data-processing and systemprototyping environment rivaling sytems such as MATLAB, IDL, Octave, R-Lab, and SciLab. The additional benefit of basing SciPy on Python is that this also makes a powerful programming language available for use in developing sophisticated programs and specialized applications. Scientific applications using SciPy benefit from the development of additional modules in numerous niche’s of the software landscape by developers across the world. Everything from parallel programming to web and data-base subroutines and classes have been made available to the Python programmer. All of this power is available in addition to the mathematical libraries in SciPy. This tutorial will acquaint the first-time user of SciPy with some of its most important features. It assumes that the user has already installed the SciPy package. Some general Python facility is also assumed, such as could be acquired by working through the Python distribution’s Tutorial. For further introductory help the user is directed to the Numpy documentation. For brevity and convenience, we will often assume that the main packages (numpy, scipy, and matplotlib) have been imported as: >>> >>> >>> >>> import import import import numpy as np scipy as sp matplotlib as mpl matplotlib.pyplot as plt These are the import conventions that our community has adopted after discussion on public mailing lists. You will see these conventions used throughout NumPy and SciPy source code and documentation. While we obviously don’t require you to follow these conventions in your own code, it is highly recommended. 1.1.1 SciPy Organization SciPy is organized into subpackages covering different scientific computing domains. These are summarized in the following table: 3 SciPy Reference Guide, Release 0.13.0 Subpackage cluster constants fftpack integrate interpolate io linalg ndimage odr optimize signal sparse spatial special stats weave Description Clustering algorithms Physical and mathematical constants Fast Fourier Transform routines Integration and ordinary differential equation solvers Interpolation and smoothing splines Input and Output Linear algebra N-dimensional image processing Orthogonal distance regression Optimization and root-finding routines Signal processing Sparse matrices and associated routines Spatial data structures and algorithms Special functions Statistical distributions and functions C/C++ integration Scipy sub-packages need to be imported separately, for example: >>> from scipy import linalg, optimize Because of their ubiquitousness, some of the functions in these subpackages are also made available in the scipy namespace to ease their use in interactive sessions and programs. In addition, many basic array functions from numpy are also available at the top-level of the scipy package. Before looking at the sub-packages individually, we will first look at some of these common functions. 1.1.2 Finding Documentation SciPy and NumPy have documentation versions in both HTML and PDF format available at http://docs.scipy.org/, that cover nearly all available functionality. However, this documentation is still work-in-progress and some parts may be incomplete or sparse. As we are a volunteer organization and depend on the community for growth, your participation - everything from providing feedback to improving the documentation and code - is welcome and actively encouraged. Python’s documentation strings are used in SciPy for on-line documentation. There are two methods for reading them and getting help. One is Python’s command help in the pydoc module. Entering this command with no arguments (i.e. >>> help ) launches an interactive help session that allows searching through the keywords and modules available to all of Python. Secondly, running the command help(obj) with an object as the argument displays that object’s calling signature, and documentation string. The pydoc method of help is sophisticated but uses a pager to display the text. Sometimes this can interfere with the terminal you are running the interactive session within. A scipy-specific help system is also available under the command sp.info. The signature and documentation string for the object passed to the help command are printed to standard output (or to a writeable object passed as the third argument). The second keyword argument of sp.info defines the maximum width of the line for printing. If a module is passed as the argument to help than a list of the functions and classes defined in that module is printed. For example: >>> sp.info(optimize.fmin) fmin(func, x0, args=(), xtol=0.0001, ftol=0.0001, maxiter=None, maxfun=None, full_output=0, disp=1, retall=0, callback=None) Minimize a function using the downhill simplex algorithm. Parameters ---------func : callable func(x,*args) 4 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 The objective function to be minimized. x0 : ndarray Initial guess. args : tuple Extra arguments passed to func, i.e. ‘‘f(x,*args)‘‘. callback : callable Called after each iteration, as callback(xk), where xk is the current parameter vector. Returns ------xopt : ndarray Parameter that minimizes function. fopt : float Value of function at minimum: ‘‘fopt = func(xopt)‘‘. iter : int Number of iterations performed. funcalls : int Number of function calls made. warnflag : int 1 : Maximum number of function evaluations made. 2 : Maximum number of iterations reached. allvecs : list Solution at each iteration. Other parameters ---------------xtol : float Relative error ftol : number Relative error maxiter : int Maximum number maxfun : number Maximum number full_output : bool Set to True if disp : bool Set to True to retall : bool Set to True to in xopt acceptable for convergence. in func(xopt) acceptable for convergence. of iterations to perform. of function evaluations to make. fopt and warnflag outputs are desired. print convergence messages. return list of solutions at each iteration. Notes ----Uses a Nelder-Mead simplex algorithm to find the minimum of function of one or more variables. Another useful command is source. When given a function written in Python as an argument, it prints out a listing of the source code for that function. This can be helpful in learning about an algorithm or understanding exactly what a function is doing with its arguments. Also don’t forget about the Python command dir which can be used to look at the namespace of a module or package. 1.2 Basic functions 1.2. Basic functions 5 SciPy Reference Guide, Release 0.13.0 Contents • Basic functions – Interaction with Numpy * Index Tricks * Shape manipulation * Polynomials * Vectorizing functions (vectorize) * Type handling * Other useful functions 1.2.1 Interaction with Numpy Scipy builds on Numpy, and for all basic array handling needs you can use Numpy functions: >>> import numpy as np >>> np.some_function() Rather than giving a detailed description of each of these functions (which is available in the Numpy Reference Guide or by using the help, info and source commands), this tutorial will discuss some of the more useful commands which require a little introduction to use to their full potential. To use functions from some of the Scipy modules, you can do: >>> from scipy import some_module >>> some_module.some_function() The top level of scipy also contains functions from numpy and numpy.lib.scimath. However, it is better to use them directly from the numpy module instead. Index Tricks There are some class instances that make special use of the slicing functionality to provide efficient means for array construction. This part will discuss the operation of np.mgrid , np.ogrid , np.r_ , and np.c_ for quickly constructing arrays. For example, rather than writing something like the following >>> concatenate(([3],[0]*5,arange(-1,1.002,2/9.0))) with the r_ command one can enter this as >>> r_[3,[0]*5,-1:1:10j] which can ease typing and make for more readable code. Notice how objects are concatenated, and the slicing syntax is (ab)used to construct ranges. The other term that deserves a little explanation is the use of the complex number 10j as the step size in the slicing syntax. This non-standard use allows the number to be interpreted as the number of points to produce in the range rather than as a step size (note we would have used the long integer notation, 10L, but this notation may go away in Python as the integers become unified). This non-standard usage may be unsightly to some, but it gives the user the ability to quickly construct complicated vectors in a very readable fashion. When the number of points is specified in this way, the end- point is inclusive. The “r” stands for row concatenation because if the objects between commas are 2 dimensional arrays, they are stacked by rows (and thus must have commensurate columns). There is an equivalent command c_ that stacks 2d arrays by columns but works identically to r_ for 1d arrays. 6 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 Another very useful class instance which makes use of extended slicing notation is the function mgrid. In the simplest case, this function can be used to construct 1d ranges as a convenient substitute for arange. It also allows the use of complex-numbers in the step-size to indicate the number of points to place between the (inclusive) end-points. The real purpose of this function however is to produce N, N-d arrays which provide coordinate arrays for an N-dimensional volume. The easiest way to understand this is with an example of its usage: >>> mgrid[0:5,0:5] array([[[0, 0, 0, 0, 0], [1, 1, 1, 1, 1], [2, 2, 2, 2, 2], [3, 3, 3, 3, 3], [4, 4, 4, 4, 4]], [[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]]]) >>> mgrid[0:5:4j,0:5:4j] array([[[ 0. , 0. , [ 1.6667, 1.6667, [ 3.3333, 3.3333, [ 5. , 5. , [[ 0. , 1.6667, [ 0. , 1.6667, [ 0. , 1.6667, [ 0. , 1.6667, 0. , 1.6667, 3.3333, 5. , 3.3333, 3.3333, 3.3333, 3.3333, 0. ], 1.6667], 3.3333], 5. ]], 5. ], 5. ], 5. ], 5. ]]]) Having meshed arrays like this is sometimes very useful. However, it is not always needed just to evaluate some Ndimensional function over a grid due to the array-broadcasting rules of Numpy and SciPy. If this is the only purpose for generating a meshgrid, you should instead use the function ogrid which generates an “open” grid using newaxis judiciously to create N, N-d arrays where only one dimension in each array has length greater than 1. This will save memory and create the same result if the only purpose for the meshgrid is to generate sample points for evaluation of an N-d function. Shape manipulation In this category of functions are routines for squeezing out length- one dimensions from N-dimensional arrays, ensuring that an array is at least 1-, 2-, or 3-dimensional, and stacking (concatenating) arrays by rows, columns, and “pages “(in the third dimension). Routines for splitting arrays (roughly the opposite of stacking arrays) are also available. Polynomials There are two (interchangeable) ways to deal with 1-d polynomials in SciPy. The first is to use the poly1d class from Numpy. This class accepts coefficients or polynomial roots to initialize a polynomial. The polynomial object can then be manipulated in algebraic expressions, integrated, differentiated, and evaluated. It even prints like a polynomial: >>> p = poly1d([3,4,5]) >>> print p 2 3 x + 4 x + 5 >>> print p*p 4 3 2 9 x + 24 x + 46 x + 40 x + 25 >>> print p.integ(k=6) 3 2 x + 2 x + 5 x + 6 1.2. Basic functions 7 SciPy Reference Guide, Release 0.13.0 >>> print p.deriv() 6 x + 4 >>> p([4,5]) array([ 69, 100]) The other way to handle polynomials is as an array of coefficients with the first element of the array giving the coefficient of the highest power. There are explicit functions to add, subtract, multiply, divide, integrate, differentiate, and evaluate polynomials represented as sequences of coefficients. Vectorizing functions (vectorize) One of the features that NumPy provides is a class vectorize to convert an ordinary Python function which accepts scalars and returns scalars into a “vectorized-function” with the same broadcasting rules as other Numpy functions (i.e. the Universal functions, or ufuncs). For example, suppose you have a Python function named addsubtract defined as: >>> def addsubtract(a,b): ... if a > b: ... return a - b ... else: ... return a + b which defines a function of two scalar variables and returns a scalar result. The class vectorize can be used to “vectorize “this function so that >>> vec_addsubtract = vectorize(addsubtract) returns a function which takes array arguments and returns an array result: >>> vec_addsubtract([0,3,6,9],[1,3,5,7]) array([1, 6, 1, 2]) This particular function could have been written in vector form without the use of vectorize . But, what if the function you have written is the result of some optimization or integration routine. Such functions can likely only be vectorized using vectorize. Type handling Note the difference between np.iscomplex/np.isreal and np.iscomplexobj/np.isrealobj. The former command is array based and returns byte arrays of ones and zeros providing the result of the element-wise test. The latter command is object based and returns a scalar describing the result of the test on the entire object. Often it is required to get just the real and/or imaginary part of a complex number. While complex numbers and arrays have attributes that return those values, if one is not sure whether or not the object will be complex-valued, it is better to use the functional forms np.real and np.imag . These functions succeed for anything that can be turned into a Numpy array. Consider also the function np.real_if_close which transforms a complex-valued number with tiny imaginary part into a real number. Occasionally the need to check whether or not a number is a scalar (Python (long)int, Python float, Python complex, or rank-0 array) occurs in coding. This functionality is provided in the convenient function np.isscalar which returns a 1 or a 0. Finally, ensuring that objects are a certain Numpy type occurs often enough that it has been given a convenient interface in SciPy through the use of the np.cast dictionary. The dictionary is keyed by the type it is desired to cast to and the dictionary stores functions to perform the casting. Thus, np.cast[’f’](d) returns an array of np.float32 from d. This function is also useful as an easy way to get a scalar of a certain type: 8 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 >>> np.cast[’f’](np.pi) array(3.1415927410125732, dtype=float32) Other useful functions There are also several other useful functions which should be mentioned. For doing phase processing, the functions angle, and unwrap are useful. Also, the linspace and logspace functions return equally spaced samples in a linear or log scale. Finally, it’s useful to be aware of the indexing capabilities of Numpy. Mention should be made of the function select which extends the functionality of where to include multiple conditions and multiple choices. The calling convention is select(condlist,choicelist,default=0). select is a vectorized form of the multiple if-statement. It allows rapid construction of a function which returns an array of results based on a list of conditions. Each element of the return array is taken from the array in a choicelist corresponding to the first condition in condlist that is true. For example >>> x = r_[-2:3] >>> x array([-2, -1, 0, 1, 2]) >>> np.select([x > 3, x >= 0],[0,x+2]) array([0, 0, 2, 3, 4]) Some additional useful functions can also be found in the module scipy.misc. For example the factorial and comb functions compute n! and n!/k!(n − k)! using either exact integer arithmetic (thanks to Python’s Long integer object), or by using floating-point precision and the gamma function. Another function returns a common image used in image processing: lena. Finally, two functions are provided that are useful for approximating derivatives of functions using discrete-differences. The function central_diff_weights returns weighting coefficients for an equally-spaced N -point approximation to the derivative of order o. These weights must be multiplied by the function corresponding to these points and the results added to obtain the derivative approximation. This function is intended for use when only samples of the function are avaiable. When the function is an object that can be handed to a routine and evaluated, the function derivative can be used to automatically evaluate the object at the correct points to obtain an N-point approximation to the o-th derivative at a given point. 1.3 Special functions (scipy.special) The main feature of the scipy.special package is the definition of numerous special functions of mathematical physics. Available functions include airy, elliptic, bessel, gamma, beta, hypergeometric, parabolic cylinder, mathieu, spheroidal wave, struve, and kelvin. There are also some low-level stats functions that are not intended for general use as an easier interface to these functions is provided by the stats module. Most of these functions can take array arguments and return array results following the same broadcasting rules as other math functions in Numerical Python. Many of these functions also accept complex numbers as input. For a complete list of the available functions with a one-line description type >>> help(special). Each function also has its own documentation accessible using help. If you don’t see a function you need, consider writing it and contributing it to the library. You can write the function in either C, Fortran, or Python. Look in the source code of the library for examples of each of these kinds of functions. 1.3. Special functions (scipy.special) 9 SciPy Reference Guide, Release 0.13.0 1.3.1 Bessel functions of real order(jn, jn_zeros) Bessel functions are a family of solutions to Bessel’s differential equation with real or complex order alpha: x2 dy d2 y +x + (x2 − α2 )y = 0 2 dx dx Among other uses, these functions arise in wave propagation problems such as the vibrational modes of a thin drum head. Here is an example of a circular drum head anchored at the edge: >>> >>> >>> ... ... >>> >>> >>> >>> >>> from scipy import * from scipy.special import jn, jn_zeros def drumhead_height(n, k, distance, angle, t): nth_zero = jn_zeros(n, k) return cos(t)*cos(n*angle)*jn(n, distance*nth_zero) theta = r_[0:2*pi:50j] radius = r_[0:1:50j] x = array([r*cos(theta) for r in radius]) y = array([r*sin(theta) for r in radius]) z = array([drumhead_height(1, 1, r, theta, 0.5) for r in radius]) >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> import pylab from mpl_toolkits.mplot3d import Axes3D from matplotlib import cm fig = pylab.figure() ax = Axes3D(fig) ax.plot_surface(x, y, z, rstride=1, cstride=1, cmap=cm.jet) ax.set_xlabel(’X’) ax.set_ylabel(’Y’) ax.set_zlabel(’Z’) pylab.show() 1.0 10 0.5 0.0 X 0.5 1.0 1.0 0.5 0.5 0.0 Y 0.6 0.4 0.2 0.0 Z 0.2 0.4 0.6 1.0 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 1.4 Integration (scipy.integrate) The scipy.integrate sub-package provides several integration techniques including an ordinary differential equation integrator. An overview of the module is provided by the help command: >>> help(integrate) Methods for Integrating Functions given function object. quad dblquad tplquad fixed_quad quadrature romberg ------- General purpose integration. General purpose double integration. General purpose triple integration. Integrate func(x) using Gaussian quadrature of order n. Integrate with given tolerance using Gaussian quadrature. Integrate func using Romberg integration. Methods for Integrating Functions given fixed samples. trapz cumtrapz simps romb ----- Use trapezoidal rule to compute integral from samples. Use trapezoidal rule to cumulatively compute integral. Use Simpson’s rule to compute integral from samples. Use Romberg Integration to compute integral from (2**k + 1) evenly-spaced samples. See the special module’s orthogonal polynomials (special) for Gaussian quadrature roots and weights for other weighting factors and regions. Interface to numerical integrators of ODE systems. odeint ode -- General integration of ordinary differential equations. -- Integrate ODE using VODE and ZVODE routines. 1.4.1 General integration (quad) The function quad is provided to integrate a function of one variable between two points. The points can be ±∞ (± inf) to indicate infinite limits. For example, suppose you wish to integrate a bessel function jv(2.5,x) along the interval [0, 4.5]. Z I= 4.5 J2.5 (x) dx. 0 This could be computed using quad: >>> result = integrate.quad(lambda x: special.jv(2.5,x), 0, 4.5) >>> print result (1.1178179380783249, 7.8663172481899801e-09) >>> I = sqrt(2/pi)*(18.0/27*sqrt(2)*cos(4.5)-4.0/27*sqrt(2)*sin(4.5)+ sqrt(2*pi)*special.fresnel(3/sqrt(pi))[0]) >>> print I 1.117817938088701 >>> print abs(result[0]-I) 1.03761443881e-11 The first argument to quad is a “callable” Python object (i.e a function, method, or class instance). Notice the use of a lambda- function in this case as the argument. The next two arguments are the limits of integration. The return value 1.4. Integration (scipy.integrate) 11 SciPy Reference Guide, Release 0.13.0 is a tuple, with the first element holding the estimated value of the integral and the second element holding an upper bound on the error. Notice, that in this case, the true value of this integral is r √ 2 18 √ 4√ 3 2 cos (4.5) − 2 sin (4.5) + 2πSi √ , I= π 27 27 π where Z x Si (x) = sin 0 π t2 dt. 2 is the Fresnel sine integral. Note that the numerically-computed integral is within 1.04 × 10−11 of the exact result — well below the reported error bound. If the function to integrate takes additional parameters, the can be provided in the args argument. Suppose that the following integral shall be calculated: Z 1 ax2 + b dx. I(a, b) = 0 This integral can be evaluated by using the following code: >>> >>> ... >>> >>> >>> >>> from scipy.integrate import quad def integrand(x, a, b): return a * x + b a = 2 b = 1 I = quad(integrand, 0, 1, args=(a,b)) I = (2.0, 2.220446049250313e-14) Infinite inputs are also allowed in quad by using ± inf as one of the arguments. For example, suppose that a numerical value for the exponential integral: Z ∞ −xt e dt. En (x) = tn 1 is desired (and the fact that this integral can be computed as special.expn(n,x) is forgotten). The functionality of the function special.expn can be replicated by defining a new function vec_expint based on the routine quad: >>> from scipy.integrate import quad >>> def integrand(t,n,x): ... return exp(-x*t) / t**n >>> def expint(n,x): ... return quad(integrand, 1, Inf, args=(n, x))[0] >>> vec_expint = vectorize(expint) >>> vec_expint(3,arange(1.0,4.0,0.5)) array([ 0.1097, 0.0567, 0.0301, 0.0163, >>> special.expn(3,arange(1.0,4.0,0.5)) array([ 0.1097, 0.0567, 0.0301, 0.0163, 0.0089, 0.0049]) 0.0089, 0.0049]) The function which is integrated can even use the quad argument (though the error bound may underestimate the error due to possible numerical error in the integrand from the use of quad ). The integral in this case is Z ∞ Z ∞ −xt e 1 In = dt dx = . n t n 0 1 12 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 >>> result = quad(lambda x: expint(3, x), 0, inf) >>> print result (0.33333333324560266, 2.8548934485373678e-09) >>> I3 = 1.0/3.0 >>> print I3 0.333333333333 >>> print I3 - result[0] 8.77306560731e-11 This last example shows that multiple integration can be handled using repeated calls to quad. 1.4.2 General multiple integration (dblquad, tplquad, nquad) The mechanics for double and triple integration have been wrapped up into the functions dblquad and tplquad. These functions take the function to integrate and four, or six arguments, respecively. The limits of all inner integrals need to be defined as functions. An example of using double integration to compute several values of In is shown below: >>> from scipy.integrate import quad, dblquad >>> def I(n): ... return dblquad(lambda t, x: exp(-x*t)/t**n, 0, Inf, lambda x: 1, lambda x: Inf) >>> print I(4) (0.25000000000435768, 1.0518245707751597e-09) >>> print I(3) (0.33333333325010883, 2.8604069919261191e-09) >>> print I(2) (0.49999999999857514, 1.8855523253868967e-09) As example for non-constant limits consider the integral Z 1/2 Z 1−2y I= xy dx dy = y=0 x=0 1 . 96 This integral can be evaluated using the expression below (Note the use of the non-constant lambda functions for the upper limit of the inner integral): >>> from scipy.integrate import dblquad >>> area = dblquad(lambda x, y: x*y, 0, 0.5, lambda x: 0, lambda x: 1-2*x) >>> area (0.010416666666666668, 1.1564823173178715e-16) For n-fold integration, scipy provides the function nquad. The integration bounds are an iterable object: either a list of constant bounds, or a list of functions for the non-constant integration bounds. The order of integration (and therefore the bounds) is from the innermost integral to the outermost one. The integral from above Z ∞ Z In = 0 1 ∞ e−xt 1 dt dx = tn n can be calculated as 1.4. Integration (scipy.integrate) 13 SciPy Reference Guide, Release 0.13.0 >>> from scipy import integrate >>> N = 5 >>> def f(t, x): >>> return np.exp(-x*t) / t**N >>> integrate.nquad(f, [[1, np.inf],[0, np.inf]]) (0.20000000000002294, 1.2239614263187945e-08) Note that the order of arguments for f must match the order of the integration bounds; i.e. the inner integral with respect to t is on the interval [1, ∞] and the outer integral with respect to x is on the interval [0, ∞]. Non-constant integration bounds can be treated in a similar manner; the example from above Z 1/2 Z 1−2y xy dx dy = I= y=0 x=0 1 . 96 can be evaluated by means of >>> from scipy import integrate >>> def f(x,y): >>> return x*y >>> def bounds_y(): >>> return [0, 0.5] >>> def bounds_x(y): >>> return [0, 1-2*y] >>> integrate.nquad(f, [bounds_x, bounds_y]) (0.010416666666666668, 4.101620128472366e-16) which is the same result as before. 1.4.3 Gaussian quadrature A few functions are also provided in order to perform simple Gaussian quadrature over a fixed interval. The first is fixed_quad which performs fixed-order Gaussian quadrature. The second function is quadrature which performs Gaussian quadrature of multiple orders until the difference in the integral estimate is beneath some tolerance supplied by the user. These functions both use the module special.orthogonal which can calculate the roots and quadrature weights of a large variety of orthogonal polynomials (the polynomials themselves are available as special functions returning instances of the polynomial class — e.g. special.legendre). 1.4.4 Romberg Integration Romberg’s method [WPR] is another method for numerically evaluating an integral. See the help function for romberg for further details. 1.4.5 Integrating using Samples If the samples are equally-spaced and the number of samples available is 2k + 1 for some integer k, then Romberg romb integration can be used to obtain high-precision estimates of the integral using the available samples. Romberg integration uses the trapezoid rule at step-sizes related by a power of two and then performs Richardson extrapolation on these estimates to approximate the integral with a higher-degree of accuracy. In case of arbitrary spaced samples, the two functions trapz (defined in numpy [NPT]) and simps are available. They are using Newton-Coates formulas of order 1 and 2 respectively to perform integration. The trapezoidal rule approximates the function as a straight line between adjacent points, while Simpson’s rule approximates the function between three adjacent points as a parabola. 14 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 For an odd number of samples that are equally spaced Simpson’s rule is exact if the function is a polynomial of order 3 or less. If the samples are not equally spaced, then the result is exact only if the function is a polynomial of order 2 or less. >>> from scipy.integrate import simps >>> import numpy as np >>> def f(x): ... return x**2 >>> def f2(x): ... return x**3 >>> x = np.array([1,3,4]) >>> y1 = f1(x) >>> I1 = integrate.simps(y1,x) >>> print(I1) 21.0 This corresponds exactly to 4 Z x2 dx = 21, 1 whereas integrating the second function >>> y2 = f2(x) >>> I2 = integrate.simps(y2,x) >>> print(I2) 61.5 does not correspond to 4 Z x3 dx = 63.75 1 because the order of the polynomial in f2 is larger than two. 1.4.6 Ordinary differential equations (odeint) Integrating a set of ordinary differential equations (ODEs) given initial conditions is another useful example. The function odeint is available in SciPy for integrating a first-order vector differential equation: dy = f (y, t) , dt given initial conditions y (0) = y0 , where y is a length N vector and f is a mapping from RN to RN . A higher-order ordinary differential equation can always be reduced to a differential equation of this type by introducing intermediate derivatives into the y vector. For example suppose it is desired to find the solution to the following second-order differential equation: d2 w − zw(z) = 0 dz 2 1 = −√ . It is known that the solution to this differential 3 3Γ( 13 ) equation with these boundary conditions is the Airy function with initial conditions w (0) = 1 √ 3 2 3 Γ( 23 ) and dw dz z=0 w = Ai (z) , which gives a means to check the integrator using special.airy. 1.4. Integration (scipy.integrate) 15 SciPy Reference Guide, Release 0.13.0 First, convert this ODE into standard form by setting y = dw dz , w and t = z. Thus, the differential equation becomes dy ty1 0 t y0 0 t = = = y. y0 1 0 y1 1 0 dt In other words, f (y, t) = A (t) y. Rt As an interesting reminder, if A (t) commutes with 0 A (τ ) dτ under matrix multiplication, then this linear differential equation has an exact solution using the matrix exponential: Z t A (τ ) dτ y (0) , y (t) = exp 0 However, in this case, A (t) and its integral do not commute. There are many optional inputs and outputs available when using odeint which can help tune the solver. These additional inputs and outputs are not needed much of the time, however, and the three required input arguments and the output solution suffice. The required inputs are the function defining the derivative, fprime, the initial conditions vector, y0, and the time points to obtain a solution, t, (with the initial value point as the first element of this sequence). The output to odeint is a matrix where each row contains the solution vector at each requested time point (thus, the initial conditions are given in the first output row). The following example illustrates the use of odeint including the usage of the Dfun option which allows the user to specify a gradient (with respect to y ) of the function, f (y, t). >>> >>> >>> >>> >>> >>> ... from scipy.integrate import odeint from scipy.special import gamma, airy y1_0 = 1.0/3**(2.0/3.0)/gamma(2.0/3.0) y0_0 = -1.0/3**(1.0/3.0)/gamma(1.0/3.0) y0 = [y0_0, y1_0] def func(y, t): return [t*y[1],y[0]] >>> def gradient(y,t): ... return [[0,t],[1,0]] >>> >>> >>> >>> >>> x = arange(0,4.0, 0.01) t = x ychk = airy(x)[0] y = odeint(func, y0, t) y2 = odeint(func, y0, t, Dfun=gradient) >>> print ychk[:36:6] [ 0.355028 0.339511 0.324068 0.308763 0.293658 0.278806] >>> print y[:36:6,1] [ 0.355028 0.339511 0.324067 0.308763 0.293658 0.278806] >>> print y2[:36:6,1] [ 0.355028 0.339511 0.324067 0.308763 0.293658 0.278806] References 1.5 Optimization (scipy.optimize) The scipy.optimize package provides several commonly used optimization algorithms. A detailed listing is available: scipy.optimize (can also be found by help(scipy.optimize)). 16 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 The module contains: 1. Unconstrained and constrained minimization of multivariate scalar functions (minimize) using a variety of algorithms (e.g. BFGS, Nelder-Mead simplex, Newton Conjugate Gradient, COBYLA or SLSQP) 2. Global (brute-force) optimization routines (e.g., anneal, basinhopping) 3. Least-squares minimization (leastsq) and curve fitting (curve_fit) algorithms 4. Scalar univariate functions minimizers (minimize_scalar) and root finders (newton) 5. Multivariate equation system solvers (root) using a variety of algorithms (e.g. hybrid Powell, LevenbergMarquardt or large-scale methods such as Newton-Krylov). Below, several examples demonstrate their basic usage. 1.5.1 Unconstrained minimization of multivariate scalar functions (minimize) The minimize function provides a common interface to unconstrained and constrained minimization algorithms for multivariate scalar functions in scipy.optimize. To demonstrate the minimization function consider the problem of minimizing the Rosenbrock function of N variables: f (x) = N −1 X 100 xi − x2i−1 2 2 + (1 − xi−1 ) . i=1 The minimum value of this function is 0 which is achieved when xi = 1. Note that the Rosenbrock function and its derivatives are included in scipy.optimize. The implementations shown in the following sections provide examples of how to define an objective function as well as its jacobian and hessian functions. Nelder-Mead Simplex algorithm (method=’Nelder-Mead’) In the example below, the minimize routine is used with the Nelder-Mead simplex algorithm (selected through the method parameter): >>> import numpy as np >>> from scipy.optimize import minimize >>> def rosen(x): ... """The Rosenbrock function""" ... return sum(100.0*(x[1:]-x[:-1]**2.0)**2.0 + (1-x[:-1])**2.0) >>> x0 = np.array([1.3, 0.7, 0.8, 1.9, 1.2]) >>> res = minimize(rosen, x0, method=’nelder-mead’, ... options={’xtol’: 1e-8, ’disp’: True}) Optimization terminated successfully. Current function value: 0.000000 Iterations: 339 Function evaluations: 571 >>> print(res.x) [ 1. 1. 1. 1. 1.] The simplex algorithm is probably the simplest way to minimize a fairly well-behaved function. It requires only function evaluations and is a good choice for simple minimization problems. However, because it does not use any gradient evaluations, it may take longer to find the minimum. 1.5. Optimization (scipy.optimize) 17 SciPy Reference Guide, Release 0.13.0 Another optimization algorithm that needs only function calls to find the minimum is Powell‘s method available by setting method=’powell’ in minimize. Broyden-Fletcher-Goldfarb-Shanno algorithm (method=’BFGS’) In order to converge more quickly to the solution, this routine uses the gradient of the objective function. If the gradient is not given by the user, then it is estimated using first-differences. The Broyden-Fletcher-Goldfarb-Shanno (BFGS) method typically requires fewer function calls than the simplex algorithm even when the gradient must be estimated. To demonstrate this algorithm, the Rosenbrock function is again used. The gradient of the Rosenbrock function is the vector: ∂f ∂xj = N X 200 xi − x2i−1 (δi,j − 2xi−1 δi−1,j ) − 2 (1 − xi−1 ) δi−1,j . i=1 = 200 xj − x2j−1 − 400xj xj+1 − x2j − 2 (1 − xj ) . This expression is valid for the interior derivatives. Special cases are ∂f ∂x0 ∂f ∂xN −1 = −400x0 x1 − x20 − 2 (1 − x0 ) , = 200 xN −1 − x2N −2 . A Python function which computes this gradient is constructed by the code-segment: >>> def rosen_der(x): ... xm = x[1:-1] ... xm_m1 = x[:-2] ... xm_p1 = x[2:] ... der = np.zeros_like(x) ... der[1:-1] = 200*(xm-xm_m1**2) - 400*(xm_p1 - xm**2)*xm - 2*(1-xm) ... der[0] = -400*x[0]*(x[1]-x[0]**2) - 2*(1-x[0]) ... der[-1] = 200*(x[-1]-x[-2]**2) ... return der This gradient information is specified in the minimize function through the jac parameter as illustrated below. >>> res = minimize(rosen, x0, method=’BFGS’, jac=rosen_der, ... options={’disp’: True}) Optimization terminated successfully. Current function value: 0.000000 Iterations: 51 Function evaluations: 63 Gradient evaluations: 63 >>> print(res.x) [ 1. 1. 1. 1. 1.] Newton-Conjugate-Gradient algorithm (method=’Newton-CG’) The method which requires the fewest function calls and is therefore often the fastest method to minimize functions of many variables uses the Newton-Conjugate Gradient algorithm. This method is a modified Newton’s method and uses a conjugate gradient algorithm to (approximately) invert the local Hessian. Newton’s method is based on fitting the function locally to a quadratic form: f (x) ≈ f (x0 ) + ∇f (x0 ) · (x − x0 ) + 18 1 T (x − x0 ) H (x0 ) (x − x0 ) . 2 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 where H (x0 ) is a matrix of second-derivatives (the Hessian). If the Hessian is positive definite then the local minimum of this function can be found by setting the gradient of the quadratic form to zero, resulting in xopt = x0 − H−1 ∇f. The inverse of the Hessian is evaluated using the conjugate-gradient method. An example of employing this method to minimizing the Rosenbrock function is given below. To take full advantage of the Newton-CG method, a function which computes the Hessian must be provided. The Hessian matrix itself does not need to be constructed, only a vector which is the product of the Hessian with an arbitrary vector needs to be available to the minimization routine. As a result, the user can provide either a function to compute the Hessian matrix, or a function to compute the product of the Hessian with an arbitrary vector. Full Hessian example: The Hessian of the Rosenbrock function is Hij = ∂2f ∂xi ∂xj 200 (δi,j − 2xi−1 δi−1,j ) − 400xi (δi+1,j − 2xi δi,j ) − 400δi,j xi+1 − x2i + 2δi,j , = 202 + 1200x2i − 400xi+1 δi,j − 400xi δi+1,j − 400xi−1 δi−1,j , = if i, j ∈ [1, N − 2] with i, j ∈ [0, N − 1] defining the N × N matrix. Other non-zero entries of the matrix are ∂2f ∂x20 2 2 ∂ f ∂ f = ∂x0 ∂x1 ∂x1 ∂x0 ∂2f ∂2f = ∂xN −1 ∂xN −2 ∂xN −2 ∂xN −1 ∂2f ∂x2N −1 For example, the Hessian when N = 5 is 1200x20 − 400x1 + 2 −400x0 2 −400x 202 + 1200x 0 1 − 400x2 0 −400x1 H= 0 0 0 = 1200x20 − 400x1 + 2, = −400x0 , = −400xN −2 , = 200. 0 −400x1 202 + 1200x22 − 400x3 −400x2 0 0 0 −400x2 202 + 1200x23 − 400x4 −400x3 0 0 0 −400x3 200 The code which computes this Hessian along with the code to minimize the function using Newton-CG method is shown in the following example: >>> def rosen_hess(x): ... x = np.asarray(x) ... H = np.diag(-400*x[:-1],1) - np.diag(400*x[:-1],-1) ... diagonal = np.zeros_like(x) ... diagonal[0] = 1200*x[0]**2-400*x[1]+2 ... diagonal[-1] = 200 ... diagonal[1:-1] = 202 + 1200*x[1:-1]**2 - 400*x[2:] ... H = H + np.diag(diagonal) ... return H >>> res = minimize(rosen, x0, method=’Newton-CG’, ... jac=rosen_der, hess=rosen_hess, ... options={’avextol’: 1e-8, ’disp’: True}) Optimization terminated successfully. Current function value: 0.000000 1.5. Optimization (scipy.optimize) 19 . SciPy Reference Guide, Release 0.13.0 Iterations: 19 Function evaluations: 22 Gradient evaluations: 19 Hessian evaluations: 19 >>> print(res.x) [ 1. 1. 1. 1. 1.] Hessian product example: For larger minimization problems, storing the entire Hessian matrix can consume considerable time and memory. The Newton-CG algorithm only needs the product of the Hessian times an arbitrary vector. As a result, the user can supply code to compute this product rather than the full Hessian by giving a hess function which take the minimization vector as the first argument and the arbitrary vector as the second argument (along with extra arguments passed to the function to be minimized). If possible, using Newton-CG with the Hessian product option is probably the fastest way to minimize the function. In this case, the product of the Rosenbrock Hessian with an arbitrary vector is not difficult to arbitrary vector, then H (x) p has elements: 1200x20 − 400x1 + 2 p0 − 400x0 p1 .. . 2 H (x) p = −400x p + 202 + 1200x i−1 i−1 i − 400xi+1 pi − 400xi pi+1 .. . −400xN −2 pN −2 + 200pN −1 compute. If p is the . Code which makes use of this Hessian product to minimize the Rosenbrock function using minimize follows: >>> def rosen_hess_p(x,p): ... x = np.asarray(x) ... Hp = np.zeros_like(x) ... Hp[0] = (1200*x[0]**2 - 400*x[1] + 2)*p[0] - 400*x[0]*p[1] ... Hp[1:-1] = -400*x[:-2]*p[:-2]+(202+1200*x[1:-1]**2-400*x[2:])*p[1:-1] \ ... -400*x[1:-1]*p[2:] ... Hp[-1] = -400*x[-2]*p[-2] + 200*p[-1] ... return Hp >>> res = minimize(rosen, x0, method=’Newton-CG’, ... jac=rosen_der, hess=rosen_hess_p, ... options={’avextol’: 1e-8, ’disp’: True}) Optimization terminated successfully. Current function value: 0.000000 Iterations: 20 Function evaluations: 23 Gradient evaluations: 20 Hessian evaluations: 44 >>> print(res.x) [ 1. 1. 1. 1. 1.] 1.5.2 Constrained minimization of multivariate scalar functions (minimize) The minimize function also provides an interface to several constrained minimization algorithm. As an example, the Sequential Least SQuares Programming optimization algorithm (SLSQP) will be considered here. This algorithm 20 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 allows to deal with constrained minimization problems of the form: min F (x) subject to Cj (X) = 0, j = 1, ..., MEQ Cj (x) ≥ 0, j = MEQ + 1, ..., M XL ≤ x ≤ XU, I = 1, ..., N. As an example, let us consider the problem of maximizing the function: f (x, y) = 2xy + 2x − x2 − 2y 2 subject to an equality and an inequality constraints defined as: x3 − y = 0 y−1≥0 The objective function and its derivative are defined as follows. >>> def func(x, sign=1.0): ... """ Objective function """ ... return sign*(2*x[0]*x[1] + 2*x[0] - x[0]**2 - 2*x[1]**2) >>> def func_deriv(x, sign=1.0): ... """ Derivative of objective function """ ... dfdx0 = sign*(-2*x[0] + 2*x[1] + 2) ... dfdx1 = sign*(2*x[0] - 4*x[1]) ... return np.array([ dfdx0, dfdx1 ]) Note that since minimize only minimizes functions, the sign parameter is introduced to multiply the objective function (and its derivative by -1) in order to perform a maximization. Then constraints are defined as a sequence of dictionaries, with keys type, fun and jac. >>> cons = ({’type’: ’eq’, ... ’fun’ : lambda x: np.array([x[0]**3 - x[1]]), ... ’jac’ : lambda x: np.array([3.0*(x[0]**2.0), -1.0])}, ... {’type’: ’ineq’, ... ’fun’ : lambda x: np.array([x[1] - 1]), ... ’jac’ : lambda x: np.array([0.0, 1.0])}) Now an unconstrained optimization can be performed as: >>> res = minimize(func, [-1.0,1.0], args=(-1.0,), jac=func_deriv, ... method=’SLSQP’, options={’disp’: True}) Optimization terminated successfully. (Exit mode 0) Current function value: -2.0 Iterations: 4 Function evaluations: 5 Gradient evaluations: 4 >>> print(res.x) [ 2. 1.] and a constrained optimization as: >>> res = minimize(func, [-1.0,1.0], args=(-1.0,), jac=func_deriv, ... constraints=cons, method=’SLSQP’, options={’disp’: True}) Optimization terminated successfully. (Exit mode 0) Current function value: -1.00000018311 Iterations: 9 1.5. Optimization (scipy.optimize) 21 SciPy Reference Guide, Release 0.13.0 Function evaluations: 14 Gradient evaluations: 9 >>> print(res.x) [ 1.00000009 1. ] 1.5.3 Least-square fitting (leastsq) All of the previously-explained minimization procedures can be used to solve a least-squares problem provided the appropriate objective function is constructed. For example, suppose it is desired to fit a set of data {xi , yi } to a known model, y = f (x, p) where p is a vector of parameters for the model that need to be found. A common method for determining which parameter vector gives the best fit to the data is to minimize the sum of squares of the residuals. The residual is usually defined for each observed data-point as ei (p, yi , xi ) = kyi − f (xi , p)k . An objective function to pass to any of the previous minization algorithms to obtain a least-squares fit is. J (p) = N −1 X e2i (p) . i=0 The leastsq algorithm performs this squaring and summing of the residuals automatically. It takes as an input argument the vector function e (p) and returns the value of p which minimizes J (p) = eT e directly. The user is also encouraged to provide the Jacobian matrix of the function (with derivatives down the columns or across the rows). If the Jacobian is not provided, it is estimated. An example should clarify the usage. Suppose it is believed some measured data follow a sinusoidal pattern yi = A sin (2πkxi + θ) where the parameters A, k , and θ are unknown. The residual vector is ei = |yi − A sin (2πkxi + θ)| . By defining a function to compute the residuals and (selecting an appropriate starting position), the least-squares fit routine can be used to find the best-fit parameters Â, k̂, θ̂. This is shown in the following example: >>> >>> >>> >>> >>> from numpy import * x = arange(0,6e-2,6e-2/30) A,k,theta = 10, 1.0/3e-2, pi/6 y_true = A*sin(2*pi*k*x+theta) y_meas = y_true + 2*random.randn(len(x)) >>> def residuals(p, y, x): ... A,k,theta = p ... err = y-A*sin(2*pi*k*x+theta) ... return err >>> def peval(x, p): ... return p[0]*sin(2*pi*p[1]*x+p[2]) >>> p0 = [8, 1/2.3e-2, pi/3] >>> print(array(p0)) [ 8. 43.4783 1.0472] >>> from scipy.optimize import leastsq >>> plsq = leastsq(residuals, p0, args=(y_meas, x)) >>> print(plsq[0]) [ 10.9437 33.3605 0.5834] 22 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 >>> print(array([A, k, theta])) [ 10. 33.3333 0.5236] >>> >>> >>> >>> >>> import matplotlib.pyplot as plt plt.plot(x,peval(x,plsq[0]),x,y_meas,’o’,x,y_true) plt.title(’Least-squares fit to noisy data’) plt.legend([’Fit’, ’Noisy’, ’True’]) plt.show() 15 10 5 0 5 10 15 0.00 Least-squares fit to noisy data Fit Noisy True 0.01 0.02 0.03 0.04 0.05 0.06 1.5.4 Univariate function minimizers (minimize_scalar) Often only the minimum of an univariate function (i.e. a function that takes a scalar as input) is needed. In these circumstances, other optimization techniques have been developed that can work faster. These are accessible from the minimize_scalar function which proposes several algorithms. Unconstrained minimization (method=’brent’) There are actually two methods that can be used to minimize an univariate function: brent and golden, but golden is included only for academic purposes and should rarely be used. These can be respectively selected through the method parameter in minimize_scalar. The brent method uses Brent’s algorithm for locating a minimum. Optimally a bracket (the bs parameter) should be given which contains the minimum desired. A bracket is a triple (a, b, c) such that f (a) > f (b) < f (c) and a < b < c . If this is not given, then alternatively two starting points can be chosen and a bracket will be found from these points using a simple marching algorithm. If these two starting points are not provided 0 and 1 will be used (this may not be the right choice for your function and result in an unexpected minimum being returned). Here is an example: >>> >>> >>> >>> 1.0 from scipy.optimize import minimize_scalar f = lambda x: (x - 2) * (x + 1)**2 res = minimize_scalar(f, method=’brent’) print(res.x) 1.5. Optimization (scipy.optimize) 23 SciPy Reference Guide, Release 0.13.0 Bounded minimization (method=’bounded’) Very often, there are constraints that can be placed on the solution space before minimization occurs. The bounded method in minimize_scalar is an example of a constrained minimization procedure that provides a rudimentary interval constraint for scalar functions. The interval constraint allows the minimization to occur only between two fixed endpoints, specified using the mandatory bs parameter. For example, to find the minimum of J1 (x) near x = 5 , minimize_scalar can be called using the interval [4, 7] as a constraint. The result is xmin = 5.3314 : >>> from scipy.special import j1 >>> res = minimize_scalar(j1, bs=(4, 7), method=’bounded’) >>> print(res.x) 5.33144184241 1.5.5 Root finding Scalar functions If one has a single-variable equation, there are four different root finding algorithms that can be tried. Each of these algorithms requires the endpoints of an interval in which a root is expected (because the function changes signs). In general brentq is the best choice, but the other methods may be useful in certain circumstances or for academic purposes. Fixed-point solving A problem closely related to finding the zeros of a function is the problem of finding a fixed-point of a function. A fixed point of a function is the point at which evaluation of the function returns the point: g (x) = x. Clearly the fixed point of g is the root of f (x) = g (x) − x. Equivalently, the root of f is the fixed_point of g (x) = f (x) + x. The routine fixed_point provides a simple iterative method using Aitkens sequence acceleration to estimate the fixed point of g given a starting point. Sets of equations Finding a root of a set of non-linear equations can be achieve using the root function. Several methods are available, amongst which hybr (the default) and lm which respectively use the hybrid method of Powell and the LevenbergMarquardt method from MINPACK. The following example considers the single-variable transcendental equation x + 2 cos (x) = 0, a root of which can be found as follows: >>> import numpy as np >>> from scipy.optimize import root >>> def func(x): ... return x + 2 * np.cos(x) >>> sol = root(func, 0.3) >>> sol.x array([-1.02986653]) >>> sol.fun array([ -6.66133815e-16]) 24 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 Consider now a set of non-linear equations x0 cos (x1 ) = 4, x0 x1 − x1 = 5. We define the objective function so that it also returns the Jacobian and indicate this by setting the jac parameter to True. Also, the Levenberg-Marquardt solver is used here. >>> def func2(x): ... f = [x[0] * np.cos(x[1]) - 4, ... x[1]*x[0] - x[1] - 5] ... df = np.array([[np.cos(x[1]), -x[0] * np.sin(x[1])], ... [x[1], x[0] - 1]]) ... return f, df >>> sol = root(func2, [1, 1], jac=True, method=’lm’) >>> sol.x array([ 6.50409711, 0.90841421]) Root finding for large problems Methods hybr and lm in root cannot deal with a very large number of variables (N), as they need to calculate and invert a dense N x N Jacobian matrix on every Newton step. This becomes rather inefficient when N grows. Consider for instance the following problem: we need to solve the following integrodifferential equation on the square [0, 1] × [0, 1]: (∂x2 + ∂y2 )P Z 1 Z +5 2 1 cosh(P ) dx dy 0 =0 0 with the boundary condition P (x, 1) = 1 on the upper edge and P = 0 elsewhere on the boundary of the square. This can be done by approximating the continuous function P by its values on a grid, Pn,m ≈ P (nh, mh), with a small grid spacing h. The derivatives and integrals can then be approximated; for instance ∂x2 P (x, y) ≈ (P (x + h, y) − 2P (x, y) + P (x − h, y))/h2 . The problem is then equivalent to finding the root of some function residual(P), where P is a vector of length Nx Ny . Now, because Nx Ny can be large, methods hybr or lm in root will take a long time to solve this problem. The solution can however be found using one of the large-scale solvers, for example krylov, broyden2, or anderson. These use what is known as the inexact Newton method, which instead of computing the Jacobian matrix exactly, forms an approximation for it. The problem we have can now be solved as follows: import numpy as np from scipy.optimize import root from numpy import cosh, zeros_like, mgrid, zeros # parameters nx, ny = 75, 75 hx, hy = 1./(nx-1), 1./(ny-1) P_left, P_right = 0, 0 P_top, P_bottom = 1, 0 def residual(P): d2x = zeros_like(P) d2y = zeros_like(P) 1.5. Optimization (scipy.optimize) 25 SciPy Reference Guide, Release 0.13.0 d2x[1:-1] = (P[2:] - 2*P[1:-1] + P[:-2]) / hx/hx d2x[0] = (P[1] - 2*P[0] + P_left)/hx/hx d2x[-1] = (P_right - 2*P[-1] + P[-2])/hx/hx d2y[:,1:-1] = (P[:,2:] - 2*P[:,1:-1] + P[:,:-2])/hy/hy d2y[:,0] = (P[:,1] - 2*P[:,0] + P_bottom)/hy/hy d2y[:,-1] = (P_top - 2*P[:,-1] + P[:,-2])/hy/hy return d2x + d2y + 5*cosh(P).mean()**2 # solve guess = zeros((nx, ny), float) sol = root(residual, guess, method=’krylov’, options={’disp’: True}) #sol = root(residual, guess, method=’broyden2’, options={’disp’: True, ’max_rank’: 50}) #sol = root(residual, guess, method=’anderson’, options={’disp’: True, ’M’: 10}) print(’Residual: %g’ % abs(residual(sol.x)).max()) # visualize import matplotlib.pyplot as plt x, y = mgrid[0:1:(nx*1j), 0:1:(ny*1j)] plt.pcolor(x, y, sol.x) plt.colorbar() plt.show() 1.0 0.90 0.75 0.60 0.45 0.30 0.15 0.8 0.6 0.4 0.2 0.00.0 0.2 0.4 0.6 0.8 1.0 Still too slow? Preconditioning. When looking for the zero of the functions fi (x) = 0, i = 1, 2, ..., N, the krylov solver spends most of its time inverting the Jacobian matrix, Jij = ∂fi . ∂xj If you have an approximation for the inverse matrix M ≈ J −1 , you can use it for preconditioning the linear inversion problem. The idea is that instead of solving Js = y one solves M Js = M y: since matrix M J is “closer” to the identity matrix than J is, the equation should be easier for the Krylov method to deal with. 26 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 The matrix M can be passed to root tion options[’jac_options’][’inner_M’]. It scipy.sparse.linalg.LinearOperator instance. with can method be a krylov (sparse) as an opmatrix or a For the problem in the previous section, we note that the function to solve consists of two parts: the first one is application of the Laplace operator, [∂x2 + ∂y2 ]P , and the second is the integral. We can actually easily compute the Jacobian corresponding to the Laplace operator part: we know that in one dimension −2 1 0 0··· 1 1 −2 1 0 · · · = h−2 ∂x2 ≈ 2 x L 1 −2 1 · · · hx 0 ... so that the whole 2-D operator is represented by −2 J1 = ∂x2 + ∂y2 ' h−2 x L ⊗ I + hy I ⊗ L The matrix J2 of the Jacobian corresponding to the integral is more difficult to calculate, and since all of it entries are nonzero, it will be difficult to invert. J1 on the other hand is a relatively simple matrix, and can be inverted by scipy.sparse.linalg.splu (or the inverse can be approximated by scipy.sparse.linalg.spilu). So we are content to take M ≈ J1−1 and hope for the best. In the example below, we use the preconditioner M = J1−1 . import numpy as np from scipy.optimize import root from scipy.sparse import spdiags, kron from scipy.sparse.linalg import spilu, LinearOperator from numpy import cosh, zeros_like, mgrid, zeros, eye # parameters nx, ny = 75, 75 hx, hy = 1./(nx-1), 1./(ny-1) P_left, P_right = 0, 0 P_top, P_bottom = 1, 0 def get_preconditioner(): """Compute the preconditioner M""" diags_x = zeros((3, nx)) diags_x[0,:] = 1/hx/hx diags_x[1,:] = -2/hx/hx diags_x[2,:] = 1/hx/hx Lx = spdiags(diags_x, [-1,0,1], nx, nx) diags_y = zeros((3, ny)) diags_y[0,:] = 1/hy/hy diags_y[1,:] = -2/hy/hy diags_y[2,:] = 1/hy/hy Ly = spdiags(diags_y, [-1,0,1], ny, ny) J1 = kron(Lx, eye(ny)) + kron(eye(nx), Ly) # Now we have the matrix ‘J_1‘. We need to find its inverse ‘M‘ -# however, since an approximate inverse is enough, we can use # the *incomplete LU* decomposition J1_ilu = spilu(J1) 1.5. Optimization (scipy.optimize) 27 SciPy Reference Guide, Release 0.13.0 # This returns an object with a method .solve() that evaluates # the corresponding matrix-vector product. We need to wrap it into # a LinearOperator before it can be passed to the Krylov methods: M = LinearOperator(shape=(nx*ny, nx*ny), matvec=J1_ilu.solve) return M def solve(preconditioning=True): """Compute the solution""" count = [0] def residual(P): count[0] += 1 d2x = zeros_like(P) d2y = zeros_like(P) d2x[1:-1] = (P[2:] - 2*P[1:-1] + P[:-2])/hx/hx d2x[0] = (P[1] - 2*P[0] + P_left)/hx/hx d2x[-1] = (P_right - 2*P[-1] + P[-2])/hx/hx d2y[:,1:-1] = (P[:,2:] - 2*P[:,1:-1] + P[:,:-2])/hy/hy d2y[:,0] = (P[:,1] - 2*P[:,0] + P_bottom)/hy/hy d2y[:,-1] = (P_top - 2*P[:,-1] + P[:,-2])/hy/hy return d2x + d2y + 5*cosh(P).mean()**2 # preconditioner if preconditioning: M = get_preconditioner() else: M = None # solve guess = zeros((nx, ny), float) sol = root(residual, guess, method=’krylov’, options={’disp’: True, ’jac_options’: {’inner_M’: M}}) print ’Residual’, abs(residual(sol.x)).max() print ’Evaluations’, count[0] return sol.x def main(): sol = solve(preconditioning=True) # visualize import matplotlib.pyplot as plt x, y = mgrid[0:1:(nx*1j), 0:1:(ny*1j)] plt.clf() plt.pcolor(x, y, sol) plt.clim(0, 1) plt.colorbar() plt.show() if __name__ == "__main__": main() 28 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 Resulting run, first without preconditioning: 0: |F(x)| = 803.614; step 1; tol 0.000257947 1: |F(x)| = 345.912; step 1; tol 0.166755 2: |F(x)| = 139.159; step 1; tol 0.145657 3: |F(x)| = 27.3682; step 1; tol 0.0348109 4: |F(x)| = 1.03303; step 1; tol 0.00128227 5: |F(x)| = 0.0406634; step 1; tol 0.00139451 6: |F(x)| = 0.00344341; step 1; tol 0.00645373 7: |F(x)| = 0.000153671; step 1; tol 0.00179246 8: |F(x)| = 6.7424e-06; step 1; tol 0.00173256 Residual 3.57078908664e-07 Evaluations 317 and then with preconditioning: 0: |F(x)| = 136.993; step 1; tol 7.49599e-06 1: |F(x)| = 4.80983; step 1; tol 0.00110945 2: |F(x)| = 0.195942; step 1; tol 0.00149362 3: |F(x)| = 0.000563597; step 1; tol 7.44604e-06 4: |F(x)| = 1.00698e-09; step 1; tol 2.87308e-12 Residual 9.29603061195e-11 Evaluations 77 Using a preconditioner reduced the number of evaluations of the residual function by a factor of 4. For problems where the residual is expensive to compute, good preconditioning can be crucial — it can even decide whether the problem is solvable in practice or not. Preconditioning is an art, science, and industry. Here, we were lucky in making a simple choice that worked reasonably well, but there is a lot more depth to this topic than is shown here. References Some further reading and related software: 1.6 Interpolation (scipy.interpolate) Contents • Interpolation (scipy.interpolate) – 1-D interpolation (interp1d) – Multivariate data interpolation (griddata) – Spline interpolation * Spline interpolation in 1-d: Procedural (interpolate.splXXX) * Spline interpolation in 1-d: Object-oriented (UnivariateSpline) * Two-dimensional spline representation: Procedural (bisplrep) * Two-dimensional spline representation: Object-oriented (BivariateSpline) – Using radial basis functions for smoothing/interpolation * 1-d Example * 2-d Example There are several general interpolation facilities available in SciPy, for data in 1, 2, and higher dimensions: • A class representing an interpolant (interp1d) in 1-D, offering several interpolation methods. 1.6. Interpolation (scipy.interpolate) 29 SciPy Reference Guide, Release 0.13.0 • Convenience function griddata offering a simple interface to interpolation in N dimensions (N = 1, 2, 3, 4, ...). Object-oriented interface for the underlying routines is also available. • Functions for 1- and 2-dimensional (smoothed) cubic-spline interpolation, based on the FORTRAN library FITPACK. There are both procedural and object-oriented interfaces for the FITPACK library. • Interpolation using Radial Basis Functions. 1.6.1 1-D interpolation (interp1d) The interp1d class in scipy.interpolate is a convenient method to create a function based on fixed data points which can be evaluated anywhere within the domain defined by the given data using linear interpolation. An instance of this class is created by passing the 1-d vectors comprising the data. The instance of this class defines a __call__ method and can therefore by treated like a function which interpolates between known data values to obtain unknown values (it also has a docstring for help). Behavior at the boundary can be specified at instantiation time. The following example demonstrates its use, for linear and cubic spline interpolation: >>> from scipy.interpolate import interp1d >>> >>> >>> >>> x = np.linspace(0, 10, 10) y = np.cos(-x**2/8.0) f = interp1d(x, y) f2 = interp1d(x, y, kind=’cubic’) >>> >>> >>> >>> >>> xnew = np.linspace(0, 10, 40) import matplotlib.pyplot as plt plt.plot(x,y,’o’,xnew,f(xnew),’-’, xnew, f2(xnew),’--’) plt.legend([’data’, ’linear’, ’cubic’], loc=’best’) plt.show() 1.0 0.5 0.0 0.5 1.00 data linear cubic 2 4 6 8 10 1.6.2 Multivariate data interpolation (griddata) Suppose you have multidimensional data, for instance for an underlying function f(x, y) you only know the values at points (x[i], y[i]) that do not form a regular grid. Suppose we want to interpolate the 2-D function 30 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 >>> def func(x, y): >>> return x*(1-x)*np.cos(4*np.pi*x) * np.sin(4*np.pi*y**2)**2 on a grid in [0, 1]x[0, 1] >>> grid_x, grid_y = np.mgrid[0:1:100j, 0:1:200j] but we only know its values at 1000 data points: >>> points = np.random.rand(1000, 2) >>> values = func(points[:,0], points[:,1]) This can be done with griddata – below we try out all of the interpolation methods: >>> >>> >>> >>> from scipy.interpolate import griddata grid_z0 = griddata(points, values, (grid_x, grid_y), method=’nearest’) grid_z1 = griddata(points, values, (grid_x, grid_y), method=’linear’) grid_z2 = griddata(points, values, (grid_x, grid_y), method=’cubic’) One can see that the exact result is reproduced by all of the methods to some degree, but for this smooth function the piecewise cubic interpolant gives the best results: >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> import matplotlib.pyplot as plt plt.subplot(221) plt.imshow(func(grid_x, grid_y).T, extent=(0,1,0,1), origin=’lower’) plt.plot(points[:,0], points[:,1], ’k.’, ms=1) plt.title(’Original’) plt.subplot(222) plt.imshow(grid_z0.T, extent=(0,1,0,1), origin=’lower’) plt.title(’Nearest’) plt.subplot(223) plt.imshow(grid_z1.T, extent=(0,1,0,1), origin=’lower’) plt.title(’Linear’) plt.subplot(224) plt.imshow(grid_z2.T, extent=(0,1,0,1), origin=’lower’) plt.title(’Cubic’) plt.gcf().set_size_inches(6, 6) plt.show() 1.6. Interpolation (scipy.interpolate) 31 SciPy Reference Guide, Release 0.13.0 1.0 Original 1.0 Nearest 0.8 0.8 0.6 0.6 0.4 0.4 0.2 0.2 0.00.0 0.2 0.4 0.6 0.8 1.0 Linear 1.0 0.00.0 0.2 0.4 0.6 0.8 1.0 Cubic 1.0 0.8 0.8 0.6 0.6 0.4 0.4 0.2 0.2 0.00.0 0.2 0.4 0.6 0.8 1.0 0.00.0 0.2 0.4 0.6 0.8 1.0 1.6.3 Spline interpolation Spline interpolation in 1-d: Procedural (interpolate.splXXX) Spline interpolation requires two essential steps: (1) a spline representation of the curve is computed, and (2) the spline is evaluated at the desired points. In order to find the spline representation, there are two different ways to represent a curve and obtain (smoothing) spline coefficients: directly and parametrically. The direct method finds the spline representation of a curve in a two- dimensional plane using the function splrep. The first two arguments are the only ones required, and these provide the x and y components of the curve. The normal output is a 3-tuple, (t, c, k) , containing the knot-points, t , the coefficients c and the order k of the spline. The default spline order is cubic, but this can be changed with the input keyword, k. For curves in N -dimensional space the function splprep allows defining the curve parametrically. For this function only 1 input argument is required. This input is a list of N -arrays representing the curve in N -dimensional space. The length of each array is the number of curve points, and each array provides one component of the N -dimensional data point. The parameter variable is given with the keword argument, u, which defaults to an equally-spaced monotonic 32 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 sequence between 0 and 1 . The default output consists of two objects: a 3-tuple, (t, c, k) , containing the spline representation and the parameter variable u. The keyword argument, √s , is used to specify the amount of smoothing to perform during the spline fit. The default value of s is s = m − 2m where m is the number of data-points being fit. Therefore, if no smoothing is desired a value of s = 0 should be passed to the routines. Once the spline representation of the data has been determined, functions are available for evaluating the spline (splev) and its derivatives (splev, spalde) at any point and the integral of the spline between any two points ( splint). In addition, for cubic splines ( k = 3 ) with 8 or more knots, the roots of the spline can be estimated ( sproot). These functions are demonstrated in the example that follows. >>> import numpy as np >>> import matplotlib.pyplot as plt >>> from scipy import interpolate Cubic-spline >>> >>> >>> >>> >>> x = np.arange(0,2*np.pi+np.pi/4,2*np.pi/8) y = np.sin(x) tck = interpolate.splrep(x,y,s=0) xnew = np.arange(0,2*np.pi,np.pi/50) ynew = interpolate.splev(xnew,tck,der=0) >>> >>> >>> >>> >>> >>> plt.figure() plt.plot(x,y,’x’,xnew,ynew,xnew,np.sin(xnew),x,y,’b’) plt.legend([’Linear’,’Cubic Spline’, ’True’]) plt.axis([-0.05,6.33,-1.05,1.05]) plt.title(’Cubic-spline interpolation’) plt.show() Cubic-spline interpolation Linear Cubic Spline True 1.0 0.5 0.0 0.5 1.0 0 1 2 3 4 5 6 Derivative of spline >>> >>> >>> >>> >>> >>> yder = interpolate.splev(xnew,tck,der=1) plt.figure() plt.plot(xnew,yder,xnew,np.cos(xnew),’--’) plt.legend([’Cubic Spline’, ’True’]) plt.axis([-0.05,6.33,-1.05,1.05]) plt.title(’Derivative estimation from spline’) 1.6. Interpolation (scipy.interpolate) 33 SciPy Reference Guide, Release 0.13.0 >>> plt.show() Derivative estimation from spline Cubic Spline True 1.0 0.5 0.0 0.5 1.0 0 1 2 3 4 5 6 Integral of spline >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> 34 def integ(x,tck,constant=-1): x = np.atleast_1d(x) out = np.zeros(x.shape, dtype=x.dtype) for n in xrange(len(out)): out[n] = interpolate.splint(0,x[n],tck) out += constant return out yint = integ(xnew,tck) plt.figure() plt.plot(xnew,yint,xnew,-np.cos(xnew),’--’) plt.legend([’Cubic Spline’, ’True’]) plt.axis([-0.05,6.33,-1.05,1.05]) plt.title(’Integral estimation from spline’) plt.show() Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 Integral estimation from spline Cubic Spline True 1.0 0.5 0.0 0.5 1.0 0 1 2 3 4 5 6 Roots of spline >>> print(interpolate.sproot(tck)) [ 0. 3.1416] Parametric spline >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> t = np.arange(0,1.1,.1) x = np.sin(2*np.pi*t) y = np.cos(2*np.pi*t) tck,u = interpolate.splprep([x,y],s=0) unew = np.arange(0,1.01,0.01) out = interpolate.splev(unew,tck) plt.figure() plt.plot(x,y,’x’,out[0],out[1],np.sin(2*np.pi*unew),np.cos(2*np.pi*unew),x,y,’b’) plt.legend([’Linear’,’Cubic Spline’, ’True’]) plt.axis([-1.05,1.05,-1.05,1.05]) plt.title(’Spline of parametrically-defined curve’) plt.show() 1.6. Interpolation (scipy.interpolate) 35 SciPy Reference Guide, Release 0.13.0 Spline of parametrically-defined curve Linear Cubic Spline True 1.0 0.5 0.0 0.5 1.0 1.0 0.5 0.0 0.5 1.0 Spline interpolation in 1-d: Object-oriented (UnivariateSpline) The spline-fitting capabilities described above are also available via an objected-oriented interface. The one dimensional splines are objects of the UnivariateSpline class, and are created with the x and y components of the curve provided as arguments to the constructor. The class defines __call__, allowing the object to be called with the x-axis values at which the spline should be evaluated, returning the interpolated y-values. This is shown in the example below for the subclass InterpolatedUnivariateSpline. The methods integral, derivatives, and roots methods are also available on UnivariateSpline objects, allowing definite integrals, derivatives, and roots to be computed for the spline. The UnivariateSpline class can also be used to smooth data by providing a non-zero value of the smoothing parameter s, with the same meaning as the s keyword of the splrep function described above. This results in a spline that has fewer knots than the number of data points, and hence is no longer strictly an interpolating spline, but rather a smoothing spline. If this is not desired, the InterpolatedUnivariateSpline class is available. It is a subclass of UnivariateSpline that always passes through all points (equivalent to forcing the smoothing parameter to 0). This class is demonstrated in the example below. The LSQUnivarateSpline is the other subclass of UnivarateSpline. It allows the user to specify the number and location of internal knots as explicitly with the parameter t. This allows creation of customized splines with non-linear spacing, to interpolate in some domains and smooth in others, or change the character of the spline. >>> import numpy as np >>> import matplotlib.pyplot as plt >>> from scipy import interpolate InterpolatedUnivariateSpline >>> >>> >>> >>> >>> x = np.arange(0,2*np.pi+np.pi/4,2*np.pi/8) y = np.sin(x) s = interpolate.InterpolatedUnivariateSpline(x,y) xnew = np.arange(0,2*np.pi,np.pi/50) ynew = s(xnew) >>> >>> >>> >>> plt.figure() plt.plot(x,y,’x’,xnew,ynew,xnew,np.sin(xnew),x,y,’b’) plt.legend([’Linear’,’InterpolatedUnivariateSpline’, ’True’]) plt.axis([-0.05,6.33,-1.05,1.05]) 36 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 >>> plt.title(’InterpolatedUnivariateSpline’) >>> plt.show() InterpolatedUnivariateSpline Linear InterpolatedUnivariateSpline True 1.0 0.5 0.0 0.5 1.0 0 1 2 3 4 5 6 LSQUnivarateSpline with non-uniform knots >>> t = [np.pi/2-.1,np.pi/2+.1,3*np.pi/2-.1,3*np.pi/2+.1] >>> s = interpolate.LSQUnivariateSpline(x,y,t,k=2) >>> ynew = s(xnew) >>> >>> >>> >>> >>> >>> plt.figure() plt.plot(x,y,’x’,xnew,ynew,xnew,np.sin(xnew),x,y,’b’) plt.legend([’Linear’,’LSQUnivariateSpline’, ’True’]) plt.axis([-0.05,6.33,-1.05,1.05]) plt.title(’Spline with Specified Interior Knots’) plt.show() Spline with Specified Interior Knots Linear LSQUnivariateSpline True 1.0 0.5 0.0 0.5 1.0 0 1 2 3 1.6. Interpolation (scipy.interpolate) 4 5 6 37 SciPy Reference Guide, Release 0.13.0 Two-dimensional spline representation: Procedural (bisplrep) For (smooth) spline-fitting to a two dimensional surface, the function bisplrep is available. This function takes as required inputs the 1-D arrays x, y, and z which represent points on the surface z = f (x, y) . The default output is a list [tx, ty, c, kx, ky] whose entries represent respectively, the components of the knot positions, the coefficients of the spline, and the order of the spline in each coordinate. It is convenient to hold this list in a single object, tck, so that it can be passed easily to the function bisplev. The keyword, s , can be used to change the amount of smoothing √ performed on the data while determining the appropriate spline. The default value is s = m − 2m where m is the number of data points in the x, y, and z vectors. As a result, if no smoothing is desired, then s = 0 should be passed to bisplrep . To evaluate the two-dimensional spline and it’s partial derivatives (up to the order of the spline), the function bisplev is required. This function takes as the first two arguments two 1-D arrays whose cross-product specifies the domain over which to evaluate the spline. The third argument is the tck list returned from bisplrep. If desired, the fourth and fifth arguments provide the orders of the partial derivative in the x and y direction respectively. It is important to note that two dimensional interpolation should not be used to find the spline representation of images. The algorithm used is not amenable to large numbers of input points. The signal processing toolbox contains more appropriate algorithms for finding the spline representation of an image. The two dimensional interpolation commands are intended for use when interpolating a two dimensional function as shown in the example that follows. This example uses the mgrid command in SciPy which is useful for defining a “mesh-grid “in many dimensions. (See also the ogrid command if the full-mesh is not needed). The number of output arguments and the number of dimensions of each argument is determined by the number of indexing objects passed in mgrid. >>> import numpy as np >>> from scipy import interpolate >>> import matplotlib.pyplot as plt Define function over sparse 20x20 grid >>> x,y = np.mgrid[-1:1:20j,-1:1:20j] >>> z = (x+y)*np.exp(-6.0*(x*x+y*y)) >>> >>> >>> >>> >>> plt.figure() plt.pcolor(x,y,z) plt.colorbar() plt.title("Sparsely sampled function.") plt.show() 1.0 Sparsely sampled function. 0.20 0.15 0.10 0.05 0.00 0.05 0.10 0.15 0.20 0.5 0.0 0.5 1.01.0 38 0.5 0.0 0.5 1.0 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 Interpolate function over new 70x70 grid >>> xnew,ynew = np.mgrid[-1:1:70j,-1:1:70j] >>> tck = interpolate.bisplrep(x,y,z,s=0) >>> znew = interpolate.bisplev(xnew[:,0],ynew[0,:],tck) >>> >>> >>> >>> >>> plt.figure() plt.pcolor(xnew,ynew,znew) plt.colorbar() plt.title("Interpolated function.") plt.show() 1.0 Interpolated function. 0.20 0.15 0.10 0.05 0.00 0.05 0.10 0.15 0.20 0.5 0.0 0.5 1.01.0 0.5 0.0 0.5 1.0 Two-dimensional spline representation: Object-oriented (BivariateSpline) The BivariateSpline class is the 2-dimensional analog of the UnivariateSpline class. It and its subclasses implement the FITPACK functions described above in an object oriented fashion, allowing objects to be instantiated that can be called to compute the spline value by passing in the two coordinates as the two arguments. 1.6.4 Using radial basis functions for smoothing/interpolation Radial basis functions can be used for smoothing/interpolating scattered data in n-dimensions, but should be used with caution for extrapolation outside of the observed data range. 1-d Example This example compares the usage of the Rbf and UnivariateSpline classes from the scipy.interpolate module. >>> import numpy as np >>> from scipy.interpolate import Rbf, InterpolatedUnivariateSpline >>> import matplotlib.pyplot as plt >>> >>> >>> >>> # setup data x = np.linspace(0, 10, 9) y = np.sin(x) xi = np.linspace(0, 10, 101) 1.6. Interpolation (scipy.interpolate) 39 SciPy Reference Guide, Release 0.13.0 >>> # use fitpack2 method >>> ius = InterpolatedUnivariateSpline(x, y) >>> yi = ius(xi) >>> >>> >>> >>> >>> plt.subplot(2, 1, 1) plt.plot(x, y, ’bo’) plt.plot(xi, yi, ’g’) plt.plot(xi, np.sin(xi), ’r’) plt.title(’Interpolation using univariate spline’) >>> # use RBF method >>> rbf = Rbf(x, y) >>> fi = rbf(xi) >>> >>> >>> >>> >>> >>> plt.subplot(2, 1, 2) plt.plot(x, y, ’bo’) plt.plot(xi, fi, ’g’) plt.plot(xi, np.sin(xi), ’r’) plt.title(’Interpolation using RBF - multiquadrics’) plt.show() 1.0 0.5 0.0 0.5 1.00 1.0 0.5 0.0 0.5 1.00 Interpolation using univariate spline Interpolation using 4 RBF 6- multiquadrics 2 8 2 4 6 8 10 10 2-d Example This example shows how to interpolate scattered 2d data. >>> >>> >>> >>> import numpy as np from scipy.interpolate import Rbf import matplotlib.pyplot as plt from matplotlib import cm >>> >>> >>> >>> >>> >>> # 2-d tests - setup scattered data x = np.random.rand(100)*4.0-2.0 y = np.random.rand(100)*4.0-2.0 z = x*np.exp(-x**2-y**2) ti = np.linspace(-2.0, 2.0, 100) XI, YI = np.meshgrid(ti, ti) 40 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 >>> # use RBF >>> rbf = Rbf(x, y, z, epsilon=2) >>> ZI = rbf(XI, YI) >>> >>> >>> >>> >>> >>> >>> >>> >>> # plot the result n = plt.normalize(-2., 2.) plt.subplot(1, 1, 1) plt.pcolor(XI, YI, ZI, cmap=cm.jet) plt.scatter(x, y, 100, z, cmap=cm.jet) plt.title(’RBF interpolation - multiquadrics’) plt.xlim(-2, 2) plt.ylim(-2, 2) plt.colorbar() RBF interpolation - multiquadrics 2.0 1.5 1.0 0.5 0.0 0.5 1.0 1.5 2.02.0 1.5 1.0 0.5 0.0 0.5 1.0 1.5 2.0 0.4 0.3 0.2 0.1 0.0 0.1 0.2 0.3 0.4 1.7 Fourier Transforms (scipy.fftpack) Warning: This is currently a stub page 1.7. Fourier Transforms (scipy.fftpack) 41 SciPy Reference Guide, Release 0.13.0 Contents • Fourier Transforms (scipy.fftpack) – Fast Fourier transforms – One dimensional discrete Fourier transforms – Two and n dimensional discrete Fourier transforms – Discrete Cosine Transforms * type I * type II * type III – Discrete Sine Transforms * type I * type II * type III * References – FFT convolution – Cache Destruction Fourier analysis is fundamentally a method for expressing a function as a sum of periodic components, and for recovering the signal from those components. When both the function and its Fourier transform are replaced with discretized counterparts, it is called the discrete Fourier transform (DFT). The DFT has become a mainstay of numerical computing in part because of a very fast algorithm for computing it, called the Fast Fourier Transform (FFT), which was known to Gauss (1805) and was brought to light in its current form by Cooley and Tukey [CT]. Press et al. [NR] provide an accessible introduction to Fourier analysis and its applications. 1.7.1 Fast Fourier transforms 1.7.2 One dimensional discrete Fourier transforms fft, ifft, rfft, irfft 1.7.3 Two and n dimensional discrete Fourier transforms fft in more than one dimension 1.7.4 Discrete Cosine Transforms Return the Discrete Cosine Transform [Mak] of arbitrary type sequence x. For a single dimension array x, dct(x, norm=’ortho’) is equal to MATLAB dct(x). There are theoretically 8 types of the DCT [WPC], only the first 3 types are implemented in scipy. ‘The’ DCT generally refers to DCT type 2, and ‘the’ Inverse DCT generally refers to DCT type 3. type I There are several definitions of the DCT-I; we use the following (for norm=None): k yk = x0 + (−1) xN −1 + 2 N −2 X n=1 42 xn cos πnk N −1 , 0 ≤ k < N. Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 Only None is supported as normalization mode for DCT-I. Note also that the DCT-I is only supported for input size > 1 type II There are several definitions of the DCT-II; we use the following (for norm=None): yk = 2 N −1 X xn cos n=0 π(2n + 1)k 2N 0 ≤ k < N. If norm=’ortho’, yk is multiplied by a scaling factor f : (p 1/(4N ), if k = 0 f= p 1/(2N ), otherwise Which makes the corresponding matrix of coefficients orthonormal (OO’ = Id). type III There are several definitions of the DCT-III, we use the following (for norm=None): yk = x0 + 2 N −1 X xn cos n=1 πn(2k + 1) 2N 0 ≤ k < N, or, for norm=’ortho’: N −1 1 X x0 πn(2k + 1) yk = √ + √ xn cos 2N N N n=1 0 ≤ k < N. The (unnormalized) DCT-III is the inverse of the (unnormalized) DCT-II, up to a factor 2N. The orthonormalized DCT-III is exactly the inverse of the orthonormalized DCT-II. 1.7.5 Discrete Sine Transforms Return the Discrete Sine Transform [Mak] of arbitrary type sequence x. There are theoretically 8 types of the DST for different combinations of even/odd boundary conditions and boundary off sets [WPS], only the first 3 types are implemented in scipy. type I There are several definitions of the DST-I; we use the following for norm=None. DST-I assumes the input is odd around n=-1 and n=N. N −1 X π(n + 1)(k + 1) , 0 ≤ k < N. yk = 2 xn sin N +1 n=0 Only None is supported as normalization mode for DST-I. Note also that the DCT-I is only supported for input size > 1. The (unnormalized) DCT-I is its own inverse, up to a factor 2(N+1). 1.7. Fourier Transforms (scipy.fftpack) 43 SciPy Reference Guide, Release 0.13.0 type II There are several definitions of the DST-II; we use the following (for norm=None). DST-II assumes the input is odd around n=-1/2 and even around n=N yk = 2 N −1 X xn sin n=0 π(n + 1/2)(k + 1) N , 0 ≤ k < N. type III There are several definitions of the DST-III, we use the following (for norm=None). DST-III assumes the input is odd around n=-1 and even around n=N-1 yk = (−1)k xN −1 + 2 N −2 X n=0 xn sin π(n + 1)(k + 1/2) N , 0 ≤ k < N. The (unnormalized) DCT-III is the inverse of the (unnormalized) DCT-II, up to a factor 2N. References 1.7.6 FFT convolution scipy.fftpack.convolve performs a convolution of two one-dimensional arrays in frequency domain. 1.7.7 Cache Destruction To accelerate repeat transforms on arrays of the same shape and dtype, scipy.fftpack keeps a cache of the prime factorization of length of the array and pre-computed trigonometric functions. These caches can be destroyed by calling the appropriate function in scipy.fftpack._fftpack. dst(type=1) and idst(type=1) share a cache (*dst1_cache). As do dst(type=2), dst(type=3), idst(type=3), and idst(type=3) (*dst2_cache). 1.8 Signal Processing (scipy.signal) The signal processing toolbox currently contains some filtering functions, a limited set of filter design tools, and a few B-spline interpolation algorithms for one- and two-dimensional data. While the B-spline algorithms could technically be placed under the interpolation category, they are included here because they only work with equally-spaced data and make heavy use of filter-theory and transfer-function formalism to provide a fast B-spline transform. To understand this section you will need to understand that a signal in SciPy is an array of real or complex numbers. 1.8.1 B-splines A B-spline is an approximation of a continuous function over a finite- domain in terms of B-spline coefficients and knot points. If the knot- points are equally spaced with spacing ∆x , then the B-spline approximation to a 1-dimensional function is the finite-basis expansion. x X −j . y (x) ≈ cj β o ∆x j 44 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 In two dimensions with knot-spacing ∆x and ∆y , the function representation is x y XX z (x, y) ≈ cjk β o − j βo −k . ∆x ∆y j k o In these expressions, β (·) is the space-limited B-spline basis function of order, o . The requirement of equallyspaced knot-points and equally-spaced data points, allows the development of fast (inverse-filtering) algorithms for determining the coefficients, cj , from sample-values, yn . Unlike the general spline interpolation algorithms, these algorithms can quickly find the spline coefficients for large images. The advantage of representing a set of samples via B-spline basis functions is that continuous-domain operators (derivatives, re- sampling, integral, etc.) which assume that the data samples are drawn from an underlying continuous function can be computed with relative ease from the spline coefficients. For example, the second-derivative of a spline is x 1 X o00 c β − j . y 00 (x) = j ∆x2 j ∆x Using the property of B-splines that d2 β o (w) = β o−2 (w + 1) − 2β o−2 (w) + β o−2 (w − 1) dw2 it can be seen that y 00 (x) = i x x 1 X h o−2 x o−2 o−2 c − j + 1 − 2β − j + β − j − 1 . β j ∆x2 j ∆x ∆x ∆x If o = 3 , then at the sample points, ∆x2 y 0 (x)|x=n∆x = X cj δn−j+1 − 2cj δn−j + cj δn−j−1 , j = cn+1 − 2cn + cn−1 . Thus, the second-derivative signal can be easily calculated from the spline fit. if desired, smoothing splines can be found to make the second-derivative less sensitive to random-errors. The savvy reader will have already noticed that the data samples are related to the knot coefficients via a convolution operator, so that simple convolution with the sampled B-spline function recovers the original data from the spline coefficients. The output of convolutions can change depending on how boundaries are handled (this becomes increasingly more important as the number of dimensions in the data- set increases). The algorithms relating to B-splines in the signal- processing sub package assume mirror-symmetric boundary conditions. Thus, spline coefficients are computed based on that assumption, and data-samples can be recovered exactly from the spline coefficients by assuming them to be mirror-symmetric also. Currently the package provides functions for determining second- and third-order cubic spline coefficients from equally spaced samples in one- and two-dimensions (signal.qspline1d, signal.qspline2d, signal.cspline1d, signal.cspline2d). The package also supplies a function ( signal.bspline ) for evaluating the bspline basis function, β o (x) for arbitrary order and x. For large o , the B-spline basis function can be approximated well by a zero-mean Gaussian function with standard-deviation equal to σo = (o + 1) /12 : 1 x2 β o (x) ≈ p exp − . 2σo 2πσo2 A function to compute this Gaussian for arbitrary x and o is also available ( signal.gauss_spline ). The following code and Figure uses spline-filtering to compute an edge-image (the second-derivative of a smoothed spline) of Lena’s face which is an array returned by the command lena. The command signal.sepfir2d was used to apply a separable two-dimensional FIR filter with mirror- symmetric boundary conditions to the spline coefficients. This function is ideally suited for reconstructing samples from spline coefficients and is faster than signal.convolve2d which convolves arbitrary two-dimensional filters and allows for choosing mirror-symmetric boundary conditions. 1.8. Signal Processing (scipy.signal) 45 SciPy Reference Guide, Release 0.13.0 >>> from numpy import * >>> from scipy import signal, misc >>> import matplotlib.pyplot as plt >>> >>> >>> >>> >>> image = misc.lena().astype(float32) derfilt = array([1.0,-2,1.0],float32) ck = signal.cspline2d(image,8.0) deriv = signal.sepfir2d(ck, derfilt, [1]) + \ signal.sepfir2d(ck, [1], derfilt) Alternatively we could have done: laplacian = array([[0,1,0],[1,-4,1],[0,1,0]],float32) deriv2 = signal.convolve2d(ck,laplacian,mode=’same’,boundary=’symm’) >>> >>> >>> >>> >>> plt.figure() plt.imshow(image) plt.gray() plt.title(’Original image’) plt.show() Original image 0 100 200 300 400 500 >>> >>> >>> >>> >>> 46 0 100 200 300 400 500 plt.figure() plt.imshow(deriv) plt.gray() plt.title(’Output of spline edge filter’) plt.show() Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 Output of spline edge filter 0 100 200 300 400 500 0 100 200 300 400 500 1.8.2 Filtering Filtering is a generic name for any system that modifies an input signal in some way. In SciPy a signal can be thought of as a Numpy array. There are different kinds of filters for different kinds of operations. There are two broad kinds of filtering operations: linear and non-linear. Linear filters can always be reduced to multiplication of the flattened Numpy array by an appropriate matrix resulting in another flattened Numpy array. Of course, this is not usually the best way to compute the filter as the matrices and vectors involved may be huge. For example filtering a 512 × 512 image with this method would require multiplication of a 5122 ×5122 matrix with a 5122 vector. Just trying to store the 5122 × 5122 matrix using a standard Numpy array would require 68, 719, 476, 736 elements. At 4 bytes per element this would require 256GB of memory. In most applications most of the elements of this matrix are zero and a different method for computing the output of the filter is employed. Convolution/Correlation Many linear filters also have the property of shift-invariance. This means that the filtering operation is the same at different locations in the signal and it implies that the filtering matrix can be constructed from knowledge of one row (or column) of the matrix alone. In this case, the matrix multiplication can be accomplished using Fourier transforms. Let x [n] define a one-dimensional signal indexed by the integer n. Full convolution of two one-dimensional signals can be expressed as ∞ X y [n] = x [k] h [n − k] . k=−∞ This equation can only be implemented directly if we limit the sequences to finite support sequences that can be stored in a computer, choose n = 0 to be the starting point of both sequences, let K + 1 be that value for which y [n] = 0 for all n > K + 1 and M + 1 be that value for which x [n] = 0 for all n > M + 1 , then the discrete convolution expression is min(n,K) X y [n] = x [k] h [n − k] . k=max(n−M,0) 1.8. Signal Processing (scipy.signal) 47 SciPy Reference Guide, Release 0.13.0 For convenience assume K ≥ M. Then, more explicitly the output of this operation is y [0] = x [0] h [0] y [1] = x [0] h [1] + x [1] h [0] y [2] .. . = .. . x [0] h [2] + x [1] h [1] + x [2] h [0] .. . y [M ] = x [0] h [M ] + x [1] h [M − 1] + · · · + x [M ] h [0] y [M + 1] = .. .. . . y [K] = x [1] h [M ] + x [2] h [M − 1] + · · · + x [M + 1] h [0] .. . y [K + 1] = .. .. . . x [K + 1 − M ] h [M ] + · · · + x [K] h [1] .. . y [K + M − 1] y [K + M ] x [K − M ] h [M ] + · · · + x [K] h [0] = x [K − 1] h [M ] + x [K] h [M − 1] = x [K] h [M ] . Thus, the full discrete convolution of two finite sequences of lengths K + 1 and M + 1 respectively results in a finite sequence of length K + M + 1 = (K + 1) + (M + 1) − 1. One dimensional convolution is implemented in SciPy with the function signal.convolve . This function takes as inputs the signals x, h , and an optional flag and returns the signal y. The optional flag allows for specification of which part of the output signal to return. The default value of ‘full’ returns the entire signal. If the flag has a value of ‘same’ then only the middle K values are returned starting at y M2−1 so that the output has the same length as the largest input. If the flag has a value of ‘valid’ then only the middle K − M + 1 = (K + 1) − (M + 1) + 1 output values are returned where z depends on all of the values of the smallest input from h [0] to h [M ] . In other words only the values y [M ] to y [K] inclusive are returned. This same function signal.convolve can actually take N -dimensional arrays as inputs and will return the N -dimensional convolution of the two arrays. The same input flags are available for that case as well. Correlation is very similar to convolution except for the minus sign becomes a plus sign. Thus w [n] = ∞ X y [k] x [n + k] k=−∞ is the (cross) correlation of the signals y and x. For finite-length signals with y [n] = 0 outside of the range [0, K] and x [n] = 0 outside of the range [0, M ] , the summation can simplify to min(K,M −n) w [n] = X y [k] x [n + k] . k=max(0,−n) 48 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 Assuming again that K ≥ M this is w [−K] = y [K] x [0] w [−K + 1] = .. .. . . y [K − 1] x [0] + y [K] x [1] .. . w [M − K] y [K − M ] x [0] + y [K − M + 1] x [1] + · · · + y [K] x [M ] = w [M − K + 1] = .. .. . . w [−1] = w [0] y [K − M − 1] x [0] + · · · + y [K − 1] x [M ] .. . y [1] x [0] + y [2] x [1] + · · · + y [M + 1] x [M ] = y [0] x [0] + y [1] x [1] + · · · + y [M ] x [M ] w [1] = y [0] x [1] + y [1] x [2] + · · · + y [M − 1] x [M ] w [2] .. . = .. . w [M − 1] w [M ] y [0] x [2] + y [1] x [3] + · · · + y [M − 2] x [M ] .. . = y [0] x [M − 1] + y [1] x [M ] = y [0] x [M ] . The SciPy function signal.correlate implements this operation. Equivalent flags are available for this operation to return the full K +M +1 length sequence (‘full’) or a sequence with the same size as the largest sequence starting at w −K + M2−1 (‘same’) or a sequence where the values depend on all the values of the smallest sequence (‘valid’). This final option returns the K − M + 1 values w [M − K] to w [0] inclusive. The function signal.correlate can also take arbitrary N -dimensional arrays as input and return the N dimensional convolution of the two arrays on output. When N = 2, signal.correlate and/or signal.convolve can be used to construct arbitrary image filters to perform actions such as blurring, enhancing, and edge-detection for an image. Convolution is mainly used for filtering when one of the signals is much smaller than the other ( K M ), otherwise linear filtering is more easily accomplished in the frequency domain (see Fourier Transforms). Difference-equation filtering A general class of linear one-dimensional filters (that includes convolution filters) are filters described by the difference equation N M X X ak y [n − k] = bk x [n − k] k=0 k=0 where x [n] is the input sequence and y [n] is the output sequence. If we assume initial rest so that y [n] = 0 for n < 0 , then this kind of filter can be implemented using convolution. However, the convolution filter sequence h [n] could be infinite if ak 6= 0 for k ≥ 1. In addition, this general class of linear filter allows initial conditions to be placed on y [n] for n < 0 resulting in a filter that cannot be expressed using convolution. The difference equation filter can be thought of as finding y [n] recursively in terms of it’s previous values a0 y [n] = −a1 y [n − 1] − · · · − aN y [n − N ] + · · · + b0 x [n] + · · · + bM x [n − M ] . Often a0 = 1 is chosen for normalization. The implementation in SciPy of this general difference equation filter is a little more complicated then would be implied by the previous equation. It is implemented so that only one signal 1.8. Signal Processing (scipy.signal) 49 SciPy Reference Guide, Release 0.13.0 needs to be delayed. The actual implementation equations are (assuming a0 = 1 ). y [n] = b0 x [n] + z0 [n − 1] z0 [n] = b1 x [n] + z1 [n − 1] − a1 y [n] z1 [n] = .. .. . . b2 x [n] + z2 [n − 1] − a2 y [n] .. . zK−2 [n] = bK−1 x [n] + zK−1 [n − 1] − aK−1 y [n] zK−1 [n] = bK x [n] − aK y [n] , where K = max (N, M ) . Note that bK = 0 if K > M and aK = 0 if K > N. In this way, the output at time n depends only on the input at time n and the value of z0 at the previous time. This can always be calculated as long as the K values z0 [n − 1] . . . zK−1 [n − 1] are computed and stored at each time step. The difference-equation filter is called using the command signal.lfilter in SciPy. This command takes as inputs the vector b, the vector, a, a signal x and returns the vector y (the same length as x ) computed using the equation given above. If x is N -dimensional, then the filter is computed along the axis provided. If, desired, initial conditions providing the values of z0 [−1] to zK−1 [−1] can be provided or else it will be assumed that they are all zero. If initial conditions are provided, then the final conditions on the intermediate variables are also returned. These could be used, for example, to restart the calculation in the same state. Sometimes it is more convenient to express the initial conditions in terms of the signals x [n] and y [n] . In other words, perhaps you have the values of x [−M ] to x [−1] and the values of y [−N ] to y [−1] and would like to determine what values of zm [−1] should be delivered as initial conditions to the difference-equation filter. It is not difficult to show that for 0 ≤ m < K, K−m−1 X (bm+p+1 x [n − p] − am+p+1 y [n − p]) . zm [n] = p=0 Using this formula we can find the intial condition vector z0 [−1] to zK−1 [−1] given initial conditions on y (and x ). The command signal.lfiltic performs this function. Other filters The signal processing package provides many more filters as well. Median Filter A median filter is commonly applied when noise is markedly non-Gaussian or when it is desired to preserve edges. The median filter works by sorting all of the array pixel values in a rectangular region surrounding the point of interest. The sample median of this list of neighborhood pixel values is used as the value for the output array. The sample median is the middle array value in a sorted list of neighborhood values. If there are an even number of elements in the neighborhood, then the average of the middle two values is used as the median. A general purpose median filter that works on N-dimensional arrays is signal.medfilt . A specialized version that works only for two-dimensional arrays is available as signal.medfilt2d . Order Filter A median filter is a specific example of a more general class of filters called order filters. To compute the output at a particular pixel, all order filters use the array values in a region surrounding that pixel. These array values are sorted and then one of them is selected as the output value. For the median filter, the sample median of the list of array values is used as the output. A general order filter allows the user to select which of the sorted values will be used as the output. So, for example one could choose to pick the maximum in the list or the minimum. The order filter takes an additional argument besides the input array and the region mask that specifies which of the elements in the sorted list of neighbor array values should be used as the output. The command to perform an order filter is signal.order_filter . 50 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 Wiener filter The Wiener filter is a simple deblurring filter for denoising images. This is not the Wiener filter commonly described in image reconstruction problems but instead it is a simple, local-mean filter. Let x be the input signal, then the output is ( 2 2 σ 1 − σσ2 x σx2 ≥ σ 2 , 2 mx + σ x x y= mx σx2 < σ 2 , where mx is the local estimate of the mean and σx2 is the local estimate of the variance. The window for these estimates is an optional input parameter (default is 3 × 3 ). The parameter σ 2 is a threshold noise parameter. If σ is not given then it is estimated as the average of the local variances. Hilbert filter The Hilbert transform constructs the complex-valued analytic signal from a real signal. For example if x = cos ωn then y = hilbert (x) would return (except near the edges) y = exp (jωn) . In the frequency domain, the hilbert transform performs Y =X ·H where H is 2 for positive frequencies, 0 for negative frequencies and 1 for zero-frequencies. 1.8.3 Least-Squares Spectral Analysis Least-squares spectral analysis (LSSA) is a method of estimating a frequency spectrum, based on a least squares fit of sinusoids to data samples, similar to Fourier analysis. Fourier analysis, the most used spectral method in science, generally boosts long-periodic noise in long gapped records; LSSA mitigates such problems. Lomb-Scargle Periodograms (lombscargle) The Lomb-Scargle method performs spectral analysis on unevenly sampled data and is known to be a powerful way to find, and test the significance of, weak periodic signals. For a time series comprising Nt measurements Xj ≡ X(tj ) sampled at times tj where (j = 1, . . . , Nt ), assumed to have been scaled and shifted such that its mean is zero and its variance is unity, the normalized Lomb-Scargle periodogram at frequency f is h i2 hP i2 PNt Nt X cos ω(t − τ ) X sin ω(t − τ ) j j j j j j 1 . + Pn (f ) PNt P Nt 2 2 2 j cos ω(tj − τ ) j sin ω(tj − τ ) Here, ω ≡ 2πf is the angular frequency. The frequency dependent time offset τ is given by PNt j sin 2ωtj j cos 2ωtj tan 2ωτ = PNt . The lombscargle function calculates the periodogram using a slightly modified algorithm due to Townsend 1 which allows the periodogram to be calculated using only a single pass through the input arrays for each frequency. The equation is refactored as: Pn (f ) = (cτ XC + sτ XS)2 1 (cτ XS − sτ XC)2 + 2 c2τ CC + 2cτ sτ CS + s2τ SS c2τ SS − 2cτ sτ CS + s2τ CC 1 R.H.D. Townsend, “Fast calculation of the Lomb-Scargle periodogram using graphics processing units.”, The Astrophysical Journal Supplement Series, vol 191, pp. 247-253, 2010 1.8. Signal Processing (scipy.signal) 51 SciPy Reference Guide, Release 0.13.0 and tan 2ωτ = 2CS . CC − SS Here, cτ = cos ωτ, sτ = sin ωτ while the sums are XC = Nt X Xj cos ωtj j XS = Nt X Xj sin ωtj j CC = Nt X cos2 ωtj j SS = Nt X sin2 ωtj j CS = Nt X cos ωtj sin ωtj . j This requires Nf (2Nt + 3) trigonometric function evaluations giving a factor of ∼ 2 speed increase over the straightforward implementation. References Some further reading and related software: 1.9 Linear Algebra (scipy.linalg) When SciPy is built using the optimized ATLAS LAPACK and BLAS libraries, it has very fast linear algebra capabilities. If you dig deep enough, all of the raw lapack and blas libraries are available for your use for even more speed. In this section, some easier-to-use interfaces to these routines are described. All of these linear algebra routines expect an object that can be converted into a 2-dimensional array. The output of these routines is also a two-dimensional array. scipy.linalg contains all the functions in numpy.linalg. plus some other more advanced ones not contained in numpy.linalg Another advantage of using scipy.linalg over numpy.linalg is that it is always compiled with BLAS/LAPACK support, while for numpy this is optional. Therefore, the scipy version might be faster depending on how numpy was installed. Therefore, unless you don’t want to add scipy as a dependency to your numpy program, use scipy.linalg instead of numpy.linalg 1.9.1 numpy.matrix vs 2D numpy.ndarray The classes that represent matrices, and basic operations such as matrix multiplications and transpose are a part of numpy. For convenience, we summarize the differences between numpy.matrix and numpy.ndarray here. 52 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 numpy.matrix is matrix class that has a more convenient interface than numpy.ndarray for matrix operations. This class supports for example MATLAB-like creation syntax via the, has matrix multiplication as default for the * operator, and contains I and T members that serve as shortcuts for inverse and transpose: >>> import numpy as np >>> A = np.mat(’[1 2;3 4]’) >>> A matrix([[1, 2], [3, 4]]) >>> A.I matrix([[-2. , 1. ], [ 1.5, -0.5]]) >>> b = np.mat(’[5 6]’) >>> b matrix([[5, 6]]) >>> b.T matrix([[5], [6]]) >>> A*b.T matrix([[17], [39]]) Despite its convenience, the use of the numpy.matrix class is discouraged, since it adds nothing that cannot be accomplished with 2D numpy.ndarray objects, and may lead to a confusion of which class is being used. For example, the above code can be rewritten as: >>> import numpy as np >>> from scipy import linalg >>> A = np.array([[1,2],[3,4]]) >>> A array([[1, 2], [3, 4]]) >>> linalg.inv(A) array([[-2. , 1. ], [ 1.5, -0.5]]) >>> b = np.array([[5,6]]) #2D array >>> b array([[5, 6]]) >>> b.T array([[5], [6]]) >>> A*b #not matrix multiplication! array([[ 5, 12], [15, 24]]) >>> A.dot(b.T) #matrix multiplication array([[17], [39]]) >>> b = np.array([5,6]) #1D array >>> b array([5, 6]) >>> b.T #not matrix transpose! array([5, 6]) >>> A.dot(b) #does not matter for multiplication array([17, 39]) scipy.linalg operations can be applied equally to numpy.matrix or to 2D numpy.ndarray objects. 1.9. Linear Algebra (scipy.linalg) 53 SciPy Reference Guide, Release 0.13.0 1.9.2 Basic routines Finding Inverse The inverse of a matrix A is the matrix B such that AB = I where I is the identity matrix consisting of ones down the main diagonal. Usually B is denoted B = A−1 . In SciPy, the matrix inverse of the Numpy array, A, is obtained using linalg.inv (A) , or using A.I if A is a Matrix. For example, let 1 3 5 A = 2 5 1 2 3 8 then A−1 −37 9 1 14 2 = 25 4 −3 22 −1.48 0.36 0.88 −9 = 0.56 0.08 −0.36 . 1 0.16 −0.12 0.04 The following example demonstrates this computation in SciPy >>> import numpy as np >>> from scipy import linalg >>> A = np.array([[1,2],[3,4]]) array([[1, 2], [3, 4]]) >>> linalg.inv(A) array([[-2. , 1. ], [ 1.5, -0.5]]) >>> A.dot(linalg.inv(A)) #double check array([[ 1.00000000e+00, 0.00000000e+00], [ 4.44089210e-16, 1.00000000e+00]]) Solving linear system Solving linear systems of equations is straightforward using the scipy command linalg.solve. This command expects an input matrix and a right-hand-side vector. The solution vector is then computed. An option for entering a symmetrix matrix is offered which can speed up the processing when applicable. As an example, suppose it is desired to solve the following simultaneous equations: x + 3y + 5z = 10 2x + 5y + z = 8 2x + 3y + 8z = 3 We could find the solution vector using a matrix inverse: x 1 y = 2 z 2 3 5 3 −1 −232 −9.28 5 10 1 129 = 5.16 . 1 8 = 25 8 3 19 0.76 However, it is better to use the linalg.solve command which can be faster and more numerically stable. In this case it however gives the same answer as shown in the following example: >>> import numpy as np >>> from scipy import linalg >>> A = np.array([[1,2],[3,4]]) >>> A array([[1, 2], 54 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 [3, 4]]) >>> b = np.array([[5],[6]]) >>> b array([[5], [6]]) >>> linalg.inv(A).dot(b) #slow array([[-4. ], [ 4.5]] >>> A.dot(linalg.inv(A).dot(b))-b #check array([[ 8.88178420e-16], [ 2.66453526e-15]]) >>> np.linalg.solve(A,b) #fast array([[-4. ], [ 4.5]]) >>> A.dot(np.linalg.solve(A,b))-b #check array([[ 0.], [ 0.]]) Finding Determinant The determinant of a square matrix A is often denoted |A| and is a quantity often used in linear algebra. Suppose aij are the elements of the matrix A and let Mij = |Aij | be the determinant of the matrix left by removing the ith row and j th column from A . Then for any row i, X i+j |A| = (−1) aij Mij . j This is a recursive way to define the determinant where the base case is defined by accepting that the determinant of a 1 × 1 matrix is the only matrix element. In SciPy the determinant can be calculated with linalg.det . For example, the determinant of 1 3 5 A = 2 5 1 2 3 8 is |A| 5 3 1 8 −3 2 2 1 8 +5 2 2 5 3 = 1 = 1 (5 · 8 − 3 · 1) − 3 (2 · 8 − 2 · 1) + 5 (2 · 3 − 2 · 5) = −25. In SciPy this is computed as shown in this example: >>> import numpy as np >>> from scipy import linalg >>> A = np.array([[1,2],[3,4]]) >>> A array([[1, 2], [3, 4]]) >>> linalg.det(A) -2.0 Computing norms Matrix and vector norms can also be computed with SciPy. A wide range of norm definitions are available using different parameters to the order argument of linalg.norm . This function takes a rank-1 (vectors) or a rank-2 1.9. Linear Algebra (scipy.linalg) 55 SciPy Reference Guide, Release 0.13.0 (matrices) array and an optional order argument (default is 2). Based on these inputs a vector or matrix norm of the requested order is computed. For vector x , the order parameter can be any real number including inf or -inf. The computed norm is max |xi | ord = inf min |x | ord = −inf i kxk = 1/ord P |x |ord |ord| < ∞. i i For matrix A the only valid values for norm are ±2, ±1, ± inf, and ‘fro’ (or ‘f’) Thus, P maxi j |aij | ord = inf P min |a | ord = −inf i ij Pj ord = 1 maxj P i |aij | kAk = minj i |aij | ord = −1 max σ ord = 2 i min σ ord = −2 i p trace (AH A) ord = ’fro’ where σi are the singular values of A . Examples: >>> import numpy as np >>> from scipy import linalg >>> A=np.array([[1,2],[3,4]]) >>> A array([[1, 2], [3, 4]]) >>> linalg.norm(A) 5.4772255750516612 >>> linalg.norm(A,’fro’) # frobenius norm is the default 5.4772255750516612 >>> linalg.norm(A,1) # L1 norm (max column sum) 6 >>> linalg.norm(A,-1) 4 >>> linalg.norm(A,inf) # L inf norm (max row sum) 7 Solving linear least-squares problems and pseudo-inverses Linear least-squares problems occur in many branches of applied mathematics. In this problem a set of linear scaling coefficients is sought that allow a model to fit data. In particular it is assumed that data yi is related to data xi through a set of coefficients cj and model functions fj (xi ) via the model X yi = cj fj (xi ) + i j where i represents uncertainty in the data. The strategy of least squares is to pick the coefficients cj to minimize 2 J (c) = X i yi − X cj fj (xi ) . j Theoretically, a global minimum will occur when X X ∂J yi − =0= cj fj (xi ) (−fn∗ (xi )) ∂c∗n i j 56 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 or X cj X j fj (xi ) fn∗ (xi ) = X i yi fn∗ (xi ) i H A Ac = AH y where {A}ij = fj (xi ) . When AH A is invertible, then c = AH A −1 AH y = A† y where A† is called the pseudo-inverse of A. Notice that using this definition of A the model can be written y = Ac + . The command linalg.lstsq will solve the linear least squares problem for c given A and y . In addition linalg.pinv or linalg.pinv2 (uses a different method based on singular value decomposition) will find A† given A. The following example and figure demonstrate the use of linalg.lstsq and linalg.pinv for solving a datafitting problem. The data shown below were generated using the model: yi = c1 e−xi + c2 xi where xi = 0.1i for i = 1 . . . 10 , c1 = 5 , and c2 = 4. Noise is added to yi and the coefficients c1 and c2 are estimated using linear least squares. >>> from numpy import * >>> from scipy import linalg >>> import matplotlib.pyplot as plt >>> >>> >>> >>> >>> c1,c2= 5.0,2.0 i = r_[1:11] xi = 0.1*i yi = c1*exp(-xi)+c2*xi zi = yi + 0.05*max(yi)*random.randn(len(yi)) >>> A = c_[exp(-xi)[:,newaxis],xi[:,newaxis]] >>> c,resid,rank,sigma = linalg.lstsq(A,zi) >>> xi2 = r_[0.1:1.0:100j] >>> yi2 = c[0]*exp(-xi2) + c[1]*xi2 >>> >>> >>> >>> >>> plt.plot(xi,zi,’x’,xi2,yi2) plt.axis([0,1.1,3.0,5.5]) plt.xlabel(’$x_i$’) plt.title(’Data fitting with linalg.lstsq’) plt.show() 1.9. Linear Algebra (scipy.linalg) 57 SciPy Reference Guide, Release 0.13.0 Data fitting with linalg.lstsq 5.5 5.0 4.5 4.0 3.5 3.00.0 0.2 0.4 xi 0.6 0.8 1.0 Generalized inverse The generalized inverse is calculated using the command linalg.pinv or linalg.pinv2. These two commands differ in how they compute the generalized inverse. The first uses the linalg.lstsq algorithm while the second uses singular value decomposition. Let A be an M × N matrix, then if M > N the generalized inverse is −1 H A† = AH A A while if M < N matrix the generalized inverse is A# = AH AAH −1 . In both cases for M = N , then A† = A# = A−1 as long as A is invertible. 1.9.3 Decompositions In many applications it is useful to decompose a matrix using other representations. There are several decompositions supported by SciPy. Eigenvalues and eigenvectors The eigenvalue-eigenvector problem is one of the most commonly employed linear algebra operations. In one popular form, the eigenvalue-eigenvector problem is to find for some square matrix A scalars λ and corresponding vectors v such that Av = λv. For an N × N matrix, there are N (not necessarily distinct) eigenvalues — roots of the (characteristic) polynomial |A − λI| = 0. The eigenvectors, v , are also sometimes called right eigenvectors to distinguish them from another set of left eigenvectors that satisfy H H vL A = λvL 58 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 or AH v L = λ ∗ v L . With it’s default optional arguments, the command linalg.eig returns λ and v. However, it can also return vL and just λ by itself ( linalg.eigvals returns just λ as well). In addtion, linalg.eig can also solve the more general eigenvalue problem Av = λBv = λ∗ BH vL H A vL for square matrices A and B. The standard eigenvalue problem is an example of the general eigenvalue problem for B = I. When a generalized eigenvalue problem can be solved, then it provides a decomposition of A as A = BVΛV−1 where V is the collection of eigenvectors into columns and Λ is a diagonal matrix of eigenvalues. By definition, eigenvectors areP only defined up to a constant scale factor. In SciPy, the scaling factor for the eigenvec2 tors is chosen so that kvk = i vi2 = 1. As an example, consider finding the eigenvalues and eigenvectors of the matrix 1 5 2 A = 2 4 1 . 3 6 2 The characteristic polynomial is |A − λI| = (1 − λ) [(4 − λ) (2 − λ) − 6] − 5 [2 (2 − λ) − 3] + 2 [12 − 3 (4 − λ)] = −λ3 + 7λ2 + 8λ − 3. The roots of this polynomial are the eigenvalues of A : λ1 = 7.9579 λ2 = −1.2577 λ3 = 0.2997. The eigenvectors corresponding to each eigenvalue can be found using the original equation. The eigenvectors associated with these eigenvalues can then be found. >>> import numpy as np >>> from scipy import linalg >>> A = np.array([[1,2],[3,4]]) >>> la,v = linalg.eig(A) >>> l1,l2 = la >>> print l1, l2 #eigenvalues (-0.372281323269+0j) (5.37228132327+0j) >>> print v[:,0] #first eigenvector [-0.82456484 0.56576746] >>> print v[:,1] #second eigenvector [-0.41597356 -0.90937671] >>> print np.sum(abs(v**2),axis=0) #eigenvectors are unitary [ 1. 1. ] >>> v1 = np.array(v[:,0]).T >>> print linalg.norm(A.dot(v1)-l1*v1) #check the computation 3.23682852457e-16 1.9. Linear Algebra (scipy.linalg) 59 SciPy Reference Guide, Release 0.13.0 Singular value decomposition Singular Value Decompostion (SVD) can be thought of as an extension of the eigenvalue problem to matrices that are not square. Let A be an M × N matrix with M and N arbitrary. The matrices AH A and AAH are square hermitian matrices 2 of size N × N and M × M respectively. It is known that the eigenvalues of square hermitian matrices are real and non-negative. In addtion, there are at most min (M, N ) identical non-zero eigenvalues of AH A and AAH . Define these positive eigenvalues as σi2 . The square-root of these are called singular values of A. The eigenvectors of AH A are collected by columns into an N × N unitary 3 matrix V while the eigenvectors of AAH are collected by columns in the unitary matrix U , the singular values are collected in an M × N zero matrix Σ with main diagonal entries set to the singular values. Then A = UΣVH is the singular-value decomposition of A. Every matrix has a singular value decomposition. Sometimes, the singular values are called the spectrum of A. The command linalg.svd will return U , VH , and σi as an array of the singular values. To obtain the matrix Σ use linalg.diagsvd. The following example illustrates the use of linalg.svd . >>> import numpy as np >>> from scipy import linalg >>> A = np.array([[1,2,3],[4,5,6]]) >>> A array([[1, 2, 3], [4, 5, 6]]) >>> M,N = A.shape >>> U,s,Vh = linalg.svd(A) >>> Sig = linalg.diagsvd(s,M,N) >>> U, Vh = U, Vh >>> U array([[-0.3863177 , -0.92236578], [-0.92236578, 0.3863177 ]]) >>> Sig array([[ 9.508032 , 0. , 0. ], [ 0. , 0.77286964, 0. ]]) >>> Vh array([[-0.42866713, -0.56630692, -0.7039467 ], [ 0.80596391, 0.11238241, -0.58119908], [ 0.40824829, -0.81649658, 0.40824829]]) >>> U.dot(Sig.dot(Vh)) #check computation array([[ 1., 2., 3.], [ 4., 5., 6.]]) LU decomposition The LU decompostion finds a representation for the M × N matrix A as A = PLU where P is an M × M permutation matrix (a permutation of the rows of the identity matrix), L is in M × K lower triangular or trapezoidal matrix ( K = min (M, N ) ) with unit-diagonal, and U is an upper triangular or trapezoidal matrix. The SciPy command for this decomposition is linalg.lu . Such a decomposition is often useful for solving many simultaneous equations where the left-hand-side does not change but the right hand side does. For example, suppose we are going to solve Axi = bi 2 3 60 DH A hermitian matrix D satisfies = D. A unitary matrix D satisfies DH D = I = DDH so that D−1 = DH . Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 for many different bi . The LU decomposition allows this to be written as PLUxi = bi . Because L is lower-triangular, the equation can be solved for Uxi and finally xi very rapidly using forward- and back-substitution. An initial time spent factoring A allows for very rapid solution of similar systems of equations in the future. If the intent for performing LU decomposition is for solving linear systems then the command linalg.lu_factor should be used followed by repeated applications of the command linalg.lu_solve to solve the system for each new right-hand-side. Cholesky decomposition Cholesky decomposition is a special case of LU decomposition applicable to Hermitian positive definite matrices. When A = AH and xH Ax ≥ 0 for all x , then decompositions of A can be found so that A = UH U A = LLH where L is lower-triangular and U is upper triangular. Notice that L = UH . The command linagl.cholesky computes the cholesky factorization. For using cholesky factorization to solve systems of equations there are also linalg.cho_factor and linalg.cho_solve routines that work similarly to their LU decomposition counterparts. QR decomposition The QR decomposition (sometimes called a polar decomposition) works for any M × N array and finds an M × M unitary matrix Q and an M × N upper-trapezoidal matrix R such that A = QR. Notice that if the SVD of A is known then the QR decomposition can be found A = UΣVH = QR implies that Q = U and R = ΣVH . Note, however, that in SciPy independent algorithms are used to find QR and SVD decompositions. The command for QR decomposition is linalg.qr . Schur decomposition For a square N × N matrix, A , the Schur decomposition finds (not-necessarily unique) matrices T and Z such that A = ZTZH where Z is a unitary matrix and T is either upper-triangular or quasi-upper triangular depending on whether or not a real schur form or complex schur form is requested. For a real schur form both T and Z are real-valued when A is real-valued. When A is a real-valued matrix the real schur form is only quasi-upper triangular because 2 × 2 blocks extrude from the main diagonal corresponding to any complex- valued eigenvalues. The command linalg.schur finds the Schur decomposition while the command linalg.rsf2csf converts T and Z from a real Schur form to a complex Schur form. The Schur form is especially useful in calculating functions of matrices. The following example illustrates the schur decomposition: 1.9. Linear Algebra (scipy.linalg) 61 SciPy Reference Guide, Release 0.13.0 >>> from scipy import linalg >>> A = mat(’[1 3 2; 1 4 5; 2 3 6]’) >>> T,Z = linalg.schur(A) >>> T1,Z1 = linalg.schur(A,’complex’) >>> T2,Z2 = linalg.rsf2csf(T,Z) >>> print T [[ 9.90012467 1.78947961 -0.65498528] [ 0. 0.54993766 -1.57754789] [ 0. 0.51260928 0.54993766]] >>> print T2 [[ 9.90012467 +0.00000000e+00j -0.32436598 +1.55463542e+00j -0.88619748 +5.69027615e-01j] [ 0.00000000 +0.00000000e+00j 0.54993766 +8.99258408e-01j 1.06493862 +1.37016050e-17j] [ 0.00000000 +0.00000000e+00j 0.00000000 +0.00000000e+00j 0.54993766 -8.99258408e-01j]] >>> print abs(T1-T2) # different [[ 1.24357637e-14 2.09205364e+00 6.56028192e-01] [ 0.00000000e+00 4.00296604e-16 1.83223097e+00] [ 0.00000000e+00 0.00000000e+00 4.57756680e-16]] >>> print abs(Z1-Z2) # different [[ 0.06833781 1.10591375 0.23662249] [ 0.11857169 0.5585604 0.29617525] [ 0.12624999 0.75656818 0.22975038]] >>> T,Z,T1,Z1,T2,Z2 = map(mat,(T,Z,T1,Z1,T2,Z2)) >>> print abs(A-Z*T*Z.H) # same [[ 1.11022302e-16 4.44089210e-16 4.44089210e-16] [ 4.44089210e-16 1.33226763e-15 8.88178420e-16] [ 8.88178420e-16 4.44089210e-16 2.66453526e-15]] >>> print abs(A-Z1*T1*Z1.H) # same [[ 1.00043248e-15 2.22301403e-15 5.55749485e-15] [ 2.88899660e-15 8.44927041e-15 9.77322008e-15] [ 3.11291538e-15 1.15463228e-14 1.15464861e-14]] >>> print abs(A-Z2*T2*Z2.H) # same [[ 3.34058710e-16 8.88611201e-16 4.18773089e-18] [ 1.48694940e-16 8.95109973e-16 8.92966151e-16] [ 1.33228956e-15 1.33582317e-15 3.55373104e-15]] Interpolative Decomposition scipy.linalg.interpolative contains routines for computing the interpolative decomposition (ID) of a matrix. For a matrix A ∈ C m×n of rank k ≤ min{m, n} this is a factorization AΠ = AΠ1 AΠ2 = AΠ1 I T , where Π = [Π1 , Π2 ] is a permutation matrix with Π1 ∈ {0, 1}n×k , i.e., AΠ2 = AΠ1 T . This can equivalently be written as A = BP , where B = AΠ1 and P = [I, T ]ΠT are the skeleton and interpolation matrices, respectively. See Also scipy.linalg.interpolative — for more information. 62 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 1.9.4 Matrix Functions Consider the function f (x) with Taylor series expansion f (x) = ∞ X f (k) (0) k! k=0 xk . A matrix function can be defined using this Taylor series for the square matrix A as f (A) = ∞ X f (k) (0) k! k=0 Ak . While, this serves as a useful representation of a matrix function, it is rarely the best way to calculate a matrix function. Exponential and logarithm functions The matrix exponential is one of the more common matrix functions. It can be defined for square matrices as eA = ∞ X 1 k A . k! k=0 The command linalg.expm3 uses this Taylor series definition to compute the matrix exponential. Due to poor convergence properties it is not often used. Another method to compute the matrix exponential is to find an eigenvalue decomposition of A : A = VΛV−1 and note that eA = VeΛ V−1 where the matrix exponential of the diagonal matrix Λ is just the exponential of its elements. This method is implemented in linalg.expm2 . The preferred method for implementing the matrix exponential is to use scaling and a Padé approximation for ex . This algorithm is implemented as linalg.expm . The inverse of the matrix exponential is the matrix logarithm defined as the inverse of the matrix exponential. A ≡ exp (log (A)) . The matrix logarithm can be obtained with linalg.logm . Trigonometric functions The trigonometric functions sin , cos , and tan are implemented for matrices in linalg.sinm, linalg.cosm, and linalg.tanm respectively. The matrix sin and cosine can be defined using Euler’s identity as sin (A) = cos (A) = ejA − e−jA 2j jA e + e−jA . 2 The tangent is tan (x) = and so the matrix tangent is defined as sin (x) −1 = [cos (x)] sin (x) cos (x) −1 [cos (A)] 1.9. Linear Algebra (scipy.linalg) sin (A) . 63 SciPy Reference Guide, Release 0.13.0 Hyperbolic trigonometric functions The hyperbolic trigonemetric functions sinh , cosh , and tanh can also be defined for matrices using the familiar definitions: sinh (A) = cosh (A) = tanh (A) = eA − e−A 2 eA + e−A 2 −1 [cosh (A)] sinh (A) . These matrix functions can be found using linalg.sinhm, linalg.coshm , and linalg.tanhm. Arbitrary function Finally, any arbitrary function that takes one complex number and returns a complex number can be called as a matrix function using the command linalg.funm. This command takes the matrix and an arbitrary Python function. It then implements an algorithm from Golub and Van Loan’s book “Matrix Computations “to compute function applied to the matrix using a Schur decomposition. Note that the function needs to accept complex numbers as input in order to work with this algorithm. For example the following code computes the zeroth-order Bessel function applied to a matrix. >>> from scipy import special, random, linalg >>> A = random.rand(3,3) >>> B = linalg.funm(A,lambda x: special.jv(0,x)) >>> print A [[ 0.72578091 0.34105276 0.79570345] [ 0.65767207 0.73855618 0.541453 ] [ 0.78397086 0.68043507 0.4837898 ]] >>> print B [[ 0.72599893 -0.20545711 -0.22721101] [-0.27426769 0.77255139 -0.23422637] [-0.27612103 -0.21754832 0.7556849 ]] >>> print linalg.eigvals(A) [ 1.91262611+0.j 0.21846476+0.j -0.18296399+0.j] >>> print special.jv(0, linalg.eigvals(A)) [ 0.27448286+0.j 0.98810383+0.j 0.99164854+0.j] >>> print linalg.eigvals(B) [ 0.27448286+0.j 0.98810383+0.j 0.99164854+0.j] Note how, by virtue of how matrix analytic functions are defined, the Bessel function has acted on the matrix eigenvalues. 1.9.5 Special matrices SciPy and NumPy provide several functions for creating special matrices that are frequently used in engineering and science. 64 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 Type block diagonal circulant companion Hadamard Hankel Hilbert Inverse Hilbert Leslie Pascal Toeplitz Van der Monde Function scipy.linalg.block_diag scipy.linalg.circulant scipy.linalg.companion scipy.linalg.hadamard scipy.linalg.hankel scipy.linalg.hilbert scipy.linalg.invhilbert scipy.linalg.leslie scipy.linalg.pascal scipy.linalg.toeplitz numpy.vander Description Create a block diagonal matrix from the provided arrays. Construct a circulant matrix. Create a companion matrix. Construct a Hadamard matrix. Construct a Hankel matrix. Construct a Hilbert matrix. Construct the inverse of a Hilbert matrix. Create a Leslie matrix. Create a Pascal matrix. Construct a Toeplitz matrix. Generate a Van der Monde matrix. For examples of the use of these functions, see their respective docstrings. 1.10 Sparse Eigenvalue Problems with ARPACK 1.10.1 Introduction ARPACK is a Fortran package which provides routines for quickly finding a few eigenvalues/eigenvectors of large sparse matrices. In order to find these solutions, it requires only left-multiplication by the matrix in question. This operation is performed through a reverse-communication interface. The result of this structure is that ARPACK is able to find eigenvalues and eigenvectors of any linear function mapping a vector to a vector. All of the functionality provided in ARPACK is contained within the two high-level interfaces scipy.sparse.linalg.eigs and scipy.sparse.linalg.eigsh. eigs provides interfaces to find the eigenvalues/vectors of real or complex nonsymmetric square matrices, while eigsh provides interfaces for real-symmetric or complex-hermitian matrices. 1.10.2 Basic Functionality ARPACK can solve either standard eigenvalue problems of the form Ax = λx or general eigenvalue problems of the form Ax = λM x The power of ARPACK is that it can compute only a specified subset of eigenvalue/eigenvector pairs. This is accomplished through the keyword which. The following values of which are available: • which = ’LM’ : Eigenvalues with largest magnitude (eigs, eigsh), that is, largest eigenvalues in the euclidean norm of complex numbers. • which = ’SM’ : Eigenvalues with smallest magnitude (eigs, eigsh), that is, smallest eigenvalues in the euclidean norm of complex numbers. • which = ’LR’ : Eigenvalues with largest real part (eigs) • which = ’SR’ : Eigenvalues with smallest real part (eigs) • which = ’LI’ : Eigenvalues with largest imaginary part (eigs) 1.10. Sparse Eigenvalue Problems with ARPACK 65 SciPy Reference Guide, Release 0.13.0 • which = ’SI’ : Eigenvalues with smallest imaginary part (eigs) • which = ’LA’ : Eigenvalues with largest algebraic value (eigsh), that is, largest eigenvalues inclusive of any negative sign. • which = ’SA’ : Eigenvalues with smallest algebraic value (eigsh), that is, smallest eigenvalues inclusive of any negative sign. • which = ’BE’ : Eigenvalues from both ends of the spectrum (eigsh) Note that ARPACK is generally better at finding extremal eigenvalues: that is, eigenvalues with large magnitudes. In particular, using which = ’SM’ may lead to slow execution time and/or anomalous results. A better approach is to use shift-invert mode. 1.10.3 Shift-Invert Mode Shift invert mode relies on the following observation. For the generalized eigenvalue problem Ax = λM x it can be shown that (A − σM )−1 M x = νx where ν= 1 λ−σ 1.10.4 Examples Imagine you’d like to find the smallest and largest eigenvalues and the corresponding eigenvectors for a large matrix. ARPACK can handle many forms of input: dense matrices such as numpy.ndarray instances, sparse matrices such as scipy.sparse.csr_matrix, or a general linear operator derived from scipy.sparse.linalg.LinearOperator. For this example, for simplicity, we’ll construct a symmetric, positive-definite matrix. >>> >>> >>> >>> >>> >>> >>> >>> import numpy as np from scipy.linalg import eigh from scipy.sparse.linalg import eigsh np.set_printoptions(suppress=True) np.random.seed(0) X = np.random.random((100,100)) - 0.5 X = np.dot(X, X.T) #create a symmetric matrix We now have a symmetric matrix X with which to test the routines. First compute a standard eigenvalue decomposition using eigh: >>> evals_all, evecs_all = eigh(X) As the dimension of X grows, this routine becomes very slow. Especially if only a few eigenvectors and eigenvalues are needed, ARPACK can be a better option. First let’s compute the largest eigenvalues (which = ’LM’) of X and compare them to the known results: 66 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 >>> evals_large, evecs_large = eigsh(X, 3, which=’LM’) >>> print evals_all[-3:] [ 29.1446102 30.05821805 31.19467646] >>> print evals_large [ 29.1446102 30.05821805 31.19467646] >>> print np.dot(evecs_large.T, evecs_all[:,-3:]) [[-1. 0. 0.] [ 0. 1. 0.] [-0. 0. -1.]] The results are as expected. ARPACK recovers the desired eigenvalues, and they match the previously known results. Furthermore, the eigenvectors are orthogonal, as we’d expect. Now let’s attempt to solve for the eigenvalues with smallest magnitude: >>> evals_small, evecs_small = eigsh(X, 3, which=’SM’) scipy.sparse.linalg.eigen.arpack.arpack.ArpackNoConvergence: ARPACK error -1: No convergence (1001 iterations, 0/3 eigenvectors converged) Oops. We see that as mentioned above, ARPACK is not quite as adept at finding small eigenvalues. There are a few ways this problem can be addressed. We could increase the tolerance (tol) to lead to faster convergence: >>> evals_small, evecs_small = eigsh(X, 3, which=’SM’, tol=1E-2) >>> print evals_all[:3] [ 0.0003783 0.00122714 0.00715878] >>> print evals_small [ 0.00037831 0.00122714 0.00715881] >>> print np.dot(evecs_small.T, evecs_all[:,:3]) [[ 0.99999999 0.00000024 -0.00000049] [-0.00000023 0.99999999 0.00000056] [ 0.00000031 -0.00000037 0.99999852]] This works, but we lose the precision in the results. Another option is to increase the maximum number of iterations (maxiter) from 1000 to 5000: >>> evals_small, evecs_small = eigsh(X, 3, which=’SM’, maxiter=5000) >>> print evals_all[:3] [ 0.0003783 0.00122714 0.00715878] >>> print evals_small [ 0.0003783 0.00122714 0.00715878] >>> print np.dot(evecs_small.T, evecs_all[:,:3]) [[ 1. 0. 0.] [-0. 1. 0.] [ 0. 0. -1.]] We get the results we’d hoped for, but the computation time is much longer. Fortunately, ARPACK contains a mode that allows quick determination of non-external eigenvalues: shift-invert mode. As mentioned above, this mode involves transforming the eigenvalue problem to an equivalent problem with different eigenvalues. In this case, we hope to find eigenvalues near zero, so we’ll choose sigma = 0. The transformed eigenvalues will then satisfy ν = 1/(σ − λ) = 1/λ, so our small eigenvalues λ become large eigenvalues ν. >>> evals_small, evecs_small = eigsh(X, 3, sigma=0, which=’LM’) >>> print evals_all[:3] [ 0.0003783 0.00122714 0.00715878] >>> print evals_small [ 0.0003783 0.00122714 0.00715878] >>> print np.dot(evecs_small.T, evecs_all[:,:3]) [[ 1. 0. 0.] [ 0. -1. -0.] [-0. -0. 1.]] 1.10. Sparse Eigenvalue Problems with ARPACK 67 SciPy Reference Guide, Release 0.13.0 We get the results we were hoping for, with much less computational time. Note that the transformation from ν → λ takes place entirely in the background. The user need not worry about the details. The shift-invert mode provides more than just a fast way to obtain a few small eigenvalues. Say you desire to find internal eigenvalues and eigenvectors, e.g. those nearest to λ = 1. Simply set sigma = 1 and ARPACK takes care of the rest: >>> evals_mid, evecs_mid = eigsh(X, 3, sigma=1, which=’LM’) >>> i_sort = np.argsort(abs(1. / (1 - evals_all)))[-3:] >>> print evals_all[i_sort] [ 1.16577199 0.85081388 1.06642272] >>> print evals_mid [ 0.85081388 1.06642272 1.16577199] >>> print np.dot(evecs_mid.T, evecs_all[:,i_sort]) [[-0. 1. 0.] [-0. -0. 1.] [ 1. 0. 0.]] The eigenvalues come out in a different order, but they’re all there. Note that the shift-invert mode requires the internal solution of a matrix inverse. This is taken care of automatically by eigsh and eigs, but the operation can also be specified by the user. See the docstring of scipy.sparse.linalg.eigsh and scipy.sparse.linalg.eigs for details. 1.10.5 References 1.11 Compressed Sparse Graph Routines scipy.sparse.csgraph 1.11.1 Example: Word Ladders A Word Ladder is a word game invented by Lewis Carroll in which players find paths between words by switching one letter at a time. For example, one can link “ape” and “man” in the following way: ape → apt → ait → bit → big → bag → mag → man Note that each step involves changing just one letter of the word. This is just one possible path from “ape” to “man”, but is it the shortest possible path? If we desire to find the shortest word ladder path between two given words, the sparse graph submodule can help. First we need a list of valid words. Many operating systems have such a list built-in. For example, on linux, a word list can often be found at one of the following locations: /usr/share/dict /var/lib/dict Another easy source for words are the scrabble word lists available at various sites around the internet (search with your favorite search engine). We’ll first create this list. The system word lists consist of a file with one word per line. The following should be modified to use the particular word list you have available: >>> word_list = open(’/usr/share/dict/words’).readlines() >>> word_list = map(str.strip, word_list) We want to look at words of length 3, so let’s select just those words of the correct length. We’ll also eliminate words which start with upper-case (proper nouns) or contain non alpha-numeric characters like apostrophes and hyphens. Finally, we’ll make sure everything is lower-case for comparison later: 68 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 >>> >>> >>> >>> >>> 586 word_list = [word for word word_list = [word for word word_list = [word for word word_list = map(str.lower, len(word_list) in word_list if len(word) == 3] in word_list if word[0].islower()] in word_list if word.isalpha()] word_list) Now we have a list of 586 valid three-letter words (the exact number may change depending on the particular list used). Each of these words will become a node in our graph, and we will create edges connecting the nodes associated with each pair of words which differs by only one letter. There are efficient ways to do this, and inefficient ways to do this. To do this as efficiently as possible, we’re going to use some sophisticated numpy array manipulation: >>> import numpy as np >>> word_list = np.asarray(word_list) >>> word_list.dtype dtype(’|S3’) >>> word_list.sort() # sort for quick searching later We have an array where each entry is three bytes. We’d like to find all pairs where exactly one byte is different. We’ll start by converting each word to a three-dimensional vector: >>> word_bytes = np.ndarray((word_list.size, word_list.itemsize), ... dtype=’int8’, ... buffer=word_list.data) >>> word_bytes.shape (586, 3) Now we’ll use the Hamming distance between each point to determine which pairs of words are connected. The Hamming distance measures the fraction of entries between two vectors which differ: any two words with a hamming distance equal to 1/N , where N is the number of letters, are connected in the word ladder: >>> >>> >>> >>> from scipy.spatial.distance import pdist, squareform from scipy.sparse import csr_matrix hamming_dist = pdist(word_bytes, metric=’hamming’) graph = csr_matrix(squareform(hamming_dist < 1.5 / word_list.itemsize)) When comparing the distances, we don’t use an equality because this can be unstable for floating point values. The inequality produces the desired result as long as no two entries of the word list are identical. Now that our graph is set up, we’ll use a shortest path search to find the path between any two words in the graph: >>> i1 = word_list.searchsorted(’ape’) >>> i2 = word_list.searchsorted(’man’) >>> word_list[i1] ’ape’ >>> word_list[i2] ’man’ We need to check that these match, because if the words are not in the list that will not be the case. Now all we need is to find the shortest path between these two indices in the graph. We’ll use dijkstra’s algorithm, because it allows us to find the path for just one node: >>> from scipy.sparse.csgraph import dijkstra >>> distances, predecessors = dijkstra(graph, indices=i1, ... return_predecessors=True) >>> print distances[i2] 5.0 1.11. Compressed Sparse Graph Routines scipy.sparse.csgraph 69 SciPy Reference Guide, Release 0.13.0 So we see that the shortest path between ‘ape’ and ‘man’ contains only five steps. We can use the predecessors returned by the algorithm to reconstruct this path: >>> path = [] >>> i = i2 >>> while i != i1: >>> path.append(word_list[i]) >>> i = predecessors[i] >>> path.append(word_list[i1]) >>> print path[::-1] [’ape’, ’apt’, ’opt’, ’oat’, ’mat’, ’man’] This is three fewer links than our initial example: the path from ape to man is only five steps. Using other tools in the module, we can answer other questions. For example, are there three-letter words which are not linked in a word ladder? This is a question of connected components in the graph: >>> from scipy.sparse.csgraph import connected_components >>> N_components, component_list = connected_components(graph) >>> print N_components 15 In this particular sample of three-letter words, there are 15 connected components: that is, 15 distinct sets of words with no paths between the sets. How many words are in each of these sets? We can learn this from the list of components: >>> [np.sum(component_list == i) for i in range(15)] [571, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] There is one large connected set, and 14 smaller ones. Let’s look at the words in the smaller ones: >>> [list(word_list[np.where(component_list == i)]) for i in range(1, 15)] [[’aha’], [’chi’], [’ebb’], [’ems’, ’emu’], [’gnu’], [’ism’], [’khz’], [’nth’], [’ova’], [’qua’], [’ugh’], [’ups’], [’urn’], [’use’]] These are all the three-letter words which do not connect to others via a word ladder. We might also be curious about which words are maximally separated. Which two words take the most links to connect? We can determine this by computing the matrix of all shortest paths. Note that by convention, the distance between two non-connected points is reported to be infinity, so we’ll need to remove these before finding the maximum: >>> distances, predecessors = dijkstra(graph, return_predecessors=True) >>> np.max(distances[~np.isinf(distances)]) 13.0 So there is at least one pair of words which takes 13 steps to get from one to the other! Let’s determine which these are: >>> i1, i2 = np.where(distances == 13) >>> zip(word_list[i1], word_list[i2]) 70 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 [(’imp’, (’imp’, (’ohm’, (’ohm’, (’ohs’, (’ohs’, (’ump’, (’ump’, ’ohm’), ’ohs’), ’imp’), ’ump’), ’imp’), ’ump’), ’ohm’), ’ohs’)] We see that there are two pairs of words which are maximally separated from each other: ‘imp’ and ‘ump’ on one hand, and ‘ohm’ and ‘ohs’ on the other hand. We can find the connecting list in the same way as above: >>> path = [] >>> i = i2[0] >>> while i != i1[0]: >>> path.append(word_list[i]) >>> i = predecessors[i1[0], i] >>> path.append(word_list[i1[0]]) >>> print path[::-1] [’imp’, ’amp’, ’asp’, ’ask’, ’ark’, ’are’, ’aye’, ’rye’, ’roe’, ’woe’, ’woo’, ’who’, ’oho’, ’ohm’] This gives us the path we desired to see. Word ladders are just one potential application of scipy’s fast graph algorithms for sparse matrices. Graph theory makes appearances in many areas of mathematics, data analysis, and machine learning. The sparse graph tools are flexible enough to handle many of these situations. 1.12 Spatial data structures and algorithms (scipy.spatial) scipy.spatial can compute triangulations, Voronoi diagrams, and convex hulls of a set of points, by leveraging the Qhull library. Moreover, it contains KDTree implementations for nearest-neighbor point queries, and utilities for distance computations in various metrics. 1.12.1 Delaunay triangulations The Delaunay triangulation is a subdivision of a set of points into a non-overlapping set of triangles, such that no point is inside the circumcircle of any triangle. In practice, such triangulations tend to avoid triangles with small angles. Delaunay triangulation can be computed using scipy.spatial as follows: >>> from scipy.spatial import Delaunay >>> points = np.array([[0, 0], [0, 1.1], [1, 0], [1, 1]]) >>> tri = Delaunay(points) We can visualize it: >>> import matplotlib.pyplot as plt >>> plt.triplot(points[:,0], points[:,1], tri.simplices.copy()) >>> plt.plot(points[:,0], points[:,1], ’o’) And add some further decorations: >>> for j, p in enumerate(points): ... plt.text(p[0]-0.03, p[1]+0.03, j, ha=’right’) # label the points 1.12. Spatial data structures and algorithms (scipy.spatial) 71 SciPy Reference Guide, Release 0.13.0 >>> for j, s in enumerate(tri.simplices): ... p = points[s].mean(axis=0) ... plt.text(p[0], p[1], ’#%d’ % j, ha=’center’) # label triangles >>> plt.xlim(-0.5, 1.5); plt.ylim(-0.5, 1.5) >>> plt.show() 1.5 1.0 1 3 #1 0.5 #0 0.0 0 0.50.5 0.0 2 0.5 1.0 1.5 The structure of the triangulation is encoded in the following way: the simplices attribute contains the indices of the points in the points array that make up the triangle. For instance: >>> i = 1 >>> tri.simplices[i,:] array([3, 1, 0], dtype=int32) >>> points[tri.simplices[i,:]] array([[ 1. , 1. ], [ 0. , 1.1], [ 0. , 0. ]]) Moreover, neighboring triangles can also be found out: >>> tri.neighbors[i] array([-1, 0, -1], dtype=int32) What this tells us is that this triangle has triangle #0 as a neighbor, but no other neighbors. Moreover, it tells us that neighbor 0 is opposite the vertex 1 of the triangle: >>> points[tri.simplices[i, 1]] array([ 0. , 1.1]) Indeed, from the figure we see that this is the case. Qhull can also perform tesselations to simplices also for higher-dimensional point sets (for instance, subdivision into tetrahedra in 3-D). Coplanar points It is important to note that not all points necessarily appear as vertices of the triangulation, due to numerical precision issues in forming the triangulation. Consider the above with a duplicated point: 72 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 >>> points = np.array([[0, 0], [0, 1], [1, 0], [1, 1], [1, 1]]) >>> tri = Delaunay(points) >>> np.unique(tri.simplices.ravel()) array([0, 1, 2, 3], dtype=int32) Observe that point #4, which is a duplicate, does not occur as a vertex of the triangulation. That this happened is recorded: >>> tri.coplanar array([[4, 0, 3]], dtype=int32) This means that point 4 resides near triangle 0 and vertex 3, but is not included in the triangulation. Note that such degeneracies can occur not only because of duplicated points, but also for more complicated geometrical reasons, even in point sets that at first sight seem well-behaved. However, Qhull has the “QJ” option, which instructs it to perturb the input data randomly until degeneracies are resolved: >>> tri = Delaunay(points, qhull_options="QJ Pp") >>> points[tri.simplices] array([[[1, 1], [1, 0], [0, 0]], [[1, 1], [1, 1], [1, 0]], [[0, 1], [1, 1], [0, 0]], [[0, 1], [1, 1], [1, 1]]]) Two new triangles appeared. However, we see that they are degenerate and have zero area. 1.12.2 Convex hulls Convex hull is the smallest convex object containing all points in a given point set. These can be computed via the Qhull wrappers in scipy.spatial as follows: >>> from scipy.spatial import ConvexHull >>> points = np.random.rand(30, 2) # 30 random points in 2-D >>> hull = ConvexHull(points) The convex hull is represented as a set of N-1 dimensional simplices, which in 2-D means line segments. The storage scheme is exactly the same as for the simplices in the Delaunay triangulation discussed above. We can illustrate the above result: >>> >>> >>> >>> >>> import matplotlib.pyplot as plt plt.plot(points[:,0], points[:,1], ’o’) for simplex in hull.simplices: plt.plot(points[simplex,0], points[simplex,1], ’k-’) plt.show() 1.12. Spatial data structures and algorithms (scipy.spatial) 73 SciPy Reference Guide, Release 0.13.0 1.0 0.8 0.6 0.4 0.2 0.00.0 0.2 0.4 0.6 0.8 1.0 The same can be achieved with scipy.spatial.convex_hull_plot_2d. 1.12.3 Voronoi diagrams A Voronoi diagram is a subdivision of the space into the nearest neighborhoods of a given set of points. There are two ways to approach this object using scipy.spatial. First, one can use the KDTree to answer the question “which of the points is closest to this one”, and define the regions that way: >>> from scipy.spatial import KDTree >>> points = np.array([[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2], ... [2, 0], [2, 1], [2, 2]]) >>> tree = KDTree(points) >>> tree.query([0.1, 0.1]) (0.14142135623730953, 0) So the point (0.1, 0.1) belongs to region 0. In color: >>> >>> >>> >>> >>> >>> >>> >>> 74 x = np.linspace(-0.5, 2.5, 31) y = np.linspace(-0.5, 2.5, 33) xx, yy = np.meshgrid(x, y) xy = np.c_[xx.ravel(), yy.ravel()] import matplotlib.pyplot as plt plt.pcolor(x, y, tree.query(xy)[1].reshape(33, 31)) plt.plot(points[:,0], points[:,1], ’ko’) plt.show() Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 2.5 2.0 1.5 1.0 0.5 0.0 0.50.5 0.0 0.5 1.0 1.5 2.0 2.5 This does not, however, give the Voronoi diagram as a geometrical object. The representation in terms of lines and points can be again obtained via the Qhull wrappers in scipy.spatial: >>> from scipy.spatial import Voronoi >>> vor = Voronoi(points) >>> vor.vertices array([[ 0.5, 0.5], [ 1.5, 0.5], [ 0.5, 1.5], [ 1.5, 1.5]]) The Voronoi vertices denote the set of points forming the polygonal edges of the Voronoi regions. In this case, there are 9 different regions: >>> vor.regions [[-1, 0], [-1, 1], [1, -1, 0], [3, -1, 2], [-1, 3], [-1, 2], [3, 1, 0, 2], [2, -1, 0], [3, -1, 1]] Negative value -1 again indicates a point at infinity. Indeed, only one of the regions, [3, 1, 0, 2], is bounded. Note here that due to similar numerical precision issues as in Delaunay triangulation above, there may be fewer Voronoi regions than input points. The ridges (lines in 2-D) separating the regions are described as a similar collection of simplices as the convex hull pieces: >>> vor.ridge_vertices [[-1, 0], [-1, 0], [-1, 1], [-1, 1], [0, 1], [-1, 3], [-1, 2], [2, 3], [-1, 3], [-1, 2], [0, 2], [1, These numbers indicate indices of the Voronoi vertices making up the line segments. -1 is again a point at infinity — only four of the 12 lines is a bounded line segment while the others extend to infinity. The Voronoi ridges are perpendicular to lines drawn between the input points. Which two points each ridge corresponds to is also recorded: >>> vor.ridge_points array([[0, 3], [0, 1], [6, 3], [6, 7], [3, 4], 1.12. Spatial data structures and algorithms (scipy.spatial) 75 SciPy Reference Guide, Release 0.13.0 [5, [5, [5, [8, [2, [4, [4, 8], 2], 4], 7], 1], 1], 7]], dtype=int32) This information, taken together, is enough to construct the full diagram. We can plot it as follows. First the points and the Voronoi vertices: >>> plt.plot(points[:,0], points[:,1], ’o’) >>> plt.plot(vor.vertices[:,0], vor.vertices[:,1], ’*’) >>> plt.xlim(-1, 3); plt.ylim(-1, 3) Plotting the finite line segments goes as for the convex hull, but now we have to guard for the infinite edges: >>> for simplex in vor.ridge_vertices: >>> simplex = np.asarray(simplex) >>> if np.all(simplex >= 0): >>> plt.plot(vor.vertices[simplex,0], vor.vertices[simplex,1], ’k-’) The ridges extending to infinity require a bit more care: >>> center = points.mean(axis=0) >>> for pointidx, simplex in zip(vor.ridge_points, vor.ridge_vertices): >>> simplex = np.asarray(simplex) >>> if np.any(simplex < 0): >>> i = simplex[simplex >= 0][0] # finite end Voronoi vertex >>> t = points[pointidx[1]] - points[pointidx[0]] # tangent >>> t /= np.linalg.norm(t) >>> n = np.array([-t[1], t[0]]) # normal >>> midpoint = points[pointidx].mean(axis=0) >>> far_point = vor.vertices[i] + np.sign(np.dot(midpoint - center, n)) * n * 100 >>> plt.plot([vor.vertices[i,0], far_point[0]], ... [vor.vertices[i,1], far_point[1]], ’k--’) >>> plt.show() 3.0 2.5 2.0 1.5 1.0 0.5 0.0 0.5 1.01.0 0.5 0.0 0.5 1.0 1.5 2.0 2.5 3.0 76 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 This plot can also be created using scipy.spatial.voronoi_plot_2d. 1.13 Statistics (scipy.stats) 1.13.1 Introduction In this tutorial we discuss many, but certainly not all, features of scipy.stats. The intention here is to provide a user with a working knowledge of this package. We refer to the reference manual for further details. Note: This documentation is work in progress. 1.13.2 Random Variables There are two general distribution classes that have been implemented for encapsulating continuous random variables and discrete random variables . Over 80 continuous random variables (RVs) and 10 discrete random variables have been implemented using these classes. Besides this, new routines and distributions can easily added by the end user. (If you create one, please contribute it). All of the statistics functions are located in the sub-package scipy.stats and a fairly complete listing of these functions can be obtained using info(stats). The list of the random variables available can also be obtained from the docstring for the stats sub-package. In the discussion below we mostly focus on continuous RVs. Nearly all applies to discrete variables also, but we point out some differences here: Specific Points for Discrete Distributions. Getting Help First of all, all distributions are accompanied with help functions. To obtain just some basic information we can call >>> from scipy import stats >>> from scipy.stats import norm >>> print norm.__doc__ To find the support, i.e., upper and lower bound of the distribution, call: >>> print ’bounds of distribution lower: %s, upper: %s’ % (norm.a,norm.b) bounds of distribution lower: -inf, upper: inf We can list all methods and properties of the distribution with dir(norm). As it turns out, some of the methods are private methods although they are not named as such (their name does not start with a leading underscore), for example veccdf, are only available for internal calculation. To obtain the real main methods, we list the methods of the frozen distribution. (We explain the meaning of a frozen distribution below). >>> rv = norm() >>> dir(rv) #reformatted [’__class__’, ’__delattr__’, ’__dict__’, ’__doc__’, ’__getattribute__’, ’__hash__’, ’__init__’, ’__module__’, ’__new__’, ’__reduce__’, ’__reduce_ex__’, ’__repr__’, ’__setattr__’, ’__str__’, ’__weakref__’, ’args’, ’cdf’, ’dist’, ’entropy’, ’isf’, ’kwds’, ’moment’, ’pdf’, ’pmf’, ’ppf’, ’rvs’, ’sf’, ’stats’] Finally, we can obtain the list of available distribution through introspection: 1.13. Statistics (scipy.stats) 77 SciPy Reference Guide, Release 0.13.0 >>> import warnings >>> warnings.simplefilter(’ignore’, DeprecationWarning) >>> dist_continu = [d for d in dir(stats) if ... isinstance(getattr(stats,d), stats.rv_continuous)] >>> dist_discrete = [d for d in dir(stats) if ... isinstance(getattr(stats,d), stats.rv_discrete)] >>> print ’number of continuous distributions:’, len(dist_continu) number of continuous distributions: 84 >>> print ’number of discrete distributions: ’, len(dist_discrete) number of discrete distributions: 12 Common Methods The main public methods for continuous RVs are: • rvs: Random Variates • pdf: Probability Density Function • cdf: Cumulative Distribution Function • sf: Survival Function (1-CDF) • ppf: Percent Point Function (Inverse of CDF) • isf: Inverse Survival Function (Inverse of SF) • stats: Return mean, variance, (Fisher’s) skew, or (Fisher’s) kurtosis • moment: non-central moments of the distribution Let’s take a normal RV as an example. >>> norm.cdf(0) 0.5 To compute the cdf at a number of points, we can pass a list or a numpy array. >>> norm.cdf([-1., 0, 1]) array([ 0.15865525, 0.5 , 0.84134475]) >>> import numpy as np >>> norm.cdf(np.array([-1., 0, 1])) array([ 0.15865525, 0.5 , 0.84134475]) Thus, the basic methods such as pdf, cdf, and so on are vectorized with np.vectorize. Other generally useful methods are supported too: >>> norm.mean(), norm.std(), norm.var() (0.0, 1.0, 1.0) >>> norm.stats(moments = "mv") (array(0.0), array(1.0)) To find the median of a distribution we can use the percent point function ppf, which is the inverse of the cdf: >>> norm.ppf(0.5) 0.0 To generate a set of random variates: >>> norm.rvs(size=5) array([-0.35687759, 1.34347647, -0.11710531, -1.00725181, -0.51275702]) 78 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 Don’t think that norm.rvs(5) generates 5 variates: >>> norm.rvs(5) 7.131624370075814 This brings us, in fact, to the topic of the next subsection. Shifting and Scaling All continuous distributions take loc and scale as keyword parameters to adjust the location and scale of the distribution, e.g. for the standard normal distribution the location is the mean and the scale is the standard deviation. >>> norm.stats(loc = 3, scale = 4, moments = "mv") (array(3.0), array(16.0)) In general the standardized distribution for a random variable X is obtained through the transformation (X - loc) / scale. The default values are loc = 0 and scale = 1. Smart use of loc and scale can help modify the standard distributions in many ways. To illustrate the scaling further, the cdf of an exponentially distributed RV with mean 1/λ is given by F (x) = 1 − exp(−λx) By applying the scaling rule above, it can be seen that by taking scale = 1./lambda we get the proper scale. >>> from scipy.stats import expon >>> expon.mean(scale = 3.) 3.0 The uniform distribution is also interesting: >>> from scipy.stats import uniform >>> uniform.cdf([0,1,2,3,4,5], loc = 1, scale = 4) array([ 0. , 0. , 0.25, 0.5 , 0.75, 1. ]) Finally, recall from the previous paragraph that we are left with the problem of the meaning of norm.rvs(5). As it turns out, calling a distribution like this, the first argument, i.e., the 5, gets passed to set the loc parameter. Let’s see: >>> np.mean(norm.rvs(5, size=500)) 4.983550784784704 Thus, to explain the output of the example of the last section: norm.rvs(5)‘ generates a normally distributed random variate with mean ‘‘loc=5. I prefer to set the loc and scale parameter explicitly, by passing the values as keywords rather than as arguments. This is less of a hassle as it may seem. We clarify this below when we explain the topic of freezing a RV. Shape Parameters While a general continuous random variable can be shifted and scaled with the loc and scale parameters, some distributions require additional shape parameters. For instance, the gamma distribution, with density γ(x, n) = λ(λx)n−1 −λx e , Γ(n) requires the shape parameter n. Observe that setting λ can be obtained by setting the scale keyword to 1/λ. Let’s check the number and name of the shape parameters of the gamma distribution. (We know from the above that this should be 1.) 1.13. Statistics (scipy.stats) 79 SciPy Reference Guide, Release 0.13.0 >>> from scipy.stats import gamma >>> gamma.numargs 1 >>> gamma.shapes ’a’ Now we set the value of the shape variable to 1 to obtain the exponential distribution, so that we compare easily whether we get the results we expect. >>> gamma(1, scale=2.).stats(moments="mv") (array(2.0), array(4.0)) Notice that we can also specify shape parameters as keywords: >>> gamma(a=1, scale=2.).stats(moments="mv") (array(2.0), array(4.0)) Freezing a Distribution Passing the loc and scale keywords time and again can become quite bothersome. The concept of freezing a RV is used to solve such problems. >>> rv = gamma(1, scale=2.) By using rv we no longer have to include the scale or the shape parameters anymore. Thus, distributions can be used in one of two ways, either by passing all distribution parameters to each method call (such as we did earlier) or by freezing the parameters for the instance of the distribution. Let us check this: >>> rv.mean(), rv.std() (2.0, 2.0) This is indeed what we should get. Broadcasting The basic methods pdf and so on satisfy the usual numpy broadcasting rules. For example, we can calculate the critical values for the upper tail of the t distribution for different probabilites and degrees of freedom. >>> stats.t.isf([0.1, 0.05, 0.01], [[10], [11]]) array([[ 1.37218364, 1.81246112, 2.76376946], [ 1.36343032, 1.79588482, 2.71807918]]) Here, the first row are the critical values for 10 degrees of freedom and the second row for 11 degrees of freedom (d.o.f.). Thus, the broadcasting rules give the same result of calling isf twice: >>> stats.t.isf([0.1, 0.05, 0.01], 10) array([ 1.37218364, 1.81246112, 2.76376946]) >>> stats.t.isf([0.1, 0.05, 0.01], 11) array([ 1.36343032, 1.79588482, 2.71807918]) If the array with probabilities, i.e, [0.1, 0.05, 0.01] and the array of degrees of freedom i.e., [10, 11, 12], have the same array shape, then element wise matching is used. As an example, we can obtain the 10% tail for 10 d.o.f., the 5% tail for 11 d.o.f. and the 1% tail for 12 d.o.f. by calling >>> stats.t.isf([0.1, 0.05, 0.01], [10, 11, 12]) array([ 1.37218364, 1.79588482, 2.68099799]) 80 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 Specific Points for Discrete Distributions Discrete distribution have mostly the same basic methods as the continuous distributions. However pdf is replaced the probability mass function pmf, no estimation methods, such as fit, are available, and scale is not a valid keyword parameter. The location parameter, keyword loc can still be used to shift the distribution. The computation of the cdf requires some extra attention. In the case of continuous distribution the cumulative distribution function is in most standard cases strictly monotonic increasing in the bounds (a,b) and has therefore a unique inverse. The cdf of a discrete distribution, however, is a step function, hence the inverse cdf, i.e., the percent point function, requires a different definition: ppf(q) = min{x : cdf(x) >= q, x integer} For further info, see the docs here. We can look at the hypergeometric distribution as an example >>> from scipy.stats import hypergeom >>> [M, n, N] = [20, 7, 12] If we use the cdf at some integer points and then evaluate the ppf at those cdf values, we get the initial integers back, for example >>> x = np.arange(4)*2 >>> x array([0, 2, 4, 6]) >>> prb = hypergeom.cdf(x, M, n, N) >>> prb array([ 0.0001031991744066, 0.0521155830753351, 0.9897832817337386]) >>> hypergeom.ppf(prb, M, n, N) array([ 0., 2., 4., 6.]) 0.6083591331269301, If we use values that are not at the kinks of the cdf step function, we get the next higher integer back: >>> hypergeom.ppf(prb+1e-8, M, n, N) array([ 1., 3., 5., 7.]) >>> hypergeom.ppf(prb-1e-8, M, n, N) array([ 0., 2., 4., 6.]) Fitting Distributions The main additional methods of the not frozen distribution are related to the estimation of distribution parameters: • fit: maximum likelihood estimation of distribution parameters, including location and scale • fit_loc_scale: estimation of location and scale when shape parameters are given • nnlf: negative log likelihood function • expect: Calculate the expectation of a function against the pdf or pmf Performance Issues and Cautionary Remarks The performance of the individual methods, in terms of speed, varies widely by distribution and method. The results of a method are obtained in one of two ways: either by explicit calculation, or by a generic algorithm that is independent of the specific distribution. 1.13. Statistics (scipy.stats) 81 SciPy Reference Guide, Release 0.13.0 Explicit calculation, on the one hand, requires that the method is directly specified for the given distribution, either through analytic formulas or through special functions in scipy.special or numpy.random for rvs. These are usually relatively fast calculations. The generic methods, on the other hand, are used if the distribution does not specify any explicit calculation. To define a distribution, only one of pdf or cdf is necessary; all other methods can be derived using numeric integration and root finding. However, these indirect methods can be very slow. As an example, rgh = stats.gausshyper.rvs(0.5, 2, 2, 2, size=100) creates random variables in a very indirect way and takes about 19 seconds for 100 random variables on my computer, while one million random variables from the standard normal or from the t distribution take just above one second. Remaining Issues The distributions in scipy.stats have recently been corrected and improved and gained a considerable test suite, however a few issues remain: • skew and kurtosis, 3rd and 4th moments and entropy are not thoroughly tested and some coarse testing indicates that there are still some incorrect results left. • the distributions have been tested over some range of parameters, however in some corner ranges, a few incorrect results may remain. • the maximum likelihood estimation in fit does not work with default starting parameters for all distributions and the user needs to supply good starting parameters. Also, for some distribution using a maximum likelihood estimator might inherently not be the best choice. 1.13.3 Building Specific Distributions The next examples shows how to build your own distributions. Further examples show the usage of the distributions and some statistical tests. Making a Continuous Distribution, i.e., Subclassing rv_continuous Making continuous distributions is fairly simple. >>> from scipy import stats >>> class deterministic_gen(stats.rv_continuous): ... def _cdf(self, x ): ... return np.where(x<0, 0., 1.) ... def _stats(self): ... return 0., 0., 0., 0. >>> deterministic = deterministic_gen(name="deterministic") >>> deterministic.cdf(np.arange(-3, 3, 0.5)) array([ 0., 0., 0., 0., 0., 0., 1., 1., 1., 1., 1., 1.]) Interestingly, the pdf is now computed automatically: >>> deterministic.pdf(np.arange(-3, 3, 0.5)) array([ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 5.83333333e+04, 4.16333634e-12, 4.16333634e-12, 4.16333634e-12, 82 0.00000000e+00, 0.00000000e+00, 4.16333634e-12, 4.16333634e-12]) Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 Be aware of the performance issues mentions in Performance Issues and Cautionary Remarks. The computation of unspecified common methods can become very slow, since only general methods are called which, by their very nature, cannot use any specific information about the distribution. Thus, as a cautionary example: >>> from scipy.integrate import quad >>> quad(deterministic.pdf, -1e-1, 1e-1) (4.163336342344337e-13, 0.0) But this is not correct: the integral over this pdf should be 1. Let’s make the integration interval smaller: >>> quad(deterministic.pdf, -1e-3, 1e-3) # warning removed (1.000076872229173, 0.0010625571718182458) This looks better. However, the problem originated from the fact that the pdf is not specified in the class definition of the deterministic distribution. Subclassing rv_discrete In the following we use stats.rv_discrete to generate a discrete distribution that has the probabilities of the truncated normal for the intervals centered around the integers. General Info From the docstring of rv_discrete, i.e., >>> from scipy.stats import rv_discrete >>> help(rv_discrete) we learn that: “You can construct an aribtrary discrete rv where P{X=xk} = pk by passing to the rv_discrete initialization method (through the values= keyword) a tuple of sequences (xk, pk) which describes only those values of X (xk) that occur with nonzero probability (pk).” Next to this, there are some further requirements for this approach to work: • The keyword name is required. • The support points of the distribution xk have to be integers. • The number of significant digits (decimals) needs to be specified. In fact, if the last two requirements are not satisfied an exception may be raised or the resulting numbers may be incorrect. An Example Let’s do the work. First >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> npoints = 20 # number of integer support points of the distribution minus 1 npointsh = npoints / 2 npointsf = float(npoints) nbound = 4 # bounds for the truncated normal normbound = (1+1/npointsf) * nbound # actual bounds of truncated normal grid = np.arange(-npointsh, npointsh+2, 1) # integer grid gridlimitsnorm = (grid-0.5) / npointsh * nbound # bin limits for the truncnorm gridlimits = grid - 0.5 # used later in the analysis grid = grid[:-1] probs = np.diff(stats.truncnorm.cdf(gridlimitsnorm, -normbound, normbound)) gridint = grid And finally we can subclass rv_discrete: 1.13. Statistics (scipy.stats) 83 SciPy Reference Guide, Release 0.13.0 >>> normdiscrete = stats.rv_discrete(values=(gridint, ... np.round(probs, decimals=7)), name=’normdiscrete’) Now that we have defined the distribution, we have access to all common methods of discrete distributions. >>> print ’mean = %6.4f, variance = %6.4f, skew = %6.4f, kurtosis = %6.4f’% \ ... normdiscrete.stats(moments = ’mvsk’) mean = -0.0000, variance = 6.3302, skew = 0.0000, kurtosis = -0.0076 >>> nd_std = np.sqrt(normdiscrete.stats(moments=’v’)) Testing the Implementation Let’s generate a random sample and compare observed frequencies with the probabilities. >>> n_sample = 500 >>> np.random.seed(87655678) # fix the seed for replicability >>> rvs = normdiscrete.rvs(size=n_sample) >>> rvsnd = rvs >>> f, l = np.histogram(rvs, bins=gridlimits) >>> sfreq = np.vstack([gridint, f, probs*n_sample]).T >>> print sfreq [[ -1.00000000e+01 0.00000000e+00 2.95019349e-02] [ -9.00000000e+00 0.00000000e+00 1.32294142e-01] [ -8.00000000e+00 0.00000000e+00 5.06497902e-01] [ -7.00000000e+00 2.00000000e+00 1.65568919e+00] [ -6.00000000e+00 1.00000000e+00 4.62125309e+00] [ -5.00000000e+00 9.00000000e+00 1.10137298e+01] [ -4.00000000e+00 2.60000000e+01 2.24137683e+01] [ -3.00000000e+00 3.70000000e+01 3.89503370e+01] [ -2.00000000e+00 5.10000000e+01 5.78004747e+01] [ -1.00000000e+00 7.10000000e+01 7.32455414e+01] [ 0.00000000e+00 7.40000000e+01 7.92618251e+01] [ 1.00000000e+00 8.90000000e+01 7.32455414e+01] [ 2.00000000e+00 5.50000000e+01 5.78004747e+01] [ 3.00000000e+00 5.00000000e+01 3.89503370e+01] [ 4.00000000e+00 1.70000000e+01 2.24137683e+01] [ 5.00000000e+00 1.10000000e+01 1.10137298e+01] [ 6.00000000e+00 4.00000000e+00 4.62125309e+00] [ 7.00000000e+00 3.00000000e+00 1.65568919e+00] [ 8.00000000e+00 0.00000000e+00 5.06497902e-01] [ 9.00000000e+00 0.00000000e+00 1.32294142e-01] [ 1.00000000e+01 0.00000000e+00 2.95019349e-02]] 84 Chapter 1. SciPy Tutorial Frequency SciPy Reference Guide, Release 0.13.0 Frequency and Probability of normdiscrete 0.18 true 0.16 sample 0.14 0.12 0.10 0.08 0.06 0.04 0.02 0.00-10-9-8-7-6-5-4-3-2-1 0 1 2 3 4 5 6 7 8 910 Cumulative Frequency and CDF of normdiscrete true sample 0.8 cdf 1.0 0.6 0.4 0.2 0.0-10-9-8-7-6-5-4-3-2-1 0 1 2 3 4 5 6 7 8 910 Next, we can test, whether our sample was generated by our normdiscrete distribution. This also verifies whether the random numbers are generated correctly. The chisquare test requires that there are a minimum number of observations in each bin. We combine the tail bins into larger bins so that they contain enough observations. >>> f2 = np.hstack([f[:5].sum(), f[5:-5], f[-5:].sum()]) >>> p2 = np.hstack([probs[:5].sum(), probs[5:-5], probs[-5:].sum()]) >>> ch2, pval = stats.chisquare(f2, p2*n_sample) >>> print ’chisquare for normdiscrete: chi2 = %6.3f pvalue = %6.4f’ % (ch2, pval) chisquare for normdiscrete: chi2 = 12.466 pvalue = 0.4090 The pvalue in this case is high, so we can be quite confident that our random sample was actually generated by the distribution. 1.13. Statistics (scipy.stats) 85 SciPy Reference Guide, Release 0.13.0 1.13.4 Analysing One Sample First, we create some random variables. We set a seed so that in each run we get identical results to look at. As an example we take a sample from the Student t distribution: >>> np.random.seed(282629734) >>> x = stats.t.rvs(10, size=1000) Here, we set the required shape parameter of the t distribution, which in statistics corresponds to the degrees of freedom, to 10. Using size=1000 means that our sample consists of 1000 independently drawn (pseudo) random numbers. Since we did not specify the keyword arguments loc and scale, those are set to their default values zero and one. Descriptive Statistics x is a numpy array, and we have direct access to all array methods, e.g. >>> print x.max(), x.min() # equivalent to np.max(x), np.min(x) 5.26327732981 -3.78975572422 >>> print x.mean(), x.var() # equivalent to np.mean(x), np.var(x) 0.0140610663985 1.28899386208 How do the some sample properties compare to their theoretical counterparts? >>> m, v, s, k = stats.t.stats(10, moments=’mvsk’) >>> n, (smin, smax), sm, sv, ss, sk = stats.describe(x) >>> print ’distribution:’, distribution: >>> sstr = ’mean = %6.4f, variance = %6.4f, skew = %6.4f, kurtosis = %6.4f’ >>> print sstr %(m, v, s ,k) mean = 0.0000, variance = 1.2500, skew = 0.0000, kurtosis = 1.0000 >>> print ’sample: ’, sample: >>> print sstr %(sm, sv, ss, sk) mean = 0.0141, variance = 1.2903, skew = 0.2165, kurtosis = 1.0556 Note: stats.describe uses the unbiased estimator for the variance, while np.var is the biased estimator. For our sample the sample statistics differ a by a small amount from their theoretical counterparts. T-test and KS-test We can use the t-test to test whether the mean of our sample differs in a statistcally significant way from the theoretical expectation. >>> print ’t-statistic = %6.3f pvalue = %6.4f’ % t-statistic = 0.391 pvalue = 0.6955 stats.ttest_1samp(x, m) The pvalue is 0.7, this means that with an alpha error of, for example, 10%, we cannot reject the hypothesis that the sample mean is equal to zero, the expectation of the standard t-distribution. As an exercise, we can calculate our ttest also directly without using the provided function, which should give us the same answer, and so it does: >>> tt = (sm-m)/np.sqrt(sv/float(n)) # t-statistic for mean >>> pval = stats.t.sf(np.abs(tt), n-1)*2 # two-sided pvalue = Prob(abs(t)>tt) 86 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 >>> print ’t-statistic = %6.3f pvalue = %6.4f’ % (tt, pval) t-statistic = 0.391 pvalue = 0.6955 The Kolmogorov-Smirnov test can be used to test the hypothesis that the sample comes from the standard t-distribution >>> print ’KS-statistic D = %6.3f pvalue = %6.4f’ % stats.kstest(x, ’t’, (10,)) KS-statistic D = 0.016 pvalue = 0.9606 Again the p-value is high enough that we cannot reject the hypothesis that the random sample really is distributed according to the t-distribution. In real applications, we don’t know what the underlying distribution is. If we perform the Kolmogorov-Smirnov test of our sample against the standard normal distribution, then we also cannot reject the hypothesis that our sample was generated by the normal distribution given that in this example the p-value is almost 40%. >>> print ’KS-statistic D = %6.3f pvalue = %6.4f’ % stats.kstest(x,’norm’) KS-statistic D = 0.028 pvalue = 0.3949 However, the standard normal distribution has a variance of 1, while our sample has a variance of 1.29. If we standardize our sample and test it against the normal distribution, then the p-value is again large enough that we cannot reject the hypothesis that the sample came form the normal distribution. >>> d, pval = stats.kstest((x-x.mean())/x.std(), ’norm’) >>> print ’KS-statistic D = %6.3f pvalue = %6.4f’ % (d, pval) KS-statistic D = 0.032 pvalue = 0.2402 Note: The Kolmogorov-Smirnov test assumes that we test against a distribution with given parameters, since in the last case we estimated mean and variance, this assumption is violated, and the distribution of the test statistic on which the p-value is based, is not correct. Tails of the distribution Finally, we can check the upper tail of the distribution. We can use the percent point function ppf, which is the inverse of the cdf function, to obtain the critical values, or, more directly, we can use the inverse of the survival function >>> crit01, crit05, crit10 = stats.t.ppf([1-0.01, 1-0.05, 1-0.10], 10) >>> print ’critical values from ppf at 1%%, 5%% and 10%% %8.4f %8.4f %8.4f’% (crit01, crit05, crit10) critical values from ppf at 1%, 5% and 10% 2.7638 1.8125 1.3722 >>> print ’critical values from isf at 1%%, 5%% and 10%% %8.4f %8.4f %8.4f’% tuple(stats.t.isf([0.01, critical values from isf at 1%, 5% and 10% 2.7638 1.8125 1.3722 >>> freq01 = np.sum(x>crit01) / float(n) * >>> freq05 = np.sum(x>crit05) / float(n) * >>> freq10 = np.sum(x>crit10) / float(n) * >>> print ’sample %%-frequency at 1%%, 5%% sample %-frequency at 1%, 5% and 10% tail 100 100 100 and 10%% tail %8.4f %8.4f %8.4f’% (freq01, freq05, freq10) 1.4000 5.8000 10.5000 In all three cases, our sample has more weight in the top tail than the underlying distribution. We can briefly check a larger sample to see if we get a closer match. In this case the empirical frequency is quite close to the theoretical probability, but if we repeat this several times the fluctuations are still pretty large. >>> freq05l = np.sum(stats.t.rvs(10, size=10000) > crit05) / 10000.0 * 100 >>> print ’larger sample %%-frequency at 5%% tail %8.4f’% freq05l larger sample %-frequency at 5% tail 4.8000 We can also compare it with the tail of the normal distribution, which has less weight in the tails: 1.13. Statistics (scipy.stats) 87 SciPy Reference Guide, Release 0.13.0 >>> print ’tail prob. of normal at 1%%, 5%% and 10%% %8.4f %8.4f %8.4f’% \ ... tuple(stats.norm.sf([crit01, crit05, crit10])*100) tail prob. of normal at 1%, 5% and 10% 0.2857 3.4957 8.5003 The chisquare test can be used to test, whether for a finite number of bins, the observed frequencies differ significantly from the probabilites of the hypothesized distribution. >>> quantiles = [0.0, 0.01, 0.05, 0.1, 1-0.10, 1-0.05, 1-0.01, 1.0] >>> crit = stats.t.ppf(quantiles, 10) >>> print crit [ -Inf -2.76376946 -1.81246112 -1.37218364 1.37218364 1.81246112 2.76376946 Inf] >>> n_sample = x.size >>> freqcount = np.histogram(x, bins=crit)[0] >>> tprob = np.diff(quantiles) >>> nprob = np.diff(stats.norm.cdf(crit)) >>> tch, tpval = stats.chisquare(freqcount, tprob*n_sample) >>> nch, npval = stats.chisquare(freqcount, nprob*n_sample) >>> print ’chisquare for t: chi2 = %6.3f pvalue = %6.4f’ % (tch, tpval) chisquare for t: chi2 = 2.300 pvalue = 0.8901 >>> print ’chisquare for normal: chi2 = %6.3f pvalue = %6.4f’ % (nch, npval) chisquare for normal: chi2 = 64.605 pvalue = 0.0000 We see that the standard normal distribution is clearly rejected while the standard t-distribution cannot be rejected. Since the variance of our sample differs from both standard distribution, we can again redo the test taking the estimate for scale and location into account. The fit method of the distributions can be used to estimate the parameters of the distribution, and the test is repeated using probabilites of the estimated distribution. >>> tdof, tloc, tscale = stats.t.fit(x) >>> nloc, nscale = stats.norm.fit(x) >>> tprob = np.diff(stats.t.cdf(crit, tdof, loc=tloc, scale=tscale)) >>> nprob = np.diff(stats.norm.cdf(crit, loc=nloc, scale=nscale)) >>> tch, tpval = stats.chisquare(freqcount, tprob*n_sample) >>> nch, npval = stats.chisquare(freqcount, nprob*n_sample) >>> print ’chisquare for t: chi2 = %6.3f pvalue = %6.4f’ % (tch, tpval) chisquare for t: chi2 = 1.577 pvalue = 0.9542 >>> print ’chisquare for normal: chi2 = %6.3f pvalue = %6.4f’ % (nch, npval) chisquare for normal: chi2 = 11.084 pvalue = 0.0858 Taking account of the estimated parameters, we can still reject the hypothesis that our sample came from a normal distribution (at the 5% level), but again, with a p-value of 0.95, we cannot reject the t distribution. Special tests for normal distributions Since the normal distribution is the most common distribution in statistics, there are several additional functions available to test whether a sample could have been drawn from a normal distribution First we can test if skew and kurtosis of our sample differ significantly from those of a normal distribution: >>> print ’normal skewtest teststat = %6.3f pvalue = %6.4f’ % stats.skewtest(x) normal skewtest teststat = 2.785 pvalue = 0.0054 >>> print ’normal kurtosistest teststat = %6.3f pvalue = %6.4f’ % stats.kurtosistest(x) normal kurtosistest teststat = 4.757 pvalue = 0.0000 These two tests are combined in the normality test 88 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 >>> print ’normaltest teststat = %6.3f pvalue = %6.4f’ % stats.normaltest(x) normaltest teststat = 30.379 pvalue = 0.0000 In all three tests the p-values are very low and we can reject the hypothesis that the our sample has skew and kurtosis of the normal distribution. Since skew and kurtosis of our sample are based on central moments, we get exactly the same results if we test the standardized sample: >>> print ’normaltest teststat = %6.3f pvalue = %6.4f’ % \ ... stats.normaltest((x-x.mean())/x.std()) normaltest teststat = 30.379 pvalue = 0.0000 Because normality is rejected so strongly, we can check whether the normaltest gives reasonable results for other cases: >>> print ’normaltest teststat = %6.3f pvalue = %6.4f’ % stats.normaltest(stats.t.rvs(10, size=100)) normaltest teststat = 4.698 pvalue = 0.0955 >>> print ’normaltest teststat = %6.3f pvalue = %6.4f’ % stats.normaltest(stats.norm.rvs(size=1000)) normaltest teststat = 0.613 pvalue = 0.7361 When testing for normality of a small sample of t-distributed observations and a large sample of normal distributed observation, then in neither case can we reject the null hypothesis that the sample comes from a normal distribution. In the first case this is because the test is not powerful enough to distinguish a t and a normally distributed random variable in a small sample. 1.13.5 Comparing two samples In the following, we are given two samples, which can come either from the same or from different distribution, and we want to test whether these samples have the same statistical properties. Comparing means Test with sample with identical means: >>> rvs1 = stats.norm.rvs(loc=5, scale=10, size=500) >>> rvs2 = stats.norm.rvs(loc=5, scale=10, size=500) >>> stats.ttest_ind(rvs1, rvs2) (-0.54890361750888583, 0.5831943748663857) Test with sample with different means: >>> rvs3 = stats.norm.rvs(loc=8, scale=10, size=500) >>> stats.ttest_ind(rvs1, rvs3) (-4.5334142901750321, 6.507128186505895e-006) Kolmogorov-Smirnov test for two samples ks_2samp For the example where both samples are drawn from the same distribution, we cannot reject the null hypothesis since the pvalue is high >>> stats.ks_2samp(rvs1, rvs2) (0.025999999999999995, 0.99541195173064878) In the second example, with different location, i.e. means, we can reject the null hypothesis since the pvalue is below 1% 1.13. Statistics (scipy.stats) 89 SciPy Reference Guide, Release 0.13.0 >>> stats.ks_2samp(rvs1, rvs3) (0.11399999999999999, 0.0027132103661283141) 1.13.6 Kernel Density Estimation A common task in statistics is to estimate the probability density function (PDF) of a random variable from a set of data samples. This task is called density estimation. The most well-known tool to do this is the histogram. A histogram is a useful tool for visualization (mainly because everyone understands it), but doesn’t use the available data very efficiently. Kernel density estimation (KDE) is a more efficient tool for the same task. The gaussian_kde estimator can be used to estimate the PDF of univariate as well as multivariate data. It works best if the data is unimodal. Univariate estimation We start with a minimal amount of data in order to see how gaussian_kde works, and what the different options for bandwidth selection do. The data sampled from the PDF is show as blue dashes at the bottom of the figure (this is called a rug plot): >>> from scipy import stats >>> import matplotlib.pyplot as plt >>> x1 = np.array([-7, -5, 1, 4, 5], dtype=np.float) >>> kde1 = stats.gaussian_kde(x1) >>> kde2 = stats.gaussian_kde(x1, bw_method=’silverman’) >>> fig = plt.figure() >>> ax = fig.add_subplot(111) >>> >>> >>> >>> ax.plot(x1, np.zeros(x1.shape), ’b+’, ms=20) # rug plot x_eval = np.linspace(-10, 10, num=200) ax.plot(x_eval, kde1(x_eval), ’k-’, label="Scott’s Rule") ax.plot(x_eval, kde1(x_eval), ’r-’, label="Silverman’s Rule") >>> plt.show() 0.06 0.05 0.04 0.03 0.02 0.01 0.00 10 90 5 0 5 10 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 We see that there is very little difference between Scott’s Rule and Silverman’s Rule, and that the bandwidth selection with a limited amount of data is probably a bit too wide. We can define our own bandwidth function to get a less smoothed out result. >>> def my_kde_bandwidth(obj, fac=1./5): ... """We use Scott’s Rule, multiplied by a constant factor.""" ... return np.power(obj.n, -1./(obj.d+4)) * fac >>> fig = plt.figure() >>> ax = fig.add_subplot(111) >>> ax.plot(x1, np.zeros(x1.shape), ’b+’, ms=20) # rug plot >>> kde3 = stats.gaussian_kde(x1, bw_method=my_kde_bandwidth) >>> ax.plot(x_eval, kde3(x_eval), ’g-’, label="With smaller BW") >>> plt.show() 0.18 0.16 0.14 0.12 0.10 0.08 0.06 0.04 0.02 0.00 10 5 0 5 10 We see that if we set bandwidth to be very narrow, the obtained estimate for the probability density function (PDF) is simply the sum of Gaussians around each data point. We now take a more realistic example, and look at the difference between the two available bandwidth selection rules. Those rules are known to work well for (close to) normal distributions, but even for unimodal distributions that are quite strongly non-normal they work reasonably well. As a non-normal distribution we take a Student’s T distribution with 5 degrees of freedom. import numpy as np import matplotlib.pyplot as plt from scipy import stats np.random.seed(12456) x1 = np.random.normal(size=200) # random data, normal distribution xs = np.linspace(x1.min()-1, x1.max()+1, 200) kde1 = stats.gaussian_kde(x1) kde2 = stats.gaussian_kde(x1, bw_method=’silverman’) fig = plt.figure(figsize=(8, 6)) 1.13. Statistics (scipy.stats) 91 SciPy Reference Guide, Release 0.13.0 ax1 = fig.add_subplot(211) ax1.plot(x1, np.zeros(x1.shape), ’b+’, ms=12) # rug plot ax1.plot(xs, kde1(xs), ’k-’, label="Scott’s Rule") ax1.plot(xs, kde2(xs), ’b-’, label="Silverman’s Rule") ax1.plot(xs, stats.norm.pdf(xs), ’r--’, label="True PDF") ax1.set_xlabel(’x’) ax1.set_ylabel(’Density’) ax1.set_title("Normal (top) and Student’s T$_{df=5}$ (bottom) distributions") ax1.legend(loc=1) x2 = stats.t.rvs(5, size=200) # random data, T distribution xs = np.linspace(x2.min() - 1, x2.max() + 1, 200) kde3 = stats.gaussian_kde(x2) kde4 = stats.gaussian_kde(x2, bw_method=’silverman’) ax2 = fig.add_subplot(212) ax2.plot(x2, np.zeros(x2.shape), ’b+’, ms=12) # rug plot ax2.plot(xs, kde3(xs), ’k-’, label="Scott’s Rule") ax2.plot(xs, kde4(xs), ’b-’, label="Silverman’s Rule") ax2.plot(xs, stats.t.pdf(xs, 5), ’r--’, label="True PDF") ax2.set_xlabel(’x’) ax2.set_ylabel(’Density’) plt.show() 92 Chapter 1. SciPy Tutorial Density Density SciPy Reference Guide, Release 0.13.0 0.40 0.35 0.30 0.25 0.20 0.15 0.10 0.05 0.00 5 0.40 0.35 0.30 0.25 0.20 0.15 0.10 0.05 0.00 6 Normal (top) and Student's Tdf =5 (bottom) distributions Scott's Rule Silverman's Rule True PDF 4 3 4 2 2 1 x 0 0 x 1 2 2 3 4 4 6 We now take a look at a bimodal distribution with one wider and one narrower Gaussian feature. We expect that this will be a more difficult density to approximate, due to the different bandwidths required to accurately resolve each feature. >>> from functools import partial >>> loc1, scale1, size1 = (-2, 1, 175) >>> loc2, scale2, size2 = (2, 0.2, 50) >>> x2 = np.concatenate([np.random.normal(loc=loc1, scale=scale1, size=size1), ... np.random.normal(loc=loc2, scale=scale2, size=size2)]) >>> x_eval = np.linspace(x2.min() - 1, x2.max() + 1, 500) >>> >>> >>> >>> kde = stats.gaussian_kde(x2) kde2 = stats.gaussian_kde(x2, bw_method=’silverman’) kde3 = stats.gaussian_kde(x2, bw_method=partial(my_kde_bandwidth, fac=0.2)) kde4 = stats.gaussian_kde(x2, bw_method=partial(my_kde_bandwidth, fac=0.5)) >>> pdf = stats.norm.pdf >>> bimodal_pdf = pdf(x_eval, loc=loc1, scale=scale1) * float(size1) / x2.size + \ ... pdf(x_eval, loc=loc2, scale=scale2) * float(size2) / x2.size >>> fig = plt.figure(figsize=(8, 6)) >>> ax = fig.add_subplot(111) 1.13. Statistics (scipy.stats) 93 SciPy Reference Guide, Release 0.13.0 >>> >>> >>> >>> >>> >>> ax.plot(x2, np.zeros(x2.shape), ’b+’, ms=12) ax.plot(x_eval, kde(x_eval), ’k-’, label="Scott’s Rule") ax.plot(x_eval, kde2(x_eval), ’b-’, label="Silverman’s Rule") ax.plot(x_eval, kde3(x_eval), ’g-’, label="Scott * 0.2") ax.plot(x_eval, kde4(x_eval), ’c-’, label="Scott * 0.5") ax.plot(x_eval, bimodal_pdf, ’r--’, label="Actual PDF") >>> >>> >>> >>> >>> ax.set_xlim([x_eval.min(), x_eval.max()]) ax.legend(loc=2) ax.set_xlabel(’x’) ax.set_ylabel(’Density’) plt.show() 0.5 0.4 Scott's Rule Silverman's Rule Scott * 0.2 Scott * 0.5 Actual PDF Density 0.3 0.2 0.1 0.0 4 2 x 0 2 As expected, the KDE is not as close to the true PDF as we would like due to the different characteristic size of the two features of the bimodal distribution. By halving the default bandwidth (Scott * 0.5) we can do somewhat better, while using a factor 5 smaller bandwidth than the default doesn’t smooth enough. What we really need though in this case is a non-uniform (adaptive) bandwidth. Multivariate estimation With gaussian_kde we can perform multivariate as well as univariate estimation. We demonstrate the bivariate case. First we generate some random data with a model in which the two variates are correlated. >>> def measure(n): ... """Measurement model, return two coupled measurements.""" 94 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 ... ... ... >>> >>> >>> >>> >>> m1 = np.random.normal(size=n) m2 = np.random.normal(scale=0.5, size=n) return m1+m2, m1-m2 m1, m2 xmin = xmax = ymin = ymax = = measure(2000) m1.min() m1.max() m2.min() m2.max() Then we apply the KDE to the data: >>> >>> >>> >>> >>> X, Y = np.mgrid[xmin:xmax:100j, ymin:ymax:100j] positions = np.vstack([X.ravel(), Y.ravel()]) values = np.vstack([m1, m2]) kernel = stats.gaussian_kde(values) Z = np.reshape(kernel.evaluate(positions).T, X.shape) Finally we plot the estimated bivariate distribution as a colormap, and plot the individual data points on top. >>> fig = plt.figure(figsize=(8, 6)) >>> ax = fig.add_subplot(111) >>> ax.imshow(np.rot90(Z), cmap=plt.cm.gist_earth_r, ... extent=[xmin, xmax, ymin, ymax]) >>> ax.plot(m1, m2, ’k.’, markersize=2) >>> ax.set_xlim([xmin, xmax]) >>> ax.set_ylim([ymin, ymax]) >>> plt.show() 1.13. Statistics (scipy.stats) 95 SciPy Reference Guide, Release 0.13.0 3 2 1 0 1 2 3 4 4 3 2 1 0 1 2 3 1.14 Multidimensional image processing (scipy.ndimage) 1.14.1 Introduction Image processing and analysis are generally seen as operations on two-dimensional arrays of values. There are however a number of fields where images of higher dimensionality must be analyzed. Good examples of these are medical imaging and biological imaging. numpy is suited very well for this type of applications due its inherent multidimensional nature. The scipy.ndimage packages provides a number of general image processing and analysis functions that are designed to operate with arrays of arbitrary dimensionality. The packages currently includes functions for linear and non-linear filtering, binary morphology, B-spline interpolation, and object measurements. 1.14.2 Properties shared by all functions All functions share some common properties. Notably, all functions allow the specification of an output array with the output argument. With this argument you can specify an array that will be changed in-place with the result with the operation. In this case the result is not returned. Usually, using the output argument is more efficient, since an existing array is used to store the result. The type of arrays returned is dependent on the type of operation, but it is in most cases equal to the type of the input. If, however, the output argument is used, the type of the result is equal to the type of the specified output argument. 96 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 If no output argument is given, it is still possible to specify what the result of the output should be. This is done by simply assigning the desired numpy type object to the output argument. For example: >>> correlate(np.arange(10), [1, 2.5]) array([ 0, 2, 6, 9, 13, 16, 20, 23, 27, 30]) >>> correlate(np.arange(10), [1, 2.5], output=np.float64) array([ 0. , 2.5, 6. , 9.5, 13. , 16.5, 20. , 23.5, 27. , 30.5]) 1.14.3 Filter functions The functions described in this section all perform some type of spatial filtering of the the input array: the elements in the output are some function of the values in the neighborhood of the corresponding input element. We refer to this neighborhood of elements as the filter kernel, which is often rectangular in shape but may also have an arbitrary footprint. Many of the functions described below allow you to define the footprint of the kernel, by passing a mask through the footprint parameter. For example a cross shaped kernel can be defined as follows: >>> footprint >>> footprint array([[0, 1, [1, 1, [0, 1, = array([[0,1,0],[1,1,1],[0,1,0]]) 0], 1], 0]]) Usually the origin of the kernel is at the center calculated by dividing the dimensions of the kernel shape by two. For instance, the origin of a one-dimensional kernel of length three is at the second element. Take for example the correlation of a one-dimensional array with a filter of length 3 consisting of ones: >>> a = [0, 0, 0, 1, 0, 0, 0] >>> correlate1d(a, [1, 1, 1]) array([0, 0, 1, 1, 1, 0, 0]) Sometimes it is convenient to choose a different origin for the kernel. For this reason most functions support the origin parameter which gives the origin of the filter relative to its center. For example: >>> a = [0, 0, 0, 1, 0, 0, 0] >>> correlate1d(a, [1, 1, 1], origin = -1) array([0 1 1 1 0 0 0]) The effect is a shift of the result towards the left. This feature will not be needed very often, but it may be useful especially for filters that have an even size. A good example is the calculation of backward and forward differences: >>> a = [0, 0, 1, 1, 1, 0, 0] >>> correlate1d(a, [-1, 1]) array([ 0 0 1 0 0 -1 0]) >>> correlate1d(a, [-1, 1], origin = -1) array([ 0 1 0 0 -1 0 0]) # backward difference # forward difference We could also have calculated the forward difference as follows: >>> correlate1d(a, [0, -1, 1]) array([ 0 1 0 0 -1 0 0]) However, using the origin parameter instead of a larger kernel is more efficient. For multidimensional kernels origin can be a number, in which case the origin is assumed to be equal along all axes, or a sequence giving the origin along each axis. Since the output elements are a function of elements in the neighborhood of the input elements, the borders of the array need to be dealt with appropriately by providing the values outside the borders. This is done by assuming that the arrays are extended beyond their boundaries according certain boundary conditions. In the functions described 1.14. Multidimensional image processing (scipy.ndimage) 97 SciPy Reference Guide, Release 0.13.0 below, the boundary conditions can be selected using the mode parameter which must be a string with the name of the boundary condition. Following boundary conditions are currently supported: “nearest” “wrap” “reflect” “constant” Use the value at the boundary Periodically replicate the array Reflect the array at the boundary Use a constant value, default is 0.0 [1 2 3]->[1 1 2 3 3] [1 2 3]->[3 1 2 3 1] [1 2 3]->[1 1 2 3 3] [1 2 3]->[0 1 2 3 0] The “constant” mode is special since it needs an additional parameter to specify the constant value that should be used. Note: The easiest way to implement such boundary conditions would be to copy the data to a larger array and extend the data at the borders according to the boundary conditions. For large arrays and large filter kernels, this would be very memory consuming, and the functions described below therefore use a different approach that does not require allocating large temporary buffers. Correlation and convolution The correlate1d function calculates a one-dimensional correlation along the given axis. The lines of the array along the given axis are correlated with the given weights. The weights parameter must be a one-dimensional sequences of numbers. The function correlate implements multidimensional correlation of the input array with a given kernel. The convolve1d function calculates a one-dimensional convolution along the given axis. The lines of the array along the given axis are convoluted with the given weights. The weights parameter must be a onedimensional sequences of numbers. Note: A convolution is essentially a correlation after mirroring the kernel. As a result, the origin parameter behaves differently than in the case of a correlation: the result is shifted in the opposite directions. The function convolve implements multidimensional convolution of the input array with a given kernel. Note: A convolution is essentially a correlation after mirroring the kernel. As a result, the origin parameter behaves differently than in the case of a correlation: the results is shifted in the opposite direction. Smoothing filters The gaussian_filter1d function implements a one-dimensional Gaussian filter. The standard-deviation of the Gaussian filter is passed through the parameter sigma. Setting order = 0 corresponds to convolution with a Gaussian kernel. An order of 1, 2, or 3 corresponds to convolution with the first, second or third derivatives of a Gaussian. Higher order derivatives are not implemented. The gaussian_filter function implements a multidimensional Gaussian filter. The standard-deviations of the Gaussian filter along each axis are passed through the parameter sigma as a sequence or numbers. If sigma is not a sequence but a single number, the standard deviation of the filter is equal along all directions. The order of the filter can be specified separately for each axis. An order of 0 corresponds to convolution with a Gaussian kernel. An order of 1, 2, or 3 corresponds to convolution with the first, second or third derivatives of a Gaussian. Higher order derivatives are not implemented. The order parameter must be a number, to specify the same order for all axes, or a sequence of numbers to specify a different order for each axis. Note: The multidimensional filter is implemented as a sequence of one-dimensional Gaussian filters. The intermediate arrays are stored in the same data type as the output. Therefore, for output types with a lower precision, the results may be imprecise because intermediate results may be stored with insufficient precision. This can be prevented by specifying a more precise output type. 98 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 The uniform_filter1d function calculates a one-dimensional uniform filter of the given size along the given axis. The uniform_filter implements a multidimensional uniform filter. The sizes of the uniform filter are given for each axis as a sequence of integers by the size parameter. If size is not a sequence, but a single number, the sizes along all axis are assumed to be equal. Note: The multidimensional filter is implemented as a sequence of one-dimensional uniform filters. The intermediate arrays are stored in the same data type as the output. Therefore, for output types with a lower precision, the results may be imprecise because intermediate results may be stored with insufficient precision. This can be prevented by specifying a more precise output type. Filters based on order statistics The minimum_filter1d function calculates a one-dimensional minimum filter of given size along the given axis. The maximum_filter1d function calculates a one-dimensional maximum filter of given size along the given axis. The minimum_filter function calculates a multidimensional minimum filter. Either the sizes of a rectangular kernel or the footprint of the kernel must be provided. The size parameter, if provided, must be a sequence of sizes or a single number in which case the size of the filter is assumed to be equal along each axis. The footprint, if provided, must be an array that defines the shape of the kernel by its non-zero elements. The maximum_filter function calculates a multidimensional maximum filter. Either the sizes of a rectangular kernel or the footprint of the kernel must be provided. The size parameter, if provided, must be a sequence of sizes or a single number in which case the size of the filter is assumed to be equal along each axis. The footprint, if provided, must be an array that defines the shape of the kernel by its non-zero elements. The rank_filter function calculates a multidimensional rank filter. The rank may be less then zero, i.e., rank = -1 indicates the largest element. Either the sizes of a rectangular kernel or the footprint of the kernel must be provided. The size parameter, if provided, must be a sequence of sizes or a single number in which case the size of the filter is assumed to be equal along each axis. The footprint, if provided, must be an array that defines the shape of the kernel by its non-zero elements. The percentile_filter function calculates a multidimensional percentile filter. The percentile may be less then zero, i.e., percentile = -20 equals percentile = 80. Either the sizes of a rectangular kernel or the footprint of the kernel must be provided. The size parameter, if provided, must be a sequence of sizes or a single number in which case the size of the filter is assumed to be equal along each axis. The footprint, if provided, must be an array that defines the shape of the kernel by its non-zero elements. The median_filter function calculates a multidimensional median filter. Either the sizes of a rectangular kernel or the footprint of the kernel must be provided. The size parameter, if provided, must be a sequence of sizes or a single number in which case the size of the filter is assumed to be equal along each axis. The footprint if provided, must be an array that defines the shape of the kernel by its non-zero elements. Derivatives Derivative filters can be constructed in several ways. The function gaussian_filter1d described in Smoothing filters can be used to calculate derivatives along a given axis using the order parameter. Other derivative filters are the Prewitt and Sobel filters: The prewitt function calculates a derivative along the given axis. The sobel function calculates a derivative along the given axis. The Laplace filter is calculated by the sum of the second derivatives along all axes. Thus, different Laplace filters can be constructed using different second derivative functions. Therefore we provide a general function that takes a function argument to calculate the second derivative along a given direction and to construct the Laplace filter: 1.14. Multidimensional image processing (scipy.ndimage) 99 SciPy Reference Guide, Release 0.13.0 The function generic_laplace calculates a laplace filter using the function passed through derivative2 to calculate second derivatives. The function derivative2 should have the following signature: derivative2(input, axis, output, mode, cval, *extra_arguments, **extra_keywords) It should calculate the second derivative along the dimension axis. If output is not None it should use that for the output and return None, otherwise it should return the result. mode, cval have the usual meaning. The extra_arguments and extra_keywords arguments can be used to pass a tuple of extra arguments and a dictionary of named arguments that are passed to derivative2 at each call. For example: >>> def d2(input, axis, output, mode, cval): ... return correlate1d(input, [1, -2, 1], axis, output, mode, cval, 0) ... >>> a = zeros((5, 5)) >>> a[2, 2] = 1 >>> generic_laplace(a, d2) array([[ 0., 0., 0., 0., 0.], [ 0., 0., 1., 0., 0.], [ 0., 1., -4., 1., 0.], [ 0., 0., 1., 0., 0.], [ 0., 0., 0., 0., 0.]]) To demonstrate the use of the extra_arguments argument we could do: >>> def d2(input, axis, output, mode, cval, weights): ... return correlate1d(input, weights, axis, output, mode, cval, 0,) ... >>> a = zeros((5, 5)) >>> a[2, 2] = 1 >>> generic_laplace(a, d2, extra_arguments = ([1, -2, 1],)) array([[ 0., 0., 0., 0., 0.], [ 0., 0., 1., 0., 0.], [ 0., 1., -4., 1., 0.], [ 0., 0., 1., 0., 0.], [ 0., 0., 0., 0., 0.]]) or: >>> generic_laplace(a, d2, extra_keywords = {’weights’: [1, -2, 1]}) array([[ 0., 0., 0., 0., 0.], [ 0., 0., 1., 0., 0.], [ 0., 1., -4., 1., 0.], [ 0., 0., 1., 0., 0.], [ 0., 0., 0., 0., 0.]]) The following two functions are implemented using generic_laplace by providing appropriate functions for the second derivative function: The function laplace calculates the Laplace using discrete differentiation for the second derivative (i.e. convolution with [1, -2, 1]). The function gaussian_laplace calculates the Laplace using gaussian_filter to calculate the second derivatives. The standard-deviations of the Gaussian filter along each axis are passed through the parameter sigma as a sequence or numbers. If sigma is not a sequence but a single number, the standard deviation of the filter is equal along all directions. The gradient magnitude is defined as the square root of the sum of the squares of the gradients in all directions. Similar to the generic Laplace function there is a generic_gradient_magnitude function that calculated the gradient magnitude of an array: The function generic_gradient_magnitude calculates a gradient magnitude using the function passed through derivative to calculate first derivatives. The function derivative should have the following 100 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 signature: derivative(input, axis, output, mode, cval, *extra_arguments, **extra_keywords) It should calculate the derivative along the dimension axis. If output is not None it should use that for the output and return None, otherwise it should return the result. mode, cval have the usual meaning. The extra_arguments and extra_keywords arguments can be used to pass a tuple of extra arguments and a dictionary of named arguments that are passed to derivative at each call. For example, the sobel function fits the required signature: >>> a = zeros((5, 5)) >>> a[2, 2] = 1 >>> generic_gradient_magnitude(a, sobel) array([[ 0. , 0. , 0. [ 0. , 1.41421356, 2. [ 0. , 2. , 0. [ 0. , 1.41421356, 2. [ 0. , 0. , 0. , , , , , 0. , 1.41421356, 2. , 1.41421356, 0. , 0. 0. 0. 0. 0. ], ], ], ], ]]) See the documentation of generic_laplace for examples of using the extra_arguments and extra_keywords arguments. The sobel and prewitt functions fit the required signature and can therefore directly be used with generic_gradient_magnitude. The following function implements the gradient magnitude using Gaussian derivatives: The function gaussian_gradient_magnitude calculates the gradient magnitude using gaussian_filter to calculate the first derivatives. The standard-deviations of the Gaussian filter along each axis are passed through the parameter sigma as a sequence or numbers. If sigma is not a sequence but a single number, the standard deviation of the filter is equal along all directions. Generic filter functions To implement filter functions, generic functions can be used that accept a callable object that implements the filtering operation. The iteration over the input and output arrays is handled by these generic functions, along with such details as the implementation of the boundary conditions. Only a callable object implementing a callback function that does the actual filtering work must be provided. The callback function can also be written in C and passed using a PyCObject (see Extending ndimage in C for more information). The generic_filter1d function implements a generic one-dimensional filter function, where the actual filtering operation must be supplied as a python function (or other callable object). The generic_filter1d function iterates over the lines of an array and calls function at each line. The arguments that are passed to function are one-dimensional arrays of the tFloat64 type. The first contains the values of the current line. It is extended at the beginning end the end, according to the filter_size and origin arguments. The second array should be modified in-place to provide the output values of the line. For example consider a correlation along one dimension: >>> a = arange(12).reshape(3,4) >>> correlate1d(a, [1, 2, 3]) array([[ 3, 8, 14, 17], [27, 32, 38, 41], [51, 56, 62, 65]]) The same operation can be implemented using generic_filter1d as follows: >>> def fnc(iline, oline): ... oline[...] = iline[:-2] + 2 * iline[1:-1] + 3 * iline[2:] ... >>> generic_filter1d(a, fnc, 3) array([[ 3, 8, 14, 17], 1.14. Multidimensional image processing (scipy.ndimage) 101 SciPy Reference Guide, Release 0.13.0 [27, 32, 38, 41], [51, 56, 62, 65]]) Here the origin of the kernel was (by default) assumed to be in the middle of the filter of length 3. Therefore, each input line was extended by one value at the beginning and at the end, before the function was called. Optionally extra arguments can be defined and passed to the filter function. The extra_arguments and extra_keywords arguments can be used to pass a tuple of extra arguments and/or a dictionary of named arguments that are passed to derivative at each call. For example, we can pass the parameters of our filter as an argument: >>> def fnc(iline, oline, a, b): ... oline[...] = iline[:-2] + a * iline[1:-1] + b * iline[2:] ... >>> generic_filter1d(a, fnc, 3, extra_arguments = (2, 3)) array([[ 3, 8, 14, 17], [27, 32, 38, 41], [51, 56, 62, 65]]) or: >>> generic_filter1d(a, fnc, 3, extra_keywords = {’a’:2, ’b’:3}) array([[ 3, 8, 14, 17], [27, 32, 38, 41], [51, 56, 62, 65]]) The generic_filter function implements a generic filter function, where the actual filtering operation must be supplied as a python function (or other callable object). The generic_filter function iterates over the array and calls function at each element. The argument of function is a one-dimensional array of the tFloat64 type, that contains the values around the current element that are within the footprint of the filter. The function should return a single value that can be converted to a double precision number. For example consider a correlation: >>> a = arange(12).reshape(3,4) >>> correlate(a, [[1, 0], [0, 3]]) array([[ 0, 3, 7, 11], [12, 15, 19, 23], [28, 31, 35, 39]]) The same operation can be implemented using generic_filter as follows: >>> def fnc(buffer): ... return (buffer * array([1, 3])).sum() ... >>> generic_filter(a, fnc, footprint = [[1, 0], [0, 1]]) array([[ 0 3 7 11], [12 15 19 23], [28 31 35 39]]) Here a kernel footprint was specified that contains only two elements. Therefore the filter function receives a buffer of length equal to two, which was multiplied with the proper weights and the result summed. When calling generic_filter, either the sizes of a rectangular kernel or the footprint of the kernel must be provided. The size parameter, if provided, must be a sequence of sizes or a single number in which case the size of the filter is assumed to be equal along each axis. The footprint, if provided, must be an array that defines the shape of the kernel by its non-zero elements. Optionally extra arguments can be defined and passed to the filter function. The extra_arguments and extra_keywords arguments can be used to pass a tuple of extra arguments and/or a dictionary of named arguments that are passed to derivative at each call. For example, we can pass the parameters of our filter as an argument: >>> def fnc(buffer, weights): ... weights = asarray(weights) ... return (buffer * weights).sum() ... 102 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 >>> generic_filter(a, fnc, footprint = [[1, 0], [0, 1]], extra_arguments = ([1, 3],)) array([[ 0, 3, 7, 11], [12, 15, 19, 23], [28, 31, 35, 39]]) or: >>> generic_filter(a, fnc, footprint = [[1, 0], [0, 1]], extra_keywords= {’weights’: [1, 3]}) array([[ 0, 3, 7, 11], [12, 15, 19, 23], [28, 31, 35, 39]]) These functions iterate over the lines or elements starting at the last axis, i.e. the last index changes the fastest. This order of iteration is guaranteed for the case that it is important to adapt the filter depending on spatial location. Here is an example of using a class that implements the filter and keeps track of the current coordinates while iterating. It performs the same filter operation as described above for generic_filter, but additionally prints the current coordinates: >>> a = arange(12).reshape(3,4) >>> >>> class fnc_class: ... def __init__(self, shape): ... # store the shape: ... self.shape = shape ... # initialize the coordinates: ... self.coordinates = [0] * len(shape) ... ... def filter(self, buffer): ... result = (buffer * array([1, 3])).sum() ... print self.coordinates ... # calculate the next coordinates: ... axes = range(len(self.shape)) ... axes.reverse() ... for jj in axes: ... if self.coordinates[jj] < self.shape[jj] - 1: ... self.coordinates[jj] += 1 ... break ... else: ... self.coordinates[jj] = 0 ... return result ... >>> fnc = fnc_class(shape = (3,4)) >>> generic_filter(a, fnc.filter, footprint = [[1, 0], [0, 1]]) [0, 0] [0, 1] [0, 2] [0, 3] [1, 0] [1, 1] [1, 2] [1, 3] [2, 0] [2, 1] [2, 2] [2, 3] array([[ 0, 3, 7, 11], [12, 15, 19, 23], [28, 31, 35, 39]]) 1.14. Multidimensional image processing (scipy.ndimage) 103 SciPy Reference Guide, Release 0.13.0 For the generic_filter1d function the same approach works, except that this function does not iterate over the axis that is being filtered. The example for generic_filter1d then becomes this: >>> a = arange(12).reshape(3,4) >>> >>> class fnc1d_class: ... def __init__(self, shape, axis = -1): ... # store the filter axis: ... self.axis = axis ... # store the shape: ... self.shape = shape ... # initialize the coordinates: ... self.coordinates = [0] * len(shape) ... ... def filter(self, iline, oline): ... oline[...] = iline[:-2] + 2 * iline[1:-1] + 3 * iline[2:] ... print self.coordinates ... # calculate the next coordinates: ... axes = range(len(self.shape)) ... # skip the filter axis: ... del axes[self.axis] ... axes.reverse() ... for jj in axes: ... if self.coordinates[jj] < self.shape[jj] - 1: ... self.coordinates[jj] += 1 ... break ... else: ... self.coordinates[jj] = 0 ... >>> fnc = fnc1d_class(shape = (3,4)) >>> generic_filter1d(a, fnc.filter, 3) [0, 0] [1, 0] [2, 0] array([[ 3, 8, 14, 17], [27, 32, 38, 41], [51, 56, 62, 65]]) Fourier domain filters The functions described in this section perform filtering operations in the Fourier domain. Thus, the input array of such a function should be compatible with an inverse Fourier transform function, such as the functions from the numpy.fft module. We therefore have to deal with arrays that may be the result of a real or a complex Fourier transform. In the case of a real Fourier transform only half of the of the symmetric complex transform is stored. Additionally, it needs to be known what the length of the axis was that was transformed by the real fft. The functions described here provide a parameter n that in the case of a real transform must be equal to the length of the real transform axis before transformation. If this parameter is less than zero, it is assumed that the input array was the result of a complex Fourier transform. The parameter axis can be used to indicate along which axis the real transform was executed. The fourier_shift function multiplies the input array with the multidimensional Fourier transform of a shift operation for the given shift. The shift parameter is a sequences of shifts for each dimension, or a single value for all dimensions. The fourier_gaussian function multiplies the input array with the multidimensional Fourier transform of a Gaussian filter with given standard-deviations sigma. The sigma parameter is a sequences of values for each dimension, or a single value for all dimensions. 104 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 The fourier_uniform function multiplies the input array with the multidimensional Fourier transform of a uniform filter with given sizes size. The size parameter is a sequences of values for each dimension, or a single value for all dimensions. The fourier_ellipsoid function multiplies the input array with the multidimensional Fourier transform of a elliptically shaped filter with given sizes size. The size parameter is a sequences of values for each dimension, or a single value for all dimensions. This function is only implemented for dimensions 1, 2, and 3. 1.14.4 Interpolation functions This section describes various interpolation functions that are based on B-spline theory. A good introduction to Bsplines can be found in: M. Unser, “Splines: A Perfect Fit for Signal and Image Processing,” IEEE Signal Processing Magazine, vol. 16, no. 6, pp. 22-38, November 1999. Spline pre-filters Interpolation using splines of an order larger than 1 requires a pre- filtering step. The interpolation functions described in section Interpolation functions apply pre-filtering by calling spline_filter, but they can be instructed not to do this by setting the prefilter keyword equal to False. This is useful if more than one interpolation operation is done on the same array. In this case it is more efficient to do the pre-filtering only once and use a prefiltered array as the input of the interpolation functions. The following two functions implement the pre-filtering: The spline_filter1d function calculates a one-dimensional spline filter along the given axis. An output array can optionally be provided. The order of the spline must be larger then 1 and less than 6. The spline_filter function calculates a multidimensional spline filter. Note: The multidimensional filter is implemented as a sequence of one-dimensional spline filters. The intermediate arrays are stored in the same data type as the output. Therefore, if an output with a limited precision is requested, the results may be imprecise because intermediate results may be stored with insufficient precision. This can be prevented by specifying a output type of high precision. Interpolation functions Following functions all employ spline interpolation to effect some type of geometric transformation of the input array. This requires a mapping of the output coordinates to the input coordinates, and therefore the possibility arises that input values outside the boundaries are needed. This problem is solved in the same way as described in Filter functions for the multidimensional filter functions. Therefore these functions all support a mode parameter that determines how the boundaries are handled, and a cval parameter that gives a constant value in case that the ‘constant’ mode is used. The geometric_transform function applies an arbitrary geometric transform to the input. The given mapping function is called at each point in the output to find the corresponding coordinates in the input. mapping must be a callable object that accepts a tuple of length equal to the output array rank and returns the corresponding input coordinates as a tuple of length equal to the input array rank. The output shape and output type can optionally be provided. If not given they are equal to the input shape and type. For example: >>> a = arange(12).reshape(4,3).astype(np.float64) >>> def shift_func(output_coordinates): ... return (output_coordinates[0] - 0.5, output_coordinates[1] - 0.5) ... >>> geometric_transform(a, shift_func) array([[ 0. , 0. , 0. ], [ 0. , 1.3625, 2.7375], 1.14. Multidimensional image processing (scipy.ndimage) 105 SciPy Reference Guide, Release 0.13.0 [ 0. [ 0. , , 4.8125, 8.2625, 6.1875], 9.6375]]) Optionally extra arguments can be defined and passed to the filter function. The extra_arguments and extra_keywords arguments can be used to pass a tuple of extra arguments and/or a dictionary of named arguments that are passed to derivative at each call. For example, we can pass the shifts in our example as arguments: >>> def shift_func(output_coordinates, s0, s1): ... return (output_coordinates[0] - s0, output_coordinates[1] - s1) ... >>> geometric_transform(a, shift_func, extra_arguments = (0.5, 0.5)) array([[ 0. , 0. , 0. ], [ 0. , 1.3625, 2.7375], [ 0. , 4.8125, 6.1875], [ 0. , 8.2625, 9.6375]]) or: >>> geometric_transform(a, array([[ 0. , 0. , [ 0. , 1.3625, [ 0. , 4.8125, [ 0. , 8.2625, shift_func, extra_keywords = {’s0’: 0.5, ’s1’: 0.5}) 0. ], 2.7375], 6.1875], 9.6375]]) Note: The mapping function can also be written in C and passed using a PyCObject. See Extending ndimage in C for more information. The function map_coordinates applies an arbitrary coordinate transformation using the given array of coordinates. The shape of the output is derived from that of the coordinate array by dropping the first axis. The parameter coordinates is used to find for each point in the output the corresponding coordinates in the input. The values of coordinates along the first axis are the coordinates in the input array at which the output value is found. (See also the numarray coordinates function.) Since the coordinates may be non- integer coordinates, the value of the input at these coordinates is determined by spline interpolation of the requested order. Here is an example that interpolates a 2D array at (0.5, 0.5) and (1, 2): >>> a = arange(12).reshape(4,3).astype(np.float64) >>> a array([[ 0., 1., 2.], [ 3., 4., 5.], [ 6., 7., 8.], [ 9., 10., 11.]]) >>> map_coordinates(a, [[0.5, 2], [0.5, 1]]) array([ 1.3625 7. ]) The affine_transform function applies an affine transformation to the input array. The given transformation matrix and offset are used to find for each point in the output the corresponding coordinates in the input. The value of the input at the calculated coordinates is determined by spline interpolation of the requested order. The transformation matrix must be two-dimensional or can also be given as a one-dimensional sequence or array. In the latter case, it is assumed that the matrix is diagonal. A more efficient interpolation algorithm is then applied that exploits the separability of the problem. The output shape and output type can optionally be provided. If not given they are equal to the input shape and type. The shift function returns a shifted version of the input, using spline interpolation of the requested order. The zoom function returns a rescaled version of the input, using spline interpolation of the requested order. The rotate function returns the input array rotated in the plane defined by the two axes given by the parameter axes, using spline interpolation of the requested order. The angle must be given in degrees. If reshape is true, then the size of the output array is adapted to contain the rotated input. 106 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 1.14.5 Morphology Binary morphology Binary morphology (need something to put here). The generate_binary_structure functions generates a binary structuring element for use in binary morphology operations. The rank of the structure must be provided. The size of the structure that is returned is equal to three in each direction. The value of each element is equal to one if the square of the Euclidean distance from the element to the center is less or equal to connectivity. For instance, two dimensional 4-connected and 8-connected structures are generated as follows: >>> generate_binary_structure(2, 1) array([[False, True, False], [ True, True, True], [False, True, False]], dtype=bool) >>> generate_binary_structure(2, 2) array([[ True, True, True], [ True, True, True], [ True, True, True]], dtype=bool) Most binary morphology functions can be expressed in terms of the basic operations erosion and dilation: The binary_erosion function implements binary erosion of arrays of arbitrary rank with the given structuring element. The origin parameter controls the placement of the structuring element as described in Filter functions. If no structuring element is provided, an element with connectivity equal to one is generated using generate_binary_structure. The border_value parameter gives the value of the array outside boundaries. The erosion is repeated iterations times. If iterations is less than one, the erosion is repeated until the result does not change anymore. If a mask array is given, only those elements with a true value at the corresponding mask element are modified at each iteration. The binary_dilation function implements binary dilation of arrays of arbitrary rank with the given structuring element. The origin parameter controls the placement of the structuring element as described in Filter functions. If no structuring element is provided, an element with connectivity equal to one is generated using generate_binary_structure. The border_value parameter gives the value of the array outside boundaries. The dilation is repeated iterations times. If iterations is less than one, the dilation is repeated until the result does not change anymore. If a mask array is given, only those elements with a true value at the corresponding mask element are modified at each iteration. Here is an example of using binary_dilation to find all elements that touch the border, by repeatedly dilating an empty array from the border using the data array as the mask: >>> struct = array([[0, 1, 0], [1, 1, 1], [0, 1, 0]]) >>> a = array([[1,0,0,0,0], [1,1,0,1,0], [0,0,1,1,0], [0,0,0,0,0]]) >>> a array([[1, 0, 0, 0, 0], [1, 1, 0, 1, 0], [0, 0, 1, 1, 0], [0, 0, 0, 0, 0]]) >>> binary_dilation(zeros(a.shape), struct, -1, a, border_value=1) array([[ True, False, False, False, False], [ True, True, False, False, False], [False, False, False, False, False], [False, False, False, False, False]], dtype=bool) The binary_erosion and binary_dilation functions both have an iterations parameter which allows the erosion or dilation to be repeated a number of times. Repeating an erosion or a dilation with a given structure n times is equivalent to an erosion or a dilation with a structure that is n-1 times dilated with itself. A function is provided that allows the calculation of a structure that is dilated a number of times with itself: 1.14. Multidimensional image processing (scipy.ndimage) 107 SciPy Reference Guide, Release 0.13.0 The iterate_structure function returns a structure by dilation of the input structure iteration - 1 times with itself. For instance: >>> struct = generate_binary_structure(2, 1) >>> struct array([[False, True, False], [ True, True, True], [False, True, False]], dtype=bool) >>> iterate_structure(struct, 2) array([[False, False, True, False, False], [False, True, True, True, False], [ True, True, True, True, True], [False, True, True, True, False], [False, False, True, False, False]], dtype=bool) If the origin of the original structure is equal to 0, then it is also equal to 0 for the iterated structure. If not, the origin must also be adapted if the equivalent of the iterations erosions or dilations must be achieved with the iterated structure. The adapted origin is simply obtained by multiplying with the number of iterations. For convenience the iterate_structure also returns the adapted origin if the origin parameter is not None: >>> iterate_structure(struct, 2, -1) (array([[False, False, True, False, False], [False, True, True, True, False], [ True, True, True, True, True], [False, True, True, True, False], [False, False, True, False, False]], dtype=bool), [-2, -2]) Other morphology operations can be defined in terms of erosion and d dilation. Following functions provide a few of these operations for convenience: The binary_opening function implements binary opening of arrays of arbitrary rank with the given structuring element. Binary opening is equivalent to a binary erosion followed by a binary dilation with the same structuring element. The origin parameter controls the placement of the structuring element as described in Filter functions. If no structuring element is provided, an element with connectivity equal to one is generated using generate_binary_structure. The iterations parameter gives the number of erosions that is performed followed by the same number of dilations. The binary_closing function implements binary closing of arrays of arbitrary rank with the given structuring element. Binary closing is equivalent to a binary dilation followed by a binary erosion with the same structuring element. The origin parameter controls the placement of the structuring element as described in Filter functions. If no structuring element is provided, an element with connectivity equal to one is generated using generate_binary_structure. The iterations parameter gives the number of dilations that is performed followed by the same number of erosions. The binary_fill_holes function is used to close holes in objects in a binary image, where the structure defines the connectivity of the holes. The origin parameter controls the placement of the structuring element as described in Filter functions. If no structuring element is provided, an element with connectivity equal to one is generated using generate_binary_structure. The binary_hit_or_miss function implements a binary hit-or-miss transform of arrays of arbitrary rank with the given structuring elements. The hit-or-miss transform is calculated by erosion of the input with the first structure, erosion of the logical not of the input with the second structure, followed by the logical and of these two erosions. The origin parameters control the placement of the structuring elements as described in Filter functions. If origin2 equals None it is set equal to the origin1 parameter. If the first structuring element is not provided, a structuring element with connectivity equal to one is generated using generate_binary_structure, if structure2 is not provided, it is set equal to the logical not of structure1. 108 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 Grey-scale morphology Grey-scale morphology operations are the equivalents of binary morphology operations that operate on arrays with arbitrary values. Below we describe the grey-scale equivalents of erosion, dilation, opening and closing. These operations are implemented in a similar fashion as the filters described in Filter functions, and we refer to this section for the description of filter kernels and footprints, and the handling of array borders. The grey-scale morphology operations optionally take a structure parameter that gives the values of the structuring element. If this parameter is not given the structuring element is assumed to be flat with a value equal to zero. The shape of the structure can optionally be defined by the footprint parameter. If this parameter is not given, the structure is assumed to be rectangular, with sizes equal to the dimensions of the structure array, or by the size parameter if structure is not given. The size parameter is only used if both structure and footprint are not given, in which case the structuring element is assumed to be rectangular and flat with the dimensions given by size. The size parameter, if provided, must be a sequence of sizes or a single number in which case the size of the filter is assumed to be equal along each axis. The footprint parameter, if provided, must be an array that defines the shape of the kernel by its non-zero elements. Similar to binary erosion and dilation there are operations for grey-scale erosion and dilation: The grey_erosion function calculates a multidimensional grey- scale erosion. The grey_dilation function calculates a multidimensional grey- scale dilation. Grey-scale opening and closing operations can be defined similar to their binary counterparts: The grey_opening function implements grey-scale opening of arrays of arbitrary rank. Grey-scale opening is equivalent to a grey-scale erosion followed by a grey-scale dilation. The grey_closing function implements grey-scale closing of arrays of arbitrary rank. Grey-scale opening is equivalent to a grey-scale dilation followed by a grey-scale erosion. The morphological_gradient function implements a grey-scale morphological gradient of arrays of arbitrary rank. The grey-scale morphological gradient is equal to the difference of a grey-scale dilation and a grey-scale erosion. The morphological_laplace function implements a grey-scale morphological laplace of arrays of arbitrary rank. The grey-scale morphological laplace is equal to the sum of a grey-scale dilation and a grey-scale erosion minus twice the input. The white_tophat function implements a white top-hat filter of arrays of arbitrary rank. The white top-hat is equal to the difference of the input and a grey-scale opening. The black_tophat function implements a black top-hat filter of arrays of arbitrary rank. The black top-hat is equal to the difference of the a grey-scale closing and the input. 1.14.6 Distance transforms Distance transforms are used to calculate the minimum distance from each element of an object to the background. The following functions implement distance transforms for three different distance metrics: Euclidean, City Block, and Chessboard distances. The function distance_transform_cdt uses a chamfer type algorithm to calculate the distance transform of the input, by replacing each object element (defined by values larger than zero) with the shortest distance to the background (all non-object elements). The structure determines the type of chamfering that is done. If the structure is equal to ‘cityblock’ a structure is generated using generate_binary_structure with a squared distance equal to 1. If the structure is equal to ‘chessboard’, a structure is generated using generate_binary_structure with a squared distance equal to the rank of the array. These choices correspond to the common interpretations of the cityblock and the chessboard distancemetrics in two dimensions. In addition to the distance transform, the feature transform can be calculated. In this case the index of the closest background element is returned along the first axis of the result. The return_distances, and return_indices flags can be used to indicate if the distance transform, the feature transform, or both must be returned. The distances and indices arguments can be used to give optional output arrays that must be of the correct size and type (both Int32). 1.14. Multidimensional image processing (scipy.ndimage) 109 SciPy Reference Guide, Release 0.13.0 The basics of the algorithm used to implement this function is described in: G. Borgefors, “Distance transformations in arbitrary dimensions.”, Computer Vision, Graphics, and Image Processing, 27:321-345, 1984. The function distance_transform_edt calculates the exact euclidean distance transform of the input, by replacing each object element (defined by values larger than zero) with the shortest euclidean distance to the background (all non-object elements). In addition to the distance transform, the feature transform can be calculated. In this case the index of the closest background element is returned along the first axis of the result. The return_distances, and return_indices flags can be used to indicate if the distance transform, the feature transform, or both must be returned. Optionally the sampling along each axis can be given by the sampling parameter which should be a sequence of length equal to the input rank, or a single number in which the sampling is assumed to be equal along all axes. The distances and indices arguments can be used to give optional output arrays that must be of the correct size and type (Float64 and Int32). The algorithm used to implement this function is described in: C. R. Maurer, Jr., R. Qi, and V. Raghavan, “A linear time algorithm for computing exact euclidean distance transforms of binary images in arbitrary dimensions. IEEE Trans. PAMI 25, 265-270, 2003. The function distance_transform_bf uses a brute-force algorithm to calculate the distance transform of the input, by replacing each object element (defined by values larger than zero) with the shortest distance to the background (all non-object elements). The metric must be one of “euclidean”, “cityblock”, or “chessboard”. In addition to the distance transform, the feature transform can be calculated. In this case the index of the closest background element is returned along the first axis of the result. The return_distances, and return_indices flags can be used to indicate if the distance transform, the feature transform, or both must be returned. Optionally the sampling along each axis can be given by the sampling parameter which should be a sequence of length equal to the input rank, or a single number in which the sampling is assumed to be equal along all axes. This parameter is only used in the case of the euclidean distance transform. The distances and indices arguments can be used to give optional output arrays that must be of the correct size and type (Float64 and Int32). Note: This function uses a slow brute-force algorithm, the function distance_transform_cdt can be used to more efficiently calculate cityblock and chessboard distance transforms. The function distance_transform_edt can be used to more efficiently calculate the exact euclidean distance transform. 1.14.7 Segmentation and labeling Segmentation is the process of separating objects of interest from the background. The most simple approach is probably intensity thresholding, which is easily done with numpy functions: >>> a = array([[1,2,2,1,1,0], ... [0,2,3,1,2,0], ... [1,1,1,3,3,2], ... [1,1,1,1,2,1]]) >>> where(a > 1, 1, 0) array([[0, 1, 1, 0, 0, 0], [0, 1, 1, 0, 1, 0], [0, 0, 0, 1, 1, 1], [0, 0, 0, 0, 1, 0]]) The result is a binary image, in which the individual objects still need to be identified and labeled. The function label generates an array where each object is assigned a unique number: The label function generates an array where the objects in the input are labeled with an integer index. It returns a tuple consisting of the array of object labels and the number of objects found, unless the output parameter is given, in which case only the number of objects is returned. The connectivity of the objects is defined by a structuring element. For instance, in two dimensions using a four-connected structuring element gives: 110 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 >>> a = array([[0,1,1,0,0,0],[0,1,1,0,1,0],[0,0,0,1,1,1],[0,0,0,0,1,0]]) >>> s = [[0, 1, 0], [1,1,1], [0,1,0]] >>> label(a, s) (array([[0, 1, 1, 0, 0, 0], [0, 1, 1, 0, 2, 0], [0, 0, 0, 2, 2, 2], [0, 0, 0, 0, 2, 0]]), 2) These two objects are not connected because there is no way in which we can place the structuring element such that it overlaps with both objects. However, an 8-connected structuring element results in only a single object: >>> a = array([[0,1,1,0,0,0],[0,1,1,0,1,0],[0,0,0,1,1,1],[0,0,0,0,1,0]]) >>> s = [[1,1,1], [1,1,1], [1,1,1]] >>> label(a, s)[0] array([[0, 1, 1, 0, 0, 0], [0, 1, 1, 0, 1, 0], [0, 0, 0, 1, 1, 1], [0, 0, 0, 0, 1, 0]]) If no structuring element is provided, one is generated by calling generate_binary_structure (see Binary morphology) using a connectivity of one (which in 2D is the 4-connected structure of the first example). The input can be of any type, any value not equal to zero is taken to be part of an object. This is useful if you need to ‘re-label’ an array of object indices, for instance after removing unwanted objects. Just apply the label function again to the index array. For instance: >>> l, n = label([1, 0, 1, 0, 1]) >>> l array([1 0 2 0 3]) >>> l = where(l != 2, l, 0) >>> l array([1 0 0 0 3]) >>> label(l)[0] array([1 0 0 0 2]) Note: The structuring element used by label is assumed to be symmetric. There is a large number of other approaches for segmentation, for instance from an estimation of the borders of the objects that can be obtained for instance by derivative filters. One such an approach is watershed segmentation. The function watershed_ift generates an array where each object is assigned a unique label, from an array that localizes the object borders, generated for instance by a gradient magnitude filter. It uses an array containing initial markers for the objects: The watershed_ift function applies a watershed from markers algorithm, using an Iterative Forest Transform, as described in: P. Felkel, R. Wegenkittl, and M. Bruckschwaiger, “Implementation and Complexity of the Watershed-from-Markers Algorithm Computed as a Minimal Cost Forest.”, Eurographics 2001, pp. C:26-35. The inputs of this function are the array to which the transform is applied, and an array of markers that designate the objects by a unique label, where any non-zero value is a marker. For instance: >>> input = array([[0, 0, 0, 0, 0, 0, 0], ... [0, 1, 1, 1, 1, 1, 0], ... [0, 1, 0, 0, 0, 1, 0], ... [0, 1, 0, 0, 0, 1, 0], ... [0, 1, 0, 0, 0, 1, 0], ... [0, 1, 1, 1, 1, 1, 0], ... [0, 0, 0, 0, 0, 0, 0]], np.uint8) >>> markers = array([[1, 0, 0, 0, 0, 0, 0], ... [0, 0, 0, 0, 0, 0, 0], ... [0, 0, 0, 0, 0, 0, 0], ... [0, 0, 0, 2, 0, 0, 0], 1.14. Multidimensional image processing (scipy.ndimage) 111 SciPy Reference Guide, Release 0.13.0 ... [0, 0, 0, 0, 0, 0, 0], ... [0, 0, 0, 0, 0, 0, 0], ... [0, 0, 0, 0, 0, 0, 0]], np.int8) >>> watershed_ift(input, markers) array([[1, 1, 1, 1, 1, 1, 1], [1, 1, 2, 2, 2, 1, 1], [1, 2, 2, 2, 2, 2, 1], [1, 2, 2, 2, 2, 2, 1], [1, 2, 2, 2, 2, 2, 1], [1, 1, 2, 2, 2, 1, 1], [1, 1, 1, 1, 1, 1, 1]], dtype=int8) Here two markers were used to designate an object (marker = 2) and the background (marker = 1). The order in which these are processed is arbitrary: moving the marker for the background to the lower right corner of the array yields a different result: >>> markers = 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, 2, 0, 0, 0], ... [0, 0, 0, 0, 0, 0, 0], ... [0, 0, 0, 0, 0, 0, 0], ... [0, 0, 0, 0, 0, 0, 1]], np.int8) >>> watershed_ift(input, markers) array([[1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1], [1, 1, 2, 2, 2, 1, 1], [1, 1, 2, 2, 2, 1, 1], [1, 1, 2, 2, 2, 1, 1], [1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1]], dtype=int8) The result is that the object (marker = 2) is smaller because the second marker was processed earlier. This may not be the desired effect if the first marker was supposed to designate a background object. Therefore watershed_ift treats markers with a negative value explicitly as background markers and processes them after the normal markers. For instance, replacing the first marker by a negative marker gives a result similar to the first example: >>> markers = 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, 2, 0, 0, 0], ... [0, 0, 0, 0, 0, 0, 0], ... [0, 0, 0, 0, 0, 0, 0], ... [0, 0, 0, 0, 0, 0, -1]], np.int8) >>> watershed_ift(input, markers) array([[-1, -1, -1, -1, -1, -1, -1], [-1, -1, 2, 2, 2, -1, -1], [-1, 2, 2, 2, 2, 2, -1], [-1, 2, 2, 2, 2, 2, -1], [-1, 2, 2, 2, 2, 2, -1], [-1, -1, 2, 2, 2, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], dtype=int8) The connectivity of the objects is defined by a structuring element. If no structuring element is provided, one is generated by calling generate_binary_structure (see Binary morphology) using a connectivity of one (which in 2D is a 4-connected structure.) For example, using an 8-connected structure with the last example yields a different object: 112 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 >>> watershed_ift(input, markers, ... structure = [[1,1,1], [1,1,1], [1,1,1]]) array([[-1, -1, -1, -1, -1, -1, -1], [-1, 2, 2, 2, 2, 2, -1], [-1, 2, 2, 2, 2, 2, -1], [-1, 2, 2, 2, 2, 2, -1], [-1, 2, 2, 2, 2, 2, -1], [-1, 2, 2, 2, 2, 2, -1], [-1, -1, -1, -1, -1, -1, -1]], dtype=int8) Note: The implementation of watershed_ift limits the data types of the input to UInt8 and UInt16. 1.14.8 Object measurements Given an array of labeled objects, the properties of the individual objects can be measured. The find_objects function can be used to generate a list of slices that for each object, give the smallest sub-array that fully contains the object: The find_objects function finds all objects in a labeled array and returns a list of slices that correspond to the smallest regions in the array that contains the object. For instance: >>> a = array([[0,1,1,0,0,0],[0,1,1,0,1,0],[0,0,0,1,1,1],[0,0,0,0,1,0]]) >>> l, n = label(a) >>> f = find_objects(l) >>> a[f[0]] array([[1 1], [1 1]]) >>> a[f[1]] array([[0, 1, 0], [1, 1, 1], [0, 1, 0]]) find_objects returns slices for all objects, unless the max_label parameter is larger then zero, in which case only the first max_label objects are returned. If an index is missing in the label array, None is return instead of a slice. For example: >>> find_objects([1, 0, 3, 4], max_label = 3) [(slice(0, 1, None),), None, (slice(2, 3, None),)] The list of slices generated by find_objects is useful to find the position and dimensions of the objects in the array, but can also be used to perform measurements on the individual objects. Say we want to find the sum of the intensities of an object in image: >>> >>> >>> >>> image = arange(4 * 6).reshape(4, 6) mask = array([[0,1,1,0,0,0],[0,1,1,0,1,0],[0,0,0,1,1,1],[0,0,0,0,1,0]]) labels = label(mask)[0] slices = find_objects(labels) Then we can calculate the sum of the elements in the second object: >>> where(labels[slices[1]] == 2, image[slices[1]], 0).sum() 80 That is however not particularly efficient, and may also be more complicated for other types of measurements. Therefore a few measurements functions are defined that accept the array of object labels and the index of the object to be measured. For instance calculating the sum of the intensities can be done by: 1.14. Multidimensional image processing (scipy.ndimage) 113 SciPy Reference Guide, Release 0.13.0 >>> sum(image, labels, 2) 80 For large arrays and small objects it is more efficient to call the measurement functions after slicing the array: >>> sum(image[slices[1]], labels[slices[1]], 2) 80 Alternatively, we can do the measurements for a number of labels with a single function call, returning a list of results. For instance, to measure the sum of the values of the background and the second object in our example we give a list of labels: >>> sum(image, labels, [0, 2]) array([178.0, 80.0]) The measurement functions described below all support the index parameter to indicate which object(s) should be measured. The default value of index is None. This indicates that all elements where the label is larger than zero should be treated as a single object and measured. Thus, in this case the labels array is treated as a mask defined by the elements that are larger than zero. If index is a number or a sequence of numbers it gives the labels of the objects that are measured. If index is a sequence, a list of the results is returned. Functions that return more than one result, return their result as a tuple if index is a single number, or as a tuple of lists, if index is a sequence. The sum function calculates the sum of the elements of the object with label(s) given by index, using the labels array for the object labels. If index is None, all elements with a non-zero label value are treated as a single object. If label is None, all elements of input are used in the calculation. The mean function calculates the mean of the elements of the object with label(s) given by index, using the labels array for the object labels. If index is None, all elements with a non-zero label value are treated as a single object. If label is None, all elements of input are used in the calculation. The variance function calculates the variance of the elements of the object with label(s) given by index, using the labels array for the object labels. If index is None, all elements with a non-zero label value are treated as a single object. If label is None, all elements of input are used in the calculation. The standard_deviation function calculates the standard deviation of the elements of the object with label(s) given by index, using the labels array for the object labels. If index is None, all elements with a nonzero label value are treated as a single object. If label is None, all elements of input are used in the calculation. The minimum function calculates the minimum of the elements of the object with label(s) given by index, using the labels array for the object labels. If index is None, all elements with a non-zero label value are treated as a single object. If label is None, all elements of input are used in the calculation. The maximum function calculates the maximum of the elements of the object with label(s) given by index, using the labels array for the object labels. If index is None, all elements with a non-zero label value are treated as a single object. If label is None, all elements of input are used in the calculation. The minimum_position function calculates the position of the minimum of the elements of the object with label(s) given by index, using the labels array for the object labels. If index is None, all elements with a non-zero label value are treated as a single object. If label is None, all elements of input are used in the calculation. The maximum_position function calculates the position of the maximum of the elements of the object with label(s) given by index, using the labels array for the object labels. If index is None, all elements with a non-zero label value are treated as a single object. If label is None, all elements of input are used in the calculation. The extrema function calculates the minimum, the maximum, and their positions, of the elements of the object with label(s) given by index, using the labels array for the object labels. If index is None, all elements with a non-zero label value are treated as a single object. If label is None, all elements of input are used in the calculation. The result is a tuple giving the minimum, the maximum, the position of the minimum and the postition of the maximum. The result is the same as a tuple formed by the results of the functions minimum, maximum, minimum_position, and maximum_position that are described above. The center_of_mass function calculates the center of mass of the of the object with label(s) given by index, using the labels array for the object labels. If index is None, all elements with a non-zero label value are treated as a single object. If label is None, all elements of input are used in the calculation. 114 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 The histogram function calculates a histogram of the of the object with label(s) given by index, using the labels array for the object labels. If index is None, all elements with a non-zero label value are treated as a single object. If label is None, all elements of input are used in the calculation. Histograms are defined by their minimum (min), maximum (max) and the number of bins (bins). They are returned as one-dimensional arrays of type Int32. 1.14.9 Extending ndimage in C A few functions in the scipy.ndimage take a call-back argument. This can be a python function, but also a PyCObject containing a pointer to a C function. To use this feature, you must write your own C extension that defines the function, and define a Python function that returns a PyCObject containing a pointer to this function. An example of a function that supports this is geometric_transform (see Interpolation functions). You can pass it a python callable object that defines a mapping from all output coordinates to corresponding coordinates in the input array. This mapping function can also be a C function, which generally will be much more efficient, since the overhead of calling a python function at each element is avoided. For example to implement a simple shift function we define the following function: static int _shift_function(int *output_coordinates, double* input_coordinates, int output_rank, int input_rank, void *callback_data) { int ii; /* get the shift from the callback data pointer: */ double shift = *(double*)callback_data; /* calculate the coordinates: */ for(ii = 0; ii < irank; ii++) icoor[ii] = ocoor[ii] - shift; /* return OK status: */ return 1; } This function is called at every element of the output array, passing the current coordinates in the output_coordinates array. On return, the input_coordinates array must contain the coordinates at which the input is interpolated. The ranks of the input and output array are passed through output_rank and input_rank. The value of the shift is passed through the callback_data argument, which is a pointer to void. The function returns an error status, in this case always 1, since no error can occur. A pointer to this function and a pointer to the shift value must be passed to geometric_transform. Both are passed by a single PyCObject which is created by the following python extension function: static PyObject * py_shift_function(PyObject *obj, PyObject *args) { double shift = 0.0; if (!PyArg_ParseTuple(args, "d", &shift)) { PyErr_SetString(PyExc_RuntimeError, "invalid parameters"); return NULL; } else { /* assign the shift to a dynamically allocated location: */ double *cdata = (double*)malloc(sizeof(double)); *cdata = shift; /* wrap function and callback_data in a CObject: */ return PyCObject_FromVoidPtrAndDesc(_shift_function, cdata, _destructor); } } 1.14. Multidimensional image processing (scipy.ndimage) 115 SciPy Reference Guide, Release 0.13.0 The value of the shift is obtained and then assigned to a dynamically allocated memory location. Both this data pointer and the function pointer are then wrapped in a PyCObject, which is returned. Additionally, a pointer to a destructor function is given, that will free the memory we allocated for the shift value when the PyCObject is destroyed. This destructor is very simple: static void _destructor(void* cobject, void *cdata) { if (cdata) free(cdata); } To use these functions, an extension module is built: static PyMethodDef methods[] = { {"shift_function", (PyCFunction)py_shift_function, METH_VARARGS, ""}, {NULL, NULL, 0, NULL} }; void initexample(void) { Py_InitModule("example", methods); } This extension can then be used in Python, for example: >>> import example >>> array = arange(12).reshape=(4, 3).astype(np.float64) >>> fnc = example.shift_function(0.5) >>> geometric_transform(array, fnc) array([[ 0. 0. 0. ], [ 0. 1.3625 2.7375], [ 0. 4.8125 6.1875], [ 0. 8.2625 9.6375]]) C callback functions for use with ndimage functions must all be written according to this scheme. The next section lists the ndimage functions that acccept a C callback function and gives the prototype of the callback function. 1.14.10 Functions that support C callback functions The ndimage functions that support C callback functions are described here. Obviously, the prototype of the function that is provided to these functions must match exactly that what they expect. Therefore we give here the prototypes of the callback functions. All these callback functions accept a void callback_data pointer that must be wrapped in a PyCObject using the Python PyCObject_FromVoidPtrAndDesc function, which can also accept a pointer to a destructor function to free any memory allocated for callback_data. If callback_data is not needed, PyCObject_FromVoidPtr may be used instead. The callback functions must return an integer error status that is equal to zero if something went wrong, or 1 otherwise. If an error occurs, you should normally set the python error status with an informative message before returning, otherwise, a default error message is set by the calling function. The function generic_filter (see Generic filter functions) accepts a callback function with the following prototype: The calling function iterates over the elements of the input and output arrays, calling the callback function at each element. The elements within the footprint of the filter at the current element are passed through the buffer parameter, and the number of elements within the footprint through filter_size. The calculated valued should be returned in the return_value argument. 116 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 The function generic_filter1d (see Generic filter functions) accepts a callback function with the following prototype: The calling function iterates over the lines of the input and output arrays, calling the callback function at each line. The current line is extended according to the border conditions set by the calling function, and the result is copied into the array that is passed through the input_line array. The length of the input line (after extension) is passed through input_length. The callback function should apply the 1D filter and store the result in the array passed through output_line. The length of the output line is passed through output_length. The function geometric_transform (see Interpolation functions) expects a function with the following prototype: The calling function iterates over the elements of the output array, calling the callback function at each element. The coordinates of the current output element are passed through output_coordinates. The callback function must return the coordinates at which the input must be interpolated in input_coordinates. The rank of the input and output arrays are given by input_rank and output_rank respectively. 1.15 File IO (scipy.io) See Also numpy-reference.routines.io (in numpy) 1.15.1 MATLAB files loadmat(file_name[, mdict, appendmat]) savemat(file_name, mdict[, appendmat, ...]) whosmat(file_name[, appendmat]) Load MATLAB file Save a dictionary of names and arrays into a MATLAB-style .mat file. List variables inside a MATLAB file The basic functions We’ll start by importing scipy.io and calling it sio for convenience: >>> import scipy.io as sio If you are using IPython, try tab completing on sio. Among the many options, you will find: sio.loadmat sio.savemat sio.whosmat These are the high-level functions you will most likely use when working with MATLAB files. You’ll also find: sio.matlab This is the package from which loadmat, savemat and whosmat are imported. Within sio.matlab, you will find the mio module This module contains the machinery that loadmat and savemat use. From time to time you may find yourself re-using this machinery. How do I start? You may have a .mat file that you want to read into Scipy. Or, you want to pass some variables from Scipy / Numpy into MATLAB. 1.15. File IO (scipy.io) 117 SciPy Reference Guide, Release 0.13.0 To save us using a MATLAB license, let’s start in Octave. Octave has MATLAB-compatible save and load functions. Start Octave (octave at the command line for me): octave:1> a = 1:12 a = 1 2 3 4 5 6 7 8 9 10 11 12 octave:2> a = reshape(a, [1 3 4]) a = ans(:,:,1) = 1 2 3 ans(:,:,2) = 4 5 6 ans(:,:,3) = 7 8 9 ans(:,:,4) = 10 11 12 octave:3> save -6 octave_a.mat a % MATLAB 6 compatible octave:4> ls octave_a.mat octave_a.mat Now, to Python: >>> mat_contents = sio.loadmat(’octave_a.mat’) >>> mat_contents {’a’: array([[[ 1., 4., 7., 10.], [ 2., 5., 8., 11.], [ 3., 6., 9., 12.]]]), ’__version__’: ’1.0’, ’__header__’: ’MATLAB 5.0 MAT-file, written by Octave 3.6.3, 2013-02-17 21:02:11 UTC’, ’__globals__’: []} >>> oct_a = mat_contents[’a’] >>> oct_a array([[[ 1., 4., 7., 10.], [ 2., 5., 8., 11.], [ 3., 6., 9., 12.]]]) >>> oct_a.shape (1, 3, 4) Now let’s try the other way round: >>> import numpy as np >>> vect = np.arange(10) >>> vect.shape (10,) >>> sio.savemat(’np_vector.mat’, {’vect’:vect}) Then back to Octave: 118 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 octave:8> load np_vector.mat octave:9> vect vect = 0 1 2 3 4 5 6 7 8 9 octave:10> size(vect) ans = 1 10 If you want to inspect the contents of a MATLAB file without reading the data into memory, use the whosmat command: >>> sio.whosmat(’octave_a.mat’) [(’a’, (1, 3, 4), ’double’)] whosmat returns a list of tuples, one for each array (or other object) in the file. Each tuple contains the name, shape and data type of the array. MATLAB structs MATLAB structs are a little bit like Python dicts, except the field names must be strings. Any MATLAB object can be a value of a field. As for all objects in MATLAB, structs are in fact arrays of structs, where a single struct is an array of shape (1, 1). octave:11> my_struct = struct(’field1’, 1, ’field2’, 2) my_struct = { field1 = 1 field2 = 2 } octave:12> save -6 octave_struct.mat my_struct We can load this in Python: >>> mat_contents = sio.loadmat(’octave_struct.mat’) >>> mat_contents {’my_struct’: array([[([[1.0]], [[2.0]])]], dtype=[(’field1’, ’O’), (’field2’, ’O’)]), ’__version__’: ’1.0’, ’__header__’: ’MATLAB 5.0 MAT>>> oct_struct = mat_contents[’my_struct’] >>> oct_struct.shape (1, 1) >>> val = oct_struct[0,0] >>> val ([[1.0]], [[2.0]]) >>> val[’field1’] array([[ 1.]]) >>> val[’field2’] array([[ 2.]]) >>> val.dtype dtype([(’field1’, ’O’), (’field2’, ’O’)]) In versions of Scipy from 0.12.0, MATLAB structs come back as numpy structured arrays, with fields named for the struct fields. You can see the field names in the dtype output above. Note also: 1.15. File IO (scipy.io) 119 SciPy Reference Guide, Release 0.13.0 >>> val = oct_struct[0,0] and: octave:13> size(my_struct) ans = 1 1 So, in MATLAB, the struct array must be at least 2D, and we replicate that when we read into Scipy. If you want all length 1 dimensions squeezed out, try this: >>> mat_contents = sio.loadmat(’octave_struct.mat’, squeeze_me=True) >>> oct_struct = mat_contents[’my_struct’] >>> oct_struct.shape () Sometimes, it’s more convenient to load the MATLAB structs as python objects rather than numpy structured arrays - it can make the access syntax in python a bit more similar to that in MATLAB. In order to do this, use the struct_as_record=False parameter setting to loadmat. >>> mat_contents = sio.loadmat(’octave_struct.mat’, struct_as_record=False) >>> oct_struct = mat_contents[’my_struct’] >>> oct_struct[0,0].field1 array([[ 1.]]) struct_as_record=False works nicely with squeeze_me: >>> mat_contents = sio.loadmat(’octave_struct.mat’, struct_as_record=False, squeeze_me=True) >>> oct_struct = mat_contents[’my_struct’] >>> oct_struct.shape # but no - it’s a scalar Traceback (most recent call last): File "", line 1, in AttributeError: ’mat_struct’ object has no attribute ’shape’ >>> type(oct_struct) >>> oct_struct.field1 1.0 Saving struct arrays can be done in various ways. One simple method is to use dicts: >>> a_dict = {’field1’: 0.5, ’field2’: ’a string’} >>> sio.savemat(’saved_struct.mat’, {’a_dict’: a_dict}) loaded as: octave:21> load saved_struct octave:22> a_dict a_dict = scalar structure containing the fields: field2 = a string field1 = 0.50000 You can also save structs back again to MATLAB (or Octave in our case) like this: >>> dt = [(’f1’, ’f8’), (’f2’, ’S10’)] >>> arr = np.zeros((2,), dtype=dt) >>> arr 120 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 array([(0.0, ’’), (0.0, ’’)], dtype=[(’f1’, ’ >> arr[0][’f1’] = 0.5 >>> arr[0][’f2’] = ’python’ >>> arr[1][’f1’] = 99 >>> arr[1][’f2’] = ’not perl’ >>> sio.savemat(’np_struct_arr.mat’, {’arr’: arr}) MATLAB cell arrays Cell arrays in MATLAB are rather like python lists, in the sense that the elements in the arrays can contain any type of MATLAB object. In fact they are most similar to numpy object arrays, and that is how we load them into numpy. octave:14> my_cells = {1, [2, 3]} my_cells = { [1,1] = 1 [1,2] = 2 3 } octave:15> save -6 octave_cells.mat my_cells Back to Python: >>> mat_contents = sio.loadmat(’octave_cells.mat’) >>> oct_cells = mat_contents[’my_cells’] >>> print(oct_cells.dtype) object >>> val = oct_cells[0,0] >>> val array([[ 1.]]) >>> print(val.dtype) float64 Saving to a MATLAB cell array just involves making a numpy object array: >>> obj_arr = np.zeros((2,), dtype=np.object) >>> obj_arr[0] = 1 >>> obj_arr[1] = ’a string’ >>> obj_arr array([1, ’a string’], dtype=object) >>> sio.savemat(’np_cells.mat’, {’obj_arr’:obj_arr}) octave:16> load np_cells.mat octave:17> obj_arr obj_arr = { [1,1] = 1 [2,1] = a string } 1.15.2 IDL files 1.15. File IO (scipy.io) 121 SciPy Reference Guide, Release 0.13.0 readsav(file_name[, idict, python_dict, ...]) Read an IDL .sav file 1.15.3 Matrix Market files mminfo(source) mmread(source) mmwrite(target, a[, comment, field, precision]) Queries the contents of the Matrix Market file ‘filename’ to Reads the contents of a Matrix Market file ‘filename’ into a matrix. Writes the sparse or dense matrix A to a Matrix Market formatted file. 1.15.4 Wav sound files (scipy.io.wavfile) read(filename[, mmap]) write(filename, rate, data) Return the sample rate (in samples/sec) and data from a WAV file Write a numpy array as a WAV file 1.15.5 Arff files (scipy.io.arff) Module to read ARFF files, which are the standard data format for WEKA. ARFF is a text file format which support numerical, string and data values. The format can also represent missing data and sparse data. See the WEKA website for more details about arff format and available datasets. Examples >>> from scipy.io import arff >>> from cStringIO import StringIO >>> content = """ ... @relation foo ... @attribute width numeric ... @attribute height numeric ... @attribute color {red,green,blue,yellow,black} ... @data ... 5.0,3.25,blue ... 4.5,3.75,green ... 3.0,4.00,red ... """ >>> f = StringIO(content) >>> data, meta = arff.loadarff(f) >>> data array([(5.0, 3.25, ’blue’), (4.5, 3.75, ’green’), (3.0, 4.0, ’red’)], dtype=[(’width’, ’ >> meta Dataset: foo width’s type is numeric height’s type is numeric color’s type is nominal, range is (’red’, ’green’, ’blue’, ’yellow’, ’black’) loadarff(f) 122 Read an arff file. Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 1.15.6 Netcdf (scipy.io.netcdf) netcdf_file(filename[, mode, mmap, version]) A file object for NetCDF data. Allows reading of NetCDF files (version of pupynere package) 1.16 Weave (scipy.weave) 1.16.1 Outline 1.16. Weave (scipy.weave) 123 SciPy Reference Guide, Release 0.13.0 Contents • Weave (scipy.weave) – Outline – Introduction – Requirements – Installation – Testing * Testing Notes: – Benchmarks – Inline * More with printf * More examples · Binary search · Dictionary Sort · NumPy – cast/copy/transpose · wxPython * Keyword Option * Inline Arguments * Distutils keywords · Keyword Option Examples · Returning Values · The issue with locals() · A quick look at the code * Technical Details * Passing Variables in/out of the C/C++ code * Type Conversions · NumPy Argument Conversion · String, List, Tuple, and Dictionary Conversion · File Conversion · Callable, Instance, and Module Conversion · Customizing Conversions * The Catalog · Function Storage · Catalog search paths and the PYTHONCOMPILED variable – Blitz * Requirements * Limitations * NumPy efficiency issues: What compilation buys you * The Tools · Parser · Blitz and NumPy * Type definitions and coersion * Cataloging Compiled Functions * Checking Array Sizes * Creating the Extension Module – Extension Modules * A Simple Example * Fibonacci Example – Customizing Type Conversions – Type Factories – Things I wish weave did 124 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 1.16.2 Introduction The scipy.weave (below just weave) package provides tools for including C/C++ code within in Python code. This offers both another level of optimization to those who need it, and an easy way to modify and extend any supported extension libraries such as wxPython and hopefully VTK soon. Inlining C/C++ code within Python generally results in speed ups of 1.5x to 30x speed-up over algorithms written in pure Python (However, it is also possible to slow things down...). Generally algorithms that require a large number of calls to the Python API don’t benefit as much from the conversion to C/C++ as algorithms that have inner loops completely convertable to C. There are three basic ways to use weave. The weave.inline() function executes C code directly within Python, and weave.blitz() translates Python NumPy expressions to C++ for fast execution. blitz() was the original reason weave was built. For those interested in building extension libraries, the ext_tools module provides classes for building extension modules within Python. Most of weave’s functionality should work on Windows and Unix, although some of its functionality requires gcc or a similarly modern C++ compiler that handles templates well. Up to now, most testing has been done on Windows 2000 with Microsoft’s C++ compiler (MSVC) and with gcc (mingw32 2.95.2 and 2.95.3-6). All tests also pass on Linux (RH 7.1 with gcc 2.96), and I’ve had reports that it works on Debian also (thanks Pearu). The inline and blitz provide new functionality to Python (although I’ve recently learned about the PyInline project which may offer similar functionality to inline). On the other hand, tools for building Python extension modules already exists (SWIG, SIP, pycpp, CXX, and others). As of yet, I’m not sure where weave fits in this spectrum. It is closest in flavor to CXX in that it makes creating new C/C++ extension modules pretty easy. However, if you’re wrapping a gaggle of legacy functions or classes, SWIG and friends are definitely the better choice. weave is set up so that you can customize how Python types are converted to C types in weave. This is great for inline(), but, for wrapping legacy code, it is more flexible to specify things the other way around – that is how C types map to Python types. This weave does not do. I guess it would be possible to build such a tool on top of weave, but with good tools like SWIG around, I’m not sure the effort produces any new capabilities. Things like function overloading are probably easily implemented in weave and it might be easier to mix Python/C code in function calls, but nothing beyond this comes to mind. So, if you’re developing new extension modules or optimizing Python functions in C, weave.ext_tools() might be the tool for you. If you’re wrapping legacy code, stick with SWIG. The next several sections give the basics of how to use weave. We’ll discuss what’s happening under the covers in more detail later on. Serious users will need to at least look at the type conversion section to understand how Python variables map to C/C++ types and how to customize this behavior. One other note. If you don’t know C or C++ then these docs are probably of very little help to you. Further, it’d be helpful if you know something about writing Python extensions. weave does quite a bit for you, but for anything complex, you’ll need to do some conversions, reference counting, etc. Note: weave is actually part of the SciPy package. However, it also works fine as a standalone package (you can install from scipy/weave with python setup.py install). The examples here are given as if it is used as a stand alone package. If you are using from within scipy, you can use from scipy import weave and the examples will work identically. 1.16.3 Requirements • Python I use 2.1.1. Probably 2.0 or higher should work. • C++ compiler weave uses distutils to actually build extension modules, so it uses whatever compiler was originally used to build Python. weave itself requires a C++ compiler. If you used a C++ compiler to build Python, your probably fine. 1.16. Weave (scipy.weave) 125 SciPy Reference Guide, Release 0.13.0 On Unix gcc is the preferred choice because I’ve done a little testing with it. All testing has been done with gcc, but I expect the majority of compilers should work for inline and ext_tools. The one issue I’m not sure about is that I’ve hard coded things so that compilations are linked with the stdc++ library. Is this standard across Unix compilers, or is this a gcc-ism? For blitz(), you’ll need a reasonably recent version of gcc. 2.95.2 works on windows and 2.96 looks fine on Linux. Other versions are likely to work. Its likely that KAI’s C++ compiler and maybe some others will work, but I haven’t tried. My advice is to use gcc for now unless your willing to tinker with the code some. On Windows, either MSVC or gcc (mingw32) should work. Again, you’ll need gcc for blitz() as the MSVC compiler doesn’t handle templates well. I have not tried Cygwin, so please report success if it works for you. • NumPy The python NumPy module is required for blitz() to work and for numpy.distutils which is used by weave. 1.16.4 Installation There are currently two ways to get weave. First, weave is part of SciPy and installed automatically (as a subpackage) whenever SciPy is installed. Second, since weave is useful outside of the scientific community, it has been setup so that it can be used as a stand-alone module. The stand-alone version can be downloaded from here. Instructions for installing should be found there as well. setup.py file to simplify installation. 1.16.5 Testing Once weave is installed, fire up python and run its unit tests. >>> import weave >>> weave.test() runs long time... spews tons of output and a few warnings . . . .............................................................. ................................................................ .................................................. ---------------------------------------------------------------------Ran 184 tests in 158.418s OK >>> This takes a while, usually several minutes. On Unix with remote file systems, I’ve had it take 15 or so minutes. In the end, it should run about 180 tests and spew some speed results along the way. If you get errors, they’ll be reported at the end of the output. Please report errors that you find. Some tests are known to fail at this point. If you only want to test a single module of the package, you can do this by running test() for that specific module. >>> import weave.scalar_spec >>> weave.scalar_spec.test() ....... ---------------------------------------------------------------------Ran 7 tests in 23.284s 126 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 Testing Notes: • Windows 1 I’ve had some test fail on windows machines where I have msvc, gcc-2.95.2 (in c:gcc-2.95.2), and gcc-2.95.3-6 (in c:gcc) all installed. My environment has c:gcc in the path and does not have c:gcc-2.95.2 in the path. The test process runs very smoothly until the end where several test using gcc fail with cpp0 not found by g++. If I check os.system(‘gcc -v’) before running tests, I get gcc-2.95.3-6. If I check after running tests (and after failure), I get gcc-2.95.2. ??huh??. The os.environ[’PATH’] still has c:gcc first in it and is not corrupted (msvc/distutils messes with the environment variables, so we have to undo its work in some places). If anyone else sees this, let me know - - it may just be an quirk on my machine (unlikely). Testing with the gcc- 2.95.2 installation always works. • Windows 2 If you run the tests from PythonWin or some other GUI tool, you’ll get a ton of DOS windows popping up periodically as weave spawns the compiler multiple times. Very annoying. Anyone know how to fix this? • wxPython wxPython tests are not enabled by default because importing wxPython on a Unix machine without access to a X-term will cause the program to exit. Anyone know of a safe way to detect whether wxPython can be imported and whether a display exists on a machine? 1.16.6 Benchmarks This section has not been updated from old scipy weave and Numeric.... This section has a few benchmarks – thats all people want to see anyway right? These are mostly taken from running files in the weave/example directory and also from the test scripts. Without more information about what the test actually do, their value is limited. Still, their here for the curious. Look at the example scripts for more specifics about what problem was actually solved by each run. These examples are run under windows 2000 using Microsoft Visual C++ and python2.1 on a 850 MHz PIII laptop with 320 MB of RAM. Speed up is the improvement (degredation) factor of weave compared to conventional Python functions. The blitz() comparisons are shown compared to NumPy. Table 1.7: inline and ext_tools Algorithm binary search fibonacci (recursive) fibonacci (loop) return None map dictionary sort vector quantization Speed up 1.50 82.10 9.17 0.14 1.20 2.54 37.40 Table 1.8: blitz – double precision Algorithm a = b + c 512x512 a = b + c + d 512x512 5 pt avg. filter, 2D Image 512x512 Electromagnetics (FDTD) 100x100x100 Speed up 3.05 4.59 9.01 8.61 The benchmarks shown blitz in the best possible light. NumPy (at least on my machine) is significantly worse for double precision than it is for single precision calculations. If your interested in single precision results, you can pretty much divide the double precision speed up by 3 and you’ll be close. 1.16. Weave (scipy.weave) 127 SciPy Reference Guide, Release 0.13.0 1.16.7 Inline inline() compiles and executes C/C++ code on the fly. Variables in the local and global Python scope are also available in the C/C++ code. Values are passed to the C/C++ code by assignment much like variables are passed into a standard Python function. Values are returned from the C/C++ code through a special argument called return_val. Also, the contents of mutable objects can be changed within the C/C++ code and the changes remain after the C code exits and returns to Python. (more on this later) Here’s a trivial printf example using inline(): >>> import weave >>> a = 1 >>> weave.inline(’printf("%d\\n",a);’,[’a’]) 1 In this, its most basic form, inline(c_code, var_list) requires two arguments. c_code is a string of valid C/C++ code. var_list is a list of variable names that are passed from Python into C/C++. Here we have a simple printf statement that writes the Python variable a to the screen. The first time you run this, there will be a pause while the code is written to a .cpp file, compiled into an extension module, loaded into Python, cataloged for future use, and executed. On windows (850 MHz PIII), this takes about 1.5 seconds when using Microsoft’s C++ compiler (MSVC) and 6-12 seconds using gcc (mingw32 2.95.2). All subsequent executions of the code will happen very quickly because the code only needs to be compiled once. If you kill and restart the interpreter and then execute the same code fragment again, there will be a much shorter delay in the fractions of seconds range. This is because weave stores a catalog of all previously compiled functions in an on disk cache. When it sees a string that has been compiled, it loads the already compiled module and executes the appropriate function. Note: If you try the printf example in a GUI shell such as IDLE, PythonWin, PyShell, etc., you’re unlikely to see the output. This is because the C code is writing to stdout, instead of to the GUI window. This doesn’t mean that inline doesn’t work in these environments – it only means that standard out in C is not the same as the standard out for Python in these cases. Non input/output functions will work as expected. Although effort has been made to reduce the overhead associated with calling inline, it is still less efficient for simple code snippets than using equivalent Python code. The simple printf example is actually slower by 30% or so than using Python print statement. And, it is not difficult to create code fragments that are 8-10 times slower using inline than equivalent Python. However, for more complicated algorithms, the speedup can be worthwhile – anywhere from 1.5-30 times faster. Algorithms that have to manipulate Python objects (sorting a list) usually only see a factor of 2 or so improvement. Algorithms that are highly computational or manipulate NumPy arrays can see much larger improvements. The examples/vq.py file shows a factor of 30 or more improvement on the vector quantization algorithm that is used heavily in information theory and classification problems. More with printf MSVC users will actually see a bit of compiler output that distutils does not suppress the first time the code executes: >>> weave.inline(r’printf("%d\n",a);’,[’a’]) sc_e013937dbc8c647ac62438874e5795131.cpp Creating library C:\DOCUME~1\eric\LOCALS~1\Temp\python21_compiled\temp \Release\sc_e013937dbc8c647ac62438874e5795131.lib and object C:\DOCUME~1\eric\LOCALS~1\Temp\python21_compiled\temp\Release\sc_e013937dbc8c647ac62438874e 1 Nothing bad is happening, its just a bit annoying. * Anyone know how to turn this off?* This example also demonstrates using ‘raw strings’. The r preceeding the code string in the last example denotes that this is a ‘raw string’. In raw strings, the backslash character is not interpreted as an escape character, and so it isn’t necessary to use a double backslash to indicate that the ‘n’ is meant to be interpreted in the C printf statement 128 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 instead of by Python. If your C code contains a lot of strings and control characters, raw strings might make things easier. Most of the time, however, standard strings work just as well. The printf statement in these examples is formatted to print out integers. What happens if a is a string? inline will happily, compile a new version of the code to accept strings as input, and execute the code. The result? >>> a = ’string’ >>> weave.inline(r’printf("%d\n",a);’,[’a’]) 32956972 In this case, the result is non-sensical, but also non-fatal. In other situations, it might produce a compile time error because a is required to be an integer at some point in the code, or it could produce a segmentation fault. Its possible to protect against passing inline arguments of the wrong data type by using asserts in Python. >>> a = ’string’ >>> def protected_printf(a): ... assert(type(a) == type(1)) ... weave.inline(r’printf("%d\n",a);’,[’a’]) >>> protected_printf(1) 1 >>> protected_printf(’string’) AssertError... For printing strings, the format statement needs to be changed. Also, weave doesn’t convert strings to char*. Instead it uses CXX Py::String type, so you have to do a little more work. Here we convert it to a C++ std::string and then ask cor the char* version. >>> a = ’string’ >>> weave.inline(r’printf("%s\n",std::string(a).c_str());’,[’a’]) string XXX This is a little convoluted. Perhaps strings should convert to std::string objects instead of CXX objects. Or maybe to char*. As in this case, C/C++ code fragments often have to change to accept different types. For the given printing task, however, C++ streams provide a way of a single statement that works for integers and strings. By default, the stream objects live in the std (standard) namespace and thus require the use of std::. >>> weave.inline(’std::cout << a << std::endl;’,[’a’]) 1 >>> a = ’string’ >>> weave.inline(’std::cout << a << std::endl;’,[’a’]) string Examples using printf and cout are included in examples/print_example.py. More examples This section shows several more advanced uses of inline. It includes a few algorithms from the Python Cookbook that have been re-written in inline C to improve speed as well as a couple examples using NumPy and wxPython. Binary search Lets look at the example of searching a sorted list of integers for a value. For inspiration, we’ll use Kalle Svensson’s binary_search() algorithm from the Python Cookbook. His recipe follows: 1.16. Weave (scipy.weave) 129 SciPy Reference Guide, Release 0.13.0 def binary_search(seq, t): min = 0; max = len(seq) - 1 while 1: if max < min: return -1 m = (min + max) / 2 if seq[m] < t: min = m + 1 elif seq[m] > t: max = m - 1 else: return m This Python version works for arbitrary Python data types. The C version below is specialized to handle integer values. There is a little type checking done in Python to assure that we’re working with the correct data types before heading into C. The variables seq and t don’t need to be declared beacuse weave handles converting and declaring them in the C code. All other temporary variables such as min, max, etc. must be declared – it is C after all. Here’s the new mixed Python/C function: def c_int_binary_search(seq,t): # do a little type checking in Python assert(type(t) == type(1)) assert(type(seq) == type([])) # now the C code code = """ #line 29 "binary_search.py" int val, m, min = 0; int max = seq.length() - 1; PyObject *py_val; for(;;) { if (max < min ) { return_val = Py::new_reference_to(Py::Int(-1)); break; } m = (min + max) /2; val = py_to_int(PyList_GetItem(seq.ptr(),m),"val"); if (val < t) min = m + 1; else if (val > t) max = m - 1; else { return_val = Py::new_reference_to(Py::Int(m)); break; } } """ return inline(code,[’seq’,’t’]) We have two variables seq and t passed in. t is guaranteed (by the assert) to be an integer. Python integers are converted to C int types in the transition from Python to C. seq is a Python list. By default, it is translated to a CXX list object. Full documentation for the CXX library can be found at its website. The basics are that the CXX provides C++ class equivalents for Python objects that simplify, or at least object orientify, working with Python objects in C/C++. For example, seq.length() returns the length of the list. A little more about CXX and its class methods, etc. is in the Type Conversions section. 130 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 Note: CXX uses templates and therefore may be a little less portable than another alternative by Gordan McMillan called SCXX which was inspired by CXX. It doesn’t use templates so it should compile faster and be more portable. SCXX has a few less features, but it appears to me that it would mesh with the needs of weave quite well. Hopefully xxx_spec files will be written for SCXX in the future, and we’ll be able to compare on a more empirical basis. Both sets of spec files will probably stick around, it just a question of which becomes the default. Most of the algorithm above looks similar in C to the original Python code. There are two main differences. The first is the setting of return_val instead of directly returning from the C code with a return statement. return_val is an automatically defined variable of type PyObject* that is returned from the C code back to Python. You’ll have to handle reference counting issues when setting this variable. In this example, CXX classes and functions handle the dirty work. All CXX functions and classes live in the namespace Py::. The following code converts the integer m to a CXX Int() object and then to a PyObject* with an incremented reference count using Py::new_reference_to(). return_val = Py::new_reference_to(Py::Int(m)); The second big differences shows up in the retrieval of integer values from the Python list. The simple Python seq[i] call balloons into a C Python API call to grab the value out of the list and then a separate call to py_to_int() that converts the PyObject* to an integer. py_to_int() includes both a NULL cheack and a PyInt_Check() call as well as the conversion call. If either of the checks fail, an exception is raised. The entire C++ code block is executed with in a try/catch block that handles exceptions much like Python does. This removes the need for most error checking code. It is worth note that CXX lists do have indexing operators that result in code that looks much like Python. However, the overhead in using them appears to be relatively high, so the standard Python API was used on the seq.ptr() which is the underlying PyObject* of the List object. The #line directive that is the first line of the C code block isn’t necessary, but it’s nice for debugging. If the compilation fails because of the syntax error in the code, the error will be reported as an error in the Python file “binary_search.py” with an offset from the given line number (29 here). So what was all our effort worth in terms of efficiency? Well not a lot in this case. The examples/binary_search.py file runs both Python and C versions of the functions As well as using the standard bisect module. If we run it on a 1 million element list and run the search 3000 times (for 0- 2999), here are the results we get: C:\home\ej\wrk\scipy\weave\examples> python binary_search.py Binary search for 3000 items in 1000000 length list of integers: speed in python: 0.159999966621 speed of bisect: 0.121000051498 speed up: 1.32 speed in c: 0.110000014305 speed up: 1.45 speed in c(no asserts): 0.0900000333786 speed up: 1.78 So, we get roughly a 50-75% improvement depending on whether we use the Python asserts in our C version. If we move down to searching a 10000 element list, the advantage evaporates. Even smaller lists might result in the Python version being faster. I’d like to say that moving to NumPy lists (and getting rid of the GetItem() call) offers a substantial speed up, but my preliminary efforts didn’t produce one. I think the log(N) algorithm is to blame. Because the algorithm is nice, there just isn’t much time spent computing things, so moving to C isn’t that big of a win. If there are ways to reduce conversion overhead of values, this may improve the C/Python speed up. Anyone have other explanations or faster code, please let me know. 1.16. Weave (scipy.weave) 131 SciPy Reference Guide, Release 0.13.0 Dictionary Sort The demo in examples/dict_sort.py is another example from the Python CookBook. This submission, by Alex Martelli, demonstrates how to return the values from a dictionary sorted by their keys: def sortedDictValues3(adict): keys = adict.keys() keys.sort() return map(adict.get, keys) Alex provides 3 algorithms and this is the 3rd and fastest of the set. The C version of this same algorithm follows: def c_sort(adict): assert(type(adict) == type({})) code = """ #line 21 "dict_sort.py" Py::List keys = adict.keys(); Py::List items(keys.length()); keys.sort(); PyObject* item = NULL; for(int i = 0; i < keys.length();i++) { item = PyList_GET_ITEM(keys.ptr(),i); item = PyDict_GetItem(adict.ptr(),item); Py_XINCREF(item); PyList_SetItem(items.ptr(),i,item); } return_val = Py::new_reference_to(items); """ return inline_tools.inline(code,[’adict’],verbose=1) Like the original Python function, the C++ version can handle any Python dictionary regardless of the key/value pair types. It uses CXX objects for the most part to declare python types in C++, but uses Python API calls to manipulate their contents. Again, this choice is made for speed. The C++ version, while more complicated, is about a factor of 2 faster than Python. C:\home\ej\wrk\scipy\weave\examples> python dict_sort.py Dict sort of 1000 items for 300 iterations: speed in python: 0.319999933243 [0, 1, 2, 3, 4] speed in c: 0.151000022888 speed up: 2.12 [0, 1, 2, 3, 4] NumPy – cast/copy/transpose CastCopyTranspose is a function called quite heavily by Linear Algebra routines in the NumPy library. Its needed in part because of the row-major memory layout of multi-demensional Python (and C) arrays vs. the col-major order of the underlying Fortran algorithms. For small matrices (say 100x100 or less), a significant portion of the common routines such as LU decompisition or singular value decompostion are spent in this setup routine. This shouldn’t happen. Here is the Python version of the function using standard NumPy operations. def _castCopyAndTranspose(type, array): if a.typecode() == type: cast_array = copy.copy(NumPy.transpose(a)) else: cast_array = copy.copy(NumPy.transpose(a).astype(type)) return cast_array And the following is a inline C version of the same function: 132 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 from weave.blitz_tools import blitz_type_factories from weave import scalar_spec from weave import inline def _cast_copy_transpose(type,a_2d): assert(len(shape(a_2d)) == 2) new_array = zeros(shape(a_2d),type) NumPy_type = scalar_spec.NumPy_to_blitz_type_mapping[type] code = \ """ for(int i = 0;i < _Na_2d[0]; i++) for(int j = 0; j < _Na_2d[1]; j++) new_array(i,j) = (%s) a_2d(j,i); """ % NumPy_type inline(code,[’new_array’,’a_2d’], type_factories = blitz_type_factories,compiler=’gcc’) return new_array This example uses blitz++ arrays instead of the standard representation of NumPy arrays so that indexing is simplier to write. This is accomplished by passing in the blitz++ “type factories” to override the standard Python to C++ type conversions. Blitz++ arrays allow you to write clean, fast code, but they also are sloooow to compile (20 seconds or more for this snippet). This is why they aren’t the default type used for Numeric arrays (and also because most compilers can’t compile blitz arrays...). inline() is also forced to use ‘gcc’ as the compiler because the default compiler on Windows (MSVC) will not compile blitz code. (‘gcc’ I think will use the standard compiler on Unix machine instead of explicitly forcing gcc (check this)) Comparisons of the Python vs inline C++ code show a factor of 3 speed up. Also shown are the results of an “inplace” transpose routine that can be used if the output of the linear algebra routine can overwrite the original matrix (this is often appropriate). This provides another factor of 2 improvement. #C:\home\ej\wrk\scipy\weave\examples> python cast_copy_transpose.py # Cast/Copy/Transposing (150,150)array 1 times # speed in python: 0.870999932289 # speed in c: 0.25 # speed up: 3.48 # inplace transpose c: 0.129999995232 # speed up: 6.70 wxPython inline knows how to handle wxPython objects. Thats nice in and of itself, but it also demonstrates that the type conversion mechanism is reasonably flexible. Chances are, it won’t take a ton of effort to support special types you might have. The examples/wx_example.py borrows the scrolled window example from the wxPython demo, accept that it mixes inline C code in the middle of the drawing function. def DoDrawing(self, dc): red = wxNamedColour("RED"); blue = wxNamedColour("BLUE"); grey_brush = wxLIGHT_GREY_BRUSH; code = \ """ #line 108 "wx_example.py" dc->BeginDrawing(); dc->SetPen(wxPen(*red,4,wxSOLID)); dc->DrawRectangle(5,5,50,50); dc->SetBrush(*grey_brush); dc->SetPen(wxPen(*blue,4,wxSOLID)); dc->DrawRectangle(15, 15, 50, 50); """ 1.16. Weave (scipy.weave) 133 SciPy Reference Guide, Release 0.13.0 inline(code,[’dc’,’red’,’blue’,’grey_brush’]) dc.SetFont(wxFont(14, wxSWISS, wxNORMAL, wxNORMAL)) dc.SetTextForeground(wxColour(0xFF, 0x20, 0xFF)) te = dc.GetTextExtent("Hello World") dc.DrawText("Hello World", 60, 65) dc.SetPen(wxPen(wxNamedColour(’VIOLET’), 4)) dc.DrawLine(5, 65+te[1], 60+te[0], 65+te[1]) ... Here, some of the Python calls to wx objects were just converted to C++ calls. There isn’t any benefit, it just demonstrates the capabilities. You might want to use this if you have a computationally intensive loop in your drawing code that you want to speed up. On windows, you’ll have to use the MSVC compiler if you use the standard wxPython DLLs distributed by Robin Dunn. Thats because MSVC and gcc, while binary compatible in C, are not binary compatible for C++. In fact, its probably best, no matter what platform you’re on, to specify that inline use the same compiler that was used to build wxPython to be on the safe side. There isn’t currently a way to learn this info from the library – you just have to know. Also, at least on the windows platform, you’ll need to install the wxWindows libraries and link to them. I think there is a way around this, but I haven’t found it yet – I get some linking errors dealing with wxString. One final note. You’ll probably have to tweak weave/wx_spec.py or weave/wx_info.py for your machine’s configuration to point at the correct directories etc. There. That should sufficiently scare people into not even looking at this... :) Keyword Option The basic definition of the inline() function has a slew of optional variables. It also takes keyword arguments that are passed to distutils as compiler options. The following is a formatted cut/paste of the argument section of inline’s doc-string. It explains all of the variables. Some examples using various options will follow. def inline(code,arg_names,local_dict = None, global_dict = None, force = 0, compiler=’’, verbose = 0, support_code = None, customize=None, type_factories = None, auto_downcast=1, **kw): inline has quite a few options as listed below. Also, the keyword arguments for distutils extension modules are accepted to specify extra information needed for compiling. Inline Arguments code string. A string of valid C++ code. It should not specify a return statement. Instead it should assign results that need to be returned to Python in the return_val. arg_names list of strings. A list of Python variable names that should be transferred from Python into the C/C++ code. local_dict optional. dictionary. If specified, it is a dictionary of values that should be used as the local scope for the C/C++ code. If local_dict is not specified the local dictionary of the calling function is used. global_dict optional. dictionary. If specified, it is a dictionary of values that should be used as the global scope for the C/C++ code. If global_dict is not specified the global dictionary of the calling function is used. force optional. 0 or 1. default 0. If 1, the C++ code is compiled every time inline is called. This is really only useful for debugging, and probably only useful if you’re editing support_code a lot. compiler optional. string. The name of compiler to use when compiling. On windows, it understands ‘msvc’ and ‘gcc’ as well as all the compiler names understood by distutils. On Unix, it’ll only understand the values understoof by distutils. (I should add ‘gcc’ though to this). 134 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 On windows, the compiler defaults to the Microsoft C++ compiler. If this isn’t available, it looks for mingw32 (the gcc compiler). On Unix, it’ll probably use the same compiler that was used when compiling Python. Cygwin’s behavior should be similar. verbose optional. 0,1, or 2. defualt 0. Speficies how much much information is printed during the compile phase of inlining code. 0 is silent (except on windows with msvc where it still prints some garbage). 1 informs you when compiling starts, finishes, and how long it took. 2 prints out the command lines for the compilation process and can be useful if you’re having problems getting code to work. Its handy for finding the name of the .cpp file if you need to examine it. verbose has no affect if the compilation isn’t necessary. support_code optional. string. A string of valid C++ code declaring extra code that might be needed by your compiled function. This could be declarations of functions, classes, or structures. customize optional. base_info.custom_info object. An alternative way to specifiy support_code, headers, etc. needed by the function see the weave.base_info module for more details. (not sure this’ll be used much). type_factories optional. list of type specification factories. These guys are what convert Python data types to C/C++ data types. If you’d like to use a different set of type conversions than the default, specify them here. Look in the type conversions section of the main documentation for examples. auto_downcast optional. 0 or 1. default 1. This only affects functions that have Numeric arrays as input variables. Setting this to 1 will cause all floating point values to be cast as float instead of double if all the NumPy arrays are of type float. If even one of the arrays has type double or double complex, all variables maintain there standard types. Distutils keywords inline() also accepts a number of distutils keywords for controlling how the code is compiled. The following descriptions have been copied from Greg Ward’s distutils.extension.Extension class doc- strings for convenience: sources [string] list of source filenames, relative to the distribution root (where the setup script lives), in Unix form (slash- separated) for portability. Source files may be C, C++, SWIG (.i), platform- specific resource files, or whatever else is recognized by the “build_ext” command as source for a Python extension. Note: The module_path file is always appended to the front of this list include_dirs [string] list of directories to search for C/C++ header files (in Unix form for portability) define_macros [(name : string, value : string|None)] list of macros to define; each macro is defined using a 2-tuple, where ‘value’ is either the string to define it to or None to define it without a particular value (equivalent of “#define FOO” in source or -DFOO on Unix C compiler command line) undef_macros [string] list of macros to undefine explicitly library_dirs [string] list of directories to search for C/C++ libraries at link time libraries [string] list of library names (not filenames or paths) to link against runtime_library_dirs [string] list of directories to search for C/C++ libraries at run time (for shared extensions, this is when the extension is loaded) extra_objects [string] list of extra files to link with (eg. object files not implied by ‘sources’, static library that must be explicitly specified, binary resource files, etc.) extra_compile_args [string] any extra platform- and compiler-specific information to use when compiling the source files in ‘sources’. For platforms and compilers where “command line” makes sense, this is typically a list of command-line arguments, but for other platforms it could be anything. extra_link_args [string] any extra platform- and compiler-specific information to use when linking object files together to create the extension (or to create a new static Python interpreter). Similar interpretation as for ‘extra_compile_args’. export_symbols [string] list of symbols to be exported from a shared extension. Not used on all platforms, and not generally necessary for Python extensions, which typically export exactly one symbol: “init” + extension_name. Keyword Option Examples We’ll walk through several examples here to demonstrate the behavior of inline and also how the various arguments are used. In the simplest (most) cases, code and arg_names are the only arguments that need to be specified. Here’s a simple example run on Windows machine that has Microsoft VC++ installed. >>> from weave import inline >>> a = ’string’ >>> code = """ ... int l = a.length(); ... return_val = Py::new_reference_to(Py::Int(l)); 1.16. Weave (scipy.weave) 135 SciPy Reference Guide, Release 0.13.0 ... """ >>> inline(code,[’a’]) sc_86e98826b65b047ffd2cd5f479c627f12.cpp Creating library C:\DOCUME~1\eric\LOCALS~1\Temp\python21_compiled\temp\Release\sc_86e98826b65b047ffd2cd5f47 and object C:\DOCUME~1\eric\LOCALS~1\Temp\python21_compiled\temp\Release\sc_86e98826b65b047ff d2cd5f479c627f12.exp 6 >>> inline(code,[’a’]) 6 When inline is first run, you’ll notice that pause and some trash printed to the screen. The “trash” is actually part of the compiler’s output that distutils does not supress. The name of the extension file, sc_bighonkingnumber.cpp, is generated from the SHA-256 check sum of the C/C++ code fragment. On Unix or windows machines with only gcc installed, the trash will not appear. On the second call, the code fragment is not compiled since it already exists, and only the answer is returned. Now kill the interpreter and restart, and run the same code with a different string. >>> >>> >>> ... ... ... >>> 15 from weave import inline a = ’a longer string’ code = """ int l = a.length(); return_val = Py::new_reference_to(Py::Int(l)); """ inline(code,[’a’]) Notice this time, inline() did not recompile the code because it found the compiled function in the persistent catalog of functions. There is a short pause as it looks up and loads the function, but it is much shorter than compiling would require. You can specify the local and global dictionaries if you’d like (much like exec or eval() in Python), but if they aren’t specified, the “expected” ones are used – i.e. the ones from the function that called inline(). This is accomplished through a little call frame trickery. Here is an example where the local_dict is specified using the same code example from above: >>> >>> >>> >>> 15 >>> 21 a = ’a longer string’ b = ’an even longer string’ my_dict = {’a’:b} inline(code,[’a’]) inline(code,[’a’],my_dict) Everytime, the code is changed, inline does a recompile. However, changing any of the other options in inline does not force a recompile. The force option was added so that one could force a recompile when tinkering with other variables. In practice, it is just as easy to change the code by a single character (like adding a space some place) to force the recompile. Note: It also might be nice to add some methods for purging the cache and on disk catalogs. I use verbose sometimes for debugging. When set to 2, it’ll output all the information (including the name of the .cpp file) that you’d expect from running a make file. This is nice if you need to examine the generated code to see where things are going haywire. Note that error messages from failed compiles are printed to the screen even if verbose is set to 0. The following example demonstrates using gcc instead of the standard msvc compiler on windows using same code fragment as above. Because the example has already been compiled, the force=1 flag is needed to make inline() 136 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 ignore the previously compiled version and recompile using gcc. The verbose flag is added to show what is printed out: >>>inline(code,[’a’],compiler=’gcc’,verbose=2,force=1) running build_ext building ’sc_86e98826b65b047ffd2cd5f479c627f13’ extension c:\gcc-2.95.2\bin\g++.exe -mno-cygwin -mdll -O2 -w -Wstrict-prototypes -IC: \home\ej\wrk\scipy\weave -IC:\Python21\Include -c C:\DOCUME~1\eric\LOCAL S~1\Temp\python21_compiled\sc_86e98826b65b047ffd2cd5f479c627f13.cpp -o C:\DOCUME~1\eric\LOCALS~1\Temp\python21_compiled\temp\Release\sc_86e98826b65b04ffd2cd5f479c627f13. skipping C:\home\ej\wrk\scipy\weave\CXX\cxxextensions.c (C:\DOCUME~1\eric\LOCALS~1\Temp\python21_compiled\temp\Release\cxxextensions.o up-to-date) skipping C:\home\ej\wrk\scipy\weave\CXX\cxxsupport.cxx (C:\DOCUME~1\eric\LOCALS~1\Temp\python21_compiled\temp\Release\cxxsupport.o up-to-date) skipping C:\home\ej\wrk\scipy\weave\CXX\IndirectPythonInterface.cxx (C:\DOCUME~1\eric\LOCALS~1\Temp\python21_compiled\temp\Release\indirectpythoninterface.o up-to-date) skipping C:\home\ej\wrk\scipy\weave\CXX\cxx_extensions.cxx (C:\DOCUME~1\eric\LOCALS~1\Temp\python21_compiled\temp\Release\cxx_extensions.o up-to-date) writing C:\DOCUME~1\eric\LOCALS~1\Temp\python21_compiled\temp\Release\sc_86e98826b65b047ffd2cd5f479c6 c:\gcc-2.95.2\bin\dllwrap.exe --driver-name g++ -mno-cygwin -mdll -static --output-lib C:\DOCUME~1\eric\LOCALS~1\Temp\python21_compiled\temp\Release\libsc_86e98826b65b047ffd2cd5f479c627f13 C:\DOCUME~1\eric\LOCALS~1\Temp\python21_compiled\temp\Release\sc_86e98826b65b047ffd2cd5f479c627f13.de -sC:\DOCUME~1\eric\LOCALS~1\Temp\python21_compiled\temp\Release\sc_86e98826b65b047ffd2cd5f479c627f13. C:\DOCUME~1\eric\LOCALS~1\Temp\python21_compiled\temp\Release\cxxextensions.o C:\DOCUME~1\eric\LOCALS~1\Temp\python21_compiled\temp\Release\cxxsupport.o C:\DOCUME~1\eric\LOCALS~1\Temp\python21_compiled\temp\Release\indirectpythoninterface.o C:\DOCUME~1\eric\LOCALS~1\Temp\python21_compiled\temp\Release\cxx_extensions.o -LC:\Python21\libs -lpython21 -o C:\DOCUME~1\eric\LOCALS~1\Temp\python21_compiled\sc_86e98826b65b047ffd2cd5f479c627f13.pyd 15 That’s quite a bit of output. verbose=1 just prints the compile time. >>>inline(code,[’a’],compiler=’gcc’,verbose=1,force=1) Compiling code... finished compiling (sec): 6.00800001621 15 Note: I’ve only used the compiler option for switching between ‘msvc’ and ‘gcc’ on windows. It may have use on Unix also, but I don’t know yet. The support_code argument is likely to be used a lot. It allows you to specify extra code fragments such as function, structure or class definitions that you want to use in the code string. Note that changes to support_code do not force a recompile. The catalog only relies on code (for performance reasons) to determine whether recompiling is necessary. So, if you make a change to support_code, you’ll need to alter code in some way or use the force argument to get the code to recompile. I usually just add some inocuous whitespace to the end of one of the lines in code somewhere. Here’s an example of defining a separate method for calculating the string length: >>> from weave import inline >>> a = ’a longer string’ >>> support_code = """ ... PyObject* length(Py::String a) ... { ... int l = a.length(); ... return Py::new_reference_to(Py::Int(l)); ... } 1.16. Weave (scipy.weave) 137 SciPy Reference Guide, Release 0.13.0 ... """ >>> inline("return_val = length(a);",[’a’], ... support_code = support_code) 15 customize is a left over from a previous way of specifying compiler options. It is a custom_info object that can specify quite a bit of information about how a file is compiled. These info objects are the standard way of defining compile information for type conversion classes. However, I don’t think they are as handy here, especially since we’ve exposed all the keyword arguments that distutils can handle. Between these keywords, and the support_code option, I think customize may be obsolete. We’ll see if anyone cares to use it. If not, it’ll get axed in the next version. The type_factories variable is important to people who want to customize the way arguments are converted from Python to C. We’ll talk about this in the next chapter xx of this document when we discuss type conversions. auto_downcast handles one of the big type conversion issues that is common when using NumPy arrays in conjunction with Python scalar values. If you have an array of single precision values and multiply that array by a Python scalar, the result is upcast to a double precision array because the scalar value is double precision. This is not usually the desired behavior because it can double your memory usage. auto_downcast goes some distance towards changing the casting precedence of arrays and scalars. If your only using single precision arrays, it will automatically downcast all scalar values from double to single precision when they are passed into the C++ code. This is the default behavior. If you want all values to keep there default type, set auto_downcast to 0. Returning Values Python variables in the local and global scope transfer seemlessly from Python into the C++ snippets. And, if inline were to completely live up to its name, any modifications to variables in the C++ code would be reflected in the Python variables when control was passed back to Python. For example, the desired behavior would be something like: # THIS DOES NOT WORK >>> a = 1 >>> weave.inline("a++;",[’a’]) >>> a 2 Instead you get: >>> a = 1 >>> weave.inline("a++;",[’a’]) >>> a 1 Variables are passed into C++ as if you are calling a Python function. Python’s calling convention is sometimes called “pass by assignment”. This means its as if a c_a = a assignment is made right before inline call is made and the c_a variable is used within the C++ code. Thus, any changes made to c_a are not reflected in Python’s a variable. Things do get a little more confusing, however, when looking at variables with mutable types. Changes made in C++ to the contents of mutable types are reflected in the Python variables. >>> >>> >>> [3, a= [1,2] weave.inline("PyList_SetItem(a.ptr(),0,PyInt_FromLong(3));",[’a’]) print a 2] So modifications to the contents of mutable types in C++ are seen when control is returned to Python. Modifications to immutable types such as tuples, strings, and numbers do not alter the Python variables. If you need to make changes to an immutable variable, you’ll need to assign the new value to the “magic” variable return_val in C++. This value is returned by the inline() function: 138 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 >>> a = 1 >>> a = weave.inline("return_val = Py::new_reference_to(Py::Int(a+1));",[’a’]) >>> a 2 The return_val variable can also be used to return newly created values. This is possible by returning a tuple. The following trivial example illustrates how this can be done: # python version def multi_return(): return 1, ’2nd’ # C version. def c_multi_return(): code = """ py::tuple results(2); results[0] = 1; results[1] = "2nd"; return_val = results; """ return inline_tools.inline(code) The example is available in examples/tuple_return.py. It also has the dubious honor of demonstrating how much inline() can slow things down. The C version here is about 7-10 times slower than the Python version. Of course, something so trivial has no reason to be written in C anyway. The issue with locals() inline passes the locals() and globals() dictionaries from Python into the C++ function from the calling function. It extracts the variables that are used in the C++ code from these dictionaries, converts then to C++ variables, and then calculates using them. It seems like it would be trivial, then, after the calculations were finished to then insert the new values back into the locals() and globals() dictionaries so that the modified values were reflected in Python. Unfortunately, as pointed out by the Python manual, the locals() dictionary is not writable. I suspect locals() is not writable because there are some optimizations done to speed lookups of the local namespace. I’m guessing local lookups don’t always look at a dictionary to find values. Can someone “in the know” confirm or correct this? Another thing I’d like to know is whether there is a way to write to the local namespace of another stack frame from C/C++. If so, it would be possible to have some clean up code in compiled functions that wrote final values of variables in C++ back to the correct Python stack frame. I think this goes a long way toward making inline truely live up to its name. I don’t think we’ll get to the point of creating variables in Python for variables created in C – although I suppose with a C/C++ parser you could do that also. A quick look at the code weave generates a C++ file holding an extension function for each inline code snippet. These file names are generated using from the SHA-256 signature of the code snippet and saved to a location specified by the PYTHONCOMPILED environment variable (discussed later). The cpp files are generally about 200-400 lines long and include quite a few functions to support type conversions, etc. However, the actual compiled function is pretty simple. Below is the familiar printf example: >>> import weave >>> a = 1 >>> weave.inline(’printf("%d\\n",a);’,[’a’]) 1 And here is the extension function generated by inline: 1.16. Weave (scipy.weave) 139 SciPy Reference Guide, Release 0.13.0 static PyObject* compiled_func(PyObject*self, PyObject* args) { py::object return_val; int exception_occured = 0; PyObject *py__locals = NULL; PyObject *py__globals = NULL; PyObject *py_a; py_a = NULL; if(!PyArg_ParseTuple(args,"OO:compiled_func",&py__locals,&py__globals)) return NULL; try { PyObject* raw_locals = py_to_raw_dict(py__locals,"_locals"); PyObject* raw_globals = py_to_raw_dict(py__globals,"_globals"); /* argument conversion code */ py_a = get_variable("a",raw_locals,raw_globals); int a = convert_to_int(py_a,"a"); /* inline code */ /* NDARRAY API VERSION 90907 */ printf("%d\n",a); /*I would like to fill in changed locals and globals here...*/ } catch(...) { return_val = py::object(); exception_occured = 1; } /* cleanup code */ if(!(PyObject*)return_val && !exception_occured) { return_val = Py_None; } return return_val.disown(); } Every inline function takes exactly two arguments – the local and global dictionaries for the current scope. All variable values are looked up out of these dictionaries. The lookups, along with all inline code execution, are done within a C++ try block. If the variables aren’t found, or there is an error converting a Python variable to the appropriate type in C++, an exception is raised. The C++ exception is automatically converted to a Python exception by SCXX and returned to Python. The py_to_int() function illustrates how the conversions and exception handling works. py_to_int first checks that the given PyObject* pointer is not NULL and is a Python integer. If all is well, it calls the Python API to convert the value to an int. Otherwise, it calls handle_bad_type() which gathers information about what went wrong and then raises a SCXX TypeError which returns to Python as a TypeError. int py_to_int(PyObject* py_obj,char* name) { if (!py_obj || !PyInt_Check(py_obj)) handle_bad_type(py_obj,"int", name); return (int) PyInt_AsLong(py_obj); } void handle_bad_type(PyObject* py_obj, char* good_type, char* var_name) { char msg[500]; sprintf(msg,"received ’%s’ type instead of ’%s’ for variable ’%s’", find_type(py_obj),good_type,var_name); throw Py::TypeError(msg); } 140 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 char* find_type(PyObject* py_obj) { if(py_obj == NULL) return "C NULL value"; if(PyCallable_Check(py_obj)) return "callable"; if(PyString_Check(py_obj)) return "string"; if(PyInt_Check(py_obj)) return "int"; if(PyFloat_Check(py_obj)) return "float"; if(PyDict_Check(py_obj)) return "dict"; if(PyList_Check(py_obj)) return "list"; if(PyTuple_Check(py_obj)) return "tuple"; if(PyFile_Check(py_obj)) return "file"; if(PyModule_Check(py_obj)) return "module"; //should probably do more interagation (and thinking) on these. if(PyCallable_Check(py_obj) && PyInstance_Check(py_obj)) return "callable"; if(PyInstance_Check(py_obj)) return "instance"; if(PyCallable_Check(py_obj)) return "callable"; return "unknown type"; } Since the inline is also executed within the try/catch block, you can use CXX exceptions within your code. It is usually a bad idea to directly return from your code, even if an error occurs. This skips the clean up section of the extension function. In this simple example, there isn’t any clean up code, but in more complicated examples, there may be some reference counting that needs to be taken care of here on converted variables. To avoid this, either uses exceptions or set return_val to NULL and use if/then’s to skip code after errors. Technical Details There are several main steps to using C/C++ code within Python: 1. Type conversion 2. Generating C/C++ code 3. Compile the code to an extension module 4. Catalog (and cache) the function for future use Items 1 and 2 above are related, but most easily discussed separately. Type conversions are customizable by the user if needed. Understanding them is pretty important for anything beyond trivial uses of inline. Generating the C/C++ code is handled by ext_function and ext_module classes and . For the most part, compiling the code is handled by distutils. Some customizations were needed, but they were relatively minor and do not require changes to distutils itself. Cataloging is pretty simple in concept, but surprisingly required the most code to implement (and still likely needs some work). So, this section covers items 1 and 4 from the list. Item 2 is covered later in the chapter covering the ext_tools module, and distutils is covered by a completely separate document xxx. Passing Variables in/out of the C/C++ code Note: Passing variables into the C code is pretty straight forward, but there are subtlties to how variable modifications in C are returned to Python. see Returning Values for a more thorough discussion of this issue. Type Conversions 1.16. Weave (scipy.weave) 141 SciPy Reference Guide, Release 0.13.0 Note: Maybe xxx_converter instead of xxx_specification is a more descriptive name. Might change in future version? By default, inline() makes the following type conversions between Python and C++ types. Table 1.9: Default Data Type Conversions Python int float complex string list dict tuple file callable instance numpy.ndarray wxXXX C++ int double std::complex py::string py::list py::dict py::tuple FILE* py::object py::object PyArrayObject* wxXXX* The Py:: namespace is defined by the SCXX library which has C++ class equivalents for many Python types. std:: is the namespace of the standard library in C++. Note: • I haven’t figured out how to handle long int yet (I think they are currenlty converted to int - - check this). • Hopefully VTK will be added to the list soon Python to C++ conversions fill in code in several locations in the generated inline extension function. Below is the basic template for the function. This is actually the exact code that is generated by calling weave.inline(""). The /* inline code */ section is filled with the code passed to the inline() function call. The /*argument conversion code*/ and /* cleanup code */ sections are filled with code that handles conversion from Python to C++ types and code that deallocates memory or manipulates reference counts before the function returns. The following sections demonstrate how these two areas are filled in by the default conversion methods. * Note: I’m not sure I have reference counting correct on a few of these. The only thing I increase/decrease the ref count on is NumPy arrays. If you see an issue, please let me know. NumPy Argument Conversion Integer, floating point, and complex arguments are handled in a very similar fashion. Consider the following inline function that has a single integer variable passed in: >>> a = 1 >>> inline("",[’a’]) The argument conversion code inserted for a is: /* argument conversion code */ int a = py_to_int (get_variable("a",raw_locals,raw_globals),"a"); get_variable() reads the variable a from the local and global namespaces. py_to_int() has the following form: 142 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 static int py_to_int(PyObject* py_obj,char* name) { if (!py_obj || !PyInt_Check(py_obj)) handle_bad_type(py_obj,"int", name); return (int) PyInt_AsLong(py_obj); } Similarly, the float and complex conversion routines look like: static double py_to_float(PyObject* py_obj,char* name) { if (!py_obj || !PyFloat_Check(py_obj)) handle_bad_type(py_obj,"float", name); return PyFloat_AsDouble(py_obj); } static std::complex py_to_complex(PyObject* py_obj,char* name) { if (!py_obj || !PyComplex_Check(py_obj)) handle_bad_type(py_obj,"complex", name); return std::complex(PyComplex_RealAsDouble(py_obj), PyComplex_ImagAsDouble(py_obj)); } NumPy conversions do not require any clean up code. String, List, Tuple, and Dictionary Conversion Strings, Lists, Tuples and Dictionary conversions are all converted to SCXX types by default. For the following code, >>> a = [1] >>> inline("",[’a’]) The argument conversion code inserted for a is: /* argument conversion code */ Py::List a = py_to_list(get_variable("a",raw_locals,raw_globals),"a"); get_variable() reads the variable a from the local and global namespaces. py_to_list() and its friends have the following form: static Py::List py_to_list(PyObject* py_obj,char* name) { if (!py_obj || !PyList_Check(py_obj)) handle_bad_type(py_obj,"list", name); return Py::List(py_obj); } static Py::String py_to_string(PyObject* py_obj,char* name) { if (!PyString_Check(py_obj)) handle_bad_type(py_obj,"string", name); return Py::String(py_obj); } static Py::Dict py_to_dict(PyObject* py_obj,char* name) { if (!py_obj || !PyDict_Check(py_obj)) handle_bad_type(py_obj,"dict", name); return Py::Dict(py_obj); 1.16. Weave (scipy.weave) 143 SciPy Reference Guide, Release 0.13.0 } static Py::Tuple py_to_tuple(PyObject* py_obj,char* name) { if (!py_obj || !PyTuple_Check(py_obj)) handle_bad_type(py_obj,"tuple", name); return Py::Tuple(py_obj); } SCXX handles reference counts on for strings, lists, tuples, and dictionaries, so clean up code isn’t necessary. File Conversion For the following code, >>> a = open("bob",’w’) >>> inline("",[’a’]) The argument conversion code is: /* argument conversion code */ PyObject* py_a = get_variable("a",raw_locals,raw_globals); FILE* a = py_to_file(py_a,"a"); get_variable() reads the variable a from the local and global namespaces. py_to_file() converts PyObject* to a FILE* and increments the reference count of the PyObject*: FILE* py_to_file(PyObject* py_obj, char* name) { if (!py_obj || !PyFile_Check(py_obj)) handle_bad_type(py_obj,"file", name); Py_INCREF(py_obj); return PyFile_AsFile(py_obj); } Because the PyObject* was incremented, the clean up code needs to decrement the counter /* cleanup code */ Py_XDECREF(py_a); Its important to understand that file conversion only works on actual files – i.e. ones created using the open() command in Python. It does not support converting arbitrary objects that support the file interface into C FILE* pointers. This can affect many things. For example, in initial printf() examples, one might be tempted to solve the problem of C and Python IDE’s (PythonWin, PyCrust, etc.) writing to different stdout and stderr by using fprintf() and passing in sys.stdout and sys.stderr. For example, instead of >>> weave.inline(’printf("hello\\n");’) You might try: >>> buf = sys.stdout >>> weave.inline(’fprintf(buf,"hello\\n");’,[’buf’]) This will work as expected from a standard python interpreter, but in PythonWin, the following occurs: >>> buf = sys.stdout >>> weave.inline(’fprintf(buf,"hello\\n");’,[’buf’]) 144 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 The traceback tells us that inline() was unable to convert ‘buf’ to a C++ type (If instance conversion was implemented, the error would have occurred at runtime instead). Why is this? Let’s look at what the buf object really is: >>> buf pywin.framework.interact.InteractiveView instance at 00EAD014 PythonWin has reassigned sys.stdout to a special object that implements the Python file interface. This works great in Python, but since the special object doesn’t have a FILE* pointer underlying it, fprintf doesn’t know what to do with it (well this will be the problem when instance conversion is implemented...). Callable, Instance, and Module Conversion Note: Need to look into how ref counts should be handled. Also, Instance and Module conversion are not currently implemented. >>> def a(): pass >>> inline("",[’a’]) Callable and instance variables are converted to PyObject*. Nothing is done to their reference counts. /* argument conversion code */ PyObject* a = py_to_callable(get_variable("a",raw_locals,raw_globals),"a"); get_variable() reads the variable a from the local and global namespaces. The py_to_callable() and py_to_instance() don’t currently increment the ref count. PyObject* py_to_callable(PyObject* py_obj, char* name) { if (!py_obj || !PyCallable_Check(py_obj)) handle_bad_type(py_obj,"callable", name); return py_obj; } PyObject* py_to_instance(PyObject* py_obj, char* name) { if (!py_obj || !PyFile_Check(py_obj)) handle_bad_type(py_obj,"instance", name); return py_obj; } There is no cleanup code for callables, modules, or instances. Customizing Conversions Converting from Python to C++ types is handled by xxx_specification classes. A type specification class actually serve in two related but different roles. The first is in determining whether a Python variable that needs to be converted should be represented by the given class. The second is as a code generator that generates C++ code needed to convert from Python to C++ types for a specific variable. When >>> a = 1 >>> weave.inline(’printf("%d",a);’,[’a’]) is called for the first time, the code snippet has to be compiled. In this process, the variable ‘a’ is tested against a list of type specifications (the default list is stored in weave/ext_tools.py). The first specification in the list is used to represent the variable. 1.16. Weave (scipy.weave) 145 SciPy Reference Guide, Release 0.13.0 Examples of xxx_specification are scattered throughout numerous “xxx_spec.py” files in the weave package. Closely related to the xxx_specification classes are yyy_info classes. These classes contain compiler, header, and support code information necessary for including a certain set of capabilities (such as blitz++ or CXX support) in a compiled module. xxx_specification classes have one or more yyy_info classes associated with them. If you’d like to define your own set of type specifications, the current best route is to examine some of the existing spec and info files. Maybe looking over sequence_spec.py and cxx_info.py are a good place to start. After defining specification classes, you’ll need to pass them into inline using the type_factories argument. A lot of times you may just want to change how a specific variable type is represented. Say you’d rather have Python strings converted to std::string or maybe char* instead of using the CXX string object, but would like all other type conversions to have default behavior. This requires that a new specification class that handles strings is written and then prepended to a list of the default type specifications. Since it is closer to the front of the list, it effectively overrides the default string specification. The following code demonstrates how this is done: ... The Catalog catalog.py has a class called catalog that helps keep track of previously compiled functions. This prevents inline() and related functions from having to compile functions everytime they are called. Instead, catalog will check an in memory cache to see if the function has already been loaded into python. If it hasn’t, then it starts searching through persisent catalogs on disk to see if it finds an entry for the given function. By saving information about compiled functions to disk, it isn’t necessary to re-compile functions everytime you stop and restart the interpreter. Functions are compiled once and stored for future use. When inline(cpp_code) is called the following things happen: 1. A fast local cache of functions is checked for the last function called for cpp_code. If an entry for cpp_code doesn’t exist in the cache or the cached function call fails (perhaps because the function doesn’t have compatible types) then the next step is to check the catalog. 2. The catalog class also keeps an in-memory cache with a list of all the functions compiled for cpp_code. If cpp_code has ever been called, then this cache will be present (loaded from disk). If the cache isn’t present, then it is loaded from disk. If the cache is present, each function in the cache is called until one is found that was compiled for the correct argument types. If none of the functions work, a new function is compiled with the given argument types. This function is written to the on-disk catalog as well as into the in-memory cache. 3. When a lookup for cpp_code fails, the catalog looks through the on-disk function catalogs for the entries. The PYTHONCOMPILED variable determines where to search for these catalogs and in what order. If PYTHONCOMPILED is not present several platform dependent locations are searched. All functions found for cpp_code in the path are loaded into the in-memory cache with functions found earlier in the search path closer to the front of the call list. If the function isn’t found in the on-disk catalog, then the function is compiled, written to the first writable directory in the PYTHONCOMPILED path, and also loaded into the in-memory cache. Function Storage Function caches are stored as dictionaries where the key is the entire C++ code string and the value is either a single function (as in the “level 1” cache) or a list of functions (as in the main catalog cache). On disk catalogs are stored in the same manor using standard Python shelves. Early on, there was a question as to whether md5 checksums of the C++ code strings should be used instead of the actual code strings. I think this is the route inline Perl took. Some (admittedly quick) tests of the md5 vs. the entire string showed that using the entire string was at least a factor of 3 or 4 faster for Python. I think this is because it is more time consuming to compute the md5 value than it is to do look-ups of long strings in the dictionary. Look at the examples/md5_speed.py file for the test run. 146 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 Catalog search paths and the PYTHONCOMPILED variable The default location for catalog files on Unix is is ~/.pythonXX_compiled where XX is version of Python being used. If this directory doesn’t exist, it is created the first time a catalog is used. The directory must be writable. If, for any reason it isn’t, then the catalog attempts to create a directory based on your user id in the /tmp directory. The directory permissions are set so that only you have access to the directory. If this fails, I think you’re out of luck. I don’t think either of these should ever fail though. On Windows, a directory called pythonXX_compiled is created in the user’s temporary directory. The actual catalog file that lives in this directory is a Python shelf with a platform specific name such as “nt21compiled_catalog” so that multiple OSes can share the same file systems without trampling on each other. Along with the catalog file, the .cpp and .so or .pyd files created by inline will live in this directory. The catalog file simply contains keys which are the C++ code strings with values that are lists of functions. The function lists point at functions within these compiled modules. Each function in the lists executes the same C++ code string, but compiled for different input variables. You can use the PYTHONCOMPILED environment variable to specify alternative locations for compiled functions. On Unix this is a colon (‘:’) separated list of directories. On windows, it is a (‘;’) separated list of directories. These directories will be searched prior to the default directory for a compiled function catalog. Also, the first writable directory in the list is where all new compiled function catalogs, .cpp and .so or .pyd files are written. Relative directory paths (‘.’ and ‘..’) should work fine in the PYTHONCOMPILED variable as should environement variables. There is a “special” path variable called MODULE that can be placed in the PYTHONCOMPILED variable. It specifies that the compiled catalog should reside in the same directory as the module that called it. This is useful if an admin wants to build a lot of compiled functions during the build of a package and then install them in site-packages along with the package. User’s who specify MODULE in their PYTHONCOMPILED variable will have access to these compiled functions. Note, however, that if they call the function with a set of argument types that it hasn’t previously been built for, the new function will be stored in their default directory (or some other writable directory in the PYTHONCOMPILED path) because the user will not have write access to the site-packages directory. An example of using the PYTHONCOMPILED path on bash follows: PYTHONCOMPILED=MODULE:/some/path;export PYTHONCOMPILED; If you are using python21 on linux, and the module bob.py in site-packages has a compiled function in it, then the catalog search order when calling that function for the first time in a python session would be: /usr/lib/python21/site-packages/linuxpython_compiled /some/path/linuxpython_compiled ~/.python21_compiled/linuxpython_compiled The default location is always included in the search path. Note: hmmm. see a possible problem here. I should probably make a sub- directory such as /usr/lib/python21/sitepackages/python21_compiled/linuxpython_compiled so that library files compiled with python21 are tried to link with python22 files in some strange scenarios. Need to check this. The in-module cache (in weave.inline_tools reduces the overhead of calling inline functions by about a factor of 2. It can be reduced a little more for type loop calls where the same function is called over and over again if the cache was a single value instead of a dictionary, but the benefit is very small (less than 5%) and the utility is quite a bit less. So, we’ll stick with a dictionary as the cache. 1.16.8 Blitz Note: most of this section is lifted from old documentation. It should be pretty accurate, but there may be a few discrepancies. 1.16. Weave (scipy.weave) 147 SciPy Reference Guide, Release 0.13.0 weave.blitz() compiles NumPy Python expressions for fast execution. For most applications, compiled expressions should provide a factor of 2-10 speed-up over NumPy arrays. Using compiled expressions is meant to be as unobtrusive as possible and works much like pythons exec statement. As an example, the following code fragment takes a 5 point average of the 512x512 2d image, b, and stores it in array, a: from scipy import * # or from NumPy import * a = ones((512,512), Float64) b = ones((512,512), Float64) # ...do some stuff to fill in b... # now average a[1:-1,1:-1] = (b[1:-1,1:-1] + b[2:,1:-1] + b[:-2,1:-1] \ + b[1:-1,2:] + b[1:-1,:-2]) / 5. To compile the expression, convert the expression to a string by putting quotes around it and then use weave.blitz: import weave expr = "a[1:-1,1:-1] = (b[1:-1,1:-1] + b[2:,1:-1] + b[:-2,1:-1]" \ "+ b[1:-1,2:] + b[1:-1,:-2]) / 5." weave.blitz(expr) The first time weave.blitz is run for a given expression and set of arguements, C++ code that accomplishes the exact same task as the Python expression is generated and compiled to an extension module. This can take up to a couple of minutes depending on the complexity of the function. Subsequent calls to the function are very fast. Futher, the generated module is saved between program executions so that the compilation is only done once for a given expression and associated set of array types. If the given expression is executed with a new set of array types, the code most be compiled again. This does not overwrite the previously compiled function – both of them are saved and available for exectution. The following table compares the run times for standard NumPy code and compiled code for the 5 point averaging. Method Run Time (seconds) Standard NumPy 0.46349 blitz (1st time compiling) 78.95526 blitz (subsequent calls) 0.05843 (factor of 8 speedup) These numbers are for a 512x512 double precision image run on a 400 MHz Celeron processor under RedHat Linux 6.2. Because of the slow compile times, its probably most effective to develop algorithms as you usually do using the capabilities of scipy or the NumPy module. Once the algorithm is perfected, put quotes around it and execute it using weave.blitz. This provides the standard rapid prototyping strengths of Python and results in algorithms that run close to that of hand coded C or Fortran. Requirements Currently, the weave.blitz has only been tested under Linux with gcc-2.95-3 and on Windows with Mingw32 (2.95.2). Its compiler requirements are pretty heavy duty (see the blitz++ home page), so it won’t work with just any compiler. Particularly MSVC++ isn’t up to snuff. A number of other compilers such as KAI++ will also work, but my suspicions are that gcc will get the most use. Limitations 1. Currently, weave.blitz handles all standard mathematical operators except for the ** power operator. The built-in trigonmetric, log, floor/ceil, and fabs functions might work (but haven’t been tested). It also handles all types of array indexing supported by the NumPy module. numarray’s NumPy compatible array indexing modes are likewise supported, but numarray’s enhanced (array based) indexing modes are not supported. 148 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 weave.blitz does not currently support operations that use array broadcasting, nor have any of the special purpose functions in NumPy such as take, compress, etc. been implemented. Note that there are no obvious reasons why most of this functionality cannot be added to scipy.weave, so it will likely trickle into future versions. Using slice() objects directly instead of start:stop:step is also not supported. 2. Currently Python only works on expressions that include assignment such as >>> result = b + c + d This means that the result array must exist before calling weave.blitz. Future versions will allow the following: >>> result = weave.blitz_eval("b + c + d") 3. weave.blitz works best when algorithms can be expressed in a “vectorized” form. Algorithms that have a large number of if/thens and other conditions are better hand-written in C or Fortran. Further, the restrictions imposed by requiring vectorized expressions sometimes preclude the use of more efficient data structures or algorithms. For maximum speed in these cases, hand-coded C or Fortran code is the only way to go. 4. weave.blitz can produce different results than NumPy in certain situations. It can happen when the array receiving the results of a calculation is also used during the calculation. The NumPy behavior is to carry out the entire calculation on the right hand side of an equation and store it in a temporary array. This temprorary array is assigned to the array on the left hand side of the equation. blitz, on the other hand, does a “running” calculation of the array elements assigning values from the right hand side to the elements on the left hand side immediately after they are calculated. Here is an example, provided by Prabhu Ramachandran, where this happens: # 4 point average. >>> expr = "u[1:-1, 1:-1] = (u[0:-2, 1:-1] + u[2:, 1:-1] + \ ... "u[1:-1,0:-2] + u[1:-1, 2:])*0.25" >>> u = zeros((5, 5), ’d’); u[0,:] = 100 >>> exec (expr) >>> u array([[ 100., 100., 100., 100., 100.], [ 0., 25., 25., 25., 0.], [ 0., 0., 0., 0., 0.], [ 0., 0., 0., 0., 0.], [ 0., 0., 0., 0., 0.]]) >>> u = zeros((5, 5), ’d’); u[0,:] = 100 >>> weave.blitz (expr) >>> u array([[ 100. , 100. , 100. [ 0. , 25. , 31.25 [ 0. , 6.25 , 9.375 [ 0. , 1.5625 , 2.734375 [ 0. , 0. , 0. , , , , , 100. , 32.8125 , 10.546875 , 3.3203125, 0. , 100. ], 0. ], 0. ], 0. ], 0. ]]) You can prevent this behavior by using a temporary array. >>> u = zeros((5, 5), ’d’); u[0,:] = 100 >>> temp = zeros((4, 4), ’d’); >>> expr = "temp = (u[0:-2, 1:-1] + u[2:, 1:-1] + "\ ... "u[1:-1,0:-2] + u[1:-1, 2:])*0.25;"\ ... "u[1:-1,1:-1] = temp" >>> weave.blitz (expr) >>> u array([[ 100., 100., 100., 100., 100.], [ 0., 25., 25., 25., 0.], [ 0., 0., 0., 0., 0.], 1.16. Weave (scipy.weave) 149 SciPy Reference Guide, Release 0.13.0 [ [ 0., 0., 0., 0., 0., 0., 0., 0., 0.], 0.]]) 5. One other point deserves mention lest people be confused. weave.blitz is not a general purpose Python->C compiler. It only works for expressions that contain NumPy arrays and/or Python scalar values. This focused scope concentrates effort on the compuationally intensive regions of the program and sidesteps the difficult issues associated with a general purpose Python->C compiler. NumPy efficiency issues: What compilation buys you Some might wonder why compiling NumPy expressions to C++ is beneficial since operations on NumPy array operations are already executed within C loops. The problem is that anything other than the simplest expression are executed in less than optimal fashion. Consider the following NumPy expression: a = 1.2 * b + c * d When NumPy calculates the value for the 2d array, a, it does the following steps: temp1 = 1.2 * b temp2 = c * d a = temp1 + temp2 Two things to note. Since c is an (perhaps large) array, a large temporary array must be created to store the results of 1.2 * b. The same is true for temp2. Allocation is slow. The second thing is that we have 3 loops executing, one to calculate temp1, one for temp2 and one for adding them up. A C loop for the same problem might look like: for(int i = 0; i < M; i++) for(int j = 0; j < N; j++) a[i,j] = 1.2 * b[i,j] + c[i,j] * d[i,j] Here, the 3 loops have been fused into a single loop and there is no longer a need for a temporary array. This provides a significant speed improvement over the above example (write me and tell me what you get). So, converting NumPy expressions into C/C++ loops that fuse the loops and eliminate temporary arrays can provide big gains. The goal, then, is to convert NumPy expression to C/C++ loops, compile them in an extension module, and then call the compiled extension function. The good news is that there is an obvious correspondence between the NumPy expression above and the C loop. The bad news is that NumPy is generally much more powerful than this simple example illustrates and handling all possible indexing possibilities results in loops that are less than straightforward to write. (Take a peek at NumPy for confirmation). Luckily, there are several available tools that simplify the process. The Tools weave.blitz relies heavily on several remarkable tools. On the Python side, the main facilitators are Jermey Hylton’s parser module and Travis Oliphant’s NumPy module. On the compiled language side, Todd Veldhuizen’s blitz++ array library, written in C++ (shhhh. don’t tell David Beazley), does the heavy lifting. Don’t assume that, because it’s C++, it’s much slower than C or Fortran. Blitz++ uses a jaw dropping array of template techniques (metaprogramming, template expression, etc) to convert innocent-looking and readable C++ expressions into to code that usually executes within a few percentage points of Fortran code for the same problem. This is good. Unfortunately all the template raz-ma-taz is very expensive to compile, so the 200 line extension modules often take 2 or more minutes to compile. This isn’t so good. weave.blitz works to minimize this issue by remembering where compiled modules live and reusing them instead of re-compiling every time a program is re-run. Parser Tearing NumPy expressions apart, examining the pieces, and then rebuilding them as C++ (blitz) expressions requires a parser of some sort. I can imagine someone attacking this problem with regular expressions, but it’d likely be ugly 150 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 and fragile. Amazingly, Python solves this problem for us. It actually exposes its parsing engine to the world through the parser module. The following fragment creates an Abstract Syntax Tree (AST) object for the expression and then converts to a (rather unpleasant looking) deeply nested list representation of the tree. >>> import parser >>> import scipy.weave.misc >>> ast = parser.suite("a = b * c + d") >>> ast_list = ast.tolist() >>> sym_list = scipy.weave.misc.translate_symbols(ast_list) >>> pprint.pprint(sym_list) [’file_input’, [’stmt’, [’simple_stmt’, [’small_stmt’, [’expr_stmt’, [’testlist’, [’test’, [’and_test’, [’not_test’, [’comparison’, [’expr’, [’xor_expr’, [’and_expr’, [’shift_expr’, [’arith_expr’, [’term’, [’factor’, [’power’, [’atom’, [’NAME’, ’a’]]]]]]]]]]]]]]], [’EQUAL’, ’=’], [’testlist’, [’test’, [’and_test’, [’not_test’, [’comparison’, [’expr’, [’xor_expr’, [’and_expr’, [’shift_expr’, [’arith_expr’, [’term’, [’factor’, [’power’, [’atom’, [’NAME’, ’b’]]]], [’STAR’, ’*’], [’factor’, [’power’, [’atom’, [’NAME’, ’c’]]]]], [’PLUS’, ’+’], [’term’, [’factor’, [’power’, [’atom’, [’NAME’, ’d’]]]]]]]]]]]]]]]]], [’NEWLINE’, ’’]]], [’ENDMARKER’, ’’]] Despite its looks, with some tools developed by Jermey H., it’s possible to search these trees for specific patterns (sub-trees), extract the sub-tree, manipulate them converting python specific code fragments to blitz code fragments, and then re-insert it in the parse tree. The parser module documentation has some details on how to do this. Traversing the new blitzified tree, writing out the terminal symbols as you go, creates our new blitz++ expression string. Blitz and NumPy The other nice discovery in the project is that the data structure used for NumPy arrays and blitz arrays is nearly identical. NumPy stores “strides” as byte offsets and blitz stores them as element offsets, but other than that, they are the same. Further, most of the concept and capabilities of the two libraries are remarkably similar. It is satisfying that two completely different implementations solved the problem with similar basic architectures. It is also fortuitous. 1.16. Weave (scipy.weave) 151 SciPy Reference Guide, Release 0.13.0 The work involved in converting NumPy expressions to blitz expressions was greatly diminished. As an example, consider the code for slicing an array in Python with a stride: >>> a = b[0:4:2] + c >>> a [0,2,4] In Blitz it is as follows: Array<2,int> b(10); Array<2,int> c(3); // ... Array<2,int> a = b(Range(0,3,2)) + c; Here the range object works exactly like Python slice objects with the exception that the top index (3) is inclusive where as Python’s (4) is exclusive. Other differences include the type declarations in C++ and parentheses instead of brackets for indexing arrays. Currently, weave.blitz handles the inclusive/exclusive issue by subtracting one from upper indices during the translation. An alternative that is likely more robust/maintainable in the long run is to write a PyRange class that behaves like Python’s range. This is likely very easy. The stock blitz also doesn’t handle negative indices in ranges. The current implementation of the blitz() has a partial solution to this problem. It calculates and index that starts with a ‘-‘ sign by subtracting it from the maximum index in the array so that: upper index limit /-----\ b[:-1] -> b(Range(0,Nb[0]-1-1)) This approach fails, however, when the top index is calculated from other values. In the following scenario, if i+j evaluates to a negative value, the compiled code will produce incorrect results and could even core-dump. Right now, all calculated indices are assumed to be positive. b[:i-j] -> b(Range(0,i+j)) A solution is to calculate all indices up front using if/then to handle the +/- cases. This is a little work and results in more code, so it hasn’t been done. I’m holding out to see if blitz++ can be modified to handle negative indexing, but haven’t looked into how much effort is involved yet. While it needs fixin’, I don’t think there is a ton of code where this is an issue. The actual translation of the Python expressions to blitz expressions is currently a two part process. First, all x:y:z slicing expression are removed from the AST, converted to slice(x,y,z) and re-inserted into the tree. Any math needed on these expressions (subtracting from the maximum index, etc.) are also preformed here. _beg and _end are used as special variables that are defined as blitz::fromBegin and blitz::toEnd. a[i+j:i+j+1,:] = b[2:3,:] becomes a more verbose: a[slice(i+j,i+j+1),slice(_beg,_end)] = b[slice(2,3),slice(_beg,_end)] The second part does a simple string search/replace to convert to a blitz expression with the following translations: slice(_beg,_end) slice [ ] _stp -> -> -> -> -> _all # not strictly needed, but cuts down on code. blitz::Range ( ) 1 _all is defined in the compiled function as blitz::Range.all(). These translations could of course happen directly in the syntax tree. But the string replacement is slightly easier. Note that namespaces are maintained in the 152 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 C++ code to lessen the likelihood of name clashes. Currently no effort is made to detect name clashes. A good rule of thumb is don’t use values that start with ‘_’ or ‘py_’ in compiled expressions and you’ll be fine. Type definitions and coersion So far we’ve glossed over the dynamic vs. static typing issue between Python and C++. In Python, the type of value that a variable holds can change through the course of program execution. C/C++, on the other hand, forces you to declare the type of value a variables will hold prior at compile time. weave.blitz handles this issue by examining the types of the variables in the expression being executed, and compiling a function for those explicit types. For example: a = ones((5,5),Float32) b = ones((5,5),Float32) weave.blitz("a = a + b") When compiling this expression to C++, weave.blitz sees that the values for a and b in the local scope have type Float32, or ‘float’ on a 32 bit architecture. As a result, it compiles the function using the float type (no attempt has been made to deal with 64 bit issues). What happens if you call a compiled function with array types that are different than the ones for which it was originally compiled? No biggie, you’ll just have to wait on it to compile a new version for your new types. This doesn’t overwrite the old functions, as they are still accessible. See the catalog section in the inline() documentation to see how this is handled. Suffice to say, the mechanism is transparent to the user and behaves like dynamic typing with the occasional wait for compiling newly typed functions. When working with combined scalar/array operations, the type of the array is always used. This is similar to the savespace flag that was recently added to NumPy. This prevents issues with the following expression perhaps unexpectedly being calculated at a higher (more expensive) precision that can occur in Python: >>> a = array((1,2,3),typecode = Float32) >>> b = a * 2.1 # results in b being a Float64 array. In this example, >>> a = ones((5,5),Float32) >>> b = ones((5,5),Float32) >>> weave.blitz("b = a * 2.1") the 2.1 is cast down to a float before carrying out the operation. If you really want to force the calculation to be a double, define a and b as double arrays. One other point of note. Currently, you must include both the right hand side and left hand side (assignment side) of your equation in the compiled expression. Also, the array being assigned to must be created prior to calling weave.blitz. I’m pretty sure this is easily changed so that a compiled_eval expression can be defined, but no effort has been made to allocate new arrays (and decern their type) on the fly. Cataloging Compiled Functions See The Catalog section in the weave.inline() documentation. Checking Array Sizes Surprisingly, one of the big initial problems with compiled code was making sure all the arrays in an operation were of compatible type. The following case is trivially easy: 1.16. Weave (scipy.weave) 153 SciPy Reference Guide, Release 0.13.0 a = b + c It only requires that arrays a, b, and c have the same shape. However, expressions like: a[i+j:i+j+1,:] = b[2:3,:] + c are not so trivial. Since slicing is involved, the size of the slices, not the input arrays, must be checked. Broadcasting complicates things further because arrays and slices with different dimensions and shapes may be compatible for math operations (broadcasting isn’t yet supported by weave.blitz). Reductions have a similar effect as their results are different shapes than their input operand. The binary operators in NumPy compare the shapes of their two operands just before they operate on them. This is possible because NumPy treats each operation independently. The intermediate (temporary) arrays created during sub-operations in an expression are tested for the correct shape before they are combined by another operation. Because weave.blitz fuses all operations into a single loop, this isn’t possible. The shape comparisons must be done and guaranteed compatible before evaluating the expression. The solution chosen converts input arrays to “dummy arrays” that only represent the dimensions of the arrays, not the data. Binary operations on dummy arrays check that input array sizes are comptible and return a dummy array with the size correct size. Evaluating an expression of dummy arrays traces the changing array sizes through all operations and fails if incompatible array sizes are ever found. The machinery for this is housed in weave.size_check. It basically involves writing a new class (dummy array) and overloading its math operators to calculate the new sizes correctly. All the code is in Python and there is a fair amount of logic (mainly to handle indexing and slicing) so the operation does impose some overhead. For large arrays (ie. 50x50x50), the overhead is negligible compared to evaluating the actual expression. For small arrays (ie. 16x16), the overhead imposed for checking the shapes with this method can cause the weave.blitz to be slower than evaluating the expression in Python. What can be done to reduce the overhead? (1) The size checking code could be moved into C. This would likely remove most of the overhead penalty compared to NumPy (although there is also some calling overhead), but no effort has been made to do this. (2) You can also call weave.blitz with check_size=0 and the size checking isn’t done. However, if the sizes aren’t compatible, it can cause a core-dump. So, foregoing size_checking isn’t advisable until your code is well debugged. Creating the Extension Module weave.blitz uses the same machinery as weave.inline to build the extension module. The only difference is the code included in the function is automatically generated from the NumPy array expression instead of supplied by the user. 1.16.9 Extension Modules weave.inline and weave.blitz are high level tools that generate extension modules automatically. Under the covers, they use several classes from weave.ext_tools to help generate the extension module. The main two classes are ext_module and ext_function (I’d like to add ext_class and ext_method also). These classes simplify the process of generating extension modules by handling most of the “boiler plate” code automatically. Note: inline actually sub-classes weave.ext_tools.ext_function to generate slightly different code than the standard ext_function. The main difference is that the standard class converts function arguments to C types, while inline always has two arguments, the local and global dicts, and the grabs the variables that need to be convereted to C from these. 154 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 A Simple Example The following simple example demonstrates how to build an extension module within a Python function: # examples/increment_example.py from weave import ext_tools def build_increment_ext(): """ Build a simple extension with functions that increment numbers. The extension will be built in the local directory. """ mod = ext_tools.ext_module(’increment_ext’) a = 1 # effectively a type declaration for ’a’ in the # following functions. ext_code = "return_val = Py::new_reference_to(Py::Int(a+1));" func = ext_tools.ext_function(’increment’,ext_code,[’a’]) mod.add_function(func) ext_code = "return_val = Py::new_reference_to(Py::Int(a+2));" func = ext_tools.ext_function(’increment_by_2’,ext_code,[’a’]) mod.add_function(func) mod.compile() The function build_increment_ext() creates an extension module named increment_ext and compiles it to a shared library (.so or .pyd) that can be loaded into Python.. increment_ext contains two functions, increment and increment_by_2. The first line of build_increment_ext(), mod = ext_tools.ext_module(‘increment_ext’) creates an ext_module instance that is ready to have ext_function instances added to it. ext_function instances are created much with a calling convention similar to weave.inline(). The most common call includes a C/C++ code snippet and a list of the arguments for the function. The following: ext_code = "return_val = Py::new_reference_to(Py::Int(a+1));" func = ext_tools.ext_function(’increment’,ext_code,[’a’]) creates a C/C++ extension function that is equivalent to the following Python function: def increment(a): return a + 1 A second method is also added to the module and then, mod.compile() is called to build the extension module. By default, the module is created in the current working directory. This example is available in the examples/increment_example.py file found in the weave directory. At the bottom of the file in the module’s “main” program, an attempt to import increment_ext without building it is made. If this fails (the module doesn’t exist in the PYTHONPATH), the module is built by calling build_increment_ext(). This approach only takes the time-consuming (a few seconds for this example) process of building the module if it hasn’t been built before. if __name__ == "__main__": try: import increment_ext except ImportError: build_increment_ext() 1.16. Weave (scipy.weave) 155 SciPy Reference Guide, Release 0.13.0 import increment_ext a = 1 print ’a, a+1:’, a, increment_ext.increment(a) print ’a, a+2:’, a, increment_ext.increment_by_2(a) Note: If we were willing to always pay the penalty of building the C++ code for a module, we could store the SHA-256 checksum of the C++ code along with some information about the compiler, platform, etc. Then, ext_module.compile() could try importing the module before it actually compiles it, check the SHA-256 checksum and other meta-data in the imported module with the meta-data of the code it just produced and only compile the code if the module didn’t exist or the meta-data didn’t match. This would reduce the above code to: if __name__ == "__main__": build_increment_ext() a = 1 print ’a, a+1:’, a, increment_ext.increment(a) print ’a, a+2:’, a, increment_ext.increment_by_2(a) Note: There would always be the overhead of building the C++ code, but it would only actually compile the code once. You pay a little in overhead and get cleaner “import” code. Needs some thought. If you run increment_example.py from the command line, you get the following: [eric@n0]$ python increment_example.py a, a+1: 1 2 a, a+2: 1 3 If the module didn’t exist before it was run, the module is created. If it did exist, it is just imported and used. Fibonacci Example examples/fibonacci.py provides a little more complex example of how to use ext_tools. Fibonacci numbers are a series of numbers where each number in the series is the sum of the previous two: 1, 1, 2, 3, 5, 8, etc. Here, the first two numbers in the series are taken to be 1. One approach to calculating Fibonacci numbers uses recursive function calls. In Python, it might be written as: def fib(a): if a <= 2: return 1 else: return fib(a-2) + fib(a-1) In C, the same function would look something like this: int fib(int a) { if(a <= 2) return 1; else return fib(a-2) + fib(a-1); } Recursion is much faster in C than in Python, so it would be beneficial to use the C version for fibonacci number calculations instead of the Python version. We need an extension function that calls this C function to do this. This 156 Chapter 1. SciPy Tutorial SciPy Reference Guide, Release 0.13.0 is possible by including the above code snippet as “support code” and then calling it from the extension function. Support code snippets (usually structure definitions, helper functions and the like) are inserted into the extension module C/C++ file before the extension function code. Here is how to build the C version of the fibonacci number generator: def build_fibonacci(): """ Builds an extension module with fibonacci calculators. """ mod = ext_tools.ext_module(’fibonacci_ext’) a = 1 # this is effectively a type declaration # recursive fibonacci in C fib_code = """ int fib1(int a) { if(a <= 2) return 1; else return fib1(a-2) + fib1(a-1); } """ ext_code = """ int val = fib1(a); return_val = Py::new_reference_to(Py::Int(val)); """ fib = ext_tools.ext_function(’fib’,ext_code,[’a’]) fib.customize.add_support_code(fib_code) mod.add_function(fib) mod.compile() XXX More about custom_info, and what xxx_info instances are good for. Note: recursion is not the fastest way to calculate fibonacci numbers, but this approach serves nicely for this example. 1.16.10 Customizing Type Conversions – Type Factories not written 1.16.11 Things I wish weave did It is possible to get name clashes if you uses a variable name that is already defined in a header automatically included (such as stdio.h) For instance, if you try to pass in a variable named stdout, you’ll get a cryptic error report due to the fact that stdio.h also defines the name. weave should probably try and handle this in some way. Other things... 1.16. Weave (scipy.weave) 157 SciPy Reference Guide, Release 0.13.0 158 Chapter 1. SciPy Tutorial CHAPTER TWO CONTRIBUTING TO SCIPY This document aims to give an overview of how to contribute to SciPy. It tries to answer commonly asked questions, and provide some insight into how the community process works in practice. Readers who are familiar with the SciPy community and are experienced Python coders may want to jump straight to the git workflow documentation. Note: You may want to check the latest version of this guide, https://github.com/scipy/scipy/blob/master/HACKING.rst.txt which is available at: 2.1 Contributing new code If you have been working with the scientific Python toolstack for a while, you probably have some code lying around of which you think “this could be useful for others too”. Perhaps it’s a good idea then to contribute it to SciPy or another open source project. The first question to ask is then, where does this code belong? That question is hard to answer here, so we start with a more specific one: what code is suitable for putting into SciPy? Almost all of the new code added to scipy has in common that it’s potentially useful in multiple scientific domains and it fits in the scope of existing scipy submodules. In principle new submodules can be added too, but this is far less common. For code that is specific to a single application, there may be an existing project that can use the code. Some scikits (scikit-learn, scikits-image, statsmodels, etc.) are good examples here; they have a narrower focus and because of that more domain-specific code than SciPy. Now if you have code that you would like to see included in SciPy, how do you go about it? After checking that your code can be distributed in SciPy under a compatible license (see FAQ for details), the first step is to discuss on the scipy-dev mailing list. All new features, as well as changes to existing code, are discussed and decided on there. You can, and probably should, already start this discussion before your code is finished. Assuming the outcome of the discussion on the mailing list is positive and you have a function or piece of code that does what you need it to do, what next? Before code is added to SciPy, it at least has to have good documentation, unit tests and correct code style. 1. Unit tests In principle you should aim to create unit tests that exercise all the code that you are adding. This gives some degree of confidence that your code runs correctly, also on Python versions and hardware or OSes that you don’t have available yourself. An extensive description of how to write unit tests is given in the NumPy testing guidelines. 2. Documentation Clear and complete documentation is essential in order for users to be able to find and understand the code. Documentation for individual functions and classes – which includes at least a basic description, type and meaning of all parameters and returns values, and usage examples in doctest format – is put in docstrings. Those docstrings can be read within the interpreter, and are compiled into a reference guide in html and pdf format. Higher-level documentation for key 159 SciPy Reference Guide, Release 0.13.0 (areas of) functionality is provided in tutorial format and/or in module docstrings. A guide on how to write documentation is given in how to document. 3. Code style Uniformity of style in which code is written is important to others trying to understand the code. SciPy follows the standard Python guidelines for code style, PEP8. In order to check that your code conforms to PEP8, you can use the pep8 package style checker. Most IDEs and text editors have settings that can help you follow PEP8, for example by translating tabs by four spaces. Using pyflakes to check your code is also a good idea. At the end of this document a checklist is given that may help to check if your code fulfills all requirements for inclusion in SciPy. Another question you may have is: where exactly do I put my code? To answer this, it is useful to understand how the SciPy public API (application programming interface) is defined. For most modules the API is two levels deep, which means your new function should appear as scipy.submodule.my_new_func. my_new_func can be put in an existing or new file under /scipy/ /, its name is added to the __all__ list in that file (which lists all public functions in the file), and those public functions are then imported in /scipy/ /__init__.py. Any private functions/classes should have a leading underscore (_) in their name. A more detailed description of what the public API of SciPy is, is given in SciPy API. Once you think your code is ready for inclusion in SciPy, you can send a pull request (PR) on Github. We won’t go into the details of how to work with git here, this is described well in the git workflow section of the NumPy documentation and on the Github help pages. When you send the PR for a new feature, be sure to also mention this on the scipy-dev mailing list. This can prompt interested people to help review your PR. Assuming that you already got positive feedback before on the general idea of your code/feature, the purpose of the code review is to ensure that the code is correct, efficient and meets the requirements outlined above. In many cases the code review happens relatively quickly, but it’s possible that it stalls. If you have addressed all feedback already given, it’s perfectly fine to ask on the mailing list again for review (after a reasonable amount of time, say a couple of weeks, has passed). Once the review is completed, the PR is merged into the “master” branch of SciPy. The above describes the requirements and process for adding code to SciPy. It doesn’t yet answer the question though how decisions are made exactly. The basic answer is: decisions are made by consensus, by everyone who chooses to participate in the discussion on the mailing list. This includes developers, other users and yourself. Aiming for consensus in the discussion is important – SciPy is a project by and for the scientific Python community. In those rare cases that agreement cannot be reached, the maintainers of the module in question can decide the issue. 2.2 Contributing by helping maintain existing code The previous section talked specifically about adding new functionality to SciPy. A large part of that discussion also applies to maintenance of existing code. Maintenance means fixing bugs, improving code quality or style, documenting existing functionality better, adding missing unit tests, keeping build scripts up-to-date, etc. The SciPy issue list contains all reported bugs, build/documentation issues, etc. Fixing issues helps improve the overall quality of SciPy, and is also a good way of getting familiar with the project. You may also want to fix a bug because you ran into it and need the function in question to work correctly. The discussion on code style and unit testing above applies equally to bug fixes. It is usually best to start by writing a unit test that shows the problem, i.e. it should pass but doesn’t. Once you have that, you can fix the code so that the test does pass. That should be enough to send a PR for this issue. Unlike when adding new code, discussing this on the mailing list may not be necessary - if the old behavior of the code is clearly incorrect, no one will object to having it fixed. It may be necessary to add some warning or deprecation message for the changed behavior. This should be part of the review process. 160 Chapter 2. Contributing to SciPy SciPy Reference Guide, Release 0.13.0 2.3 Other ways to contribute There are many ways to contribute other than contributing code. Participating in discussions on the scipy-user and scipy-dev mailing lists is a contribution in itself. The scipy.org website contains a lot of information on the SciPy community and can always use a new pair of hands. A redesign of this website is ongoing, see scipy.github.com. The redesigned website is a static site based on Sphinx, the sources for it are also on Github at scipy.org-new. The SciPy documentation is constantly being improved by many developers and users. You can contribute by sending a PR on Github that improves the documentation, but there’s also a documentation wiki that is very convenient for making edits to docstrings (and doesn’t require git knowledge). Anyone can register a username on that wiki, ask on the scipy-dev mailing list for edit rights and make edits. The documentation there is updated every day with the latest changes in the SciPy master branch, and wiki edits are regularly reviewed and merged into master. Another advantage of the documentation wiki is that you can immediately see how the reStructuredText (reST) of docstrings and other docs is rendered as html, so you can easily catch formatting errors. Code that doesn’t belong in SciPy itself or in another package but helps users accomplish a certain task is valuable. SciPy Central is the place to share this type of code (snippets, examples, plotting code, etc.). 2.4 Recommended development setup Since Scipy contains parts written in C, C++, and Fortran that need to be compiled before use, make sure you have the necessary compilers and Python development headers installed. Having compiled code also means that importing Scipy from the development sources needs some additional steps, which are explained below. First fork a copy of the main Scipy repository in Github onto your own account and then create your local repository via: $ git clone git@github.com:YOURUSERNAME/scipy.git scipy $ cd scipy $ git remote add upstream git://github.com/scipy/scipy.git To build the development version of Scipy and run tests, spawn interactive shells with the Python import paths properly set up etc., do one of: $ $ $ $ $ python python python python python runtests.py runtests.py runtests.py runtests.py runtests.py -v -v -s optimize -v -t scipy/special/tests/test_basic.py:test_xlogy --ipython --python somescript.py This builds Scipy first, so the first time it may take some time. If you specify -n, the tests are run against the version of Scipy (if any) found on current PYTHONPATH. You may want to set up an in-place build so that changes made to .py files have effect without rebuild. First, run: $ python setup.py build_ext -i Then you need to point your PYTHONPATH environment variable to this directory. Some IDEs (Spyder for example) have utilities to manage PYTHONPATH. On Linux and OSX, you can run the command: $ export PYTHONPATH=$PWD and on Windows $ set PYTHONPATH=/path/to/scipy 2.3. Other ways to contribute 161 SciPy Reference Guide, Release 0.13.0 Now editing a Python source file in SciPy allows you to immediately test and use your changes (in .py files), by simply restarting the interpreter. Another good approach is to install Scipy normally in an isolated test environment using virtualenv, and work from there (see FAQ below). 2.5 SciPy structure All SciPy modules should follow the following conventions. In the following, a SciPy module is defined as a Python package, say yyy, that is located in the scipy/ directory. • Ideally, each SciPy module should be as self-contained as possible. That is, it should have minimal dependencies on other packages or modules. Even dependencies on other SciPy modules should be kept to a minimum. A dependency on NumPy is of course assumed. • Directory yyy/ contains: – A file setup.py that defines configuration(parent_package=”,top_path=None) function for numpy.distutils. – A directory tests/ that contains yyy/ {.py,.so,/}. files test_ .py corresponding to modules – A directory benchmarks/ that contains files bench_ .py corresponding to modules yyy/ {.py,.so,/}. • Private modules should be prefixed with an underscore _, for instance yyy/_somemodule.py. • User-visible functions should have good documentation following the Numpy documentation style, see how to document • The __init__.py of the module should contain the main reference documentation in its docstring. This is connected to the Sphinx documentation under doc/ via Sphinx’s automodule directive. The reference documentation should first give a categorized list of the contents of the module using autosummary:: directives, and after that explain points essential for understanding the use of the module. Tutorial-style documentation doc/source/tutorial/ with extensive examples should be separate, and put under See the existing Scipy submodules for guidance. For further details on Numpy distutils, see: https://github.com/numpy/numpy/blob/master/doc/DISTUTILS.rst.txt 2.6 Useful links, FAQ, checklist 2.6.1 Checklist before submitting a PR • Are there unit tests with good code coverage? • Do all public function have docstrings including examples? • Is the code style correct (PEP8, pyflakes) • Is the new functionality tagged with .. versionadded:: the next release - can be found in setup.py)? 162 X.Y.Z (with X.Y.Z the version number of Chapter 2. Contributing to SciPy SciPy Reference Guide, Release 0.13.0 • Is the new functionality mentioned in the release notes of the next release? • Is the new functionality added to the reference guide? • In case of larger additions, is there a tutorial or more extensive module-level description? • In case compiled code is added, is it integrated correctly via setup.py (and preferably also Bento configuration files - bento.info and bscript)? • If you are a first-time contributor, did you add yourself to THANKS.txt? Please note that this is perfectly normal and desirable - the aim is to give every single contributor credit, and if you don’t add yourself it’s simply extra work for the reviewer (or worse, the reviewer may forget). • Did you check that the code can be distributed under a BSD license? 2.6.2 Useful SciPy documents • The how to document guidelines • NumPy/SciPy testing guidelines • SciPy API • SciPy maintainers • NumPy/SciPy git workflow 2.6.3 FAQ I based my code on existing Matlab/R/... code I found online, is this OK? It depends. SciPy is distributed under a BSD license, so if the code that you based your code on is also BSD licensed or has a BSD-compatible license (MIT, Apache, ...) then it’s OK. Code which is GPL-licensed, has no clear license, requires citation or is free for academic use only can’t be included in SciPy. Therefore if you copied existing code with such a license or made a direct translation to Python of it, your code can’t be included. See also license compatibility. Why is SciPy under the BSD license and not, say, the GPL? Like Python, SciPy uses a “permissive” open source license, which allows proprietary re-use. While this allows companies to use and modify the software without giving anything back, it is felt that the larger user base results in more contributions overall, and companies often publish their modifications anyway, without being required to. See John Hunter’s BSD pitch. How do I set up a development version of SciPy in parallel to a released version that I use to do my job/research? One simple way to achieve this is to install the released version in site-packages, by using a binary installer or pip for example, and set up the development version in a virtualenv. First install virtualenv (optionally use virtualenvwrapper), then create your virtualenv (named scipy-dev here) with: $ virtualenv scipy-dev Now, whenever you want to switch to the virtual environment, you can use the command source scipy-dev/bin/activate, and deactivate to exit from the virtual environment and back to your previous shell. With scipy-dev activated, install first Scipy’s dependencies: $ pip install Numpy Nose Cython After that, you can install a development version of Scipy, for example via: $ python setup.py install 2.6. Useful links, FAQ, checklist 163 SciPy Reference Guide, Release 0.13.0 The installation goes to the virtual environment. Can I use a programming language other than Python to speed up my code? Yes. The languages used in SciPy are Python, Cython, C, C++ and Fortran. All of these have their pros and cons. If Python really doesn’t offer enough performance, one of those languages can be used. Important concerns when using compiled languages are maintainability and portability. For maintainability, Cython is clearly preferred over C/C++/Fortran. Cython and C are more portable than C++/Fortran. A lot of the existing C and Fortran code in SciPy is older, battle-tested code that was only wrapped in (but not specifically written for) Python/SciPy. Therefore the basic advice is: use Cython. If there’s specific reasons why C/C++/Fortran should be preferred, please discuss those reasons first. How do I debug code written in C/C++/Fortran inside Scipy? The easiest way to do this is to first write a Python script that invokes the C code whose execution you want to debug. For instance mytest.py: from scipy.special import hyp2f1 print(hyp2f1(5.0, 1.0, -1.8, 0.95)) Now, you can run: gdb --args python runtests.py -g --python mytest.py If you didn’t compile with debug symbols enabled before, remove the build directory first. While in the debugger: (gdb) break cephes_hyp2f1 (gdb) run The execution will now stop at the corresponding C function and you can step through it as usual. Instead of plain gdb you can of course use your favourite alternative debugger; run it on the python binary with arguments runtests.py -g --python mytest.py. 164 Chapter 2. Contributing to SciPy CHAPTER THREE API - IMPORTING FROM SCIPY In Python the distinction between what is the public API of a library and what are private implementation details is not always clear. Unlike in other languages like Java, it is possible in Python to access “private” function or objects. Occasionally this may be convenient, but be aware that if you do so your code may break without warning in future releases. Some widely understood rules for what is and isn’t public in Python are: • Methods / functions / classes and module attributes whose names begin with a leading underscore are private. • If a class name begins with a leading underscore none of its members are public, whether or not they begin with a leading underscore. • If a module name in a package begins with a leading underscore none of its members are public, whether or not they begin with a leading underscore. • If a module or package defines __all__ that authoritatively defines the public interface. • If a module or package doesn’t define __all__ then all names that don’t start with a leading underscore are public. Note: Reading the above guidelines one could draw the conclusion that every private module or object starts with an underscore. This is not the case; the presence of underscores do mark something as private, but the absence of underscores do not mark something as public. In Scipy there are modules whose names don’t start with an underscore, but that should be considered private. To clarify which modules these are we define below what the public API is for Scipy, and give some recommendations for how to import modules/functions/objects from Scipy. 3.1 Guidelines for importing functions from Scipy The scipy namespace itself only contains functions imported from numpy. These functions still exist for backwards compatibility, but should be imported from numpy directly. Everything in the namespaces of scipy submodules is public. In general, it is recommended to import functions from submodule namespaces. For example, the function curve_fit (defined in scipy/optimize/minpack.py) should be imported like this: from scipy import optimize result = optimize.curve_fit(...) This form of importing submodules is preferred for all submodules except scipy.io (because io is also the name of a module in the Python stdlib): 165 SciPy Reference Guide, Release 0.13.0 from scipy import interpolate from scipy import integrate import scipy.io as spio In some cases, the public API is one level deeper. For example the scipy.sparse.linalg module is public, and the functions it contains are not available in the scipy.sparse namespace. Sometimes it may result in more easily understandable code if functions are imported from one level deeper. For example, in the following it is immediately clear that lomax is a distribution if the second form is chosen: # first form from scipy import stats stats.lomax(...) # second form from scipy.stats import distributions distributions.lomax(...) In that case the second form can be chosen, if it is documented in the next section that the submodule in question is public. 3.2 API definition Every submodule listed below is public. That means that these submodules are unlikely to be renamed or changed in an incompatible way, and if that is necessary a deprecation warning will be raised for one Scipy release before the change is made. • scipy.cluster – vq – hierarchy • scipy.constants • scipy.fftpack • scipy.integrate • scipy.interpolate • scipy.io – arff – harwell_boeing – idl – matlab – netcdf – wavfile • scipy.linalg – scipy.linalg.blas – scipy.linalg.lapack – scipy.linalg.interpolative • scipy.misc 166 Chapter 3. API - importing from Scipy SciPy Reference Guide, Release 0.13.0 • scipy.ndimage • scipy.odr • scipy.optimize • scipy.signal • scipy.sparse – linalg – csgraph • scipy.spatial – distance • scipy.special • scipy.stats – distributions – mstats • scipy.weave 3.2. API definition 167 SciPy Reference Guide, Release 0.13.0 168 Chapter 3. API - importing from Scipy CHAPTER FOUR RELEASE NOTES 4.1 SciPy 0.13.0 Release Notes 169 SciPy Reference Guide, Release 0.13.0 Contents • SciPy 0.13.0 Release Notes – New features * scipy.integrate improvements · N-dimensional numerical integration · dopri* improvements scipy.linalg improvements * · Interpolative decompositions · Polar decomposition · BLAS level 3 functions · Matrix functions * scipy.optimize improvements · Trust-region unconstrained minimization algorithms * scipy.sparse improvements · Boolean comparisons and sparse matrices · CSR and CSC fancy indexing * scipy.sparse.linalg improvements * scipy.spatial improvements * scipy.signal improvements * scipy.special improvements * scipy.io improvements · Unformatted Fortran file reader · scipy.io.wavfile enhancements * scipy.interpolate improvements · B-spline derivatives and antiderivatives * scipy.stats improvements – Deprecated features * expm2 and expm3 * scipy.stats functions – Backwards incompatible changes * LIL matrix assignment * Deprecated radon function removed * Removed deprecated keywords xa and xb from stats.distributions * Changes to MATLAB file readers / writers – Other changes – Authors SciPy 0.13.0 is the culmination of 7 months of hard work. It contains many new features, numerous bug-fixes, improved test coverage and better documentation. There have been a number of deprecations and API changes in this release, which are documented below. All users are encouraged to upgrade to this release, as there are a large number of bug-fixes and optimizations. Moreover, our development attention will now shift to bug-fix releases on the 0.13.x branch, and on adding new features on the master branch. This release requires Python 2.6, 2.7 or 3.1-3.3 and NumPy 1.5.1 or greater. Highlights of this release are: • support for fancy indexing and boolean comparisons with sparse matrices • interpolative decompositions and matrix functions in the linalg module • two new trust-region solvers for unconstrained minimization 170 Chapter 4. Release Notes SciPy Reference Guide, Release 0.13.0 4.1.1 New features scipy.integrate improvements N-dimensional numerical integration A new function scipy.integrate.nquad, which provides N-dimensional integration functionality with a more flexible interface than dblquad and tplquad, has been added. dopri* improvements The intermediate results from the dopri family of ODE solvers can now be accessed by a solout callback function. scipy.linalg improvements Interpolative decompositions Scipy now includes a new module scipy.linalg.interpolative containing routines for computing interpolative matrix decompositions (ID). This feature is based on the ID software package by P.G. Martinsson, V. Rokhlin, Y. Shkolnisky, and M. Tygert, previously adapted for Python in the PymatrixId package by K.L. Ho. Polar decomposition A new function scipy.linalg.polar, to compute the polar decomposition of a matrix, was added. BLAS level 3 functions The BLAS functions symm, syrk, syr2k, hemm, herk and her2k are now wrapped in scipy.linalg. Matrix functions Several matrix function algorithms have been implemented or updated following detailed descriptions in recent papers of Nick Higham and his co-authors. These include the matrix square root (sqrtm), the matrix logarithm (logm), the matrix exponential (expm) and its Frechet derivative (expm_frechet), and fractional matrix powers (fractional_matrix_power). scipy.optimize improvements Trust-region unconstrained minimization algorithms The minimize function gained two trust-region solvers for unconstrained minimization: dogleg and trust-ncg. scipy.sparse improvements Boolean comparisons and sparse matrices All sparse matrix types now support boolean data, and boolean operations. Two sparse matrices A and B can be compared in all the expected ways A < B, A >= B, A != B, producing similar results as dense Numpy arrays. Comparisons with dense matrices and scalars are also supported. CSR and CSC fancy indexing Compressed sparse row and column sparse matrix types now support fancy indexing with boolean matrices, slices, and lists. So where A is a (CSC or CSR) sparse matrix, you can do things like: 4.1. SciPy 0.13.0 Release Notes 171 SciPy Reference Guide, Release 0.13.0 >>> A[A > 0.5] = 1 # since Boolean sparse matrices work >>> A[:2, :3] = 2 >>> A[[1,2], 2] = 3 scipy.sparse.linalg improvements The new function onenormest provides a lower bound of the 1-norm of a linear operator and has been implemented according to Higham and Tisseur (2000). This function is not only useful for sparse matrices, but can also be used to estimate the norm of products or powers of dense matrices without explictly building the intermediate matrix. The multiplicative action of the matrix exponential of a linear operator (expm_multiply) has been implemented following the description in Al-Mohy and Higham (2011). Abstract linear operators (scipy.sparse.linalg.LinearOperator) can now be multiplied, added to each other, and exponentiated, producing new linear operators. This enables easier construction of composite linear operations. scipy.spatial improvements The vertices of a ConvexHull can now be accessed via the vertices attribute, which gives proper orientation in 2-D. scipy.signal improvements The cosine window function scipy.signal.cosine was added. scipy.special improvements New functions scipy.special.xlogy and scipy.special.xlog1py were added. These functions can simplify and speed up code that has to calculate x * log(y) and give 0 when x == 0. scipy.io improvements Unformatted Fortran file reader The new class scipy.io.FortranFile facilitates reading unformatted sequential files written by Fortran code. scipy.io.wavfile enhancements scipy.io.wavfile.write now accepts a file buffer. Previously it only accepted a filename. scipy.io.wavfile.read and scipy.io.wavfile.write can now handle floating point WAV files. scipy.interpolate improvements B-spline derivatives and antiderivatives scipy.interpolate.splder and scipy.interpolate.splantider functions for computing B-splines that represent derivatives and antiderivatives of B-splines were added. These functions are also available in the class-based FITPACK interface as UnivariateSpline.derivative and UnivariateSpline.antiderivative. 172 Chapter 4. Release Notes SciPy Reference Guide, Release 0.13.0 scipy.stats improvements Distributions now allow using keyword parameters in addition to positional parameters in all methods. The function scipy.stats.power_divergence has been added for the Cressie-Read power divergence statistic and goodness of fit test. Included in this family of statistics is the “G-test” (http://en.wikipedia.org/wiki/G-test). scipy.stats.mood now accepts multidimensional input. An option was added to scipy.stats.wilcoxon for continuity correction. scipy.stats.chisquare now has an axis argument. scipy.stats.mstats.chisquare now has axis and ddof arguments. 4.1.2 Deprecated features expm2 and expm3 The matrix exponential functions scipy.linalg.expm2 and scipy.linalg.expm3 are deprecated. All users should use the numerically more robust scipy.linalg.expm function instead. scipy.stats functions scipy.stats.oneway is deprecated; scipy.stats.f_oneway should be used instead. scipy.stats.glm is deprecated. scipy.stats.ttest_ind is an equivalent function; more full-featured general (and generalized) linear model implementations can be found in statsmodels. scipy.stats.cmedian is deprecated; numpy.median should be used instead. 4.1.3 Backwards incompatible changes LIL matrix assignment Assigning values to LIL matrices with two index arrays now works similarly as assigning into ndarrays: >>> x = lil_matrix((3, 3)) >>> x[[0,1,2],[0,1,2]]=[0,1,2] >>> x.todense() matrix([[ 0., 0., 0.], [ 0., 1., 0.], [ 0., 0., 2.]]) rather than giving the result: >>> x.todense() matrix([[ 0., 1., [ 0., 1., [ 0., 1., 2.], 2.], 2.]]) Users relying on the previous behavior will need to revisit their code. The previous behavior is obtained by ‘‘x[numpy.ix_([0,1,2],[0,1,2])] = ...‘. 4.1. SciPy 0.13.0 Release Notes 173 SciPy Reference Guide, Release 0.13.0 Deprecated radon function removed The misc.radon function, which was deprecated in scipy 0.11.0, has been removed. Users can find a more fullfeatured radon function in scikit-image. Removed deprecated keywords xa and xb from stats.distributions The keywords xa and xb, which were deprecated since 0.11.0, have been removed from the distributions in scipy.stats. Changes to MATLAB file readers / writers The major change is that 1D arrays in numpy now become row vectors (shape 1, N) when saved to a MATLAB 5 format file. Previously 1D arrays saved as column vectors (N, 1). This is to harmonize the behavior of writing MATLAB 4 and 5 formats, and adapt to the defaults of numpy and MATLAB - for example np.atleast_2d returns 1D arrays as row vectors. Trying to save arrays of greater than 2 dimensions in MATLAB 4 format now raises an error instead of silently reshaping the array as 2D. scipy.io.loadmat(’afile’) used to look for afile on the Python system path (sys.path); now loadmat only looks in the current directory for a relative path filename. 4.1.4 Other changes Security fix: scipy.weave previously used temporary directories in an insecure manner under certain circumstances. Cython is now required to build unreleased versions of scipy. The C files generated from Cython sources are not included in the git repo anymore. They are however still shipped in source releases. The code base received a fairly large PEP8 cleanup. A tox pep8 command has been added; new code should pass this test command. Scipy cannot be compiled with gfortran 4.1 anymore (at least on RH5), likely due to that compiler version not supporting entry constructs well. 4.1.5 Authors This release contains work by the following people (contributed at least one patch to this release, names in alphabetical order): • Jorge Cañardo Alastuey + • Tom Aldcroft + • Max Bolingbroke + • Joseph Jon Booker + • François Boulogne • Matthew Brett • Christian Brodbeck + • Per Brodtkorb + 174 Chapter 4. Release Notes SciPy Reference Guide, Release 0.13.0 • Christian Brueffer + • Lars Buitinck • Evgeni Burovski + • Tim Cera • Lawrence Chan + • David Cournapeau • Drazen Lucanin + • Alexander J. Dunlap + • endolith • André Gaul + • Christoph Gohlke • Ralf Gommers • Alex Griffing + • Blake Griffith + • Charles Harris • Bob Helmbold + • Andreas Hilboll • Kat Huang + • Oleksandr (Sasha) Huziy + • Gert-Ludwig Ingold + • Thouis (Ray) Jones • Juan Luis Cano Rodríguez + • Robert Kern • Andreas Kloeckner + • Sytse Knypstra + • Gustav Larsson + • Denis Laxalde • Christopher Lee • Tim Leslie • Wendy Liu + • Clemens Novak + • Takuya Oshima + • Josef Perktold • Illia Polosukhin + • Przemek Porebski + • Steve Richardson + 4.1. SciPy 0.13.0 Release Notes 175 SciPy Reference Guide, Release 0.13.0 • Branden Rolston + • Skipper Seabold • Fazlul Shahriar • Leo Singer + • Rohit Sivaprasad + • Daniel B. Smith + • Julian Taylor • Louis Thibault + • Tomas Tomecek + • John Travers • Richard Tsai + • Jacob Vanderplas • Patrick Varilly • Pauli Virtanen • Stefan van der Walt • Warren Weckesser • Pedro Werneck + • Nils Werner + • Michael Wimmer + • Nathan Woods + • Tony S. Yu + A total of 65 people contributed to this release. People with a “+” by their names contributed a patch for the first time. 4.2 SciPy 0.12.0 Release Notes 176 Chapter 4. Release Notes SciPy Reference Guide, Release 0.13.0 Contents • SciPy 0.12.0 Release Notes – New features * scipy.spatial improvements · cKDTree feature-complete · Voronoi diagrams and convex hulls · Delaunay improvements Spectral estimators (scipy.signal) * scipy.optimize improvements * · Callback functions in L-BFGS-B and TNC · Basin hopping global optimization (scipy.optimize.basinhopping) * scipy.special improvements · Revised complex error functions · Faster orthogonal polynomials * scipy.sparse.linalg features * Listing Matlab(R) file contents in scipy.io * Documented BLAS and LAPACK low-level interfaces (scipy.linalg) * Polynomial interpolation improvements (scipy.interpolate) – Deprecated features * scipy.lib.lapack * fblas and cblas – Backwards incompatible changes * Removal of scipy.io.save_as_module – Other changes – Authors SciPy 0.12.0 is the culmination of 7 months of hard work. It contains many new features, numerous bug-fixes, improved test coverage and better documentation. There have been a number of deprecations and API changes in this release, which are documented below. All users are encouraged to upgrade to this release, as there are a large number of bug-fixes and optimizations. Moreover, our development attention will now shift to bug-fix releases on the 0.12.x branch, and on adding new features on the master branch. Some of the highlights of this release are: • Completed QHull wrappers in scipy.spatial. • cKDTree now a drop-in replacement for KDTree. • A new global optimizer, basinhopping. • Support for Python 2 and Python 3 from the same code base (no more 2to3). This release requires Python 2.6, 2.7 or 3.1-3.3 and NumPy 1.5.1 or greater. Support for Python 2.4 and 2.5 has been dropped as of this release. 4.2.1 New features scipy.spatial improvements cKDTree feature-complete Cython version of KDTree, cKDTree, is now feature-complete. Most operations (construction, query, query_ball_point, query_pairs, count_neighbors and sparse_distance_matrix) are between 200 and 1000 times faster in cKDTree than in KDTree. With very minor caveats, cKDTree has exactly the same interface as KDTree, and can be used as a drop-in replacement. 4.2. SciPy 0.12.0 Release Notes 177 SciPy Reference Guide, Release 0.13.0 Voronoi diagrams and convex hulls scipy.spatial now contains functionality for computing Voronoi diagrams and convex hulls using the Qhull library. (Delaunay triangulation was available since Scipy 0.9.0.) Delaunay improvements It’s now possible to pass in custom Qhull options in Delaunay triangulation. Coplanar points are now also recorded, if present. Incremental construction of Delaunay triangulations is now also possible. Spectral estimators (scipy.signal) The functions scipy.signal.periodogram and scipy.signal.welch were added, providing DFT-based spectral estimators. scipy.optimize improvements Callback functions in L-BFGS-B and TNC A callback mechanism was added to L-BFGS-B and TNC minimization solvers. Basin hopping global optimization (scipy.optimize.basinhopping) A new global optimization algorithm. Basinhopping is designed to efficiently find the global minimum of a smooth function. scipy.special improvements Revised complex error functions The computation of special functions related to the error function now uses a new Faddeeva library from MIT which increases their numerical precision. The scaled and imaginary error functions erfcx and erfi were also added, and the Dawson integral dawsn can now be evaluated for a complex argument. Faster orthogonal polynomials Evaluation of orthogonal polynomials (the eval_* routines) in now faster in scipy.special, and their out= argument functions properly. scipy.sparse.linalg features • In scipy.sparse.linalg.spsolve, the b argument can now be either a vector or a matrix. • scipy.sparse.linalg.inv was added. This uses spsolve to compute a sparse matrix inverse. • scipy.sparse.linalg.expm was added. This computes the exponential of a sparse matrix using a similar algorithm to the existing dense array implementation in scipy.linalg.expm. Listing Matlab(R) file contents in scipy.io A new function whosmat is available in scipy.io for inspecting contents of MAT files without reading them to memory. 178 Chapter 4. Release Notes SciPy Reference Guide, Release 0.13.0 Documented BLAS and LAPACK low-level interfaces (scipy.linalg) The modules scipy.linalg.blas and scipy.linalg.lapack can be used to access low-level BLAS and LAPACK functions. Polynomial interpolation improvements (scipy.interpolate) The barycentric, Krogh, piecewise and pchip polynomial interpolators in scipy.interpolate accept now an axis argument. 4.2.2 Deprecated features scipy.lib.lapack The module scipy.lib.lapack is deprecated. You can use scipy.linalg.lapack instead. The module scipy.lib.blas was deprecated earlier in Scipy 0.10.0. fblas and cblas Accessing the modules scipy.linalg.fblas, cblas, flapack, clapack is deprecated. Instead, use the modules scipy.linalg.lapack and scipy.linalg.blas. 4.2.3 Backwards incompatible changes Removal of scipy.io.save_as_module The function scipy.io.save_as_module was deprecated in Scipy 0.11.0, and is now removed. Its private support modules scipy.io.dumbdbm_patched and scipy.io.dumb_shelve are also removed. 4.2.4 Other changes 4.2.5 Authors • Anton Akhmerov + • Alexander Eberspächer + • Anne Archibald • Jisk Attema + • K.-Michael Aye + • bemasc + • Sebastian Berg + • François Boulogne + • Matthew Brett • Lars Buitinck • Steven Byrnes + 4.2. SciPy 0.12.0 Release Notes 179 SciPy Reference Guide, Release 0.13.0 • Tim Cera + • Christian + • Keith Clawson + • David Cournapeau • Nathan Crock + • endolith • Bradley M. Froehle + • Matthew R Goodman • Christoph Gohlke • Ralf Gommers • Robert David Grant + • Yaroslav Halchenko • Charles Harris • Jonathan Helmus • Andreas Hilboll • Hugo + • Oleksandr Huziy • Jeroen Demeyer + • Johannes Schönberger + • Steven G. Johnson + • Chris Jordan-Squire • Jonathan Taylor + • Niklas Kroeger + • Jerome Kieffer + • kingson + • Josh Lawrence • Denis Laxalde • Alex Leach + • Tim Leslie • Richard Lindsley + • Lorenzo Luengo + • Stephen McQuay + • MinRK • Sturla Molden + • Eric Moore + • mszep + 180 Chapter 4. Release Notes SciPy Reference Guide, Release 0.13.0 • Matt Newville + • Vlad Niculae • Travis Oliphant • David Parker + • Fabian Pedregosa • Josef Perktold • Zach Ploskey + • Alex Reinhart + • Gilles Rochefort + • Ciro Duran Santillli + • Jan Schlueter + • Jonathan Scholz + • Anthony Scopatz • Skipper Seabold • Fabrice Silva + • Scott Sinclair • Jacob Stevenson + • Sturla Molden + • Julian Taylor + • thorstenkranz + • John Travers + • True Price + • Nicky van Foreest • Jacob Vanderplas • Patrick Varilly • Daniel Velkov + • Pauli Virtanen • Stefan van der Walt • Warren Weckesser A total of 75 people contributed to this release. People with a “+” by their names contributed a patch for the first time. 4.3 SciPy 0.11.0 Release Notes 4.3. SciPy 0.11.0 Release Notes 181 SciPy Reference Guide, Release 0.13.0 Contents • SciPy 0.11.0 Release Notes – New features * Sparse Graph Submodule * scipy.optimize improvements · Unified interfaces to minimizers · Unified interface to root finding algorithms * scipy.linalg improvements · New matrix equation solvers · QZ and QR Decomposition · Pascal matrices * Sparse matrix construction and operations * LSMR iterative solver * Discrete Sine Transform * scipy.interpolate improvements * Binned statistics (scipy.stats) – Deprecated features – Backwards incompatible changes * Removal of scipy.maxentropy * Minor change in behavior of splev * Behavior of scipy.integrate.complex_ode * Minor change in behavior of T-tests – Other changes – Authors SciPy 0.11.0 is the culmination of 8 months of hard work. It contains many new features, numerous bug-fixes, improved test coverage and better documentation. Highlights of this release are: • A new module has been added which provides a number of common sparse graph algorithms. • New unified interfaces to the existing optimization and root finding functions have been added. All users are encouraged to upgrade to this release, as there are a large number of bug-fixes and optimizations. Our development attention will now shift to bug-fix releases on the 0.11.x branch, and on adding new features on the master branch. This release requires Python 2.4-2.7 or 3.1-3.2 and NumPy 1.5.1 or greater. 4.3.1 New features Sparse Graph Submodule The new submodule scipy.sparse.csgraph implements a number of efficient graph algorithms for graphs stored as sparse adjacency matrices. Available routines are: • connected_components - determine connected components of a graph • laplacian - compute the laplacian of a graph • shortest_path - compute the shortest path between points on a positive graph • dijkstra - use Dijkstra’s algorithm for shortest path • floyd_warshall - use the Floyd-Warshall algorithm for shortest path • breadth_first_order - compute a breadth-first order of nodes 182 Chapter 4. Release Notes SciPy Reference Guide, Release 0.13.0 • depth_first_order - compute a depth-first order of nodes • breadth_first_tree - construct the breadth-first tree from a given node • depth_first_tree - construct a depth-first tree from a given node • minimum_spanning_tree - construct the minimum spanning tree of a graph scipy.optimize improvements The optimize module has received a lot of attention this release. In addition to added tests, documentation improvements, bug fixes and code clean-up, the following improvements were made: • A unified interface to minimizers of univariate and multivariate functions has been added. • A unified interface to root finding algorithms for multivariate functions has been added. • The L-BFGS-B algorithm has been updated to version 3.0. Unified interfaces to minimizers Two new functions scipy.optimize.minimize and scipy.optimize.minimize_scalar were added to provide a common interface to minimizers of multivariate and univariate functions respectively. For multivariate functions, scipy.optimize.minimize provides an interface to methods for unconstrained optimization (fmin, fmin_powell, fmin_cg, fmin_ncg, fmin_bfgs and anneal) or constrained optimization (fmin_l_bfgs_b, fmin_tnc, fmin_cobyla and fmin_slsqp). For univariate functions, scipy.optimize.minimize_scalar provides an interface to methods for unconstrained and bounded optimization (brent, golden, fminbound). This allows for easier comparing and switching between solvers. Unified interface to root finding algorithms The new function scipy.optimize.root provides a common interface to root finding algorithms for multivariate functions, embeding fsolve, leastsq and nonlin solvers. scipy.linalg improvements New matrix equation solvers Solvers for the Sylvester equation (scipy.linalg.solve_sylvester, discrete and continuous Lyapunov equations (scipy.linalg.solve_lyapunov, scipy.linalg.solve_discrete_lyapunov) and discrete and continuous algebraic Riccati equations (scipy.linalg.solve_continuous_are, scipy.linalg.solve_discrete_are) have been added to scipy.linalg. These solvers are often used in the field of linear control theory. QZ and QR Decomposition It is now possible to calculate the QZ, or Generalized Schur, decomposition using scipy.linalg.qz. This function wraps the LAPACK routines sgges, dgges, cgges, and zgges. The function scipy.linalg.qr_multiply, which allows efficient computation of the matrix product of Q (from a QR decompostion) and a vector, has been added. Pascal matrices A function for creating Pascal matrices, scipy.linalg.pascal, was added. 4.3. SciPy 0.11.0 Release Notes 183 SciPy Reference Guide, Release 0.13.0 Sparse matrix construction and operations Two new functions, scipy.sparse.diags and scipy.sparse.block_diag, were added to easily construct diagonal and block-diagonal sparse matrices respectively. scipy.sparse.csc_matrix and csr_matrix now support the operations sin, tan, arcsin, arctan, sinh, tanh, arcsinh, arctanh, rint, sign, expm1, log1p, deg2rad, rad2deg, floor, ceil and trunc. Previously, these operations had to be performed by operating on the matrices’ data attribute. LSMR iterative solver LSMR, an iterative method for solving (sparse) linear and linear least-squares systems, was added as scipy.sparse.linalg.lsmr. Discrete Sine Transform Bindings for the discrete sine transform functions have been added to scipy.fftpack. scipy.interpolate improvements For interpolation in spherical coordinates, the three classes scipy.interpolate.SmoothSphereBivariateSpline, scipy.interpolate.LSQSphereBivariateSpline, and scipy.interpolate.RectSphereBivariateSpline have been added. Binned statistics (scipy.stats) The stats module has gained functions to do binned statistics, which are a generalization of histograms, in 1-D, 2-D and multiple dimensions: scipy.stats.binned_statistic, scipy.stats.binned_statistic_2d and scipy.stats.binned_statistic_dd. 4.3.2 Deprecated features scipy.sparse.cs_graph_components has been made a part of the sparse graph submodule, and renamed to scipy.sparse.csgraph.connected_components. Calling the former routine will result in a deprecation warning. scipy.misc.radon has been deprecated. A more full-featured radon transform can be found in scikits-image. scipy.io.save_as_module has been deprecated. numpy.savez function. A better way to save multiple Numpy arrays is the The xa and xb parameters for all distributions in scipy.stats.distributions already weren’t used; they have now been deprecated. 4.3.3 Backwards incompatible changes Removal of scipy.maxentropy The scipy.maxentropy module, which was deprecated in the 0.10.0 release, has been removed. Logistic regression in scikits.learn is a good and modern alternative for this functionality. 184 Chapter 4. Release Notes SciPy Reference Guide, Release 0.13.0 Minor change in behavior of splev The spline evaluation function now behaves similarly to interp1d for size-1 arrays. Previous behavior: >>> >>> >>> >>> >>> 4. >>> 4. from scipy.interpolate import splev, splrep, interp1d x = [1,2,3,4,5] y = [4,5,6,7,8] tck = splrep(x, y) splev([1], tck) splev(1, tck) Corrected behavior: >>> splev([1], tck) array([ 4.]) >>> splev(1, tck) array(4.) This affects also the UnivariateSpline classes. Behavior of scipy.integrate.complex_ode The behavior of the y attribute of complex_ode is changed. Previously, it expressed the complex-valued solution in the form: z = ode.y[::2] + 1j * ode.y[1::2] Now, it is directly the complex-valued solution: z = ode.y Minor change in behavior of T-tests The T-tests scipy.stats.ttest_ind, scipy.stats.ttest_rel and scipy.stats.ttest_1samp have been changed so that 0 / 0 now returns NaN instead of 1. 4.3.4 Other changes The SuperLU sources in scipy.sparse.linalg have been updated to version 4.3 from upstream. The function scipy.signal.bode, which calculates magnitude and phase data for a continuous-time system, has been added. The two-sample T-test scipy.stats.ttest_ind gained an option to compare samples with unequal variances, i.e. Welch’s T-test. scipy.misc.logsumexp now takes an optional axis keyword argument. 4.3.5 Authors This release contains work by the following people (contributed at least one patch to this release, names in alphabetical order): • Jeff Armstrong 4.3. SciPy 0.11.0 Release Notes 185 SciPy Reference Guide, Release 0.13.0 • Chad Baker • Brandon Beacher + • behrisch + • borishim + • Matthew Brett • Lars Buitinck • Luis Pedro Coelho + • Johann Cohen-Tanugi • David Cournapeau • dougal + • Ali Ebrahim + • endolith + • Bjørn Forsman + • Robert Gantner + • Sebastian Gassner + • Christoph Gohlke • Ralf Gommers • Yaroslav Halchenko • Charles Harris • Jonathan Helmus + • Andreas Hilboll + • Marc Honnorat + • Jonathan Hunt + • Maxim Ivanov + • Thouis (Ray) Jones • Christopher Kuster + • Josh Lawrence + • Denis Laxalde + • Travis Oliphant • Joonas Paalasmaa + • Fabian Pedregosa • Josef Perktold • Gavin Price + • Jim Radford + • Andrew Schein + • Skipper Seabold 186 Chapter 4. Release Notes SciPy Reference Guide, Release 0.13.0 • Jacob Silterra + • Scott Sinclair • Alexis Tabary + • Martin Teichmann • Matt Terry + • Nicky van Foreest + • Jacob Vanderplas • Patrick Varilly + • Pauli Virtanen • Nils Wagner + • Darryl Wally + • Stefan van der Walt • Liming Wang + • David Warde-Farley + • Warren Weckesser • Sebastian Werk + • Mike Wimmer + • Tony S Yu + A total of 55 people contributed to this release. People with a “+” by their names contributed a patch for the first time. 4.4 SciPy 0.10.0 Release Notes Contents • SciPy 0.10.0 Release Notes – New features * Bento: new optional build system * Generalized and shift-invert eigenvalue problems in scipy.sparse.linalg * Discrete-Time Linear Systems (scipy.signal) * Enhancements to scipy.signal * Additional decomposition options (scipy.linalg) * Additional special matrices (scipy.linalg) * Enhancements to scipy.stats * Basic support for Harwell-Boeing file format for sparse matrices – Deprecated features * scipy.maxentropy * scipy.lib.blas * Numscons build system – Backwards-incompatible changes – Other changes – Authors 4.4. SciPy 0.10.0 Release Notes 187 SciPy Reference Guide, Release 0.13.0 SciPy 0.10.0 is the culmination of 8 months of hard work. It contains many new features, numerous bug-fixes, improved test coverage and better documentation. There have been a limited number of deprecations and backwardsincompatible changes in this release, which are documented below. All users are encouraged to upgrade to this release, as there are a large number of bug-fixes and optimizations. Moreover, our development attention will now shift to bugfix releases on the 0.10.x branch, and on adding new features on the development master branch. Release highlights: • Support for Bento as optional build system. • Support for generalized eigenvalue problems, and all shift-invert modes available in ARPACK. This release requires Python 2.4-2.7 or 3.1- and NumPy 1.5 or greater. 4.4.1 New features Bento: new optional build system Scipy can now be built with Bento. Bento has some nice features like parallel builds and partial rebuilds, that are not possible with the default build system (distutils). For usage instructions see BENTO_BUILD.txt in the scipy top-level directory. Currently Scipy has three build systems, distutils, numscons and bento. Numscons is deprecated and is planned and will likely be removed in the next release. Generalized and shift-invert eigenvalue problems in scipy.sparse.linalg The sparse eigenvalue problem solver functions scipy.sparse.eigs/eigh now support generalized eigenvalue problems, and all shift-invert modes available in ARPACK. Discrete-Time Linear Systems (scipy.signal) Support for simulating discrete-time linear systems, including scipy.signal.dlsim, scipy.signal.dimpulse, and scipy.signal.dstep, has been added to SciPy. Conversion of linear systems from continuous-time to discrete-time representations is also present via the scipy.signal.cont2discrete function. Enhancements to scipy.signal A Lomb-Scargle periodogram can now be computed with the new function scipy.signal.lombscargle. The forward-backward filter function scipy.signal.filtfilt can now filter the data in a given axis of an ndimensional numpy array. (Previously it only handled a 1-dimensional array.) Options have been added to allow more control over how the data is extended before filtering. FIR filter design with scipy.signal.firwin2 now has options to create filters of type III (zero at zero and Nyquist frequencies) and IV (zero at zero frequency). Additional decomposition options (scipy.linalg) A sort keyword has been added to the Schur decomposition routine (scipy.linalg.schur) to allow the sorting of eigenvalues in the resultant Schur form. 188 Chapter 4. Release Notes SciPy Reference Guide, Release 0.13.0 Additional special matrices (scipy.linalg) The functions hilbert and invhilbert were added to scipy.linalg. Enhancements to scipy.stats • The one-sided form of Fisher’s exact test is now also implemented in stats.fisher_exact. • The function stats.chi2_contingency for computing the chi-square test of independence of factors in a contingency table has been added, along with the related utility functions stats.contingency.margins and stats.contingency.expected_freq. Basic support for Harwell-Boeing file format for sparse matrices Both read and write are support through a simple function-based API, as well as a more complete API to control number format. The functions may be found in scipy.sparse.io. The following features are supported: • Read and write sparse matrices in the CSC format • Only real, symmetric, assembled matrix are supported (RUA format) 4.4.2 Deprecated features scipy.maxentropy The maxentropy module is unmaintained, rarely used and has not been functioning well for several releases. Therefore it has been deprecated for this release, and will be removed for scipy 0.11. Logistic regression in scikits.learn is a good alternative for this functionality. The scipy.maxentropy.logsumexp function has been moved to scipy.misc. scipy.lib.blas There are similar BLAS wrappers in scipy.linalg and scipy.lib. These have now been consolidated as scipy.linalg.blas, and scipy.lib.blas is deprecated. Numscons build system The numscons build system is being replaced by Bento, and will be removed in one of the next scipy releases. 4.4.3 Backwards-incompatible changes The deprecated name invnorm was removed from scipy.stats.distributions, this distribution is available as invgauss. The following deprecated nonlinear solvers from scipy.optimize have been removed: 4.4. SciPy 0.10.0 Release Notes 189 SciPy Reference Guide, Release 0.13.0 - ‘‘broyden_modified‘‘ (bad performance) ‘‘broyden1_modified‘‘ (bad performance) ‘‘broyden_generalized‘‘ (equivalent to ‘‘anderson‘‘) ‘‘anderson2‘‘ (equivalent to ‘‘anderson‘‘) ‘‘broyden3‘‘ (obsoleted by new limited-memory broyden methods) ‘‘vackar‘‘ (renamed to ‘‘diagbroyden‘‘) 4.4.4 Other changes scipy.constants has been updated with the CODATA 2010 constants. __all__ dicts have been added to all modules, which has cleaned up the namespaces (particularly useful for interactive work). An API section has been added to the documentation, giving recommended import guidelines and specifying which submodules are public and which aren’t. 4.4.5 Authors This release contains work by the following people (contributed at least one patch to this release, names in alphabetical order): • Jeff Armstrong + • Matthew Brett • Lars Buitinck + • David Cournapeau • FI$H 2000 + • Michael McNeil Forbes + • Matty G + • Christoph Gohlke • Ralf Gommers • Yaroslav Halchenko • Charles Harris • Thouis (Ray) Jones + • Chris Jordan-Squire + • Robert Kern • Chris Lasher + • Wes McKinney + • Travis Oliphant • Fabian Pedregosa • Josef Perktold • Thomas Robitaille + • Pim Schellart + 190 Chapter 4. Release Notes SciPy Reference Guide, Release 0.13.0 • Anthony Scopatz + • Skipper Seabold + • Fazlul Shahriar + • David Simcha + • Scott Sinclair + • Andrey Smirnov + • Collin RM Stocks + • Martin Teichmann + • Jake Vanderplas + • Gaël Varoquaux + • Pauli Virtanen • Stefan van der Walt • Warren Weckesser • Mark Wiebe + A total of 35 people contributed to this release. People with a “+” by their names contributed a patch for the first time. 4.5 SciPy 0.9.0 Release Notes Contents • SciPy 0.9.0 Release Notes – Python 3 – Scipy source code location to be changed – New features * Delaunay tesselations (scipy.spatial) * N-dimensional interpolation (scipy.interpolate) * Nonlinear equation solvers (scipy.optimize) * New linear algebra routines (scipy.linalg) * Improved FIR filter design functions (scipy.signal) * Improved statistical tests (scipy.stats) – Deprecated features * Obsolete nonlinear solvers (in scipy.optimize) – Removed features * Old correlate/convolve behavior (in scipy.signal) * scipy.stats * scipy.sparse * scipy.sparse.linalg.arpack.speigs – Other changes * ARPACK interface changes SciPy 0.9.0 is the culmination of 6 months of hard work. It contains many new features, numerous bug-fixes, improved test coverage and better documentation. There have been a number of deprecations and API changes in this release, 4.5. SciPy 0.9.0 Release Notes 191 SciPy Reference Guide, Release 0.13.0 which are documented below. All users are encouraged to upgrade to this release, as there are a large number of bugfixes and optimizations. Moreover, our development attention will now shift to bug-fix releases on the 0.9.x branch, and on adding new features on the development trunk. This release requires Python 2.4 - 2.7 or 3.1 - and NumPy 1.5 or greater. Please note that SciPy is still considered to have “Beta” status, as we work toward a SciPy 1.0.0 release. The 1.0.0 release will mark a major milestone in the development of SciPy, after which changing the package structure or API will be much more difficult. Whilst these pre-1.0 releases are considered to have “Beta” status, we are committed to making them as bug-free as possible. However, until the 1.0 release, we are aggressively reviewing and refining the functionality, organization, and interface. This is being done in an effort to make the package as coherent, intuitive, and useful as possible. To achieve this, we need help from the community of users. Specifically, we need feedback regarding all aspects of the project - everything - from which algorithms we implement, to details about our function’s call signatures. 4.5.1 Python 3 Scipy 0.9.0 is the first SciPy release to support Python 3. The only module that is not yet ported is scipy.weave. 4.5.2 Scipy source code location to be changed Soon after this release, Scipy will stop using SVN as the version control system, and move to Git. The development source code for Scipy can from then on be found at http://github.com/scipy/scipy 4.5.3 New features Delaunay tesselations (scipy.spatial) Scipy now includes routines for computing Delaunay tesselations in N dimensions, powered by the Qhull computational geometry library. Such calculations can now make use of the new scipy.spatial.Delaunay interface. N-dimensional interpolation (scipy.interpolate) Support for scattered data interpolation is now significantly improved. This version includes a scipy.interpolate.griddata function that can perform linear and nearest-neighbour interpolation for N-dimensional scattered data, in addition to cubic spline (C1-smooth) interpolation in 2D and 1D. An object-oriented interface to each interpolator type is also available. Nonlinear equation solvers (scipy.optimize) Scipy includes new routines for large-scale nonlinear equation solving in scipy.optimize. The following methods are implemented: • Newton-Krylov (scipy.optimize.newton_krylov) • (Generalized) secant methods: – Limited-memory Broyden scipy.optimize.broyden2) methods (scipy.optimize.broyden1, – Anderson method (scipy.optimize.anderson) 192 Chapter 4. Release Notes SciPy Reference Guide, Release 0.13.0 • Simple iterations (scipy.optimize.diagbroyden, scipy.optimize.linearmixing) scipy.optimize.excitingmixing, The scipy.optimize.nonlin module was completely rewritten, and some of the functions were deprecated (see above). New linear algebra routines (scipy.linalg) Scipy now contains routines for (scipy.linalg.solve_triangular). effectively solving triangular equation systems Improved FIR filter design functions (scipy.signal) The function scipy.signal.firwin was enhanced to allow the design of highpass, bandpass, bandstop and multi-band FIR filters. The function scipy.signal.firwin2 was added. This function uses the window method to create a linear phase FIR filter with an arbitrary frequency response. The functions scipy.signal.kaiser_atten and scipy.signal.kaiser_beta were added. Improved statistical tests (scipy.stats) A new function scipy.stats.fisher_exact was added, that provides Fisher’s exact test for 2x2 contingency tables. The function scipy.stats.kendalltau was rewritten to make it much faster (O(n log(n)) vs O(n^2)). 4.5.4 Deprecated features Obsolete nonlinear solvers (in scipy.optimize) The following nonlinear solvers from scipy.optimize are deprecated: • broyden_modified (bad performance) • broyden1_modified (bad performance) • broyden_generalized (equivalent to anderson) • anderson2 (equivalent to anderson) • broyden3 (obsoleted by new limited-memory broyden methods) • vackar (renamed to diagbroyden) 4.5.5 Removed features The deprecated modules helpmod, pexec and ppimport were removed from scipy.misc. The output_type keyword in many scipy.ndimage interpolation functions has been removed. The econ keyword in scipy.linalg.qr has been removed. The same functionality is still available by specifying mode=’economic’. 4.5. SciPy 0.9.0 Release Notes 193 SciPy Reference Guide, Release 0.13.0 Old correlate/convolve behavior (in scipy.signal) The old behavior for scipy.signal.convolve, scipy.signal.convolve2d, scipy.signal.correlate and scipy.signal.correlate2d was deprecated in 0.8.0 and has now been removed. Convolve and correlate used to swap their arguments if the second argument has dimensions larger than the first one, and the mode was relative to the input with the largest dimension. The current behavior is to never swap the inputs, which is what most people expect, and is how correlation is usually defined. scipy.stats Many functions in scipy.stats that are either available from numpy or have been superseded, and have been deprecated since version 0.7, have been removed: std, var, mean, median, cov, corrcoef, z, zs, stderr, samplestd, samplevar, pdfapprox, pdf_moments and erfc. These changes are mirrored in scipy.stats.mstats. scipy.sparse Several methods of the sparse matrix classes in scipy.sparse which had been deprecated since version 0.7 were removed: save, rowcol, getdata, listprint, ensure_sorted_indices, matvec, matmat and rmatvec. The functions spkron, speye, spidentity, lil_eye and lil_diags were removed from scipy.sparse. The first three functions are still available as scipy.sparse.kron, scipy.sparse.eye and scipy.sparse.identity. The dims and nzmax keywords were removed from the sparse matrix constructor. The colind and rowind attributes were removed from CSR and CSC matrices respectively. scipy.sparse.linalg.arpack.speigs A duplicated interface to the ARPACK library was removed. 4.5.6 Other changes ARPACK interface changes The interface to the ARPACK eigenvalue routines in scipy.sparse.linalg was changed for more robustness. The eigenvalue and SVD routines now raise ArpackNoConvergence if the eigenvalue iteration fails to converge. If partially converged results are desired, they can be accessed as follows: import numpy as np from scipy.sparse.linalg import eigs, ArpackNoConvergence m = np.random.randn(30, 30) try: w, v = eigs(m, 6) except ArpackNoConvergence, err: partially_converged_w = err.eigenvalues partially_converged_v = err.eigenvectors Several bugs were also fixed. The routines were moreover renamed as follows: • eigen –> eigs 194 Chapter 4. Release Notes SciPy Reference Guide, Release 0.13.0 • eigen_symmetric –> eigsh • svd –> svds 4.6 SciPy 0.8.0 Release Notes Contents • SciPy 0.8.0 Release Notes – Python 3 – Major documentation improvements – Deprecated features * Swapping inputs for correlation functions (scipy.signal) * Obsolete code deprecated (scipy.misc) * Additional deprecations – New features * DCT support (scipy.fftpack) * Single precision support for fft functions (scipy.fftpack) * Correlation functions now implement the usual definition (scipy.signal) * Additions and modification to LTI functions (scipy.signal) * Improved waveform generators (scipy.signal) * New functions and other changes in scipy.linalg * New function and changes in scipy.optimize * New sparse least squares solver * ARPACK-based sparse SVD * Alternative behavior available for scipy.constants.find * Incomplete sparse LU decompositions * Faster matlab file reader and default behavior change * Faster evaluation of orthogonal polynomials * Lambert W function * Improved hypergeometric 2F1 function * More flexible interface for Radial basis function interpolation – Removed features * scipy.io SciPy 0.8.0 is the culmination of 17 months of hard work. It contains many new features, numerous bug-fixes, improved test coverage and better documentation. There have been a number of deprecations and API changes in this release, which are documented below. All users are encouraged to upgrade to this release, as there are a large number of bug-fixes and optimizations. Moreover, our development attention will now shift to bug-fix releases on the 0.8.x branch, and on adding new features on the development trunk. This release requires Python 2.4 - 2.6 and NumPy 1.4.1 or greater. Please note that SciPy is still considered to have “Beta” status, as we work toward a SciPy 1.0.0 release. The 1.0.0 release will mark a major milestone in the development of SciPy, after which changing the package structure or API will be much more difficult. Whilst these pre-1.0 releases are considered to have “Beta” status, we are committed to making them as bug-free as possible. However, until the 1.0 release, we are aggressively reviewing and refining the functionality, organization, and interface. This is being done in an effort to make the package as coherent, intuitive, and useful as possible. To achieve this, we need help from the community of users. Specifically, we need feedback regarding all aspects of the project - everything - from which algorithms we implement, to details about our function’s call signatures. 4.6. SciPy 0.8.0 Release Notes 195 SciPy Reference Guide, Release 0.13.0 4.6.1 Python 3 Python 3 compatibility is planned and is currently technically feasible, since Numpy has been ported. However, since the Python 3 compatible Numpy 1.5 has not been released yet, support for Python 3 in Scipy is not yet included in Scipy 0.8. SciPy 0.9, planned for fall 2010, will very likely include experimental support for Python 3. 4.6.2 Major documentation improvements SciPy documentation is greatly improved. 4.6.3 Deprecated features Swapping inputs for correlation functions (scipy.signal) Concern correlate, correlate2d, convolve and convolve2d. If the second input is larger than the first input, the inputs are swapped before calling the underlying computation routine. This behavior is deprecated, and will be removed in scipy 0.9.0. Obsolete code deprecated (scipy.misc) The modules helpmod, ppimport and pexec from scipy.misc are deprecated. They will be removed from SciPy in version 0.9. Additional deprecations • linalg: The function solveh_banded currently returns a tuple containing the Cholesky factorization and the solution to the linear system. In SciPy 0.9, the return value will be just the solution. • The function constants.codata.find will generate a DeprecationWarning. In Scipy version 0.8.0, the keyword argument ‘disp’ was added to the function, with the default value ‘True’. In 0.9.0, the default will be ‘False’. • The qshape keyword argument of signal.chirp is deprecated. Use the argument vertex_zero instead. • Passing the coefficients of a polynomial as the argument f0 to signal.chirp is deprecated. Use the function signal.sweep_poly instead. • The io.recaster module has been deprecated and will be removed in 0.9.0. 4.6.4 New features DCT support (scipy.fftpack) New realtransforms have been added, namely dct and idct for Discrete Cosine Transform; type I, II and III are available. Single precision support for fft functions (scipy.fftpack) fft functions can now handle single precision inputs as well: fft(x) will return a single precision array if x is single precision. At the moment, for FFT sizes that are not composites of 2, 3, and 5, the transform is computed internally in double precision to avoid rounding error in FFTPACK. 196 Chapter 4. Release Notes SciPy Reference Guide, Release 0.13.0 Correlation functions now implement the usual definition (scipy.signal) The outputs should now correspond to their matlab and R counterparts, and do what most people expect if the old_behavior=False argument is passed: • correlate, convolve and their 2d counterparts do not swap their inputs depending on their relative shape anymore; • correlation functions now conjugate their second argument while computing the slided sum-products, which correspond to the usual definition of correlation. Additions and modification to LTI functions (scipy.signal) • The functions impulse2 and step2 were added to scipy.signal. They use the function scipy.signal.lsim2 to compute the impulse and step response of a system, respectively. • The function scipy.signal.lsim2 was changed to pass any additional keyword arguments to the ODE solver. Improved waveform generators (scipy.signal) Several improvements to the chirp function in scipy.signal were made: • The waveform generated when method=”logarithmic” was corrected; it now generates a waveform that is also known as an “exponential” or “geometric” chirp. (See http://en.wikipedia.org/wiki/Chirp.) • A new chirp method, “hyperbolic”, was added. • Instead of the keyword qshape, chirp now uses the keyword vertex_zero, a boolean. • chirp no longer handles an arbitrary polynomial. This functionality has been moved to a new function, sweep_poly. A new function, sweep_poly, was added. New functions and other changes in scipy.linalg The functions cho_solve_banded, circulant, companion, hadamard and leslie were added to scipy.linalg. The function block_diag was enhanced to accept scalar and 1D arguments, along with the usual 2D arguments. New function and changes in scipy.optimize The curve_fit function has been added; it takes a function and uses non-linear least squares to fit that to the provided data. The leastsq and fsolve functions now return an array of size one instead of a scalar when solving for a single parameter. New sparse least squares solver The lsqr function was added to scipy.sparse. This routine finds a least-squares solution to a large, sparse, linear system of equations. 4.6. SciPy 0.8.0 Release Notes 197 SciPy Reference Guide, Release 0.13.0 ARPACK-based sparse SVD A naive implementation of SVD for sparse matrices is available in scipy.sparse.linalg.eigen.arpack. It is based on using an symmetric solver on , and as such may not be very precise. Alternative behavior available for scipy.constants.find The keyword argument disp was added to the function scipy.constants.find, with the default value True. When disp is True, the behavior is the same as in Scipy version 0.7. When False, the function returns the list of keys instead of printing them. (In SciPy version 0.9, the default will be reversed.) Incomplete sparse LU decompositions Scipy now wraps SuperLU version 4.0, which supports incomplete sparse LU decompositions. These can be accessed via scipy.sparse.linalg.spilu. Upgrade to SuperLU 4.0 also fixes some known bugs. Faster matlab file reader and default behavior change We’ve rewritten the matlab file reader in Cython and it should now read matlab files at around the same speed that Matlab does. The reader reads matlab named and anonymous functions, but it can’t write them. Until scipy 0.8.0 we have returned arrays of matlab structs as numpy object arrays, where the objects have attributes named for the struct fields. As of 0.8.0, we return matlab structs as numpy structured arrays. You can get the older behavior by using the optional struct_as_record=False keyword argument to scipy.io.loadmat and friends. There is an inconsistency in the matlab file writer, in that it writes numpy 1D arrays as column vectors in matlab 5 files, and row vectors in matlab 4 files. We will change this in the next version, so both write row vectors. There is a FutureWarning when calling the writer to warn of this change; for now we suggest using the oned_as=’row’ keyword argument to scipy.io.savemat and friends. Faster evaluation of orthogonal polynomials Values of orthogonal polynomials can be evaluated with new vectorized functions in scipy.special: eval_legendre, eval_chebyt, eval_chebyu, eval_chebyc, eval_chebys, eval_jacobi, eval_laguerre, eval_genlaguerre, eval_hermite, eval_hermitenorm, eval_gegenbauer, eval_sh_legendre, eval_sh_chebyt, eval_sh_chebyu, eval_sh_jacobi. This is faster than constructing the full coefficient representation of the polynomials, which was previously the only available way. Note that the previous orthogonal polynomial routines will now also invoke this feature, when possible. Lambert W function scipy.special.lambertw can now be used for evaluating the Lambert W function. Improved hypergeometric 2F1 function Implementation of scipy.special.hyp2f1 for real parameters was revised. The new version should produce accurate values for all real parameters. 198 Chapter 4. Release Notes SciPy Reference Guide, Release 0.13.0 More flexible interface for Radial basis function interpolation The scipy.interpolate.Rbf class now accepts a callable as input for the “function” argument, in addition to the built-in radial basis functions which can be selected with a string argument. 4.6.5 Removed features scipy.stsci: the package was removed The module scipy.misc.limits was removed. The IO code in both NumPy and SciPy is being extensively reworked. NumPy will be where basic code for reading and writing NumPy arrays is located, while SciPy will house file readers and writers for various data formats (data, audio, video, images, matlab, etc.). Several functions in scipy.io are removed in the 0.8.0 release including: npfile, save, load, create_module, create_shelf, objload, objsave, fopen, read_array, write_array, fread, fwrite, bswap, packbits, unpackbits, and convert_objectarray. Some of these functions have been replaced by NumPy’s raw reading and writing capabilities, memory-mapping capabilities, or array methods. Others have been moved from SciPy to NumPy, since basic array reading and writing capability is now handled by NumPy. 4.7 SciPy 0.7.2 Release Notes Contents • SciPy 0.7.2 Release Notes SciPy 0.7.2 is a bug-fix release with no new features compared to 0.7.1. The only change is that all C sources from Cython code have been regenerated with Cython 0.12.1. This fixes the incompatibility between binaries of SciPy 0.7.1 and NumPy 1.4. 4.8 SciPy 0.7.1 Release Notes Contents • SciPy 0.7.1 Release Notes – scipy.io – scipy.odr – scipy.signal – scipy.sparse – scipy.special – scipy.stats – Windows binaries for python 2.6 – Universal build for scipy SciPy 0.7.1 is a bug-fix release with no new features compared to 0.7.0. Bugs fixed: • Several fixes in Matlab file IO 4.7. SciPy 0.7.2 Release Notes 199 SciPy Reference Guide, Release 0.13.0 Bugs fixed: • Work around a failure with Python 2.6 Memory leak in lfilter have been fixed, as well as support for array object Bugs fixed: • #880, #925: lfilter fixes • #871: bicgstab fails on Win32 Bugs fixed: • #883: scipy.io.mmread with scipy.sparse.lil_matrix broken • lil_matrix and csc_matrix reject now unexpected sequences, cf. http://thread.gmane.org/gmane.comp.python.scientific.user/19996 Several bugs of varying severity were fixed in the special functions: • #503, #640: iv: problems at large arguments fixed by new implementation • #623: jv: fix errors at large arguments • #679: struve: fix wrong output for v < 0 • #803: pbdv produces invalid output • #804: lqmn: fix crashes on some input • #823: betainc: fix documentation • #834: exp1 strange behavior near negative integer values • #852: jn_zeros: more accurate results for large s, also in jnp/yn/ynp_zeros • #853: jv, yv, iv: invalid results for non-integer v < 0, complex x • #854: jv, yv, iv, kv: return nan more consistently when out-of-domain • #927: ellipj: fix segfault on Windows • #946: ellpj: fix segfault on Mac OS X/python 2.6 combination. • ive, jve, yve, kv, kve: with real-valued input, return nan for out-of-domain instead of returning only the real part of the result. Also, when scipy.special.errprint(1) has been enabled, warning messages are now issued as Python warnings instead of printing them to stderr. • linregress, mannwhitneyu, describe: errors fixed • kstwobign, norm, expon, exponweib, exponpow, frechet, genexpon, rdist, truncexpon, planck: improvements to numerical accuracy in distributions 4.8.1 Windows binaries for python 2.6 python 2.6 binaries for windows are now included. The binary for python 2.5 requires numpy 1.2.0 or above, and and the one for python 2.6 requires numpy 1.3.0 or above. 4.8.2 Universal build for scipy Mac OS X binary installer is now a proper universal build, and does not depend on gfortran anymore (libgfortran is statically linked). The python 2.5 version of scipy requires numpy 1.2.0 or above, the python 2.6 version requires numpy 1.3.0 or above. 200 Chapter 4. Release Notes SciPy Reference Guide, Release 0.13.0 4.9 SciPy 0.7.0 Release Notes Contents • SciPy 0.7.0 Release Notes – Python 2.6 and 3.0 – Major documentation improvements – Running Tests – Building SciPy – Sandbox Removed – Sparse Matrices – Statistics package – Reworking of IO package – New Hierarchical Clustering module – New Spatial package – Reworked fftpack package – New Constants package – New Radial Basis Function module – New complex ODE integrator – New generalized symmetric and hermitian eigenvalue problem solver – Bug fixes in the interpolation package – Weave clean up – Known problems SciPy 0.7.0 is the culmination of 16 months of hard work. It contains many new features, numerous bug-fixes, improved test coverage and better documentation. There have been a number of deprecations and API changes in this release, which are documented below. All users are encouraged to upgrade to this release, as there are a large number of bug-fixes and optimizations. Moreover, our development attention will now shift to bug-fix releases on the 0.7.x branch, and on adding new features on the development trunk. This release requires Python 2.4 or 2.5 and NumPy 1.2 or greater. Please note that SciPy is still considered to have “Beta” status, as we work toward a SciPy 1.0.0 release. The 1.0.0 release will mark a major milestone in the development of SciPy, after which changing the package structure or API will be much more difficult. Whilst these pre-1.0 releases are considered to have “Beta” status, we are committed to making them as bug-free as possible. For example, in addition to fixing numerous bugs in this release, we have also doubled the number of unit tests since the last release. However, until the 1.0 release, we are aggressively reviewing and refining the functionality, organization, and interface. This is being done in an effort to make the package as coherent, intuitive, and useful as possible. To achieve this, we need help from the community of users. Specifically, we need feedback regarding all aspects of the project - everything - from which algorithms we implement, to details about our function’s call signatures. Over the last year, we have seen a rapid increase in community involvement, and numerous infrastructure improvements to lower the barrier to contributions (e.g., more explicit coding standards, improved testing infrastructure, better documentation tools). Over the next year, we hope to see this trend continue and invite everyone to become more involved. 4.9.1 Python 2.6 and 3.0 A significant amount of work has gone into making SciPy compatible with Python 2.6; however, there are still some issues in this regard. The main issue with 2.6 support is NumPy. On UNIX (including Mac OS X), NumPy 1.2.1 mostly works, with a few caveats. On Windows, there are problems related to the compilation process. The upcoming 4.9. SciPy 0.7.0 Release Notes 201 SciPy Reference Guide, Release 0.13.0 NumPy 1.3 release will fix these problems. Any remaining issues with 2.6 support for SciPy 0.7 will be addressed in a bug-fix release. Python 3.0 is not supported at all; it requires NumPy to be ported to Python 3.0. This requires immense effort, since a lot of C code has to be ported. The transition to 3.0 is still under consideration; currently, we don’t have any timeline or roadmap for this transition. 4.9.2 Major documentation improvements SciPy documentation is greatly improved; you can view a HTML reference manual online or download it as a PDF file. The new reference guide was built using the popular Sphinx tool. This release also includes an updated tutorial, which hadn’t been available since SciPy was ported to NumPy in 2005. Though not comprehensive, the tutorial shows how to use several essential parts of Scipy. It also includes the ndimage documentation from the numarray manual. Nevertheless, more effort is needed on the documentation front. Luckily, contributing to Scipy documentation is now easier than before: if you find that a part of it requires improvements, and want to help us out, please register a user name in our web-based documentation editor at http://docs.scipy.org/ and correct the issues. 4.9.3 Running Tests NumPy 1.2 introduced a new testing framework based on nose. Starting with this release, SciPy now uses the new NumPy test framework as well. Taking advantage of the new testing framework requires nose version 0.10, or later. One major advantage of the new framework is that it greatly simplifies writing unit tests - which has all ready paid off, given the rapid increase in tests. To run the full test suite: >>> import scipy >>> scipy.test(’full’) For more information, please see The NumPy/SciPy Testing Guide. We have also greatly improved our test coverage. There were just over 2,000 unit tests in the 0.6.0 release; this release nearly doubles that number, with just over 4,000 unit tests. 4.9.4 Building SciPy Support for NumScons has been added. NumScons is a tentative new build system for NumPy/SciPy, using SCons at its core. SCons is a next-generation build system, intended to replace the venerable Make with the integrated functionality of autoconf/automake and ccache. Scons is written in Python and its configuration files are Python scripts. NumScons is meant to replace NumPy’s custom version of distutils providing more advanced functionality, such as autoconf, improved fortran support, more tools, and support for numpy.distutils/scons cooperation. 4.9.5 Sandbox Removed While porting SciPy to NumPy in 2005, several packages and modules were moved into scipy.sandbox. The sandbox was a staging ground for packages that were undergoing rapid development and whose APIs were in flux. It was also a place where broken code could live. The sandbox has served its purpose well, but was starting to create confusion. Thus scipy.sandbox was removed. Most of the code was moved into scipy, some code was made into a scikit, and the remaining code was just deleted, as the functionality had been replaced by other code. 202 Chapter 4. Release Notes SciPy Reference Guide, Release 0.13.0 4.9.6 Sparse Matrices Sparse matrices have seen extensive improvements. There is now support for integer dtypes such int8, uint32, etc. Two new sparse formats were added: • new class dia_matrix : the sparse DIAgonal format • new class bsr_matrix : the Block CSR format Several new sparse matrix construction functions were added: • sparse.kron : sparse Kronecker product • sparse.bmat : sparse version of numpy.bmat • sparse.vstack : sparse version of numpy.vstack • sparse.hstack : sparse version of numpy.hstack Extraction of submatrices and nonzero values have been added: • sparse.tril : extract lower triangle • sparse.triu : extract upper triangle • sparse.find : nonzero values and their indices csr_matrix and csc_matrix now support slicing and fancy indexing (e.g., A[1:3, 4:7] and A[[3,2,6,8],:]). Conversions among all sparse formats are now possible: • using member functions such as .tocsr() and .tolil() • using the .asformat() member function, e.g. A.asformat(’csr’) • using constructors A = lil_matrix([[1,2]]); B = csr_matrix(A) All sparse constructors now accept dense matrices and lists of lists. For example: • A = csr_matrix( rand(3,3) ) and B = lil_matrix( [[1,2],[3,4]] ) The handling of diagonals in the spdiags function has been changed. It now agrees with the MATLAB(TM) function of the same name. Numerous efficiency improvements to format conversions and sparse matrix arithmetic have been made. Finally, this release contains numerous bugfixes. 4.9.7 Statistics package Statistical functions for masked arrays have been added, and are accessible through scipy.stats.mstats. The functions are similar to their counterparts in scipy.stats but they have not yet been verified for identical interfaces and algorithms. Several bugs were fixed for statistical functions, of those, kstest and percentileofscore gained new keyword arguments. Added deprecation warning for mean, median, var, std, cov, and corrcoef. These functions should be replaced by their numpy counterparts. Note, however, that some of the default options differ between the scipy.stats and numpy versions of these functions. Numerous bug fixes to stats.distributions: all generic methods now work correctly, several methods in individual distributions were corrected. However, a few issues remain with higher moments (skew, kurtosis) and entropy. The maximum likelihood estimator, fit, does not work out-of-the-box for some distributions - in some cases, starting values have to be carefully chosen, in other cases, the generic implementation of the maximum likelihood method might not be the numerically appropriate estimation method. 4.9. SciPy 0.7.0 Release Notes 203 SciPy Reference Guide, Release 0.13.0 We expect more bugfixes, increases in numerical precision and enhancements in the next release of scipy. 4.9.8 Reworking of IO package The IO code in both NumPy and SciPy is being extensively reworked. NumPy will be where basic code for reading and writing NumPy arrays is located, while SciPy will house file readers and writers for various data formats (data, audio, video, images, matlab, etc.). Several functions in scipy.io have been deprecated and will be removed in the 0.8.0 release including npfile, save, load, create_module, create_shelf, objload, objsave, fopen, read_array, write_array, fread, fwrite, bswap, packbits, unpackbits, and convert_objectarray. Some of these functions have been replaced by NumPy’s raw reading and writing capabilities, memory-mapping capabilities, or array methods. Others have been moved from SciPy to NumPy, since basic array reading and writing capability is now handled by NumPy. The Matlab (TM) file readers/writers have a number of improvements: • default version 5 • v5 writers for structures, cell arrays, and objects • v5 readers/writers for function handles and 64-bit integers • new struct_as_record keyword argument to loadmat, which loads struct arrays in matlab as record arrays in numpy • string arrays have dtype=’U...’ instead of dtype=object • loadmat no longer squeezes singleton dimensions, i.e. squeeze_me=False by default 4.9.9 New Hierarchical Clustering module This module adds new hierarchical clustering functionality to the scipy.cluster package. The function interfaces are similar to the functions provided MATLAB(TM)’s Statistics Toolbox to help facilitate easier migration to the NumPy/SciPy framework. Linkage methods implemented include single, complete, average, weighted, centroid, median, and ward. In addition, several functions are provided for computing inconsistency statistics, cophenetic distance, and maximum distance between descendants. The fcluster and fclusterdata functions transform a hierarchical clustering into a set of flat clusters. Since these flat clusters are generated by cutting the tree into a forest of trees, the leaders function takes a linkage and a flat clustering, and finds the root of each tree in the forest. The ClusterNode class represents a hierarchical clusterings as a field-navigable tree object. to_tree converts a matrix-encoded hierarchical clustering to a ClusterNode object. Routines for converting between MATLAB and SciPy linkage encodings are provided. Finally, a dendrogram function plots hierarchical clusterings as a dendrogram, using matplotlib. 4.9.10 New Spatial package The new spatial package contains a collection of spatial algorithms and data structures, useful for spatial statistics and clustering applications. It includes rapidly compiled code for computing exact and approximate nearest neighbors, as well as a pure-python kd-tree with the same interface, but that supports annotation and a variety of other algorithms. The API for both modules may change somewhat, as user requirements become clearer. It also includes a distance module, containing a collection of distance and dissimilarity functions for computing distances between vectors, which is useful for spatial statistics, clustering, and kd-trees. Distance and dissimilarity functions provided include Bray-Curtis, Canberra, Chebyshev, City Block, Cosine, Dice, Euclidean, Hamming, 204 Chapter 4. Release Notes SciPy Reference Guide, Release 0.13.0 Jaccard, Kulsinski, Mahalanobis, Matching, Minkowski, Rogers-Tanimoto, Russell-Rao, Squared Euclidean, Standardized Euclidean, Sokal-Michener, Sokal-Sneath, and Yule. The pdist function computes pairwise distance between all unordered pairs of vectors in a set of vectors. The cdist computes the distance on all pairs of vectors in the Cartesian product of two sets of vectors. Pairwise distance matrices are stored in condensed form; only the upper triangular is stored. squareform converts distance matrices between square and condensed forms. 4.9.11 Reworked fftpack package FFTW2, FFTW3, MKL and DJBFFT wrappers have been removed. Only (NETLIB) fftpack remains. By focusing on one backend, we hope to add new features - like float32 support - more easily. 4.9.12 New Constants package scipy.constants provides a collection of physical constants and conversion factors. These constants are taken from CODATA Recommended Values of the Fundamental Physical Constants: 2002. They may be found at physics.nist.gov/constants. The values are stored in the dictionary physical_constants as a tuple containing the value, the units, and the relative precision - in that order. All constants are in SI units, unless otherwise stated. Several helper functions are provided. 4.9.13 New Radial Basis Function module scipy.interpolate now contains a Radial Basis Function module. Radial basis functions can be used for smoothing/interpolating scattered data in n-dimensions, but should be used with caution for extrapolation outside of the observed data range. 4.9.14 New complex ODE integrator scipy.integrate.ode now contains a wrapper for the ZVODE complex-valued ordinary differential equation solver (by Peter N. Brown, Alan C. Hindmarsh, and George D. Byrne). 4.9.15 New generalized symmetric and hermitian eigenvalue problem solver scipy.linalg.eigh now contains wrappers for more LAPACK symmetric and hermitian eigenvalue problem solvers. Users can now solve generalized problems, select a range of eigenvalues only, and choose to use a faster algorithm at the expense of increased memory usage. The signature of the scipy.linalg.eigh changed accordingly. 4.9.16 Bug fixes in the interpolation package The shape of return values from scipy.interpolate.interp1d used to be incorrect, if interpolated data had more than 2 dimensions and the axis keyword was set to a non-default value. This has been fixed. Moreover, interp1d returns now a scalar (0D-array) if the input is a scalar. Users of scipy.interpolate.interp1d may need to revise their code if it relies on the previous behavior. 4.9.17 Weave clean up There were numerous improvements to scipy.weave. blitz++ was relicensed by the author to be compatible with the SciPy license. wx_spec.py was removed. 4.9. SciPy 0.7.0 Release Notes 205 SciPy Reference Guide, Release 0.13.0 4.9.18 Known problems Here are known problems with scipy 0.7.0: • weave test failures on windows: those are known, and are being revised. • weave test failure with gcc 4.3 (std::labs): this is a gcc 4.3 bug. A workaround is to add #include in scipy/weave/blitz/blitz/funcs.h (line 27). You can make the change in the installed scipy (in site-packages). 206 Chapter 4. Release Notes CHAPTER FIVE REFERENCE 5.1 Clustering package (scipy.cluster) scipy.cluster.vq Clustering algorithms are useful in information theory, target detection, communications, compression, and other areas. The vq module only supports vector quantization and the k-means algorithms. scipy.cluster.hierarchy The hierarchy module provides functions for hierarchical and agglomerative clustering. Its features include generating hierarchical clusters from distance matrices, computing distance matrices from observation vectors, calculating statistics on clusters, cutting linkages to generate flat clusters, and visualizing clusters with dendrograms. 5.2 K-means clustering (scipy.cluster.vq) and vector quantization Provides routines for k-means clustering, generating code books from k-means models, and quantizing vectors by comparing them with centroids in a code book. whiten(obs) vq(obs, code_book) kmeans(obs, k_or_guess[, iter, thresh]) kmeans2(data, k[, iter, thresh, minit, missing]) Normalize a group of observations on a per feature basis. Assign codes from a code book to observations. Performs k-means on a set of observation vectors forming k clusters. Classify a set of observations into k clusters using the k-means algorithm. scipy.cluster.vq.whiten(obs) Normalize a group of observations on a per feature basis. Before running k-means, it is beneficial to rescale each feature dimension of the observation set with whitening. Each feature is divided by its standard deviation across all observations to give it unit variance. Parameters obs : ndarray Each row of the array is an observation. The columns are the features seen during each observation. >>> # >>> obs = [[ ... [ ... [ ... [ f0 1., 2., 3., 4., f1 1., 2., 3., 4., f2 1.], 2.], 3.], 4.]]) #o0 #o1 #o2 #o3 207 SciPy Reference Guide, Release 0.13.0 Returns result : ndarray Contains the values in obs scaled by the standard deviation of each column. Examples >>> from scipy.cluster.vq import whiten >>> features = np.array([[1.9, 2.3, 1.7], ... [1.5, 2.5, 2.2], ... [0.8, 0.6, 1.7,]]) >>> whiten(features) array([[ 4.17944278, 2.69811351, 7.21248917], [ 3.29956009, 2.93273208, 9.33380951], [ 1.75976538, 0.7038557 , 7.21248917]]) scipy.cluster.vq.vq(obs, code_book) Assign codes from a code book to observations. Assigns a code from a code book to each observation. Each observation vector in the ‘M’ by ‘N’ obs array is compared with the centroids in the code book and assigned the code of the closest centroid. The features in obs should have unit variance, which can be acheived by passing them through the whiten function. The code book can be created with the k-means algorithm or a different encoding algorithm. Parameters obs : ndarray Each row of the ‘N’ x ‘M’ array is an observation. The columns are the “features” seen during each observation. The features must be whitened first using the whiten function or something equivalent. code_book : ndarray The code book is usually generated using the k-means algorithm. Each row of the array holds a different code, and the columns are the features of the code. >>> # >>> code_book = [ ... [ ... [ ... [ Returns f0 f1 f2 1., 1., 1., 2., 2., 2., 3., 3., 3., f3 4.], #c0 4.], #c1 4.]]) #c2 code : ndarray A length N array holding the code book index for each observation. dist : ndarray The distortion (distance) between the observation and its nearest code. Notes This currently forces 32-bit math precision for speed. Anyone know of a situation where this undermines the accuracy of the algorithm? Examples >>> from numpy import array >>> from scipy.cluster.vq import vq >>> code_book = array([[1.,1.,1.], ... [2.,2.,2.]]) >>> features = array([[ 1.9,2.3,1.7], ... [ 1.5,2.5,2.2], ... [ 0.8,0.6,1.7]]) >>> vq(features,code_book) (array([1, 1, 0],’i’), array([ 0.43588989, 208 0.73484692, 0.83066239])) Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 scipy.cluster.vq.kmeans(obs, k_or_guess, iter=20, thresh=1e-05) Performs k-means on a set of observation vectors forming k clusters. The k-means algorithm adjusts the centroids until sufficient progress cannot be made, i.e. the change in distortion since the last iteration is less than some threshold. This yields a code book mapping centroids to codes and vice versa. Distortion is defined as the sum of the squared differences between the observations and the corresponding centroid. Parameters Returns obs : ndarray Each row of the M by N array is an observation vector. The columns are the features seen during each observation. The features must be whitened first with the whiten function. k_or_guess : int or ndarray The number of centroids to generate. A code is assigned to each centroid, which is also the row index of the centroid in the code_book matrix generated. The initial k centroids are chosen by randomly selecting observations from the observation matrix. Alternatively, passing a k by N array specifies the initial k centroids. iter : int, optional The number of times to run k-means, returning the codebook with the lowest distortion. This argument is ignored if initial centroids are specified with an array for the k_or_guess parameter. This parameter does not represent the number of iterations of the k-means algorithm. thresh : float, optional Terminates the k-means algorithm if the change in distortion since the last k-means iteration is less than or equal to thresh. codebook : ndarray A k by N array of k centroids. The i’th centroid codebook[i] is represented with the code i. The centroids and codes generated represent the lowest distortion seen, not necessarily the globally minimal distortion. distortion : float The distortion between the observations passed and the centroids generated. See Also kmeans2 a different implementation of k-means clustering with more methods for generating initial centroids but without using a distortion change threshold as a stopping criterion. whiten must be called prior to passing an observation matrix to kmeans. Examples >>> >>> >>> ... ... ... ... ... ... ... ... >>> >>> >>> from numpy import array from scipy.cluster.vq import vq, kmeans, whiten features = array([[ 1.9,2.3], [ 1.5,2.5], [ 0.8,0.6], [ 0.4,1.8], [ 0.1,0.1], [ 0.2,1.8], [ 2.0,0.5], [ 0.3,1.5], [ 1.0,1.0]]) whitened = whiten(features) book = array((whitened[0],whitened[2])) kmeans(whitened,book) 5.2. K-means clustering and vector quantization (scipy.cluster.vq) 209 SciPy Reference Guide, Release 0.13.0 (array([[ 2.3110306 , 2.86287398], [ 0.93218041, 1.24398691]]), 0.85684700941625547) >>> from numpy import random >>> random.seed((1000,2000)) >>> codes = 3 >>> kmeans(whitened,codes) (array([[ 2.3110306 , 2.86287398], [ 1.32544402, 0.65607529], [ 0.40782893, 2.02786907]]), 0.5196582527686241) scipy.cluster.vq.kmeans2(data, k, iter=10, thresh=1e-05, minit=’random’, missing=’warn’) Classify a set of observations into k clusters using the k-means algorithm. The algorithm attempts to minimize the Euclidian distance between observations and centroids. Several initialization methods are included. Parameters Returns data : ndarray A ‘M’ by ‘N’ array of ‘M’ observations in ‘N’ dimensions or a length ‘M’ array of ‘M’ one-dimensional observations. k : int or ndarray The number of clusters to form as well as the number of centroids to generate. If minit initialization string is ‘matrix’, or if a ndarray is given instead, it is interpreted as initial cluster to use instead. iter : int Number of iterations of the k-means algrithm to run. Note that this differs in meaning from the iters parameter to the kmeans function. thresh : float (not used yet) minit : string Method for initialization. Available methods are ‘random’, ‘points’, ‘uniform’, and ‘matrix’: ‘random’: generate k centroids from a Gaussian with mean and variance estimated from the data. ‘points’: choose k observations (rows) at random from data for the initial centroids. ‘uniform’: generate k observations from the data from a uniform distribution defined by the data set (unsupported). ‘matrix’: interpret the k parameter as a k by M (or length k array for one-dimensional data) array of initial centroids. centroid : ndarray A ‘k’ by ‘N’ array of centroids found at the last iteration of k-means. label : ndarray label[i] is the code or index of the centroid the i’th observation is closest to. 5.2.1 Background information The k-means algorithm takes as input the number of clusters to generate, k, and a set of observation vectors to cluster. It returns a set of centroids, one for each of the k clusters. An observation vector is classified with the cluster number or centroid index of the centroid closest to it. A vector v belongs to cluster i if it is closer to centroid i than any other centroids. If v belongs to i, we say centroid i is the dominating centroid of v. The k-means algorithm tries to minimize distortion, which is defined as the sum of the squared distances between each observation vector and its dominating centroid. Each step of the k-means algorithm refines the choices of centroids to reduce distortion. The change in distortion is used as a stopping criterion: when 210 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 the change is lower than a threshold, the k-means algorithm is not making sufficient progress and terminates. One can also define a maximum number of iterations. Since vector quantization is a natural application for k-means, information theory terminology is often used. The centroid index or cluster index is also referred to as a “code” and the table mapping codes to centroids and vice versa is often referred as a “code book”. The result of k-means, a set of centroids, can be used to quantize vectors. Quantization aims to find an encoding of vectors that reduces the expected distortion. All routines expect obs to be a M by N array where the rows are the observation vectors. The codebook is a k by N array where the i’th row is the centroid of code word i. The observation vectors and centroids have the same feature dimension. As an example, suppose we wish to compress a 24-bit color image (each pixel is represented by one byte for red, one for blue, and one for green) before sending it over the web. By using a smaller 8-bit encoding, we can reduce the amount of data by two thirds. Ideally, the colors for each of the 256 possible 8-bit encoding values should be chosen to minimize distortion of the color. Running k-means with k=256 generates a code book of 256 codes, which fills up all possible 8-bit sequences. Instead of sending a 3-byte value for each pixel, the 8-bit centroid index (or code word) of the dominating centroid is transmitted. The code book is also sent over the wire so each 8-bit code can be translated back to a 24-bit pixel value representation. If the image of interest was of an ocean, we would expect many 24-bit blues to be represented by 8-bit codes. If it was an image of a human face, more flesh tone colors would be represented in the code book. 5.3 Hierarchical clustering (scipy.cluster.hierarchy) These functions cut hierarchical clusterings into flat clusterings or find the roots of the forest formed by a cut by providing the flat cluster ids of each observation. fcluster(Z, t[, criterion, depth, R, monocrit]) fclusterdata(X, t[, criterion, metric, ...]) leaders(Z, T) Forms flat clusters from the hierarchical clustering defined by Cluster observation data using a given metric. Returns the root nodes in a hierarchical clustering. scipy.cluster.hierarchy.fcluster(Z, t, criterion=’inconsistent’, depth=2, R=None, monocrit=None) Forms flat clusters from the hierarchical clustering defined by the linkage matrix Z. Parameters Z : ndarray The hierarchical clustering encoded with the matrix returned by the linkage function. t : float The threshold to apply when forming flat clusters. criterion : str, optional The criterion to use in forming flat clusters. This can be any of the following values: inconsistent [If a cluster node and all its] descendants have an inconsistent value less than or equal to t then all its leaf descendants belong to the same flat cluster. When no non-singleton cluster meets this criterion, every node is assigned to its own cluster. (Default) distance [Forms flat clusters so that the original] observations in each flat cluster have no greater a cophenetic distance than t. maxclust [Finds a minimum threshold r so that] the cophenetic distance between any two original observations in the same flat cluster is no more than r and no more than t flat clusters are formed. monocrit [Forms a flat cluster from a cluster node c] with index i when monocrit[j] <= t. 5.3. Hierarchical clustering (scipy.cluster.hierarchy) 211 SciPy Reference Guide, Release 0.13.0 Returns For example, to threshold on the maximum mean distance as computed in the inconsistency matrix R with a threshold of 0.8 do: MR = maxRstat(Z, R, 3) cluster(Z, t=0.8, criterion=’monocrit’, monocrit=MR) maxclust_monocrit [Forms a flat cluster from a] non-singleton cluster node c when monocrit[i] <= r for all cluster indices i below and including c. r is minimized such that no more than t flat clusters are formed. monocrit must be monotonic. For example, to minimize the threshold t on maximum inconsistency values so that no more than 3 flat clusters are formed, do: MI = maxinconsts(Z, R) cluster(Z, t=3, criterion=’maxclust_monocrit’, monocrit=MI) depth : int, optional The maximum depth to perform the inconsistency calculation. It has no meaning for the other criteria. Default is 2. R : ndarray, optional The inconsistency matrix to use for the ‘inconsistent’ criterion. This matrix is computed if not provided. monocrit : ndarray, optional An array of length n-1. monocrit[i] is the statistics upon which non-singleton i is thresholded. The monocrit vector must be monotonic, i.e. given a node c with index i, for all node indices j corresponding to nodes below c, monocrit[i] >= monocrit[j]. fcluster : ndarray An array of length n. T[i] is the flat cluster number to which original observation i belongs. scipy.cluster.hierarchy.fclusterdata(X, t, criterion=’inconsistent’, metric=’euclidean’, depth=2, method=’single’, R=None) Cluster observation data using a given metric. Clusters the original observations in the n-by-m data matrix X (n observations in m dimensions), using the euclidean distance metric to calculate distances between original observations, performs hierarchical clustering using the single linkage algorithm, and forms flat clusters using the inconsistency method with t as the cut-off threshold. A one-dimensional array T of length n is returned. T[i] is the index of the flat cluster to which the original observation i belongs. Parameters 212 X : (N, M) ndarray N by M data matrix with N observations in M dimensions. t : float The threshold to apply when forming flat clusters. criterion : str, optional Specifies the criterion for forming flat clusters. Valid values are ‘inconsistent’ (default), ‘distance’, or ‘maxclust’ cluster formation algorithms. See fcluster for descriptions. metric : str, optional The distance metric for calculating pairwise distances. See distance.pdist for descriptions and linkage to verify compatibility with the linkage method. depth : int, optional The maximum depth for the inconsistency calculation. See inconsistent for more information. method : str, optional The linkage method to use (single, complete, average, weighted, median centroid, ward). See linkage for more information. Default is “single”. Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Returns R : ndarray, optional The inconsistency matrix. It will be computed if necessary if it is not passed. fclusterdata : ndarray A vector of length n. T[i] is the flat cluster number to which original observation i belongs. Notes This function is similar to the MATLAB function clusterdata. scipy.cluster.hierarchy.leaders(Z, T) Returns the root nodes in a hierarchical clustering. Returns the root nodes in a hierarchical clustering corresponding to a cut defined by a flat cluster assignment vector T. See the fcluster function for more information on the format of T. For each flat cluster j of the k flat clusters represented in the n-sized flat cluster assignment vector T, this function finds the lowest cluster node i in the linkage tree Z such that: •leaf descendents belong only to flat cluster j (i.e. T[p]==j for all p in S(i) where S(i) is the set of leaf ids of leaf nodes descendent with cluster node i) •there does not exist a leaf that is not descendent with i that also belongs to cluster j (i.e. T[q]!=j for all q not in S(i)). If this condition is violated, T is not a valid cluster assignment vector, and an exception will be thrown. Parameters Returns Z : ndarray The hierarchical clustering encoded as a matrix. See linkage for more information. T : ndarray The flat cluster assignment vector. L : ndarray The leader linkage node id’s stored as a k-element 1-D array where k is the number of flat clusters found in T. L[j]=i is the linkage cluster node id that is the leader of flat cluster with id M[j]. If i < n, i corresponds to an original observation, otherwise it corresponds to a non-singleton cluster. For example: if L[3]=2 and M[3]=8, the flat cluster with id 8’s leader is linkage node 2. M : ndarray The leader linkage node id’s stored as a k-element 1-D array where k is the number of flat clusters found in T. This allows the set of flat cluster ids to be any arbitrary set of k integers. These are routines for agglomerative clustering. linkage(y[, method, metric]) single(y) complete(y) average(y) weighted(y) centroid(y) median(y) ward(y) Performs hierarchical/agglomerative clustering on the condensed distance matrix y. Performs single/min/nearest linkage on the condensed distance matrix y Performs complete/max/farthest point linkage on a condensed distance matrix Performs average/UPGMA linkage on a condensed distance matrix Performs weighted/WPGMA linkage on the condensed distance matrix. Performs centroid/UPGMC linkage. Performs median/WPGMC linkage. Performs Ward’s linkage on a condensed or redundant distance matrix. scipy.cluster.hierarchy.linkage(y, method=’single’, metric=’euclidean’) Performs hierarchical/agglomerative clustering on the condensed distance matrix y. 5.3. Hierarchical clustering (scipy.cluster.hierarchy) 213 SciPy Reference Guide, Release 0.13.0 y must be a n2 sized vector where n is the number of original observations paired in the distance matrix. The behavior of this function is very similar to the MATLAB linkage function. A 4 by (n − 1) matrix Z is returned. At the i-th iteration, clusters with indices Z[i, 0] and Z[i, 1] are combined to form cluster n + i. A cluster with an index less than n corresponds to one of the n original observations. The distance between clusters Z[i, 0] and Z[i, 1] is given by Z[i, 2]. The fourth value Z[i, 3] represents the number of original observations in the newly formed cluster. The following linkage methods are used to compute the distance d(s, t) between two clusters s and t. The algorithm begins with a forest of clusters that have yet to be used in the hierarchy being formed. When two clusters s and t from this forest are combined into a single cluster u, s and t are removed from the forest, and u is added to the forest. When only one cluster remains in the forest, the algorithm stops, and this cluster becomes the root. A distance matrix is maintained at each iteration. The d[i,j] entry corresponds to the distance between cluster i and j in the original forest. At each iteration, the algorithm must update the distance matrix to reflect the distance of the newly formed cluster u with the remaining clusters in the forest. Suppose there are |u| original observations u[0], . . . , u[|u| − 1] in cluster u and |v| original objects v[0], . . . , v[|v| − 1] in cluster v. Recall s and t are combined to form cluster u. Let v be any remaining cluster in the forest that is not u. The following are methods for calculating the distance between the newly formed cluster u and each v. •method=’single’ assigns d(u, v) = min(dist(u[i], v[j])) for all points i in cluster u and j in cluster v. This is also known as the Nearest Point Algorithm. •method=’complete’ assigns d(u, v) = max(dist(u[i], v[j])) for all points i in cluster u and j in cluster v. This is also known by the Farthest Point Algorithm or Voor Hees Algorithm. •method=’average’ assigns d(u, v) = X d(u[i], v[j]) ij (|u| ∗ |v|) for all points i and j where |u| and |v| are the cardinalities of clusters u and v, respectively. This is also called the UPGMA algorithm. This is called UPGMA. •method=’weighted’ assigns d(u, v) = (dist(s, v) + dist(t, v))/2 where cluster u was formed with cluster s and t and v is a remaining cluster in the forest. (also called WPGMA) 214 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 •method=’centroid’ assigns dist(s, t) = ||cs − ct ||2 where cs and ct are the centroids of clusters s and t, respectively. When two clusters s and t are combined into a new cluster u, the new centroid is computed over all the original objects in clusters s and t. The distance then becomes the Euclidean distance between the centroid of u and the centroid of a remaining cluster v in the forest. This is also known as the UPGMC algorithm. •method=’median’ assigns math:d(s,t) like the centroid method. When two clusters s and t are combined into a new cluster u, the average of centroids s and t give the new centroid u. This is also known as the WPGMC algorithm. •method=’ward’ uses the Ward variance minimization algorithm. The new entry d(u, v) is computed as follows, r |v| + |s| |v| + |t| |v| d(v, s)2 + d(v, t)2 + d(s, t)2 d(u, v) = T T T where u is the newly joined cluster consisting of clusters s and t, v is an unused cluster in the forest, T = |v| + |s| + |t|, and | ∗ | is the cardinality of its argument. This is also known as the incremental algorithm. Warning: When the minimum distance pair in the forest is chosen, there may be two or more pairs with the same minimum distance. This implementation may chose a different minimum than the MATLAB version. Parameters Returns y : ndarray A condensed or redundant distance matrix. A condensed distance matrix is a flat array containing the upper triangular of the distance matrix. This is the form that pdist returns. Alternatively, a collection of m observation vectors in n dimensions may be passed as an m by n array. method : str, optional The linkage algorithm to use. See the Linkage Methods section below for full descriptions. metric : str, optional The distance metric to use. See the distance.pdist function for a list of valid distance metrics. Z : ndarray The hierarchical clustering encoded as a linkage matrix. scipy.cluster.hierarchy.single(y) Performs single/min/nearest linkage on the condensed distance matrix y Parameters Returns y : ndarray The upper triangular of the distance matrix. The result of pdist is returned in this form. Z : ndarray The linkage matrix. See Also linkage for advanced creation of hierarchical clusterings. scipy.cluster.hierarchy.complete(y) Performs complete/max/farthest point linkage on a condensed distance matrix Parameters y : ndarray 5.3. Hierarchical clustering (scipy.cluster.hierarchy) 215 SciPy Reference Guide, Release 0.13.0 The upper triangular of the distance matrix. The result of pdist is returned in this form. Z : ndarray A linkage matrix containing the hierarchical clustering. See the linkage function documentation for more information on its structure. Returns See Also linkage scipy.cluster.hierarchy.average(y) Performs average/UPGMA linkage on a condensed distance matrix Parameters Returns y : ndarray The upper triangular of the distance matrix. The result of pdist is returned in this form. Z : ndarray A linkage matrix containing the hierarchical clustering. See the linkage function documentation for more information on its structure. See Also linkage for advanced creation of hierarchical clusterings. scipy.cluster.hierarchy.weighted(y) Performs weighted/WPGMA linkage on the condensed distance matrix. See linkage for more information on the return structure and algorithm. Parameters Returns y : ndarray The upper triangular of the distance matrix. The result of pdist is returned in this form. Z : ndarray A linkage matrix containing the hierarchical clustering. See the linkage function documentation for more information on its structure. See Also linkage for advanced creation of hierarchical clusterings. scipy.cluster.hierarchy.centroid(y) Performs centroid/UPGMC linkage. See linkage for more information on the return structure and algorithm. The following are common calling conventions: 1.Z = centroid(y) Performs centroid/UPGMC linkage on the condensed distance matrix y. See linkage for more information on the return structure and algorithm. 2.Z = centroid(X) Performs centroid/UPGMC linkage on the observation matrix X using Euclidean distance as the distance metric. See linkage for more information on the return structure and algorithm. Parameters 216 Q : ndarray Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 A condensed or redundant distance matrix. A condensed distance matrix is a flat array containing the upper triangular of the distance matrix. This is the form that pdist returns. Alternatively, a collection of m observation vectors in n dimensions may be passed as a m by n array. Z : ndarray A linkage matrix containing the hierarchical clustering. See the linkage function documentation for more information on its structure. Returns See Also linkage for advanced creation of hierarchical clusterings. scipy.cluster.hierarchy.median(y) Performs median/WPGMC linkage. See linkage for more information on the return structure and algorithm. The following are common calling conventions: 1.Z = median(y) Performs median/WPGMC linkage on the condensed distance matrix y. See linkage for more information on the return structure and algorithm. 2.Z = median(X) Performs median/WPGMC linkage on the observation matrix X using Euclidean distance as the distance metric. See linkage for more information on the return structure and algorithm. Parameters Returns Q : ndarray A condensed or redundant distance matrix. A condensed distance matrix is a flat array containing the upper triangular of the distance matrix. This is the form that pdist returns. Alternatively, a collection of m observation vectors in n dimensions may be passed as a m by n array. Z : ndarray The hierarchical clustering encoded as a linkage matrix. See Also linkage for advanced creation of hierarchical clusterings. scipy.cluster.hierarchy.ward(y) Performs Ward’s linkage on a condensed or redundant distance matrix. See linkage for more information on the return structure and algorithm. The following are common calling conventions: 1.Z = ward(y) Performs Ward’s linkage on the condensed distance matrix Z. See linkage for more information on the return structure and algorithm. 2.Z = ward(X) Performs Ward’s linkage on the observation matrix X using Euclidean distance as the distance metric. See linkage for more information on the return structure and algorithm. Parameters Returns Q : ndarray A condensed or redundant distance matrix. A condensed distance matrix is a flat array containing the upper triangular of the distance matrix. This is the form that pdist returns. Alternatively, a collection of m observation vectors in n dimensions may be passed as a m by n array. Z : ndarray The hierarchical clustering encoded as a linkage matrix. 5.3. Hierarchical clustering (scipy.cluster.hierarchy) 217 SciPy Reference Guide, Release 0.13.0 See Also linkage for advanced creation of hierarchical clusterings. These routines compute statistics on hierarchies. cophenet(Z[, Y]) from_mlab_linkage(Z) inconsistent(Z[, d]) maxinconsts(Z, R) maxdists(Z) maxRstat(Z, R, i) to_mlab_linkage(Z) Calculates the cophenetic distances between each observation in Converts a linkage matrix generated by MATLAB(TM) to a new Calculates inconsistency statistics on a linkage. Returns the maximum inconsistency coefficient for each non-singleton cluster and its descendents. Returns the maximum distance between any non-singleton cluster. Returns the maximum statistic for each non-singleton cluster and its descendents. Converts a linkage matrix to a MATLAB(TM) compatible one. scipy.cluster.hierarchy.cophenet(Z, Y=None) Calculates the cophenetic distances between each observation in the hierarchical clustering defined by the linkage Z. Suppose p and q are original observations in disjoint clusters s and t, respectively and s and t are joined by a direct parent cluster u. The cophenetic distance between observations i and j is simply the distance between clusters s and t. Parameters Returns Z : ndarray The hierarchical clustering encoded as an array (see linkage function). Y : ndarray (optional) Calculates the cophenetic correlation coefficient c of a hierarchical clustering defined by the linkage matrix Z of a set of n observations in m dimensions. Y is the condensed distance matrix from which Z was generated. c : ndarray The cophentic correlation distance (if y is passed). d : ndarray The cophenetic distance matrix in condensed form. The ij th entry is the cophenetic distance between original observations i and j. scipy.cluster.hierarchy.from_mlab_linkage(Z) Converts a linkage matrix generated by MATLAB(TM) to a new linkage matrix compatible with this module. The conversion does two things: •the indices are converted from 1..N to 0..(N-1) form, and •a fourth column Z[:,3] is added where Z[i,3] is represents the number of original observations (leaves) in the non-singleton cluster i. This function is useful when loading in linkages from legacy data files generated by MATLAB. Parameters Returns Z : ndarray A linkage matrix generated by MATLAB(TM). ZS : ndarray A linkage matrix compatible with this library. scipy.cluster.hierarchy.inconsistent(Z, d=2) Calculates inconsistency statistics on a linkage. Note: This function behaves similarly to the MATLAB(TM) inconsistent function. Parameters 218 Z : ndarray The (n − 1) by 4 matrix encoding the linkage (hierarchical clustering). See linkage documentation for more information on its form. Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Returns d : int, optional The number of links up to d levels below each non-singleton cluster. R : ndarray A (n − 1) by 5 matrix where the i‘th row contains the link statistics for the nonsingleton cluster i. The link statistics are computed over the link heights for links d levels below the cluster i. R[i,0] and R[i,1] are the mean and standard deviation of the link heights, respectively; R[i,2] is the number of links included in the calculation; and R[i,3] is the inconsistency coefficient, Z[i, 2] − R[i, 0] R[i, 1] scipy.cluster.hierarchy.maxinconsts(Z, R) Returns the maximum inconsistency coefficient for each non-singleton cluster and its descendents. Parameters Returns Z : ndarray The hierarchical clustering encoded as a matrix. See linkage for more information. R : ndarray The inconsistency matrix. MI : ndarray A monotonic (n-1)-sized numpy array of doubles. scipy.cluster.hierarchy.maxdists(Z) Returns the maximum distance between any non-singleton cluster. Parameters Returns Z : ndarray The hierarchical clustering encoded as a matrix. See linkage for more information. maxdists : ndarray A (n-1) sized numpy array of doubles; MD[i] represents the maximum distance between any cluster (including singletons) below and including the node with index i. More specifically, MD[i] = Z[Q(i)-n, 2].max() where Q(i) is the set of all node indices below and including node i. scipy.cluster.hierarchy.maxRstat(Z, R, i) Returns the maximum statistic for each non-singleton cluster and its descendents. Parameters Returns Z : array_like The hierarchical clustering encoded as a matrix. See linkage for more information. R : array_like The inconsistency matrix. i : int The column of R to use as the statistic. MR : ndarray Calculates the maximum statistic for the i’th column of the inconsistency matrix R for each non-singleton cluster node. MR[j] is the maximum over R[Q(j)-n, i] where Q(j) the set of all node ids corresponding to nodes below and including j. scipy.cluster.hierarchy.to_mlab_linkage(Z) Converts a linkage matrix to a MATLAB(TM) compatible one. Converts a linkage matrix Z generated by the linkage function of this module to a MATLAB(TM) compatible one. The return linkage matrix has the last column removed and the cluster indices are converted to 1..N indexing. Parameters Returns Z : ndarray A linkage matrix generated by this library. to_mlab_linkage : ndarray 5.3. Hierarchical clustering (scipy.cluster.hierarchy) 219 SciPy Reference Guide, Release 0.13.0 A linkage matrix compatible with MATLAB(TM)’s hierarchical clustering functions. The return linkage matrix has the last column removed and the cluster indices are converted to 1..N indexing. Routines for visualizing flat clusters. dendrogram(Z[, p, truncate_mode, ...]) Plots the hierarchical clustering as a dendrogram. scipy.cluster.hierarchy.dendrogram(Z, p=30, truncate_mode=None, color_threshold=None, get_leaves=True, orientation=’top’, labels=None, count_sort=False, distance_sort=False, show_leaf_counts=True, no_plot=False, no_labels=False, color_list=None, leaf_font_size=None, leaf_rotation=None, leaf_label_func=None, no_leaves=False, show_contracted=False, link_color_func=None) Plots the hierarchical clustering as a dendrogram. The dendrogram illustrates how each cluster is composed by drawing a U-shaped link between a non-singleton cluster and its children. The height of the top of the U-link is the distance between its children clusters. It is also the cophenetic distance between original observations in the two children clusters. It is expected that the distances in Z[:,2] be monotonic, otherwise crossings appear in the dendrogram. Parameters 220 Z : ndarray The linkage matrix encoding the hierarchical clustering to render as a dendrogram. See the linkage function for more information on the format of Z. p : int, optional The p parameter for truncate_mode. truncate_mode : str, optional The dendrogram can be hard to read when the original observation matrix from which the linkage is derived is large. Truncation is used to condense the dendrogram. There are several modes: None/’none’: no truncation is performed (Default) ‘lastp’: the last p non-singleton formed in the linkage are the only non-leaf nodes in the linkage; they correspond to to rows Z[n-p-2:end] in Z. All other non-singleton clusters are contracted into leaf nodes. ‘mlab’: This corresponds to MATLAB(TM) behavior. (not implemented yet) ‘level’/’mtica’: no more than p levels of the dendrogram tree are displayed. This corresponds to Mathematica(TM) behavior. color_threshold : double, optional For brevity, let t be the color_threshold. Colors all the descendent links below a cluster node k the same color if k is the first node below the cut threshold t. All links connecting nodes with distances greater than or equal to the threshold are colored blue. If t is less than or equal to zero, all nodes are colored blue. If color_threshold is None or ‘default’, corresponding with MATLAB(TM) behavior, the threshold is set to 0.7*max(Z[:,2]). get_leaves : bool, optional Includes a list R[’leaves’]=H in the result dictionary. For each i, H[i] == j, cluster node j appears in position i in the left-to-right traversal of the leaves, where j < 2n − 1 and i < n. orientation : str, optional The direction to plot the dendrogram, which can be any of the following strings: Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 ‘top’ plots the root at the top, and plot descendent links going downwards. (default). ‘bottom’- plots the root at the bottom, and plot descendent links going upwards. ‘left’- plots the root at the left, and plot descendent links going right. ‘right’- plots the root at the right, and plot descendent links going left. labels : ndarray, optional By default labels is None so the index of the original observation is used to label the leaf nodes. Otherwise, this is an n -sized list (or tuple). The labels[i] value is the text to put under the i th leaf node only if it corresponds to an original observation and not a non-singleton cluster. count_sort : str or bool, optional For each node n, the order (visually, from left-to-right) n’s two descendent links are plotted is determined by this parameter, which can be any of the following values: False: nothing is done. ‘ascending’/True: the child with the minimum number of original objects in its cluster is plotted first. ‘descendent’: the child with the maximum number of original objects in its cluster is plotted first. Note distance_sort and count_sort cannot both be True. distance_sort : str or bool, optional For each node n, the order (visually, from left-to-right) n’s two descendent links are plotted is determined by this parameter, which can be any of the following values: False: nothing is done. ‘ascending’/True: the child with the minimum distance between its direct descendents is plotted first. ‘descending’: the child with the maximum distance between its direct descendents is plotted first. Note distance_sort and count_sort cannot both be True. show_leaf_counts : bool, optional When True, leaf nodes representing k > 1 original observation are labeled with the number of observations they contain in parentheses. no_plot : bool, optional When True, the final rendering is not performed. This is useful if only the data structures computed for the rendering are needed or if matplotlib is not available. no_labels : bool, optional When True, no labels appear next to the leaf nodes in the rendering of the dendrogram. leaf_label_rotation : double, optional Specifies the angle (in degrees) to rotate the leaf labels. When unspecified, the rotation based on the number of nodes in the dendrogram. (Default=0) leaf_font_size : int, optional Specifies the font size (in points) of the leaf labels. When unspecified, the size based on the number of nodes in the dendrogram. leaf_label_func : lambda or function, optional When leaf_label_func is a callable function, for each leaf with cluster index k < 2n − 1. The function is expected to return a string with the label for the leaf. Indices k < n correspond to original observations while indices k ≥ n correspond to non-singleton clusters. For example, to label singletons with their node id and non-singletons with their id, count, and inconsistency coefficient, simply do: 5.3. Hierarchical clustering (scipy.cluster.hierarchy) 221 SciPy Reference Guide, Release 0.13.0 >>> # First define the leaf label function. >>> def llf(id): ... if id < n: ... return str(id) ... else: >>> return ’[%d %d %1.2f]’ % (id, count, R[n-id,3]) >>> >>> # The text for the leaf nodes is going to be big so force >>> # a rotation of 90 degrees. >>> dendrogram(Z, leaf_label_func=llf, leaf_rotation=90) show_contracted : bool When True the heights of non-singleton nodes contracted into a leaf node are plotted as crosses along the link connecting that leaf node. This really is only useful when truncation is used (see truncate_mode parameter). link_color_func : lambda/function When a callable function, link_color_function is called with each non-singleton id corresponding to each U-shaped link it will paint. The function is expected to return the color to paint the link, encoded as a matplotlib color string code. For example: >>> dendrogram(Z, link_color_func=lambda k: colors[k]) Returns colors the direct links below each untruncated non-singleton node k using colors[k]. R : dict A dictionary of data structures computed to render the dendrogram. Its has the following keys: ‘icoords’: a list of lists [I1, I2, ..., Ip] where Ik is a list of 4 independent variable coordinates corresponding to the line that represents the k’th link painted. ‘dcoords’: a list of lists [I2, I2, ..., Ip] where Ik is a list of 4 independent variable coordinates corresponding to the line that represents the k’th link painted. ‘ivl’: a list of labels corresponding to the leaf nodes. ‘leaves’: for each i, H[i] == j, cluster node j appears in position i in the left-to-right traversal of the leaves, where j < 2n − 1 and i < n. If j is less than n, the i th leaf node corresponds to an original observation. Otherwise, it corresponds to a non-singleton cluster. These are data structures and routines for representing hierarchies as tree objects. ClusterNode(id[, left, right, dist, count]) leaves_list(Z) to_tree(Z[, rd]) A tree node class for representing a cluster. Returns a list of leaf node ids Converts a hierarchical clustering encoded in the matrix Z (by class scipy.cluster.hierarchy.ClusterNode(id, left=None, right=None, dist=0, count=1) A tree node class for representing a cluster. Leaf nodes correspond to original observations, while non-leaf nodes correspond to non-singleton clusters. The to_tree function converts a matrix returned by the linkage function into an easy-to-use tree representation. See Also to_tree 222 for converting a linkage matrix Z into a tree object. Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Methods get_count() get_id() get_left() get_right() is_leaf() pre_order([func]) The number of leaf nodes (original observations) belonging to the cluster node nd. The identifier of the target node. Return a reference to the left child tree object. Returns a reference to the right child tree object. Returns True if the target node is a leaf. Performs pre-order traversal without recursive function calls. ClusterNode.get_count() The number of leaf nodes (original observations) belonging to the cluster node nd. If the target node is a leaf, 1 is returned. Returns get_count : int The number of leaf nodes below the target node. ClusterNode.get_id() The identifier of the target node. For 0 <= i < n, i corresponds to original observation i. For n <= i < 2n-1, i corresponds to non-singleton cluster formed at iteration i-n. Returns id : int The identifier of the target node. ClusterNode.get_left() Return a reference to the left child tree object. Returns left : ClusterNode The left child of the target node. If the node is a leaf, None is returned. ClusterNode.get_right() Returns a reference to the right child tree object. Returns right : ClusterNode The left child of the target node. If the node is a leaf, None is returned. ClusterNode.is_leaf() Returns True if the target node is a leaf. Returns leafness : bool True if the target node is a leaf node. ClusterNode.pre_order(func= at 0x5336cf8>) Performs pre-order traversal without recursive function calls. When a leaf node is first encountered, func is called with the leaf node as its argument, and its result is appended to the list. For example, the statement: ids = root.pre_order(lambda x: x.id) returns a list of the node ids corresponding to the leaf nodes of the tree as they appear from left to right. Parameters func : function Applied to each leaf ClusterNode object in the pre-order traversal. Given the i’th leaf node in the pre-ordeR traversal n[i], the result of func(n[i]) is stored in L[i]. If not provided, the index of the original observation to which the node corresponds is used. 5.3. Hierarchical clustering (scipy.cluster.hierarchy) 223 SciPy Reference Guide, Release 0.13.0 Returns L : list The pre-order traversal. scipy.cluster.hierarchy.leaves_list(Z) Returns a list of leaf node ids The return corresponds to the observation vector index as it appears in the tree from left to right. Z is a linkage matrix. Parameters Returns Z : ndarray The hierarchical clustering encoded as a matrix. Z is a linkage matrix. See linkage for more information. leaves_list : ndarray The list of leaf node ids. scipy.cluster.hierarchy.to_tree(Z, rd=False) Converts a hierarchical clustering encoded in the matrix Z (by linkage) into an easy-to-use tree object. The reference r to the root ClusterNode object is returned. Each ClusterNode object has a left, right, dist, id, and count attribute. The left and right attributes point to ClusterNode objects that were combined to generate the cluster. If both are None then the ClusterNode object is a leaf node, its count must be 1, and its distance is meaningless but set to 0. Note: This function is provided for the convenience of the library user. ClusterNodes are not used as input to any of the functions in this library. Parameters Returns Z : ndarray The linkage matrix in proper form (see the linkage function documentation). rd : bool, optional When False, a reference to the root ClusterNode object is returned. Otherwise, a tuple (r,d) is returned. r is a reference to the root node while d is a dictionary mapping cluster ids to ClusterNode references. If a cluster id is less than n, then it corresponds to a singleton cluster (leaf node). See linkage for more information on the assignment of cluster ids to clusters. L : list The pre-order traversal. These are predicates for checking the validity of linkage and inconsistency matrices as well as for checking isomorphism of two flat cluster assignments. is_valid_im(R[, warning, throw, name]) is_valid_linkage(Z[, warning, throw, name]) is_isomorphic(T1, T2) is_monotonic(Z) correspond(Z, Y) num_obs_linkage(Z) Returns True if the inconsistency matrix passed is valid. Checks the validity of a linkage matrix. Determines if two different cluster assignments are equivalent. Returns True if the linkage passed is monotonic. Checks for correspondence between linkage and condensed distance matrices Returns the number of original observations of the linkage matrix passed. scipy.cluster.hierarchy.is_valid_im(R, warning=False, throw=False, name=None) Returns True if the inconsistency matrix passed is valid. It must be a n by 4 numpy array of doubles. The standard deviations R[:,1] must be nonnegative. The link counts R[:,2] must be positive and no greater than n − 1. Parameters 224 R : ndarray The inconsistency matrix to check for validity. warning : bool, optional When True, issues a Python warning if the linkage matrix passed is invalid. Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Returns throw : bool, optional When True, throws a Python exception if the linkage matrix passed is invalid. name : str, optional This string refers to the variable name of the invalid linkage matrix. b : bool True if the inconsistency matrix is valid. scipy.cluster.hierarchy.is_valid_linkage(Z, warning=False, throw=False, name=None) Checks the validity of a linkage matrix. A linkage matrix is valid if it is a two dimensional ndarray (type double) with n rows and 4 columns. The first two columns must contain indices between 0 and 2n − 1. For a given row i, 0 ≤ Z[i, 0] ≤ i + n − 1 and 0 ≤ Z[i, 1] ≤ i + n − 1 (i.e. a cluster cannot join another cluster unless the cluster being joined has been generated.) Parameters Returns Z : array_like Linkage matrix. warning : bool, optional When True, issues a Python warning if the linkage matrix passed is invalid. throw : bool, optional When True, throws a Python exception if the linkage matrix passed is invalid. name : str, optional This string refers to the variable name of the invalid linkage matrix. b : bool True iff the inconsistency matrix is valid. scipy.cluster.hierarchy.is_isomorphic(T1, T2) Determines if two different cluster assignments are equivalent. Parameters Returns T1 : array_like An assignment of singleton cluster ids to flat cluster ids. T2 : array_like An assignment of singleton cluster ids to flat cluster ids. b : bool Whether the flat cluster assignments T1 and T2 are equivalent. scipy.cluster.hierarchy.is_monotonic(Z) Returns True if the linkage passed is monotonic. The linkage is monotonic if for every cluster s and t joined, the distance between them is no less than the distance between any previously joined clusters. Parameters Returns Z : ndarray The linkage matrix to check for monotonicity. b : bool A boolean indicating whether the linkage is monotonic. scipy.cluster.hierarchy.correspond(Z, Y) Checks for correspondence between linkage and condensed distance matrices They must have the same number of original observations for the check to succeed. This function is useful as a sanity check in algorithms that make extensive use of linkage and distance matrices that must correspond to the same set of original observations. Parameters Returns Z : array_like The linkage matrix to check for correspondence. Y : array_like The condensed distance matrix to check for correspondence. b : bool 5.3. Hierarchical clustering (scipy.cluster.hierarchy) 225 SciPy Reference Guide, Release 0.13.0 A boolean indicating whether the linkage matrix and distance matrix could possibly correspond to one another. scipy.cluster.hierarchy.num_obs_linkage(Z) Returns the number of original observations of the linkage matrix passed. Parameters Returns Z : ndarray The linkage matrix on which to perform the operation. n : int The number of original observations in the linkage. Utility routines for plotting: set_link_color_palette(palette) Set list of matplotlib color codes for dendrogram color_threshold. scipy.cluster.hierarchy.set_link_color_palette(palette) Set list of matplotlib color codes for dendrogram color_threshold. Parameters palette : list A list of matplotlib color codes. The order of the color codes is the order in which the colors are cycled through when color thresholding in the dendrogram. 5.3.1 References • MATLAB and MathWorks are registered trademarks of The MathWorks, Inc. • Mathematica is a registered trademark of The Wolfram Research, Inc. 5.4 Constants (scipy.constants) Physical and mathematical constants and units. 5.4.1 Mathematical constants pi golden 226 Pi Golden ratio Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 5.4.2 Physical constants c mu_0 epsilon_0 h hbar G g e R alpha N_A k sigma Wien Rydberg m_e m_p m_n speed of light in vacuum the magnetic constant µ0 the electric constant (vacuum permittivity), 0 the Planck constant h h̄ = h/(2π) Newtonian constant of gravitation standard acceleration of gravity elementary charge molar gas constant fine-structure constant Avogadro constant Boltzmann constant Stefan-Boltzmann constant σ Wien displacement law constant Rydberg constant electron mass proton mass neutron mass Constants database In addition to the above variables, scipy.constants also contains the 2010 CODATA recommended values [CODATA2010] database containing more physical constants. value(key) unit(key) precision(key) find([sub, disp]) ConstantWarning Value in physical_constants indexed by key Unit in physical_constants indexed by key Relative precision in physical_constants indexed by key Return list of codata.physical_constant keys containing a given string. Accessing a constant no longer in current CODATA data set scipy.constants.value(key) Value in physical_constants indexed by key Parameters Returns key : Python string or unicode Key in dictionary physical_constants value : float Value in physical_constants corresponding to key See Also codata Contains the description of physical_constants, which, as a dictionary literal object, does not itself possess a docstring. Examples >>> from scipy.constants import codata >>> codata.value(’elementary charge’) 1.602176487e-019 scipy.constants.unit(key) Unit in physical_constants indexed by key 5.4. Constants (scipy.constants) 227 SciPy Reference Guide, Release 0.13.0 Parameters Returns key : Python string or unicode Key in dictionary physical_constants unit : Python string Unit in physical_constants corresponding to key See Also codata Contains the description of physical_constants, which, as a dictionary literal object, does not itself possess a docstring. Examples >>> from scipy.constants import codata >>> codata.unit(u’proton mass’) ’kg’ scipy.constants.precision(key) Relative precision in physical_constants indexed by key Parameters Returns key : Python string or unicode Key in dictionary physical_constants prec : float Relative precision in physical_constants corresponding to key See Also codata Contains the description of physical_constants, which, as a dictionary literal object, does not itself possess a docstring. Examples >>> from scipy.constants import codata >>> codata.precision(u’proton mass’) 4.96226989798e-08 scipy.constants.find(sub=None, disp=False) Return list of codata.physical_constant keys containing a given string. Parameters Returns sub : str, unicode Sub-string to search keys for. By default, return all keys. disp : bool If True, print the keys that are found, and return None. Otherwise, return the list of keys without printing anything. keys : list or None If disp is False, the list of keys is returned. Otherwise, None is returned. See Also codata Contains the description of physical_constants, which, as a dictionary literal object, does not itself possess a docstring. exception scipy.constants.ConstantWarning Accessing a constant no longer in current CODATA data set scipy.constants.physical_constants Dictionary of physical constants, of the format physical_constants[name] = (value, unit, uncertainty). Available constants: 228 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 alpha particle mass alpha particle mass energy equivalent alpha particle mass energy equivalent in MeV alpha particle mass in u alpha particle molar mass alpha particle-electron mass ratio alpha particle-proton mass ratio Angstrom star atomic mass constant atomic mass constant energy equivalent atomic mass constant energy equivalent in MeV atomic mass unit-electron volt relationship atomic mass unit-hartree relationship atomic mass unit-hertz relationship atomic mass unit-inverse meter relationship atomic mass unit-joule relationship atomic mass unit-kelvin relationship atomic mass unit-kilogram relationship atomic unit of 1st hyperpolarizability atomic unit of 2nd hyperpolarizability atomic unit of action atomic unit of charge atomic unit of charge density atomic unit of current atomic unit of electric dipole mom. atomic unit of electric field atomic unit of electric field gradient atomic unit of electric polarizability atomic unit of electric potential atomic unit of electric quadrupole mom. atomic unit of energy atomic unit of force atomic unit of length atomic unit of mag. dipole mom. atomic unit of mag. flux density atomic unit of magnetizability atomic unit of mass atomic unit of mom.um atomic unit of permittivity atomic unit of time atomic unit of velocity Avogadro constant Bohr magneton Bohr magneton in eV/T Bohr magneton in Hz/T Bohr magneton in inverse meters per tesla Bohr magneton in K/T Bohr radius Boltzmann constant Boltzmann constant in eV/K 5.4. Constants (scipy.constants) 6.64465675e-27 kg 5.97191967e-10 J 3727.37924 MeV 4.00150617913 u 0.00400150617912 kg mol^-1 7294.2995361 3.97259968933 1.00001495e-10 m 1.660538921e-27 kg 1.492417954e-10 J 931.494061 MeV 931494061.0 eV 34231776.845 E_h 2.2523427168e+23 Hz 7.5130066042e+14 m^-1 1.492417954e-10 J 1.08095408e+13 K 1.660538921e-27 kg 3.206361449e-53 C^3 m^3 J^-2 6.23538054e-65 C^4 m^4 J^-3 1.054571726e-34 J s 1.602176565e-19 C 1.081202338e+12 C m^-3 0.00662361795 A 8.47835326e-30 C m 5.14220652e+11 V m^-1 9.717362e+21 V m^-2 1.6487772754e-41 C^2 m^2 J^-1 27.21138505 V 4.486551331e-40 C m^2 4.35974434e-18 J 8.23872278e-08 N 5.2917721092e-11 m 1.854801936e-23 J T^-1 235051.7464 T 7.891036607e-29 J T^-2 9.10938291e-31 kg 1.99285174e-24 kg m s^-1 1.11265005605e-10 F m^-1 2.4188843265e-17 s 2187691.26379 m s^-1 6.02214129e+23 mol^-1 9.27400968e-24 J T^-1 5.7883818066e-05 eV T^-1 13996245550.0 Hz T^-1 46.6864498 m^-1 T^-1 0.67171388 K T^-1 5.2917721092e-11 m 1.3806488e-23 J K^-1 8.6173324e-05 eV K^-1 Continued on next page 229 SciPy Reference Guide, Release 0.13.0 Table 5.11 – continued from previous page Boltzmann constant in Hz/K Boltzmann constant in inverse meters per kelvin characteristic impedance of vacuum classical electron radius Compton wavelength Compton wavelength over 2 pi conductance quantum conventional value of Josephson constant conventional value of von Klitzing constant Cu x unit deuteron g factor deuteron mag. mom. deuteron mag. mom. to Bohr magneton ratio deuteron mag. mom. to nuclear magneton ratio deuteron mass deuteron mass energy equivalent deuteron mass energy equivalent in MeV deuteron mass in u deuteron molar mass deuteron rms charge radius deuteron-electron mag. mom. ratio deuteron-electron mass ratio deuteron-neutron mag. mom. ratio deuteron-proton mag. mom. ratio deuteron-proton mass ratio electric constant electron charge to mass quotient electron g factor electron gyromag. ratio electron gyromag. ratio over 2 pi electron mag. mom. electron mag. mom. anomaly electron mag. mom. to Bohr magneton ratio electron mag. mom. to nuclear magneton ratio electron mass electron mass energy equivalent electron mass energy equivalent in MeV electron mass in u electron molar mass electron to alpha particle mass ratio electron to shielded helion mag. mom. ratio electron to shielded proton mag. mom. ratio electron volt electron volt-atomic mass unit relationship electron volt-hartree relationship electron volt-hertz relationship electron volt-inverse meter relationship electron volt-joule relationship electron volt-kelvin relationship electron volt-kilogram relationship 230 20836618000.0 Hz K^-1 69.503476 m^-1 K^-1 376.730313462 ohm 2.8179403267e-15 m 2.4263102389e-12 m 3.86159268e-13 m 7.7480917346e-05 S 4.835979e+14 Hz V^-1 25812.807 ohm 1.00207697e-13 m 0.8574382308 4.33073489e-27 J T^-1 0.0004669754556 0.8574382308 3.34358348e-27 kg 3.00506297e-10 J 1875.612859 MeV 2.01355321271 u 0.00201355321271 kg mol^-1 2.1424e-15 m -0.0004664345537 3670.4829652 -0.44820652 0.307012207 1.99900750097 8.85418781762e-12 F m^-1 -1.758820088e+11 C kg^-1 -2.00231930436 1.760859708e+11 s^-1 T^-1 28024.95266 MHz T^-1 -9.2847643e-24 J T^-1 0.00115965218076 -1.00115965218 -1838.2819709 9.10938291e-31 kg 8.18710506e-14 J 0.510998928 MeV 0.00054857990946 u 5.4857990946e-07 kg mol^-1 0.000137093355578 864.058257 -658.2275971 1.602176565e-19 J 1.07354415e-09 u 0.03674932379 E_h 2.417989348e+14 Hz 806554.429 m^-1 1.602176565e-19 J 11604.519 K 1.782661845e-36 kg Continued on next page Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Table 5.11 – continued from previous page electron-deuteron mag. mom. ratio electron-deuteron mass ratio electron-helion mass ratio electron-muon mag. mom. ratio electron-muon mass ratio electron-neutron mag. mom. ratio electron-neutron mass ratio electron-proton mag. mom. ratio electron-proton mass ratio electron-tau mass ratio electron-triton mass ratio elementary charge elementary charge over h Faraday constant Faraday constant for conventional electric current Fermi coupling constant fine-structure constant first radiation constant first radiation constant for spectral radiance Hartree energy Hartree energy in eV hartree-atomic mass unit relationship hartree-electron volt relationship hartree-hertz relationship hartree-inverse meter relationship hartree-joule relationship hartree-kelvin relationship hartree-kilogram relationship helion g factor helion mag. mom. helion mag. mom. to Bohr magneton ratio helion mag. mom. to nuclear magneton ratio helion mass helion mass energy equivalent helion mass energy equivalent in MeV helion mass in u helion molar mass helion-electron mass ratio helion-proton mass ratio hertz-atomic mass unit relationship hertz-electron volt relationship hertz-hartree relationship hertz-inverse meter relationship hertz-joule relationship hertz-kelvin relationship hertz-kilogram relationship inverse fine-structure constant inverse meter-atomic mass unit relationship inverse meter-electron volt relationship inverse meter-hartree relationship 5.4. Constants (scipy.constants) -2143.923498 0.00027244371095 0.00018195430761 206.7669896 0.00483633166 960.9205 0.00054386734461 -658.2106848 0.00054461702178 0.000287592 0.00018192000653 1.602176565e-19 C 2.417989348e+14 A J^-1 96485.3365 C mol^-1 96485.3321 C_90 mol^-1 1.166364e-05 GeV^-2 0.0072973525698 3.74177153e-16 W m^2 1.191042869e-16 W m^2 sr^-1 4.35974434e-18 J 27.21138505 eV 2.9212623246e-08 u 27.21138505 eV 6.57968392073e+15 Hz 21947463.1371 m^-1 4.35974434e-18 J 315775.04 K 4.85086979e-35 kg -4.255250613 -1.074617486e-26 J T^-1 -0.001158740958 -2.127625306 5.00641234e-27 kg 4.49953902e-10 J 2808.391482 MeV 3.0149322468 u 0.0030149322468 kg mol^-1 5495.8852754 2.9931526707 4.4398216689e-24 u 4.135667516e-15 eV 1.519829846e-16 E_h 3.33564095198e-09 m^-1 6.62606957e-34 J 4.7992434e-11 K 7.37249668e-51 kg 137.035999074 1.3310250512e-15 u 1.23984193e-06 eV 4.55633525276e-08 E_h Continued on next page 231 SciPy Reference Guide, Release 0.13.0 Table 5.11 – continued from previous page inverse meter-hertz relationship inverse meter-joule relationship inverse meter-kelvin relationship inverse meter-kilogram relationship inverse of conductance quantum Josephson constant joule-atomic mass unit relationship joule-electron volt relationship joule-hartree relationship joule-hertz relationship joule-inverse meter relationship joule-kelvin relationship joule-kilogram relationship kelvin-atomic mass unit relationship kelvin-electron volt relationship kelvin-hartree relationship kelvin-hertz relationship kelvin-inverse meter relationship kelvin-joule relationship kelvin-kilogram relationship kilogram-atomic mass unit relationship kilogram-electron volt relationship kilogram-hartree relationship kilogram-hertz relationship kilogram-inverse meter relationship kilogram-joule relationship kilogram-kelvin relationship lattice parameter of silicon Loschmidt constant (273.15 K, 100 kPa) Loschmidt constant (273.15 K, 101.325 kPa) mag. constant mag. flux quantum Mo x unit molar gas constant molar mass constant molar mass of carbon-12 molar Planck constant molar Planck constant times c molar volume of ideal gas (273.15 K, 100 kPa) molar volume of ideal gas (273.15 K, 101.325 kPa) molar volume of silicon muon Compton wavelength muon Compton wavelength over 2 pi muon g factor muon mag. mom. muon mag. mom. anomaly muon mag. mom. to Bohr magneton ratio muon mag. mom. to nuclear magneton ratio muon mass muon mass energy equivalent 232 299792458.0 Hz 1.986445684e-25 J 0.01438777 K 2.210218902e-42 kg 12906.4037217 ohm 4.8359787e+14 Hz V^-1 6700535850.0 u 6.24150934e+18 eV 2.29371248e+17 E_h 1.509190311e+33 Hz 5.03411701e+24 m^-1 7.2429716e+22 K 1.11265005605e-17 kg 9.2510868e-14 u 8.6173324e-05 eV 3.1668114e-06 E_h 20836618000.0 Hz 69.503476 m^-1 1.3806488e-23 J 1.536179e-40 kg 6.02214129e+26 u 5.60958885e+35 eV 2.061485968e+34 E_h 1.356392608e+50 Hz 4.52443873e+41 m^-1 8.98755178737e+16 J 6.5096582e+39 K 5.431020504e-10 m 2.6516462e+25 m^-3 2.6867805e+25 m^-3 1.25663706144e-06 N A^-2 2.067833758e-15 Wb 1.00209952e-13 m 8.3144621 J mol^-1 K^-1 0.001 kg mol^-1 0.012 kg mol^-1 3.9903127176e-10 J s mol^-1 0.119626565779 J m mol^-1 0.022710953 m^3 mol^-1 0.022413968 m^3 mol^-1 1.205883301e-05 m^3 mol^-1 1.173444103e-14 m 1.867594294e-15 m -2.0023318418 -4.49044807e-26 J T^-1 0.00116592091 -0.00484197044 -8.89059697 1.883531475e-28 kg 1.692833667e-11 J Continued on next page Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Table 5.11 – continued from previous page muon mass energy equivalent in MeV muon mass in u muon molar mass muon-electron mass ratio muon-neutron mass ratio muon-proton mag. mom. ratio muon-proton mass ratio muon-tau mass ratio natural unit of action natural unit of action in eV s natural unit of energy natural unit of energy in MeV natural unit of length natural unit of mass natural unit of mom.um natural unit of mom.um in MeV/c natural unit of time natural unit of velocity neutron Compton wavelength neutron Compton wavelength over 2 pi neutron g factor neutron gyromag. ratio neutron gyromag. ratio over 2 pi neutron mag. mom. neutron mag. mom. to Bohr magneton ratio neutron mag. mom. to nuclear magneton ratio neutron mass neutron mass energy equivalent neutron mass energy equivalent in MeV neutron mass in u neutron molar mass neutron to shielded proton mag. mom. ratio neutron-electron mag. mom. ratio neutron-electron mass ratio neutron-muon mass ratio neutron-proton mag. mom. ratio neutron-proton mass difference neutron-proton mass difference energy equivalent neutron-proton mass difference energy equivalent in MeV neutron-proton mass difference in u neutron-proton mass ratio neutron-tau mass ratio Newtonian constant of gravitation Newtonian constant of gravitation over h-bar c nuclear magneton nuclear magneton in eV/T nuclear magneton in inverse meters per tesla nuclear magneton in K/T nuclear magneton in MHz/T Planck constant 5.4. Constants (scipy.constants) 105.6583715 MeV 0.1134289267 u 0.0001134289267 kg mol^-1 206.7682843 0.1124545177 -3.183345107 0.1126095272 0.0594649 1.054571726e-34 J s 6.58211928e-16 eV s 8.18710506e-14 J 0.510998928 MeV 3.86159268e-13 m 9.10938291e-31 kg 2.73092429e-22 kg m s^-1 0.510998928 MeV/c 1.28808866833e-21 s 299792458.0 m s^-1 1.3195909068e-15 m 2.1001941568e-16 m -3.82608545 183247179.0 s^-1 T^-1 29.1646943 MHz T^-1 -9.6623647e-27 J T^-1 -0.00104187563 -1.91304272 1.674927351e-27 kg 1.505349631e-10 J 939.565379 MeV 1.008664916 u 0.001008664916 kg mol^-1 -0.68499694 0.00104066882 1838.6836605 8.892484 -0.68497934 2.30557392e-30 2.0721465e-13 1.29333217 0.00138844919 1.00137841917 0.52879 6.67384e-11 m^3 kg^-1 s^-2 6.70837e-39 (GeV/c^2)^-2 5.05078353e-27 J T^-1 3.1524512605e-08 eV T^-1 0.02542623527 m^-1 T^-1 0.00036582682 K T^-1 7.62259357 MHz T^-1 6.62606957e-34 J s Continued on next page 233 SciPy Reference Guide, Release 0.13.0 Table 5.11 – continued from previous page Planck constant in eV s Planck constant over 2 pi Planck constant over 2 pi in eV s Planck constant over 2 pi times c in MeV fm Planck length Planck mass Planck mass energy equivalent in GeV Planck temperature Planck time proton charge to mass quotient proton Compton wavelength proton Compton wavelength over 2 pi proton g factor proton gyromag. ratio proton gyromag. ratio over 2 pi proton mag. mom. proton mag. mom. to Bohr magneton ratio proton mag. mom. to nuclear magneton ratio proton mag. shielding correction proton mass proton mass energy equivalent proton mass energy equivalent in MeV proton mass in u proton molar mass proton rms charge radius proton-electron mass ratio proton-muon mass ratio proton-neutron mag. mom. ratio proton-neutron mass ratio proton-tau mass ratio quantum of circulation quantum of circulation times 2 Rydberg constant Rydberg constant times c in Hz Rydberg constant times hc in eV Rydberg constant times hc in J Sackur-Tetrode constant (1 K, 100 kPa) Sackur-Tetrode constant (1 K, 101.325 kPa) second radiation constant shielded helion gyromag. ratio shielded helion gyromag. ratio over 2 pi shielded helion mag. mom. shielded helion mag. mom. to Bohr magneton ratio shielded helion mag. mom. to nuclear magneton ratio shielded helion to proton mag. mom. ratio shielded helion to shielded proton mag. mom. ratio shielded proton gyromag. ratio shielded proton gyromag. ratio over 2 pi shielded proton mag. mom. shielded proton mag. mom. to Bohr magneton ratio 234 4.135667516e-15 eV s 1.054571726e-34 J s 6.58211928e-16 eV s 197.3269718 MeV fm 1.616199e-35 m 2.17651e-08 kg 1.220932e+19 GeV 1.416833e+32 K 5.39106e-44 s 95788335.8 C kg^-1 1.32140985623e-15 m 2.1030891047e-16 m 5.585694713 267522200.5 s^-1 T^-1 42.5774806 MHz T^-1 1.410606743e-26 J T^-1 0.00152103221 2.792847356 2.5694e-05 1.672621777e-27 kg 1.503277484e-10 J 938.272046 MeV 1.00727646681 u 0.00100727646681 kg mol^-1 8.775e-16 m 1836.15267245 8.88024331 -1.45989806 0.99862347826 0.528063 0.0003636947552 m^2 s^-1 0.0007273895104 m^2 s^-1 10973731.5685 m^-1 3.28984196036e+15 Hz 13.60569253 eV 2.179872171e-18 J -1.1517078 -1.1648708 0.01438777 m K 203789465.9 s^-1 T^-1 32.43410084 MHz T^-1 -1.074553044e-26 J T^-1 -0.001158671471 -2.127497718 -0.761766558 -0.7617861313 267515326.8 s^-1 T^-1 42.5763866 MHz T^-1 1.410570499e-26 J T^-1 0.001520993128 Continued on next page Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Table 5.11 – continued from previous page shielded proton mag. mom. to nuclear magneton ratio speed of light in vacuum standard acceleration of gravity standard atmosphere standard-state pressure Stefan-Boltzmann constant tau Compton wavelength tau Compton wavelength over 2 pi tau mass tau mass energy equivalent tau mass energy equivalent in MeV tau mass in u tau molar mass tau-electron mass ratio tau-muon mass ratio tau-neutron mass ratio tau-proton mass ratio Thomson cross section triton g factor triton mag. mom. triton mag. mom. to Bohr magneton ratio triton mag. mom. to nuclear magneton ratio triton mass triton mass energy equivalent triton mass energy equivalent in MeV triton mass in u triton molar mass triton-electron mass ratio triton-proton mass ratio unified atomic mass unit von Klitzing constant weak mixing angle Wien frequency displacement law constant Wien wavelength displacement law constant {220} lattice spacing of silicon 5.4. Constants (scipy.constants) 2.792775598 299792458.0 m s^-1 9.80665 m s^-2 101325.0 Pa 100000.0 Pa 5.670373e-08 W m^-2 K^-4 6.97787e-16 m 1.11056e-16 m 3.16747e-27 kg 2.84678e-10 J 1776.82 MeV 1.90749 u 0.00190749 kg mol^-1 3477.15 16.8167 1.89111 1.89372 6.652458734e-29 m^2 5.957924896 1.504609447e-26 J T^-1 0.001622393657 2.978962448 5.0073563e-27 kg 4.50038741e-10 J 2808.921005 MeV 3.0155007134 u 0.0030155007134 kg mol^-1 5496.9215267 2.9937170308 1.660538921e-27 kg 25812.8074434 ohm 0.2223 58789254000.0 Hz K^-1 0.0028977721 m K 1.920155714e-10 m 235 SciPy Reference Guide, Release 0.13.0 5.4.3 Units SI prefixes yotta zetta exa peta tera giga mega kilo hecto deka deci centi milli micro nano pico femto atto zepto 1024 1021 1018 1015 1012 109 106 103 102 101 10−1 10−2 10−3 10−6 10−9 10−12 10−15 10−18 10−21 Binary prefixes kibi mebi gibi tebi pebi exbi zebi yobi 210 220 230 240 250 260 270 280 Weight gram metric_ton grain lb oz stone grain long_ton short_ton troy_ounce troy_pound carat m_u 236 10−3 kg 103 kg one grain in kg one pound (avoirdupous) in kg one ounce in kg one stone in kg one grain in kg one long ton in kg one short ton in kg one Troy ounce in kg one Troy pound in kg one carat in kg atomic mass constant (in kg) Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Angle degree in radians arc minute in radians arc second in radians degree arcmin arcsec Time minute hour day week year Julian_year one minute in seconds one hour in seconds one day in seconds one week in seconds one year (365 days) in seconds one Julian year (365.25 days) in seconds Length inch foot yard mile mil pt survey_foot survey_mile nautical_mile fermi angstrom micron au light_year parsec one inch in meters one foot in meters one yard in meters one mile in meters one mil in meters one point in meters one survey foot in meters one survey mile in meters one nautical mile in meters one Fermi in meters one Angstrom in meters one micron in meters one astronomical unit in meters one light year in meters one parsec in meters Pressure atm bar torr psi standard atmosphere in pascals one bar in pascals one torr (mmHg) in pascals one psi in pascals Area hectare acre one hectare in square meters one acre in square meters 5.4. Constants (scipy.constants) 237 SciPy Reference Guide, Release 0.13.0 Volume liter gallon gallon_imp fluid_ounce fluid_ounce_imp bbl one liter in cubic meters one gallon (US) in cubic meters one gallon (UK) in cubic meters one fluid ounce (US) in cubic meters one fluid ounce (UK) in cubic meters one barrel in cubic meters Speed kmh mph mach knot kilometers per hour in meters per second miles per hour in meters per second one Mach (approx., at 15 C, 1 atm) in meters per second one knot in meters per second Temperature zero_Celsius degree_Fahrenheit zero of Celsius scale in Kelvin one Fahrenheit (only differences) in Kelvins C2K(C) K2C(K) F2C(F) C2F(C) F2K(F) K2F(K) Convert Celsius to Kelvin Convert Kelvin to Celsius Convert Fahrenheit to Celsius Convert Celsius to Fahrenheit Convert Fahrenheit to Kelvin Convert Kelvin to Fahrenheit scipy.constants.C2K(C) Convert Celsius to Kelvin Parameters Returns C : array_like Celsius temperature(s) to be converted. K : float or array of floats Equivalent Kelvin temperature(s). Notes Computes K = C + zero_Celsius where zero_Celsius = 273.15, i.e., (the absolute value of) temperature “absolute zero” as measured in Celsius. Examples >>> from scipy.constants.constants import C2K >>> C2K(_np.array([-40, 40.0])) array([ 233.15, 313.15]) scipy.constants.K2C(K) Convert Kelvin to Celsius Parameters Returns 238 K : array_like Kelvin temperature(s) to be converted. C : float or array of floats Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Equivalent Celsius temperature(s). Notes Computes C = K - zero_Celsius where zero_Celsius = 273.15, i.e., (the absolute value of) temperature “absolute zero” as measured in Celsius. Examples >>> from scipy.constants.constants import K2C >>> K2C(_np.array([233.15, 313.15])) array([-40., 40.]) scipy.constants.F2C(F) Convert Fahrenheit to Celsius Parameters Returns F : array_like Fahrenheit temperature(s) to be converted. C : float or array of floats Equivalent Celsius temperature(s). Notes Computes C = (F - 32) / 1.8. Examples >>> from scipy.constants.constants import F2C >>> F2C(_np.array([-40, 40.0])) array([-40. , 4.44444444]) scipy.constants.C2F(C) Convert Celsius to Fahrenheit Parameters Returns C : array_like Celsius temperature(s) to be converted. F : float or array of floats Equivalent Fahrenheit temperature(s). Notes Computes F = 1.8 * C + 32. Examples >>> from scipy.constants.constants import C2F >>> C2F(_np.array([-40, 40.0])) array([ -40., 104.]) scipy.constants.F2K(F) Convert Fahrenheit to Kelvin Parameters Returns F : array_like Fahrenheit temperature(s) to be converted. K : float or array of floats Equivalent Kelvin temperature(s). Notes Computes K = (F - 32)/1.8 + zero_Celsius where zero_Celsius = 273.15, i.e., (the absolute value of) temperature “absolute zero” as measured in Celsius. 5.4. Constants (scipy.constants) 239 SciPy Reference Guide, Release 0.13.0 Examples >>> from scipy.constants.constants import F2K >>> F2K(_np.array([-40, 104])) array([ 233.15, 313.15]) scipy.constants.K2F(K) Convert Kelvin to Fahrenheit Parameters Returns K : array_like Kelvin temperature(s) to be converted. F : float or array of floats Equivalent Fahrenheit temperature(s). Notes Computes F = 1.8 * (K - zero_Celsius) + 32 where zero_Celsius = 273.15, i.e., (the absolute value of) temperature “absolute zero” as measured in Celsius. Examples >>> from scipy.constants.constants import K2F >>> K2F(_np.array([233.15, 313.15])) array([ -40., 104.]) Energy eV calorie calorie_IT erg Btu Btu_th ton_TNT one electron volt in Joules one calorie (thermochemical) in Joules one calorie (International Steam Table calorie, 1956) in Joules one erg in Joules one British thermal unit (International Steam Table) in Joules one British thermal unit (thermochemical) in Joules one ton of TNT in Joules Power hp one horsepower in watts Force dyn lbf kgf one dyne in newtons one pound force in newtons one kilogram force in newtons Optics lambda2nu(lambda_) nu2lambda(nu) 240 Convert wavelength to optical frequency Convert optical frequency to wavelength. Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 scipy.constants.lambda2nu(lambda_) Convert wavelength to optical frequency Parameters Returns lambda : array_like Wavelength(s) to be converted. nu : float or array of floats Equivalent optical frequency. Notes Computes nu = c / lambda where c = 299792458.0, i.e., the (vacuum) speed of light in meters/second. Examples >>> from scipy.constants.constants import lambda2nu >>> lambda2nu(_np.array((1, speed_of_light))) array([ 2.99792458e+08, 1.00000000e+00]) scipy.constants.nu2lambda(nu) Convert optical frequency to wavelength. Parameters Returns nu : array_like Optical frequency to be converted. lambda : float or array of floats Equivalent wavelength(s). Notes Computes lambda = c / nu where c = 299792458.0, i.e., the (vacuum) speed of light in meters/second. Examples >>> from scipy.constants.constants import nu2lambda >>> nu2lambda(_np.array((1, speed_of_light))) array([ 2.99792458e+08, 1.00000000e+00]) 5.4.4 References 5.5 Discrete Fourier transforms (scipy.fftpack) 5.5.1 Fast Fourier Transforms (FFTs) fft(x[, n, axis, overwrite_x]) ifft(x[, n, axis, overwrite_x]) fft2(x[, shape, axes, overwrite_x]) ifft2(x[, shape, axes, overwrite_x]) fftn(x[, shape, axes, overwrite_x]) ifftn(x[, shape, axes, overwrite_x]) rfft(x[, n, axis, overwrite_x]) irfft(x[, n, axis, overwrite_x]) dct(x[, type, n, axis, norm, overwrite_x]) idct(x[, type, n, axis, norm, overwrite_x]) Return discrete Fourier transform of real or complex sequence. Return discrete inverse Fourier transform of real or complex sequence. 2-D discrete Fourier transform. 2-D discrete inverse Fourier transform of real or complex sequence. Return multidimensional discrete Fourier transform. Return inverse multi-dimensional discrete Fourier transform of Discrete Fourier transform of a real sequence. Return inverse discrete Fourier transform of real sequence x. Return the Discrete Cosine Transform of arbitrary type sequence x. Return the Inverse Discrete Cosine Transform of an arbitrary type sequence. 5.5. Discrete Fourier transforms (scipy.fftpack) 241 SciPy Reference Guide, Release 0.13.0 scipy.fftpack.fft(x, n=None, axis=-1, overwrite_x=0) Return discrete Fourier transform of real or complex sequence. The returned complex array contains y(0), y(1),..., y(n-1) where y(j) = (x * exp(-2*pi*sqrt(-1)*j*np.arange(n)/n)).sum(). Parameters Returns x : array_like Array to Fourier transform. n : int, optional Length of the Fourier transform. If n < x.shape[axis], x is truncated. If n > x.shape[axis], x is zero-padded. The default results in n = x.shape[axis]. axis : int, optional Axis along which the fft’s are computed; the default is over the last axis (i.e., axis=-1). overwrite_x : bool, optional If True the contents of x can be destroyed; the default is False. z : complex ndarray with the elements: [y(0),y(1),..,y(n/2),y(1-n/2),...,y(-1)] if n is even [y(0),y(1),..,y((n-1)/2),y(-(n-1)/2),...,y(-1)] if n is odd where: y(j) = sum[k=0..n-1] x[k] * exp(-sqrt(-1)*j*k* 2*pi/n), j = 0..n-1 Note that y(-j) = y(n-j).conjugate(). See Also ifft Inverse FFT rfft FFT of a real sequence Notes The packing of the result is “standard”: If A = fft(a, n), then A[0] contains the zero-frequency term, A[1:n/2] contains the positive-frequency terms, and A[n/2:] contains the negative-frequency terms, in order of decreasingly negative frequency. So for an 8-point transform, the frequencies of the result are [0, 1, 2, 3, -4, -3, -2, -1]. To rearrange the fft output so that the zero-frequency component is centered, like [-4, -3, -2, -1, 0, 1, 2, 3], use fftshift. For n even, A[n/2] contains the sum of the positive and negative-frequency terms. For n even and x real, A[n/2] will always be real. This function is most efficient when n is a power of two. Examples >>> from scipy.fftpack import fft, ifft >>> x = np.arange(5) >>> np.allclose(fft(ifft(x)), x, atol=1e-15) True # within numerical accuracy. scipy.fftpack.ifft(x, n=None, axis=-1, overwrite_x=0) Return discrete inverse Fourier transform of real or complex sequence. The returned complex array contains y(0), y(1),..., y(n-1) where y(j) = (x * exp(2*pi*sqrt(-1)*j*np.arange(n)/n)).mean(). 242 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Parameters x : array_like Transformed data to invert. n : int, optional Length of the inverse Fourier transform. If n < x.shape[axis], x is truncated. If n > x.shape[axis], x is zero-padded. The default results in n = x.shape[axis]. axis : int, optional Axis along which the ifft’s are computed; the default is over the last axis (i.e., axis=-1). overwrite_x : bool, optional If True the contents of x can be destroyed; the default is False. scipy.fftpack.fft2(x, shape=None, axes=(-2, -1), overwrite_x=0) 2-D discrete Fourier transform. Return the two-dimensional discrete Fourier transform of the 2-D argument x. See Also for detailed information. fftn scipy.fftpack.ifft2(x, shape=None, axes=(-2, -1), overwrite_x=0) 2-D discrete inverse Fourier transform of real or complex sequence. Return inverse two-dimensional discrete Fourier transform of arbitrary type sequence x. See ifft for more information. See Also fft2, ifft scipy.fftpack.fftn(x, shape=None, axes=None, overwrite_x=0) Return multidimensional discrete Fourier transform. The returned array contains: y[j_1,..,j_d] = sum[k_1=0..n_1-1, ..., k_d=0..n_d-1] x[k_1,..,k_d] * prod[i=1..d] exp(-sqrt(-1)*2*pi/n_i * j_i * k_i) where d = len(x.shape) and n = x.shape. Note that y[..., -j_i, ...] ...].conjugate(). Parameters Returns = y[..., n_i-j_i, x : array_like The (n-dimensional) array to transform. shape : tuple of ints, optional The shape of the result. If both shape and axes (see below) are None, shape is x.shape; if shape is None but axes is not None, then shape is scipy.take(x.shape, axes, axis=0). If shape[i] > x.shape[i], the i-th dimension is padded with zeros. If shape[i] < x.shape[i], the i-th dimension is truncated to length shape[i]. axes : array_like of ints, optional The axes of x (y if shape is not None) along which the transform is applied. overwrite_x : bool, optional If True, the contents of x can be destroyed. Default is False. y : complex-valued n-dimensional numpy array The (n-dimensional) DFT of the input array. 5.5. Discrete Fourier transforms (scipy.fftpack) 243 SciPy Reference Guide, Release 0.13.0 See Also ifftn Examples >>> y = (-np.arange(16), 8 - np.arange(16), np.arange(16)) >>> np.allclose(y, fftn(ifftn(y))) True scipy.fftpack.ifftn(x, shape=None, axes=None, overwrite_x=0) Return inverse multi-dimensional discrete Fourier transform of arbitrary type sequence x. The returned array contains: y[j_1,..,j_d] = 1/p * sum[k_1=0..n_1-1, ..., k_d=0..n_d-1] x[k_1,..,k_d] * prod[i=1..d] exp(sqrt(-1)*2*pi/n_i * j_i * k_i) where d = len(x.shape), n = x.shape, and p = prod[i=1..d] n_i. For description of parameters see fftn. See Also for detailed information. fftn scipy.fftpack.rfft(x, n=None, axis=-1, overwrite_x=0) Discrete Fourier transform of a real sequence. The returned real arrays contains: [y(0),Re(y(1)),Im(y(1)),...,Re(y(n/2))] [y(0),Re(y(1)),Im(y(1)),...,Re(y(n/2)),Im(y(n/2))] if n is even if n is odd where y(j) = sum[k=0..n-1] x[k] * exp(-sqrt(-1)*j*k*2*pi/n) j = 0..n-1 Note that y(-j) == y(n-j).conjugate(). Parameters x : array_like, real-valued The data to transform. n : int, optional Defines the length of the Fourier transform. If n is not specified (the default) then n = x.shape[axis]. If n < x.shape[axis], x is truncated, if n > x.shape[axis], x is zero-padded. axis : int, optional The axis along which the transform is applied. The default is the last axis. overwrite_x : bool, optional If set to true, the contents of x can be overwritten. Default is False. See Also fft, irfft, scipy.fftpack.basic Notes Within numerical accuracy, y == rfft(irfft(y)). 244 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 scipy.fftpack.irfft(x, n=None, axis=-1, overwrite_x=0) Return inverse discrete Fourier transform of real sequence x. The contents of x is interpreted as the output of the rfft(..) function. Parameters Returns x : array_like Transformed data to invert. n : int, optional Length of the inverse Fourier transform. If n < x.shape[axis], x is truncated. If n > x.shape[axis], x is zero-padded. The default results in n = x.shape[axis]. axis : int, optional Axis along which the ifft’s are computed; the default is over the last axis (i.e., axis=-1). overwrite_x : bool, optional If True the contents of x can be destroyed; the default is False. irfft : ndarray of floats The inverse discrete Fourier transform. See Also rfft, ifft Notes The returned real array contains: [y(0),y(1),...,y(n-1)] where for n is even: y(j) = 1/n (sum[k=1..n/2-1] (x[2*k-1]+sqrt(-1)*x[2*k]) * exp(sqrt(-1)*j*k* 2*pi/n) + c.c. + x[0] + (-1)**(j) x[n-1]) and for n is odd: y(j) = 1/n (sum[k=1..(n-1)/2] (x[2*k-1]+sqrt(-1)*x[2*k]) * exp(sqrt(-1)*j*k* 2*pi/n) + c.c. + x[0]) c.c. denotes complex conjugate of preceeding expression. For details on input parameters, see rfft. scipy.fftpack.dct(x, type=2, n=None, axis=-1, norm=None, overwrite_x=0) Return the Discrete Cosine Transform of arbitrary type sequence x. Parameters Returns x : array_like The input array. type : {1, 2, 3}, optional Type of the DCT (see Notes). Default type is 2. n : int, optional Length of the transform. axis : int, optional Axis over which to compute the transform. norm : {None, ‘ortho’}, optional Normalization mode (see Notes). Default is None. overwrite_x : bool, optional If True the contents of x can be destroyed. (default=False) y : ndarray of real The transformed input array. 5.5. Discrete Fourier transforms (scipy.fftpack) 245 SciPy Reference Guide, Release 0.13.0 See Also idct Notes For a single dimension array x, dct(x, norm=’ortho’) is equal to MATLAB dct(x). There are theoretically 8 types of the DCT, only the first 3 types are implemented in scipy. ‘The’ DCT generally refers to DCT type 2, and ‘the’ Inverse DCT generally refers to DCT type 3. type I There are several definitions of the DCT-I; we use the following (for norm=None): N-2 y[k] = x[0] + (-1)**k x[N-1] + 2 * sum x[n]*cos(pi*k*n/(N-1)) n=1 Only None is supported as normalization mode for DCT-I. Note also that the DCT-I is only supported for input size > 1 type II There are several definitions of the DCT-II; we use the following (for norm=None): N-1 y[k] = 2* sum x[n]*cos(pi*k*(2n+1)/(2*N)), 0 <= k < N. n=0 If norm=’ortho’, y[k] is multiplied by a scaling factor f : f = sqrt(1/(4*N)) if k = 0, f = sqrt(1/(2*N)) otherwise. Which makes the corresponding matrix of coefficients orthonormal (OO’ = Id). type III There are several definitions, we use the following (for norm=None): N-1 y[k] = x[0] + 2 * sum x[n]*cos(pi*(k+0.5)*n/N), 0 <= k < N. n=1 or, for norm=’ortho’ and 0 <= k < N: N-1 y[k] = x[0] / sqrt(N) + sqrt(1/N) * sum x[n]*cos(pi*(k+0.5)*n/N) n=1 The (unnormalized) DCT-III is the inverse of the (unnormalized) DCT-II, up to a factor 2N. The orthonormalized DCT-III is exactly the inverse of the orthonormalized DCT-II. References [R29], [R30] scipy.fftpack.idct(x, type=2, n=None, axis=-1, norm=None, overwrite_x=0) Return the Inverse Discrete Cosine Transform of an arbitrary type sequence. Parameters 246 x : array_like The input array. type : {1, 2, 3}, optional Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Returns Type of the DCT (see Notes). Default type is 2. n : int, optional Length of the transform. axis : int, optional Axis over which to compute the transform. norm : {None, ‘ortho’}, optional Normalization mode (see Notes). Default is None. overwrite_x : bool, optional If True the contents of x can be destroyed. (default=False) idct : ndarray of real The transformed input array. See Also dct Notes For a single dimension array x, idct(x, norm=’ortho’) is equal to MATLAB idct(x). ‘The’ IDCT is the IDCT of type 2, which is the same as DCT of type 3. IDCT of type 1 is the DCT of type 1, IDCT of type 2 is the DCT of type 3, and IDCT of type 3 is the DCT of type 2. For the definition of these types, see dct. 5.5.2 Differential and pseudo-differential operators diff(x[, order, period, _cache]) tilbert(x, h[, period, _cache]) itilbert(x, h[, period, _cache]) hilbert(x[, _cache]) ihilbert(x) cs_diff(x, a, b[, period, _cache]) sc_diff(x, a, b[, period, _cache]) ss_diff(x, a, b[, period, _cache]) cc_diff(x, a, b[, period, _cache]) shift(x, a[, period, _cache]) Return k-th derivative (or integral) of a periodic sequence x. Return h-Tilbert transform of a periodic sequence x. Return inverse h-Tilbert transform of a periodic sequence x. Return Hilbert transform of a periodic sequence x. Return inverse Hilbert transform of a periodic sequence x. Return (a,b)-cosh/sinh pseudo-derivative of a periodic sequence. Return (a,b)-sinh/cosh pseudo-derivative of a periodic sequence x. Return (a,b)-sinh/sinh pseudo-derivative of a periodic sequence x. Return (a,b)-cosh/cosh pseudo-derivative of a periodic sequence. Shift periodic sequence x by a: y(u) = x(u+a). scipy.fftpack.diff(x, order=1, period=None, _cache={}) Return k-th derivative (or integral) of a periodic sequence x. If x_j and y_j are Fourier coefficients of periodic functions x and y, respectively, then: y_j = pow(sqrt(-1)*j*2*pi/period, order) * x_j y_0 = 0 if order is not 0. Parameters x : array_like Input array. order : int, optional The order of differentiation. Default order is 1. If order is negative, then integration is carried out under the assumption that x_0 == 0. period : float, optional The assumed period of the sequence. Default is 2*pi. 5.5. Discrete Fourier transforms (scipy.fftpack) 247 SciPy Reference Guide, Release 0.13.0 Notes If sum(x, axis=0) = 0 then diff(diff(x, k), -k) == x (within numerical accuracy). For odd order and even len(x), the Nyquist mode is taken zero. scipy.fftpack.tilbert(x, h, period=None, _cache={}) Return h-Tilbert transform of a periodic sequence x. If x_j and y_j are Fourier coefficients of periodic functions x and y, respectively, then: y_j = sqrt(-1)*coth(j*h*2*pi/period) * x_j y_0 = 0 Parameters Returns x : array_like The input array to transform. h : float Defines the parameter of the Tilbert transform. period : float, optional The assumed period of the sequence. Default period is 2*pi. tilbert : ndarray The result of the transform. Notes If sum(x, axis=0) == 0 and n = len(x) is odd then tilbert(itilbert(x)) == x. If 2 * pi * h / period is approximately 10 or larger, then numerically tilbert == hilbert (theoretically oo-Tilbert == Hilbert). For even len(x), the Nyquist mode of x is taken zero. scipy.fftpack.itilbert(x, h, period=None, _cache={}) Return inverse h-Tilbert transform of a periodic sequence x. If x_j and y_j are Fourier coefficients of periodic functions x and y, respectively, then: y_j = -sqrt(-1)*tanh(j*h*2*pi/period) * x_j y_0 = 0 For more details, see tilbert. scipy.fftpack.hilbert(x, _cache={}) Return Hilbert transform of a periodic sequence x. If x_j and y_j are Fourier coefficients of periodic functions x and y, respectively, then: y_j = sqrt(-1)*sign(j) * x_j y_0 = 0 Parameters Returns 248 x : array_like The input array, should be periodic. _cache : dict, optional Dictionary that contains the kernel used to do a convolution with. y : ndarray The transformed input. Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Notes If sum(x, axis=0) == 0 then hilbert(ihilbert(x)) == x. For even len(x), the Nyquist mode of x is taken zero. The sign of the returned transform does not have a factor -1 that is more often than not found in the definition of the Hilbert transform. Note also that scipy.signal.hilbert does have an extra -1 factor compared to this function. scipy.fftpack.ihilbert(x) Return inverse Hilbert transform of a periodic sequence x. If x_j and y_j are Fourier coefficients of periodic functions x and y, respectively, then: y_j = -sqrt(-1)*sign(j) * x_j y_0 = 0 scipy.fftpack.cs_diff(x, a, b, period=None, _cache={}) Return (a,b)-cosh/sinh pseudo-derivative of a periodic sequence. If x_j and y_j are Fourier coefficients of periodic functions x and y, respectively, then: y_j = -sqrt(-1)*cosh(j*a*2*pi/period)/sinh(j*b*2*pi/period) * x_j y_0 = 0 Parameters Returns x : array_like The array to take the pseudo-derivative from. a, b : float Defines the parameters of the cosh/sinh pseudo-differential operator. period : float, optional The period of the sequence. Default period is 2*pi. cs_diff : ndarray Pseudo-derivative of periodic sequence x. Notes For even len(x), the Nyquist mode of x is taken as zero. scipy.fftpack.sc_diff(x, a, b, period=None, _cache={}) Return (a,b)-sinh/cosh pseudo-derivative of a periodic sequence x. If x_j and y_j are Fourier coefficients of periodic functions x and y, respectively, then: y_j = sqrt(-1)*sinh(j*a*2*pi/period)/cosh(j*b*2*pi/period) * x_j y_0 = 0 Parameters x : array_like Input array. a,b : float Defines the parameters of the sinh/cosh pseudo-differential operator. period : float, optional The period of the sequence x. Default is 2*pi. Notes sc_diff(cs_diff(x,a,b),b,a) == x For even len(x), the Nyquist mode of x is taken as zero. 5.5. Discrete Fourier transforms (scipy.fftpack) 249 SciPy Reference Guide, Release 0.13.0 scipy.fftpack.ss_diff(x, a, b, period=None, _cache={}) Return (a,b)-sinh/sinh pseudo-derivative of a periodic sequence x. If x_j and y_j are Fourier coefficients of periodic functions x and y, respectively, then: y_j = sinh(j*a*2*pi/period)/sinh(j*b*2*pi/period) * x_j y_0 = a/b * x_0 Parameters x : array_like The array to take the pseudo-derivative from. a,b Defines the parameters of the sinh/sinh pseudo-differential operator. period : float, optional The period of the sequence x. Default is 2*pi. Notes ss_diff(ss_diff(x,a,b),b,a) == x scipy.fftpack.cc_diff(x, a, b, period=None, _cache={}) Return (a,b)-cosh/cosh pseudo-derivative of a periodic sequence. If x_j and y_j are Fourier coefficients of periodic functions x and y, respectively, then: y_j = cosh(j*a*2*pi/period)/cosh(j*b*2*pi/period) * x_j Parameters Returns x : array_like The array to take the pseudo-derivative from. a,b : float Defines the parameters of the sinh/sinh pseudo-differential operator. period : float, optional The period of the sequence x. Default is 2*pi. cc_diff : ndarray Pseudo-derivative of periodic sequence x. Notes cc_diff(cc_diff(x,a,b),b,a) == x scipy.fftpack.shift(x, a, period=None, _cache={}) Shift periodic sequence x by a: y(u) = x(u+a). If x_j and y_j are Fourier coefficients of periodic functions x and y, respectively, then: y_j = exp(j*a*2*pi/period*sqrt(-1)) * x_f Parameters 250 x : array_like The array to take the pseudo-derivative from. a : float Defines the parameters of the sinh/sinh pseudo-differential period : float, optional The period of the sequences x and y. Default period is 2*pi. Continued on next page Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Table 5.16 – continued from previous page 5.5.3 Helper functions fftshift(x[, axes]) ifftshift(x[, axes]) fftfreq(n[, d]) rfftfreq(n[, d]) Shift the zero-frequency component to the center of the spectrum. The inverse of fftshift. Return the Discrete Fourier Transform sample frequencies. DFT sample frequencies (for usage with rfft, irfft). scipy.fftpack.fftshift(x, axes=None) Shift the zero-frequency component to the center of the spectrum. This function swaps half-spaces for all axes listed (defaults to all). Note that y[0] is the Nyquist component only if len(x) is even. Parameters Returns x : array_like Input array. axes : int or shape tuple, optional Axes over which to shift. Default is None, which shifts all axes. y : ndarray The shifted array. See Also ifftshift The inverse of fftshift. Examples >>> freqs = np.fft.fftfreq(10, 0.1) >>> freqs array([ 0., 1., 2., 3., 4., -5., -4., -3., -2., -1.]) >>> np.fft.fftshift(freqs) array([-5., -4., -3., -2., -1., 0., 1., 2., 3., 4.]) Shift the zero-frequency component only along the second axis: >>> freqs = np.fft.fftfreq(9, d=1./9).reshape(3, 3) >>> freqs array([[ 0., 1., 2.], [ 3., 4., -4.], [-3., -2., -1.]]) >>> np.fft.fftshift(freqs, axes=(1,)) array([[ 2., 0., 1.], [-4., 3., 4.], [-1., -3., -2.]]) scipy.fftpack.ifftshift(x, axes=None) The inverse of fftshift. Parameters Returns x : array_like Input array. axes : int or shape tuple, optional Axes over which to calculate. Defaults to None, which shifts all axes. y : ndarray The shifted array. 5.5. Discrete Fourier transforms (scipy.fftpack) 251 SciPy Reference Guide, Release 0.13.0 See Also fftshift Shift zero-frequency component to the center of the spectrum. Examples >>> freqs = np.fft.fftfreq(9, d=1./9).reshape(3, 3) >>> freqs array([[ 0., 1., 2.], [ 3., 4., -4.], [-3., -2., -1.]]) >>> np.fft.ifftshift(np.fft.fftshift(freqs)) array([[ 0., 1., 2.], [ 3., 4., -4.], [-3., -2., -1.]]) scipy.fftpack.fftfreq(n, d=1.0) Return the Discrete Fourier Transform sample frequencies. The returned float array contains the frequency bins in cycles/unit (with zero at the start) given a window length n and a sample spacing d: f = [0, 1, ..., n/2-1, -n/2, ..., -1] / (d*n) f = [0, 1, ..., (n-1)/2, -(n-1)/2, ..., -1] / (d*n) Parameters Returns if n is even if n is odd n : int Window length. d : scalar Sample spacing. out : ndarray The array of length n, containing the sample frequencies. Examples >>> signal = np.array([-2, 8, 6, 4, 1, 0, 3, 5], dtype=float) >>> fourier = np.fft.fft(signal) >>> n = signal.size >>> timestep = 0.1 >>> freq = np.fft.fftfreq(n, d=timestep) >>> freq array([ 0. , 1.25, 2.5 , 3.75, -5. , -3.75, -2.5 , -1.25]) scipy.fftpack.rfftfreq(n, d=1.0) DFT sample frequencies (for usage with rfft, irfft). The returned float array contains the frequency bins in cycles/unit (with zero at the start) given a window length n and a sample spacing d: f = [0,1,1,2,2,...,n/2-1,n/2-1,n/2]/(d*n) if n is even f = [0,1,1,2,2,...,n/2-1,n/2-1,n/2,n/2]/(d*n) if n is odd Parameters Returns 252 n : int Window length. d : scalar, optional Sample spacing. Default is 1. out : ndarray The array of length n, containing the sample frequencies. Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Examples >>> from scipy import fftpack >>> sig = np.array([-2, 8, 6, 4, 1, 0, 3, 5], dtype=float) >>> sig_fft = fftpack.rfft(sig) >>> n = sig_fft.size >>> timestep = 0.1 >>> freq = fftpack.rfftfreq(n, d=timestep) >>> freq array([ 0. , 1.25, 1.25, 2.5 , 2.5 , 3.75, 3.75, 5. ]) 5.5.4 Convolutions (scipy.fftpack.convolve) convolve convolve_z init_convolution_kernel destroy_convolve_cache convolve - Function signature: convolve_z - Function signature: init_convolution_kernel - Function signature: destroy_convolve_cache - Function signature: scipy.fftpack.convolve.convolve = convolve - Function signature: y = convolve(x,omega,[swap_real_imag,overwrite_x]) Required arguments: x : input rank-1 array(‘d’) with bounds (n) omega : input rank-1 array(‘d’) with bounds (n) Optional arguments: overwrite_x := 0 input int swap_real_imag := 0 input int Return objects: y : rank-1 array(‘d’) with bounds (n) and x storage scipy.fftpack.convolve.convolve_z = convolve_z - Function signature: y = convolve_z(x,omega_real,omega_imag,[overwrite_x]) Required arguments: x : input rank-1 array(‘d’) with bounds (n) omega_real : input rank-1 array(‘d’) with bounds (n) omega_imag : input rank-1 array(‘d’) with bounds (n) Optional arguments: overwrite_x := 0 input int Return objects: y : rank-1 array(‘d’) with bounds (n) and x storage scipy.fftpack.convolve.init_convolution_kernel = init_convolution_kernel - Function signature: omega = init_convolution_kernel(n,kernel_func,[d,zero_nyquist,kernel_func_extra_args]) Required arguments: n : input int kernel_func : call-back function 5.5. Discrete Fourier transforms (scipy.fftpack) 253 SciPy Reference Guide, Release 0.13.0 Optional arguments: d := 0 input int kernel_func_extra_args := () input tuple zero_nyquist := d%2 input int Return objects: omega : rank-1 array(‘d’) with bounds (n) Call-back functions: def kernel_func(k): return kernel_func Required arguments: k : input int Return objects: kernel_func : float scipy.fftpack.convolve.destroy_convolve_cache = destroy_convolve_cache - Function signature: destroy_convolve_cache() 5.5.5 Other (scipy.fftpack._fftpack) drfft zfft zrfft zfftnd destroy_drfft_cache destroy_zfft_cache destroy_zfftnd_cache drfft - Function signature: zfft - Function signature: zrfft - Function signature: zfftnd - Function signature: destroy_drfft_cache - Function signature: destroy_zfft_cache - Function signature: destroy_zfftnd_cache - Function signature: scipy.fftpack._fftpack.drfft = drfft - Function signature: y = drfft(x,[n,direction,normalize,overwrite_x]) Required arguments: x : input rank-1 array(‘d’) with bounds (*) Optional arguments: overwrite_x := 0 input int n := size(x) input int direction := 1 input int normalize := (direction<0) input int Return objects: y : rank-1 array(‘d’) with bounds (*) and x storage scipy.fftpack._fftpack.zfft = zfft - Function signature: y = zfft(x,[n,direction,normalize,overwrite_x]) Required arguments: x : input rank-1 array(‘D’) with bounds (*) Optional arguments: overwrite_x := 0 input int n := size(x) input int direction := 1 input int normalize := (direction<0) input int Return objects: y : rank-1 array(‘D’) with bounds (*) and x storage 254 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 scipy.fftpack._fftpack.zrfft = zrfft - Function signature: y = zrfft(x,[n,direction,normalize,overwrite_x]) Required arguments: x : input rank-1 array(‘D’) with bounds (*) Optional arguments: overwrite_x := 1 input int n := size(x) input int direction := 1 input int normalize := (direction<0) input int Return objects: y : rank-1 array(‘D’) with bounds (*) and x storage scipy.fftpack._fftpack.zfftnd = zfftnd - Function signature: y = zfftnd(x,[s,direction,normalize,overwrite_x]) Required arguments: x : input rank-1 array(‘D’) with bounds (*) Optional arguments: overwrite_x := 0 input int s := old_shape(x,j++) input rank-1 array(‘i’) with bounds (r) direction := 1 input int normalize := (direction<0) input int Return objects: y : rank-1 array(‘D’) with bounds (*) and x storage scipy.fftpack._fftpack.destroy_drfft_cache = destroy_drfft_cache - Function signature: destroy_drfft_cache() scipy.fftpack._fftpack.destroy_zfft_cache = destroy_zfft_cache - Function signature: destroy_zfft_cache() scipy.fftpack._fftpack.destroy_zfftnd_cache = destroy_zfftnd_cache - Function signature: destroy_zfftnd_cache() 5.6 Integration and ODEs (scipy.integrate) 5.6.1 Integrating functions, given function object quad(func, a, b[, args, full_output, ...]) dblquad(func, a, b, gfun, hfun[, args, ...]) tplquad(func, a, b, gfun, hfun, qfun, rfun) nquad(func, ranges[, args, opts]) fixed_quad(func, a, b[, args, n]) quadrature(func, a, b[, args, tol, rtol, ...]) romberg(function, a, b[, args, tol, rtol, ...]) Compute a definite integral. Compute a double integral. Compute a triple (definite) integral. Integration over multiple variables. Compute a definite integral using fixed-order Gaussian quadrature. Compute a definite integral using fixed-tolerance Gaussian quadrature. Romberg integration of a callable function or method. scipy.integrate.quad(func, a, b, args=(), full_output=0, epsabs=1.49e-08, epsrel=1.49e-08, limit=50, points=None, weight=None, wvar=None, wopts=None, maxp1=50, limlst=50) Compute a definite integral. 5.6. Integration and ODEs (scipy.integrate) 255 SciPy Reference Guide, Release 0.13.0 Integrate func from a to b (possibly infinite interval) using a technique from the Fortran library QUADPACK. Run scipy.integrate.quad_explain() for more information on the more esoteric inputs and outputs. func : function A Python function or method to integrate. If func takes many arguments, it is integrated along the axis corresponding to the first argument. a : float Lower limit of integration (use -numpy.inf for -infinity). b : float Upper limit of integration (use numpy.inf for +infinity). args : tuple, optional Extra arguments to pass to func. full_output : int, optional Non-zero to return a dictionary of integration information. If non-zero, warning messages are also suppressed and the message is appended to the output tuple. Returns y : float The integral of func from a to b. abserr : float An estimate of the absolute error in the result. infodict : dict A dictionary containing additional information. Run scipy.integrate.quad_explain() for more information. message : A convergence message. explain : Appended only with ‘cos’ or ‘sin’ weighting and infinite integration limits, it contains an explanation of the codes in infodict[’ierlst’] Other Parameters epsabs : float or int, optional Absolute error tolerance. epsrel : float or int, optional Relative error tolerance. limit : float or int, optional An upper bound on the number of subintervals used in the adaptive algorithm. points : (sequence of floats,ints), optional A sequence of break points in the bounded integration interval where local difficulties of the integrand may occur (e.g., singularities, discontinuities). The sequence does not have to be sorted. weight : float or int, optional String indicating weighting function. wvar : optional Variables for use with weighting functions. wopts : optional Optional input for reusing Chebyshev moments. maxp1 : float or int, optional An upper bound on the number of Chebyshev moments. limlst : int, optional Upper bound on the number of cylces (>=3) for use with a sinusoidal weighting and an infinite end-point. Parameters See Also 256 dblquad double integral tplquad triple integral Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 n-dimensional integrals (uses quad recursively) nquad fixed_quadfixed-order Gaussian quadrature quadratureadaptive Gaussian quadrature odeint ODE integrator ode ODE integrator simps integrator for sampled data romb integrator for sampled data scipy.special for coefficients and roots of orthogonal polynomials Examples R4 Calculate 0 x2 dx and compare with an analytic result >>> from scipy import integrate >>> x2 = lambda x: x**2 >>> integrate.quad(x2, 0, 4) (21.333333333333332, 2.3684757858670003e-13) >>> print(4**3 / 3.) # analytical result 21.3333333333 Calculate R∞ 0 e−x dx >>> invexp = lambda x: np.exp(-x) >>> integrate.quad(invexp, 0, np.inf) (1.0, 5.842605999138044e-11) >>> >>> >>> 0.5 >>> >>> 1.5 f = lambda x,a : a*x y, err = integrate.quad(f, 0, 1, args=(1,)) y y, err = integrate.quad(f, 0, 1, args=(3,)) y scipy.integrate.dblquad(func, a, b, gfun, hfun, args=(), epsabs=1.49e-08, epsrel=1.49e-08) Compute a double integral. Return the double (definite) integral of func(y, x) from x = a..b and y = gfun(x)..hfun(x). Parameters func : callable A Python function or method of at least two variables: y must be the first argument and x the second argument. (a,b) : tuple The limits of integration in x: a < b gfun : callable The lower boundary curve in y which is a function taking a single floating point argument (x) and returning a floating point result: a lambda function can be useful here. hfun : callable The upper boundary curve in y (same requirements as gfun). args : sequence, optional Extra arguments to pass to func. epsabs : float, optional 5.6. Integration and ODEs (scipy.integrate) 257 SciPy Reference Guide, Release 0.13.0 Absolute tolerance passed directly to the inner 1-D quadrature integration. Default is 1.49e-8. epsrel : float Relative tolerance of the inner 1-D integrals. Default is 1.49e-8. y : float The resultant integral. abserr : float An estimate of the error. Returns See Also quad single integral tplquad triple integral nquad N-dimensional integrals fixed_quadfixed-order Gaussian quadrature quadratureadaptive Gaussian quadrature odeint ODE integrator ode ODE integrator simps integrator for sampled data romb integrator for sampled data scipy.special for coefficients and roots of orthogonal polynomials scipy.integrate.tplquad(func, a, b, gfun, hfun, qfun, rfun, args=(), epsabs=1.49e-08, epsrel=1.49e08) Compute a triple (definite) integral. Return the triple integral of func(z, y, x) from x = a..b, y = gfun(x)..hfun(x), and z = qfun(x,y)..rfun(x,y). Parameters 258 func : function A Python function or method of at least three variables in the order (z, y, x). (a,b) : tuple The limits of integration in x: a < b gfun : function The lower boundary curve in y which is a function taking a single floating point argument (x) and returning a floating point result: a lambda function can be useful here. hfun : function The upper boundary curve in y (same requirements as gfun). qfun : function The lower boundary surface in z. It must be a function that takes two floats in the order (x, y) and returns a float. rfun : function The upper boundary surface in z. (Same requirements as qfun.) args : Arguments Extra arguments to pass to func. epsabs : float, optional Absolute tolerance passed directly to the innermost 1-D quadrature integration. Default is 1.49e-8. epsrel : float, optional Relative tolerance of the innermost 1-D integrals. Default is 1.49e-8. Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 y : float The resultant integral. abserr : float An estimate of the error. Returns See Also Adaptive quadrature using QUADPACK quad quadratureAdaptive Gaussian quadrature fixed_quadFixed-order Gaussian quadrature dblquad Double integrals nquad N-dimensional integrals romb Integrators for sampled data simps Integrators for sampled data ode ODE integrators odeint ODE integrators scipy.special For coefficients and roots of orthogonal polynomials scipy.integrate.nquad(func, ranges, args=None, opts=None) Integration over multiple variables. Wraps quad to enable integration over multiple variables. Various options allow improved integration of discontinuous functions, as well as the use of weighted integration, and generally finer control of the integration process. Parameters func : callable The function to be integrated. Has arguments of x0, ... xn, t0, tm, where integration is carried out over x0, ... xn, which must be floats. Function signature should be func(x0, x1, ..., xn, t0, t1, ..., tm). Integration is carried out in order. That is, integration over x0 is the innermost integral, and xn is the outermost. ranges : iterable object Each element of ranges may be either a sequence of 2 numbers, or else a callable that returns such a sequence. ranges[0] corresponds to integration over x0, and so on. If an element of ranges is a callable, then it will be called with all of the integration arguments available. e.g. if func = f(x0, x1, x2), then ranges[0] may be defined as either (a, b) or else as (a, b) = range0(x1, x2). args : iterable object, optional Additional arguments t0, ..., tn, required by func. opts : iterable object or dict, optional Options to be passed to quad. May be empty, a dict, or a sequence of dicts or functions that return a dict. If empty, the default options from scipy.integrate.quadare used. If a dict, the same options are used for all levels of integraion. If a sequence, then each element of the sequence corresponds to a particular integration. e.g. opts[0] corresponds to integration over x0, and so on. The available options together with their default values are: •epsabs = 1.49e-08 •epsrel = 1.49e-08 •limit = 50 •points = None 5.6. Integration and ODEs (scipy.integrate) 259 SciPy Reference Guide, Release 0.13.0 Returns •weight = None •wvar = None •wopts = None The full_output option from quad is unavailable, due to the complexity of handling the large amount of data such an option would return for this kind of nested integration. For more information on these options, see quad and quad_explain. result : float The result of the integration. abserr : float The maximum of the estimates of the absolute error in the various integration results. See Also quad 1-dimensional numerical integration dblquad, tplquad fixed_quadfixed-order Gaussian quadrature quadratureadaptive Gaussian quadrature Examples >>> from scipy import integrate >>> func = lambda x0,x1,x2,x3 : x0**2 + x1*x2 - x3**3 + np.sin(x0) + ( ... 1 if (x0-.2*x3-.5-.25*x1>0) else 0) >>> points = [[lambda (x1,x2,x3) : 0.2*x3 + 0.5 + 0.25*x1], [], [], []] >>> def opts0(*args, **kwargs): ... return {’points’:[0.2*args[2] + 0.5 + 0.25*args[0]]} >>> integrate.nquad(func, [[0,1], [-1,1], [.13,.8], [-.15,1]], ... opts=[opts0,{},{},{}]) (1.5267454070738633, 2.9437360001402324e-14) scale = .1 def func2(x0, x1, x2, x3, t0, t1): return x0*x1*x3**2 + np.sin(x2) + 1 + (1 if x0+t1*x1-t0>0 else 0) def lim0(x1, x2, x3, t0, t1): return [scale * (x1**2 + x2 + np.cos(x3)*t0*t1 + 1) - 1, scale * (x1**2 + x2 + np.cos(x3)*t0*t1 + 1) + 1] def lim1(x2, x3, t0, t1): return [scale * (t0*x2 + t1*x3) - 1, scale * (t0*x2 + t1*x3) + 1] def lim2(x3, t0, t1): return [scale * (x3 + t0**2*t1**3) - 1, scale * (x3 + t0**2*t1**3) + 1] def lim3(t0, t1): return [scale * (t0+t1) - 1, scale * (t0+t1) + 1] def opts0(x1, x2, x3, t0, t1): return {’points’ : [t0 - t1*x1]} def opts1(x2, x3, t0, t1): return {} def opts2(x3, t0, t1): return {} def opts3(t0, t1): return {} integrate.nquad(func2, [lim0, lim1, lim2, lim3], args=(0,0), opts=[opts0, opts1, opts2, opts3]) (25.066666666666666, 2.7829590483937256e-13) >>> >>> ... >>> ... ... >>> ... ... >>> ... ... >>> ... >>> ... >>> ... >>> ... >>> ... >>> 260 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 scipy.integrate.fixed_quad(func, a, b, args=(), n=5) Compute a definite integral using fixed-order Gaussian quadrature. Integrate func from a to b using Gaussian quadrature of order n. Parameters Returns func : callable A Python function or method to integrate (must accept vector inputs). a : float Lower limit of integration. b : float Upper limit of integration. args : tuple, optional Extra arguments to pass to function, if any. n : int, optional Order of quadrature integration. Default is 5. val : float Gaussian quadrature approximation to the integral See Also quad adaptive quadrature using QUADPACK dblquad double integrals tplquad triple integrals romberg adaptive Romberg quadrature quadratureadaptive Gaussian quadrature romb integrators for sampled data simps integrators for sampled data cumtrapz cumulative integration for sampled data ode ODE integrator odeint ODE integrator scipy.integrate.quadrature(func, a, b, args=(), tol=1.49e-08, rtol=1.49e-08, maxiter=50, vec_func=True) Compute a definite integral using fixed-tolerance Gaussian quadrature. Integrate func from a to b using Gaussian quadrature with absolute tolerance tol. Parameters func : function A Python function or method to integrate. a : float Lower limit of integration. b : float Upper limit of integration. args : tuple, optional Extra arguments to pass to function. tol, rol : float, optional Iteration stops when error between last two iterates is less than tol OR the relative change is less than rtol. maxiter : int, optional Maximum number of iterations. vec_func : bool, optional 5.6. Integration and ODEs (scipy.integrate) 261 SciPy Reference Guide, Release 0.13.0 True or False if func handles arrays as arguments (is a “vector” function). Default is True. val : float Gaussian quadrature approximation (within tolerance) to integral. err : float Difference between last two estimates of the integral. Returns See Also romberg adaptive Romberg quadrature fixed_quadfixed-order Gaussian quadrature quad adaptive quadrature using QUADPACK dblquad double integrals tplquad triple integrals romb integrator for sampled data simps integrator for sampled data cumtrapz cumulative integration for sampled data ode ODE integrator odeint ODE integrator scipy.integrate.romberg(function, a, b, args=(), tol=1.48e-08, rtol=1.48e-08, show=False, divmax=10, vec_func=False) Romberg integration of a callable function or method. Returns the integral of function (a function of one variable) over the interval (a, b). If show is 1, the triangular array of the intermediate results will be printed. If vec_func is True (default is False), then function is assumed to support vector arguments. function : callable Function to be integrated. a : float Lower limit of integration. b : float Upper limit of integration. Returns results : float Result of the integration. Other Parameters args : tuple, optional Extra arguments to pass to function. Each element of args will be passed as a single argument to func. Default is to pass no extra arguments. tol, rtol : float, optional The desired absolute and relative tolerances. Defaults are 1.48e-8. show : bool, optional Whether to print the results. Default is False. divmax : int, optional Maximum order of extrapolation. Default is 10. vec_func : bool, optional Whether func handles arrays as arguments (i.e whether it is a “vector” function). Default is False. Parameters 262 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 See Also fixed_quadFixed-order Gaussian quadrature. quad Adaptive quadrature using QUADPACK. dblquad Double integrals. tplquad Triple integrals. romb Integrators for sampled data. simps Integrators for sampled data. cumtrapz Cumulative integration for sampled data. ode ODE integrator. odeint ODE integrator. References [R31] Examples Integrate a gaussian from 0 to 1 and compare to the error function. >>> from scipy import integrate >>> from scipy.special import erf >>> gaussian = lambda x: 1/np.sqrt(np.pi) * np.exp(-x**2) >>> result = integrate.romberg(gaussian, 0, 1, show=True) Romberg integration of from [0, 1] Steps 1 2 4 8 16 32 StepSize 1.000000 0.500000 0.250000 0.125000 0.062500 0.031250 Results 0.385872 0.412631 0.419184 0.420810 0.421215 0.421317 0.421551 0.421368 0.421352 0.421350 0.421350 0.421356 0.421350 0.421350 0.421350 0.421350 0.421350 0.421350 0.421350 0.421350 0.421350 The final result is 0.421350396475 after 33 function evaluations. >>> print("%g %g" % (2*result, erf(1))) 0.842701 0.842701 5.6.2 Integrating functions, given fixed samples cumtrapz(y[, x, dx, axis, initial]) simps(y[, x, dx, axis, even]) romb(y[, dx, axis, show]) Cumulatively integrate y(x) using the composite trapezoidal rule. Integrate y(x) using samples along the given axis and the composite Romberg integration using samples of a function. scipy.integrate.cumtrapz(y, x=None, dx=1.0, axis=-1, initial=None) Cumulatively integrate y(x) using the composite trapezoidal rule. Parameters y : array_like Values to integrate. x : array_like, optional 5.6. Integration and ODEs (scipy.integrate) 263 SciPy Reference Guide, Release 0.13.0 Returns The coordinate to integrate along. If None (default), use spacing dx between consecutive elements in y. dx : int, optional Spacing between elements of y. Only used if x is None. axis : int, optional Specifies the axis to cumulate. Default is -1 (last axis). initial : scalar, optional If given, uses this value as the first value in the returned result. Typically this value should be 0. Default is None, which means no value at x[0] is returned and res has one element less than y along the axis of integration. res : ndarray The result of cumulative integration of y along axis. If initial is None, the shape is such that the axis of integration has one less value than y. If initial is given, the shape is equal to that of y. See Also numpy.cumsum, numpy.cumprod quad adaptive quadrature using QUADPACK romberg adaptive Romberg quadrature quadratureadaptive Gaussian quadrature fixed_quadfixed-order Gaussian quadrature dblquad double integrals tplquad triple integrals romb integrators for sampled data ode ODE integrators odeint ODE integrators Examples >>> from scipy import integrate >>> import matplotlib.pyplot as plt >>> >>> >>> >>> >>> 264 x = np.linspace(-2, 2, num=20) y = x y_int = integrate.cumtrapz(y, x, initial=0) plt.plot(x, y_int, ’ro’, x, y[0] + 0.5 * x**2, ’b-’) plt.show() Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 0.0 0.5 1.0 1.5 2.02.0 1.5 1.0 0.5 0.0 0.5 1.0 1.5 2.0 scipy.integrate.simps(y, x=None, dx=1, axis=-1, even=’avg’) Integrate y(x) using samples along the given axis and the composite Simpson’s rule. If x is None, spacing of dx is assumed. If there are an even number of samples, N, then there are an odd number of intervals (N-1), but Simpson’s rule requires an even number of intervals. The parameter ‘even’ controls how this is handled. Parameters y : array_like Array to be integrated. x : array_like, optional If given, the points at which y is sampled. dx : int, optional Spacing of integration points along axis of y. Only used when x is None. Default is 1. axis : int, optional Axis along which to integrate. Default is the last axis. even : {‘avg’, ‘first’, ‘str’}, optional ‘avg’ [Average two results:1) use the first N-2 intervals with] a trapezoidal rule on the last interval and 2) use the last N-2 intervals with a trapezoidal rule on the first interval. ‘first’ [Use Simpson’s rule for the first N-2 intervals with] a trapezoidal rule on the last interval. ‘last’ [Use Simpson’s rule for the last N-2 intervals with a] trapezoidal rule on the first interval. See Also quad adaptive quadrature using QUADPACK romberg adaptive Romberg quadrature quadratureadaptive Gaussian quadrature fixed_quadfixed-order Gaussian quadrature dblquad double integrals tplquad triple integrals romb integrators for sampled data 5.6. Integration and ODEs (scipy.integrate) 265 SciPy Reference Guide, Release 0.13.0 cumtrapz cumulative integration for sampled data ode ODE integrators odeint ODE integrators Notes For an odd number of samples that are equally spaced the result is exact if the function is a polynomial of order 3 or less. If the samples are not equally spaced, then the result is exact only if the function is a polynomial of order 2 or less. scipy.integrate.romb(y, dx=1.0, axis=-1, show=False) Romberg integration using samples of a function. Parameters Returns y : array_like A vector of 2**k + 1 equally-spaced samples of a function. dx : array_like, optional The sample spacing. Default is 1. axis : int, optional The axis along which to integrate. Default is -1 (last axis). show : bool, optional When y is a single 1-D array, then if this argument is True print the table showing Richardson extrapolation from the samples. Default is False. romb : ndarray The integrated result for axis. See Also quad adaptive quadrature using QUADPACK romberg adaptive Romberg quadrature quadratureadaptive Gaussian quadrature fixed_quadfixed-order Gaussian quadrature dblquad double integrals tplquad triple integrals simps integrators for sampled data cumtrapz cumulative integration for sampled data ode ODE integrators odeint ODE integrators See Also scipy.special for orthogonal polynomials (special) for Gaussian quadrature roots and weights for other weighting factors and regions. 5.6.3 Integrators of ODE systems odeint(func, y0, t[, args, Dfun, col_deriv, ...]) ode(f[, jac]) complex_ode(f[, jac]) 266 Integrate a system of ordinary differential equations. A generic interface class to numeric integrators. A wrapper of ode for complex systems. Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 scipy.integrate.odeint(func, y0, t, args=(), Dfun=None, col_deriv=0, full_output=0, ml=None, mu=None, rtol=None, atol=None, tcrit=None, h0=0.0, hmax=0.0, hmin=0.0, ixpr=0, mxstep=0, mxhnil=0, mxordn=12, mxords=5, printmessg=0) Integrate a system of ordinary differential equations. Solve a system of ordinary differential equations using lsoda from the FORTRAN library odepack. Solves the initial value problem for stiff or non-stiff systems of first order ode-s: dy/dt = func(y,t0,...) where y can be a vector. func : callable(y, t0, ...) Computes the derivative of y at t0. y0 : array Initial condition on y (can be a vector). t : array A sequence of time points for which to solve for y. The initial value point should be the first element of this sequence. args : tuple, optional Extra arguments to pass to function. Dfun : callable(y, t0, ...) Gradient (Jacobian) of func. col_deriv : bool, optional True if Dfun defines derivatives down columns (faster), otherwise Dfun should define derivatives across rows. full_output : bool, optional True if to return a dictionary of optional outputs as the second output printmessg : bool, optional Whether to print the convergence message Returns y : array, shape (len(t), len(y0)) Array containing the value of y for each desired time in t, with the initial value y0 in the first row. infodict : dict, only returned if full_output == True Dictionary containing additional output information key meaning ‘hu’ vector of step sizes successfully used for each time step. ‘tcur’ vector with the value of t reached for each time step. (will always be at least as large as the input times). ‘tolsf’ vector of tolerance scale factors, greater than 1.0, computed when a request for too much accuracy was detected. ‘tsw’ value of t at the time of the last method switch (given for each time step) ‘nst’ cumulative number of time steps ‘nfe’ cumulative number of function evaluations for each time step ‘nje’ cumulative number of jacobian evaluations for each time step ‘nqu’ a vector of method orders for each successful step. ‘imxer’ index of the component of largest magnitude in the weighted local error vector (e / ewt) on an error return, -1 otherwise. ‘lenrw’ the length of the double work array required. ‘leniw’ the length of integer work array required. ‘mused’a vector of method indicators for each successful time step: 1: adams (nonstiff), 2: bdf (stiff) Other Parameters ml, mu : int, optional Parameters 5.6. Integration and ODEs (scipy.integrate) 267 SciPy Reference Guide, Release 0.13.0 If either of these are not None or non-negative, then the Jacobian is assumed to be banded. These give the number of lower and upper non-zero diagonals in this banded matrix. For the banded case, Dfun should return a matrix whose columns contain the non-zero bands (starting with the lowest diagonal). Thus, the return matrix from Dfun should have shape len(y0) * (ml + mu + 1) when ml >=0 or mu >=0. rtol, atol : float, optional The input parameters rtol and atol determine the error control performed by the solver. The solver will control the vector, e, of estimated local errors in y, according to an inequality of the form max-norm of (e / ewt) <= 1, where ewt is a vector of positive error weights computed as ewt = rtol * abs(y) + atol. rtol and atol can be either vectors the same length as y or scalars. Defaults to 1.49012e-8. tcrit : ndarray, optional Vector of critical points (e.g. singularities) where integration care should be taken. h0 : float, (0: solver-determined), optional The step size to be attempted on the first step. hmax : float, (0: solver-determined), optional The maximum absolute step size allowed. hmin : float, (0: solver-determined), optional The minimum absolute step size allowed. ixpr : bool, optional Whether to generate extra printing at method switches. mxstep : int, (0: solver-determined), optional Maximum number of (internally defined) steps allowed for each integration point in t. mxhnil : int, (0: solver-determined), optional Maximum number of messages printed. mxordn : int, (0: solver-determined), optional Maximum order to be allowed for the non-stiff (Adams) method. mxords : int, (0: solver-determined), optional Maximum order to be allowed for the stiff (BDF) method. See Also ode a more object-oriented integrator based on VODE. quad for finding the area under a curve. class scipy.integrate.ode(f, jac=None) A generic interface class to numeric integrators. Solve an equation system y 0 (t) = f (t, y) with (optional) jac = df/dy. Parameters f : callable f(t, y, *f_args) Rhs of the equation. t is a scalar, y.shape == (n,). f_args is set by calling set_f_params(*args). f should return a scalar, array or list (not a tuple). jac : callable jac(t, y, *jac_args) Jacobian of the rhs, jac[i,j] = d f[i] / d y[j]. jac_args is set by calling set_f_params(*args). See Also 268 odeint an integrator with a simpler interface based on lsoda from ODEPACK quad for finding the area under a curve Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Notes Available integrators are listed below. They can be selected using the set_integrator method. “vode” Real-valued Variable-coefficient Ordinary Differential Equation solver, with fixed-leading-coefficient implementation. It provides implicit Adams method (for non-stiff problems) and a method based on backward differentiation formulas (BDF) (for stiff problems). Source: http://www.netlib.org/ode/vode.f Warning: This integrator is not re-entrant. You cannot have two ode instances using the “vode” integrator at the same time. This integrator accepts the following parameters in set_integrator method of the ode class: •atol : float or sequence absolute tolerance for solution •rtol : float or sequence relative tolerance for solution •lband : None or int •rband : None or int Jacobian band width, jac[i,j] != 0 for i-lband <= j <= i+rband. Setting these requires your jac routine to return the jacobian in packed format, jac_packed[i-j+lband, j] = jac[i,j]. •method: ‘adams’ or ‘bdf’ Which solver to use, Adams (non-stiff) or BDF (stiff) •with_jacobian : bool Whether to use the jacobian •nsteps : int Maximum number of (internally defined) steps allowed during one call to the solver. •first_step : float •min_step : float •max_step : float Limits for the step sizes used by the integrator. •order : int Maximum order used by the integrator, order <= 12 for Adams, <= 5 for BDF. “zvode” Complex-valued Variable-coefficient Ordinary Differential Equation solver, with fixed-leading-coefficient implementation. It provides implicit Adams method (for non-stiff problems) and a method based on backward differentiation formulas (BDF) (for stiff problems). Source: http://www.netlib.org/ode/zvode.f Warning: This integrator is not re-entrant. You cannot have two ode instances using the “zvode” integrator at the same time. This integrator accepts the same parameters in set_integrator as the “vode” solver. Note: When using ZVODE for a stiff system, it should only be used for the case in which the function f is analytic, that is, when each f(i) is an analytic function of each y(j). Analyticity means that the partial derivative df(i)/dy(j) is a unique complex number, and this fact is critical in the way ZVODE solves the dense or banded linear systems that arise in the stiff case. For a complex stiff ODE system in which f is not analytic, ZVODE is likely to have convergence failures, and for this problem one should instead use DVODE on the equivalent real system (in the real and imaginary parts of y). “lsoda” Real-valued Variable-coefficient Ordinary Differential Equation solver, with fixed-leading-coefficient implementation. It provides automatic method switching between implicit Adams method (for non-stiff problems) and a method based on backward differentiation formulas (BDF) (for stiff problems). Source: http://www.netlib.org/odepack Warning: This integrator is not re-entrant. You cannot have two ode instances using the “lsoda” integrator at the same time. This integrator accepts the following parameters in set_integrator method of the ode class: •atol : float or sequence absolute tolerance for solution 5.6. Integration and ODEs (scipy.integrate) 269 SciPy Reference Guide, Release 0.13.0 •rtol : float or sequence relative tolerance for solution •lband : None or int •rband : None or int Jacobian band width, jac[i,j] != 0 for i-lband <= j <= i+rband. Setting these requires your jac routine to return the jacobian in packed format, jac_packed[i-j+lband, j] = jac[i,j]. •with_jacobian : bool Whether to use the jacobian •nsteps : int Maximum number of (internally defined) steps allowed during one call to the solver. •first_step : float •min_step : float •max_step : float Limits for the step sizes used by the integrator. •max_order_ns : int Maximum order used in the nonstiff case (default 12). •max_order_s : int Maximum order used in the stiff case (default 5). •max_hnil : int Maximum number of messages reporting too small step size (t + h = t) (default 0) •ixpr : int Whether to generate extra printing at method switches (default False). “dopri5” This is an explicit runge-kutta method of order (4)5 due to Dormand & Prince (with stepsize control and dense output). Authors: E. Hairer and G. Wanner Universite de Geneve, Dept. de Mathematiques CH-1211 Geneve 24, Switzerland e-mail: ernst.hairer@math.unige.ch, gerhard.wanner@math.unige.ch This code is described in [HNW93]. This integrator accepts the following parameters in set_integrator() method of the ode class: •atol : float or sequence absolute tolerance for solution •rtol : float or sequence relative tolerance for solution •nsteps : int Maximum number of (internally defined) steps allowed during one call to the solver. •first_step : float •max_step : float •safety : float Safety factor on new step selection (default 0.9) •ifactor : float •dfactor : float Maximum factor to increase/decrease step size by in one step •beta : float Beta parameter for stabilised step size control. •verbosity : int Switch for printing messages (< 0 for no messages). “dop853” This is an explicit runge-kutta method of order 8(5,3) due to Dormand & Prince (with stepsize control and dense output). Options and references the same as “dopri5”. References [HNW93] Examples A problem to integrate and the corresponding jacobian: >>> >>> >>> >>> >>> >>> >>> >>> from scipy.integrate import ode y0, t0 = [1.0j, 2.0], 0 def f(t, y, arg1): return [1j*arg1*y[0] + y[1], -arg1*y[1]**2] def jac(t, y, arg1): return [[1j*arg1, 1], [0, -arg1*2*y[1]]] The integration: 270 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 >>> >>> >>> >>> >>> >>> >>> r = ode(f, jac).set_integrator(’zvode’, method=’bdf’, with_jacobian=True) r.set_initial_value(y0, t0).set_f_params(2.0).set_jac_params(2.0) t1 = 10 dt = 1 while r.successful() and r.t < t1: r.integrate(r.t+dt) print("%g %g" % (r.t, r.y)) Attributes t y (float) Current time. (ndarray) Current variable values. Methods integrate(t[, step, relax]) set_f_params(*args) set_initial_value(y[, t]) set_integrator(name, **integrator_params) set_jac_params(*args) set_solout(solout) successful() Find y=y(t), set y as an initial condition, and return y. Set extra parameters for user-supplied function f. Set initial conditions y(t) = y. Set integrator by name. Set extra parameters for user-supplied function jac. Set callable to be called at every successful integration step. Check if integration was successful. ode.integrate(t, step=0, relax=0) Find y=y(t), set y as an initial condition, and return y. ode.set_f_params(*args) Set extra parameters for user-supplied function f. ode.set_initial_value(y, t=0.0) Set initial conditions y(t) = y. ode.set_integrator(name, **integrator_params) Set integrator by name. Parameters name : str Name of the integrator. integrator_params : Additional parameters for the integrator. ode.set_jac_params(*args) Set extra parameters for user-supplied function jac. ode.set_solout(solout) Set callable to be called at every successful integration step. Parameters solout : callable solout(t, y) is called at each internal integrator step, t is a scalar providing the current independent position y is the current soloution y.shape == (n,) solout should return -1 to stop integration otherwise it should return None or 0 ode.successful() Check if integration was successful. class scipy.integrate.complex_ode(f, jac=None) A wrapper of ode for complex systems. 5.6. Integration and ODEs (scipy.integrate) 271 SciPy Reference Guide, Release 0.13.0 This functions similarly as ode, but re-maps a complex-valued equation system to a real-valued one before using the integrators. Parameters f : callable f(t, y, *f_args) Rhs of the equation. t is a scalar, y.shape == (n,). f_args is set by calling set_f_params(*args). jac : callable jac(t, y, *jac_args) Jacobian of the rhs, jac[i,j] = d f[i] / d y[j]. jac_args is set by calling set_f_params(*args). Examples For usage examples, see ode. Attributes t y (float) Current time. (ndarray) Current variable values. Methods integrate(t[, step, relax]) set_f_params(*args) set_initial_value(y[, t]) set_integrator(name, **integrator_params) set_jac_params(*args) set_solout(solout) successful() Find y=y(t), set y as an initial condition, and return y. Set extra parameters for user-supplied function f. Set initial conditions y(t) = y. Set integrator by name. Set extra parameters for user-supplied function jac. Set callable to be called at every successful integration step. Check if integration was successful. complex_ode.integrate(t, step=0, relax=0) Find y=y(t), set y as an initial condition, and return y. complex_ode.set_f_params(*args) Set extra parameters for user-supplied function f. complex_ode.set_initial_value(y, t=0.0) Set initial conditions y(t) = y. complex_ode.set_integrator(name, **integrator_params) Set integrator by name. Parameters name : str Name of the integrator integrator_params : Additional parameters for the integrator. complex_ode.set_jac_params(*args) Set extra parameters for user-supplied function jac. complex_ode.set_solout(solout) Set callable to be called at every successful integration step. Parameters solout : callable solout(t, y) is called at each internal integrator step, t is a scalar providing the current independent position y is the current soloution y.shape == (n,) solout should return -1 to stop integration otherwise it should return None or 0 complex_ode.successful() Check if integration was successful. 272 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 5.7 Interpolation (scipy.interpolate) Sub-package for objects used in interpolation. As listed below, this sub-package contains spline functions and classes, one-dimensional and multi-dimensional (univariate and multivariate) interpolation classes, Lagrange and Taylor polynomial interpolators, and wrappers for FITPACK and DFITPACK functions. 5.7.1 Univariate interpolation interp1d(x, y[, kind, axis, copy, ...]) BarycentricInterpolator(xi[, yi, axis]) KroghInterpolator(xi, yi[, axis]) PiecewisePolynomial(xi, yi[, orders, ...]) PchipInterpolator(x, y[, axis]) barycentric_interpolate(xi, yi, x[, axis]) krogh_interpolate(xi, yi, x[, der, axis]) piecewise_polynomial_interpolate(xi, yi, x) pchip_interpolate(xi, yi, x[, der, axis]) Interpolate a 1-D function. The interpolating polynomial for a set of points Interpolating polynomial for a set of points. Piecewise polynomial curve specified by points and derivatives PCHIP 1-d monotonic cubic interpolation Convenience function for polynomial interpolation. Convenience function for polynomial interpolation. Convenience function for piecewise polynomial interpolation. Convenience function for pchip interpolation. class scipy.interpolate.interp1d(x, y, kind=’linear’, axis=-1, copy=True, bounds_error=True, fill_value=np.nan) Interpolate a 1-D function. x and y are arrays of values used to approximate some function f: y = f(x). This class returns a function whose call method uses interpolation to find the value of new points. Parameters x : (N,) array_like A 1-D array of monotonically increasing real values. y : (...,N,...) array_like A N-D array of real values. The length of y along the interpolation axis must be equal to the length of x. kind : str or int, optional Specifies the kind of interpolation as a string (‘linear’, ‘nearest’, ‘zero’, ‘slinear’, ‘quadratic, ‘cubic’ where ‘slinear’, ‘quadratic’ and ‘cubic’ refer to a spline interpolation of first, second or third order) or as an integer specifying the order of the spline interpolator to use. Default is ‘linear’. axis : int, optional Specifies the axis of y along which to interpolate. Interpolation defaults to the last axis of y. copy : bool, optional If True, the class makes internal copies of x and y. If False, references to x and y are used. The default is to copy. bounds_error : bool, optional If True, a ValueError is raised any time interpolation is attempted on a value outside of the range of x (where extrapolation is necessary). If False, out of bounds values are assigned fill_value. By default, an error is raised. fill_value : float, optional If provided, then this value will be used to fill in for requested points outside of the data range. If not provided, then the default is NaN. 5.7. Interpolation (scipy.interpolate) 273 SciPy Reference Guide, Release 0.13.0 See Also UnivariateSpline A more recent wrapper of the FITPACK routines. splrep, splev, interp2d Examples >>> >>> >>> >>> from scipy import interpolate x = np.arange(0, 10) y = np.exp(-x/3.0) f = interpolate.interp1d(x, y) >>> >>> >>> >>> xnew = np.arange(0,9, 0.1) ynew = f(xnew) # use interpolation function returned by ‘interp1d‘ plt.plot(x, y, ’o’, xnew, ynew, ’-’) plt.show() Methods __call__(x) Evaluate the interpolant interp1d.__call__(x) Evaluate the interpolant Parameters Returns x : array-like Points to evaluate the interpolant at. y : array-like Interpolated values. Shape is determined by replacing the interpolation axis in the original array with the shape of x. class scipy.interpolate.BarycentricInterpolator(xi, yi=None, axis=0) The interpolating polynomial for a set of points Constructs a polynomial that passes through a given set of points. Allows evaluation of the polynomial, efficient changing of the y values to be interpolated, and updating by adding more x values. For reasons of numerical stability, this function does not compute the coefficients of the polynomial. The values yi need to be provided before the function is evaluated, but none of the preprocessing depends on them, so rapid updates are possible. Parameters xi : array-like 1-d array of x coordinates of the points the polynomial should pass through yi : array-like The y coordinates of the points the polynomial should pass through. If None, the y values will be supplied later via the set_y method. axis : int, optional Axis in the yi array corresponding to the x-coordinate values. Notes This class uses a “barycentric interpolation” method that treats the problem as a special case of rational function interpolation. This algorithm is quite stable, numerically, but even in a world of exact computation, unless the x coordinates are chosen very carefully - Chebyshev zeros (e.g. cos(i*pi/n)) are a good choice - polynomial interpolation itself is a very ill-conditioned process due to the Runge phenomenon. Based on Berrut and Trefethen 2004, “Barycentric Lagrange Interpolation”. 274 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Methods __call__(x) add_xi(xi[, yi]) set_yi(yi[, axis]) Evaluate the interpolating polynomial at the points x Add more x values to the set to be interpolated Update the y values to be interpolated BarycentricInterpolator.__call__(x) Evaluate the interpolating polynomial at the points x Parameters Returns x : array-like Points to evaluate the interpolant at. y : array-like Interpolated values. Shape is determined by replacing the interpolation axis in the original array with the shape of x. Notes Currently the code computes an outer product between x and the weights, that is, it constructs an intermediate array of size N by len(x), where N is the degree of the polynomial. BarycentricInterpolator.add_xi(xi, yi=None) Add more x values to the set to be interpolated The barycentric interpolation algorithm allows easy updating by adding more points for the polynomial to pass through. Parameters xi : array_like The x coordinates of the points that the polynomial should pass through. yi : array_like, optional The y coordinates of the points the polynomial should pass through. Should have shape (xi.size, R); if R > 1 then the polynomial is vector-valued. If yi is not given, the y values will be supplied later. yi should be given if and only if the interpolator has y values specified. BarycentricInterpolator.set_yi(yi, axis=None) Update the y values to be interpolated The barycentric interpolation algorithm requires the calculation of weights, but these depend only on the xi. The yi can be changed at any time. Parameters yi : array_like The y coordinates of the points the polynomial should pass through. If None, the y values will be supplied later. axis : int, optional Axis in the yi array corresponding to the x-coordinate values. class scipy.interpolate.KroghInterpolator(xi, yi, axis=0) Interpolating polynomial for a set of points. The polynomial passes through all the pairs (xi,yi). One may additionally specify a number of derivatives at each point xi; this is done by repeating the value xi and specifying the derivatives as successive yi values. Allows evaluation of the polynomial and all its derivatives. For reasons of numerical stability, this function does not compute the coefficients of the polynomial, although they can be obtained by evaluating all the derivatives. Parameters xi : array-like, length N Known x-coordinates. Must be sorted in increasing order. yi : array-like 5.7. Interpolation (scipy.interpolate) 275 SciPy Reference Guide, Release 0.13.0 Known y-coordinates. When an xi occurs two or more times in a row, the corresponding yi’s represent derivative values. axis : int, optional Axis in the yi array corresponding to the x-coordinate values. Notes Be aware that the algorithms implemented here are not necessarily the most numerically stable known. Moreover, even in a world of exact computation, unless the x coordinates are chosen very carefully - Chebyshev zeros (e.g. cos(i*pi/n)) are a good choice - polynomial interpolation itself is a very ill-conditioned process due to the Runge phenomenon. In general, even with well-chosen x values, degrees higher than about thirty cause problems with numerical instability in this code. Based on [R33]. References [R33] Examples To produce a polynomial that is zero at 0 and 1 and has derivative 2 at 0, call >>> KroghInterpolator([0,0,1],[0,2,0]) This constructs the quadratic 2*X**2-2*X. The derivative condition is indicated by the repeated zero in the xi array; the corresponding yi values are 0, the function value, and 2, the derivative value. For another example, given xi, yi, and a derivative ypi for each point, appropriate arrays can be constructed as: >>> xi_k, yi_k = np.repeat(xi, 2), np.ravel(np.dstack((yi,ypi))) >>> KroghInterpolator(xi_k, yi_k) To produce a vector-valued polynomial, supply a higher-dimensional array for yi: >>> KroghInterpolator([0,1],[[2,3],[4,5]]) This constructs a linear polynomial giving (2,3) at 0 and (4,5) at 1. Methods __call__(x) derivative(x[, der]) derivatives(x[, der]) Evaluate the interpolant Evaluate one derivative of the polynomial at the point x Evaluate many derivatives of the polynomial at the point x KroghInterpolator.__call__(x) Evaluate the interpolant Parameters Returns x : array-like Points to evaluate the interpolant at. y : array-like Interpolated values. Shape is determined by replacing the interpolation axis in the original array with the shape of x. KroghInterpolator.derivative(x, der=1) Evaluate one derivative of the polynomial at the point x Parameters 276 x : array-like Point or points at which to evaluate the derivatives Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 der : integer, optional Which derivative to extract. This number includes the function value as 0th derivative. d : ndarray Derivative interpolated at the x-points. Shape of d is determined by replacing the interpolation axis in the original array with the shape of x. Returns Notes This is computed by evaluating all derivatives up to the desired one (using self.derivatives()) and then discarding the rest. KroghInterpolator.derivatives(x, der=None) Evaluate many derivatives of the polynomial at the point x Produce an array of all derivative values at the point x. Parameters Returns x : array-like Point or points at which to evaluate the derivatives der : None or integer How many derivatives to extract; None for all potentially nonzero derivatives (that is a number equal to the number of points). This number includes the function value as 0th derivative. d : ndarray Array with derivatives; d[j] contains the j-th derivative. Shape of d[j] is determined by replacing the interpolation axis in the original array with the shape of x. Examples >>> KroghInterpolator([0,0,0],[1,2,3]).derivatives(0) array([1.0,2.0,3.0]) >>> KroghInterpolator([0,0,0],[1,2,3]).derivatives([0,0]) array([[1.0,1.0], [2.0,2.0], [3.0,3.0]]) class scipy.interpolate.PiecewisePolynomial(xi, yi, orders=None, direction=None, axis=0) Piecewise polynomial curve specified by points and derivatives This class represents a curve that is a piecewise polynomial. It passes through a list of points and has specified derivatives at each point. The degree of the polynomial may vary from segment to segment, as may the number of derivatives available. The degree should not exceed about thirty. Appending points to the end of the curve is efficient. Parameters xi : array-like a sorted 1-d array of x-coordinates yi : array-like or list of array-likes yi[i][j] is the j-th derivative known at xi[i] (for axis=0) orders : list of integers, or integer a list of polynomial orders, or a single universal order direction : {None, 1, -1} indicates whether the xi are increasing or decreasing +1 indicates increasing -1 indicates decreasing None indicates that it should be deduced from the first two xi axis : int, optional Axis in the yi array corresponding to the x-coordinate values. 5.7. Interpolation (scipy.interpolate) 277 SciPy Reference Guide, Release 0.13.0 Notes If orders is None, or orders[i] is None, then the degree of the polynomial segment is exactly the degree required to match all i available derivatives at both endpoints. If orders[i] is not None, then some derivatives will be ignored. The code will try to use an equal number of derivatives from each end; if the total number of derivatives needed is odd, it will prefer the rightmost endpoint. If not enough derivatives are available, an exception is raised. Methods __call__(x) append(xi, yi[, order]) derivative(x[, der]) derivatives(x[, der]) extend(xi, yi[, orders]) Evaluate the interpolant Append a single point with derivatives to the PiecewisePolynomial Evaluate one derivative of the polynomial at the point x Evaluate many derivatives of the polynomial at the point x Extend the PiecewisePolynomial by a list of points PiecewisePolynomial.__call__(x) Evaluate the interpolant Parameters Returns x : array-like Points to evaluate the interpolant at. y : array-like Interpolated values. Shape is determined by replacing the interpolation axis in the original array with the shape of x. PiecewisePolynomial.append(xi, yi, order=None) Append a single point with derivatives to the PiecewisePolynomial Parameters xi : float Input yi : array_like yi is the list of derivatives known at xi order : integer or None a polynomial order, or instructions to use the highest possible order PiecewisePolynomial.derivative(x, der=1) Evaluate one derivative of the polynomial at the point x Parameters Returns x : array-like Point or points at which to evaluate the derivatives der : integer, optional Which derivative to extract. This number includes the function value as 0th derivative. d : ndarray Derivative interpolated at the x-points. Shape of d is determined by replacing the interpolation axis in the original array with the shape of x. Notes This is computed by evaluating all derivatives up to the desired one (using self.derivatives()) and then discarding the rest. PiecewisePolynomial.derivatives(x, der=None) Evaluate many derivatives of the polynomial at the point x Produce an array of all derivative values at the point x. Parameters 278 x : array-like Point or points at which to evaluate the derivatives Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 der : None or integer How many derivatives to extract; None for all potentially nonzero derivatives (that is a number equal to the number of points). This number includes the function value as 0th derivative. d : ndarray Array with derivatives; d[j] contains the j-th derivative. Shape of d[j] is determined by replacing the interpolation axis in the original array with the shape of x. Returns Examples >>> KroghInterpolator([0,0,0],[1,2,3]).derivatives(0) array([1.0,2.0,3.0]) >>> KroghInterpolator([0,0,0],[1,2,3]).derivatives([0,0]) array([[1.0,1.0], [2.0,2.0], [3.0,3.0]]) PiecewisePolynomial.extend(xi, yi, orders=None) Extend the PiecewisePolynomial by a list of points Parameters xi : array_like A sorted list of x-coordinates. yi : list of lists of length N1 yi[i] (if axis == 0) is the list of derivatives known at xi[i]. orders : int or list of ints A list of polynomial orders, or a single universal order. direction : {None, 1, -1} Indicates whether the xi are increasing or decreasing. +1 indicates increasing -1 indicates decreasing None indicates that it should be deduced from the first two xi. class scipy.interpolate.PchipInterpolator(x, y, axis=0) PCHIP 1-d monotonic cubic interpolation x and y are arrays of values used to approximate some function f, with y = f(x). The interpolant uses monotonic cubic splines to find the value of new points. Parameters x : ndarray A 1-D array of monotonically increasing real values. x cannot include duplicate values (otherwise f is overspecified) y : ndarray A 1-D array of real values. y‘s length along the interpolation axis must be equal to the length of x. axis : int, optional Axis in the yi array corresponding to the x-coordinate values. Notes Assumes x is sorted in monotonic order (e.g. x[1] > x[0]). Methods __call__(x) append(xi, yi[, order]) Evaluate the interpolant Append a single point with derivatives to the PiecewisePolynomial Continued on next page 5.7. Interpolation (scipy.interpolate) 279 SciPy Reference Guide, Release 0.13.0 Table 5.29 – continued from previous page derivative(x[, der]) Evaluate one derivative of the polynomial at the point x derivatives(x[, der]) Evaluate many derivatives of the polynomial at the point x extend(xi, yi[, orders]) Extend the PiecewisePolynomial by a list of points PchipInterpolator.__call__(x) Evaluate the interpolant Parameters Returns x : array-like Points to evaluate the interpolant at. y : array-like Interpolated values. Shape is determined by replacing the interpolation axis in the original array with the shape of x. PchipInterpolator.append(xi, yi, order=None) Append a single point with derivatives to the PiecewisePolynomial Parameters xi : float Input yi : array_like yi is the list of derivatives known at xi order : integer or None a polynomial order, or instructions to use the highest possible order PchipInterpolator.derivative(x, der=1) Evaluate one derivative of the polynomial at the point x Parameters Returns x : array-like Point or points at which to evaluate the derivatives der : integer, optional Which derivative to extract. This number includes the function value as 0th derivative. d : ndarray Derivative interpolated at the x-points. Shape of d is determined by replacing the interpolation axis in the original array with the shape of x. Notes This is computed by evaluating all derivatives up to the desired one (using self.derivatives()) and then discarding the rest. PchipInterpolator.derivatives(x, der=None) Evaluate many derivatives of the polynomial at the point x Produce an array of all derivative values at the point x. Parameters Returns 280 x : array-like Point or points at which to evaluate the derivatives der : None or integer How many derivatives to extract; None for all potentially nonzero derivatives (that is a number equal to the number of points). This number includes the function value as 0th derivative. d : ndarray Array with derivatives; d[j] contains the j-th derivative. Shape of d[j] is determined by replacing the interpolation axis in the original array with the shape of x. Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Examples >>> KroghInterpolator([0,0,0],[1,2,3]).derivatives(0) array([1.0,2.0,3.0]) >>> KroghInterpolator([0,0,0],[1,2,3]).derivatives([0,0]) array([[1.0,1.0], [2.0,2.0], [3.0,3.0]]) PchipInterpolator.extend(xi, yi, orders=None) Extend the PiecewisePolynomial by a list of points Parameters xi : array_like A sorted list of x-coordinates. yi : list of lists of length N1 yi[i] (if axis == 0) is the list of derivatives known at xi[i]. orders : int or list of ints A list of polynomial orders, or a single universal order. direction : {None, 1, -1} Indicates whether the xi are increasing or decreasing. +1 indicates increasing -1 indicates decreasing None indicates that it should be deduced from the first two xi. scipy.interpolate.barycentric_interpolate(xi, yi, x, axis=0) Convenience function for polynomial interpolation. Constructs a polynomial that passes through a given set of points, then evaluates the polynomial. For reasons of numerical stability, this function does not compute the coefficients of the polynomial. This function uses a “barycentric interpolation” method that treats the problem as a special case of rational function interpolation. This algorithm is quite stable, numerically, but even in a world of exact computation, unless the x coordinates are chosen very carefully - Chebyshev zeros (e.g. cos(i*pi/n)) are a good choice polynomial interpolation itself is a very ill-conditioned process due to the Runge phenomenon. Parameters Returns xi : array_like 1-d array of x coordinates of the points the polynomial should pass through yi : array_like The y coordinates of the points the polynomial should pass through. x : scalar or array_like Points to evaluate the interpolator at. axis : int, optional Axis in the yi array corresponding to the x-coordinate values. y : scalar or array_like Interpolated values. Shape is determined by replacing the interpolation axis in the original array with the shape of x. See Also BarycentricInterpolator Notes Construction of the interpolation weights is a relatively slow process. If you want to call this many times with the same xi (but possibly varying yi or x) you should use the class BarycentricInterpolator. This is what this function uses internally. scipy.interpolate.krogh_interpolate(xi, yi, x, der=0, axis=0) Convenience function for polynomial interpolation. 5.7. Interpolation (scipy.interpolate) 281 SciPy Reference Guide, Release 0.13.0 See KroghInterpolator for more details. Parameters Returns xi : array_like Known x-coordinates. yi : array_like Known y-coordinates, of shape (xi.size, R). Interpreted as vectors of length R, or scalars if R=1. x : array_like Point or points at which to evaluate the derivatives. der : int or list How many derivatives to extract; None for all potentially nonzero derivatives (that is a number equal to the number of points), or a list of derivatives to extract. This number includes the function value as 0th derivative. axis : int, optional Axis in the yi array corresponding to the x-coordinate values. d : ndarray If the interpolator’s values are R-dimensional then the returned array will be the number of derivatives by N by R. If x is a scalar, the middle dimension will be dropped; if the yi are scalars then the last dimension will be dropped. See Also KroghInterpolator Notes Construction of the interpolating polynomial is a relatively expensive process. If you want to evaluate it repeatedly consider using the class KroghInterpolator (which is what this function uses). scipy.interpolate.piecewise_polynomial_interpolate(xi, yi, x, orders=None, der=0, axis=0) Convenience function for piecewise polynomial interpolation. Parameters Returns xi : array_like A sorted list of x-coordinates. yi : list of lists yi[i] is the list of derivatives known at xi[i]. x : scalar or array_like Coordinates at which to evalualte the polynomial. orders : int or list of ints, optional A list of polynomial orders, or a single universal order. der : int or list How many derivatives to extract; None for all potentially nonzero derivatives (that is a number equal to the number of points), or a list of derivatives to extract. This number includes the function value as 0th derivative. axis : int, optional Axis in the yi array corresponding to the x-coordinate values. y : ndarray Interpolated values or derivatives. If multiple derivatives were requested, these are given along the first axis. See Also PiecewisePolynomial 282 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Notes If orders is None, or orders[i] is None, then the degree of the polynomial segment is exactly the degree required to match all i available derivatives at both endpoints. If orders[i] is not None, then some derivatives will be ignored. The code will try to use an equal number of derivatives from each end; if the total number of derivatives needed is odd, it will prefer the rightmost endpoint. If not enough derivatives are available, an exception is raised. Construction of these piecewise polynomials can be an expensive process; if you repeatedly evaluate the same polynomial, consider using the class PiecewisePolynomial (which is what this function does). scipy.interpolate.pchip_interpolate(xi, yi, x, der=0, axis=0) Convenience function for pchip interpolation. See PchipInterpolator for details. Parameters Returns xi : array_like A sorted list of x-coordinates, of length N. yi : list of lists yi[i] is the list of derivatives known at xi[i]. Of length N. x : scalar or array_like Of length M. der : integer or list How many derivatives to extract; None for all potentially nonzero derivatives (that is a number equal to the number of points), or a list of derivatives to extract. This number includes the function value as 0th derivative. axis : int, optional Axis in the yi array corresponding to the x-coordinate values. y : scalar or array_like The result, of length R or length M or M by R, See Also PchipInterpolator 5.7.2 Multivariate interpolation Unstructured data: griddata(points, values, xi[, method, ...]) LinearNDInterpolator(points, values[, ...]) NearestNDInterpolator(points, values) CloughTocher2DInterpolator(points, values[, tol]) Rbf(*args) interp2d(x, y, z[, kind, copy, ...]) Interpolate unstructured N-dimensional data. Piecewise linear interpolant in N dimensions. Nearest-neighbour interpolation in N dimensions. Piecewise cubic, C1 smooth, curvature-minimizing interpolant in 2D. A class for radial basis function approximation/interpolation of n-dimen Interpolate over a 2-D grid. scipy.interpolate.griddata(points, values, xi, method=’linear’, fill_value=nan) Interpolate unstructured N-dimensional data. New in version 0.9. Parameters points : ndarray of floats, shape (N, ndim) Data point coordinates. Can either be an array of size (N, ndim), or a tuple of ndim arrays. values : ndarray of float or complex, shape (N,) Data values. xi : ndarray of float, shape (M, ndim) Points at which to interpolate data. 5.7. Interpolation (scipy.interpolate) 283 SciPy Reference Guide, Release 0.13.0 method : {‘linear’, ‘nearest’, ‘cubic’}, optional Method of interpolation. One of nearest return the value at the data point closest to the point of interpolation. See NearestNDInterpolator for more details. linear tesselate the input point set to n-dimensional simplices, and interpolate linearly on each simplex. See LinearNDInterpolator for more details. cubic (1-D) return the value determined from a cubic spline. cubic (2-D) return the value determined from a piecewise cubic, continuously differentiable (C1), and approximately curvature-minimizing polynomial surface. See CloughTocher2DInterpolator for more details. fill_value : float, optional Value used to fill in for requested points outside of the convex hull of the input points. If not provided, then the default is nan. This option has no effect for the ‘nearest’ method. Examples Suppose we want to interpolate the 2-D function >>> def func(x, y): >>> return x*(1-x)*np.cos(4*np.pi*x) * np.sin(4*np.pi*y**2)**2 on a grid in [0, 1]x[0, 1] >>> grid_x, grid_y = np.mgrid[0:1:100j, 0:1:200j] but we only know its values at 1000 data points: >>> points = np.random.rand(1000, 2) >>> values = func(points[:,0], points[:,1]) This can be done with griddata – below we try out all of the interpolation methods: >>> >>> >>> >>> from scipy.interpolate import griddata grid_z0 = griddata(points, values, (grid_x, grid_y), method=’nearest’) grid_z1 = griddata(points, values, (grid_x, grid_y), method=’linear’) grid_z2 = griddata(points, values, (grid_x, grid_y), method=’cubic’) One can see that the exact result is reproduced by all of the methods to some degree, but for this smooth function the piecewise cubic interpolant gives the best results: >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> 284 import matplotlib.pyplot as plt plt.subplot(221) plt.imshow(func(grid_x, grid_y).T, extent=(0,1,0,1), origin=’lower’) plt.plot(points[:,0], points[:,1], ’k.’, ms=1) plt.title(’Original’) plt.subplot(222) plt.imshow(grid_z0.T, extent=(0,1,0,1), origin=’lower’) plt.title(’Nearest’) plt.subplot(223) plt.imshow(grid_z1.T, extent=(0,1,0,1), origin=’lower’) plt.title(’Linear’) plt.subplot(224) plt.imshow(grid_z2.T, extent=(0,1,0,1), origin=’lower’) plt.title(’Cubic’) plt.gcf().set_size_inches(6, 6) plt.show() Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 1.0 Original 1.0 Nearest 0.8 0.8 0.6 0.6 0.4 0.4 0.2 0.2 0.00.0 0.2 0.4 0.6 0.8 1.0 Linear 1.0 0.00.0 0.2 0.4 0.6 0.8 1.0 Cubic 1.0 0.8 0.8 0.6 0.6 0.4 0.4 0.2 0.2 0.00.0 0.2 0.4 0.6 0.8 1.0 0.00.0 0.2 0.4 0.6 0.8 1.0 class scipy.interpolate.LinearNDInterpolator(points, values, fill_value=np.nan) Piecewise linear interpolant in N dimensions. New in version 0.9. Parameters points : ndarray of floats, shape (npoints, ndims); or Delaunay Data point coordinates, or a precomputed Delaunay triangulation. values : ndarray of float or complex, shape (npoints, ...) Data values. fill_value : float, optional Value used to fill in for requested points outside of the convex hull of the input points. If not provided, then the default is nan. Notes The interpolant is constructed by triangulating the input data with Qhull [R34], and on each triangle performing linear barycentric interpolation. References [R34] 5.7. Interpolation (scipy.interpolate) 285 SciPy Reference Guide, Release 0.13.0 Methods __call__(xi) Evaluate interpolator at given points. LinearNDInterpolator.__call__(xi) Evaluate interpolator at given points. Parameters xi : ndarray of float, shape (..., ndim) Points where to interpolate data at. class scipy.interpolate.NearestNDInterpolator(points, values) Nearest-neighbour interpolation in N dimensions. New in version 0.9. Parameters points : (Npoints, Ndims) ndarray of floats Data point coordinates. values : (Npoints,) ndarray of float or complex Data values. Notes Uses scipy.spatial.cKDTree Methods __call__(*args) Evaluate interpolator at given points. NearestNDInterpolator.__call__(*args) Evaluate interpolator at given points. Parameters xi : ndarray of float, shape (..., ndim) Points where to interpolate data at. class scipy.interpolate.CloughTocher2DInterpolator(points, values, tol=1e-6) Piecewise cubic, C1 smooth, curvature-minimizing interpolant in 2D. New in version 0.9. Parameters points : ndarray of floats, shape (npoints, ndims); or Delaunay Data point coordinates, or a precomputed Delaunay triangulation. values : ndarray of float or complex, shape (npoints, ...) Data values. fill_value : float, optional Value used to fill in for requested points outside of the convex hull of the input points. If not provided, then the default is nan. tol : float, optional Absolute/relative tolerance for gradient estimation. maxiter : int, optional Maximum number of iterations in gradient estimation. Notes The interpolant is constructed by triangulating the input data with Qhull [R32], and constructing a piecewise cubic interpolating Bezier polynomial on each triangle, using a Clough-Tocher scheme [CT]. The interpolant is guaranteed to be continuously differentiable. The gradients of the interpolant are chosen so that the curvature of the interpolating surface is approximatively minimized. The gradients necessary for this are estimated using the global algorithm described in [Nielson83,Renka84]_. 286 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 References [R32], [CT], [Nielson83], [Renka84] Methods __call__(xi) Evaluate interpolator at given points. CloughTocher2DInterpolator.__call__(xi) Evaluate interpolator at given points. Parameters xi : ndarray of float, shape (..., ndim) Points where to interpolate data at. class scipy.interpolate.Rbf(*args) A class for radial basis function approximation/interpolation of n-dimensional scattered data. Parameters *args : arrays x, y, z, ..., d, where x, y, z, ... are the coordinates of the nodes and d is the array of values at the nodes function : str or callable, optional The radial basis function, based on the radius, r, given by the norm (default is Euclidean distance); the default is ‘multiquadric’: ’multiquadric’: sqrt((r/self.epsilon)**2 + 1) ’inverse’: 1.0/sqrt((r/self.epsilon)**2 + 1) ’gaussian’: exp(-(r/self.epsilon)**2) ’linear’: r ’cubic’: r**3 ’quintic’: r**5 ’thin_plate’: r**2 * log(r) If callable, then it must take 2 arguments (self, r). The epsilon parameter will be available as self.epsilon. Other keyword arguments passed in will be available as well. epsilon : float, optional Adjustable constant for gaussian or multiquadrics functions - defaults to approximate average distance between nodes (which is a good start). smooth : float, optional Values greater than zero increase the smoothness of the approximation. 0 is for interpolation (default), the function will always go through the nodal points in this case. norm : callable, optional A function that returns the ‘distance’ between two points, with inputs as arrays of positions (x, y, z, ...), and an output as an array of distance. E.g, the default: def euclidean_norm(x1, x2): return sqrt( ((x1 - x2)**2).sum(axis=0) ) which is called with x1=x1[ndims,newaxis,:] and x2=x2[ndims,:,newaxis] such that the result is a matrix of the distances from each point in x1 to each point in x2. Examples >>> rbfi = Rbf(x, y, z, d) >>> di = rbfi(xi, yi, zi) # radial basis function interpolator instance # interpolated values Methods 5.7. Interpolation (scipy.interpolate) 287 SciPy Reference Guide, Release 0.13.0 __call__(*args) Rbf.__call__(*args) class scipy.interpolate.interp2d(x, y, z, kind=’linear’, fill_value=nan) Interpolate over a 2-D grid. copy=True, bounds_error=False, x, y and z are arrays of values used to approximate some function f: z = f(x, y). This class returns a function whose call method uses spline interpolation to find the value of new points. If x and y represent a regular grid, consider using RectBivariateSpline. Parameters x, y : array_like Arrays defining the data point coordinates. If the points lie on a regular grid, x can specify the column coordinates and y the row coordinates, for example: >>> x = [0,1,2]; y = [0,3]; z = [[1,2,3], [4,5,6]] Otherwise, x and y must specify the full coordinates for each point, for example: >>> x = [0,1,2,0,1,2]; y = [0,0,0,3,3,3]; z = [1,2,3,4,5,6] If x and y are multi-dimensional, they are flattened before use. z : array_like The values of the function to interpolate at the data points. If z is a multi-dimensional array, it is flattened before use. The length of a flattened z array is either len(x)*len(y) if x and y specify the column and row coordinates or len(z) == len(x) == len(y) if x and y specify coordinates for each point. kind : {‘linear’, ‘cubic’, ‘quintic’}, optional The kind of spline interpolation to use. Default is ‘linear’. copy : bool, optional If True, the class makes internal copies of x, y and z. If False, references may be used. The default is to copy. bounds_error : bool, optional If True, when interpolated values are requested outside of the domain of the input data (x,y), a ValueError is raised. If False, then fill_value is used. fill_value : number, optional If provided, the value to use for points outside of the interpolation domain. If omitted (None), values outside the domain are extrapolated. See Also RectBivariateSpline Much faster 2D interpolation if your input data is on a grid bisplrep, bisplev BivariateSpline a more recent wrapper of the FITPACK routines interp1d 288 one dimension version of this function Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Notes The minimum number of data points required along the interpolation axis is (k+1)**2, with k=1 for linear, k=3 for cubic and k=5 for quintic interpolation. The interpolator is constructed by bisplrep, with a smoothing factor of 0. If more control over smoothing is needed, bisplrep should be used directly. Examples Construct a 2-D grid and interpolate on it: >>> >>> >>> >>> >>> >>> from scipy import interpolate x = np.arange(-5.01, 5.01, 0.25) y = np.arange(-5.01, 5.01, 0.25) xx, yy = np.meshgrid(x, y) z = np.sin(xx**2+yy**2) f = interpolate.interp2d(x, y, z, kind=’cubic’) Now use the obtained interpolation function and plot the result: >>> >>> >>> >>> >>> xnew = np.arange(-5.01, 5.01, 1e-2) ynew = np.arange(-5.01, 5.01, 1e-2) znew = f(xnew, ynew) plt.plot(x, z[:, 0], ’ro-’, xnew, znew[:, 0], ’b-’) plt.show() Methods __call__(x, y[, dx, dy]) Interpolate the function. interp2d.__call__(x, y, dx=0, dy=0) Interpolate the function. Parameters Returns x : 1D array x-coordinates of the mesh on which to interpolate. y : 1D array y-coordinates of the mesh on which to interpolate. dx : int >= 0, < kx Order of partial derivatives in x. dy : int >= 0, < ky Order of partial derivatives in y. z : 2D array with shape (len(y), len(x)) The interpolated values. For data on a grid: RectBivariateSpline(x, y, z[, bbox, kx, ky, s]) Bivariate spline approximation over a rectangular mesh. See Also scipy.ndimage.map_coordinates 5.7.3 1-D Splines 5.7. Interpolation (scipy.interpolate) 289 SciPy Reference Guide, Release 0.13.0 UnivariateSpline(x, y[, w, bbox, k, s]) InterpolatedUnivariateSpline(x, y[, w, bbox, k]) LSQUnivariateSpline(x, y, t[, w, bbox, k]) One-dimensional smoothing spline fit to a given set of data points. One-dimensional interpolating spline for a given set of data points. One-dimensional spline with explicit internal knots. class scipy.interpolate.UnivariateSpline(x, y, w=None, bbox=[None, None], k=3, s=None) One-dimensional smoothing spline fit to a given set of data points. Fits a spline y=s(x) of degree k to the provided x, y data. s specifies the number of knots by specifying a smoothing condition. Parameters x : (N,) array_like 1-D array of independent input data. Must be increasing. y : (N,) array_like 1-D array of dependent input data, of the same length as x. w : (N,) array_like, optional Weights for spline fitting. Must be positive. If None (default), weights are all equal. bbox : (2,) array_like, optional 2-sequence specifying the boundary of the approximation interval. If None (default), bbox=[x[0], x[-1]]. k : int, optional Degree of the smoothing spline. Must be <= 5. s : float or None, optional Positive smoothing factor used to choose the number of knots. Number of knots will be increased until the smoothing condition is satisfied: sum((w[i]*(y[i]-s(x[i])))**2,axis=0) <= s If None (default), s=len(w) which should be a good value if 1/w[i] is an estimate of the standard deviation of y[i]. If 0, spline will interpolate through all data points. See Also InterpolatedUnivariateSpline Subclass with smoothing forced to 0 LSQUnivariateSpline Subclass in which knots are user-selected instead of being set by smoothing condition splrep An older, non object-oriented wrapping of FITPACK splev, sproot, splint, spalde BivariateSpline A similar class for two-dimensional spline interpolation Notes The number of data points must be larger than the spline degree k. Examples >>> >>> >>> >>> >>> >>> >>> >>> 290 from numpy import linspace,exp from numpy.random import randn import matplotlib.pyplot as plt from scipy.interpolate import UnivariateSpline x = linspace(-3, 3, 100) y = exp(-x**2) + randn(100)/10 s = UnivariateSpline(x, y, s=1) xs = linspace(-3, 3, 1000) Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 >>> >>> >>> >>> ys = s(xs) plt.plot(x, y, ’.-’) plt.plot(xs, ys) plt.show() xs,ys is now a smoothed, super-sampled version of the noisy gaussian x,y. Methods __call__(x[, nu]) antiderivative([n]) derivative([n]) derivatives(x) get_coeffs() get_knots() get_residual() integral(a, b) roots() set_smoothing_factor(s) Evaluate spline (or its nu-th derivative) at positions x. Construct a new spline representing the antiderivative of this spline. Construct a new spline representing the derivative of this spline. Return all derivatives of the spline at the point x. Return spline coefficients. Return positions of (boundary and interior) knots of the spline. Return weighted sum of squared residuals of the spline Return definite integral of the spline between two given points. Return the zeros of the spline. Continue spline computation with the given smoothing UnivariateSpline.__call__(x, nu=0) Evaluate spline (or its nu-th derivative) at positions x. Note: x can be unordered but the evaluation is more efficient if x is (partially) ordered. UnivariateSpline.antiderivative(n=1) Construct a new spline representing the antiderivative of this spline. New in version 0.13.0. Parameters Returns n : int, optional Order of antiderivative to evaluate. Default: 1 spline : UnivariateSpline Spline of order k2=k+n representing the antiderivative of this spline. See Also splantider, derivative Examples >>> >>> >>> >>> from scipy.interpolate import UnivariateSpline x = np.linspace(0, np.pi/2, 70) y = 1 / np.sqrt(1 - 0.8*np.sin(x)**2) spl = UnivariateSpline(x, y, s=0) The derivative is the inverse operation of the antiderivative, although some floating point error accumulates: >>> spl(1.7), spl.antiderivative().derivative()(1.7) (array(2.1565429877197317), array(2.1565429877201865)) Antiderivative can be used to evaluate definite integrals: >>> ispl = spl.antiderivative() >>> ispl(np.pi/2) - ispl(0) 2.2572053588768486 This is indeed an approximation to the complete elliptic integral K(m) = 5.7. Interpolation (scipy.interpolate) R π/2 0 [1 − m sin2 x]−1/2 dx: 291 SciPy Reference Guide, Release 0.13.0 >>> from scipy.special import ellipk >>> ellipk(0.8) 2.2572053268208538 UnivariateSpline.derivative(n=1) Construct a new spline representing the derivative of this spline. New in version 0.13.0. Parameters Returns n : int, optional Order of derivative to evaluate. Default: 1 spline : UnivariateSpline Spline of order k2=k-n representing the derivative of this spline. See Also splder, antiderivative Examples This can be used for finding maxima of a curve: >>> >>> >>> >>> from scipy.interpolate import UnivariateSpline x = np.linspace(0, 10, 70) y = np.sin(x) spl = UnivariateSpline(x, y, k=4, s=0) Now, differentiate the spline and find the zeros of the derivative. (NB: sproot only works for order 3 splines, so we fit an order 4 spline): >>> spl.derivative().roots() / np.pi array([ 0.50000001, 1.5 , 2.49999998]) This agrees well with roots π/2 + nπ of cos(x) = sin’(x). UnivariateSpline.derivatives(x) Return all derivatives of the spline at the point x. UnivariateSpline.get_coeffs() Return spline coefficients. UnivariateSpline.get_knots() Return positions of (boundary and interior) knots of the spline. UnivariateSpline.get_residual() Return weighted sum of squared residuals of the spline approximation: (y[i]-s(x[i])))**2, axis=0). sum((w[i] * UnivariateSpline.integral(a, b) Return definite integral of the spline between two given points. UnivariateSpline.roots() Return the zeros of the spline. Restriction: only cubic splines are supported by fitpack. UnivariateSpline.set_smoothing_factor(s) Continue spline computation with the given smoothing factor s and with the knots found at the last call. class scipy.interpolate.InterpolatedUnivariateSpline(x, y, w=None, bbox=[None, None], k=3) One-dimensional interpolating spline for a given set of data points. Fits a spline y=s(x) of degree k to the provided x, y data. Spline function passes through all provided points. Equivalent to UnivariateSpline with s=0. 292 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Parameters x : (N,) array_like Input dimension of data points – must be increasing y : (N,) array_like input dimension of data points w : (N,) array_like, optional Weights for spline fitting. Must be positive. If None (default), weights are all equal. bbox : (2,) array_like, optional 2-sequence specifying the boundary of the approximation interval. If None (default), bbox=[x[0],x[-1]]. k : int, optional Degree of the smoothing spline. Must be 1 <= k <= 5. See Also UnivariateSpline Superclass – allows knots to be selected by a smoothing condition LSQUnivariateSpline spline for which knots are user-selected splrep An older, non object-oriented wrapping of FITPACK splev, sproot, splint, spalde BivariateSpline A similar class for two-dimensional spline interpolation Notes The number of data points must be larger than the spline degree k. Examples >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> from numpy import linspace,exp from numpy.random import randn from scipy.interpolate import InterpolatedUnivariateSpline import matplotlib.pyplot as plt x = linspace(-3, 3, 100) y = exp(-x**2) + randn(100)/10 s = InterpolatedUnivariateSpline(x, y) xs = linspace(-3, 3, 1000) ys = s(xs) plt.plot(x, y, ’.-’) plt.plot(xs, ys) plt.show() xs,ys is now a smoothed, super-sampled version of the noisy gaussian x,y Methods __call__(x[, nu]) antiderivative([n]) derivative([n]) derivatives(x) get_coeffs() get_knots() get_residual() Evaluate spline (or its nu-th derivative) at positions x. Construct a new spline representing the antiderivative of this spline. Construct a new spline representing the derivative of this spline. Return all derivatives of the spline at the point x. Return spline coefficients. Return positions of (boundary and interior) knots of the spline. Return weighted sum of squared residuals of the spline Continued on next page 5.7. Interpolation (scipy.interpolate) 293 SciPy Reference Guide, Release 0.13.0 Table 5.39 – continued from previous page integral(a, b) Return definite integral of the spline between two given points. roots() Return the zeros of the spline. set_smoothing_factor(s) Continue spline computation with the given smoothing InterpolatedUnivariateSpline.__call__(x, nu=0) Evaluate spline (or its nu-th derivative) at positions x. Note: x can be unordered but the evaluation is more efficient if x is (partially) ordered. InterpolatedUnivariateSpline.antiderivative(n=1) Construct a new spline representing the antiderivative of this spline. New in version 0.13.0. Parameters Returns n : int, optional Order of antiderivative to evaluate. Default: 1 spline : UnivariateSpline Spline of order k2=k+n representing the antiderivative of this spline. See Also splantider, derivative Examples >>> >>> >>> >>> from scipy.interpolate import UnivariateSpline x = np.linspace(0, np.pi/2, 70) y = 1 / np.sqrt(1 - 0.8*np.sin(x)**2) spl = UnivariateSpline(x, y, s=0) The derivative is the inverse operation of the antiderivative, although some floating point error accumulates: >>> spl(1.7), spl.antiderivative().derivative()(1.7) (array(2.1565429877197317), array(2.1565429877201865)) Antiderivative can be used to evaluate definite integrals: >>> ispl = spl.antiderivative() >>> ispl(np.pi/2) - ispl(0) 2.2572053588768486 This is indeed an approximation to the complete elliptic integral K(m) = R π/2 0 [1 − m sin2 x]−1/2 dx: >>> from scipy.special import ellipk >>> ellipk(0.8) 2.2572053268208538 InterpolatedUnivariateSpline.derivative(n=1) Construct a new spline representing the derivative of this spline. New in version 0.13.0. Parameters Returns n : int, optional Order of derivative to evaluate. Default: 1 spline : UnivariateSpline Spline of order k2=k-n representing the derivative of this spline. See Also splder, antiderivative 294 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Examples This can be used for finding maxima of a curve: >>> >>> >>> >>> from scipy.interpolate import UnivariateSpline x = np.linspace(0, 10, 70) y = np.sin(x) spl = UnivariateSpline(x, y, k=4, s=0) Now, differentiate the spline and find the zeros of the derivative. (NB: sproot only works for order 3 splines, so we fit an order 4 spline): >>> spl.derivative().roots() / np.pi array([ 0.50000001, 1.5 , 2.49999998]) This agrees well with roots π/2 + nπ of cos(x) = sin’(x). InterpolatedUnivariateSpline.derivatives(x) Return all derivatives of the spline at the point x. InterpolatedUnivariateSpline.get_coeffs() Return spline coefficients. InterpolatedUnivariateSpline.get_knots() Return positions of (boundary and interior) knots of the spline. InterpolatedUnivariateSpline.get_residual() Return weighted sum of squared residuals of the spline approximation: (y[i]-s(x[i])))**2, axis=0). sum((w[i] * InterpolatedUnivariateSpline.integral(a, b) Return definite integral of the spline between two given points. InterpolatedUnivariateSpline.roots() Return the zeros of the spline. Restriction: only cubic splines are supported by fitpack. InterpolatedUnivariateSpline.set_smoothing_factor(s) Continue spline computation with the given smoothing factor s and with the knots found at the last call. class scipy.interpolate.LSQUnivariateSpline(x, y, t, w=None, bbox=[None, None], k=3) One-dimensional spline with explicit internal knots. Fits a spline y=s(x) of degree k to the provided x, y data. t specifies the internal knots of the spline Parameters Raises x : (N,) array_like Input dimension of data points – must be increasing y : (N,) array_like Input dimension of data points t : (M,) array_like interior knots of the spline. Must be in ascending order and bbox[0] >> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> from numpy import linspace,exp from numpy.random import randn from scipy.interpolate import LSQUnivariateSpline import matplotlib.pyplot as plt x = linspace(-3,3,100) y = exp(-x**2) + randn(100)/10 t = [-1,0,1] s = LSQUnivariateSpline(x,y,t) xs = linspace(-3,3,1000) ys = s(xs) plt.plot(x, y, ’.-’) plt.plot(xs, ys) plt.show() xs,ys is now a smoothed, super-sampled version of the noisy gaussian x,y with knots [-3,-1,0,1,3] Methods __call__(x[, nu]) antiderivative([n]) derivative([n]) derivatives(x) get_coeffs() get_knots() get_residual() integral(a, b) roots() set_smoothing_factor(s) Evaluate spline (or its nu-th derivative) at positions x. Construct a new spline representing the antiderivative of this spline. Construct a new spline representing the derivative of this spline. Return all derivatives of the spline at the point x. Return spline coefficients. Return positions of (boundary and interior) knots of the spline. Return weighted sum of squared residuals of the spline Return definite integral of the spline between two given points. Return the zeros of the spline. Continue spline computation with the given smoothing LSQUnivariateSpline.__call__(x, nu=0) Evaluate spline (or its nu-th derivative) at positions x. Note: x can be unordered but the evaluation is more efficient if x is (partially) ordered. LSQUnivariateSpline.antiderivative(n=1) 296 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Construct a new spline representing the antiderivative of this spline. New in version 0.13.0. Parameters Returns n : int, optional Order of antiderivative to evaluate. Default: 1 spline : UnivariateSpline Spline of order k2=k+n representing the antiderivative of this spline. See Also splantider, derivative Examples >>> >>> >>> >>> from scipy.interpolate import UnivariateSpline x = np.linspace(0, np.pi/2, 70) y = 1 / np.sqrt(1 - 0.8*np.sin(x)**2) spl = UnivariateSpline(x, y, s=0) The derivative is the inverse operation of the antiderivative, although some floating point error accumulates: >>> spl(1.7), spl.antiderivative().derivative()(1.7) (array(2.1565429877197317), array(2.1565429877201865)) Antiderivative can be used to evaluate definite integrals: >>> ispl = spl.antiderivative() >>> ispl(np.pi/2) - ispl(0) 2.2572053588768486 This is indeed an approximation to the complete elliptic integral K(m) = R π/2 0 [1 − m sin2 x]−1/2 dx: >>> from scipy.special import ellipk >>> ellipk(0.8) 2.2572053268208538 LSQUnivariateSpline.derivative(n=1) Construct a new spline representing the derivative of this spline. New in version 0.13.0. Parameters Returns n : int, optional Order of derivative to evaluate. Default: 1 spline : UnivariateSpline Spline of order k2=k-n representing the derivative of this spline. See Also splder, antiderivative Examples This can be used for finding maxima of a curve: >>> >>> >>> >>> from scipy.interpolate import UnivariateSpline x = np.linspace(0, 10, 70) y = np.sin(x) spl = UnivariateSpline(x, y, k=4, s=0) Now, differentiate the spline and find the zeros of the derivative. (NB: sproot only works for order 3 splines, so we fit an order 4 spline): 5.7. Interpolation (scipy.interpolate) 297 SciPy Reference Guide, Release 0.13.0 >>> spl.derivative().roots() / np.pi array([ 0.50000001, 1.5 , 2.49999998]) This agrees well with roots π/2 + nπ of cos(x) = sin’(x). LSQUnivariateSpline.derivatives(x) Return all derivatives of the spline at the point x. LSQUnivariateSpline.get_coeffs() Return spline coefficients. LSQUnivariateSpline.get_knots() Return positions of (boundary and interior) knots of the spline. LSQUnivariateSpline.get_residual() Return weighted sum of squared residuals of the spline approximation: (y[i]-s(x[i])))**2, axis=0). sum((w[i] * LSQUnivariateSpline.integral(a, b) Return definite integral of the spline between two given points. LSQUnivariateSpline.roots() Return the zeros of the spline. Restriction: only cubic splines are supported by fitpack. LSQUnivariateSpline.set_smoothing_factor(s) Continue spline computation with the given smoothing factor s and with the knots found at the last call. The above univariate spline classes have the following methods: UnivariateSpline.__call__(x[, nu]) UnivariateSpline.derivatives(x) UnivariateSpline.integral(a, b) UnivariateSpline.roots() UnivariateSpline.derivative([n]) UnivariateSpline.antiderivative([n]) UnivariateSpline.get_coeffs() UnivariateSpline.get_knots() UnivariateSpline.get_residual() UnivariateSpline.set_smoothing_factor(s) Evaluate spline (or its nu-th derivative) at positions x. Return all derivatives of the spline at the point x. Return definite integral of the spline between two given points. Return the zeros of the spline. Construct a new spline representing the derivative of this spline. Construct a new spline representing the antiderivative of this spline. Return spline coefficients. Return positions of (boundary and interior) knots of the spline. Return weighted sum of squared residuals of the spline Continue spline computation with the given smoothing Functional interface to FITPACK functions: splrep(x, y[, w, xb, xe, k, task, s, t, ...]) splprep(x[, w, u, ub, ue, k, task, s, t, ...]) splev(x, tck[, der, ext]) splint(a, b, tck[, full_output]) sproot(tck[, mest]) spalde(x, tck) splder(tck[, n]) splantider(tck[, n]) bisplrep(x, y, z[, w, xb, xe, yb, ye, kx, ...]) bisplev(x, y, tck[, dx, dy]) 298 Find the B-spline representation of 1-D curve. Find the B-spline representation of an N-dimensional curve. Evaluate a B-spline or its derivatives. Evaluate the definite integral of a B-spline. Find the roots of a cubic B-spline. Evaluate all derivatives of a B-spline. Compute the spline representation of the derivative of a given spline .. Compute the spline for the antiderivative (integral) of a given spline. Find a bivariate B-spline representation of a surface. Evaluate a bivariate B-spline and its derivatives. Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 scipy.interpolate.splrep(x, y, w=None, xb=None, xe=None, k=3, task=0, s=None, t=None, full_output=0, per=0, quiet=1) Find the B-spline representation of 1-D curve. Given the set of data points (x[i], y[i]) determine a smooth spline approximation of degree k on the interval xb <= x <= xe. Parameters Returns x, y : array_like The data points defining a curve y = f(x). w : array_like Strictly positive rank-1 array of weights the same length as x and y. The weights are used in computing the weighted least-squares spline fit. If the errors in the y values have standard-deviation given by the vector d, then w should be 1/d. Default is ones(len(x)). xb, xe : float The interval to fit. If None, these default to x[0] and x[-1] respectively. k : int The order of the spline fit. It is recommended to use cubic splines. Even order splines should be avoided especially with small s values. 1 <= k <= 5 task : {1, 0, -1} If task==0 find t and c for a given smoothing factor, s. If task==1 find t and c for another value of the smoothing factor, s. There must have been a previous call with task=0 or task=1 for the same set of data (t will be stored an used internally) If task=-1 find the weighted least square spline for a given set of knots, t. These should be interior knots as knots on the ends will be added automatically. s : float A smoothing condition. The amount of smoothness is determined by satisfying the conditions: sum((w * (y - g))**2,axis=0) <= s where g(x) is the smoothed interpolation of (x,y). The user can use s to control the tradeoff between closeness and smoothness of fit. Larger s means more smoothing while smaller values of s indicate less smoothing. Recommended values of s depend on the weights, w. If the weights represent the inverse of the standard-deviation of y, then a good s value should be found in the range (m-sqrt(2*m),m+sqrt(2*m)) where m is the number of datapoints in x, y, and w. default : s=m-sqrt(2*m) if weights are supplied. s = 0.0 (interpolating) if no weights are supplied. t : int The knots needed for task=-1. If given then task is automatically set to -1. full_output : bool If non-zero, then return optional outputs. per : bool If non-zero, data points are considered periodic with period x[m-1] - x[0] and a smooth periodic spline approximation is returned. Values of y[m-1] and w[m-1] are not used. quiet : bool Non-zero to suppress messages. tck : tuple (t,c,k) a tuple containing the vector of knots, the B-spline coefficients, and the degree of the spline. fp : array, optional The weighted sum of squared residuals of the spline approximation. ier : int, optional An integer flag about splrep success. Success is indicated if ier<=0. If ier in [1,2,3] an error occurred but was not raised. Otherwise an error is raised. msg : str, optional A message corresponding to the integer flag, ier. 5.7. Interpolation (scipy.interpolate) 299 SciPy Reference Guide, Release 0.13.0 See Also UnivariateSpline, bisplrep, bisplev BivariateSpline, splprep, splev, sproot, spalde, splint, Notes See splev for evaluation of the spline and its derivatives. Uses the FORTRAN routine curfit from FITPACK. References Based on algorithms described in [1], [2], [3], and [4]: [R52], [R53], [R54], [R55] Examples >>> >>> >>> >>> >>> >>> x = linspace(0, 10, 10) y = sin(x) tck = splrep(x, y) x2 = linspace(0, 10, 200) y2 = splev(x2, tck) plot(x, y, ’o’, x2, y2) scipy.interpolate.splprep(x, w=None, u=None, ub=None, ue=None, k=3, task=0, s=None, t=None, full_output=0, nest=None, per=0, quiet=1) Find the B-spline representation of an N-dimensional curve. Given a list of N rank-1 arrays, x, which represent a curve in N-dimensional space parametrized by u, find a smooth approximating spline curve g(u). Uses the FORTRAN routine parcur from FITPACK. Parameters 300 x : array_like A list of sample vector arrays representing the curve. w : array_like Strictly positive rank-1 array of weights the same length as x[0]. The weights are used in computing the weighted least-squares spline fit. If the errors in the x values have standard-deviation given by the vector d, then w should be 1/d. Default is ones(len(x[0])). u : array_like, optional An array of parameter values. If not given, these values are calculated automatically as M = len(x[0]), where v[0] = 0 v[i] = v[i-1] + distance(x[i], x[i-1]) u[i] = v[i] / v[M-1] ub, ue : int, optional The end-points of the parameters interval. Defaults to u[0] and u[-1]. k : int, optional Degree of the spline. Cubic splines are recommended. Even values of k should be avoided especially with a small s-value. 1 <= k <= 5, default is 3. task : int, optional If task==0 (default), find t and c for a given smoothing factor, s. If task==1, find t and c for another value of the smoothing factor, s. There must have been a previous call with task=0 or task=1 for the same set of data. If task=-1 find the weighted least square spline for a given set of knots, t. s : float, optional A smoothing condition. The amount of smoothness is determined by satisfying the conditions: sum((w * (y - g))**2,axis=0) <= s, where g(x) is the smoothed interpolation of (x,y). The user can use s to control the trade-off between Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Returns closeness and smoothness of fit. Larger s means more smoothing while smaller values of s indicate less smoothing. Recommended values of s depend on the weights, w. If the weights represent the inverse of the standard-deviation of y, then a good s value should be found in the range (m-sqrt(2*m),m+sqrt(2*m)), where m is the number of data points in x, y, and w. t : int, optional The knots needed for task=-1. full_output : int, optional If non-zero, then return optional outputs. nest : int, optional An over-estimate of the total number of knots of the spline to help in determining the storage space. By default nest=m/2. Always large enough is nest=m+k+1. per : int, optional If non-zero, data points are considered periodic with period x[m-1] - x[0] and a smooth periodic spline approximation is returned. Values of y[m-1] and w[m-1] are not used. quiet : int, optional Non-zero to suppress messages. tck : tuple A tuple (t,c,k) containing the vector of knots, the B-spline coefficients, and the degree of the spline. u : array An array of the values of the parameter. fp : float The weighted sum of squared residuals of the spline approximation. ier : int An integer flag about splrep success. Success is indicated if ier<=0. If ier in [1,2,3] an error occurred but was not raised. Otherwise an error is raised. msg : str A message corresponding to the integer flag, ier. See Also splrep, splev, sproot, spalde, splint, bisplrep, bisplev, UnivariateSpline, BivariateSpline Notes See splev for evaluation of the spline and its derivatives. References [R49], [R50], [R51] scipy.interpolate.splev(x, tck, der=0, ext=0) Evaluate a B-spline or its derivatives. Given the knots and coefficients of a B-spline representation, evaluate the value of the smoothing polynomial and its derivatives. This is a wrapper around the FORTRAN routines splev and splder of FITPACK. Parameters x : array_like A 1-D array of points at which to return the value of the smoothed spline or its derivatives. If tck was returned from splprep, then the parameter values, u should be given. tck : tuple A sequence of length 3 returned by splrep or splprep containing the knots, coefficients, and degree of the spline. 5.7. Interpolation (scipy.interpolate) 301 SciPy Reference Guide, Release 0.13.0 Returns der : int The order of derivative of the spline to compute (must be less than or equal to k). ext : int Controls the value returned for elements of x not in the interval defined by the knot sequence. •if ext=0, return the extrapolated value. •if ext=1, return 0 •if ext=2, raise a ValueError The default value is 0. y : ndarray or list of ndarrays An array of values representing the spline function evaluated at the points in x. If tck was returned from splrep, then this is a list of arrays representing the curve in N-dimensional space. See Also splprep, splrep, sproot, spalde, splint, bisplrep, bisplev References [R44], [R45], [R46] scipy.interpolate.splint(a, b, tck, full_output=0) Evaluate the definite integral of a B-spline. Given the knots and coefficients of a B-spline, evaluate the definite integral of the smoothing polynomial between two given points. Parameters Returns a, b : float The end-points of the integration interval. tck : tuple A tuple (t,c,k) containing the vector of knots, the B-spline coefficients, and the degree of the spline (see splev). full_output : int, optional Non-zero to return optional output. integral : float The resulting integral. wrk : ndarray An array containing the integrals of the normalized B-splines defined on the set of knots. See Also splprep, splrep, sproot, spalde, splev, bisplrep, bisplev, UnivariateSpline, BivariateSpline References [R47], [R48] scipy.interpolate.sproot(tck, mest=10) Find the roots of a cubic B-spline. Given the knots (>=8) and coefficients of a cubic B-spline return the roots of the spline. Parameters 302 tck : tuple A tuple (t,c,k) containing the vector of knots, the B-spline coefficients, and the degree of the spline. The number of knots must be >= 8, and the degree must be 3. The knots must be a montonically increasing sequence. Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Returns mest : int An estimate of the number of zeros (Default is 10). zeros : ndarray An array giving the roots of the spline. See Also splprep, splrep, splint, spalde, splev, bisplrep, bisplev, UnivariateSpline, BivariateSpline References [R56], [R57], [R58] scipy.interpolate.spalde(x, tck) Evaluate all derivatives of a B-spline. Given the knots and coefficients of a cubic B-spline compute all derivatives up to order k at a point (or set of points). Parameters Returns x : array_like A point or a set of points at which to evaluate the derivatives. Note that t(k) <= x <= t(n-k+1) must hold for each x. tck : tuple A tuple (t,c,k) containing the vector of knots, the B-spline coefficients, and the degree of the spline. results : {ndarray, list of ndarrays} An array (or a list of arrays) containing all derivatives up to order k inclusive for each point x. See Also splprep, splrep, splint, sproot, splev, bisplrep, bisplev, UnivariateSpline, BivariateSpline References [R41], [R42], [R43] scipy.interpolate.splder(tck, n=1) Compute the spline representation of the derivative of a given spline New in version 0.13.0. Parameters Returns tck : tuple of (t, c, k) Spline whose derivative to compute n : int, optional Order of derivative to evaluate. Default: 1 tck_der : tuple of (t2, c2, k2) Spline of order k2=k-n representing the derivative of the input spline. See Also splantider, splev, spalde Examples This can be used for finding maxima of a curve: >>> >>> >>> >>> from scipy.interpolate import splrep, splder, sproot x = np.linspace(0, 10, 70) y = np.sin(x) spl = splrep(x, y, k=4) 5.7. Interpolation (scipy.interpolate) 303 SciPy Reference Guide, Release 0.13.0 Now, differentiate the spline and find the zeros of the derivative. (NB: sproot only works for order 3 splines, so we fit an order 4 spline): >>> dspl = splder(spl) >>> sproot(dspl) / np.pi array([ 0.50000001, 1.5 , 2.49999998]) This agrees well with roots π/2 + nπ of cos(x) = sin0 (x). scipy.interpolate.splantider(tck, n=1) Compute the spline for the antiderivative (integral) of a given spline. New in version 0.13.0. Parameters Returns tck : tuple of (t, c, k) Spline whose antiderivative to compute n : int, optional Order of antiderivative to evaluate. Default: 1 tck_ader : tuple of (t2, c2, k2) Spline of order k2=k+n representing the antiderivative of the input spline. See Also splder, splev, spalde Notes The splder function is the inverse operation of this function. Namely, splder(splantider(tck)) is identical to tck, modulo rounding error. Examples >>> >>> >>> >>> from scipy.interpolate import splrep, splder, splantider, splev x = np.linspace(0, np.pi/2, 70) y = 1 / np.sqrt(1 - 0.8*np.sin(x)**2) spl = splrep(x, y) The derivative is the inverse operation of the antiderivative, although some floating point error accumulates: >>> splev(1.7, spl), splev(1.7, splder(splantider(spl))) (array(2.1565429877197317), array(2.1565429877201865)) Antiderivative can be used to evaluate definite integrals: >>> ispl = splantider(spl) >>> splev(np.pi/2, ispl) - splev(0, ispl) 2.2572053588768486 This is indeed an approximation to the complete elliptic integral K(m) = R π/2 0 [1 − m sin2 x]−1/2 dx: >>> from scipy.special import ellipk >>> ellipk(0.8) 2.2572053268208538 scipy.interpolate.bisplrep(x, y, z, w=None, xb=None, xe=None, yb=None, ye=None, kx=3, ky=3, task=0, s=None, eps=1e-16, tx=None, ty=None, full_output=0, nxest=None, nyest=None, quiet=1) Find a bivariate B-spline representation of a surface. Given a set of data points (x[i], y[i], z[i]) representing a surface z=f(x,y), compute a B-spline representation of the surface. Based on the routine SURFIT from FITPACK. Parameters 304 x, y, z : ndarray Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Returns Rank-1 arrays of data points. w : ndarray, optional Rank-1 array of weights. By default w=np.ones(len(x)). xb, xe : float, optional End points of approximation interval in x. By default xb = x.min(), xe=x.max(). yb, ye : float, optional End points of approximation interval in y. By default yb=y.min(), ye = y.max(). kx, ky : int, optional The degrees of the spline (1 <= kx, ky <= 5). Third order (kx=ky=3) is recommended. task : int, optional If task=0, find knots in x and y and coefficients for a given smoothing factor, s. If task=1, find knots and coefficients for another value of the smoothing factor, s. bisplrep must have been previously called with task=0 or task=1. If task=-1, find coefficients for a given set of knots tx, ty. s : float, optional A non-negative smoothing factor. If weights correspond to the inverse of the standarddeviation of the errors in z, then a good s-value should be found in the range (m-sqrt(2*m),m+sqrt(2*m)) where m=len(x). eps : float, optional A threshold for determining the effective rank of an over-determined linear system of equations (0 < eps < 1). eps is not likely to need changing. tx, ty : ndarray, optional Rank-1 arrays of the knots of the spline for task=-1 full_output : int, optional Non-zero to return optional outputs. nxest, nyest : int, optional Over-estimates of the total number of knots. If None then nxest = max(kx+sqrt(m/2),2*kx+3), nyest = max(ky+sqrt(m/2),2*ky+3). quiet : int, optional Non-zero to suppress printing of messages. tck : array_like A list [tx, ty, c, kx, ky] containing the knots (tx, ty) and coefficients (c) of the bivariate B-spline representation of the surface along with the degree of the spline. fp : ndarray The weighted sum of squared residuals of the spline approximation. ier : int An integer flag about splrep success. Success is indicated if ier<=0. If ier in [1,2,3] an error occurred but was not raised. Otherwise an error is raised. msg : str A message corresponding to the integer flag, ier. See Also splprep, splrep, splint, sproot, splev, UnivariateSpline, BivariateSpline Notes See bisplev to evaluate the value of the B-spline given its tck representation. References [R38], [R39], [R40] 5.7. Interpolation (scipy.interpolate) 305 SciPy Reference Guide, Release 0.13.0 scipy.interpolate.bisplev(x, y, tck, dx=0, dy=0) Evaluate a bivariate B-spline and its derivatives. Return a rank-2 array of spline function values (or spline derivative values) at points given by the cross-product of the rank-1 arrays x and y. In special cases, return an array or just a float if either x or y or both are floats. Based on BISPEV from FITPACK. Parameters Returns x, y : ndarray Rank-1 arrays specifying the domain over which to evaluate the spline or its derivative. tck : tuple A sequence of length 5 returned by bisplrep containing the knot locations, the coefficients, and the degree of the spline: [tx, ty, c, kx, ky]. dx, dy : int, optional The orders of the partial derivatives in x and y respectively. vals : ndarray The B-spline or its derivative evaluated over the set formed by the cross-product of x and y. See Also splprep, splrep, splint, sproot, splev, UnivariateSpline, BivariateSpline Notes See bisplrep to generate the tck representation. References [R35], [R36], [R37] 5.7.4 2-D Splines For data on a grid: RectBivariateSpline(x, y, z[, bbox, kx, ky, s]) RectSphereBivariateSpline(u, v, r[, s, ...]) Bivariate spline approximation over a rectangular mesh. Bivariate spline approximation over a rectangular mesh on a sphere. class scipy.interpolate.RectBivariateSpline(x, y, z, bbox=[None, None, None, None], kx=3, ky=3, s=0) Bivariate spline approximation over a rectangular mesh. Can be used for both smoothing and interpolating data. Parameters 306 x,y : array_like 1-D arrays of coordinates in strictly ascending order. z : array_like 2-D array of data with shape (x.size,y.size). bbox : array_like, optional Sequence of length 4 specifying the boundary of the rectangular approximation domain. By default, bbox=[min(x,tx),max(x,tx), min(y,ty),max(y,ty)]. kx, ky : ints, optional Degrees of the bivariate spline. Default is 3. s : float, optional Positive smoothing factor defined for estimation condition: sum((w[i]*(z[i]-s(x[i], y[i])))**2, axis=0) <= s Default Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 is s=0, which is for interpolation. See Also SmoothBivariateSpline a smoothing bivariate spline for scattered data bisplrep an older wrapping of FITPACK bisplev an older wrapping of FITPACK UnivariateSpline a similar class for univariate spline interpolation Methods __call__(x, y[, mth]) ev(xi, yi) get_coeffs() get_knots() get_residual() integral(xa, xb, ya, yb) Evaluate spline at the grid points defined by the coordinate arrays Evaluate spline at points (x[i], y[i]), i=0,...,len(x)-1 Return spline coefficients. Return a tuple (tx,ty) where tx,ty contain knots positions of the spline with respect to x-, y-variable, resp Return weighted sum of squared residuals of the spline Evaluate the integral of the spline over area [xa,xb] x [ya,yb]. RectBivariateSpline.__call__(x, y, mth=’array’) Evaluate spline at the grid points defined by the coordinate arrays x,y. RectBivariateSpline.ev(xi, yi) Evaluate spline at points (x[i], y[i]), i=0,...,len(x)-1 RectBivariateSpline.get_coeffs() Return spline coefficients. RectBivariateSpline.get_knots() Return a tuple (tx,ty) where tx,ty contain knots positions of the spline with respect to x-, y-variable, respectively. The position of interior and additional knots are given as t[k+1:-k-1] and t[:k+1]=b, t[-k-1:]=e, respectively. RectBivariateSpline.get_residual() Return weighted sum of squared residuals of the spline approximation: s(x[i],y[i])))**2,axis=0) sum ((w[i]*(z[i]- RectBivariateSpline.integral(xa, xb, ya, yb) Evaluate the integral of the spline over area [xa,xb] x [ya,yb]. Parameters Returns xa, xb : float The end-points of the x integration interval. ya, yb : float The end-points of the y integration interval. integ : float The value of the resulting integral. class scipy.interpolate.RectSphereBivariateSpline(u, v, r, s=0.0, pole_continuity=False, pole_values=None, pole_exact=False, pole_flat=False) Bivariate spline approximation over a rectangular mesh on a sphere. Can be used for smoothing data. New in version 0.11.0. Parameters u : array_like 5.7. Interpolation (scipy.interpolate) 307 SciPy Reference Guide, Release 0.13.0 1-D array of latitude coordinates in strictly ascending order. Coordinates must be given in radians and lie within the interval (0, pi). v : array_like 1-D array of longitude coordinates in strictly ascending order. Coordinates must be given in radians, and must lie within (0, 2pi). r : array_like 2-D array of data with shape (u.size, v.size). s : float, optional Positive smoothing factor defined for estimation condition (s=0 is for interpolation). pole_continuity : bool or (bool, bool), optional Order of continuity at the poles u=0 (pole_continuity[0]) and u=pi (pole_continuity[1]). The order of continuity at the pole will be 1 or 0 when this is True or False, respectively. Defaults to False. pole_values : float or (float, float), optional Data values at the poles u=0 and u=pi. Either the whole parameter or each individual element can be None. Defaults to None. pole_exact : bool or (bool, bool), optional Data value exactness at the poles u=0 and u=pi. If True, the value is considered to be the right function value, and it will be fitted exactly. If False, the value will be considered to be a data value just like the other data values. Defaults to False. pole_flat : bool or (bool, bool), optional For the poles at u=0 and u=pi, specify whether or not the approximation has vanishing derivatives. Defaults to False. See Also RectBivariateSpline bivariate spline approximation over a rectangular mesh Notes Currently, only the smoothing spline approximation (iopt[0] = 0 and iopt[0] = 1 in the FITPACK routine) is supported. The exact least-squares spline approximation is not implemented yet. When actually performing the interpolation, the requested v values must lie within the same length 2pi interval that the original v values were chosen from. For more information, see the FITPACK site about this function. Examples Suppose we have global data on a coarse grid >>> lats = np.linspace(10, 170, 9) * np.pi / 180. >>> lons = np.linspace(0, 350, 18) * np.pi / 180. >>> data = np.dot(np.atleast_2d(90. - np.linspace(-80., 80., 18)).T, np.atleast_2d(180. - np.abs(np.linspace(0., 350., 9)))).T We want to interpolate it to a global one-degree grid >>> new_lats = np.linspace(1, 180, 180) * np.pi / 180 >>> new_lons = np.linspace(1, 360, 360) * np.pi / 180 >>> new_lats, new_lons = np.meshgrid(new_lats, new_lons) We need to set up the interpolator object >>> from scipy.interpolate import RectSphereBivariateSpline >>> lut = RectSphereBivariateSpline(lats, lons, data) 308 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Finally we interpolate the data. The RectSphereBivariateSpline object only takes 1-D arrays as input, therefore we need to do some reshaping. >>> data_interp = lut.ev(new_lats.ravel(), ... new_lons.ravel()).reshape((360, 180)).T Looking at the original and the interpolated data, one can see that the interpolant reproduces the original data very well: >>> >>> >>> >>> >>> >>> fig = plt.figure() ax1 = fig.add_subplot(211) ax1.imshow(data, interpolation=’nearest’) ax2 = fig.add_subplot(212) ax2.imshow(data_interp, interpolation=’nearest’) plt.show() Chosing the optimal value of s can be a delicate task. Recommended values for s depend on the accuracy of the data values. If the user has an idea of the statistical errors on the data, she can also find a proper estimate for s. By assuming that, if she specifies the right s, the interpolator will use a spline f(u,v) which exactly reproduces the function underlying the data, she can evaluate sum((r(i,j)-s(u(i),v(j)))**2) to find a good estimate for this s. For example, if she knows that the statistical errors on her r(i,j)-values are not greater than 0.1, she may expect that a good s should have a value not larger than u.size * v.size * (0.1)**2. If nothing is known about the statistical error in r(i,j), s must be determined by trial and error. The best is then to start with a very large value of s (to determine the least-squares polynomial and the corresponding upper bound fp0 for s) and then to progressively decrease the value of s (say by a factor 10 in the beginning, i.e. s = fp0 / 10, fp0 / 100, ... and more carefully as the approximation shows more detail) to obtain closer fits. The interpolation results for different values of s give some insight into this process: >>> >>> >>> >>> >>> ... >>> >>> >>> >>> fig2 = plt.figure() s = [3e9, 2e9, 1e9, 1e8] for ii in xrange(len(s)): lut = RectSphereBivariateSpline(lats, lons, data, s=s[ii]) data_interp = lut.ev(new_lats.ravel(), new_lons.ravel()).reshape((360, 180)).T ax = fig2.add_subplot(2, 2, ii+1) ax.imshow(data_interp, interpolation=’nearest’) ax.set_title("s = %g" % s[ii]) plt.show() Methods __call__(theta, phi) ev(thetai, phii) get_coeffs() get_knots() get_residual() Evaluate the spline at the grid ponts defined by the coordinate Evaluate the spline at the points (theta[i], phi[i]), Return spline coefficients. Return a tuple (tx,ty) where tx,ty contain knots positions of the spline with respect to x-, y-variable, respectiv Return weighted sum of squared residuals of the spline RectSphereBivariateSpline.__call__(theta, phi) Evaluate the spline at the grid ponts defined by the coordinate arrays theta, phi. RectSphereBivariateSpline.ev(thetai, phii) Evaluate the spline at the points (theta[i], phi[i]), i=0,...,len(theta)-1 RectSphereBivariateSpline.get_coeffs() 5.7. Interpolation (scipy.interpolate) 309 SciPy Reference Guide, Release 0.13.0 Return spline coefficients. RectSphereBivariateSpline.get_knots() Return a tuple (tx,ty) where tx,ty contain knots positions of the spline with respect to x-, y-variable, respectively. The position of interior and additional knots are given as t[k+1:-k-1] and t[:k+1]=b, t[-k-1:]=e, respectively. RectSphereBivariateSpline.get_residual() Return weighted sum of squared residuals of the spline approximation: s(x[i],y[i])))**2,axis=0) sum ((w[i]*(z[i]- For unstructured data: BivariateSpline SmoothBivariateSpline(x, y, z[, w, bbox, ...]) SmoothSphereBivariateSpline(theta, phi, r[, ...]) LSQBivariateSpline(x, y, z, tx, ty[, w, ...]) LSQSphereBivariateSpline(theta, phi, r, tt, tp) Base class for bivariate splines. Smooth bivariate spline approximation. Smooth bivariate spline approximation in spherical coordinates. Weighted least-squares bivariate spline approximation. Weighted least-squares bivariate spline approximation in spherical coordi class scipy.interpolate.BivariateSpline Base class for bivariate splines. This describes a spline s(x, y) of degrees kx and ky on the rectangle [xb, xe] * [yb, ye] calculated from a given set of data points (x, y, z). This class is meant to be subclassed, not instantiated directly. SmoothBivariateSpline or LSQBivariateSpline. To construct these splines, call either See Also UnivariateSpline a similar class for univariate spline interpolation SmoothBivariateSpline to create a BivariateSpline through the given points LSQBivariateSpline to create a BivariateSpline using weighted least-squares fitting SphereBivariateSpline bivariate spline interpolation in spherical cooridinates bisplrep older wrapping of FITPACK bisplev older wrapping of FITPACK Methods __call__(x, y[, mth]) ev(xi, yi) get_coeffs() get_knots() get_residual() integral(xa, xb, ya, yb) Evaluate spline at the grid points defined by the coordinate arrays Evaluate spline at points (x[i], y[i]), i=0,...,len(x)-1 Return spline coefficients. Return a tuple (tx,ty) where tx,ty contain knots positions of the spline with respect to x-, y-variable, resp Return weighted sum of squared residuals of the spline Evaluate the integral of the spline over area [xa,xb] x [ya,yb]. BivariateSpline.__call__(x, y, mth=’array’) Evaluate spline at the grid points defined by the coordinate arrays x,y. 310 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 BivariateSpline.ev(xi, yi) Evaluate spline at points (x[i], y[i]), i=0,...,len(x)-1 BivariateSpline.get_coeffs() Return spline coefficients. BivariateSpline.get_knots() Return a tuple (tx,ty) where tx,ty contain knots positions of the spline with respect to x-, y-variable, respectively. The position of interior and additional knots are given as t[k+1:-k-1] and t[:k+1]=b, t[-k-1:]=e, respectively. BivariateSpline.get_residual() Return weighted sum of squared residuals of the spline approximation: s(x[i],y[i])))**2,axis=0) sum ((w[i]*(z[i]- BivariateSpline.integral(xa, xb, ya, yb) Evaluate the integral of the spline over area [xa,xb] x [ya,yb]. Parameters Returns xa, xb : float The end-points of the x integration interval. ya, yb : float The end-points of the y integration interval. integ : float The value of the resulting integral. class scipy.interpolate.SmoothBivariateSpline(x, y, z, w=None, bbox=[None, None, None, None], kx=3, ky=3, s=None, eps=None) Smooth bivariate spline approximation. Parameters x, y, z : array_like 1-D sequences of data points (order is not important). w : array_like, optional Positive 1-D sequence of weights, of same length as x, y and z. bbox : array_like, optional Sequence of length 4 specifying the boundary of the rectangular approximation domain. By default, bbox=[min(x,tx),max(x,tx), min(y,ty),max(y,ty)]. kx, ky : ints, optional Degrees of the bivariate spline. Default is 3. s : float, optional Positive smoothing factor defined for estimation condition: sum((w[i]*(z[i]-s(x[i], y[i])))**2, axis=0) <= s Default s=len(w) which should be a good value if 1/w[i] is an estimate of the standard deviation of z[i]. eps : float, optional A threshold for determining the effective rank of an over-determined linear system of equations. eps should have a value between 0 and 1, the default is 1e-16. See Also bisplrep an older wrapping of FITPACK bisplev an older wrapping of FITPACK UnivariateSpline a similar class for univariate spline interpolation LSQUnivariateSpline to create a BivariateSpline using weighted 5.7. Interpolation (scipy.interpolate) 311 SciPy Reference Guide, Release 0.13.0 Notes The length of x, y and z should be at least (kx+1) * (ky+1). Methods __call__(x, y[, mth]) ev(xi, yi) get_coeffs() get_knots() get_residual() integral(xa, xb, ya, yb) Evaluate spline at the grid points defined by the coordinate arrays Evaluate spline at points (x[i], y[i]), i=0,...,len(x)-1 Return spline coefficients. Return a tuple (tx,ty) where tx,ty contain knots positions of the spline with respect to x-, y-variable, resp Return weighted sum of squared residuals of the spline Evaluate the integral of the spline over area [xa,xb] x [ya,yb]. SmoothBivariateSpline.__call__(x, y, mth=’array’) Evaluate spline at the grid points defined by the coordinate arrays x,y. SmoothBivariateSpline.ev(xi, yi) Evaluate spline at points (x[i], y[i]), i=0,...,len(x)-1 SmoothBivariateSpline.get_coeffs() Return spline coefficients. SmoothBivariateSpline.get_knots() Return a tuple (tx,ty) where tx,ty contain knots positions of the spline with respect to x-, y-variable, respectively. The position of interior and additional knots are given as t[k+1:-k-1] and t[:k+1]=b, t[-k-1:]=e, respectively. SmoothBivariateSpline.get_residual() Return weighted sum of squared residuals of the spline approximation: s(x[i],y[i])))**2,axis=0) sum ((w[i]*(z[i]- SmoothBivariateSpline.integral(xa, xb, ya, yb) Evaluate the integral of the spline over area [xa,xb] x [ya,yb]. Parameters Returns xa, xb : float The end-points of the x integration interval. ya, yb : float The end-points of the y integration interval. integ : float The value of the resulting integral. class scipy.interpolate.SmoothSphereBivariateSpline(theta, phi, r, w=None, s=0.0, eps=1e-16) Smooth bivariate spline approximation in spherical coordinates. New in version 0.11.0. Parameters 312 theta, phi, r : array_like 1-D sequences of data points (order is not important). Coordinates must be given in radians. Theta must lie within the interval (0, pi), and phi must lie within the interval (0, 2pi). w : array_like, optional Positive 1-D sequence of weights. s : float, optional Positive smoothing factor defined for estimation condition: sum((w(i)*(r(i) s(theta(i), phi(i))))**2, axis=0) <= s Default s=len(w) which should be a good value if 1/w[i] is an estimate of the standard deviation of r[i]. eps : float, optional Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 A threshold for determining the effective rank of an over-determined linear system of equations. eps should have a value between 0 and 1, the default is 1e-16. Notes For more information, see the FITPACK site about this function. Examples Suppose we have global data on a coarse grid (the input data does not have to be on a grid): >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> theta = np.linspace(0., np.pi, 7) phi = np.linspace(0., 2*np.pi, 9) data = np.empty((theta.shape[0], phi.shape[0])) data[:,0], data[0,:], data[-1,:] = 0., 0., 0. data[1:-1,1], data[1:-1,-1] = 1., 1. data[1,1:-1], data[-2,1:-1] = 1., 1. data[2:-2,2], data[2:-2,-2] = 2., 2. data[2,2:-2], data[-3,2:-2] = 2., 2. data[3,3:-2] = 3. data = np.roll(data, 4, 1) We need to set up the interpolator object >>> lats, lons = np.meshgrid(theta, phi) >>> from scipy.interpolate import SmoothSphereBivariateSpline >>> lut = SmoothSphereBivariateSpline(lats.ravel(), lons.ravel(), data.T.ravel(),s=3.5) As a first test, we’ll see what the algorithm returns when run on the input coordinates >>> data_orig = lut(theta, phi) Finally we interpolate the data to a finer grid >>> fine_lats = np.linspace(0., np.pi, 70) >>> fine_lons = np.linspace(0., 2 * np.pi, 90) >>> data_smth = lut(fine_lats, fine_lons) >>> >>> >>> >>> >>> >>> >>> >>> fig = plt.figure() ax1 = fig.add_subplot(131) ax1.imshow(data, interpolation=’nearest’) ax2 = fig.add_subplot(132) ax2.imshow(data_orig, interpolation=’nearest’) ax3 = fig.add_subplot(133) ax3.imshow(data_smth, interpolation=’nearest’) plt.show() Methods __call__(theta, phi) ev(thetai, phii) get_coeffs() get_knots() get_residual() Evaluate the spline at the grid ponts defined by the coordinate Evaluate the spline at the points (theta[i], phi[i]), Return spline coefficients. Return a tuple (tx,ty) where tx,ty contain knots positions of the spline with respect to x-, y-variable, respectiv Return weighted sum of squared residuals of the spline 5.7. Interpolation (scipy.interpolate) 313 SciPy Reference Guide, Release 0.13.0 SmoothSphereBivariateSpline.__call__(theta, phi) Evaluate the spline at the grid ponts defined by the coordinate arrays theta, phi. SmoothSphereBivariateSpline.ev(thetai, phii) Evaluate the spline at the points (theta[i], phi[i]), i=0,...,len(theta)-1 SmoothSphereBivariateSpline.get_coeffs() Return spline coefficients. SmoothSphereBivariateSpline.get_knots() Return a tuple (tx,ty) where tx,ty contain knots positions of the spline with respect to x-, y-variable, respectively. The position of interior and additional knots are given as t[k+1:-k-1] and t[:k+1]=b, t[-k-1:]=e, respectively. SmoothSphereBivariateSpline.get_residual() Return weighted sum of squared residuals of the spline approximation: s(x[i],y[i])))**2,axis=0) sum ((w[i]*(z[i]- class scipy.interpolate.LSQBivariateSpline(x, y, z, tx, ty, w=None, bbox=[None, None, None, None], kx=3, ky=3, eps=None) Weighted least-squares bivariate spline approximation. Parameters x, y, z : array_like 1-D sequences of data points (order is not important). tx, ty : array_like Strictly ordered 1-D sequences of knots coordinates. w : array_like, optional Positive 1-D array of weights, of the same length as x, y and z. bbox : (4,) array_like, optional Sequence of length 4 specifying the boundary of the rectangular approximation domain. By default, bbox=[min(x,tx),max(x,tx), min(y,ty),max(y,ty)]. kx, ky : ints, optional Degrees of the bivariate spline. Default is 3. s : float, optional Positive smoothing factor defined for estimation condition: sum((w[i]*(z[i]-s(x[i], y[i])))**2, axis=0) <= s Default s=len(w) which should be a good value if 1/w[i] is an estimate of the standard deviation of z[i]. eps : float, optional A threshold for determining the effective rank of an over-determined linear system of equations. eps should have a value between 0 and 1, the default is 1e-16. See Also bisplrep an older wrapping of FITPACK bisplev an older wrapping of FITPACK UnivariateSpline a similar class for univariate spline interpolation SmoothBivariateSpline create a smoothing BivariateSpline Notes The length of x, y and z should be at least (kx+1) * (ky+1). 314 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Methods __call__(x, y[, mth]) ev(xi, yi) get_coeffs() get_knots() get_residual() integral(xa, xb, ya, yb) Evaluate spline at the grid points defined by the coordinate arrays Evaluate spline at points (x[i], y[i]), i=0,...,len(x)-1 Return spline coefficients. Return a tuple (tx,ty) where tx,ty contain knots positions of the spline with respect to x-, y-variable, resp Return weighted sum of squared residuals of the spline Evaluate the integral of the spline over area [xa,xb] x [ya,yb]. LSQBivariateSpline.__call__(x, y, mth=’array’) Evaluate spline at the grid points defined by the coordinate arrays x,y. LSQBivariateSpline.ev(xi, yi) Evaluate spline at points (x[i], y[i]), i=0,...,len(x)-1 LSQBivariateSpline.get_coeffs() Return spline coefficients. LSQBivariateSpline.get_knots() Return a tuple (tx,ty) where tx,ty contain knots positions of the spline with respect to x-, y-variable, respectively. The position of interior and additional knots are given as t[k+1:-k-1] and t[:k+1]=b, t[-k-1:]=e, respectively. LSQBivariateSpline.get_residual() Return weighted sum of squared residuals of the spline approximation: s(x[i],y[i])))**2,axis=0) sum ((w[i]*(z[i]- LSQBivariateSpline.integral(xa, xb, ya, yb) Evaluate the integral of the spline over area [xa,xb] x [ya,yb]. Parameters Returns xa, xb : float The end-points of the x integration interval. ya, yb : float The end-points of the y integration interval. integ : float The value of the resulting integral. class scipy.interpolate.LSQSphereBivariateSpline(theta, phi, r, tt, tp, w=None, eps=1e-16) Weighted least-squares bivariate spline approximation in spherical coordinates. New in version 0.11.0. Parameters theta, phi, r : array_like 1-D sequences of data points (order is not important). Coordinates must be given in radians. Theta must lie within the interval (0, pi), and phi must lie within the interval (0, 2pi). tt, tp : array_like Strictly ordered 1-D sequences of knots coordinates. Coordinates must satisfy 0 < tt[i] < pi, 0 < tp[i] < 2*pi. w : array_like, optional Positive 1-D sequence of weights, of the same length as theta, phi and r. eps : float, optional A threshold for determining the effective rank of an over-determined linear system of equations. eps should have a value between 0 and 1, the default is 1e-16. Notes For more information, see the FITPACK site about this function. 5.7. Interpolation (scipy.interpolate) 315 SciPy Reference Guide, Release 0.13.0 Examples Suppose we have global data on a coarse grid (the input data does not have to be on a grid): >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> theta = np.linspace(0., np.pi, 7) phi = np.linspace(0., 2*np.pi, 9) data = np.empty((theta.shape[0], phi.shape[0])) data[:,0], data[0,:], data[-1,:] = 0., 0., 0. data[1:-1,1], data[1:-1,-1] = 1., 1. data[1,1:-1], data[-2,1:-1] = 1., 1. data[2:-2,2], data[2:-2,-2] = 2., 2. data[2,2:-2], data[-3,2:-2] = 2., 2. data[3,3:-2] = 3. data = np.roll(data, 4, 1) We need to set up the interpolator object. Here, we must also specify the coordinates of the knots to use. >>> >>> >>> >>> >>> >>> >>> >>> lats, lons = np.meshgrid(theta, phi) knotst, knotsp = theta.copy(), phi.copy() knotst[0] += .0001 knotst[-1] -= .0001 knotsp[0] += .0001 knotsp[-1] -= .0001 from scipy.interpolate import LSQSphereBivariateSpline lut = LSQSphereBivariateSpline(lats.ravel(), lons.ravel(), data.T.ravel(),knotst,knotsp) As a first test, we’ll see what the algorithm returns when run on the input coordinates >>> data_orig = lut(theta, phi) Finally we interpolate the data to a finer grid >>> fine_lats = np.linspace(0., np.pi, 70) >>> fine_lons = np.linspace(0., 2*np.pi, 90) >>> data_lsq = lut(fine_lats, fine_lons) >>> >>> >>> >>> >>> >>> >>> >>> fig = plt.figure() ax1 = fig.add_subplot(131) ax1.imshow(data, interpolation=’nearest’) ax2 = fig.add_subplot(132) ax2.imshow(data_orig, interpolation=’nearest’) ax3 = fig.add_subplot(133) ax3.imshow(data_lsq, interpolation=’nearest’) plt.show() Methods __call__(theta, phi) ev(thetai, phii) get_coeffs() get_knots() get_residual() Evaluate the spline at the grid ponts defined by the coordinate Evaluate the spline at the points (theta[i], phi[i]), Return spline coefficients. Return a tuple (tx,ty) where tx,ty contain knots positions of the spline with respect to x-, y-variable, respectiv Return weighted sum of squared residuals of the spline LSQSphereBivariateSpline.__call__(theta, phi) Evaluate the spline at the grid ponts defined by the coordinate arrays theta, phi. 316 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 LSQSphereBivariateSpline.ev(thetai, phii) Evaluate the spline at the points (theta[i], phi[i]), i=0,...,len(theta)-1 LSQSphereBivariateSpline.get_coeffs() Return spline coefficients. LSQSphereBivariateSpline.get_knots() Return a tuple (tx,ty) where tx,ty contain knots positions of the spline with respect to x-, y-variable, respectively. The position of interior and additional knots are given as t[k+1:-k-1] and t[:k+1]=b, t[-k-1:]=e, respectively. LSQSphereBivariateSpline.get_residual() Return weighted sum of squared residuals of the spline approximation: s(x[i],y[i])))**2,axis=0) sum ((w[i]*(z[i]- Low-level interface to FITPACK functions: bisplrep(x, y, z[, w, xb, xe, yb, ye, kx, ...]) bisplev(x, y, tck[, dx, dy]) Find a bivariate B-spline representation of a surface. Evaluate a bivariate B-spline and its derivatives. scipy.interpolate.bisplrep(x, y, z, w=None, xb=None, xe=None, yb=None, ye=None, kx=3, ky=3, task=0, s=None, eps=1e-16, tx=None, ty=None, full_output=0, nxest=None, nyest=None, quiet=1) Find a bivariate B-spline representation of a surface. Given a set of data points (x[i], y[i], z[i]) representing a surface z=f(x,y), compute a B-spline representation of the surface. Based on the routine SURFIT from FITPACK. Parameters x, y, z : ndarray Rank-1 arrays of data points. w : ndarray, optional Rank-1 array of weights. By default w=np.ones(len(x)). xb, xe : float, optional End points of approximation interval in x. By default xb = x.min(), xe=x.max(). yb, ye : float, optional End points of approximation interval in y. By default yb=y.min(), ye = y.max(). kx, ky : int, optional The degrees of the spline (1 <= kx, ky <= 5). Third order (kx=ky=3) is recommended. task : int, optional If task=0, find knots in x and y and coefficients for a given smoothing factor, s. If task=1, find knots and coefficients for another value of the smoothing factor, s. bisplrep must have been previously called with task=0 or task=1. If task=-1, find coefficients for a given set of knots tx, ty. s : float, optional A non-negative smoothing factor. If weights correspond to the inverse of the standarddeviation of the errors in z, then a good s-value should be found in the range (m-sqrt(2*m),m+sqrt(2*m)) where m=len(x). eps : float, optional A threshold for determining the effective rank of an over-determined linear system of equations (0 < eps < 1). eps is not likely to need changing. tx, ty : ndarray, optional Rank-1 arrays of the knots of the spline for task=-1 full_output : int, optional Non-zero to return optional outputs. 5.7. Interpolation (scipy.interpolate) 317 SciPy Reference Guide, Release 0.13.0 Returns nxest, nyest : int, optional Over-estimates of the total number of knots. If None then nxest = max(kx+sqrt(m/2),2*kx+3), nyest = max(ky+sqrt(m/2),2*ky+3). quiet : int, optional Non-zero to suppress printing of messages. tck : array_like A list [tx, ty, c, kx, ky] containing the knots (tx, ty) and coefficients (c) of the bivariate B-spline representation of the surface along with the degree of the spline. fp : ndarray The weighted sum of squared residuals of the spline approximation. ier : int An integer flag about splrep success. Success is indicated if ier<=0. If ier in [1,2,3] an error occurred but was not raised. Otherwise an error is raised. msg : str A message corresponding to the integer flag, ier. See Also splprep, splrep, splint, sproot, splev, UnivariateSpline, BivariateSpline Notes See bisplev to evaluate the value of the B-spline given its tck representation. References [R38], [R39], [R40] scipy.interpolate.bisplev(x, y, tck, dx=0, dy=0) Evaluate a bivariate B-spline and its derivatives. Return a rank-2 array of spline function values (or spline derivative values) at points given by the cross-product of the rank-1 arrays x and y. In special cases, return an array or just a float if either x or y or both are floats. Based on BISPEV from FITPACK. Parameters Returns x, y : ndarray Rank-1 arrays specifying the domain over which to evaluate the spline or its derivative. tck : tuple A sequence of length 5 returned by bisplrep containing the knot locations, the coefficients, and the degree of the spline: [tx, ty, c, kx, ky]. dx, dy : int, optional The orders of the partial derivatives in x and y respectively. vals : ndarray The B-spline or its derivative evaluated over the set formed by the cross-product of x and y. See Also splprep, splrep, splint, sproot, splev, UnivariateSpline, BivariateSpline Notes See bisplrep to generate the tck representation. References [R35], [R36], [R37] 318 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 5.7.5 Additional tools lagrange(x, w) approximate_taylor_polynomial(f, x, degree, ...) Return a Lagrange interpolating polynomial. Estimate the Taylor polynomial of f at x by polynomial fitting. scipy.interpolate.lagrange(x, w) Return a Lagrange interpolating polynomial. Given two 1-D arrays x and w, returns the Lagrange interpolating polynomial through the points (x, w). Warning: This implementation is numerically unstable. Do not expect to be able to use more than about 20 points even if they are chosen optimally. Parameters Returns x : array_like x represents the x-coordinates of a set of datapoints. w : array_like w represents the y-coordinates of a set of datapoints, i.e. f(x). lagrange : numpy.poly1d instance The Lagrange interpolating polynomial. scipy.interpolate.approximate_taylor_polynomial(f, x, degree, scale, order=None) Estimate the Taylor polynomial of f at x by polynomial fitting. Parameters Returns f : callable The function whose Taylor polynomial is sought. Should accept a vector of x values. x : scalar The point at which the polynomial is to be evaluated. degree : int The degree of the Taylor polynomial scale : scalar The width of the interval to use to evaluate the Taylor polynomial. Function values spread over a range this wide are used to fit the polynomial. Must be chosen carefully. order : int or None, optional The order of the polynomial to be used in the fitting; f will be evaluated order+1 times. If None, use degree. p : poly1d instance The Taylor polynomial (translated to the origin, so that for example p(0)=f(x)). Notes The appropriate choice of “scale” is a trade-off; too large and the function differs from its Taylor polynomial too much to get a good answer, too small and round-off errors overwhelm the higher-order terms. The algorithm used becomes numerically unstable around order 30 even under ideal circumstances. Choosing order somewhat larger than degree may improve the higher-order terms. See Also scipy.ndimage.map_coordinates, scipy.ndimage.spline_filter, scipy.signal.resample, scipy.signal.bspline, scipy.signal.gauss_spline, scipy.signal.qspline1d, scipy.signal.cspline1d, scipy.signal.qspline1d_eval, scipy.signal.cspline1d_eval, scipy.signal.qspline2d, scipy.signal.cspline2d. 5.7. Interpolation (scipy.interpolate) 319 SciPy Reference Guide, Release 0.13.0 5.8 Input and output (scipy.io) SciPy has many modules, classes, and functions available to read data from and write data to a variety of file formats. See Also numpy-reference.routines.io (in Numpy) 5.8.1 MATLAB® files loadmat(file_name[, mdict, appendmat]) savemat(file_name, mdict[, appendmat, ...]) whosmat(file_name[, appendmat]) Load MATLAB file Save a dictionary of names and arrays into a MATLAB-style .mat file. List variables inside a MATLAB file scipy.io.loadmat(file_name, mdict=None, appendmat=True, **kwargs) Load MATLAB file Parameters Returns 320 file_name : str Name of the mat file (do not need .mat extension if appendmat==True) Can also pass open file-like object. m_dict : dict, optional Dictionary in which to insert matfile variables. appendmat : bool, optional True to append the .mat extension to the end of the given filename, if not already present. byte_order : str or None, optional None by default, implying byte order guessed from mat file. Otherwise can be one of (‘native’, ‘=’, ‘little’, ‘<’, ‘BIG’, ‘>’). mat_dtype : bool, optional If True, return arrays in same dtype as would be loaded into MATLAB (instead of the dtype with which they are saved). squeeze_me : bool, optional Whether to squeeze unit matrix dimensions or not. chars_as_strings : bool, optional Whether to convert char arrays to string arrays. matlab_compatible : bool, optional Returns matrices as would be loaded by MATLAB (implies squeeze_me=False, chars_as_strings=False, mat_dtype=True, struct_as_record=True). struct_as_record : bool, optional Whether to load MATLAB structs as numpy record arrays, or as old-style numpy arrays with dtype=object. Setting this flag to False replicates the behavior of scipy version 0.7.x (returning numpy object arrays). The default setting is True, because it allows easier round-trip load and save of MATLAB files. variable_names : None or sequence If None (the default) - read all variables in file. Otherwise variable_names should be a sequence of strings, giving names of the matlab variables to read from the file. The reader will skip any variable with a name not in this sequence, possibly saving some read processing. mat_dict : dict dictionary with variable names as keys, and loaded matrices as values Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Notes v4 (Level 1.0), v6 and v7 to 7.2 matfiles are supported. You will need an HDF5 python library to read matlab 7.3 format mat files. Because scipy does not supply one, we do not implement the HDF5 / 7.3 interface here. scipy.io.savemat(file_name, mdict, appendmat=True, format=‘5’, do_compression=False, oned_as=’row’) Save a dictionary of names and arrays into a MATLAB-style .mat file. long_field_names=False, This saves the array objects in the given dictionary to a MATLAB- style .mat file. Parameters file_name : str or file-like object Name of the .mat file (.mat extension not needed if appendmat == True). Can also pass open file_like object. mdict : dict Dictionary from which to save matfile variables. appendmat : bool, optional True (the default) to append the .mat extension to the end of the given filename, if not already present. format : {‘5’, ‘4’}, string, optional ‘5’ (the default) for MATLAB 5 and up (to 7.2), ‘4’ for MATLAB 4 .mat files long_field_names : bool, optional False (the default) - maximum field name length in a structure is 31 characters which is the documented maximum length. True - maximum field name length in a structure is 63 characters which works for MATLAB 7.6+ do_compression : bool, optional Whether or not to compress matrices on write. Default is False. oned_as : {‘row’, ‘column’}, optional If ‘column’, write 1-D numpy arrays as column vectors. If ‘row’, write 1-D numpy arrays as row vectors. See Also mio4.MatFile4Writer, mio5.MatFile5Writer scipy.io.whosmat(file_name, appendmat=True, **kwargs) List variables inside a MATLAB file New in version 0.12.0. Parameters file_name : str Name of the mat file (do not need .mat extension if appendmat==True) Can also pass open file-like object. appendmat : bool, optional True to append the .mat extension to the end of the given filename, if not already present. byte_order : str or None, optional None by default, implying byte order guessed from mat file. Otherwise can be one of (‘native’, ‘=’, ‘little’, ‘<’, ‘BIG’, ‘>’). mat_dtype : bool, optional If True, return arrays in same dtype as would be loaded into MATLAB (instead of the dtype with which they are saved). squeeze_me : bool, optional Whether to squeeze unit matrix dimensions or not. chars_as_strings : bool, optional Whether to convert char arrays to string arrays. matlab_compatible : bool, optional 5.8. Input and output (scipy.io) 321 SciPy Reference Guide, Release 0.13.0 Returns matrices as would be loaded by MATLAB (implies squeeze_me=False, chars_as_strings=False, mat_dtype=True, struct_as_record=True). struct_as_record : bool, optional Whether to load MATLAB structs as numpy record arrays, or as old-style numpy arrays with dtype=object. Setting this flag to False replicates the behavior of scipy version 0.7.x (returning numpy object arrays). The default setting is True, because it allows easier round-trip load and save of MATLAB files. variables : list of tuples A list of tuples, where each tuple holds the matrix name (a string), its shape (tuple of ints), and its data class (a string). Possible data classes are: int8, uint8, int16, uint16, int32, uint32, int64, uint64, single, double, cell, struct, object, char, sparse, function, opaque, logical, unknown. Returns Notes v4 (Level 1.0), v6 and v7 to 7.2 matfiles are supported. You will need an HDF5 python library to read matlab 7.3 format mat files. Because scipy does not supply one, we do not implement the HDF5 / 7.3 interface here. 5.8.2 IDL® files readsav(file_name[, idict, python_dict, ...]) Read an IDL .sav file scipy.io.readsav(file_name, idict=None, python_dict=False, uncompressed_file_name=None, verbose=False) Read an IDL .sav file Parameters Returns file_name : str Name of the IDL save file. idict : dict, optional Dictionary in which to insert .sav file variables python_dict : bool, optional By default, the object return is not a Python dictionary, but a case-insensitive dictionary with item, attribute, and call access to variables. To get a standard Python dictionary, set this option to True. uncompressed_file_name : str, optional This option only has an effect for .sav files written with the /compress option. If a file name is specified, compressed .sav files are uncompressed to this file. Otherwise, readsav will use the tempfile module to determine a temporary filename automatically, and will remove the temporary file upon successfully reading it in. verbose : bool, optional Whether to print out information about the save file, including the records read, and available variables. idl_dict : AttrDict or dict If python_dict is set to False (default), this function returns a case-insensitive dictionary with item, attribute, and call access to variables. If python_dict is set to True, this function returns a Python dictionary with all variable names in lowercase. If idict was specified, then variables are written to the dictionary specified, and the updated dictionary is returned. 5.8.3 Matrix Market files 322 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 mminfo(source) mmread(source) mmwrite(target, a[, comment, field, precision]) Queries the contents of the Matrix Market file ‘filename’ to Reads the contents of a Matrix Market file ‘filename’ into a matrix. Writes the sparse or dense matrix A to a Matrix Market formatted file. scipy.io.mminfo(source) Queries the contents of the Matrix Market file ‘filename’ to extract size and storage information. Parameters Returns source : file Matrix Market filename (extension .mtx) or open file object rows,cols : int Number of matrix rows and columns entries : int Number of non-zero entries of a sparse matrix or rows*cols for a dense matrix format : str Either ‘coordinate’ or ‘array’. field : str Either ‘real’, ‘complex’, ‘pattern’, or ‘integer’. symm : str Either ‘general’, ‘symmetric’, ‘skew-symmetric’, or ‘hermitian’. scipy.io.mmread(source) Reads the contents of a Matrix Market file ‘filename’ into a matrix. Parameters Returns source : file Matrix Market filename (extensions .mtx, .mtz.gz) or open file object. a: Sparse or full matrix scipy.io.mmwrite(target, a, comment=’‘, field=None, precision=None) Writes the sparse or dense matrix A to a Matrix Market formatted file. Parameters target : file Matrix Market filename (extension .mtx) or open file object a : array like Sparse or full matrix comment : str, optional comments to be prepended to the Matrix Market file field : str, optional Either ‘real’, ‘complex’, ‘pattern’, or ‘integer’. precision : int, optional Number of digits to display for real or complex values. 5.8.4 Unformatted Fortran files FortranFile(filename[, mode, header_dtype]) A file object for unformatted sequential files from Fortran code. class scipy.io.FortranFile(filename, mode=’r’, header_dtype= ) A file object for unformatted sequential files from Fortran code. Parameters filename: file or str Open file object or filename. mode : {‘r’, ‘w’}, optional Read-write mode, default is ‘r’. 5.8. Input and output (scipy.io) 323 SciPy Reference Guide, Release 0.13.0 header_dtype : data-type Data type of the header. Size and endiness must match the input/output file. Notes These files are broken up into records of unspecified types. The size of each record is given at the start (although the size of this header is not standard) and the data is written onto disk without any formatting. Fortran compilers supporting the BACKSPACE statement will write a second copy of the size to facilitate backwards seeking. This class only supports files written with both sizes for the record. It also does not support the subrecords used in Intel and gfortran compilers for records which are greater than 2GB with a 4-byte header. An example of an unformatted sequential file in Fortran would be written as: OPEN(1, FILE=myfilename, FORM=’unformatted’) WRITE(1) myvariable Since this is a non-standard file format, whose contents depend on the compiler and the endianness of the machine, caution is advised. Files from gfortran 4.8.0 and gfortran 4.1.2 on x86_64 are known to work. Consider using Fortran direct-access files or files from the newer Stream I/O, which can be easily read by numpy.fromfile. Examples To create an unformatted sequential Fortran file: >>> >>> >>> >>> >>> from scipy.io import FortranFile f = FortranFile(’test.unf’, ’w’) f.write_record(np.array([1,2,3,4,5],dtype=np.int32)) f.write_record(np.linspace(0,1,20).reshape((5,-1))) f.close() To read this file: >>> from scipy.io import FortranFile >>> f = FortranFile(’test.unf’, ’r’) >>> print(f.read_ints(dtype=np.int32)) [1 2 3 4 5] >>> print(f.read_reals(dtype=np.float).reshape((5,-1))) [[ 0. 0.05263158 0.10526316 0.15789474] [ 0.21052632 0.26315789 0.31578947 0.36842105] [ 0.42105263 0.47368421 0.52631579 0.57894737] [ 0.63157895 0.68421053 0.73684211 0.78947368] [ 0.84210526 0.89473684 0.94736842 1. ]] >>> f.close() Methods close() read_ints([dtype]) read_reals([dtype]) read_record([dtype]) write_record(s) Closes the file. Reads a record of a given type from the file, defaulting to an integer Reads a record of a given type from the file, defaulting to a floating Reads a record of a given type from the file. Write a record (including sizes) to the file. FortranFile.close() Closes the file. It is unsupported to call any other methods off this object after closing it. Note that this 324 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 class supports the ‘with’ statement in modern versions of Python, to call this automatically FortranFile.read_ints(dtype=’i4’) Reads a record of a given type from the file, defaulting to an integer type (INTEGER*4 in Fortran) Parameters Returns dtype : data-type Data type specifying the size and endiness of the data. data : ndarray A one-dimensional array object. See Also read_reals, read_record FortranFile.read_reals(dtype=’f8’) Reads a record of a given type from the file, defaulting to a floating point number (real*8 in Fortran) Parameters Returns dtype : data-type Data type specifying the size and endiness of the data. data : ndarray A one-dimensional array object. See Also read_ints, read_record FortranFile.read_record(dtype=None) Reads a record of a given type from the file. Parameters Returns dtype : data-type Data type specifying the size and endiness of the data. data : ndarray A one-dimensional array object. See Also read_reals, read_ints Notes If the record contains a multi-dimensional array, calling reshape or resize will restructure the array to the correct size. Since Fortran multidimensional arrays are stored in column-major format, this may have some non-intuitive consequences. If the variable was declared as ‘INTEGER var(5,4)’, for example, var could be read with ‘read_record(dtype=np.integer).reshape( (4,5) )’ since Python uses row-major ordering of indices. One can transpose to obtain the indices in the same order as in Fortran. FortranFile.write_record(s) Write a record (including sizes) to the file. Parameters s : array_like The data to write. 5.8.5 Wav sound files (scipy.io.wavfile) read(filename[, mmap]) write(filename, rate, data) 5.8. Input and output (scipy.io) Return the sample rate (in samples/sec) and data from a WAV file Write a numpy array as a WAV file 325 SciPy Reference Guide, Release 0.13.0 scipy.io.wavfile.read(filename, mmap=False) Return the sample rate (in samples/sec) and data from a WAV file Parameters Returns filename : string or open file handle Input wav file. mmap : bool, optional Whether to read data as memory mapped. Only to be used on real files (Default: False) New in version 0.12.0. rate : int Sample rate of wav file data : numpy array Data read from wav file Notes •The file can be an open file or a filename. •The returned sample rate is a Python integer •The data is returned as a numpy array with a data-type determined from the file. scipy.io.wavfile.write(filename, rate, data) Write a numpy array as a WAV file Parameters filename : string or open file handle Output wav file rate : int The sample rate (in samples/sec). data : ndarray A 1-D or 2-D numpy array of either integer or float data-type. Notes •The file can be an open file or a filename. •Writes a simple uncompressed WAV file. •The bits-per-sample will be determined by the data-type. •To write multiple-channels, use a 2-D array of shape (Nsamples, Nchannels). 5.8.6 Arff files (scipy.io.arff) loadarff(f) Read an arff file. scipy.io.arff.loadarff(f ) Read an arff file. The data is returned as a record array, which can be accessed much like a dictionary of numpy arrays. For example, if one of the attributes is called ‘pressure’, then its first 10 data points can be accessed from the data record array like so: data[’pressure’][0:10] Parameters Returns 326 f : file-like or str File-like object to read from, or filename to open. data : record array The data of the arff file, accessible by attribute names. meta : MetaData Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Raises Contains information about the arff file such as name and type of attributes, the relation (name of the dataset), etc... ‘ParseArffError‘ This is raised if the given file is not ARFF-formatted. NotImplementedError The ARFF file has an attribute which is not supported yet. Notes This function should be able to read most arff files. Not implemented functionality include: •date type attributes •string type attributes It can read files with numeric and nominal attributes. It cannot read files with sparse data ({} in the file). However, this function can read files with missing data (? in the file), representing the data points as NaNs. 5.8.7 Netcdf (scipy.io.netcdf) netcdf_file(filename[, mode, mmap, version]) netcdf_variable(data, typecode, size, shape, ...) A file object for NetCDF data. A data object for the netcdf module. class scipy.io.netcdf.netcdf_file(filename, mode=’r’, mmap=None, version=1) A file object for NetCDF data. A netcdf_file object has two standard attributes: dimensions and variables. The values of both are dictionaries, mapping dimension names to their associated lengths and variable names to variables, respectively. Application programs should never modify these dictionaries. All other attributes correspond to global attributes defined in the NetCDF file. Global file attributes are created by assigning to an attribute of the netcdf_file object. Parameters filename : string or file-like string -> filename mode : {‘r’, ‘w’}, optional read-write mode, default is ‘r’ mmap : None or bool, optional Whether to mmap filename when reading. Default is True when filename is a file name, False when filename is a file-like object version : {1, 2}, optional version of netcdf to read / write, where 1 means Classic format and 2 means 64-bit offset format. Default is 1. See here for more info. Notes The major advantage of this module over other modules is that it doesn’t require the code to be linked to the NetCDF libraries. This module is derived from pupynere. NetCDF files are a self-describing binary data format. The file contains metadata that describes the dimensions and variables in the file. More details about NetCDF files can be found here. There are three main sections to a NetCDF data structure: 1.Dimensions 2.Variables 3.Attributes 5.8. Input and output (scipy.io) 327 SciPy Reference Guide, Release 0.13.0 The dimensions section records the name and length of each dimension used by the variables. The variables would then indicate which dimensions it uses and any attributes such as data units, along with containing the data values for the variable. It is good practice to include a variable that is the same name as a dimension to provide the values for that axes. Lastly, the attributes section would contain additional information such as the name of the file creator or the instrument used to collect the data. When writing data to a NetCDF file, there is often the need to indicate the ‘record dimension’. A record dimension is the unbounded dimension for a variable. For example, a temperature variable may have dimensions of latitude, longitude and time. If one wants to add more temperature data to the NetCDF file as time progresses, then the temperature variable should have the time dimension flagged as the record dimension. In addition, the NetCDF file header contains the position of the data in the file, so access can be done in an efficient manner without loading unnecessary data into memory. It uses the mmap module to create Numpy arrays mapped to the data on disk, for the same purpose. Examples To create a NetCDF file: >>> >>> >>> >>> >>> >>> >>> >>> from scipy.io import netcdf f = netcdf.netcdf_file(’simple.nc’, ’w’) f.history = ’Created for a test’ f.createDimension(’time’, 10) time = f.createVariable(’time’, ’i’, (’time’,)) time[:] = np.arange(10) time.units = ’days since 2008-01-01’ f.close() Note the assignment of range(10) to time[:]. Exposing the slice of the time variable allows for the data to be set in the object, rather than letting range(10) overwrite the time variable. To read the NetCDF file we just created: >>> from scipy.io import netcdf >>> f = netcdf.netcdf_file(’simple.nc’, ’r’) >>> print(f.history) Created for a test >>> time = f.variables[’time’] >>> print(time.units) days since 2008-01-01 >>> print(time.shape) (10,) >>> print(time[-1]) 9 >>> f.close() A NetCDF file can also be used as context manager: >>> from scipy.io import netcdf >>> with netcdf.netcdf_file(’simple.nc’, ’r’) as f: >>> print(f.history) Created for a test Methods close() createDimension(name, length) createVariable(name, type, dimensions) 328 Closes the NetCDF file. Adds a dimension to the Dimension section of the NetCDF data structure. Create an empty variable for the netcdf_file object, specifying its data type and C Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Table 5.62 – continued from previous page Perform a sync-to-disk flush if the netcdf_file object is in write mode. Perform a sync-to-disk flush if the netcdf_file object is in write mode. flush() sync() netcdf_file.close() Closes the NetCDF file. netcdf_file.createDimension(name, length) Adds a dimension to the Dimension section of the NetCDF data structure. Note that this function merely adds a new dimension that the variables can reference. The values for the dimension, if desired, should be added as a variable using createVariable, referring to this dimension. Parameters name : str Name of the dimension (Eg, ‘lat’ or ‘time’). length : int Length of the dimension. See Also createVariable netcdf_file.createVariable(name, type, dimensions) Create an empty variable for the netcdf_file object, specifying its data type and the dimensions it uses. Parameters Returns name : str Name of the new variable. type : dtype or str Data type of the variable. dimensions : sequence of str List of the dimension names used by the variable, in the desired order. variable : netcdf_variable The newly created netcdf_variable object. This object has also been added to the netcdf_file object as well. See Also createDimension Notes Any dimensions to be used by the variable should already exist in the NetCDF data structure or should be created by createDimension prior to creating the NetCDF variable. netcdf_file.flush() Perform a sync-to-disk flush if the netcdf_file object is in write mode. See Also sync Identical function netcdf_file.sync() Perform a sync-to-disk flush if the netcdf_file object is in write mode. 5.8. Input and output (scipy.io) 329 SciPy Reference Guide, Release 0.13.0 See Also Identical function sync class scipy.io.netcdf.netcdf_variable(data, typecode, tributes=None) A data object for the netcdf module. size, shape, dimensions, at- netcdf_variable objects are constructed by calling the method netcdf_file.createVariable on the netcdf_file object. netcdf_variable objects behave much like array objects defined in numpy, except that their data resides in a file. Data is read by indexing and written by assigning to an indexed subset; the entire array can be accessed by the index [:] or (for scalars) by using the methods getValue and assignValue. netcdf_variable objects also have attribute shape with the same meaning as for arrays, but the shape cannot be modified. There is another read-only attribute dimensions, whose value is the tuple of dimension names. All other attributes correspond to variable attributes defined in the NetCDF file. Variable attributes are created by assigning to an attribute of the netcdf_variable object. Parameters data : array_like The data array that holds the values for the variable. Typically, this is initialized as empty, but with the proper shape. typecode : dtype character code Desired data-type for the data array. size : int Desired element size for the data array. shape : sequence of ints The shape of the array. This should match the lengths of the variable’s dimensions. dimensions : sequence of strings The names of the dimensions used by the variable. Must be in the same order of the dimension lengths given by shape. attributes : dict, optional Attribute values (any type) keyed by string names. These attributes become attributes for the netcdf_variable object. See Also isrec, shape Attributes dimensions isrec, shape (list of str) List of names of dimensions used by the variable object. Properties Methods assignValue(value) getValue() itemsize() typecode() Assign a scalar value to a netcdf_variable of length one. Retrieve a scalar value from a netcdf_variable of length one. Return the itemsize of the variable. Return the typecode of the variable. netcdf_variable.assignValue(value) Assign a scalar value to a netcdf_variable of length one. Parameters 330 value : scalar Scalar value (of compatible type) to assign to a length-one netcdf variable. This value will be written to file. Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Raises ValueError If the input is not a scalar, or if the destination is not a length-one netcdf variable. netcdf_variable.getValue() Retrieve a scalar value from a netcdf_variable of length one. Raises ValueError If the netcdf variable is an array of length greater than one, this exception will be raised. netcdf_variable.itemsize() Return the itemsize of the variable. Returns itemsize : int The element size of the variable (eg, 8 for float64). netcdf_variable.typecode() Return the typecode of the variable. Returns typecode : char The character typecode of the variable (eg, ‘i’ for int). 5.9 Linear algebra (scipy.linalg) Linear algebra functions. See Also numpy.linalg for more linear algebra functions. Note that although scipy.linalg imports most of them, identically named functions from scipy.linalg may offer more or slightly differing functionality. 5.9.1 Basics inv(a[, overwrite_a, check_finite]) solve(a, b[, sym_pos, lower, overwrite_a, ...]) solve_banded(l_and_u, ab, b[, overwrite_ab, ...]) solveh_banded(ab, b[, overwrite_ab, ...]) solve_triangular(a, b[, trans, lower, ...]) det(a[, overwrite_a, check_finite]) norm(a[, ord]) lstsq(a, b[, cond, overwrite_a, ...]) pinv(a[, cond, rcond, return_rank, check_finite]) pinv2(a[, cond, rcond, return_rank, ...]) pinvh(a[, cond, rcond, lower, return_rank, ...]) kron(a, b) tril(m[, k]) triu(m[, k]) Compute the inverse of a matrix. Solve the equation a x = b for x. Solve the equation a x = b for x, assuming a is banded matrix. Solve equation a x = b. Solve the equation a x = b for x, assuming a is a triangular matrix. Compute the determinant of a matrix Matrix or vector norm. Compute least-squares solution to equation Ax = b. Compute the (Moore-Penrose) pseudo-inverse of a matrix. Compute the (Moore-Penrose) pseudo-inverse of a matrix. Compute the (Moore-Penrose) pseudo-inverse of a Hermitian matrix. Kronecker product. Make a copy of a matrix with elements above the k-th diagonal zeroed. Make a copy of a matrix with elements below the k-th diagonal zeroed. scipy.linalg.inv(a, overwrite_a=False, check_finite=True) Compute the inverse of a matrix. Parameters a : array_like Square matrix to be inverted. overwrite_a : bool, optional 5.9. Linear algebra (scipy.linalg) 331 SciPy Reference Guide, Release 0.13.0 Returns Raises Discard data in a (may improve performance). Default is False. check_finite : boolean, optional Whether to check that the input matrix contains only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. ainv : ndarray Inverse of the matrix a. LinAlgError : If a is singular. ValueError : If a is not square, or not 2-dimensional. Examples >>> a = np.array([[1., 2.], [3., 4.]]) >>> sp.linalg.inv(a) array([[-2. , 1. ], [ 1.5, -0.5]]) >>> np.dot(a, sp.linalg.inv(a)) array([[ 1., 0.], [ 0., 1.]]) scipy.linalg.solve(a, b, sym_pos=False, lower=False, overwrite_a=False, overwrite_b=False, debug=False, check_finite=True) Solve the equation a x = b for x. Parameters Returns Raises a : (M, M) array_like A square matrix. b : (M,) or (M, N) array_like Right-hand side matrix in a x = b. sym_pos : bool Assume a is symmetric and positive definite. lower : boolean Use only data contained in the lower triangle of a, if sym_pos is true. Default is to use upper triangle. overwrite_a : bool Allow overwriting data in a (may enhance performance). Default is False. overwrite_b : bool Allow overwriting data in b (may enhance performance). Default is False. check_finite : boolean, optional Whether to check that the input matrices contain only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. x : (M,) or (M, N) ndarray Solution to the system a x = b. Shape of the return matches the shape of b. LinAlgError If a is singular. Examples Given a and b, solve for x: >>> a = >>> b = >>> x = >>> x array([ 332 np.array([[3,2,0],[1,-1,0],[0,5,1]]) np.array([2,4,-1]) linalg.solve(a,b) 2., -2., 9.]) Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 >>> np.dot(a, x) == b array([ True, True, True], dtype=bool) scipy.linalg.solve_banded(l_and_u, ab, b, overwrite_ab=False, overwrite_b=False, debug=False, check_finite=True) Solve the equation a x = b for x, assuming a is banded matrix. The matrix a is stored in ab using the matrix diagonal ordered form: ab[u + i - j, j] == a[i,j] Example of ab (shape of a is (6,6), u =1, l =2): * a00 a10 a20 a01 a11 a21 a31 a12 a22 a32 a42 Parameters Returns a23 a33 a43 a53 a34 a44 a54 * a45 a55 * * (l, u) : (integer, integer) Number of non-zero lower and upper diagonals ab : (l + u + 1, M) array_like Banded matrix b : (M,) or (M, K) array_like Right-hand side overwrite_ab : boolean, optional Discard data in ab (may enhance performance) overwrite_b : boolean, optional Discard data in b (may enhance performance) check_finite : boolean, optional Whether to check that the input matrices contain only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. x : (M,) or (M, K) ndarray The solution to the system a x = b. Returned shape depends on the shape of b. scipy.linalg.solveh_banded(ab, b, overwrite_ab=False, overwrite_b=False, check_finite=True) Solve equation a x = b. a is Hermitian positive-definite banded matrix. lower=False, The matrix a is stored in ab either in lower diagonal or upper diagonal ordered form: ab[u + i - j, j] == a[i,j] (if upper form; i <= j) ab[ i - j, j] == a[i,j] (if lower form; i >= j) Example of ab (shape of a is (6,6), u =2): upper form: a02 a13 a24 a35 * * a01 a12 a23 a34 a45 * a00 a11 a22 a33 a44 a55 lower form: a00 a11 a22 a33 a44 a55 a10 a21 a32 a43 a54 * a20 a31 a42 a53 * * Cells marked with * are not used. Parameters ab : (u + 1, M) array_like Banded matrix 5.9. Linear algebra (scipy.linalg) 333 SciPy Reference Guide, Release 0.13.0 Returns b : (M,) or (M, K) array_like Right-hand side overwrite_ab : bool, optional Discard data in ab (may enhance performance) overwrite_b : bool, optional Discard data in b (may enhance performance) lower : bool, optional Is the matrix in the lower form. (Default is upper form) check_finite : boolean, optional Whether to check that the input matrices contain only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. x : (M,) or (M, K) ndarray The solution to the system a x = b. Shape of return matches shape of b. scipy.linalg.solve_triangular(a, b, trans=0, lower=False, unit_diagonal=False, write_b=False, debug=False, check_finite=True) Solve the equation a x = b for x, assuming a is a triangular matrix. Parameters Returns Raises over- a : (M, M) array_like A triangular matrix b : (M,) or (M, N) array_like Right-hand side matrix in a x = b lower : boolean Use only data contained in the lower triangle of a. Default is to use upper triangle. trans : {0, 1, 2, ‘N’, ‘T’, ‘C’}, optional Type of system to solve: trans system 0 or ‘N’ a x = b 1 or ‘T’ a^T x = b 2 or ‘C’ a^H x = b unit_diagonal : bool, optional If True, diagonal elements of a are assumed to be 1 and will not be referenced. overwrite_b : bool, optional Allow overwriting data in b (may enhance performance) check_finite : bool, optional Whether to check that the input matrices contain only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. x : (M,) or (M, N) ndarray Solution to the system a x = b. Shape of return matches b. LinAlgError If a is singular Notes New in version 0.9.0. scipy.linalg.det(a, overwrite_a=False, check_finite=True) Compute the determinant of a matrix The determinant of a square matrix is a value derived arithmetically from the coefficients of the matrix. The determinant for a 3x3 matrix, for example, is computed as follows: 334 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 a d g b e h c f = A i det(A) = a*e*i + b*f*g + c*d*h - c*e*g - b*d*i - a*f*h Parameters Returns a : (M, M) array_like A square matrix. overwrite_a : bool Allow overwriting data in a (may enhance performance). check_finite : boolean, optional Whether to check that the input matrix contains only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. det : float or complex Determinant of a. Notes The determinant is computed via LU factorization, LAPACK routine z/dgetrf. Examples >>> >>> 0.0 >>> >>> 3.0 a = np.array([[1,2,3],[4,5,6],[7,8,9]]) linalg.det(a) a = np.array([[0,2,3],[4,5,6],[7,8,9]]) linalg.det(a) scipy.linalg.norm(a, ord=None) Matrix or vector norm. This function is able to return one of seven different matrix norms, or one of an infinite number of vector norms (described below), depending on the value of the ord parameter. Parameters Returns x : {(M,), (M, N)} array_like Input array. ord : {non-zero int, inf, -inf, ‘fro’}, optional Order of the norm (see table under Notes). inf means numpy’s inf object. n : float Norm of the matrix or vector. Notes For values of ord <= 0, the result is, strictly speaking, not a mathematical ‘norm’, but it may still be useful for various numerical purposes. The following norms can be calculated: 5.9. Linear algebra (scipy.linalg) 335 SciPy Reference Guide, Release 0.13.0 ord None ‘fro’ inf -inf 0 1 -1 2 -2 other norm for matrices Frobenius norm Frobenius norm max(sum(abs(x), axis=1)) min(sum(abs(x), axis=1)) – max(sum(abs(x), axis=0)) min(sum(abs(x), axis=0)) 2-norm (largest sing. value) smallest singular value – norm for vectors 2-norm – max(abs(x)) min(abs(x)) sum(x != 0) as below as below as below as below sum(abs(x)**ord)**(1./ord) The Frobenius norm is given by [R63]: P ||A||F = [ i,j abs(ai,j )2 ]1/2 References [R63] Examples >>> from numpy import linalg as LA >>> a = np.arange(9) - 4 >>> a array([-4, -3, -2, -1, 0, 1, 2, >>> b = a.reshape((3, 3)) >>> b array([[-4, -3, -2], [-1, 0, 1], [ 2, 3, 4]]) 3, 4]) >>> LA.norm(a) 7.745966692414834 >>> LA.norm(b) 7.745966692414834 >>> LA.norm(b, ’fro’) 7.745966692414834 >>> LA.norm(a, np.inf) 4 >>> LA.norm(b, np.inf) 9 >>> LA.norm(a, -np.inf) 0 >>> LA.norm(b, -np.inf) 2 >>> LA.norm(a, 1) 20 >>> LA.norm(b, 1) 7 >>> LA.norm(a, -1) -4.6566128774142013e-010 >>> LA.norm(b, -1) 6 >>> LA.norm(a, 2) 7.745966692414834 >>> LA.norm(b, 2) 7.3484692283495345 336 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 >>> LA.norm(a, -2) nan >>> LA.norm(b, -2) 1.8570331885190563e-016 >>> LA.norm(a, 3) 5.8480354764257312 >>> LA.norm(a, -3) nan scipy.linalg.lstsq(a, b, cond=None, overwrite_a=False, overwrite_b=False, check_finite=True) Compute least-squares solution to equation Ax = b. Compute a vector x such that the 2-norm |b - A x| is minimized. Parameters Returns Raises a : (M, N) array_like Left hand side matrix (2-D array). b : (M,) or (M, K) array_like Right hand side matrix or vector (1-D or 2-D array). cond : float, optional Cutoff for ‘small’ singular values; used to determine effective rank of a. Singular values smaller than rcond * largest_singular_value are considered zero. overwrite_a : bool, optional Discard data in a (may enhance performance). Default is False. overwrite_b : bool, optional Discard data in b (may enhance performance). Default is False. check_finite : boolean, optional Whether to check that the input matrices contain only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. x : (N,) or (N, K) ndarray Least-squares solution. Return shape matches shape of b. residues : () or (1,) or (K,) ndarray Sums of residues, squared 2-norm for each column in b - a x. If rank of matrix a is < N or > M this is an empty array. If b was 1-D, this is an (1,) shape array, otherwise the shape is (K,). rank : int Effective rank of matrix a. s : (min(M,N),) ndarray Singular values of a. The condition number of a is abs(s[0]/s[-1]). LinAlgError : If computation does not converge. See Also optimize.nnls linear least squares with non-negativity constraint scipy.linalg.pinv(a, cond=None, rcond=None, return_rank=False, check_finite=True) Compute the (Moore-Penrose) pseudo-inverse of a matrix. Calculate a generalized inverse of a matrix using a least-squares solver. Parameters a : (M, N) array_like Matrix to be pseudo-inverted. cond, rcond : float, optional Cutoff for ‘small’ singular values in the least-squares solver. Singular values smaller than rcond * largest_singular_value are considered zero. 5.9. Linear algebra (scipy.linalg) 337 SciPy Reference Guide, Release 0.13.0 Returns Raises return_rank : bool, optional if True, return the effective rank of the matrix check_finite : boolean, optional Whether to check that the input matrix contains only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. B : (N, M) ndarray The pseudo-inverse of matrix a. rank : int The effective rank of the matrix. Returned if return_rank == True LinAlgError If computation does not converge. Examples >>> a = np.random.randn(9, 6) >>> B = linalg.pinv(a) >>> np.allclose(a, dot(a, dot(B, a))) True >>> np.allclose(B, dot(B, dot(a, B))) True scipy.linalg.pinv2(a, cond=None, rcond=None, return_rank=False, check_finite=True) Compute the (Moore-Penrose) pseudo-inverse of a matrix. Calculate a generalized inverse of a matrix using its singular-value decomposition and including all ‘large’ singular values. Parameters Returns Raises a : (M, N) array_like Matrix to be pseudo-inverted. cond, rcond : float or None Cutoff for ‘small’ singular values. Singular values smaller than rcond*largest_singular_value are considered zero. If None or -1, suitable machine precision is used. return_rank : bool, optional if True, return the effective rank of the matrix check_finite : boolean, optional Whether to check that the input matrix contains only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. B : (N, M) ndarray The pseudo-inverse of matrix a. rank : int The effective rank of the matrix. Returned if return_rank == True LinAlgError If SVD computation does not converge. Examples >>> a = np.random.randn(9, 6) >>> B = linalg.pinv2(a) >>> np.allclose(a, dot(a, dot(B, a))) True >>> np.allclose(B, dot(B, dot(a, B))) True 338 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 scipy.linalg.pinvh(a, cond=None, rcond=None, lower=True, return_rank=False, check_finite=True) Compute the (Moore-Penrose) pseudo-inverse of a Hermitian matrix. Calculate a generalized inverse of a Hermitian or real symmetric matrix using its eigenvalue decomposition and including all eigenvalues with ‘large’ absolute value. Parameters Returns Raises a : (N, N) array_like Real symmetric or complex hermetian matrix to be pseudo-inverted cond, rcond : float or None Cutoff for ‘small’ eigenvalues. Singular values smaller than rcond * largest_eigenvalue are considered zero. If None or -1, suitable machine precision is used. lower : bool Whether the pertinent array data is taken from the lower or upper triangle of a. (Default: lower) return_rank : bool, optional if True, return the effective rank of the matrix check_finite : boolean, optional Whether to check that the input matrix contains only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. B : (N, N) ndarray The pseudo-inverse of matrix a. rank : int The effective rank of the matrix. Returned if return_rank == True LinAlgError If eigenvalue does not converge Examples >>> from numpy import * >>> a = random.randn(9, 6) >>> a = np.dot(a, a.T) >>> B = pinvh(a) >>> allclose(a, dot(a, dot(B, a))) True >>> allclose(B, dot(B, dot(a, B))) True scipy.linalg.kron(a, b) Kronecker product. The result is the block matrix: a[0,0]*b a[1,0]*b ... a[-1,0]*b a[0,1]*b a[1,1]*b a[-1,1]*b ... a[-1,-1]*b Parameters Returns ... a[0,-1]*b ... a[1,-1]*b a : (M, N) ndarray Input array b : (P, Q) ndarray Input array A : (M*P, N*Q) ndarray Kronecker product of a and b. 5.9. Linear algebra (scipy.linalg) 339 SciPy Reference Guide, Release 0.13.0 Examples >>> from numpy import array >>> from scipy.linalg import kron >>> kron(array([[1,2],[3,4]]), array([[1,1,1]])) array([[1, 1, 1, 2, 2, 2], [3, 3, 3, 4, 4, 4]]) scipy.linalg.tril(m, k=0) Make a copy of a matrix with elements above the k-th diagonal zeroed. Parameters Returns m : array_like Matrix whose elements to return k : integer Diagonal above which to zero elements. k == 0 is the main diagonal, k < 0 subdiagonal and k > 0 superdiagonal. tril : ndarray Return is the same shape and type as m. Examples >>> from scipy.linalg import tril >>> tril([[1,2,3],[4,5,6],[7,8,9],[10,11,12]], -1) array([[ 0, 0, 0], [ 4, 0, 0], [ 7, 8, 0], [10, 11, 12]]) scipy.linalg.triu(m, k=0) Make a copy of a matrix with elements below the k-th diagonal zeroed. Parameters Returns m : array_like Matrix whose elements to return k : int, optional Diagonal below which to zero elements. k == 0 is the main diagonal, k < 0 subdiagonal and k > 0 superdiagonal. triu : ndarray Return matrix with zeroed elements below the k-th diagonal and has same shape and type as m. Examples >>> from scipy.linalg import triu >>> triu([[1,2,3],[4,5,6],[7,8,9],[10,11,12]], -1) array([[ 1, 2, 3], [ 4, 5, 6], [ 0, 8, 9], [ 0, 0, 12]]) 5.9.2 Eigenvalue Problems eig(a[, b, left, right, overwrite_a, ...]) eigvals(a[, b, overwrite_a, check_finite]) eigh(a[, b, lower, eigvals_only, ...]) eigvalsh(a[, b, lower, overwrite_a, ...]) 340 Solve an ordinary or generalized eigenvalue problem of a square matrix. Compute eigenvalues from an ordinary or generalized eigenvalue problem. Solve an ordinary or generalized eigenvalue problem for a complex Solve an ordinary or generalized eigenvalue problem for a complex Continued on next page Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Table 5.65 – continued from previous page eig_banded(a_band[, lower, eigvals_only, ...]) Solve real symmetric or complex hermitian band matrix eigenvalue problem. eigvals_banded(a_band[, lower, ...]) Solve real symmetric or complex hermitian band matrix eigenvalue problem. scipy.linalg.eig(a, b=None, left=False, right=True, overwrite_a=False, check_finite=True) Solve an ordinary or generalized eigenvalue problem of a square matrix. overwrite_b=False, Find eigenvalues w and right or left eigenvectors of a general matrix: a vr[:,i] = w[i] b vr[:,i] a.H vl[:,i] = w[i].conj() b.H vl[:,i] where .H is the Hermitian conjugation. Parameters Returns Raises a : (M, M) array_like A complex or real matrix whose eigenvalues and eigenvectors will be computed. b : (M, M) array_like, optional Right-hand side matrix in a generalized eigenvalue problem. Default is None, identity matrix is assumed. left : bool, optional Whether to calculate and return left eigenvectors. Default is False. right : bool, optional Whether to calculate and return right eigenvectors. Default is True. overwrite_a : bool, optional Whether to overwrite a; may improve performance. Default is False. overwrite_b : bool, optional Whether to overwrite b; may improve performance. Default is False. check_finite : boolean, optional Whether to check that the input matrices contain only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. w : (M,) double or complex ndarray The eigenvalues, each repeated according to its multiplicity. vl : (M, M) double or complex ndarray The normalized left eigenvector corresponding to the eigenvalue w[i] is the column v[:,i]. Only returned if left=True. vr : (M, M) double or complex ndarray The normalized right eigenvector corresponding to the eigenvalue w[i] is the column vr[:,i]. Only returned if right=True. LinAlgError If eigenvalue computation does not converge. See Also eigh Eigenvalues and right eigenvectors for symmetric/Hermitian arrays. scipy.linalg.eigvals(a, b=None, overwrite_a=False, check_finite=True) Compute eigenvalues from an ordinary or generalized eigenvalue problem. Find eigenvalues of a general matrix: a vr[:,i] = w[i] Parameters b vr[:,i] a : (M, M) array_like A complex or real matrix whose eigenvalues and eigenvectors will be computed. 5.9. Linear algebra (scipy.linalg) 341 SciPy Reference Guide, Release 0.13.0 b : (M, M) array_like, optional Right-hand side matrix in a generalized eigenvalue problem. If omitted, identity matrix is assumed. overwrite_a : boolean, optional Whether to overwrite data in a (may improve performance) check_finite : boolean, optional Whether to check that the input matrices contain only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. w : (M,) double or complex ndarray The eigenvalues, each repeated according to its multiplicity, but not in any specific order. LinAlgError If eigenvalue computation does not converge Returns Raises See Also eigvalsh eigenvalues of symmetric or Hermitian arrays, eig eigenvalues and right eigenvectors of general arrays. eigh eigenvalues and eigenvectors of symmetric/Hermitian arrays. scipy.linalg.eigh(a, b=None, lower=True, eigvals_only=False, overwrite_a=False, overwrite_b=False, turbo=True, eigvals=None, type=1, check_finite=True) Solve an ordinary or generalized eigenvalue problem for a complex Hermitian or real symmetric matrix. Find eigenvalues w and optionally eigenvectors v of matrix a, where b is positive definite: a v[:,i] = w[i] b v[:,i] v[i,:].conj() a v[:,i] = w[i] v[i,:].conj() b v[:,i] = 1 Parameters 342 a : (M, M) array_like A complex Hermitian or real symmetric matrix whose eigenvalues and eigenvectors will be computed. b : (M, M) array_like, optional A complex Hermitian or real symmetric definite positive matrix in. If omitted, identity matrix is assumed. lower : bool, optional Whether the pertinent array data is taken from the lower or upper triangle of a. (Default: lower) eigvals_only : bool, optional Whether to calculate only eigenvalues and no eigenvectors. (Default: both are calculated) turbo : bool, optional Use divide and conquer algorithm (faster but expensive in memory, only for generalized eigenvalue problem and if eigvals=None) eigvals : tuple (lo, hi), optional Indexes of the smallest and largest (in ascending order) eigenvalues and corresponding eigenvectors to be returned: 0 <= lo <= hi <= M-1. If omitted, all eigenvalues and eigenvectors are returned. type : int, optional Specifies the problem type to be solved: Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 type = 1: a v[:,i] = w[i] b v[:,i] type = 2: a b v[:,i] = w[i] v[:,i] type = 3: b a v[:,i] = w[i] v[:,i] overwrite_a : bool, optional Whether to overwrite data in a (may improve performance) overwrite_b : bool, optional Whether to overwrite data in b (may improve performance) check_finite : boolean, optional Whether to check that the input matrices contain only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. w : (N,) float ndarray The N (1<=N<=M) selected eigenvalues, in ascending order, each repeated according to its multiplicity. v : (M, N) complex ndarray (if eigvals_only == False) The normalized selected eigenvector corresponding to the eigenvalue w[i] is the column v[:,i]. Normalization: type 1 and 3: v.conj() a v = w type 2: inv(v).conj() a inv(v) = w type = 1 or 2: v.conj() b v = I type = 3: v.conj() inv(b) v = I LinAlgError : If eigenvalue computation does not converge, an error occurred, or b matrix is not definite positive. Note that if input matrices are not symmetric or hermitian, no error is reported but results will be wrong. Returns Raises See Also eig eigenvalues and right eigenvectors for non-symmetric arrays scipy.linalg.eigvalsh(a, b=None, lower=True, overwrite_a=False, overwrite_b=False, turbo=True, eigvals=None, type=1, check_finite=True) Solve an ordinary or generalized eigenvalue problem for a complex Hermitian or real symmetric matrix. Find eigenvalues w of matrix a, where b is positive definite: a v[:,i] = w[i] b v[:,i] v[i,:].conj() a v[:,i] = w[i] v[i,:].conj() b v[:,i] = 1 Parameters a : (M, M) array_like A complex Hermitian or real symmetric matrix whose eigenvalues and eigenvectors will be computed. b : (M, M) array_like, optional A complex Hermitian or real symmetric definite positive matrix in. If omitted, identity matrix is assumed. lower : bool, optional Whether the pertinent array data is taken from the lower or upper triangle of a. (Default: lower) turbo : bool, optional Use divide and conquer algorithm (faster but expensive in memory, only for generalized eigenvalue problem and if eigvals=None) eigvals : tuple (lo, hi), optional 5.9. Linear algebra (scipy.linalg) 343 SciPy Reference Guide, Release 0.13.0 Returns Raises Indexes of the smallest and largest (in ascending order) eigenvalues and corresponding eigenvectors to be returned: 0 <= lo < hi <= M-1. If omitted, all eigenvalues and eigenvectors are returned. type : integer, optional Specifies the problem type to be solved: type = 1: a v[:,i] = w[i] b v[:,i] type = 2: a b v[:,i] = w[i] v[:,i] type = 3: b a v[:,i] = w[i] v[:,i] overwrite_a : bool, optional Whether to overwrite data in a (may improve performance) overwrite_b : bool, optional Whether to overwrite data in b (may improve performance) check_finite : boolean, optional Whether to check that the input matrices contain only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. w : (N,) float ndarray The N (1<=N<=M) selected eigenvalues, in ascending order, each repeated according to its multiplicity. LinAlgError : If eigenvalue computation does not converge, an error occurred, or b matrix is not definite positive. Note that if input matrices are not symmetric or hermitian, no error is reported but results will be wrong. See Also eigvals eigenvalues of general arrays eigh eigenvalues and right eigenvectors for symmetric/Hermitian arrays eig eigenvalues and right eigenvectors for non-symmetric arrays scipy.linalg.eig_banded(a_band, lower=False, eigvals_only=False, overwrite_a_band=False, select=’a’, select_range=None, max_ev=0, check_finite=True) Solve real symmetric or complex hermitian band matrix eigenvalue problem. Find eigenvalues w and optionally right eigenvectors v of a: a v[:,i] = w[i] v[:,i] v.H v = identity The matrix a is stored in a_band either in lower diagonal or upper diagonal ordered form: a_band[u + i - j, j] == a[i,j] (if upper form; i <= j) a_band[ i - j, j] == a[i,j] (if lower form; i >= j) where u is the number of bands above the diagonal. Example of a_band (shape of a is (6,6), u=2): upper form: a02 a13 a24 a35 * * a01 a12 a23 a34 a45 * a00 a11 a22 a33 a44 a55 lower form: a00 a11 a22 a33 a44 a55 a10 a21 a32 a43 a54 * a20 a31 a42 a53 * * Cells marked with * are not used. 344 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Parameters Returns a_band : (u+1, M) array_like The bands of the M by M matrix a. lower : bool, optional Is the matrix in the lower form. (Default is upper form) eigvals_only : bool, optional Compute only the eigenvalues and no eigenvectors. (Default: calculate also eigenvectors) overwrite_a_band : bool, optional Discard data in a_band (may enhance performance) select : {‘a’, ‘v’, ‘i’}, optional Which eigenvalues to calculate select calculated ‘a’ All eigenvalues ‘v’ Eigenvalues in the interval (min, max] ‘i’ Eigenvalues with indices min <= i <= max select_range : (min, max), optional Range of selected eigenvalues max_ev : int, optional For select==’v’, maximum number of eigenvalues expected. For other values of select, has no meaning. In doubt, leave this parameter untouched. check_finite : boolean, optional Whether to check that the input matrix contains only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. w : (M,) ndarray The eigenvalues, in ascending order, each repeated according to its multiplicity. v : (M, M) float or complex ndarray The normalized eigenvector corresponding to the eigenvalue w[i] is the column v[:,i]. Raises LinAlgError if eigenvalue computation does not converge scipy.linalg.eigvals_banded(a_band, lower=False, overwrite_a_band=False, select=’a’, select_range=None, check_finite=True) Solve real symmetric or complex hermitian band matrix eigenvalue problem. Find eigenvalues w of a: a v[:,i] = w[i] v[:,i] v.H v = identity The matrix a is stored in a_band either in lower diagonal or upper diagonal ordered form: a_band[u + i - j, j] == a[i,j] (if upper form; i <= j) a_band[ i - j, j] == a[i,j] (if lower form; i >= j) where u is the number of bands above the diagonal. Example of a_band (shape of a is (6,6), u=2): upper form: a02 a13 a24 a35 * * a01 a12 a23 a34 a45 * a00 a11 a22 a33 a44 a55 lower form: a00 a11 a22 a33 a44 a55 a10 a21 a32 a43 a54 * a20 a31 a42 a53 * * Cells marked with * are not used. 5.9. Linear algebra (scipy.linalg) 345 SciPy Reference Guide, Release 0.13.0 Parameters Returns a_band : (u+1, M) array_like The bands of the M by M matrix a. lower : boolean Is the matrix in the lower form. (Default is upper form) overwrite_a_band: Discard data in a_band (may enhance performance) select : {‘a’, ‘v’, ‘i’} Which eigenvalues to calculate select calculated ‘a’ All eigenvalues ‘v’ Eigenvalues in the interval (min, max] ‘i’ Eigenvalues with indices min <= i <= max select_range : (min, max) Range of selected eigenvalues check_finite : boolean, optional Whether to check that the input matrix contains only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. w : (M,) ndarray The eigenvalues, in ascending order, each repeated according to its multiplicity. Raises LinAlgError if eigenvalue computation does not converge See Also eig_bandedeigenvalues and right eigenvectors for symmetric/Hermitian band matrices eigvals eigenvalues of general arrays eigh eigenvalues and right eigenvectors for symmetric/Hermitian arrays eig eigenvalues and right eigenvectors for non-symmetric arrays 5.9.3 Decompositions lu(a[, permute_l, overwrite_a, check_finite]) lu_factor(a[, overwrite_a, check_finite]) lu_solve(lu_and_piv, b[, trans, ...]) svd(a[, full_matrices, compute_uv, ...]) svdvals(a[, overwrite_a, check_finite]) diagsvd(s, M, N) orth(A) cholesky(a[, lower, overwrite_a, check_finite]) cholesky_banded(ab[, overwrite_ab, lower, ...]) cho_factor(a[, lower, overwrite_a, check_finite]) cho_solve(c_and_lower, b[, overwrite_b, ...]) cho_solve_banded(cb_and_lower, b[, ...]) polar(a[, side]) qr(a[, overwrite_a, lwork, mode, pivoting, ...]) qr_multiply(a, c[, mode, pivoting, ...]) qz(A, B[, output, lwork, sort, overwrite_a, ...]) schur(a[, output, lwork, overwrite_a, sort, ...]) rsf2csf(T, Z[, check_finite]) hessenberg(a[, calc_q, overwrite_a, ...]) 346 Compute pivoted LU decompostion of a matrix. Compute pivoted LU decomposition of a matrix. Solve an equation system, a x = b, given the LU factorization of a Singular Value Decomposition. Compute singular values of a matrix. Construct the sigma matrix in SVD from singular values and size M, N. Construct an orthonormal basis for the range of A using SVD Compute the Cholesky decomposition of a matrix. Cholesky decompose a banded Hermitian positive-definite matrix Compute the Cholesky decomposition of a matrix, to use in cho_solve Solve the linear equations A x = b, given the Cholesky factorization of A. Solve the linear equations A x = b, given the Cholesky factorization of A. Compute the polar decomposition. Compute QR decomposition of a matrix. Calculate the QR decomposition and multiply Q with a matrix. QZ decompostion for generalized eigenvalues of a pair of matrices. Compute Schur decomposition of a matrix. Convert real Schur form to complex Schur form. Compute Hessenberg form of a matrix. Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 scipy.linalg.lu(a, permute_l=False, overwrite_a=False, check_finite=True) Compute pivoted LU decompostion of a matrix. The decomposition is: A = P L U where P is a permutation matrix, L lower triangular with unit diagonal elements, and U upper triangular. Parameters Returns a : (M, N) array_like Array to decompose permute_l : bool Perform the multiplication P*L (Default: do not permute) overwrite_a : bool Whether to overwrite data in a (may improve performance) check_finite : boolean, optional Whether to check that the input matrix contains only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. (If permute_l == False) p : (M, M) ndarray Permutation matrix l : (M, K) ndarray Lower triangular or trapezoidal matrix with unit diagonal. K = min(M, N) u : (K, N) ndarray Upper triangular or trapezoidal matrix (If permute_l == True) pl : (M, K) ndarray Permuted L matrix. K = min(M, N) u : (K, N) ndarray Upper triangular or trapezoidal matrix Notes This is a LU factorization routine written for Scipy. scipy.linalg.lu_factor(a, overwrite_a=False, check_finite=True) Compute pivoted LU decomposition of a matrix. The decomposition is: A = P L U where P is a permutation matrix, L lower triangular with unit diagonal elements, and U upper triangular. Parameters Returns a : (M, M) array_like Matrix to decompose overwrite_a : boolean Whether to overwrite data in A (may increase performance) check_finite : boolean, optional Whether to check that the input matrix contains only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. lu : (N, N) ndarray Matrix containing U in its upper triangle, and L in its lower triangle. The unit diagonal elements of L are not stored. piv : (N,) ndarray Pivot indices representing the permutation matrix P: row i of matrix was interchanged with row piv[i]. 5.9. Linear algebra (scipy.linalg) 347 SciPy Reference Guide, Release 0.13.0 See Also lu_solve solve an equation system using the LU factorization of a matrix Notes This is a wrapper to the *GETRF routines from LAPACK. scipy.linalg.lu_solve(lu_and_piv, b, trans=0, overwrite_b=False, check_finite=True) Solve an equation system, a x = b, given the LU factorization of a Parameters Returns (lu, piv) Factorization of the coefficient matrix a, as given by lu_factor b : array Right-hand side trans : {0, 1, 2} Type of system to solve: trans system 0 ax=b 1 a^T x = b 2 a^H x = b check_finite : boolean, optional Whether to check that the input matrices contain only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. x : array Solution to the system See Also lu_factor LU factorize a matrix scipy.linalg.svd(a, full_matrices=True, compute_uv=True, overwrite_a=False, check_finite=True) Singular Value Decomposition. Factorizes the matrix a into two unitary matrices U and Vh, and a 1-D array s of singular values (real, nonnegative) such that a == U*S*Vh, where S is a suitably shaped matrix of zeros with main diagonal s. Parameters Returns 348 a : (M, N) array_like Matrix to decompose. full_matrices : bool, optional If True, U and Vh are of shape (M,M), (N,N). If False, the shapes are (M,K) and (K,N), where K = min(M,N). compute_uv : bool, optional Whether to compute also U and Vh in addition to s. Default is True. overwrite_a : bool, optional Whether to overwrite a; may improve performance. Default is False. check_finite : boolean, optional Whether to check that the input matrix contains only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. U : ndarray Unitary matrix having left singular vectors as columns. Of shape (M,M) or (M,K), depending on full_matrices. s : ndarray The singular values, sorted in non-increasing order. Of shape (K,), with K = min(M, N). Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Vh : ndarray Unitary matrix having right singular vectors as rows. Of shape (N,N) or (K,N) depending on full_matrices. For compute_uv = False, only s is returned. LinAlgError If SVD computation does not converge. Raises See Also svdvals Compute singular values of a matrix. diagsvd Construct the Sigma matrix, given the vector s. Examples >>> from scipy import linalg >>> a = np.random.randn(9, 6) + 1.j*np.random.randn(9, 6) >>> U, s, Vh = linalg.svd(a) >>> U.shape, Vh.shape, s.shape ((9, 9), (6, 6), (6,)) >>> U, s, Vh = linalg.svd(a, full_matrices=False) >>> U.shape, Vh.shape, s.shape ((9, 6), (6, 6), (6,)) >>> S = linalg.diagsvd(s, 6, 6) >>> np.allclose(a, np.dot(U, np.dot(S, Vh))) True >>> s2 = linalg.svd(a, compute_uv=False) >>> np.allclose(s, s2) True scipy.linalg.svdvals(a, overwrite_a=False, check_finite=True) Compute singular values of a matrix. Parameters Returns Raises a : (M, N) array_like Matrix to decompose. overwrite_a : bool, optional Whether to overwrite a; may improve performance. Default is False. check_finite : boolean, optional Whether to check that the input matrix contains only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. s : (min(M, N),) ndarray The singular values, sorted in decreasing order. LinAlgError If SVD computation does not converge. See Also svd Compute the full singular value decomposition of a matrix. diagsvd Construct the Sigma matrix, given the vector s. scipy.linalg.diagsvd(s, M, N) Construct the sigma matrix in SVD from singular values and size M, N. Parameters s : (M,) or (N,) array_like Singular values 5.9. Linear algebra (scipy.linalg) 349 SciPy Reference Guide, Release 0.13.0 M : int Size of the matrix whose singular values are s. N : int Size of the matrix whose singular values are s. S : (M, N) ndarray The S-matrix in the singular value decomposition Returns scipy.linalg.orth(A) Construct an orthonormal basis for the range of A using SVD Parameters Returns A : (M, N) ndarray Input array Q : (M, K) ndarray Orthonormal basis for the range of A. K = effective rank of A, as determined by automatic cutoff See Also Singular value decomposition of a matrix svd scipy.linalg.cholesky(a, lower=False, overwrite_a=False, check_finite=True) Compute the Cholesky decomposition of a matrix. Returns the Cholesky decomposition, A = LL∗ or A = U ∗ U of a Hermitian positive-definite matrix A. Parameters Returns Raises a : (M, M) array_like Matrix to be decomposed lower : bool Whether to compute the upper or lower triangular Cholesky factorization. Default is upper-triangular. overwrite_a : bool Whether to overwrite data in a (may improve performance). check_finite : boolean, optional Whether to check that the input matrix contains only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. c : (M, M) ndarray Upper- or lower-triangular Cholesky factor of a. LinAlgError : if decomposition fails. Examples >>> from scipy import array, linalg, dot >>> a = array([[1,-2j],[2j,5]]) >>> L = linalg.cholesky(a, lower=True) >>> L array([[ 1.+0.j, 0.+0.j], [ 0.+2.j, 1.+0.j]]) >>> dot(L, L.T.conj()) array([[ 1.+0.j, 0.-2.j], [ 0.+2.j, 5.+0.j]]) scipy.linalg.cholesky_banded(ab, overwrite_ab=False, lower=False, check_finite=True) Cholesky decompose a banded Hermitian positive-definite matrix The matrix a is stored in ab either in lower diagonal or upper diagonal ordered form: ab[u + i - j, j] == a[i,j] (if upper form; i <= j) ab[ i - j, j] == a[i,j] (if lower form; i >= j) 350 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Example of ab (shape of a is (6,6), u=2): upper form: a02 a13 a24 a35 * * a01 a12 a23 a34 a45 * a00 a11 a22 a33 a44 a55 lower form: a00 a11 a22 a33 a44 a55 a10 a21 a32 a43 a54 * a20 a31 a42 a53 * * Parameters Returns ab : (u + 1, M) array_like Banded matrix overwrite_ab : boolean Discard data in ab (may enhance performance) lower : boolean Is the matrix in the lower form. (Default is upper form) check_finite : boolean, optional Whether to check that the input matrix contains only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. c : (u + 1, M) ndarray Cholesky factorization of a, in the same banded format as ab scipy.linalg.cho_factor(a, lower=False, overwrite_a=False, check_finite=True) Compute the Cholesky decomposition of a matrix, to use in cho_solve Returns a matrix containing the Cholesky decomposition, A = L L* or A = U* U of a Hermitian positivedefinite matrix a. The return value can be directly used as the first parameter to cho_solve. Warning: The returned matrix also contains random data in the entries not used by the Cholesky decomposition. If you need to zero these entries, use the function cholesky instead. Parameters Returns Raises a : (M, M) array_like Matrix to be decomposed lower : boolean Whether to compute the upper or lower triangular Cholesky factorization (Default: upper-triangular) overwrite_a : boolean Whether to overwrite data in a (may improve performance) check_finite : boolean, optional Whether to check that the input matrix contains only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. c : (M, M) ndarray Matrix whose upper or lower triangle contains the Cholesky factor of a. Other parts of the matrix contain random data. lower : boolean Flag indicating whether the factor is in the lower or upper triangle LinAlgError Raised if decomposition fails. 5.9. Linear algebra (scipy.linalg) 351 SciPy Reference Guide, Release 0.13.0 See Also cho_solve Solve a linear set equations using the Cholesky factorization of a matrix. scipy.linalg.cho_solve(c_and_lower, b, overwrite_b=False, check_finite=True) Solve the linear equations A x = b, given the Cholesky factorization of A. Parameters Returns (c, lower) : tuple, (array, bool) Cholesky factorization of a, as given by cho_factor b : array Right-hand side check_finite : boolean, optional Whether to check that the input matrices contain only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. x : array The solution to the system A x = b See Also cho_factorCholesky factorization of a matrix scipy.linalg.cho_solve_banded(cb_and_lower, b, overwrite_b=False, check_finite=True) Solve the linear equations A x = b, given the Cholesky factorization of A. Parameters Returns (cb, lower) : tuple, (array, bool) cb is the Cholesky factorization of A, as given by cholesky_banded. lower must be the same value that was given to cholesky_banded. b : array Right-hand side overwrite_b : bool If True, the function will overwrite the values in b. check_finite : boolean, optional Whether to check that the input matrices contain only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. x : array The solution to the system A x = b See Also cholesky_banded Cholesky factorization of a banded matrix Notes New in version 0.8.0. scipy.linalg.polar(a, side=’right’) Compute the polar decomposition. Returns the factors of the polar decomposition [R64] u and p such that a = up (if side is “right”) or a = pu (if side is “left”), where p is positive semidefinite. Depending on the shape of a, either the rows or columns of u are orthonormal. When a is a square array, u is a square unitary array. When a is not square, the “canonical polar decomposition” [R65] is computed. Parameters 352 a : (m, n) array_like The array to be factored. side : string, optional Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Returns Determines whether a right or left polar decomposition is computed. If side is “right”, then a = up. If side is “left”, then a = pu. The default is “right”. u : (m, n) ndarray If a is square, then u is unitary. If m > n, then the columns of a are orthonormal, and if m < n, then the rows of u are orthonormal. p : ndarray p is Hermitian positive semidefinite. If a is nonsingular, p is positive definite. The shape of p is (n, n) or (m, m), depending on whether side is “right” or “left”, respectively. References [R64], [R65] Examples >>> a = np.array([[1, -1], [2, 4]]) >>> u, p = polar(a) >>> u array([[ 0.85749293, -0.51449576], [ 0.51449576, 0.85749293]]) >>> p array([[ 1.88648444, 1.2004901 ], [ 1.2004901 , 3.94446746]]) A non-square example, with m < n: >>> b = np.array([[0.5, 1, 2], [1.5, 3, 4]]) >>> u, p = polar(b) >>> u array([[-0.21196618, -0.42393237, 0.88054056], [ 0.39378971, 0.78757942, 0.4739708 ]]) >>> p array([[ 0.48470147, 0.96940295, 1.15122648], [ 0.96940295, 1.9388059 , 2.30245295], [ 1.15122648, 2.30245295, 3.65696431]]) >>> u.dot(p) # Verify the decomposition. array([[ 0.5, 1. , 2. ], [ 1.5, 3. , 4. ]]) >>> u.dot(u.T) # The rows of u are orthonormal. array([[ 1.00000000e+00, -2.07353665e-17], [ -2.07353665e-17, 1.00000000e+00]]) Another non-square example, with m > n: >>> c = b.T >>> u, p = polar(c) >>> u array([[-0.21196618, 0.39378971], [-0.42393237, 0.78757942], [ 0.88054056, 0.4739708 ]]) >>> p array([[ 1.23116567, 1.93241587], [ 1.93241587, 4.84930602]]) >>> u.dot(p) # Verify the decomposition. array([[ 0.5, 1.5], [ 1. , 3. ], [ 2. , 4. ]]) >>> u.T.dot(u) # The columns of u are orthonormal. 5.9. Linear algebra (scipy.linalg) 353 SciPy Reference Guide, Release 0.13.0 array([[ 1.00000000e+00, [ -1.26363763e-16, -1.26363763e-16], 1.00000000e+00]]) scipy.linalg.qr(a, overwrite_a=False, lwork=None, mode=’full’, pivoting=False, check_finite=True) Compute QR decomposition of a matrix. Calculate the decomposition A = Q R where Q is unitary/orthogonal and R upper triangular. Parameters Returns Raises a : (M, N) array_like Matrix to be decomposed overwrite_a : bool, optional Whether data in a is overwritten (may improve performance) lwork : int, optional Work array size, lwork >= a.shape[1]. If None or -1, an optimal size is computed. mode : {‘full’, ‘r’, ‘economic’, ‘raw’}, optional Determines what information is to be returned: either both Q and R (‘full’, default), only R (‘r’) or both Q and R but computed in economy-size (‘economic’, see Notes). The final option ‘raw’ (added in Scipy 0.11) makes the function return two matrices (Q, TAU) in the internal format used by LAPACK. pivoting : bool, optional Whether or not factorization should include pivoting for rank-revealing qr decomposition. If pivoting, compute the decomposition A P = Q R as above, but where P is chosen such that the diagonal of R is non-increasing. check_finite : boolean, optional Whether to check that the input matrix contains only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. Q : float or complex ndarray Of shape (M, M), or (M, K) for mode=’economic’. Not returned if mode=’r’. R : float or complex ndarray Of shape (M, N), or (K, N) for mode=’economic’. K = min(M, N). P : int ndarray Of shape (N,) for pivoting=True. Not returned if pivoting=False. LinAlgError Raised if decomposition fails Notes This is an interface to the LAPACK routines dgeqrf, zgeqrf, dorgqr, zungqr, dgeqp3, and zgeqp3. If mode=economic, the shapes of Q and R are (M, K) and (K, N) instead of (M,M) and (M,N), with K=min(M,N). Examples >>> from scipy import random, linalg, dot, diag, all, allclose >>> a = random.randn(9, 6) >>> q, r = linalg.qr(a) >>> allclose(a, np.dot(q, r)) True >>> q.shape, r.shape ((9, 9), (9, 6)) >>> r2 = linalg.qr(a, mode=’r’) >>> allclose(r, r2) True 354 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 >>> q3, r3 = linalg.qr(a, mode=’economic’) >>> q3.shape, r3.shape ((9, 6), (6, 6)) >>> q4, r4, p4 = linalg.qr(a, pivoting=True) >>> d = abs(diag(r4)) >>> all(d[1:] <= d[:-1]) True >>> allclose(a[:, p4], dot(q4, r4)) True >>> q4.shape, r4.shape, p4.shape ((9, 9), (9, 6), (6,)) >>> q5, r5, p5 = linalg.qr(a, mode=’economic’, pivoting=True) >>> q5.shape, r5.shape, p5.shape ((9, 6), (6, 6), (6,)) scipy.linalg.qr_multiply(a, c, mode=’right’, pivoting=False, conjugate=False, overwrite_a=False, overwrite_c=False) Calculate the QR decomposition and multiply Q with a matrix. Calculate the decomposition A = Q R where Q is unitary/orthogonal and R upper triangular. Multiply Q with a vector or a matrix c. New in version 0.11.0. Parameters Returns Raises a : ndarray, shape (M, N) Matrix to be decomposed c : ndarray, one- or two-dimensional calculate the product of c and q, depending on the mode: mode : {‘left’, ‘right’}, optional dot(Q, c) is returned if mode is ‘left’, dot(c, Q) is returned if mode is ‘right’. The shape of c must be appropriate for the matrix multiplications, if mode is ‘left’, min(a.shape) == c.shape[0], if mode is ‘right’, a.shape[0] == c.shape[1]. pivoting : bool, optional Whether or not factorization should include pivoting for rank-revealing qr decomposition, see the documentation of qr. conjugate : bool, optional Whether Q should be complex-conjugated. This might be faster than explicit conjugation. overwrite_a : bool, optional Whether data in a is overwritten (may improve performance) overwrite_c : bool, optional Whether data in c is overwritten (may improve performance). If this is used, c must be big enough to keep the result, i.e. c.shape[0] = a.shape[0] if mode is ‘left’. CQ : float or complex ndarray the product of Q and c, as defined in mode R : float or complex ndarray Of shape (K, N), K = min(M, N). P : ndarray of ints Of shape (N,) for pivoting=True. Not returned if pivoting=False. LinAlgError Raised if decomposition fails Notes This is an interface to the LAPACK routines dgeqrf, zgeqrf, dormqr, zunmqr, dgeqp3, and zgeqp3. 5.9. Linear algebra (scipy.linalg) 355 SciPy Reference Guide, Release 0.13.0 scipy.linalg.qz(A, B, output=’real’, lwork=None, sort=None, overwrite_a=False, overwrite_b=False, check_finite=True) QZ decompostion for generalized eigenvalues of a pair of matrices. The QZ, or generalized Schur, decomposition for a pair of N x N nonsymmetric matrices (A,B) is: (A,B) = (Q*AA*Z’, Q*BB*Z’) where AA, BB is in generalized Schur form if BB is upper-triangular with non-negative diagonal and AA is upper-triangular, or for real QZ decomposition (output=’real’) block upper triangular with 1x1 and 2x2 blocks. In this case, the 1x1 blocks correspond to real generalized eigenvalues and 2x2 blocks are ‘standardized’ by making the corresponding elements of BB have the form: [ a 0 ] [ 0 b ] and the pair of corresponding 2x2 blocks in AA and BB will have a complex conjugate pair of generalized eigenvalues. If (output=’complex’) or A and B are complex matrices, Z’ denotes the conjugate-transpose of Z. Q and Z are unitary matrices. New in version 0.11.0. Parameters Returns 356 A : (N, N) array_like 2d array to decompose B : (N, N) array_like 2d array to decompose output : str {‘real’,’complex’} Construct the real or complex QZ decomposition for real matrices. Default is ‘real’. lwork : int, optional Work array size. If None or -1, it is automatically computed. sort : {None, callable, ‘lhp’, ‘rhp’, ‘iuc’, ‘ouc’}, optional NOTE: THIS INPUT IS DISABLED FOR NOW, IT DOESN’T WORK WELL ON WINDOWS. Specifies whether the upper eigenvalues should be sorted. A callable may be passed that, given a eigenvalue, returns a boolean denoting whether the eigenvalue should be sorted to the top-left (True). For real matrix pairs, the sort function takes three real arguments (alphar, alphai, beta). The eigenvalue x = (alphar + alphai*1j)/beta. For complex matrix pairs or output=’complex’, the sort function takes two complex arguments (alpha, beta). The eigenvalue x = (alpha/beta). Alternatively, string parameters may be used: •‘lhp’ Left-hand plane (x.real < 0.0) •‘rhp’ Right-hand plane (x.real > 0.0) •‘iuc’ Inside the unit circle (x*x.conjugate() <= 1.0) •‘ouc’ Outside the unit circle (x*x.conjugate() > 1.0) Defaults to None (no sorting). check_finite : boolean If true checks the elements of A and B are finite numbers. If false does no checking and passes matrix through to underlying algorithm. AA : (N, N) ndarray Generalized Schur form of A. BB : (N, N) ndarray Generalized Schur form of B. Q : (N, N) ndarray The left Schur vectors. Z : (N, N) ndarray The right Schur vectors. sdim : int, optional If sorting was requested, a fifth return value will contain the number of eigenvalues for which the sort condition was True. Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Notes Q is transposed versus the equivalent function in Matlab. Examples >>> >>> >>> >>> from scipy import linalg np.random.seed(1234) A = np.arange(9).reshape((3, 3)) B = np.random.randn(3, 3) >>> AA, BB, Q, Z = linalg.qz(A, B) >>> AA array([[-13.40928183, -4.62471562, 1.09215523], [ 0. , 0. , 1.22805978], [ 0. , 0. , 0.31973817]]) >>> BB array([[ 0.33362547, -1.37393632, 0.02179805], [ 0. , 1.68144922, 0.74683866], [ 0. , 0. , 0.9258294 ]]) >>> Q array([[ 0.14134727, -0.97562773, 0.16784365], [ 0.49835904, -0.07636948, -0.86360059], [ 0.85537081, 0.20571399, 0.47541828]]) >>> Z array([[-0.24900855, -0.51772687, 0.81850696], [-0.79813178, 0.58842606, 0.12938478], [-0.54861681, -0.6210585 , -0.55973739]]) scipy.linalg.schur(a, output=’real’, check_finite=True) Compute Schur decomposition of a matrix. lwork=None, overwrite_a=False, sort=None, The Schur decomposition is: A = Z T Z^H where Z is unitary and T is either upper-triangular, or for real Schur decomposition (output=’real’), quasi-upper triangular. In the quasi-triangular form, 2x2 blocks describing complex-valued eigenvalue pairs may extrude from the diagonal. Parameters a : (M, M) array_like Matrix to decompose output : {‘real’, ‘complex’}, optional Construct the real or complex Schur decomposition (for real matrices). lwork : int, optional Work array size. If None or -1, it is automatically computed. overwrite_a : bool, optional Whether to overwrite data in a (may improve performance). sort : {None, callable, ‘lhp’, ‘rhp’, ‘iuc’, ‘ouc’}, optional Specifies whether the upper eigenvalues should be sorted. A callable may be passed that, given a eigenvalue, returns a boolean denoting whether the eigenvalue should be sorted to the top-left (True). Alternatively, string parameters may be used: ’lhp’ ’rhp’ ’iuc’ ’ouc’ Left-hand plane (x.real < 0.0) Right-hand plane (x.real > 0.0) Inside the unit circle (x*x.conjugate() <= 1.0) Outside the unit circle (x*x.conjugate() > 1.0) Defaults to None (no sorting). 5.9. Linear algebra (scipy.linalg) 357 SciPy Reference Guide, Release 0.13.0 check_finite : boolean, optional Whether to check that the input matrix contains only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. T : (M, M) ndarray Schur form of A. It is real-valued for the real Schur decomposition. Z : (M, M) ndarray An unitary Schur transformation matrix for A. It is real-valued for the real Schur decomposition. sdim : int If and only if sorting was requested, a third return value will contain the number of eigenvalues satisfying the sort condition. LinAlgError Error raised under three conditions: 1.The algorithm failed due to a failure of the QR algorithm to compute all eigenvalues 2.If eigenvalue sorting was requested, the eigenvalues could not be reordered due to a failure to separate eigenvalues, usually because of poor conditioning 3.If eigenvalue sorting was requested, roundoff errors caused the leading eigenvalues to no longer satisfy the sorting condition Returns Raises See Also rsf2csf Convert real Schur form to complex Schur form scipy.linalg.rsf2csf(T, Z, check_finite=True) Convert real Schur form to complex Schur form. Convert a quasi-diagonal real-valued Schur form to the upper triangular complex-valued Schur form. Parameters Returns T : (M, M) array_like Real Schur form of the original matrix Z : (M, M) array_like Schur transformation matrix check_finite : boolean, optional Whether to check that the input matrices contain only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. T : (M, M) ndarray Complex Schur form of the original matrix Z : (M, M) ndarray Schur transformation matrix corresponding to the complex form See Also schur Schur decompose a matrix scipy.linalg.hessenberg(a, calc_q=False, overwrite_a=False, check_finite=True) Compute Hessenberg form of a matrix. The Hessenberg decomposition is: A = Q H Q^H where Q is unitary/orthogonal and H has only zero elements below the first sub-diagonal. Parameters 358 a : (M, M) array_like Matrix to bring into Hessenberg form. Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Returns calc_q : bool, optional Whether to compute the transformation matrix. Default is False. overwrite_a : bool, optional Whether to overwrite a; may improve performance. Default is False. check_finite : boolean, optional Whether to check that the input matrix contains only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. H : (M, M) ndarray Hessenberg form of a. Q : (M, M) ndarray Unitary/orthogonal similarity transformation matrix A = Q H Q^H. Only returned if calc_q=True. See Also scipy.linalg.interpolative – Interpolative matrix decompositions 5.9.4 Matrix Functions expm(A[, q]) logm(A[, disp]) cosm(A) sinm(A) tanm(A) coshm(A) sinhm(A) tanhm(A) signm(a[, disp]) sqrtm(A[, disp, blocksize]) funm(A, func[, disp]) expm_frechet(A, E[, method, compute_expm, ...]) fractional_matrix_power(A, t) Compute the matrix exponential using Pade approximation. Compute matrix logarithm. Compute the matrix cosine. Compute the matrix sine. Compute the matrix tangent. Compute the hyperbolic matrix cosine. Compute the hyperbolic matrix sine. Compute the hyperbolic matrix tangent. Matrix sign function. Matrix square root. Evaluate a matrix function specified by a callable. Frechet derivative of the matrix exponential of A in the direction E. scipy.linalg.expm(A, q=None) Compute the matrix exponential using Pade approximation. Parameters Returns A : (N, N) array_like Matrix to be exponentiated expm : (N, N) ndarray Matrix exponential of A References N. J. Higham, “The Scaling and Squaring Method for the Matrix Exponential Revisited”, SIAM. J. Matrix Anal. & Appl. 26, 1179 (2005). scipy.linalg.logm(A, disp=True) Compute matrix logarithm. The matrix logarithm is the inverse of expm: expm(logm(A)) == A Parameters A : (N, N) array_like Matrix whose logarithm to evaluate 5.9. Linear algebra (scipy.linalg) 359 SciPy Reference Guide, Release 0.13.0 Returns disp : bool, optional Print warning if error in the result is estimated large instead of returning estimated error. (Default: True) logm : (N, N) ndarray Matrix logarithm of A errest : float (if disp == False) 1-norm of the estimated error, ||err||_1 / ||A||_1 scipy.linalg.cosm(A) Compute the matrix cosine. This routine uses expm to compute the matrix exponentials. Parameters Returns A : (N, N) array_like Input array cosm : (N, N) ndarray Matrix cosine of A scipy.linalg.sinm(A) Compute the matrix sine. This routine uses expm to compute the matrix exponentials. Parameters Returns A : (N, N) array_like Input array. sinm : (N, N) ndarray Matrix cosine of A scipy.linalg.tanm(A) Compute the matrix tangent. This routine uses expm to compute the matrix exponentials. Parameters Returns A : (N, N) array_like Input array. tanm : (N, N) ndarray Matrix tangent of A scipy.linalg.coshm(A) Compute the hyperbolic matrix cosine. This routine uses expm to compute the matrix exponentials. Parameters Returns A : (N, N) array_like Input array. coshm : (N, N) ndarray Hyperbolic matrix cosine of A scipy.linalg.sinhm(A) Compute the hyperbolic matrix sine. This routine uses expm to compute the matrix exponentials. Parameters Returns 360 A : (N, N) array_like Input array. sinhm : (N, N) ndarray Hyperbolic matrix sine of A Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 scipy.linalg.tanhm(A) Compute the hyperbolic matrix tangent. This routine uses expm to compute the matrix exponentials. Parameters Returns A : (N, N) array_like Input array tanhm : (N, N) ndarray Hyperbolic matrix tangent of A scipy.linalg.signm(a, disp=True) Matrix sign function. Extension of the scalar sign(x) to matrices. Parameters Returns A : (N, N) array_like Matrix at which to evaluate the sign function disp : bool, optional Print warning if error in the result is estimated large instead of returning estimated error. (Default: True) signm : (N, N) ndarray Value of the sign function at A errest : float (if disp == False) 1-norm of the estimated error, ||err||_1 / ||A||_1 Examples >>> from scipy.linalg import signm, eigvals >>> a = [[1,2,3], [1,2,1], [1,1,1]] >>> eigvals(a) array([ 4.12488542+0.j, -0.76155718+0.j, 0.63667176+0.j]) >>> eigvals(signm(a)) array([-1.+0.j, 1.+0.j, 1.+0.j]) scipy.linalg.sqrtm(A, disp=True, blocksize=64) Matrix square root. Parameters Returns A : (N, N) array_like Matrix whose square root to evaluate disp : bool, optional Print warning if error in the result is estimated large instead of returning estimated error. (Default: True) blocksize : integer, optional If the blocksize is not degenerate with respect to the size of the input array, then use a blocked algorithm. (Default: 64) sqrtm : (N, N) ndarray Value of the sqrt function at A errest : float (if disp == False) Frobenius norm of the estimated error, ||err||_F / ||A||_F References [R66] scipy.linalg.funm(A, func, disp=True) Evaluate a matrix function specified by a callable. 5.9. Linear algebra (scipy.linalg) 361 SciPy Reference Guide, Release 0.13.0 Returns the value of matrix-valued function f at A. The function f is an extension of the scalar-valued function func to matrices. Parameters Returns A : (N, N) array_like Matrix at which to evaluate the function func : callable Callable object that evaluates a scalar function f. Must be vectorized (eg. using vectorize). disp : bool, optional Print warning if error in the result is estimated large instead of returning estimated error. (Default: True) funm : (N, N) ndarray Value of the matrix function specified by func evaluated at A errest : float (if disp == False) 1-norm of the estimated error, ||err||_1 / ||A||_1 scipy.linalg.expm_frechet(A, E, method=’SPS’, compute_expm=True, check_finite=True) Frechet derivative of the matrix exponential of A in the direction E. New in version 0.13.0. Parameters Returns A : (N, N) array_like Matrix of which to take the matrix exponential. E : (N, N) array_like Matrix direction in which to take the Frechet derivative. method : str, optional Choice of algorithm. Should be one of •SPS •blockEnlarge compute_expm : bool, optional Whether to compute also expm_A in addition to expm_frechet_AE. Default is True. check_finite : boolean, optional Whether to check that the input matrix contains only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. expm_A : ndarray Matrix exponential of A. expm_frechet_AE : ndarray Frechet derivative of the matrix exponential of A in the direction E. For compute_expm = False, only expm_frechet_AE is returned. See Also expm Compute the exponential of a matrix. Notes This section describes the available implementations that can be selected by the method parameter. The default method is SPS. Method blockEnlarge is a naive algorithm. Method SPS is Scaling-Pade-Squaring [R60]. It is a sophisticated implementation which should take only about 3/8 as much time as the naive implementation. The asymptotics are the same. References [R60] 362 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Examples >>> import scipy.linalg >>> A = np.random.randn(3, 3) >>> E = np.random.randn(3, 3) >>> expm_A, expm_frechet_AE = scipy.linalg.expm_frechet(A, E) >>> expm_A.shape, expm_frechet_AE.shape ((3, 3), (3, 3)) >>> import scipy.linalg >>> A = np.random.randn(3, 3) >>> E = np.random.randn(3, 3) >>> expm_A, expm_frechet_AE = scipy.linalg.expm_frechet(A, E) >>> M = np.zeros((6, 6)) >>> M[:3, :3] = A; M[:3, 3:] = E; M[3:, 3:] = A >>> expm_M = scipy.linalg.expm(M) >>> np.allclose(expm_A, expm_M[:3, :3]) True >>> np.allclose(expm_frechet_AE, expm_M[:3, 3:]) True scipy.linalg.fractional_matrix_power(A, t) 5.9.5 Matrix Equation Solvers solve_sylvester(a, b, q) solve_continuous_are(a, b, q, r) solve_discrete_are(a, b, q, r) solve_discrete_lyapunov(a, q) solve_lyapunov(a, q) Computes a solution (X) to the Sylvester equation (AX + XB = Q). Solves the continuous algebraic Riccati equation, or CARE, defined Solves the disctrete algebraic Riccati equation, or DARE, defined as Solves the Discrete Lyapunov Equation (A’XA-X=-Q) directly. Solves the continuous Lyapunov equation (AX + XA^H = Q) given the values scipy.linalg.solve_sylvester(a, b, q) Computes a solution (X) to the Sylvester equation (AX + XB = Q). New in version 0.11.0. Parameters Returns Raises a : (M, M) array_like Leading matrix of the Sylvester equation b : (N, N) array_like Trailing matrix of the Sylvester equation q : (M, N) array_like Right-hand side x : (M, N) ndarray The solution to the Sylvester equation. LinAlgError If solution was not found Notes Computes a solution to the Sylvester matrix equation via the Bartels- Stewart algorithm. The A and B matrices first undergo Schur decompositions. The resulting matrices are used to construct an alternative Sylvester equation (RY + YS^T = F) where the R and S matrices are in quasi-triangular form (or, when R, S or F are complex, triangular form). The simplified equation is then solved using *TRSYL from LAPACK directly. scipy.linalg.solve_continuous_are(a, b, q, r) Solves the continuous algebraic Riccati equation, or CARE, defined as (A’X + XA - XBR^-1B’X+Q=0) directly 5.9. Linear algebra (scipy.linalg) 363 SciPy Reference Guide, Release 0.13.0 using a Schur decomposition method. New in version 0.11.0. Parameters Returns a : (M, M) array_like Input b : (M, N) array_like Input q : (M, M) array_like Input r : (N, N) array_like Non-singular, square matrix x : (M, M) ndarray Solution to the continuous algebraic Riccati equation See Also solve_discrete_are Solves the discrete algebraic Riccati equation Notes Method taken from: Laub, “A Schur Method for Solving Algebraic Riccati Equations.” U.S. Energy Research and Development Agency under contract ERDA-E(49-18)-2087. http://dspace.mit.edu/bitstream/handle/1721.1/1301/R-0859-05666488.pdf scipy.linalg.solve_discrete_are(a, b, q, r) Solves the disctrete algebraic Riccati equation, or DARE, defined as (X = A’XA-(A’XB)(R+B’XB)^1(B’XA)+Q), directly using a Schur decomposition method. New in version 0.11.0. Parameters Returns a : (M, M) array_like Non-singular, square matrix b : (M, N) array_like Input q : (M, M) array_like Input r : (N, N) array_like Non-singular, square matrix x : ndarray Solution to the continuous Lyapunov equation See Also solve_continuous_are Solves the continuous algebraic Riccati equation Notes Method taken from: Laub, “A Schur Method for Solving Algebraic Riccati Equations.” U.S. Energy Research and Development Agency under contract ERDA-E(49-18)-2087. http://dspace.mit.edu/bitstream/handle/1721.1/1301/R-0859-05666488.pdf scipy.linalg.solve_discrete_lyapunov(a, q) Solves the Discrete Lyapunov Equation (A’XA-X=-Q) directly. New in version 0.11.0. Parameters Returns 364 a : (M, M) array_like A square matrix q : (M, M) array_like Right-hand side square matrix x : ndarray Solution to the continuous Lyapunov equation Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Notes Algorithm is based on a direct analytical solution from: Hamilton, James D. Time Series Analysis, Princeton: Princeton University Press, 1994. 265. Print. http://www.scribd.com/doc/20577138/Hamilton-1994-TimeSeries-Analysis scipy.linalg.solve_lyapunov(a, q) Solves the continuous Lyapunov equation (AX + XA^H = Q) given the values of A and Q using the BartelsStewart algorithm. New in version 0.11.0. Parameters Returns a : array_like A square matrix q : array_like Right-hand side square matrix x : array_like Solution to the continuous Lyapunov equation See Also solve_sylvester computes the solution to the Sylvester equation Notes Because the continuous Lyapunov equation is just a special form of the Sylvester equation, this solver relies entirely on solve_sylvester for a solution. 5.9.6 Special Matrices block_diag(*arrs) circulant(c) companion(a) hadamard(n[, dtype]) hankel(c[, r]) hilbert(n) invhilbert(n[, exact]) leslie(f, s) pascal(n[, kind, exact]) toeplitz(c[, r]) tri(N[, M, k, dtype]) Create a block diagonal matrix from provided arrays. Construct a circulant matrix. Create a companion matrix. Construct a Hadamard matrix. Construct a Hankel matrix. Create a Hilbert matrix of order n. Compute the inverse of the Hilbert matrix of order n. Create a Leslie matrix. Returns the n x n Pascal matrix. Construct a Toeplitz matrix. Construct (N, M) matrix filled with ones at and below the k-th diagonal. scipy.linalg.block_diag(*arrs) Create a block diagonal matrix from provided arrays. Given the inputs A, B and C, the output will have these arrays arranged on the diagonal: [[A, 0, 0], [0, B, 0], [0, 0, C]] Parameters Returns A, B, C, ... : array_like, up to 2-D Input arrays. A 1-D array or array_like sequence of length n‘is treated as a 2-D array with shape ‘‘(1,n)‘. D : ndarray Array with A, B, C, ... on the diagonal. D has the same dtype as A. 5.9. Linear algebra (scipy.linalg) 365 SciPy Reference Guide, Release 0.13.0 Notes If all the input arrays are square, the output is known as a block diagonal matrix. Examples >>> from scipy.linalg import block_diag >>> A = [[1, 0], ... [0, 1]] >>> B = [[3, 4, 5], ... [6, 7, 8]] >>> C = [[7]] >>> block_diag(A, B, C) [[1 0 0 0 0 0] [0 1 0 0 0 0] [0 0 3 4 5 0] [0 0 6 7 8 0] [0 0 0 0 0 7]] >>> block_diag(1.0, [2, 3], [[4, 5], [6, 7]]) array([[ 1., 0., 0., 0., 0.], [ 0., 2., 3., 0., 0.], [ 0., 0., 0., 4., 5.], [ 0., 0., 0., 6., 7.]]) scipy.linalg.circulant(c) Construct a circulant matrix. Parameters Returns c : (N,) array_like 1-D array, the first column of the matrix. A : (N, N) ndarray A circulant matrix whose first column is c. See Also toeplitz Toeplitz matrix hankel Hankel matrix Notes New in version 0.8.0. Examples >>> from scipy.linalg import circulant >>> circulant([1, 2, 3]) array([[1, 3, 2], [2, 1, 3], [3, 2, 1]]) scipy.linalg.companion(a) Create a companion matrix. Create the companion matrix [R59] associated with the polynomial whose coefficients are given in a. Parameters Returns 366 a : (N,) array_like 1-D array of polynomial coefficients. The length of a must be at least two, and a[0] must not be zero. c : (N-1, N-1) ndarray The first row of c is -a[1:]/a[0], and the first sub-diagonal is all ones. The datatype of the array is the same as the data-type of 1.0*a[0]. Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Raises ValueError If any of the following are true: a) a.ndim != 1; b) a.size < 2; c) a[0] == 0. Notes New in version 0.8.0. References [R59] Examples >>> from scipy.linalg import companion >>> companion([1, -10, 31, -30]) array([[ 10., -31., 30.], [ 1., 0., 0.], [ 0., 1., 0.]]) scipy.linalg.hadamard(n, dtype= ) Construct a Hadamard matrix. Constructs an n-by-n Hadamard matrix, using Sylvester’s construction. n must be a power of 2. Parameters Returns n : int The order of the matrix. n must be a power of 2. dtype : numpy dtype The data type of the array to be constructed. H : (n, n) ndarray The Hadamard matrix. Notes New in version 0.8.0. Examples >>> from scipy.linalg import hadamard >>> hadamard(2, dtype=complex) array([[ 1.+0.j, 1.+0.j], [ 1.+0.j, -1.-0.j]]) >>> hadamard(4) array([[ 1, 1, 1, 1], [ 1, -1, 1, -1], [ 1, 1, -1, -1], [ 1, -1, -1, 1]]) scipy.linalg.hankel(c, r=None) Construct a Hankel matrix. The Hankel matrix has constant anti-diagonals, with c as its first column and r as its last row. If r is not given, then r = zeros_like(c) is assumed. Parameters c : array_like First column of the matrix. Whatever the actual shape of c, it will be converted to a 1-D array. r : array_like 5.9. Linear algebra (scipy.linalg) 367 SciPy Reference Guide, Release 0.13.0 Last row of the matrix. If None, r = zeros_like(c) is assumed. r[0] is ignored; the last row of the returned matrix is [c[-1], r[1:]]. Whatever the actual shape of r, it will be converted to a 1-D array. A : (len(c), len(r)) ndarray The Hankel matrix. Dtype is the same as (c[0] + r[0]).dtype. Returns See Also toeplitz Toeplitz matrix circulant circulant matrix Examples >>> from scipy.linalg import hankel >>> hankel([1, 17, 99]) array([[ 1, 17, 99], [17, 99, 0], [99, 0, 0]]) >>> hankel([1,2,3,4], [4,7,7,8,9]) array([[1, 2, 3, 4, 7], [2, 3, 4, 7, 7], [3, 4, 7, 7, 8], [4, 7, 7, 8, 9]]) scipy.linalg.hilbert(n) Create a Hilbert matrix of order n. Returns the n by n array with entries h[i,j] = 1 / (i + j + 1). Parameters Returns n : int The size of the array to create. h : (n, n) ndarray The Hilbert matrix. See Also invhilbertCompute the inverse of a Hilbert matrix. Notes New in version 0.10.0. Examples >>> from scipy.linalg >>> hilbert(3) array([[ 1. , [ 0.5 , [ 0.33333333, import hilbert 0.5 , 0.33333333, 0.25 , 0.33333333], 0.25 ], 0.2 ]]) scipy.linalg.invhilbert(n, exact=False) Compute the inverse of the Hilbert matrix of order n. The entries in the inverse of a Hilbert matrix are integers. When n is greater than 14, some entries in the inverse exceed the upper limit of 64 bit integers. The exact argument provides two options for dealing with these large integers. Parameters 368 n : int The order of the Hilbert matrix. exact : bool Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 If False, the data type of the array that is returned is np.float64, and the array is an approximation of the inverse. If True, the array is the exact integer inverse array. To represent the exact inverse when n > 14, the returned array is an object array of long integers. For n <= 14, the exact inverse is returned as an array with data type np.int64. invh : (n, n) ndarray The data type of the array is np.float64 if exact is False. If exact is True, the data type is either np.int64 (for n <= 14) or object (for n > 14). In the latter case, the objects in the array will be long integers. Returns See Also hilbert Create a Hilbert matrix. Notes New in version 0.10.0. Examples >>> from scipy.linalg import invhilbert >>> invhilbert(4) array([[ 16., -120., 240., -140.], [ -120., 1200., -2700., 1680.], [ 240., -2700., 6480., -4200.], [ -140., 1680., -4200., 2800.]]) >>> invhilbert(4, exact=True) array([[ 16, -120, 240, -140], [ -120, 1200, -2700, 1680], [ 240, -2700, 6480, -4200], [ -140, 1680, -4200, 2800]], dtype=int64) >>> invhilbert(16)[7,7] 4.2475099528537506e+19 >>> invhilbert(16, exact=True)[7,7] 42475099528537378560L scipy.linalg.leslie(f, s) Create a Leslie matrix. Given the length n array of fecundity coefficients f and the length n-1 array of survival coefficents s, return the associated Leslie matrix. Parameters Returns f : (N,) array_like The “fecundity” coefficients. s : (N-1,) array_like The “survival” coefficients, has to be 1-D. The length of s must be one less than the length of f, and it must be at least 1. L : (N, N) ndarray The array is zero except for the first row, which is f, and the first sub-diagonal, which is s. The data-type of the array will be the data-type of f[0]+s[0]. Notes New in version 0.8.0. The Leslie matrix is used to model discrete-time, age-structured population growth [R61] [R62]. In a population with n age classes, two sets of parameters define a Leslie matrix: the n “fecundity coefficients”, which give the number of offspring per-capita produced by each age class, and the n - 1 “survival coefficients”, which give the per-capita survival rate of each age class. 5.9. Linear algebra (scipy.linalg) 369 SciPy Reference Guide, Release 0.13.0 References [R61], [R62] Examples >>> from scipy.linalg import leslie >>> leslie([0.1, 2.0, 1.0, 0.1], [0.2, 0.8, 0.7]) array([[ 0.1, 2. , 1. , 0.1], [ 0.2, 0. , 0. , 0. ], [ 0. , 0.8, 0. , 0. ], [ 0. , 0. , 0.7, 0. ]]) scipy.linalg.pascal(n, kind=’symmetric’, exact=True) Returns the n x n Pascal matrix. The Pascal matrix is a matrix containing the binomial coefficients as its elements. New in version 0.11.0. Parameters Returns n : int The size of the matrix to create; that is, the result is an n x n matrix. kind : str, optional Must be one of ‘symmetric’, ‘lower’, or ‘upper’. Default is ‘symmetric’. exact : bool, optional If exact is True, the result is either an array of type numpy.uint64 (if n <= 35) or an object array of Python long integers. If exact is False, the coefficients in the matrix are computed using scipy.misc.comb with exact=False. The result will be a floating point array, and the values in the array will not be the exact coefficients, but this version is much faster than exact=True. p : (n, n) ndarray The Pascal matrix. Notes See http://en.wikipedia.org/wiki/Pascal_matrix for more information about Pascal matrices. Examples >>> from scipy.linalg import pascal >>> pascal(4) array([[ 1, 1, 1, 1], [ 1, 2, 3, 4], [ 1, 3, 6, 10], [ 1, 4, 10, 20]], dtype=uint64) >>> pascal(4, kind=’lower’) array([[1, 0, 0, 0], [1, 1, 0, 0], [1, 2, 1, 0], [1, 3, 3, 1]], dtype=uint64) >>> pascal(50)[-1, -1] 25477612258980856902730428600L >>> from scipy.misc import comb >>> comb(98, 49, exact=True) 25477612258980856902730428600L scipy.linalg.toeplitz(c, r=None) Construct a Toeplitz matrix. The Toeplitz matrix has constant diagonals, with c as its first column and r as its first row. If r is not given, r == conjugate(c) is assumed. 370 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Parameters Returns c : array_like First column of the matrix. Whatever the actual shape of c, it will be converted to a 1-D array. r : array_like First row of the matrix. If None, r = conjugate(c) is assumed; in this case, if c[0] is real, the result is a Hermitian matrix. r[0] is ignored; the first row of the returned matrix is [c[0], r[1:]]. Whatever the actual shape of r, it will be converted to a 1-D array. A : (len(c), len(r)) ndarray The Toeplitz matrix. Dtype is the same as (c[0] + r[0]).dtype. See Also circulant circulant matrix hankel Hankel matrix Notes The behavior when c or r is a scalar, or when c is complex and r is None, was changed in version 0.8.0. The behavior in previous versions was undocumented and is no longer supported. Examples >>> from scipy.linalg import toeplitz >>> toeplitz([1,2,3], [1,4,5,6]) array([[1, 4, 5, 6], [2, 1, 4, 5], [3, 2, 1, 4]]) >>> toeplitz([1.0, 2+3j, 4-1j]) array([[ 1.+0.j, 2.-3.j, 4.+1.j], [ 2.+3.j, 1.+0.j, 2.-3.j], [ 4.-1.j, 2.+3.j, 1.+0.j]]) scipy.linalg.tri(N, M=None, k=0, dtype=None) Construct (N, M) matrix filled with ones at and below the k-th diagonal. The matrix has A[i,j] == 1 for i <= j + k Parameters Returns N : integer The size of the first dimension of the matrix. M : integer or None The size of the second dimension of the matrix. If M is None, M = N is assumed. k : integer Number of subdiagonal below which matrix is filled with ones. k = 0 is the main diagonal, k < 0 subdiagonal and k > 0 superdiagonal. dtype : dtype Data type of the matrix. tri : (N, M) ndarray Tri matrix. Examples >>> from scipy.linalg import tri >>> tri(3, 5, 2, dtype=int) array([[1, 1, 1, 0, 0], [1, 1, 1, 1, 0], [1, 1, 1, 1, 1]]) >>> tri(3, 5, -1, dtype=int) 5.9. Linear algebra (scipy.linalg) 371 SciPy Reference Guide, Release 0.13.0 array([[0, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 1, 0, 0, 0]]) 5.9.7 Low-level routines get_blas_funcs(names[, arrays, dtype]) get_lapack_funcs(names[, arrays, dtype]) find_best_blas_type([arrays, dtype]) Return available BLAS function objects from names. Return available LAPACK function objects from names. Find best-matching BLAS/LAPACK type. scipy.linalg.get_blas_funcs(names, arrays=(), dtype=None) Return available BLAS function objects from names. Arrays are used to determine the optimal prefix of BLAS routines. Parameters Returns names : str or sequence of str Name(s) of BLAS functions withouth type prefix. arrays : sequency of ndarrays, optional Arrays can be given to determine optiomal prefix of BLAS routines. If not given, double-precision routines will be used, otherwise the most generic type in arrays will be used. dtype : str or dtype, optional Data-type specifier. Not used if arrays is non-empty. funcs : list List containing the found function(s). Notes This routines automatically chooses between Fortran/C interfaces. Fortran code is used whenever possible for arrays with column major order. In all other cases, C code is preferred. In BLAS, the naming convention is that all functions start with a type prefix, which depends on the type of the principal matrix. These can be one of {‘s’, ‘d’, ‘c’, ‘z’} for the numpy types {float32, float64, complex64, complex128} respectively. The code and the dtype are stored in attributes typecode and dtype of the returned functions. scipy.linalg.get_lapack_funcs(names, arrays=(), dtype=None) Return available LAPACK function objects from names. Arrays are used to determine the optimal prefix of LAPACK routines. Parameters Returns 372 names : str or sequence of str Name(s) of LAPACK functions withouth type prefix. arrays : sequency of ndarrays, optional Arrays can be given to determine optiomal prefix of LAPACK routines. If not given, double-precision routines will be used, otherwise the most generic type in arrays will be used. dtype : str or dtype, optional Data-type specifier. Not used if arrays is non-empty. funcs : list List containing the found function(s). Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Notes This routines automatically chooses between Fortran/C interfaces. Fortran code is used whenever possible for arrays with column major order. In all other cases, C code is preferred. In LAPACK, the naming convention is that all functions start with a type prefix, which depends on the type of the principal matrix. These can be one of {‘s’, ‘d’, ‘c’, ‘z’} for the numpy types {float32, float64, complex64, complex128} respectevely, and are stored in attribute typecode of the returned functions. scipy.linalg.find_best_blas_type(arrays=(), dtype=None) Find best-matching BLAS/LAPACK type. Arrays are used to determine the optimal prefix of BLAS routines. Parameters Returns arrays : sequency of ndarrays, optional Arrays can be given to determine optiomal prefix of BLAS routines. If not given, double-precision routines will be used, otherwise the most generic type in arrays will be used. dtype : str or dtype, optional Data-type specifier. Not used if arrays is non-empty. prefix : str BLAS/LAPACK prefix character. dtype : dtype Inferred Numpy data type. prefer_fortran : bool Whether to prefer Fortran order routines over C order. See Also scipy.linalg.blas – Low-level BLAS functions scipy.linalg.lapack – Low-level LAPACK functions 5.10 Low-level BLAS functions This module contains low-level functions from the BLAS library. New in version 0.12.0. Warning: These functions do little to no error checking. It is possible to cause crashes by mis-using them, so prefer using the higher-level routines in scipy.linalg. 5.11 Finding functions get_blas_funcs(names[, arrays, dtype]) find_best_blas_type([arrays, dtype]) Return available BLAS function objects from names. Find best-matching BLAS/LAPACK type. 5.12 All functions caxpy ccopy cdotc 5.12. All functions caxpy - Function signature: ccopy - Function signature: cdotc - Function signature: Continued on next page 373 SciPy Reference Guide, Release 0.13.0 Table 5.72 – continued from previous page cdotu cdotu - Function signature: cgemm cgemm - Function signature: cgemv cgemv - Function signature: cgerc cgerc - Function signature: cgeru cgeru - Function signature: chemm chemm - Function signature: chemv chemv - Function signature: cherk cherk - Function signature: cher2k cher2k - Function signature: crotg crotg - Function signature: cscal cscal - Function signature: csrot csrot - Function signature: csscal csscal - Function signature: csymm csymm - Function signature: csyrk csyrk - Function signature: csyr2k csyr2k - Function signature: cswap cswap - Function signature: ctrmv ctrmv - Function signature: dasum dasum - Function signature: daxpy daxpy - Function signature: dcopy dcopy - Function signature: ddot ddot - Function signature: dgemm dgemm - Function signature: dgemv dgemv - Function signature: dger dger - Function signature: dnrm2 dnrm2 - Function signature: drot drot - Function signature: drotg drotg - Function signature: drotm drotm - Function signature: drotmg drotmg - Function signature: dscal dscal - Function signature: dswap dswap - Function signature: dsymm dsymm - Function signature: dsymv dsymv - Function signature: dsyrk dsyrk - Function signature: dsyr2k dsyr2k - Function signature: dtrmv dtrmv - Function signature: dzasum dzasum - Function signature: dznrm2 dznrm2 - Function signature: icamax icamax - Function signature: idamax idamax - Function signature: isamax isamax - Function signature: izamax izamax - Function signature: sasum sasum - Function signature: saxpy saxpy - Function signature: scasum scasum - Function signature: scnrm2 scnrm2 - Function signature: scopy scopy - Function signature: sdot sdot - Function signature: sgemm sgemm - Function signature: Continued on next page 374 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Table 5.72 – continued from previous page sgemv sgemv - Function signature: sger sger - Function signature: snrm2 snrm2 - Function signature: srot srot - Function signature: srotg srotg - Function signature: srotm srotm - Function signature: srotmg srotmg - Function signature: sscal sscal - Function signature: sswap sswap - Function signature: ssymm ssymm - Function signature: ssymv ssymv - Function signature: ssyrk ssyrk - Function signature: ssyr2k ssyr2k - Function signature: strmv strmv - Function signature: zaxpy zaxpy - Function signature: zcopy zcopy - Function signature: zdotc zdotc - Function signature: zdotu zdotu - Function signature: zdrot zdrot - Function signature: zdscal zdscal - Function signature: zgemm zgemm - Function signature: zgemv zgemv - Function signature: zgerc zgerc - Function signature: zgeru zgeru - Function signature: zhemm zhemm - Function signature: zhemv zhemv - Function signature: zherk zherk - Function signature: zher2k zher2k - Function signature: zrotg zrotg - Function signature: zscal zscal - Function signature: zsymm zsymm - Function signature: zsyrk zsyrk - Function signature: zsyr2k zsyr2k - Function signature: zswap zswap - Function signature: ztrmv ztrmv - Function signature: scipy.linalg.blas.caxpy = caxpy - Function signature: z = caxpy(x,y,[n,a,offx,incx,offy,incy]) Required arguments: x : input rank-1 array(‘F’) with bounds (*) y : input rank-1 array(‘F’) with bounds (*) Optional arguments: n := (len(x)-offx)/abs(incx) input int a := (1.0, 0.0) input complex offx := 0 input int incx := 1 input int offy := 0 input int incy := 1 input int Return objects: z : rank-1 array(‘F’) with bounds (*) and y storage scipy.linalg.blas.ccopy = 5.12. All functions 375 SciPy Reference Guide, Release 0.13.0 ccopy - Function signature: y = ccopy(x,y,[n,offx,incx,offy,incy]) Required arguments: x : input rank-1 array(‘F’) with bounds (*) y : input rank-1 array(‘F’) with bounds (*) Optional arguments: n := (len(x)-offx)/abs(incx) input int offx := 0 input int incx := 1 input int offy := 0 input int incy := 1 input int Return objects: y : rank-1 array(‘F’) with bounds (*) scipy.linalg.blas.cdotc = cdotc - Function signature: xy = cdotc(x,y,[n,offx,incx,offy,incy]) Required arguments: x : input rank-1 array(‘F’) with bounds (*) y : input rank-1 array(‘F’) with bounds (*) Optional arguments: n := (len(x)-offx)/abs(incx) input int offx := 0 input int incx := 1 input int offy := 0 input int incy := 1 input int Return objects: xy : complex scipy.linalg.blas.cdotu = cdotu - Function signature: xy = cdotu(x,y,[n,offx,incx,offy,incy]) Required arguments: x : input rank-1 array(‘F’) with bounds (*) y : input rank-1 array(‘F’) with bounds (*) Optional arguments: n := (len(x)-offx)/abs(incx) input int offx := 0 input int incx := 1 input int offy := 0 input int incy := 1 input int Return objects: xy : complex scipy.linalg.blas.cgemm = cgemm - Function signature: c = cgemm(alpha,a,b,[beta,c,trans_a,trans_b,overwrite_c]) Required arguments: alpha : input complex a : input rank-2 array(‘F’) with bounds (lda,ka) b : input rank-2 array(‘F’) with bounds (ldb,kb) Optional arguments: beta := (0.0, 0.0) input complex c : input rank-2 array(‘F’) with bounds (m,n) overwrite_c := 0 input int trans_a := 0 input int trans_b := 0 input int Return objects: c : rank-2 array(‘F’) with bounds (m,n) 376 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 scipy.linalg.blas.cgemv = cgemv - Function signature: y = cgemv(alpha,a,x,[beta,y,offx,incx,offy,incy,trans,overwrite_y]) Required arguments: alpha : input complex a : input rank-2 array(‘F’) with bounds (m,n) x : input rank-1 array(‘F’) with bounds (*) Optional arguments: beta := (0.0, 0.0) input complex y : input rank-1 array(‘F’) with bounds (ly) overwrite_y := 0 input int offx := 0 input int incx := 1 input int offy := 0 input int incy := 1 input int trans := 0 input int Return objects: y : rank-1 array(‘F’) with bounds (ly) scipy.linalg.blas.cgerc = cgerc - Function signature: a = cgerc(alpha,x,y,[incx,incy,a,overwrite_x,overwrite_y,overwrite_a]) Required arguments: alpha : input complex x : input rank-1 array(‘F’) with bounds (m) y : input rank-1 array(‘F’) with bounds (n) Optional arguments: overwrite_x := 1 input int incx := 1 input int overwrite_y := 1 input int incy := 1 input int a := (0.0,0.0) input rank-2 array(‘F’) with bounds (m,n) overwrite_a := 0 input int Return objects: a : rank-2 array(‘F’) with bounds (m,n) scipy.linalg.blas.cgeru = cgeru - Function signature: a = cgeru(alpha,x,y,[incx,incy,a,overwrite_x,overwrite_y,overwrite_a]) Required arguments: alpha : input complex x : input rank-1 array(‘F’) with bounds (m) y : input rank-1 array(‘F’) with bounds (n) Optional arguments: overwrite_x := 1 input int incx := 1 input int overwrite_y := 1 input int incy := 1 input int a := (0.0,0.0) input rank-2 array(‘F’) with bounds (m,n) overwrite_a := 0 input int Return objects: a : rank-2 array(‘F’) with bounds (m,n) scipy.linalg.blas.chemm = chemm - Function signature: c = chemm(alpha,a,b,[beta,c,side,lower,overwrite_c]) Required arguments: alpha : input complex a : input rank-2 array(‘F’) with bounds (lda,ka) b : input rank-2 array(‘F’) with bounds (ldb,kb) 5.12. All functions 377 SciPy Reference Guide, Release 0.13.0 Optional arguments: beta := (0.0, 0.0) input complex c : input rank-2 array(‘F’) with bounds (m,n) overwrite_c := 0 input int side := 0 input int lower := 0 input int Return objects: c : rank-2 array(‘F’) with bounds (m,n) scipy.linalg.blas.chemv = chemv - Function signature: y = chemv(alpha,a,x,[beta,y,offx,incx,offy,incy,lower,overwrite_y]) Required arguments: alpha : input complex a : input rank-2 array(‘F’) with bounds (n,n) x : input rank-1 array(‘F’) with bounds (*) Optional arguments: beta := (0.0, 0.0) input complex y : input rank-1 array(‘F’) with bounds (ly) overwrite_y := 0 input int offx := 0 input int incx := 1 input int offy := 0 input int incy := 1 input int lower := 0 input int Return objects: y : rank-1 array(‘F’) with bounds (ly) scipy.linalg.blas.cherk = cherk - Function signature: c = cherk(alpha,a,[beta,c,trans,lower,overwrite_c]) Required arguments: alpha : input complex a : input rank-2 array(‘F’) with bounds (lda,ka) Optional arguments: beta := (0.0, 0.0) input complex c : input rank-2 array(‘F’) with bounds (n,n) overwrite_c := 0 input int trans := 0 input int lower := 0 input int Return objects: c : rank-2 array(‘F’) with bounds (n,n) scipy.linalg.blas.cher2k = cher2k - Function signature: c = cher2k(alpha,a,b,[beta,c,trans,lower,overwrite_c]) Required arguments: alpha : input complex a : input rank-2 array(‘F’) with bounds (lda,ka) b : input rank-2 array(‘F’) with bounds (ldb,kb) Optional arguments: beta := (0.0, 0.0) input complex c : input rank-2 array(‘F’) with bounds (n,n) overwrite_c := 0 input int trans := 0 input int lower := 0 input int Return objects: c : rank-2 array(‘F’) with bounds (n,n) scipy.linalg.blas.crotg = crotg - Function signature: c,s = crotg(a,b) 378 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Required arguments: a : input complex b : input complex Return objects: c : complex s : complex scipy.linalg.blas.cscal = cscal - Function signature: x = cscal(a,x,[n,offx,incx]) Required arguments: a : input complex x : input rank-1 array(‘F’) with bounds (*) Optional arguments: n := (len(x)-offx)/abs(incx) input int offx := 0 input int incx := 1 input int Return objects: x : rank-1 array(‘F’) with bounds (*) scipy.linalg.blas.csrot = csrot - Function signature: x,y = csrot(x,y,c,s,[n,offx,incx,offy,incy,overwrite_x,overwrite_y]) Required arguments: x : input rank-1 array(‘F’) with bounds (*) y : input rank-1 array(‘F’) with bounds (*) c : input float s : input float Optional arguments: n := (len(x)-offx)/abs(incx) input int overwrite_x := 0 input int offx := 0 input int incx := 1 input int overwrite_y := 0 input int offy := 0 input int incy := 1 input int Return objects: x : rank-1 array(‘F’) with bounds (*) y : rank-1 array(‘F’) with bounds (*) scipy.linalg.blas.csscal = csscal - Function signature: x = csscal(a,x,[n,offx,incx,overwrite_x]) Required arguments: a : input float x : input rank-1 array(‘F’) with bounds (*) Optional arguments: n := (len(x)-offx)/abs(incx) input int overwrite_x := 0 input int offx := 0 input int incx := 1 input int Return objects: x : rank-1 array(‘F’) with bounds (*) scipy.linalg.blas.csymm = csymm - Function signature: c = csymm(alpha,a,b,[beta,c,side,lower,overwrite_c]) Required arguments: alpha : input complex a : input rank-2 array(‘F’) with bounds (lda,ka) b : input rank-2 array(‘F’) with bounds (ldb,kb) 5.12. All functions 379 SciPy Reference Guide, Release 0.13.0 Optional arguments: beta := (0.0, 0.0) input complex c : input rank-2 array(‘F’) with bounds (m,n) overwrite_c := 0 input int side := 0 input int lower := 0 input int Return objects: c : rank-2 array(‘F’) with bounds (m,n) scipy.linalg.blas.csyrk = csyrk - Function signature: c = csyrk(alpha,a,[beta,c,trans,lower,overwrite_c]) Required arguments: alpha : input complex a : input rank-2 array(‘F’) with bounds (lda,ka) Optional arguments: beta := (0.0, 0.0) input complex c : input rank-2 array(‘F’) with bounds (n,n) overwrite_c := 0 input int trans := 0 input int lower := 0 input int Return objects: c : rank-2 array(‘F’) with bounds (n,n) scipy.linalg.blas.csyr2k = csyr2k - Function signature: c = csyr2k(alpha,a,b,[beta,c,trans,lower,overwrite_c]) Required arguments: alpha : input complex a : input rank-2 array(‘F’) with bounds (lda,ka) b : input rank-2 array(‘F’) with bounds (ldb,kb) Optional arguments: beta := (0.0, 0.0) input complex c : input rank-2 array(‘F’) with bounds (n,n) overwrite_c := 0 input int trans := 0 input int lower := 0 input int Return objects: c : rank-2 array(‘F’) with bounds (n,n) scipy.linalg.blas.cswap = cswap - Function signature: x,y = cswap(x,y,[n,offx,incx,offy,incy]) Required arguments: x : input rank-1 array(‘F’) with bounds (*) y : input rank-1 array(‘F’) with bounds (*) Optional arguments: n := (len(x)-offx)/abs(incx) input int offx := 0 input int incx := 1 input int offy := 0 input int incy := 1 input int Return objects: x : rank-1 array(‘F’) with bounds (*) y : rank-1 array(‘F’) with bounds (*) scipy.linalg.blas.ctrmv = ctrmv - Function signature: x = ctrmv(a,x,[offx,incx,lower,trans,unitdiag,overwrite_x]) 380 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Required arguments: a : input rank-2 array(‘F’) with bounds (n,n) x : input rank-1 array(‘F’) with bounds (*) Optional arguments: overwrite_x := 0 input int offx := 0 input int incx := 1 input int lower := 0 input int trans := 0 input int unitdiag := 0 input int Return objects: x : rank-1 array(‘F’) with bounds (*) scipy.linalg.blas.dasum = dasum - Function signature: s = dasum(x,[n,offx,incx]) Required arguments: x : input rank-1 array(‘d’) with bounds (*) Optional arguments: n := (len(x)-offx)/abs(incx) input int offx := 0 input int incx := 1 input int Return objects: s : float scipy.linalg.blas.daxpy = daxpy - Function signature: z = daxpy(x,y,[n,a,offx,incx,offy,incy]) Required arguments: x : input rank-1 array(‘d’) with bounds (*) y : input rank-1 array(‘d’) with bounds (*) Optional arguments: n := (len(x)-offx)/abs(incx) input int a := 1.0 input float offx := 0 input int incx := 1 input int offy := 0 input int incy := 1 input int Return objects: z : rank-1 array(‘d’) with bounds (*) and y storage scipy.linalg.blas.dcopy = dcopy - Function signature: y = dcopy(x,y,[n,offx,incx,offy,incy]) Required arguments: x : input rank-1 array(‘d’) with bounds (*) y : input rank-1 array(‘d’) with bounds (*) Optional arguments: n := (len(x)-offx)/abs(incx) input int offx := 0 input int incx := 1 input int offy := 0 input int incy := 1 input int Return objects: y : rank-1 array(‘d’) with bounds (*) scipy.linalg.blas.ddot = ddot - Function signature: xy = ddot(x,y,[n,offx,incx,offy,incy]) 5.12. All functions 381 SciPy Reference Guide, Release 0.13.0 Required arguments: x : input rank-1 array(‘d’) with bounds (*) y : input rank-1 array(‘d’) with bounds (*) Optional arguments: n := (len(x)-offx)/abs(incx) input int offx := 0 input int incx := 1 input int offy := 0 input int incy := 1 input int Return objects: xy : float scipy.linalg.blas.dgemm = dgemm - Function signature: c = dgemm(alpha,a,b,[beta,c,trans_a,trans_b,overwrite_c]) Required arguments: alpha : input float a : input rank-2 array(‘d’) with bounds (lda,ka) b : input rank-2 array(‘d’) with bounds (ldb,kb) Optional arguments: beta := 0.0 input float c : input rank-2 array(‘d’) with bounds (m,n) overwrite_c := 0 input int trans_a := 0 input int trans_b := 0 input int Return objects: c : rank-2 array(‘d’) with bounds (m,n) scipy.linalg.blas.dgemv = dgemv - Function signature: y = dgemv(alpha,a,x,[beta,y,offx,incx,offy,incy,trans,overwrite_y]) Required arguments: alpha : input float a : input rank-2 array(‘d’) with bounds (m,n) x : input rank-1 array(‘d’) with bounds (*) Optional arguments: beta := 0.0 input float y : input rank-1 array(‘d’) with bounds (ly) overwrite_y := 0 input int offx := 0 input int incx := 1 input int offy := 0 input int incy := 1 input int trans := 0 input int Return objects: y : rank-1 array(‘d’) with bounds (ly) scipy.linalg.blas.dger = dger - Function signature: a = dger(alpha,x,y,[incx,incy,a,overwrite_x,overwrite_y,overwrite_a]) Required arguments: alpha : input float x : input rank-1 array(‘d’) with bounds (m) y : input rank-1 array(‘d’) with bounds (n) Optional arguments: overwrite_x := 1 input int incx := 1 input int overwrite_y := 1 input int incy := 1 input int a := 0.0 input rank-2 array(‘d’) with bounds (m,n) overwrite_a := 0 input int Return objects: a : rank-2 array(‘d’) with bounds (m,n) scipy.linalg.blas.dnrm2 = 382 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 dnrm2 - Function signature: n2 = dnrm2(x,[n,offx,incx]) Required arguments: x : input rank-1 array(‘d’) with bounds (*) Optional arguments: n := (len(x)-offx)/abs(incx) input int offx := 0 input int incx := 1 input int Return objects: n2 : float scipy.linalg.blas.drot = drot - Function signature: x,y = drot(x,y,c,s,[n,offx,incx,offy,incy,overwrite_x,overwrite_y]) Required arguments: x : input rank-1 array(‘d’) with bounds (*) y : input rank-1 array(‘d’) with bounds (*) c : input float s : input float Optional arguments: n := (len(x)-offx)/abs(incx) input int overwrite_x := 0 input int offx := 0 input int incx := 1 input int overwrite_y := 0 input int offy := 0 input int incy := 1 input int Return objects: x : rank-1 array(‘d’) with bounds (*) y : rank-1 array(‘d’) with bounds (*) scipy.linalg.blas.drotg = drotg - Function signature: c,s = drotg(a,b) Required arguments: a : input float b : input float Return objects: c : float s : float scipy.linalg.blas.drotm = drotm - Function signature: x,y = drotm(x,y,param,[n,offx,incx,offy,incy,overwrite_x,overwrite_y]) Required arguments: x : input rank-1 array(‘d’) with bounds (*) y : input rank-1 array(‘d’) with bounds (*) param : input rank-1 array(‘d’) with bounds (5) Optional arguments: n := (len(x)-offx)/abs(incx) input int overwrite_x := 0 input int offx := 0 input int incx := 1 input int overwrite_y := 0 input int offy := 0 input int incy := 1 input int Return objects: x : rank-1 array(‘d’) with bounds (*) y : rank-1 array(‘d’) with bounds (*) scipy.linalg.blas.drotmg = drotmg - Function signature: param = drotmg(d1,d2,x1,y1) 5.12. All functions 383 SciPy Reference Guide, Release 0.13.0 Required arguments: d1 : input float d2 : input float x1 : input float y1 : input float Return objects: param : rank-1 array(‘d’) with bounds (5) scipy.linalg.blas.dscal = dscal - Function signature: x = dscal(a,x,[n,offx,incx]) Required arguments: a : input float x : input rank-1 array(‘d’) with bounds (*) Optional arguments: n := (len(x)-offx)/abs(incx) input int offx := 0 input int incx := 1 input int Return objects: x : rank-1 array(‘d’) with bounds (*) scipy.linalg.blas.dswap = dswap - Function signature: x,y = dswap(x,y,[n,offx,incx,offy,incy]) Required arguments: x : input rank-1 array(‘d’) with bounds (*) y : input rank-1 array(‘d’) with bounds (*) Optional arguments: n := (len(x)-offx)/abs(incx) input int offx := 0 input int incx := 1 input int offy := 0 input int incy := 1 input int Return objects: x : rank-1 array(‘d’) with bounds (*) y : rank-1 array(‘d’) with bounds (*) scipy.linalg.blas.dsymm = dsymm - Function signature: c = dsymm(alpha,a,b,[beta,c,side,lower,overwrite_c]) Required arguments: alpha : input float a : input rank-2 array(‘d’) with bounds (lda,ka) b : input rank-2 array(‘d’) with bounds (ldb,kb) Optional arguments: beta := 0.0 input float c : input rank-2 array(‘d’) with bounds (m,n) overwrite_c := 0 input int side := 0 input int lower := 0 input int Return objects: c : rank-2 array(‘d’) with bounds (m,n) scipy.linalg.blas.dsymv = dsymv - Function signature: y = dsymv(alpha,a,x,[beta,y,offx,incx,offy,incy,lower,overwrite_y]) Required arguments: alpha : input float a : input rank-2 array(‘d’) with bounds (n,n) x : input rank-1 array(‘d’) with bounds (*) 384 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Optional arguments: beta := 0.0 input float y : input rank-1 array(‘d’) with bounds (ly) overwrite_y := 0 input int offx := 0 input int incx := 1 input int offy := 0 input int incy := 1 input int lower := 0 input int Return objects: y : rank-1 array(‘d’) with bounds (ly) scipy.linalg.blas.dsyrk = dsyrk - Function signature: c = dsyrk(alpha,a,[beta,c,trans,lower,overwrite_c]) Required arguments: alpha : input float a : input rank-2 array(‘d’) with bounds (lda,ka) Optional arguments: beta := 0.0 input float c : input rank-2 array(‘d’) with bounds (n,n) overwrite_c := 0 input int trans := 0 input int lower := 0 input int Return objects: c : rank-2 array(‘d’) with bounds (n,n) scipy.linalg.blas.dsyr2k = dsyr2k - Function signature: c = dsyr2k(alpha,a,b,[beta,c,trans,lower,overwrite_c]) Required arguments: alpha : input float a : input rank-2 array(‘d’) with bounds (lda,ka) b : input rank-2 array(‘d’) with bounds (ldb,kb) Optional arguments: beta := 0.0 input float c : input rank-2 array(‘d’) with bounds (n,n) overwrite_c := 0 input int trans := 0 input int lower := 0 input int Return objects: c : rank-2 array(‘d’) with bounds (n,n) scipy.linalg.blas.dtrmv = dtrmv - Function signature: x = dtrmv(a,x,[offx,incx,lower,trans,unitdiag,overwrite_x]) Required arguments: a : input rank-2 array(‘d’) with bounds (n,n) x : input rank-1 array(‘d’) with bounds (*) Optional arguments: overwrite_x := 0 input int offx := 0 input int incx := 1 input int lower := 0 input int trans := 0 input int unitdiag := 0 input int Return objects: x : rank-1 array(‘d’) with bounds (*) scipy.linalg.blas.dzasum = dzasum - Function signature: s = dzasum(x,[n,offx,incx]) 5.12. All functions 385 SciPy Reference Guide, Release 0.13.0 Required arguments: x : input rank-1 array(‘D’) with bounds (*) Optional arguments: n := (len(x)-offx)/abs(incx) input int offx := 0 input int incx := 1 input int Return objects: s : float scipy.linalg.blas.dznrm2 = dznrm2 - Function signature: n2 = dznrm2(x,[n,offx,incx]) Required arguments: x : input rank-1 array(‘D’) with bounds (*) Optional arguments: n := (len(x)-offx)/abs(incx) input int offx := 0 input int incx := 1 input int Return objects: n2 : float scipy.linalg.blas.icamax = icamax - Function signature: k = icamax(x,[n,offx,incx]) Required arguments: x : input rank-1 array(‘F’) with bounds (*) Optional arguments: n := (len(x)-offx)/abs(incx) input int offx := 0 input int incx := 1 input int Return objects: k : int scipy.linalg.blas.idamax = idamax - Function signature: k = idamax(x,[n,offx,incx]) Required arguments: x : input rank-1 array(‘d’) with bounds (*) Optional arguments: n := (len(x)-offx)/abs(incx) input int offx := 0 input int incx := 1 input int Return objects: k : int scipy.linalg.blas.isamax = isamax - Function signature: k = isamax(x,[n,offx,incx]) Required arguments: x : input rank-1 array(‘f’) with bounds (*) 386 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Optional arguments: n := (len(x)-offx)/abs(incx) input int offx := 0 input int incx := 1 input int Return objects: k : int scipy.linalg.blas.izamax = izamax - Function signature: k = izamax(x,[n,offx,incx]) Required arguments: x : input rank-1 array(‘D’) with bounds (*) Optional arguments: n := (len(x)-offx)/abs(incx) input int offx := 0 input int incx := 1 input int Return objects: k : int scipy.linalg.blas.sasum = sasum - Function signature: s = sasum(x,[n,offx,incx]) Required arguments: x : input rank-1 array(‘f’) with bounds (*) Optional arguments: n := (len(x)-offx)/abs(incx) input int offx := 0 input int incx := 1 input int Return objects: s : float scipy.linalg.blas.saxpy = saxpy - Function signature: z = saxpy(x,y,[n,a,offx,incx,offy,incy]) Required arguments: x : input rank-1 array(‘f’) with bounds (*) y : input rank-1 array(‘f’) with bounds (*) Optional arguments: n := (len(x)-offx)/abs(incx) input int a := 1.0 input float offx := 0 input int incx := 1 input int offy := 0 input int incy := 1 input int Return objects: z : rank-1 array(‘f’) with bounds (*) and y storage scipy.linalg.blas.scasum = scasum - Function signature: s = scasum(x,[n,offx,incx]) Required arguments: x : input rank-1 array(‘F’) with bounds (*) Optional arguments: n := (len(x)-offx)/abs(incx) input int offx := 0 input int incx := 1 input int 5.12. All functions 387 SciPy Reference Guide, Release 0.13.0 Return objects: s : float scipy.linalg.blas.scnrm2 = scnrm2 - Function signature: n2 = scnrm2(x,[n,offx,incx]) Required arguments: x : input rank-1 array(‘F’) with bounds (*) Optional arguments: n := (len(x)-offx)/abs(incx) input int offx := 0 input int incx := 1 input int Return objects: n2 : float scipy.linalg.blas.scopy = scopy - Function signature: y = scopy(x,y,[n,offx,incx,offy,incy]) Required arguments: x : input rank-1 array(‘f’) with bounds (*) y : input rank-1 array(‘f’) with bounds (*) Optional arguments: n := (len(x)-offx)/abs(incx) input int offx := 0 input int incx := 1 input int offy := 0 input int incy := 1 input int Return objects: y : rank-1 array(‘f’) with bounds (*) scipy.linalg.blas.sdot = sdot - Function signature: xy = sdot(x,y,[n,offx,incx,offy,incy]) Required arguments: x : input rank-1 array(‘f’) with bounds (*) y : input rank-1 array(‘f’) with bounds (*) Optional arguments: n := (len(x)-offx)/abs(incx) input int offx := 0 input int incx := 1 input int offy := 0 input int incy := 1 input int Return objects: xy : float scipy.linalg.blas.sgemm = sgemm - Function signature: c = sgemm(alpha,a,b,[beta,c,trans_a,trans_b,overwrite_c]) Required arguments: alpha : input float a : input rank-2 array(‘f’) with bounds (lda,ka) b : input rank-2 array(‘f’) with bounds (ldb,kb) Optional arguments: beta := 0.0 input float c : input rank-2 array(‘f’) with bounds (m,n) overwrite_c := 0 input int trans_a := 0 input int trans_b := 0 input int 388 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Return objects: c : rank-2 array(‘f’) with bounds (m,n) scipy.linalg.blas.sgemv = sgemv - Function signature: y = sgemv(alpha,a,x,[beta,y,offx,incx,offy,incy,trans,overwrite_y]) Required arguments: alpha : input float a : input rank-2 array(‘f’) with bounds (m,n) x : input rank-1 array(‘f’) with bounds (*) Optional arguments: beta := 0.0 input float y : input rank-1 array(‘f’) with bounds (ly) overwrite_y := 0 input int offx := 0 input int incx := 1 input int offy := 0 input int incy := 1 input int trans := 0 input int Return objects: y : rank-1 array(‘f’) with bounds (ly) scipy.linalg.blas.sger = sger - Function signature: a = sger(alpha,x,y,[incx,incy,a,overwrite_x,overwrite_y,overwrite_a]) Required arguments: alpha : input float x : input rank-1 array(‘f’) with bounds (m) y : input rank-1 array(‘f’) with bounds (n) Optional arguments: overwrite_x := 1 input int incx := 1 input int overwrite_y := 1 input int incy := 1 input int a := 0.0 input rank-2 array(‘f’) with bounds (m,n) overwrite_a := 0 input int Return objects: a : rank-2 array(‘f’) with bounds (m,n) scipy.linalg.blas.snrm2 = snrm2 - Function signature: n2 = snrm2(x,[n,offx,incx]) Required arguments: x : input rank-1 array(‘f’) with bounds (*) Optional arguments: n := (len(x)-offx)/abs(incx) input int offx := 0 input int incx := 1 input int Return objects: n2 : float scipy.linalg.blas.srot = srot - Function signature: x,y = srot(x,y,c,s,[n,offx,incx,offy,incy,overwrite_x,overwrite_y]) Required arguments: x : input rank-1 array(‘f’) with bounds (*) y : input rank-1 array(‘f’) with bounds (*) c : input float s : input float 5.12. All functions 389 SciPy Reference Guide, Release 0.13.0 Optional arguments: n := (len(x)-offx)/abs(incx) input int overwrite_x := 0 input int offx := 0 input int incx := 1 input int overwrite_y := 0 input int offy := 0 input int incy := 1 input int Return objects: x : rank-1 array(‘f’) with bounds (*) y : rank-1 array(‘f’) with bounds (*) scipy.linalg.blas.srotg = srotg - Function signature: c,s = srotg(a,b) Required arguments: a : input float b : input float Return objects: c : float s : float scipy.linalg.blas.srotm = srotm - Function signature: x,y = srotm(x,y,param,[n,offx,incx,offy,incy,overwrite_x,overwrite_y]) Required arguments: x : input rank-1 array(‘f’) with bounds (*) y : input rank-1 array(‘f’) with bounds (*) param : input rank-1 array(‘f’) with bounds (5) Optional arguments: n := (len(x)-offx)/abs(incx) input int overwrite_x := 0 input int offx := 0 input int incx := 1 input int overwrite_y := 0 input int offy := 0 input int incy := 1 input int Return objects: x : rank-1 array(‘f’) with bounds (*) y : rank-1 array(‘f’) with bounds (*) scipy.linalg.blas.srotmg = srotmg - Function signature: param = srotmg(d1,d2,x1,y1) Required arguments: d1 : input float d2 : input float x1 : input float y1 : input float Return objects: param : rank-1 array(‘f’) with bounds (5) scipy.linalg.blas.sscal = sscal - Function signature: x = sscal(a,x,[n,offx,incx]) Required arguments: a : input float x : input rank-1 array(‘f’) with bounds (*) Optional arguments: n := (len(x)-offx)/abs(incx) input int offx := 0 input int incx := 1 input int Return objects: x : rank-1 array(‘f’) with bounds (*) 390 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 scipy.linalg.blas.sswap = sswap - Function signature: x,y = sswap(x,y,[n,offx,incx,offy,incy]) Required arguments: x : input rank-1 array(‘f’) with bounds (*) y : input rank-1 array(‘f’) with bounds (*) Optional arguments: n := (len(x)-offx)/abs(incx) input int offx := 0 input int incx := 1 input int offy := 0 input int incy := 1 input int Return objects: x : rank-1 array(‘f’) with bounds (*) y : rank-1 array(‘f’) with bounds (*) scipy.linalg.blas.ssymm = ssymm - Function signature: c = ssymm(alpha,a,b,[beta,c,side,lower,overwrite_c]) Required arguments: alpha : input float a : input rank-2 array(‘f’) with bounds (lda,ka) b : input rank-2 array(‘f’) with bounds (ldb,kb) Optional arguments: beta := 0.0 input float c : input rank-2 array(‘f’) with bounds (m,n) overwrite_c := 0 input int side := 0 input int lower := 0 input int Return objects: c : rank-2 array(‘f’) with bounds (m,n) scipy.linalg.blas.ssymv = ssymv - Function signature: y = ssymv(alpha,a,x,[beta,y,offx,incx,offy,incy,lower,overwrite_y]) Required arguments: alpha : input float a : input rank-2 array(‘f’) with bounds (n,n) x : input rank-1 array(‘f’) with bounds (*) Optional arguments: beta := 0.0 input float y : input rank-1 array(‘f’) with bounds (ly) overwrite_y := 0 input int offx := 0 input int incx := 1 input int offy := 0 input int incy := 1 input int lower := 0 input int Return objects: y : rank-1 array(‘f’) with bounds (ly) scipy.linalg.blas.ssyrk = ssyrk - Function signature: c = ssyrk(alpha,a,[beta,c,trans,lower,overwrite_c]) Required arguments: alpha : input float a : input rank-2 array(‘f’) with bounds (lda,ka) Optional arguments: beta := 0.0 input float c : input rank-2 array(‘f’) with bounds (n,n) overwrite_c := 0 input int trans := 0 input int lower := 0 input int 5.12. All functions 391 SciPy Reference Guide, Release 0.13.0 Return objects: c : rank-2 array(‘f’) with bounds (n,n) scipy.linalg.blas.ssyr2k = ssyr2k - Function signature: c = ssyr2k(alpha,a,b,[beta,c,trans,lower,overwrite_c]) Required arguments: alpha : input float a : input rank-2 array(‘f’) with bounds (lda,ka) b : input rank-2 array(‘f’) with bounds (ldb,kb) Optional arguments: beta := 0.0 input float c : input rank-2 array(‘f’) with bounds (n,n) overwrite_c := 0 input int trans := 0 input int lower := 0 input int Return objects: c : rank-2 array(‘f’) with bounds (n,n) scipy.linalg.blas.strmv = strmv - Function signature: x = strmv(a,x,[offx,incx,lower,trans,unitdiag,overwrite_x]) Required arguments: a : input rank-2 array(‘f’) with bounds (n,n) x : input rank-1 array(‘f’) with bounds (*) Optional arguments: overwrite_x := 0 input int offx := 0 input int incx := 1 input int lower := 0 input int trans := 0 input int unitdiag := 0 input int Return objects: x : rank-1 array(‘f’) with bounds (*) scipy.linalg.blas.zaxpy = zaxpy - Function signature: z = zaxpy(x,y,[n,a,offx,incx,offy,incy]) Required arguments: x : input rank-1 array(‘D’) with bounds (*) y : input rank-1 array(‘D’) with bounds (*) Optional arguments: n := (len(x)-offx)/abs(incx) input int a := (1.0, 0.0) input complex offx := 0 input int incx := 1 input int offy := 0 input int incy := 1 input int Return objects: z : rank-1 array(‘D’) with bounds (*) and y storage scipy.linalg.blas.zcopy = zcopy - Function signature: y = zcopy(x,y,[n,offx,incx,offy,incy]) Required arguments: x : input rank-1 array(‘D’) with bounds (*) y : input rank-1 array(‘D’) with bounds (*) 392 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Optional arguments: n := (len(x)-offx)/abs(incx) input int offx := 0 input int incx := 1 input int offy := 0 input int incy := 1 input int Return objects: y : rank-1 array(‘D’) with bounds (*) scipy.linalg.blas.zdotc = zdotc - Function signature: xy = zdotc(x,y,[n,offx,incx,offy,incy]) Required arguments: x : input rank-1 array(‘D’) with bounds (*) y : input rank-1 array(‘D’) with bounds (*) Optional arguments: n := (len(x)-offx)/abs(incx) input int offx := 0 input int incx := 1 input int offy := 0 input int incy := 1 input int Return objects: xy : complex scipy.linalg.blas.zdotu = zdotu - Function signature: xy = zdotu(x,y,[n,offx,incx,offy,incy]) Required arguments: x : input rank-1 array(‘D’) with bounds (*) y : input rank-1 array(‘D’) with bounds (*) Optional arguments: n := (len(x)-offx)/abs(incx) input int offx := 0 input int incx := 1 input int offy := 0 input int incy := 1 input int Return objects: xy : complex scipy.linalg.blas.zdrot = zdrot - Function signature: x,y = zdrot(x,y,c,s,[n,offx,incx,offy,incy,overwrite_x,overwrite_y]) Required arguments: x : input rank-1 array(‘D’) with bounds (*) y : input rank-1 array(‘D’) with bounds (*) c : input float s : input float Optional arguments: n := (len(x)-offx)/abs(incx) input int overwrite_x := 0 input int offx := 0 input int incx := 1 input int overwrite_y := 0 input int offy := 0 input int incy := 1 input int Return objects: x : rank-1 array(‘D’) with bounds (*) y : rank-1 array(‘D’) with bounds (*) scipy.linalg.blas.zdscal = zdscal - Function signature: x = zdscal(a,x,[n,offx,incx,overwrite_x]) 5.12. All functions 393 SciPy Reference Guide, Release 0.13.0 Required arguments: a : input float x : input rank-1 array(‘D’) with bounds (*) Optional arguments: n := (len(x)-offx)/abs(incx) input int overwrite_x := 0 input int offx := 0 input int incx := 1 input int Return objects: x : rank-1 array(‘D’) with bounds (*) scipy.linalg.blas.zgemm = zgemm - Function signature: c = zgemm(alpha,a,b,[beta,c,trans_a,trans_b,overwrite_c]) Required arguments: alpha : input complex a : input rank-2 array(‘D’) with bounds (lda,ka) b : input rank-2 array(‘D’) with bounds (ldb,kb) Optional arguments: beta := (0.0, 0.0) input complex c : input rank-2 array(‘D’) with bounds (m,n) overwrite_c := 0 input int trans_a := 0 input int trans_b := 0 input int Return objects: c : rank-2 array(‘D’) with bounds (m,n) scipy.linalg.blas.zgemv = zgemv - Function signature: y = zgemv(alpha,a,x,[beta,y,offx,incx,offy,incy,trans,overwrite_y]) Required arguments: alpha : input complex a : input rank-2 array(‘D’) with bounds (m,n) x : input rank-1 array(‘D’) with bounds (*) Optional arguments: beta := (0.0, 0.0) input complex y : input rank-1 array(‘D’) with bounds (ly) overwrite_y := 0 input int offx := 0 input int incx := 1 input int offy := 0 input int incy := 1 input int trans := 0 input int Return objects: y : rank-1 array(‘D’) with bounds (ly) scipy.linalg.blas.zgerc = zgerc - Function signature: a = zgerc(alpha,x,y,[incx,incy,a,overwrite_x,overwrite_y,overwrite_a]) Required arguments: alpha : input complex x : input rank-1 array(‘D’) with bounds (m) y : input rank-1 array(‘D’) with bounds (n) Optional arguments: overwrite_x := 1 input int incx := 1 input int overwrite_y := 1 input int incy := 1 input int a := (0.0,0.0) input rank-2 array(‘D’) with bounds (m,n) overwrite_a := 0 input int Return objects: a : rank-2 array(‘D’) with bounds (m,n) 394 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 scipy.linalg.blas.zgeru = zgeru - Function signature: a = zgeru(alpha,x,y,[incx,incy,a,overwrite_x,overwrite_y,overwrite_a]) Required arguments: alpha : input complex x : input rank-1 array(‘D’) with bounds (m) y : input rank-1 array(‘D’) with bounds (n) Optional arguments: overwrite_x := 1 input int incx := 1 input int overwrite_y := 1 input int incy := 1 input int a := (0.0,0.0) input rank-2 array(‘D’) with bounds (m,n) overwrite_a := 0 input int Return objects: a : rank-2 array(‘D’) with bounds (m,n) scipy.linalg.blas.zhemm = zhemm - Function signature: c = zhemm(alpha,a,b,[beta,c,side,lower,overwrite_c]) Required arguments: alpha : input complex a : input rank-2 array(‘D’) with bounds (lda,ka) b : input rank-2 array(‘D’) with bounds (ldb,kb) Optional arguments: beta := (0.0, 0.0) input complex c : input rank-2 array(‘D’) with bounds (m,n) overwrite_c := 0 input int side := 0 input int lower := 0 input int Return objects: c : rank-2 array(‘D’) with bounds (m,n) scipy.linalg.blas.zhemv = zhemv - Function signature: y = zhemv(alpha,a,x,[beta,y,offx,incx,offy,incy,lower,overwrite_y]) Required arguments: alpha : input complex a : input rank-2 array(‘D’) with bounds (n,n) x : input rank-1 array(‘D’) with bounds (*) Optional arguments: beta := (0.0, 0.0) input complex y : input rank-1 array(‘D’) with bounds (ly) overwrite_y := 0 input int offx := 0 input int incx := 1 input int offy := 0 input int incy := 1 input int lower := 0 input int Return objects: y : rank-1 array(‘D’) with bounds (ly) scipy.linalg.blas.zherk = zherk - Function signature: c = zherk(alpha,a,[beta,c,trans,lower,overwrite_c]) Required arguments: alpha : input complex a : input rank-2 array(‘D’) with bounds (lda,ka) 5.12. All functions 395 SciPy Reference Guide, Release 0.13.0 Optional arguments: beta := (0.0, 0.0) input complex c : input rank-2 array(‘D’) with bounds (n,n) overwrite_c := 0 input int trans := 0 input int lower := 0 input int Return objects: c : rank-2 array(‘D’) with bounds (n,n) scipy.linalg.blas.zher2k = zher2k - Function signature: c = zher2k(alpha,a,b,[beta,c,trans,lower,overwrite_c]) Required arguments: alpha : input complex a : input rank-2 array(‘D’) with bounds (lda,ka) b : input rank-2 array(‘D’) with bounds (ldb,kb) Optional arguments: beta := (0.0, 0.0) input complex c : input rank-2 array(‘D’) with bounds (n,n) overwrite_c := 0 input int trans := 0 input int lower := 0 input int Return objects: c : rank-2 array(‘D’) with bounds (n,n) scipy.linalg.blas.zrotg = zrotg - Function signature: c,s = zrotg(a,b) Required arguments: a : input complex b : input complex Return objects: c : complex s : complex scipy.linalg.blas.zscal = zscal - Function signature: x = zscal(a,x,[n,offx,incx]) Required arguments: a : input complex x : input rank-1 array(‘D’) with bounds (*) Optional arguments: n := (len(x)-offx)/abs(incx) input int offx := 0 input int incx := 1 input int Return objects: x : rank-1 array(‘D’) with bounds (*) scipy.linalg.blas.zsymm = zsymm - Function signature: c = zsymm(alpha,a,b,[beta,c,side,lower,overwrite_c]) Required arguments: alpha : input complex a : input rank-2 array(‘D’) with bounds (lda,ka) b : input rank-2 array(‘D’) with bounds (ldb,kb) 396 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Optional arguments: beta := (0.0, 0.0) input complex c : input rank-2 array(‘D’) with bounds (m,n) overwrite_c := 0 input int side := 0 input int lower := 0 input int Return objects: c : rank-2 array(‘D’) with bounds (m,n) scipy.linalg.blas.zsyrk = zsyrk - Function signature: c = zsyrk(alpha,a,[beta,c,trans,lower,overwrite_c]) Required arguments: alpha : input complex a : input rank-2 array(‘D’) with bounds (lda,ka) Optional arguments: beta := (0.0, 0.0) input complex c : input rank-2 array(‘D’) with bounds (n,n) overwrite_c := 0 input int trans := 0 input int lower := 0 input int Return objects: c : rank-2 array(‘D’) with bounds (n,n) scipy.linalg.blas.zsyr2k = zsyr2k - Function signature: c = zsyr2k(alpha,a,b,[beta,c,trans,lower,overwrite_c]) Required arguments: alpha : input complex a : input rank-2 array(‘D’) with bounds (lda,ka) b : input rank-2 array(‘D’) with bounds (ldb,kb) Optional arguments: beta := (0.0, 0.0) input complex c : input rank-2 array(‘D’) with bounds (n,n) overwrite_c := 0 input int trans := 0 input int lower := 0 input int Return objects: c : rank-2 array(‘D’) with bounds (n,n) scipy.linalg.blas.zswap = zswap - Function signature: x,y = zswap(x,y,[n,offx,incx,offy,incy]) Required arguments: x : input rank-1 array(‘D’) with bounds (*) y : input rank-1 array(‘D’) with bounds (*) Optional arguments: n := (len(x)-offx)/abs(incx) input int offx := 0 input int incx := 1 input int offy := 0 input int incy := 1 input int Return objects: x : rank-1 array(‘D’) with bounds (*) y : rank-1 array(‘D’) with bounds (*) scipy.linalg.blas.ztrmv = ztrmv - Function signature: x = ztrmv(a,x,[offx,incx,lower,trans,unitdiag,overwrite_x]) 5.12. All functions 397 SciPy Reference Guide, Release 0.13.0 Required arguments: a : input rank-2 array(‘D’) with bounds (n,n) x : input rank-1 array(‘D’) with bounds (*) Optional arguments: overwrite_x := 0 input int offx := 0 input int incx := 1 input int lower := 0 input int trans := 0 input int unitdiag := 0 input int Return objects: x : rank-1 array(‘D’) with bounds (*) 5.13 Low-level LAPACK functions This module contains low-level functions from the LAPACK library. New in version 0.12.0. Warning: These functions do little to no error checking. It is possible to cause crashes by mis-using them, so prefer using the higher-level routines in scipy.linalg. 5.14 Finding functions get_lapack_funcs(names[, arrays, dtype]) Return available LAPACK function objects from names. 5.15 All functions cgbsv cgbtrf cgbtrs cgebal cgees cgeev cgegv cgehrd cgelss cgeqp3 cgeqrf cgerqf cgesdd cgesv cgetrf cgetri cgetrs cgges cggev chbevd chbevx cheev cheevd cheevr 398 cgbsv - Function signature: cgbtrf - Function signature: cgbtrs - Function signature: cgebal - Function signature: cgees - Function signature: cgeev - Function signature: cgegv - Function signature: cgehrd - Function signature: cgelss - Function signature: cgeqp3 - Function signature: cgeqrf - Function signature: cgerqf - Function signature: cgesdd - Function signature: cgesv - Function signature: cgetrf - Function signature: cgetri - Function signature: cgetrs - Function signature: cgges - Function signature: cggev - Function signature: chbevd - Function signature: chbevx - Function signature: cheev - Function signature: cheevd - Function signature: cheevr - Function signature: Continued on next page Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Table 5.74 – continued from previous page chegv chegv - Function signature: chegvd chegvd - Function signature: chegvx chegvx - Function signature: claswp claswp - Function signature: clauum clauum - Function signature: cpbsv cpbsv - Function signature: cpbtrf cpbtrf - Function signature: cpbtrs cpbtrs - Function signature: cposv cposv - Function signature: cpotrf cpotrf - Function signature: cpotri cpotri - Function signature: cpotrs cpotrs - Function signature: ctrsyl ctrsyl - Function signature: ctrtri ctrtri - Function signature: ctrtrs ctrtrs - Function signature: cungqr cungqr - Function signature: cungrq cungrq - Function signature: cunmqr cunmqr - Function signature: dgbsv dgbsv - Function signature: dgbtrf dgbtrf - Function signature: dgbtrs dgbtrs - Function signature: dgebal dgebal - Function signature: dgees dgees - Function signature: dgeev dgeev - Function signature: dgegv dgegv - Function signature: dgehrd dgehrd - Function signature: dgelss dgelss - Function signature: dgeqp3 dgeqp3 - Function signature: dgeqrf dgeqrf - Function signature: dgerqf dgerqf - Function signature: dgesdd dgesdd - Function signature: dgesv dgesv - Function signature: dgetrf dgetrf - Function signature: dgetri dgetri - Function signature: dgetrs dgetrs - Function signature: dgges dgges - Function signature: dggev dggev - Function signature: dlamch dlamch - Function signature: dlaswp dlaswp - Function signature: dlauum dlauum - Function signature: dorgqr dorgqr - Function signature: dorgrq dorgrq - Function signature: dormqr dormqr - Function signature: dpbsv dpbsv - Function signature: dpbtrf dpbtrf - Function signature: dpbtrs dpbtrs - Function signature: dposv dposv - Function signature: dpotrf dpotrf - Function signature: dpotri dpotri - Function signature: dpotrs dpotrs - Function signature: Continued on next page 5.15. All functions 399 SciPy Reference Guide, Release 0.13.0 Table 5.74 – continued from previous page dsbev dsbev - Function signature: dsbevd dsbevd - Function signature: dsbevx dsbevx - Function signature: dsyev dsyev - Function signature: dsyevd dsyevd - Function signature: dsyevr dsyevr - Function signature: dsygv dsygv - Function signature: dsygvd dsygvd - Function signature: dsygvx dsygvx - Function signature: dtrsyl dtrsyl - Function signature: dtrtri dtrtri - Function signature: dtrtrs dtrtrs - Function signature: sgbsv sgbsv - Function signature: sgbtrf sgbtrf - Function signature: sgbtrs sgbtrs - Function signature: sgebal sgebal - Function signature: sgees sgees - Function signature: sgeev sgeev - Function signature: sgegv sgegv - Function signature: sgehrd sgehrd - Function signature: sgelss sgelss - Function signature: sgeqp3 sgeqp3 - Function signature: sgeqrf sgeqrf - Function signature: sgerqf sgerqf - Function signature: sgesdd sgesdd - Function signature: sgesv sgesv - Function signature: sgetrf sgetrf - Function signature: sgetri sgetri - Function signature: sgetrs sgetrs - Function signature: sgges sgges - Function signature: sggev sggev - Function signature: slamch slamch - Function signature: slaswp slaswp - Function signature: slauum slauum - Function signature: sorgqr sorgqr - Function signature: sorgrq sorgrq - Function signature: sormqr sormqr - Function signature: spbsv spbsv - Function signature: spbtrf spbtrf - Function signature: spbtrs spbtrs - Function signature: sposv sposv - Function signature: spotrf spotrf - Function signature: spotri spotri - Function signature: spotrs spotrs - Function signature: ssbev ssbev - Function signature: ssbevd ssbevd - Function signature: ssbevx ssbevx - Function signature: ssyev ssyev - Function signature: ssyevd ssyevd - Function signature: ssyevr ssyevr - Function signature: Continued on next page 400 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Table 5.74 – continued from previous page ssygv ssygv - Function signature: ssygvd ssygvd - Function signature: ssygvx ssygvx - Function signature: strsyl strsyl - Function signature: strtri strtri - Function signature: strtrs strtrs - Function signature: zgbsv zgbsv - Function signature: zgbtrf zgbtrf - Function signature: zgbtrs zgbtrs - Function signature: zgebal zgebal - Function signature: zgees zgees - Function signature: zgeev zgeev - Function signature: zgegv zgegv - Function signature: zgehrd zgehrd - Function signature: zgelss zgelss - Function signature: zgeqp3 zgeqp3 - Function signature: zgeqrf zgeqrf - Function signature: zgerqf zgerqf - Function signature: zgesdd zgesdd - Function signature: zgesv zgesv - Function signature: zgetrf zgetrf - Function signature: zgetri zgetri - Function signature: zgetrs zgetrs - Function signature: zgges zgges - Function signature: zggev zggev - Function signature: zhbevd zhbevd - Function signature: zhbevx zhbevx - Function signature: zheev zheev - Function signature: zheevd zheevd - Function signature: zheevr zheevr - Function signature: zhegv zhegv - Function signature: zhegvd zhegvd - Function signature: zhegvx zhegvx - Function signature: zlaswp zlaswp - Function signature: zlauum zlauum - Function signature: zpbsv zpbsv - Function signature: zpbtrf zpbtrf - Function signature: zpbtrs zpbtrs - Function signature: zposv zposv - Function signature: zpotrf zpotrf - Function signature: zpotri zpotri - Function signature: zpotrs zpotrs - Function signature: ztrsyl ztrsyl - Function signature: ztrtri ztrtri - Function signature: ztrtrs ztrtrs - Function signature: zungqr zungqr - Function signature: zungrq zungrq - Function signature: zunmqr zunmqr - Function signature: scipy.linalg.lapack.cgbsv = 5.15. All functions 401 SciPy Reference Guide, Release 0.13.0 cgbsv - Function signature: lub,piv,x,info = cgbsv(kl,ku,ab,b,[overwrite_ab,overwrite_b]) Required arguments: kl : input int ku : input int ab : input rank-2 array(‘F’) with bounds (2*kl+ku+1,n) b : input rank-2 array(‘F’) with bounds (n,nrhs) Optional arguments: overwrite_ab := 0 input int overwrite_b := 0 input int Return objects: lub : rank-2 array(‘F’) with bounds (2*kl+ku+1,n) and ab storage piv : rank-1 array(‘i’) with bounds (n) x : rank-2 array(‘F’) with bounds (n,nrhs) and b storage info : int scipy.linalg.lapack.cgbtrf = cgbtrf - Function signature: lu,ipiv,info = cgbtrf(ab,kl,ku,[m,n,ldab,overwrite_ab]) Required arguments: ab : input rank-2 array(‘F’) with bounds (ldab,*) kl : input int ku : input int Optional arguments: m := shape(ab,1) input int n := shape(ab,1) input int overwrite_ab := 0 input int ldab := shape(ab,0) input int Return objects: lu : rank-2 array(‘F’) with bounds (ldab,*) and ab storage ipiv : rank-1 array(‘i’) with bounds (MIN(m,n)) info : int scipy.linalg.lapack.cgbtrs = cgbtrs - Function signature: x,info = cgbtrs(ab,kl,ku,b,ipiv,[trans,n,ldab,ldb,overwrite_b]) Required arguments: ab : input rank-2 array(‘F’) with bounds (ldab,*) kl : input int ku : input int b : input rank-2 array(‘F’) with bounds (ldb,*) ipiv : input rank-1 array(‘i’) with bounds (n) Optional arguments: overwrite_b := 0 input int trans := 0 input int n := shape(ab,1) input int ldab := shape(ab,0) input int ldb := shape(b,0) input int Return objects: x : rank-2 array(‘F’) with bounds (ldb,*) and b storage info : int scipy.linalg.lapack.cgebal = cgebal - Function signature: ba,lo,hi,pivscale,info = cgebal(a,[scale,permute,overwrite_a]) Required arguments: a : input rank-2 array(‘F’) with bounds (m,n) Optional arguments: scale := 0 input int permute := 0 input int overwrite_a := 0 input int Return objects: ba : rank-2 array(‘F’) with bounds (m,n) and a storage lo : int hi : int pivscale : rank-1 array(‘f’) with bounds (n) info : int 402 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 scipy.linalg.lapack.cgees = cgees - Function signature: t,sdim,w,vs,work,info = cgees(cselect,a,[compute_v,sort_t,lwork,cselect_extra_args,overwrite_a]) Required arguments: cselect : call-back function a : input rank-2 array(‘F’) with bounds (n,n) Optional arguments: compute_v := 1 input int sort_t := 0 input int cselect_extra_args := () input tuple overwrite_a := 0 input int lwork := 3*n input int Return objects: t : rank-2 array(‘F’) with bounds (n,n) and a storage sdim : int w : rank-1 array(‘F’) with bounds (n) vs : rank-2 array(‘F’) with bounds (ldvs,n) work : rank-1 array(‘F’) with bounds (MAX(lwork,1)) info : int Call-back functions: def cselect(arg): return cselect Required arguments: arg : input complex Return objects: cselect : int scipy.linalg.lapack.cgeev = cgeev - Function signature: w,vl,vr,info = cgeev(a,[compute_vl,compute_vr,lwork,overwrite_a]) Required arguments: a : input rank-2 array(‘F’) with bounds (n,n) Optional arguments: compute_vl := 1 input int compute_vr := 1 input int overwrite_a := 0 input int lwork := 2*n input int Return objects: w : rank-1 array(‘F’) with bounds (n) vl : rank-2 array(‘F’) with bounds (ldvl,n) vr : rank-2 array(‘F’) with bounds (ldvr,n) info : int scipy.linalg.lapack.cgegv = cgegv - Function signature: alpha,beta,vl,vr,info = cgegv(a,b,[compute_vl,compute_vr,lwork,overwrite_a,overwrite_b]) Required arguments: a : input rank-2 array(‘F’) with bounds (n,n) b : input rank-2 array(‘F’) with bounds (n,n) Optional arguments: compute_vl := 1 input int compute_vr := 1 input int overwrite_a := 0 input int overwrite_b := 0 input int lwork := 2*n input int Return objects: alpha : rank-1 array(‘F’) with bounds (n) beta : rank-1 array(‘F’) with bounds (n) vl : rank-2 array(‘F’) with bounds (ldvl,n) vr : rank-2 array(‘F’) with bounds (ldvr,n) info : int scipy.linalg.lapack.cgehrd = 5.15. All functions 403 SciPy Reference Guide, Release 0.13.0 cgehrd - Function signature: ht,tau,info = cgehrd(a,[lo,hi,lwork,overwrite_a]) Required arguments: a : input rank-2 array(‘F’) with bounds (n,n) Optional arguments: lo := 0 input int hi := n-1 input int overwrite_a := 0 input int lwork := MAX(n,1) input int Return objects: ht : rank-2 array(‘F’) with bounds (n,n) and a storage tau : rank-1 array(‘F’) with bounds (n - 1) info : int scipy.linalg.lapack.cgelss = cgelss - Function signature: v,x,s,rank,work,info = cgelss(a,b,[cond,lwork,overwrite_a,overwrite_b]) Required arguments: a : input rank-2 array(‘F’) with bounds (m,n) b : input rank-2 array(‘F’) with bounds (maxmn,nrhs) Optional arguments: overwrite_a := 0 input int overwrite_b := 0 input int cond := -1.0 input float lwork := 2*minmn+MAX(maxmn,nrhs) input int Return objects: v : rank-2 array(‘F’) with bounds (m,n) and a storage x : rank-2 array(‘F’) with bounds (maxmn,nrhs) and b storage s : rank-1 array(‘f’) with bounds (minmn) rank : int work : rank-1 array(‘F’) with bounds (MAX(lwork,1)) info : int scipy.linalg.lapack.cgeqp3 = cgeqp3 - Function signature: qr,jpvt,tau,work,info = cgeqp3(a,[lwork,overwrite_a]) Required arguments: a : input rank-2 array(‘F’) with bounds (m,n) Optional arguments: overwrite_a := 0 input int lwork := 3*(n+1) input int Return objects: qr : rank-2 array(‘F’) with bounds (m,n) and a storage jpvt : rank-1 array(‘i’) with bounds (n) tau : rank-1 array(‘F’) with bounds (MIN(m,n)) work : rank-1 array(‘F’) with bounds (MAX(lwork,1)) info : int scipy.linalg.lapack.cgeqrf = cgeqrf - Function signature: qr,tau,work,info = cgeqrf(a,[lwork,overwrite_a]) Required arguments: a : input rank-2 array(‘F’) with bounds (m,n) Optional arguments: overwrite_a := 0 input int lwork := 3*n input int 404 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Return objects: qr : rank-2 array(‘F’) with bounds (m,n) and a storage tau : rank-1 array(‘F’) with bounds (MIN(m,n)) work : rank-1 array(‘F’) with bounds (MAX(lwork,1)) info : int scipy.linalg.lapack.cgerqf = cgerqf - Function signature: qr,tau,work,info = cgerqf(a,[lwork,overwrite_a]) Required arguments: a : input rank-2 array(‘F’) with bounds (m,n) Optional arguments: overwrite_a := 0 input int lwork := 3*m input int Return objects: qr : rank-2 array(‘F’) with bounds (m,n) and a storage tau : rank-1 array(‘F’) with bounds (MIN(m,n)) work : rank-1 array(‘F’) with bounds (MAX(lwork,1)) info : int scipy.linalg.lapack.cgesdd = cgesdd - Function signature: u,s,vt,info = cgesdd(a,[compute_uv,full_matrices,lwork,overwrite_a]) Required arguments: a : input rank-2 array(‘F’) with bounds (m,n) Optional arguments: overwrite_a := 0 input int compute_uv := 1 input int full_matrices := 1 input int lwork := (compute_uv?2*minmn*minmn+MAX(m,n)+2*minmn:2*minmn+MAX(m,n)) input int Return objects: u : rank-2 array(‘F’) with bounds (u0,u1) s : rank-1 array(‘f’) with bounds (minmn) vt : rank-2 array(‘F’) with bounds (vt0,vt1) info : int scipy.linalg.lapack.cgesv = cgesv - Function signature: lu,piv,x,info = cgesv(a,b,[overwrite_a,overwrite_b]) Required arguments: a : input rank-2 array(‘F’) with bounds (n,n) b : input rank-2 array(‘F’) with bounds (n,nrhs) Optional arguments: overwrite_a := 0 input int overwrite_b := 0 input int Return objects: lu : rank-2 array(‘F’) with bounds (n,n) and a storage piv : rank-1 array(‘i’) with bounds (n) x : rank-2 array(‘F’) with bounds (n,nrhs) and b storage info : int scipy.linalg.lapack.cgetrf = cgetrf - Function signature: lu,piv,info = cgetrf(a,[overwrite_a]) Required arguments: a : input rank-2 array(‘F’) with bounds (m,n) 5.15. All functions 405 SciPy Reference Guide, Release 0.13.0 Optional arguments: overwrite_a := 0 input int Return objects: lu : rank-2 array(‘F’) with bounds (m,n) and a storage piv : rank-1 array(‘i’) with bounds (MIN(m,n)) info : int scipy.linalg.lapack.cgetri = cgetri - Function signature: inv_a,info = cgetri(lu,piv,[lwork,overwrite_lu]) Required arguments: lu : input rank-2 array(‘F’) with bounds (n,n) piv : input rank-1 array(‘i’) with bounds (n) Optional arguments: overwrite_lu := 0 input int lwork := 3*n input int Return objects: inv_a : rank-2 array(‘F’) with bounds (n,n) and lu storage info : int scipy.linalg.lapack.cgetrs = cgetrs - Function signature: x,info = cgetrs(lu,piv,b,[trans,overwrite_b]) Required arguments: lu : input rank-2 array(‘F’) with bounds (n,n) piv : input rank-1 array(‘i’) with bounds (n) b : input rank-2 array(‘F’) with bounds (n,nrhs) Optional arguments: overwrite_b := 0 input int trans := 0 input int Return objects: x : rank-2 array(‘F’) with bounds (n,nrhs) and b storage info : int scipy.linalg.lapack.cgges = cgges - Function signature: a,b,sdim,alpha,beta,vsl,vsr,work,info = cgges(cselect,a,b,[jobvsl,jobvsr,sort_t,ldvsl,ldvsr,lwork,cselect_extra_args,o Required arguments: cselect : call-back function a : input rank-2 array(‘F’) with bounds (lda,*) b : input rank-2 array(‘F’) with bounds (ldb,*) Optional arguments: jobvsl := 1 input int jobvsr := 1 input int sort_t := 0 input int cselect_extra_args := () input tuple overwrite_a := 0 input int overwrite_b := 0 input int ldvsl := ((jobvsl==1)?n:1) input int ldvsr := ((jobvsr==1)?n:1) input int lwork := 2*n input int Return objects: a : rank-2 array(‘F’) with bounds (lda,*) b : rank-2 array(‘F’) with bounds (ldb,*) sdim : int alpha : rank-1 array(‘F’) with bounds (n) beta : rank-1 array(‘F’) with bounds (n) vsl : rank2 array(‘F’) with bounds (ldvsl,n) vsr : rank-2 array(‘F’) with bounds (ldvsr,n) work : rank-1 array(‘F’) with bounds (MAX(lwork,1)) info : int Call-back functions: def cselect(alpha,beta): return cselect Required arguments: alpha : input complex beta : input complex 406 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Return objects: cselect : int scipy.linalg.lapack.cggev = cggev - Function signature: alpha,beta,vl,vr,work,info = cggev(a,b,[compute_vl,compute_vr,lwork,overwrite_a,overwrite_b]) Required arguments: a : input rank-2 array(‘F’) with bounds (n,n) b : input rank-2 array(‘F’) with bounds (n,n) Optional arguments: compute_vl := 1 input int compute_vr := 1 input int overwrite_a := 0 input int overwrite_b := 0 input int lwork := 2*n input int Return objects: alpha : rank-1 array(‘F’) with bounds (n) beta : rank-1 array(‘F’) with bounds (n) vl : rank-2 array(‘F’) with bounds (ldvl,n) vr : rank-2 array(‘F’) with bounds (ldvr,n) work : rank-1 array(‘F’) with bounds (MAX(lwork,1)) info : int scipy.linalg.lapack.chbevd = chbevd - Function signature: w,z,info = chbevd(ab,[compute_v,lower,ldab,lrwork,liwork,overwrite_ab]) Required arguments: ab : input rank-2 array(‘F’) with bounds (ldab,*) Optional arguments: overwrite_ab := 1 input int compute_v := 1 input int lower := 0 input int ldab := shape(ab,0) input int lrwork := (compute_v?1+5*n+2*n*n:n) input int liwork := (compute_v?3+5*n:1) input int Return objects: w : rank-1 array(‘f’) with bounds (n) z : rank-2 array(‘F’) with bounds (ldz,ldz) info : int scipy.linalg.lapack.chbevx = chbevx - Function signature: w,z,m,ifail,info = chbevx(ab,vl,vu,il,iu,[ldab,compute_v,range,lower,abstol,mmax,overwrite_ab]) Required arguments: ab : input rank-2 array(‘F’) with bounds (ldab,*) vl : input float vu : input float il : input int iu : input int Optional arguments: overwrite_ab := 1 input int ldab := shape(ab,0) input int compute_v := 1 input int range := 0 input int lower := 0 input int abstol := 0.0 input float mmax := (compute_v?(range==2?(iu-il+1):n):1) input int Return objects: w : rank-1 array(‘f’) with bounds (n) z : rank-2 array(‘F’) with bounds (ldz,mmax) m : int ifail : rank-1 array(‘i’) with bounds ((compute_v?n:1)) info : int scipy.linalg.lapack.cheev = cheev - Function signature: w,v,info = cheev(a,[compute_v,lower,lwork,overwrite_a]) 5.15. All functions 407 SciPy Reference Guide, Release 0.13.0 Required arguments: a : input rank-2 array(‘F’) with bounds (n,n) Optional arguments: compute_v := 1 input int lower := 0 input int overwrite_a := 0 input int lwork := 2*n-1 input int Return objects: w : rank-1 array(‘f’) with bounds (n) v : rank-2 array(‘F’) with bounds (n,n) and a storage info : int scipy.linalg.lapack.cheevd = cheevd - Function signature: w,v,info = cheevd(a,[compute_v,lower,lwork,overwrite_a]) Required arguments: a : input rank-2 array(‘F’) with bounds (n,n) Optional arguments: compute_v := 1 input int lower := 0 input int overwrite_a := 0 input int lwork := (compute_v?2*n+n*n:n+1) input int Return objects: w : rank-1 array(‘f’) with bounds (n) v : rank-2 array(‘F’) with bounds (n,n) and a storage info : int scipy.linalg.lapack.cheevr = cheevr - Function signature: w,z,info = cheevr(a,[jobz,range,uplo,il,iu,lwork,overwrite_a]) Required arguments: a : input rank-2 array(‘F’) with bounds (n,n) Optional arguments: jobz := ‘V’ input string(len=1) range := ‘A’ input string(len=1) uplo := ‘L’ input string(len=1) overwrite_a := 0 input int il := 1 input int iu := n input int lwork := 18*n input int Return objects: w : rank-1 array(‘f’) with bounds (n) z : rank-2 array(‘F’) with bounds (n,m) info : int scipy.linalg.lapack.chegv = chegv - Function signature: a,w,info = chegv(a,b,[itype,jobz,uplo,overwrite_a,overwrite_b]) Required arguments: a : input rank-2 array(‘F’) with bounds (n,n) b : input rank-2 array(‘F’) with bounds (n,n) Optional arguments: itype := 1 input int jobz := ‘V’ input string(len=1) uplo := ‘L’ input string(len=1) overwrite_a := 0 input int overwrite_b := 0 input int Return objects: a : rank-2 array(‘F’) with bounds (n,n) w : rank-1 array(‘f’) with bounds (n) info : int scipy.linalg.lapack.chegvd = 408 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 chegvd - Function signature: a,w,info = chegvd(a,b,[itype,jobz,uplo,lwork,overwrite_a,overwrite_b]) Required arguments: a : input rank-2 array(‘F’) with bounds (n,n) b : input rank-2 array(‘F’) with bounds (n,n) Optional arguments: itype := 1 input int jobz := ‘V’ input string(len=1) uplo := ‘L’ input string(len=1) overwrite_a := 0 input int overwrite_b := 0 input int lwork := 2*n+n*n input int Return objects: a : rank-2 array(‘F’) with bounds (n,n) w : rank-1 array(‘f’) with bounds (n) info : int scipy.linalg.lapack.chegvx = chegvx - Function signature: w,z,ifail,info = chegvx(a,b,iu,[itype,jobz,uplo,il,lwork,overwrite_a,overwrite_b]) Required arguments: a : input rank-2 array(‘F’) with bounds (n,n) b : input rank-2 array(‘F’) with bounds (n,n) iu : input int Optional arguments: itype := 1 input int jobz := ‘V’ input string(len=1) uplo := ‘L’ input string(len=1) overwrite_a := 0 input int overwrite_b := 0 input int il := 1 input int lwork := 18*n-1 input int Return objects: w : rank-1 array(‘f’) with bounds (n) z : rank-2 array(‘F’) with bounds (n,m) ifail : rank-1 array(‘i’) with bounds (n) info : int scipy.linalg.lapack.claswp = claswp - Function signature: a = claswp(a,piv,[k1,k2,off,inc,overwrite_a]) Required arguments: a : input rank-2 array(‘F’) with bounds (nrows,n) piv : input rank-1 array(‘i’) with bounds (*) Optional arguments: overwrite_a := 0 input int k1 := 0 input int k2 := len(piv)-1 input int off := 0 input int inc := 1 input int Return objects: a : rank-2 array(‘F’) with bounds (nrows,n) scipy.linalg.lapack.clauum = clauum - Function signature: a,info = clauum(c,[lower,overwrite_c]) Required arguments: c : input rank-2 array(‘F’) with bounds (n,n) Optional arguments: overwrite_c := 0 input int lower := 0 input int Return objects: a : rank-2 array(‘F’) with bounds (n,n) and c storage info : int 5.15. All functions 409 SciPy Reference Guide, Release 0.13.0 scipy.linalg.lapack.cpbsv = cpbsv - Function signature: c,x,info = cpbsv(ab,b,[lower,ldab,overwrite_ab,overwrite_b]) Required arguments: ab : input rank-2 array(‘F’) with bounds (ldab,n) b : input rank-2 array(‘F’) with bounds (ldb,nrhs) Optional arguments: lower := 0 input int overwrite_ab := 0 input int ldab := shape(ab,0) input int overwrite_b := 0 input int Return objects: c : rank-2 array(‘F’) with bounds (ldab,n) and ab storage x : rank-2 array(‘F’) with bounds (ldb,nrhs) and b storage info : int scipy.linalg.lapack.cpbtrf = cpbtrf - Function signature: c,info = cpbtrf(ab,[lower,ldab,overwrite_ab]) Required arguments: ab : input rank-2 array(‘F’) with bounds (ldab,n) Optional arguments: lower := 0 input int overwrite_ab := 0 input int ldab := shape(ab,0) input int Return objects: c : rank-2 array(‘F’) with bounds (ldab,n) and ab storage info : int scipy.linalg.lapack.cpbtrs = cpbtrs - Function signature: x,info = cpbtrs(ab,b,[lower,ldab,overwrite_b]) Required arguments: ab : input rank-2 array(‘F’) with bounds (ldab,n) b : input rank-2 array(‘F’) with bounds (ldb,nrhs) Optional arguments: lower := 0 input int ldab := shape(ab,0) input int overwrite_b := 0 input int Return objects: x : rank-2 array(‘F’) with bounds (ldb,nrhs) and b storage info : int scipy.linalg.lapack.cposv = cposv - Function signature: c,x,info = cposv(a,b,[lower,overwrite_a,overwrite_b]) Required arguments: a : input rank-2 array(‘F’) with bounds (n,n) b : input rank-2 array(‘F’) with bounds (n,nrhs) Optional arguments: overwrite_a := 0 input int overwrite_b := 0 input int lower := 0 input int 410 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Return objects: c : rank-2 array(‘F’) with bounds (n,n) and a storage x : rank-2 array(‘F’) with bounds (n,nrhs) and b storage info : int scipy.linalg.lapack.cpotrf = cpotrf - Function signature: c,info = cpotrf(a,[lower,clean,overwrite_a]) Required arguments: a : input rank-2 array(‘F’) with bounds (n,n) Optional arguments: overwrite_a := 0 input int lower := 0 input int clean := 1 input int Return objects: c : rank-2 array(‘F’) with bounds (n,n) and a storage info : int scipy.linalg.lapack.cpotri = cpotri - Function signature: inv_a,info = cpotri(c,[lower,overwrite_c]) Required arguments: c : input rank-2 array(‘F’) with bounds (n,n) Optional arguments: overwrite_c := 0 input int lower := 0 input int Return objects: inv_a : rank-2 array(‘F’) with bounds (n,n) and c storage info : int scipy.linalg.lapack.cpotrs = cpotrs - Function signature: x,info = cpotrs(c,b,[lower,overwrite_b]) Required arguments: c : input rank-2 array(‘F’) with bounds (n,n) b : input rank-2 array(‘F’) with bounds (n,nrhs) Optional arguments: overwrite_b := 0 input int lower := 0 input int Return objects: x : rank-2 array(‘F’) with bounds (n,nrhs) and b storage info : int scipy.linalg.lapack.ctrsyl = ctrsyl - Function signature: x,scale,info = ctrsyl(a,b,c,[trana,tranb,isgn,overwrite_c]) Required arguments: a : input rank-2 array(‘F’) with bounds (m,m) b : input rank-2 array(‘F’) with bounds (n,n) c : input rank-2 array(‘F’) with bounds (m,n) Optional arguments: trana := ‘N’ input string(len=1) tranb := ‘N’ input string(len=1) isgn := 1 input int overwrite_c := 0 input int 5.15. All functions 411 SciPy Reference Guide, Release 0.13.0 Return objects: x : rank-2 array(‘F’) with bounds (m,n) and c storage scale : float info : int scipy.linalg.lapack.ctrtri = ctrtri - Function signature: inv_c,info = ctrtri(c,[lower,unitdiag,overwrite_c]) Required arguments: c : input rank-2 array(‘F’) with bounds (n,n) Optional arguments: overwrite_c := 0 input int lower := 0 input int unitdiag := 0 input int Return objects: inv_c : rank-2 array(‘F’) with bounds (n,n) and c storage info : int scipy.linalg.lapack.ctrtrs = ctrtrs - Function signature: x,info = ctrtrs(a,b,[lower,trans,unitdiag,lda,overwrite_b]) Required arguments: a : input rank-2 array(‘F’) with bounds (lda,n) b : input rank-2 array(‘F’) with bounds (ldb,nrhs) Optional arguments: lower := 0 input int trans := 0 input int unitdiag := 0 input int lda := shape(a,0) input int overwrite_b := 0 input int Return objects: x : rank-2 array(‘F’) with bounds (ldb,nrhs) and b storage info : int scipy.linalg.lapack.cungqr = cungqr - Function signature: q,work,info = cungqr(a,tau,[lwork,overwrite_a]) Required arguments: a : input rank-2 array(‘F’) with bounds (m,n) tau : input rank-1 array(‘F’) with bounds (k) Optional arguments: overwrite_a := 0 input int lwork := 3*n input int Return objects: q : rank-2 array(‘F’) with bounds (m,n) and a storage work : rank-1 array(‘F’) with bounds (MAX(lwork,1)) info : int scipy.linalg.lapack.cungrq = cungrq - Function signature: q,work,info = cungrq(a,tau,[lwork,overwrite_a]) Required arguments: a : input rank-2 array(‘F’) with bounds (m,n) tau : input rank-1 array(‘F’) with bounds (k) Optional arguments: overwrite_a := 0 input int lwork := 3*m input int 412 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Return objects: q : rank-2 array(‘F’) with bounds (m,n) and a storage work : rank-1 array(‘F’) with bounds (MAX(lwork,1)) info : int scipy.linalg.lapack.cunmqr = cunmqr - Function signature: cq,work,info = cunmqr(side,trans,a,tau,c,lwork,[overwrite_c]) Required arguments: side : input string(len=1) trans : input string(len=1) a : input rank-2 array(‘F’) with bounds (lda,k) tau : input rank-1 array(‘F’) with bounds (k) c : input rank-2 array(‘F’) with bounds (ldc,n) lwork : input int Optional arguments: overwrite_c := 0 input int Return objects: cq : rank-2 array(‘F’) with bounds (ldc,n) and c storage work : rank-1 array(‘F’) with bounds (MAX(lwork,1)) info : int scipy.linalg.lapack.dgbsv = dgbsv - Function signature: lub,piv,x,info = dgbsv(kl,ku,ab,b,[overwrite_ab,overwrite_b]) Required arguments: kl : input int ku : input int ab : input rank-2 array(‘d’) with bounds (2*kl+ku+1,n) b : input rank-2 array(‘d’) with bounds (n,nrhs) Optional arguments: overwrite_ab := 0 input int overwrite_b := 0 input int Return objects: lub : rank-2 array(‘d’) with bounds (2*kl+ku+1,n) and ab storage piv : rank-1 array(‘i’) with bounds (n) x : rank-2 array(‘d’) with bounds (n,nrhs) and b storage info : int scipy.linalg.lapack.dgbtrf = dgbtrf - Function signature: lu,ipiv,info = dgbtrf(ab,kl,ku,[m,n,ldab,overwrite_ab]) Required arguments: ab : input rank-2 array(‘d’) with bounds (ldab,*) kl : input int ku : input int Optional arguments: m := shape(ab,1) input int n := shape(ab,1) input int overwrite_ab := 0 input int ldab := shape(ab,0) input int Return objects: lu : rank-2 array(‘d’) with bounds (ldab,*) and ab storage ipiv : rank-1 array(‘i’) with bounds (MIN(m,n)) info : int scipy.linalg.lapack.dgbtrs = dgbtrs - Function signature: x,info = dgbtrs(ab,kl,ku,b,ipiv,[trans,n,ldab,ldb,overwrite_b]) 5.15. All functions 413 SciPy Reference Guide, Release 0.13.0 Required arguments: ab : input rank-2 array(‘d’) with bounds (ldab,*) kl : input int ku : input int b : input rank-2 array(‘d’) with bounds (ldb,*) ipiv : input rank-1 array(‘i’) with bounds (n) Optional arguments: overwrite_b := 0 input int trans := 0 input int n := shape(ab,1) input int ldab := shape(ab,0) input int ldb := shape(b,0) input int Return objects: x : rank-2 array(‘d’) with bounds (ldb,*) and b storage info : int scipy.linalg.lapack.dgebal = dgebal - Function signature: ba,lo,hi,pivscale,info = dgebal(a,[scale,permute,overwrite_a]) Required arguments: a : input rank-2 array(‘d’) with bounds (m,n) Optional arguments: scale := 0 input int permute := 0 input int overwrite_a := 0 input int Return objects: ba : rank-2 array(‘d’) with bounds (m,n) and a storage lo : int hi : int pivscale : rank-1 array(‘d’) with bounds (n) info : int scipy.linalg.lapack.dgees = dgees - Function signature: t,sdim,wr,wi,vs,work,info = dgees(dselect,a,[compute_v,sort_t,lwork,dselect_extra_args,overwrite_a]) Required arguments: dselect : call-back function a : input rank-2 array(‘d’) with bounds (n,n) Optional arguments: compute_v := 1 input int sort_t := 0 input int dselect_extra_args := () input tuple overwrite_a := 0 input int lwork := 3*n input int Return objects: t : rank-2 array(‘d’) with bounds (n,n) and a storage sdim : int wr : rank-1 array(‘d’) with bounds (n) wi : rank-1 array(‘d’) with bounds (n) vs : rank-2 array(‘d’) with bounds (ldvs,n) work : rank-1 array(‘d’) with bounds (MAX(lwork,1)) info : int Call-back functions: def dselect(arg1,arg2): return dselect Required arguments: arg1 : input float arg2 : input float Return objects: dselect : int scipy.linalg.lapack.dgeev = dgeev - Function signature: wr,wi,vl,vr,info = dgeev(a,[compute_vl,compute_vr,lwork,overwrite_a]) Required arguments: a : input rank-2 array(‘d’) with bounds (n,n) 414 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Optional arguments: compute_vl := 1 input int compute_vr := 1 input int overwrite_a := 0 input int lwork := 4*n input int Return objects: wr : rank-1 array(‘d’) with bounds (n) wi : rank-1 array(‘d’) with bounds (n) vl : rank-2 array(‘d’) with bounds (ldvl,n) vr : rank-2 array(‘d’) with bounds (ldvr,n) info : int scipy.linalg.lapack.dgegv = dgegv - Function signature: alphar,alphai,beta,vl,vr,info = dgegv(a,b,[compute_vl,compute_vr,lwork,overwrite_a,overwrite_b]) Required arguments: a : input rank-2 array(‘d’) with bounds (n,n) b : input rank-2 array(‘d’) with bounds (n,n) Optional arguments: compute_vl := 1 input int compute_vr := 1 input int overwrite_a := 0 input int overwrite_b := 0 input int lwork := 8*n input int Return objects: alphar : rank-1 array(‘d’) with bounds (n) alphai : rank-1 array(‘d’) with bounds (n) beta : rank-1 array(‘d’) with bounds (n) vl : rank-2 array(‘d’) with bounds (ldvl,n) vr : rank-2 array(‘d’) with bounds (ldvr,n) info : int scipy.linalg.lapack.dgehrd = dgehrd - Function signature: ht,tau,info = dgehrd(a,[lo,hi,lwork,overwrite_a]) Required arguments: a : input rank-2 array(‘d’) with bounds (n,n) Optional arguments: lo := 0 input int hi := n-1 input int overwrite_a := 0 input int lwork := MAX(n,1) input int Return objects: ht : rank-2 array(‘d’) with bounds (n,n) and a storage tau : rank-1 array(‘d’) with bounds (n - 1) info : int scipy.linalg.lapack.dgelss = dgelss - Function signature: v,x,s,rank,work,info = dgelss(a,b,[cond,lwork,overwrite_a,overwrite_b]) Required arguments: a : input rank-2 array(‘d’) with bounds (m,n) b : input rank-2 array(‘d’) with bounds (maxmn,nrhs) Optional arguments: overwrite_a := 0 input int overwrite_b := 0 input int cond := -1.0 input float lwork := 3*minmn+MAX(2*minmn,MAX(maxmn,nrhs)) input int Return objects: v : rank-2 array(‘d’) with bounds (m,n) and a storage x : rank-2 array(‘d’) with bounds (maxmn,nrhs) and b storage s : rank-1 array(‘d’) with bounds (minmn) rank : int work : rank-1 array(‘d’) with bounds (MAX(lwork,1)) info : int 5.15. All functions 415 SciPy Reference Guide, Release 0.13.0 scipy.linalg.lapack.dgeqp3 = dgeqp3 - Function signature: qr,jpvt,tau,work,info = dgeqp3(a,[lwork,overwrite_a]) Required arguments: a : input rank-2 array(‘d’) with bounds (m,n) Optional arguments: overwrite_a := 0 input int lwork := 3*(n+1) input int Return objects: qr : rank-2 array(‘d’) with bounds (m,n) and a storage jpvt : rank-1 array(‘i’) with bounds (n) tau : rank-1 array(‘d’) with bounds (MIN(m,n)) work : rank-1 array(‘d’) with bounds (MAX(lwork,1)) info : int scipy.linalg.lapack.dgeqrf = dgeqrf - Function signature: qr,tau,work,info = dgeqrf(a,[lwork,overwrite_a]) Required arguments: a : input rank-2 array(‘d’) with bounds (m,n) Optional arguments: overwrite_a := 0 input int lwork := 3*n input int Return objects: qr : rank-2 array(‘d’) with bounds (m,n) and a storage tau : rank-1 array(‘d’) with bounds (MIN(m,n)) work : rank-1 array(‘d’) with bounds (MAX(lwork,1)) info : int scipy.linalg.lapack.dgerqf = dgerqf - Function signature: qr,tau,work,info = dgerqf(a,[lwork,overwrite_a]) Required arguments: a : input rank-2 array(‘d’) with bounds (m,n) Optional arguments: overwrite_a := 0 input int lwork := 3*m input int Return objects: qr : rank-2 array(‘d’) with bounds (m,n) and a storage tau : rank-1 array(‘d’) with bounds (MIN(m,n)) work : rank-1 array(‘d’) with bounds (MAX(lwork,1)) info : int scipy.linalg.lapack.dgesdd = dgesdd - Function signature: u,s,vt,info = dgesdd(a,[compute_uv,full_matrices,lwork,overwrite_a]) Required arguments: a : input rank-2 array(‘d’) with bounds (m,n) Optional arguments: overwrite_a := 0 input int compute_uv := 1 input int full_matrices := 1 input int lwork := (compute_uv?4*minmn*minmn+MAX(m,n)+9*minmn:MAX(14*minmn+4,10*minmn+2+25*(25+8))+MAX(m,n)) input int 416 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Return objects: u : rank-2 array(‘d’) with bounds (u0,u1) s : rank-1 array(‘d’) with bounds (minmn) vt : rank-2 array(‘d’) with bounds (vt0,vt1) info : int scipy.linalg.lapack.dgesv = dgesv - Function signature: lu,piv,x,info = dgesv(a,b,[overwrite_a,overwrite_b]) Required arguments: a : input rank-2 array(‘d’) with bounds (n,n) b : input rank-2 array(‘d’) with bounds (n,nrhs) Optional arguments: overwrite_a := 0 input int overwrite_b := 0 input int Return objects: lu : rank-2 array(‘d’) with bounds (n,n) and a storage piv : rank-1 array(‘i’) with bounds (n) x : rank-2 array(‘d’) with bounds (n,nrhs) and b storage info : int scipy.linalg.lapack.dgetrf = dgetrf - Function signature: lu,piv,info = dgetrf(a,[overwrite_a]) Required arguments: a : input rank-2 array(‘d’) with bounds (m,n) Optional arguments: overwrite_a := 0 input int Return objects: lu : rank-2 array(‘d’) with bounds (m,n) and a storage piv : rank-1 array(‘i’) with bounds (MIN(m,n)) info : int scipy.linalg.lapack.dgetri = dgetri - Function signature: inv_a,info = dgetri(lu,piv,[lwork,overwrite_lu]) Required arguments: lu : input rank-2 array(‘d’) with bounds (n,n) piv : input rank-1 array(‘i’) with bounds (n) Optional arguments: overwrite_lu := 0 input int lwork := 3*n input int Return objects: inv_a : rank-2 array(‘d’) with bounds (n,n) and lu storage info : int scipy.linalg.lapack.dgetrs = dgetrs - Function signature: x,info = dgetrs(lu,piv,b,[trans,overwrite_b]) Required arguments: lu : input rank-2 array(‘d’) with bounds (n,n) piv : input rank-1 array(‘i’) with bounds (n) b : input rank-2 array(‘d’) with bounds (n,nrhs) Optional arguments: overwrite_b := 0 input int trans := 0 input int 5.15. All functions 417 SciPy Reference Guide, Release 0.13.0 Return objects: x : rank-2 array(‘d’) with bounds (n,nrhs) and b storage info : int scipy.linalg.lapack.dgges = dgges - Function signature: a,b,sdim,alphar,alphai,beta,vsl,vsr,work,info = dgges(dselect,a,b,[jobvsl,jobvsr,sort_t,ldvsl,ldvsr,lwork,dselect_extr Required arguments: dselect : call-back function a : input rank-2 array(‘d’) with bounds (lda,*) b : input rank-2 array(‘d’) with bounds (ldb,*) Optional arguments: jobvsl := 1 input int jobvsr := 1 input int sort_t := 0 input int dselect_extra_args := () input tuple overwrite_a := 0 input int overwrite_b := 0 input int ldvsl := ((jobvsl==1)?n:1) input int ldvsr := ((jobvsr==1)?n:1) input int lwork := 8*n+16 input int Return objects: a : rank-2 array(‘d’) with bounds (lda,*) b : rank-2 array(‘d’) with bounds (ldb,*) sdim : int alphar : rank-1 array(‘d’) with bounds (n) alphai : rank-1 array(‘d’) with bounds (n) beta : rank-1 array(‘d’) with bounds (n) vsl : rank-2 array(‘d’) with bounds (ldvsl,n) vsr : rank-2 array(‘d’) with bounds (ldvsr,n) work : rank-1 array(‘d’) with bounds (MAX(lwork,1)) info : int Call-back functions: def dselect(alphar,alphai,beta): return dselect Required arguments: alphar : input float alphai : input float beta : input float Return objects: dselect : int scipy.linalg.lapack.dggev = dggev - Function signature: alphar,alphai,beta,vl,vr,work,info = dggev(a,b,[compute_vl,compute_vr,lwork,overwrite_a,overwrite_b]) Required arguments: a : input rank-2 array(‘d’) with bounds (n,n) b : input rank-2 array(‘d’) with bounds (n,n) Optional arguments: compute_vl := 1 input int compute_vr := 1 input int overwrite_a := 0 input int overwrite_b := 0 input int lwork := 8*n input int Return objects: alphar : rank-1 array(‘d’) with bounds (n) alphai : rank-1 array(‘d’) with bounds (n) beta : rank-1 array(‘d’) with bounds (n) vl : rank-2 array(‘d’) with bounds (ldvl,n) vr : rank-2 array(‘d’) with bounds (ldvr,n) work : rank-1 array(‘d’) with bounds (MAX(lwork,1)) info : int scipy.linalg.lapack.dlamch = dlamch - Function signature: dlamch = dlamch(cmach) Required arguments: cmach : input string(len=1) Return objects: dlamch : float 418 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 scipy.linalg.lapack.dlaswp = dlaswp - Function signature: a = dlaswp(a,piv,[k1,k2,off,inc,overwrite_a]) Required arguments: a : input rank-2 array(‘d’) with bounds (nrows,n) piv : input rank-1 array(‘i’) with bounds (*) Optional arguments: overwrite_a := 0 input int k1 := 0 input int k2 := len(piv)-1 input int off := 0 input int inc := 1 input int Return objects: a : rank-2 array(‘d’) with bounds (nrows,n) scipy.linalg.lapack.dlauum = dlauum - Function signature: a,info = dlauum(c,[lower,overwrite_c]) Required arguments: c : input rank-2 array(‘d’) with bounds (n,n) Optional arguments: overwrite_c := 0 input int lower := 0 input int Return objects: a : rank-2 array(‘d’) with bounds (n,n) and c storage info : int scipy.linalg.lapack.dorgqr = dorgqr - Function signature: q,work,info = dorgqr(a,tau,[lwork,overwrite_a]) Required arguments: a : input rank-2 array(‘d’) with bounds (m,n) tau : input rank-1 array(‘d’) with bounds (k) Optional arguments: overwrite_a := 0 input int lwork := 3*n input int Return objects: q : rank-2 array(‘d’) with bounds (m,n) and a storage work : rank-1 array(‘d’) with bounds (MAX(lwork,1)) info : int scipy.linalg.lapack.dorgrq = dorgrq - Function signature: q,work,info = dorgrq(a,tau,[lwork,overwrite_a]) Required arguments: a : input rank-2 array(‘d’) with bounds (m,n) tau : input rank-1 array(‘d’) with bounds (k) Optional arguments: overwrite_a := 0 input int lwork := 3*m input int Return objects: q : rank-2 array(‘d’) with bounds (m,n) and a storage work : rank-1 array(‘d’) with bounds (MAX(lwork,1)) info : int 5.15. All functions 419 SciPy Reference Guide, Release 0.13.0 scipy.linalg.lapack.dormqr = dormqr - Function signature: cq,work,info = dormqr(side,trans,a,tau,c,lwork,[overwrite_c]) Required arguments: side : input string(len=1) trans : input string(len=1) a : input rank-2 array(‘d’) with bounds (lda,k) tau : input rank-1 array(‘d’) with bounds (k) c : input rank-2 array(‘d’) with bounds (ldc,n) lwork : input int Optional arguments: overwrite_c := 0 input int Return objects: cq : rank-2 array(‘d’) with bounds (ldc,n) and c storage work : rank-1 array(‘d’) with bounds (MAX(lwork,1)) info : int scipy.linalg.lapack.dpbsv = dpbsv - Function signature: c,x,info = dpbsv(ab,b,[lower,ldab,overwrite_ab,overwrite_b]) Required arguments: ab : input rank-2 array(‘d’) with bounds (ldab,n) b : input rank-2 array(‘d’) with bounds (ldb,nrhs) Optional arguments: lower := 0 input int overwrite_ab := 0 input int ldab := shape(ab,0) input int overwrite_b := 0 input int Return objects: c : rank-2 array(‘d’) with bounds (ldab,n) and ab storage x : rank-2 array(‘d’) with bounds (ldb,nrhs) and b storage info : int scipy.linalg.lapack.dpbtrf = dpbtrf - Function signature: c,info = dpbtrf(ab,[lower,ldab,overwrite_ab]) Required arguments: ab : input rank-2 array(‘d’) with bounds (ldab,n) Optional arguments: lower := 0 input int overwrite_ab := 0 input int ldab := shape(ab,0) input int Return objects: c : rank-2 array(‘d’) with bounds (ldab,n) and ab storage info : int scipy.linalg.lapack.dpbtrs = dpbtrs - Function signature: x,info = dpbtrs(ab,b,[lower,ldab,overwrite_b]) Required arguments: ab : input rank-2 array(‘d’) with bounds (ldab,n) b : input rank-2 array(‘d’) with bounds (ldb,nrhs) Optional arguments: lower := 0 input int ldab := shape(ab,0) input int overwrite_b := 0 input int 420 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Return objects: x : rank-2 array(‘d’) with bounds (ldb,nrhs) and b storage info : int scipy.linalg.lapack.dposv = dposv - Function signature: c,x,info = dposv(a,b,[lower,overwrite_a,overwrite_b]) Required arguments: a : input rank-2 array(‘d’) with bounds (n,n) b : input rank-2 array(‘d’) with bounds (n,nrhs) Optional arguments: overwrite_a := 0 input int overwrite_b := 0 input int lower := 0 input int Return objects: c : rank-2 array(‘d’) with bounds (n,n) and a storage x : rank-2 array(‘d’) with bounds (n,nrhs) and b storage info : int scipy.linalg.lapack.dpotrf = dpotrf - Function signature: c,info = dpotrf(a,[lower,clean,overwrite_a]) Required arguments: a : input rank-2 array(‘d’) with bounds (n,n) Optional arguments: overwrite_a := 0 input int lower := 0 input int clean := 1 input int Return objects: c : rank-2 array(‘d’) with bounds (n,n) and a storage info : int scipy.linalg.lapack.dpotri = dpotri - Function signature: inv_a,info = dpotri(c,[lower,overwrite_c]) Required arguments: c : input rank-2 array(‘d’) with bounds (n,n) Optional arguments: overwrite_c := 0 input int lower := 0 input int Return objects: inv_a : rank-2 array(‘d’) with bounds (n,n) and c storage info : int scipy.linalg.lapack.dpotrs = dpotrs - Function signature: x,info = dpotrs(c,b,[lower,overwrite_b]) Required arguments: c : input rank-2 array(‘d’) with bounds (n,n) b : input rank-2 array(‘d’) with bounds (n,nrhs) Optional arguments: overwrite_b := 0 input int lower := 0 input int Return objects: x : rank-2 array(‘d’) with bounds (n,nrhs) and b storage info : int 5.15. All functions 421 SciPy Reference Guide, Release 0.13.0 scipy.linalg.lapack.dsbev = dsbev - Function signature: w,z,info = dsbev(ab,[compute_v,lower,ldab,overwrite_ab]) Required arguments: ab : input rank-2 array(‘d’) with bounds (ldab,*) Optional arguments: overwrite_ab := 1 input int compute_v := 1 input int lower := 0 input int ldab := shape(ab,0) input int Return objects: w : rank-1 array(‘d’) with bounds (n) z : rank-2 array(‘d’) with bounds (ldz,ldz) info : int scipy.linalg.lapack.dsbevd = dsbevd - Function signature: w,z,info = dsbevd(ab,[compute_v,lower,ldab,liwork,overwrite_ab]) Required arguments: ab : input rank-2 array(‘d’) with bounds (ldab,*) Optional arguments: overwrite_ab := 1 input int compute_v := 1 input int lower := 0 input int ldab := shape(ab,0) input int liwork := (compute_v?3+5*n:1) input int Return objects: w : rank-1 array(‘d’) with bounds (n) z : rank-2 array(‘d’) with bounds (ldz,ldz) info : int scipy.linalg.lapack.dsbevx = dsbevx - Function signature: w,z,m,ifail,info = dsbevx(ab,vl,vu,il,iu,[ldab,compute_v,range,lower,abstol,mmax,overwrite_ab]) Required arguments: ab : input rank-2 array(‘d’) with bounds (ldab,*) vl : input float vu : input float il : input int iu : input int Optional arguments: overwrite_ab := 1 input int ldab := shape(ab,0) input int compute_v := 1 input int range := 0 input int lower := 0 input int abstol := 0.0 input float mmax := (compute_v?(range==2?(iu-il+1):n):1) input int Return objects: w : rank-1 array(‘d’) with bounds (n) z : rank-2 array(‘d’) with bounds (ldz,mmax) m : int ifail : rank-1 array(‘i’) with bounds ((compute_v?n:1)) info : int scipy.linalg.lapack.dsyev = dsyev - Function signature: w,v,info = dsyev(a,[compute_v,lower,lwork,overwrite_a]) Required arguments: a : input rank-2 array(‘d’) with bounds (n,n) Optional arguments: compute_v := 1 input int lower := 0 input int overwrite_a := 0 input int lwork := 3*n-1 input int 422 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Return objects: w : rank-1 array(‘d’) with bounds (n) v : rank-2 array(‘d’) with bounds (n,n) and a storage info : int scipy.linalg.lapack.dsyevd = dsyevd - Function signature: w,v,info = dsyevd(a,[compute_v,lower,lwork,overwrite_a]) Required arguments: a : input rank-2 array(‘d’) with bounds (n,n) Optional arguments: compute_v := 1 input int lower := 0 input int overwrite_a := 0 input int lwork := (compute_v?1+6*n+2*n*n:2*n+1) input int Return objects: w : rank-1 array(‘d’) with bounds (n) v : rank-2 array(‘d’) with bounds (n,n) and a storage info : int scipy.linalg.lapack.dsyevr = dsyevr - Function signature: w,z,info = dsyevr(a,[jobz,range,uplo,il,iu,lwork,overwrite_a]) Required arguments: a : input rank-2 array(‘d’) with bounds (n,n) Optional arguments: jobz := ‘V’ input string(len=1) range := ‘A’ input string(len=1) uplo := ‘L’ input string(len=1) overwrite_a := 0 input int il := 1 input int iu := n input int lwork := 26*n input int Return objects: w : rank-1 array(‘d’) with bounds (n) z : rank-2 array(‘d’) with bounds (n,m) info : int scipy.linalg.lapack.dsygv = dsygv - Function signature: a,w,info = dsygv(a,b,[itype,jobz,uplo,overwrite_a,overwrite_b]) Required arguments: a : input rank-2 array(‘d’) with bounds (n,n) b : input rank-2 array(‘d’) with bounds (n,n) Optional arguments: itype := 1 input int jobz := ‘V’ input string(len=1) uplo := ‘L’ input string(len=1) overwrite_a := 0 input int overwrite_b := 0 input int Return objects: a : rank-2 array(‘d’) with bounds (n,n) w : rank-1 array(‘d’) with bounds (n) info : int scipy.linalg.lapack.dsygvd = dsygvd - Function signature: a,w,info = dsygvd(a,b,[itype,jobz,uplo,lwork,overwrite_a,overwrite_b]) Required arguments: a : input rank-2 array(‘d’) with bounds (n,n) b : input rank-2 array(‘d’) with bounds (n,n) 5.15. All functions 423 SciPy Reference Guide, Release 0.13.0 Optional arguments: itype := 1 input int jobz := ‘V’ input string(len=1) uplo := ‘L’ input string(len=1) overwrite_a := 0 input int overwrite_b := 0 input int lwork := 1+6*n+2*n*n input int Return objects: a : rank-2 array(‘d’) with bounds (n,n) w : rank-1 array(‘d’) with bounds (n) info : int scipy.linalg.lapack.dsygvx = dsygvx - Function signature: w,z,ifail,info = dsygvx(a,b,iu,[itype,jobz,uplo,il,lwork,overwrite_a,overwrite_b]) Required arguments: a : input rank-2 array(‘d’) with bounds (n,n) b : input rank-2 array(‘d’) with bounds (n,n) iu : input int Optional arguments: itype := 1 input int jobz := ‘V’ input string(len=1) uplo := ‘L’ input string(len=1) overwrite_a := 0 input int overwrite_b := 0 input int il := 1 input int lwork := 8*n input int Return objects: w : rank-1 array(‘d’) with bounds (n) z : rank-2 array(‘d’) with bounds (n,m) ifail : rank-1 array(‘i’) with bounds (n) info : int scipy.linalg.lapack.dtrsyl = dtrsyl - Function signature: x,scale,info = dtrsyl(a,b,c,[trana,tranb,isgn,overwrite_c]) Required arguments: a : input rank-2 array(‘d’) with bounds (m,m) b : input rank-2 array(‘d’) with bounds (n,n) c : input rank-2 array(‘d’) with bounds (m,n) Optional arguments: trana := ‘N’ input string(len=1) tranb := ‘N’ input string(len=1) isgn := 1 input int overwrite_c := 0 input int Return objects: x : rank-2 array(‘d’) with bounds (m,n) and c storage scale : float info : int scipy.linalg.lapack.dtrtri = dtrtri - Function signature: inv_c,info = dtrtri(c,[lower,unitdiag,overwrite_c]) Required arguments: c : input rank-2 array(‘d’) with bounds (n,n) Optional arguments: overwrite_c := 0 input int lower := 0 input int unitdiag := 0 input int Return objects: inv_c : rank-2 array(‘d’) with bounds (n,n) and c storage info : int scipy.linalg.lapack.dtrtrs = dtrtrs - Function signature: x,info = dtrtrs(a,b,[lower,trans,unitdiag,lda,overwrite_b]) 424 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Required arguments: a : input rank-2 array(‘d’) with bounds (lda,n) b : input rank-2 array(‘d’) with bounds (ldb,nrhs) Optional arguments: lower := 0 input int trans := 0 input int unitdiag := 0 input int lda := shape(a,0) input int overwrite_b := 0 input int Return objects: x : rank-2 array(‘d’) with bounds (ldb,nrhs) and b storage info : int scipy.linalg.lapack.sgbsv = sgbsv - Function signature: lub,piv,x,info = sgbsv(kl,ku,ab,b,[overwrite_ab,overwrite_b]) Required arguments: kl : input int ku : input int ab : input rank-2 array(‘f’) with bounds (2*kl+ku+1,n) b : input rank-2 array(‘f’) with bounds (n,nrhs) Optional arguments: overwrite_ab := 0 input int overwrite_b := 0 input int Return objects: lub : rank-2 array(‘f’) with bounds (2*kl+ku+1,n) and ab storage piv : rank-1 array(‘i’) with bounds (n) x : rank-2 array(‘f’) with bounds (n,nrhs) and b storage info : int scipy.linalg.lapack.sgbtrf = sgbtrf - Function signature: lu,ipiv,info = sgbtrf(ab,kl,ku,[m,n,ldab,overwrite_ab]) Required arguments: ab : input rank-2 array(‘f’) with bounds (ldab,*) kl : input int ku : input int Optional arguments: m := shape(ab,1) input int n := shape(ab,1) input int overwrite_ab := 0 input int ldab := shape(ab,0) input int Return objects: lu : rank-2 array(‘f’) with bounds (ldab,*) and ab storage ipiv : rank-1 array(‘i’) with bounds (MIN(m,n)) info : int scipy.linalg.lapack.sgbtrs = sgbtrs - Function signature: x,info = sgbtrs(ab,kl,ku,b,ipiv,[trans,n,ldab,ldb,overwrite_b]) Required arguments: ab : input rank-2 array(‘f’) with bounds (ldab,*) kl : input int ku : input int b : input rank-2 array(‘f’) with bounds (ldb,*) ipiv : input rank-1 array(‘i’) with bounds (n) Optional arguments: overwrite_b := 0 input int trans := 0 input int n := shape(ab,1) input int ldab := shape(ab,0) input int ldb := shape(b,0) input int Return objects: x : rank-2 array(‘f’) with bounds (ldb,*) and b storage info : int scipy.linalg.lapack.sgebal = 5.15. All functions 425 SciPy Reference Guide, Release 0.13.0 sgebal - Function signature: ba,lo,hi,pivscale,info = sgebal(a,[scale,permute,overwrite_a]) Required arguments: a : input rank-2 array(‘f’) with bounds (m,n) Optional arguments: scale := 0 input int permute := 0 input int overwrite_a := 0 input int Return objects: ba : rank-2 array(‘f’) with bounds (m,n) and a storage lo : int hi : int pivscale : rank-1 array(‘f’) with bounds (n) info : int scipy.linalg.lapack.sgees = sgees - Function signature: t,sdim,wr,wi,vs,work,info = sgees(sselect,a,[compute_v,sort_t,lwork,sselect_extra_args,overwrite_a]) Required arguments: sselect : call-back function a : input rank-2 array(‘f’) with bounds (n,n) Optional arguments: compute_v := 1 input int sort_t := 0 input int sselect_extra_args := () input tuple overwrite_a := 0 input int lwork := 3*n input int Return objects: t : rank-2 array(‘f’) with bounds (n,n) and a storage sdim : int wr : rank-1 array(‘f’) with bounds (n) wi : rank-1 array(‘f’) with bounds (n) vs : rank-2 array(‘f’) with bounds (ldvs,n) work : rank-1 array(‘f’) with bounds (MAX(lwork,1)) info : int Call-back functions: def sselect(arg1,arg2): return sselect Required arguments: arg1 : input float arg2 : input float Return objects: sselect : int scipy.linalg.lapack.sgeev = sgeev - Function signature: wr,wi,vl,vr,info = sgeev(a,[compute_vl,compute_vr,lwork,overwrite_a]) Required arguments: a : input rank-2 array(‘f’) with bounds (n,n) Optional arguments: compute_vl := 1 input int compute_vr := 1 input int overwrite_a := 0 input int lwork := 4*n input int Return objects: wr : rank-1 array(‘f’) with bounds (n) wi : rank-1 array(‘f’) with bounds (n) vl : rank-2 array(‘f’) with bounds (ldvl,n) vr : rank-2 array(‘f’) with bounds (ldvr,n) info : int scipy.linalg.lapack.sgegv = sgegv - Function signature: alphar,alphai,beta,vl,vr,info = sgegv(a,b,[compute_vl,compute_vr,lwork,overwrite_a,overwrite_b]) 426 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Required arguments: a : input rank-2 array(‘f’) with bounds (n,n) b : input rank-2 array(‘f’) with bounds (n,n) Optional arguments: compute_vl := 1 input int compute_vr := 1 input int overwrite_a := 0 input int overwrite_b := 0 input int lwork := 8*n input int Return objects: alphar : rank-1 array(‘f’) with bounds (n) alphai : rank-1 array(‘f’) with bounds (n) beta : rank-1 array(‘f’) with bounds (n) vl : rank-2 array(‘f’) with bounds (ldvl,n) vr : rank-2 array(‘f’) with bounds (ldvr,n) info : int scipy.linalg.lapack.sgehrd = sgehrd - Function signature: ht,tau,info = sgehrd(a,[lo,hi,lwork,overwrite_a]) Required arguments: a : input rank-2 array(‘f’) with bounds (n,n) Optional arguments: lo := 0 input int hi := n-1 input int overwrite_a := 0 input int lwork := MAX(n,1) input int Return objects: ht : rank-2 array(‘f’) with bounds (n,n) and a storage tau : rank-1 array(‘f’) with bounds (n - 1) info : int scipy.linalg.lapack.sgelss = sgelss - Function signature: v,x,s,rank,work,info = sgelss(a,b,[cond,lwork,overwrite_a,overwrite_b]) Required arguments: a : input rank-2 array(‘f’) with bounds (m,n) b : input rank-2 array(‘f’) with bounds (maxmn,nrhs) Optional arguments: overwrite_a := 0 input int overwrite_b := 0 input int cond := -1.0 input float lwork := 3*minmn+MAX(2*minmn,MAX(maxmn,nrhs)) input int Return objects: v : rank-2 array(‘f’) with bounds (m,n) and a storage x : rank-2 array(‘f’) with bounds (maxmn,nrhs) and b storage s : rank-1 array(‘f’) with bounds (minmn) rank : int work : rank-1 array(‘f’) with bounds (MAX(lwork,1)) info : int scipy.linalg.lapack.sgeqp3 = sgeqp3 - Function signature: qr,jpvt,tau,work,info = sgeqp3(a,[lwork,overwrite_a]) Required arguments: a : input rank-2 array(‘f’) with bounds (m,n) Optional arguments: overwrite_a := 0 input int lwork := 3*(n+1) input int Return objects: qr : rank-2 array(‘f’) with bounds (m,n) and a storage jpvt : rank-1 array(‘i’) with bounds (n) tau : 5.15. All functions 427 SciPy Reference Guide, Release 0.13.0 rank-1 array(‘f’) with bounds (MIN(m,n)) work : rank-1 array(‘f’) with bounds (MAX(lwork,1)) info : int scipy.linalg.lapack.sgeqrf = sgeqrf - Function signature: qr,tau,work,info = sgeqrf(a,[lwork,overwrite_a]) Required arguments: a : input rank-2 array(‘f’) with bounds (m,n) Optional arguments: overwrite_a := 0 input int lwork := 3*n input int Return objects: qr : rank-2 array(‘f’) with bounds (m,n) and a storage tau : rank-1 array(‘f’) with bounds (MIN(m,n)) work : rank-1 array(‘f’) with bounds (MAX(lwork,1)) info : int scipy.linalg.lapack.sgerqf = sgerqf - Function signature: qr,tau,work,info = sgerqf(a,[lwork,overwrite_a]) Required arguments: a : input rank-2 array(‘f’) with bounds (m,n) Optional arguments: overwrite_a := 0 input int lwork := 3*m input int Return objects: qr : rank-2 array(‘f’) with bounds (m,n) and a storage tau : rank-1 array(‘f’) with bounds (MIN(m,n)) work : rank-1 array(‘f’) with bounds (MAX(lwork,1)) info : int scipy.linalg.lapack.sgesdd = sgesdd - Function signature: u,s,vt,info = sgesdd(a,[compute_uv,full_matrices,lwork,overwrite_a]) Required arguments: a : input rank-2 array(‘f’) with bounds (m,n) Optional arguments: overwrite_a := 0 input int compute_uv := 1 input int full_matrices := 1 input int lwork := (compute_uv?4*minmn*minmn+MAX(m,n)+9*minmn:MAX(14*minmn+4,10*minmn+2+25*(25+8))+MAX(m,n)) input int Return objects: u : rank-2 array(‘f’) with bounds (u0,u1) s : rank-1 array(‘f’) with bounds (minmn) vt : rank-2 array(‘f’) with bounds (vt0,vt1) info : int scipy.linalg.lapack.sgesv = sgesv - Function signature: lu,piv,x,info = sgesv(a,b,[overwrite_a,overwrite_b]) Required arguments: a : input rank-2 array(‘f’) with bounds (n,n) b : input rank-2 array(‘f’) with bounds (n,nrhs) 428 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Optional arguments: overwrite_a := 0 input int overwrite_b := 0 input int Return objects: lu : rank-2 array(‘f’) with bounds (n,n) and a storage piv : rank-1 array(‘i’) with bounds (n) x : rank-2 array(‘f’) with bounds (n,nrhs) and b storage info : int scipy.linalg.lapack.sgetrf = sgetrf - Function signature: lu,piv,info = sgetrf(a,[overwrite_a]) Required arguments: a : input rank-2 array(‘f’) with bounds (m,n) Optional arguments: overwrite_a := 0 input int Return objects: lu : rank-2 array(‘f’) with bounds (m,n) and a storage piv : rank-1 array(‘i’) with bounds (MIN(m,n)) info : int scipy.linalg.lapack.sgetri = sgetri - Function signature: inv_a,info = sgetri(lu,piv,[lwork,overwrite_lu]) Required arguments: lu : input rank-2 array(‘f’) with bounds (n,n) piv : input rank-1 array(‘i’) with bounds (n) Optional arguments: overwrite_lu := 0 input int lwork := 3*n input int Return objects: inv_a : rank-2 array(‘f’) with bounds (n,n) and lu storage info : int scipy.linalg.lapack.sgetrs = sgetrs - Function signature: x,info = sgetrs(lu,piv,b,[trans,overwrite_b]) Required arguments: lu : input rank-2 array(‘f’) with bounds (n,n) piv : input rank-1 array(‘i’) with bounds (n) b : input rank-2 array(‘f’) with bounds (n,nrhs) Optional arguments: overwrite_b := 0 input int trans := 0 input int Return objects: x : rank-2 array(‘f’) with bounds (n,nrhs) and b storage info : int scipy.linalg.lapack.sgges = sgges - Function signature: a,b,sdim,alphar,alphai,beta,vsl,vsr,work,info = sgges(sselect,a,b,[jobvsl,jobvsr,sort_t,ldvsl,ldvsr,lwork,sselect_extra Required arguments: sselect : call-back function a : input rank-2 array(‘f’) with bounds (lda,*) b : input rank-2 array(‘f’) with bounds (ldb,*) 5.15. All functions 429 SciPy Reference Guide, Release 0.13.0 Optional arguments: jobvsl := 1 input int jobvsr := 1 input int sort_t := 0 input int sselect_extra_args := () input tuple overwrite_a := 0 input int overwrite_b := 0 input int ldvsl := ((jobvsl==1)?n:1) input int ldvsr := ((jobvsr==1)?n:1) input int lwork := 8*n+16 input int Return objects: a : rank-2 array(‘f’) with bounds (lda,*) b : rank-2 array(‘f’) with bounds (ldb,*) sdim : int alphar : rank-1 array(‘f’) with bounds (n) alphai : rank-1 array(‘f’) with bounds (n) beta : rank-1 array(‘f’) with bounds (n) vsl : rank-2 array(‘f’) with bounds (ldvsl,n) vsr : rank-2 array(‘f’) with bounds (ldvsr,n) work : rank-1 array(‘f’) with bounds (MAX(lwork,1)) info : int Call-back functions: def sselect(alphar,alphai,beta): return sselect Required arguments: alphar : input float alphai : input float beta : input float Return objects: sselect : int scipy.linalg.lapack.sggev = sggev - Function signature: alphar,alphai,beta,vl,vr,work,info = sggev(a,b,[compute_vl,compute_vr,lwork,overwrite_a,overwrite_b]) Required arguments: a : input rank-2 array(‘f’) with bounds (n,n) b : input rank-2 array(‘f’) with bounds (n,n) Optional arguments: compute_vl := 1 input int compute_vr := 1 input int overwrite_a := 0 input int overwrite_b := 0 input int lwork := 8*n input int Return objects: alphar : rank-1 array(‘f’) with bounds (n) alphai : rank-1 array(‘f’) with bounds (n) beta : rank-1 array(‘f’) with bounds (n) vl : rank-2 array(‘f’) with bounds (ldvl,n) vr : rank-2 array(‘f’) with bounds (ldvr,n) work : rank-1 array(‘f’) with bounds (MAX(lwork,1)) info : int scipy.linalg.lapack.slamch = slamch - Function signature: slamch = slamch(cmach) Required arguments: cmach : input string(len=1) Return objects: slamch : float scipy.linalg.lapack.slaswp = slaswp - Function signature: a = slaswp(a,piv,[k1,k2,off,inc,overwrite_a]) Required arguments: a : input rank-2 array(‘f’) with bounds (nrows,n) piv : input rank-1 array(‘i’) with bounds (*) Optional arguments: overwrite_a := 0 input int k1 := 0 input int k2 := len(piv)-1 input int off := 0 input int inc := 1 input int 430 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Return objects: a : rank-2 array(‘f’) with bounds (nrows,n) scipy.linalg.lapack.slauum = slauum - Function signature: a,info = slauum(c,[lower,overwrite_c]) Required arguments: c : input rank-2 array(‘f’) with bounds (n,n) Optional arguments: overwrite_c := 0 input int lower := 0 input int Return objects: a : rank-2 array(‘f’) with bounds (n,n) and c storage info : int scipy.linalg.lapack.sorgqr = sorgqr - Function signature: q,work,info = sorgqr(a,tau,[lwork,overwrite_a]) Required arguments: a : input rank-2 array(‘f’) with bounds (m,n) tau : input rank-1 array(‘f’) with bounds (k) Optional arguments: overwrite_a := 0 input int lwork := 3*n input int Return objects: q : rank-2 array(‘f’) with bounds (m,n) and a storage work : rank-1 array(‘f’) with bounds (MAX(lwork,1)) info : int scipy.linalg.lapack.sorgrq = sorgrq - Function signature: q,work,info = sorgrq(a,tau,[lwork,overwrite_a]) Required arguments: a : input rank-2 array(‘f’) with bounds (m,n) tau : input rank-1 array(‘f’) with bounds (k) Optional arguments: overwrite_a := 0 input int lwork := 3*m input int Return objects: q : rank-2 array(‘f’) with bounds (m,n) and a storage work : rank-1 array(‘f’) with bounds (MAX(lwork,1)) info : int scipy.linalg.lapack.sormqr = sormqr - Function signature: cq,work,info = sormqr(side,trans,a,tau,c,lwork,[overwrite_c]) Required arguments: side : input string(len=1) trans : input string(len=1) a : input rank-2 array(‘f’) with bounds (lda,k) tau : input rank-1 array(‘f’) with bounds (k) c : input rank-2 array(‘f’) with bounds (ldc,n) lwork : input int Optional arguments: overwrite_c := 0 input int 5.15. All functions 431 SciPy Reference Guide, Release 0.13.0 Return objects: cq : rank-2 array(‘f’) with bounds (ldc,n) and c storage work : rank-1 array(‘f’) with bounds (MAX(lwork,1)) info : int scipy.linalg.lapack.spbsv = spbsv - Function signature: c,x,info = spbsv(ab,b,[lower,ldab,overwrite_ab,overwrite_b]) Required arguments: ab : input rank-2 array(‘f’) with bounds (ldab,n) b : input rank-2 array(‘f’) with bounds (ldb,nrhs) Optional arguments: lower := 0 input int overwrite_ab := 0 input int ldab := shape(ab,0) input int overwrite_b := 0 input int Return objects: c : rank-2 array(‘f’) with bounds (ldab,n) and ab storage x : rank-2 array(‘f’) with bounds (ldb,nrhs) and b storage info : int scipy.linalg.lapack.spbtrf = spbtrf - Function signature: c,info = spbtrf(ab,[lower,ldab,overwrite_ab]) Required arguments: ab : input rank-2 array(‘f’) with bounds (ldab,n) Optional arguments: lower := 0 input int overwrite_ab := 0 input int ldab := shape(ab,0) input int Return objects: c : rank-2 array(‘f’) with bounds (ldab,n) and ab storage info : int scipy.linalg.lapack.spbtrs = spbtrs - Function signature: x,info = spbtrs(ab,b,[lower,ldab,overwrite_b]) Required arguments: ab : input rank-2 array(‘f’) with bounds (ldab,n) b : input rank-2 array(‘f’) with bounds (ldb,nrhs) Optional arguments: lower := 0 input int ldab := shape(ab,0) input int overwrite_b := 0 input int Return objects: x : rank-2 array(‘f’) with bounds (ldb,nrhs) and b storage info : int scipy.linalg.lapack.sposv = sposv - Function signature: c,x,info = sposv(a,b,[lower,overwrite_a,overwrite_b]) Required arguments: a : input rank-2 array(‘f’) with bounds (n,n) b : input rank-2 array(‘f’) with bounds (n,nrhs) Optional arguments: overwrite_a := 0 input int overwrite_b := 0 input int lower := 0 input int 432 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Return objects: c : rank-2 array(‘f’) with bounds (n,n) and a storage x : rank-2 array(‘f’) with bounds (n,nrhs) and b storage info : int scipy.linalg.lapack.spotrf = spotrf - Function signature: c,info = spotrf(a,[lower,clean,overwrite_a]) Required arguments: a : input rank-2 array(‘f’) with bounds (n,n) Optional arguments: overwrite_a := 0 input int lower := 0 input int clean := 1 input int Return objects: c : rank-2 array(‘f’) with bounds (n,n) and a storage info : int scipy.linalg.lapack.spotri = spotri - Function signature: inv_a,info = spotri(c,[lower,overwrite_c]) Required arguments: c : input rank-2 array(‘f’) with bounds (n,n) Optional arguments: overwrite_c := 0 input int lower := 0 input int Return objects: inv_a : rank-2 array(‘f’) with bounds (n,n) and c storage info : int scipy.linalg.lapack.spotrs = spotrs - Function signature: x,info = spotrs(c,b,[lower,overwrite_b]) Required arguments: c : input rank-2 array(‘f’) with bounds (n,n) b : input rank-2 array(‘f’) with bounds (n,nrhs) Optional arguments: overwrite_b := 0 input int lower := 0 input int Return objects: x : rank-2 array(‘f’) with bounds (n,nrhs) and b storage info : int scipy.linalg.lapack.ssbev = ssbev - Function signature: w,z,info = ssbev(ab,[compute_v,lower,ldab,overwrite_ab]) Required arguments: ab : input rank-2 array(‘f’) with bounds (ldab,*) Optional arguments: overwrite_ab := 1 input int compute_v := 1 input int lower := 0 input int ldab := shape(ab,0) input int Return objects: w : rank-1 array(‘f’) with bounds (n) z : rank-2 array(‘f’) with bounds (ldz,ldz) info : int 5.15. All functions 433 SciPy Reference Guide, Release 0.13.0 scipy.linalg.lapack.ssbevd = ssbevd - Function signature: w,z,info = ssbevd(ab,[compute_v,lower,ldab,liwork,overwrite_ab]) Required arguments: ab : input rank-2 array(‘f’) with bounds (ldab,*) Optional arguments: overwrite_ab := 1 input int compute_v := 1 input int lower := 0 input int ldab := shape(ab,0) input int liwork := (compute_v?3+5*n:1) input int Return objects: w : rank-1 array(‘f’) with bounds (n) z : rank-2 array(‘f’) with bounds (ldz,ldz) info : int scipy.linalg.lapack.ssbevx = ssbevx - Function signature: w,z,m,ifail,info = ssbevx(ab,vl,vu,il,iu,[ldab,compute_v,range,lower,abstol,mmax,overwrite_ab]) Required arguments: ab : input rank-2 array(‘f’) with bounds (ldab,*) vl : input float vu : input float il : input int iu : input int Optional arguments: overwrite_ab := 1 input int ldab := shape(ab,0) input int compute_v := 1 input int range := 0 input int lower := 0 input int abstol := 0.0 input float mmax := (compute_v?(range==2?(iu-il+1):n):1) input int Return objects: w : rank-1 array(‘f’) with bounds (n) z : rank-2 array(‘f’) with bounds (ldz,mmax) m : int ifail : rank-1 array(‘i’) with bounds ((compute_v?n:1)) info : int scipy.linalg.lapack.ssyev = ssyev - Function signature: w,v,info = ssyev(a,[compute_v,lower,lwork,overwrite_a]) Required arguments: a : input rank-2 array(‘f’) with bounds (n,n) Optional arguments: compute_v := 1 input int lower := 0 input int overwrite_a := 0 input int lwork := 3*n-1 input int Return objects: w : rank-1 array(‘f’) with bounds (n) v : rank-2 array(‘f’) with bounds (n,n) and a storage info : int scipy.linalg.lapack.ssyevd = ssyevd - Function signature: w,v,info = ssyevd(a,[compute_v,lower,lwork,overwrite_a]) Required arguments: a : input rank-2 array(‘f’) with bounds (n,n) Optional arguments: compute_v := 1 input int lower := 0 input int overwrite_a := 0 input int lwork := (compute_v?1+6*n+2*n*n:2*n+1) input int 434 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Return objects: w : rank-1 array(‘f’) with bounds (n) v : rank-2 array(‘f’) with bounds (n,n) and a storage info : int scipy.linalg.lapack.ssyevr = ssyevr - Function signature: w,z,info = ssyevr(a,[jobz,range,uplo,il,iu,lwork,overwrite_a]) Required arguments: a : input rank-2 array(‘f’) with bounds (n,n) Optional arguments: jobz := ‘V’ input string(len=1) range := ‘A’ input string(len=1) uplo := ‘L’ input string(len=1) overwrite_a := 0 input int il := 1 input int iu := n input int lwork := 26*n input int Return objects: w : rank-1 array(‘f’) with bounds (n) z : rank-2 array(‘f’) with bounds (n,m) info : int scipy.linalg.lapack.ssygv = ssygv - Function signature: a,w,info = ssygv(a,b,[itype,jobz,uplo,overwrite_a,overwrite_b]) Required arguments: a : input rank-2 array(‘f’) with bounds (n,n) b : input rank-2 array(‘f’) with bounds (n,n) Optional arguments: itype := 1 input int jobz := ‘V’ input string(len=1) uplo := ‘L’ input string(len=1) overwrite_a := 0 input int overwrite_b := 0 input int Return objects: a : rank-2 array(‘f’) with bounds (n,n) w : rank-1 array(‘f’) with bounds (n) info : int scipy.linalg.lapack.ssygvd = ssygvd - Function signature: a,w,info = ssygvd(a,b,[itype,jobz,uplo,lwork,overwrite_a,overwrite_b]) Required arguments: a : input rank-2 array(‘f’) with bounds (n,n) b : input rank-2 array(‘f’) with bounds (n,n) Optional arguments: itype := 1 input int jobz := ‘V’ input string(len=1) uplo := ‘L’ input string(len=1) overwrite_a := 0 input int overwrite_b := 0 input int lwork := 1+6*n+2*n*n input int Return objects: a : rank-2 array(‘f’) with bounds (n,n) w : rank-1 array(‘f’) with bounds (n) info : int scipy.linalg.lapack.ssygvx = ssygvx - Function signature: w,z,ifail,info = ssygvx(a,b,iu,[itype,jobz,uplo,il,lwork,overwrite_a,overwrite_b]) Required arguments: a : input rank-2 array(‘f’) with bounds (n,n) b : input rank-2 array(‘f’) with bounds (n,n) iu : input int 5.15. All functions 435 SciPy Reference Guide, Release 0.13.0 Optional arguments: itype := 1 input int jobz := ‘V’ input string(len=1) uplo := ‘L’ input string(len=1) overwrite_a := 0 input int overwrite_b := 0 input int il := 1 input int lwork := 8*n input int Return objects: w : rank-1 array(‘f’) with bounds (n) z : rank-2 array(‘f’) with bounds (n,m) ifail : rank-1 array(‘i’) with bounds (n) info : int scipy.linalg.lapack.strsyl = strsyl - Function signature: x,scale,info = strsyl(a,b,c,[trana,tranb,isgn,overwrite_c]) Required arguments: a : input rank-2 array(‘f’) with bounds (m,m) b : input rank-2 array(‘f’) with bounds (n,n) c : input rank-2 array(‘f’) with bounds (m,n) Optional arguments: trana := ‘N’ input string(len=1) tranb := ‘N’ input string(len=1) isgn := 1 input int overwrite_c := 0 input int Return objects: x : rank-2 array(‘f’) with bounds (m,n) and c storage scale : float info : int scipy.linalg.lapack.strtri = strtri - Function signature: inv_c,info = strtri(c,[lower,unitdiag,overwrite_c]) Required arguments: c : input rank-2 array(‘f’) with bounds (n,n) Optional arguments: overwrite_c := 0 input int lower := 0 input int unitdiag := 0 input int Return objects: inv_c : rank-2 array(‘f’) with bounds (n,n) and c storage info : int scipy.linalg.lapack.strtrs = strtrs - Function signature: x,info = strtrs(a,b,[lower,trans,unitdiag,lda,overwrite_b]) Required arguments: a : input rank-2 array(‘f’) with bounds (lda,n) b : input rank-2 array(‘f’) with bounds (ldb,nrhs) Optional arguments: lower := 0 input int trans := 0 input int unitdiag := 0 input int lda := shape(a,0) input int overwrite_b := 0 input int Return objects: x : rank-2 array(‘f’) with bounds (ldb,nrhs) and b storage info : int scipy.linalg.lapack.zgbsv = zgbsv - Function signature: lub,piv,x,info = zgbsv(kl,ku,ab,b,[overwrite_ab,overwrite_b]) 436 Chapter 5. Reference SciPy Reference Guide, Release 0.13.0 Required arguments: kl : input int ku : input int ab : input rank-2 array(‘D’) with bounds (2*kl+ku+1,n) b : input rank-2 array(‘D’) with bounds (n,nrhs) Optional arguments: overwrite_ab := 0 input int overwrite_b := 0 input int Return objects: lub : rank-2 array(‘D’) with bounds (2*kl+ku+1,n) and ab storage piv : rank-1 array(‘i’) with bounds (n) x : rank-2 array(‘D’) with bounds (n,nrhs) and b storage info : int scipy.linalg.lapack.zgbtrf = zgbtrf - Function signature: lu,ipiv,info = zgbtrf(ab,kl,ku,[m,n,ldab,overwrite_ab]) Required arguments: ab : input rank-2 array(‘D’) with bounds (ldab,*) kl : input int ku : input int Optional arguments: m := shape(ab,1) input int n := shape(ab,1) input int overwrite_ab := 0 input int ldab := shape(ab,0) input int Return objects: lu : rank-2 array(‘D’) with bounds (ldab,*) and ab storage ipiv : rank-1 array(‘i’) with bounds (MIN(m,n)) info : int scipy.linalg.lapack.zgbtrs = zgbtrs - Function signature: x,info = zgbtrs(ab,kl,ku,b,ipiv,[trans,n,ldab,ldb,overwrite_b]) Required arguments: ab : input rank-2 array(‘D’) with bounds (ldab,*) kl : input int ku : input int b : input rank-2 array(‘D’) with bounds (ldb,*) ipiv : input rank-1 array(‘i’) with bounds (n) Optional arguments: overwrite_b := 0 input int trans := 0 input int n := shape(ab,1) input int ldab := shape(ab,0) input int ldb := shape(b,0) input int Return objects: x : rank-2 array(‘D’) with bounds (ldb,*) and b storage info : int scipy.linalg.lapack.zgebal = zgebal - Function signature: ba,lo,hi,pivscale,info = zgebal(a,[scale,permute,overwrite_a]) Required arguments: a : input rank-2 array(‘D’) with bounds (m,n) Optional arguments: scale := 0 input int permute := 0 input int overwrite_a := 0 input int Return objects: ba : rank-2 array(‘D’) with bounds (m,n) and a storage lo : int hi : int pivscale : rank-1 array(‘d’) with bounds (n) info : int scipy.linalg.lapack.zgees =