def ftlan_rdm1s1c(qud, hop, v0, T, norb, m=60, Min_b=1e-15, Min_m=2, kB=1., E0=0., norm=np.linalg.norm): beta = 1. / (kB * T) E = 0. v0 = v0 / norm(v0) rdm1 = qud(v0) a, b = [], [] krylov = [] krylov.append(v0) Hv = hop(v0) a.append(v0.dot(Hv)) v1 = Hv - a[0] * v0 b.append(norm(v1)) if b[0] < Min_b: log.warning("Insufficient size of the Krylov space!") return rdm1, 0., 1e-5 v1 = v1 / b[0] Hv = hop(v1) a.append(v1.dot(Hv)) krylov.append(v1) for i in range(1, int(m - 1)): v2 = Hv - b[i - 1] * v0 - a[i] * v1 b.append(norm(v2)) if abs(b[i]) < Min_b: if i < Min_m: log.warning("Insufficient size of the Krylov space!") return rdm1, 0., 1e-5 b.pop() break v2 = v2 / b[i] krylov.append(v2) Hv = hop(v2) a.append(v2.dot(Hv)) v0 = v1.copy() v1 = v2.copy() a, b = np.asarray(a), np.asarray(b) krylov = np.asarray(krylov).real eps, phi = Tri_diag(a, b) l = len(eps) estate = krylov.T.dot(phi).real coef = np.exp(-beta * (eps - E0) / 2.) * phi[0, :].real exp_eps = np.exp(-beta * (eps - E0)) E = np.sum(exp_eps * eps * phi[0, :]**2.).real Z = np.sum(exp_eps * phi[0, :]**2.).real psi = estate.dot(coef.T) rdm1 = qud(psi) return np.asarray(rdm1), E, Z
def ftlan_E1c(hop, v0, T, m=40, Min_b=1e-15, Min_m=3, kB=1.0, norm=np.linalg.norm, E0=0., **kwargs): beta = 1. / (T * kB) E = 0. a, b = [], [] v0 = v0 / norm(v0) Hv = hop(v0) a.append(v0.dot(Hv)) v1 = Hv - a[0] * v0 b.append(norm(v1)) if b[0] < Min_b: log.warning("Insufficient size of the Krylov space!") return 0., 1e-10 v1 = v1 / b[0] Hv = hop(v1) a.append(v1.dot(Hv)) for i in range(1, m - 1): v2 = Hv - b[i - 1] * v0 - a[i] * v1 b.append(norm(v2)) if abs(b[i]) < Min_b: if i < Min_m: log.warning("Insufficient size of the Krylov space!") return 0., 1e-10 b.pop() break v2 = v2 / b[i] Hv = hop(v2) a.append(v2.dot(Hv)) v0 = v1.copy() v1 = v2.copy() a = np.asarray(a) b = np.asarray(b) eps, phi = Tri_diag(a, b) l = len(eps) # Eo = eps[0] # eps = eps-Eo exp_eps = np.exp(-beta * (eps - E0)) E = np.sum(exp_eps * eps * phi[0, :]**2.).real Z = np.sum(exp_eps * phi[0, :]**2.).real return E, Z
def ftlan_E(hop, v0, m=40, norm=np.linalg.norm, Min_b=1e-10, Min_m=3): a, b = [], [] v0 = v0 / norm(v0) Hv = hop(v0) a.append(v0.dot(Hv)) v1 = Hv - a[0] * v0 b.append(norm(v1)) if b[0] < Min_b: log.warning("Insufficient size of the Krylov space!") return 0., 1e-10 v1 = v1 / b[0] Hv = hop(v1) a.append(v1.dot(Hv)) for i in range(1, m - 1): v2 = Hv - b[i - 1] * v0 - a[i] * v1 b.append(norm(v2)) if abs(b[i]) < Min_b: if i < Min_m: log.warning("Insufficient size of the Krylov space!") return 0., 1e-10 b.pop() break v2 = v2 / b[i] Hv = hop(v2) a.append(v2.dot(Hv)) v0 = v1.copy() v1 = v2.copy() a = np.asarray(a) b = np.asarray(b) eps, phi = Tri_diag(a, b) return eps[0]
def ftlan_mu1c_time(H_prod_v, mu_prod_v, v0, T, time_step, m=40, Min_b=1e-15, Min_m=3, kB=1.0, norm=np.linalg.norm, E0=0., **kwargs): # H_prod_v - H*c function # mu_prod_v - mu*c function beta = 1. / (T * kB) a_v, b_v, a_w, b_w = [], [], [], [] krylov_v, krylov_w = [], [] v0 = v0 / norm(v0) w0 = mu_prod_v(v0) w0 = w0 / norm(w0) krylov_v.append(v0) krylov_w.append(w0) Hv = H_prod_v(v0) Hw = H_prod_v(w0) a_v.append(v0.dot(Hv)) a_w.append(w0.dot(Hw)) v1 = Hv - a_v[0] * v0 w1 = Hw - a_w[0] * w0 b_v.append(norm(v1)) b_w.append(norm(w1)) if b_v[0] < Min_b or b_w < Min_b: log.warning("Insufficient size of the Krylov space!") return 0., 1e-10 v1 = v1 / b_v[0] w1 = w1 / b_w[0] krylov_v.append(v1) krylov_w.append(w1) Hv = H_prod_v(v1) Hw = H_prod_v(w1) a_v.append(v1.dot(Hv)) a_w.append(w1.dot(Hw)) for i in range(1, m - 1): v2 = Hv - b_v[i - 1] * v0 - a_v[i] * v1 b_v.append(norm(v2)) if abs(b_v[i]) < Min_b: if i < Min_m: log.warning("Insufficient size of the Krylov space!") return 0., 1e-10 b_v.pop() break v2 = v2 / b_v[i] Hv = H_prod_v(v2) krylov_v.append(v2) a_v.append(v2.dot(Hv)) v0 = v1.copy() v1 = v2.copy() for i in range(1, m - 1): w2 = Hw - b_w[i - 1] * w0 - a_w[i] * w1 b_w.append(norm(w2)) if abs(b_w[i] < Min_b): if i < Min_m: log.warning("Insufficient size of the Krylov space!") return 0., 1e-10 b_w.pop() break w2 = w2 / b_w[i] krylov_w.append(w2) Hw = H_prod_v(w2) a_w.append(w2.dot(Hw)) w0 = w1.copy() w1 = w2.copy() a_v, b_v, a_w, b_w = np.asarray(a_v), np.asarray(b_v), np.asarray( a_w), np.asarray(b_w) krylov_v, krylov_w = np.asarray(krylov_v), np.asarray(krylov_w) eps_v, phi_v = Tri_diag(a_v, b_v) eps_w, phi_w = Tri_diag(a_w, b_w) estate_v = krylov_v.T.dot(phi_v) estate_w = krylov_w.T.dot(phi_w) coef_v = np.exp((-beta - 1.j * time_step) * eps_v) * (phi_v[0, :].conj()) coef_w = np.exp(-1.j * time_step * eps_w) * (phi_w[0, :].conj()) Z = np.sum(np.exp(-beta * (eps_v)) * (phi_v[0, :] * phi_v[0, :].conj())) # Eo = eps[0] # eps = eps-Eo bra = estate_v.dot(coef_v.T) ket = estate_w.dot(coef_w.T) C_t = bra.T.conj().dot(mu_prod_v(ket)) return C_t, Z
def ftlan_mu1c_freq(H_prod_v, mu_prod_v, v0, T, freq_list, m=40, Min_b=1e-15, Min_m=3, kB=1.0, norm=np.linalg.norm, E0=0., **kwargs): # H_prod_v - H*c function # mu_prod_v - mu*c function # a list of w grid i.e. (5.0, 20) means the range of w is (-5.0, 5.0), and 20 grids are made beta = 1. / (T * kB) a_v, b_v, a_w, b_w = [], [], [], [] krylov_v, krylov_w = [], [] v0 = v0 / norm(v0) w0 = mu_prod_v(v0) w0 = w0 / norm(w0) krylov_v.append(v0) krylov_w.append(w0) Hv = H_prod_v(v0) Hw = H_prod_v(w0) a_v.append(v0.dot(Hv)) a_w.append(w0.dot(Hw)) v1 = Hv - a_v[0] * v0 w1 = Hw - a_w[0] * w0 b_v.append(norm(v1)) b_w.append(norm(w1)) if b_v[0] < Min_b or b_w < Min_b: log.warning("Insufficient size of the Krylov space!") return 0., 1e-10 v1 = v1 / b_v[0] w1 = w1 / b_w[0] krylov_v.append(v1) krylov_w.append(w1) Hv = H_prod_v(v1) Hw = H_prod_v(w1) a_v.append(v1.dot(Hv)) a_w.append(w1.dot(Hw)) for i in range(1, m - 1): v2 = Hv - b_v[i - 1] * v0 - a_v[i] * v1 b_v.append(norm(v2)) if abs(b_v[i]) < Min_b: if i < Min_m: log.warning("Insufficient size of the Krylov space!") return 0., 1e-10 b_v.pop() break v2 = v2 / b_v[i] Hv = H_prod_v(v2) krylov_v.append(v2) a_v.append(v2.dot(Hv)) v0 = v1.copy() v1 = v2.copy() for i in range(1, m - 1): w2 = Hw - b_w[i - 1] * w0 - a_w[i] * w1 b_w.append(norm(w2)) if abs(b_w[i] < Min_b): if i < Min_m: log.warning("Insufficient size of the Krylov space!") return 0., 1e-10 b_w.pop() break w2 = w2 / b_w[i] krylov_w.append(w2) Hw = H_prod_v(w2) a_w.append(w2.dot(Hw)) w0 = w1.copy() w1 = w2.copy() a_v, b_v, a_w, b_w = np.asarray(a_v), np.asarray(b_v), np.asarray( a_w), np.asarray(b_w) krylov_v, krylov_w = np.asarray(krylov_v), np.asarray(krylov_w) eps_v, phi_v = Tri_diag(a_v, b_v) eps_w, phi_w = Tri_diag(a_w, b_w) estate_v = krylov_v.T.dot(phi_v) estate_w = krylov_w.T.dot(phi_w) coef_v = np.exp(-beta * eps_v) * (phi_v[0, :].conj()) coef_w = phi_w[0, :].conj() bra = np.einsum('ij,j -> ij', estate_v, coef_v) ket = np.einsum('ij,j -> ij', estate_w, coef_w) half_Nstep = freq_list[1] w_max = freq_list[0] lstep = float(w_max) / half_Nstep C_omega = np.zeros(2 * half_Nstep, dtype=np.complex64) for i in range(len(krylov_v)): for j in range(len(krylov_w)): delta_e = eps_w[j] - eps_v[i] if abs(delta_e) > w_max: continue if delta_e < 0: idx = int(delta_e / lstep) + half_Nstep - 1 else: idx = int(delta_e / lstep) + half_Nstep C_omega[idx] = bra[:, i].T.conj().dot(mu_prod_v(ket[:, j])) Z = np.sum(np.exp(-beta * (eps_v)) * (phi_v[0, :] * phi_v[0, :].conj())) return C_omega, Z