def test_christoffel(self): mps = self.mps_0_6.left_canonicalise() ijks = ((4, 5, 4), (3, 5, 3), (3, 4, 3)) # all non zero indexes (for full rank) for i, j, k in ijks: # Gauge projectors are in the right place mps.left_canonicalise() l, r = mps.get_envs() self.assertTrue(not allclose(mps.christoffel(i, j, k), 0)) i_true=allclose(mps.christoffel(i, j, k, closed=(l(i-1)@c(mps[i]), None, None)), 0) i_false=allclose(mps.christoffel(i, j, k, closed=(l(i-1)@mps[i], None, None)), 0) j_true=allclose(mps.christoffel(i, j, k, closed=(None, l(j-1)@c(mps[j]), None)), 0) j_false=allclose(mps.christoffel(i, j, k, closed=(None, l(j-1)@mps[j], None)), 0) k_true=allclose(mps.christoffel(i, j, k, closed=(None, None, l(k-1)@mps[k])), 0) k_false=allclose(mps.christoffel(i, j, k, closed=(None, None, l(k-1)@c(mps[k]))), 0) self.assertTrue(i_true) self.assertTrue(j_true) self.assertTrue(k_true) self.assertTrue(not i_false) self.assertTrue(not j_false) self.assertTrue(not k_false) mps.right_canonicalise() l, r = mps.get_envs() self.assertTrue(not allclose(mps.christoffel(i, j, k), 0)) i_true=allclose(mps.christoffel(i, j, k, closed=(l(i-1)@c(mps[i]), None, None)), 0) i_false=allclose(mps.christoffel(i, j, k, closed=(l(i-1)@mps[i], None, None)), 0) j_true=allclose(mps.christoffel(i, j, k, closed=(None, l(j-1)@c(mps[j]), None)), 0) j_false=allclose(mps.christoffel(i, j, k, closed=(None, l(j-1)@mps[j], None)), 0) k_true=allclose(mps.christoffel(i, j, k, closed=(None, None, l(k-1)@mps[k])), 0) k_false=allclose(mps.christoffel(i, j, k, closed=(None, None, l(k-1)@c(mps[k]))), 0) self.assertTrue(i_true) self.assertTrue(j_true) self.assertTrue(k_true) self.assertTrue(not i_false) self.assertTrue(not j_false) self.assertTrue(not k_false) # symmetric in i, j self.assertTrue(allclose(mps.christoffel(i, j, k, closed=(c(mps[i]), c(mps[j]), mps[k])), mps.christoffel(j, i, k, closed=(c(mps[j]), c(mps[i]), mps[k])) )) self.assertTrue(allclose(tra(mps.christoffel(i, j, k), [3, 4, 5, 0, 1, 2, 6, 7, 8]), mps.christoffel(j, i, k))) ijks = ((1, 2, 1),) for i, j, k in ijks: # Christoffel symbols that are zero for untruncated become not zero after truncation self.assertTrue(allclose(mps.christoffel(i, j, k), 0)) mps.left_canonicalise(2) self.assertTrue(not allclose(mps.christoffel(i, j, k), 0))
def test_Maps(self): for tm in self.maps: r = rand(tm.shape[1]) full_tm = transpose(tensordot(tm.A, C(tm.B), [0, 0]), [0, 2, 1, 3]).reshape(tm.shape) self.assertTrue(allclose(full_tm @ r, tm.mv(r))) self.assertTrue(allclose(c(r @ full_tm), tm.mvr(r)))
def test_Map_operators(self): for tm in self.maps: r = rand(tm.shape[1]) full_tm = transpose(tensordot(tm.A, C(tm.B), [0, 0]), [0, 2, 1, 3]).reshape(tm.shape) self.assertTrue(allclose(full_tm @ r, tm.aslinearoperator() @ (r))) self.assertTrue( allclose(c(r @ full_tm), tm.aslinearoperator().H @ r))
def test_F2_F1(self): '''<d_id_j ψ|H|ψ>, <d_iψ|H|d_jψ>''' Sx1, Sy1, Sz1 = N_body_spins(0.5, 1, 6) Sx2, Sy2, Sz2 = N_body_spins(0.5, 2, 6) Sx3, Sy3, Sz3 = N_body_spins(0.5, 3, 6) Sx4, Sy4, Sz4 = N_body_spins(0.5, 4, 6) Sx5, Sy5, Sz5 = N_body_spins(0.5, 5, 6) Sx6, Sy6, Sz6 = N_body_spins(0.5, 6, 6) Sx12, Sy12, Sz12 = N_body_spins(0.5, 1, 2) Sx22, Sy22, Sz22 = N_body_spins(0.5, 2, 2) mps = self.mps_0_6.left_canonicalise() listH = [Sz12@Sz22+Sx12, Sz12@Sz22+Sx12+Sx22, Sz12@Sz22+Sx22+Sx12+Sx22, Sz12@Sz22+Sz12+Sx22, Sz12@Sz22+Sx22] eyeH = [(1/(mps.L-1))*eye(4) for _ in range(5)] fullH = Sz1@Sz2+Sz2@Sz3+Sz3@Sz4+Sz4@Sz5+Sz5@Sz6+Sx1+Sx2+Sx3+Sx4+Sx5+Sx6 for i, j in product(range(mps.L), range(mps.L)): ## F2 = <d_id_j ψ|H|ψ> # zero for H = I self.assertTrue(allclose(mps.F2(i, j, eyeH, testing=True), 0)) # Test gauge projectors are in the right place mps.right_canonicalise() l, r = mps.get_envs() z1 = ncon([mps.F2(i, j, listH, testing=True), l(i-1)@c(mps[i])], [[1, 2, 3, -1, -2, -3], [1, 2, 3]]) z2 = ncon([mps.F2(i, j, listH, testing=True), l(j-1)@c(mps[j])], [[-1, -2, -3, 1, 2, 3], [1, 2, 3]]) self.assertTrue(allclose(z1, 0)) self.assertTrue(allclose(z2, 0)) mps.left_canonicalise() l, r = mps.get_envs() z1 = ncon([mps.F2(i, j, listH, testing=True), l(i-1)@c(mps[i])], [[1, 2, 3, -1, -2, -3], [1, 2, 3]]) z2 = ncon([mps.F2(i, j, listH, testing=True), l(j-1)@c(mps[j])], [[-1, -2, -3, 1, 2, 3], [1, 2, 3]]) self.assertTrue(allclose(z1, 0)) self.assertTrue(allclose(z2, 0)) ## F1 = <d_iψ|H|d_jψ> # For H = I: should be equal to δ_{ij} pr(i) if i!=j: self.assertTrue(allclose(mps.F1(i, j, eyeH, testing=True), 0)) if i==j: b = mps.F1(i, j, eyeH, testing=True) a = ncon([mps.left_null_projector(i), inv(r(i))], [[-1, -2, -4, -5], [-3, -6]]) self.assertTrue(allclose(a, b)) # Test gauge projectors are in the right place mps.left_canonicalise() l, r = mps.get_envs() z1 = td(mps.F1(i, j, listH, testing=True), l(i-1)@c(mps[i]), [[0, 1, 2], [0, 1, 2]]) z1 = td(mps.F1(i, j, listH, testing=True), l(j-1)@mps[j], [[3, 4, 5], [0, 1, 2]]) self.assertTrue(allclose(z1, 0)) self.assertTrue(allclose(z2, 0)) mps.right_canonicalise() l, r = mps.get_envs() z1 = td(mps.F1(i, j, listH, testing=True), l(i-1)@c(mps[i]), [[0, 1, 2], [0, 1, 2]]) z1 = td(mps.F1(i, j, listH, testing=True), l(j-1)@mps[j], [[3, 4, 5], [0, 1, 2]]) self.assertTrue(allclose(z1, 0)) self.assertTrue(allclose(z2, 0))
def left_null_projector(self, n, l=None, get_vL=False, store_envs=False, vL=None): """left_null_projector: | - inv(sqrt(l)) - vL = vL- inv(sqrt(l))- | replaces A(n) in TDVP :param n: site """ if l is None: l, _ = self.get_envs(store_envs) if vL is None: L_ = sw(cT(self[n]) @ ch(l(n - 1)), 0, 1) L = L_.reshape(-1, self.d * L_.shape[-1]) vL = null(L).reshape((self.d, L.shape[1] // self.d, -1)) pr = ncon([inv(ch(l(n - 1))) @ vL, inv(ch(l(n - 1))) @ c(vL)], [[-1, -2, 1], [-3, -4, 1]]) if get_vL: return pr, vL return pr