A first TEBD Example
Like examples/c_tebd.py
, this notebook shows the basic interface for TEBD. It initalized the transverse field Ising model \(H = J XX + g Z\) at the critical point \(J=g=1\), and an MPS in the all-up state \(|\uparrow\cdots \uparrow\rangle\). It then performs a real-time evolution with TEBD and measures a few observables. This setup correspond to a global quench from \(g =\infty\) to \(g=1\).
[1]:
import numpy as np
import scipy
import matplotlib.pyplot as plt
import matplotlib
np.set_printoptions(precision=5, suppress=True, linewidth=100)
plt.rcParams['figure.dpi'] = 150
[2]:
import tenpy
import tenpy.linalg.np_conserved as npc
from tenpy.algorithms import tebd
from tenpy.networks.mps import MPS
from tenpy.models.tf_ising import TFIChain
tenpy.tools.misc.setup_logging(to_stdout="INFO")
[3]:
L = 30
[4]:
model_params = {
'J': 1. , 'g': 1., # critical
'L': L,
'bc_MPS': 'finite',
}
M = TFIChain(model_params)
INFO : TFIChain: reading 'bc_MPS'='finite'
INFO : TFIChain: reading 'L'=30
INFO : TFIChain: reading 'J'=1.0
INFO : TFIChain: reading 'g'=1.0
[5]:
psi = MPS.from_lat_product_state(M.lat, [['up']])
[6]:
tebd_params = {
'N_steps': 1,
'dt': 0.1,
'order': 4,
'trunc_params': {'chi_max': 100, 'svd_min': 1.e-12}
}
eng = tebd.TEBDEngine(psi, M, tebd_params)
INFO : TEBDEngine: subconfig 'trunc_params'=Config(<2 options>, 'trunc_params')
[7]:
def measurement(eng, data):
keys = ['t', 'entropy', 'Sx', 'Sz', 'corr_XX', 'corr_ZZ', 'trunc_err']
if data is None:
data = dict([(k, []) for k in keys])
data['t'].append(eng.evolved_time)
data['entropy'].append(eng.psi.entanglement_entropy())
data['Sx'].append(eng.psi.expectation_value('Sigmax'))
data['Sz'].append(eng.psi.expectation_value('Sigmaz'))
data['corr_XX'].append(eng.psi.correlation_function('Sigmax', 'Sigmax'))
data['trunc_err'].append(eng.trunc_err.eps)
return data
[8]:
data = measurement(eng, None)
[9]:
while eng.evolved_time < 5.:
eng.run()
measurement(eng, data)
INFO : TEBDEngine: reading 'dt'=0.1
INFO : TEBDEngine: reading 'N_steps'=1
INFO : TEBDEngine: reading 'order'=4
INFO : Calculate U for {'order': 4, 'delta_t': 0.1, 'type_evo': 'real', 'E_offset': None, 'tau': 0.1}
INFO : trunc_params: reading 'chi_max'=100
INFO : trunc_params: reading 'svd_min'=1e-12
INFO : --> time=0.100, max(chi)=6, max(S)=0.05524, avg DeltaS=5.5243e-02, since last update: 0.5s
INFO : --> time=0.200, max(chi)=6, max(S)=0.15978, avg DeltaS=1.0453e-01, since last update: 0.6s
INFO : --> time=0.300, max(chi)=8, max(S)=0.27350, avg DeltaS=1.1368e-01, since last update: 0.6s
INFO : --> time=0.400, max(chi)=10, max(S)=0.37590, avg DeltaS=1.0226e-01, since last update: 0.6s
INFO : --> time=0.500, max(chi)=12, max(S)=0.45873, avg DeltaS=8.2474e-02, since last update: 0.5s
INFO : --> time=0.600, max(chi)=12, max(S)=0.52284, avg DeltaS=6.3393e-02, since last update: 0.5s
INFO : --> time=0.700, max(chi)=15, max(S)=0.57503, avg DeltaS=5.0837e-02, since last update: 0.7s
INFO : --> time=0.800, max(chi)=18, max(S)=0.62434, avg DeltaS=4.7046e-02, since last update: 0.9s
INFO : --> time=0.900, max(chi)=20, max(S)=0.67838, avg DeltaS=5.0606e-02, since last update: 1.0s
INFO : --> time=1.000, max(chi)=20, max(S)=0.74043, avg DeltaS=5.7462e-02, since last update: 0.9s
INFO : --> time=1.100, max(chi)=24, max(S)=0.80903, avg DeltaS=6.3115e-02, since last update: 0.8s
INFO : --> time=1.200, max(chi)=26, max(S)=0.87983, avg DeltaS=6.4779e-02, since last update: 0.8s
INFO : --> time=1.300, max(chi)=30, max(S)=0.94838, avg DeltaS=6.2269e-02, since last update: 0.7s
INFO : --> time=1.400, max(chi)=34, max(S)=1.01236, avg DeltaS=5.7451e-02, since last update: 1.0s
INFO : --> time=1.500, max(chi)=40, max(S)=1.07232, avg DeltaS=5.2899e-02, since last update: 1.3s
INFO : --> time=1.600, max(chi)=40, max(S)=1.13085, avg DeltaS=5.0543e-02, since last update: 1.1s
INFO : --> time=1.700, max(chi)=46, max(S)=1.19091, avg DeltaS=5.0852e-02, since last update: 1.1s
INFO : --> time=1.800, max(chi)=52, max(S)=1.25415, avg DeltaS=5.2841e-02, since last update: 1.0s
INFO : --> time=1.900, max(chi)=57, max(S)=1.32023, avg DeltaS=5.4804e-02, since last update: 0.8s
INFO : --> time=2.000, max(chi)=62, max(S)=1.38731, avg DeltaS=5.5311e-02, since last update: 0.9s
INFO : --> time=2.100, max(chi)=71, max(S)=1.45325, avg DeltaS=5.3906e-02, since last update: 0.8s
INFO : --> time=2.200, max(chi)=80, max(S)=1.51684, avg DeltaS=5.1209e-02, since last update: 0.8s
INFO : --> time=2.300, max(chi)=85, max(S)=1.57836, avg DeltaS=4.8446e-02, since last update: 0.8s
INFO : --> time=2.400, max(chi)=95, max(S)=1.63919, avg DeltaS=4.6732e-02, since last update: 0.8s
INFO : --> time=2.500, max(chi)=100, max(S)=1.70098, avg DeltaS=4.6486e-02, since last update: 0.8s
INFO : --> time=2.600, max(chi)=100, max(S)=1.76463, avg DeltaS=4.7282e-02, since last update: 0.9s
INFO : --> time=2.700, max(chi)=100, max(S)=1.82990, avg DeltaS=4.8160e-02, since last update: 0.9s
INFO : --> time=2.800, max(chi)=100, max(S)=1.89566, avg DeltaS=4.8202e-02, since last update: 0.9s
INFO : --> time=2.900, max(chi)=100, max(S)=1.96060, avg DeltaS=4.7044e-02, since last update: 1.0s
INFO : --> time=3.000, max(chi)=100, max(S)=2.02403, avg DeltaS=4.5033e-02, since last update: 1.0s
INFO : --> time=3.100, max(chi)=100, max(S)=2.08618, avg DeltaS=4.2960e-02, since last update: 1.0s
INFO : --> time=3.200, max(chi)=100, max(S)=2.14801, avg DeltaS=4.1575e-02, since last update: 1.0s
INFO : --> time=3.300, max(chi)=100, max(S)=2.21056, avg DeltaS=4.1182e-02, since last update: 1.0s
INFO : --> time=3.400, max(chi)=100, max(S)=2.27439, avg DeltaS=4.1503e-02, since last update: 1.0s
INFO : --> time=3.500, max(chi)=100, max(S)=2.33926, avg DeltaS=4.1873e-02, since last update: 0.9s
INFO : --> time=3.600, max(chi)=100, max(S)=2.40435, avg DeltaS=4.1645e-02, since last update: 0.9s
INFO : --> time=3.700, max(chi)=100, max(S)=2.46880, avg DeltaS=4.0570e-02, since last update: 0.9s
INFO : --> time=3.800, max(chi)=100, max(S)=2.53215, avg DeltaS=3.8897e-02, since last update: 1.0s
INFO : --> time=3.900, max(chi)=100, max(S)=2.59465, avg DeltaS=3.7189e-02, since last update: 0.9s
INFO : --> time=4.000, max(chi)=100, max(S)=2.65702, avg DeltaS=3.5994e-02, since last update: 1.0s
INFO : --> time=4.100, max(chi)=100, max(S)=2.71998, avg DeltaS=3.5534e-02, since last update: 1.1s
INFO : --> time=4.200, max(chi)=100, max(S)=2.78389, avg DeltaS=3.5597e-02, since last update: 1.0s
INFO : --> time=4.300, max(chi)=100, max(S)=2.84850, avg DeltaS=3.5673e-02, since last update: 0.9s
INFO : --> time=4.400, max(chi)=100, max(S)=2.91314, avg DeltaS=3.5272e-02, since last update: 0.9s
INFO : --> time=4.500, max(chi)=100, max(S)=2.97713, avg DeltaS=3.4188e-02, since last update: 1.0s
INFO : --> time=4.600, max(chi)=100, max(S)=3.04010, avg DeltaS=3.2596e-02, since last update: 1.0s
INFO : --> time=4.700, max(chi)=100, max(S)=3.10214, avg DeltaS=3.0915e-02, since last update: 1.1s
INFO : --> time=4.800, max(chi)=100, max(S)=3.16360, avg DeltaS=2.9546e-02, since last update: 1.1s
INFO : --> time=4.900, max(chi)=100, max(S)=3.22475, avg DeltaS=2.8630e-02, since last update: 1.1s
INFO : --> time=5.000, max(chi)=100, max(S)=3.28549, avg DeltaS=2.7962e-02, since last update: 1.1s
INFO : --> time=5.100, max(chi)=100, max(S)=3.34517, avg DeltaS=2.7099e-02, since last update: 1.1s
[10]:
plt.plot(data['t'], np.array(data['entropy'])[:, L//2])
plt.xlabel('time $t$')
plt.ylabel('entropy $S$')
[10]:
Text(0, 0.5, 'entropy $S$')
The growth of \(S\) linear in time is typical for a global quench and to be expected from the quasi-particle picture
[11]:
plt.plot(data['t'], np.sum(data['Sx'], axis=1), label="X")
plt.plot(data['t'], np.sum(data['Sz'], axis=1), label="Z")
plt.xlabel('time $t$')
plt.ylabel('magnetization')
plt.legend(loc='best')
[11]:
<matplotlib.legend.Legend at 0x7fb1dfb64280>
The strict conservation of X
being zero is ensured by charge conservation, because X
changes the parity sector.
Nevertheless, the XX
correlation function can be nontrivial:
[12]:
corrs = np.array(data['corr_XX'])
tmax = data['t'][-1]
x = np.arange(L)
cmap = matplotlib.cm.viridis
for i, t in list(enumerate(data['t'])):
if i == 0 or i == len(data['t']) - 1:
label = '{t:.2f}'.format(t=t)
else:
label = None
plt.plot(x, corrs[i, L//2, :], color=cmap(t/tmax), label=label)
plt.xlabel(r'time $t$')
plt.ylabel(r'correlations $\langle X_i X_{j:d}\rangle$'.format(j=L//2))
plt.yscale('log')
plt.ylim(1.e-4, 1.)
plt.legend()
plt.show()
The output of the run showed that we gradually increased the bond dimension and only reached the maximum chi around \(t=2.5\). At this point we start to truncate significantly, because we cut off the tail whatever the singular values are. This is clearly visible if we plot the truncation error vs. time below. Note the log-scale, though: if you are fine with an error of say 1 permille for expectation values, you can still go on for a bit more!
[13]:
plt.plot(data['t'], data['trunc_err'])
plt.yscale('log')
#plt.ylim(1.e-15, 1.)
plt.xlabel('time $t$')
plt.ylabel('truncation error')
[13]:
Text(0, 0.5, 'truncation error')
[ ]: