MPSKit.jl

Efficient and versatile tools for working with matrix product states

Table of contents

Installation

MPSKit.jl is a part of the general registry, and can be installed via the package manager as:

pkg> add MPSKit

Key Features

  • Construction and manipulation of Matrix Product States (MPS)
  • Calculation of observables and expectation values
  • Various optimization methods for obtaining MPS fixed points
  • Support for both finite and infinite MPS
  • Support for wide variety of symmetries, including Abelian, non-Abelian, fermionic and anyonic symmetries

Usage

To get started with MPSKit, we recommend also including TensorKit.jl and MPSKitModels.jl. The former defines the tensor backend which is used throughout MPSKit, while the latter includes some common operators and models.

using TensorOperations
using TensorKit
using MPSKit
using MPSKitModels
using LinearAlgebra: norm

Finite Matrix Product States

Finite MPS are characterised by a set of tensors, one for each site, which each have 3 legs. They can be constructed by specifying the virtual spaces and the physical spaces, i.e. the dimensions of each of the legs. These are then contracted to form the MPS. In MPSKit, they are represented by FiniteMPS, which can be constructed either by passing in the tensors directly, or by specifying the dimensions of the legs.

d = 2 # physical dimension
D = 5 # virtual dimension
L = 10 # number of sites

mps = FiniteMPS(L, ComplexSpace(d), ComplexSpace(D)) # random MPS with maximal bond dimension D
10-site FiniteMPS:
┌ CL[11]: TensorMap(ℂ^1 ← ℂ^1)
├── AL[10]: TensorMap((ℂ^2 ⊗ ℂ^2) ← ℂ^1)
├── AL[9]: TensorMap((ℂ^4 ⊗ ℂ^2) ← ℂ^2)
├── AL[8]: TensorMap((ℂ^5 ⊗ ℂ^2) ← ℂ^4)
├── AL[7]: TensorMap((ℂ^5 ⊗ ℂ^2) ← ℂ^5)
├── AL[6]: TensorMap((ℂ^5 ⊗ ℂ^2) ← ℂ^5)
├── AL[5]: TensorMap((ℂ^5 ⊗ ℂ^2) ← ℂ^5)
├── AL[4]: TensorMap((ℂ^5 ⊗ ℂ^2) ← ℂ^5)
├── AL[3]: TensorMap((ℂ^4 ⊗ ℂ^2) ← ℂ^5)
├── AL[2]: TensorMap((ℂ^2 ⊗ ℂ^2) ← ℂ^4)
└── AL[1]: TensorMap((ℂ^1 ⊗ ℂ^2) ← ℂ^2)

The FiniteMPS object then handles the gauging of the MPS, which is necessary for many of the algorithms. This is done automatically when needed, and the user can access the gauged tensors by getting and setting the AL, AR, CR/CL and AC fields, which each represent a vector of these tensors.

al = mps.AL[3] # left gauged tensor of the third site
@tensor E[a; b] := al[c, d, b] * conj(al[c, d, a])
@show isapprox(E, id(left_virtualspace(mps, 3)))
true
ar = mps.AR[3] # right gauged tensor of the third site
@tensor E[a; b] := ar[a, d, c] * conj(ar[b, d, c])
@show isapprox(E, id(right_virtualspace(mps, 2)))
true

As the mps will be kept in a gauged form, updating a tensor will also update the gauged tensors. For example, we can set the tensor of the third site to the identity, and the gauged tensors will be updated accordingly.

mps.CR[3] = id(domain(mps.CR[3]))
println(mps)
┌── AR[10]: TensorMap((ℂ^2 ⊗ ℂ^2) ← ℂ^1)
├── AR[9]: TensorMap((ℂ^4 ⊗ ℂ^2) ← ℂ^2)
├── AR[8]: TensorMap((ℂ^5 ⊗ ℂ^2) ← ℂ^4)
├── AR[7]: TensorMap((ℂ^5 ⊗ ℂ^2) ← ℂ^5)
├── AR[6]: TensorMap((ℂ^5 ⊗ ℂ^2) ← ℂ^5)
├── AR[5]: TensorMap((ℂ^5 ⊗ ℂ^2) ← ℂ^5)
├── AR[4]: TensorMap((ℂ^5 ⊗ ℂ^2) ← ℂ^5)
│ CL[4]: TensorMap(ℂ^5 ← ℂ^5)
├── AL[3]: TensorMap((ℂ^4 ⊗ ℂ^2) ← ℂ^5)
├── AL[2]: TensorMap((ℂ^2 ⊗ ℂ^2) ← ℂ^4)
└── AL[1]: TensorMap((ℂ^1 ⊗ ℂ^2) ← ℂ^2)

These objects can then be used to compute observables and expectation values. For example, the expectation value of the identity operator at the third site, which is equal to the norm of the MPS, can be computed as:

N1 = LinearAlgebra.norm(mps)
N2 = expectation_value(mps, id(physicalspace(mps, 3)), 3)
println("‖mps‖ = $N1")
println("<mps|𝕀₃|mps> = $N2")
‖mps‖ = 2.2360679774997894
<mps|𝕀₃|mps> = 5.0 + 0.0im

Finally, the MPS can be optimized in order to determine groundstates of given Hamiltonians. Using the pre-defined models in MPSKitModels, we can construct the groundstate for the transverse field Ising model:

H = transverse_field_ising(; J=1.0, g=0.5)
find_groundstate!(mps, H, DMRG(; maxiter=10))
E0 = expectation_value(mps, H)
println("<mps|H|mps> = $(sum(real(E0)) / length(mps))")
[ Info: DMRG init:	obj = -2.346927993428e+00	err = 4.9914e-01
[ Info: DMRG   1:	obj = -9.765502508620e+00	err = 2.5252741271e-02	time = 0.49 sec
[ Info: DMRG   2:	obj = -9.765503492642e+00	err = 1.9026005711e-04	time = 0.47 sec
[ Info: DMRG   3:	obj = -9.765503493164e+00	err = 2.5708608350e-06	time = 0.04 sec
[ Info: DMRG   4:	obj = -9.765503493276e+00	err = 1.2153880042e-06	time = 0.04 sec
[ Info: DMRG   5:	obj = -9.765503493301e+00	err = 5.9059162042e-07	time = 0.04 sec
[ Info: DMRG   6:	obj = -9.765503493307e+00	err = 2.9108749615e-07	time = 0.03 sec
[ Info: DMRG   7:	obj = -9.765503493309e+00	err = 1.4448141411e-07	time = 0.03 sec
[ Info: DMRG   8:	obj = -9.765503493309e+00	err = 7.2605783958e-08	time = 0.03 sec
[ Info: DMRG   9:	obj = -9.765503493309e+00	err = 4.4411489827e-08	time = 0.03 sec
┌ Warning: DMRG cancel 10:	obj = -9.765503493309e+00	err = 2.7374557627e-08	time = 1.25 sec
└ @ MPSKit ~/work/MPSKit.jl/MPSKit.jl/src/algorithms/groundstate/dmrg.jl:48
<mps|H|mps> = -0.976550349330914

Infinite Matrix Product States

Similarly, an infinite MPS can be constructed by specifying the tensors for the unit cell, characterised by the spaces (dimensions) thereof.

d = 2 # physical dimension
D = 5 # virtual dimension
mps = InfiniteMPS(d, D) # random MPS
single site InfiniteMPS:
│   ⋮
│ CR[1]: TensorMap(ℂ^5 ← ℂ^5)
├── AL[1]: TensorMap((ℂ^5 ⊗ ℂ^2) ← ℂ^5)
│   ⋮

The InfiniteMPS object then handles the gauging of the MPS, which is necessary for many of the algorithms. This is done automatically upon creation of the object, and the user can access the gauged tensors by getting and setting the AL, AR, CR/CL and AC fields, which each represent a (periodic) vector of these tensors.

al = mps.AL[1] # left gauged tensor of the third site
@tensor E[a; b] := al[c, d, b] * conj(al[c, d, a])
@show isapprox(E, id(left_virtualspace(mps, 1)))
true
ar = mps.AR[1] # right gauged tensor of the third site
@tensor E[a; b] := ar[a, d, c] * conj(ar[b, d, c])
@show isapprox(E, id(right_virtualspace(mps, 2)))
true

As regauging the MPS is not possible without recomputing all the tensors, setting a single tensor is not supported. Instead, the user should construct a new mps object with the desired tensor, which will then be gauged upon construction.

als = 3 .* mps.AL
mps = InfiniteMPS(als)
single site InfiniteMPS:
│   ⋮
│ CR[1]: TensorMap(ℂ^5 ← ℂ^5)
├── AL[1]: TensorMap((ℂ^5 ⊗ ℂ^2) ← ℂ^5)
│   ⋮

These objects can then be used to compute observables and expectation values. For example, the norm of the MPS, which is equal to the expectation value of the identity operator can be computed by:

N1 = norm(mps)
N2 = expectation_value(mps, id(physicalspace(mps, 1)), 1)
println("‖mps‖ = $N1")
println("<mps|𝕀₁|mps> = $N2")
‖mps‖ = 1.0
<mps|𝕀₁|mps> = 0.9999999999999999 - 8.673617379884035e-19im
Normalization of infinite MPS

Because infinite MPS cannot sensibly be normalized to anything but $1$, the norm of an infinite MPS is always set to be $1$ at construction. If this were not the case, any observable computed from the MPS would either blow up to infinity or vanish to zero.

Finally, the MPS can be optimized in order to determine groundstates of given Hamiltonians. Using the pre-defined models in MPSKitModels, we can construct the groundstate for the transverse field Ising model:

H = transverse_field_ising(; J=1.0, g=0.5)
mps, = find_groundstate(mps, H, VUMPS(; maxiter=10))
E0 = expectation_value(mps, H)
println("<mps|H|mps> = $(sum(real(E0)) / length(mps))")
[ Info: VUMPS init:	obj = -4.894302661392e-01	err = 4.3647e-01
[ Info: VUMPS   1:	obj = -1.062852073000e+00	err = 2.2851566865e-02	time = 0.01 sec
[ Info: VUMPS   2:	obj = -1.063544408716e+00	err = 2.8801236035e-05	time = 0.00 sec
[ Info: VUMPS   3:	obj = -1.063544409973e+00	err = 1.0300050282e-07	time = 0.00 sec
[ Info: VUMPS   4:	obj = -1.063544409973e+00	err = 1.1520572923e-08	time = 0.00 sec
[ Info: VUMPS   5:	obj = -1.063544409973e+00	err = 1.2594311089e-09	time = 0.00 sec
[ Info: VUMPS   6:	obj = -1.063544409973e+00	err = 1.3557582790e-10	time = 0.00 sec
[ Info: VUMPS   7:	obj = -1.063544409973e+00	err = 1.4617591222e-11	time = 0.00 sec
[ Info: VUMPS   8:	obj = -1.063544409973e+00	err = 1.5981333288e-12	time = 0.00 sec
[ Info: VUMPS conv 9:	obj = -1.063544409973e+00	err = 3.3674051898e-13	time = 0.03 sec
<mps|H|mps> = -1.0635444099732507

Additional Resources

For more detailed information on the functionality and capabilities of MPSKit, refer to the Manual section, or have a look at the Examples page.

Keep in mind that the documentation is still a work in progress, and that some features may not be fully documented yet. If you encounter any issues or have questions, please check the library's issue tracker on the GitHub repository and open a new issue.

Publications using MPSKit

Below you can find a list of publications that have made use of MPSKit. If you have used this package and wish to have your publication added to this list, please open a pull request or an issue on the GitHub repository.

  • R. Belyansky et al., “High-Energy Collision of Quarks and Hadrons in the Schwinger Model: From Tensor Networks to Circuit QED,” 2023, doi: 10.48550/ARXIV.2307.02522.
  • L. Devos, L. Vanderstraeten, and F. Verstraete, “Haldane gap in the SU(3) [3 0 0] Heisenberg chain,” Phys. Rev. B, vol. 106, no. 15, p. 155103, Oct. 2022, doi: 10.1103/PhysRevB.106.155103.
  • J. C. Halimeh, M. V. Damme, T. V. Zache, D. Banerjee, and P. Hauke, “Achieving the quantum field theory limit in far-from-equilibrium quantum link models,” Quantum, vol. 6, p. 878, Dec. 2022, doi: 10.22331/q-2022-12-19-878.
  • J. C. Halimeh, D. Trapin, M. Van Damme, and M. Heyl, “Local measures of dynamical quantum phase transitions,” Phys. Rev. B, vol. 104, no. 7, p. 075130, Aug. 2021, doi: 10.1103/PhysRevB.104.075130.
  • M. Hauru, M. Van Damme, and J. Haegeman, “Riemannian optimization of isometric tensor networks,” SciPost Physics, vol. 10, no. 2, p. 040, Feb. 2021, doi: 10.21468/SciPostPhys.10.2.040.
  • M. Van Damme, R. Vanhove, J. Haegeman, F. Verstraete, and L. Vanderstraeten, “Efficient matrix product state methods for extracting spectral information on rings and cylinders,” Phys. Rev. B, vol. 104, no. 11, p. 115142, Sep. 2021, doi: 10.1103/PhysRevB.104.115142.
  • M. Van Damme, T. V. Zache, D. Banerjee, P. Hauke, and J. C. Halimeh, “Dynamical quantum phase transitions in spin-$S$ $\text{U}(1)$ quantum link models,” Phys. Rev. B, vol. 106, no. 24, p. 245110, Dec. 2022, doi: 10.1103/PhysRevB.106.245110.
  • E. L. Weerda and M. Rizzi, “Fractional quantum Hall states with variational Projected Entangled-Pair States: a study of the bosonic Harper-Hofstadter model,” 2023, doi: 10.48550/ARXIV.2309.12811.
  • C. Yu and J.-W. Lee, “Closing of the Haldane gap in a spin-1 XXZ chain,” J. Korean Phys. Soc., vol. 79, no. 9, pp. 841–845, Nov. 2021, doi: 10.1007/s40042-021-00283-z.
  • Y. Zhang, A. Hulsch, H.-C. Zhang, W. Tang, L. Wang, and H.-H. Tu, “Universal Scaling of Klein Bottle Entropy near Conformal Critical Points,” Phys. Rev. Lett., vol. 130, no. 15, p. 151602, Apr. 2023, doi: 10.1103/PhysRevLett.130.151602.