Example I: tMPS (MPO based)¶
In this example, we demonstrate how to use the program at the basic level with line by line explanation.
Models¶
$$(a + b)^2 = a^2 + 2ab + b^2$$
Parameters Setting¶
size_t L = paras.getInt("L", 10);
double hx = paras.getDouble("hx", 0.);
double hz = paras.getDouble("hz", 1.);
double J = paras.getDouble("J", 1.);
double Jzz = paras.getDouble("Jzz", 0.5);
double dt = paras.getDouble("dt",0.01);
double t = paras.getDouble("t", 10.);
size_t measurestep = paras.getInt("measurestep", 10);
auto op = generateNSymSpinOperator<std::complex<double> > ();
nsym_simple_uniform_lattice<std::complex<double> > lattice(L, op.at("id"));
Hamiltonian Construction¶
In tMPS, the Hamiltonian and the dissipator are constructed as MPOs.
template<typename _T>
gc::NSymMPO<_T>
createSpinChainMPO(const std::map<std::string, gc::TensorNd<_T, 2, SHIFU_MAJOR> >& op,
const gc::nsym_simple_uniform_lattice<_T>& lattice, size_t L,
double hx,
double hz,
double J,
double Jzz)
{
assert(L == lattice.size());
gc::NSymMPO<_t> mpo(L);
for (size_t i = 0; i < L; ++i)
{
mpo += lattice.generateProdMPO({{i, J * op.at("sp")},{i + 1, op.at("sm")}});
mpo += lattice.generateProdMPO({{i, J * op.at("sm")},{i + 1, op.at("sp")}});
mpo += lattice.generateProdMPO({{i, Jzz * op.at("sz")},{i + 1, op.at("sz")}});
}
}
Function createSpinChainMPO
Input:
- The operators map op, this map is defined in the main function. Available operators, spins, bosons.
- Read in 1D lattice
- Size of system L
- Other parameters hx, hz, J, Jzz, for Hamiltonian
Initial State Preparation¶
template <typename _T>
gc::NSymMPS<_T>
createNaiveInitialState(const gc::nsym_simple_uniform_lattice<_T>& lattice,
size_t L,
size_t N)
{
if (N > L) {
throw std::runtime_error("Too many particles, local cutoff is too small.");
}
for (size_t i = 0; i < N; ++i)
{
v[i] = 0;
}
return lattice.generateProdMPS(v);
}
Function createNaiveInitialState
Input: lattice and size of the initial state.
Output: A product nonsymetric MPS.
More details about initial state construction refer to here.
Observable Setting¶
gc::uniformNSymLocalObserver<std:complex<double> > ob(L);
ob.set("su", op.at("su"));
gc::NSymCorrelation<std::complex<double> > corr(0, L, 2 ,"spsm");
for (size_t i = 0; i < corr.size(); ++i) {
corr.op1(i) = op.at("sp");
corr.op2(i) = op.at("sm");
}
ob.measure(mps);
corr.measure(mps);
Time Evolution¶
Data Saving¶
Benchmark¶
The results are benchmarked with the dense matrix time evolution
Complete source code is available at