Example #1
0
def test_eig():
    size = 10
    max_nulp = 10 * size**3
    ci = chinfo3
    l = gen_random_legcharge(ci, size)
    A = npc.Array.from_func(np.random.random, [l, l.conj()],
                            qtotal=None,
                            shape_kw='size')
    print("hermitian A")
    A += A.conj().itranspose()
    Aflat = A.to_ndarray()
    W, V = npc.eigh(A, sort='m>')
    V.test_sanity()
    V_W = V.scale_axis(W, axis=-1)
    recalc = npc.tensordot(V_W, V.conj(), axes=[1, 1])
    npt.assert_array_almost_equal_nulp(Aflat, recalc.to_ndarray(), max_nulp)
    Wflat, Vflat = np.linalg.eigh(Aflat)
    npt.assert_array_almost_equal_nulp(np.sort(W), Wflat, max_nulp)
    W2 = npc.eigvalsh(A, sort='m>')
    npt.assert_array_almost_equal_nulp(W, W2, max_nulp)

    print("check complex B")
    B = 1.j * npc.Array.from_func(np.random.random, [l, l.conj()],
                                  shape_kw='size')
    B += B.conj().itranspose()
    B = A + B
    Bflat = B.to_ndarray()
    W, V = npc.eigh(B, sort='m>')
    V.test_sanity()
    recalc = npc.tensordot(V.scale_axis(W, axis=-1), V.conj(), axes=[1, 1])
    npt.assert_array_almost_equal_nulp(Bflat, recalc.to_ndarray(), max_nulp)
    Wflat, Vflat = np.linalg.eigh(Bflat)
    npt.assert_array_almost_equal_nulp(np.sort(W), Wflat, max_nulp)

    print("calculate without 'hermitian' knownledge")
    W, V = npc.eig(B, sort='m>')
    assert (np.max(np.abs(W.imag)) < EPS * max_nulp)
    npt.assert_array_almost_equal_nulp(np.sort(W.real), Wflat, max_nulp)

    print("sparse speigs")
    qi = 1
    ch_sect = B.legs[0].get_charge(qi)
    k = min(3, B.legs[0].slices[qi + 1] - B.legs[0].slices[qi])
    Wsp, Vsp = npc.speigs(B, ch_sect, k=k, which='LM')
    for W_i, V_i in zip(Wsp, Vsp):
        V_i.test_sanity()
        diff = npc.tensordot(B, V_i, axes=1) - V_i * W_i
        assert (npc.norm(diff, np.inf) < EPS * max_nulp)

    print("for trivial charges")
    A = npc.Array.from_func(np.random.random, [lcTr, lcTr.conj()],
                            shape_kw='size')
    A = A + A.conj().itranspose()
    Aflat = A.to_ndarray()
    W, V = npc.eigh(A)
    recalc = npc.tensordot(V.scale_axis(W, axis=-1), V.conj(), axes=[1, 1])
    npt.assert_array_almost_equal_nulp(Aflat, recalc.to_ndarray(),
                                       10 * A.shape[0]**3)
Example #2
0
E = env.full_contraction(L - 1)
print("E =", E)

print("5) calculate two-site hamiltonian ``H2`` from the MPO")
# label left, right physical legs with p, q
W0 = H.get_W(0).replace_labels(['p', 'p*'], ['p0', 'p0*'])
W1 = H.get_W(1).replace_labels(['p', 'p*'], ['p1', 'p1*'])
H2 = npc.tensordot(W0, W1, axes=('wR', 'wL')).itranspose(['wL', 'wR', 'p0', 'p1', 'p0*', 'p1*'])
H2 = H2[H.IdL[0], H.IdR[2]]  # (If H has single-site terms, it's not that simple anymore)
print("H2 labels:", H2.get_leg_labels())

print("6) calculate exp(H2) by diagonalization of H2")
# diagonalization requires to view H2 as a matrix
H2 = H2.combine_legs([('p0', 'p1'), ('p0*', 'p1*')], qconj=[+1, -1])
print("labels after combine_legs:", H2.get_leg_labels())
E2, U2 = npc.eigh(H2)
print("Eigenvalues of H2:", E2)
U_expE2 = U2.scale_axis(np.exp(-1.j * dt * E2), axis=1)  # scale_axis ~= apply a diagonal matrix
exp_H2 = npc.tensordot(U_expE2, U2.conj(), axes=(1, 1))
exp_H2.iset_leg_labels(H2.get_leg_labels())
exp_H2 = exp_H2.split_legs()  # by default split all legs which are `LegPipe`
# (this restores the originial labels ['p0', 'p1', 'p0*', 'p1*'] of `H2` in `exp_H2`)

# alternative way: use :func:`~tenpy.linalg.np_conserved.expm`
exp_H2_alternative = npc.expm(-1.j * dt * H2).split_legs()
assert (npc.norm(exp_H2_alternative - exp_H2) < 1.e-14)

print("7) apply exp(H2) to even/odd bonds of the MPS and truncate with svd")
# (this implements one time step of first order TEBD)
trunc_par = {'svd_min': cutoff, 'trunc_cut': None, 'verbose': 0}
for even_odd in [0, 1]:
Example #3
0
"""Explicit definition of charges and spin-1/2 operators."""

import tenpy.linalg.np_conserved as npc

# consider spin-1/2 with Sz-conservation
chinfo = npc.ChargeInfo([1])  # just a U(1) charge
# charges for up, down state
p_leg = npc.LegCharge.from_qflat(chinfo, [[1], [-1]])
Sz = npc.Array.from_ndarray([[0.5, 0.], [0., -0.5]], [p_leg, p_leg.conj()])
Sp = npc.Array.from_ndarray([[0., 1.], [0., 0.]], [p_leg, p_leg.conj()])
Sm = npc.Array.from_ndarray([[0., 0.], [1., 0.]], [p_leg, p_leg.conj()])

Hxy = 0.5 * (npc.outer(Sp, Sm) + npc.outer(Sm, Sp))
Hz = npc.outer(Sz, Sz)
H = Hxy + Hz
# here, H has 4 legs
H.iset_leg_labels(["s1", "t1", "s2", "t2"])
H = H.combine_legs([["s1", "s2"], ["t1", "t2"]], qconj=[+1, -1])
# here, H has 2 legs
print(H.legs[0].to_qflat().flatten())
# prints [-2  0  0  2]
E, U = npc.eigh(H)  # diagonalize blocks individually
print(E)
# [ 0.25 -0.75  0.25  0.25]