def init_mps(self): tentative_mpo = Mpo(self.model) if self.temperature == 0: gs_mp = Mps.ground_state(self.model, max_entangled=False) else: if self._defined_output_path: gs_mp = load_thermal_state(self.model, self._thermal_dump_path) else: gs_mp = None if gs_mp is None: gs_mp = MpDm.max_entangled_gs(self.model) # subtract the energy otherwise might cause numeric error because of large offset * dbeta energy = Quantity(gs_mp.expectation(tentative_mpo)) mpo = Mpo(self.model, offset=energy) tp = ThermalProp(gs_mp, mpo, exact=True, space="GS") tp.evolve(None, max(20, len(gs_mp)), self.temperature.to_beta() / 2j) gs_mp = tp.latest_mps if self._defined_output_path: gs_mp.dump(self._thermal_dump_path) init_mp = self.create_electron(gs_mp) energy = Quantity(init_mp.expectation(tentative_mpo)) self.mpo = Mpo(self.model, offset=energy) logger.info(f"mpo bond dims: {self.mpo.bond_dims}") logger.info(f"mpo physical dims: {self.mpo.pbond_list}") init_mp.evolve_config = self.evolve_config init_mp.compress_config = self.compress_config if self.evolve_config.is_tdvp: init_mp = init_mp.expand_bond_dimension(self.mpo) init_mp.canonicalise() return init_mp
def test_phonon_onsite(): gs = Mps.ground_state(holstein_model, max_entangled=False) assert not gs.ph_occupations.any() b2 = Mpo.ph_onsite(holstein_model, r"b^\dagger", 0, 0) p1 = b2.apply(gs).normalize() assert np.allclose(p1.ph_occupations, [1, 0, 0, 0, 0, 0]) p2 = b2.apply(p1).normalize() assert np.allclose(p2.ph_occupations, [2, 0, 0, 0, 0, 0]) b = b2.conj_trans() assert b.distance(Mpo.ph_onsite(holstein_model, r"b", 0, 0)) == 0 assert b.apply(p2).normalize().distance(p1) == pytest.approx(0, abs=1e-5)
def max_entangled_ex(cls, model, normalize=True): """ T = \\infty locally maximal entangled EX state """ mps = Mps.ground_state(model, max_entangled=True) # the creation operator \\sum_i a^\\dagger_i ex_mpo = Mpo.onsite(model, r"a^\dagger") ex_mps = ex_mpo @ mps if normalize: ex_mps.normalize(1.0) return cls.from_mps(ex_mps)
def init_mps(self): logger.debug( f"mpo bond and physical dimension: {self.h_mpo.bond_dims}, {self.h_mpo.pbond_list}" ) if self.temperature == 0: init_mps = Mps.ground_state(self.model, False) else: raise NotImplementedError init_mps.compress_config = self.compress_config init_mps.evolve_config = self.evolve_config init_mps.use_dummy_qn = True self.h_mpo = Mpo(self.model, offset=Quantity(init_mps.expectation(self.h_mpo))) init_mps = init_mps.expand_bond_dimension(self.h_mpo, include_ex=False) return init_mps
def test_save_load(): model = holstein_model mps = Mpo.onsite(model, r"a^\dagger", dof_set={0}) @ Mps.ground_state( model, False) mpo = Mpo(model) mps1 = mps.copy() for i in range(2): mps1 = mps1.evolve(mpo, 10) mps2 = mps.evolve(mpo, 10) fname = "test.npz" mps2.dump(fname) mps2 = Mps.load(model, fname) mps2 = mps2.evolve(mpo, 10) assert np.allclose(mps1.e_occupations, mps2.e_occupations) os.remove(fname)
def test_zt(): model = get_model() mps = Mps.ground_state(model, False) mps.compress_config = CompressConfig(threshold=1e-6) mps.evolve_config = EvolveConfig(adaptive=True, guess_dt=0.1) mps.use_dummy_qn = True mpo = Mpo(model) time_series = [0] spin = [1] sigma_z_oper = Mpo(model, Op("sigma_z", "spin")) for i in range(30): dt = mps.evolve_config.guess_dt mps = mps.evolve(mpo, evolve_dt=dt) time_series.append(time_series[-1] + dt) spin.append(mps.expectation(sigma_z_oper)) qutip_res = get_qutip_zt(model, time_series) assert np.allclose(qutip_res, spin, atol=1e-3)
def f(model, run_qutip=True): tentative_mpo = Mpo(model) init_mps = (Mpo.onsite(model, r"a^\dagger", dof_set={0}) @ Mps.ground_state(model, False)).expand_bond_dimension(hint_mpo=tentative_mpo) init_mpdm = MpDm.from_mps(init_mps).expand_bond_dimension(hint_mpo=tentative_mpo) e = init_mps.expectation(tentative_mpo) mpo = Mpo(model, offset=Quantity(e)) if run_qutip: # calculate result in ZT. FT result is exactly the same TIME_LIMIT = 10 QUTIP_STEP = 0.01 N_POINTS = TIME_LIMIT / QUTIP_STEP + 1 qutip_time_series = np.linspace(0, TIME_LIMIT, N_POINTS) init = qutip.Qobj(init_mps.full_wfn(), [qutip_h.dims[0], [1] * len(qutip_h.dims[0])]) # the result is not exact and the error scale is approximately 1e-5 res = qutip.sesolve(qutip_h-e, init, qutip_time_series, e_ops=[c.dag() * c for c in qutip_clist]) qutip_expectations = np.array(res.expect).T return qutip_expectations, QUTIP_STEP, init_mps, init_mpdm, mpo else: return init_mps, init_mpdm, mpo
def max_entangled_gs(cls, model) -> "MpDm": return cls.from_mps(Mps.ground_state(model, max_entangled=True))