Esempio n. 1
0
def getTridiagonal(HL, HR, H, k, psi, psiCompare=None):
    accuracy = 1e-10 # 1e-12

    v = bops.multiContraction(psi[k], psi[k + 1], '2', '0')
    # Small innaccuracies ruin everything!
    v.set_tensor(v.get_tensor() / bops.getNodeNorm(v))

    psiCopy = bops.copyState(psi)

    base = []
    base.append(v)
    Hv = applyHToM(HL, HR, H, v, k)
    alpha = bops.multiContraction(v, Hv, '0123', '0123*').get_tensor()

    if psiCompare is not None:
        copyV = bops.copyState([v])[0]
        psiCopy = bops.assignNewSiteTensors(psiCopy, k, copyV, '>>')[0]

    E = stateEnergy(psi, H)

    w = bops.addNodes(Hv, bops.multNode(v, -alpha))
    beta = bops.getNodeNorm(w)

    # Start with T as an array and turn into tridiagonal matrix at the end.
    Tarr = [[0, 0, 0]]
    Tarr[0][1] = alpha
    counter = 0
    formBeta = 2 * beta # This is just some value to init formBeta > beta.
    while (beta > accuracy) and (counter <= 50) and (beta < formBeta):
        Tarr[counter][2] = beta
        Tarr.append([0, 0, 0])
        Tarr[counter + 1][0] = beta
        counter += 1

        v = bops.multNode(w, 1 / beta)
        base.append(v)

        if psiCompare is not None:
            copyV = bops.copyState([v])[0]
            psiCopy = bops.assignNewSiteTensors(psiCopy, k, copyV, '>>')[0]
        Hv = applyHToM(HL, HR, H, v, k)

        alpha = bops.multiContraction(v, Hv, '0123', '0123*').get_tensor()
        Tarr[counter][1] = alpha
        w = bops.addNodes(bops.addNodes(Hv, bops.multNode(v, -alpha)), \
                          bops.multNode(base[counter-1], -beta))
        formBeta = beta
        beta = bops.getNodeNorm(w)
    T = np.zeros((len(Tarr), len(Tarr)), dtype=complex)
    T[0][0] = Tarr[0][1]
    if len(Tarr) > 1:
        T[0][1] = Tarr[0][2]
    for i in range(1, len(Tarr)-1):
        T[i][i-1] = Tarr[i][0]
        T[i][i] = Tarr[i][1]
        T[i][i+1] = Tarr[i][2]
    T[len(Tarr)-1][len(Tarr)-2] = Tarr[len(Tarr)-1][0]
    T[len(Tarr) - 1][len(Tarr) - 1] = Tarr[len(Tarr) - 1][1]
    return [T, base]
Esempio n. 2
0
def lanczos(HL, HR, H, k, psi, psiCompare):
    [T, base] = getTridiagonal(HL, HR, H, k, psi, psiCompare)
    [Es, Vs] = np.linalg.eig(T)
    minIndex = np.argmin(Es)
    E0 = Es[minIndex]
    M = None
    for i in range(len(Es)):
        M = bops.addNodes(M, bops.multNode(base[i], Vs[i][minIndex]))

    M = bops.multNode(M, 1/bops.getNodeNorm(M))
    return [M, E0]
Esempio n. 3
0
def applyHToM(HL, HR, H, M, k):
    k1 = k
    k2 = k + 1

    # Add HL.opSum x h.identity(k1) x h.identity(k2) x I(Right)
    # and I(Left) x h.identity(k1) x h.identity(k2) x HR.opSum
    Hv = bops.multiContraction(HL.opSum, M, '0', '0')
    Hv = bops.addNodes(Hv, bops.multiContraction(M, HR.opSum, '3', '0'))

    # Add I(Left) x h.single(k1) x h.identity(k2) x I(Right)
    # And I(Left) x h.identity(k1) x h.single(k2) x I(Right)
    Hv = bops.addNodes(Hv, \
                       bops.permute(bops.multiContraction(M, H.singles[k1], '1', '0'), [0, 3, 1, 2]))
    Hv = bops.addNodes(Hv, \
                       bops.permute(bops.multiContraction(M, H.singles[k2], '2', '0'), [0, 1, 3, 2]))

    # Add HL.openOp x h.r2l(k1) x h.identity(k2) x I(Right)
    # And I(Left) x h.identity(k1) x h.l2r(k2) x HR.openOp
    HK1R2L = bops.permute(bops.multiContraction(M, H.r2l[k1], '1', '0'), [0, 4, 3, 1, 2])
    Hv = bops.addNodes(Hv, \
                       bops.multiContraction(HL.openOp, HK1R2L, '02', '01'))
    HK2L2R = bops.permute(bops.multiContraction(M, H.l2r[k2], '2', '0'), [0, 1, 3, 4, 2])
    Hv = bops.addNodes(Hv, \
                       bops.multiContraction(HK2L2R, HR.openOp, '43', '02'))

    # Add I(Left) x h.l2r(k1) x h.r2l(k2) x I(Right)
    HK1K2 = bops.multiContraction(M, H.l2r[k1], '1', '0')
    HK1K2 = bops.multiContraction(HK1K2, H.r2l[k2], '14', '02')
    HK1K2 = bops.permute(HK1K2, [0, 2, 3, 1])
    Hv = bops.addNodes(Hv, HK1K2)

    return Hv
Esempio n. 4
0
def getHLR(psi, l, H, dir, HLRold):
    if dir == '>>':
        if l == -1:
            opSum = tn.Node(np.zeros((psi[0].get_dimension(0), psi[0].get_dimension(0)), dtype=complex))
            openOp = tn.Node(np.zeros((psi[0].get_dimension(0), psi[0].get_dimension(0)), dtype=complex))
            return HExpValMid(opSum, openOp)
        else:
            psil = bops.copyState([psi[l]], conj=False)[0]
            psilConj = bops.copyState([psi[l]], conj=True)[0]
            singlel = bops.copyState([H.singles[l]], conj=False)[0]
            psil[0] ^ psilConj[0]
            psil[1] ^ singlel[0]
            psilConj[1] ^ singlel[1]
            opSum1 = tn.contract_between(psil, \
                     tn.contract_between(singlel, psilConj), name='operator-sum')
            if np.max(opSum1.tensor) > 100:
                g=1
            if l > 0:
                psil = bops.copyState([psi[l]], conj=False)[0]
                psilConj = bops.copyState([psi[l]], conj=True)[0]
                HLRoldCopy = bops.copyState([HLRold.openOp])[0]
                r2l_l = bops.copyState([H.r2l[l]], conj=False)[0]
                psil[0] ^ HLRoldCopy[0]
                psilConj[0] ^ HLRoldCopy[1]
                psil[1] ^ r2l_l[0]
                psilConj[1] ^ r2l_l[1]
                r2l_l[2] ^ HLRoldCopy[2]
                opSum2 = tn.contract_between(psil, tn.contract_between(psilConj, tn.contract_between(r2l_l, HLRoldCopy)))
                opSum1 = bops.addNodes(opSum1, opSum2)
                if np.max(opSum1.tensor) > 100:
                    g = 1

            psil = bops.copyState([psi[l]], conj=False)[0]
            psilConj = bops.copyState([psi[l]], conj=True)[0]
            HLRoldCopy = bops.copyState([HLRold.opSum])[0]
            psil[0] ^ HLRoldCopy[0]
            psilConj[0] ^ HLRoldCopy[1]
            psil[1] ^ psilConj[1]
            opSum3 = tn.contract_between(psil, tn.contract_between(psilConj, HLRoldCopy))
            opSum1 = bops.addNodes(opSum1, opSum3)
            if np.max(opSum1.tensor) > 100:
                g=1

            if l < len(psi) - 1:
                psil = bops.copyState([psi[l]], conj=False)[0]
                psilConj = bops.copyState([psi[l]], conj=True)[0]
                l2r_l = bops.copyState([H.l2r[l]], conj=False)[0]
                psil[0] ^ psilConj[0]
                psil[1] ^ l2r_l[0]
                psilConj[1] ^ l2r_l[1]
                openOp = tn.contract_between(psil, tn.contract_between(psilConj, l2r_l), name='open-operator')
            else:
                openOp = None
            return HExpValMid(opSum1, openOp)
    if dir == '<<':
        if l == len(psi):
            opSum = tn.Node(np.zeros((psi[l-1].get_dimension(2), psi[l-1].get_dimension(2)), dtype=complex))
            openOp = tn.Node(np.zeros((psi[l-1].get_dimension(2), psi[l-1].get_dimension(2)), dtype=complex))
            return HExpValMid(opSum, openOp)
        else:
            psil = bops.copyState([psi[l]], conj=False)[0]
            psilConj = bops.copyState([psi[l]], conj=True)[0]
            single_l = bops.copyState([H.singles[l]], conj=False)[0]
            psil[2] ^ psilConj[2]
            psil[1] ^ single_l[0]
            psilConj[1] ^ single_l[1]
            opSum1 = tn.contract_between(psil, \
                                         tn.contract_between(single_l, psilConj), name='operator-sum')

            if l < len(psi) -1:
                psil = bops.copyState([psi[l]], conj=False)[0]
                psilConj = bops.copyState([psi[l]], conj=True)[0]
                HLRoldCopy = bops.copyState([HLRold.openOp])[0]
                l2r_l = bops.copyState([H.l2r[l]], conj=False)[0]
                psil[2] ^ HLRoldCopy[0]
                psilConj[2] ^ HLRoldCopy[1]
                psil[1] ^ l2r_l[0]
                psilConj[1] ^ l2r_l[1]
                l2r_l[2] ^ HLRoldCopy[2]
                opSum2 = tn.contract_between(psil, tn.contract_between(psilConj, tn.contract_between(l2r_l, HLRoldCopy)))
                opSum1 = bops.addNodes(opSum1, opSum2)

            psil = bops.copyState([psi[l]], conj=False)[0]
            psilConj = bops.copyState([psi[l]], conj=True)[0]
            HLRoldCopy = bops.copyState([HLRold.opSum])[0]
            psil[2] ^ HLRoldCopy[0]
            psilConj[2] ^ HLRoldCopy[1]
            psil[1] ^ psilConj[1]
            opSum3 = tn.contract_between(psil, tn.contract_between(psilConj, HLRoldCopy))
            opSum1 = bops.addNodes(opSum1, opSum3)

            if l > 0:
                psil = bops.copyState([psi[l]], conj=False)[0]
                psilConj = bops.copyState([psi[l]], conj=True)[0]
                r2l_l = bops.copyState([H.r2l[l]], conj=False)[0]
                psil[2] ^ psilConj[2]
                psil[1] ^ r2l_l[0]
                psilConj[1] ^ r2l_l[1]
                openOp = tn.contract_between(psil, tn.contract_between(psilConj, r2l_l), name='open-operator')
            else:
                openOp = None
            return HExpValMid(opSum1, openOp)