ToricCode¶
full name: tenpy.models.toric_code.ToricCode
parent module:
tenpy.models.toric_code
type: class
Inheritance Diagram
Methods

Initialize self. 

Add twosite coupling terms to the Hamiltonian, summing over lattice sites. 

Add a twosite coupling term on given MPS sites. 

Add multisite coupling terms to the Hamiltonian, summing over lattice sites. 

Add a general Msite coupling term on given MPS sites. 

Add onsite terms to 

Add an onsite term on a given MPS site. 
Sum of all 

Sum of all 


Calculate MPO representation of the Hamiltonian. 

calculate H_bond from 

Calculate the bond Hamiltonian from the MPO Hamiltonian. 

Calculate H_onsite from self.onsite_terms. 
Add an external flux to the coupling strength. 


Load instance from a HDF5 file. 

Modify self in place to group sites. 

Initialize a lattice for the given model parameters. 

Define the local Hilbert space and operators; needs to be implemented in subclasses. 

Add the onsite and coupling terms to the model; subclasses should implement this. 

Export self into a HDF5 file. 
Sanity check, raises ValueErrors, if something is wrong. 

class
tenpy.models.toric_code.
ToricCode
(model_params)[source]¶ Bases:
tenpy.models.model.CouplingMPOModel
,tenpy.models.model.MultiCouplingModel
Toric code model.
The Hamiltonian reads:
\[H =  \mathtt{Jv} \sum_{vertices v} \prod_{i \in v} \sigma^x_i  \mathtt{Jp} \sum_{plaquettes p} \prod_{i \in p} \sigma^z_i\](Note that this are Pauli matrices, not spin1/2 operators.) All parameters are collected in a single dictionary model_params and read out with
get_parameter()
. Parameters
Ly (Lx,) – Dimension of the lattice, number of plaquettes around the cylinder.
conserve ('parity'  None) – What should be conserved. See
SpinHalfSite
.Jp (Jc,) – Couplings as defined for the Hamiltonian above.
bc_MPS ({'finite'  'infinte'}) – MPS boundary conditions. Coupling boundary conditions are chosen appropriately.
order (str) – The order of the lattice sites in the lattice, see
DualSquare
.

init_sites
(model_params)[source]¶ Define the local Hilbert space and operators; needs to be implemented in subclasses.
This function gets called by
init_lattice()
to get theSite
for the lattice unit cell.Note
Initializing the sites requires to define the conserved quantum numbers. All predefined sites accept
conserve=None
to disable using quantum numbers. Many models in TeNPy read out the conserve model parameter, which can be set to"best"
to indicate the optimal parameters.

init_lattice
(model_params)[source]¶ Initialize a lattice for the given model parameters.
This function reads out the model parameter lattice. This can be a full
Lattice
instance, in which case it is just returned without further action. Alternatively, the lattice parameter can be a string giving the name of one of the predefined lattices, which then gets initialized. Depending on the dimensionality of the lattice, this requires different model parameters.The following model parameters get read out.
key
type
description
lattice
str  Lattice
The name of a lattice predefined in TeNPy to be initialized. Alternatively, a (possibly selfdefined) Lattice instance. In the latter case, no further parameters are read out.
bc_MPS
str
Boundary conditions for the MPS
order
str
The order of sites within the lattice for nontrivial lattices.
L
int
The length in xdirection (or lenght of the unit cell for infinite systems). Only read out for 1D lattices.
Lx, Ly
int
The length in x and ydirection. For
"infinite"
bc_MPS, the system is infinite in xdirection and Lx is the number of “rings” in the infinite MPS unit cell, while Ly gives the circumference around the cylinder or width of th the rung for a ladder (depending on bc_y. Only read out for 2D lattices.bc_y
str
"cylinder"  "ladder"
. The boundary conditions in ydirection. Only read out for 2D lattices.bc_x
str
"open"  "periodic"
. Can be used to force “periodic” boundaries for the lattice, i.e., for the couplings in the Hamiltonian, even if the MPS is finite. Defaults to"open"
forbc_MPS="finite"
and"periodic"
forbc_MPS="infinite
. If you are not aware of the consequences, you should probably not use “periodic” boundary conditions. (The MPS is still “open”, so this will introduce longrange couplings between the first and last sites of the MPS!)

init_terms
(model_params)[source]¶ Add the onsite and coupling terms to the model; subclasses should implement this.

add_coupling
(strength, u1, op1, u2, op2, dx, op_string=None, str_on_first=True, raise_op2_left=False, category=None)[source]¶ Add twosite coupling terms to the Hamiltonian, summing over lattice sites.
Represents couplings of the form \(\sum_{x_0, ..., x_{dim1}} strength[loc(\vec{x})] * OP1 * OP2\), where
OP1 := lat.unit_cell[u1].get_op(op1)
acts on the site(x_0, ..., x_{dim1}, u1)
, andOP2 := lat.unit_cell[u2].get_op(op2)
acts on the site(x_0+dx[0], ..., x_{dim1}+dx[dim1], u2)
. Possible combinationsx_0, ..., x_{dim1}
are determined from the boundary conditions inpossible_couplings()
.The coupling strength may vary spatially, \(loc(\vec{x})\) indicates the lower left corner of the hypercube containing the involved sites \(\vec{x}\) and \(\vec{x}+\vec{dx}\).
The necessary terms are just added to
coupling_terms
; doesn’t (re)build the MPO.Deprecated since version 0.4.0: The arguments str_on_first and raise_op2_left will be removed in version 1.0.0.
 Parameters
strength (scalar  array) – Prefactor of the coupling. May vary spatially (see above). If an array of smaller size is provided, it gets tiled to the required shape.
u1 (int) – Picks the site
lat.unit_cell[u1]
for OP1.op1 (str) – Valid operator name of an onsite operator in
lat.unit_cell[u1]
for OP1.u2 (int) – Picks the site
lat.unit_cell[u2]
for OP2.op2 (str) – Valid operator name of an onsite operator in
lat.unit_cell[u2]
for OP2.dx (iterable of int) – Translation vector (of the unit cell) between OP1 and OP2. For a 1D lattice, a single int is also fine.
op_string (str  None) – Name of an operator to be used between the OP1 and OP2 sites. Typical use case is the phase for a JordanWigner transformation. The operator should be defined on all sites in the unit cell. If
None
, autodetermine whether a JordanWigner string is needed, usingop_needs_JW()
.str_on_first (bool) – Whether the provided op_string should also act on the first site. This option should be chosen as
True
for JordanWigner strings. When handling JordanWigner strings we need to extend the op_string to also act on the ‘left’, first site (in the sense of the MPS ordering of the sites given by the lattice). In this case, there is a welldefined ordering of the operators in the physical sense (i.e. which of op1 or op2 acts first on a given state). We follow the convention that op2 acts first (in the physical sense), independent of the MPS ordering. Deprecated.raise_op2_left (bool) – Raise an error when op2 appears left of op1 (in the sense of the MPS ordering given by the lattice). Deprecated.
category (str) – Descriptive name used as key for
coupling_terms
. Defaults to a string of the form"{op1}_i {op2}_j"
.
Examples
When initializing a model, you can add a term \(J \sum_{<i,j>} S^z_i S^z_j\) on all nearestneighbor bonds of the lattice like this:
>>> J = 1. # the strength >>> for u1, u2, dx in self.lat.pairs['nearest_neighbors']: ... self.add_coupling(J, u1, 'Sz', u2, 'Sz', dx)
The strength can be an array, which get’s tiled to the correct shape. For example, in a 1D
Chain
with an even number of sites and periodic (or infinite) boundary conditions, you can add alternating strong and weak couplings with a line like:>>> self.add_coupling([1.5, 1.], 0, 'Sz', 0, 'Sz', dx)
To add the hermitian conjugate, e.g. for a hopping term, you should add it in the opposite direction
dx
, complex conjugate the strength, and take the hermitian conjugate of the operators in swapped order (including a swap of u1 <> u2). For spinless fermions (FermionSite
), this would be>>> t = 1. # hopping strength >>> for u1, u2, dx in self.lat.pairs['nearest_neighbors']: ... self.add_coupling(t, u1, 'Cd', u2, 'C', dx) ... self.add_coupling(np.conj(t), u2, 'Cd', u1, 'C', dx) # h.c.
With spinfull fermions (
SpinHalfFermions
), it could be:>>> for u1, u2, dx in self.lat.pairs['nearest_neighbors']: ... self.add_coupling(t, u1, 'Cdu', u2, 'Cd', dx) # Cdagger_up C_down ... self.add_coupling(np.conj(t), u2, 'Cdd', u1, 'Cu', dx) # h.c. Cdagger_down C_up
Note that the JordanWigner strings are figured out automatically!

add_coupling_term
(strength, i, j, op_i, op_j, op_string='Id', category=None)[source]¶ Add a twosite coupling term on given MPS sites.
Wrapper for
self.coupling_terms[category].add_coupling_term(...)
. Parameters
strength (float) – The strength of the coupling term.
j (i,) – The MPS indices of the two sites on which the operator acts. We require
0 <= i < N_sites
andi < j
, i.e., op_i acts “left” of op_j. If j >= N_sites, it indicates couplings between unit cells of an infinite MPS.op2 (op1,) – Names of the involved operators.
op_string (str) – The operator to be inserted between i and j.
category (str) – Descriptive name used as key for
coupling_terms
. Defaults to a string of the form"{op1}_i {op2}_j"
.

add_multi_coupling
(strength, u0, op0, other_ops, op_string=None, category=None)[source]¶ Add multisite coupling terms to the Hamiltonian, summing over lattice sites.
Represents couplings of the form \(sum_{x_0, ..., x_{dim1}} strength[loc(\vec{x})] * OP0 * OP1 * ... * OPM\), where
OP_0 := lat.unit_cell[u0].get_op(op0)
acts on the site(x_0, ..., x_{dim1}, u0)
, andOP_m := lat.unit_cell[other_u[m]].get_op(other_op[m])
, m=1…M, acts on the site(x_0+other_dx[m][0], ..., x_{dim1}+other_dx[m][dim1], other_u[m])
. For periodic boundary conditions along direction a (lat.bc[a] == False
) the indexx_a
is taken modulolat.Ls[a]
and runs throughrange(lat.Ls[a])
. For open boundary conditions,x_a
is limited to0 <= x_a < Ls[a]
and0 <= x_a+other_dx[m,a] < lat.Ls[a]
. The coupling strength may vary spatially, \(loc(\vec{x})\) indicates the lower left corner of the hypercube containing all the involved sites \(\vec{x}, \vec{x}+\vec{other_dx[m, :]}\).The necessary terms are just added to
coupling_terms
; doesn’t rebuild the MPO. Parameters
strength (scalar  array) – Prefactor of the coupling. May vary spatially and is tiled to the required shape.
u0 (int) – Picks the site
lat.unit_cell[u0]
for OP0.op0 (str) – Valid operator name of an onsite operator in
lat.unit_cell[u0]
for OP0.other_ops (list of
(u, op_m, dx)
) – One tuple for each of the other operatorsOP1, OP2, ... OPM
involved. u picks the sitelat.unit_cell[u]
, op_name is a valid operator acting on that site, and dx gives the translation vector betweenOP0
and the specified operator.op_string (str  None) –
Name of an operator to be used inbetween the operators, excluding the sites on which the operators act. This operator should be defined on all sites in the unit cell.
Special case: If
None
, autodetermine whether a JordanWigner string is needed (usingop_needs_JW()
), for each of the segments inbetween the operators and also on the sites of the left operators. Note that in this case the ordering of the operators is important and handled in the usual convention thatOPM
acts first andOP0
last on a physical state.category (str) – Descriptive name used as key for
coupling_terms
. Defaults to a string of the form"{op0}_i {other_ops[0]}_j {other_ops[1]}_k ..."
.

add_multi_coupling_term
(strength, ijkl, ops_ijkl, op_string, category=None)[source]¶ Add a general Msite coupling term on given MPS sites.
Wrapper for
self.coupling_terms[category].add_multi_coupling_term(...)
. Parameters
strength (float) – The strength of the coupling term.
ijkl (list of int) – The MPS indices of the sites on which the operators acts. With i, j, k, … = ijkl, we require that they are ordered ascending,
i < j < k < ...
and that0 <= i < N_sites
. Inidces >= N_sites indicate couplings between different unit cells of an infinite MPS.ops_ijkl (list of str) – Names of the involved operators on sites i, j, k, ….
op_string (list of str) – Names of the operator to be inserted between the operators, e.g., op_string[0] is inserted between i and j.
category (str) – Descriptive name used as key for
coupling_terms
. Defaults to a string of the form"{op0}_i {other_ops[0]}_j {other_ops[1]}_k ..."
.

add_onsite
(strength, u, opname, category=None)[source]¶ Add onsite terms to
onsite_terms
.Adds a term \(\sum_{x_0, ..., x_{dim1}} strength[x_0, ..., x_{dim1}] * OP\), where the operator
OP=lat.unit_cell[u].get_op(opname)
acts on the site given by a lattice index(x_0, ..., x_{dim1}, u)
, to the represented Hamiltonian.The necessary terms are just added to
onsite_terms
; doesn’t rebuild the MPO. Parameters
strength (scalar  array) – Prefactor of the onsite term. May vary spatially. If an array of smaller size is provided, it gets tiled to the required shape.
u (int) – Picks a
Site
lat.unit_cell[u]
out of the unit cell.opname (str) – valid operator name of an onsite operator in
lat.unit_cell[u]
.category (str) – Descriptive name used as key for
onsite_terms
. Defaults to opname.

add_onsite_term
(strength, i, op, category=None)[source]¶ Add an onsite term on a given MPS site.
Wrapper for
self.onsite_terms[category].add_onsite_term(...)
.

calc_H_MPO
(tol_zero=1e15)[source]¶ Calculate MPO representation of the Hamiltonian.
Uses
onsite_terms
andcoupling_terms
to build an MPO graph (and then an MPO).

calc_H_bond
(tol_zero=1e15)[source]¶ calculate H_bond from
coupling_terms
andonsite_terms
. Parameters
tol_zero (float) – prefactors with
abs(strength) < tol_zero
are considered to be zero. Returns
H_bond – Bond terms as required by the constructor of
NearestNeighborModel
. Legs are['p0', 'p0*', 'p1', 'p1*']
 Return type
list of
Array
:raises ValueError : if the Hamiltonian contains longerrange terms.:

calc_H_bond_from_MPO
(tol_zero=1e15)[source]¶ Calculate the bond Hamiltonian from the MPO Hamiltonian.
 Parameters
tol_zero (float) – Arrays with norm < tol_zero are considered to be zero.
 Returns
H_bond – Bond terms as required by the constructor of
NearestNeighborModel
. Legs are['p0', 'p0*', 'p1', 'p1*']
 Return type
list of
Array
:raises ValueError : if the Hamiltonian contains longerrange terms.:

calc_H_onsite
(tol_zero=1e15)[source]¶ Calculate H_onsite from self.onsite_terms.
Deprecated since version 0.4.0: This function will be removed in 1.0.0. Replace calls to this function by
self.all_onsite_terms().remove_zeros(tol_zero).to_Arrays(self.lat.mps_sites())
. Parameters
tol_zero (float) – prefactors with
abs(strength) < tol_zero
are considered to be zero. Returns
H_onsite – onsite terms of the Hamiltonian.
 Return type
list of npc.Array

coupling_strength_add_ext_flux
(strength, dx, phase)[source]¶ Add an external flux to the coupling strength.
When performing DMRG on a “cylinder” geometry, it might be useful to put an “external flux” through the cylinder. This means that a particle hopping around the cylinder should pick up a phase given by the external flux [Resta1997]. This is also called “twisted boundary conditions” in literature. This function adds a complex phase to the strength array on some bonds, such that particles hopping in positive direction around the cylinder pick up exp(+i phase).
Warning
For the sign of phase it is important that you consistently use the creation operator as op1 and the annihilation operator as op2 in
add_coupling()
. Parameters
strength (scalar  array) – The strength to be used in
add_coupling()
, when no external flux would be present.dx (iterable of int) – Translation vector (of the unit cell) between op1 and op2 in
add_coupling()
.phase (iterable of float) – The phase of the external flux for hopping in each direction of the lattice. E.g., if you want flux through the cylinder on which you have an infinite MPS, you should give
phase=[0, phi]
souch that particles pick up a phase phi when hopping around the cylinder.
 Returns
strength – The strength array to be used as strength in
add_coupling()
with the given dx. Return type
complex array
Examples
Let’s say you have an infinite MPS on a cylinder, and want to add nearestneighbor hopping of fermions with the
FermionSite
. The cylinder axis is the xdirection of the lattice, so to put a flux through the cylinder, you want particles hopping around the cylinder to pick up a phase phi given by the external flux.>>> strength = 1. # hopping strength without external flux >>> phi = np.pi/4 # determines the external flux strength >>> strength_with_flux = self.coupling_strength_add_ext_flux(strength, dx, [0, phi]) >>> for u1, u2, dx in self.lat.pairs['nearest_neighbors']: ... self.add_coupling(strength_with_flux, u1, 'Cd', u2, 'C', dx) ... self.add_coupling(np.conj(strength_with_flux), u2, 'Cd', u1, 'C', dx)

classmethod
from_hdf5
(hdf5_loader, h5gr, subpath)[source]¶ Load instance from a HDF5 file.
This method reconstructs a class instance from the data saved with
save_hdf5()
.

group_sites
(n=2, grouped_sites=None)[source]¶ Modify self in place to group sites.
Group each n sites together using the
GroupedSite
. This might allow to do TEBD with a Trotter decomposition, or help the convergence of DMRG (in case of too long range interactions).This has to be done after finishing initialization and can not be reverted.
 Parameters
n (int) – Number of sites to be grouped together.
grouped_sites (None  list of
GroupedSite
) – The sites grouped together.
 Returns
grouped_sites – The sites grouped together.
 Return type
list of
GroupedSite

save_hdf5
(hdf5_saver, h5gr, subpath)[source]¶ Export self into a HDF5 file.
This method saves all the data it needs to reconstruct self with
from_hdf5()
.This implementation saves the content of
__dict__
withsave_dict_content()
, storing the format under the attribute'format'
. Parameters
hdf5_saver (
Hdf5Saver
) – Instance of the saving engine.h5gr (:class`Group`) – HDF5 group which is supposed to represent self.
subpath (str) – The name of h5gr with a
'/'
in the end.