def inverse_iteration(L, shift, acc, iter_lim):
k = L.shape[0]
eig_vals = []
init_eig_vec = np.ones(k) / np.sqrt(k)
for iteration in range(0, iter_lim + 1):
L_shift = np.linalg.inv(L - shift * np.eye(n))
eig_vec = L_shift @ init_eig_vec
eig_vec /= np.linalg.norm(eig_vec)
eig_val = eig_vec @ L @ eig_vec
eig_vals.append(eig_val)
if len(eig_vals) > 1 and abs(eig_vals[-1] - eig_vals[-2]) < acc:
break
init_eig_vec = eig_vec / np.linalg.norm(eig_vec)
min_eig_val = min(eig_vals)
return eig_vals, min_eig_val
shift = 0.2
acc = 1e-6
iter_lim = 100
nlist = [10, 20]
for n in nlist:
Ln = np.diag(2 * np.ones(n)) + np.diag(-np.ones(n - 1), k=-1) + np.diag(-np.ones(n - 1), k=1)
eig_vals_Ln, min_eig_val_Ln = inverse_iteration(Ln**2, shift, acc, iter_lim)
eigenvalues = np.linalg.eig(Ln**2)
print(f"Code min: {min_eig_val_Ln}")
print(f"True min: {eigenvalues[0][0]}")
It always gives pre-min value. When I try [0][1] they are the same
I have no idea why it happens, I changed shift values and use np.sqrt instead on linalg.norm, but it does not help