This page was generated from 00_tebd.ipynb.

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
[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
[3]:
L = 30
[4]:
model_params = {
    'J': 1. , 'g': 1.,  # critical
    'L': L,
    'bc_MPS': 'finite',
}

M = TFIChain(model_params)
Reading 'bc_MPS'='finite' for config TFIChain
Reading 'L'=30 for config TFIChain
Reading 'J'=1.0 for config TFIChain
Reading 'g'=1.0 for config TFIChain
[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.Engine(psi, M, tebd_params)
Subconfig 'trunc_params'=Config(<3 options>, 'trunc_params') for config TEBD
[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)
Reading 'dt'=0.1 for config TEBD
Reading 'N_steps'=1 for config TEBD
Reading 'order'=4 for config TEBD
Calculate U for  {'order': 4, 'delta_t': 0.1, 'type_evo': 'real', 'E_offset': None, 'tau': 0.1}
--> time=0.100, max_chi=6, Delta_S=5.5243e-02, S=0.0552432967, since last update: 0.5 s
--> time=0.200, max_chi=6, Delta_S=1.0453e-01, S=0.1597705686, since last update: 0.5 s
--> time=0.300, max_chi=8, Delta_S=1.1368e-01, S=0.2734471407, since last update: 0.5 s
--> time=0.400, max_chi=10, Delta_S=1.0226e-01, S=0.3757082127, since last update: 0.5 s
--> time=0.500, max_chi=12, Delta_S=8.2474e-02, S=0.4581821173, since last update: 0.5 s
--> time=0.600, max_chi=12, Delta_S=6.3393e-02, S=0.5215746922, since last update: 0.5 s
--> time=0.700, max_chi=15, Delta_S=5.0837e-02, S=0.5724119006, since last update: 0.5 s
--> time=0.800, max_chi=18, Delta_S=4.7046e-02, S=0.6194580889, since last update: 0.5 s
--> time=0.900, max_chi=20, Delta_S=5.0606e-02, S=0.6700636890, since last update: 0.5 s
--> time=1.000, max_chi=20, Delta_S=5.7462e-02, S=0.7275254979, since last update: 0.5 s
--> time=1.100, max_chi=24, Delta_S=6.3115e-02, S=0.7906402648, since last update: 0.5 s
--> time=1.200, max_chi=26, Delta_S=6.4779e-02, S=0.8554189184, since last update: 0.5 s
--> time=1.300, max_chi=30, Delta_S=6.2269e-02, S=0.9176882429, since last update: 0.5 s
--> time=1.400, max_chi=34, Delta_S=5.7451e-02, S=0.9751394599, since last update: 0.5 s
--> time=1.500, max_chi=40, Delta_S=5.2899e-02, S=1.0280386118, since last update: 0.5 s
--> time=1.600, max_chi=40, Delta_S=5.0543e-02, S=1.0785817862, since last update: 0.5 s
--> time=1.700, max_chi=46, Delta_S=5.0852e-02, S=1.1294340516, since last update: 0.5 s
--> time=1.800, max_chi=52, Delta_S=5.2841e-02, S=1.1822748827, since last update: 0.7 s
--> time=1.900, max_chi=57, Delta_S=5.4804e-02, S=1.2370787276, since last update: 0.9 s
--> time=2.000, max_chi=62, Delta_S=5.5311e-02, S=1.2923895877, since last update: 0.9 s
--> time=2.100, max_chi=71, Delta_S=5.3906e-02, S=1.3462960135, since last update: 1.0 s
--> time=2.200, max_chi=80, Delta_S=5.1209e-02, S=1.3975050668, since last update: 1.2 s
--> time=2.300, max_chi=85, Delta_S=4.8446e-02, S=1.4459514729, since last update: 1.4 s
--> time=2.400, max_chi=95, Delta_S=4.6732e-02, S=1.4926837515, since last update: 1.4 s
--> time=2.500, max_chi=100, Delta_S=4.6486e-02, S=1.5391700161, since last update: 1.8 s
--> time=2.600, max_chi=100, Delta_S=4.7282e-02, S=1.5864521162, since last update: 1.9 s
--> time=2.700, max_chi=100, Delta_S=4.8160e-02, S=1.6346120966, since last update: 1.9 s
--> time=2.800, max_chi=100, Delta_S=4.8202e-02, S=1.6828138289, since last update: 1.6 s
--> time=2.900, max_chi=100, Delta_S=4.7044e-02, S=1.7298576742, since last update: 1.7 s
--> time=3.000, max_chi=100, Delta_S=4.5033e-02, S=1.7748910539, since last update: 1.6 s
--> time=3.100, max_chi=100, Delta_S=4.2960e-02, S=1.8178514255, since last update: 1.5 s
--> time=3.200, max_chi=100, Delta_S=4.1575e-02, S=1.8594265450, since last update: 1.4 s
--> time=3.300, max_chi=100, Delta_S=4.1182e-02, S=1.9006080872, since last update: 1.4 s
--> time=3.400, max_chi=100, Delta_S=4.1503e-02, S=1.9421110677, since last update: 1.4 s
--> time=3.500, max_chi=100, Delta_S=4.1873e-02, S=1.9839839097, since last update: 1.6 s
--> time=3.600, max_chi=100, Delta_S=4.1645e-02, S=2.0256293591, since last update: 1.6 s
--> time=3.700, max_chi=100, Delta_S=4.0570e-02, S=2.0661996178, since last update: 1.8 s
--> time=3.800, max_chi=100, Delta_S=3.8897e-02, S=2.1050963078, since last update: 1.6 s
--> time=3.900, max_chi=100, Delta_S=3.7189e-02, S=2.1422855970, since last update: 2.0 s
--> time=4.000, max_chi=100, Delta_S=3.5994e-02, S=2.1782792652, since last update: 1.6 s
--> time=4.100, max_chi=100, Delta_S=3.5534e-02, S=2.2138131347, since last update: 1.6 s
--> time=4.200, max_chi=100, Delta_S=3.5597e-02, S=2.2494096463, since last update: 1.6 s
--> time=4.300, max_chi=100, Delta_S=3.5673e-02, S=2.2850830917, since last update: 1.5 s
--> time=4.400, max_chi=100, Delta_S=3.5272e-02, S=2.3203546259, since last update: 1.4 s
--> time=4.500, max_chi=100, Delta_S=3.4188e-02, S=2.3545423452, since last update: 1.4 s
--> time=4.600, max_chi=100, Delta_S=3.2596e-02, S=2.3871383468, since last update: 1.4 s
--> time=4.700, max_chi=100, Delta_S=3.0915e-02, S=2.4180531110, since last update: 1.6 s
--> time=4.800, max_chi=100, Delta_S=2.9546e-02, S=2.4475988717, since last update: 1.7 s
--> time=4.900, max_chi=100, Delta_S=2.8630e-02, S=2.4762292780, since last update: 1.6 s
--> time=5.000, max_chi=100, Delta_S=2.7962e-02, S=2.5041913364, since last update: 1.6 s
--> time=5.100, max_chi=100, Delta_S=2.7099e-02, S=2.5312904883, since last update: 1.6 s
[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$')
../_images/notebooks_00_tebd_10_1.png

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 0x7f1018760e80>
../_images/notebooks_00_tebd_12_1.png

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-6, 1.)
plt.legend()
plt.show()
../_images/notebooks_00_tebd_14_0.png

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. 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')
../_images/notebooks_00_tebd_16_1.png
[ ]: