Skip to content

Commit

Permalink
maintenance work on cv and mpo (#94)
Browse files Browse the repository at this point in the history
* maintenance work on cv and mpo

* update doc

* enhance hartree_product_states

* bugfix and optimization for finite T cv

Co-authored-by: jjren <jjren@thinkpad>
Co-authored-by: weitang li <liwt31@163.com>
Co-authored-by: jiangtong1000 <tongjiang1000@gmail.com>
  • Loading branch information
4 people authored Jun 28, 2020
1 parent db176c6 commit 54cf9c1
Show file tree
Hide file tree
Showing 36 changed files with 2,053 additions and 1,102 deletions.
489 changes: 425 additions & 64 deletions example/1D-Heisenberg.ipynb

Large diffs are not rendered by default.

File renamed without changes.
192 changes: 4 additions & 188 deletions example/h2o_qc.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from renormalizer.mps import Mps, Mpo, solver
from renormalizer.model import MolList2, ModelTranslator
from renormalizer.model import MolList2, ModelTranslator, h_qc
from renormalizer.utils import basis as ba
from renormalizer.utils import Op
from renormalizer.utils import log
Expand All @@ -18,190 +18,6 @@
H -0.7499151 0.0000000 0.5114913,
'''

def read_fcidump(fname, norb):
eri = np.zeros((norb, norb, norb, norb))
h = np.zeros((norb,norb))

with open(fname, "r") as f:
a = f.readlines()
for line, info in enumerate(a):
if line < 4:
continue
s = info.split()
integral, p, q, r, s = float(s[0]),int(s[1]),int(s[2]),int(s[3]),int(s[4])
if r != 0:
eri[p-1,q-1,r-1,s-1] = integral
eri[q-1,p-1,r-1,s-1] = integral
eri[p-1,q-1,s-1,r-1] = integral
eri[q-1,p-1,s-1,r-1] = integral
elif p != 0:
h[p-1,q-1] = integral
h[q-1,p-1] = integral
else:
nuc = integral

nsorb = norb*2
seri = np.zeros((nsorb, nsorb, nsorb, nsorb))
sh = np.zeros((nsorb,nsorb))
for p, q, r, s in itertools.product(range(nsorb),repeat=4):
# a_p^\dagger a_q^\dagger a_r a_s
if p % 2 == s % 2 and q % 2 == r % 2:
seri[p,q,r,s] = eri[p//2,s//2,q//2,r//2]

for q, s in itertools.product(range(nsorb),repeat=2):
if q % 2 == s % 2:
sh[q,s] = h[q//2,s//2]

aseri = np.zeros((nsorb, nsorb, nsorb, nsorb))
for q, s in itertools.product(range(nsorb),repeat=2):
for p, r in itertools.product(range(q), range(s)):
#aseri[p,q,r,s] = seri[p,q,r,s] - seri[q,p,r,s]
aseri[p,q,r,s] = seri[p,q,r,s] - seri[p,q,s,r]

logger.info(f"nuclear repulsion: {nuc}")

return sh, aseri, nuc


def qc_model(h1e, h2e):
#------------------------------------------------------------------------
# Jordan-Wigner transformation maps fermion problem into spin problem
#
# |0> => |alpha> and |1> => |beta >:
#
# a_j^+ => Prod_{l=1}^{j-1}(sigma_z[l]) * sigma_-[j]
# a_j => Prod_{l=1}^{j-1}(sigma_z[l]) * sigma_+[j]
#------------------------------------------------------------------------

norbs = h1e.shape[0]
logger.info(f"spin norbs: {norbs}")
assert np.all(np.array(h1e.shape) == norbs)
assert np.all(np.array(h2e.shape) == norbs)

model = defaultdict(list)

# sigma_-, sigma_+, sigma_z
# one electron
for idxs in itertools.product(range(norbs),repeat = 2):
sort = np.argsort(idxs)

key = tuple()
op = tuple()
line1 = []
line2 = []
for idx in range(idxs[sort[0]],idxs[sort[1]]+1):
key += (f"e_{idx}",)
if idx == idxs[0]:
line1.append(("sigma_-",1))
elif idx < idxs[0]:
line1.append(("sigma_z",0))
else:
line1.append(("",0))

if idx == idxs[1]:
line2.append(("sigma_+",-1))
elif idx < idxs[1]:
line2.append(("sigma_z",0))
else:
line2.append(("",0))

npermute = 0
for term1, term2 in zip(line1, line2):
ops = list(filter(lambda a: a != "", [term1[0],term2[0]]))

sz_idx = [i for i,j in enumerate(ops) if j == "sigma_z"]
for index, i in enumerate(sz_idx):
npermute += i - len(sz_idx[:index])
ops = list(filter(lambda a: a != "sigma_z", ops))

ops = " ".join(ops)
if len(sz_idx) % 2 == 1:
ops = ("sigma_z " + ops).strip()

if ops == "":
ops = "I"

op += (Op(ops, term1[1]+term2[1]),)

#print(idxs)
#print(key)
#print(op)
op += (h1e[idxs[0], idxs[1]]*(-1)**(npermute%2),)
model[key].append(op)

#2e term
for q,s in itertools.product(range(norbs),repeat = 2):
# a^\dagger_p a^\dagger_q a_r a_s
for p,r in itertools.product(range(q),range(s)):
idxs = [p,q,r,s]
sort = np.argsort(idxs)

key = tuple()
op = tuple()
line1 = []
line2 = []
line3 = []
line4 = []

for idx in range(idxs[sort[0]],idxs[sort[3]]+1):
key += (f"e_{idx}",)
if idx == p:
line1.append(("sigma_-",1))
elif idx < p:
line1.append(("sigma_z",0))
else:
line1.append(("",0))

if idx == q:
line2.append(("sigma_-",1))
elif idx < q:
line2.append(("sigma_z",0))
else:
line2.append(("",0))

if idx == r:
line3.append(("sigma_+",-1))
elif idx < r:
line3.append(("sigma_z",0))
else:
line3.append(("",0))

if idx == s:
line4.append(("sigma_+",-1))
elif idx < s:
line4.append(("sigma_z",0))
else:
line4.append(("",0))


npermute = 0
for term1, term2, term3, term4 in zip(line1, line2, line3, line4):
ops = [op for op in [term1[0],term2[0],term3[0],term4[0]] if op != ""]
sz_idx = [i for i,j in enumerate(ops) if j == "sigma_z"]
#for index, i in enumerate(sz_idx):
# npermute += i - len(sz_idx[:index])
nn = len(sz_idx)
npermute += sum(sz_idx) - int((nn-1)*nn/2)
ops = [op for op in ops if op != "sigma_z"]

ops = " ".join(ops)
if nn % 2 == 1:
ops = ("sigma_z " + ops).strip()

if ops == "":
ops = "I"
op += (Op(ops, term1[1]+term2[1]+term3[1]+term4[1]),)

#print(p,q,r,s)
#print(key)
#print(op,(-1)**(npermute%2), npermute)
op += (h2e[p,q,r,s]*(-1)**(npermute%2),)
model[key].append(op)

return model



start = time.time()
dump_dir = "./"
job_name = "qc" #########
Expand All @@ -210,15 +26,15 @@ def qc_model(h1e, h2e):

spatial_norbs = 7
spin_norbs = spatial_norbs * 2
h1e, h2e, nuc = read_fcidump("h2o_fcidump.out", spatial_norbs)
h1e, h2e, nuc = h_qc.read_fcidump("h2o_fcidump.txt", spatial_norbs)

# a randon integral
#h1e = np.random.uniform(-1,1,size=(spin_norbs,spin_norbs))
#h2e = np.random.uniform(-1,1,size=(spin_norbs,spin_norbs,spin_norbs,spin_norbs))
#h1e = 0.5*(h1e+h1e.T)
#h2e = 0.5*(h2e+h2e.transpose((2,3,0,1)))

model = qc_model(h1e, h2e)
model = h_qc.qc_model(h1e, h2e)

order = {}
basis = []
Expand All @@ -239,7 +55,7 @@ def qc_model(h1e, h2e):
mps.optimize_config.procedure = procedure
mps.optimize_config.method = "2site"
energies = solver.optimize_mps_dmrg(mps.copy(), mpo)
gs_e = energies.min()+nuc
gs_e = min(energies)+nuc
logger.info(f"lowest energy: {gs_e}")
# fci result
assert np.allclose(gs_e, -75.008697516450)
Expand Down
2 changes: 1 addition & 1 deletion example/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ for python_args in fmo.py sbm.py h2o_qc.py "transport.py std.yaml" "transport_au
fi
done

exit $code
exit $code
2 changes: 1 addition & 1 deletion renormalizer/cv/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# -*- coding: utf-8 -*-

#from renormalizer.cv.zerot import SpectraZtCV
from renormalizer.cv.spectra_cv import batch_run
Loading

0 comments on commit 54cf9c1

Please sign in to comment.