def random_prod_state_tenpy(L, a_model): product_state = [] #the numpy mps used to compare psi_compare = [] sz = 2. * np.random.randint(0, 2, size=L) - 1.0 for i in range(L): psi_compare.append(np.zeros((2, 1, 1))) if sz[i] > 0: product_state += ["up"] psi_compare[-1][0, 0, 0] = 1 else: product_state += ["down"] psi_compare[-1][1, 0, 0] = 1 psi = MPS.from_product_state(a_model.lat.mps_sites(), product_state, bc=a_model.lat.bc_MPS, form='B') psi_converted = [] for i in range(L): site = psi.sites[i] perm = site.perm B_tmp = psi.get_B(i).transpose(['p', 'vL', 'vR']).to_ndarray() B = B_tmp[inverse_permutation(perm), :, :] B = B[::-1, :, :] psi_converted.append(B) return psi
def get_site_op_flat(site, op): """Like ``site.get_op(op)``, but return a flat numpy array and revert permutation from charges. site.perm should store the permutation compared to "conserve=None", so we can use that to convert to the "standard" flat form with conserve=None. """ op = site.get_op(op).to_ndarray() iperm = inverse_permutation(site.perm) return op[np.ix_(iperm, iperm)]
def test_npc_svd(): for m, n in [(1, 1), (1, 10), (10, 1), (10, 10), (10, 20)]: print("m, n = ", m, n) tol_NULP = max(20 * max(m, n)**3, 1000) for i in range(1000): A = random_Array((m, n), chinfo3, sort=True) if A.stored_blocks > 0: break Aflat = A.to_ndarray() Sonly = npc.svd(A, compute_uv=False) U, S, VH = npc.svd(A, full_matrices=False, compute_uv=True) assert (U.shape[1] == S.shape[0] == VH.shape[0]) U.test_sanity() VH.test_sanity() npt.assert_array_almost_equal_nulp(Sonly, S, tol_NULP) recalc = npc.tensordot(U.scale_axis(S, axis=-1), VH, axes=1) npt.assert_array_almost_equal_nulp(recalc.to_ndarray(), Aflat, tol_NULP) # compare with flat SVD Uflat, Sflat, VHflat = np.linalg.svd(Aflat, False, True) perm = np.argsort(-S) # sort descending print(S[perm]) iperm = inverse_permutation(perm) for i in range(len(Sflat)): if i not in iperm: # dopped it in npc.svd() assert (Sflat[i] < EPS * 10) Sflat = Sflat[iperm] npt.assert_array_almost_equal_nulp(Sonly, Sflat, tol_NULP) # comparing U and Uflat is hard: U columns can change by a phase... print("with full_matrices") Ufull, Sfull, VHfull = npc.svd(A, full_matrices=True, compute_uv=True) Ufull.test_sanity() VHfull.test_sanity() npt.assert_array_almost_equal_nulp(Sfull, S, tol_NULP) print("for trivial charges") A = npc.Array.from_func(np.random.random, [lcTr, lcTr.conj()], shape_kw='size') Aflat = A.to_ndarray() U, S, VH = npc.svd(A) recalc = npc.tensordot(U.scale_axis(S, axis=-1), VH, axes=1) tol_NULP = max(20 * max(A.shape)**3, 1000) npt.assert_array_almost_equal_nulp(recalc.to_ndarray(), Aflat, tol_NULP)