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)
def test_XXZChain(): pars = dict(L=4, Jxx=1., Jz=1., hz=0., bc_MPS='finite') chain = XXZChain(pars) chain.test_sanity() for Hb in chain.H_bond[1:]: # check bond eigenvalues Hb2 = Hb.combine_legs([['p0', 'p1'], ['p0*', 'p1*']], qconj=[+1, -1]) print(Hb2.to_ndarray()) W = npc.eigvalsh(Hb2) npt.assert_array_almost_equal_nulp(np.sort(W), np.sort([-0.75, 0.25, 0.25, 0.25]), 16**3) # now check with non-trivial onsite terms pars['hz'] = 0.2 print("hz =", pars['hz']) chain = XXZChain(pars) chain.test_sanity() Hb = chain.H_bond[ 2] # the only central bonds: boundaries have different hz. Hb2 = Hb.combine_legs([['p0', 'p1'], ['p0*', 'p1*']], qconj=[+1, -1]) print(Hb2.to_ndarray()) W = npc.eigvalsh(Hb2) print(W) npt.assert_array_almost_equal_nulp( np.sort(W), np.sort([ -0.75, 0.25 - 2 * 0.5 * 0.5 * pars['hz'], 0.25, 0.25 + 2. * 0.5 * 0.5 * pars['hz'] ]), 16**3) pars['bc_MPS'] = 'infinite' for L in [2, 3, 4, 5, 6]: print("L =", L) pars['L'] = L chain = XXZChain(pars) pprint.pprint(chain.coupling_terms) assert len(chain.H_bond) == L Hb0 = chain.H_bond[0] for Hb in chain.H_bond[1:]: assert (npc.norm(Hb - Hb0, np.inf) == 0.) # exactly equal pars['Jxx'] = 0. chain = XXZChain(pars) chain.test_sanity()