示例#1
0
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
示例#2
0
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
示例#3
0
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]
示例#4
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
示例#5
0
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