Comparing Wave Functions with Different Charge Infos

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

Comparing Wave Functions with Different Charge Infos

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!
Johannes
Site Admin
Posts: 357
Joined: 21 Jul 2018, 12:52
Location: TU Munich

Re: Comparing Wave Functions with Different Charge Infos

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!