Example #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]
Example #2
0
def stateEnergy(psi: List[tn.Node], H: HOp):
    E = 0
    for i in range(len(psi)):
        psiCopy = bops.copyState(psi)
        single_i = bops.copyState([H.singles[i]])[0]
        psiCopy[i] = bops.permute(tn.contract(psiCopy[i][1] ^ single_i[0], name=('site' + str(i))), [0, 2, 1])
        E += bops.getOverlap(psiCopy, psi)
        bops.removeState(psiCopy)
        tn.remove_node(single_i)
    for i in range(len(psi) - 1):
        psiCopy = bops.copyState(psi)
        r2l = bops.copyState([H.r2l[i+1]])[0]
        l2r = bops.copyState([H.l2r[i]])[0]
        psiCopy[i][2] ^ psiCopy[i+1][0]
        psiCopy[i][1] ^ l2r[0]
        r2l[0] ^ psiCopy[i+1][1]
        l2r[2] ^ r2l[2]
        M = tn.contract_between(psiCopy[i], \
                                tn.contract_between(l2r, tn.contract_between(r2l, psiCopy[i+1])))
        if bops.multiContraction(M, M, '0123', '0123*').tensor != 0:
            [psiCopy, te] = bops.assignNewSiteTensors(psiCopy, i, M, '>>')
            E += bops.getOverlap(psiCopy, psi)
        bops.removeState(psiCopy)
        tn.remove_node(r2l)
        tn.remove_node(l2r)
    return E
Example #3
0
def dmrgStep(HL, HR, H, psi, k, dir, psiCompare=None, opts=None):
    # Perform a single DMRG step:
    # 1. Contracts psi(k) and psi(k + dir) to get M.
    # 2. Performs lancsoz and get a new contracted M.
    # 3. Performs an SVD in order to get the new working site, at k + dir.
    # 4. Calculates HL(k) / HR(k) (according to dir)
    k1 = k
    k2 = k + 1
    [M, E0] = lanczos(HL, HR, H, k1, psi, psiCompare)
    [psi, truncErr] = bops.assignNewSiteTensors(psi, k, M, dir)
    if dir == '>>':
        if psiCompare is not None:
            for state in psiCompare:
                state = bops.shiftWorkingSite(state, k, '>>')
                psi = bops.getOrthogonalState(state, psiInitial=psi)
            HLs, HRs = getHLRs(H, psi, workingSite=k+1)
            return psi, HLs, HRs, E0, truncErr
        else:
            newHL = getHLR(psi, k, H, dir, HL)
            return psi, newHL, E0, truncErr
    else:
        if psiCompare is not None:
            for state in psiCompare:
                state = bops.shiftWorkingSite(state, k, '<<')
                psi = bops.getOrthogonalState(state, psiInitial=psi)
            HLs, HRs = getHLRs(H, psi, workingSite=k)
            return psi, HLs, HRs, E0, truncErr
        else:
            newHR = getHLR(psi, k+1, H, dir, HR)
            return psi, newHR, E0, truncErr
Example #4
0
def applyH(psi: List[tn.Node], H: HOp):
    psiCopy = bops.copyState(psi)
    single_0 = bops.copyState([H.singles[0]])[0]
    psiCopy[0] = bops.permute(tn.contract(psiCopy[0][1] ^ single_0[0], name=('site' + str(0))), [0, 2, 1])
    result = psiCopy
    for i in range(1, len(psi)):
        psiCopy = bops.copyState(psi)
        single_i = bops.copyState([H.singles[i]])[0]
        psiCopy[i] = bops.permute(tn.contract(psiCopy[i][1] ^ single_i[0], name=('site' + str(i))), [0, 2, 1])
        result = bops.addStates(result, psiCopy)
    for i in range(len(psi) - 1):
        psiCopy = bops.copyState(psi)
        r2l = bops.copyState([H.r2l[i+1]])[0]
        l2r = bops.copyState([H.l2r[i]])[0]
        psiCopy[i][2] ^ psiCopy[i+1][0]
        psiCopy[i][1] ^ l2r[0]
        r2l[0] ^ psiCopy[i+1][1]
        l2r[2] ^ r2l[2]
        M = tn.contract_between(psiCopy[i], \
                                tn.contract_between(l2r, tn.contract_between(r2l, psiCopy[i+1])))
        [psiCopy, te] = bops.assignNewSiteTensors(psiCopy, i, M, '>>')
        result = bops.addStates(result, psiCopy)
    return result