Transfer matrix is incorrect without imposing canonical form

How do I use this algorithm? What does that parameter do?
Post Reply
Posts: 1
Joined: 12 Apr 2024, 08:21

Transfer matrix is incorrect without imposing canonical form

Post by yuhanliu »

Hi all,

I am trying to implement the transfer matrix by myself and try it on the example of the Heisenberg model using infinite DMRG with `L=2`. (The reason why I need my own implementation is because `TransferMatrix.to_matrix()` is not implemented. Here is my simple implementation,

Code: Select all

def readOut(psi):
    psi_arr = []
    for i in range(0, psi.L):
        psi_i = (psi.get_B(i, form=None)).drop_charge().to_ndarray()
    return psi_arr

def transferMatrixEpl(psi1, psi2):
    # input are two lists of numpy array
    d = np.shape(psi1[0])[0]
    T = np.zeros((d**2, d**2), dtype = np.complex128)
    for i in range(len(psi1)):
        T += np.kron(psi1[i], psi2[i].conj())
    return T

def debug():
    E, psi, M = example_DMRG_heisenberg_xxz_infinite(1.5)
    psi.canonical_form()  # this is essential!
    psi_arr = readOut(psi)
    psi_00 = psi_arr[0][:,0,:]
    psi_01 = psi_arr[0][:,1,:]
    psi_10 = psi_arr[1][:,0,:]
    psi_11 = psi_arr[1][:,1,:]
    psi_mtr = [psi_00 @ psi_10, psi_00 @ psi_11, psi_01 @ psi_10, psi_01 @ psi_11]
    Tpsi = transferMatrixEpl(psi_mtr, psi_mtr)
    return Tpsi
However, I found that if I comment out the line `psi.canonical_form()`, the transfer matrix is wrong and I cannot get the expected correlation length and correlation function. This confuses me because the correlation length should be independent of whether I choose the MPS canonical form or not. Is this a bug or something else? Thank you very much!

User avatar
Site Admin
Posts: 435
Joined: 21 Jul 2018, 12:52
Location: TU Munich

Re: Transfer matrix is incorrect without imposing canonical form

Post by Johannes »

If you need to_matrix, why don't you implement that function directly on the existing transfer matrix?

To get a consistent result, all tensor which you extract *need* to be in the same canonical form, e.g. all right-canonical 'B' form.
After a plain DMRG run (without a call of psi.canonical_form() in the end), the state returned is in a mixed canonical form, roughly A A S B ... B, and you get that form
Thus, you would need to explicitly specify form='B' rather than form=None
Post Reply