Comparing Wave Functions with Different Charge Infos

How do I use this algorithm? What does that parameter do?
Post Reply
rsajith
Posts: 1
Joined: 03 Nov 2022, 20:03

Comparing Wave Functions with Different Charge Infos

Post by rsajith »

Hello all,

I ran DMRG on two systems, one conserving parity and one conserving number. I want to compare the resulting wave functions by computing their overlap; however, when doing this, I get an error saying that I have "Incompatible Charge Info." Is there I can do to modify the charge info for either of the wave functions so that I can compare them? One of my models is strictly number-conserving and the other isn't, so it is important that I operate in the fixed number and fixed parity sectors, respectively, when running the DMRG.

Any help would be appreciated!
User avatar
Johannes
Site Admin
Posts: 357
Joined: 21 Jul 2018, 12:52
Location: TU Munich

Re: Comparing Wave Functions with Different Charge Infos

Post by Johannes »

The Array class has the methods drop_charge and change_charge.
What's missing is functions to do this for each tensor in an MPS (or similarly, an MPO).
You could do something along the following snippet:

Code: Select all

def MPS_drop_charge(psi, charge=None, chinfo=None, permute_p_leg=True):
    psi_c = psi.copy()
    psi_c.chinfo = chinfo = npc.ChargeInfo.drop(chinfo, charge=charge)
    if permute_p_leg is None and chinfo.qnumber == 0:
        permute_p_leg = True
    for i, B in enumerate(psi_c._B):
        psi_c._B[i] = B = B.drop_charge(charge=charge, chinfo=chinfo)
        psi_c.sites[i] = site = copy.copy(psi.sites[i])
        if permute_p_leg:
            if permute_p_leg is True:
                perm = tenpy.tools.misc.inverse_permutation(site.perm)
            else:
                perm = permute_p_leg
            psi_c._B[i] = B = B.permute(perm, 'p')
        else:
            perm = None
        site.change_charge(B.get_leg('p'), perm) # in place
    print(psi_c.chinfo)
    psi_c.test_sanity()
    return psi_c

def MPO_drop_charge(H_MPO, charge=None, chinfo=None, permute_p_leg=True):
    H = H_MPO.copy()
    H.sites = list(H.sites) # extra copy!
    H.chinfo = chinfo = npc.ChargeInfo.drop(chinfo, charge=charge)
    if permute_p_leg is None and chinfo.qnumber == 0:
        permute_p_leg = True
    for i, W in enumerate(H_MPO._W):
        H._W[i] = W = W.drop_charge(charge=charge, chinfo=chinfo)
        H.sites[i] = site = copy.copy(H_MPO.sites[i])
        if permute_p_leg:
            if permute_p_leg is True:
                perm = tenpy.tools.misc.inverse_permutation(site.perm)
            else:
                perm = permute_p_leg
            H._W[i] = W = W.permute(perm, 'p').permute(perm, 'p*')
        else:
            perm = None
        site.change_charge(W.get_leg('p'), perm)
    print(H.chinfo)
    H.test_sanity()
    return H
You can ajdust them to also call the change_charge instead of the drop_charge method.

Watch out for the permutation of the local basis. When charges are used, (most) legs are sorted by charge values, such that the indices for your local basis states might change, in particular when you have more than just 2 basis states (e.g. spin 1 or bosons). Note also that I just merged Issue #175 changing exactly this permutation of local basis states for sites, at least depending on a config parameter for now!
Post Reply