Page 1 of 1
Comparing Wave Functions with Different Charge Infos
Posted: 03 Nov 2022, 20:09
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!
Re: Comparing Wave Functions with Different Charge Infos
Posted: 04 Nov 2022, 15:03
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!