Harvesting the power of tensor networks to represent high-dimensional probability distributions as Matrix Product States.
In this python package, we develop Matrix Product State (MPS) representations for probability distributions over all
- In
stochasticTNwe use the density matrix renormalization group (DMRG) algorithm to find steady state distribution of$2^n$ -dimensional Markov generators. - In
spinmodelTNwe construct MPS representations of the$2^n$ dimensional probability distributions of spin models with arbitrary higher-order interactions.
The MPS allows us to find efficient and accurate representations for the steady state distributions over all
One example where we apply these methods is the SIS model of infectious disease spreading. We use this to study rare events, the large deviation statistics and characterize the active-inactive phase transition using information measures in the following paper:
Efficient simulations of epidemic models with tensor networks: application to the one-dimensional SIS model Wout Merbis, Clélia de Mulatier, Philippe Corboz arxiv/2305.06815
We refer to there and the example notebook Examples.ipynb for more information on the large deviation statistics on the SIS model in one-dimension. In the notebook Network_example.ipynb we showcase an example based on using DMRG to find the non-equilibrium steady state of the SIS model on networks.
Code base for performing computations with Matrix Product State (MPS, sometimes called tensor trains) representations of large probability distributions. It is divided into several files.
mps.py defines the MPS class for the stochasticTN package defining the MPS object with attributes:
.tensorsgives a list of the MPS tensors. All tensors are rank-3 tensors with index structure (left, physical, right)..centergives the location of the center node in the mixed canonical representation of the mps (all tensors to the left and right of 'center' are unitary matrices w.r.t. contraction from the left/right respectively).nameoptional name for the mps.bond_dimensionsgives a list of bond dimensions of the MPS.physical_dimensionsgives a list of physical dimensions of the MPS The MPS object is iterable, where iterating the MPS means iterating over MPS.tensors. Its lengthlen()is defined as the number of sites in the MPS
mps.py contains many methods which are convenient for computations. Most notably:
-
.position(site)moves themps.centerto the specified site by series of singular value decompositions. Specifyingnormalize_SVs = Truerescales all singular values to form a distribution which sums to 1. SpecifyingDmaxorcutofftruncates the singular value spectrum to maximallyDmaxSVs with magnitude abovecutoff -
.canonicalize()puts the MPS in canonical form with respect to the left-most site (0) such that all tensors on the right are unitaries. Specifyingnormalize_SVs = Truerescales all singular values to form a distribution which sums to 1. SpecifyingDmaxorcutofftruncates the singular value spectrum to maximallyDmaxSVs with magnitude abovecutoff -
.norm()returns the norm of the MPS. There are two protocols for computing the norm:cx = 'stoch'computes the$$L^1$$ norm (default),cx = 'complex'computes the$$L^2$$ norm for complex valued MPS tensors -
.probabilties()returns all$$2^n$$ probabilities as computed from the MPS, so this is exponentially costly. Raises a ValueError whenlen(MPS)>28 -
.save('name')saves the MPS tensors and attributes in local folder "/MPSs/name/" -
.sample_array()returns an array sampled according to the probability distribution represented by the MPS
Additionally mps.py contains functions for creating some frequently used MPS objects. Most notably:
randomMPS(N, D): creates a random MPS of lengthNwith maximal bond dimensionDoccupied_mps(N,D): creates an MPS where all sites are in the occupied stateuniform_mps(N,D): creates an MPS representing the uniform distribution over all configurationsmps_from_array(array): creates an MPS with bond dimension 1 from an array of numbers between 0 and 1loadMPS('name'): loads an MPS from file which was saved using the.save()method
Here we define the MPO object for the stochasticTN package. It has as main attributes and methods:
MPO.tensors: A list of MPS tensors with length N and index structure (left, down, up, right)MPO.center: Location of orthogonality site of the MPO. Can be moved withMPO.position(site)MPO.bond_dimensionslist of local bond dimensions with length N + 1MPO.physical_dimensions: gives list of physical dimensions of the MPOMPO.canonicalize(): puts the MP) in canonical form with respect to the left-most site (0) such that all tensors on the right are unitaries. Specifyingnormalize_SVs = Truerescales all singular values to form a distribution which sums to 1. SpecifyingDmaxorcutofftruncates the singular value spectrum to maximallyDmaxSVs with magnitude abovecutoff
It furthermore contains several functions to construct the MPO representation of various infinitesimal Markov generators or MPOs which are useful for computing observables when contracted with the MPS
SIS_MPO(N,r,s,driving, omega): constructs the Markov generator for the SIS process on a 1-dimensional lattice, Arguments are:N: length of MPOr: effective transmission rate between nearest-neighborss: tilting parameter for the dynamical activitydriving: driving protocol. Choose from 'boundary', 'right boundary', 'left boundary', 'absorbing', 'spontaneous'omega: infection rate for the driving term
network_SIS(A,r,s,epsilon,cutoff): constructs the MPO for the SIS model on a network. Arguments:A: network adjacency matrix as 2-dimensional array. Edge weights are accounted for such that the transmission probability is rA[i,j] from nodes i to j and rA[j,i] from node j to ir: effective transmission rate between nearest neighborss: tilting parameter for the dynamical activityepsilon: spontaneous infection ratecutoff: optional size of minimal bond dimensions to keep when compressing the final MPO
occupancy_MPO(N): constructs an MPO of lengthNwhich projects on the occupied state. Its expectation value gives the expected number of occupied sites in the MPSgapMPO(N,k): constructs an MPO of lengthNwhich projects on all configurations withkvacant sites in a rowproject_on_k_infected(N,k): Builds an MPO of lengthNwhich projects on all configurations withkinfected (occupied) sitesproject_on_k_healthy(N,k): Builds an MPO of lengthNwhich projects on all configurations withkhealthy (vacant) sites
Defines the DMRG class used for running the DMRG algorithm which enables one to find the non-equilibrium steady state of Markov processes and to compute the scaled cumulant generating function for the dynamical activity in those processes as the leading eigenvalue of the tilted Markov generators.
The DMRG object itself is defined by specifying an MPS object to initiate the DMRG with and an MPO object whose leading eigenvector is sought in MPS form. Optionally, one can specify a left and right environment. The DMRG algorithm is run by calling:
-
DMRG.run_single_site_dmrg()Runs the DMRG algorithm by optimizing single sites in the mps. Arguments are:MaxSweeps: maximal number of sweepsaccuracy: Global accuracy as convergence criteria for the variance in energytol: Relative accuracy for local eigenvalues (stopping criterion)Dmax: maximal number of bond dimensions to keep per sitecutoff: maximal absolute value for the singular values, SVs below this value are droppedncv: The number of Lanczos vectors for the single site optimizationverbose: Boolean, if True will print the sweep results
Returns:
energy: eigenvalue of the MPO (returns the density if tilting parameter s=0)variance: variance in the eigenvalue (returns variance in density if tilting parameter s=0)truncation_error: size of the singular values discarded during the final sweepconverged: Boolean, returns True if the algorithm has converged, False otherwise
-
DMRG.run_double_site_dmrg()Runs the DMRG algorithm by optimizing two adjacent sites in the mps at the same time. This allows for dynamical adjustment of the MPS bond dimensions. Argumments are the same as for the single site updates.
This file contains several functions which are convenient for performing computations using the MPS and MPO. Most notably:
-
overlap(mps1, mps2): computes the overlap betweenmps1andmps2 -
MPOexpectation(mps,mpo): computes the expectation value of thempoon themps. Specifycx = 'stoch'for the$$L^1$$ expectation value (default) andcx = 'complex'for the$$L^2$$ expectation value -
MPSvariance(mps, mpo): computes the variance of an MPO as the expectation value of the square of the MPO. Specifycx = 'stoch'for the$$L^1$$ expectation value (default) andcx = 'complex'for the$$L^2$$ expectation value -
MPSMPOcontraction(mps, mpo): contracts the mps with an mpo site by site. Optionally performs truncation ifrenormalizeis True. Overwrites mps with the contracted result. SpecifyDmaxandcutoffto truncate to a maximum ofDmaxsingular values with values abovecutoff. -
MPOMPOcontraction(mpo1, mpo2): contracts the mpo1 with mpo2 site by site. Optionally performs truncation ifrenormalizeis True. Overwrites mps with the contracted result. SpecifyDmaxandcutoffto truncate to a maximum ofDmaxsingular values with values abovecutoff. -
single_site_occupancy(mps, site): computes the expectation value forsiteto be occupied -
single_site_vacancy(mps, site): computes the expectation value forsiteto be empty -
single_site_magnetization(mps, site): computes the magnetization expectation value forsite -
marginal(mps, sites): computes the marginal distribution over the sites specified in the arraysites -
compute_pk_infected(mps): returns a list of N+1 elements whose k-th component is the probability of having exactly k occupied in the mps -
find_permutation(L): returns the permutation which brings MPS into the optimal ordering. Based on the first Fielder vector of the graph LaplacianL.
Collects various functions which compute information theoretic quantities from the MPS representation. It contains:
ShannonE(mps): computes the Shannon entropy of the complete distribution. Note that this is exponentially costly in the number of MPS sites so only use for small MPS (n<28)mutual_information(mps, site): Computes the mutual information between the halves of the system, separated atsite. Also exponentially costly as it uses the full distributionsingular_value_entropy(mps, site): computes the entropy of the singular value spectrum of the bond right ofsite. Usemethod='square'to get the entropy of the squares of the SVs (default),method = 'linear'gives the entropy of the SV distribution directlysecond_Renyi_entropy(mps): computes the second Renyi entropy based on the MPSsecond_Renyi_EE(mps,site): computes the second Renyi entanglement entropy across the bond to the right ofsitesecond_Renyi_MI(mps,site): Computes the second Renyi mutual information in the MPS across the bond right ofsiteMI_matrix(mps): Computes the matrix of pairwise mutual information between the nodes
This file essentially only contains a costum singular value decomposition function which is able to handle tensors of any shape and allows from the trunctation of the singular value spectrum up to keeping a maximal of Dmax singular values above a fixed threshold set by cutoff.
The spin model Tensor network library is still very much under development. It builds on the stochasticTN code base to create MPS and Tree Tensor Networks (TTN) for probability distributions over spin models with (arbitrary) higher-order interactions.