def init_mps(self): mmax = self.optimize_config.procedure[0][0] i_mps = Mps.random(self.h_mpo.model, self.nexciton, mmax, 1) i_mps.optimize_config = self.optimize_config energy, i_mps = gs.optimize_mps(i_mps, self.h_mpo) if self.spectratype == "emi": operator = "a" else: operator = r"a^\dagger" dipole_mpo = Mpo.onsite(self.model, operator, dipole=True) if self.temperature != 0: beta = self.temperature.to_beta() # print "beta=", beta # thermal_mpo = Mpo.exact_propagator(self.model, -beta / 2.0, space=self.space1, shift=self.shift1) # ket_mps = thermal_mpo.apply(i_mps) # ket_mps.normalize() # no test, don't know work or not i_mpdm = MpDm.from_mps(i_mps) tp = ThermalProp(i_mpdm, self.h_mpo, exact=True, space=self.space1) tp.evolve(None, 1, beta / 2j) ket_mps = tp.latest_mps else: ket_mps = i_mps a_ket_mps = dipole_mpo.apply(ket_mps, canonicalise=True) a_ket_mps.canonical_normalize() if self.temperature != 0: a_bra_mps = ket_mps.copy() else: a_bra_mps = a_ket_mps.copy() return BraKetPair(a_bra_mps, a_ket_mps)
def test_from_mps(): gs = Mps.random(parameter.holstein_model, 1, 20) gs_mpdm = MpDm.from_mps(gs) assert np.allclose(gs.e_occupations, gs_mpdm.e_occupations) gs = gs.canonicalise() gs_mpdm = gs_mpdm.canonicalise() assert np.allclose(gs.e_occupations, gs_mpdm.e_occupations)
def test_svd_compress(comp, mp): if mp == "mpo": mps = Mpo(holstein_model) M = 22 else: mps = Mps.random(holstein_model, 1, 10) if mp == "mpdm": mps = MpDm.from_mps(mps) mps.canonicalise().normalize() M = 36 if comp: mps = mps.to_complex(inplace=True) print(f"{mps}") mpo = Mpo(holstein_model) if comp: mpo = mpo.scale(-1.0j) print(f"{mpo.bond_dims}") std_mps = mpo.apply(mps, canonicalise=True).canonicalise() print(f"std_mps: {std_mps}") mps.compress_config.bond_dim_max_value = M mps.compress_config.criteria = CompressCriteria.fixed svd_mps = mpo.contract(mps) dis = svd_mps.distance(std_mps) / std_mps.dmrg_norm print(f"svd_mps: {svd_mps}, dis: {dis}") assert np.allclose(dis, 0.0, atol=1e-3) assert np.allclose(svd_mps.dmrg_norm, std_mps.dmrg_norm, atol=1e-4)
def init_mps(self): tentative_mpo = Mpo(self.mol_list) if self.temperature == 0: gs_mp = Mps.gs(self.mol_list, max_entangled=False) if self.dissipation != 0: gs_mp = MpDm.from_mps(gs_mp) else: gs_mp = MpDm.max_entangled_gs(self.mol_list) # subtract the energy otherwise might cause numeric error because of large offset * dbeta energy = Quantity(gs_mp.expectation(tentative_mpo)) mpo = Mpo(self.mol_list, offset=energy) tp = ThermalProp(gs_mp, mpo, exact=True, space="GS") tp.evolve(None, len(gs_mp), self.temperature.to_beta() / 2j) gs_mp = tp.latest_mps init_mp = self.create_electron(gs_mp) if self.dissipation != 0: init_mp = MpDmFull.from_mpdm(init_mp) energy = Quantity(init_mp.expectation(tentative_mpo)) self.mpo = Mpo(self.mol_list, offset=energy) logger.info(f"mpo bond dims: {self.mpo.bond_dims}") logger.info(f"mpo physical dims: {self.mpo.pbond_list}") if self.dissipation != 0: self.mpo = SuperLiouville(self.mpo, self.dissipation) init_mp.canonicalise() init_mp.evolve_config = self.evolve_config # init the compress config if not using threshold and not set if self.compress_config.criteria is not CompressCriteria.threshold\ and self.compress_config.max_dims is None: self.compress_config.set_bonddim(length=len(init_mp) + 1) init_mp.compress_config = self.compress_config # init_mp.invalidate_cache() return init_mp
def f(mol_list, run_qutip=True): tentative_mpo = Mpo(mol_list) init_mps = (Mpo.onsite(mol_list, r"a^\dagger", mol_idx_set={0}) @ Mps.gs( mol_list, 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(mol_list, 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 test_environ_multi_mpo(mpdm): mps = Mps.random(holstein_model, 1, 10) if mpdm: mps = MpDm.from_mps(mps) mpo = Mpo(holstein_model) mps = mps.evolve(mpo, 10) environ = Environ(mps, mpo) environ_multi_mpo = Environ(mps, [mpo]) for i in range(len(mps) - 1): l = environ.read("L", i) r = environ.read("R", i + 1) l2 = environ_multi_mpo.read("L", i) r2 = environ_multi_mpo.read("R", i + 1) assert np.allclose(asnumpy(l), asnumpy(l2)) assert np.allclose(asnumpy(r), asnumpy(r2))
def test_variational_compress(comp, mp): if mp == "mpo": mps = Mpo(holstein_model) M = 20 else: mps = Mps.random(holstein_model, 1, 10) if mp == "mpdm": mps = MpDm.from_mps(mps) mps.canonicalise().normalize() M = 36 if comp: mps = mps.to_complex(inplace=True) print(f"{mps}") mpo = Mpo(holstein_model) if comp: mpo = mpo.scale(-1.0j) print(f"{mpo.bond_dims}") std_mps = mpo.apply(mps, canonicalise=True).canonicalise() print(f"std_mps: {std_mps}") # 2site algorithm mps.compress_config.vprocedure = [[M, 1.0], [M, 0.2], [M, 0.1]] + [ [M, 0], ] * 10 mps.compress_config.vmethod = "2site" var_mps = mps.variational_compress(mpo, guess=None) dis = var_mps.distance(std_mps) / std_mps.dmrg_norm print(f"var2_mps: {var_mps}, dis: {dis}") assert np.allclose(dis, 0.0, atol=1e-4) assert np.allclose(var_mps.dmrg_norm, std_mps.dmrg_norm, atol=1e-4) # 1site algorithm with 2site result as a guess # 1site algorithm is easy to be trapped in a local minimum var_mps.compress_config.vprocedure = [ [M, 0], ] * 10 var_mps.compress_config.vmethod = "1site" var_mps = mps.variational_compress(mpo, guess=var_mps) dis = var_mps.distance(std_mps) / std_mps.dmrg_norm print(f"var1_mps: {var_mps}, dis: {dis}") assert np.allclose(dis, 0.0, atol=1e-4) assert np.allclose(var_mps.dmrg_norm, std_mps.dmrg_norm, atol=1e-4)
def test_2site(): ph = Phonon.simple_phonon(Quantity(1), Quantity(1), 2) m = Mol(Quantity(0), [ph]) mol_list = MolList([m] * 2, Quantity(1), scheme=3) gs_mp = Mpo.onsite(mol_list, opera=r"a^\dagger", mol_idx_set={0}).apply(Mps.gs(mol_list, max_entangled=False)) mpdm = MpDm.from_mps(gs_mp) mpdm_full = MpDmFull.from_mpdm(mpdm) mpdm_full.compress_config = CompressConfig(threshold=1e-4) liouville = SuperLiouville(Mpo(mol_list), dissipation=1) ph_occupations_array = [] energies = [] for i in range(51): logger.info(mpdm_full) logger.info(mpdm_full.ph_occupations) ph_occupations_array.append(mpdm_full.ph_occupations) logger.info(mpdm_full.expectation(liouville)) energies.append(mpdm_full.expectation(liouville)) mpdm_full = mpdm_full.evolve(liouville, 0.4) ph_occupations_array = np.array(ph_occupations_array) assert energies[-1] == pytest.approx(-0.340162, rel=1e-2) assert np.allclose(ph_occupations_array[-1], [0.0930588, 0.099115], rtol=1e-2)
def init_mps(self): tentative_mpo = Mpo(self.mol_list) if self.temperature == 0: gs_mp = Mps.gs(self.mol_list, max_entangled=False) if self.dissipation != 0: gs_mp = MpDm.from_mps(gs_mp) else: if self._defined_output_path: gs_mp = load_thermal_state(self.mol_list, self._thermal_dump_path) else: gs_mp = None if gs_mp is None: gs_mp = MpDm.max_entangled_gs(self.mol_list) # subtract the energy otherwise might cause numeric error because of large offset * dbeta energy = Quantity(gs_mp.expectation(tentative_mpo)) mpo = Mpo(self.mol_list, 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) if self.dissipation != 0: init_mp = MpDmFull.from_mpdm(init_mp) energy = Quantity(init_mp.expectation(tentative_mpo)) self.mpo = Mpo(self.mol_list, 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) if self.dissipation != 0: self.mpo = SuperLiouville(self.mpo, self.dissipation) init_mp.canonicalise() return init_mp