Lab 9: Eigenvalue Problem Demo

Lab 9: Eigenvalue Problem Demo#

import matplotlib.pyplot as plt
import numpy as np
import scipy.linalg
import scipy.sparse.linalg
OMEGA = 1
BOXSIZE = 8
ND = 60 #600
DELTAX = BOXSIZE / ND
HBAR = 1 
ALPHA = 0.4

x = np.linspace(-BOXSIZE / 2, BOXSIZE / 2, ND + 1)

def V(x):
    return 0.5*x**2

H = np.zeros((ND + 1, ND + 1))

for i in range(ND + 1):
    for j in range(ND + 1):
        # kinetic part
        H[i, j] = -(0.5 / DELTAX**2) * ((i + 1 == j) - 2 * (i == j) + (i - 1 == j)) 
        # potential part
        H[i, j] += V(x[i]) * (i == j)

# print the first 4x4 elements of H
print(H[:4,:4])
[[ 64.25       -28.125        0.           0.        ]
 [-28.125       63.72555556 -28.125        0.        ]
 [  0.         -28.125       63.21888889 -28.125     ]
 [  0.           0.         -28.125       62.73      ]]
%%timeit
# standard method
Es, psi = scipy.linalg.eigh(H)
#print(Es)
291 μs ± 1.92 μs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
%%timeit
# find the lowest eigenvalues and corresponding eigenvectors of H using ARPACK
Es, psis = scipy.sparse.linalg.eigsh(H, k=2, which='SM')
#print(Es)
1.96 ms ± 4.99 μs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
%%timeit
# shift-invert mode is faster for finding these
Es, psis = scipy.sparse.linalg.eigsh(H, k=2, sigma=0, which='LM')
#print(Es)
384 μs ± 787 ns per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
Es, psis = scipy.sparse.linalg.eigsh(H, k=2, sigma=0, which='LM')

E_0 = Es[0]
E_1 = Es[1]
psi_0 = psis[:, 0]
psi_1 = psis[:, 1]

# normalize the wave functions
psi_0 /= np.sqrt(np.sum(psi_0.conjugate() * psi_0) * DELTAX)
psi_1 /= np.sqrt(np.sum(psi_1.conjugate() * psi_1) * DELTAX)
xmin, xmax, ymin, ymax = -BOXSIZE/2, BOXSIZE/2, -1, 3
plt.figure(dpi=300, figsize=(8, 6))
plt.plot(x, E_0*np.ones_like(x), 'b--', label=f"$E_0$")
plt.plot(x, E_1*np.ones_like(x), 'r--', label=f"$E_1$")
plt.plot(x, psi_0 + E_0, 'b-', label=f"$\psi_0(x)$")
plt.plot(x, psi_1 + E_1, 'r-', label=f"$\psi_1(x)$")
plt.plot(x, V(x), 'k', label='$V(x)$')
plt.xlabel("$x$")
plt.ylabel(r"$V(x)$ or $\psi(x)$")
plt.xlim([xmin, xmax])
plt.ylim([ymin, ymax])
plt.legend(loc='upper right')
plt.tight_layout()
plt.savefig("ho_e0_e1.pdf")
plt.show()
../../_images/0ffe10b81bfe17b0b25295110fb3ec361b0dc8ec5c4966fb8271589bdbe496a9.png

Manual power method#

Let’s try the power method manually for the lowest eigenvalue of the following matrix.

Following lecture, we will need to first invert the matrix.

n_iter = 80
u = [np.ones(ND + 1)]
lambda_0 = [np.dot(u[-1].conjugate(), H @ u[0]) / np.dot(u[-1].conjugate(), u[0])]
Hinv = scipy.linalg.inv(H)
for i in range(n_iter):
    u.append(Hinv @ u[-1])
    u[-1] /= (np.sum(u[-1].conjugate() * u[-1]) * DELTAX)
    lambda_0.append(np.dot(u[-1].conjugate(), H @ u[-1]) / np.dot(u[-1].conjugate(), u[-1]))
 
print(lambda_0[-1])
0.4994440124683848
plt.figure(dpi=300, figsize=(8, 6))
plt.plot(x, V(x), 'k', label='$V(x)$')
plt.plot(x, lambda_0[-1]*np.ones_like(x), 'b--', label=f"$E_0$")
plt.plot(x, u[-1] + lambda_0[-1], 'b-', label=f"$\psi_0(x)$")
plt.xlabel("$x$")
plt.ylabel(r"$V(x)$ or $\psi(x)$")
plt.xlim([xmin, xmax])
plt.ylim([ymin, ymax])
plt.legend()
plt.show()
../../_images/d15daf20cdc117d9ef158a2aadd4582539c078b7e61622e954dab2afb2e7512c.png

Exercise: repeat for the second eigenvalue#

n_iter = 80
u = [np.ones(ND + 1)]
lambda_0 = [np.dot(u[-1].conjugate(), H @ u[0]) / np.dot(u[-1].conjugate(), u[0])]
Hinv = scipy.linalg.inv((H-1.3*np.identity(ND+1)))
for i in range(n_iter):
    u.append(Hinv @ u[-1])
    u[-1] /= (np.sum(u[-1].conjugate() * u[-1]) * DELTAX)
    lambda_0.append(np.dot(u[-1].conjugate(), H @ u[-1]) / np.dot(u[-1].conjugate(), u[-1]))

print(lambda_0[-1])
1.4972224091357913
plt.figure(dpi=300, figsize=(8, 6))
plt.plot(x, V(x), 'k', label='$V(x)$')
plt.plot(x, lambda_0[-1]*np.ones_like(x), 'b--', label=f"$E_0$")
plt.plot(x, u[-1] + lambda_0[-1], 'b-', label=f"$\psi_0(x)$")
plt.xlabel("$x$")
plt.ylabel(r"$V(x)$ or $\psi(x)$")
plt.xlim([xmin, xmax])
plt.ylim([ymin, ymax])
plt.legend()
plt.show()
../../_images/f20d2693e85e9f3d7f934cfd697f0792aaf953018c808dbbb229c1d272f74685.png