def test_drop_add_change_charge(): chinfo14 = npc.ChargeInfo([1, 4], ['U1', 'Z4']) chinfo41 = npc.ChargeInfo([4, 1], ['Z4', 'U1']) chinfo1 = npc.ChargeInfo([1], ['U1']) chinfo4 = npc.ChargeInfo([4], ['Z4']) chinfo12 = npc.ChargeInfo([1, 2], ['U1', 'Z2']) for shape in [(50, ), (10, 4), (1, 1, 2)]: A14 = random_Array(shape, chinfo14) A14_flat = A14.to_ndarray() A = A14.drop_charge() A.test_sanity() npt.assert_equal(A.to_ndarray(), A14_flat) assert A.chinfo == chinfoTr A1 = A14.drop_charge(1) A1.test_sanity() npt.assert_equal(A1.to_ndarray(), A14_flat) assert A1.chinfo == chinfo1 A4 = A14.drop_charge('U1', chinfo4) npt.assert_equal(A4.to_ndarray(), A14_flat) assert A4.chinfo is chinfo4 A12 = A14.change_charge('Z4', 2, 'Z2', chinfo12) A12.test_sanity() npt.assert_equal(A4.to_ndarray(), A14_flat) assert A12.chinfo is chinfo12 A14_new = A1.add_charge(A4.legs, qtotal=A4.qtotal) A14_new.test_sanity() npt.assert_equal(A14_new.to_ndarray(), A14_flat) assert A14_new.chinfo == chinfo14 A41_new = A4.add_charge(A1.legs, chinfo41, qtotal=A1.qtotal) A41_new.test_sanity() npt.assert_equal(A41_new.to_ndarray(), A14_flat) assert A41_new.chinfo is chinfo41
def test_site(): chinfo = npc.ChargeInfo([1, 3]) leg = gen_random_legcharge(chinfo, 8) op1 = npc.Array.from_func(np.random.random, [leg, leg.conj()], shape_kw='size') op2 = npc.Array.from_func(np.random.random, [leg, leg.conj()], shape_kw='size') labels = ['up'] + [None] * (leg.ind_len - 2) + ['down'] s = site.Site(leg, labels, silly_op=op1) assert s.state_index('up') == 0 assert s.state_index('down') == leg.ind_len - 1 assert s.opnames == set(['silly_op', 'Id', 'JW']) assert s.silly_op is op1 s.add_op('op2', op2) assert s.op2 is op2 assert s.get_op('op2') is op2 assert s.get_op('silly_op') is op1 npt.assert_equal( s.get_op('silly_op op2').to_ndarray(), npc.tensordot(op1, op2, [1, 0]).to_ndarray()) leg2 = npc.LegCharge.from_drop_charge(leg, 1) leg2 = npc.LegCharge.from_change_charge(leg2, 0, 2, 'changed') s2 = copy.deepcopy(s) s2.change_charge(leg2) perm_qind, leg2s = leg2.sort() perm_flat = leg2.perm_flat_from_perm_qind(perm_qind) s2s = copy.deepcopy(s2) s2s.change_charge(leg2s, perm_flat) for site_check in [s2, s2s]: print("site_check.leg = ", site_check.leg) for opn in site_check.opnames: op1 = s.get_op(opn).to_ndarray() op2 = site_check.get_op(opn).to_ndarray() perm = site_check.perm npt.assert_equal(op1[np.ix_(perm, perm)], op2)
def test_lattice(): chinfo = npc.ChargeInfo([1, 3]) leg = gen_random_legcharge(chinfo, 8) leg2 = gen_random_legcharge(chinfo, 2) op1 = npc.Array.from_func(np.random.random, [leg, leg.conj()], shape_kw='size') op2 = npc.Array.from_func(np.random.random, [leg2, leg2.conj()], shape_kw='size') site1 = lattice.Site(leg, [('up', 0), ('down', -1)], op1=op1) site2 = lattice.Site(leg2, [('down', 0), ('up', -1)], op2=op2) for order in ['default', 'Fstyle', 'snake', 'snakeFstyle']: print("order =", order) Ls = [5, 2] basis = [[1., 1.], [0., 1.]] pos = [[0.1, 0.], [0.2, 0.]] lat = lattice.Lattice(Ls, [site1, site2], order=order, basis=basis, positions=pos, bc='periodic', bc_MPS='infinite') assert lat.dim == len(Ls) assert lat.N_sites == np.prod(Ls) * 2 for i in range(lat.N_sites): assert lat.lat2mps_idx(lat.mps2lat_idx(i)) == i idx = [4, 1, 0] assert np.all(lat.mps2lat_idx(lat.lat2mps_idx(idx)) == idx) # index conversion should also work for arbitrary index arrays and indices outside bc_MPS # for bc_MPS=infinite i = np.arange(-3, lat.N_sites * 2 - 3).reshape((-1, 2)) assert np.all(lat.lat2mps_idx(lat.mps2lat_idx(i)) == i) # test position npt.assert_equal([4.1, 5.], lat.position(idx)) # test lat.mps2lat_values A = np.random.random([lat.N_sites, 2, lat.N_sites]) print(A.shape) Ares = lat.mps2lat_values(A, axes=[-1, 0]) Ares_ma = lat.mps2lat_values_masked(A, [-1, 0], [None] * 2, [None] * 2) for i in range(lat.N_sites): idx_i = lat.mps2lat_idx(i) for j in range(lat.N_sites): idx_j = lat.mps2lat_idx(j) for k in range(2): idx = tuple(idx_i) + (k, ) + tuple(idx_j) assert Ares[idx] == A[i, k, j] assert Ares_ma[idx] == A[i, k, j] # and again for fixed `u` within the unit cell for u in range(len(lat.unit_cell)): mps_u = lat.mps_idx_fix_u(u) A_u = A[np.ix_(mps_u, np.arange(2), mps_u)] A_u_res = lat.mps2lat_values(A_u, axes=[-1, 0], u=u) A_u_res_masked = lat.mps2lat_values_masked(A_u, axes=[-1, 0], mps_inds=[mps_u] * 2, include_u=[False] * 2) A_u_expected = Ares[:, :, u, :, :, :, u] npt.assert_equal(A_u_res, A_u_expected) npt.assert_equal(A_u_res_masked, A_u_expected)
def setup_npc(mod_q=[1], n_qsectors=3, size=20, leg_a_out=2, leg_b_out=2, leg_contract=2, select_frac=1., dtype=np.float, seed=123): """Returns ``a, b, axes`` for timing of ``npc.tensordot(a, b, axes)`` Constructed such that leg_contract legs are contracted, with a.rank = leg_a_out + leg_contract b.rank = leg_b_out + leg_contract If `select_frac` < 1, select only the given fraction of blocks compared to what is possible by charge requirements. """ chinfo = npc.ChargeInfo(mod_q) np.random.seed(seed) legs_contr = [ gen_random_legcharge_nq(chinfo, size, n_qsectors) for i in range(leg_contract) ] legs_a = legs_contr + \ [gen_random_legcharge_nq(chinfo, size, n_qsectors) for i in range(leg_a_out)] legs_b = [l.conj() for l in legs_contr] + \ [gen_random_legcharge_nq(chinfo, size, n_qsectors) for i in range(leg_b_out)] a = npc.Array.from_func(np.random.random, legs_a, dtype, shape_kw='size') b = npc.Array.from_func(np.random.random, legs_b, dtype, shape_kw='size') a.ipurge_zeros() b.ipurge_zeros() if chinfo.qnumber > 0 and select_frac < 1.: a_bl = a.stored_blocks if a_bl > 0: a_subset = rand_distinct_int(0, a_bl - 1, max(int(a_bl * select_frac), 1)) a._qdata = a._qdata[a_subset, :] a._data = [a._data[i] for i in a_subset] b_bl = a.stored_blocks if b_bl > 0: b_subset = rand_distinct_int(0, b_bl - 1, max(int(b_bl * select_frac), 1)) b._qdata = b._qdata[b_subset, :] b._data = [b._data[i] for i in b_subset] labs = [ "l{i:d}".format(i=i) for i in range(max(leg_a_out, leg_b_out) + leg_contract) ] a.iset_leg_labels(labs[:a.rank]) b.iset_leg_labels(labs[:b.rank]) a.itranspose(rand_permutation(a.rank)) b.itranspose(rand_permutation(b.rank)) axes = [labs[:leg_contract]] * 2 return a, b, axes
def test_lattice(): chinfo = npc.ChargeInfo([1, 3]) leg = gen_random_legcharge(chinfo, 8) leg2 = gen_random_legcharge(chinfo, 2) op1 = npc.Array.from_func(np.random.random, [leg, leg.conj()], shape_kw='size') op2 = npc.Array.from_func(np.random.random, [leg2, leg2.conj()], shape_kw='size') site1 = lattice.Site(leg, [('up', 0), ('down', -1)], op1=op1) site2 = lattice.Site(leg2, [('down', 0), ('up', -1)], op2=op2) for order in ['default', 'Fstyle', 'snake', 'snakeFstyle']: print("order =", order) Ls = [5, 2] basis = [[1., 1.], [0., 1.]] pos = [[0.1, 0.], [0.2, 0.]] lat = lattice.Lattice(Ls, [site1, site2], order=order, basis=basis, positions=pos) nst.eq_(lat.dim, len(Ls)) nst.eq_(lat.N_sites, np.prod(Ls) * 2) for i in range(lat.N_sites): nst.eq_(lat.lat2mps_idx(lat.mps2lat_idx(i)), i) idx = (4, 1, 0) nst.eq_(lat.mps2lat_idx(lat.lat2mps_idx(idx)), idx) npt.assert_equal([4.1, 5.], lat.position(idx)) # test lat.mps2lat_values A = np.random.random([lat.N_sites, 2, lat.N_sites]) print(A.shape) Ares = lat.mps2lat_values(A, axes=[-1, 0]) for i in range(lat.N_sites): idx_i = lat.mps2lat_idx(i) for j in range(lat.N_sites): idx_j = lat.mps2lat_idx(j) for k in range(2): idx = idx_i + (k, ) + idx_j nst.eq_(Ares[idx], A[i, k, j]) # and again for fixed `u` within the unit cell for u in range(len(lat.unit_cell)): A_u = A[np.ix_(lat.mps_idx_fix_u(u), np.arange(2), lat.mps_idx_fix_u(u))] A_u_res = lat.mps2lat_values(A_u, axes=[-1, 0], u=u) npt.assert_equal(A_u_res, Ares[:, :, u, :, :, :, u])
def test_npc_tensordot_extra(): # check that the sorting of charges is fine with special test matrices # which gave me some headaches at some point :/ chinfo = npc.ChargeInfo([1], ['Sz']) leg = npc.LegCharge.from_qflat(chinfo, [-1, 1]) legs = [leg, leg, leg.conj(), leg.conj()] idx = [(0, 0, 0, 0), (0, 1, 0, 1), (0, 1, 1, 0), (1, 0, 0, 1), (1, 0, 1, 0), (1, 1, 1, 1)] Uflat = np.eye(4).reshape([2, 2, 2, 2]) # up to numerical rubbish the identity Uflat[0, 1, 1, 0] = Uflat[1, 0, 0, 1] = 1.e-20 U = npc.Array.from_ndarray(Uflat, legs, cutoff=0.) theta_flat = np.zeros([2, 2, 2, 2]) vals = np.random.random(len(idx)) vals /= np.linalg.norm(vals) for i, val in zip(idx, vals): theta_flat[i] = val theta = npc.Array.from_ndarray(theta_flat, [leg, leg, leg.conj(), leg.conj()], cutoff=0.) assert abs(np.linalg.norm(theta_flat) - npc.norm(theta)) < 1.e-14 Utheta_flat = np.tensordot(Uflat, theta_flat, axes=2) Utheta = npc.tensordot(U, theta, axes=2) npt.assert_array_almost_equal_nulp(Utheta.to_ndarray(), Utheta_flat, 10) assert abs(np.linalg.norm(theta_flat) - npc.norm(Utheta)) < 1.e-10
def convert_array(self, h5gr_orig, subpath_orig, h5gr_new, subpath_new): # copy (hardlinks avoid copies) h5gr_new["dtype"] = h5gr_orig["dtype"] h5gr_new["blocks"] = h5gr_orig["blocks"] total_charge = self.get_attr(h5gr_orig, "total_charge") self.save(total_charge, subpath_new + "total_charge") block_inds = np.asarray(self.load(subpath_orig + "block_inds"), np.intp) self.save(block_inds, subpath_new + "block_inds") h5gr_new.attrs["block_inds_sorted"] = h5gr_orig.attrs[ "block_inds_sorted"] h5gr_new.attrs["rank"] = rank = self.get_attr(h5gr_orig, "rank") h5gr_new.attrs["shape"] = self.get_attr(h5gr_orig, "shape") # convert charges num_q = self.get_attr(h5gr_orig, "num_charges") mod_q = self.get_attr(h5gr_orig, "U1_ZN") leg_charges = self.load(subpath_orig + "leg_charges") qconj = self.get_attr(h5gr_orig, "qconj") # ChargeInfo chinfo = npc.ChargeInfo(mod_q) # no names available assert chinfo.qnumber == num_q # legs: convert leg_charges, qconj into list of LegCharge instances legs_new = [] for q_ind, q_conj in zip(leg_charges, qconj): slices = np.concatenate((q_ind[:, 0], [q_ind[-1, 1]])) charges = q_ind[:, 2:] leg = npc.LegCharge(chinfo, slices, charges, q_conj) legs_new.append(leg) self.save(chinfo, subpath_new + "chinfo") self.save(legs_new, subpath_new + "legs") labels = self.load(subpath_orig + "labels") # convert {str: int} -> [str] labels_new = [None] * rank if labels is not None: for k, v in labels.items(): labels_new[v] = k self.save(labels_new, subpath_new + "labels")
"""A collection of tests for tenpy.linalg.lanczos.""" # Copyright 2018-2019 TeNPy Developers, GNU GPLv3 import tenpy.linalg.np_conserved as npc import numpy as np from random_test import gen_random_legcharge from tenpy.linalg import lanczos, sparse import tenpy.linalg.random_matrix as rmat from scipy.linalg import expm import pytest ch = npc.ChargeInfo([2]) def test_gramschmidt(n=30, k=5, tol=1.e-15): leg = gen_random_legcharge(ch, n) vecs_old = [ npc.Array.from_func(np.random.random, [leg], shape_kw='size') for i in range(k) ] vecs_new, _ = lanczos.gram_schmidt(vecs_old, rcond=0., verbose=1) assert all([v == w for v, w in zip(vecs_new, vecs_old)]) vecs_new, _ = lanczos.gram_schmidt(vecs_old, rcond=tol, verbose=1) vecs = [v.to_ndarray() for v in vecs_new] ovs = np.zeros((k, k)) for i, v in enumerate(vecs): for j, w in enumerate(vecs): ovs[i, j] = np.inner(v.conj(), w) print(ovs) assert (np.linalg.norm(ovs - np.eye(k)) < 2 * n * k * k * tol)
"""A collection of tests for tenpy.linalg.np_conserved.""" # Copyright 2018-2021 TeNPy Developers, GNU GPLv3 import tenpy.linalg.np_conserved as npc import numpy as np import numpy.testing as npt import itertools as it from tenpy.tools.misc import inverse_permutation import warnings import pytest from random_test import gen_random_legcharge, random_Array chinfo = npc.ChargeInfo([1, 2], ['number', 'parity']) # parity can be derived from number. Yet, this should all work... qflat = np.array([[0, 0], [1, 1], [2, 0], [-2, 0], [1, 1]]) lc = npc.LegCharge.from_qflat(chinfo, qflat) arr = np.zeros((5, 5)) arr[0, 0] = 1. arr[1, 1] = arr[4, 1] = arr[1, 4] = 2. arr[2, 2] = 3. # don't fill all sectors compatible with charges: [3, 3] and [4, 4] are empty # arr[3, 3] = 4. qflat_add = qflat + np.array([[1, 0]]) # for checking non-zero total charge lc_add = npc.LegCharge.from_qflat(chinfo, qflat_add) chinfo2 = npc.ChargeInfo([1, 3, 1, 2]) # more charges for better testing chinfo3 = npc.ChargeInfo( [3]) # for larger blocks with random arrays of the same shape chinfoTr = npc.ChargeInfo() # trivial charge
Jxx, Jz = 1., 1. L = 20 dt = 0.1 cutoff = 1.e-10 print("Jxx={Jxx}, Jz={Jz}, L={L:d}".format(Jxx=Jxx, Jz=Jz, L=L)) print("1) create Arrays for an Neel MPS") # vL ->--B-->- vR # | # ^ # | # p # create a ChargeInfo to specify the nature of the charge chinfo = npc.ChargeInfo( [1], ['2*Sz']) # the second argument is just a descriptive name # create LegCharges on physical leg and even/odd bonds p_leg = npc.LegCharge.from_qflat(chinfo, [[1], [-1]]) # charges for up, down v_leg_even = npc.LegCharge.from_qflat(chinfo, [[0]]) v_leg_odd = npc.LegCharge.from_qflat(chinfo, [[1]]) B_even = npc.zeros([v_leg_even, v_leg_odd.conj(), p_leg]) B_odd = npc.zeros([v_leg_odd, v_leg_even.conj(), p_leg]) B_even[0, 0, 0] = 1. # up B_odd[0, 0, 1] = 1. # down for B in [B_even, B_odd]: B.iset_leg_labels(['vL', 'vR', 'p']) # virtual left/right, physical Bs = [B_even, B_odd] * (L // 2) + [B_even] * (L % 2) # (right-canonical)
"""A collection of tests for :module:`tenpy.linalg.random_matrix`.""" # Copyright 2018-2020 TeNPy Developers, GNU GPLv3 import numpy as np import numpy.testing as npt import tenpy.linalg.random_matrix as rmat import tenpy.linalg.np_conserved as npc chinfo = npc.ChargeInfo([1], ['testcharge']) _, leg = npc.LegCharge.from_qflat(chinfo, np.array([0, 1, 1, 2, 2, 2, 3, 4, 4])).bunch() np.random.seed(123) EPS = 1.e-14 def test_random_matrix_standard_normal_complex(): for size in [1, 3, 4]: a = rmat.standard_normal_complex((size, size)) assert (a.dtype == np.complex) print(a) b = npc.Array.from_func_square(rmat.standard_normal_complex, leg) b.test_sanity() print("b =", b) assert (b.dtype == np.complex) def test_random_matrix_GOE(): for size in [1, 3, 4]: a = rmat.GOE((size, size)) assert (a.dtype == np.float)
import tenpy import tenpy.linalg.np_conserved as npc import tenpy.algorithms.network_contractor as nc import numpy as np Triv = npc.ChargeInfo([]) U1 = npc.ChargeInfo([1]) Z2 = npc.ChargeInfo([2]) def createLegCharge(charge, dims): if isinstance(dims, int): return npc.LegCharge.from_trivial(dims) else: charges = [[d[0]] for d in dims] slices = np.append([0], np.cumsum([d[1] for d in dims])) return npc.LegCharge.from_qind(charge, slices, charges) TeNPyTensor = npc.Array.from_func def mpo_timer(Vmps, Vphys, Vmpo, f=np.random.standard_normal, dtype=np.float64): Vmpsc = Vmps.conj() Vphysc = Vphys.conj() Vmpoc = Vmpo.conj() #
"""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]