# what is this line all about? Answer in lecture 4 %pylab inline from IPython.display import Image from scipy import * import scipy.linalg as la # # The scipy.special module includes a large number of Bessel-functions # Here we will use the functions jn and yn, which are the Bessel functions # of the first and second kind and real-valued order. We also include the # function jn_zeros and yn_zeros that gives the zeres of the functions jn # and yn. # from scipy.special import jn, yn, jn_zeros, yn_zeros n = 0 # order x = 0.0 # Bessel function of first kind print "J_%d(%f) = %f" % (n, x, jn(n, x)) x = 1.0 # Bessel function of second kind print "Y_%d(%f) = %f" % (n, x, yn(n, x)) x = linspace(0, 10, 100) fig, ax = subplots() for n in range(4): ax.plot(x, jn(n, x), label=r"$J_%d(x)$" % n) ax.legend(); # zeros of Bessel functions n = 0 # order m = 4 # number of roots to compute jn_zeros(n, m) from scipy.integrate import quad, dblquad, tplquad # define a simple function for the integrand def f(x): return x x_lower = 0 # the lower limit of x x_upper = 1 # the upper limit of x val, abserr = quad(f, x_lower, x_upper) print "integral value =", val, ", absolute error =", abserr def integrand(x, n): """ Bessel function of first kind and order n. """ return jn(n, x) x_lower = 0 # the lower limit of x x_upper = 10 # the upper limit of x val, abserr = quad(integrand, x_lower, x_upper, args=(3,)) print val, abserr val, abserr = quad(lambda x: exp(-x ** 2), -Inf, Inf) print "numerical =", val, abserr analytical = sqrt(pi) print "analytical =", analytical def integrand(x, y): return exp(-x**2-y**2) x_lower = 0 x_upper = 10 y_lower = 0 y_upper = 10 val, abserr = dblquad(integrand, x_lower, x_upper, lambda x : y_lower, lambda x: y_upper) print val, abserr from scipy.integrate import odeint, ode Image(url='http://upload.wikimedia.org/wikipedia/commons/c/c9/Double-compound-pendulum-dimensioned.svg') g = 9.82 L = 0.5 m = 0.1 def dx(x, t): """ The right-hand side of the pendelum ODE """ x1, x2, x3, x4 = x[0], x[1], x[2], x[3] dx1 = 6.0/(m*L**2) * (2 * x3 - 3 * cos(x1-x2) * x4)/(16 - 9 * cos(x1-x2)**2) dx2 = 6.0/(m*L**2) * (8 * x4 - 3 * cos(x1-x2) * x3)/(16 - 9 * cos(x1-x2)**2) dx3 = -0.5 * m * L**2 * ( dx1 * dx2 * sin(x1-x2) + 3 * (g/L) * sin(x1)) dx4 = -0.5 * m * L**2 * (-dx1 * dx2 * sin(x1-x2) + (g/L) * sin(x2)) return [dx1, dx2, dx3, dx4] # choose an initial state x0 = [pi/4, pi/2, 0, 0] # time coodinate to solve the ODE for: from 0 to 10 seconds t = linspace(0, 10, 250) # solve the ODE problem x = odeint(dx, x0, t) # plot the angles as a function of time fig, axes = subplots(1,2, figsize=(12,4)) axes[0].plot(t, x[:, 0], 'r', label="theta1") axes[0].plot(t, x[:, 1], 'b', label="theta2") x1 = + L * sin(x[:, 0]) y1 = - L * cos(x[:, 0]) x2 = x1 + L * sin(x[:, 1]) y2 = y1 - L * cos(x[:, 1]) axes[1].plot(x1, y1, 'r', label="pendulum1") axes[1].plot(x2, y2, 'b', label="pendulum2") axes[1].set_ylim([-1, 0]) axes[1].set_xlim([1, -1]); from IPython.display import clear_output import time fig, ax = subplots(figsize=(4,4)) for t_idx, tt in enumerate(t[:200]): x1 = + L * sin(x[t_idx, 0]) y1 = - L * cos(x[t_idx, 0]) x2 = x1 + L * sin(x[t_idx, 1]) y2 = y1 - L * cos(x[t_idx, 1]) ax.cla() ax.plot([0, x1], [0, y1], 'r.-') ax.plot([x1, x2], [y1, y2], 'b.-') ax.set_ylim([-1.5, 0.5]) ax.set_xlim([1, -1]) display(fig) clear_output() time.sleep(0.1) def dy(y, t, zeta, w0): """ The right-hand side of the damped oscillator ODE """ x, p = y[0], y[1] dx = p dp = -2 * zeta * w0 * p - w0**2 * x return [dx, dp] # initial state: y0 = [1.0, 0.0] # time coodinate to solve the ODE for t = linspace(0, 10, 1000) w0 = 2*pi*1.0 # solve the ODE problem for three different values of the damping ratio y1 = odeint(dy, y0, t, args=(0.0, w0)) # undamped y2 = odeint(dy, y0, t, args=(0.2, w0)) # under damped y3 = odeint(dy, y0, t, args=(1.0, w0)) # critial damping y4 = odeint(dy, y0, t, args=(5.0, w0)) # over damped fig, ax = subplots() ax.plot(t, y1[:,0], 'k', label="undamped", linewidth=0.25) ax.plot(t, y2[:,0], 'r', label="under damped") ax.plot(t, y3[:,0], 'b', label=r"critical damping") ax.plot(t, y4[:,0], 'g', label="over damped") ax.legend(); from scipy.fftpack import * N = len(t) dt = t[1]-t[0] # calculate the fast fourier transform # y2 is the solution to the under-damped oscillator from the previous section F = fft(y2[:,0]) # calculate the frequencies for the components in F w = fftfreq(N, dt) fig, ax = subplots(figsize=(9,3)) ax.plot(w, abs(F)); indices = where(w > 0) # select only indices for elements that corresponds to positive frequencies w_pos = w[indices] F_pos = F[indices] fig, ax = subplots(figsize=(9,3)) ax.plot(w_pos, abs(F_pos)) ax.set_xlim(0, 5); A = array([[1,2,3], [4,5,6], [7,8,9]]) b = array([1,2,3]) x = solve(A, b) x # check dot(A, x) - b A = rand(3,3) B = rand(3,3) X = solve(A, B) X # check norm(dot(A, X) - B) evals = eigvals(A) evals evals, evecs = eig(A) evals evecs n = 1 norm(dot(A, evecs[:,n]) - evals[n] * evecs[:,n]) # the matrix inverse inv(A) # determinant det(A) # norms of various orders norm(A, ord=2), norm(A, ord=Inf) from scipy.sparse import * # dense matrix M = array([[1,0,0,0], [0,3,0,0], [0,1,1,0], [1,0,0,1]]); M # convert from dense to sparse A = csr_matrix(M); A # convert from sparse to dense A.todense() A = lil_matrix((4,4)) # empty 4x4 sparse matrix A[0,0] = 1 A[1,1] = 3 A[2,2] = A[2,1] = 1 A[3,3] = A[3,0] = 1 A A.todense() A A = csr_matrix(A); A A = csc_matrix(A); A A.todense() (A * A).todense() dot(A, A).todense() v = array([1,2,3,4])[:,newaxis]; v # sparse matrix - dense vector multiplication A * v # same result with dense matrix - dense vector multiplcation A.todense() * v from scipy import optimize def f(x): return 4*x**3 + (x-2)**2 + x**4 fig, ax = subplots() x = linspace(-5, 3, 100) ax.plot(x, f(x)); x_min = optimize.fmin_bfgs(f, -2) x_min optimize.fmin_bfgs(f, 0.5) optimize.brent(f) optimize.fminbound(f, -4, 2) omega_c = 3.0 def f(omega): # a transcendental equation: resonance frequencies of a low-Q SQUID terminated microwave resonator return tan(2*pi*omega) - omega_c/omega fig, ax = subplots(figsize=(10,4)) x = linspace(0, 3, 1000) y = f(x) mask = where(abs(y) > 50) x[mask] = y[mask] = NaN # get rid of vertical line when the function flip sign ax.plot(x, y) ax.plot([0, 3], [0, 0], 'k') ax.set_ylim(-5,5); optimize.fsolve(f, 0.1) optimize.fsolve(f, 0.6) optimize.fsolve(f, 1.1) from scipy.interpolate import * def f(x): return sin(x) n = arange(0, 10) x = linspace(0, 9, 100) y_meas = f(n) + 0.1 * randn(len(n)) # simulate measurement with noise y_real = f(x) linear_interpolation = interp1d(n, y_meas) y_interp1 = linear_interpolation(x) cubic_interpolation = interp1d(n, y_meas, kind='cubic') y_interp2 = cubic_interpolation(x) fig, ax = subplots(figsize=(10,4)) ax.plot(n, y_meas, 'bs', label='noisy data') ax.plot(x, y_real, 'k', lw=2, label='true function') ax.plot(x, y_interp1, 'r', label='linear interp') ax.plot(x, y_interp2, 'g', label='cubic interp') ax.legend(loc=3); from scipy import stats # create a (discreet) random variable with poissionian distribution X = stats.poisson(3.5) # photon distribution for a coherent state with n=3.5 photons n = arange(0,15) fig, axes = subplots(3,1, sharex=True) # plot the probability mass function (PMF) axes[0].step(n, X.pmf(n)) # plot the commulative distribution function (CDF) axes[1].step(n, X.cdf(n)) # plot histogram of 1000 random realizations of the stochastic variable X axes[2].hist(X.rvs(size=1000)); # create a (continous) random variable with normal distribution Y = stats.norm() x = linspace(-5,5,100) fig, axes = subplots(3,1, sharex=True) # plot the probability distribution function (PDF) axes[0].plot(x, Y.pdf(x)) # plot the commulative distributin function (CDF) axes[1].plot(x, Y.cdf(x)); # plot histogram of 1000 random realizations of the stochastic variable Y axes[2].hist(Y.rvs(size=1000), bins=50); X.mean(), X.std(), X.var() # poission distribution Y.mean(), Y.std(), Y.var() # normal distribution t_statistic, p_value = stats.ttest_ind(X.rvs(size=1000), X.rvs(size=1000)) print "t-statistic =", t_statistic print "p-value =", p_value stats.ttest_1samp(Y.rvs(size=1000), 0.1) Y.mean() stats.ttest_1samp(Y.rvs(size=1000), Y.mean())