Skip to content

Commit

Permalink
rename tts and tto
Browse files Browse the repository at this point in the history
  • Loading branch information
liwt31 committed Mar 7, 2024
1 parent 2b162f0 commit 699cf5f
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 89 deletions.
1 change: 1 addition & 0 deletions renormalizer/model/op.py
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@ def __repr__(self):
return str(self)

def __add__(self, other):
# if want to add with a scalar, convert the scalar to identity operator first
if isinstance(other, Op):
return OpSum([self, other])
elif isinstance(other, list):
Expand Down
14 changes: 7 additions & 7 deletions renormalizer/tn/gs.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
logger = logging.getLogger(__name__)


def optimize_tts(ttns: TTNS, ttno: TTNO, procedure=None):
def optimize_ttns(ttns: TTNS, ttno: TTNO, procedure=None):
if procedure is None:
procedure = ttns.optimize_config.procedure
tte = TTNEnviron(ttns, ttno)
Expand Down Expand Up @@ -56,21 +56,21 @@ def optimize_recursion(snode: TreeNodeTensor, ttns: TTNS, ttno: TTNO, ttne: TTNE
return micro_e


def optimize_2site(snode: TreeNodeTensor, tts: TTNS, tto: TTNO, tte: TTNEnviron):
def optimize_2site(snode: TreeNodeTensor, ttns: TTNS, ttno: TTNO, ttne: TTNEnviron):

cguess = tts.merge_with_parent(snode)
qn_mask = tts.get_qnmask(snode, include_parent=True)
cguess = ttns.merge_with_parent(snode)
qn_mask = ttns.get_qnmask(snode, include_parent=True)
cguess = cguess[qn_mask].ravel()
expr, hdiag = hop_expr2(snode, tts, tto, tte)
expr, hdiag = hop_expr2(snode, ttns, ttno, ttne)
hdiag = hdiag[qn_mask].ravel()

def hop(x):
cstruct = vec2tensor(x, qn_mask)
ret = expr(asxp(cstruct))[qn_mask].ravel()
return asnumpy(ret)

assert tts.optimize_config.nroots == 1
algo:str = tts.optimize_config.algo
assert ttns.optimize_config.nroots == 1
algo:str = ttns.optimize_config.algo
e, c = eigh_iterative(hop, hdiag, cguess, algo)
c = vec2tensor(c, qn_mask)
return e, c
Expand Down
45 changes: 22 additions & 23 deletions renormalizer/tn/tests/test_evolve.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,18 @@
from renormalizer.utils import EvolveConfig, EvolveMethod, CompressConfig, CompressCriteria


def add_tto_offset(tts: TTNS, tto: TTNO):
# todo: change tts/tto to ttns/ttno
e = tts.expectation(tto)
ham_terms = tto.terms.copy()
ham_terms.append(tts.basis.identity_op * (-e))
return TTNO(tto.basis, ham_terms)
def add_ttno_offset(ttns: TTNS, ttno: TTNO):
e = ttns.expectation(ttno)
ham_terms = ttno.terms.copy()
ham_terms.append(ttns.basis.identity_op * (-e))
return TTNO(ttno.basis, ham_terms)



def construct_ttns_and_ttno_chain():
basis, ttns, ttno = from_mps(init_mps)
op_n_list = [TTNO(basis, [Op(r"a^\dagger a", i)]) for i in range(3)]
ttno = add_tto_offset(ttns, ttno)
ttno = add_ttno_offset(ttns, ttno)
return ttns, ttno, op_n_list


Expand All @@ -44,29 +43,29 @@ def construct_ttns_and_ttno_tree():
ttno = TTNO(basis, model.ham_terms)
op_n_list = [TTNO(basis, [Op(r"a^\dagger a", i)]) for i in range(3)]
ttns = TTNS(basis, {0: 1})
ttno = add_tto_offset(ttns, ttno)
ttno = add_ttno_offset(ttns, ttno)
return ttns, ttno, op_n_list


def construct_tts_and_tto_tree_mctdh():
def construct_ttns_and_ttno_tree_mctdh():
basis = BasisTree.binary_mctdh(model.basis)
op_n_list = [TTNO(basis, [Op(r"a^\dagger a", i)]) for i in range(3)]
ttns = TTNS(basis, {0: 1})
ttno = TTNO(basis, model.ham_terms)
ttno = add_tto_offset(ttns, ttno)
ttno = add_ttno_offset(ttns, ttno)
return ttns, ttno, op_n_list


init_chain = construct_ttns_and_ttno_chain()
init_tree = construct_ttns_and_ttno_tree()
init_tree_mctdh = construct_tts_and_tto_tree_mctdh()
init_tree_mctdh = construct_ttns_and_ttno_tree_mctdh()


def check_result(tts: TTNS, tto: TTNO, time_step: float, final_time: float, op_n_list: List, atol: float=1e-4):
expectations = [[tts.expectation(o) for o in op_n_list]]
def check_result(ttns: TTNS, ttno: TTNO, time_step: float, final_time: float, op_n_list: List, atol: float=1e-4):
expectations = [[ttns.expectation(o) for o in op_n_list]]
for i in range(round(final_time / time_step)):
tts = tts.evolve(tto, time_step)
es = [tts.expectation(o) for o in op_n_list]
ttns = ttns.evolve(ttno, time_step)
es = [ttns.expectation(o) for o in op_n_list]
expectations.append(es)
expectations = np.array(expectations)
qutip_end = round(final_time / QUTIP_STEP) + 1
Expand All @@ -75,7 +74,7 @@ def check_result(tts: TTNS, tto: TTNO, time_step: float, final_time: float, op_n
np.testing.assert_allclose(expectations, qutip_expectations[:qutip_end:qutip_interval], atol=atol)
diff = np.max(np.abs(expectations - qutip_expectations[:qutip_end:qutip_interval]), axis=0)
print(diff)
return tts
return ttns


@pytest.mark.parametrize("ttns_and_ttno", [init_chain, init_tree, init_tree_mctdh])
Expand All @@ -88,13 +87,13 @@ def test_tdvp_vmf(ttns_and_ttno):
check_result(ttns, ttno, 0.5, 2, op_n_list)


@pytest.mark.parametrize("tts_and_tto", [init_chain, init_tree, init_tree_mctdh])
def test_pc(tts_and_tto):
tts, tto, op_n_list = tts_and_tto
tts = tts.copy()
tts.evolve_config = EvolveConfig(EvolveMethod.prop_and_compress_tdrk4)
tts.compress_config = CompressConfig(CompressCriteria.fixed)
check_result(tts, tto, 0.2, 5, op_n_list, 5e-4)
@pytest.mark.parametrize("ttns_and_ttno", [init_chain, init_tree, init_tree_mctdh])
def test_pc(ttns_and_ttno):
ttns, ttno, op_n_list = ttns_and_ttno
ttns = ttns.copy()
ttns.evolve_config = EvolveConfig(EvolveMethod.prop_and_compress_tdrk4)
ttns.compress_config = CompressConfig(CompressCriteria.fixed)
check_result(ttns, ttno, 0.2, 5, op_n_list, 5e-4)


@pytest.mark.parametrize("ttns_and_ttno", [init_chain, init_tree, init_tree_mctdh])
Expand Down
92 changes: 46 additions & 46 deletions renormalizer/tn/tests/test_tn.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from renormalizer.tn.node import TreeNodeBasis
from renormalizer.tn.tree import TTNO, TTNS, TTNEnviron, from_mps
from renormalizer.tn.treebase import BasisTree
from renormalizer.tn.gs import optimize_tts
from renormalizer.tn.gs import optimize_ttns
from renormalizer.tests.parameter import holstein_model
from renormalizer.tests.parameter_exact import model

Expand Down Expand Up @@ -47,29 +47,29 @@ def holstein_scheme3() -> BasisTree:


@pytest.mark.parametrize("basis", [basis_binary, basis_multi_basis])
def test_tto(basis):
def test_ttno(basis):
ham_terms = heisenberg_ops(nspin)

tto = TTNO(basis, ham_terms)
dense = tto.todense(basis_list)
ttno = TTNO(basis, ham_terms)
dense = ttno.todense(basis_list)

dense2 = Mpo(Model(basis_list, ham_terms)).todense()
np.testing.assert_allclose(dense, dense2)


@pytest.mark.parametrize("basis", [basis_binary, basis_multi_basis])
def test_tts(basis):
def test_ttns(basis):
ham_terms = heisenberg_ops(nspin)
condition = {1:1, 3:1}
tts = TTNS(basis, condition)
tto = TTNO(basis, ham_terms)
e1 = tts.expectation(tto)
ttns = TTNS(basis, condition)
ttno = TTNO(basis, ham_terms)
e1 = ttns.expectation(ttno)
model = Model([BasisHalfSpin(i) for i in range(nspin)], ham_terms)
mps = Mps.hartree_product_state(model, condition)
mpo = Mpo(model)
e2 = mps.expectation(mpo)
np.testing.assert_allclose(e1, e2)
env = TTNEnviron(tts, tto)
env = TTNEnviron(ttns, ttno)
for node in env.node_list:
for child, environ_child in zip(node.children, node.environ_children):
e3 = environ_child.ravel() @ child.environ_parent.ravel()
Expand All @@ -78,41 +78,41 @@ def test_tts(basis):

@pytest.mark.parametrize("basis", [basis_binary, basis_multi_basis])
def test_push_cano(basis):
tts = TTNS.random(basis, 0, 5, 1)
s1 = tts.todense()
tts.push_cano_to_child(tts.root, 0)
s2 = tts.todense()
ttns = TTNS.random(basis, 0, 5, 1)
s1 = ttns.todense()
ttns.push_cano_to_child(ttns.root, 0)
s2 = ttns.todense()
np.testing.assert_allclose(s2, s1)
tts.push_cano_to_parent(tts.root.children[0])
s3 = tts.todense()
ttns.push_cano_to_parent(ttns.root.children[0])
s3 = ttns.todense()
np.testing.assert_allclose(s3, s1)


def test_from_mps():
mps = Mps.random(model, 1, 10)
mpo = Mpo(model)
e_ref = mps.expectation(mpo)
basis, tts, tto = from_mps(mps)
e = tts.expectation(tto)
basis, ttns, ttno = from_mps(mps)
e = ttns.expectation(ttno)
np.testing.assert_allclose(e, e_ref)


@pytest.mark.parametrize("basis_tree", [basis_binary, basis_multi_basis])
@pytest.mark.parametrize("ite", [False, True])
def test_gs_heisenberg(basis_tree, ite):
ham_terms = heisenberg_ops(4)
tts = TTNS.random(basis_tree, qntot=0, m_max=20)
tto = TTNO(basis_tree, ham_terms)
ttns = TTNS.random(basis_tree, qntot=0, m_max=20)
ttno = TTNO(basis_tree, ham_terms)
if not ite:
e1 = optimize_tts(tts, tto)
e1 = optimize_ttns(ttns, ttno)
e1 = min(e1)
else:
# imaginary time evolution for the ground state
for i in range(10):
tts.check_canonical()
tts = tts.evolve(tto, -2j)
e1 = tts.expectation(tto)
h = tto.todense()
ttns.check_canonical()
ttns = ttns.evolve(ttno, -2j)
e1 = ttns.expectation(ttno)
h = ttno.todense()
e2 = np.linalg.eigh(h)[0][0]
np.testing.assert_allclose(e1, e2)

Expand All @@ -133,48 +133,48 @@ def test_gs_holstein(scheme):
node_list[2*i].add_child(node_list[2*i+1])
basis = BasisTree(root)
m = 4
tts = TTNS.random(basis, qntot=1, m_max=m)
tto = TTNO(basis, model.ham_terms)
ttns = TTNS.random(basis, qntot=1, m_max=m)
ttno = TTNO(basis, model.ham_terms)
procedure = [[m, 0.4], [m, 0.2], [m, 0.1], [m, 0], [m, 0]]
e1 = optimize_tts(tts, tto, procedure)
e1 = optimize_ttns(ttns, ttno, procedure)
e2 = 0.08401412 + model.gs_zpe
np.testing.assert_allclose(min(e1), e2)


@pytest.mark.parametrize("basis_tree", [basis_binary, basis_multi_basis])
def test_add(basis_tree):
tts1 = TTNS.random(basis_tree, qntot=0, m_max=4)
tts2 = TTNS.random(basis_tree, qntot=0, m_max=2).scale(1j)
tts3 = tts1.add(tts2)
s1 = tts1.todense()
s2 = tts2.todense()
ttns1 = TTNS.random(basis_tree, qntot=0, m_max=4)
ttns2 = TTNS.random(basis_tree, qntot=0, m_max=2).scale(1j)
ttns3 = ttns1.add(ttns2)
s1 = ttns1.todense()
s2 = ttns2.todense()
assert np.iscomplexobj(s2)
s3 = tts3.todense()
s3 = ttns3.todense()
np.testing.assert_allclose(s1 + s2, s3)


@pytest.mark.parametrize("basis_tree", [basis_binary, basis_multi_basis])
def test_apply(basis_tree):
tts1 = TTNS.random(basis_tree, qntot=0, m_max=4)
tto = TTNO(basis_tree, heisenberg_ops(nspin))
tts2 = tto.apply(tts1)
s1 = tts1.todense()
s2 = tts2.todense()
op = tto.todense()
ttns1 = TTNS.random(basis_tree, qntot=0, m_max=4)
ttno = TTNO(basis_tree, heisenberg_ops(nspin))
ttns2 = ttno.apply(ttns1)
s1 = ttns1.todense()
s2 = ttns2.todense()
op = ttno.todense()
np.testing.assert_allclose(s2.ravel(), op @ s1.ravel())


def test_compress():
m1 = 5
m2 = 4
basis = holstein_scheme3()
tto = TTNO(basis, holstein_model.ham_terms)
tts = TTNS.random(basis, 1, m1)
ttno = TTNO(basis, holstein_model.ham_terms)
ttns = TTNS.random(basis, 1, m1)
procedure1, procedure2 = [[[m, 0.4], [m, 0.2], [m, 0.1], [m, 0], [m, 0]] for m in [m1, m2]]
optimize_tts(tts, tto, procedure1)
tts2 = tts.copy().compress(m2)
optimize_tts(tts, tto, procedure2)
s1 = tts.todense().ravel()
s2 = tts2.todense().ravel()
optimize_ttns(ttns, ttno, procedure1)
ttns2 = ttns.copy().compress(m2)
optimize_ttns(ttns, ttno, procedure2)
s1 = ttns.todense().ravel()
s2 = ttns2.todense().ravel()

np.testing.assert_allclose(np.abs(s1 @ s2), 1, atol=1e-5)
22 changes: 11 additions & 11 deletions renormalizer/tn/time_evolution.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,19 +75,19 @@ def regularized_inversion(m, eps):
return evecs @ np.diag(1 / evals) @ evecs.T.conj()


def evolve_tdvp_vmf(tts:TTNS, tto:TTNO, coeff:Union[complex, float], tau:float, first_step=None):
def evolve_tdvp_vmf(ttns:TTNS, ttno:TTNO, coeff:Union[complex, float], tau:float, first_step=None):

def ivp_func(t, params):
tts_t = TTNS.from_tensors(tts, params)
return coeff * time_derivative_vmf(tts_t, tto)
init_y = np.concatenate([node.tensor[tts.get_qnmask(node)].ravel() for node in tts.node_list])
atol = tts.evolve_config.ivp_atol
rtol = tts.evolve_config.ivp_rtol
ttns_t = TTNS.from_tensors(ttns, params)
return coeff * time_derivative_vmf(ttns_t, ttno)
init_y = np.concatenate([node.tensor[ttns.get_qnmask(node)].ravel() for node in ttns.node_list])
atol = ttns.evolve_config.ivp_atol
rtol = ttns.evolve_config.ivp_rtol
sol = solve_ivp(ivp_func, (0, tau), init_y, first_step=first_step, atol=atol, rtol=rtol)
logger.info(f"VMF func called: {sol.nfev}. RKF steps: {len(sol.t)}")
new_tts = TTNS.from_tensors(tts, sol.y[:, -1])
new_tts.canonicalise()
return new_tts
new_ttns = TTNS.from_tensors(ttns, sol.y[:, -1])
new_ttns.canonicalise()
return new_ttns


def evolve_prop_and_compress_tdrk4(ttns:TTNS, ttno:TTNO, coeff:Union[complex, float], tau:float):
Expand Down Expand Up @@ -294,7 +294,7 @@ def _tdvp_ps2_recursion_forward(snode: TreeNodeTensor,
coeff:Union[complex, float],
tau:float) -> List[int]:
"""time evolution all of snode's children (without evolve snode!).
The exception is when snode == tts.root, which is evolved.
The exception is when snode == ttns.root, which is evolved.
Cano center at snode when entering and leaving"""
assert snode.children # 2 site can't do only one node
# todo: update to more general cases like truncation based on singular values
Expand Down Expand Up @@ -336,7 +336,7 @@ def _tdvp_ps2_recursion_backward(snode: TreeNodeTensor,
coeff:Union[complex, float],
tau:float) -> List[int]:
"""time evolution all of snode's children (without evolve snode!).
The exception is when snode == tts.root, which is evolved.
The exception is when snode == ttns.root, which is evolved.
Cano center at snode when entering and leaving"""
assert snode.children # 2 site can't do only one node
# todo: update to more general cases like truncation based on singular values
Expand Down
Loading

0 comments on commit 699cf5f

Please sign in to comment.