Scipy is the canonical Python library for applied mathematics computation. It aim is comparable in scope to MATLAB, and indeed it has much of the same functionality, evidently wrapping in some cases the same FORTRAN library. Scipy is large, fast, and powerful, and if you're doing any applied math, or considering Python versus MATLAB for a project, etc., check to see if the algorithms you need aren't already easily available in scipy.
There is a free online (and pdf) reference manual for scipy http://docs.scipy.org/doc/scipy/reference. You have to look at it, because often the documentation is better than what you get just by using ? in Sage. In particular, the reference manual includes the Scipy Tutorial -- http://docs.scipy.org/doc/scipy/reference/tutorial/.
The examples below all assume the following block fo code has been evaluated. In particular, note that we turn the preparser off with preparse(False) and import scipy using import scipy as sp.
The examples below illustrate many of the main packages in scipy, by given just one or two small examples that illustrate the simplest capabilities. Many show how to draw plots using Sage 2d plotting, Sage 3d plotting, and Matplotlib matlab-style plotting, which are all topics we'll cover soon.
{{{id=2| %auto import numpy as np import scipy as sp import matplotlib as mpl import matplotlib.pyplot as plt preparser(False) /// }}}Subpackage | Description |
---|---|
cluster | Clustering algorithms |
constants | Physical and mathematical constants |
fftpack | Fast Fourier Transform routines |
integrate | Integration and ordinary differential equation solvers |
interpolate | Interpolation and smoothing splines |
io | Input and Output |
linalg | Linear algebra |
maxentropy | Maximum entropy methods |
ndimage | N-dimensional image processing |
odr | Orthogonal distance regression |
optimize | Optimization and root-finding routines |
signal | Signal processing |
sparse | Sparse matrices and associated routines |
spatial | Spatial data structures and algorithms |
special | Special functions |
stats | Statistical distributions and functions |
weave | C/C++ integration |
Import separately as follows:
{{{id=1| from scipy import linalg, optimize /// }}} {{{id=8| optimize? /// }}} {{{id=7| optimize.fmin? /// }}} {{{id=12| sp. # tab /// }}}Example: Use r_ for easily defining complicated 1d arrays.
{{{id=11| sp.r_[3, [0]*5, -1:1:10j] /// array([ 3. , 0. , 0. , 0. , 0. , 0. , -1. , -0.77777778, -0.55555556, -0.33333333, -0.11111111, 0.11111111, 0.33333333, 0.55555556, 0.77777778, 1. ]) }}}The "10j" above means "the number of steps" (between -1 and 1), with endpoints being inclusive.
{{{id=15| /// }}}Example: Polynomials
{{{id=19| p = sp.poly1d([1,-3,3,-3,2]); p /// poly1d([ 1, -3, 3, -3, 2]) }}} {{{id=10| print p /// 4 3 2 1 x - 3 x + 3 x - 3 x + 2 }}}WARNING: In Sage the coefficients of a polynomial are all given in the opposite order to Scipy! Watch out, e.g.,:
{{{id=26| R = PolynomialRing(QQ, 'x') f = R([2,-3,3,-3,1]); f # opposite order! /// x^4 - 3*x^3 + 3*x^2 - 3*x + 2 }}} {{{id=18| print p*p /// 8 7 6 5 4 3 2 1 x - 6 x + 15 x - 24 x + 31 x - 30 x + 21 x - 12 x + 4 }}} {{{id=27| p([4, 5]) /// array([102, 312]) }}} {{{id=28| p(4), p(5) /// (102, 312) }}} {{{id=21| sp.roots(p) /// array([ 2.00000000e+00+0.j, 3.33066907e-16+1.j, 3.33066907e-16-1.j, 1.00000000e+00+0.j]) }}} {{{id=20| plot(lambda x: p(x), -1, 2.5, figsize=[8,3]) ///Vectorizing your own functions, i.e., making them so they can take numpy arrays as inputs, is easy.
{{{id=35| @sp.vectorize def f(a,b): if a > b: return a-b else: return a+b /// }}} {{{id=37| f(2,3) /// array(5) }}} {{{id=38| f([0,3,6,9], [1,3,5,7]) /// array([1, 6, 1, 2]) }}} {{{id=39| f(sp.r_[0,3,6,9], sp.r_[1,3,5,7]) /// array([1, 6, 1, 2]) }}} {{{id=43| /// }}}Special Functions.
{{{id=45| from scipy import special /// }}} {{{id=42| special? ///The Gamma function is a complex special function such that $\Gamma(s) = (s-1)!$ for positive integers $s$.
{{{id=46| special.gamma(10) /// 362880.0 }}} {{{id=49| special.gamma(2+2j) /// (0.11229424234632605+0.32361288550192724j) }}} {{{id=47| complex_plot(special.gamma, (-2,2), (-2,2)) ///All the scipy special functions can also be applied to numpy arrays (often very fast!).
{{{id=52| v = sp.r_[.5:4:10000j]; v /// array([ 0.5 , 0.50035004, 0.50070007, ..., 3.99929993, 3.99964996, 4. ]) }}} {{{id=51| special.gamma(v) /// array([ 1.77245385, 1.7712366 , 1.77002126, ..., 5.99472651, 5.99736257, 6. ]) }}}Matlab-style data plotting is supported through plt (remember, we did import matplotlib.pyplot as plt above).
{{{id=50| plt.clf() # clear the current figure plt.plot(v, special.gamma(v)) # plot(array of x vals, array of y values) plt.savefig('a.png') # makes plot get displayed /// }}}Here is an example from the Scipy tutorial that involves using a special Bessel function to model the vibrational modes of a thin drum head. Here we use Sage's integrated 3d plotting capabilities instead of matplotlib's pseudo-3d plotting.
{{{id=56| from scipy.special import jn, jn_zeros def drumhead_height(n, k, distance, angle, t): nth_zero = jn_zeros(n, k) # zeros of Bessel function return sp.cos(t)*sp.cos(n*angle)*jn(n, distance*nth_zero) # Now use a Sage function to create the 3d visualization pnt = (lambda r,theta: r*sp.cos(theta), lambda r,theta: r*sp.sin(theta), lambda r,theta: drumhead_height(1,1,r,theta,0.5)) G = parametric_plot3d(pnt, (0,1), (0,2*pi), plot_points=50) /// }}} {{{id=54| G.show() # default plotting requires java (e.g., not iphone/ipad/chrome friendly) /// }}} {{{id=58| G.show(viewer='tachyon') /// }}} {{{id=59| G.show(viewer='canvas3d') # works on everything (except Internet Explorer...) /// }}} {{{id=65| /// }}}The scipy.integrate module provides numerical integration and solving of ordinary differential equations.
{{{id=67| import scipy.integrate /// }}} {{{id=64| scipy.integrate? /// }}}Example: quad -- integrate a 1d functions over an interval
{{{id=63| from scipy.special import jv result = scipy.integrate.quad(lambda x: jv(2.5, x), 0, 4.5) result /// (1.1178179380783249, 7.8663171825372256e-09) }}} {{{id=69| plot(lambda x: jv(2.5, x), 0, 4.5, fill=True) ///The scipy.optimize module provides common optimization algorithms.
{{{id=95| import scipy.optimize /// }}} {{{id=94| scipy.optimize? /// }}}Example: Uses the Simplex Algorithm to minimize a function:
{{{id=96| def f(x): return x[0]*x[0] + x[1]*x[1] + 10 * cos(x[0])*cos(x[1]) A = scipy.optimize.fmin(f, (0,0)); A /// Optimization terminated successfully. Current function value: -1.808983 Iterations: 70 Function evaluations: 132 array([ 2.59576477e+00, -2.62130635e-05]) }}} {{{id=70| G = plot3d(lambda x,y: f((x,y)), (-1,4), (-1,1), opacity=.7) G += sphere((A[0],A[1],f(A)), color='red', size=.1) G.show() /// }}} {{{id=103| /// }}}Example: Least squares fit to noisy data.
{{{id=102| from scipy.optimize import leastsq from scipy import pi x = sp.r_[0:6e-2:30j] A = 10; k=1.0/3e-2; theta = pi/6 y_true = A * sp.sin(2*pi*k*x + theta) y_measured = y_true + 2*sp.random.randn(len(x)) # add random array def residuals(p, y, x): A, k, theta = p return y - A*sp.sin(2*pi*k*x + theta) def peval(x, p): return p[0]*sp.sin(2*pi*p[1]*x + p[2]) p0 = [8, 1/2.3e-2, pi/3] from scipy.optimize import leastsq plsq = leastsq(residuals, p0, args=(y_measured, x)) plt.clf() plt.plot(x, peval(x, plsq[0]), x, y_measured, 'o', x, y_true) plt.title('Least-squares fit to noisy data') plt.legend(['Fit', 'Noisy', 'True']) plt.savefig('a.png') /// }}} {{{id=101| /// }}} {{{id=98| /// }}} {{{id=73| /// }}}The scipy.interpolate package provides single and multivariate interpolation capabilities.
{{{id=109| import scipy.interpolate /// }}} {{{id=108| scipy.interpolate? /// }}}Example: 1-d interpolation
The function interp1d in scipy.interpolate creates an object that you can treat like a function that evaluate to the interpolation through a given list of x,y points in the plane (that partially define a *function*).
{{{id=107| random_vec = sp.random.randn(len(x)) @interact def demo(kind=['linear','nearest', 'zero', 'slinear', 'quadratic', 'cubic'], points=(50,(i for i in xrange(3,1000))), noisy=True): import scipy.interpolate # interpolate the function exp(-x/3): x = sp.r_[0:10:10j] y = sp.exp(-x/3.0) if noisy: y += 0.05*random_vec f = scipy.interpolate.interp1d(x, y, kind=kind) x_new = sp.r_[0:10:int(points)*1j] plt.clf() plt.plot(x, y, 'o', x_new, f(x_new), '-') plt.legend(['data', kind]) plt.axis([0,10,0,1]) plt.savefig('a.png') ///
|
The scipy.fftpack package provides numerical Fast Fourier Transform algorithms.
{{{id=113| import scipy.fftpack /// }}} {{{id=112| scipy.fftpack? /// }}} {{{id=118| plt.savefig( /// }}} {{{id=116| @interact def demo(frequencies=input_box("1 2", type=str)): print frequencies, type(frequencies) frequencies = [eval(a) for a in frequencies.split()] x = sp.r_[0:4*sp.pi:200j] y = sum(sp.sin(f*x) for f in frequencies) z = sp.fftpack.fft(y) plt.clf() plt.plot(x, y) plt.savefig('a.png', dpi=40) plt.clf() plt.plot(sp.arange(len(z)), abs(z)) plt.savefig('b.png', dpi=40) ///
|
The scipy.signal package provides a "signal processing toolbox", including filtering functions, and spline interpolation algorithms.
{{{id=114| import scipy.signal /// }}} {{{id=79| scipy.signal? /// }}} {{{id=82| /// }}}The scipy.linalg package provides algorithms for matrix and linear algebra, including a range of decomposition algorithms, special matrices, etc.
{{{id=121| import scipy.linalg /// }}} {{{id=84| scipy.linalg? /// }}} {{{id=87| /// }}}The scipy.stats package has a large number of basic descriptive statistic routines.
{{{id=86| import scipy.stats /// }}} {{{id=119| scipy.stats? /// }}} {{{id=89| /// }}}The scipy.ndimage package provides general image processing and analysis algorithms.
{{{id=85| import scipy.ndimage /// }}} {{{id=120| scipy.ndimage? /// }}} {{{id=91| /// }}}The scipy.io module lets you read and write various special file types, e.g., matlab matrices.
{{{id=74| import scipy.io /// }}} {{{id=93| scipy.io? /// }}}