示例#1
0
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
示例#2
0
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)
示例#3
0
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)
示例#4
0
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
示例#5
0
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])
示例#6
0
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")
示例#8
0
"""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)
示例#9
0
"""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
示例#10
0
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)
示例#12
0
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()
    #
示例#13
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]