# TransferMatrix

Inheritance Diagram

Methods

 TransferMatrix.__init__(bra, ket[, ...]) Return the hermitian conjugate of self TransferMatrix.eigenvectors(*args, **kwargs) Find (dominant) eigenvector(s) of self using scipy.sparse. TransferMatrix.from_Ns_Ms(bra_N, ket_M[, ...]) Initialize a TransferMatrix directly from the MPS tensors. Return a diagonal matrix as initial guess for the eigenvector. Given vec as an npc.Array, apply the transfer matrix. Contract self to a matrix.

Class Attributes and Properties

 TransferMatrix.acts_on TransferMatrix.charge_sector
class tenpy.networks.mps.TransferMatrix(bra, ket, shift_bra=0, shift_ket=0, transpose=False, charge_sector=0, form='B')[source]

Transfer matrix of two MPS (bra & ket).

For an iMPS in the thermodynamic limit, we often need to find the ‘dominant RP’ (and LP). This mean nothing else than to take the transfer matrix of the unit cell and find the (right/left) eigenvector with the largest (magnitude) eigenvalue, since it will dominate $$(TM)^n RP$$ (or $$LP (TM)^n$$) in the limit $$n \rightarrow \infty$$ - whatever the initial RP is. This class provides exactly that functionality with eigenvectors().

Given two MPS, we define the transfer matrix as:

|    ---M[i]---M[i+1]- ... --M[i+L]---
|       |      |             |
|    ---N[j]*--N[j+1]* ... --N[j+L]*--


Here the N denotes the matrices of the bra and M the ones of the ket, respectively. To view it as a matrix, we combine the left and right indices to pipes:

|  (vL.vL*) ->-TM->- (vR.vR*)   acting on  (vL.vL*) ->-RP


Note that we keep all M and N as copies.

Changed in version 1.0: shift_bra defaults to 0 rather than shift_ket.

Parameters:
• bra (MPS) – The MPS which is to be (complex) conjugated.

• ket (MPS) – The MPS which is not (complex) conjugated.

• shift_bra (int) – We start the N of the bra at site shift_bra (i.e. the j in the above network).

• shift_ket (int) – We start the M of the ket at site shift_ket (i.e. the i in the above network).

• transpose (bool) – Whether self.matvec acts on RP (False) or LP (True).

• charge_sector (None | charges | 0) – Selects the charge sector of the vector onto which the Linear operator acts. None stands for all sectors, 0 stands for the zero-charge sector. Defaults to 0, i.e., assumes the dominant eigenvector is in charge sector 0. Note that you can update the charge_sector after initialization via the charge_sector property.

• form ('B' | 'A' | 'C' | 'G' | 'Th' | None | tuple(float, float)) – In which canonical form we take the M and N matrices.

L

Number of physical sites involved in the transfer matrix, i.e. the least common multiple of bra.L and ket.L.

Type:

int

shift_bra

We start the N of the bra at site shift_bra.

Type:

int

shift_ket

We start the M of the ket at site shift_ket.

Type:

int

transpose

Whether self.matvec acts on RP (True) or LP (False).

Type:

bool

qtotal

Total charge of the transfer matrix (which is gauged away in matvec).

Type:

charges

form

In which canonical form (all of) the M and N matrices are.

Type:

tuple(float, float) | None

flat_linop

Class lifting matvec() to ndarrays in order to use speigs().

Type:

FlatLinearOperator

pipe

Pipe corresponding to '(vL.vL*)' for transpose=False or to '(vR.vR*)' for transpose=True.

Type:

LegPipe

label_split

['vL', 'vL*'] if transpose=False or ['vR', 'vR*'] if transpose=True.

_bra_N

Complex conjugated matrices of the bra, transposed for fast matvec.

Type:

list of npc.Array

_ket_M

The matrices of the ket, transposed for fast matvec.

Type:

list of npc.Array

classmethod from_Ns_Ms(bra_N, ket_M, transpose=False, charge_sector=0, p_label=['p'])[source]

Initialize a TransferMatrix directly from the MPS tensors.

Parameters:
• bra_N (list of Array) – Plain tensors of the bra and ket, in a list going left to right, the bra not conjugated.

• ket_M (list of Array) – Plain tensors of the bra and ket, in a list going left to right, the bra not conjugated.

• transpose (bool) – Whether self.matvec acts on RP (False) or LP (True).

• charge_sector (None | charges | 0) – Selects the charge sector of the vector onto which the Linear operator acts. None stands for all sectors, 0 stands for the zero-charge sector. Defaults to 0, i.e., assumes the dominant eigenvector is in charge sector 0.

• p_label (list of str) – Physical label(s) of the tensors.

matvec(vec)[source]

Given vec as an npc.Array, apply the transfer matrix.

Parameters:

vec (Array) – Vector to act on with the transfermatrix. If not transposed, vec is the right part RP of an environment, with legs '(vL.vL*)' in a pipe or splitted. If transposed, the left part LP of an environment with legs '(vR*.vR)'.

Returns:

mat_vec – The transfer matrix acted on vec, in the same form as given.

Return type:

Array

initial_guess(diag=1.0)[source]

Return a diagonal matrix as initial guess for the eigenvector.

Parameters:

diag (float | 1D ndarray) – Should be 1. for the identity or some singular values squared.

Returns:

mat – A 2D array with diag on the diagonal such that matvec() can act on it.

Return type:

Array

eigenvectors(*args, **kwargs)[source]

Find (dominant) eigenvector(s) of self using scipy.sparse.

For arguments see eigenvectors().

If no charge_sector was selected, we look in all charge sectors. The returned eigenvectors have combined legs '(vL.vL*)' or (vR*.vR).

Return the hermitian conjugate of self

If self is hermitian, subclasses can choose to implement this to define the adjoint operator of self.

to_matrix()[source]

Contract self to a matrix.

If self represents an operator with very small shape, e.g. because the MPS bond dimension is very small, an algorithm might choose to contract self to a single tensor.

Returns:

matrix – Contraction of the represented operator.

Return type:

Array