From 2cf24e439dce4a719f8532aa216e96515f5cd85e Mon Sep 17 00:00:00 2001 From: lkdvos Date: Tue, 30 Jun 2026 17:57:01 -0400 Subject: [PATCH 01/76] docs(wave1): lib/public.md Add the curated public-API contract page (grouped @ref links to the canonical docstrings) and expand the Library nav section in make.jl to hold the new per-category reference pages alongside the existing full index (lib/lib.md, now anchored as @id lib_index). Content-neutral: lib/lib.md stays the canonical @autodocs catch-all. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/make.jl | 8 ++++- docs/src/lib/lib.md | 2 +- docs/src/lib/public.md | 73 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 docs/src/lib/public.md diff --git a/docs/make.jl b/docs/make.jl index 5922e4ee3..a9c8fcee9 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -57,7 +57,13 @@ makedocs(; "man/lattices.md", ], "Examples" => "examples/index.md", - "Library" => "lib/lib.md", + "Library" => [ + "lib/public.md", + "lib/states.md", + "lib/operators.md", + "lib/groundstate.md", + "lib/lib.md", + ], "References" => "references.md", "Changelog" => "changelog.md", ], diff --git a/docs/src/lib/lib.md b/docs/src/lib/lib.md index b1645c273..7f7b23eb0 100644 --- a/docs/src/lib/lib.md +++ b/docs/src/lib/lib.md @@ -1,4 +1,4 @@ -# Library documentation +# [Library documentation](@id lib_index) ```@autodocs Modules = [MPSKit] diff --git a/docs/src/lib/public.md b/docs/src/lib/public.md new file mode 100644 index 000000000..85bdac341 --- /dev/null +++ b/docs/src/lib/public.md @@ -0,0 +1,73 @@ +# [Public API](@id public_api) + +This page is the curated, stable public API surface of MPSKit — the symbols that +are exported and intended for direct use. Each entry links to its full docstring +in the [Library](@ref lib_index) index. The category reference pages +([States](@ref lib_states), [Operators](@ref lib_operators), +[Ground-state algorithms](@ref lib_groundstate)) group the same docstrings by +topic. + +!!! note + Anything not listed here (or marked internal in the [Library](@ref lib_index) index) is + not part of the public API and may change without notice. + +## States + +[`FiniteMPS`](@ref), [`InfiniteMPS`](@ref), [`WindowMPS`](@ref), +[`MultilineMPS`](@ref) + +## Operators and Hamiltonians + +[`AbstractMPO`](@ref), [`MPO`](@ref), [`FiniteMPO`](@ref), [`InfiniteMPO`](@ref), +[`MultilineMPO`](@ref), [`MPOHamiltonian`](@ref), [`FiniteMPOHamiltonian`](@ref), +[`InfiniteMPOHamiltonian`](@ref), [`JordanMPOTensor`](@ref), +[`MultipliedOperator`](@ref), [`TimedOperator`](@ref), +[`UntimedOperator`](@ref), [`LazySum`](@ref) + +## Environments + +[`environments`](@ref) + +## Ground states and boundaries + +[`find_groundstate`](@ref), [`leading_boundary`](@ref), [`approximate`](@ref), +[`VUMPS`](@ref), [`VOMPS`](@ref), [`DMRG`](@ref), [`DMRG2`](@ref), +[`IDMRG`](@ref), [`IDMRG2`](@ref), [`GradientGrassmann`](@ref) + +## Bond dimension + +[`changebonds`](@ref), [`OptimalExpand`](@ref), [`RandExpand`](@ref), +[`SvdCut`](@ref), [`VUMPSSvdCut`](@ref) + +## Time evolution + +[`time_evolve`](@ref), [`timestep`](@ref), [`make_time_mpo`](@ref), +[`TDVP`](@ref), [`TDVP2`](@ref), [`WI`](@ref), [`WII`](@ref), +[`TaylorCluster`](@ref) + +## Excitations + +[`excitations`](@ref), [`FiniteExcited`](@ref), [`QuasiparticleAnsatz`](@ref), +[`ChepigaAnsatz`](@ref), [`ChepigaAnsatz2`](@ref) + +## Linear problems and spectral functions + +[`propagator`](@ref), [`DynamicalDMRG`](@ref), [`NaiveInvert`](@ref), +[`Jeckelmann`](@ref), [`exact_diagonalization`](@ref), +[`fidelity_susceptibility`](@ref) + +## Observables and analysis + +[`expectation_value`](@ref), [`correlator`](@ref), [`variance`](@ref), +[`correlation_length`](@ref), [`marek_gap`](@ref), [`transfer_spectrum`](@ref), +[`entropy`](@ref), [`entanglement_spectrum`](@ref) + +## Boundary conditions + +[`open_boundary_conditions`](@ref), [`periodic_boundary_conditions`](@ref) + +## Utility + +[`PeriodicArray`](@ref), [`PeriodicVector`](@ref), [`PeriodicMatrix`](@ref), +[`WindowArray`](@ref), [`left_virtualspace`](@ref), [`right_virtualspace`](@ref), +[`physicalspace`](@ref), [`braille`](@ref) From e5281d2c7844b6561a11462cf5452bf7e0e62292 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Tue, 30 Jun 2026 17:57:01 -0400 Subject: [PATCH 02/76] docs(wave1): lib/states.md Category reference for the MPS state types via @docs; canonical=false (canonical home remains lib/lib.md), mirroring the man/algorithms.md convention. Quasiparticle types omitted pending docstrings (REVIEW flag). Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/src/lib/states.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 docs/src/lib/states.md diff --git a/docs/src/lib/states.md b/docs/src/lib/states.md new file mode 100644 index 000000000..6116b055c --- /dev/null +++ b/docs/src/lib/states.md @@ -0,0 +1,19 @@ +# [States](@id lib_states) + +Reference for the matrix product state types. The full, canonical docstrings for +the whole package live in the [Library](@ref lib_index) index. + +## Matrix product states + +```@docs; canonical=false +FiniteMPS +InfiniteMPS +WindowMPS +MultilineMPS +``` + + + From 2d56fc4ce244879bf319114173010dfa81781349 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Tue, 30 Jun 2026 17:57:01 -0400 Subject: [PATCH 03/76] docs(wave1): lib/operators.md Category reference for MPO and Hamiltonian types via @docs; canonical=false. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/src/lib/operators.md | 41 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 docs/src/lib/operators.md diff --git a/docs/src/lib/operators.md b/docs/src/lib/operators.md new file mode 100644 index 000000000..57c755856 --- /dev/null +++ b/docs/src/lib/operators.md @@ -0,0 +1,41 @@ +# [Operators](@id lib_operators) + +Reference for matrix product operators and Hamiltonians. The full, canonical +docstrings for the whole package live in the [Library](@ref lib_index) index. + +## Matrix product operators + +```@docs; canonical=false +AbstractMPO +MPO +FiniteMPO +InfiniteMPO +MultilineMPO +``` + +## Hamiltonians + +```@docs; canonical=false +MPOHamiltonian +FiniteMPOHamiltonian +InfiniteMPOHamiltonian +``` + +## Jordan-block MPO tensors + +```@docs; canonical=false +JordanMPOTensor +``` + + + + +## Operator algebra + +```@docs; canonical=false +MultipliedOperator +TimedOperator +UntimedOperator +LazySum +``` From b191b84c452ce448e6000f9faffb8059e7814e0e Mon Sep 17 00:00:00 2001 From: lkdvos Date: Tue, 30 Jun 2026 17:57:02 -0400 Subject: [PATCH 04/76] docs(wave1): lib/groundstate.md Category reference for the ground-state interface and algorithms via @docs; canonical=false. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/src/lib/groundstate.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 docs/src/lib/groundstate.md diff --git a/docs/src/lib/groundstate.md b/docs/src/lib/groundstate.md new file mode 100644 index 000000000..d4c9b8dbc --- /dev/null +++ b/docs/src/lib/groundstate.md @@ -0,0 +1,22 @@ +# [Ground-state algorithms](@id lib_groundstate) + +Reference for the ground-state search interface and its algorithms. For a +task-oriented walkthrough see the how-to guides; the full, canonical docstrings +for the whole package live in the [Library](@ref lib_index) index. + +## Interface + +```@docs; canonical=false +find_groundstate +``` + +## Algorithms + +```@docs; canonical=false +DMRG +DMRG2 +VUMPS +IDMRG +IDMRG2 +GradientGrassmann +``` From aa7b1913bfee351f6b6aa8cd3a44d87d64c62c6b Mon Sep 17 00:00:00 2001 From: lkdvos Date: Tue, 30 Jun 2026 18:28:26 -0400 Subject: [PATCH 05/76] docs(wave1): howto/states.md Add a how-to guide with runnable recipes for constructing FiniteMPS, InfiniteMPS, WindowMPS, and MultilineMPS (random/initializer/element-type, product states, from tensors, multi-site unit cells, and U(1)-symmetric states), and introduce the How-to nav section in make.jl. All examples are @example blocks verified by the full build. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/make.jl | 3 + docs/src/howto/states.md | 326 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 329 insertions(+) create mode 100644 docs/src/howto/states.md diff --git a/docs/make.jl b/docs/make.jl index a9c8fcee9..5909b6c95 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -56,6 +56,9 @@ makedocs(; "man/parallelism.md", "man/lattices.md", ], + "How-to" => [ + "howto/states.md", + ], "Examples" => "examples/index.md", "Library" => [ "lib/public.md", diff --git a/docs/src/howto/states.md b/docs/src/howto/states.md new file mode 100644 index 000000000..22aa1a861 --- /dev/null +++ b/docs/src/howto/states.md @@ -0,0 +1,326 @@ +# [Constructing states](@id howto_states) + +This page collects recipes for building [`FiniteMPS`](@ref), +[`InfiniteMPS`](@ref), [`WindowMPS`](@ref), and [`MultilineMPS`](@ref) objects. +All constructors live in the `MPSKit` namespace; the examples below assume + +```@example howto_states +using MPSKit, TensorKit +``` + +For background on what these types represent and how gauging works, see the +[States](@ref lib_states) reference page. + +--- + +## 1. A finite MPS from length, physical space, and maximum bond dimension + +The most common starting point: give the chain length `N`, the local physical +`VectorSpace`, and the maximum allowed virtual space. +The constructor fills the tensors with random `ComplexF64` entries and trims the +actual bond dimensions to full rank, so passing an over-large `maxVspace` is safe. + +```@example howto_states +L = 10 +d = ℂ^2 # spin-1/2 physical space (dim 2) +D = ℂ^16 # maximum bond dimension + +ψ = FiniteMPS(L, d, D) +``` + +Inspect the resulting virtual spaces with `left_virtualspace` and `right_virtualspace`. +To get the numeric bond dimension at bond `i` use `dim`: + +```@example howto_states +dim(left_virtualspace(ψ, 3)) # bond dimension between sites 2 and 3 +``` + +```@example howto_states +physicalspace(ψ, 1) # local Hilbert space at site 1 +``` + +--- + +## 2. Choosing the initializer and element type + +Pass an initializer function (`rand` or `randn`) and an element type +as the first two arguments: + +```@example howto_states +ψ_rand = FiniteMPS(rand, ComplexF64, L, d, D) # default — same as FiniteMPS(L, d, D) +ψ_randn = FiniteMPS(randn, ComplexF64, L, d, D) # normally distributed entries +``` + +The element type sets the scalar type of the tensors, e.g. `ComplexF64` (the +default) or `Float64` for a real-valued state. + +--- + +## 3. Per-site physical and virtual spaces + +When the physical space varies from site to site — or you want fine control over +which bond gets which maximum dimension — pass vectors instead of scalars. +The `maxVspaces` vector must have length `N - 1` (one entry per bond): + +```@example howto_states +Pspaces = [ℂ^2, ℂ^3, ℂ^2, ℂ^3, ℂ^2] # alternating physical spaces +maxVspaces = [ℂ^8, ℂ^8, ℂ^8, ℂ^8] # one per bond (length N-1) + +ψ_het = FiniteMPS(rand, ComplexF64, Pspaces, maxVspaces) +``` + +```@example howto_states +physicalspace(ψ_het, 2) # ℂ^3 +``` + +--- + +## 4. A product state (trivial virtual space) + +A product (bond-dimension-1) state has no entanglement. +Achieve this by passing `oneunit(d)` — the one-dimensional unit space of the same +symmetry sector — as the maximum virtual space: + +```@example howto_states +ψ_prod = FiniteMPS(rand, ComplexF64, L, ℂ^2, oneunit(ℂ^2)) +dim(left_virtualspace(ψ_prod, 5)) # should be 1 +``` + +!!! note + `oneunit(V)` returns the one-dimensional trivial space matching the symmetry + type of `V`. + For plain complex spaces, `oneunit(ℂ^2) == ℂ^1`. + + + +--- + +## 5. From your own site tensors + +If you already have a vector of `TensorMap` objects with the correct index +structure (virtual ⊗ physical ← virtual), pass them directly. +The constructor performs a left-to-right QR sweep to bring the state into a +canonical form: + +```@example howto_states +# build three-site rank-1 tensors by hand +site_tensors = [rand(ComplexF64, ℂ^1 ⊗ ℂ^2 ← ℂ^1) for _ in 1:L] +ψ_from_tensors = FiniteMPS(site_tensors) +``` + +Set `normalize=true` to also normalise the state during construction +(the default is `false` when passing raw tensors): + +```@example howto_states +ψ_normed = FiniteMPS(site_tensors; normalize=true) +``` + +--- + +## 6. An infinite MPS + +### Scalar convenience form + +Provide `d` and `D` as integers or spaces; the constructor builds a single-site +unit cell: + +```@example howto_states +ψ_inf = InfiniteMPS(2, 20) # integers → plain ComplexSpace dimensions +``` + +```@example howto_states +ψ_inf2 = InfiniteMPS(ℂ^2, ℂ^20) # same, spelled out as spaces +``` + +### Multi-site unit cell + +Pass vectors of physical and virtual spaces. +The virtual spaces are those to the *right* of the corresponding sites: + +```@example howto_states +ψ_2site = InfiniteMPS([ℂ^2, ℂ^2], [ℂ^20, ℂ^20]) +``` + +```@example howto_states +physicalspace(ψ_2site, 1) +``` + +```@example howto_states +right_virtualspace(ψ_2site, 1) # virtual space to the right of site 1 +``` + +### Choosing element type and initializer + +```@example howto_states +ψ_inf_r = InfiniteMPS(rand, Float64, [ℂ^2], [ℂ^10]) +``` + +### From site tensors + +Tensors must form a valid periodic chain (virtual spaces must match across the +unit-cell boundary): + +```@example howto_states +inf_tensors = [rand(ComplexF64, ℂ^4 ⊗ ℂ^2 ← ℂ^4)] +ψ_inf_t = InfiniteMPS(inf_tensors) +``` + +--- + +## 7. A window MPS + +A [`WindowMPS`](@ref) embeds a mutable finite window inside two infinite +environments. + +### Slice an existing InfiniteMPS + +The simplest route: pick a region of length `L` from an `InfiniteMPS`. +Both environments are set to the same object (the original infinite state): + +```@example howto_states +ψ_bulk = InfiniteMPS(ℂ^2, ℂ^8) +ψ_win = WindowMPS(ψ_bulk, 6) # window of 6 sites +``` + +```@example howto_states +length(ψ_win) # 6 +``` + +### From space specifications + +Provide the window dimensions together with the infinite environments. +The boundary virtual spaces are taken automatically from `ψₗ`/`ψᵣ`: + +```@example howto_states +ψ_win2 = WindowMPS(rand, ComplexF64, 6, ℂ^2, ℂ^8, ψ_bulk) +``` + +### From a FiniteMPS and two environments + +Build a `FiniteMPS` with matching boundary virtual spaces first, then wrap: + +```@example howto_states +finite_part = FiniteMPS(6, ℂ^2, ℂ^8; left=ℂ^8, right=ℂ^8) +ψ_win3 = WindowMPS(ψ_bulk, finite_part, ψ_bulk) +``` + +!!! warning + When `ψᵣ` is omitted in the outer constructors, the right environment is + **the same object** as the left environment (no copy is made). + If you later evolve the two environments independently, pass `copy(ψ_bulk)` + explicitly as the right argument to avoid aliasing: + + ```julia + ψ_win_safe = WindowMPS(rand, ComplexF64, 6, ℂ^2, ℂ^8, ψ_bulk, copy(ψ_bulk)) + ``` + +--- + +## 8. A multiline MPS + +[`MultilineMPS`](@ref) stacks several [`InfiniteMPS`](@ref) rows and is used in +boundary-MPS methods for 2D classical partition functions. + +### From a vector of InfiniteMPS rows + +```@example howto_states +row1 = InfiniteMPS(ℂ^2, ℂ^8) +row2 = InfiniteMPS(ℂ^2, ℂ^8) +ψ_ml = MultilineMPS([row1, row2]) +``` + +Access tensors with Cartesian `[row, col]` indexing: + +```@example howto_states +ψ_ml.AL[1, 1] # left-gauged tensor of row 1, unit-cell site 1 +``` + +### From space matrices + +Pass matrices whose rows correspond to MPS rows and columns to unit-cell sites: + +```@example howto_states +pspaces = fill(ℂ^2, 2, 2) # 2 rows × 2-site unit cell +Dspaces = fill(ℂ^8, 2, 2) +ψ_ml2 = MultilineMPS(pspaces, Dspaces) +``` + +--- + +## 9. States with symmetries + +All constructors accept TensorKit graded spaces. +Pass a `Rep[G]` physical space and a `Rep[G]` maximum virtual space; the +constructor automatically selects the consistent fusion channels. + +### Finite MPS with U(1) symmetry + + + +```@example howto_states +# U(1) spin-1/2: physical space = spin up (charge +1/2) + spin down (charge -1/2) +d_u1 = Rep[U₁](1//2 => 1, -1//2 => 1) # dim 2 total +D_u1 = Rep[U₁](1//2 => 4, -1//2 => 4, 3//2 => 2, -3//2 => 2) + +ψ_u1 = FiniteMPS(rand, ComplexF64, L, d_u1, D_u1) +physicalspace(ψ_u1, 1) +``` + +```@example howto_states +dim(left_virtualspace(ψ_u1, 5)) # actual trimmed bond dimension ≤ dim(D_u1) +``` + +!!! note + The boundary virtual spaces default to `oneunit(spacetype(d_u1))`, i.e. the + charge-0 sector. + Use the `left` and `right` keywords to target a different total charge: + + ```julia + # state in total charge-sector +1 (one more up-spin than down-spin) + ψ_charged = FiniteMPS(rand, ComplexF64, L, d_u1, D_u1; + right = Rep[U₁](1 => 1)) + ``` + +### Infinite MPS with U(1) symmetry + +```@example howto_states +ψ_inf_u1 = InfiniteMPS(d_u1, D_u1) +physicalspace(ψ_inf_u1, 1) +``` + + + +--- + + From e7c2f6daa64e4972ec0bb3a17e4103906182d180 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Tue, 30 Jun 2026 18:58:27 -0400 Subject: [PATCH 06/76] docs(wave1): howto/bond_dimension.md Add a how-to guide for inspecting, growing (RandExpand/OptimalExpand), and reducing (SvdCut) bond dimension, truncation schemes, dynamic growth via DMRG2/IDMRG2 and find_groundstate(...; trscheme), and algorithm chaining with &. All examples verified by the full build. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/make.jl | 1 + docs/src/howto/bond_dimension.md | 359 +++++++++++++++++++++++++++++++ 2 files changed, 360 insertions(+) create mode 100644 docs/src/howto/bond_dimension.md diff --git a/docs/make.jl b/docs/make.jl index 5909b6c95..7590b6f74 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -58,6 +58,7 @@ makedocs(; ], "How-to" => [ "howto/states.md", + "howto/bond_dimension.md", ], "Examples" => "examples/index.md", "Library" => [ diff --git a/docs/src/howto/bond_dimension.md b/docs/src/howto/bond_dimension.md new file mode 100644 index 000000000..f0e74d905 --- /dev/null +++ b/docs/src/howto/bond_dimension.md @@ -0,0 +1,359 @@ +# [Controlling bond dimension](@id howto_bond_dimension) + +Bond dimension is the key knob in every MPS calculation: too small and the ansatz +cannot represent the state, too large and computation slows to a crawl. +This page gives concrete recipes for inspecting, growing, and shrinking bond dimension +in MPSKit.jl. +All examples share a single namespace: + +```@example bond_dim +using MPSKit, TensorKit +``` + +--- + +## 1. Inspecting the current bond dimension + +MPSKit exposes the virtual spaces through `left_virtualspace` and +`right_virtualspace`. +There is **no** `bond_dimension` function; use `dim` on the space: + +```@example bond_dim +L = 10 +ψ = FiniteMPS(L, ℂ^2, ℂ^8) # finite MPS, max bond dim 8 + +# Bond dimension between sites i and i+1 equals dim(left_virtualspace(ψ, i+1)) +# or equivalently dim(right_virtualspace(ψ, i)). +dim(left_virtualspace(ψ, 5)) # bond to the left of site 5 +``` + +```@example bond_dim +# All bond dimensions in one go +[dim(left_virtualspace(ψ, i)) for i in 1:L] +``` + +!!! note + For a `FiniteMPS` the leftmost and rightmost virtual spaces are always + one-dimensional (the trivial boundary space), so `left_virtualspace(ψ, 1)` + and `left_virtualspace(ψ, L+1)` have dimension 1. + +For an `InfiniteMPS` the same call works per unit-cell site: + +```@example bond_dim +ψ_inf = InfiniteMPS(ℂ^2, ℂ^8) +dim(left_virtualspace(ψ_inf, 1)) +``` + +--- + +## 2. Growing bond dimension + +### 2a. Random expansion (no Hamiltonian required) + +[`RandExpand`](@ref) pads the MPS with orthogonal random vectors drawn from the +two-site null space. +It does **not** need the Hamiltonian, so it is cheap and works for any MPS type. + +`trscheme` is **mandatory** and controls how many new directions are added. +Use `truncrank(n)` from MatrixAlgebraKit (re-exported by MPSKit) to add at most `n` +extra singular values: + +```@example bond_dim +ψ_small = FiniteMPS(L, ℂ^2, ℂ^4) # start with D = 4 +dim(left_virtualspace(ψ_small, 5)) +``` + +```@example bond_dim +ψ_grown = changebonds(ψ_small, RandExpand(; trscheme = truncrank(8))) +dim(left_virtualspace(ψ_grown, 5)) # expanded, but ≤ 4 + 8 = 12 +``` + +The new vectors are orthogonal to the original state, so the physical content is +unchanged but the variational manifold is larger. + + +For an `InfiniteMPS` the call is identical: + +```@example bond_dim +ψ_inf_small = InfiniteMPS(ℂ^2, ℂ^4) +ψ_inf_grown = changebonds(ψ_inf_small, RandExpand(; trscheme = truncrank(8))) +dim(left_virtualspace(ψ_inf_grown, 1)) +``` + +### 2b. Optimal expansion (requires Hamiltonian) + +[`OptimalExpand`](@ref) selects expansion directions that have the largest overlap +with the two-site Hamiltonian action on the current state. + +It needs both the state and the Hamiltonian: + +```@example bond_dim +# Build a finite TFIM Hamiltonian manually +J = 1.0; g = 0.5 +lattice = fill(ℂ^2, L) +X = TensorMap(ComplexF64[0 1; 1 0], ℂ^2, ℂ^2) +Z = TensorMap(ComplexF64[1 0; 0 -1], ℂ^2, ℂ^2) +H = FiniteMPOHamiltonian(lattice, (i, i+1) => -J * X ⊗ X for i in 1:L-1) + + FiniteMPOHamiltonian(lattice, (i,) => -g * Z for i in 1:L) + +ψ_opt, envs_opt = changebonds(ψ_small, H, OptimalExpand(; trscheme = truncrank(8))) +dim(left_virtualspace(ψ_opt, 5)) +``` + +`OptimalExpand` also works on `InfiniteMPS` with an `InfiniteMPOHamiltonian`. +The environment argument is optional and defaults to a freshly computed set: + +```@example bond_dim +lattice_inf = PeriodicVector([ℂ^2]) +H_inf = InfiniteMPOHamiltonian(lattice_inf, (1, 2) => -J * X ⊗ X, (1,) => -g * Z) + +ψ_inf_opt, _ = changebonds(ψ_inf_small, H_inf, OptimalExpand(; trscheme = truncrank(8))) +dim(left_virtualspace(ψ_inf_opt, 1)) +``` + +!!! note + `OptimalExpand` and `VUMPSSvdCut` (see [§5](#5-growing-during-infinite-mps-optimization)) + both require the Hamiltonian. + Pass environments as the optional fourth argument to avoid recomputing them if you + already have them from a previous `find_groundstate` call. + +--- + +## 3. Reducing bond dimension + +[`SvdCut`](@ref) truncates the bond dimension by an SVD sweep. +It does **not** need the Hamiltonian and is the standard tool for compression. + +```@example bond_dim +# compress ψ_grown (D up to 12) back to at most 6 singular values per bond +ψ_cut = changebonds(ψ_grown, SvdCut(; trscheme = truncrank(6))) +dim(left_virtualspace(ψ_cut, 5)) +``` + +An in-place variant, `changebonds!`, exists for `FiniteMPS` and avoids allocating +a copy. +It also accepts a `normalize` keyword (default `true`): + +```@example bond_dim +ψ_inplace = FiniteMPS(L, ℂ^2, ℂ^12) +changebonds!(ψ_inplace, SvdCut(; trscheme = truncrank(6)); normalize = true) +dim(left_virtualspace(ψ_inplace, 5)) +``` + +`SvdCut` also works on `InfiniteMPS` (2-arg form only; no in-place variant): + +```@example bond_dim +ψ_inf_cut = changebonds(ψ_inf_grown, SvdCut(; trscheme = truncrank(6))) +dim(left_virtualspace(ψ_inf_cut, 1)) +``` + +--- + +## 4. Truncation schemes + +Every bond-change algorithm takes a mandatory `trscheme` keyword drawn from +**MatrixAlgebraKit** (re-exported by MPSKit). +The main schemes are: + +| Scheme | Meaning | +|:-------|:--------| +| `truncrank(n)` | Keep at most `n` singular values | +| `truncbelow(x)` | Drop singular values below the absolute value `x` | +| `trunctol(; atol)` | Drop singular values below `atol` times the largest | +| `notrunc()` | Keep all singular values (no truncation) | +| `truncspace(V)` | Keep only singular values whose index fits in the given space `V` | + +Schemes compose with `&` to apply multiple criteria simultaneously. +For example, to keep at most 16 singular values **and** also drop anything below +`1e-8`: + +```@example bond_dim +trscheme_combined = trunctol(; atol = 1e-8) & truncrank(16) +ψ_combined = changebonds(ψ_grown, SvdCut(; trscheme = trscheme_combined)) +dim(left_virtualspace(ψ_combined, 5)) +``` + +!!! warning + `trscheme` is **required** on every algorithm; there is no default. + Omitting it will throw a `MethodError` at construction time. + +--- + +## 5. Growing during finite MPS optimization + +The two-site DMRG variant, [`DMRG2`](@ref), performs a bond expansion at every sweep +step by keeping both sites together in the update. +Pass `trscheme` to control which singular values are retained: + +```@example bond_dim +ψ_dmrg2_start = FiniteMPS(L, ℂ^2, ℂ^2) # start small + +ψ_dmrg2, envs_dmrg2, _ = find_groundstate( + ψ_dmrg2_start, H, + DMRG2(; trscheme = truncrank(16), maxiter = 5) +) +dim(left_virtualspace(ψ_dmrg2, 5)) +``` + +A common pattern is to warm up with `DMRG2` to grow the bond dimension, then +refine with single-site `DMRG` for efficiency. +The algorithm chaining operator `&` makes this easy (see [§7](#7-chaining-algorithms)): + +```@example bond_dim +warmup_then_refine = DMRG2(; trscheme = truncrank(16), maxiter = 3) & + DMRG(; maxiter = 20) + +ψ_dmrg2, envs_dmrg2, _ = find_groundstate(ψ_dmrg2_start, H, warmup_then_refine) +dim(left_virtualspace(ψ_dmrg2, 5)) +``` + +The `find_groundstate` convenience function also accepts a `trscheme` keyword that +triggers the same warm-up automatically: + +```@example bond_dim +ψ_conv, envs_conv, _ = find_groundstate( + ψ_dmrg2_start, H; + trscheme = truncrank(16), maxiter = 20 +) +dim(left_virtualspace(ψ_conv, 5)) +``` + +The `trscheme` keyword makes `find_groundstate` prepend a `DMRG2` pass before +switching to the default `DMRG`. + + +TDVP2 also supports `trscheme` for two-site real- or imaginary-time evolution, +but that is covered in the time-evolution documentation rather than here. + +--- + +## 6. Growing during infinite MPS optimization + +### IDMRG2 (two-site infinite DMRG) + +[`IDMRG2`](@ref) is the infinite analogue of `DMRG2`. + +!!! warning + `IDMRG2` requires a unit cell of **at least 2 sites**. + Passing a single-site `InfiniteMPS` will throw an `ArgumentError`. + +```@example bond_dim +# 2-site unit cell: lattice, Hamiltonian, and initial state +lattice_2 = PeriodicVector([ℂ^2, ℂ^2]) +H_inf_2 = InfiniteMPOHamiltonian( + lattice_2, + (1, 2) => -J * X ⊗ X, + (2, 3) => -J * X ⊗ X, + (1,) => -g * Z, + (2,) => -g * Z, +) +# + +ψ_idmrg2_start = InfiniteMPS([ℂ^2, ℂ^2], [ℂ^2, ℂ^2]) + +ψ_idmrg2, _, _ = find_groundstate( + ψ_idmrg2_start, H_inf_2, + IDMRG2(; trscheme = truncrank(16), maxiter = 5) +) +dim(left_virtualspace(ψ_idmrg2, 1)) +``` + +### VUMPSSvdCut + +[`VUMPSSvdCut`](@ref) grows the bond dimension of an `InfiniteMPS` by performing a +two-site VUMPS update followed by an SVD truncation. +It requires the Hamiltonian and returns a new state with updated environments: + +```@example bond_dim +ψ_vs, _ = changebonds(ψ_inf_small, H_inf, VUMPSSvdCut(; trscheme = truncrank(16))) +dim(left_virtualspace(ψ_vs, 1)) +``` + +The typical workflow for infinite systems is to grow the bond dimension first +(with `VUMPSSvdCut` or `IDMRG2`), then converge with [`VUMPS`](@ref) as a separate +step, reusing the expanded state `ψ_vs` from above: + +```@example bond_dim +ψ_vc, = find_groundstate(ψ_vs, H_inf, VUMPS(; maxiter = 10)) +dim(left_virtualspace(ψ_vc, 1)) +``` + +!!! note + Bond-changing algorithms such as `VUMPSSvdCut` are applied through + [`changebonds`](@ref), not `find_groundstate`. Grow the state first, then pass + the result to a ground-state algorithm. + + + +--- + +## 7. Chaining algorithms + +The `&` operator chains any two algorithms that share the same interface, applying +them in sequence. +This works for both ground-state algorithms and `changebonds` algorithms: + +```@example bond_dim +# Expand with random vectors, then compress to a target rank +grow_and_cut = RandExpand(; trscheme = truncrank(12)) & + SvdCut(; trscheme = truncrank(6)) + +ψ_final = changebonds(ψ_small, grow_and_cut) +dim(left_virtualspace(ψ_final, 5)) +``` + +```@example bond_dim +# Alternatively: combine changebonds with a ground-state algorithm +ψ_expanded, envs_expanded = changebonds( + ψ_small, H, OptimalExpand(; trscheme = truncrank(8)) +) +ψ_gs, _, _ = find_groundstate(ψ_expanded, H, DMRG(; maxiter = 10), envs_expanded) +dim(left_virtualspace(ψ_gs, 5)) +``` + +For background on when each algorithm is appropriate and how convergence is +assessed, see [Ground-state algorithms](@ref lib_groundstate). +For constructing MPS objects from scratch, see [Constructing states](@ref howto_states). + +--- + + From 7c651aa068941b5d19eaf129e088ee35f4f57499 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Tue, 30 Jun 2026 19:30:48 -0400 Subject: [PATCH 07/76] docs(wave1): howto/observables.md Add a how-to guide for local and multi-site expectation values (expectation_value), two-point correlators (correlator, incl. range form), full-MPO energies, and the energy variance convergence diagnostic. Wire the page into the How-to nav. All examples verified by the full build. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/make.jl | 1 + docs/src/howto/observables.md | 240 ++++++++++++++++++++++++++++++++++ 2 files changed, 241 insertions(+) create mode 100644 docs/src/howto/observables.md diff --git a/docs/make.jl b/docs/make.jl index 7590b6f74..eabd3ac48 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -59,6 +59,7 @@ makedocs(; "How-to" => [ "howto/states.md", "howto/bond_dimension.md", + "howto/observables.md", ], "Examples" => "examples/index.md", "Library" => [ diff --git a/docs/src/howto/observables.md b/docs/src/howto/observables.md new file mode 100644 index 000000000..1fc9e4b43 --- /dev/null +++ b/docs/src/howto/observables.md @@ -0,0 +1,240 @@ +# [Computing observables](@id howto_observables) + +This page collects recipes for extracting physical quantities from an MPS: local and multi-site expectation values, the energy of a Hamiltonian, two-point correlators, and the energy variance as a convergence diagnostic. +All examples share a single namespace and build on state and operator objects you would have in hand after a ground-state calculation. + +```@example observables +using MPSKit, TensorKit +``` + +For building MPS objects see [Constructing states](@ref howto_states). +For controlling the bond dimension during optimization see [Controlling bond dimension](@ref howto_bond_dimension). +The reference page for ground-state algorithms is [Ground-state algorithms](@ref lib_groundstate). + +--- + +## Setup: state and operators + +The examples below use a spin-1/2 `FiniteMPS` together with the Pauli matrices built directly from `TensorMap`. +All operators use `ComplexF64` to match the default element type of the state. + +```@example observables +L = 8 +ψ = FiniteMPS(L, ℂ^2, ℂ^8) # random finite MPS, bond dim ≤ 8 + +# single-site Pauli operators +X = TensorMap(ComplexF64[0 1; 1 0], ℂ^2, ℂ^2) +Z = TensorMap(ComplexF64[1 0; 0 -1], ℂ^2, ℂ^2) +``` + +The finite TFIM Hamiltonian used in recipes 3 and 5 is built from these: + +```@example observables +lattice = fill(ℂ^2, L) +H = FiniteMPOHamiltonian(lattice, (i, i + 1) => -(X ⊗ X) for i in 1:(L - 1)) + + FiniteMPOHamiltonian(lattice, (i,) => -0.5 * Z for i in 1:L) +``` + +--- + +## 1. Local (one-site) expectation value + +Use `expectation_value(ψ, i => O)` to evaluate ⟨ψ|Oᵢ|ψ⟩ at a single site `i`. +The pair `i => O` identifies the site and the single-site operator. + +```@example observables +expectation_value(ψ, 4 => Z) # ⟨Z⟩ at site 4 +``` + +To compute a local observable at every site, broadcast over the indices: + +```@example observables +[expectation_value(ψ, i => Z) for i in 1:L] +``` + + + +!!! note + The state `ψ` must be normalised for the expectation value to be meaningful. + A freshly constructed `FiniteMPS` is normalised by default; if you modified + the tensors by hand, call `normalize!(ψ)` first. + +--- + +## 2. Multi-site (contiguous) expectation value + +For a product of operators on a contiguous range of sites, pass a tuple of indices together with a multi-site operator formed by taking tensor products `⊗`: + +```@example observables +# ⟨X₂ X₃⟩ — two-site operator on sites 2 and 3 +expectation_value(ψ, (2, 3) => X ⊗ X) +``` + +The operator `X ⊗ X` is a `{2,2}` `TensorMap` (two incoming, two outgoing legs) matching the two-site index tuple `(2, 3)`. +The tuple must be contiguous; arbitrary non-adjacent index sets are not supported by this form. + +```@example observables +# ⟨Z₁ Z₂ Z₃⟩ — three-site operator +expectation_value(ψ, (1, 2, 3) => Z ⊗ Z ⊗ Z) +``` + + + +--- + +## 3. Energy (full-MPO expectation value) + +When the operator is an [`AbstractMPO`](@ref) (e.g. a Hamiltonian), pass it directly without an index argument. +MPSKit evaluates the full contraction ⟨ψ|H|ψ⟩: + +```@example observables +E = expectation_value(ψ, H) +``` + + + +The same form works for `InfiniteMPS` with an `InfiniteMPOHamiltonian`. + + +!!! note + The full-MPO form automatically computes and caches the environments. + If you already have environments from a prior `find_groundstate` call you can + pass them as a trailing argument to avoid recomputation, but this is optional; + omitting them is always safe and correct. + +--- + +## 4. Two-point correlators + +[`correlator`](@ref) computes ⟨O₁ᵢ O₂ⱼ⟩ for two sites with `i < j`. +The recommended call uses a single two-site operator `O₁₂`: + +```@example observables +# ⟨Z₂ Zⱼ⟩ for a single target site j = 6 +correlator(ψ, Z ⊗ Z, 2, 6) +``` + +!!! warning + `i` must be strictly less than `j`. + Calling `correlator(ψ, O₁₂, i, j)` with `i ≥ j` will throw an error. + +### Correlation profile over a range + +Pass a range as `j` to obtain a vector of correlators — one entry per target site. +This is the efficient route for a full correlation profile: + +```@example observables +# ⟨Z₂ Zⱼ⟩ for j = 3, 4, …, L +corr = correlator(ψ, Z ⊗ Z, 2, 3:L) +``` + +The result is a `Vector` whose `k`-th element corresponds to `j = 3 + k - 1`. + + + +A common pattern is to normalise the correlator by ⟨Z⟩² to extract the connected part: + +```@example observables +z_mean = expectation_value(ψ, 2 => Z) +connected = [c - z_mean * expectation_value(ψ, j => Z) for (j, c) in zip(3:L, corr)] +``` + + + +--- + +## 5. Energy variance as a convergence check + +[`variance`](@ref) returns ⟨H²⟩ − ⟨H⟩², which is zero if and only if `ψ` is an exact eigenstate of `H`. +Use it as a quantitative convergence diagnostic after a ground-state search: + +```@example observables +var_E = variance(ψ, H) +``` + +A smaller variance indicates that `ψ` is closer to a true eigenstate. + + +After running a ground-state algorithm the variance should have dropped significantly compared to the random starting state above: + +```@example observables +ψ_gs, envs, _ = find_groundstate(ψ, H, DMRG(; maxiter = 10)) +variance(ψ_gs, H) +``` + + + +!!! note + The `variance` function also accepts an optional pre-computed `envs` argument. + Pass the environments returned by `find_groundstate` to skip recomputation: + + ```julia + variance(ψ_gs, H, envs) + ``` + +--- + + From 07216b46c4ebc838c4e0ca37d9579ac26ee6e7af Mon Sep 17 00:00:00 2001 From: lkdvos Date: Tue, 30 Jun 2026 19:30:48 -0400 Subject: [PATCH 08/76] docs(wave1): format markdown (one sentence per line + Runic) Reflow prose to one sentence per line (semantic line breaks) and run the Runic formatter over the Julia code blocks across the Wave 1 reference and how-to pages. Whitespace/style only; no content or API changes, full build still green. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/src/howto/bond_dimension.md | 70 ++++++++++++-------------------- docs/src/howto/states.md | 68 ++++++++++++------------------- docs/src/lib/groundstate.md | 5 +-- docs/src/lib/operators.md | 4 +- docs/src/lib/public.md | 44 ++++++-------------- docs/src/lib/states.md | 4 +- 6 files changed, 69 insertions(+), 126 deletions(-) diff --git a/docs/src/howto/bond_dimension.md b/docs/src/howto/bond_dimension.md index f0e74d905..c27c9377e 100644 --- a/docs/src/howto/bond_dimension.md +++ b/docs/src/howto/bond_dimension.md @@ -1,9 +1,7 @@ # [Controlling bond dimension](@id howto_bond_dimension) -Bond dimension is the key knob in every MPS calculation: too small and the ansatz -cannot represent the state, too large and computation slows to a crawl. -This page gives concrete recipes for inspecting, growing, and shrinking bond dimension -in MPSKit.jl. +Bond dimension is the key knob in every MPS calculation: too small and the ansatz cannot represent the state, too large and computation slows to a crawl. +This page gives concrete recipes for inspecting, growing, and shrinking bond dimension in MPSKit.jl. All examples share a single namespace: ```@example bond_dim @@ -14,8 +12,7 @@ using MPSKit, TensorKit ## 1. Inspecting the current bond dimension -MPSKit exposes the virtual spaces through `left_virtualspace` and -`right_virtualspace`. +MPSKit exposes the virtual spaces through `left_virtualspace` and `right_virtualspace`. There is **no** `bond_dimension` function; use `dim` on the space: ```@example bond_dim @@ -50,13 +47,11 @@ dim(left_virtualspace(ψ_inf, 1)) ### 2a. Random expansion (no Hamiltonian required) -[`RandExpand`](@ref) pads the MPS with orthogonal random vectors drawn from the -two-site null space. +[`RandExpand`](@ref) pads the MPS with orthogonal random vectors drawn from the two-site null space. It does **not** need the Hamiltonian, so it is cheap and works for any MPS type. `trscheme` is **mandatory** and controls how many new directions are added. -Use `truncrank(n)` from MatrixAlgebraKit (re-exported by MPSKit) to add at most `n` -extra singular values: +Use `truncrank(n)` from MatrixAlgebraKit (re-exported by MPSKit) to add at most `n` extra singular values: ```@example bond_dim ψ_small = FiniteMPS(L, ℂ^2, ℂ^4) # start with D = 4 @@ -68,8 +63,7 @@ dim(left_virtualspace(ψ_small, 5)) dim(left_virtualspace(ψ_grown, 5)) # expanded, but ≤ 4 + 8 = 12 ``` -The new vectors are orthogonal to the original state, so the physical content is -unchanged but the variational manifold is larger. +The new vectors are orthogonal to the original state, so the physical content is unchanged but the variational manifold is larger. @@ -84,8 +78,7 @@ dim(left_virtualspace(ψ_inf_grown, 1)) ### 2b. Optimal expansion (requires Hamiltonian) -[`OptimalExpand`](@ref) selects expansion directions that have the largest overlap -with the two-site Hamiltonian action on the current state. +[`OptimalExpand`](@ref) selects expansion directions that have the largest overlap with the two-site Hamiltonian action on the current state. @@ -97,7 +90,7 @@ J = 1.0; g = 0.5 lattice = fill(ℂ^2, L) X = TensorMap(ComplexF64[0 1; 1 0], ℂ^2, ℂ^2) Z = TensorMap(ComplexF64[1 0; 0 -1], ℂ^2, ℂ^2) -H = FiniteMPOHamiltonian(lattice, (i, i+1) => -J * X ⊗ X for i in 1:L-1) + +H = FiniteMPOHamiltonian(lattice, (i, i + 1) => -J * X ⊗ X for i in 1:(L - 1)) + FiniteMPOHamiltonian(lattice, (i,) => -g * Z for i in 1:L) ψ_opt, envs_opt = changebonds(ψ_small, H, OptimalExpand(; trscheme = truncrank(8))) @@ -134,8 +127,7 @@ It does **not** need the Hamiltonian and is the standard tool for compression. dim(left_virtualspace(ψ_cut, 5)) ``` -An in-place variant, `changebonds!`, exists for `FiniteMPS` and avoids allocating -a copy. +An in-place variant, `changebonds!`, exists for `FiniteMPS` and avoids allocating a copy. It also accepts a `normalize` keyword (default `true`): ```@example bond_dim @@ -155,8 +147,7 @@ dim(left_virtualspace(ψ_inf_cut, 1)) ## 4. Truncation schemes -Every bond-change algorithm takes a mandatory `trscheme` keyword drawn from -**MatrixAlgebraKit** (re-exported by MPSKit). +Every bond-change algorithm takes a mandatory `trscheme` keyword drawn from **MatrixAlgebraKit** (re-exported by MPSKit). The main schemes are: | Scheme | Meaning | @@ -168,11 +159,10 @@ The main schemes are: | `truncspace(V)` | Keep only singular values whose index fits in the given space `V` | Schemes compose with `&` to apply multiple criteria simultaneously. -For example, to keep at most 16 singular values **and** also drop anything below -`1e-8`: +For example, to keep at most 16 singular values **and** also drop anything below `1e-8`: ```@example bond_dim -trscheme_combined = trunctol(; atol = 1e-8) & truncrank(16) +trscheme_combined = trunctol(; atol = 1.0e-8) & truncrank(16) ψ_combined = changebonds(ψ_grown, SvdCut(; trscheme = trscheme_combined)) dim(left_virtualspace(ψ_combined, 5)) ``` @@ -185,8 +175,7 @@ dim(left_virtualspace(ψ_combined, 5)) ## 5. Growing during finite MPS optimization -The two-site DMRG variant, [`DMRG2`](@ref), performs a bond expansion at every sweep -step by keeping both sites together in the update. +The two-site DMRG variant, [`DMRG2`](@ref), performs a bond expansion at every sweep step by keeping both sites together in the update. Pass `trscheme` to control which singular values are retained: ```@example bond_dim @@ -199,20 +188,18 @@ Pass `trscheme` to control which singular values are retained: dim(left_virtualspace(ψ_dmrg2, 5)) ``` -A common pattern is to warm up with `DMRG2` to grow the bond dimension, then -refine with single-site `DMRG` for efficiency. +A common pattern is to warm up with `DMRG2` to grow the bond dimension, then refine with single-site `DMRG` for efficiency. The algorithm chaining operator `&` makes this easy (see [§7](#7-chaining-algorithms)): ```@example bond_dim warmup_then_refine = DMRG2(; trscheme = truncrank(16), maxiter = 3) & - DMRG(; maxiter = 20) + DMRG(; maxiter = 20) ψ_dmrg2, envs_dmrg2, _ = find_groundstate(ψ_dmrg2_start, H, warmup_then_refine) dim(left_virtualspace(ψ_dmrg2, 5)) ``` -The `find_groundstate` convenience function also accepts a `trscheme` keyword that -triggers the same warm-up automatically: +The `find_groundstate` convenience function also accepts a `trscheme` keyword that triggers the same warm-up automatically: ```@example bond_dim ψ_conv, envs_conv, _ = find_groundstate( @@ -222,14 +209,12 @@ triggers the same warm-up automatically: dim(left_virtualspace(ψ_conv, 5)) ``` -The `trscheme` keyword makes `find_groundstate` prepend a `DMRG2` pass before -switching to the default `DMRG`. +The `trscheme` keyword makes `find_groundstate` prepend a `DMRG2` pass before switching to the default `DMRG`. -TDVP2 also supports `trscheme` for two-site real- or imaginary-time evolution, -but that is covered in the time-evolution documentation rather than here. +TDVP2 also supports `trscheme` for two-site real- or imaginary-time evolution, but that is covered in the time-evolution documentation rather than here. --- @@ -250,8 +235,8 @@ H_inf_2 = InfiniteMPOHamiltonian( lattice_2, (1, 2) => -J * X ⊗ X, (2, 3) => -J * X ⊗ X, - (1,) => -g * Z, - (2,) => -g * Z, + (1,) => -g * Z, + (2,) => -g * Z, ) # @@ -266,8 +251,7 @@ dim(left_virtualspace(ψ_idmrg2, 1)) ### VUMPSSvdCut -[`VUMPSSvdCut`](@ref) grows the bond dimension of an `InfiniteMPS` by performing a -two-site VUMPS update followed by an SVD truncation. +[`VUMPSSvdCut`](@ref) grows the bond dimension of an `InfiniteMPS` by performing a two-site VUMPS update followed by an SVD truncation. It requires the Hamiltonian and returns a new state with updated environments: ```@example bond_dim @@ -275,9 +259,7 @@ It requires the Hamiltonian and returns a new state with updated environments: dim(left_virtualspace(ψ_vs, 1)) ``` -The typical workflow for infinite systems is to grow the bond dimension first -(with `VUMPSSvdCut` or `IDMRG2`), then converge with [`VUMPS`](@ref) as a separate -step, reusing the expanded state `ψ_vs` from above: +The typical workflow for infinite systems is to grow the bond dimension first (with `VUMPSSvdCut` or `IDMRG2`), then converge with [`VUMPS`](@ref) as a separate step, reusing the expanded state `ψ_vs` from above: ```@example bond_dim ψ_vc, = find_groundstate(ψ_vs, H_inf, VUMPS(; maxiter = 10)) @@ -297,14 +279,13 @@ dim(left_virtualspace(ψ_vc, 1)) ## 7. Chaining algorithms -The `&` operator chains any two algorithms that share the same interface, applying -them in sequence. +The `&` operator chains any two algorithms that share the same interface, applying them in sequence. This works for both ground-state algorithms and `changebonds` algorithms: ```@example bond_dim # Expand with random vectors, then compress to a target rank grow_and_cut = RandExpand(; trscheme = truncrank(12)) & - SvdCut(; trscheme = truncrank(6)) + SvdCut(; trscheme = truncrank(6)) ψ_final = changebonds(ψ_small, grow_and_cut) dim(left_virtualspace(ψ_final, 5)) @@ -319,8 +300,7 @@ dim(left_virtualspace(ψ_final, 5)) dim(left_virtualspace(ψ_gs, 5)) ``` -For background on when each algorithm is appropriate and how convergence is -assessed, see [Ground-state algorithms](@ref lib_groundstate). +For background on when each algorithm is appropriate and how convergence is assessed, see [Ground-state algorithms](@ref lib_groundstate). For constructing MPS objects from scratch, see [Constructing states](@ref howto_states). --- diff --git a/docs/src/howto/states.md b/docs/src/howto/states.md index 22aa1a861..f8335347f 100644 --- a/docs/src/howto/states.md +++ b/docs/src/howto/states.md @@ -1,29 +1,25 @@ # [Constructing states](@id howto_states) -This page collects recipes for building [`FiniteMPS`](@ref), -[`InfiniteMPS`](@ref), [`WindowMPS`](@ref), and [`MultilineMPS`](@ref) objects. +This page collects recipes for building [`FiniteMPS`](@ref), [`InfiniteMPS`](@ref), [`WindowMPS`](@ref), and [`MultilineMPS`](@ref) objects. All constructors live in the `MPSKit` namespace; the examples below assume ```@example howto_states using MPSKit, TensorKit ``` -For background on what these types represent and how gauging works, see the -[States](@ref lib_states) reference page. +For background on what these types represent and how gauging works, see the [States](@ref lib_states) reference page. --- ## 1. A finite MPS from length, physical space, and maximum bond dimension -The most common starting point: give the chain length `N`, the local physical -`VectorSpace`, and the maximum allowed virtual space. -The constructor fills the tensors with random `ComplexF64` entries and trims the -actual bond dimensions to full rank, so passing an over-large `maxVspace` is safe. +The most common starting point: give the chain length `N`, the local physical `VectorSpace`, and the maximum allowed virtual space. +The constructor fills the tensors with random `ComplexF64` entries and trims the actual bond dimensions to full rank, so passing an over-large `maxVspace` is safe. ```@example howto_states -L = 10 -d = ℂ^2 # spin-1/2 physical space (dim 2) -D = ℂ^16 # maximum bond dimension +L = 10 +d = ℂ^2 # spin-1/2 physical space (dim 2) +D = ℂ^16 # maximum bond dimension ψ = FiniteMPS(L, d, D) ``` @@ -43,27 +39,24 @@ physicalspace(ψ, 1) # local Hilbert space at site 1 ## 2. Choosing the initializer and element type -Pass an initializer function (`rand` or `randn`) and an element type -as the first two arguments: +Pass an initializer function (`rand` or `randn`) and an element type as the first two arguments: ```@example howto_states -ψ_rand = FiniteMPS(rand, ComplexF64, L, d, D) # default — same as FiniteMPS(L, d, D) +ψ_rand = FiniteMPS(rand, ComplexF64, L, d, D) # default — same as FiniteMPS(L, d, D) ψ_randn = FiniteMPS(randn, ComplexF64, L, d, D) # normally distributed entries ``` -The element type sets the scalar type of the tensors, e.g. `ComplexF64` (the -default) or `Float64` for a real-valued state. +The element type sets the scalar type of the tensors, e.g. `ComplexF64` (the default) or `Float64` for a real-valued state. --- ## 3. Per-site physical and virtual spaces -When the physical space varies from site to site — or you want fine control over -which bond gets which maximum dimension — pass vectors instead of scalars. +When the physical space varies from site to site — or you want fine control over which bond gets which maximum dimension — pass vectors instead of scalars. The `maxVspaces` vector must have length `N - 1` (one entry per bond): ```@example howto_states -Pspaces = [ℂ^2, ℂ^3, ℂ^2, ℂ^3, ℂ^2] # alternating physical spaces +Pspaces = [ℂ^2, ℂ^3, ℂ^2, ℂ^3, ℂ^2] # alternating physical spaces maxVspaces = [ℂ^8, ℂ^8, ℂ^8, ℂ^8] # one per bond (length N-1) ψ_het = FiniteMPS(rand, ComplexF64, Pspaces, maxVspaces) @@ -78,8 +71,7 @@ physicalspace(ψ_het, 2) # ℂ^3 ## 4. A product state (trivial virtual space) A product (bond-dimension-1) state has no entanglement. -Achieve this by passing `oneunit(d)` — the one-dimensional unit space of the same -symmetry sector — as the maximum virtual space: +Achieve this by passing `oneunit(d)` — the one-dimensional unit space of the same symmetry sector — as the maximum virtual space: ```@example howto_states ψ_prod = FiniteMPS(rand, ComplexF64, L, ℂ^2, oneunit(ℂ^2)) @@ -98,10 +90,8 @@ configurations — is there a cleaner physics description worth giving here? --> ## 5. From your own site tensors -If you already have a vector of `TensorMap` objects with the correct index -structure (virtual ⊗ physical ← virtual), pass them directly. -The constructor performs a left-to-right QR sweep to bring the state into a -canonical form: +If you already have a vector of `TensorMap` objects with the correct index structure (virtual ⊗ physical ← virtual), pass them directly. +The constructor performs a left-to-right QR sweep to bring the state into a canonical form: ```@example howto_states # build three-site rank-1 tensors by hand @@ -109,11 +99,10 @@ site_tensors = [rand(ComplexF64, ℂ^1 ⊗ ℂ^2 ← ℂ^1) for _ in 1:L] ψ_from_tensors = FiniteMPS(site_tensors) ``` -Set `normalize=true` to also normalise the state during construction -(the default is `false` when passing raw tensors): +Set `normalize=true` to also normalise the state during construction (the default is `false` when passing raw tensors): ```@example howto_states -ψ_normed = FiniteMPS(site_tensors; normalize=true) +ψ_normed = FiniteMPS(site_tensors; normalize = true) ``` --- @@ -122,8 +111,7 @@ Set `normalize=true` to also normalise the state during construction ### Scalar convenience form -Provide `d` and `D` as integers or spaces; the constructor builds a single-site -unit cell: +Provide `d` and `D` as integers or spaces; the constructor builds a single-site unit cell: ```@example howto_states ψ_inf = InfiniteMPS(2, 20) # integers → plain ComplexSpace dimensions @@ -158,8 +146,7 @@ right_virtualspace(ψ_2site, 1) # virtual space to the right of site 1 ### From site tensors -Tensors must form a valid periodic chain (virtual spaces must match across the -unit-cell boundary): +Tensors must form a valid periodic chain (virtual spaces must match across the unit-cell boundary): ```@example howto_states inf_tensors = [rand(ComplexF64, ℂ^4 ⊗ ℂ^2 ← ℂ^4)] @@ -170,8 +157,7 @@ inf_tensors = [rand(ComplexF64, ℂ^4 ⊗ ℂ^2 ← ℂ^4)] ## 7. A window MPS -A [`WindowMPS`](@ref) embeds a mutable finite window inside two infinite -environments. +A [`WindowMPS`](@ref) embeds a mutable finite window inside two infinite environments. ### Slice an existing InfiniteMPS @@ -180,7 +166,7 @@ Both environments are set to the same object (the original infinite state): ```@example howto_states ψ_bulk = InfiniteMPS(ℂ^2, ℂ^8) -ψ_win = WindowMPS(ψ_bulk, 6) # window of 6 sites +ψ_win = WindowMPS(ψ_bulk, 6) # window of 6 sites ``` ```@example howto_states @@ -201,7 +187,7 @@ The boundary virtual spaces are taken automatically from `ψₗ`/`ψᵣ`: Build a `FiniteMPS` with matching boundary virtual spaces first, then wrap: ```@example howto_states -finite_part = FiniteMPS(6, ℂ^2, ℂ^8; left=ℂ^8, right=ℂ^8) +finite_part = FiniteMPS(6, ℂ^2, ℂ^8; left = ℂ^8, right = ℂ^8) ψ_win3 = WindowMPS(ψ_bulk, finite_part, ψ_bulk) ``` @@ -219,8 +205,7 @@ finite_part = FiniteMPS(6, ℂ^2, ℂ^8; left=ℂ^8, right=ℂ^8) ## 8. A multiline MPS -[`MultilineMPS`](@ref) stacks several [`InfiniteMPS`](@ref) rows and is used in -boundary-MPS methods for 2D classical partition functions. +[`MultilineMPS`](@ref) stacks several [`InfiniteMPS`](@ref) rows and is used in boundary-MPS methods for 2D classical partition functions. ### From a vector of InfiniteMPS rows @@ -251,8 +236,7 @@ Dspaces = fill(ℂ^8, 2, 2) ## 9. States with symmetries All constructors accept TensorKit graded spaces. -Pass a `Rep[G]` physical space and a `Rep[G]` maximum virtual space; the -constructor automatically selects the consistent fusion channels. +Pass a `Rep[G]` physical space and a `Rep[G]` maximum virtual space; the constructor automatically selects the consistent fusion channels. ### Finite MPS with U(1) symmetry @@ -262,8 +246,8 @@ confirm execution. --> ```@example howto_states # U(1) spin-1/2: physical space = spin up (charge +1/2) + spin down (charge -1/2) -d_u1 = Rep[U₁](1//2 => 1, -1//2 => 1) # dim 2 total -D_u1 = Rep[U₁](1//2 => 4, -1//2 => 4, 3//2 => 2, -3//2 => 2) +d_u1 = Rep[U₁](1 // 2 => 1, -1 // 2 => 1) # dim 2 total +D_u1 = Rep[U₁](1 // 2 => 4, -1 // 2 => 4, 3 // 2 => 2, -3 // 2 => 2) ψ_u1 = FiniteMPS(rand, ComplexF64, L, d_u1, D_u1) physicalspace(ψ_u1, 1) diff --git a/docs/src/lib/groundstate.md b/docs/src/lib/groundstate.md index d4c9b8dbc..7ec0b3425 100644 --- a/docs/src/lib/groundstate.md +++ b/docs/src/lib/groundstate.md @@ -1,8 +1,7 @@ # [Ground-state algorithms](@id lib_groundstate) -Reference for the ground-state search interface and its algorithms. For a -task-oriented walkthrough see the how-to guides; the full, canonical docstrings -for the whole package live in the [Library](@ref lib_index) index. +Reference for the ground-state search interface and its algorithms. +For a task-oriented walkthrough see the how-to guides; the full, canonical docstrings for the whole package live in the [Library](@ref lib_index) index. ## Interface diff --git a/docs/src/lib/operators.md b/docs/src/lib/operators.md index 57c755856..2adea868f 100644 --- a/docs/src/lib/operators.md +++ b/docs/src/lib/operators.md @@ -1,7 +1,7 @@ # [Operators](@id lib_operators) -Reference for matrix product operators and Hamiltonians. The full, canonical -docstrings for the whole package live in the [Library](@ref lib_index) index. +Reference for matrix product operators and Hamiltonians. +The full, canonical docstrings for the whole package live in the [Library](@ref lib_index) index. ## Matrix product operators diff --git a/docs/src/lib/public.md b/docs/src/lib/public.md index 85bdac341..c8e5fd8b9 100644 --- a/docs/src/lib/public.md +++ b/docs/src/lib/public.md @@ -1,11 +1,8 @@ # [Public API](@id public_api) -This page is the curated, stable public API surface of MPSKit — the symbols that -are exported and intended for direct use. Each entry links to its full docstring -in the [Library](@ref lib_index) index. The category reference pages -([States](@ref lib_states), [Operators](@ref lib_operators), -[Ground-state algorithms](@ref lib_groundstate)) group the same docstrings by -topic. +This page is the curated, stable public API surface of MPSKit — the symbols that are exported and intended for direct use. +Each entry links to its full docstring in the [Library](@ref lib_index) index. +The category reference pages ([States](@ref lib_states), [Operators](@ref lib_operators), [Ground-state algorithms](@ref lib_groundstate)) group the same docstrings by topic. !!! note Anything not listed here (or marked internal in the [Library](@ref lib_index) index) is @@ -13,16 +10,11 @@ topic. ## States -[`FiniteMPS`](@ref), [`InfiniteMPS`](@ref), [`WindowMPS`](@ref), -[`MultilineMPS`](@ref) +[`FiniteMPS`](@ref), [`InfiniteMPS`](@ref), [`WindowMPS`](@ref), [`MultilineMPS`](@ref) ## Operators and Hamiltonians -[`AbstractMPO`](@ref), [`MPO`](@ref), [`FiniteMPO`](@ref), [`InfiniteMPO`](@ref), -[`MultilineMPO`](@ref), [`MPOHamiltonian`](@ref), [`FiniteMPOHamiltonian`](@ref), -[`InfiniteMPOHamiltonian`](@ref), [`JordanMPOTensor`](@ref), -[`MultipliedOperator`](@ref), [`TimedOperator`](@ref), -[`UntimedOperator`](@ref), [`LazySum`](@ref) +[`AbstractMPO`](@ref), [`MPO`](@ref), [`FiniteMPO`](@ref), [`InfiniteMPO`](@ref), [`MultilineMPO`](@ref), [`MPOHamiltonian`](@ref), [`FiniteMPOHamiltonian`](@ref), [`InfiniteMPOHamiltonian`](@ref), [`JordanMPOTensor`](@ref), [`MultipliedOperator`](@ref), [`TimedOperator`](@ref), [`UntimedOperator`](@ref), [`LazySum`](@ref) ## Environments @@ -30,37 +22,27 @@ topic. ## Ground states and boundaries -[`find_groundstate`](@ref), [`leading_boundary`](@ref), [`approximate`](@ref), -[`VUMPS`](@ref), [`VOMPS`](@ref), [`DMRG`](@ref), [`DMRG2`](@ref), -[`IDMRG`](@ref), [`IDMRG2`](@ref), [`GradientGrassmann`](@ref) +[`find_groundstate`](@ref), [`leading_boundary`](@ref), [`approximate`](@ref), [`VUMPS`](@ref), [`VOMPS`](@ref), [`DMRG`](@ref), [`DMRG2`](@ref), [`IDMRG`](@ref), [`IDMRG2`](@ref), [`GradientGrassmann`](@ref) ## Bond dimension -[`changebonds`](@ref), [`OptimalExpand`](@ref), [`RandExpand`](@ref), -[`SvdCut`](@ref), [`VUMPSSvdCut`](@ref) +[`changebonds`](@ref), [`OptimalExpand`](@ref), [`RandExpand`](@ref), [`SvdCut`](@ref), [`VUMPSSvdCut`](@ref) ## Time evolution -[`time_evolve`](@ref), [`timestep`](@ref), [`make_time_mpo`](@ref), -[`TDVP`](@ref), [`TDVP2`](@ref), [`WI`](@ref), [`WII`](@ref), -[`TaylorCluster`](@ref) +[`time_evolve`](@ref), [`timestep`](@ref), [`make_time_mpo`](@ref), [`TDVP`](@ref), [`TDVP2`](@ref), [`WI`](@ref), [`WII`](@ref), [`TaylorCluster`](@ref) ## Excitations -[`excitations`](@ref), [`FiniteExcited`](@ref), [`QuasiparticleAnsatz`](@ref), -[`ChepigaAnsatz`](@ref), [`ChepigaAnsatz2`](@ref) +[`excitations`](@ref), [`FiniteExcited`](@ref), [`QuasiparticleAnsatz`](@ref), [`ChepigaAnsatz`](@ref), [`ChepigaAnsatz2`](@ref) ## Linear problems and spectral functions -[`propagator`](@ref), [`DynamicalDMRG`](@ref), [`NaiveInvert`](@ref), -[`Jeckelmann`](@ref), [`exact_diagonalization`](@ref), -[`fidelity_susceptibility`](@ref) +[`propagator`](@ref), [`DynamicalDMRG`](@ref), [`NaiveInvert`](@ref), [`Jeckelmann`](@ref), [`exact_diagonalization`](@ref), [`fidelity_susceptibility`](@ref) ## Observables and analysis -[`expectation_value`](@ref), [`correlator`](@ref), [`variance`](@ref), -[`correlation_length`](@ref), [`marek_gap`](@ref), [`transfer_spectrum`](@ref), -[`entropy`](@ref), [`entanglement_spectrum`](@ref) +[`expectation_value`](@ref), [`correlator`](@ref), [`variance`](@ref), [`correlation_length`](@ref), [`marek_gap`](@ref), [`transfer_spectrum`](@ref), [`entropy`](@ref), [`entanglement_spectrum`](@ref) ## Boundary conditions @@ -68,6 +50,4 @@ topic. ## Utility -[`PeriodicArray`](@ref), [`PeriodicVector`](@ref), [`PeriodicMatrix`](@ref), -[`WindowArray`](@ref), [`left_virtualspace`](@ref), [`right_virtualspace`](@ref), -[`physicalspace`](@ref), [`braille`](@ref) +[`PeriodicArray`](@ref), [`PeriodicVector`](@ref), [`PeriodicMatrix`](@ref), [`WindowArray`](@ref), [`left_virtualspace`](@ref), [`right_virtualspace`](@ref), [`physicalspace`](@ref), [`braille`](@ref) diff --git a/docs/src/lib/states.md b/docs/src/lib/states.md index 6116b055c..4b854bd4c 100644 --- a/docs/src/lib/states.md +++ b/docs/src/lib/states.md @@ -1,7 +1,7 @@ # [States](@id lib_states) -Reference for the matrix product state types. The full, canonical docstrings for -the whole package live in the [Library](@ref lib_index) index. +Reference for the matrix product state types. +The full, canonical docstrings for the whole package live in the [Library](@ref lib_index) index. ## Matrix product states From 4e631dca786c107b8e7166d948c5daca32f14ab8 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Thu, 2 Jul 2026 08:36:54 -0400 Subject: [PATCH 09/76] add howto pages --- docs/src/howto/bond_dimension.md | 59 +++----------------------------- docs/src/howto/observables.md | 49 ++++---------------------- docs/src/howto/states.md | 56 +++++------------------------- 3 files changed, 20 insertions(+), 144 deletions(-) diff --git a/docs/src/howto/bond_dimension.md b/docs/src/howto/bond_dimension.md index c27c9377e..c46192200 100644 --- a/docs/src/howto/bond_dimension.md +++ b/docs/src/howto/bond_dimension.md @@ -13,7 +13,7 @@ using MPSKit, TensorKit ## 1. Inspecting the current bond dimension MPSKit exposes the virtual spaces through `left_virtualspace` and `right_virtualspace`. -There is **no** `bond_dimension` function; use `dim` on the space: +This returns the raw vector spaces, which carry the information about the different sectors, but we can obtain a single number using `dim`: ```@example bond_dim L = 10 @@ -30,9 +30,8 @@ dim(left_virtualspace(ψ, 5)) # bond to the left of site 5 ``` !!! note - For a `FiniteMPS` the leftmost and rightmost virtual spaces are always - one-dimensional (the trivial boundary space), so `left_virtualspace(ψ, 1)` - and `left_virtualspace(ψ, L+1)` have dimension 1. + For a `FiniteMPS` the leftmost and rightmost virtual spaces are typically one-dimensional (the trivial boundary space), + so `left_virtualspace(ψ, 1)` and `left_virtualspace(ψ, L+1)` have dimension 1. For an `InfiniteMPS` the same call works per unit-cell site: @@ -63,10 +62,7 @@ dim(left_virtualspace(ψ_small, 5)) dim(left_virtualspace(ψ_grown, 5)) # expanded, but ≤ 4 + 8 = 12 ``` -The new vectors are orthogonal to the original state, so the physical content is unchanged but the variational manifold is larger. - +The new vectors are orthogonal to the original state, so the state it represents is unchanged (its overlap with the original is 1) while the variational manifold grows. For an `InfiniteMPS` the call is identical: @@ -78,10 +74,7 @@ dim(left_virtualspace(ψ_inf_grown, 1)) ### 2b. Optimal expansion (requires Hamiltonian) -[`OptimalExpand`](@ref) selects expansion directions that have the largest overlap with the two-site Hamiltonian action on the current state. - +[`OptimalExpand`](@ref) selects the dominant contributions of the two-site-updated MPS tensor that are orthogonal to the current state, as described by [Zauner-Stauber et al., Phys. Rev. B 97, 045145 (2018)](https://doi.org/10.1103/PhysRevB.97.045145). It needs both the state and the Hamiltonian: ```@example bond_dim @@ -210,9 +203,6 @@ dim(left_virtualspace(ψ_conv, 5)) ``` The `trscheme` keyword makes `find_groundstate` prepend a `DMRG2` pass before switching to the default `DMRG`. - TDVP2 also supports `trscheme` for two-site real- or imaginary-time evolution, but that is covered in the time-evolution documentation rather than here. @@ -238,7 +228,6 @@ H_inf_2 = InfiniteMPOHamiltonian( (1,) => -g * Z, (2,) => -g * Z, ) -# ψ_idmrg2_start = InfiniteMPS([ℂ^2, ℂ^2], [ℂ^2, ℂ^2]) @@ -271,10 +260,6 @@ dim(left_virtualspace(ψ_vc, 1)) [`changebonds`](@ref), not `find_groundstate`. Grow the state first, then pass the result to a ground-state algorithm. - - --- ## 7. Chaining algorithms @@ -303,37 +288,3 @@ dim(left_virtualspace(ψ_gs, 5)) For background on when each algorithm is appropriate and how convergence is assessed, see [Ground-state algorithms](@ref lib_groundstate). For constructing MPS objects from scratch, see [Constructing states](@ref howto_states). ---- - - diff --git a/docs/src/howto/observables.md b/docs/src/howto/observables.md index 1fc9e4b43..d34e2d12e 100644 --- a/docs/src/howto/observables.md +++ b/docs/src/howto/observables.md @@ -52,9 +52,6 @@ To compute a local observable at every site, broadcast over the indices: [expectation_value(ψ, i => Z) for i in 1:L] ``` - - !!! note The state `ψ` must be normalised for the expectation value to be meaningful. A freshly constructed `FiniteMPS` is normalised by default; if you modified @@ -79,11 +76,6 @@ The tuple must be contiguous; arbitrary non-adjacent index sets are not supporte expectation_value(ψ, (1, 2, 3) => Z ⊗ Z ⊗ Z) ``` - - --- ## 3. Energy (full-MPO expectation value) @@ -95,14 +87,9 @@ MPSKit evaluates the full contraction ⟨ψ|H|ψ⟩: E = expectation_value(ψ, H) ``` - +The result is a scalar; for a Hermitian `H` and a normalised `ψ` its imaginary part is zero up to floating-point noise. -The same form works for `InfiniteMPS` with an `InfiniteMPOHamiltonian`. - +The same form works for `InfiniteMPS` with an `InfiniteMPOHamiltonian`, where the returned value is the energy **per unit cell**. !!! note The full-MPO form automatically computes and caches the environments. @@ -138,10 +125,6 @@ corr = correlator(ψ, Z ⊗ Z, 2, 3:L) The result is a `Vector` whose `k`-th element corresponds to `j = 3 + k - 1`. - - A common pattern is to normalise the correlator by ⟨Z⟩² to extract the connected part: ```@example observables @@ -149,11 +132,10 @@ z_mean = expectation_value(ψ, 2 => Z) connected = [c - z_mean * expectation_value(ψ, j => Z) for (j, c) in zip(3:L, corr)] ``` - +This subtracts the disconnected part ``\langle Z_i\rangle\langle Z_j\rangle`` to leave the connected correlator ``\langle Z_i Z_j\rangle - \langle Z_i\rangle\langle Z_j\rangle``. + --- @@ -167,9 +149,6 @@ var_E = variance(ψ, H) ``` A smaller variance indicates that `ψ` is closer to a true eigenstate. - After running a ground-state algorithm the variance should have dropped significantly compared to the random starting state above: @@ -178,12 +157,6 @@ After running a ground-state algorithm the variance should have dropped signific variance(ψ_gs, H) ``` - - !!! note The `variance` function also accepts an optional pre-computed `envs` argument. Pass the environments returned by `find_groundstate` to skip recomputation: @@ -228,13 +201,5 @@ Changes needed in OTHER files (do NOT edit those pages here): - docs/docs/src/howto/bond_dimension.md: same optional cross-link. - docs/docs/src/lib/groundstate.md: add a "see also" pointer to @ref howto_observables. -Doctest-runner items to validate: - 1. `expectation_value(ψ, 4 => Z)` — confirm scalar return. - 2. `expectation_value(ψ, (2, 3) => X ⊗ X)` — confirm {2,2} TensorMap is accepted. - 3. `expectation_value(ψ, (1, 2, 3) => Z ⊗ Z ⊗ Z)` — REVIEW: three-site tuple. - 4. `expectation_value(ψ, H)` — confirm FiniteMPOHamiltonian accepted without envs. - 5. `correlator(ψ, Z ⊗ Z, 2, 6)` — confirm scalar return. - 6. `correlator(ψ, Z ⊗ Z, 2, 3:L)` — confirm Vector return and length L-2. - 7. `variance(ψ, H)` — confirm non-negative real return (or near-real complex). - 8. `find_groundstate(ψ, H, DMRG(; maxiter = 10))` followed by `variance(ψ_gs, H)`. +All code blocks on this page were verified to execute against MPSKit (2026-07-01). --> diff --git a/docs/src/howto/states.md b/docs/src/howto/states.md index f8335347f..9a8ec76bd 100644 --- a/docs/src/howto/states.md +++ b/docs/src/howto/states.md @@ -70,7 +70,7 @@ physicalspace(ψ_het, 2) # ℂ^3 ## 4. A product state (trivial virtual space) -A product (bond-dimension-1) state has no entanglement. +A product (bond-dimension-1) state has no entanglement: each site carries its own single-site state, independent of the others (with `rand`, a random such state per site). Achieve this by passing `oneunit(d)` — the one-dimensional unit space of the same symmetry sector — as the maximum virtual space: ```@example howto_states @@ -79,13 +79,9 @@ dim(left_virtualspace(ψ_prod, 5)) # should be 1 ``` !!! note - `oneunit(V)` returns the one-dimensional trivial space matching the symmetry - type of `V`. + `oneunit(V)` returns the one-dimensional trivial space matching the symmetry type of `V`. For plain complex spaces, `oneunit(ℂ^2) == ℂ^1`. - - --- ## 5. From your own site tensors @@ -99,7 +95,7 @@ site_tensors = [rand(ComplexF64, ℂ^1 ⊗ ℂ^2 ← ℂ^1) for _ in 1:L] ψ_from_tensors = FiniteMPS(site_tensors) ``` -Set `normalize=true` to also normalise the state during construction (the default is `false` when passing raw tensors): +Set `normalize = true` to also normalize the state during construction (the default is `false` when passing raw tensors): ```@example howto_states ψ_normed = FiniteMPS(site_tensors; normalize = true) @@ -240,14 +236,13 @@ Pass a `Rep[G]` physical space and a `Rep[G]` maximum virtual space; the constru ### Finite MPS with U(1) symmetry - - ```@example howto_states # U(1) spin-1/2: physical space = spin up (charge +1/2) + spin down (charge -1/2) d_u1 = Rep[U₁](1 // 2 => 1, -1 // 2 => 1) # dim 2 total -D_u1 = Rep[U₁](1 // 2 => 4, -1 // 2 => 4, 3 // 2 => 2, -3 // 2 => 2) +# the virtual space must span both charge parities (integer and half-integer): +# with only ±1/2 on each site, the total charge alternates parity bond to bond, +# so a purely half-integer virtual space would starve every even bond +D_u1 = Rep[U₁](0 => 2, 1 // 2 => 2, -1 // 2 => 2, 1 => 1, -1 => 1) ψ_u1 = FiniteMPS(rand, ComplexF64, L, d_u1, D_u1) physicalspace(ψ_u1, 1) @@ -258,8 +253,7 @@ dim(left_virtualspace(ψ_u1, 5)) # actual trimmed bond dimension ≤ dim(D_u1) ``` !!! note - The boundary virtual spaces default to `oneunit(spacetype(d_u1))`, i.e. the - charge-0 sector. + The boundary virtual spaces default to `oneunit(spacetype(d_u1))`, i.e. the charge-0 sector. Use the `left` and `right` keywords to target a different total charge: ```julia @@ -274,37 +268,3 @@ dim(left_virtualspace(ψ_u1, 5)) # actual trimmed bond dimension ≤ dim(D_u1) ψ_inf_u1 = InfiniteMPS(d_u1, D_u1) physicalspace(ψ_inf_u1, 1) ``` - - - ---- - - From 12e8f25c6307601a63f23b5b24e3547fe2b8af82 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Thu, 2 Jul 2026 08:37:01 -0400 Subject: [PATCH 10/76] add quasiparticle docstrings --- docs/src/lib/operators.md | 4 --- docs/src/lib/states.md | 14 +++++--- src/states/quasiparticle_state.jl | 54 +++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 8 deletions(-) diff --git a/docs/src/lib/operators.md b/docs/src/lib/operators.md index 2adea868f..a6fbe02e3 100644 --- a/docs/src/lib/operators.md +++ b/docs/src/lib/operators.md @@ -27,10 +27,6 @@ InfiniteMPOHamiltonian JordanMPOTensor ``` - - - ## Operator algebra ```@docs; canonical=false diff --git a/docs/src/lib/states.md b/docs/src/lib/states.md index 4b854bd4c..dc7f14587 100644 --- a/docs/src/lib/states.md +++ b/docs/src/lib/states.md @@ -12,8 +12,14 @@ WindowMPS MultilineMPS ``` - +## Quasiparticle states + +Excitation ansätze produced by [`excitations`](@ref). +These behave as vectors and are normally obtained from `excitations` rather than constructed directly. + +```@docs; canonical=false +QP +LeftGaugedQP +RightGaugedQP +``` diff --git a/src/states/quasiparticle_state.jl b/src/states/quasiparticle_state.jl index 83ef7553c..c4de86e8f 100644 --- a/src/states/quasiparticle_state.jl +++ b/src/states/quasiparticle_state.jl @@ -4,6 +4,33 @@ I think it makes sense to see these things as an actual state instead of return This will allow us to plot energy density (finite qp) and measure observables. =# +""" + LeftGaugedQP{S,T1,T2,E} + LeftGaugedQP(datfun, left_gs, right_gs=left_gs; sector, momentum=0.0) + +Left-gauged quasiparticle excitation ansatz on top of a matrix product state ground state. +The excitation is parametrized through the left-gauge nullspace of the ground-state tensors, +and the object behaves as a vector so it can be handed directly to the iterative eigensolvers +used by [`excitations`](@ref). + +For a `FiniteMPS` ground state this represents a finite (localized) quasiparticle; for an +`InfiniteMPS` ground state it represents a momentum eigenstate with the given `momentum`. +When `left_gs !== right_gs` the ansatz describes a domain wall between the two ground states. + +These states are normally produced by [`excitations`](@ref) with a +[`QuasiparticleAnsatz`](@ref) rather than constructed directly. When constructing manually, +`datfun` initializes the variational tensors (e.g. `rand`/`randn`), `sector` selects the +charge sector of the excitation, and `momentum` sets the momentum for infinite ground states. + +## Fields + +- `left_gs`, `right_gs`: the ground state(s) the excitation lives on; distinct values yield a domain wall. +- `VLs`: left-nullspace tensors of the ground-state `AL` (satisfying `AL' * VL == 0`). +- `Xs`: the variational parameters of the ansatz. +- `momentum`: the excitation momentum (used for infinite ground states). + +See also [`RightGaugedQP`](@ref), [`QP`](@ref). +""" struct LeftGaugedQP{S, T1, T2, E <: Number} # !(left_gs === right_gs) => domain wall excitation left_gs::S @@ -15,6 +42,24 @@ struct LeftGaugedQP{S, T1, T2, E <: Number} momentum::E end +""" + RightGaugedQP{S,T1,T2,E} + RightGaugedQP(datfun, left_gs, right_gs=left_gs; sector, momentum=0.0) + +Right-gauged counterpart of [`LeftGaugedQP`](@ref): the same quasiparticle excitation ansatz, +but parametrized through the right-gauge nullspace of the ground-state tensors. It is most +often obtained via `convert(RightGaugedQP, ϕ)` from a `LeftGaugedQP` rather than constructed +directly. + +## Fields + +- `left_gs`, `right_gs`: the ground state(s) the excitation lives on; distinct values yield a domain wall. +- `Xs`: the variational parameters of the ansatz. +- `VRs`: right-nullspace tensors of the ground-state `AR`. +- `momentum`: the excitation momentum (used for infinite ground states). + +See also [`LeftGaugedQP`](@ref), [`QP`](@ref). +""" struct RightGaugedQP{S, T1, T2, E <: Number} # !(left_gs === right_gs) => domain wall excitation left_gs::S @@ -207,6 +252,15 @@ function Base.convert( end # gauge independent code +""" + QP{S,T1,T2} + +Union of the quasiparticle excitation ansätze [`LeftGaugedQP`](@ref) and +[`RightGaugedQP`](@ref). It is used for dispatch and to share their gauge-independent +interface; it is not a concrete type and cannot be constructed on its own. The internal +aliases `FiniteQP` and `InfiniteQP` further restrict the ground-state type to `FiniteMPS` +or `InfiniteMPS` respectively. +""" const QP{S, T1, T2} = Union{LeftGaugedQP{S, T1, T2}, RightGaugedQP{S, T1, T2}} const FiniteQP{S <: FiniteMPS, T1, T2} = QP{S, T1, T2} const InfiniteQP{S <: InfiniteMPS, T1, T2} = QP{S, T1, T2} From fbb6e4f60db0744b59cd8df7e58cfd89a067142f Mon Sep 17 00:00:00 2001 From: lkdvos Date: Fri, 3 Jul 2026 08:18:11 -0400 Subject: [PATCH 11/76] docs(references): add recent publications using MPSKit Add 20 entries to the "Publications using MPSKit" list: 17 from the append-candidates review plus 3 found via web search (staelens2026, yang2026, zemlevskiy2026). Introduce a 2026 section and extend 2025. - Verified every arXiv ID / DOI resolves to a real paper. - Upgraded published preprints: vancraeynestdecuiper2026 to @article (SciPost Phys. Lect. Notes 128); added arXiv eprints to the already published zong2026pseudogap, vandamme2025pseudogenerators, sommer2025. - Flagged with % NOTE the entries whose MPSKit citation could not be independently confirmed (lu2026 cites it only in its bibliography). Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/src/assets/mpskit.bib | 296 +++++++++++++++++++++++++++++++++++++ docs/src/references.md | 28 +++- 2 files changed, 323 insertions(+), 1 deletion(-) diff --git a/docs/src/assets/mpskit.bib b/docs/src/assets/mpskit.bib index 296f4194b..f8daacdc3 100644 --- a/docs/src/assets/mpskit.bib +++ b/docs/src/assets/mpskit.bib @@ -614,3 +614,299 @@ @article{zhang2023 url = {https://link.aps.org/doi/10.1103/PhysRevLett.130.151602}, abstract = {We show that the Klein bottle entropy [H.-H. Tu, Phys. Rev. Lett. 119, 261603 (2017)] for conformal field theories perturbed by a relevant operator is a universal function of the dimensionless coupling constant. The universal scaling of the Klein bottle entropy near criticality provides an efficient approach to extract the scaling dimension of lattice operators via data collapse. As paradigmatic examples, we validate the universal scaling of the Klein bottle entropy for Ising and {$\mathbb{Z}$}3 parafermion conformal field theories with various perturbations using numerical simulation with continuous matrix product operator approach.} } + +% --------------------------------------------------------------------------- +% Publications using MPSKit added 2026-07 (from append-candidates review + web search). +% Entries verified to exist (arXiv IDs / DOIs checked). Notes flag any entry whose +% MPSKit citation could not be independently confirmed during review. +% --------------------------------------------------------------------------- + +@misc{ueda2026, + title = {Emergent {{Andreev Reflection}} from a {{Lattice Duality Defect}}}, + author = {Ueda, Atsushi and Numasawa, Tokiro and {De Vos}, Boris and Watanabe, Masataka}, + year = {2026}, + month = jun, + number = {arXiv:2606.23684}, + eprint = {2606.23684}, + primaryclass = {cond-mat.str-el}, + publisher = {arXiv}, + doi = {10.48550/arXiv.2606.23684}, + url = {https://arxiv.org/abs/2606.23684}, + archiveprefix = {arXiv} +} + +@misc{kaplan2026, + title = {Wavelet {{Matrix Product States}} for {{Quantum Fields}}}, + author = {Kaplan, Molly and Tilloy, Antoine}, + year = {2026}, + month = jun, + number = {arXiv:2606.23823}, + eprint = {2606.23823}, + primaryclass = {quant-ph}, + publisher = {arXiv}, + doi = {10.48550/arXiv.2606.23823}, + url = {https://arxiv.org/abs/2606.23823}, + archiveprefix = {arXiv} +} + +@misc{shankar2026, + title = {Finite-{{Element Matrix Product States}} for {{Continuum Models}} in {{One Dimension}}}, + author = {Shankar, Akshay and {Van Acoleyen}, Karel and Haegeman, Jutho}, + year = {2026}, + month = jun, + number = {arXiv:2606.14873}, + eprint = {2606.14873}, + primaryclass = {quant-ph}, + publisher = {arXiv}, + doi = {10.48550/arXiv.2606.14873}, + url = {https://arxiv.org/abs/2606.14873}, + archiveprefix = {arXiv} +} + +@misc{veitas2026, + title = {Fluctuation-Driven Chiral Ferromagnetism}, + author = {Veitas, Rokas and Khalifa, Ahmed and Machado, Francisco and Chatterjee, Shubhayu}, + year = {2026}, + month = may, + number = {arXiv:2605.06852}, + eprint = {2605.06852}, + primaryclass = {cond-mat.str-el}, + publisher = {arXiv}, + doi = {10.48550/arXiv.2605.06852}, + url = {https://arxiv.org/abs/2605.06852}, + archiveprefix = {arXiv} +} + +@misc{vanthilt2026, + title = {Matrix {{Product Operator}} Encodings of the {{Magnus Expansion}} and {{Dyson Series}}}, + author = {Vanthilt, Victor and {Van Damme}, Maarten and Haegeman, Jutho and McCulloch, Ian P. and Vanderstraeten, Laurens}, + year = {2026}, + month = may, + number = {arXiv:2605.21597}, + eprint = {2605.21597}, + primaryclass = {quant-ph}, + publisher = {arXiv}, + doi = {10.48550/arXiv.2605.21597}, + url = {https://arxiv.org/abs/2605.21597}, + archiveprefix = {arXiv} +} + +@misc{zong2026nickelate, + title = {Correlation-Driven Orbital-Selective Fermiology and Superconductivity in the Bilayer Nickelate {{La}}$_3${{Ni}}$_2${{O}}$_7$}, + author = {Zong, Yong-Yue and Yu, Shun-Li and Li, Jian-Xin}, + year = {2026}, + month = may, + number = {arXiv:2605.10101}, + eprint = {2605.10101}, + primaryclass = {cond-mat.str-el}, + publisher = {arXiv}, + doi = {10.48550/arXiv.2605.10101}, + url = {https://arxiv.org/abs/2605.10101}, + archiveprefix = {arXiv} +} + +% NOTE: published PRX; MPSKit citation not independently confirmed during review (uses DMRG). +@article{zong2026pseudogap, + title = {Pseudogap with {{Fermi Arcs}} and {{Fermi Pockets}} in Half-Filled Twisted Transition Metal Dichalcogenides}, + author = {Zong, Yong-Yue and Gu, Zhao-Long and Li, Jian-Xin}, + year = {2026}, + month = jan, + journal = {Physical Review X}, + volume = {16}, + number = {1}, + pages = {011005}, + publisher = {American Physical Society}, + doi = {10.1103/kmn8-y59j}, + url = {https://link.aps.org/doi/10.1103/kmn8-y59j}, + eprint = {2406.11374}, + archiveprefix = {arXiv} +} + +% NOTE: MPSKit appears in the bibliography; primary numerics use ITensor. +@misc{lu2026, + title = {Generalized {{Kramers-Wannier Self-Duality}} in {{Hopf-Ising Models}}}, + author = {Lu, Da-Chuan and Chatterjee, Arkya and Tantivasadakarn, Nathanan}, + year = {2026}, + month = feb, + number = {arXiv:2602.10183}, + eprint = {2602.10183}, + primaryclass = {cond-mat.str-el}, + publisher = {arXiv}, + doi = {10.48550/arXiv.2602.10183}, + url = {https://arxiv.org/abs/2602.10183}, + archiveprefix = {arXiv} +} + +@misc{hormann2026, + title = {Folds of One Curve: The Superradiant Phase Diagram of {{Dicke}} Modes with Interacting Matter}, + author = {H{\"o}rmann, Max}, + year = {2026}, + month = jun, + number = {arXiv:2606.26081}, + eprint = {2606.26081}, + primaryclass = {cond-mat.str-el}, + publisher = {arXiv}, + doi = {10.48550/arXiv.2606.26081}, + url = {https://arxiv.org/abs/2606.26081}, + archiveprefix = {arXiv} +} + +@misc{kadow2026, + title = {Fractionalization from Kinetic Frustration in Doped Two-Dimensional {{SU}}(4) Quantum Magnets}, + author = {Kadow, Wilhelm and Morera, Ivan and Demler, Eugene and Knap, Michael}, + year = {2026}, + month = mar, + number = {arXiv:2603.28871}, + eprint = {2603.28871}, + primaryclass = {cond-mat.str-el}, + publisher = {arXiv}, + doi = {10.48550/arXiv.2603.28871}, + url = {https://arxiv.org/abs/2603.28871}, + archiveprefix = {arXiv} +} + +@misc{basumatary2026, + title = {Cosmological Correlators Using Tensor Networks}, + author = {Basumatary, Ujjwal and Sinha, Aninda and Zhou, Xinan}, + year = {2026}, + month = mar, + number = {arXiv:2603.26090}, + eprint = {2603.26090}, + primaryclass = {hep-th}, + publisher = {arXiv}, + doi = {10.48550/arXiv.2603.26090}, + url = {https://arxiv.org/abs/2603.26090}, + archiveprefix = {arXiv} +} + +@misc{brehmer2026, + title = {{{PEPSKit.jl}}: A {{Julia}} Package for Projected Entangled-Pair State Simulations}, + author = {Brehmer, Paul and Burgelman, Lander and Yue, Zheng-Yuan and Fedorovich, Gleb and Haegeman, Jutho and Devos, Lukas}, + year = {2026}, + month = may, + number = {arXiv:2605.19960}, + eprint = {2605.19960}, + primaryclass = {cond-mat.str-el}, + publisher = {arXiv}, + doi = {10.48550/arXiv.2605.19960}, + url = {https://arxiv.org/abs/2605.19960}, + archiveprefix = {arXiv} +} + +@misc{ritter2026, + title = {Fast Elementwise Operations on Tensor Trains with Alternating Cross Interpolation}, + author = {Ritter, Marc K.}, + year = {2026}, + month = apr, + number = {arXiv:2604.00037}, + eprint = {2604.00037}, + primaryclass = {math.NA}, + publisher = {arXiv}, + doi = {10.48550/arXiv.2604.00037}, + url = {https://arxiv.org/abs/2604.00037}, + archiveprefix = {arXiv} +} + +% NOTE: published SciPost lecture notes; MPSKit citation not independently confirmed during review. +@article{vancraeynestdecuiper2026, + title = {Les {{Houches}} Lecture Notes on Tensor Networks}, + author = {{Vancraeynest-De Cuiper}, Bram and Wiesiolek, Weronika and Verstraete, Frank}, + year = {2026}, + journal = {SciPost Physics Lecture Notes}, + pages = {128}, + issn = {2590-1990}, + doi = {10.21468/SciPostPhysLectNotes.128}, + url = {https://scipost.org/10.21468/SciPostPhysLectNotes.128}, + eprint = {2512.24390}, + archiveprefix = {arXiv} +} + +@misc{staelens2026, + title = {Combining Matrix Product States and Mean-Field Theory to Capture Magnetic Order in Quasi-1D Cuprates}, + author = {Staelens, Quentin and Verraes, Daan and Vrancken, Daan and Braeckevelt, Tom and Haegeman, Jutho and {Van Speybroeck}, Veronique}, + year = {2026}, + month = feb, + number = {arXiv:2602.21695}, + eprint = {2602.21695}, + primaryclass = {cond-mat.str-el}, + publisher = {arXiv}, + doi = {10.48550/arXiv.2602.21695}, + url = {https://arxiv.org/abs/2602.21695}, + archiveprefix = {arXiv} +} + +@misc{yang2026, + title = {Transfer-Matrix Functions for Algebraically Decaying Interactions in Variational Infinite Matrix Product States}, + author = {Yang, Qi}, + year = {2026}, + month = jun, + number = {arXiv:2606.20522}, + eprint = {2606.20522}, + primaryclass = {cond-mat.str-el}, + publisher = {arXiv}, + doi = {10.48550/arXiv.2606.20522}, + url = {https://arxiv.org/abs/2606.20522}, + archiveprefix = {arXiv} +} + +@misc{zemlevskiy2026, + title = {Exclusive Scattering Channels from Entanglement Structure in Real-Time Simulations}, + author = {Zemlevskiy, Nikita A.}, + year = {2026}, + month = mar, + number = {arXiv:2603.15621}, + eprint = {2603.15621}, + primaryclass = {quant-ph}, + publisher = {arXiv}, + doi = {10.48550/arXiv.2603.15621}, + url = {https://arxiv.org/abs/2603.15621}, + archiveprefix = {arXiv} +} + +% NOTE: published Communications Physics; MPSKit citation not independently confirmed during review. +@article{vandamme2025pseudogenerators, + title = {Suppressing Nonperturbative Gauge Errors in the Thermodynamic Limit Using Local Pseudogenerators}, + author = {{Van Damme}, Maarten and Mildenberger, Julius and Grusdt, Fabian and Hauke, Philipp and Halimeh, Jad C.}, + year = {2025}, + month = mar, + journal = {Communications Physics}, + volume = {8}, + number = {1}, + pages = {106}, + publisher = {Springer Nature}, + doi = {10.1038/s42005-025-02035-y}, + url = {https://www.nature.com/articles/s42005-025-02035-y}, + eprint = {2110.08041}, + archiveprefix = {arXiv} +} + +@article{sommer2025, + title = {Higher Berry Curvature from the Wave Function. I. {{Schmidt}} Decomposition and Matrix Product States}, + author = {Sommer, Ophelia Evelyn and Wen, Xueda and Vishwanath, Ashvin}, + year = {2025}, + month = apr, + journal = {Physical Review Letters}, + volume = {134}, + number = {14}, + pages = {146601}, + publisher = {American Physical Society}, + doi = {10.1103/PhysRevLett.134.146601}, + url = {https://link.aps.org/doi/10.1103/PhysRevLett.134.146601}, + eprint = {2405.05316}, + archiveprefix = {arXiv} +} + +% NOTE: lecture notes; MPSKit citation not independently confirmed during review. +@misc{sinha2025, + title = {Lectures on Quantum Field Theory on a Quantum Computer}, + author = {Sinha, Aninda and Basumatary, Ujjwal}, + year = {2025}, + month = dec, + number = {arXiv:2512.02706}, + eprint = {2512.02706}, + primaryclass = {quant-ph}, + publisher = {arXiv}, + doi = {10.48550/arXiv.2512.02706}, + url = {https://arxiv.org/abs/2512.02706}, + archiveprefix = {arXiv} +} diff --git a/docs/src/references.md b/docs/src/references.md index bdfee2cf7..a2670933c 100644 --- a/docs/src/references.md +++ b/docs/src/references.md @@ -6,6 +6,29 @@ Below you can find a list of publications that have made use of MPSKit. If you h this package and wish to have your publication added to this list, please open a pull request or an issue on the [GitHub repository](https://github.com/QuantumKitHub/MPSKit.jl/). +### 2026 + +```@bibliography +Pages = [] +basumatary2026 +brehmer2026 +hormann2026 +kadow2026 +kaplan2026 +lu2026 +ritter2026 +shankar2026 +staelens2026 +ueda2026 +vancraeynestdecuiper2026 +vanthilt2026 +veitas2026 +yang2026 +zemlevskiy2026 +zong2026nickelate +zong2026pseudogap +``` + ### 2025 ```@bibliography @@ -15,10 +38,13 @@ dempsey2025 herviou2025 kirchner2025 linden2025 -mortier2025 maertens2025 +mortier2025 shen2025 +sinha2025 +sommer2025 ueda2025 +vandamme2025pseudogenerators vrancken2025 ``` ### 2024 From ee00ff2f3a3b9ab62e9f66954af3d35f4e9b1f35 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Fri, 3 Jul 2026 08:23:03 -0400 Subject: [PATCH 12/76] docs(wave1): lib reference pages (observables, bond_dimension, time_evolution, excitations) Category reference pages grouping the exported observables/analysis, bond-dimension, time-evolution, and excitation docstrings via `@docs; canonical=false`, mirroring the existing lib/ page structure. Every listed symbol verified exported with an attached docstring against src/. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/src/lib/bond_dimension.md | 54 +++++++++++++++++++++++++++++++ docs/src/lib/excitations.md | 45 ++++++++++++++++++++++++++ docs/src/lib/observables.md | 58 ++++++++++++++++++++++++++++++++++ docs/src/lib/time_evolution.md | 41 ++++++++++++++++++++++++ 4 files changed, 198 insertions(+) create mode 100644 docs/src/lib/bond_dimension.md create mode 100644 docs/src/lib/excitations.md create mode 100644 docs/src/lib/observables.md create mode 100644 docs/src/lib/time_evolution.md diff --git a/docs/src/lib/bond_dimension.md b/docs/src/lib/bond_dimension.md new file mode 100644 index 000000000..dfd3d8c7e --- /dev/null +++ b/docs/src/lib/bond_dimension.md @@ -0,0 +1,54 @@ +# [Bond dimension](@id lib_bond_dimension) + +Reference for changing the bond dimension of a state — expanding or truncating its virtual spaces — and for inspecting those virtual spaces directly. +For a task-oriented walkthrough see [Controlling bond dimension](@ref howto_bond_dimension); the full, canonical docstrings for the whole package live in the [Library](@ref lib_index) index. + +## Interface + +```@docs; canonical=false +changebonds +changebonds! +``` + +## Expansion and truncation algorithms + +```@docs; canonical=false +OptimalExpand +RandExpand +SvdCut +VUMPSSvdCut +SketchedExpand +``` + +!!! note + `SketchedExpand` is experimental: it uses randomized controlled bond expansion (CBE), so its reported error estimate is itself randomized, and it is only defined for `FiniteMPS`. + +## Inspecting the virtual spaces + +The bond dimension of an MPS or MPO is the dimension of the virtual space living on a given bond. +The accessors below return that `VectorSpace`, whose `dim` gives the numeric bond dimension. + +```@docs; canonical=false +left_virtualspace +right_virtualspace +physicalspace +``` + + diff --git a/docs/src/lib/excitations.md b/docs/src/lib/excitations.md new file mode 100644 index 000000000..3433a2e42 --- /dev/null +++ b/docs/src/lib/excitations.md @@ -0,0 +1,45 @@ +# [Excitations](@id lib_excitations) + +Reference for the excitation interface, its algorithms, and the quasiparticle state types it produces. +For a task-oriented walkthrough see the how-to guides. +The full, canonical docstrings for the whole package live in the [Library](@ref lib_index) index. + +## Interface + +```@docs; canonical=false +excitations +``` + +## Algorithms + +```@docs; canonical=false +QuasiparticleAnsatz +FiniteExcited +ChepigaAnsatz +ChepigaAnsatz2 +``` + +## Quasiparticle states + +These are the ansatz states produced by, and passed to, `excitations` on top of a ground state. + +```@docs; canonical=false +QP +LeftGaugedQP +RightGaugedQP +``` + + diff --git a/docs/src/lib/observables.md b/docs/src/lib/observables.md new file mode 100644 index 000000000..737694663 --- /dev/null +++ b/docs/src/lib/observables.md @@ -0,0 +1,58 @@ +# [Observables and analysis](@id lib_observables) + +Reference for extracting physical quantities and analysis diagnostics from an MPS. +For a task-oriented walkthrough see the how-to guide [Computing observables](@ref howto_observables). +The full, canonical docstrings for the whole package live in the [Library](@ref lib_index) index. + +## Expectation values + +```@docs; canonical=false +expectation_value +``` + +## Correlators + +```@docs; canonical=false +correlator +``` + +## Convergence diagnostics + +```@docs; canonical=false +variance +``` + +## Transfer matrix and correlation length + +```@docs; canonical=false +correlation_length +marek_gap +transfer_spectrum +transferplot +``` + +## Entanglement + +Entropy and entanglement spectrum are computed from the state's bond/gauge tensors. +See the how-to [Entanglement entropy and spectrum](@ref howto_entanglement) for worked recipes. + +```@docs; canonical=false +entropy +entanglement_spectrum +entanglementplot +``` + + diff --git a/docs/src/lib/time_evolution.md b/docs/src/lib/time_evolution.md new file mode 100644 index 000000000..698712db7 --- /dev/null +++ b/docs/src/lib/time_evolution.md @@ -0,0 +1,41 @@ +# [Time evolution](@id lib_time_evolution) + +Reference for the time-evolution drivers and algorithms. +For a task-oriented walkthrough see the how-to guides. +The full, canonical docstrings for the whole package live in the [Library](@ref lib_index) index. + +## Drivers + +```@docs; canonical=false +time_evolve +timestep +timestep! +``` + +## MPS time-evolution algorithms + +```@docs; canonical=false +TDVP +TDVP2 +``` + +## Time-evolution MPOs + +For evolving with an explicitly constructed propagator MPO, e.g. for an [`InfiniteMPS`](@ref), use [`make_time_mpo`](@ref) with one of the expansion algorithms below. + +```@docs; canonical=false +make_time_mpo +TaylorCluster +WI +WII +``` + + From 1d941c8d0b00cef548a1ae28d2e324853db42fdb Mon Sep 17 00:00:00 2001 From: lkdvos Date: Fri, 3 Jul 2026 08:23:03 -0400 Subject: [PATCH 13/76] docs(wave1): how-to guides for building Hamiltonians and entanglement Two task-oriented how-to pages following the observables.md template: - howto/hamiltonians.md: finite/infinite MPO Hamiltonians from local terms, boundary-condition conversion, and window Hamiltonians. - howto/entanglement.md: entanglement entropy and spectrum from gauge tensors. All @example blocks verified to execute against real MPSKit; physics claims flagged with REVIEW for maintainer sign-off. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/src/howto/entanglement.md | 198 +++++++++++++++++++++++++++++++++ docs/src/howto/hamiltonians.md | 155 ++++++++++++++++++++++++++ 2 files changed, 353 insertions(+) create mode 100644 docs/src/howto/entanglement.md create mode 100644 docs/src/howto/hamiltonians.md diff --git a/docs/src/howto/entanglement.md b/docs/src/howto/entanglement.md new file mode 100644 index 000000000..d635dde2b --- /dev/null +++ b/docs/src/howto/entanglement.md @@ -0,0 +1,198 @@ +# [Entanglement entropy and spectrum](@id howto_entanglement) + +This page collects recipes for extracting the entanglement entropy and the entanglement spectrum from the gauge (bond) tensors of an MPS. +For general expectation values and correlators see [Computing observables](@ref howto_observables); for building the state objects used below see [Constructing states](@ref howto_states). +The reference page for these and related functions is [Observables and analysis](@ref lib_observables). + +```@example entanglement +using MPSKit, TensorKit +``` + +--- + +## Setup: a TFIM ground state + +The examples below reuse a spin-1/2 `FiniteMPS` and the transverse-field Ising Hamiltonian, optimized with DMRG so the entanglement structure reflects an actual ground state rather than a random tensor: + +```@example entanglement +L = 8 +ψ0 = FiniteMPS(L, ℂ^2, ℂ^8) + +# single-site Pauli operators +X = TensorMap(ComplexF64[0 1; 1 0], ℂ^2, ℂ^2) +Z = TensorMap(ComplexF64[1 0; 0 -1], ℂ^2, ℂ^2) + +lattice = fill(ℂ^2, L) +H = FiniteMPOHamiltonian(lattice, (i, i + 1) => -(X ⊗ X) for i in 1:(L - 1)) + + FiniteMPOHamiltonian(lattice, (i,) => -0.5 * Z for i in 1:L) + +ψ, envs, _ = find_groundstate(ψ0, H, DMRG(; maxiter = 10)) +``` + +--- + +## 1. Entanglement entropy at a single cut + +[`entropy`](@ref) returns the von Neumann entanglement entropy across the cut to the right of a given site. +For a `FiniteMPS` the site is a required argument: + +```@example entanglement +entropy(ψ, L ÷ 2) # entropy across the central cut +``` + + + +--- + +## 2. Entropy profile across every cut + +Collecting `entropy(ψ, i)` over the valid range of sites gives the full entropy profile of the chain: + +```@example entanglement +[entropy(ψ, i) for i in 1:L] +``` + +!!! warning + For `FiniteMPS` the cut site is required and must lie in `1:length(ψ)`. + `site = 0` — a valid default for `InfiniteMPS` and `WindowMPS` (see recipe 5) — throws a `BoundsError` for `FiniteMPS`. + +--- + +## 3. The entanglement spectrum + +[`entanglement_spectrum`](@ref) returns the singular values of the gauge tensor to the right of a site, packaged as a sector-resolved vector: + +```@example entanglement +spectrum = entanglement_spectrum(ψ, L ÷ 2) +``` + +The entropy can equivalently be computed directly from this spectrum with [`entropy`](@ref): + +```@example entanglement +entropy(spectrum) +``` + +```@example entanglement +entropy(ψ, L ÷ 2) ≈ entropy(spectrum) +``` + +Both routes agree, since `entropy(ψ, site)` computes the entropy from exactly this spectrum internally. + +--- + +## 4. Sector-resolved spectrum + +Because the returned spectrum is indexed by symmetry sector, you can inspect the singular values sector by sector. +Use `keys` to list the sectors present at a cut, and index the spectrum with a sector to obtain its singular values: + +```@example entanglement +collect(keys(spectrum)) +``` + +```@example entanglement +spectrum[only(keys(spectrum))] +``` + +For the plain (no explicit symmetry) `FiniteMPS` built above there is a single sector, `Trivial()`, so all singular values live in one block. +`pairs(spectrum)` iterates `sector => values` pairs and is the natural entry point for a symmetric state where multiple sectors are populated at a cut: + +```@example entanglement +collect(pairs(spectrum)) +``` + + + +--- + +## 5. Entanglement of an infinite MPS + +For `InfiniteMPS`, the cut site defaults to `0`, and `entropy` without a site argument returns one entropy per site in the unit cell: + +```@example entanglement +ψ∞ = InfiniteMPS(ℂ^2, ℂ^8) +entropy(ψ∞) +``` + +```@example entanglement +entanglement_spectrum(ψ∞) # site defaults to 0 +``` + + + +!!! note + `WindowMPS` also supports `entropy(ψ, site)` with a required site argument, mirroring the `FiniteMPS` form. + + +--- + +## Plotting the spectrum + +MPSKit defines an `entanglementplot` recipe via `RecipesBase`, but does not depend on Plots.jl itself. +To use it, add `using Plots` (or another Plots-backed package) in your own environment: + +```julia +using Plots +entanglementplot(ψ; site = L ÷ 2) +``` + +!!! note + `entanglementplot` is a plotting *recipe*: it only becomes available once `Plots` (or a compatible plotting package) is loaded. + This block is not executed on this page to keep the docs build free of the Plots.jl dependency. + +--- + + diff --git a/docs/src/howto/hamiltonians.md b/docs/src/howto/hamiltonians.md new file mode 100644 index 000000000..f90bae4ed --- /dev/null +++ b/docs/src/howto/hamiltonians.md @@ -0,0 +1,155 @@ +# [Building Hamiltonians](@id howto_hamiltonians) + +This page collects recipes for constructing MPO Hamiltonians from local operators, for both finite and infinite (translation-invariant) lattices. +It also covers converting an infinite Hamiltonian to finite open or periodic boundary conditions, and carving a finite window out of an infinite Hamiltonian. +For building the matching state objects see [Constructing states](@ref howto_states); for evaluating a Hamiltonian's energy on a state see [Computing observables](@ref howto_observables). +The reference page for the underlying MPO structure is [Operators](@ref lib_operators). + +```@example hamiltonians +using MPSKit, TensorKit +``` + +--- + +## Setup: local operators + +The examples below build the transverse-field Ising model (TFIM), the same flagship model used elsewhere in these docs. + +All operators are `ComplexF64` `TensorMap`s on the spin-1/2 physical space `ℂ^2`: + +```@example hamiltonians +X = TensorMap(ComplexF64[0 1; 1 0], ℂ^2, ℂ^2) +Z = TensorMap(ComplexF64[1 0; 0 -1], ℂ^2, ℂ^2) +g = 0.5 +``` + +--- + +## 1. Finite Hamiltonian from local terms + +[`FiniteMPOHamiltonian`](@ref) takes an array of `VectorSpace` objects describing the local Hilbert spaces, followed by any number of `inds => operator` pairs. +A single-site term uses a one-element tuple `(i,) => O`; a nearest-neighbour term uses a two-element tuple `(i, i + 1) => O₁₂`, where `O₁₂` is a two-site operator built with `⊗`: + +```@example hamiltonians +L = 8 +lattice = fill(ℂ^2, L) + +H_finite = FiniteMPOHamiltonian(lattice, (i, i + 1) => -(X ⊗ X) for i in 1:(L - 1)) + + FiniteMPOHamiltonian(lattice, (i,) => -g * Z for i in 1:L) +``` + +Adding the two `FiniteMPOHamiltonian` objects combines the bond terms and the field terms into a single Jordan-block MPO. +Equivalently, all terms can be passed as one call by splatting a single collection of `inds => operator` pairs; see [Operators](@ref lib_operators) for that form. + +!!! note + The index tuples must refer to contiguous sites for the two-site pairs shown here. + See [Operators](@ref lib_operators) for the general, non-nearest-neighbour "expert mode" construction, which is not covered on this task-oriented page. + +--- + +## 2. Infinite (translation-invariant) Hamiltonian + +[`InfiniteMPOHamiltonian`](@ref) uses the same `inds => operator` convention, but the lattice argument is a single unit cell, and site indices wrap around it periodically. +For the 1-site TFIM unit cell, `(1, 2) => O₁₂` couples site 1 to site 2 of the *next* unit cell: + +```@example hamiltonians +unitcell = fill(ℂ^2, 1) +H_inf = InfiniteMPOHamiltonian(unitcell, (1, 2) => -(X ⊗ X), (1,) => -g * Z) +``` + +The resulting operator repeats this single bond-plus-field pattern along the whole infinite chain. +Use it directly with an [`InfiniteMPS`](@ref) in `expectation_value` or `find_groundstate`, exactly as described in [Computing observables](@ref howto_observables). + +!!! tip + Hand-assembling local operators works for any model, but for standard lattice models MPSKitModels.jl provides ready-made Hamiltonian builders and the `@mpoham` macro for a more compact syntax. + See the MPSKitModels.jl documentation for that higher-level interface; it is a separate package from MPSKit and not covered here. + +--- + +## 3. Converting between boundary conditions + +Starting from an `InfiniteMPOHamiltonian`, [`open_boundary_conditions`](@ref) truncates it to a finite chain of length `L` with open ends, and [`periodic_boundary_conditions`](@ref) instead closes it into a finite ring. +In both cases `L` must be a multiple of the unit-cell length: + +```@example hamiltonians +L_finite = 6 # multiple of the 1-site unit cell + +H_open = open_boundary_conditions(H_inf, L_finite) +``` + +```@example hamiltonians +H_periodic = periodic_boundary_conditions(H_inf, L_finite) +``` + +`H_open` is the same finite-chain Hamiltonian you would get from writing out the terms by hand, as in recipe 1 above, restricted to `L_finite` sites. +`H_periodic` additionally couples the last site back to the first, forming a ring. + +!!! note + Both functions return a [`FiniteMPOHamiltonian`](@ref). + There is no boundary-condition keyword on the `FiniteMPOHamiltonian`/`InfiniteMPOHamiltonian` constructors themselves; boundary conditions are chosen by picking which constructor (or conversion function) to call. + +--- + +## 4. A window Hamiltonian + +[`WindowMPOHamiltonian`](@ref) carves a finite interval out of an infinite Hamiltonian while keeping the infinite left and right environments intact. +This is the operator counterpart of a [`WindowMPS`](@ref) (see [Constructing states](@ref howto_states)), and the two are used together to study a finite region embedded in, and coupled to, an infinite bulk: + +```@example hamiltonians +H_window = WindowMPOHamiltonian(H_inf, 1:6) +``` + +The interval `1:6` selects which unit cells of `H_inf` become the mutable finite window; everything outside it is treated as the fixed infinite environment. + +--- + + From e7ce07aaf4b49543e0fe3620b05c97de4fb15ce4 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Fri, 3 Jul 2026 08:23:03 -0400 Subject: [PATCH 14/76] docs(wave1): register new reference and how-to pages in make.jl Adds howto/{hamiltonians,entanglement}.md to the How-to section and lib/{bond_dimension,time_evolution,excitations,observables}.md to the Library section, ordered to mirror the public API surface in lib/public.md. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/make.jl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/make.jl b/docs/make.jl index eabd3ac48..613e8e0bf 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -58,8 +58,10 @@ makedocs(; ], "How-to" => [ "howto/states.md", + "howto/hamiltonians.md", "howto/bond_dimension.md", "howto/observables.md", + "howto/entanglement.md", ], "Examples" => "examples/index.md", "Library" => [ @@ -67,6 +69,10 @@ makedocs(; "lib/states.md", "lib/operators.md", "lib/groundstate.md", + "lib/bond_dimension.md", + "lib/time_evolution.md", + "lib/excitations.md", + "lib/observables.md", "lib/lib.md", ], "References" => "references.md", From bbf43c193bf9ca426a3d56b5366c57224f4ee3ed Mon Sep 17 00:00:00 2001 From: lkdvos Date: Fri, 3 Jul 2026 08:44:02 -0400 Subject: [PATCH 15/76] docs: address PR #438 review comments on bond-expansion docstrings Incorporate post-merge review feedback (docstring/wording only): - changebond docstring: drop inaccurate "in place", "enriched" -> "expanded" - OptimalExpand: reword "does not alter the state" -> "state-preserving" to avoid implying out-of-place operation - TDVP: "enriches" -> "expands" the bond Co-Authored-By: Claude Opus 4.8 (1M context) --- src/algorithms/changebonds/changebonds.jl | 4 ++-- src/algorithms/changebonds/optimalexpand.jl | 5 +++-- src/algorithms/timestep/tdvp.jl | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/algorithms/changebonds/changebonds.jl b/src/algorithms/changebonds/changebonds.jl index 9dce51c45..29152111b 100644 --- a/src/algorithms/changebonds/changebonds.jl +++ b/src/algorithms/changebonds/changebonds.jl @@ -16,9 +16,9 @@ function changebonds! end changebond(site, dir, ψ, [H], alg, [envs]) -> ψ changebond!(site, dir, ψ, [H], alg, [envs]) -> ψ -Expand a single bond of `ψ` in place by adding directions orthogonal to the current state, keeping the state in mixed-canonical form around the enriched bond. +Expand a single bond of `ψ` by adding directions orthogonal to the current state, keeping the state in mixed-canonical form around the expanded bond. The sweep direction `dir` is a `Val(:right)` or `Val(:left)` used for dispatch. -For `Val(:right)` the bond `(site, site + 1)` is enriched on the right tensor (`ψ.AR[site + 1]`) with zero weight added at `ψ.AC[site]`, so that a subsequent single-site optimization of `site` sees the new directions; +For `Val(:right)` the bond `(site, site + 1)` is expanded on the right tensor (`ψ.AR[site + 1]`) with zero weight added at `ψ.AC[site]`, so that a subsequent single-site optimization of `site` sees the new directions; for `Val(:left)` the mirror is applied to bond `(site - 1, site)`. See also [`changebonds`](@ref), [`changebonds!`](@ref). diff --git a/src/algorithms/changebonds/optimalexpand.jl b/src/algorithms/changebonds/optimalexpand.jl index 73da47899..db5ac9a76 100644 --- a/src/algorithms/changebonds/optimalexpand.jl +++ b/src/algorithms/changebonds/optimalexpand.jl @@ -5,8 +5,9 @@ An algorithm that expands the given mps as described in [Zauner-Stauber et al. Phys. Rev. B 97 (2018)](@cite zauner-stauber2018), by selecting the dominant contributions of a two-site updated MPS tensor, orthogonal to the original ψ. -The expansion does not alter the state: the added directions are connected through a zero block, -so that the expanded state is identical to the original one (as required for e.g. TDVP). +The expansion is state-preserving: the added directions are connected through a zero block, +so that the expanded state represents the same physical state as the original one (as required +for e.g. TDVP). !!! note [`changebonds!`](@ref) is only defined for `FiniteMPS`, and modifies both the state and its environment. diff --git a/src/algorithms/timestep/tdvp.jl b/src/algorithms/timestep/tdvp.jl index 993782e54..209ca8aef 100644 --- a/src/algorithms/timestep/tdvp.jl +++ b/src/algorithms/timestep/tdvp.jl @@ -4,7 +4,7 @@ $(TYPEDEF) Single site MPS time-evolution algorithm based on the Time-Dependent Variational Principle. For finite MPS, setting `alg_expand` to a bond-expansion algorithm (e.g. [`OptimalExpand`](@ref), -[`SketchedExpand`](@ref)) enriches the bond with directions orthogonal to the current state +[`SketchedExpand`](@ref)) expands the bond with directions orthogonal to the current state ahead of each local integration, recovering Controlled Bond Expansion (CBE) TDVP and lifting the fixed-bond limitation of plain single-site TDVP. A truncating `trscheme` is then required to cut the enlarged bond back down (selecting the truncated-SVD gauge). The expansion is From d6b87f467bdc34a84cf2b989a6c3664d5991d159 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Fri, 3 Jul 2026 08:59:47 -0400 Subject: [PATCH 16/76] docs(docstrings): standardize docstrings package-wide Apply the new docstring style guide (docs/DOCSTRING_STYLE.md) across all of src/. Single-hash section headers, canonical section order and names (`Keyword Arguments`, not `Keywords`), dash bullets with types only where they earn their place, spaces around `=` in defaults and after commas in type-parameter lists. Templates applied: - A1 (`@kwdef` algorithm/config structs): $(TYPEDEF) + # Fields via $(TYPEDFIELDS) + # See also naming the consuming driver(s) + # References. - A2 (container/data types): $(TYPEDEF) + # Constructors + flat # Arguments/# Keyword Arguments + # Properties + # Notes. - B (user-facing verbs): stacked signatures with -> returns, # Arguments, # Keyword Arguments, # Returns. Also documents three previously-undocumented exports (find_groundstate!, leftenv, rightenv) and adds flags for pre-existing doc inaccuracies surfaced during the sweep (non-existent Defaults.solver / Defaults.trscheme references, MPOHamiltonian constructor signatures with no matching methods) for maintainer follow-up. Verified: MPSKit precompiles and the full doctest suite passes. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/DOCSTRING_STYLE.md | 215 ++++++++++++++++++ src/algorithms/approximate/approximate.jl | 6 +- src/algorithms/changebonds/optimalexpand.jl | 6 +- src/algorithms/changebonds/randexpand.jl | 6 +- src/algorithms/changebonds/sketchedexpand.jl | 6 +- src/algorithms/changebonds/svdcut.jl | 10 +- src/algorithms/changebonds/vumpssvd.jl | 6 +- src/algorithms/derivatives/mpo_derivatives.jl | 2 +- src/algorithms/excitation/chepigaansatz.jl | 42 ++-- src/algorithms/excitation/dmrgexcitation.jl | 6 +- src/algorithms/excitation/excitations.jl | 14 +- .../excitation/quasiparticleexcitation.jl | 36 +-- src/algorithms/expval.jl | 18 +- src/algorithms/groundstate/dmrg.jl | 30 ++- .../groundstate/find_groundstate.jl | 6 +- .../groundstate/gradient_grassmann.jl | 32 +-- src/algorithms/groundstate/idmrg.jl | 12 +- src/algorithms/groundstate/vumps.jl | 8 +- src/algorithms/propagator/corvector.jl | 25 +- src/algorithms/statmech/leading_boundary.jl | 6 +- src/algorithms/statmech/vomps.jl | 10 +- src/algorithms/timestep/integrators.jl | 4 +- src/algorithms/timestep/taylorcluster.jl | 10 +- src/algorithms/timestep/tdvp.jl | 16 +- src/algorithms/timestep/time_evolve.jl | 36 +-- src/algorithms/timestep/wii.jl | 8 +- src/algorithms/unionalg.jl | 9 +- src/environments/finite_envs.jl | 26 +++ src/operators/jordanmpotensor.jl | 31 ++- src/operators/lazysum.jl | 18 +- src/operators/mpohamiltonian.jl | 42 ++-- src/operators/multilinempo.jl | 5 +- src/operators/windowhamiltonian.jl | 10 +- src/states/finitemps.jl | 86 ++++--- src/states/infinitemps.jl | 59 +++-- src/states/multilinemps.jl | 16 +- src/states/ortho.jl | 8 +- src/states/quasiparticle_state.jl | 24 +- src/states/windowmps.jl | 35 ++- src/utility/dynamictols.jl | 6 +- src/utility/multiline.jl | 8 +- src/utility/periodicarray.jl | 12 +- src/utility/plotting.jl | 24 +- 43 files changed, 688 insertions(+), 307 deletions(-) create mode 100644 docs/DOCSTRING_STYLE.md diff --git a/docs/DOCSTRING_STYLE.md b/docs/DOCSTRING_STYLE.md new file mode 100644 index 000000000..eaaf315ed --- /dev/null +++ b/docs/DOCSTRING_STYLE.md @@ -0,0 +1,215 @@ +# Docstring style guide + +This document defines the conventions for docstrings across MPSKit.jl. +The goal is a single, uniform presentation for all public-facing functionality, so that the API reference reads as one coherent whole. + +These rules apply to **every** docstring in `src/`, exported or not. +Not every symbol needs every section — pick the template that fits (see [Templates](#templates)) — but when a docstring documents arguments, returns, fields, examples, or references, it does so in the one format described here. + +## Quick rules + +- **Section headers use a single hash** (`# Arguments`, `# Returns`), matching Julia Base. +- **Bullet entries** are `` - `name`: description `` — a dash, the name in backticks, a colon, one space, then the description. Add the type (`` `name::Type` ``) only when it is helpful. +- **Cross-references** use `[`name`](@ref)` for internal symbols and `[`name`](@extref Pkg.name)` for symbols in other packages. +- **Type parameter lists** put a space after each comma: `Array{T, N}`, `Union{A, B, C}` — never `Array{T,N}`. +- **Default values** put spaces around the `=`: `tol = 1e-10`, not `tol=1e-10`. +- **Literature references** use `@cite` keys, never inline DOIs or URLs. +- **Examples** that show output are runnable `jldoctest` blocks. +- **Caveats** use `!!! note`; **unstable or experimental** features use `!!! warning`. + +## Section headers + +Use a single hash (`#`) for all section headers inside a docstring. +The canonical section names, in the order they should appear, are: + +1. `# Constructors` — constructor signatures (container types with non-trivial constructors). +2. `# Arguments` — positional arguments. +3. `# Keyword Arguments` — keyword arguments. +4. `# Returns` — the return value(s). +5. `# Fields` — the struct fields, when the raw fields are the public API (algorithm structs; rendered by `$(TYPEDFIELDS)`). +6. `# Properties` — the `getproperty` interface, when it differs from the raw storage (e.g. the gauge views of an MPS container). Use `# Fields` **or** `# Properties`, whichever describes the public surface — not both. +7. `# Notes` — conventions and caveats worth a dedicated block. +8. `# Examples` — runnable examples. +9. `# See also` — related functions; for an algorithm struct, the driver(s) that consume it. +10. `# References` — literature citations. + +Omit any section that does not apply. +Do not use `## Arguments` (double hash), `# Keywords`, or other spellings. +For docstrings long enough to warrant it, split off detail into a `# Extended help` section (a Julia Base convention) so the summary line and first paragraph stay terse. + +## Bullet format + +Document arguments, keyword arguments, returns, and manually-listed properties as bullet lists in this form: + +``` +- `name`: description +- `name::Type`: description +``` + +A dash (not `*`), the name in backticks, a colon **with no leading space**, one trailing space, then the description. + +Include the type in the backtick span **only when it earns its place** — when it constrains what the caller may pass or disambiguates an overloaded name (e.g. `` `O::Union{AbstractMPO, Pair, AbstractTensorMap}` ``). +Omit it when the type is obvious from the name, the surrounding prose, or the default value (e.g. `` `verbosity`: how much information is displayed ``). +Never repeat a type that `$(TYPEDFIELDS)` already renders from the struct definition. + +Give keyword arguments their default in the backtick span when it is informative, with spaces around the `=`: `` - `tol = 1e-10`: convergence tolerance ``. +Always put spaces around `=` when writing a default value in a docstring (both in bullet entries and in signature blocks), even where the underlying code omits them. +Continuation lines of a long description are indented to align under the description text. + +## Cross-references and citations + +- Internal symbols: `` [`find_groundstate`](@ref) ``. +- External symbols: `` [`Householder`](@extref MatrixAlgebraKit.Householder) ``. + Note the parentheses — `@extref` only expands the `[text](@extref target)` form, not `[text][target]`. +- Literature: `[Zauner-Stauber et al. Phys. Rev. B 97 (2018)](@cite zauner-stauber2018)`, with the key defined in the bibliography. + Do not paste raw DOIs or arXiv links. + +## Templates + +Three templates cover the whole package. +Choose by what the symbol is, not by how important it is. + +There are two flavours of type docstring — pick by what the type is. +Algorithm and configuration structs (`A1`) are keyword-configured bags of settings; container/data types (`A2`) hold state and are built through hand-written constructors. + +### Template A1 — algorithm and configuration structs + +For the keyword-configured `@kwdef` structs: every `Algorithm` subtype, and any similar options struct. +Each field carries a per-field string literal so that `$(TYPEDFIELDS)` renders the field documentation, including its type — the doc strings themselves do not repeat the type. + +```julia +""" +$(TYPEDEF) + +One paragraph: what the algorithm does and how. + +# Fields + +$(TYPEDFIELDS) + +# See also + +Used as the `algorithm` argument of [`find_groundstate`](@ref) and [`leading_boundary`](@ref). + +# References + +* [Author et al. Journal (Year)](@cite key) +""" +@kwdef struct VUMPS <: Algorithm + "tolerance for convergence criterium" + tol::Float64 = 1e-10 + "maximal amount of iterations" + maxiter::Int = 200 +end +``` + +`$(TYPEDEF)` generates the type signature — do not hand-write it. +The keyword constructor generated by `@kwdef` *is* the field list, so there is no `# Constructors` section; add one only if the type also offers a non-obvious convenience constructor. +`# See also` names the driver function(s) that accept the struct, so the algorithm is discoverable from its own page. +`# References` is optional and only appears when there is literature to cite. + +### Template A2 — container and data types + +For state-holding types with hand-written constructors: `FiniteMPS`, `InfiniteMPS`, `WindowMPS`, the MPO types, and similar. +Here the raw fields are internal; document the public `getproperty` interface under `# Properties`, and the constructors explicitly. + +```julia +""" +$(TYPEDEF) + +Type that represents a finite Matrix Product State. + +# Constructors + FiniteMPS([f, eltype], physicalspaces, maxvirtualspaces; kwargs...) + FiniteMPS([f, eltype], N, physicalspace, maxvirtualspaces; kwargs...) + FiniteMPS(As::Vector{<:GenericMPSTensor}; kwargs...) + +Construct an MPS from physical and virtual spaces, or from a list of tensors `As`. + +# Arguments +- `As`: vector of site tensors +- `f = rand`: initializer for tensor data +- `physicalspaces`: list of physical spaces + +# Keyword Arguments +- `normalize = true`: normalize the constructed state +- `left`: left-most virtual space + +# Properties +- `AL`: left-gauged MPS tensors +- `AR`: right-gauged MPS tensors +- `AC`: center-gauged MPS tensors +- `C`: gauge (bond) tensors + +# Notes +By convention, `AL[i] * C[i] == AC[i] == C[i-1] * AR[i]`. +""" +``` + +Use `$(TYPEDEF)` for the top line here too, so the type signature never drifts from the definition. +The constructors are the user-facing interface and are documented separately: stack their signatures as an indented code block under `# Constructors`, then document their parameters in flat sibling `# Arguments` / `# Keyword Arguments` sections (not nested `### ` sub-headers). + +### Template B — full-contract functions + +Use for the user-facing verbs: `find_groundstate`, `leading_boundary`, `timestep`, `time_evolve`, `expectation_value`, `changebonds`, `approximate`, `correlator`, and the like. + +```julia +""" + funcname(ψ₀, H, [environments]; kwargs...) -> (ψ, environments, ϵ) + +One paragraph describing the operation. + +# Arguments +- `ψ₀::AbstractMPS`: initial guess +- `H::AbstractMPO`: the operator + +# Keyword Arguments +- `tol::Float64 = 1e-10`: convergence tolerance + +# Returns +- `ψ::AbstractMPS`: the converged state +- `ϵ::Float64`: final error estimate + +# Examples +```jldoctest +julia> # runnable example +``` + +# References +* [...](@cite key) +""" +``` + +The top line is an indented, four-space signature; stack multiple overloads as separate signature lines. +Keep the `-> (...)` return annotation on the signature even when a `# Returns` section is present: the signature is the glanceable form, the section is the contract. +Omit any section that does not apply (a function with no keywords has no `# Keyword Arguments`). + +### Template C — lightweight + +Use for simple helpers and most internal functions: a signature and a one- or two-sentence description, no sections. + +```julia +""" + correlator(ψ, O1, O2, i, j) + correlator(ψ, O12, i, j) + +Compute the 2-point correlator `⟨ψ|O1[i]O2[j]|ψ⟩`. +Also accepts a range for `j`. +""" +``` + +## Admonitions + +- `!!! note` for caveats and conventions the reader must know (e.g. gauge conventions). +- `!!! warning` for anything unstable or experimental — everything in `lib/internals`, current GPU support, and any feature that may change. + +## Attachment + +- Prefer a leading `"""..."""` block directly above the definition. +- Use `@doc (@doc a) b` only to alias a genuinely identical docstring onto a sibling. +- A comment between the docstring and the definition silently detaches the docstring; keep them adjacent and put any comment above the docstring. + +## Physics claims + +Any statement about physical behavior, convergence, or the meaning of a result that has not been verified gets a `` comment for the maintainer. +Correctness of physics is the maintainer's call. diff --git a/src/algorithms/approximate/approximate.jl b/src/algorithms/approximate/approximate.jl index f28e67e6b..a46c37d93 100644 --- a/src/algorithms/approximate/approximate.jl +++ b/src/algorithms/approximate/approximate.jl @@ -8,19 +8,19 @@ Compute an approximation to the application of an operator `O` to the state `ψ` of an MPS `ψ₀`. If only a state `ψ` is supplied instead of the `(O, ψ)` pair, `ψ₀` is approximated directly to `ψ` (i.e. `O` is taken to be the identity). -## Arguments +# Arguments - `ψ₀::AbstractMPS`: initial guess of the approximated state - `(O::AbstractMPO, ψ::AbstractMPS)`: operator `O` and state `ψ` to be approximated - `ψ::AbstractMPS`: state to be approximated directly (without an operator) - `algorithm`: approximation algorithm. See below for a list of available algorithms. - `[environments]`: MPS environment manager -## Keywords +# Keyword Arguments - `tol::Float64`: tolerance for convergence criterium - `maxiter::Int`: maximum amount of iterations - `verbosity::Int`: display progress information -## Algorithms +# Algorithms - `DMRG`: Alternating least square method for maximizing the fidelity with a single-site scheme. - `DMRG2`: Alternating least square method for maximizing the fidelity with a two-site scheme. diff --git a/src/algorithms/changebonds/optimalexpand.jl b/src/algorithms/changebonds/optimalexpand.jl index db5ac9a76..5fe4a5e77 100644 --- a/src/algorithms/changebonds/optimalexpand.jl +++ b/src/algorithms/changebonds/optimalexpand.jl @@ -12,9 +12,13 @@ for e.g. TDVP). !!! note [`changebonds!`](@ref) is only defined for `FiniteMPS`, and modifies both the state and its environment. -## Fields +# Fields $(TYPEDFIELDS) + +# See also + +Used as the `algorithm` argument of [`changebonds`](@ref) and [`changebonds!`](@ref). """ @kwdef struct OptimalExpand{S} <: Algorithm "algorithm used for the singular value decomposition" diff --git a/src/algorithms/changebonds/randexpand.jl b/src/algorithms/changebonds/randexpand.jl index 7445a0e21..7d93cfe92 100644 --- a/src/algorithms/changebonds/randexpand.jl +++ b/src/algorithms/changebonds/randexpand.jl @@ -13,9 +13,13 @@ distributed weights for each state in the two-site space and truncating that. The environments are not used here, but [`changebonds!`](@ref) modifies both the state and environment so they remain consistent. -## Fields +# Fields $(TYPEDFIELDS) + +# See also + +Used as the `algorithm` argument of [`changebonds`](@ref) and [`changebonds!`](@ref). """ @kwdef struct RandExpand{S} <: Algorithm "algorithm used for the singular value decomposition" diff --git a/src/algorithms/changebonds/sketchedexpand.jl b/src/algorithms/changebonds/sketchedexpand.jl index 9e89b3b81..e839ea2fb 100644 --- a/src/algorithms/changebonds/sketchedexpand.jl +++ b/src/algorithms/changebonds/sketchedexpand.jl @@ -15,9 +15,13 @@ The state-preserving behaviour matches [`OptimalExpand`](@ref). as the `alg_expand` strategy of [`DMRG`](@ref). The reported `ϵ_2site` is a randomized estimate, and the folded application does not exploit `JordanMPO` sparsity. -## Fields +# Fields $(TYPEDFIELDS) + +# See also + +Used as the `algorithm` argument of [`changebonds`](@ref) and [`changebonds!`](@ref). """ @kwdef struct SketchedExpand{S} <: Algorithm "algorithm used to orthonormalize the sketched complement (passed as the `alg` of `left_orth!`/`right_orth!`); `nothing` selects QR without oversampling and an SVD-based decomposition otherwise" diff --git a/src/algorithms/changebonds/svdcut.jl b/src/algorithms/changebonds/svdcut.jl index fbbcb757c..a4a3312c9 100644 --- a/src/algorithms/changebonds/svdcut.jl +++ b/src/algorithms/changebonds/svdcut.jl @@ -6,13 +6,15 @@ This is achieved by a sweeping algorithm that locally performs (optimal) truncat changedbonds! is only defined for FiniteMPS and FiniteMPO. -See also [`changebonds(!)`](@ref changebonds) - -## Fields +# Fields $(TYPEDFIELDS) -## References +# See also + +Used as the `algorithm` argument of [`changebonds`](@ref) and [`changebonds!`](@ref). + +# References * [Parker et al. Phys. Rev. B 102 (2020)](@cite parker2020) """ diff --git a/src/algorithms/changebonds/vumpssvd.jl b/src/algorithms/changebonds/vumpssvd.jl index 75655f65a..d2aa4d570 100644 --- a/src/algorithms/changebonds/vumpssvd.jl +++ b/src/algorithms/changebonds/vumpssvd.jl @@ -6,9 +6,13 @@ An algorithm that uses a two-site update step to change the bond dimension of a !!! note [`changebonds!`](@ref) is not defined. -## Fields +# Fields $(TYPEDFIELDS) + +# See also + +Used as the `algorithm` argument of [`changebonds`](@ref). """ @kwdef struct VUMPSSvdCut <: Algorithm "algorithm used for gauging the `InfiniteMPS`" diff --git a/src/algorithms/derivatives/mpo_derivatives.jl b/src/algorithms/derivatives/mpo_derivatives.jl index db78fe768..5bc4bc943 100644 --- a/src/algorithms/derivatives/mpo_derivatives.jl +++ b/src/algorithms/derivatives/mpo_derivatives.jl @@ -1,5 +1,5 @@ """ - struct MPODerivativeOperator{L,O<:Tuple,R} + struct MPODerivativeOperator{L, O <: Tuple, R} Effective local operator obtained from taking the partial derivative of an MPS-MPO-MPS sandwich. """ diff --git a/src/algorithms/excitation/chepigaansatz.jl b/src/algorithms/excitation/chepigaansatz.jl index 68e6efc22..6be4f158e 100644 --- a/src/algorithms/excitation/chepigaansatz.jl +++ b/src/algorithms/excitation/chepigaansatz.jl @@ -3,11 +3,7 @@ $(TYPEDEF) Single-site optimization algorithm for excitations on top of MPS groundstates. -## Fields - -$(TYPEDFIELDS) - -## Constructors +# Constructors ChepigaAnsatz() ChepigaAnsatz(; kwargs...) @@ -16,9 +12,17 @@ $(TYPEDFIELDS) Create a `ChepigaAnsatz` algorithm with the given eigensolver, or by passing the keyword arguments to [`Arnoldi`](@extref KrylovKit.Arnoldi). -## References +# Fields + +$(TYPEDFIELDS) + +# See also + +Used as the `algorithm` argument of [`excitations`](@ref). + +# References -- [Chepiga et al. Phys. Rev. B 96 (2017)](@cite chepiga2017) +* [Chepiga et al. Phys. Rev. B 96 (2017)](@cite chepiga2017) """ struct ChepigaAnsatz{A <: KrylovAlgorithm} <: Algorithm "algorithm used for the eigenvalue solvers" @@ -64,26 +68,32 @@ function excitations( end """ - ChepigaAnsatz2 <: Algorithm +$(TYPEDEF) Two-site optimization algorithm for excitations on top of MPS groundstates. -## Fields -- `alg::A = Defaults.eigsolver`: algorithm to use for the eigenvalue problem. -- `trscheme = Defaults.trscheme`: algorithm to use for truncation. - -## Constructors +# Constructors ChepigaAnsatz2() ChepigaAnsatz2(; kwargs...) ChepigaAnsatz2(alg, trscheme) Create a `ChepigaAnsatz2` algorithm with the given eigensolver and truncation, or by passing the -keyword arguments to `Arnoldi`. +keyword arguments to [`Arnoldi`](@extref KrylovKit.Arnoldi). + +# Fields +- `alg`: algorithm used for the eigenvalue problem +- `trscheme`: truncation scheme used when splitting the optimized two-site tensor + + + +# See also + +Used as the `algorithm` argument of [`excitations`](@ref). -## References +# References -- [Chepiga et al. Phys. Rev. B 96 (2017)](@cite chepiga2017) +* [Chepiga et al. Phys. Rev. B 96 (2017)](@cite chepiga2017) """ struct ChepigaAnsatz2{A <: KrylovAlgorithm} <: Algorithm alg::A diff --git a/src/algorithms/excitation/dmrgexcitation.jl b/src/algorithms/excitation/dmrgexcitation.jl index 8bdb934c6..fed0d5812 100644 --- a/src/algorithms/excitation/dmrgexcitation.jl +++ b/src/algorithms/excitation/dmrgexcitation.jl @@ -7,9 +7,13 @@ Variational optimization algorithm for excitations of finite MPS by minimizing t H + λᵢ |ψᵢ⟩⟨ψᵢ| ``` -## Fields +# Fields $(TYPEDFIELDS) + +# See also + +Used as the `algorithm` argument of [`excitations`](@ref). """ @kwdef struct FiniteExcited{A} <: Algorithm "optimization algorithm" diff --git a/src/algorithms/excitation/excitations.jl b/src/algorithms/excitation/excitations.jl index eb1247f90..e528d43da 100644 --- a/src/algorithms/excitation/excitations.jl +++ b/src/algorithms/excitation/excitations.jl @@ -1,17 +1,19 @@ """ excitations(H, algorithm::QuasiparticleAnsatz, ψ::FiniteQP, [left_environments], - [right_environments]; num=1) -> (energies, states) + [right_environments]; num = 1) -> (energies, states) excitations(H, algorithm::QuasiparticleAnsatz, ψ::InfiniteQP, [left_environments], - [right_environments]; num=1, solver=Defaults.solver) -> (energies, states) + [right_environments]; num = 1, solver = Defaults.solver) -> (energies, states) excitations(H, algorithm::FiniteExcited, ψs::NTuple{<:Any, <:FiniteMPS}; - num=1, init=copy(first(ψs))) -> (energies, states) + num = 1, init = copy(first(ψs))) -> (energies, states) excitations(H, algorithm::ChepigaAnsatz, ψ::FiniteMPS, [envs]; - num=1, pos=length(ψ)÷2) -> (energies, states) + num = 1, pos = length(ψ) ÷ 2) -> (energies, states) excitations(H, algorithm::ChepigaAnsatz2, ψ::FiniteMPS, [envs]; - num=1, pos=length(ψ)÷2) -> (energies, states) + num = 1, pos = length(ψ) ÷ 2) -> (energies, states) Compute the first excited states and their energy gap above a ground state. + + # Arguments - `H::AbstractMPO`: operator for which to find the excitations - `algorithm`: optimization algorithm @@ -20,7 +22,7 @@ Compute the first excited states and their energy gap above a ground state. - `[left_environments]`: left ground state environment - `[right_environments]`: right ground state environment -# Keywords +# Keyword Arguments - `num::Int`: number of excited states to compute - `solver`: algorithm for the linear solver of the quasiparticle environments - `init`: initial excited state guess diff --git a/src/algorithms/excitation/quasiparticleexcitation.jl b/src/algorithms/excitation/quasiparticleexcitation.jl index dab59fecd..bc83f30c4 100644 --- a/src/algorithms/excitation/quasiparticleexcitation.jl +++ b/src/algorithms/excitation/quasiparticleexcitation.jl @@ -7,22 +7,26 @@ $(TYPEDEF) Optimization algorithm for quasi-particle excitations on top of MPS groundstates. -## Fields +# Constructors -$(TYPEDFIELDS) - -## Constructors - QuasiparticleAnsatz() QuasiparticleAnsatz(; kwargs...) QuasiparticleAnsatz(alg) -Create a `QuasiparticleAnsatz` algorithm with the given algorithm, or by passing the -keyword arguments to `Arnoldi`. +Create a `QuasiparticleAnsatz` algorithm with the given eigensolver, or by passing the +keyword arguments to [`Arnoldi`](@extref KrylovKit.Arnoldi). + +# Fields + +$(TYPEDFIELDS) + +# See also + +Used as the `algorithm` argument of [`excitations`](@ref). -## References +# References -- [Haegeman et al. Phys. Rev. Let. 111 (2013)](@cite haegeman2013) +* [Haegeman et al. Phys. Rev. Let. 111 (2013)](@cite haegeman2013) """ struct QuasiparticleAnsatz{A, E} <: Algorithm "algorithm used for the eigenvalue solvers" @@ -69,7 +73,7 @@ end excitations(H, algorithm::QuasiparticleAnsatz, momentum::Union{Number, Vector{<:Number}}, left_ψ::InfiniteMPS, [left_environment], [right_ψ::InfiniteMPS], [right_environment]; - kwargs...) + kwargs...) -> (energies, states) Create and optimize infinite quasiparticle states. @@ -82,11 +86,11 @@ Create and optimize infinite quasiparticle states. - `[right_ψ::InfiniteMPS]`: right ground state - `[right_environment]`: right ground state environment -# Keywords +# Keyword Arguments - `num::Int`: number of excited states to compute - `solver`: algorithm for the linear solver of the quasiparticle environments -- `sector=leftunit(left_ψ)`: charge of the quasiparticle state -- `parallel=true`: enable multi-threading over different momenta +- `sector = leftunit(left_ψ)`: charge of the quasiparticle state +- `parallel = true`: enable multi-threading over different momenta """ function excitations( H, alg::QuasiparticleAnsatz, momentum::Number, lmps::InfiniteMPS, @@ -160,7 +164,7 @@ end """ excitations(H, algorithm::QuasiparticleAnsatz, left_ψ::FiniteMPS, [left_environment], - [right_ψ::FiniteMPS], [right_environment]; kwargs...) + [right_ψ::FiniteMPS], [right_environment]; kwargs...) -> (energies, states) Create and optimize finite quasiparticle states. @@ -172,9 +176,9 @@ Create and optimize finite quasiparticle states. - `[right_ψ::FiniteMPS]`: right ground state - `[right_environment]`: right ground state environment -# Keywords +# Keyword Arguments - `num::Int`: number of excited states to compute -- `sector=leftunit(lmps)`: charge of the quasiparticle state +- `sector = leftunit(lmps)`: charge of the quasiparticle state """ function excitations( H, alg::QuasiparticleAnsatz, lmps::FiniteMPS, diff --git a/src/algorithms/expval.jl b/src/algorithms/expval.jl index d60213af2..0daf7dc03 100644 --- a/src/algorithms/expval.jl +++ b/src/algorithms/expval.jl @@ -1,9 +1,9 @@ """ - expectation_value(ψ, O, [environments]) - expectation_value(ψ, inds => O) - expectation_value(ψ, (mpo, site => O), [environments]) + expectation_value(ψ, O, [environments]) -> val + expectation_value(ψ, inds => O) -> val + expectation_value(ψ, (mpo, site => O), [environments]) -> val -Compute the expectation value of an operator `O` on a state `ψ`. +Compute the expectation value of an operator `O` on a state `ψ`, normalized by `⟨ψ|ψ⟩`. Optionally, it is possible to make the computations more efficient by also passing in previously calculated `environments`. @@ -15,12 +15,16 @@ acts, while the operator is either a `AbstractTensorMap` or a `FiniteMPO`. In th the operator is a `AbstractTensorMap` that acts on the physical space of a single site. # Arguments -* `ψ::AbstractMPS` : the state on which to compute the expectation value -* `O::Union{AbstractMPO,Pair,AbstractTensorMap}` : the operator to compute the expectation value of. +- `ψ::AbstractMPS`: the state on which to compute the expectation value +- `O::Union{AbstractMPO, Pair, AbstractTensorMap}`: the operator to compute the expectation value of. This can either be an `AbstractMPO`, a pair of indices and local operator, or a local MPO tensor represented as a `AbstractTensorMap`. -* `environments::AbstractMPSEnvironments` : the environments to use for the calculation. If not given, they will be calculated. +- `environments::AbstractMPSEnvironments`: the environments to use for the calculation. If not given, they will be calculated. Depending on the type of `O`, these will be the environments of the operator `O` or the MPO `mpo`. + +# Returns +- `val::Number`: the (normalized) expectation value `⟨ψ|O|ψ⟩ / ⟨ψ|ψ⟩`. + # Examples ```jldoctest julia> ψ = FiniteMPS(ones(Float64, (ℂ^2)^4)); diff --git a/src/algorithms/groundstate/dmrg.jl b/src/algorithms/groundstate/dmrg.jl index 61f3097a0..9d8a85c22 100644 --- a/src/algorithms/groundstate/dmrg.jl +++ b/src/algorithms/groundstate/dmrg.jl @@ -21,9 +21,13 @@ is `notrunc()` the gauge is a QR decomposition (`alg_orth`, [`Householder`](@ext MatrixAlgebraKit.Householder) by default), otherwise it is a truncated SVD (`alg_svd` with the given `trscheme`). -## Fields +# Fields $(TYPEDFIELDS) + +# See also + +Used as the `algorithm` argument of [`find_groundstate`](@ref) and [`approximate`](@ref). """ struct DMRG{A, F, E, G} <: Algorithm "tolerance for convergence criterium" @@ -64,6 +68,24 @@ function DMRG(; return DMRG(tol, maxiter, verbosity, alg_eigsolve′, finalize, alg_expand, alg_gauge) end +""" + find_groundstate!(ψ, H, algorithm, [environments]) -> (ψ, environments, ϵ) + +In-place version of [`find_groundstate`](@ref): optimize the finite MPS `ψ` for the +Hamiltonian `H`, overwriting the input state instead of working on a copy. +Currently supported for the finite-system algorithms [`DMRG`](@ref) and [`DMRG2`](@ref). + +# Arguments +- `ψ::AbstractFiniteMPS`: initial guess, mutated in place +- `H`: operator for which to find the ground state +- `algorithm`: optimization algorithm +- `[environments]`: MPS environment manager + +# Returns +- `ψ::AbstractFiniteMPS`: converged ground state +- `environments`: environments corresponding to the converged state +- `ϵ::Float64`: final convergence error upon terminating the algorithm +""" function find_groundstate!(ψ::AbstractFiniteMPS, H, alg::DMRG, envs = environments(ψ, H, ψ)) ϵs = map(pos -> calc_galerkin(pos, ψ, H, ψ, envs), 1:length(ψ)) ϵ = maximum(ϵs) @@ -146,9 +168,13 @@ $(TYPEDEF) Two-site DMRG algorithm for finding the dominant eigenvector. -## Fields +# Fields $(TYPEDFIELDS) + +# See also + +Used as the `algorithm` argument of [`find_groundstate`](@ref) and [`approximate`](@ref). """ struct DMRG2{A, S, F} <: Algorithm "tolerance for convergence criterium" diff --git a/src/algorithms/groundstate/find_groundstate.jl b/src/algorithms/groundstate/find_groundstate.jl index 28ebc182d..cfd44352e 100644 --- a/src/algorithms/groundstate/find_groundstate.jl +++ b/src/algorithms/groundstate/find_groundstate.jl @@ -5,18 +5,18 @@ Compute the ground state for Hamiltonian `H` with initial guess `ψ`. If not specified, an optimization algorithm will be attempted based on the supplied keywords. -## Arguments +# Arguments - `ψ₀::AbstractMPS`: initial guess - `H::AbstractMPO`: operator for which to find the ground state - `[environments]`: MPS environment manager - `algorithm`: optimization algorithm -## Keywords +# Keyword Arguments - `tol::Float64`: tolerance for convergence criterium - `maxiter::Int`: maximum amount of iterations - `verbosity::Int`: display progress information -## Returns +# Returns - `ψ::AbstractMPS`: converged ground state - `environments`: environments corresponding to the converged state - `ϵ::Float64`: final convergence error upon terminating the algorithm diff --git a/src/algorithms/groundstate/gradient_grassmann.jl b/src/algorithms/groundstate/gradient_grassmann.jl index 049cfaae5..b62113159 100644 --- a/src/algorithms/groundstate/gradient_grassmann.jl +++ b/src/algorithms/groundstate/gradient_grassmann.jl @@ -2,29 +2,31 @@ $(TYPEDEF) Variational gradient-based optimization algorithm that keeps the MPS in left-canonical form, -as points on a Grassmann manifold. The optimization is then a Riemannian gradient descent +as points on a Grassmann manifold. The optimization is then a Riemannian gradient descent with a preconditioner to induce the metric from the Hilbert space inner product. -## Fields +# Constructors + GradientGrassmann(; kwargs...) -$(TYPEDFIELDS) +# Keyword Arguments +- `method = ConjugateGradient`: instance of optimization algorithm, or type of optimization + algorithm to construct +- `finalize!`: finalizer algorithm +- `tol = Defaults.tol`: tolerance for convergence criterium +- `maxiter = Defaults.maxiter`: maximum amount of iterations +- `verbosity = Defaults.verbosity - 1`: level of information display -## References +# Fields -* [Hauru et al. SciPost Phys. 10 (2021)](@cite hauru2021) +$(TYPEDFIELDS) ---- +# See also -## Constructors - GradientGrassmann(; kwargs...) +Used as the `algorithm` argument of [`find_groundstate`](@ref) and [`leading_boundary`](@ref). -### Keywords -- `method=ConjugateGradient`: instance of optimization algorithm, or type of optimization - algorithm to construct -- `finalize!`: finalizer algorithm -- `tol::Float64`: tolerance for convergence criterium -- `maxiter::Int`: maximum amount of iterations -- `verbosity::Int`: level of information display +# References + +* [Hauru et al. SciPost Phys. 10 (2021)](@cite hauru2021) """ struct GradientGrassmann{O <: OptimKit.OptimizationAlgorithm, F} <: Algorithm "optimization algorithm" diff --git a/src/algorithms/groundstate/idmrg.jl b/src/algorithms/groundstate/idmrg.jl index ed83e664a..f7775ad26 100644 --- a/src/algorithms/groundstate/idmrg.jl +++ b/src/algorithms/groundstate/idmrg.jl @@ -3,9 +3,13 @@ $(TYPEDEF) Single site infinite DMRG algorithm for finding the dominant eigenvector. -## Fields +# Fields $(TYPEDFIELDS) + +# See also + +Used as the `algorithm` argument of [`find_groundstate`](@ref), [`leading_boundary`](@ref), and [`approximate`](@ref). """ @kwdef struct IDMRG{A} <: Algorithm "tolerance for convergence criterium" @@ -29,9 +33,13 @@ $(TYPEDEF) Two-site infinite DMRG algorithm for finding the dominant eigenvector. -## Fields +# Fields $(TYPEDFIELDS) + +# See also + +Used as the `algorithm` argument of [`find_groundstate`](@ref), [`leading_boundary`](@ref), and [`approximate`](@ref). """ @kwdef struct IDMRG2{A, S} <: Algorithm "tolerance for convergence criterium" diff --git a/src/algorithms/groundstate/vumps.jl b/src/algorithms/groundstate/vumps.jl index aa1c413cb..0183e94e0 100644 --- a/src/algorithms/groundstate/vumps.jl +++ b/src/algorithms/groundstate/vumps.jl @@ -3,11 +3,15 @@ $(TYPEDEF) Variational optimization algorithm for uniform matrix product states, based on the combination of DMRG with matrix product state tangent space concepts. -## Fields +# Fields $(TYPEDFIELDS) -## References +# See also + +Used as the `algorithm` argument of [`find_groundstate`](@ref) and [`leading_boundary`](@ref). + +# References * [Zauner-Stauber et al. Phys. Rev. B 97 (2018)](@cite zauner-stauber2018) * [Vanderstraeten et al. SciPost Phys. Lect. Notes 7 (2019)](@cite vanderstraeten2019) diff --git a/src/algorithms/propagator/corvector.jl b/src/algorithms/propagator/corvector.jl index 93bfd6637..c8d9c966b 100644 --- a/src/algorithms/propagator/corvector.jl +++ b/src/algorithms/propagator/corvector.jl @@ -11,11 +11,15 @@ $(TYPEDEF) A dynamical DMRG method for calculating dynamical properties and excited states, based on a variational principle for dynamical correlation functions. -## Fields +# Fields $(TYPEDFIELDS) -## References +# See also + +Used as the `algorithm` argument of [`propagator`](@ref). + +# References * [Jeckelmann. Phys. Rev. B 66 (2002)](@cite jeckelmann2002) """ @@ -33,13 +37,14 @@ $(TYPEDFIELDS) end """ - propagator(ψ₀::AbstractFiniteMPS, z::Number, H::MPOHamiltonian, alg::DynamicalDMRG; init=copy(ψ₀)) + propagator(ψ₀::AbstractFiniteMPS, z::Number, H::MPOHamiltonian, alg::DynamicalDMRG; init = copy(ψ₀)) -> (g, ψ) Calculate the action of the propagator ``\\frac{1}{z - H}|ψ₀⟩`` using the dynamical DMRG algorithm. -Returns a tuple `(g, ψ)` where `g` is the approximation of the propagator matrix element -``⟨ψ₀|\\frac{1}{z - H}|ψ₀⟩`` and `ψ` is the MPS approximation of ``\\frac{1}{z - H}|ψ₀⟩``. +# Returns +- `g`: approximation of the propagator matrix element ``⟨ψ₀|\\frac{1}{z - H}|ψ₀⟩`` +- `ψ`: MPS approximation of ``\\frac{1}{z - H}|ψ₀⟩`` """ function propagator end @@ -55,7 +60,9 @@ This algorithm minimizes the following cost function Returns the approximation of ``⟨ψ₀|\\frac{1}{z - H}|ψ₀⟩`` and ``\\frac{1}{z - H}|ψ₀⟩``. -See also [`Jeckelmann`](@ref) for the original approach. +# See also + +[`Jeckelmann`](@ref) for the original approach. """ struct NaiveInvert <: DDMRG_Flavour end @@ -121,9 +128,11 @@ Together with equation (11) from that same paper we can determine the full propa Returns the approximation of ``⟨ψ₀|\\frac{1}{z - H}|ψ₀⟩`` and ``\\frac{1}{z - H}|ψ₀⟩``. -See also [`NaiveInvert`](@ref) for a less costly but less accurate alternative. +# See also + +[`NaiveInvert`](@ref) for a less costly but less accurate alternative. -## References +# References * [Jeckelmann. Phys. Rev. B 66 (2002)](@cite jeckelmann2002) """ diff --git a/src/algorithms/statmech/leading_boundary.jl b/src/algorithms/statmech/leading_boundary.jl index d66088eea..b0ed228d6 100644 --- a/src/algorithms/statmech/leading_boundary.jl +++ b/src/algorithms/statmech/leading_boundary.jl @@ -5,18 +5,18 @@ Compute the leading boundary MPS for operator `O` with initial guess `ψ`. If not specified, an optimization algorithm will be attempted based on the supplied keywords. -## Arguments +# Arguments - `ψ₀::AbstractMPS`: initial guess - `O::AbstractMPO`: operator for which to find the leading_boundary - `[environments]`: MPS environment manager - `algorithm`: optimization algorithm -## Keywords +# Keyword Arguments - `tol::Float64`: tolerance for convergence criterium - `maxiter::Int`: maximum amount of iterations - `verbosity::Int`: display progress information -## Returns +# Returns - `ψ::AbstractMPS`: converged leading boundary MPS - `environments`: environments corresponding to the converged boundary - `ϵ::Float64`: final convergence error upon terminating the algorithm diff --git a/src/algorithms/statmech/vomps.jl b/src/algorithms/statmech/vomps.jl index 9295f2b28..33c94d6c1 100644 --- a/src/algorithms/statmech/vomps.jl +++ b/src/algorithms/statmech/vomps.jl @@ -1,15 +1,19 @@ """ $(TYPEDEF) - + Power method algorithm for finding dominant eigenvectors of infinite MPOs. This method works by iteratively approximating the product of an operator and a state with a new state of the same bond dimension. -## Fields +# Fields $(TYPEDFIELDS) -## References +# See also + +Used as the `algorithm` argument of [`leading_boundary`](@ref) and [`approximate`](@ref). + +# References * [Vanhecke et al. SciPost Phys. Core 4 (2021)](@cite vanhecke2021) """ diff --git a/src/algorithms/timestep/integrators.jl b/src/algorithms/timestep/integrators.jl index 7b2983c34..8cee4bd96 100644 --- a/src/algorithms/timestep/integrators.jl +++ b/src/algorithms/timestep/integrators.jl @@ -1,7 +1,7 @@ """ - integrate(f, y₀, t, dt, alg) + integrate(f, y₀, t, dt, alg) -> y -Integrate the differential equation ``i dy/dt = f(y, t)`` over a time step 'dt' starting from +Integrate the differential equation ``i dy/dt = f(y, t)`` over a time step `dt` starting from ``y(t₀)=y₀``, using the provided algorithm. # Arguments diff --git a/src/algorithms/timestep/taylorcluster.jl b/src/algorithms/timestep/taylorcluster.jl index 9e5943288..b129e9d0c 100644 --- a/src/algorithms/timestep/taylorcluster.jl +++ b/src/algorithms/timestep/taylorcluster.jl @@ -3,11 +3,15 @@ $(TYPEDEF) Algorithm for constructing the `N`th order time evolution MPO using the Taylor cluster expansion. -## Fields +# Fields $(TYPEDFIELDS) -## References +# See also + +Used as the `algorithm` argument of [`make_time_mpo`](@ref). + +# References * [Van Damme et al. SciPost Phys. 17 (2024)](@cite vandamme2024) """ @@ -21,7 +25,7 @@ $(TYPEDFIELDS) end """ - const WI = TaylorCluster(; N=1, extension=false, compression=false) + const WI = TaylorCluster(; N = 1, extension = false, compression = false) First order Taylor expansion for a time-evolution MPO. """ diff --git a/src/algorithms/timestep/tdvp.jl b/src/algorithms/timestep/tdvp.jl index 209ca8aef..8cec04a05 100644 --- a/src/algorithms/timestep/tdvp.jl +++ b/src/algorithms/timestep/tdvp.jl @@ -16,11 +16,15 @@ state-preserving, as required for a consistent time evolution. evolution instead renormalizes at every step, like a ground-state search. CBE is only available for finite MPS. -## Fields +# Fields $(TYPEDFIELDS) -## References +# See also + +Used as the `algorithm` argument of [`timestep`](@ref), [`timestep!`](@ref) and [`time_evolve`](@ref). + +# References * [Haegeman et al. Phys. Rev. Lett. 107 (2011)](@cite haegeman2011) """ @@ -190,11 +194,15 @@ $(TYPEDEF) Two-site MPS time-evolution algorithm based on the Time-Dependent Variational Principle. -## Fields +# Fields $(TYPEDFIELDS) -## References +# See also + +Used as the `algorithm` argument of [`timestep`](@ref), [`timestep!`](@ref) and [`time_evolve`](@ref). + +# References * [Haegeman et al. Phys. Rev. Lett. 107 (2011)](@cite haegeman2011) """ diff --git a/src/algorithms/timestep/time_evolve.jl b/src/algorithms/timestep/time_evolve.jl index 51288abd7..edba67d3a 100644 --- a/src/algorithms/timestep/time_evolve.jl +++ b/src/algorithms/timestep/time_evolve.jl @@ -5,21 +5,26 @@ Time-evolve the initial state `ψ₀` with Hamiltonian `H` over a given time span by stepping through each of the time points obtained by iterating t_span. -## Arguments +# Arguments - `ψ₀::AbstractMPS`: initial state - `H::AbstractMPO`: operator that generates the time evolution (can be time-dependent). - `t_span::AbstractVector{<:Number}`: time points over which the time evolution is stepped -- `[alg]`: algorithm to use for the time evolution. Defaults to [`TDVP`](@ref). -- `[envs]`: MPS environment manager +- `alg`: algorithm to use for the time evolution. Defaults to [`TDVP`](@ref). +- `envs`: MPS environment manager -## Keyword Arguments +# Keyword Arguments -- `verbosity::Int=0`: verbosity level for logging -- `imaginary_evolution::Bool=false`: if true, the time evolution is done with an imaginary time step +- `verbosity::Int = 0`: verbosity level for logging +- `imaginary_evolution::Bool = false`: if true, the time evolution is done with an imaginary time step instead, (i.e. ``\\exp(-Hdt)`` instead of ``\\exp(-iHdt)``). This can be useful for using this function to compute the ground state of a Hamiltonian, or to compute finite-temperature properties of a system. + +# Returns + +- `ψ`: the time-evolved state +- `envs`: the updated environment manager """ function time_evolve end, function time_evolve! end @@ -54,21 +59,26 @@ end Time-step the state `ψ₀` with Hamiltonian `H` over a given time step `dt` at time `t`, solving the Schroedinger equation: ``i ∂ψ/∂t = H ψ``. -## Arguments +# Arguments - `ψ₀::AbstractMPS`: initial state - `H::AbstractMPO`: operator that generates the time evolution (can be time-dependent). - `t::Number`: starting time of time-step - `dt::Number`: time-step magnitude -- `[alg]`: algorithm to use for the time evolution. Defaults to [`TDVP`](@ref). -- `[envs]`: MPS environment manager +- `alg`: algorithm to use for the time evolution. Defaults to [`TDVP`](@ref). +- `envs`: MPS environment manager -## Keyword Arguments +# Keyword Arguments -- `imaginary_evolution::Bool=false`: if true, the time evolution is done with an imaginary time step +- `imaginary_evolution::Bool = false`: if true, the time evolution is done with an imaginary time step instead, (i.e. ``\\exp(-Hdt)`` instead of ``\\exp(-iHdt)``). This can be useful for using this function to compute the ground state of a Hamiltonian, or to compute finite-temperature properties of a system. + +# Returns + +- `ψ`: the time-stepped state +- `envs`: the updated environment manager """ function timestep end, function timestep! end @@ -77,9 +87,9 @@ function timestep end, function timestep! end Construct an `MPO` that approximates ``\\exp(-iHdt)``. -## Keyword Arguments +# Keyword Arguments -- `imaginary_evolution::Bool=false`: if true, the time evolution operator is constructed +- `imaginary_evolution::Bool = false`: if true, the time evolution operator is constructed with an imaginary time step instead, (i.e. ``\\exp(-Hdt)`` instead of ``\\exp(-iHdt)``). This can be useful for using this function to compute the ground state of a Hamiltonian, or to compute finite-temperature properties of a system. diff --git a/src/algorithms/timestep/wii.jl b/src/algorithms/timestep/wii.jl index 5c39500fd..e41405fd2 100644 --- a/src/algorithms/timestep/wii.jl +++ b/src/algorithms/timestep/wii.jl @@ -3,11 +3,15 @@ $(TYPEDEF) Generalization of the Euler approximation of the operator exponential for MPOs. -## Fields +# Fields $(TYPEDFIELDS) -## References +# See also + +Used as the `algorithm` argument of [`make_time_mpo`](@ref). + +# References * [Zaletel et al. Phys. Rev. B 91 (2015)](@cite zaletel2015) * [Paeckel et al. Ann. of Phys. 411 (2019)](@cite paeckel2019) diff --git a/src/algorithms/unionalg.jl b/src/algorithms/unionalg.jl index 3e37f67f4..bdbdd121c 100644 --- a/src/algorithms/unionalg.jl +++ b/src/algorithms/unionalg.jl @@ -1,11 +1,16 @@ """ $(TYPEDEF) -Algorithm wrapper representing the sequential application of two algorithms. +Algorithm wrapper representing the sequential application of two algorithms, as produced by +`alg1 & alg2`. -## Fields +# Fields $(TYPEDFIELDS) + +# See also + +Used as the `algorithm` argument of [`find_groundstate`](@ref) and [`changebonds`](@ref). """ struct UnionAlg{A, B} <: Algorithm "first algorithm" diff --git a/src/environments/finite_envs.jl b/src/environments/finite_envs.jl index cb11cd53f..8aeeb266f 100644 --- a/src/environments/finite_envs.jl +++ b/src/environments/finite_envs.jl @@ -97,6 +97,19 @@ function poison!(ca::FiniteEnvironments, ind) end #rightenv[ind] will be contracteable with the tensor on site [ind] +""" + rightenv(envs, site, state) + +Return the right environment stored in `envs` at `site` for the given `state`: the contraction +of everything to the right of `site` in the network the environments were built for. +The result is gauge-compatible with the tensor of `state` at `site` and can be contracted onto +it directly. + + + +See also [`leftenv`](@ref) and [`environments`](@ref). +""" function rightenv(ca::FiniteEnvironments, ind, state) a = findfirst(i -> !(state.AR[i] === ca.rdependencies[i]), length(state):-1:(ind + 1)) a = isnothing(a) ? nothing : length(state) - a + 1 @@ -114,6 +127,19 @@ function rightenv(ca::FiniteEnvironments, ind, state) return ca.GRs[ind + 1] end +""" + leftenv(envs, site, state) + +Return the left environment stored in `envs` at `site` for the given `state`: the contraction +of everything to the left of `site` in the network the environments were built for. +The result is gauge-compatible with the tensor of `state` at `site` and can be contracted onto +it directly. + + + +See also [`rightenv`](@ref) and [`environments`](@ref). +""" function leftenv(ca::FiniteEnvironments, ind, state) a = findfirst(i -> !(state.AL[i] === ca.ldependencies[i]), 1:(ind - 1)) diff --git a/src/operators/jordanmpotensor.jl b/src/operators/jordanmpotensor.jl index acea13fe3..773db97ba 100644 --- a/src/operators/jordanmpotensor.jl +++ b/src/operators/jordanmpotensor.jl @@ -1,5 +1,5 @@ """ - JordanMPOTensor{T,S,A} <: AbstractBlockTensorMap{T,S,2,2} +$(TYPEDEF) A single tensor of a matrix product operator (MPO) in upper triangular (Jordan) block form, as used to represent the local tensors of an [`MPOHamiltonian`](@ref). @@ -16,28 +16,27 @@ The virtual (row, column) structure is where `A` is the bulk of interacting operators, `C`/`B` are the operators that start/finish an interaction, `D` is the on-site term, and the diagonal `1`s are identities. -## Representation +# Type parameters +- `T <: Number`: the `scalartype` of the tensors. +- `S`: the `spacetype` of the tensors. +- `A <: DenseVector{T}`: the storage type of the underlying tensors. -Rather than storing the dense block matrix, the genuine operators and the identities are kept separately: +# Properties +The reduced-leg `A`, `B`, `C` and `D` blocks are exposed as properties (`W.A`, `W.B`, `W.C`, +`W.D`), reconstructed on demand from the stored `tensors` and `scalars`. + +# Notes +Rather than storing the dense block matrix, the genuine operators and the identities are kept +separately: - `tensors::SparseBlockTensorMap` holds the non-identity operators over the *full* virtual space (so `A`, `B`, `C` and `D` all live at their `(row, 1, 1, col)` position). -- `scalars::Dict{CartesianIndex{4},T}` holds the scalar multiples of the identity, keyed by +- `scalars::Dict{CartesianIndex{4}, T}` holds the scalar multiples of the identity, keyed by their `(row, 1, 1, col)` virtual position; the diagonal corner `1`s are stored here as well. An index is never present in both `tensors` and `scalars`. -This keeps the ubiquitous identity blocks free of dense storage and lets identities be materialized lazily only when needed. - -## Type parameters - -- `T <: Number`: the `scalartype` of the tensors. -- `S`: the `spacetype` of the tensors. -- `A <: DenseVector{T}`: the storage type of the underlying tensors. - -## Block accessors - -The reduced-leg `A`, `B`, `C` and `D` blocks are exposed as properties (`W.A`, `W.B`, `W.C`, `W.D`), -reconstructed on demand from `tensors` and `scalars`. +This keeps the ubiquitous identity blocks free of dense storage and lets identities be +materialized lazily only when needed. """ struct JordanMPOTensor{ T <: Number, S, A <: DenseVector{T}, diff --git a/src/operators/lazysum.jl b/src/operators/lazysum.jl index 49af40ba4..b2c415ccb 100644 --- a/src/operators/lazysum.jl +++ b/src/operators/lazysum.jl @@ -1,19 +1,19 @@ """ - LazySum{O} <: AbstractVector{O} +$(TYPEDEF) -Type that represents a lazy sum i.e explicit summation is only done when needed. -This type is basically an `AbstractVector` with some extra functionality to calculate things efficiently. +Type that represents a lazy sum, i.e. explicit summation is only done when needed. +This type is basically an `AbstractVector` with some extra functionality to calculate things +efficiently. -## Fields -- ops -- Vector of summable objects - ---- - -## Constructors +# Constructors LazySum(x::Vector) + LazySum(ops::AbstractVector, fs::AbstractVector) +# Fields +$(TYPEDFIELDS) """ struct LazySum{O} <: AbstractVector{O} + "vector of summable objects" ops::Vector{O} end diff --git a/src/operators/mpohamiltonian.jl b/src/operators/mpohamiltonian.jl index cc7e42b15..2a6cb5b14 100644 --- a/src/operators/mpohamiltonian.jl +++ b/src/operators/mpohamiltonian.jl @@ -1,10 +1,9 @@ """ - MPOHamiltonian(lattice::AbstractArray{<:VectorSpace}, local_operators...) - MPOHamiltonian(lattice::AbstractArray{<:VectorSpace}) - MPOHamiltonian(x::AbstractArray{<:Any,3}) +$(TYPEDEF) -MPO representation of a Hamiltonian. This is a specific form of an [`AbstractMPO`](@ref), where -all the sites are represented by an upper triangular block matrix of the following form: +MPO representation of a Hamiltonian. +This is a specific form of an [`AbstractMPO`](@ref), where all the sites are represented by an +upper triangular block matrix of the following form: ```math \\begin{pmatrix} @@ -16,8 +15,22 @@ all the sites are represented by an upper triangular block matrix of the followi where `A`, `B`, `C`, and `D` are `MPOTensor`s, or (sparse) blocks thereof. -## Examples +# Constructors + MPOHamiltonian(lattice::AbstractArray{<:VectorSpace}, local_operators...) + MPOHamiltonian(lattice::AbstractArray{<:VectorSpace}) + MPOHamiltonian(x::AbstractArray{<:Any, 3}) + + + +# Properties +- `A`: bulk block of interacting operators at each site +- `B`: operators that finish an interaction +- `C`: operators that start an interaction +- `D`: on-site terms +# Examples For example, constructing a nearest-neighbour Hamiltonian would look like this: ```julia @@ -25,8 +38,9 @@ lattice = fill(ℂ^2, 10) H = MPOHamiltonian(lattice, (i, i+1) => O for i in 1:length(lattice)-1) ``` -See also [`instantiate_operator`](@ref), which is responsible for instantiating the local -operators in a form that is compatible with this constructor. +# See also +[`instantiate_operator`](@ref) is responsible for instantiating the local operators in a form +that is compatible with this constructor. """ struct MPOHamiltonian{TO <: JordanMPOTensor, V <: AbstractVector{TO}} <: AbstractMPO{TO} W::V @@ -62,8 +76,8 @@ end FiniteMPOHamiltonian(Ws::Vector{<:AbstractMatrix}) Create a `FiniteMPOHamiltonian` from a vector of matrices, such that `Ws[i][j, k]` represents -the operator at site `i`, left level `j` and right level `k`. Here, the entries can be -either `MPOTensor`, `Missing` or `Number`. +the operator at site `i`, left level `j` and right level `k`. +Here, the entries can be either `MPOTensor`, `Missing` or `Number`. """ function FiniteMPOHamiltonian(Ws::Vector{<:AbstractMatrix}) T = promote_type(_split_mpoham_types.(Ws)...) @@ -151,11 +165,11 @@ function FiniteMPOHamiltonian{O}(W_mats::Vector{<:AbstractMatrix}) where {O <: J end """ - InfiniteMPOHamiltonian(Ws::Vector{<:Matrix}) + InfiniteMPOHamiltonian(Ws::Vector{<:AbstractMatrix}) -Create a `InfiniteMPOHamiltonian` from a vector of matrices, such that `Ws[i][j, k]` represents -the the operator at site `i`, left level `j` and right level `k`. Here, the entries can be -either `MPOTensor`, `Missing` or `Number`. +Create an `InfiniteMPOHamiltonian` from a vector of matrices, such that `Ws[i][j, k]` +represents the operator at site `i`, left level `j` and right level `k`. +Here, the entries can be either `MPOTensor`, `Missing` or `Number`. """ function InfiniteMPOHamiltonian(Ws::Vector{<:AbstractMatrix}) T = promote_type(_split_mpoham_types.(Ws)...) diff --git a/src/operators/multilinempo.jl b/src/operators/multilinempo.jl index d49413e63..27db945b2 100644 --- a/src/operators/multilinempo.jl +++ b/src/operators/multilinempo.jl @@ -6,10 +6,11 @@ Type that represents multiple lines of `MPO` objects. # Constructors - MultilineMPO(mpos::AbstractVector{<:Union{SparseMPO,DenseMPO}}) + MultilineMPO(mpos::AbstractVector{<:Union{SparseMPO, DenseMPO}}) MultilineMPO(Os::AbstractMatrix{<:MPOTensor}) -See also: [`Multiline`](@ref), [`AbstractMPO`](@ref) +# See also +[`Multiline`](@ref), [`AbstractMPO`](@ref) """ const MultilineMPO = Multiline{<:AbstractMPO} diff --git a/src/operators/windowhamiltonian.jl b/src/operators/windowhamiltonian.jl index a0833aa56..b6d0b9ffd 100644 --- a/src/operators/windowhamiltonian.jl +++ b/src/operators/windowhamiltonian.jl @@ -10,12 +10,7 @@ an infinite Hamiltonian to the right. Acts similar to just a finite Hamiltonian, but we "remember" the boundary Hamiltonians. -## Fields - -$(TYPEDFIELDS) - -## Constructors - +# Constructors WindowMPOHamiltonian(ham::InfiniteMPOHamiltonian, interval::UnitRange) Construct a `WindowMPOHamiltonian` by carving a finite `interval` out of an infinite @@ -23,6 +18,9 @@ Hamiltonian `ham`. The finite window consists of the sites in `interval`, while the left and right environments are copies of `ham` whose unit cells are circshifted so that they line up with the window boundaries. + +# Fields +$(TYPEDFIELDS) """ struct WindowMPOHamiltonian{O} <: AbstractMPO{O} "Hamiltonian acting on the infinite environment to the left of the window" diff --git a/src/states/finitemps.jl b/src/states/finitemps.jl index 6f65dbbe5..9d87e874c 100644 --- a/src/states/finitemps.jl +++ b/src/states/finitemps.jl @@ -1,61 +1,55 @@ """ - FiniteMPS{A<:GenericMPSTensor,B<:MPSBondTensor} <: AbstractFiniteMPS +$(TYPEDEF) Type that represents a finite Matrix Product State. -## Properties -- `AL` -- left-gauged MPS tensors -- `AR` -- right-gauged MPS tensors -- `AC` -- center-gauged MPS tensors -- `C` -- gauge tensors -- `center` -- location of the gauge center +# Constructors + FiniteMPS([f, eltype], physicalspaces::Vector{<:Union{S, CompositeSpace{S}}}, + maxvirtualspaces::Union{S, Vector{S}}; + normalize = true, left = unitspace(S), right = unitspace(S)) where {S <: ElementarySpace} + FiniteMPS([f, eltype], N::Int, physicalspace::Union{S, CompositeSpace{S}}, + maxvirtualspaces::Union{S, Vector{S}}; + normalize = true, left = unitspace(S), right = unitspace(S)) where {S <: ElementarySpace} + FiniteMPS(As::Vector{<:GenericMPSTensor}; normalize = false, overwrite = false) -The center property returns `center::HalfInt` that indicates the location of the MPS center: +Construct an MPS via a specification of physical and virtual spaces, or from a list of +tensors `As`. All cases reduce to the latter. In particular, a state with a non-trivial +total charge can be constructed by passing a non-trivially charged vector space as the +`left` or `right` virtual spaces. + +# Arguments +- `As`: vector of site tensors +- `f = rand`: initializer function for the tensor data +- `eltype = ComplexF64`: scalar type of the tensors +- `physicalspaces`: list of physical spaces +- `N`: number of sites +- `physicalspace`: local physical space, repeated for every site +- `maxvirtualspaces`: maximal virtual space(s), truncated to what symmetry allows + +# Keyword Arguments +- `normalize`: normalize the constructed state +- `overwrite = false`: overwrite the given input tensors +- `left = unitspace(S)`: left-most virtual space +- `right = unitspace(S)`: right-most virtual space + +# Properties +- `AL`: left-gauged MPS tensors +- `AR`: right-gauged MPS tensors +- `AC`: center-gauged MPS tensors +- `C`: gauge (bond) tensors +- `center`: location of the gauge center + +The `center` property returns a `center::HalfInt` that indicates the location of the MPS center: - `isinteger(center)` → `center` is a whole number and indicates the location of the first `AC` tensor present in the underlying `ψ.ACs` field. - `ishalfodd(center)` → `center` is a half-odd-integer, meaning that there are no `AC` tensors, and indicating between which sites the bond tensor lives. -e.g `mps.center = 7/2` means that the bond tensor is to the right of the 3rd site and can be accessed via `mps.C[3]`. +For example, `mps.center = 7/2` means that the bond tensor is to the right of the 3rd site and can be accessed via `mps.C[3]`. -## Notes +# Notes By convention, we have that: - `AL[i] * C[i]` = `AC[i]` = `C[i-1] * AR[i]` - `AL[i]' * AL[i] = 1` - `AR[i] * AR[i]' = 1` - ---- - -## Constructors - FiniteMPS([f, eltype], physicalspaces::Vector{<:Union{S,CompositeSpace{S}}}, - maxvirtualspaces::Union{S,Vector{S}}; - normalize=true, left=unitspace(S), right=unitspace(S)) where {S<:ElementarySpace} - FiniteMPS([f, eltype], N::Int, physicalspace::Union{S,CompositeSpace{S}}, - maxvirtualspaces::Union{S,Vector{S}}; - normalize=true, left=unitspace(S), right=unitspace(S)) where {S<:ElementarySpace} - FiniteMPS(As::Vector{<:GenericMPSTensor}; normalize=false, overwrite=false) - -Construct an MPS via a specification of physical and virtual spaces, or from a list of -tensors `As`. All cases reduce to the latter. In particular, a state with a non-trivial -total charge can be constructed by passing a non-trivially charged vector space as the -`left` or `right` virtual spaces. - -### Arguments -- `As::Vector{<:GenericMPSTensor}`: vector of site tensors - -- `f::Function=rand`: initializer function for tensor data -- `eltype::Type{<:Number}=ComplexF64`: scalar type of tensors - -- `physicalspaces::Vector{<:Union{S, CompositeSpace{S}}`: list of physical spaces -- `N::Int`: number of sites -- `physicalspace::Union{S,CompositeSpace{S}}`: local physical space - -- `virtualspaces::Vector{<:Union{S, CompositeSpace{S}}`: list of virtual spaces -- `maxvirtualspace::S`: maximum virtual space - -### Keywords -- `normalize=true`: normalize the constructed state -- `overwrite=false`: overwrite the given input tensors -- `left=unitspace(S)`: left-most virtual space -- `right=unitspace(S)`: right-most virtual space """ struct FiniteMPS{A <: GenericMPSTensor, B <: MPSBondTensor} <: AbstractFiniteMPS ALs::Vector{Union{Missing, A}} @@ -182,7 +176,7 @@ Return the location of the MPS center. - `isinteger(center)` → `center` is a whole number and indicates the location of the first `AC` tensor present in `ψ.ACs` - `ishalfodd(center)` → `center` is a half-odd-integer, meaning that there are no `AC` tensors, and indicating between which sites the bond tensor lives. -## Example +# Examples ```julia ψ = FiniteMPS(3, ℂ^2, ℂ^16) ψ.center # returns 7/2, bond tensor is to the right of the 3rd site diff --git a/src/states/infinitemps.jl b/src/states/infinitemps.jl index 33636e53d..4c6051c5d 100644 --- a/src/states/infinitemps.jl +++ b/src/states/infinitemps.jl @@ -1,47 +1,42 @@ """ - InfiniteMPS{A<:GenericMPSTensor,B<:MPSBondTensor} <: AbtractMPS +$(TYPEDEF) Type that represents an infinite Matrix Product State. -## Fields -- `AL` -- left-gauged MPS tensors -- `AR` -- right-gauged MPS tensors -- `AC` -- center-gauged MPS tensors -- `C` -- gauge tensors - -## Notes -By convention, we have that: -- `AL[i] * C[i]` = `AC[i]` = `C[i-1] * AR[i]` -- `AL[i]' * AL[i] = 1` -- `AR[i] * AR[i]' = 1` - ---- - -## Constructors - InfiniteMPS([f, eltype], physicalspaces::Vector{<:Union{S, CompositeSpace{S}}, - virtualspaces::Vector{<:Union{S, CompositeSpace{S}}; - kwargs...) where {S<:ElementarySpace} +# Constructors + InfiniteMPS([f, eltype], physicalspaces::Vector{<:Union{S, CompositeSpace{S}}}, + virtualspaces::Vector{<:Union{S, CompositeSpace{S}}}; + kwargs...) where {S <: ElementarySpace} InfiniteMPS(As::AbstractVector{<:GenericMPSTensor}; kwargs...) - InfiniteMPS(ALs::AbstractVector{<:GenericMPSTensor}, C₀::MPSBondTensor; - kwargs...) + InfiniteMPS(ALs::AbstractVector{<:GenericMPSTensor}, C₀::MPSBondTensor; kwargs...) Construct an MPS via a specification of physical and virtual spaces, or from a list of tensors `As`, or a list of left-gauged tensors `ALs`. -### Arguments -- `As::AbstractVector{<:GenericMPSTensor}`: vector of site tensors -- `ALs::AbstractVector{<:GenericMPSTensor}`: vector of left-gauged site tensors -- `C₀::MPSBondTensor`: initial gauge tensor - -- `f::Function=rand`: initializer function for tensor data -- `eltype::Type{<:Number}=ComplexF64`: scalar type of tensors +# Arguments +- `As`: vector of site tensors +- `ALs`: vector of left-gauged site tensors +- `C₀`: initial gauge tensor +- `f = rand`: initializer function for the tensor data +- `eltype = ComplexF64`: scalar type of the tensors +- `physicalspaces`: list of physical spaces +- `virtualspaces`: list of virtual spaces -- `physicalspaces::AbstractVector{<:Union{S, CompositeSpace{S}}`: list of physical spaces -- `virtualspaces::AbstractVector{<:Union{S, CompositeSpace{S}}`: list of virtual spaces - -### Keywords +# Keyword Arguments - `tol`: gauge fixing tolerance - `maxiter`: gauge fixing maximum iterations + +# Properties +- `AL`: left-gauged MPS tensors +- `AR`: right-gauged MPS tensors +- `AC`: center-gauged MPS tensors +- `C`: gauge (bond) tensors + +# Notes +By convention, we have that: +- `AL[i] * C[i]` = `AC[i]` = `C[i-1] * AR[i]` +- `AL[i]' * AL[i] = 1` +- `AR[i] * AR[i]' = 1` """ struct InfiniteMPS{A <: GenericMPSTensor, B <: MPSBondTensor} <: AbstractMPS AL::PeriodicVector{A} diff --git a/src/states/multilinemps.jl b/src/states/multilinemps.jl index eda3c5c35..75954a5e6 100644 --- a/src/states/multilinemps.jl +++ b/src/states/multilinemps.jl @@ -5,18 +5,24 @@ const MultilineMPS = Multiline{<:InfiniteMPS} @doc """ const MultilineMPS = Multiline{<:InfiniteMPS} -Type that represents multiple lines of `InfiniteMPS` objects. +Type that represents multiple lines of [`InfiniteMPS`](@ref) objects. # Constructors MultilineMPS(mpss::AbstractVector{<:InfiniteMPS}) - MultilineMPS([f, eltype], physicalspaces::Matrix{<:Union{S, CompositeSpace{S}}, - virtualspaces::Matrix{<:Union{S, CompositeSpace{S}}) where - {S<:ElementarySpace} + MultilineMPS([f, eltype], physicalspaces::Matrix{<:Union{S, CompositeSpace{S}}}, + virtualspaces::Matrix{<:Union{S, CompositeSpace{S}}}) where {S <: ElementarySpace} MultilineMPS(As::AbstractMatrix{<:GenericMPSTensor}; kwargs...) MultilineMPS(ALs::AbstractMatrix{<:GenericMPSTensor}, C₀::AbstractVector{<:MPSBondTensor}; kwargs...) -See also: [`Multiline`](@ref) +# Properties +- `AL`: left-gauged MPS tensors +- `AR`: right-gauged MPS tensors +- `AC`: center-gauged MPS tensors +- `C`: gauge (bond) tensors + +# See also +[`Multiline`](@ref) """ function MultilineMPS end diff --git a/src/states/ortho.jl b/src/states/ortho.jl index 0b4cbd6ca..6322b366c 100644 --- a/src/states/ortho.jl +++ b/src/states/ortho.jl @@ -8,7 +8,7 @@ $(TYPEDEF) Algorithm for bringing an `InfiniteMPS` into the left-canonical form. -## Fields +# Fields $(TYPEDFIELDS) """ @@ -33,7 +33,7 @@ $(TYPEDEF) Algorithm for bringing an `InfiniteMPS` into the right-canonical form. -## Fields +# Fields $(TYPEDFIELDS) """ @@ -58,7 +58,7 @@ $(TYPEDEF) Algorithm for bringing an `InfiniteMPS` into the mixed-canonical form. -## Fields +# Fields $(TYPEDFIELDS) """ @@ -153,7 +153,7 @@ end Bring updated `AC` and `C` tensors back into a consistent set of left or right canonical tensors. This minimizes `∥AC_i - AL_i * C_i∥` or `∥AC_i - C_{i-1} * AR_i∥`. -The `alg` is passed on to `left_orth!` and `right_orth!`, and can be used to control the kind of +The `alg` is passed on to `left_orth!` and `right_orth!`, and can be used to control the kind of factorization used. By default, this is set to a (positive) QR/LQ, even though the optimal algorithm would use a polar decompositions instead, sacrificing a bit of performance for accuracy. diff --git a/src/states/quasiparticle_state.jl b/src/states/quasiparticle_state.jl index c4de86e8f..6926d5631 100644 --- a/src/states/quasiparticle_state.jl +++ b/src/states/quasiparticle_state.jl @@ -5,8 +5,7 @@ This will allow us to plot energy density (finite qp) and measure observables. =# """ - LeftGaugedQP{S,T1,T2,E} - LeftGaugedQP(datfun, left_gs, right_gs=left_gs; sector, momentum=0.0) +$(TYPEDEF) Left-gauged quasiparticle excitation ansatz on top of a matrix product state ground state. The excitation is parametrized through the left-gauge nullspace of the ground-state tensors, @@ -17,19 +16,22 @@ For a `FiniteMPS` ground state this represents a finite (localized) quasiparticl `InfiniteMPS` ground state it represents a momentum eigenstate with the given `momentum`. When `left_gs !== right_gs` the ansatz describes a domain wall between the two ground states. +# Constructors + LeftGaugedQP(datfun, left_gs, right_gs = left_gs; sector, momentum = 0.0) + These states are normally produced by [`excitations`](@ref) with a [`QuasiparticleAnsatz`](@ref) rather than constructed directly. When constructing manually, `datfun` initializes the variational tensors (e.g. `rand`/`randn`), `sector` selects the charge sector of the excitation, and `momentum` sets the momentum for infinite ground states. -## Fields - +# Fields - `left_gs`, `right_gs`: the ground state(s) the excitation lives on; distinct values yield a domain wall. - `VLs`: left-nullspace tensors of the ground-state `AL` (satisfying `AL' * VL == 0`). - `Xs`: the variational parameters of the ansatz. - `momentum`: the excitation momentum (used for infinite ground states). -See also [`RightGaugedQP`](@ref), [`QP`](@ref). +# See also +[`RightGaugedQP`](@ref), [`QP`](@ref) """ struct LeftGaugedQP{S, T1, T2, E <: Number} # !(left_gs === right_gs) => domain wall excitation @@ -43,22 +45,24 @@ struct LeftGaugedQP{S, T1, T2, E <: Number} end """ - RightGaugedQP{S,T1,T2,E} - RightGaugedQP(datfun, left_gs, right_gs=left_gs; sector, momentum=0.0) +$(TYPEDEF) Right-gauged counterpart of [`LeftGaugedQP`](@ref): the same quasiparticle excitation ansatz, but parametrized through the right-gauge nullspace of the ground-state tensors. It is most often obtained via `convert(RightGaugedQP, ϕ)` from a `LeftGaugedQP` rather than constructed directly. -## Fields +# Constructors + RightGaugedQP(datfun, left_gs, right_gs = left_gs; sector, momentum = 0.0) +# Fields - `left_gs`, `right_gs`: the ground state(s) the excitation lives on; distinct values yield a domain wall. - `Xs`: the variational parameters of the ansatz. - `VRs`: right-nullspace tensors of the ground-state `AR`. - `momentum`: the excitation momentum (used for infinite ground states). -See also [`LeftGaugedQP`](@ref), [`QP`](@ref). +# See also +[`LeftGaugedQP`](@ref), [`QP`](@ref) """ struct RightGaugedQP{S, T1, T2, E <: Number} # !(left_gs === right_gs) => domain wall excitation @@ -253,7 +257,7 @@ end # gauge independent code """ - QP{S,T1,T2} + QP{S, T1, T2} Union of the quasiparticle excitation ansätze [`LeftGaugedQP`](@ref) and [`RightGaugedQP`](@ref). It is used for dispatch and to share their gauge-independent diff --git a/src/states/windowmps.jl b/src/states/windowmps.jl index e32ac35d2..9a072604d 100644 --- a/src/states/windowmps.jl +++ b/src/states/windowmps.jl @@ -1,39 +1,36 @@ """ - WindowMPS{A<:GenericMPSTensor,B<:MPSBondTensor} <: AbstractFiniteMPS +$(TYPEDEF) Type that represents a finite Matrix Product State embedded in an infinite Matrix Product State. -## Fields - -- `left_gs::InfiniteMPS` -- left infinite environment -- `window::FiniteMPS` -- finite window Matrix Product State -- `right_gs::InfiniteMPS` -- right infinite environment - ---- - -## Constructors - +# Constructors WindowMPS(left_gs::InfiniteMPS, window_state::FiniteMPS, [right_gs::InfiniteMPS]) WindowMPS(left_gs::InfiniteMPS, window_tensors::AbstractVector, [right_gs::InfiniteMPS]) - WindowMPS([f, eltype], physicalspaces::Vector{<:Union{S, CompositeSpace{S}}, - virtualspaces::Vector{<:Union{S, CompositeSpace{S}}, left_gs::InfiniteMPS, + WindowMPS([f, eltype], physicalspaces::Vector{<:Union{S, CompositeSpace{S}}}, + virtualspaces::Vector{<:Union{S, CompositeSpace{S}}}, left_gs::InfiniteMPS, [right_gs::InfiniteMPS]) - WindowMPS([f, eltype], physicalspaces::Vector{<:Union{S,CompositeSpace{S}}}, + WindowMPS([f, eltype], physicalspaces::Vector{<:Union{S, CompositeSpace{S}}}, maxvirtualspace::S, left_gs::InfiniteMPS, [right_gs::InfiniteMPS]) + WindowMPS(ψ::InfiniteMPS, L::Int) Construct a WindowMPS via a specification of left and right infinite environment, and either a window state or a vector of tensors to construct the window. Alternatively, it is possible to supply the same arguments as for the constructor of [`FiniteMPS`](@ref), followed by a -left (and right) environment to construct the WindowMPS in one step. +left (and right) environment to construct the WindowMPS in one step. Finally, a WindowMPS can +be constructed from an `InfiniteMPS` by promoting a region of length `L` to a `FiniteMPS`. !!! note By default, the right environment is chosen to be equal to the left, however no copy is made. In this case, changing the left state will also affect the right state. - WindowMPS(state::InfiniteMPS, L::Int) - -Construct a WindowMPS from an InfiniteMPS, by promoting a region of length `L` to a -`FiniteMPS`. +# Properties +- `left_gs::InfiniteMPS`: left infinite environment +- `window::FiniteMPS`: finite window Matrix Product State +- `right_gs::InfiniteMPS`: right infinite environment +- `AL`: left-gauged MPS tensors +- `AR`: right-gauged MPS tensors +- `AC`: center-gauged MPS tensors +- `C`: gauge (bond) tensors """ struct WindowMPS{A <: GenericMPSTensor, B <: MPSBondTensor} <: AbstractFiniteMPS left_gs::InfiniteMPS{A, B} diff --git a/src/utility/dynamictols.jl b/src/utility/dynamictols.jl index 7a67a9a01..39ac6d6d9 100644 --- a/src/utility/dynamictols.jl +++ b/src/utility/dynamictols.jl @@ -23,11 +23,13 @@ $(TYPEDEF) Algorithm wrapper with dynamically adjusted tolerances. -## Fields +# Fields $(TYPEDFIELDS) -See also [`updatetol`](@ref). +# See also + +[`updatetol`](@ref) """ struct DynamicTol{A} <: Algorithm "parent algorithm" diff --git a/src/utility/multiline.jl b/src/utility/multiline.jl index 53b02cfc6..cef1a0f6d 100644 --- a/src/utility/multiline.jl +++ b/src/utility/multiline.jl @@ -1,13 +1,15 @@ """ - struct Multiline{T} +$(TYPEDEF) Object that represents multiple lines of objects of type `T`. Typically used to represent multiple lines of `InfiniteMPS` (`MultilineMPS`) or MPO (`Multiline{<:AbstractMPO}`). # Fields -- `data::PeriodicArray{T,1}`: the data of the multiline object +- `data::PeriodicArray{T, 1}`: the data of the multiline object -See also: [`MultilineMPS`](@ref) and [`MultilineMPO`](@ref) +# See also + +[`MultilineMPS`](@ref) and [`MultilineMPO`](@ref) """ struct Multiline{T} data::PeriodicArray{T, 1} diff --git a/src/utility/periodicarray.jl b/src/utility/periodicarray.jl index 14ce75b65..3963d46ba 100644 --- a/src/utility/periodicarray.jl +++ b/src/utility/periodicarray.jl @@ -1,10 +1,10 @@ """ - PeriodicArray{T,N} <: AbstractArray{T,N} +$(TYPEDEF) Array wrapper with periodic boundary conditions. # Fields -- `data::Array{T,N}`: the data of the array +- `data::Array{T, N}`: the data of the array # Examples ```jldoctest @@ -24,7 +24,9 @@ A[-1, 1], A[1, 1], A[4, 5] (1, 1, 3) ``` -See also [`PeriodicVector`](@ref), [`PeriodicMatrix`](@ref) +# See also + +[`PeriodicVector`](@ref), [`PeriodicMatrix`](@ref) """ struct PeriodicArray{T, N} <: AbstractArray{T, N} data::Array{T, N} @@ -42,7 +44,7 @@ end PeriodicVector{T} One-dimensional dense array with elements of type `T` and periodic boundary conditions. -Alias for [`PeriodicArray{T,1}`](@ref). +Alias for [`PeriodicArray{T, 1}`](@ref). """ const PeriodicVector{T} = PeriodicArray{T, 1} PeriodicVector(data::AbstractVector{T}) where {T} = PeriodicVector{T}(data) @@ -51,7 +53,7 @@ PeriodicVector(data::AbstractVector{T}) where {T} = PeriodicVector{T}(data) PeriodicMatrix{T} Two-dimensional dense array with elements of type `T` and periodic boundary conditions. -Alias for [`PeriodicArray{T,2}`](@ref). +Alias for [`PeriodicArray{T, 2}`](@ref). """ const PeriodicMatrix{T} = PeriodicArray{T, 2} PeriodicMatrix(data::AbstractMatrix{T}) where {T} = PeriodicMatrix{T}(data) diff --git a/src/utility/plotting.jl b/src/utility/plotting.jl index 022fee33b..9d6d4e319 100644 --- a/src/utility/plotting.jl +++ b/src/utility/plotting.jl @@ -1,18 +1,18 @@ """ - entanglementplot(state; site=0[, kwargs...]) + entanglementplot(state; site = 0[, kwargs...]) -Plot the [entanglement spectrum](@ref entanglement_spectrum) of a given MPS `state`. +Plot the [entanglement spectrum](@ref entanglement_spectrum) of a given MPS `state`. # Arguments - `state`: the MPS for which to compute the entanglement spectrum. # Keyword Arguments -- `site::Int=0`: MPS index for multisite unit cells. The spectrum is computed for the bond +- `site::Int = 0`: MPS index for multisite unit cells. The spectrum is computed for the bond between `site` and `site + 1`. -- `expand_symmetry::Logical=false`: add quantum dimension degeneracies. -- `sortby=maximum`: the method of sorting the sectors. -- `sector_margin=1//10`: the amount of whitespace between sectors. -- `sector_formatter=string`: how to convert sectors to strings. +- `expand_symmetry = false`: add quantum dimension degeneracies. +- `sortby = maximum`: the method of sorting the sectors. +- `sector_margin = 1 // 10`: the amount of whitespace between sectors. +- `sector_formatter = string`: how to convert sectors to strings. - `kwargs...`: other kwargs are passed on to the plotting backend. !!! note @@ -89,21 +89,21 @@ function entanglementplot end end """ - transferplot(above, below=above; sectors=nothing, transferkwargs=(;)[, kwargs...]) + transferplot(above, below = above; sectors = nothing, transferkwargs = (;)[, kwargs...]) Plot the partial transfer matrix spectrum of two InfiniteMPS's. # Arguments - `above::InfiniteMPS`: above mps for [`transfer_spectrum`](@ref). -- `below::InfiniteMPS=above`: below mps for [`transfer_spectrum`](@ref). +- `below::InfiniteMPS = above`: below mps for [`transfer_spectrum`](@ref). # Keyword Arguments -- `sectors=nothing`: restrict the spectrum to the given sectors; by default all sectors of +- `sectors = nothing`: restrict the spectrum to the given sectors; by default all sectors of the transfer space are included. - `transferkwargs`: kwargs for call to [`transfer_spectrum`](@ref). - `kwargs`: other kwargs are passed on to the plotting backend. -- `thetaorigin=0`: origin of the angle range. -- `sector_formatter=string`: how to convert sectors to strings. +- `thetaorigin = 0`: origin of the angle range. +- `sector_formatter = string`: how to convert sectors to strings. !!! note You will need to manually import [Plots.jl](https://github.com/JuliaPlots/Plots.jl) to From d31f3337b9aab8006fc30efe40ee7f94fd3cad64 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Sat, 4 Jul 2026 07:17:32 -0400 Subject: [PATCH 17/76] use TensorKitTensors --- docs/Project.toml | 2 ++ docs/src/howto/bond_dimension.md | 5 +++-- docs/src/howto/entanglement.md | 5 +++-- docs/src/howto/hamiltonians.md | 7 ++++--- docs/src/howto/observables.md | 9 +++++---- docs/src/index.md | 10 ++++++---- docs/src/man/operators.md | 23 ++++++++++++----------- 7 files changed, 35 insertions(+), 26 deletions(-) diff --git a/docs/Project.toml b/docs/Project.toml index dc5e8d2bc..a62ccff45 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -13,6 +13,7 @@ Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" Polynomials = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7" TensorKit = "07d1fe3e-3e46-537d-9eac-e9e13d0d4cec" +TensorKitTensors = "41b62e7d-e9d1-4e23-942c-79a97adf954b" TensorOperations = "6aa20fa7-93e2-5fca-9bc0-fbd0db3c71a2" [sources] @@ -22,3 +23,4 @@ MPSKit = {path = ".."} Documenter = "1.11" DocumenterInterLinks = "1" DocumenterVitepress = "0.3" +TensorKitTensors = "0.2" diff --git a/docs/src/howto/bond_dimension.md b/docs/src/howto/bond_dimension.md index c46192200..5b1d25ea2 100644 --- a/docs/src/howto/bond_dimension.md +++ b/docs/src/howto/bond_dimension.md @@ -6,6 +6,7 @@ All examples share a single namespace: ```@example bond_dim using MPSKit, TensorKit +using TensorKitTensors.SpinOperators: σˣ, σᶻ ``` --- @@ -81,8 +82,8 @@ It needs both the state and the Hamiltonian: # Build a finite TFIM Hamiltonian manually J = 1.0; g = 0.5 lattice = fill(ℂ^2, L) -X = TensorMap(ComplexF64[0 1; 1 0], ℂ^2, ℂ^2) -Z = TensorMap(ComplexF64[1 0; 0 -1], ℂ^2, ℂ^2) +X = σˣ() +Z = σᶻ() H = FiniteMPOHamiltonian(lattice, (i, i + 1) => -J * X ⊗ X for i in 1:(L - 1)) + FiniteMPOHamiltonian(lattice, (i,) => -g * Z for i in 1:L) diff --git a/docs/src/howto/entanglement.md b/docs/src/howto/entanglement.md index d635dde2b..27ca524e1 100644 --- a/docs/src/howto/entanglement.md +++ b/docs/src/howto/entanglement.md @@ -6,6 +6,7 @@ The reference page for these and related functions is [Observables and analysis] ```@example entanglement using MPSKit, TensorKit +using TensorKitTensors.SpinOperators: σˣ, σᶻ ``` --- @@ -19,8 +20,8 @@ L = 8 ψ0 = FiniteMPS(L, ℂ^2, ℂ^8) # single-site Pauli operators -X = TensorMap(ComplexF64[0 1; 1 0], ℂ^2, ℂ^2) -Z = TensorMap(ComplexF64[1 0; 0 -1], ℂ^2, ℂ^2) +X = σˣ() +Z = σᶻ() lattice = fill(ℂ^2, L) H = FiniteMPOHamiltonian(lattice, (i, i + 1) => -(X ⊗ X) for i in 1:(L - 1)) + diff --git a/docs/src/howto/hamiltonians.md b/docs/src/howto/hamiltonians.md index f90bae4ed..47285b882 100644 --- a/docs/src/howto/hamiltonians.md +++ b/docs/src/howto/hamiltonians.md @@ -7,6 +7,7 @@ The reference page for the underlying MPO structure is [Operators](@ref lib_oper ```@example hamiltonians using MPSKit, TensorKit +using TensorKitTensors.SpinOperators: σˣ, σᶻ ``` --- @@ -15,11 +16,11 @@ using MPSKit, TensorKit The examples below build the transverse-field Ising model (TFIM), the same flagship model used elsewhere in these docs. -All operators are `ComplexF64` `TensorMap`s on the spin-1/2 physical space `ℂ^2`: +The single-site Pauli operators come from [TensorKitTensors.jl](https://github.com/QuantumKitHub/TensorKitTensors.jl), which returns `ComplexF64` `TensorMap`s on the spin-1/2 physical space `ℂ^2`: ```@example hamiltonians -X = TensorMap(ComplexF64[0 1; 1 0], ℂ^2, ℂ^2) -Z = TensorMap(ComplexF64[1 0; 0 -1], ℂ^2, ℂ^2) +X = σˣ() +Z = σᶻ() g = 0.5 ``` diff --git a/docs/src/howto/observables.md b/docs/src/howto/observables.md index d34e2d12e..44309def5 100644 --- a/docs/src/howto/observables.md +++ b/docs/src/howto/observables.md @@ -5,6 +5,7 @@ All examples share a single namespace and build on state and operator objects yo ```@example observables using MPSKit, TensorKit +using TensorKitTensors.SpinOperators: σˣ, σᶻ ``` For building MPS objects see [Constructing states](@ref howto_states). @@ -15,16 +16,16 @@ The reference page for ground-state algorithms is [Ground-state algorithms](@ref ## Setup: state and operators -The examples below use a spin-1/2 `FiniteMPS` together with the Pauli matrices built directly from `TensorMap`. -All operators use `ComplexF64` to match the default element type of the state. +The examples below use a spin-1/2 `FiniteMPS` together with the Pauli operators from [TensorKitTensors.jl](https://github.com/QuantumKitHub/TensorKitTensors.jl). +These are `ComplexF64` `TensorMap`s, matching the default element type of the state. ```@example observables L = 8 ψ = FiniteMPS(L, ℂ^2, ℂ^8) # random finite MPS, bond dim ≤ 8 # single-site Pauli operators -X = TensorMap(ComplexF64[0 1; 1 0], ℂ^2, ℂ^2) -Z = TensorMap(ComplexF64[1 0; 0 -1], ℂ^2, ℂ^2) +X = σˣ() +Z = σᶻ() ``` The finite TFIM Hamiltonian used in recipes 3 and 5 is built from these: diff --git a/docs/src/index.md b/docs/src/index.md index dd86bb1ba..689a04e1a 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -76,6 +76,7 @@ using LinearAlgebra using TensorOperations using TensorKit using MPSKit +using TensorKitTensors.SpinOperators: σˣ, σᶻ ``` Finite MPS are characterised by a set of tensors, one for each site, which each have 3 legs. @@ -136,8 +137,8 @@ transverse field Ising model: J = 1.0 g = 0.5 lattice = fill(ComplexSpace(2), 10) -X = TensorMap(ComplexF64[0 1; 1 0], ComplexSpace(2), ComplexSpace(2)) -Z = TensorMap(ComplexF64[1 0; 0 -1], space(X)) +X = σˣ() +Z = σᶻ() H = FiniteMPOHamiltonian(lattice, (i, i+1) => -J * X ⊗ X for i in 1:length(lattice)-1) + FiniteMPOHamiltonian(lattice, (i,) => - g * Z for i in 1:length(lattice)) find_groundstate!(mps, H, DMRG(; maxiter=10)) @@ -152,6 +153,7 @@ using LinearAlgebra using TensorOperations using TensorKit using MPSKit +using TensorKitTensors.SpinOperators: σˣ, σᶻ ``` Similarly, an infinite MPS can be constructed by specifying the tensors for the unit cell, @@ -212,8 +214,8 @@ the ground state for the transverse field Ising model: J = 1.0 g = 0.5 lattice = PeriodicVector([ComplexSpace(2)]) -X = TensorMap(ComplexF64[0 1; 1 0], ComplexSpace(2), ComplexSpace(2)) -Z = TensorMap(ComplexF64[1 0; 0 -1], space(X)) +X = σˣ() +Z = σᶻ() H = InfiniteMPOHamiltonian(lattice, (1, 2) => -J * X ⊗ X, (1,) => - g * Z) mps, = find_groundstate(mps, H, VUMPS(; maxiter=10)) E0 = expectation_value(mps, H) diff --git a/docs/src/man/operators.md b/docs/src/man/operators.md index 05525add2..649fbc193 100644 --- a/docs/src/man/operators.md +++ b/docs/src/man/operators.md @@ -19,12 +19,13 @@ product of local tensors. ```@setup operators using TensorKit, MPSKit, MPSKitModels +using TensorKitTensors.SpinOperators: σˣ, σᶻ ``` ```@example operators -S_x = TensorMap(ComplexF64[0 1; 1 0], ℂ^2 ← ℂ^2) -S_z = TensorMap(ComplexF64[1 0; 0 -1], ℂ^2 ← ℂ^2) -O_xzx = FiniteMPO(S_x ⊗ S_z ⊗ S_x); +X = σˣ() +Z = σᶻ() +O_xzx = FiniteMPO(X ⊗ Z ⊗ X); ``` The individual tensors are accessible via regular indexing. Note that the tensors are @@ -115,8 +116,8 @@ H = -J \sum_{\langle i, j \rangle} X_i X_j - h \sum_j Z_j J = 1.0 h = 0.5 chain = fill(ℂ^2, 3) # a finite chain of 4 sites, each with a 2-dimensional Hilbert space -single_site_operators = [1 => -h * S_z, 2 => -h * S_z, 3 => -h * S_z] -two_site_operators = [(1, 2) => -J * S_x ⊗ S_x, (2, 3) => -J * S_x ⊗ S_x] +single_site_operators = [1 => -h * Z, 2 => -h * Z, 3 => -h * Z] +two_site_operators = [(1, 2) => -J * X ⊗ X, (2, 3) => -J * X ⊗ X] H_ising = FiniteMPOHamiltonian(chain, single_site_operators..., two_site_operators...) ``` @@ -125,8 +126,8 @@ that specify the operators, or using generator expressions to simplify the const ```@example operators H_ising′ = -J * FiniteMPOHamiltonian(chain, - (i, i + 1) => S_x ⊗ S_x for i in 1:(length(chain) - 1)) - - h * FiniteMPOHamiltonian(chain, i => S_z for i in 1:length(chain)) + (i, i + 1) => X ⊗ X for i in 1:(length(chain) - 1)) - + h * FiniteMPOHamiltonian(chain, i => Z for i in 1:length(chain)) isapprox(H_ising, H_ising′; atol=1e-6) ``` @@ -141,7 +142,7 @@ operators = Dict() local_operators = Dict() for I in eachindex(square) - local_operators[(I,)] = -h * S_z # single site operators still require tuples of indices + local_operators[(I,)] = -h * Z # single site operators still require tuples of indices end # horizontal and vertical interactions are easier using Cartesian indices @@ -149,7 +150,7 @@ horizontal_operators = Dict() I_horizontal = CartesianIndex(0, 1) for I in eachindex(IndexCartesian(), square) if I[2] < size(square, 2) - horizontal_operators[(I, I + I_horizontal)] = -J * S_x ⊗ S_x + horizontal_operators[(I, I + I_horizontal)] = -J * X ⊗ X end end @@ -157,7 +158,7 @@ vertical_operators = Dict() I_vertical = CartesianIndex(1, 0) for I in eachindex(IndexCartesian(), square) if I[1] < size(square, 1) - vertical_operators[(I, I + I_vertical)] = -J * S_x ⊗ S_x + vertical_operators[(I, I + I_vertical)] = -J * X ⊗ X end end @@ -179,7 +180,7 @@ In particular, an [`InfiniteMPOHamiltonian`](@ref) for the Ising model is obtain J = 1.0 h = 0.5 infinite_chain = PeriodicVector([ℂ^2]) # an infinite chain of a local 2-dimensional Hilbert space -H_ising_infinite = InfiniteMPOHamiltonian(infinite_chain, 1 => -h * S_z, (1, 2) => -J * S_x ⊗ S_x) +H_ising_infinite = InfiniteMPOHamiltonian(infinite_chain, 1 => -h * Z, (1, 2) => -J * X ⊗ X) ``` ### Expert mode From 9876933502a568e3c7761d650cce9398e93234b6 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Sat, 4 Jul 2026 07:17:43 -0400 Subject: [PATCH 18/76] small fix windowhamiltonian --- src/operators/windowhamiltonian.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/operators/windowhamiltonian.jl b/src/operators/windowhamiltonian.jl index b6d0b9ffd..8fadae00d 100644 --- a/src/operators/windowhamiltonian.jl +++ b/src/operators/windowhamiltonian.jl @@ -40,6 +40,8 @@ function WindowMPOHamiltonian(ham::InfiniteMPOHamiltonian, interval::UnitRange) return WindowMPOHamiltonian(left_ham, finite_ham, right_ham) end +Base.isfinite(::Type{<:WindowMPOHamiltonian}) = true + Base.parent(h::WindowMPOHamiltonian) = h.finite_ham Base.copy(h::WindowMPOHamiltonian) = WindowMPOHamiltonian(copy(h.left_ham), copy(h.finite_ham), copy(h.right_ham)) Base.conj(h::WindowMPOHamiltonian) = WindowMPOHamiltonian(conj(h.left_ham), conj(h.finite_ham), conj(h.right_ham)) From 3d261f2845b6ff86a1f83109f8160be82ca21969 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Sat, 4 Jul 2026 07:31:07 -0400 Subject: [PATCH 19/76] fix interpolation bug --- docs/src/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/index.md b/docs/src/index.md index 689a04e1a..42e52902f 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -143,7 +143,7 @@ H = FiniteMPOHamiltonian(lattice, (i, i+1) => -J * X ⊗ X for i in 1:length(lat FiniteMPOHamiltonian(lattice, (i,) => - g * Z for i in 1:length(lattice)) find_groundstate!(mps, H, DMRG(; maxiter=10)) E0 = expectation_value(mps, H) -println(" = $real(E0)") +println(" = $(real(E0))") ``` ### Infinite Matrix Product States From 633fc17a18938e033465e34dbd92c4e50897a0e9 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Sat, 4 Jul 2026 10:39:32 -0400 Subject: [PATCH 20/76] docs: resolve REVIEW flags in docstrings and reference pages Address the batch of accurate/verifiable REVIEW comments left throughout the docs and package docstrings: - MPOHamiltonian: retarget the docstring constructor signatures and example to the concrete FiniteMPOHamiltonian / InfiniteMPOHamiltonian entry points (the MPOHamiltonian(lattice, ...) methods do not exist). - excitations umbrella docstring: drop the nonexistent `solver = Defaults.solver` default and the oversimplified FiniteExcited `init` default; describe the real forwarding/default behaviour. - ChepigaAnsatz2: document the real field defaults (Arnoldi(; krylovdim=30, tol=1e-10, eager=true) and notrunc()). - time_evolve / timestep: `alg` is a required positional argument, not defaulted to TDVP; correct both docstrings accordingly. - Fix a used-before-assignment bug in the InfiniteMPO QuasiparticleAnsatz excitations method (EffectiveExcitationHamiltonian(H_eff, ...) -> H). - observables reference page: surface the known source-status concerns for expectation_value(::MultilineMPS, ::MultilineMPO) and variance(::InfiniteQP, ::InfiniteMPOHamiltonian) as !!! warning admonitions. Doctests pass. Co-Authored-By: Claude Opus 4.8 --- docs/src/lib/excitations.md | 10 +------- docs/src/lib/observables.md | 25 +++++++++++++------ docs/src/lib/time_evolution.md | 3 --- src/algorithms/excitation/chepigaansatz.jl | 6 ++--- src/algorithms/excitation/excitations.jl | 8 +++--- .../excitation/quasiparticleexcitation.jl | 2 +- src/algorithms/timestep/time_evolve.jl | 12 ++++----- src/operators/mpohamiltonian.jl | 14 +++++------ 8 files changed, 37 insertions(+), 43 deletions(-) diff --git a/docs/src/lib/excitations.md b/docs/src/lib/excitations.md index 3433a2e42..48767b015 100644 --- a/docs/src/lib/excitations.md +++ b/docs/src/lib/excitations.md @@ -30,16 +30,8 @@ RightGaugedQP ``` diff --git a/docs/src/lib/observables.md b/docs/src/lib/observables.md index 737694663..b882596eb 100644 --- a/docs/src/lib/observables.md +++ b/docs/src/lib/observables.md @@ -10,6 +10,13 @@ The full, canonical docstrings for the whole package live in the [Library](@ref expectation_value ``` +!!! warning "Multiline environments" + The `expectation_value(::MultilineMPS, ::MultilineMPO, envs...)` method reuses the + passed environments without recomputing them for the operator (see the `# TODO: fix + environments` note in `src/algorithms/expval.jl`). + Results along this code path should be cross-checked against an independent calculation + until the environment handling is finalized. + ## Correlators ```@docs; canonical=false @@ -22,6 +29,11 @@ correlator variance ``` +!!! warning "Variance of infinite quasiparticle states" + The `variance(::InfiniteQP, ::InfiniteMPOHamiltonian, envs)` method carries an + unresolved implementation note in `src/algorithms/toolbox.jl` and may be unreliable. + Verify its output before using it as a convergence diagnostic for quasiparticle states. + ## Transfer matrix and correlation length ```@docs; canonical=false @@ -47,12 +59,9 @@ Maintainer notes: - Symbols included: `expectation_value`, `correlator`, `variance`, `correlation_length`, `marek_gap`, `transfer_spectrum`, `transferplot`, `entropy`, `entanglement_spectrum`, `entanglementplot`. -- REVIEW: `expectation_value(::MultilineMPS, ::MultilineMPO, envs...)` in - `src/algorithms/expval.jl` carries a `# TODO: fix environments` comment in the source; - the docstring surfaces as-is here, but the method's correctness/status should be - confirmed before calling this reference page complete. -- REVIEW: `variance(::InfiniteQP, ::InfiniteMPOHamiltonian, envs)` in - `src/algorithms/toolbox.jl` carries a `# I remember there being an issue here @gertian?` - comment, suggesting the method may be unreliable; flagging for maintainer judgment on - whether it needs a caveat note or an `!!! warning` admonition on this page. +- The `# TODO: fix environments` concern on `expectation_value(::MultilineMPS, ::MultilineMPO)` + (`src/algorithms/expval.jl`) and the unresolved-issue comment on + `variance(::InfiniteQP, ::InfiniteMPOHamiltonian)` (`src/algorithms/toolbox.jl`) are now + surfaced to readers via `!!! warning` admonitions above. Remove those warnings once the + underlying source issues are resolved. --> diff --git a/docs/src/lib/time_evolution.md b/docs/src/lib/time_evolution.md index 698712db7..87b9ab9f7 100644 --- a/docs/src/lib/time_evolution.md +++ b/docs/src/lib/time_evolution.md @@ -35,7 +35,4 @@ Maintainer footer. Symbols included: time_evolve, timestep, timestep!, TDVP, TDVP2, make_time_mpo, TaylorCluster, WI, WII. Caveats: - `time_evolve!` exists in src but is NOT exported, so it is intentionally omitted from this page. -- REVIEW: the `time_evolve` docstring claims a default `alg=TDVP`, but this is not an actual default - argument in the `src` method signature. This is a docstring/signature mismatch that should be - reconciled by the maintainer (either add the default in code or correct the docstring). --> diff --git a/src/algorithms/excitation/chepigaansatz.jl b/src/algorithms/excitation/chepigaansatz.jl index 6be4f158e..37241ac0a 100644 --- a/src/algorithms/excitation/chepigaansatz.jl +++ b/src/algorithms/excitation/chepigaansatz.jl @@ -82,10 +82,8 @@ Create a `ChepigaAnsatz2` algorithm with the given eigensolver and truncation, o keyword arguments to [`Arnoldi`](@extref KrylovKit.Arnoldi). # Fields -- `alg`: algorithm used for the eigenvalue problem -- `trscheme`: truncation scheme used when splitting the optimized two-site tensor - - +- `alg`: algorithm used for the eigenvalue problem, defaults to `Arnoldi(; krylovdim = 30, tol = 1.0e-10, eager = true)` +- `trscheme`: truncation scheme used when splitting the optimized two-site tensor, defaults to `notrunc()` # See also diff --git a/src/algorithms/excitation/excitations.jl b/src/algorithms/excitation/excitations.jl index e528d43da..1bcc0bb93 100644 --- a/src/algorithms/excitation/excitations.jl +++ b/src/algorithms/excitation/excitations.jl @@ -2,9 +2,9 @@ excitations(H, algorithm::QuasiparticleAnsatz, ψ::FiniteQP, [left_environments], [right_environments]; num = 1) -> (energies, states) excitations(H, algorithm::QuasiparticleAnsatz, ψ::InfiniteQP, [left_environments], - [right_environments]; num = 1, solver = Defaults.solver) -> (energies, states) + [right_environments]; num = 1) -> (energies, states) excitations(H, algorithm::FiniteExcited, ψs::NTuple{<:Any, <:FiniteMPS}; - num = 1, init = copy(first(ψs))) -> (energies, states) + num = 1, init) -> (energies, states) excitations(H, algorithm::ChepigaAnsatz, ψ::FiniteMPS, [envs]; num = 1, pos = length(ψ) ÷ 2) -> (energies, states) excitations(H, algorithm::ChepigaAnsatz2, ψ::FiniteMPS, [envs]; @@ -12,8 +12,6 @@ Compute the first excited states and their energy gap above a ground state. - - # Arguments - `H::AbstractMPO`: operator for which to find the excitations - `algorithm`: optimization algorithm @@ -25,7 +23,7 @@ Compute the first excited states and their energy gap above a ground state. # Keyword Arguments - `num::Int`: number of excited states to compute - `solver`: algorithm for the linear solver of the quasiparticle environments -- `init`: initial excited state guess +- `init`: initial excited state guess; defaults to a copy of the first state in `ψs` - `pos`: position of perturbation """ function excitations end diff --git a/src/algorithms/excitation/quasiparticleexcitation.jl b/src/algorithms/excitation/quasiparticleexcitation.jl index bc83f30c4..0a44c4e8f 100644 --- a/src/algorithms/excitation/quasiparticleexcitation.jl +++ b/src/algorithms/excitation/quasiparticleexcitation.jl @@ -218,7 +218,7 @@ function excitations( num = 1 ) E = effective_excitation_renormalization_energy(H, ϕ₀, lenvs, renvs) - H_eff = EffectiveExcitationHamiltonian(H_eff, lenvs, renvs, E) + H_eff = EffectiveExcitationHamiltonian(H, lenvs, renvs, E) Es, ϕs, convhist = eigsolve(ϕ₀, num, :LM, alg.alg) do ϕ return H_eff(ϕ, alg.alg_environments) diff --git a/src/algorithms/timestep/time_evolve.jl b/src/algorithms/timestep/time_evolve.jl index edba67d3a..5465d7f6b 100644 --- a/src/algorithms/timestep/time_evolve.jl +++ b/src/algorithms/timestep/time_evolve.jl @@ -1,6 +1,6 @@ """ - time_evolve(ψ₀, H, t_span, [alg], [envs]; kwargs...) -> (ψ, envs) - time_evolve!(ψ₀, H, t_span, [alg], [envs]; kwargs...) -> (ψ₀, envs) + time_evolve(ψ₀, H, t_span, alg, [envs]; kwargs...) -> (ψ, envs) + time_evolve!(ψ₀, H, t_span, alg, [envs]; kwargs...) -> (ψ₀, envs) Time-evolve the initial state `ψ₀` with Hamiltonian `H` over a given time span by stepping through each of the time points obtained by iterating t_span. @@ -10,7 +10,7 @@ through each of the time points obtained by iterating t_span. - `ψ₀::AbstractMPS`: initial state - `H::AbstractMPO`: operator that generates the time evolution (can be time-dependent). - `t_span::AbstractVector{<:Number}`: time points over which the time evolution is stepped -- `alg`: algorithm to use for the time evolution. Defaults to [`TDVP`](@ref). +- `alg`: algorithm to use for the time evolution, e.g. [`TDVP`](@ref) or [`TDVP2`](@ref). - `envs`: MPS environment manager # Keyword Arguments @@ -53,8 +53,8 @@ for (timestep, time_evolve) in zip((:timestep, :timestep!), (:time_evolve, :time end """ - timestep(ψ₀, H, t, dt, [alg], [envs]; kwargs...) -> (ψ, envs) - timestep!(ψ₀, H, t, dt, [alg], [envs]; kwargs...) -> (ψ₀, envs) + timestep(ψ₀, H, t, dt, alg, [envs]; kwargs...) -> (ψ, envs) + timestep!(ψ₀, H, t, dt, alg, [envs]; kwargs...) -> (ψ₀, envs) Time-step the state `ψ₀` with Hamiltonian `H` over a given time step `dt` at time `t`, solving the Schroedinger equation: ``i ∂ψ/∂t = H ψ``. @@ -65,7 +65,7 @@ solving the Schroedinger equation: ``i ∂ψ/∂t = H ψ``. - `H::AbstractMPO`: operator that generates the time evolution (can be time-dependent). - `t::Number`: starting time of time-step - `dt::Number`: time-step magnitude -- `alg`: algorithm to use for the time evolution. Defaults to [`TDVP`](@ref). +- `alg`: algorithm to use for the time evolution, e.g. [`TDVP`](@ref) or [`TDVP2`](@ref). - `envs`: MPS environment manager # Keyword Arguments diff --git a/src/operators/mpohamiltonian.jl b/src/operators/mpohamiltonian.jl index 2a6cb5b14..6f6fce32d 100644 --- a/src/operators/mpohamiltonian.jl +++ b/src/operators/mpohamiltonian.jl @@ -16,13 +16,13 @@ upper triangular block matrix of the following form: where `A`, `B`, `C`, and `D` are `MPOTensor`s, or (sparse) blocks thereof. # Constructors - MPOHamiltonian(lattice::AbstractArray{<:VectorSpace}, local_operators...) - MPOHamiltonian(lattice::AbstractArray{<:VectorSpace}) - MPOHamiltonian(x::AbstractArray{<:Any, 3}) - +The finite and infinite variants, [`FiniteMPOHamiltonian`](@ref) and +[`InfiniteMPOHamiltonian`](@ref), are constructed from a lattice of physical spaces together +with a set of `inds => operator` pairs describing the local terms: + + FiniteMPOHamiltonian(lattice::AbstractArray{<:VectorSpace}, local_operators...) + InfiniteMPOHamiltonian(lattice::AbstractArray{<:VectorSpace}, local_operators...) # Properties - `A`: bulk block of interacting operators at each site @@ -35,7 +35,7 @@ For example, constructing a nearest-neighbour Hamiltonian would look like this: ```julia lattice = fill(ℂ^2, 10) -H = MPOHamiltonian(lattice, (i, i+1) => O for i in 1:length(lattice)-1) +H = FiniteMPOHamiltonian(lattice, (i, i+1) => O for i in 1:length(lattice)-1) ``` # See also From ca77904d65eab4e2330c9c33c4310603cc7fee45 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Sat, 4 Jul 2026 11:44:24 -0400 Subject: [PATCH 21/76] docs: resolve physics/interpretation REVIEW flags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Maintainer-confirmed resolutions for the remaining REVIEW comments: - hamiltonians.md: add a short TFIM description (X⊗X coupling, transverse field g along Z, quantum phase transition at g=1). - observables.md / entanglement.md: drop the connected-correlator, area-law, and sector-spectrum REVIEWs, leaving the text neutral (no phase-dependent physical interpretation asserted). - entanglement.md: replace the random-ψ∞ REVIEW with a !!! note clarifying it is not a converged ground state and pointing to find_groundstate. - entanglement.md: drop the WindowMPS REVIEW after verifying entropy(::WindowMPS, site) runs. - finite_envs.jl: drop the left/right environment REVIEWs; the wording matches the code (GRs[ind+1] contracts sites ind+1..end, gauge-compatible with the tensor at site ind, and mirror for leftenv). No REVIEW comments remain in src/ or docs/src/. Doctests pass. Co-Authored-By: Claude Opus 4.8 --- docs/src/howto/entanglement.md | 17 +++-------------- docs/src/howto/hamiltonians.md | 3 ++- docs/src/howto/observables.md | 3 --- src/environments/finite_envs.jl | 6 ------ src/operators/mpohamiltonian.jl | 1 + 5 files changed, 6 insertions(+), 24 deletions(-) diff --git a/docs/src/howto/entanglement.md b/docs/src/howto/entanglement.md index 27ca524e1..ecda798c7 100644 --- a/docs/src/howto/entanglement.md +++ b/docs/src/howto/entanglement.md @@ -41,10 +41,6 @@ For a `FiniteMPS` the site is a required argument: entropy(ψ, L ÷ 2) # entropy across the central cut ``` - - --- ## 2. Entropy profile across every cut @@ -103,12 +99,6 @@ For the plain (no explicit symmetry) `FiniteMPS` built above there is a single s collect(pairs(spectrum)) ``` - - --- ## 5. Entanglement of an infinite MPS @@ -124,13 +114,12 @@ entropy(ψ∞) entanglement_spectrum(ψ∞) # site defaults to 0 ``` - +!!! note + `ψ∞` here is a random `InfiniteMPS`, not a converged ground state, so the values above illustrate the interface rather than any physical entanglement profile. + For a physically meaningful result, compute the entropy of a state obtained from [`find_groundstate`](@ref) (for example via VUMPS). !!! note `WindowMPS` also supports `entropy(ψ, site)` with a required site argument, mirroring the `FiniteMPS` form. - --- diff --git a/docs/src/howto/hamiltonians.md b/docs/src/howto/hamiltonians.md index 47285b882..66cb36663 100644 --- a/docs/src/howto/hamiltonians.md +++ b/docs/src/howto/hamiltonians.md @@ -15,7 +15,8 @@ using TensorKitTensors.SpinOperators: σˣ, σᶻ ## Setup: local operators The examples below build the transverse-field Ising model (TFIM), the same flagship model used elsewhere in these docs. - +It couples neighbouring spins through `X ⊗ X` and applies a transverse field of strength `g` along `Z`. +The model has a quantum phase transition at `g = 1`, separating an ordered (ferromagnetic) phase at small `g` from a disordered (paramagnetic) phase at large `g`. The single-site Pauli operators come from [TensorKitTensors.jl](https://github.com/QuantumKitHub/TensorKitTensors.jl), which returns `ComplexF64` `TensorMap`s on the spin-1/2 physical space `ℂ^2`: ```@example hamiltonians diff --git a/docs/src/howto/observables.md b/docs/src/howto/observables.md index 44309def5..3d6dde478 100644 --- a/docs/src/howto/observables.md +++ b/docs/src/howto/observables.md @@ -134,9 +134,6 @@ connected = [c - z_mean * expectation_value(ψ, j => Z) for (j, c) in zip(3:L, c ``` This subtracts the disconnected part ``\langle Z_i\rangle\langle Z_j\rangle`` to leave the connected correlator ``\langle Z_i Z_j\rangle - \langle Z_i\rangle\langle Z_j\rangle``. - --- diff --git a/src/environments/finite_envs.jl b/src/environments/finite_envs.jl index 8aeeb266f..6605ccc74 100644 --- a/src/environments/finite_envs.jl +++ b/src/environments/finite_envs.jl @@ -105,9 +105,6 @@ of everything to the right of `site` in the network the environments were built The result is gauge-compatible with the tensor of `state` at `site` and can be contracted onto it directly. - - See also [`leftenv`](@ref) and [`environments`](@ref). """ function rightenv(ca::FiniteEnvironments, ind, state) @@ -135,9 +132,6 @@ of everything to the left of `site` in the network the environments were built f The result is gauge-compatible with the tensor of `state` at `site` and can be contracted onto it directly. - - See also [`rightenv`](@ref) and [`environments`](@ref). """ function leftenv(ca::FiniteEnvironments, ind, state) diff --git a/src/operators/mpohamiltonian.jl b/src/operators/mpohamiltonian.jl index 6f6fce32d..66b71b10f 100644 --- a/src/operators/mpohamiltonian.jl +++ b/src/operators/mpohamiltonian.jl @@ -25,6 +25,7 @@ with a set of `inds => operator` pairs describing the local terms: InfiniteMPOHamiltonian(lattice::AbstractArray{<:VectorSpace}, local_operators...) # Properties + - `A`: bulk block of interacting operators at each site - `B`: operators that finish an interaction - `C`: operators that start an interaction From 82672a28795225f6f136c934fd108fa0c96a844f Mon Sep 17 00:00:00 2001 From: lkdvos Date: Sat, 4 Jul 2026 12:24:25 -0400 Subject: [PATCH 22/76] =?UTF-8?q?docs(w0):=20repo=20metadata=20=E2=80=94?= =?UTF-8?q?=20root=20changelog,=20contributing=20guide,=20templates,=20cit?= =?UTF-8?q?ation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - CHANGELOG.md now canonical at repo root (visible on GitHub); make.jl copies it into docs/src at build time, generated copy gitignored - add CONTRIBUTING.md, issue templates (bug/question), PR template - CITATION.cff bumped to v0.13.13 (tag date 2026-06-09) - README gains a Citing section with BibTeX Co-Authored-By: Claude Fable 5 --- .github/ISSUE_TEMPLATE/bug_report.md | 49 +++++++++++++++ .github/ISSUE_TEMPLATE/question.md | 27 ++++++++ .github/PULL_REQUEST_TEMPLATE.md | 9 +++ docs/src/changelog.md => CHANGELOG.md | 0 CITATION.cff | 4 +- CONTRIBUTING.md | 90 +++++++++++++++++++++++++++ README.md | 16 +++++ docs/.gitignore | 3 +- docs/make.jl | 3 + 9 files changed, 198 insertions(+), 3 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/question.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md rename docs/src/changelog.md => CHANGELOG.md (100%) create mode 100644 CONTRIBUTING.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..cc0720870 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,49 @@ +--- +name: Bug report +about: Something isn't working as expected +title: "" +labels: bug +--- + +## Description + +A clear and concise description of what went wrong, and what you expected to happen instead. + +## Minimal working example (MWE) + +Please include the smallest possible piece of code that reproduces the issue. +Trim away everything that is not needed to trigger the bug (unrelated setup, unused imports, etc). + +```julia +using MPSKit, TensorKit + +# ... +``` + +## Error / output + +Paste the full error message and stacktrace (or the incorrect output), if any. + +``` +paste here +``` + +## Version info + +Please include the versions of MPSKit and its main dependencies. +From the Julia REPL: + +```julia-repl +julia> using Pkg +julia> Pkg.status(["MPSKit", "TensorKit"]) +``` + +Also include the Julia version: + +```julia-repl +julia> versioninfo() +``` + +## Additional context + +Anything else that might help (OS, whether it also happens on the latest `main`, related issues, etc). diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md new file mode 100644 index 000000000..c7215fe11 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/question.md @@ -0,0 +1,27 @@ +--- +name: Question +about: Ask a question about using MPSKit +title: "" +labels: question +--- + +## What are you trying to do? + +Describe the physics or the workflow you are trying to set up. + +## What have you tried? + +If applicable, include the code you have so far, and what result you got (or expected but didn't get). + +```julia +using MPSKit, TensorKit + +# ... +``` + +## Version info (optional but helpful) + +```julia-repl +julia> using Pkg +julia> Pkg.status(["MPSKit", "TensorKit"]) +``` diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..9b4d4812d --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,9 @@ +## Description + +Briefly describe what this PR changes and why. + +## Checklist + +- [ ] Tests pass locally (`julia --project=test test/runtests.jl`, or the relevant subset) +- [ ] Documentation updated, if this PR changes public API (docstrings, `docs/src/`) +- [ ] Changelog entry added under `[Unreleased]` in `CHANGELOG.md` diff --git a/docs/src/changelog.md b/CHANGELOG.md similarity index 100% rename from docs/src/changelog.md rename to CHANGELOG.md diff --git a/CITATION.cff b/CITATION.cff index 8592b6a9a..62c16459b 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -12,7 +12,7 @@ authors: orcid: "https://orcid.org/0000-0002-0858-291X" title: "MPSKit" -version: 0.13.11 +version: 0.13.13 doi: 10.5281/zenodo.10654900 -date-released: 2026-05-04 +date-released: 2026-06-09 url: "https://github.com/QuantumKitHub/MPSKit.jl" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..0db85c7b6 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,90 @@ +# Contributing to MPSKit.jl + +Thanks for taking the time to contribute! +This document is a short, practical guide to reporting issues, asking questions, and submitting changes. + +## Asking questions and reporting bugs + +Use [GitHub issues](https://github.com/QuantumKitHub/MPSKit.jl/issues) for both. +There are two templates to help you: + +- **Bug report** — for something that doesn't work as expected. +- **Question** — for anything else, from "how do I model X" to "is Y possible". + +A good bug report is one we can act on immediately, and it needs two things: + +1. A minimal working example (MWE): the smallest snippet of code that reproduces the problem. + Strip away everything not needed to trigger the bug — unrelated setup, unused imports, alternative approaches you also tried. +2. Version information for MPSKit, TensorKit, and Julia, obtained with: + + ```julia-repl + julia> using Pkg + julia> Pkg.status(["MPSKit", "TensorKit"]) + ``` + + ```julia-repl + julia> versioninfo() + ``` + +Please also include the full error message and stacktrace, if there is one. + +## Contributing code + +### Development setup + +1. Fork and clone the repository. +2. From the Julia REPL, develop the package against your local checkout: + + ```julia-repl + pkg> dev /path/to/your/clone/MPSKit.jl + ``` + + or, from a fresh environment: + + ```julia-repl + julia> using Pkg; Pkg.develop(path = "/path/to/your/clone/MPSKit.jl") + ``` + +### Running the tests + +The repository root is a Julia workspace (`Project.toml` lists `test`, `docs`, and `examples` as workspace projects), and `test/Project.toml` already points `MPSKit` back at the repo checkout. +From the repository root, run the full suite with: + +``` +julia --project=test test/runtests.jl +``` + +The test suite is organized by topic under `test/` (`algorithms/`, `states/`, `operators/`, `misc/`, `gpu/`), with shared setup code in `test/setup/`. +GPU tests only run when a functional CUDA/cuTENSOR install is detected, so most contributors will only ever exercise the CPU tests. +A `--fast` flag is available for a quicker, reduced run while iterating. + +### Building the documentation + +The docs use Documenter.jl with the DocumenterVitepress backend, so a full render needs Node.js in addition to Julia. + +For routine verification of code examples (fast, no Node required), run the doctests directly: + +``` +julia --project=docs -e 'using Documenter, MPSKit; doctest(MPSKit)' +``` + +For a full local site build (slower, needs `npm`): + +``` +julia --project=docs docs/make.jl +``` + +### Code formatting + +This repository is formatted with [Runic](https://github.com/fredrikekre/Runic.jl). +Formatting is checked automatically on pull requests, and there is a [pre-commit](https://pre-commit.com/) hook (`.pre-commit-config.yaml`) that runs Runic locally if you use pre-commit. +Please format any Julia files you touch before opening a PR. + +### Changelog + +If your change is user-facing (new feature, behavior change, bug fix, deprecation, or removal), add an entry under the `[Unreleased]` section of `CHANGELOG.md`, in the category that matches your change. + +### Opening a pull request + +Small, focused pull requests are easiest to review. +Please describe what the change does and why, link any related issues, and make sure the checklist in the PR template is filled in before requesting review. diff --git a/README.md b/README.md index 215b4145a..ce717e5ae 100644 --- a/README.md +++ b/README.md @@ -118,3 +118,19 @@ scatter(g_values, M, xlabel="g", ylabel="M", label="D=$D", title="Magnetization" ``` ![Magnetization](docs/src/assets/README_ising_infinite.png) + +## Citing + +If you use MPSKit.jl in your research, please cite it. +See [`CITATION.cff`](CITATION.cff) for the up-to-date citation metadata, or use the BibTeX entry below. + +```bibtex +@software{mpskitjl, + author = {Devos, Lukas and Van Damme, Maarten and Haegeman, Jutho}, + title = {{MPSKit.jl}}, + version = {v0.13.13}, + doi = {10.5281/zenodo.10654900}, + url = {https://github.com/QuantumKitHub/MPSKit.jl}, + year = {2026} +} +``` diff --git a/docs/.gitignore b/docs/.gitignore index 0587d7400..c5cc3ab56 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -1,4 +1,5 @@ build/ node_modules/ package-lock.json -Manifest.toml \ No newline at end of file +Manifest.toml +src/changelog.md \ No newline at end of file diff --git a/docs/make.jl b/docs/make.jl index 613e8e0bf..aff1bdb38 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -38,6 +38,9 @@ links = InterLinks( # include MPSKit in all doctests DocMeta.setdocmeta!(MPSKit, :DocTestSetup, :(using MPSKit, TensorKit); recursive = true) +# root CHANGELOG.md is canonical (visible on GitHub); copy it in for rendering +cp(joinpath(@__DIR__, "..", "CHANGELOG.md"), joinpath(@__DIR__, "src", "changelog.md"); force = true) + makedocs(; sitename = "MPSKit.jl", format = DocumenterVitepress.MarkdownVitepress(; From b08368e982d0b4b98347bbfabfebb4c1b0b8f257 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Sat, 4 Jul 2026 12:31:54 -0400 Subject: [PATCH 23/76] docs(w1): curate examples gallery index Replace the bare auto-generated title list with a curated gallery: difficulty ordering within each grouping, 1-2 sentence teasers stating the physics question and MPSKit features showcased, and thumbnail figures from the existing example outputs. Co-Authored-By: Claude Fable 5 --- docs/src/examples/index.md | 86 ++++++++++++++++++++++++++++++++++---- 1 file changed, 78 insertions(+), 8 deletions(-) diff --git a/docs/src/examples/index.md b/docs/src/examples/index.md index d56cc7397..bd9fd952d 100644 --- a/docs/src/examples/index.md +++ b/docs/src/examples/index.md @@ -1,15 +1,85 @@ # Examples +This gallery collects the full worked examples that ship with MPSKit.jl. +Each one is a complete, runnable script (also available as a Jupyter notebook, linked from the example page itself) that goes well beyond the short snippets in the how-to guides. + +Within each physics grouping below, the examples are listed roughly in order of increasing difficulty: start at the top if you are new to MPSKit, and work down as you get comfortable with symmetries, infinite systems, and the less common algorithms. + ## Quantum (1+1)d -```@contents -Pages = map(file -> joinpath("quantum1d", file, "index.md"), readdir("quantum1d")) -Depth = 1 -``` +### [The Ising CFT spectrum](quantum1d/1.ising-cft/index.md) + +![](quantum1d/1.ising-cft/figure-2.png) + +Extracts the finite-size conformal spectrum of the critical transverse-field Ising chain, first by brute-force `exact_diagonalization` on a small periodic chain, then by extending to larger sizes with finite `DMRG` and the `QuasiparticleAnsatz`, using a translation MPO to assign a momentum label to each state. +No symmetries are used, which makes this a good entry point into the finite-MPS workflow. +**Level: introductory.** + +### [DQPT in the Ising model](quantum1d/3.ising-dqpt/index.md) + +![](quantum1d/3.ising-dqpt/infinite_timeev.png) + +Quenches the transverse-field Ising chain across its critical point and tracks the Loschmidt echo in search of non-analyticities (dynamical quantum phase transitions), on both a finite chain (`TDVP2`/`TDVP`) and directly in the thermodynamic limit (`changebonds` with `OptimalExpand`, then `TDVP`). +A compact introduction to real-time evolution and environment reuse, still without symmetries. +**Level: introductory/intermediate.** + +### [The Haldane gap](quantum1d/2.haldane/index.md) + +![](quantum1d/2.haldane/figure-3.png) + +Computes the Haldane gap of the spin-1 Heisenberg antiferromagnet in two complementary ways: finite-size `DMRG` with the `QuasiparticleAnsatz`, extrapolated over system size, and a direct infinite-chain `VUMPS` calculation with a momentum-resolved excitation scan. +Introduces `SU2Irrep`/`SU2Space` symmetric tensors for both `FiniteMPS` and `InfiniteMPS`. +**Level: intermediate.** + +### [The XXZ model](quantum1d/4.xxz-heisenberg/index.md) + +![](quantum1d/4.xxz-heisenberg/figure-2.png) + +Walks through a ground-state search that first goes wrong: single-site `VUMPS` and `GradientGrassmann` stall on the spin-1/2 Heisenberg antiferromagnet, and `transferplot`/`entanglementplot` reveal a near-non-injective state with several almost-degenerate transfer-matrix eigenvalues. +The fix is a two-site unit cell together with the `SU2Irrep`-symmetric Hamiltonian, after which `IDMRG2` and `VUMPS` converge cleanly. +A useful, diagnostic-driven example for recognizing and debugging convergence failures. +**Level: intermediate.** + +### [Spin 1 Heisenberg model](quantum1d/5.haldane-spt/index.md) + +![](quantum1d/5.haldane-spt/figure-3.png) + +Distinguishes the two symmetry-protected topological phases of the SU(2)-symmetric spin-1 Heisenberg chain by restricting the virtual `SU2Space` to integer or half-integer charges, then compares the two resulting ground states through their energy, transfer-matrix spectrum (`transferplot`), entanglement spectrum (`entanglementplot`), and entanglement entropy (`entropy`). +Builds directly on the symmetry machinery introduced in the Haldane gap example. + +**Level: intermediate/advanced.** + +### [Hubbard chain at half filling](quantum1d/6.hubbard/index.md) + +![](quantum1d/6.hubbard/figure-2.png) + +Studies the 1D Hubbard model at half filling with fermionic `InfiniteMPS`, first benchmarking a plain `VUMPS`/`GradientGrassmann` ground-state search against the exact Bethe-ansatz integral for the energy, then imposing the full particle-number and spin symmetry (`U1Irrep`, `SU2Irrep`, with `MPSKit.add_physical_charge` to pin the filling) and constructing the spinon/holon excitation spectrum with the `QuasiparticleAnsatz`. +Combines fermionic symmetry sectors with a more elaborate ground-state recipe (staged bond-dimension growth via `changebonds`/`OptimalExpand`, `SvdCut`, and mixed `VUMPS`/`GradientGrassmann` refinement). +**Level: advanced.** + +### [Finite temperature XY model](quantum1d/7.xy-finiteT/index.md) + +![](quantum1d/7.xy-finiteT/figure-1.png) + +Simulates the finite-temperature XY chain by purifying the infinite-temperature density matrix and evolving it in imaginary time, then compares the resulting partition function and free energy against exact diagonalization and, via BenchmarkFreeFermions.jl, the exact free-fermion solution. +A technical, comparison-heavy example built around `MPSKit.infinite_temperature_density_matrix` and imaginary-time evolution rather than ground-state search. +**Level: advanced.** + +### [1D Bose-Hubbard model](quantum1d/8.bose-hubbard/index.md) + +![](quantum1d/8.bose-hubbard/figure-6.png) + +The most comprehensive example in the gallery: works directly in the thermodynamic limit with a truncated bosonic local Hilbert space, extracts correlation functions and the correlation length as a function of bond dimension, computes the momentum distribution, and maps out the Mott-insulator/superfluid structure of the phase diagram from the ground-state response to an applied phase twist. +Touches most of the ground-state toolbox (`InfiniteMPS`, `find_groundstate`, bond-dimension control, `expectation_value`-based observables) in a single, longer study. + +**Level: advanced.** ## Classical (2+0)d -```@contents -Pages = map(file -> joinpath("classic2d", file, "index.md"), readdir("classic2d")) -Depth = 1 -``` \ No newline at end of file +### [The Hard Hexagon model](classic2d/1.hard-hexagon/index.md) + +![](classic2d/1.hard-hexagon/figure-1.png) + +Extracts the central charge of the hard hexagon lattice gas by finding the leading boundary MPS of its transfer matrix with `VUMPS` (using Fibonacci-anyon virtual spaces), then fitting the CFT-predicted scaling relation between entanglement entropy and correlation length as the bond dimension is increased. +The only classical statistical-mechanics example in the gallery, and the only one demonstrating non-abelian anyonic symmetries (`FibonacciAnyon`) in MPSKit. +**Level: advanced.** From 7809306b9928dfb6428f4d5358a969f23a9c03ed Mon Sep 17 00:00:00 2001 From: lkdvos Date: Sat, 4 Jul 2026 12:36:26 -0400 Subject: [PATCH 24/76] docs(w0): remove stale drafting-notes blocks from how-to pages The trailing CLOSING NOTES maintainer-comment blocks claimed the pages' outputs were unverified and listed make.jl changes that have since landed. All @example blocks in the three pages were re-verified to execute end-to-end against the current package (32/32 pass, no code changes needed). Co-Authored-By: Claude Fable 5 --- docs/src/howto/entanglement.md | 50 -------------------------------- docs/src/howto/hamiltonians.md | 53 ---------------------------------- docs/src/howto/observables.md | 39 ------------------------- 3 files changed, 142 deletions(-) diff --git a/docs/src/howto/entanglement.md b/docs/src/howto/entanglement.md index ecda798c7..2cbbe2408 100644 --- a/docs/src/howto/entanglement.md +++ b/docs/src/howto/entanglement.md @@ -136,53 +136,3 @@ entanglementplot(ψ; site = L ÷ 2) !!! note `entanglementplot` is a plotting *recipe*: it only becomes available once `Plots` (or a compatible plotting package) is loaded. This block is not executed on this page to keep the docs build free of the Plots.jl dependency. - ---- - - diff --git a/docs/src/howto/hamiltonians.md b/docs/src/howto/hamiltonians.md index 66cb36663..e865eb50b 100644 --- a/docs/src/howto/hamiltonians.md +++ b/docs/src/howto/hamiltonians.md @@ -102,56 +102,3 @@ H_window = WindowMPOHamiltonian(H_inf, 1:6) ``` The interval `1:6` selects which unit cells of `H_inf` become the mutable finite window; everything outside it is treated as the fixed infinite environment. - ---- - - diff --git a/docs/src/howto/observables.md b/docs/src/howto/observables.md index 3d6dde478..3233c44f3 100644 --- a/docs/src/howto/observables.md +++ b/docs/src/howto/observables.md @@ -162,42 +162,3 @@ variance(ψ_gs, H) ```julia variance(ψ_gs, H, envs) ``` - ---- - - From 560926f2ec8e825f0edf7fbf424f8a0de0983747 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Sat, 4 Jul 2026 12:42:44 -0400 Subject: [PATCH 25/76] docs(w1): tutorials/installation.md First page of the tutorial track: prerequisites, project environment, the full recommended package set with one-line roles, a verified smoke-test @example (TFIM Hamiltonian + FiniteMPS), and troubleshooting notes. Registered a Tutorials section in the nav. Co-Authored-By: Claude Fable 5 --- docs/make.jl | 3 ++ docs/src/tutorials/installation.md | 64 ++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 docs/src/tutorials/installation.md diff --git a/docs/make.jl b/docs/make.jl index aff1bdb38..18d354fea 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -50,6 +50,9 @@ makedocs(; ), pages = [ "Home" => "index.md", + "Tutorials" => [ + "tutorials/installation.md", + ], "Manual" => [ "man/intro.md", "man/states.md", diff --git a/docs/src/tutorials/installation.md b/docs/src/tutorials/installation.md new file mode 100644 index 000000000..b5904806e --- /dev/null +++ b/docs/src/tutorials/installation.md @@ -0,0 +1,64 @@ +# Installation + +This page walks you through setting up a Julia environment for working with MPSKit.jl, and ends with a small snippet you can run to check that everything works. + +## Prerequisites + +You need a working installation of Julia, version 1.10 or later. +If you don't have Julia yet, install it via [juliaup](https://github.com/JuliaLang/juliaup) or download it directly from [julialang.org](https://julialang.org/downloads/). +This tutorial assumes you are comfortable starting the Julia REPL and typing commands into it, but does not assume any prior experience with Julia's package manager. + +## Set up a project environment + +Before installing any packages, create a dedicated environment for this tutorial. +Working in a fresh, named environment (rather than the global default environment) keeps the exact package versions you use here reproducible, and avoids clashes with other projects on your machine. + +Start Julia, enter the package manager by pressing `]`, and activate a new environment: + +``` +pkg> activate mpskit-tutorial +``` + +Julia will create the environment the first time you add a package to it. + +## Install the packages + +With the environment activated, install MPSKit.jl and the packages used throughout this documentation: + +``` +pkg> add MPSKit TensorKit TensorOperations MPSKitModels TensorKitTensors Plots +``` + +- `MPSKit` provides the matrix product state and operator types, together with the ground-state, time-evolution, and bond-dimension algorithms. +- `TensorKit` supplies the tensor backend (`TensorMap`s and vector spaces) that MPSKit is built on; installing it alongside MPSKit also gives access to truncation-scheme constructors such as `truncrank`, which TensorKit re-exports from MatrixAlgebraKit. +- `TensorOperations` provides the `@tensor` macro used to contract tensors by hand. +- `MPSKitModels` collects pre-defined Hamiltonians (such as the transverse-field Ising model) and lattices for common physical models. +- `TensorKitTensors` provides ready-made local operators, such as the Pauli operators. +- `Plots` is used to visualize results in several of the how-to guides and examples; it is optional if you only intend to run computations without plotting. + +MPSKit.jl is registered in Julia's General registry, so `pkg> add` fetches it directly; you do not need to add any custom registries. + +!!! note "First `using` is slow" + The first time you load these packages with `using`, Julia precompiles them, which can take a minute or two. + Subsequent loads in the same environment are much faster. + +## Verify your setup + +Once the packages have finished installing, exit the package manager (backspace) and run the following in the same environment to check that MPSKit, TensorKit, and MPSKitModels work together. + +```@example verify-install +using MPSKit, TensorKit, MPSKitModels + +H = transverse_field_ising(FiniteChain(8); J = 1.0, g = 0.5) +ψ = FiniteMPS(8, ℂ^2, ℂ^8) +``` + +If this runs without error and prints a `FiniteMPS`, your environment is ready. + + +From here, continue with the first ground state tutorial, which uses this same Hamiltonian and initial state to find the ground state of the transverse-field Ising model with DMRG. + +## Troubleshooting + +- **Long precompilation on first use:** this is expected the first time you `using` a package (or after updating one), especially for a large dependency stack; it is not a sign that anything is wrong. +- **Version resolver conflicts:** if `pkg> add` reports that it cannot find a compatible set of versions, try creating a fresh environment (as above) rather than adding these packages to an existing environment that already has other constraints. From a81f1eba9126ab0a55ae7d8c6642633a84d541f2 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Sat, 4 Jul 2026 12:43:42 -0400 Subject: [PATCH 26/76] docs(w0): complete install instructions and add packages-used preambles index.md now lists the full environment the documentation actually uses (MPSKit, TensorKit, TensorOperations, MPSKitModels, TensorKitTensors, Plots) with one-line roles, including the verified note that truncrank reaches users via TensorKit's re-export from MatrixAlgebraKit. howto/states.md and howto/bond_dimension.md gain a packages-used preamble linking the installation tutorial. Co-Authored-By: Claude Fable 5 --- docs/src/howto/bond_dimension.md | 3 +++ docs/src/howto/states.md | 3 +++ docs/src/index.md | 22 +++++++++++++++++----- docs/src/tutorials/installation.md | 2 +- 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/docs/src/howto/bond_dimension.md b/docs/src/howto/bond_dimension.md index 5b1d25ea2..520487dca 100644 --- a/docs/src/howto/bond_dimension.md +++ b/docs/src/howto/bond_dimension.md @@ -1,5 +1,8 @@ # [Controlling bond dimension](@id howto_bond_dimension) +The examples on this page use MPSKit.jl, TensorKit.jl, and TensorKitTensors.jl. +See [Installation](@ref tutorial_installation) for how to add these packages to your environment. + Bond dimension is the key knob in every MPS calculation: too small and the ansatz cannot represent the state, too large and computation slows to a crawl. This page gives concrete recipes for inspecting, growing, and shrinking bond dimension in MPSKit.jl. All examples share a single namespace: diff --git a/docs/src/howto/states.md b/docs/src/howto/states.md index 9a8ec76bd..d4a65d3cd 100644 --- a/docs/src/howto/states.md +++ b/docs/src/howto/states.md @@ -1,5 +1,8 @@ # [Constructing states](@id howto_states) +The examples on this page use MPSKit.jl and TensorKit.jl. +See [Installation](@ref tutorial_installation) for how to add these packages to your environment. + This page collects recipes for building [`FiniteMPS`](@ref), [`InfiniteMPS`](@ref), [`WindowMPS`](@ref), and [`MultilineMPS`](@ref) objects. All constructors live in the `MPSKit` namespace; the examples below assume diff --git a/docs/src/index.md b/docs/src/index.md index 42e52902f..7ed7f1229 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -48,11 +48,23 @@ features: ## Installation -MPSKit.jl is a part of the general registry, and can be installed via the package manager -as: -``` -pkg> add MPSKit -``` +MPSKit.jl is a part of the general registry. +Together with the packages used throughout this documentation, it can be installed via the +package manager as: +``` +pkg> add MPSKit TensorKit TensorOperations MPSKitModels TensorKitTensors Plots +``` +- `MPSKit` provides the matrix product state and operator types, together with the + ground-state, time-evolution, and bond-dimension algorithms. +- `TensorKit` supplies the tensor backend (`TensorMap`s and vector spaces) that MPSKit is + built on; installing it alongside MPSKit also gives access to truncation-scheme + constructors such as `truncrank`, which TensorKit re-exports from MatrixAlgebraKit. +- `TensorOperations` provides the `@tensor` macro used below to contract tensors by hand. +- `MPSKitModels` collects pre-defined Hamiltonians and local operators for common physical + models. +- `TensorKitTensors` provides ready-made local operators, such as the Pauli operators used + in the examples below. +- `Plots` is used to visualize results in several of the how-to guides and examples. ## Usage diff --git a/docs/src/tutorials/installation.md b/docs/src/tutorials/installation.md index b5904806e..840a10334 100644 --- a/docs/src/tutorials/installation.md +++ b/docs/src/tutorials/installation.md @@ -1,4 +1,4 @@ -# Installation +# [Installation](@id tutorial_installation) This page walks you through setting up a Julia environment for working with MPSKit.jl, and ends with a small snippet you can run to check that everything works. From 1eb5c272918bcbe137c126646fb0532257e3b172 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Sat, 4 Jul 2026 12:53:30 -0400 Subject: [PATCH 27/76] docs(w0): mechanical defect fixes across manual pages - remove the empty man/lattices.md stub from nav and delete it; the forward reference in man/operators.md now points to MPSKitModels docs - fix off-by-one comment (3-site chain) in man/operators.md - repair garbled finite-excitations LaTeX in man/algorithms.md, formula verified against the FiniteExcited implementation - verbosity=false -> verbosity=0 in the leading-boundary snippet - fix empty MKL.jl link in man/parallelism.md - make hidden @setup imports visible in man/operators.md (13/13 blocks re-verified to execute) - add packages-used preambles to the remaining three how-to pages Co-Authored-By: Claude Fable 5 --- docs/make.jl | 1 - docs/src/howto/entanglement.md | 3 +++ docs/src/howto/hamiltonians.md | 3 +++ docs/src/howto/observables.md | 3 +++ docs/src/man/algorithms.md | 16 +++++++++++++--- docs/src/man/lattices.md | 4 ---- docs/src/man/operators.md | 9 ++++----- docs/src/man/parallelism.md | 2 +- 8 files changed, 27 insertions(+), 14 deletions(-) delete mode 100644 docs/src/man/lattices.md diff --git a/docs/make.jl b/docs/make.jl index 18d354fea..03eea5242 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -60,7 +60,6 @@ makedocs(; "man/algorithms.md", # "man/environments.md", "man/parallelism.md", - "man/lattices.md", ], "How-to" => [ "howto/states.md", diff --git a/docs/src/howto/entanglement.md b/docs/src/howto/entanglement.md index 2cbbe2408..88e446212 100644 --- a/docs/src/howto/entanglement.md +++ b/docs/src/howto/entanglement.md @@ -1,5 +1,8 @@ # [Entanglement entropy and spectrum](@id howto_entanglement) +The examples on this page use MPSKit.jl, TensorKit.jl, and TensorKitTensors.jl. +See [Installation](@ref tutorial_installation) for how to add these packages to your environment. + This page collects recipes for extracting the entanglement entropy and the entanglement spectrum from the gauge (bond) tensors of an MPS. For general expectation values and correlators see [Computing observables](@ref howto_observables); for building the state objects used below see [Constructing states](@ref howto_states). The reference page for these and related functions is [Observables and analysis](@ref lib_observables). diff --git a/docs/src/howto/hamiltonians.md b/docs/src/howto/hamiltonians.md index e865eb50b..9b8206684 100644 --- a/docs/src/howto/hamiltonians.md +++ b/docs/src/howto/hamiltonians.md @@ -1,5 +1,8 @@ # [Building Hamiltonians](@id howto_hamiltonians) +The examples on this page use MPSKit.jl, TensorKit.jl, and TensorKitTensors.jl. +See [Installation](@ref tutorial_installation) for how to add these packages to your environment. + This page collects recipes for constructing MPO Hamiltonians from local operators, for both finite and infinite (translation-invariant) lattices. It also covers converting an infinite Hamiltonian to finite open or periodic boundary conditions, and carving a finite window out of an infinite Hamiltonian. For building the matching state objects see [Constructing states](@ref howto_states); for evaluating a Hamiltonian's energy on a state see [Computing observables](@ref howto_observables). diff --git a/docs/src/howto/observables.md b/docs/src/howto/observables.md index 3233c44f3..a69288767 100644 --- a/docs/src/howto/observables.md +++ b/docs/src/howto/observables.md @@ -1,5 +1,8 @@ # [Computing observables](@id howto_observables) +The examples on this page use MPSKit.jl, TensorKit.jl, and TensorKitTensors.jl. +See [Installation](@ref tutorial_installation) for how to add these packages to your environment. + This page collects recipes for extracting physical quantities from an MPS: local and multi-site expectation values, the energy of a Hamiltonian, two-point correlators, and the energy variance as a convergence diagnostic. All examples share a single namespace and build on state and operator objects you would have in hand after a ground-state calculation. diff --git a/docs/src/man/algorithms.md b/docs/src/man/algorithms.md index 3cf71d52a..aa84d909e 100644 --- a/docs/src/man/algorithms.md +++ b/docs/src/man/algorithms.md @@ -206,8 +206,18 @@ QuasiparticleAnsatz ### Finite excitations -For finite systems we can also do something else - find the ground state of the Hamiltonian + -``\\text{weight} \sum_i | \\psi_i ⟩ ⟨ \\psi_i ``. This is also supported by calling +For finite systems we can also do something else - find the state that minimizes the energy of a +modified Hamiltonian + +```math +H_n = H + \text{weight} \sum_{i < n} | \psi_i ⟩ ⟨ \psi_i | +``` + +which adds an energy penalty for overlapping with the ground state and all previously found +excited states ``\psi_i``, ``i < n``. +This pushes the optimization towards higher excited states while enforcing (approximate) +orthogonality with the ones already found. +This is also supported by calling ```@example excitations # Model parameters @@ -318,7 +328,7 @@ boundary MPS. Again this can be done with VUMPS: ```julia th = nonsym_ising_mpo() ts = InfiniteMPS([ℂ^2],[ℂ^20]); -(ts,envs,_) = leading_boundary(ts,th,VUMPS(maxiter=400,verbosity=false)); +(ts,envs,_) = leading_boundary(ts,th,VUMPS(maxiter=400,verbosity=0)); ``` If the mpo satisfies certain properties (positive and hermitian), it may also be possible to diff --git a/docs/src/man/lattices.md b/docs/src/man/lattices.md deleted file mode 100644 index 7ec0c4ad0..000000000 --- a/docs/src/man/lattices.md +++ /dev/null @@ -1,4 +0,0 @@ -# [Lattices](@id lattices) - -!!! warning - This section is still under construction. Coming soon! \ No newline at end of file diff --git a/docs/src/man/operators.md b/docs/src/man/operators.md index 649fbc193..690fea6f6 100644 --- a/docs/src/man/operators.md +++ b/docs/src/man/operators.md @@ -17,12 +17,10 @@ product of local tensors. MPO ``` -```@setup operators +```@example operators using TensorKit, MPSKit, MPSKitModels using TensorKitTensors.SpinOperators: σˣ, σᶻ -``` -```@example operators X = σˣ() Z = σᶻ() O_xzx = FiniteMPO(X ⊗ Z ⊗ X); @@ -115,7 +113,7 @@ H = -J \sum_{\langle i, j \rangle} X_i X_j - h \sum_j Z_j ```@example operators J = 1.0 h = 0.5 -chain = fill(ℂ^2, 3) # a finite chain of 4 sites, each with a 2-dimensional Hilbert space +chain = fill(ℂ^2, 3) # a finite chain of 3 sites, each with a 2-dimensional Hilbert space single_site_operators = [1 => -h * Z, 2 => -h * Z, 3 => -h * Z] two_site_operators = [(1, 2) => -J * X ⊗ X, (2, 3) => -J * X ⊗ X] H_ising = FiniteMPOHamiltonian(chain, single_site_operators..., two_site_operators...) @@ -168,7 +166,8 @@ H_ising_2d = FiniteMPOHamiltonian(square, local_operators) + ``` There are various utility functions available for constructing more advanced lattices, for -which the [lattices](@ref) section should be consulted. +which the [MPSKitModels.jl](https://quantumkithub.github.io/MPSKitModels.jl/dev/) +documentation should be consulted. ## InfiniteMPOHamiltonian diff --git a/docs/src/man/parallelism.md b/docs/src/man/parallelism.md index 683be061c..c7911ae7c 100644 --- a/docs/src/man/parallelism.md +++ b/docs/src/man/parallelism.md @@ -26,7 +26,7 @@ using `BLAS.set_num_threads(1)`, OpenBLAS will now utilize the julia threads to jobs. Thus, for OpenBLAS, very often setting the number of BLAS threads to 1 is the best option, which will then maximally utilize the julia threading infrastructure of MPSKit. -In the case of [MKL.jl](), which often outperforms OpenBLAS, the situation is a bit +In the case of [MKL.jl](https://github.com/JuliaLinearAlgebra/MKL.jl), which often outperforms OpenBLAS, the situation is a bit different. Here, the number of BLAS threads corresponds to the number of threads that are spawned by **each** julia thread. Thus, if you have 4 julia threads and 4 BLAS threads, then each julia thread will spawn 4 BLAS threads, for a total of 16 BLAS threads. As such, it From 094600c6b47c8caf3ffe581e43bc734a98d05187 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Sat, 4 Jul 2026 12:55:18 -0400 Subject: [PATCH 28/76] =?UTF-8?q?docs(w1):=20tutorials/first=5Fgroundstate?= =?UTF-8?q?.md=20=E2=80=94=20the=20flagship=20tutorial?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Complete TFIM walkthrough: Hamiltonian, FiniteMPS, DMRG via find_groundstate, energy/magnetization/variance, and the magnetization curve across the phase transition (mirroring the README quickstart). All blocks verified to execute (E = -16.146, variance ~7e-8, M sweeps 1 -> 0 across g = 1). Physics claims carry REVIEW flags for the maintainer. Registered in nav; installation tutorial now links here. Co-Authored-By: Claude Fable 5 --- docs/make.jl | 1 + docs/src/tutorials/first_groundstate.md | 159 ++++++++++++++++++++++++ docs/src/tutorials/installation.md | 3 +- 3 files changed, 161 insertions(+), 2 deletions(-) create mode 100644 docs/src/tutorials/first_groundstate.md diff --git a/docs/make.jl b/docs/make.jl index 03eea5242..bc92643df 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -52,6 +52,7 @@ makedocs(; "Home" => "index.md", "Tutorials" => [ "tutorials/installation.md", + "tutorials/first_groundstate.md", ], "Manual" => [ "man/intro.md", diff --git a/docs/src/tutorials/first_groundstate.md b/docs/src/tutorials/first_groundstate.md new file mode 100644 index 000000000..46e08be3d --- /dev/null +++ b/docs/src/tutorials/first_groundstate.md @@ -0,0 +1,159 @@ +# [Your first ground state](@id tutorial_first_groundstate) + +This tutorial walks you through a complete MPSKit.jl calculation from start to finish: we build the transverse-field Ising model, find its ground state with DMRG, measure a few physical quantities, and finish with a plot of the magnetization across the model's phase transition. +It assumes only that you are comfortable with basic quantum mechanics and that you have finished [Installation](@ref tutorial_installation), so the packages used below are already available in your environment. + +The transverse-field Ising model (TFIM) is the "hello world" of quantum many-body physics: it is the simplest model that still shows a genuine quantum phase transition, so it is the natural place to learn the tools. +On a chain of ``L`` spin-1/2 sites it is + +```math +H = -J\left(\sum_{\langle i,j\rangle} \sigma^z_i\,\sigma^z_j + g\sum_i \sigma^x_i\right), +``` + +where the first sum runs over neighbouring pairs. +The coupling ``J`` sets the overall energy scale, and the dimensionless field ``g`` tunes the competition between the ferromagnetic ``\sigma^z\sigma^z`` interaction and the transverse ``\sigma^x`` field. + +The ground state of ``H`` lives in a Hilbert space of dimension ``2^L``, which is far too large to store as a plain vector for any interesting ``L``. +A *matrix product state* (MPS) sidesteps this by storing the state as a chain of small tensors, one per site, whose sizes we control directly; this is what makes the calculation below tractable. +The details of that compression are the subject of the concept pages — here we simply use it. + + + +## Loading the packages + +Every code block on this page shares one Julia session, so we only need to load packages once. +We take the model and lattice from MPSKitModels, the local spin operators from TensorKitTensors, and `Plots` for the final figure. + +```@example first-groundstate +using MPSKit, MPSKitModels, TensorKit +using TensorKitTensors.SpinOperators: σˣ, σᶻ +using Plots +``` + +## 1. Build the Hamiltonian + +We work with a chain of `L = 16` sites and fix the field to `g = 0.5` for now. +`transverse_field_ising` assembles the Hamiltonian above; passing `FiniteChain(L)` asks for a finite open chain of `L` sites. + +```@example first-groundstate +L = 16 +H = transverse_field_ising(FiniteChain(L); g = 0.5) +``` + +The returned object is an `MPOHamiltonian`: the Hamiltonian written in matrix-product-operator form, i.e. as a chain of small tensors just like the state it acts on. +You do not need to know its internals to use it — MPSKit's algorithms consume it directly. +For other ways to build Hamiltonians see [Building Hamiltonians](@ref howto_hamiltonians). + + + +## 2. Build the initial state + +DMRG is an optimization: it needs a starting state to improve. +We create a random `FiniteMPS` with the right structure. + +```@example first-groundstate +D = 4 +ψ₀ = FiniteMPS(L, ℂ^2, ℂ^D) +``` + +The two space arguments describe the two kinds of index every MPS tensor carries: + +- `ℂ^2` is the **physical space** — the local Hilbert space of a single spin-1/2 site, which has dimension 2. +- `ℂ^D` is the **virtual (bond) space** — the internal index linking neighbouring tensors, whose dimension `D` is the *bond dimension*. + +The bond dimension `D` is the accuracy knob of the whole method: a larger `D` lets the MPS capture more entanglement and represent the true ground state more faithfully, at the cost of more computation. +`D = 4` is deliberately small so this tutorial runs quickly; [Controlling bond dimension](@ref howto_bond_dimension) covers how to choose and grow it. + +!!! warning "Pass spaces, not integers" + The physical and virtual arguments must be *vector spaces* (`ℂ^2`, `ℂ^D`, or equivalently `ComplexSpace(2)`), never bare integers. + Writing `FiniteMPS(16, 2, 4)` throws a `MethodError` — this is the single most common beginner mistake. + +## 3. Find the ground state + +Now we run the calculation. +`find_groundstate` takes the starting state, the Hamiltonian, and an algorithm; we pass [`DMRG`](@ref) explicitly so the algorithm is visible. + +```@example first-groundstate +ψ, envs, ϵ = find_groundstate(ψ₀, H, DMRG()) +``` + +DMRG (the density-matrix renormalization group) sweeps back and forth along the chain, locally optimizing each tensor while holding the others fixed, and repeats until the state stops changing. +The lines printed above are the per-iteration convergence log (shown at the default `verbosity`); each reports how much the state improved on that sweep. + + + +!!! note "The algorithm is optional" + Calling `find_groundstate(ψ₀, H)` with no algorithm argument selects DMRG automatically for a finite input, so the explicit `DMRG()` above is only for clarity. + `DMRG` accepts keywords such as `tol` (default `1e-10`), `maxiter` (default `200`), and `verbosity` (default `3`); we use `verbosity = 0` later to silence the log inside a loop. + +`find_groundstate` returns a triple: + +- `ψ` — the optimized ground-state MPS (a *new* state; `ψ₀` is left untouched, so we can reuse it below). A mutating variant `find_groundstate!` also exists. +- `envs` — the *environments*, cached partial contractions that later measurements can reuse to save work. +- `ϵ` — a convergence-error measure (the Galerkin residual). It quantifies how well the sweeps converged; note that it is **not** the error in the energy. + +## 4. Measure observables + +With a ground state in hand we can extract physical quantities. +The energy is the expectation value of the Hamiltonian itself — pass `H` directly, with no site index: + +```@example first-groundstate +E = expectation_value(ψ, H) +``` + +For a Hermitian `H` and a normalized state this is real up to floating-point noise. + +The order parameter of the TFIM is the local magnetization ``\langle\sigma^z_i\rangle``. +We measure it at every site by pairing each site index with the single-site operator `σᶻ()`: + +```@example first-groundstate +[expectation_value(ψ, i => σᶻ()) for i in 1:L] +``` + +Finally, a good "how converged am I really?" check is the energy variance ``\langle H^2\rangle - \langle H\rangle^2``, which vanishes exactly when `ψ` is a true eigenstate: + +```@example first-groundstate +variance(ψ, H) +``` + +A small variance indicates the state is close to an eigenstate of `H`. +More recipes for observables live in [Computing observables](@ref howto_observables). + + + +## 5. Magnetization across the transition + +The payoff: we sweep the field `g` from 0 to 2 and, for each value, find the ground state and record its average magnetization. +This traces out the phase transition. + +For this sweep we place the chain on a ring rather than an open segment: `transverse_field_ising()` with no lattice argument builds the Hamiltonian for an infinite chain, and [`periodic_boundary_conditions`](@ref) wraps it onto a finite ring of `L` sites. + + + +```@example first-groundstate +g_values = 0:0.1:2 +M = map(g_values) do g + Hg = periodic_boundary_conditions(transverse_field_ising(; g = g), L) + ψg, = find_groundstate(ψ₀, Hg; verbosity = 0) + return abs(sum(expectation_value(ψg, i => σᶻ()) for i in 1:L)) / L +end +scatter(g_values, M; xlabel = "g", ylabel = "M", label = "D = $D", title = "TFIM magnetization") +``` + +Here we take the **absolute value** of the mean magnetization. +A finite chain does not spontaneously break its symmetry, so the raw ``\sum_i\langle\sigma^z_i\rangle`` can land on either sign (or average toward zero); taking `abs` collapses the two symmetry-related ground states onto a single, well-defined order-parameter curve. + + + +The plot should show the magnetization large on the ordered side (small `g`) and dropping toward zero on the disordered side (large `g`), with the crossover near `g = 1`. + + + +## Where to go next + +You have run a full MPSKit workflow: build a model, optimize an MPS ground state, measure observables, and scan a parameter. +A natural next step is to perform the same calculation directly in the thermodynamic limit, working with an `InfiniteMPS` instead of a finite chain, which removes the finite-size effects seen above and lets you locate the critical point more cleanly. + + + +To go deeper on the individual steps, see [Constructing states](@ref howto_states), [Building Hamiltonians](@ref howto_hamiltonians), [Computing observables](@ref howto_observables), [Controlling bond dimension](@ref howto_bond_dimension), and [Entanglement entropy and spectrum](@ref howto_entanglement); the algorithm reference is [Ground-state algorithms](@ref lib_groundstate). diff --git a/docs/src/tutorials/installation.md b/docs/src/tutorials/installation.md index 840a10334..78b67dc4b 100644 --- a/docs/src/tutorials/installation.md +++ b/docs/src/tutorials/installation.md @@ -55,8 +55,7 @@ H = transverse_field_ising(FiniteChain(8); J = 1.0, g = 0.5) If this runs without error and prints a `FiniteMPS`, your environment is ready. - -From here, continue with the first ground state tutorial, which uses this same Hamiltonian and initial state to find the ground state of the transverse-field Ising model with DMRG. +From here, continue with [Your first ground state](@ref tutorial_first_groundstate), which uses this same Hamiltonian and initial state to find the ground state of the transverse-field Ising model with DMRG. ## Troubleshooting From 0c41bf3896c45a0bfad62740d1e3563118a297e4 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Sat, 4 Jul 2026 13:04:31 -0400 Subject: [PATCH 29/76] docs(w1): landing page rewrite + tutorials/thermodynamic_limit.md Landing page: 30-second verified hero example replaces the gauge-tensor walkthrough; 'Where next' router, ecosystem and community sections; hero button routes to the tutorial track; stale TOC removed. Thermodynamic-limit tutorial: the near-identical-code payoff page (InfiniteMPS + VUMPS, correlation length as the infinite-only observable, magnetization sweep). All 9 blocks verified: E/site = -1.0635 at g = 0.5, correlation length 0.58 -> 7.45 approaching g = 1, sharp finite-D crossover just past g = 1. Physics claims carry REVIEW flags. Registered in nav; flagship now links here. Co-Authored-By: Claude Fable 5 --- docs/make.jl | 1 + docs/src/index.md | 216 ++++------------------ docs/src/tutorials/first_groundstate.md | 4 +- docs/src/tutorials/thermodynamic_limit.md | 147 +++++++++++++++ 4 files changed, 185 insertions(+), 183 deletions(-) create mode 100644 docs/src/tutorials/thermodynamic_limit.md diff --git a/docs/make.jl b/docs/make.jl index bc92643df..f8a741973 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -53,6 +53,7 @@ makedocs(; "Tutorials" => [ "tutorials/installation.md", "tutorials/first_groundstate.md", + "tutorials/thermodynamic_limit.md", ], "Manual" => [ "man/intro.md", diff --git a/docs/src/index.md b/docs/src/index.md index 7ed7f1229..c54a17cbc 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -12,8 +12,8 @@ hero: alt: MPSKit.jl actions: - theme: brand - text: Manual - link: /man/intro + text: Get started + link: /tutorials/installation - theme: alt text: Examples link: /examples/ @@ -24,27 +24,22 @@ hero: features: - icon: 🔗 title: States - details: Construction and manipulation of finite and infinite Matrix Product States (MPS). + details: Construct and manipulate finite and infinite matrix product states (MPS). - icon: 📏 title: Observables - details: Calculation of observables and expectation values. + details: Measure expectation values, correlations, and other observables. - icon: 🎯 title: Optimization - details: Various optimization methods for obtaining MPS fixed points. + details: Ground states, time evolution, and excitations via DMRG, VUMPS, and more. - icon: ⚛️ title: Symmetries - details: Support for a wide variety of symmetries, including Abelian, non-Abelian, fermionic and anyonic symmetries. + details: Abelian, non-Abelian, fermionic, and anyonic symmetries out of the box. --- ``` -## Table of contents - -- [Prerequisites](@ref) -- [States](@ref um_states) -- [Operators](@ref um_operators) -- [Algorithms](@ref um_algorithms) -- [Parallelism in julia](@ref) -- [Lattices](@ref lattices) +MPSKit.jl is a Julia library for simulating one-dimensional quantum many-body systems with matrix product states and operators. +It provides both finite and infinite MPS, a range of ground-state, time-evolution, and excitation algorithms, and support for arbitrary symmetries through the [TensorKit.jl](https://github.com/Jutho/TensorKit.jl) tensor backend. +It is aimed at researchers and students who want to run tensor-network calculations without reimplementing the underlying machinery. ## Installation @@ -59,188 +54,49 @@ pkg> add MPSKit TensorKit TensorOperations MPSKitModels TensorKitTensors Plots - `TensorKit` supplies the tensor backend (`TensorMap`s and vector spaces) that MPSKit is built on; installing it alongside MPSKit also gives access to truncation-scheme constructors such as `truncrank`, which TensorKit re-exports from MatrixAlgebraKit. -- `TensorOperations` provides the `@tensor` macro used below to contract tensors by hand. +- `TensorOperations` provides the `@tensor` macro for contracting tensors by hand. - `MPSKitModels` collects pre-defined Hamiltonians and local operators for common physical models. -- `TensorKitTensors` provides ready-made local operators, such as the Pauli operators used - in the examples below. +- `TensorKitTensors` provides ready-made local operators, such as the Pauli operators used throughout the documentation. - `Plots` is used to visualize results in several of the how-to guides and examples. -## Usage - -To get started with MPSKit, we recommend also including -[TensorKit.jl](https://github.com/Jutho/TensorKit.jl) and -[MPSKitModels.jl](https://github.com/QuantumKitHub/MPSKitModels.jl). The former defines the -tensor backend which is used throughout MPSKit, while the latter includes some common -operators and models. - -```julia -using TensorOperations -using TensorKit -using MPSKit -using LinearAlgebra: norm -``` - -### Finite Matrix Product States - -```@setup finitemps -using LinearAlgebra -using TensorOperations -using TensorKit -using MPSKit -using TensorKitTensors.SpinOperators: σˣ, σᶻ -``` - -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. - -```@example finitemps -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 -``` - -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. - -```@example finitemps -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(right_virtualspace(mps, 3))) -``` -```@example finitemps -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(left_virtualspace(mps, 3))) -``` - -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. - -```@example finitemps -mps.C[3] = id(domain(mps.C[3])) -mps -``` +For a step-by-step walkthrough that sets up a dedicated environment and verifies the installation, see [Installation](@ref tutorial_installation). -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: +## A 30-second example -```@example finitemps -N1 = LinearAlgebra.norm(mps) -N2 = expectation_value(mps, 3 => id(physicalspace(mps, 3))) -println("‖mps‖ = $N1") -println(" = $N2") -``` +Finding the ground state of the transverse-field Ising chain takes a handful of lines. -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 ground state for the -transverse field Ising model: - -```@example finitemps -J = 1.0 -g = 0.5 -lattice = fill(ComplexSpace(2), 10) -X = σˣ() -Z = σᶻ() -H = FiniteMPOHamiltonian(lattice, (i, i+1) => -J * X ⊗ X for i in 1:length(lattice)-1) + - FiniteMPOHamiltonian(lattice, (i,) => - g * Z for i in 1:length(lattice)) -find_groundstate!(mps, H, DMRG(; maxiter=10)) -E0 = expectation_value(mps, H) -println(" = $(real(E0))") +```@example index +using MPSKit, MPSKitModels, TensorKit +H = transverse_field_ising(FiniteChain(16); g = 0.5) +ψ₀ = FiniteMPS(16, ℂ^2, ℂ^4) +ψ, envs, ϵ = find_groundstate(ψ₀, H, DMRG(; verbosity = 0)) +E = expectation_value(ψ, H) ``` -### Infinite Matrix Product States +For a guided version of this calculation that explains each step and measures more observables, see [Your first ground state](@ref tutorial_first_groundstate). -```@setup infinitemps -using LinearAlgebra -using TensorOperations -using TensorKit -using MPSKit -using TensorKitTensors.SpinOperators: σˣ, σᶻ -``` +## Where next -Similarly, an infinite MPS can be constructed by specifying the tensors for the unit cell, -characterised by the spaces (dimensions) thereof. +**Tutorials** walk you through complete calculations from scratch. +Start with [Installation](@ref tutorial_installation), then run [Your first ground state](@ref tutorial_first_groundstate), and continue to [The thermodynamic limit](@ref tutorial_thermodynamic_limit) to work directly at infinite system size. -```@example infinitemps -d = 2 # physical dimension -D = 5 # virtual dimension -mps = InfiniteMPS(d, D) # random MPS -``` +**How-to guides** are focused task recipes for when you already know what you want to do. +See [Constructing states](@ref howto_states), [Building Hamiltonians](@ref howto_hamiltonians), and [Computing observables](@ref howto_observables), among others. -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`, `C` and `AC` fields, -which each represent a (periodic) vector of these tensors. +**The manual** explains the concepts behind the library — the [States](@ref um_states), [Operators](@ref um_operators), and [Algorithms](@ref um_algorithms) that make up MPSKit. -```@example infinitemps -al = mps.AL[1] # left gauged tensor of the first site -@tensor E[a; b] := al[c, d, b] * conj(al[c, d, a]) -@show isapprox(E, id(left_virtualspace(mps, 1))) -``` -```@example infinitemps -ar = mps.AR[1] # right gauged tensor of the first site -@tensor E[a; b] := ar[a, d, c] * conj(ar[b, d, c]) -@show isapprox(E, id(right_virtualspace(mps, 2))) -``` +**The examples** gallery collects longer, fully worked scripts covering symmetries, infinite systems, and less common algorithms; browse it at [Examples](@ref). -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. - -```@example infinitemps -als = 3 .* mps.AL -mps = InfiniteMPS(als) -``` - -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: - -```@example infinitemps -N1 = norm(mps) -N2 = expectation_value(mps, 1 => id(physicalspace(mps, 1))) -println("‖mps‖ = $N1") -println(" = $N2") -``` - -!!! note "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. -There are plenty of pre-defined models in `MPSKitModels`, but we can also manually construct -the ground state for the transverse field Ising model: - -```@example infinitemps -J = 1.0 -g = 0.5 -lattice = PeriodicVector([ComplexSpace(2)]) -X = σˣ() -Z = σᶻ() -H = InfiniteMPOHamiltonian(lattice, (1, 2) => -J * X ⊗ X, (1,) => - g * Z) -mps, = find_groundstate(mps, H, VUMPS(; maxiter=10)) -E0 = expectation_value(mps, H) -println(" = $(sum(real(E0)) / length(mps))") -``` +**The library** is the API reference; the curated, stable entry point is the [Public API](@ref public_api). -### Additional Resources +## Ecosystem -For more detailed information on the functionality and capabilities of MPSKit, refer to the -Manual section, or have a look at the [Examples](@ref) page. +MPSKit builds on [TensorKit.jl](https://github.com/Jutho/TensorKit.jl), which supplies the tensors and vector spaces and handles the symmetries. +Models and ready-made operators come from [MPSKitModels.jl](https://github.com/QuantumKitHub/MPSKitModels.jl) and [TensorKitTensors.jl](https://github.com/QuantumKitHub/TensorKitTensors.jl). +All of these are part of the [QuantumKitHub](https://github.com/QuantumKitHub) organization; the TensorKit documentation is available [here](https://quantumkithub.github.io/TensorKit.jl/stable/). -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](https://github.com/QuantumKitHub/MPSKit.jl/issues) on the GitHub -repository and open a new issue. +## Community and support +Questions and bug reports are welcome on the [issue tracker](https://github.com/QuantumKitHub/MPSKit.jl/issues). +If you would like to contribute, see [CONTRIBUTING.md](https://github.com/QuantumKitHub/MPSKit.jl/blob/main/CONTRIBUTING.md) on GitHub. diff --git a/docs/src/tutorials/first_groundstate.md b/docs/src/tutorials/first_groundstate.md index 46e08be3d..fe7faef41 100644 --- a/docs/src/tutorials/first_groundstate.md +++ b/docs/src/tutorials/first_groundstate.md @@ -152,8 +152,6 @@ The plot should show the magnetization large on the ordered side (small `g`) and ## Where to go next You have run a full MPSKit workflow: build a model, optimize an MPS ground state, measure observables, and scan a parameter. -A natural next step is to perform the same calculation directly in the thermodynamic limit, working with an `InfiniteMPS` instead of a finite chain, which removes the finite-size effects seen above and lets you locate the critical point more cleanly. - - +A natural next step is [The thermodynamic limit](@ref tutorial_thermodynamic_limit): the same calculation performed directly at infinite system size with an `InfiniteMPS`, which removes the finite-size effects seen above and lets you locate the critical point more cleanly. To go deeper on the individual steps, see [Constructing states](@ref howto_states), [Building Hamiltonians](@ref howto_hamiltonians), [Computing observables](@ref howto_observables), [Controlling bond dimension](@ref howto_bond_dimension), and [Entanglement entropy and spectrum](@ref howto_entanglement); the algorithm reference is [Ground-state algorithms](@ref lib_groundstate). diff --git a/docs/src/tutorials/thermodynamic_limit.md b/docs/src/tutorials/thermodynamic_limit.md new file mode 100644 index 000000000..c8920f6dd --- /dev/null +++ b/docs/src/tutorials/thermodynamic_limit.md @@ -0,0 +1,147 @@ +# [The thermodynamic limit](@id tutorial_thermodynamic_limit) + +In [Your first ground state](@ref tutorial_first_groundstate) we put the transverse-field Ising model on a finite chain of `L = 16` sites. +That is a perfectly good calculation, but it carries two prices: the open ends of the chain are physically different from its middle (boundary effects), and every quantity we measured still depends on the length `L` (finite-size effects). +To read off the true physics of the model we would have to repeat the calculation at several lengths and extrapolate `L → ∞`. + +MPSKit lets you skip that extrapolation and work *directly* at `L = ∞`. +The trick is translation invariance: instead of storing one tensor per site, we store a single tensor and imagine it repeated forever along the chain — an [`InfiniteMPS`](@ref). +There are no ends, so there are no boundary effects, and there is no `L` to extrapolate. +Best of all, as you are about to see, the code barely changes: the same model, the same workflow, two edits. + +!!! note "Infinite states are always normalized" + An `InfiniteMPS` is normalized to 1 by construction, and you cannot choose otherwise. + Any other normalization would make expectation values either blow up or vanish as the (infinite) chain length is taken to infinity, so per-site quantities are the only ones that make sense here. + +## Loading the packages + +As before, every code block on this page shares one Julia session, so we load the packages once. + +```@example thermodynamic-limit +using MPSKit, MPSKitModels, TensorKit +using TensorKitTensors.SpinOperators: σˣ, σᶻ +using Plots +``` + +## 1. Build the Hamiltonian and initial state + +Here are the only two lines that differ from the finite tutorial. + +For the Hamiltonian, we drop the lattice argument. +Where the finite version wrote `transverse_field_ising(FiniteChain(L); g = 0.5)`, we simply omit `FiniteChain(L)`: with no lattice, `transverse_field_ising` builds the Hamiltonian for the infinite chain. + +```@example thermodynamic-limit +H = transverse_field_ising(; g = 0.5) +``` + +For the state, we swap `FiniteMPS` for `InfiniteMPS`. +There is no length to pass, so the constructor takes just the physical and virtual spaces — the physical space `ℂ^2` of a spin-1/2 site and the bond space `ℂ^D` whose dimension `D` is again the accuracy knob. + +```@example thermodynamic-limit +D = 4 +ψ₀ = InfiniteMPS(ℂ^2, ℂ^D) +``` + +That is the whole difference. +The bond dimension means exactly what it did on the finite chain (see [Controlling bond dimension](@ref howto_bond_dimension)), and `ℂ^2`/`ℂ^D` are the same physical/virtual spaces. + +!!! note "`InfiniteMPS` also accepts bare integers" + Unlike `FiniteMPS`, the infinite constructor happily takes plain integers: `InfiniteMPS(2, D)` is equivalent to `InfiniteMPS(ℂ^2, ℂ^D)`. + We stick with the explicit spaces to match the rest of the documentation. + +## 2. Find the ground state + +We optimize with [`VUMPS`](@ref), the infinite-chain workhorse, passing it explicitly so it is visible. + +```@example thermodynamic-limit +ψ, envs, ϵ = find_groundstate(ψ₀, H, VUMPS()) +``` + +The lines printed above are VUMPS's per-iteration convergence log, shown at the default `verbosity`. +VUMPS (the variational uniform matrix product state algorithm) optimizes the single repeated tensor directly in the thermodynamic limit, iterating until it reaches a fixed point. + + + +The return value has the same shape as on the finite chain: the optimized state `ψ`, the reusable `envs`, and a convergence-error measure `ϵ`. + +!!! note "The algorithm is optional here too" + Just as `find_groundstate(ψ₀, H)` selected DMRG for a finite input, calling it with no algorithm on an *infinite* input selects VUMPS automatically. + `VUMPS` accepts the familiar keywords `tol` (default `1e-10`), `maxiter` (default `200`), and `verbosity` (default `3`); we use `verbosity = 0` later to silence the log inside a loop. + Note there is no `find_groundstate!` for infinite states — VUMPS returns a fresh state and leaves `ψ₀` untouched. + +## 3. Measure observables + +For the default single-site unit cell used here, `expectation_value(ψ, H)` returns the energy of that one-site unit cell, which is exactly the **energy per site**: + +```@example thermodynamic-limit +E = expectation_value(ψ, H) +``` + +The magnetization is the local order parameter ``\langle\sigma^z\rangle``. +Because the state is translation-invariant, every site is identical, so we measure it at site 1 of the unit cell: + +```@example thermodynamic-limit +expectation_value(ψ, 1 => σᶻ()) +``` + +So far these are the same quantities we computed on the finite chain. +The infinite setting also unlocks an observable with no finite-chain analogue: the [`correlation_length`](@ref), extracted from the transfer-matrix spectrum of the uniform state. + +```@example thermodynamic-limit +correlation_length(ψ) +``` + + + +The correlation length tells us how far apart two spins can still "feel" each other. +It grows as we approach the critical point `g = 1`, where correlations become long-ranged. +We can see this by optimizing a second state right at criticality and comparing: + +```@example thermodynamic-limit +H_crit = transverse_field_ising(; g = 1.0) +ψ_crit, = find_groundstate(ψ₀, H_crit, VUMPS(; verbosity = 0)) +correlation_length(ψ_crit) +``` + + + +At a genuine critical point the correlation length diverges, but a finite bond dimension `D` can only capture correlations out to a finite range, so what we measure is large but capped rather than infinite. + + + +## 4. Magnetization across the transition + +As on the finite chain, we finish by sweeping the field `g` and recording the magnetization. +The structure mirrors the finite sweep exactly — only `InfiniteMPS` and `VUMPS` have changed. + +```@example thermodynamic-limit +g_values = 0.1:0.1:2 +M = map(g_values) do g + Hg = transverse_field_ising(; g = g) + ψg, = find_groundstate(ψ₀, Hg, VUMPS(; verbosity = 0)) + return abs(expectation_value(ψg, 1 => σᶻ())) +end +scatter(g_values, M; xlabel = "g", ylabel = "M", label = "D = $D", title = "TFIM magnetization (L = ∞)") +``` + +Compared with the finite-chain curve, the transition here should look sharper and its crossover should sit closer to the thermodynamic critical point `g = 1`, because we have removed the finite-size rounding. + + + +We still take the **absolute value** of the magnetization, but for a subtly different reason than on the finite chain. +A finite chain cannot spontaneously break its symmetry, so there `abs` merely collapsed a sign that averaged toward zero. +An infinite MPS at finite bond dimension, by contrast, *can* settle into one of the two symmetry-broken ground states on the ordered side, landing on a definite nonzero magnetization of either sign; `abs` again puts both branches onto a single order-parameter curve. + + + +## Where to go next + +You have now run the same TFIM calculation twice — once at finite size, once directly at `L = ∞` — and seen how little the code had to change. + +From here you can go beyond ground states. +A natural next step is to compute the excitations above this infinite ground state (the model's quasiparticle spectrum), or to exploit the symmetries of the model to make the calculation cheaper and more accurate. + + + + +To go deeper on the individual steps used here, see [Constructing states](@ref howto_states), [Controlling bond dimension](@ref howto_bond_dimension), and [Entanglement entropy and spectrum](@ref howto_entanglement); the algorithm reference is [Ground-state algorithms](@ref lib_groundstate). From 5a12c5325f373e4b83793a6e38868042b21bad51 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Sat, 4 Jul 2026 13:32:40 -0400 Subject: [PATCH 30/76] docs(w0): remove invented truncbelow from truncation table, fix truncrank attribution truncbelow does not exist in MatrixAlgebraKit or TensorKit (verified at runtime); truncrank reaches users via TensorKit's re-export, not MPSKit's. Co-Authored-By: Claude Fable 5 --- docs/src/howto/bond_dimension.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/src/howto/bond_dimension.md b/docs/src/howto/bond_dimension.md index 520487dca..4f41e2acf 100644 --- a/docs/src/howto/bond_dimension.md +++ b/docs/src/howto/bond_dimension.md @@ -54,7 +54,7 @@ dim(left_virtualspace(ψ_inf, 1)) It does **not** need the Hamiltonian, so it is cheap and works for any MPS type. `trscheme` is **mandatory** and controls how many new directions are added. -Use `truncrank(n)` from MatrixAlgebraKit (re-exported by MPSKit) to add at most `n` extra singular values: +Use `truncrank(n)` from MatrixAlgebraKit (re-exported by TensorKit) to add at most `n` extra singular values: ```@example bond_dim ψ_small = FiniteMPS(L, ℂ^2, ℂ^4) # start with D = 4 @@ -144,13 +144,12 @@ dim(left_virtualspace(ψ_inf_cut, 1)) ## 4. Truncation schemes -Every bond-change algorithm takes a mandatory `trscheme` keyword drawn from **MatrixAlgebraKit** (re-exported by MPSKit). +Every bond-change algorithm takes a mandatory `trscheme` keyword drawn from **MatrixAlgebraKit** (re-exported by TensorKit). The main schemes are: | Scheme | Meaning | |:-------|:--------| | `truncrank(n)` | Keep at most `n` singular values | -| `truncbelow(x)` | Drop singular values below the absolute value `x` | | `trunctol(; atol)` | Drop singular values below `atol` times the largest | | `notrunc()` | Keep all singular values (no truncation) | | `truncspace(V)` | Keep only singular values whose index fits in the given space `V` | From 1caa45935cb48cfd748a07f594a61116fdc3641f Mon Sep 17 00:00:00 2001 From: lkdvos Date: Sat, 4 Jul 2026 13:51:22 -0400 Subject: [PATCH 31/76] =?UTF-8?q?docs(w1):=20beginner=20gallery=20example?= =?UTF-8?q?=20=E2=80=94=20TFIM=20complete=20ground-state=20study?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New 0.tfim-groundstate Literate example bridging the tutorial track into the gallery: finite-ring DMRG vs infinite VUMPS magnetization in one figure, entanglement entropy and correlation length across the transition. Executed for real by examples/make.jl (3 figures + notebook); physics claims carry REVIEW flags. Gallery index gains its entry as the new first rung. Co-Authored-By: Claude Fable 5 --- docs/src/examples/index.md | 8 + .../quantum1d/0.tfim-groundstate/figure-1.png | Bin 0 -> 22901 bytes .../quantum1d/0.tfim-groundstate/figure-2.png | Bin 0 -> 21132 bytes .../quantum1d/0.tfim-groundstate/figure-3.png | Bin 0 -> 18355 bytes .../quantum1d/0.tfim-groundstate/index.md | 212 ++++++++++++ .../quantum1d/0.tfim-groundstate/main.ipynb | 323 ++++++++++++++++++ examples/Cache.toml | 5 +- examples/quantum1d/0.tfim-groundstate/main.jl | 197 +++++++++++ 8 files changed, 743 insertions(+), 2 deletions(-) create mode 100644 docs/src/examples/quantum1d/0.tfim-groundstate/figure-1.png create mode 100644 docs/src/examples/quantum1d/0.tfim-groundstate/figure-2.png create mode 100644 docs/src/examples/quantum1d/0.tfim-groundstate/figure-3.png create mode 100644 docs/src/examples/quantum1d/0.tfim-groundstate/index.md create mode 100644 docs/src/examples/quantum1d/0.tfim-groundstate/main.ipynb create mode 100644 examples/quantum1d/0.tfim-groundstate/main.jl diff --git a/docs/src/examples/index.md b/docs/src/examples/index.md index bd9fd952d..67193a47a 100644 --- a/docs/src/examples/index.md +++ b/docs/src/examples/index.md @@ -7,6 +7,14 @@ Within each physics grouping below, the examples are listed roughly in order of ## Quantum (1+1)d +### [The transverse-field Ising model: a complete ground-state study](quantum1d/0.tfim-groundstate/index.md) + +![](quantum1d/0.tfim-groundstate/figure-1.png) + +Assembles the tools from the tutorials into one case study of the TFIM phase transition: finite-ring `DMRG` versus infinite-chain `VUMPS` magnetization curves in a single figure, plus the entanglement entropy and correlation length of the infinite state across the transition. +The natural first example after finishing the tutorial track. +**Level: introductory.** + ### [The Ising CFT spectrum](quantum1d/1.ising-cft/index.md) ![](quantum1d/1.ising-cft/figure-2.png) diff --git a/docs/src/examples/quantum1d/0.tfim-groundstate/figure-1.png b/docs/src/examples/quantum1d/0.tfim-groundstate/figure-1.png new file mode 100644 index 0000000000000000000000000000000000000000..0269c8380b7a8ded03f30682c412a200c5218979 GIT binary patch literal 22901 zcma%j1z45qw(b;B5fD)kK^j3&NFzG2L%O6y=|;NYj_KNK z?{&_(=RTMHJS;X&=KSaPf8Q8yjTs;#C3*w>J~{${xba*}NDhHOQAQvxg`%OrZ_bng zdf`7;b;U)65Esb*eX7fdKp;pF&xQCEoa5J~ocQFGrmy{u@TohXZC60OE8KGFG0I~$ zYZ)5_+0~Ji+05bNp_l80Wva(RvP!GDBV**~ito@rqoHG=@*Chq-newzvGt^FonY`a z+8bxGBaibJQa#)U(Ly`(`F8l^VQ=Bpsc9ZgU4j4hUFS#R3kkf(K(ATL_UKW-h5#ax z$P0T(R$e}31U*G0h}=g=RJ0+h>HO>@>r!t#drEpbi$N#O)?>@5>K5%Mc$j{{!B`<} zW~xn-Rd!iefw*)otedKGwzk`EE?-OJcHQ4l%KIXf$o1;ymrK<-ujxg6H&FPVKaG)K zU|{HoDlIJy55Ily-aQNq3>&=y%{nwPf#kxXB3Wta-lir&Q$ib~H++5HkzdrqZ@y|P zC@CfJdV2K4vxl#95pSLz?OqcwFLqYdy|f`1#)y6>a_g)s&EsK&h3N zmGx?SE+9EM+1p!CN9WgYj#A*ecPN)HX9cN-iP`Tgbe|k-=H%quBw+d0-MubpmX)6$ z91zga(V@c_Q|Ed>%;UxuadeC=A}AchwA9qFSl2NzhlYngtaQw7Sx(n?8?|D-uj-Vq)@W?2T$! ze!k_w##BoV@l)OAFK;eiCv)TBee`JgXlGGaSXe|vM9>e@#=+r(sxUmco?Z&9j)sPY zzWyBS3tBolDv6Ju^714d#9q9phF2D&*xuP$9V;;!tY})?nVp>_;q{pO{(Wg~Zf&6UGuzc5|8_MUmstcSvKq>`QrE0)zt*7mR#<~3KX~Z*2e7S+QYK5vuBiq$z@-> zc<1Nm7Z*nm-4*oi9lYn&>4t`okY0j%8W|k&*FA4IY7e>?8lJf?7c`uc`(P4rl=`+v zCvrVU!{_y=t)%4PNyKKz)@UNn#Y)nVG+Lb|Owa zE1b7xdU;OXW82O&U+=g}#Oe6$`*-EyjGCI0oyFc3BF$Q7el&a@x5I!tRIr&ddEi~T z$wO=U~3|V*YiA%M@NEXGR%ux}F(Omvb? z7V2CkYwqvgg5##5q5?-KE%>FMkI&l^8Gd8fE@^3HCWGlqOG_U=esn$92oU;gGuwJg zKqQ3NeX)m#CGKp(sv#yeR*ttboZtEM(B`VQj*d=|)pR{v(`22i)85Lk#KXb4}LyV3Rga zMZu}GUmk#;)6>&=JWdbcU^+TF`h+(5-wcH76w7m&s&)v^IiHW#dMKTEda~ItUFXXB z;K2iO^2UjY8k2Y5$Hy6CBnSxN`uh4BF3vg0$aMDC#(YA_1pU6nvk$_d{T9RY=+UDZ z$Mu1sAq7Rn52qNU?CdIVV8zAF;LbjO{v6Kic$Hm7R8&-Xxub}PpBTks28NK}U=~(Z zqbGR%7n}R*6GJob#%OW7`ud*G($ccCvr|&e2Qt*lC@L~DF~Q0GdY59C|{Wj|My+G=9U&&GF2rdD$Do5!RZ`<-l1Ld_wn&f z%*>1o4PVfoZ?%!!5%4(tb#3L*T_2xNi;40wnG!tjucSWT5;&ELw<4r@$b4uuYb$-P zz$wp8PamnU(z3xoKGv$?Y(H-mYT@#ax|-~4(^s#mD*H!9US{LH;p1B`C@(C`%*~C= zwqEQ>n2Gx8eeI4wV^b65sDS%2iQDftm1%HhhOWzm-zOkgUt3d9P`G{P4&?;g3|E2n zHesF zr65+TC?q7Lr>7?-_BJIYrLzCa7wwL4N}o`Sd-P(Ca5g5w7Zg5jyZxf!C&XuG zXD9pXG-K=A^Ih}v^JHXXP#~hswaU%$$tV~Z<%*%2+0A!;$a|Dn?6|Jlkul_#t}rhb zpO63rlZ4xaBKX?7sHl;5cWHi9i%3d#Lx*8yVc~K9&9{=qY&Pqg$nc6fd_3e1t%Nl+e8H;&p75Zu;Jw2AN@r`=okCro%f(h9hwVxPv z#}0QIByqhGKwBOyNK$aUI6u2i28|&+h@PIF7FWEOlAAjLduC&UzRVe(l|pa^TD?!` zJqAsg8l4s&0W$Be*j7OS)4_+-Q)*e+*)I|*bm9E!=!7LDX{oE58ybqBnV6eTR#;6h z4`$fe+QOxyqP(eO@^1>`GFy<$!Mb^Ky1~;E+Kh*Xhr4@SWnF2hLNS5&*HDg*_MxFj zZ1TGo3VO1#xAr2BtqipI)Hzd$+Pu9bfm6Qknc!4usDhwx5-5Y)k2w{De}m-F-U zLn$4~`gjeCu)U{eVduz7W6x>Yy+Wty>gCJcMS5-H6BF_oshU-`^RPwb0^tVVxN##3 zSK#g8oOFlCmZPSy@D(x&8k(H3z|lbaZ#oP~|4Fh9;8Vg#-l!y?u+vVZT&nHcD|YP0Vha%AB*X<*Zh2{*;BK z-t(eRv-x5-Drz-_XJIHBVDQc#bz}Hh+v)NhZ-zUnP8iYLJ|gvU7g2 zIXW`3va}?T$W^t6Avby&z#w@ir6)L<{*L*j;pAn<#G%(i`J)pRRu%PyFK2d+va+(m z=>X9^e*Bn`l{KUMMHY8y1eJ7@1V5Jl10JE#;&0!+!8=64KpYC6)YMdazCEANiwo<_ zop99+*l3S$2T(Yz-+tv${s|8dnNa=t@hUVKXt40T)FbQDCsJnSGP}hdZqIY|N#&O> zMI`Mw99D*+?q&4&P1U(p%&Aa$p6x{|uwA)w1)qSx-`}5#g5nub>R6SWniZ6waA{Ad za>+7>@aE*Dv)J@Y#=_m}k5_0`W_Bw+zGF=!7Z8yg$z-njqa z)H*XzPP5+a(U?y2+gn&zSX*0L(CbZK*~mzt3CNJYeEIVH{Cwy+eV&n}CMGOD)tg;=I(CjicV|a zZGL`v1Mlay0KAUp(fmEQGe3X+gvUa;N=r}ItaEV~&DVhUI#&D2?%K$8joS&MmI$%X z=_`A5w8NbkE4~810J~8h5HiMmOB0VC866Egd21A9Qq30KMFcp{S>>vCk?HW`mCqho zF$Uxh9#Aq2eEL2yp;c`kutJ)sl0NU%k{M%=4;zksCom|eJAu=QqK1gwR%n|L*WLXL z?qfu(>icd(dG}_fu4fuuP}nJZX$^{$0YRmw_pra(POT(hE_pvx3~b?nPdvMwNbwdd zuTSXDpV}R*q9MexN_So`GBe-6z_@eph=BoWYVqMDc}I+a<&WAid*1T0vc0X@wk)if z7z5R#F|WoiLnnPII5;@Jow@AncG5F0hKGh~UG`qc%kR`3{BRwd;UX^h^odVYRP;1Z zT}dfADX9Re9CJ|=1%0%doZRP}oQd7sp7a;u;?TjwU%c4e+w;Fc@K8|#-cF8EL1|f8 zT%y*CDyPjK-q&sp4GsBW5v|P4HN(y#433G38S+ql!xtJKAD@`0sikFQVzRunM9u#6 zQBto_$rxS3qvrs+Mn(XdM7PbJogGXA6&M*Aff_AmWO7^JU0~py+qcm%F!FM9p}3Zn zmF)oPUs*A?u*lkZtfuJz-3^+Kt(~2NgM;XMJRK7g6-`Y|Sy{59tH8vPdZWkXQmbR) z;sT8bEsmPpw&$MP+A@Z;F+F{{Jdzg&hjHi?pAUAJn1ZshvYJ{>diuj7=Ig$Vu+H2r zyP4_ft&NS1Jv}{BQyOlL@5LxOJ33?mb8&pXj((FL?NfU*znBvlBH>=}EfmCSIYDgX z_ogd*hw6q$h&2)H-l7@z)({;Y@=KH`dmhw@=BqeW5Q6k7} z4>eY@`O$z_lVSTH5TAzr`aXBpCoC*1$@BbZcX==(JUn)t^mc&b`ZzQ2mg{#OBJtZ~ zB2b|F_gCiU%M82kL-WhnMpR>OCFot^BZfcs$0C~9at1)`e6&3u$8ov|l;L=_Ku|#7 zp;Y|G4UAz<)zvP5jLuFD zE{+zHdI1P3D^uIufCZ_GClWPLm`dbkGsz$A;EUF3m|}F=P>;C=pz2`V$#N>8M&;wa zlM}#T%U&5oUbAiy=8YT6`6zrk{dVtxzCNX+vjCztGzfqYfI<@XHn28+@2j$$Uch4E zi_kOIqWKDJkyHT;fsO7HIy0kt`SN8OR)Fu>by?%%Xf&J z4Pv@U5o#3K`hNJJs3w{M%!TA)qR3lbRaf8e9E6ECZ{8FKJ>cac4%xW<8e1ScC&y-0 zX8f1h62$@H(wW)6D) z9*c;B!qUdkab$S-Oo{524l{cfpKpgYW6S`z+OH5hBc+3LrJp9*g(93PiR^ZUgXxkM zL_ye$I;V&C9yy(JHh=Zd4q1#}>86Q}Ct2`3Uc<-t3#Y;7p;=OfH3*wtvuOVgAtUNWMhZQsAM(a>~_kH=z%fA}z*r^YHER$)1nuU;jvmsL>Ud9+PA z{DW3eaTvg3MIo-JQia)CxQb=e4DK5-dxipgPnl3m=F#Dyr5u9i%(2Fqksm&EJW+*L z8L69)9lRnJg7x+4d!!~5!ua2-AwZCD8aZ5xjfI3t|gBF+F^wLH&0xNzAm ze1o$TgDod3YqK(xh0kP&E$~n>cK2{=76|AqfnZ|pm7hQRGNegjl$?J4{92frYsPSX zJv-awe1K-Tj?4dJTwK?aSUsoc8sC9y_pIt>4i698pN#jqdL~XxsM>lf`gVMrI^kYn z3X^nmt3Bu=>zOj=;^vZyXCvETLm*xVYw|Cxu6AiZ0eRFe0ZGZ@$o?GApVtt72$}7lHod~=u%Yy>ARL@@;6?p zm}HsHyO*A(ut&7^GMTV(4R{1`n=Secdpr>BWWj;5sMF`V7Ts-VW?~Wp=$GZClG44q zcgM!ZvomXLdMz|H6QiT=#dTZGzXRe88pgOH4H@93QLnL*_rrKET~zT~?p7PVl=Zxj zT%WSY0UGmrhQXa@h##oncO&kHz8+gG_biC$XlTruU)PWF;^k&FepdA%?@!%%wCc2x z$YK$TIUitCrB3)DRRcJ=y1F`N!Red**)3-_k?;8Shnu&#+t6B|vBa^MnwfF3u|2b} z3fa#fC8HoE{b}&r#Kpx0B(ac?5c3-4M{wU?g;-u|9-S%PH_NuwdfBN?mef04Ww)4j=*;PQLMa|qdO>#? zVK4R3K91$bj~{D|GlIW7j~Gtogoer{m9Eewp-y;Rx_ou=QFwjf!>W&?O~aDqmu6>X z%)d!&oR{}DZ22CaEg?3)l6V{@n+sk-*xNoMc@U|h7INz`3r~`jp5bv_NJPjwuiZE| z-E4Q|At@!de7WGqD8H-zZPojXXN%-LSKnASj=3iJt|v=v_&NckX=`omN#u^(5QroS zzU6rPo#T6K4xe}LUf54|fBJ$*XeLyWKfCvVc`f@`kV>i}$_v_1MoCyX+m-8NrnC!2 zf<#Up2Si?>xJbUksBwyp$a_PofL-UZ*V*G56CdvefGBNaqsi}v9;3nJW++#M|LAp<9G-LKg{MGiyfaX19Gtdye;;m4Y;t^-m?y_ZTcW?j zr$dIue?Ovw%VS|Ow=0WaHc`vvrSot8#9k{Wmy`ElNBTj(fB)v`3C^F#*GXJhB~;MG z+T75wng$)G$bjYvOPu@GjPRdkhbCa$nkk#|T{vz34o_vD_Hn08d(zXQh6JuhJI3OR z-AC?n(=F~6>XP>UwMM&UpC+^)jC}SDGwrc>NImCiTHpWbB;QoMwC`wNe(eX84s z^FeKGPoe~&u9@n~3F}S8v3Sa^#cwf!P8tY=4=LI&q9;$DIDd@V2N5JQlNt!;^h2qk z!9mv(UAkk?kRmKwa?DJFcS+`d{pu%kKzVH|fZfPBkRc5s&T*+{d}n88)@+;Vvq;xC z(`RTx7ia6C4x4XILWq@qK5qxC3EcHh(}t_Df0`3Ti_VgHVklNoB()IXqD)A*oVhde zYlFn|Qw=>k@V$ebos=4Mgs(5DPreW-HU-tg_jb=dn5z#=Y#+>uEPeqSk>6MHC&e{>k(@Er_*PLgI+33 zxazK4-y}*jsgF66SWO3ps&*C!HKGYYtE_NBL8y?SB?tER^|9G(gzWC_Hgh^XD=Woy zc{TR^d!Ggl!d?dy(r|U?#~K>21_+!>{{?mC%OY%{%pX=Nhsi84yET8}_gkog4>BO2x0$@nFfj zC`+yA6uJ7iCyhs|u~>ep$@hH9$Y^VA{pqjeL`}o>IG?Q5j0&eK(V!!L(72qPp>p-= z)yiR<*Qcat{8>+Z-0nUUEcR{DE))__Z^HV-1>|`Mk9PR#8<}EX2Au17v{${i(uEOx zUy%>@{f0iZ^F*uIU^?ZrgKTgKo(+&N$dZ3AA$6Gp!NrNJ)XSym3K134r*D@wy;N)J z6M3zEyl~REkOR>wK7O*s$*LOTl8gk;zx%^oZRrPX!PN8B?_X_516do`Heec0nlZH@&bwl?)CIHBV6?=B^T zfA1SpR8XLxq8ik=^14v~8^zucw7bd^ROEtO;*itRo6Rpwh!8mm+P=R#9Wn~oqhI3| zqV@_rWfSn#Bh33UcsBOlH!l2taJ-bZe80O3a6YYu9$|cagXdD8PPu29!#jMv*g(oX z`_CmYaRK|CS9bELexy`9K^R{uhu8Qv+%6sw-%X(wk6E@#(^aKTuR(d~iy9gH6J|qL zK~MNOZ(2&e9FPWaZbaXGG=bMxdYeCgr|xPIcm|>9Tq^kS?c17UAOf)te1T{oqFc)& zaksd#I?+Y7?VkAy=ck?>whv1*F8c8>MMM>@A-bWIB8Uw8KJjZ^oUVSp+a;k85cPP~ zgxzY{bAY@_^_YN3SaDPFwSf9jAEmWojiC{nE zGNK!~Y+Ud+)#8ZPBaMIGm)AXDG*Lf%=!e8$xX4=ocyz&B>m223p3fUkpZG$Fvl2+ePyw1=pB6;@V$?3xENOHSH#e=X+2hrRS3P#}p} z%s(RaWrOXx4mgVsM1yOcHZ?KKfRYhjpIH}2z?w#M)wjKShkn&NIW0|?d$_+JBm__S zMUYwC_s5K8GQc0)9Lxxjp+*u2K#WXGOn~@f=@o&kDJw7i{7Gu50*D)=WsVI=1ep)0 z3UIFk(0^9W zgi&vzq!U?Z@K+h}(`ao5GV>S|)~v3vky#KXhiziUgGIu<$Kr#zOS@ zA3OKfVi)4~ksFu*$nq^t&)=^71eZ>A7pUao+#E>sLc+q`ajYTOjfN%e?(X1|W?6!F z0U90Bwr#-xQVXiUGgy)b5A=Zlf^so2p+~xvAvbw$Li*pb$uArjg;o-$|ICS>( z1Y?8tO(E?eE+v%+ZrbZhmo=4AKHGwC1b#-5GVRTqA>bEsb91vRLMh=x)3NW@Yk2kQ z6-XFtBGgvu^!M7(OrjGKi0<8^dKGZ1&#P_r7oLt$->(Mok7hUsMC5%h?0-2C_Zw|D#xp@d@g&-?e^evW;2C~I%O3%FmkA=THn1bwS-h_w79G7fKMx3SnO^8CP#*vefI#I` zRDdf>JKgOJZkq))4zA1obn`ZV3HwXm$x%Z|{#y4BtaUP4TApBa{{C$Z^%-b6P$0$_ zF-e3AfFL;aGRgyEt-q{+j^4U`Ti4W-L#NRPa7%l8JGhmgrZGU6gORZqA_h?cmm+cF zy6c^{$dPw8ca$Gkw7aLLClgZ%keS~{ry4bmcX4rBTUxl?4xeyxx}F{H0VKSEjt)|1 z0*8aCiVA*^@MY?|JV_yR0*Iqmb!NNsUD3efE{=LVPtVRknV{qZ)3HFc%yc+g(ZIkU znn4RZ9}v$NSy((4hvAUg7mo6?!8L-^RXRBVQo=LjmqHJqTSV;xwhKt2M8?`Brje0yZe;kSR&nRvQ18d5-YvR8M4TgF zm6zKfnePn(mc!#?xSBlmDqEK{gq*}Zy%pNery#V zr!WBGGt~TMX$y06qzf|a|5Y1GIQYuk&cC%Gn*%C`;S;=YjACV4pdqjwVEeLY_{vb{ z=H+n%*{Dnd%^Fl*W64*2E+}shcCq$X56L+$yI~{<#nq!djOfsQqPnrus?7gzSLdqJwtIx^ed-oA=OxHLP<Tq#!39+ci$!EZDOavVSypON0|RnfgW=)f z>7s1SC6&M$P*G7S9zK*x;23UfoPns!3{Oi-3&aAt^93|CroMkageZj--PLhHQfy-r zlYR}~;;xR4D!?-kqJok!cHLLt)M*Km6hqk>~!Tr9U; zjE3*eMv4z&>xG^XKrz^!9fPB3t-Y&@)^hu z%*OV8bab@4I|#ejYMSTf&70ZM+S=O6%HKiuqmqh0Tp6ZWDVTyHvoIfv7HD9nHV7F?-y_s)b`{aD2mBtIqBEzQSeu$_4Mf=4OhgPi3>W;L!MB z1AZNO4_oQStDOZ(3JO@#w;^*kh&UA7>Y71CA2W9ZRVXQGdbTa3<)FCI?Wnk-!bw+m zrtMX5RFA)K0#3ZUmPFn~I9+eh!KZS3$*Z*a%q|i__TvZu9e{EGaJm#`Nh) zP|`O(Flh`tosrY9+&cQ!D9maLVKosD9o{WCU_<<=|JyfO3W_;Ek8p$}YhaTTb2`Fr znkOd-jj|B!1c5Ca1UBq*4bvh4-#nxle!56i+8msJSui9-eZBAOK4Sdp)e#&KsLKT! zH6mzRdwU6NHo7u0GN4HVc!4iDxp2t&z$?HOV>20`fR=NAwN)i$^J>ribqecxU8C1l z$q`Gxr_&7SlQOfiKtZm8Fc3(E&!_G;0xlyZ)rKISUhDg0){ACrpUtaYg%Mw*t^fR) z^F4lQPD;omp!AZfPh0m zfz`EqOoTpMCA6dWq^O~H)bAlV>G~e7j-;ey2~}Xd&GWl=@7%e=9tl9`_eL#NBQmz9 zR*}Ca4iXInj|8z`jS;n+1>V-?MRrI00$%~iR51}kCJ-g{w&9Zf!Jq$Jp#SY>4o(XT3owWNef2$)lasx@A^(?!`&4oV4fS6> z#hSd9?RILHFoX^&z{tX9|1-S}R1!AS?PF zp9z9SS^H3&KYaKg8v++-^z9>A13GM@xiVqr;e7Y;NoHta{*C(;h+rN5}a-* zqdmW@kN4MIq48#)`IC46c6sXG1YWUZG>VJ>SQ8)#{8=k_ro;7$=?yq;f1nj42@<$o z*>26WgcJ27aAu^Zi*VD^(Q!MjeFs*RnIRrUyS2R?F0X^o2nMUm-~Za5y-{U;%eHC~ z?8C#86M1RKRlxyEJ$@@6irqN7h1A%j!9+aR8`TmO7XHPdi$H|3!k^&c;9v_#NJwO6 z7#bP^6SrD%gR~W-e<4ULBMo$|th5viGzeR8IRE}R?Ril*mbS9G%1+n=4Yh?XMKmPw ziH?AO-8E7lY&kWxF5MzH6i9D2B0zq^*bl0N@!)1Sk`s5Tg-g-%i&?B+M@50cB_Jj! z=nWoc2{+h#04!XNcTJ!(X3w{WJs9%7I9=oo4u-rg(wQ=?{siQ@y80NBv@LW1uB=os z+H-w3v3|sWjd*%`3P@y7<884SKqRn^k$gPwXhN8tA3A-9KBHE>+cI!ov{!p8AJ`Tt zkdO(0G1$BJnN1Z2mAWBlxV8qidfW|xhY?wjt<>)b$6_F+0McrHYaqX}@(_GdKniJK z)cIdvK~?g+Wjpo_0N+hCG&c9+XJo1Q`Se^|Zs6YfghINg;ruwTckzyZoV+~PQ0E5? z7tc3(b8~W1G%0t;Jiv;t~Th3`ts!q$QnGZ``>>2@Bnw(2OBsl z9$xz|YbcUYv?{Q+ClDF%gs_rN=&vS!`Fm0l@oYAL9mvC|Sy&urTZ16bVw(*d>vcN= z+BHnP(6BI@odrp#dsbFfrVM%B-c4X8LmRzL)^NHl?%+^X+3@Dgr7{HxiEj{rQ=uIJ z0~-3>oC4_P2;pF+E<6GP>DXt_i-mzqxy3iNw4{xtK{x!d3oL=pzbWg>f9&>ulgNaG zv^2_v`&W?Eiq9wmT0@OA0;whbv+#kam6<6fB?Z3zUu9(tLdXzg`ychR!v>^YcEDBu zr$;TPhX-UxRyUd823FIcyr#zlRaydivzCllaK3n23Gbtv>6#7yjX0{BS9YA?io^6(cI zjXUlAl3!f^<*;8;ufGt7{& z*kO!lCZ-4KzC;-T{qbQ$BBWcjC zlQ9{7Q-;vwl;Uf0Wk?SoDpB= z79n7VzkT}_irBU@7w{oqd%#QrH$KB1*TDA4yGumGt+zjU-_OOnB!o{;Ye(wTD9MVL z+vb&T*k*G({0$=(6CCEyE#>6oAio1O5D-a>gdyZfGlxN&2hsvi zD!z9Sz*Itq{%rxnp7`f=okyNN*jqjiAg>8^KuStVa#KV>UcO2Di4b`|LncP(1W4+g5c7jU+=9l0)k@+tOIn4$$EFS$?p)bc0bg9#aX#MjGLx0nn`i?js}9 z2Qv?(O*Lk)&uNH=h_YHC+lKDj2uVEH^U!ozZY*tVfJ?rQ{EK?c)}u<0n89<;Y6CG4 z;AU~qpvPZ`E5GbAH5cly2?Kro%(2Sb!>s0a9afWKwuJn2K%ix{7#}LoY5*M=84;|f zz(I##8ZH6B2?Q`;3*S3@RD-__J~1;_yMFF}R3n5zDO4XW8uzbJ_YBy1ty2zrG3@1Jiltt8ig=&f{v zbYapx16u(G2f&Yq8Ub-3H#JsdU|dOF{y|xOadEMsIERzev4|817cU`wx3zU03yTK; z46xRT(tRv_Gcy7l9HG(iOE|=iLG^$Xjh;-O@)s$fx{ciwVh;SOT?-fFgAIq0m9+wl z12Fh&v+NWUA_D_495#JHUGLBc)CGMCgbvAxy4u>zI4VrMC!`Sm?_K0|*=_&!?R_UQ z#Rt`AzcviETYD|P2wGNNp8Niq%8M5-;Gh8if=MDshH$`u#!Gss^-H*DsNq3ySMq2d zJ$p_>OZ+UjbKy&=#gV5r7?JZ}urw}4D!Z$jQ)h&)V&8tPW+w)bbq z^{;v5MZ!=FF78Mv?3wk44-Rb+QMoC}FFg-v z@t%+cx zZ*gWu;QRuIn47x};wFF;P7V(tMPd-|?CLrSvr&T*| zbIoBi3u69&+``x4Ep$hLAop;%QJ=BJ)9V=v3nL!pN-m|Un8hdx-!%bPWtdRfAaUwZ zDNN;`_NqLr^++y~nx8|LmmThe(7ypUlph%DP%kkIs;WAoN^-l6i^~GU6U-CvROjdB zV3nWM+!}cSmd5I60SUY9T;wBpm~()=l{J?GnkgeAlzB53);5UKf`=*-a_z=_3j7X; zrQ~rHMu&!4LnVL`22~J7_8YYq;3FQZDezj{H5Vt)1v>=T%VGXiCDeUc{%Kdw7C zC}=&i!2!XC?p3ImE}f*=^D9@CsCi{sesn52bM?uK;^7GC3AI?Eb9dod@1nfpgH48d zFU?bBQBkAmdiNO~nwPmtKk7Ki^uZY$n%V^P2;~g!kD9!^AR0c5qd~caN*7XE`V2;I z(i^rRvvy~blhTJ)y)v{~P8Y@*0C+2;#Kw-pzR412fa-{Yjr|*GT?O8Q(-J$5mf{ta zEi?ebPmoY;L5h<4C)Ciuz)(ZZ9jusuo|$=V=xY_wU@fg_c<=I7bMP(!qek547Z(rY zNb>!v4FRyz-9c%_dx9WX`IVIHK*NOeYlX#x$n5fCHy#o-AH;Uk(q|{!?yfG-&A=YB zP&EZF3UDst^hZ_(hE1Rftd>+ZuZDZDrXEV;vA){YZ{Z9id-SLSgn96HVSG)s*4YNg z9Bd5`)WCYql6N+)0P_vZFV?A;qu@Nvx@rjZ=e*1VR0h)_K$;eM5@@^?9NX$}Uu z{hXS$1z=W9#70_)6@Z3A6)cT*_Z9gTphR zfr6mMLe(Jv%myQrJX=yIAzfu_#qRB2Bhi@rgWX~&ZM^F^hnWg#pT_p|~74VOYjD(0e1mve18@-x- zl}=Wrr~7dX&qGQc^6|B{^Dop^$$WA(YNFa^+1c12i=CR00o%e8xi{~aj%UMQBn*B+ z>i|wY1t%ge&%)W6tr#1@K>*DU;>h!X_bdokC}O;Pupda4U4B!C(mToN{QDCo)lW=9 zw$N%Eep2khF>_bf6F8IGN2kzSLG`AOCLkbK1vdgxrl384{wy#R|F(Cr!R=_Er)L8; zGI?10)KmiKu@n?OExItc1qpr7kD)xlaGaHuG+j8%qd-^<+F6Ar;)&6wKN|KgrF{ zN2Z(c@gFe{cE&BOtiX)H=;Y)noQUvhTTpEvo11km@lbvRRTUI!sL#-LAmt9|7An;K zWTk8jjHd-!F`*!cup%rQrhp;V#NlTa$6n-4ezRvv;xPALD&f9@!Y?859%fEq@<&U%SzNo0bx!I@saHy}Z(6>hU*>GRqZ&2L901zwlgu4yH1#&?E zwuVlJbm5d&l$Aj|@EJ%6aJ3+Bz)7pz1AnddGFoE=!87B~^27}i{3Cgdyfn=j4B@sU zoNkq=Z*+)dC;a)->0j&W=JKt9RAjU=4oqN3}PIh_7+y3+h+S4HzXw!IQHVK>W_YU-@JO`zWsdX zU63dUm%?u_FSDd8UxrK4$$`14SG~O_U?h*XHEL&81=stTN*S!D<;t}YbLXGmqMxuS zfFO*jvNE;+&34nT44d zIWJMU1J9fpP>2j^NQyxZjE8d@87V|mMaXWeFDEwu*9$ZDKqc>DWAmXwN3w=hb##n+ zYyzXJl$4Y{*bv?Z_9)A$9UkNBE9~NO3_TJ99UWem1*WRfW6<;Zg{e@lE_`AE zB6JR}Ek~|`cV>%A&nz2#fGj$;&@{tP8H};??_R~~d-%~_ZA^P$T?!?_aJG z_19IaF-#cZi%<}xeye|i5jue~{BMOmFZL#7q@}@D{lo2T5r}F`^IMPK0)&BiDEnWH zzHkdZ*We;v=cDqAmB3s8jZ%JObaZrNq{7RWom@R2L&1>kK`Zf~Y|M-zu-B`Em1uEWn?W+=n zl&GkeP@B6pF>nI@p@|yY1XB*|`H4~ut{AE`&^N~{hnUxJz=itr5eMH(<6v%huoa{T zdmzfyyfD^vUZ~SOxnKfYl~HRC9EQB)HU6cUnSt0Nc`k15>2Z)x4PXc@PYX1b@JToG z{l-%yb%gO}xgg-nupcbW-hobXrIXm_*~(}E;J#j{S)eh(8vGetN-2a`I|1!(Of~FK3~qHUZg%m(wQW|E2K=-p)G={|km9M+A za~m8t77JBQQCCR{5*{8NQ1oAc+z$ueWq<7v4tg4gkFW3E#?%QMMNmGWTf#0N56etW z{yH)O3Pb~F)^Hoam~k0AG-sIr+bT~H)DCl)A+pdw|D*zN7S=Gr^whBJ;+qTBP{MYM zVLNO3nW$t8a|4)-3yOpsE{(OKynzR-l|2`&`oD#ew!RW#i7xb)n@^c07ci9+%w{yX z9J8sY#NkcXI7u(`V-d0$=NE9MRh+f{;=Zh5PKUV*9|1tSV+`Iv@slBvRoxmJ=iWzk z>)m?}@L1{{W0=n$NpF3SkjqOnVke>{YR8>Gr&iI)rD|!JUspE#$#Nmd`5=C9dhCUk z(bi{S#t=x@s3#;GE63#S*{ZM=*5oB`q<(tN7%~C@7UM6kH`1@t`0pz7WcsHB)E|VB zp}gT+xO7=0q?~C$ZEehbPv#ygMhXwNE6iJTagE3Kv5#Eku)D@qu;YlYt+!yT7m<|2 zuwzWXVqQ2j8Z+E$a#onwM3@V60+25^AeOu>I5bJozaAMD)(@l^U_B@)$uh_aa)f)Oy7Ke?+CxM-8)b;&*Ao;&e zBItcF`;?T@RKvGvqAn7SvP*NBtzLG*R`t8NbnmIdYv16j!`r3rS!ZXOj9wLhJT=at z3L}0cL3^8bPB;k8m}smn70@rO)g4CqGn&g`_zIZaNl6mjBh=24E>jp`4d!$|SR%P) z5sNDO?HBjz-WhExd#s$a*^$>zj7KyT9u?YOQSe1pM{5pH@AQ)&czTS$#6fNQ&>ML} zi|Kj|zkZafn4Y~uJDNKlbZM)A$%Bu{N4roepz1^tD&_9v3vW-fbKz6Mk52Ig%bcj z#Lrl#-F9FWj>)J;W{QxA2*x%Rksm0a;cL$SF*4Hr?AT%KN2DzXG12kL>RWF2%Hx=v zFUiWfPf_43O^;tJ$KJKlT!J}V?T)E);s>phBn?S;stp@tw`11vcDHT9;S(B|x+kuj7P9f3a)-yF7AL;jVebvpFOSG#0aE$FlZl&0Q_uZn7aa|0PA;(=F z^||u`Zl9!9Zl_qb6Zi}Y<5gqO8he5d*W+|9I%{E!!8Y$C;c#6@O_UQ<*!tcPVv>V` zlR9+|O}A{h#n$f1^5Ce%MB=qoBJMM-k{iRO9ZOEQWhtGouLM_#|EZeu)-tx}m#t25GdX0J>tN{_7+roMfH z!*=y<#tXlOsOkxaiP*(k2>gPX3}7G-*a;^BDMpw)tTF_gDF+6MtSfNWQgLx|^76WSd!uWwPeYU# zSY~Gw2J-W8pxjLyT1MUvX@d_lNv=U>AAfcD48K7(TbB8(7iu;O=M5Kmb$X@K%F5I^ ztw&;LI#1pvJ3#dTxTR+1nwTKzw;O7T^N}4Oi;$pTN?yv{`376Z$RAY$T?z-F|3T@7 zIjhyN!RzG%ZNIrBo>}oYlODY(9Z2!NSr?Qx9Tpe%(%#SyGX>s86~6dI%DQE$VrXlW zPAQNe_WR;ivm68_N>N6gPvA3Fva9mbhj?kliGo^>Iq*du_+*xR42O&ASJ26N^42`% z`k@Q>-%^$sfDj@+a6zz7y7NzJhU4q!d%ycn+3?i z+sReX#KnG`hOx)s4UOL;yR&_E?y|YCJ&#&Fnd`K>J85ZpU#L^H$c& zEj{>*D#Eltk>nrljiN6dDSX>q3y6q~8~%*%E-D)ZeXNzuPNiX&S?!%b-IOh1wYu%R(E|7UG2L7$5{kigAryiuxL5qv3rtS< zW=%G_fZ?o$cf`3QR(}~+8caNm{=oJ*tV3VkY$D0SbERlxv8#gGsYkccor7-H~&;K_27t zQpxF4hm*yT=bV$LV=!=0nL^pz=E{D%A)dsVJ|+QwL$Jt|o0pfwsq|nZRg!XIJ&85N zTBV(r{A>v|PGfAWGG)E9C;g7OqsZ}HdWKDVuwCF!B zFN?V`kzI0nMjyQ@R5*sW;_xsap~QGWqPmH|oMpop=3$e=(Q*u{l2q@XN}lFgKOAmr za(8yd(|QIGcxzjAM)#EfO8)73{L1fbEgwXd*Vkc`R9pLtUbb23wKM0&+z4@RrEmHJ z?Ww@VW&_h@sG(Qtm}?m>5~EP9v?dD>f>A>l{#UyA2}t}A z&bx?+2uOIr+|bU9AXz*f5)yRiANS}^+Eh*6p&F~8rB$H!ELjE|i~rNcwTDBU?(vzat&wYp8HY3~JGo!7<z2C`@Qea_x*l9Hv?^oK+CvBaidx_&9ydhKtbI)XxnXz&fUq4-#(6~DmJ+@ zGcA2V5%E#vDn$p;bnNLwhYE1-2eNJrC}cPB3;N=pAt z6l4(yRT7I;B+;=A$3Ous(sIqwykufXFk4YCzVs-o1&N0C+Pb%} z?eM}#dR=NT5DLP%eWV+RnIPDN`zU{;IM5O8@TY6umqT237?EAbHCm^w^s%^={!N_D zhN(V9Aw?h22l&Xg$hnN!+uz^udIoBxnVgSN;o;2c@%E9Erkl5n(fDl$y}}%ooRrie zG1JR{wLn@9C=ShgSR>I$K0DigKi1DAd+BGNZHY4PMdxIdi;=Mb)Xg!gfH^ysl)jx@ zJTk)8xDbZ;L76NO6C7al@M>$J4;>N*Z7S6fsd8K&C}aVt$*;cs?#1AsYd3o;6y$U)JQd!)*^V z%T{elCc9f#Cx)hgTkbdy9oL

wLZrl{(*{0X`dA<|L8b7hRvH^zN@WY;M4UPR{TTbXm($V^iE`TAT}AS15`(P807Fn|e0sC9bNl!QOz;tM zd>jPSy?0Oih2LgjW|sfXkceQVjRs!gt}KzrzVK;Jl!se8E~%?{C%9qx+}y32njVf5 zzaMxez6FTT(b9uf(=u7$S&npkjF5Z;hA~t@zvqjI=FCrp0RyT5FjbAs%nNgo(b*6u zp9HIRAUN1NUfAM^5+o4Z{A*`N#}A2KtkBy*RXI6&FHRvi6Wn^N%Z)_8{KpurefIB< z9cxjq{<@5r#ug}airZU>x5z{Wx%>D=`T8OsI$-lMW<_va9zH8>)!7Eiy>hFKBKVi9N?|32ZV)`Zf# z5;~Zj+ZI16`Fn}T-UNDvuo_3G2*H(4Tyr`T01v^OY~Vmh$gPG4KY>X*d-lO((3G*h zENh8pA%RR=r=3P3kwU}5phpDu@(pyCI5yUD5e6d+s02Y7t@OT)hQeio=uZfb5vl+f zf695v{W#bY81Yb(fQdku@T9YI7g_viu5T%61k4$^7=Nd)s~h?1_6XDslvG%U63Sgv zK+Qr{(GMCA+CLQ)6~vPPf+5qO&4;B>;{v~+p!4<278e&_caTVtm(@k#h<{%iJ8IR^eP#l?CJ)TpuhQDsDss^thI0X6Y9%c11||FM&~A^*92<#?diI zJ*508cnyHx0o+GDLB}S~9{cC+b=s(LQolFlUf+K2wE63|0;EqcjyI>TLY7SYR%PAA zh>R4Xxb~P2CEdr-P~}?+=Rbg>2h;6a$4yNI6|T2xl`s7&gbe-n+(y!sDnsAoV}CBn z>MLj{(WT2${&i zOK`HO^?Ps zE|c{NNqT7Zj%K{vKp1ZR&u@^pyM0YpB!a=7?Xx3LOmG%a?iLjlA#tp>)-I+U-y|1k z5|%B;3Zz;(I>xr}s6fhbl#icofb0w8ox*zsVJ8Vo({z;0_Qh&asd?GicOrZ3?gYiZ z8{WaajP5|%=sYGaOR5FFFm*8ygBYG1cMzS7$<)Nz>Dnx ze`u1uN70FoC*tFifzIzPV-5@qAaNBDj6jS%Z!RAm&tp-(pEd+hNi{O62J3d>gb|f` xio?+a&}wi0oWsPT{P&3MHvp0JKU-F}NLadOAv48OuNiwxaNp(adW*qI`ZpH4q0j&T literal 0 HcmV?d00001 diff --git a/docs/src/examples/quantum1d/0.tfim-groundstate/figure-2.png b/docs/src/examples/quantum1d/0.tfim-groundstate/figure-2.png new file mode 100644 index 0000000000000000000000000000000000000000..19e71c3eac126fece3a3f8c26f217675376ff2d3 GIT binary patch literal 21132 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 literal 0 HcmV?d00001 diff --git a/docs/src/examples/quantum1d/0.tfim-groundstate/figure-3.png b/docs/src/examples/quantum1d/0.tfim-groundstate/figure-3.png new file mode 100644 index 0000000000000000000000000000000000000000..e6397bc9c1addeb10fc59f2eab14dddec950b8ee GIT binary patch literal 18355 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 H`TqX{XpE$f literal 0 HcmV?d00001 diff --git a/docs/src/examples/quantum1d/0.tfim-groundstate/index.md b/docs/src/examples/quantum1d/0.tfim-groundstate/index.md new file mode 100644 index 000000000..67e8d9ad0 --- /dev/null +++ b/docs/src/examples/quantum1d/0.tfim-groundstate/index.md @@ -0,0 +1,212 @@ +```@meta +EditURL = "../../../../../examples/quantum1d/0.tfim-groundstate/main.jl" +``` + +[![](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/QuantumKitHub/MPSKit.jl/gh-pages?filepath=dev/examples/quantum1d/0.tfim-groundstate/main.ipynb) +[![](https://img.shields.io/badge/show-nbviewer-579ACA.svg)](https://nbviewer.jupyter.org/github/QuantumKitHub/MPSKit.jl/blob/gh-pages/dev/examples/quantum1d/0.tfim-groundstate/main.ipynb) +[![](https://img.shields.io/badge/download-project-orange)](https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/QuantumKitHub/MPSKit.jl/examples/tree/gh-pages/dev/examples/quantum1d/0.tfim-groundstate) + +# The transverse-field Ising model: a complete ground-state study + +This example is the bridge from the introductory tutorials into the research-grade +gallery. +If you have worked through [Your first ground state](@ref tutorial_first_groundstate) and +[The thermodynamic limit](@ref tutorial_thermodynamic_limit) you already know every +individual tool used here; the goal now is to *assemble* them into one coherent case +study of a genuine quantum phase transition. + +We use the same transverse-field Ising model (TFIM) as the tutorials, on a chain of +spin-1/2 sites: + +```math +H = -J\left(\sum_{\langle i,j\rangle} \sigma^z_i \sigma^z_j + g\sum_i \sigma^x_i\right), +``` + +where the first sum runs over neighbouring pairs, ``J`` sets the energy scale, and the +dimensionless field ``g`` tunes the competition between the ``\sigma^z\sigma^z`` +interaction and the transverse ``\sigma^x`` field. +The model has a quantum critical point at ``g = 1``. + + + +Rather than looking at a single field value, we will scan ``g`` across the transition and +diagnose it three independent ways, comparing a *finite* chain against a calculation +performed *directly in the thermodynamic limit*: + +1. the order parameter ``|\langle\sigma^z\rangle|``, computed both for a finite ring and + for an infinite chain, in one figure; +2. the entanglement entropy of the infinite state; +3. the correlation length of the infinite state. + +All three should point at the same place — that agreement is the payoff. + +We take the model and lattice from MPSKitModels, the tensor backend from TensorKit, and +Plots for the figures. The Pauli operators `σᶻ`, `σˣ` are re-exported by MPSKitModels. + +````julia +using MPSKit, MPSKitModels, TensorKit, Plots +```` + +## Shared parameters + +We fix a finite chain length `L`, a bond dimension `D` (the accuracy knob, see +[Controlling bond dimension](@ref howto_bond_dimension)), and the set of field values to +scan. +`D` is kept modest so the whole page runs in a couple of minutes; increasing it sharpens +every curve below. + + + +````julia +L = 16 +D = 8 +g_values = 0.1:0.1:2.0 +```` + +```` +0.1:0.1:2.0 +```` + +## 1. Finite versus infinite magnetization + +We compute the order parameter ``|\langle\sigma^z\rangle|`` two ways at every field value. + +For the **finite** calculation we place the chain on a ring with +[`periodic_boundary_conditions`](@ref) — this removes the open-end boundary effects and +gives a cleaner curve at fixed `L` — and optimize with [`DMRG`](@ref). +We average ``\langle\sigma^z_i\rangle`` over the sites and take the absolute value, because +a finite chain does not spontaneously break its symmetry and the raw sum can land on either +sign (see the discussion in [Your first ground state](@ref tutorial_first_groundstate)). + +````julia +ψ₀_finite = FiniteMPS(L, ℂ^2, ℂ^D) +M_finite = map(g_values) do g + H = periodic_boundary_conditions(transverse_field_ising(; g = g), L) + ψ, = find_groundstate(ψ₀_finite, H, DMRG(; verbosity = 0)) + return abs(sum(expectation_value(ψ, i => σᶻ()) for i in 1:L)) / L +end; +```` + +For the **infinite** calculation we drop the lattice argument to build the Hamiltonian on +the infinite chain, use an [`InfiniteMPS`](@ref), and optimize with [`VUMPS`](@ref). +We keep every optimized infinite state, because we will reuse them for the entropy and +correlation-length diagnostics below. + +````julia +ψ₀_infinite = InfiniteMPS(ℂ^2, ℂ^D) +states_infinite = map(g_values) do g + H = transverse_field_ising(; g = g) + ψ, = find_groundstate(ψ₀_infinite, H, VUMPS(; verbosity = 0)) + return ψ +end; +```` + +The order parameter of a translation-invariant state is just ``\langle\sigma^z\rangle`` on +a single site of the unit cell; we again take the absolute value. + + + +````julia +M_infinite = [abs(expectation_value(ψ, 1 => σᶻ())) for ψ in states_infinite]; +```` + +Plotting both curves in a single figure lets us compare them directly. + +````julia +p_magnetization = plot(; + xlabel = "g", ylabel = "|⟨σᶻ⟩|", title = "TFIM order parameter", legend = :bottomleft +) +scatter!(p_magnetization, g_values, M_finite; label = "finite ring, L = $L, D = $D") +scatter!(p_magnetization, g_values, M_infinite; label = "infinite, D = $D") +vline!(p_magnetization, [1.0]; color = "gray", linestyle = :dash, label = "g = 1") +p_magnetization +```` + +![](figure-1.png) + +Both curves are large on the ordered side (small `g`) and fall toward zero on the +disordered side (large `g`), with the crossover near `g = 1`. +The finite ring rounds the transition off into a smooth crossover whose apparent location +is shifted away from `g = 1`, while the infinite calculation drops much more steeply near +the critical point because there is no finite size to smear it out. + + + +## 2. Entanglement entropy across the transition + +Entanglement is a hallmark of criticality: it is bounded away from the critical point but +grows sharply as we approach it. +For an [`InfiniteMPS`](@ref), [`entropy`](@ref) returns the von Neumann entanglement entropy +per bond, one value for each site of the unit cell. +Our unit cell has a single site, so we take the one entry with `only`. + + + +````julia +S_infinite = [real(only(entropy(ψ))) for ψ in states_infinite] +p_entropy = scatter( + g_values, S_infinite; + xlabel = "g", ylabel = "entanglement entropy S", title = "TFIM entanglement entropy", + legend = false +) +vline!(p_entropy, [1.0]; color = "gray", linestyle = :dash) +p_entropy +```` + +![](figure-2.png) + +The entropy peaks near `g = 1`. +That peak is the entanglement signature of the phase transition: at criticality +correlations become long-ranged and the ground state is maximally entangled, whereas deep +in either phase the state is closer to a simple product and the entropy is small. + + + +## 3. Correlation length across the transition + +The [`correlation_length`](@ref) measures how far apart two spins can still influence each +other; it is extracted from the transfer-matrix spectrum of the uniform infinite state and +has no finite-chain analogue. +It grows toward criticality, so we plot it on a logarithmic vertical axis to make the +growth visible. + +````julia +ξ_infinite = [correlation_length(ψ) for ψ in states_infinite] +p_xi = scatter( + g_values, ξ_infinite; + xlabel = "g", ylabel = "correlation length ξ", yscale = :log10, + title = "TFIM correlation length", legend = false +) +vline!(p_xi, [1.0]; color = "gray", linestyle = :dash) +p_xi +```` + +![](figure-3.png) + +The correlation length peaks near `g = 1` as well. +At a genuine critical point it would diverge, but a finite bond dimension `D` can only +capture correlations out to a finite range, so what we measure is large-but-capped rather +than infinite — the peak grows and sharpens as `D` is increased. + + + +## What you now have + +Three independent diagnostics — the order parameter, the entanglement entropy, and the +correlation length — all locate the transition of the transverse-field Ising model near +`g = 1`, and the finite-versus-infinite comparison shows concretely how working directly in +the thermodynamic limit removes the finite-size rounding. + + + +From here the gallery goes further. +The Ising CFT example extracts the momentum-resolved excitation spectrum right at +criticality and matches it to the predictions of conformal field theory, turning the "there +is a critical point near `g = 1`" of this page into a quantitative fingerprint of *which* +critical theory it is. +Every curve on this page also sharpens if you rerun it at a larger bond dimension `D`. + +--- + +*This page was generated using [Literate.jl](https://github.com/fredrikekre/Literate.jl).* + diff --git a/docs/src/examples/quantum1d/0.tfim-groundstate/main.ipynb b/docs/src/examples/quantum1d/0.tfim-groundstate/main.ipynb new file mode 100644 index 000000000..2138941b8 --- /dev/null +++ b/docs/src/examples/quantum1d/0.tfim-groundstate/main.ipynb @@ -0,0 +1,323 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# The transverse-field Ising model: a complete ground-state study\n", + "\n", + "This example is the bridge from the introductory tutorials into the research-grade\n", + "gallery.\n", + "If you have worked through Your first ground state and\n", + "The thermodynamic limit you already know every\n", + "individual tool used here; the goal now is to *assemble* them into one coherent case\n", + "study of a genuine quantum phase transition.\n", + "\n", + "We use the same transverse-field Ising model (TFIM) as the tutorials, on a chain of\n", + "spin-1/2 sites:\n", + "\n", + "$$\n", + "H = -J\\left(\\sum_{\\langle i,j\\rangle} \\sigma^z_i \\sigma^z_j + g\\sum_i \\sigma^x_i\\right),\n", + "$$\n", + "\n", + "where the first sum runs over neighbouring pairs, $J$ sets the energy scale, and the\n", + "dimensionless field $g$ tunes the competition between the $\\sigma^z\\sigma^z$\n", + "interaction and the transverse $\\sigma^x$ field.\n", + "The model has a quantum critical point at $g = 1$.\n", + "\n", + "\n", + "\n", + "Rather than looking at a single field value, we will scan $g$ across the transition and\n", + "diagnose it three independent ways, comparing a *finite* chain against a calculation\n", + "performed *directly in the thermodynamic limit*:\n", + "\n", + "1. the order parameter $|\\langle\\sigma^z\\rangle|$, computed both for a finite ring and\n", + " for an infinite chain, in one figure;\n", + "2. the entanglement entropy of the infinite state;\n", + "3. the correlation length of the infinite state.\n", + "\n", + "All three should point at the same place — that agreement is the payoff." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We take the model and lattice from MPSKitModels, the tensor backend from TensorKit, and\n", + "Plots for the figures. The Pauli operators `σᶻ`, `σˣ` are re-exported by MPSKitModels." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "using MPSKit, MPSKitModels, TensorKit, Plots" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Shared parameters\n", + "\n", + "We fix a finite chain length `L`, a bond dimension `D` (the accuracy knob, see\n", + "Controlling bond dimension), and the set of field values to\n", + "scan.\n", + "`D` is kept modest so the whole page runs in a couple of minutes; increasing it sharpens\n", + "every curve below.\n", + "\n", + "" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "L = 16\n", + "D = 8\n", + "g_values = 0.1:0.1:2.0" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1. Finite versus infinite magnetization\n", + "\n", + "We compute the order parameter $|\\langle\\sigma^z\\rangle|$ two ways at every field value.\n", + "\n", + "For the **finite** calculation we place the chain on a ring with\n", + "`periodic_boundary_conditions` — this removes the open-end boundary effects and\n", + "gives a cleaner curve at fixed `L` — and optimize with `DMRG`.\n", + "We average $\\langle\\sigma^z_i\\rangle$ over the sites and take the absolute value, because\n", + "a finite chain does not spontaneously break its symmetry and the raw sum can land on either\n", + "sign (see the discussion in Your first ground state)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ψ₀_finite = FiniteMPS(L, ℂ^2, ℂ^D)\n", + "M_finite = map(g_values) do g\n", + " H = periodic_boundary_conditions(transverse_field_ising(; g = g), L)\n", + " ψ, = find_groundstate(ψ₀_finite, H, DMRG(; verbosity = 0))\n", + " return abs(sum(expectation_value(ψ, i => σᶻ()) for i in 1:L)) / L\n", + "end;" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For the **infinite** calculation we drop the lattice argument to build the Hamiltonian on\n", + "the infinite chain, use an `InfiniteMPS`, and optimize with `VUMPS`.\n", + "We keep every optimized infinite state, because we will reuse them for the entropy and\n", + "correlation-length diagnostics below." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ψ₀_infinite = InfiniteMPS(ℂ^2, ℂ^D)\n", + "states_infinite = map(g_values) do g\n", + " H = transverse_field_ising(; g = g)\n", + " ψ, = find_groundstate(ψ₀_infinite, H, VUMPS(; verbosity = 0))\n", + " return ψ\n", + "end;" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The order parameter of a translation-invariant state is just $\\langle\\sigma^z\\rangle$ on\n", + "a single site of the unit cell; we again take the absolute value.\n", + "\n", + "" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "M_infinite = [abs(expectation_value(ψ, 1 => σᶻ())) for ψ in states_infinite];" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Plotting both curves in a single figure lets us compare them directly." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "p_magnetization = plot(;\n", + " xlabel = \"g\", ylabel = \"|⟨σᶻ⟩|\", title = \"TFIM order parameter\", legend = :bottomleft\n", + ")\n", + "scatter!(p_magnetization, g_values, M_finite; label = \"finite ring, L = $L, D = $D\")\n", + "scatter!(p_magnetization, g_values, M_infinite; label = \"infinite, D = $D\")\n", + "vline!(p_magnetization, [1.0]; color = \"gray\", linestyle = :dash, label = \"g = 1\")\n", + "p_magnetization" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Both curves are large on the ordered side (small `g`) and fall toward zero on the\n", + "disordered side (large `g`), with the crossover near `g = 1`.\n", + "The finite ring rounds the transition off into a smooth crossover whose apparent location\n", + "is shifted away from `g = 1`, while the infinite calculation drops much more steeply near\n", + "the critical point because there is no finite size to smear it out.\n", + "\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2. Entanglement entropy across the transition\n", + "\n", + "Entanglement is a hallmark of criticality: it is bounded away from the critical point but\n", + "grows sharply as we approach it.\n", + "For an `InfiniteMPS`, `entropy` returns the von Neumann entanglement entropy\n", + "per bond, one value for each site of the unit cell.\n", + "Our unit cell has a single site, so we take the one entry with `only`.\n", + "\n", + "" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "S_infinite = [real(only(entropy(ψ))) for ψ in states_infinite]\n", + "p_entropy = scatter(\n", + " g_values, S_infinite;\n", + " xlabel = \"g\", ylabel = \"entanglement entropy S\", title = \"TFIM entanglement entropy\",\n", + " legend = false\n", + ")\n", + "vline!(p_entropy, [1.0]; color = \"gray\", linestyle = :dash)\n", + "p_entropy" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The entropy peaks near `g = 1`.\n", + "That peak is the entanglement signature of the phase transition: at criticality\n", + "correlations become long-ranged and the ground state is maximally entangled, whereas deep\n", + "in either phase the state is closer to a simple product and the entropy is small.\n", + "\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3. Correlation length across the transition\n", + "\n", + "The `correlation_length` measures how far apart two spins can still influence each\n", + "other; it is extracted from the transfer-matrix spectrum of the uniform infinite state and\n", + "has no finite-chain analogue.\n", + "It grows toward criticality, so we plot it on a logarithmic vertical axis to make the\n", + "growth visible." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ξ_infinite = [correlation_length(ψ) for ψ in states_infinite]\n", + "p_xi = scatter(\n", + " g_values, ξ_infinite;\n", + " xlabel = \"g\", ylabel = \"correlation length ξ\", yscale = :log10,\n", + " title = \"TFIM correlation length\", legend = false\n", + ")\n", + "vline!(p_xi, [1.0]; color = \"gray\", linestyle = :dash)\n", + "p_xi" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The correlation length peaks near `g = 1` as well.\n", + "At a genuine critical point it would diverge, but a finite bond dimension `D` can only\n", + "capture correlations out to a finite range, so what we measure is large-but-capped rather\n", + "than infinite — the peak grows and sharpens as `D` is increased.\n", + "\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## What you now have\n", + "\n", + "Three independent diagnostics — the order parameter, the entanglement entropy, and the\n", + "correlation length — all locate the transition of the transverse-field Ising model near\n", + "`g = 1`, and the finite-versus-infinite comparison shows concretely how working directly in\n", + "the thermodynamic limit removes the finite-size rounding.\n", + "\n", + "\n", + "\n", + "From here the gallery goes further.\n", + "The Ising CFT example extracts the momentum-resolved excitation spectrum right at\n", + "criticality and matches it to the predictions of conformal field theory, turning the \"there\n", + "is a critical point near `g = 1`\" of this page into a quantitative fingerprint of *which*\n", + "critical theory it is.\n", + "Every curve on this page also sharpens if you rerun it at a larger bond dimension `D`." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "\n", + "*This notebook was generated using [Literate.jl](https://github.com/fredrikekre/Literate.jl).*" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Julia 1.12.6", + "language": "julia", + "name": "julia-1.12" + }, + "language_info": { + "file_extension": ".jl", + "mimetype": "application/julia", + "name": "julia", + "version": "1.12.6" + } + }, + "nbformat": 4, + "nbformat_minor": 3 +} \ No newline at end of file diff --git a/examples/Cache.toml b/examples/Cache.toml index 1b15ac166..905489698 100644 --- a/examples/Cache.toml +++ b/examples/Cache.toml @@ -1,12 +1,13 @@ [classic2d] -"1.hard-hexagon" = "059f9a5162d75323c7104a8fb178458f965db7bda1481021ae51d4fb8ec9cde9" +"1.hard-hexagon" = "71d189b9138f98545c4239ed80a922cc4182e934db30af5ba867a0cee57305d0" [quantum1d] "2.haldane" = "c5a0eb70f0930d38053535c659ab39a87121b6ebda040ceadd9deb5f30921315" "6.hubbard" = "cef140a6224350345735aac889ee7e33724fc0af9ce94f68be47a7e40107c09c" "7.xy-finiteT" = "0f330a157bea739a43a82a937791c680b2fa6e5e479171ee5ef318d1fdae7bcf" -"8.bose-hubbard" = "cf0d9a543e784dc6053e413780d19e1b59bf956dd4598752fdf664804dd68ce6" +"8.bose-hubbard" = "ba9ec53721371aab311dadbe05a31a3c95cb1b8a394abb7f81ee97e15b84d503" "3.ising-dqpt" = "a2900eed23de7655f600943fae72d1dc35f87f33d11947f707d302ce245399fe" "5.haldane-spt" = "c8fd3a8d406b9ff3ea9a34b596c5910d81e4eb710b665d7fa04e30f795a46086" "4.xxz-heisenberg" = "9033fb104c3f658ccb1b8e335b986b7abda59e0b5359be086d3b62e1cc32ebd6" "1.ising-cft" = "3d34757eee7b95120b746c5e30e713203a876a87353ecd9937798f29183c9916" +"0.tfim-groundstate" = "b42a582081dc9e3a92839360f92857d2cd5071184539fa658ef087eee40c5cee" diff --git a/examples/quantum1d/0.tfim-groundstate/main.jl b/examples/quantum1d/0.tfim-groundstate/main.jl new file mode 100644 index 000000000..71bce351e --- /dev/null +++ b/examples/quantum1d/0.tfim-groundstate/main.jl @@ -0,0 +1,197 @@ +md""" +# The transverse-field Ising model: a complete ground-state study + +This example is the bridge from the introductory tutorials into the research-grade +gallery. +If you have worked through [Your first ground state](@ref tutorial_first_groundstate) and +[The thermodynamic limit](@ref tutorial_thermodynamic_limit) you already know every +individual tool used here; the goal now is to *assemble* them into one coherent case +study of a genuine quantum phase transition. + +We use the same transverse-field Ising model (TFIM) as the tutorials, on a chain of +spin-1/2 sites: + +```math +H = -J\left(\sum_{\langle i,j\rangle} \sigma^z_i \sigma^z_j + g\sum_i \sigma^x_i\right), +``` + +where the first sum runs over neighbouring pairs, ``J`` sets the energy scale, and the +dimensionless field ``g`` tunes the competition between the ``\sigma^z\sigma^z`` +interaction and the transverse ``\sigma^x`` field. +The model has a quantum critical point at ``g = 1``. + + + +Rather than looking at a single field value, we will scan ``g`` across the transition and +diagnose it three independent ways, comparing a *finite* chain against a calculation +performed *directly in the thermodynamic limit*: + +1. the order parameter ``|\langle\sigma^z\rangle|``, computed both for a finite ring and + for an infinite chain, in one figure; +2. the entanglement entropy of the infinite state; +3. the correlation length of the infinite state. + +All three should point at the same place — that agreement is the payoff. +""" + +# We take the model and lattice from MPSKitModels, the tensor backend from TensorKit, and +# Plots for the figures. The Pauli operators `σᶻ`, `σˣ` are re-exported by MPSKitModels. + +using MPSKit, MPSKitModels, TensorKit, Plots + +md""" +## Shared parameters + +We fix a finite chain length `L`, a bond dimension `D` (the accuracy knob, see +[Controlling bond dimension](@ref howto_bond_dimension)), and the set of field values to +scan. +`D` is kept modest so the whole page runs in a couple of minutes; increasing it sharpens +every curve below. + + +""" + +L = 16 +D = 8 +g_values = 0.1:0.1:2.0 + +md""" +## 1. Finite versus infinite magnetization + +We compute the order parameter ``|\langle\sigma^z\rangle|`` two ways at every field value. + +For the **finite** calculation we place the chain on a ring with +[`periodic_boundary_conditions`](@ref) — this removes the open-end boundary effects and +gives a cleaner curve at fixed `L` — and optimize with [`DMRG`](@ref). +We average ``\langle\sigma^z_i\rangle`` over the sites and take the absolute value, because +a finite chain does not spontaneously break its symmetry and the raw sum can land on either +sign (see the discussion in [Your first ground state](@ref tutorial_first_groundstate)). +""" + +ψ₀_finite = FiniteMPS(L, ℂ^2, ℂ^D) +M_finite = map(g_values) do g + H = periodic_boundary_conditions(transverse_field_ising(; g = g), L) + ψ, = find_groundstate(ψ₀_finite, H, DMRG(; verbosity = 0)) + return abs(sum(expectation_value(ψ, i => σᶻ()) for i in 1:L)) / L +end; + +md""" +For the **infinite** calculation we drop the lattice argument to build the Hamiltonian on +the infinite chain, use an [`InfiniteMPS`](@ref), and optimize with [`VUMPS`](@ref). +We keep every optimized infinite state, because we will reuse them for the entropy and +correlation-length diagnostics below. +""" + +ψ₀_infinite = InfiniteMPS(ℂ^2, ℂ^D) +states_infinite = map(g_values) do g + H = transverse_field_ising(; g = g) + ψ, = find_groundstate(ψ₀_infinite, H, VUMPS(; verbosity = 0)) + return ψ +end; + +md""" +The order parameter of a translation-invariant state is just ``\langle\sigma^z\rangle`` on +a single site of the unit cell; we again take the absolute value. + + +""" + +M_infinite = [abs(expectation_value(ψ, 1 => σᶻ())) for ψ in states_infinite]; + +md""" +Plotting both curves in a single figure lets us compare them directly. +""" + +p_magnetization = plot(; + xlabel = "g", ylabel = "|⟨σᶻ⟩|", title = "TFIM order parameter", legend = :bottomleft +) +scatter!(p_magnetization, g_values, M_finite; label = "finite ring, L = $L, D = $D") +scatter!(p_magnetization, g_values, M_infinite; label = "infinite, D = $D") +vline!(p_magnetization, [1.0]; color = "gray", linestyle = :dash, label = "g = 1") +p_magnetization + +md""" +Both curves are large on the ordered side (small `g`) and fall toward zero on the +disordered side (large `g`), with the crossover near `g = 1`. +The finite ring rounds the transition off into a smooth crossover whose apparent location +is shifted away from `g = 1`, while the infinite calculation drops much more steeply near +the critical point because there is no finite size to smear it out. + + +""" + +md""" +## 2. Entanglement entropy across the transition + +Entanglement is a hallmark of criticality: it is bounded away from the critical point but +grows sharply as we approach it. +For an [`InfiniteMPS`](@ref), [`entropy`](@ref) returns the von Neumann entanglement entropy +per bond, one value for each site of the unit cell. +Our unit cell has a single site, so we take the one entry with `only`. + + +""" + +S_infinite = [real(only(entropy(ψ))) for ψ in states_infinite] +p_entropy = scatter( + g_values, S_infinite; + xlabel = "g", ylabel = "entanglement entropy S", title = "TFIM entanglement entropy", + legend = false +) +vline!(p_entropy, [1.0]; color = "gray", linestyle = :dash) +p_entropy + +md""" +The entropy peaks near `g = 1`. +That peak is the entanglement signature of the phase transition: at criticality +correlations become long-ranged and the ground state is maximally entangled, whereas deep +in either phase the state is closer to a simple product and the entropy is small. + + +""" + +md""" +## 3. Correlation length across the transition + +The [`correlation_length`](@ref) measures how far apart two spins can still influence each +other; it is extracted from the transfer-matrix spectrum of the uniform infinite state and +has no finite-chain analogue. +It grows toward criticality, so we plot it on a logarithmic vertical axis to make the +growth visible. +""" + +ξ_infinite = [correlation_length(ψ) for ψ in states_infinite] +p_xi = scatter( + g_values, ξ_infinite; + xlabel = "g", ylabel = "correlation length ξ", yscale = :log10, + title = "TFIM correlation length", legend = false +) +vline!(p_xi, [1.0]; color = "gray", linestyle = :dash) +p_xi + +md""" +The correlation length peaks near `g = 1` as well. +At a genuine critical point it would diverge, but a finite bond dimension `D` can only +capture correlations out to a finite range, so what we measure is large-but-capped rather +than infinite — the peak grows and sharpens as `D` is increased. + + +""" + +md""" +## What you now have + +Three independent diagnostics — the order parameter, the entanglement entropy, and the +correlation length — all locate the transition of the transverse-field Ising model near +`g = 1`, and the finite-versus-infinite comparison shows concretely how working directly in +the thermodynamic limit removes the finite-size rounding. + + + +From here the gallery goes further. +The Ising CFT example extracts the momentum-resolved excitation spectrum right at +criticality and matches it to the predictions of conformal field theory, turning the "there +is a critical point near `g = 1`" of this page into a quantitative fingerprint of *which* +critical theory it is. +Every curve on this page also sharpens if you rerun it at a larger bond dimension `D`. +""" From c3815c58dc07aa22ebc9f1c923ecb0052c3f4703 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Sat, 4 Jul 2026 13:51:22 -0400 Subject: [PATCH 32/76] docs: refresh stale rendered output of haldane-spt and bose-hubbard examples Their main.jl sources were edited during wave 1 without regeneration, so the cached checksums no longer matched; examples/make.jl re-executed both. Diffs are floating-point noise in captured outputs plus refreshed figures. Co-Authored-By: Claude Fable 5 --- .../quantum1d/5.haldane-spt/figure-1.png | Bin 32871 -> 34236 bytes .../quantum1d/5.haldane-spt/figure-2.png | Bin 32025 -> 32088 bytes .../quantum1d/5.haldane-spt/figure-3.png | Bin 37379 -> 37375 bytes .../examples/quantum1d/5.haldane-spt/index.md | 8 +++---- .../quantum1d/8.bose-hubbard/figure-1.png | Bin 16373 -> 16582 bytes .../quantum1d/8.bose-hubbard/figure-3.png | Bin 39405 -> 39270 bytes .../quantum1d/8.bose-hubbard/figure-4.png | Bin 36800 -> 36932 bytes .../quantum1d/8.bose-hubbard/figure-5.png | Bin 35226 -> 37038 bytes .../quantum1d/8.bose-hubbard/figure-6.png | Bin 15426 -> 15425 bytes .../quantum1d/8.bose-hubbard/index.md | 22 +++++++++--------- 10 files changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/src/examples/quantum1d/5.haldane-spt/figure-1.png b/docs/src/examples/quantum1d/5.haldane-spt/figure-1.png index 5d8edbbce382990db34b736598b756254f3ed724..31124b5a5ddb9cf04911c80c753d4fb676e55a9c 100644 GIT binary patch literal 34236 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 Ou6$lYK11%3_x}P>LODAC literal 32871 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 diff --git a/docs/src/examples/quantum1d/5.haldane-spt/figure-2.png b/docs/src/examples/quantum1d/5.haldane-spt/figure-2.png index 1df134303b1bc1c9099bfcfd8322f961099235e0..f9d22360f133fc8811c5f63b8b04d9e047fbd663 100644 GIT binary patch literal 32088 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

    >VQ!vZRplr!=+>tq{O&grFJkD$aFRYT2}vIX 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 JN!;Mw{{l5GIj8^t literal 32025 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 B7DfO7 delta 18122 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 z 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 diff --git a/docs/src/examples/quantum1d/5.haldane-spt/index.md b/docs/src/examples/quantum1d/5.haldane-spt/index.md index 8fb8dee4d..28f90de21 100644 --- a/docs/src/examples/quantum1d/5.haldane-spt/index.md +++ b/docs/src/examples/quantum1d/5.haldane-spt/index.md @@ -128,7 +128,7 @@ E_plus = expectation_value(ψ_plus, H) ```` ```` --1.4014193313393009 - 3.851708855717825e-17im +-1.4014193313393004 - 2.2233521403023605e-17im ```` ````julia @@ -139,7 +139,7 @@ E_minus = expectation_value(ψ_minus, H) ```` ```` --1.4014839739630844 - 5.800167584873572e-17im +-1.4014839739630827 + 6.744598315147384e-17im ```` ````julia @@ -188,8 +188,8 @@ println("S_plus = $S_plus") ```` ```` -S_minus + log(2) = 1.548622723541372 -S_plus = 1.5450323530299226 +S_minus + log(2) = 1.5486227235423025 +S_plus = 1.545032353055433 ```` diff --git a/docs/src/examples/quantum1d/8.bose-hubbard/figure-1.png b/docs/src/examples/quantum1d/8.bose-hubbard/figure-1.png index 2ab23add4762bc48733092ba0aa888d34f863735..75d0d96924a7487c87e7a3dcbe251cb92fa8c0e9 100644 GIT binary patch literal 16582 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

    FnHG1xs{s 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

    M;iiL^zAZ?OIG1inzdm+2 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 ieNr5xrV4E!B?BV8{nc5{D)36kh)Gv z%-_~3LRolb&;LUA%_wL4BhPj zCr#F|riC$58h<>zxouBvV8PzBDm~R-4$I580#okn?A$p``u6RWv2lt~ zJqEYMlQ4(tRMm5@rD#l?eiA=YqQ-K2|%o4#GD|V|Bdk5%}9ZjwMvftnuvm; zWkLP;_wcYh-8);MI*vbfpzVNQ3zF}8+7<+>0o()N^KzV!T^av$aEJ*r5Jm`2pE8Kd z=H{R#E+MLq;QSP%7S4ld+!%*fWobJ%uC^-IjC$~^#eVrGbu;qjZqgpfoMyLwdIDmK zk<;IHrZE^`|E$@{;^LGpjTi7VxQ~^=h3=%Y)1x(FP+Yd$? z4BuM`dp$5ii6jAS&C4#V+!BH)GknatZ8b=^#>a~mS|q%C2l-Fbl;qDBFC;LBA1RL& ztNj@EQRI8)B`J2WS>|8k(%No@D-L4=i0jbsaH~m?5N9F)y#4FJdtZx-0pmUm?>mj_x}E76Fr@zN(Flq$nvNhVmqejAL%nO7Q4xpb22wsQj31~Me}lb zJB+S}q~b-V&79)^n&>!Cbi;4n?da@$ewG9{TDpmQR83u48V;ppEP!O|V@!j$pE-ihI(5l-xg06|VIG`L1*$6FEb>&{ohWEx(P=C8ro1F$fL z3W|%1L0SO=hDZ_~3dHVXWo8-a-VJ#cg&1R3zv_y-B}Ypr(=6e$&EC8$9jb6FCYL3n z=J(9(lhTp$#K3UPX)1e82#kyXMow>U>xs(Yx;o!9JBV$0v^OYl8C1gQI1>s9p#H0` zL=w78!s7j@VW}bx~14mEG?+SGH6 z7t)`6Z=_m&hQN~;TLZ-qToTZ-Z`YHvdUh#`CI5%ihb0VO}nOUA=WM_Bhu7jtiCxi|R3}_4kHxYyk zgNB&u-j2zI2K4b?SUfw9s_Zh;_BZ!A5%gpi0uB*t)W?K`N9m8@Obrh&FF?@1@%_gZ z7OWM7aQcHoyU<6Gslh(Wh(WcdH1VgX144>?^}>9Yv~gbJs0W8J7L$f04*J!rJe~O7g!0}o8u1jeoeiIkx>YlIPBa2UAU6p)Lg!iT z@}5l)kbzv}>6BVP?sG*_j)6EYH~0HM9t;PtJZer4*=T8vz#Cd=hKTSoGy&W1V3^(V zJ|;qKL!=7$gov;(csP@zqZRI5;)qxk^}bIu)ps`{Jl{yqFr;San`>3By$acBzsAR2 z6pmf{t0|qZ8f=Jj3W#6edS1cc6Tsbr#p!t#4VybNbK&1;S%pmyh)LC6CvMPxkSUKo z2|!O6BE6ld7hiQANduyr(NcH(qvaOQictx+|Efrx;3&-&%=2 z14k+oh&4b!a2=KzmK<^iVuAzv<>2anii;~URFIQ{5Px(`44jU2E~|uu zlENgA6yRxixQA;Jt)OJK=V;V`^a~mZm@h89qqP7s=+OHmw&PRYQ>EYAap;^C`K@C} zEJvL*vctZ(&#cTPwo7fxq(ANkkaDsM!-9#42@~HZYB=%J#}|X5VzzR@FEiehy*yDK z5sq566!fQM_@1YQpgjEEO{e|!S*zdWs}NXcA$^mVXT4{5((n_6HB3xQ5LTgI4E_40 zVqoy{*)w1z;_f)x3UD5+oZ=QZHGDVD9clL_l2`39)$K;y&^amul?lno1DcdB&jUQm z^xmubmVRFyi9%P)?htI=@Ybnd5I`NUO`7n;sk25YWfo6@n~B$V_Uzf$nU&;Uqjs5p z3`$6@JRIQP^tK^T(ZAEsYk~{>f|B)+FF{F8?q^$D_R&9>g%H^3E|aU2&Flj)5h9V0 zOViQSh0Rs*8BW{mR*^h;G7M3+T}##|Ru?hc7Bp6+s9yM!m$l|7qa?R z7^|_|zOB#T@DUtscmO^+I6jakFeGq=YMGy#D>8%=p`#-sALHVHSngR(dpdHP&8FmT%#t1^T6K2FiTi zuSuKw9VP|u8%k{4`r9dMgme9WSpa?~x8-q6l#cpSo*t|wtrI8bia=$`M1&=WZ_hHX z_aU4co$#yxM|}wxJT;Eh*!Op9KU~7#xMvQnj){Jk5jjAb63(pS=?EsKeu zf^~(Q!nh^%-g!y@{I(52(gIJ2-i?<#0d`x_b=%q55i?cuhz4U0(wjmzAZ{d#-3NPl zY;4Ts6Z!UFoLUS1Eo9FJ(;g9390iN+ItKt@E2oYb#aofGIWaWBIy2hLT){l;QfuU_ zGKT;9dL`+H;+GUYGC7V3Q-3kEp_S>CJ^N*H>!tJFs5I$ni=!?=2Agvh1?RS40IUo` zssLO`NHWFpTapJ$&3FqW{%~G1aB=xwRCMPkE}ULA9Iv8Bf1NQ9U#e0LPkHE}u>`)F z#@SL#5_$ab)-AA%SD(HLT;gp<}PeU@7MC+dMbSH{Xe*4gSqVnYGsqee?=mH?E*Z7^g<%Af!pH^yY{+ag2K2q9uDEqC;cu7^7CuyfFV)FYViH9tfPhq)E z5057)J_*{a!kIAF%|8u+1kgPyM&%iLK}8!MAHPf%A(){U_Z4XCDn=3D*Hz=kkR(!2 zm_`3-v#=;3I~$FCtMqYN6sJO^AvQJk*WR*Z!5`80K?>?Gv{|P(LcEnf{}p(oyAT1G zaDOr6%oYyr0zj|?``OmEkQQ^}bz0giBoJq3XZKdekCytFMQI53kg}n#Tha#D9mfCY zN%VZ^8StGk3}Pa)82cf(0;P93@NMAEX9Db}vjteg$)y95T+CSGOp z1d-N*R*ZSax5PXD4YGbs79_LlJ=CbP(Ng?E=;f<@vllD!&DN7Wd@S05LOokDpMvGd zJW|l1(Z9Y~kGgR-2yMgKxw^Z@#KaV9<$=TrC)TJ+x3Xku;4~GcY?qw`{x%MNV6?7~ z=HifE71`gnjO-8lqw;x`ckui4gk<{aE-yQt+ih(1a7+hG^^dW!izgD`)5CE_Tqf!Q zZpu*5ED8+;`S}yX+`lb^DRX~-v=>)xi)CPUK@UZm(Qf9Hxg64Zb4dTIy-aW;Z=)3% zNBZos|`LUJ1_=5*qDd^HZOA$EaK+U+( zn!dtN`76#IUGM2)EyThK&DY*Y{818$WIuloAFu z+!Xh4fyWPtNPyX-xZrdYI!EI?7m(~!yhGvlS5#=s$LsszW+ z{$-t$PF=M6f0RC$=VcM9Rvlo>)~lp$2*?yE?sJfUp79LBZfR(kh2x3Ocn*N!0RSaY ztgbVPSl*p*EQBv>;pQfcluKS4G2?4BIFfFAI0Kvau=E|n6o=T?ptD?`zQ0RkS>D7pTclejP2?>gW?$DSm>N7)v%k~nQxzBuZ5(x0Di zFKY1d$@D(^x=};OEcZAe9@mMkc}HVoV{`L792)U>hkEnJ6LmseW3d4YLXOt)byE1XUg>MCU0fC|JU|V^Q<>@Dyr^{i=DR zh^{8yu+^R)Zt>gF9JVm2mqE|RT|YYOx#6tj`hw5^E8uILO3M>u$eTCu2?;e{CCNgX zKuwr+VC6Oe%olL^phf>ja+Z%x^4C8a*YIyf9JU=|12qMSK3(NDkPp9lvu*k_8Lz2KH8Wfsma-hRGVSmaTqz=4+o?4^0);Ipj z6B`xVk>$Nx^W7gl`*&Ws$$6O~n+(r1yK9q3Ga=aN9zr~#n9#z~(q{PU-16jbxf9#u z=KAH=b>9Iny1EMcOWsF5fAIpWJENNxeBhb6e2Tg8ZKH++P!JNWqNLOXEe|L>7R6f%z)A4s17MUwM}-Tl0i#1KCRmZ?MZ49bX|sFX zt#VBa1XCouPd3)&?=G8i$lpxT?R)2|{r`yi3aBdDF5E*XN2NhRkQ4-@ML_8eK|*Py z8>B-T=|<_0Zjh4hkWi42ZUsb;2I;(;@4t85vu1sv#GE zaZwoEEvI7RvCW>lj5H5#c*eMIZ%6GEe`OMtW%zhh%%=OTzxiRhmW5#bN}7Y9%`j1J zC7OSR_iEOX7u@ia9y{&9c(hQgBB-FS&L06Gr{!>t%n==b4=xgYVjyGi>(^E0;X88* zPQw!7;0eSoYX_`OYhMR`l4OTLhrA zY6;KS@fKTsH`KKs0-_sOT$EnNnGQbR-&2dhvS<)umx7XWrq#Rk$6Kf7Qm78wjT=7F zJbij%^;Dn!s>04C&1}EU{6#2oO-BiTp*NFqO-j&-yQHc;I)a@$T*kaNayYJ(x)-a04kd1y|L-0!qDu0 z&#*D6v=*4w-p4q7KswmlKV!?;0J$6VNDYr4^ZXUwR>?L(Zzb_$_T!V3 z%W0jbhu^kE1$jRXdk-fx;uvMFwrWkHtl80YX2liu6)q^42+Kll}b8~dEi?W3+3}&-Ha8zR;1jZ-8VZfNYZbgLJpZ3BS83h3<0cV{VKObH`J=A~`H{hb)8Kw8qtw z@$1?Z?hpue_-77861x3%{DACJ0ZRl<>U5~>|&25}VhP%9k zSeC`QU3a(i6W`=bZ#I>$+^FbdZ%MDD4WOWY&343Y^z}V}7SmST$$9RpJr@An&wC!t z4Gk6laEukxTPp6GYnGNIqC1~Hiby?7O1uz(uuQl*9xIxkx#Y!Mzajei zHg2%sz4LE3YnKu_YO;b9_NClt6BC-ep6Y7;UOcT{=)EHCo7kmUx#h+tTCX#JP2~2~ zi9;GiS-C`7cyHY|u|5W$8VuTF3A%1(p<2W<{Hjn*zRMVat2P6(z6e+QL)dpF= z->Qd1!n08dx&YE91eov>}n z-#GjFCg9Kl|L8E^iu(-qEdnIE3*MIq>1eKd5ffNj%|emn(++0eg#HZkKknQ+F8Y2X zbUFKOd$EmxD@o2}GE%4PYPW}yPl_0B{AWx|Yx8J6*1x|HH1q6?lx%s&2U@V~4`7q=JuW8R6fmaRE{?~5+q@dN5Q+vjF^KX~1G8K=@G-LXfO)94@c|qK>`Xd{rDgb@AfX~rfo|kXb^-F7jJ|$L0q&Bz8Ue-DIhn-#V zj9iqh>1h4KPLs_SL*S`5*1pEw5g+<})PGkuv4|(dq9)nG%kV7kpF5k8dz7v7*CDa2 zF!4k<@y(uhb0F|*WTB9HX8-%EmQAw?0KCADfKfl~+KqA|!MKNo$%;-YzS%_Fnr;*%QHo{>xEm7Q`>{LI(4lx>{lu z2WM@?!9U%9TIaW8veWX5#k~3j9IZc%Vdw{pZPa}~Kv}31y4%V6INsZa;bNeOSux#< zsJSkY@`O^S^EpG$m#KGR0xHBI*E26b90aTr%^tc7sk@zyg=V-lx4?W2T65O!BPmJA zdzgX1{{fp10L5ptE@2V|;%G%}ZE`Ti0ql127o`VDpl9=GK9rFJ$S7s{7xc>yqV*3J=7mX;0<3c^6NDJ|(ye|_z~>h;qL-C_#e2o~bMh9&l3dEKV|rAzCW-vA5!z%U00hwvDHf5Iy|8b3f(NkhY&O$A3}$j_!=&?gD4<(7N5 zslulk9TyV)@K+d`$A2SFV@?o=c$ee{EF*^YaT$XKu}jt}zs(1lCu`=^9K6!1X(y&C z#012M)%-zm$i~Lz4HlXJ>~H3Vg-aTOag}FCKMFhMBWC8=a((Cx3q73_$$P*|XtR=v z3b}@djt>4Cef9!ue=uz7YnLIM_FW)pY2C49s@5j+!K;ChU+ynkcG z@&#eM`ye?b>2HIdSS}%i2WRQ*yRGrvXnDQq{qjM~SZ6F)XLzDtZzX=k@(SI2jGs~d zjK>jfjv+xh;p`v3S5_>!l3@Y|E>$aO?prOLf22W(&<|3pji@n;gVDm5shnsR?fa+a zQz|#k(nvGjAN%<>HT$(*E#|YhpB>6?oJu3@1Epo;jx%hq-=(2egeSI)o zGS~Q+{_U?$6hYtOpLTe$UANx)66~PAiBB<_k$a+5vS)RccrSLd_f}%tt&iXLyfE7- zy0SQisvAlfcR_S|J!)w2za7@)cCEyP`e+O1`v(}#-SQ<7@@h&*AQr&|Cmi-W&eM$# zE3^3>zGz2Wn0v54&2srStMSsFZLDp;X!TtH&1zk_+L_xJ#qA4=e=W}yQl2v8>+ZyL zN3XH;j7UX1w@t9Uq_`DqKYOB7wwJAw>o`U~#T~QZl2Y_lz5a)KJs!0Iw?}L(kbNo??b|oep|m!u&_Sate5T zfO>)cH1+wW6g^i$hwF$%SB9Ms5PJSOzE zetDN~S)1zN+G1#VVWBy+I;jf4HVwogI~>=tadLQtEs5I+8wx+HI(Vc^75}|vu}p~w zFvNyp|HVq^p%B%Qk_vj<@h-!g<;h!TUxk^0ayIWdmlIL~vgJdCLQ9p4v=g0<^7bFr zhQ6-a=cg@LvvkV1wQ{(%;lmTj>nNrk@qkZ1&t)J{{HJ zUKUWXk~PYx3DF}LrCQsgy!@!2#Q&lF(=8UC_a!#-hx$oO#oj{%t~UOc!+QgJY-aPEnG>#|!oUgKv$GWR7=S%`da2MzA|?GIpvxf8^U- zU)Rak4I++0JCUJQqICg|)1-wN+Sd74SM!FD2>X{exoaeLK09PjK|7g1!ryO{m{@$xZa>o|@3_YEZi1x zYtW!#*6~VeJdtB*cv$jU91ON;Ug?5B{Tqlx`fi1!8-4XQrQeQt-Ryd{oFBm)%cG}f zs72{|QIk0Ovv<{Vtow(^><f*2;z6d&X3O_i&I4|>4@ALaAL3Q!UmQs=OS~4~1 zbTfm~F5>LmtdZ?>o=7`P_;;5Qi4ZQ;>uMYUl7`FM|3D!x^zZv);GAieaMRIsja2r` zKJ(hFo&XhYZ1Qk(fi-!oN7 z|M{I>i2OIVj@Mi{T&`~tqvewS$?N<_#Q6=;`BvjLREpI=Z-L6Xa*F)ky|vCZDrAF@|M}|j;3wXsDyP0Y z2L;ke1{+~<9Q6?55AJ8@u#Qk6bF1 zcfU;g%BD=U7!XhwXstn|0rR)(%|@qGI#>BV|69fEA988@^%yJ-Z;oI`3Kq}0y4d!X z%;sQa-GYK#GW$c%(o;TGq;CVIZ@#1;-;Q6^Am>Ct+CVri<`M}VT9gSLo$Ct5!&J+P zkJg;&)|^N2pSy4VTb$EysSQULMQUuJsc)e@t7TU$k$~=n^F@xJf`SIYHXFc z&ne5+s6tCJLAETdR70rWm}SKiyBYfVHC{Z4u?((gFg}exE)_FztnIstQfx<08q8a_ zT){5}*unb)eA|$$dN|Kyn%VTzvlJDK zs=F?ug54tQtR48YBxLO;$N>pb_ieX*N-shaL?D)+8NfjF+*`_ep6ml zA???zop61lGH`kkVrNgP(8!tu@hqyRLBR+nFvqGGP4FgxTXQ&}>%G}V)j$@S1)d0? z?V&qj98 zye3M;$-*E=>c)>bu)eLd7%PHj%ak5FSakrbvAe(^@MCuNd@JiD;N&T$nClt3N0Yr1 zFx5ZaCqx$*V*h>+@i6`s*4L@yFWn&)M7?CVibi}|4e?3Qd;L2(VQ=EUROjK}aIG3} ztQsKvE6Y#RCckS!uzI2HLTntO6i?z4%r}*kDTirn!psy{!_G}>_?VsW+vL7a4JS9P zm=;28BW%_}VKG8rnG7F+Y52`H?|^qgfaU%F~aCIarprw0NBt#O5w(UY(JkAquSDxL*YP z*e*GLYWSVkH0Y)X)Sf!u`hG^8oqSbj5_9jUFH95eJ$GIndAu@0ALTAYSD<9Wr)l|Y z%!u`+W?$@h1l?Cf-2q$gt=9XBBPF=uVS3ta(Y$=`gW3;jwVIonp7q_G>jgSfbCcV! zvKXw1lV5%~xah8CpQ#XfT|swE6ZnDTKjkqpWF9c4Y)`J@abK zhuurKuJu!5hKZK7b+>(j4ON-q25#T-bt4y=7&`iSR^w%0ALqp;THMSqm@q)|v*gNa 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 q7x!;CEYL&-~8sUS!?FH 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 diff --git a/docs/src/examples/quantum1d/8.bose-hubbard/figure-5.png b/docs/src/examples/quantum1d/8.bose-hubbard/figure-5.png index a33028f2eb2ec4a897a1834e864b55c9c3cf237e..450c0c63f9dcd74bfb0c5d67b415b5af245c257c 100644 GIT binary patch literal 37038 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 TMSnMbg`};auU@KZf93xG({`+} diff --git a/docs/src/examples/quantum1d/8.bose-hubbard/figure-6.png b/docs/src/examples/quantum1d/8.bose-hubbard/figure-6.png index 805386dc73278b942b87c8a0974aa70b11ac28be..54b85d98d41d8c3993cc136ca8a0c08b980a656b 100644 GIT binary patch literal 15425 zcmZ8|2Rzm7-~UOflgJ^-<|JFlEIWiKd(X($K|(g^M1?4$knA0jEvqCuSy@>jJA1GH z=Nvu1=lA^GukQPHoSf@>U7ztDpX-^LiUJ7{4G{u?Ai1e1r-48a=phit!jS~<%D(Qi zcKFXpb7ciN#3AmV#Hx%41cC{1Q|`K!``d*f4;KpU>QhUDhCfvrRfH|iprYkag#E8j z7HU-egi$y8v1H3xj}x!X-WLmbF5d9@6cML98KF9gknjmNij2VQR8%;Y1%30>N7tVw z*~5&JYl5dIhB+M`vdt_`t&M4AJ2(u5r}~v^Z|X`#u|Fq7AZm@Xj3r=62wfQ_Lbb+w z!iys{ha0;$Z{M!kS3yW$A(TNpDZvbuc&z>zT%0POddJ1Z^=aQ1Ax(|@iRA8lVSk~u zNEZ_uTZ4_D#%_$L>+H_@+;-?0#Kd*@g~^GDiSOUPcO0n}k+3T^7;zsDJ={(>q!zGh z{X6t2Zqe>fYYYbm$6gQ;aSw$&7OD5iZJ{+rz|qxZe`lRpKBTY8YqQ#CH_xQXb8WiA zs)C4=H0;HT@87@wky1k3NtD?k^fyXo|5jgbX=QbikkDzyX?J7c)5ArRV!QLNhY`}0 zt;k~*gQbq9HNN}qH?GSxPIshqb#~g>+k3bo5%cho7Vrq|u!;vcDM6%+zQ3QbMe`U} z*mNZC?d@%j_$3S^>EzH$`R+X&@o8{ZS&eLV6!gaB7 zRmIcO)5gZ;#*O-_&0#|=EiDt1JRQx0>DHDOFZi|Ln#fUa16@)?V$}9*PJa6BIJYkL zH}UZjUK{i92OAhjE<->-aFLn$lgo@uXaF|+d%W10fbfWju3~%LgU2WR4eQd>5gyfh zD=n~pzt(;fwoB4dQ(yDma+;CN>G7QJE0~zD`1Wq9HKx#Q!9X&F5MhPHB38P4d%e88 zM1~G`7i$hzT6iN^Z-2Z^Sy)&IM~S)rvbnuIjO7?3VhaKweCnkFL;nXe*{*#ymA6b- zVj98561K~ibB#Z_Jsfh??fQ1�l%~Z*7Yrb~0%YPJ|Ey9#-w|e7a73hL1TX|6Q?t@Ap`t zmPg~TDbld)h4dVQzty{c6&O4wT6k+NVfVJi!^9r`rIYY*?9F@OsY|G+4F8*1xkkhM*hkWcMe3F!fzKdR4?@W#V?6 za44~Oy@aA9h_7H?Rps(X_Y<5hGi^Q~UX!iMy!(uFm<>gztps&j?B`?>?OvX0E2`m~EQ zeYsoT=#WRE1tpmYO}e<4*N` zGN(K#f$I15Mpv1?f zQWKEfczK{uOOkN0P~zcbQ4|3}dhQ}h-Qvy6@D>M8pfnN=>!}>dB2c)aCkd4!e+*HZ zYbK9-Rquv+`1XX#=N{4>IVNZg4ssWps{}bqB_84qx;8ZGsSbDaBTAMnZkEH;R7RHZ zcc_atGfia|>%v|oCXGZ;3ay!s>EBR^o_bVNq=+2(mx9N$jls_lSCi-ajTk7u~ z()~|q=VqE>Ssx9D>D*WhnlUO8;ksN$?oCo>n5R?UNxILb*5c%$R=2cvT%fL8ubL-X z*iPn9UhUZmZ)im&k{m)20fjIGVy;Zx#kRX%Kn53cqw?W??d?6m@?^+k2!F=wmvmw_ z_a?qGmCNFvgz%zQQ)r8BsCfY~E=r*(ApB{6F=Hte;(gz5pEQX-sV+t)KI4H6c)`*e zp2QevBpWR*!zC+qt2~fcd$NcI4(fC;?ia}B;NuvXJp%E=?P;!){8KMn z{`}-)#_jccte&Nb`FVGvS5@>!+byl7qi%91V(^{V(E~DZmJ5iJ3BbeJ2oNT}@`Gpp zpm!3NdRExKJWH#lSs3m!Cp8C=qC4e!E6A7uy=lyw6=ctvuvN4twn*@Lw1u32tOm28 z1LMAtsKK!tGEbw?@h>~X5{MB3e{R7nH$v(!;*e788V=i>8}U+ zQoTEDN@GZ3$|i(;b+V;EAO_AJ!v{~izTud}zcZld31D|zfA(wRmlgUY!46i zr@qI3n(3IGoec>IdHa^GexDhl5+Tx=rmmm=hd1iK21bKbJc0|^W#&z#uXNRYh9{RKBJFL z?d|WMBPXY!HxI(cJ2KheuktGGM@HEED$}gDep54MGF`#8-*p$B~2Wqy-q>IZ0R>~L8^*RpA-MslMKR>@Hw|6c$ zICvrKdz{E(U%_2?Y+qRM&s@Wdd5WWl3{ZG~-n2M1BV%)MWW;wWl0);I-+_nBQ}*XN za|wQ*kpXuK^ycHBYS%Y3K$AG=w@!$^_TUfnwA?%Y_DNey-!fg6u%vf=rt87>%H)Pv zN^){)=#L+2DIM$>+R$$RsQN_=OYZe&B=}})WW9=rfXW^h6(w}17Eyjz{wV(ke!ouF zqPZDz&!+4|Sf7x5UVx>-Wd=_6g1+@V!biAzLH1PXuY^pbS%8jo{QZ!DZ-rb{ zR!Kb(zC4i2!O;iyto##XL^Ph?-aJWSJX6Jh-j}kpx)y1G304IKa?_nm_-#q4o4{+!0sjgbnUbg zvl(OO1Cspe+Hm_us3+YYCz$z*%o>?f|IozddOH)|hHW(9k`0v(^wpasgP(rvX0~Y7 zr(m}Y;9ftx#a(=o`rv_JzSBTI}B9-ypN2GY>gFCPO}qV9V&ldt*;*g zAYa_w38I=#5Gt1w>-7T(sn=|ntDGnvy$^RFgI>OT37Bg26r=ajX3gQy!89ZeC-O_B z$Lg@}?m}f{Jl=O0y2gD z@4IFw{3^bpAAP8(5ET;>MV5}d2;5$z^N}#TYF8sF7xt+p;my-WcQS*o<<-_ z*E$p!pFDY@t)l}BY3M<_MCjRtf#Q~t5!0QegWbgh39pi02lV7fUZb)*XF7a+ef{>9 zgV>*!5%!@|NAY>bVE0CUaG%_$?dXEGAxL#WVm-Q+>7-$LY5GBPrX z7G`E_iw*4U?CvQ*@z&DOp=1OWu;>2x^9Se2X2W%;Tb2sMqzDAX9S>E?rvsd;J>Jym zZE+$1(Uk{}9Xn=gYrCPK5K1HT;7@B)1l#6J*VN}zj9MkXVVi!8jEqoj1JBdujPgN{ z5)%`jK7E>$lnuK!+hY$Ur*xK$mGv809pu)D3fDP#3^RZtZGO`>SNDTG58E#a$c{N& z$=XoZU7L|blHFMTv{+3m=Jx($ehd1wycqBsU0pU@B~^(R?H@q``AWeUrfED&ZqX%% z+Q+DIFJhe|-N1giKG^=}`+^aVUgL)(bXUVs8k(ASKlT2ZnbFtQ?kNfaxWBP5s5=u* zFThNUL{0-qv9;wuPpr*!g^8~q(U;iRtjE4Q!G;6;pIi4#=}<&od-(U)L{kL)6$o;h z^R4UA&!0b^r=6UdQdT%lK#-l2lePc>;kGa!v|u*b9Hr5%^-X=|9G7n1-k&%}(T9J% zf$r*>csxP<9v?qPPk)(ysK~Y}R>)pPMyAMML7-iHJn;&ktcaVNNK2pRx`_`HBz<)9 zO?Lc3h?s)<&-wIQK^l-yK%ypSbodrJ$6D=#Lu2R!-lgZc&`9GVH9`g zLto190$x?ppGWT-RjcIX0Cd z%*g!)`qGN`%}7;OIOWnnYJ6crMQKB4(aJo9@E4X1_X|UvpFM_1Tu}R9SF~Nvui}4% zy3guykK6pGoZI*e9PTm|xAm~B8OdIsO8s4>1C8d4teJ{HE&(4}t}arcF`T)vGpv?P zAw1WeH%MG2ov4<(-dTSIN&Sjjzgqv+wjc4h`UB1-Wy|xHywL>}JCC}K$|HNWC0qBW zoqGiWTL;^>x=ca@VfMmMQ zi~O?mpQ)l_pR5V%7~~}-rcDj12h)(tw9-U(3+|Mc^>9x_F*iE%yzC4d@aLn{x5yrB zSh=y>ba=NZOiO_KlSP(LV;X~*Jr=(MPQ0yig!mPb=!D|CO7>AdvGvK3U$(&aoj1^K z5F&~RAW4<7K3`efMxzL>28;v(yq&$k*Ui0_c=%jnj)sW%21$$^B@ToMK>J87i_vr5 zb?@P}xVe~;)^(r5P7&GhablyOn|Y#}G~eJccX=51z8XiS+Tx0KN|^#2E3Tyi{yy1G z1Kg<;wjS5nE~+V=xa1F!2S^SgJw)@NB9%djZ? zZoVK~ZqG^KH)(UzQ&al@c;neQwzIUt^HA?79lgJl_1O9RiLnM%cC! zE!n*r!xb8%?G+vGS~ZiU)?DN35t`60RJ)O*&^RZ@ea%CqRiPWneS;lhYsOxnhuHMO znerUzI7d?*oj>E_%$VJs9g|OPZ3olPZ&p@TOnkQ|LA1D?Ah|!6UlZ-&EQ4n;FDP1( zbHSXYn8Ealj^FjcX=f$G#c610QWpXPPsXcQ`-$f2;KaBnrJfw!eA%G0Ab#n5escxS zfaC_!zNd?SIsPq_wiFbAIEK)tPx)vtc-Ah z;!wucJ?BzED!G+dR3ymC%F4&5HehQ=k$tu80TH8Z@4n?s<%0=T6l) ze5UO+swPN3@r3pu2A>o89}ao%*b}!&(7XPZ1haTx|2OMD7s^}m=8ciyVs4Afa_Ypz zFjQjCDo3*52hYyKQ6YP3XA){>!d&8gJ^1)G;%z_HbYRN9dd?*AT4CW?Kbe#zFDg4< z0wx5Q2DneO?^QX%6Q|d)W$yBLxcEPG_eeB~J)*$hDN~Qx5IOReZfcjy7w?! zP?5qyO2uW)_OeI4r*U;ZqW#mdwG!18M6}F=AI7dyCcfQ%Q+VfB1b{irTROKk242HY`Q; zSGJjVS?>9PN$$L|9ma)$njgi(zItC)MjNHexlf(n>iKY~Tp&c@@)GA#%lIFLMYa|_ z?&u39?q(|!O|N-POAK-~GgOMDpm_9u{rVLMn?83mi*j@bqm;?#aJivuvx>*%)GlkcY%s3bDpA15PXR}MFAO){69N` zAS(mlOsSw66JUk3gRa;y80*}#je__TiG@g7&t>}hkyH=c~7i|S*ovyG5W<_(e zlI^FDA6MRa{Y7J+CTD77A<-a$ADrQ>MA6WIAu%^Q`=ze#JTWzn`}i{sdteK#+LTmP z*|3qXU!Mv1QRC+))A%Dv_ThZrbtK5hDi#)(&=#QgpSi$8Ohlx?X8}dX0GnAlQy%!* zG-HY;wut+L@65FT9gv7jJg`R3H${v2@?(=2qkl;P&3tqadZ&fVMTY_HNH6NL)gX0H z0M)*^xf!I~VuRbr?cc$?$tfwP(NJLS*xAkU*6fipFi1Z5bIUTrW^dsaZap$z7D#qg zf%)@ZzI-RG(EiI|3sX=yGUSGehqH@q%bI?=N2DRL8cR{2+1F~u~c{#14wzgI~ zM+fkz<3Lf<9lp$-*|M@SEEfCW1K);u+oKQaoXG~c)pL2Da9u#A5%4~bN##|{ zfMB#QMua9;$37+Q1x^53TDlWs9vBovtNQUR2>?G8C9Oo8C+BBrN0^KJ-rQymli1Lc zm8}ESI4d5c>H#Ta?ZM44Z1{OD9gyYC+G2%39T9f;<(}hPSyh!a1!!h!X?Z!R zME#i@OSVOo5yMs5cI4r9yI=Le&RnUT1dtcVYHq`l_uDFvj&_Djng#}<_xku`6fqbK zY`L7=*Eq*&4tk}VH?PFCg-PyY{_Z$l7WHCe#QRuDRb|leOiZhRiqIJ$Vxco06G-yF z*eBdgPYu$4Nd|gi-|mb>+q3h(ZHe)~<}P&Fj3=!B`t=K-?9V$bS&f ztSv2t1O;(8qFsEI7(EfpTMf+jQEpq7W`^(1Ove2De0O*EAe9twYK-mPL-1{GfSv}O z?Hv9q;?*lpfJPFXp(u0VIAvvJ{T-j(g;Ldc(Wuzi3h(U|e}9BbBe28-_ur=tAHR9? z2K*Ir8NG{KfQQcJE-{#mOM@QP03zY>Q)g45`ELCVE-o%kN=gFiwmIyTuaW^}XYo&a zLVKU9H}0!)p8-(C;KuT@S@|!Z?YTE;^@L*IzI_W%6dt|=URPY(AFv-mIbyu(bO&50 zums@gT0v4X;#Y(Ac!ENl<6Dnvv@IQy?be$+gFk0nAiSyhEgF@1t0sP_A45pzq>?{V za*&W|2*D1K1X~_#jgvkyI}a^HI_`d52n$~%DHNjYoXXpjlI2C!e0{x+_;<`UmYMp{<@GbInwTx78&cDY z%#`FUnwsurDX=eP*=L$%B3piv%C^bKEGo2dT`ZoJW`}ADzzK?n4bVqO04`3>tk~A`ZXw3=PG+x0WEsMeXlFrk-sOZ2GkN zT@08$k1_vkW#u{+O@IaE!r^Ko#DgrFDIH~i@UpYBj~zb=T(sf-j?wmWKa5 zmqm-vM8qx*>$NSpUJI}(j*gCouc}HVe2mSAHDm*ND%i@oxOxZy_Fk%cqcNfDuq&I=>GL3}j}q?^=Q9;JLTl z;AsC9j{qa~X3rTM`ahBlyf;*_o~|I~I%^?FlZHv@=*!Y%8%%=ac=hU)ko`}T3`l^$ zdP+PzJcfKWhn#~#@W7EhOKoJn1EeWNNpHOY9v&WsE9Qh~i~f(6e*1H#&@0LT56%35 ze)KJbI)#ad9KYOWn}zbAYPo{y18Vy6%47>~)!M6?8Y#3~S_RrO&!9LPOj}qh5fZ5u zKK}yuQI`h-PMo1xD7a0?qAIc8y|5OBd)2780FQO&BY!c2rRPt{zH`|#Z!E2Jx;&5- zxZxRDhNNc-4Cvx>-+YU>g$QzSd%yjZ8$&hR)I;1M-i`++ZiUg15| zw<4A!j!yKKtioF!50Q<^ML#q>QBHv_e&lEQ8kp@6;sEy1_fJGCmD+_`{o>x)+gLRV zr2<`drx3Eh)Nvh#u`s?&V?cw~2jb`~Gk@z4?yus3dR^5H_8b$=E0X&E>@r`2v41MM zdXs8Utpsp)8`;P$2%^YouCx zcx|55%{v*T9VGjZ(fgivefljrn?1vsf48uf55BvF|V{!aPjcNt>_Ci`o9gx z&$6XppH>xrQO3WaHtaY-QiqMW`%+>;!pP`n5e`QWa3G-B%E`$QQ}Idvd3K1SXFNYW zmh-!X%MX($Xf(KBz~L4#rtJKpWs^PymGkavKYs!B>L8ykN+ zQW{`zfd^DxKS4101q3v6bwK`f7_QXs5683byfPD-w#LRcVh{6*=;`R*zI;h`?%Z9m z3X3Lk+i}3ZFf;PX4XXo4&UM1+S*ba^sIva6SPw^GTIw@II=KO;|COE zMP-i>pF&}K_57@N``cr@V5r5s<^hyg;M=Sa$r}3Hl(rd|Ium#IEr?y<7Yv@$Nzk#b zr@e}Qfu|LD6Jr-}bQ)xlK3{7^#ivDNFa~mzfmDo)jw9Rx0);>bK7alUx^n`I9s!IA zBBs9h5P?_Oeks0|x2)Czz!>j1vAD?V3Q*X{zhtBzO;g}G z9VrT~qC=48Y4I^JF`ZSlpdnFGQZfLIgR%hXx~?11zdDw!Za2ENv}Ch(i+cC`6?Oa< zzpBS^yfks7>@7VGa)34Xis(3r`a-qUpFkvTa) z98KtHX}y+z*Mn2w?%~nTh#PByCnGue7`g_u3keAcdc3v5dE&Laahv*U`Pba~{C3@$ zu)QHvSInDUv1|n0V(kJk+`9Emf&21rKoFo(*I&O2kbq5-gY)LJ!P(Q;04DFl{Y?$y zOwhd`l)l*&54@lu4%9XE(ayg5_RX6uuz;_b0~j17sGK7ceI&~h3d+^(Y>_U-dQZvZ1^fB=oY#K#woGUuZLmQV)7+i+b|OKU>;BHa}zW8pc8iT(rW zEJm}DIG+I*Y~UB{g6mTO4L@{1FZZX&i1#WGg7WbfVh%m387lE~SHuwrwL~CrYx2pN z6O$USO@Of8y?YnHgp!d{@1Ai%qtT%Q?~Te=qI6AW28!oiGAq#G>;tD`+gz4Ll8;>! znY40xz;I{;a&sCDzcdyUaQPGtPEK4$Ow$&Cxf~&yP*Cp{iJ2rx`Fr8#t?Hz-)wESuc8QiQ_^eLG1t*9t;nvKRxe1b46at~s*Oo~dGfaD1Q3(aDMd9Y%Nki_UJi z5({}hc(NotY)~VQMqc(tJK5o*1fmqF^1cWkQ1s%ZIbS+HW}}jO`Y^VTlbsEI$=k?C z3%|xYeD?-RZlkb3PQ=%{H6NcMjrMSm!OMKiQS8me++E(gAjBdA_-s2b$uz?J7)+!& z_#GbdJTWXVuZQvg(|zRR+pA+zEi`K2*}Ym3p*=rFYwm=IBBND7d)Dd?V>n5YB}wjs8=xhRDfTQQhi z`PHegmns<%&nrYOBENvN^1*lClb4tGgzV86ffkX@Bcg!*dpx|nr6anAhFloJlP7g_ zb(IHudU{~T?hSl?ex8ex$0&2FspntU*a;BLeb~z*G2$^5AIGo&MNnHi3MT}CS~8UR z875L;8-M1T)~rso?`~~@%hW;-NEAp}ixAY4x**bXGPhVY0dIdWt3#qS({J5WR%XTm zHk^aDI0CLMoX0zlKQW+5oXDufjT~%^8QX|RO8Wl(`V1xq1*wR^w(FR20cYx+`$Zm} z7r2Z)NkVg}m=0XPpi_0T{;c@Jhhd|DRz*d_xi0o+FcFoTg2uwogXVC#!%2J%Ro4jn zafR6oKZ#;AmNfWdqdSaV5p%b*>w<|sHNW?J2I6Z0Z&wcA>JWq*zDPXxU{`Mk&3!F^ zd!H}$Z^z&V7%`ccfMKF+YCDpT6Es8wvJ0|Y`+hN?w$>eneN&oIXxcCRc~q~*4&JM? z;YDs=3UTwco+A>8)SrB=Bzk%_4*;wx6kN$|$42tFFw=HQmo}fDse;3hRmM zH8x@sx(QC(=G25=gunBD^jjsFeLO97oRZgbfHz;xy`1b>a zpXCm>BTWOFdIS{z)8=0PUk{(O6Q8sk?jJ*P@1t2lIPP6W0xU2g!V zjLR`hmo_@*;Jeb$`0K$2Htp}_7`<<;DWL*2?AGR6HD>y8=97_OiW#H&Db9ndf&V>z z6{(fkfSYZw5sT!GzTc|&=BVT82|<~2$URT_r~W@s5(j`NTYd~Ah+eG zP<3SJJb%vr&(L}CqI!r-_z~_1YDpLC`Ee{3bc(bEAXH?`@+cW7i5f61YtM`faHmz) zK0@_Tidq5eb3NY8&EVJ?>F7j*umm=@0;7*0H+KkX1s)S>Ao$aKRFa_6fC&x=%?%oU z^S2P?6n>k;o#65I^8f+yP-inHK0Km`5-L zEa@S3WHb3vNV>$4w^UVDMv^|mmx3*I6!NqLO7tk{x`^h;{(Bygae%qY;Y&}j3qEPN zaAq=MGtH?dlM9VHc$OxAr z3MY`AVj9be8JhQ%^(?4Kl=ILD!UW2+fd-EWz!r&q&~ci8jL;+D_pJ1P+cCcQiN0Sk zigNw!HE!!e7w~zgz=U^UMOcaC@I=c0=W)DasxT&7YTR_0z-$Qns9RWvUba(Jxq0Dk z{rIU6mbTy%U5=;nN08PVvb<3Zb8_A*8}6Y&$_I?&HKQ5A0c>bU1NM8!Agj#%h3dpIu$yDX6&fo)rS^Yq^ zbh2dXpJ8R3z{Gpuh@U+e4OxN_34oLi!8^}^0I{E4Ql+oIi)t#(6 z%{>-PWT~5V8VYLlPye!Q$aR^v2;M^RuO=l!D&bcI{XBgAybofQXkb&HUD2=ni;Mr<;?L zQws3%AJ1{cbDpik=}$Oy(&sx%>+4Y^fPX;`WbHF1;JJLcc<4g+-1^DKV>`Mc8mK4^~#3v(i4_QB+iP`U)Cd?TN34k(Vs|%421% zurP}cGmt~j>Y*;|feeM?$=Gl}YTPE3TOcZfh77Xq_Ij`B`0wAK%ze7o{}Bd^*5?;@ zOwZnslk3}fd-eWBPR{I@o0p0%LX3b%wCjKDxRC^Elvzyd6X;<8sPh<*PHHA5@8aSH z!G{@q2kwY>psJD2o<#Z7K(&vTlG5{E?Y|W#%Lrcpoh`I(-v-#0E*ZG%?ub% zzA%o1mJJk)P)mr3(bv(j8X2AK$$@h!vltKtX#eHQ7mxzGdX68HBqAajD0R&5n!&B1 z*1Q0wRfb^pq(p**gam>J5YCiu9tc;UUBW<{(_+la(FmVbGs;2hiF{z}DUuII08E6%-WpG`ER?sHg=i`~8TTxL_faV#& zSp@w6oW)+CBfBZkf?Z;2_giffF~}8W zX1?1T$pN73ehbJ!YY zg%|f+y6^C5X=}r|cK7s@o4YWn8W;>n9W0aDdcjKI2Fr$msngpaY4rBa^ z5)tK28k{L~l zgn@rd@!K`e{rcbw{b4d^T$X>|*mdlO9&9AWP)6T&NPshIK)R2Ljk%Q$U3@AG)u%q9 z0v^rk%F4l}-{C{p1lT5*jV-$T$&+7To-kCN83RKNv9YmMF94W}d3iGh!DLpb65qB{_BQx5j{DPcAMl{_1!n4u)O3r8keBv^^$eF@<)8^?2Q{H za6#qx@#C;S<&+K^*x`j5OLxHsIX|Z_@G&tZ+Q#AZ_TfqoKqzj1e@F|@4rZ}G@95}A zkq?EyH~47rtn1XY(`6A90II=eN*!%&p^6G}yn@aFLwE8Px|ZZ z?&6=@e#bz|?yvDXJjLJ+7tcn47O5~YHKJ%~4NXmXF(N*N;N0398NDr{2cMbM(XQy1 z^j6>9FmO|zqRjbYo(Bg_(2(y|88>Kbil}m7PHrLlZu{v?`BvcL6=T2E!Szx;|V_^(j`KCR<8n{}= ziL*p;DHnS3m531WB_E+QliAQB~Y5vbaG&f+;^gp4DJ+xsNL767isUX4RV(b++x$w z5e74IhPMM3Gt)oN+}!gpkg}1lb6Qp<-KzXpXut*IKJUvFKOu zV!P=c+8=&r56rM}*|^-k!pFz&t%HwJXIwA{VC#2mjOmKZ@Cb6SF{ zUUVS7!IWs|1|t}4qqUDZ-GFx%8(?f~ra`RK;*2U1;OBR4eRBnOFrbuZDi9+MAHgu- zDL6L~AEdOKn;V#;7{>IB47hmJpPXm`7a`z?9&VwIjZy-{b5I5a#KFPA%IZ)2!{Pqv zD&~{K!H*ZWwy4+24rM$*FRlR00bY zyuf=35cVFRiVaG(Ha7!bi1^vq2e$-rtO*f3uqc0LgIqV5B7yPyrlux{syLXu+*hA@ zwp2n2R}2_wXa=AF?+SzJGduLDG$QZ}LgcYD(&-aFKR->|DiRID8ll-difuGQOmNq& z;oP@lMgZ_fOOOHKF){rv#VrsjG!hwy5R09Kdkg0;To^xz_O}NP^(z`$r-!Gf+v0FM z>SEM%;Y+34H|5md=jP%@FMS@v$XZgmpnnVgtzh<(f=UivOlG*7m8B(IGia}lQA$&~ zb*r_hsbB$TUV+j?JETL1n5xTG_aEfHQ|phzQgc6Zp;ULJ-;QvzvbKhBs8Mf$5d^qR zcbT0%6N;h23%UY5?)<6^gA~I+#HcrW>lvp{uu~_lFKuqVmK2P+1p}$C-ti7RtvAPA zs05V-&THX9B!T}KSesJ`5SZ(aPolpcE24zy!CL*4wd)9*F*rx}3g3NEC5~f7JfQp5 zMzBBEJ0$o~fpaa6?rZ+%Ivftx*XH7QrN7}(bKW@g8VauGxprO}asYAjhKgLC%$TedPPDI?jGt;ovA z-hQt`_x|tW@ju_kx8j`h8SnRNJjd%3tgfm+a+>Be0)Zg8sVJ+7KoIC75XT~s1n`?Z zz2J8Ei_k(@K^Ad<|1Y^V>m>rgh`1>$t?l`Ge%Q;6LZ|N3(x6eFYLlwak8_Ni!Hmd~ zE2ySq-V!4A&=Ml1pIWD+?|=H`aq)szcn~Rt_Or{#R7NE7v;l&g!2DEnB<2e0=BX0* zrY_~)owV19S04=-HO?Ur!+;g~=Dvt8JQ}Fkg5)y+r z9oP2TZ)bhjOVZZX_Q41df)y);Oz!9_FcNkcaGTl_JJ?;Zva)(GLW*Dw!oPDj$xq1j z_t&d56B82`!{qHGU$Ur~Ryxwv-#_+H3=XJ7K|v7}9lf?Nyn|CH(4C`os`)E$r5`NqB;e|$(j^B&T-+9arynC?No2M5+ zFFqivH$Fbz+1dHy$B$hFA_TFvViF=!nWAxXbMyGAvnNiRaGr4&r?oXrm5*UQ+Ic_y`7z>I}-7S4Bp-OQ`&Cb7VrKp?FlJ^|8g@+ z45vZK?GJ&wySp2s0Z9WXx_NY>9)BK;`h9VaMZ7-|BY$jyje|p3RaL@kIbA8k&ev^z zpnS1rMO9v2-p0m8POi~!V^~jHTievMP*-bz`fF>e4;=Qn7IMtjP>&Rm{CI0NuP9R` z&ZU(#HX%VA7I668gC|(*IT->1g3C-ycPuQjH6qEnaI=|B9lsd z`}T&D)8glyfP=jaGyg5Cj~JqgW(yAw4=bw-E^f`Ot*tlAW5*F@uwTn!+tX=t{Y6eS z2cLq^Vgt-J;`ARdVv!*EoI>4^0N0LJ|Ur@p&=n~-Skh0X%LR2_{+=A z&K?^Z`}HM4_ft@>((5P`N>p_4%asp=UKGSt&hC1CWV6VK4MNn`pm?d#c{08E7 zhS%O&zlk{EL&_ZG81Bi*$-jU9mPo)kTki=e$jQyPy**2JgG@$%hNLi*po)yL6(JJM zh#d9bae!!pWt^IQgFv8Q1Qog>H)h#?vR6ciJ|6EX;dv;E;4ePxC8Qd*|52Ol#e z3paOm2G=L1rXb2^*Sx91bFJQN`v?w8_3*BKT-tb%Z85Fj-rbVFy}b?B16MuyTZni# zdzzyr7TeH88u2%qs5N-gSHmvTf7*fK*>z!I;mem(Kdk6gCxrH4Cq)}4WifxVLX9Me z9WK^+R=Dm}>X?|ANJ~rKyO-~v=I&nJJg}Y?A(6Uj!G-$t$+_a7rLA_=zOOMyE30Lj zGd$j%@$2;jqj!3GH`yJ0%9yiX>$lFYOLZ$vt=YVlHbK^&FXh?O8<<5qF?k!%F3gT* zZ2qRRYnOMR>GbXx^z@F+ai|gF>=7Ed;Vs!CRA;!o6G)1tH6y7Fqf(Zf_1^Zp_-!(; zIwwj0r*xCMOyOt`X=`;4@qr|}k|bw>XP*85@9sqQMSqtbg7PpHbn&WY=fT-EOFMKx z<%aqU&HOv-gAaQzIkFRwlWON$7kjMNRq1N}4)^UNF_pikru39&jm4qiFn%f=vOa&} za>(Vqh=;Evun8&ahEQN$UeJUH}W2^1xvj9Pjcu31ZUZBr;yiIAzKxzNxO$MdU;wagU zu9x@aunbqE(e*4`cGLAT1ZdjO=>2p=Y4rY?Y@P0%&RjOHu&Y>AH-g%*n~ix4+Ygjk zx?T$2BB*632pJ*muC{T~HN;-oq`_7i7ldRmY^x>X#+Q?^<1?qMv951?O*kETF#BQ2 z=O)c)+`Y(|IdR7jh)OIqM4NNkbXRuhT?{_j-iI+BBqrrigY7_@&=XQgh>Mvd3l5t`+1-I^{wXT9UXL z%jt#D#rns(kWlBg*a}AZ>z|{HgC7QBFD@h9iMO6|R%2DJ2f_!hV(o1W2ZTR3Q5L~mMZKCv%VG5fF_E%&4B{M4HFS1ZLI9NnOlw#!}5%hqtS9d=0BD+h4z=5L7c zN%s{wY%(@guQ{myn+4L`J0YG-bwP@8HcZ&Ye-w$K+fi;*4T9UiXn;Z zYPT|i5DXa?`Uag=I3v0+1(y<^fx}&G>I%lDSf}9F6e3gh8PEmN6=E{D8-c`oykZA0 zmBnSGwTWO|p=KcvW%LAx!6RB)@!sd(9K^5zkWSrM**S|;h3(RR$_X~jHdSfug_X);=QGJ)u7If_$&&F#3v=yL!}?7 z^`W|O!EbZ?Nz3PF|2ER?yYv8V({%4 z9hJOx?ac?2$G_mnovizGwVP{wVHog%k*z2*GcyxY!@iBB<-~Mn8js0a=;4A+PEJ;L zK3h;HpOMf~aL{roqADj*Zj*U*C88ro@C>yJi7ng1tGHAwCs8N?8kS95<~(|zK}#aF z)a8W1c4x^1lJ9ks?8RAfK4!O)2~InaUQWvvCd(#!?RWlrzqz8KqBgg;l?J_Q>#C~0 z?@zzJ?ix-f+6ToSuGkqcM2qU9!<%IF{ABo7M;YM6Xr15u1J!tena5P7jF_jXHs$+U zRL>ZZl%b7v2BxN_GBO{(zqym-vrs+LofQBz{q(6V_GHY4fKu?TKG$hH{Mm_DmLgH2ak+R;$yU1_lOu+iNdHt?_kyOg^2< z-&Q4~6M)s~O!pK{;r#jYMP~Kf4rcZKeoJE?Fp)1_yciq1U7%}UZm7e40rjcBe*;=f zWX0r1{Qi$&eYQWrH#ZhX&GhtQUcNj}PTpDT^FXG_>|ncpez5Yq3>*N^<=r>>F0QUc z(BH9JYrvxLrxeZZ0nK=f!=3=?A2<`pXABoH;(k z*F%YaUF-auW)88~d~j#e`dTlIrA@<9($^kREqYWf1I|~LT}}=6;V@^piuDO$J>ywh z6308Ia?fIY@Lj%-mkFP;&bAcz_oRAUk~o_;%9`2ESM zaYG&t-vkX`4<|)A=hjo`%*)7}YOFO!(k1Ehu#9~z>P(R-3^;ELybBd7&V}-%Qaq#b zp5%Gu0%`2QC6XdB8Ph$HH-+YTn4>-BDyB!_afWl+SQjgPU8LqvPuYJ&=pQyPLy||? z6NEyYy^qM${)X^2~d6l`f}DKngZ|LFK& zrPE@vIV?9n(emO}wU}*##v|vE8n0FySLm~6yIWI9lAB{e^#^;4hm}T4n(X)2xRv!m zr>V)w+T|9GvowTdA|n~AW~VFSA47v!tw+n@D~M7{g50gePhVd!HFaP!7;rW6FVC+a z%h|D-f$S~S`gSBG6Z5vzvov-WLpbe_Xxiud3{83Aj737)A+zM{N#yZu)(NUvo84E= z5@Dc>0{waZ{5d8P%42(ygv|k*0*lm^77h(BzEeLXts3uv;>R(2%x?lEiASKU%`ymbfUPAlCm-!SQ$wTL;-spa*0|N2Za*a@I7 zIy(9aGxIYjh_`w3_22yT*fXy4{XyPv9Dz8gKl1WqYDJ5$pa~Y(!7U;pqAm|9DJgI7 zw|kxBO!6u~?tXp>uJvB?o=$lZRUmR-k#Tinqf)LeKAt98$%^6q@#DwQP%9f6h*09* ztNN9W!}Ht0VPWn^x5I7nR(%k8nOrvdtDY8JqGW(+{1Um$s<)r2YWQBKX{|T8jI72k zPyzV}`hq`mE=?Jo>+^&CeSJ!U@@a4GdTo#6^gU_?vuz>vQxEwpjdEvr^ zAHuEe?J?nmCr)VV=_wCFlmJJx9cl=%Jv^DM24MK@pnFEAFj*`68L_)sdIs~F(T zvI+{y3c!l0yw_$UBgqPM@pSlx4IFvQvP)dXAnE6Y>ES%RBAqR6XeH_>K<Q)v>^`Ttwbw`b~nqST-0$@!cpnJn56zDr;KAE zZuAi(j@#KiH)~MmjB|ZMF>IyyR__hP?@6t(7$piF-&WpXpT$}^IXMVdR&H*5pQ){> zL81b-TFvgY-jYG1SyW<^-D)t5cr>XHo-NVod3_oY)c)xje{_rrusmCc>MQHw8&J7bQ4kQ#ET;0jV z`_((H=Xe%Hqar#!s>gP#W&|0(3_@Y)-B)!5UR;JXsx~YdXU}Rgv*po~ip7wX zVy_5>`Exr8p7EMQmb_L@FG~?(d?rU3H@p7ESHpMtK!2I3m$;SNz>dTvN8$T96n-Iv zht90rICgl2K{{#pu2O7w)K3gYay7&Z@O_5{4{+a;bg|%9H#l|I#~(UN_*mt>p53dr zUc`cD#HZ_1d){IR&>HB>_{YR+$TmC}XLG!Y8;JY&$cV>9Ds971zWri`=N5BkdW zwT8StM&$)2Wl8PR>^<*%ds!C%|Nn>ed?=O2qj1zAi;Y**b~#R4?&s*Z00|~Q(-uT3 zF+DT$W4gO>vHrl63QBqKVZe+Q;`4^2P_WB)n z_tUE+UdM97B)|0^3&Zb786gxInO-d!b$3H%< zsj1O3^_m>2cGb#K-P@ikvPyhSh6imAnNIS5e4E-*U{smwSm8V_lY=HDjo9AywtZJu zXPVXhBS|%{7a+J%hUVII=dX?w^xgJE9bW6h@6tZ^$SJ)RvGnlTozM4vluY6jm@Z#_ zCZAU3AV35E`V&!M->+KKuRJ(1GSb-Cc$zZY0#BUU`a#hDKnsE&tIRzK*urqz;?u}o^M#hHNRw;nwny`?lSSpsgC-(i>0L{GYUi; ziRXoZbxR-5K#!f7nE|=-Gw=%N9Td-~LHGj}yg;;eBVhsJf|ZLaEG&$Km^jK~fU*&^ zp~==5DoV<;mqd#17m70-A!xE-M%N##$}1fm9aqEU<>Z=0C)Do;GPfJt%}+68Bxs4t zT8@zavCBwn)COnk; z4~1rq=#WO6gUk!L$LiUa{iji|<}g_$Q~%URO^_3mc}mDd5$dXKGt^jfp@AHSCr76+ zoB;qAhdOBg6lLGkMXFqw@)B4Nz)Ik}H^VKVVC4ul0VM7seeyJ!F(r|VsvY^}5Lf=o z@1qPnfB!J+;sRHRV$gVq?r#XRIMnLDm30@;T`#k-AKQgTWMir){p52DZ2S{7izADB zIVlY6DDAd-IJHYB*6+8FTi%RL%OnCQZka6zP`t<+L;TCUnS27L&@@hy@j@r9@Y_G& zt?mc4DEaXRyy&q>J~_JLx<+yCNEeyRLRX3T5#WE=w0$H@M2?T@SGdi5jeoiWew}uo zhL{RK2ttny+b}B7ec8Tf1xmZI`PlIEAfc=|&()6Ui*U-?fJxl7)#^s-(JgTon{w`0p>gKsG zPc*M9v?q$cii+wj(EV1cK1;D|6k?#lw-|n^P7P|Mn1AYfmE%8O(+h1d^H9R3D zB_S!NyKrJ0Uqc|W0Ur?@KOUVxa2Uc2w(_itz1jhy4;Jo?*438LojX_ZU~z}l#X7vY>EVF?VQX#dvhepuKaC9MPHo(6c8$I<(DHQc#)y%D0h@!Kt}Z~|S`3*61)if$?18HP zw~-2sMgwnkaB%SStO`Wk!E>3V2GIy-;05r)L@qD8NRw@^&jY9haRKli5ej7IkY~@B zG5G++_II~HUObI`MvamxC0i2`?_XM;TQx?%#AUqa5m)GFiHvCCh=^4FYnny*TZezO z;l<#W7xt_j_2l=i2Yzc|nkWFHW3PUF7J-OA zIr3LPNT}jNf%FckmZs)H@c}kKEHg9Hu%J)$PZZhmXIiJ8o*rTv0f;9#K#!I8@RGWq zec#YlHRMLM`U{2cU+LeP7#eN^HgXy$Yrf6Px=@y%&&kj4+L0^`?SPGq4M==FO=UG8 zN2mI|%uQ(J2xEa70h)^!t6U~qz&`;sn}(RM+>nleAt^TYA|>VLk(o!wPu+XK859(h zvGbbb&uG0Q8{5sdgG7J^*h!9$r^h!P#o&Avu!|~cy@E=%9Sf{ z?yicYB(q=5lc0!W&(e8sE{$jIG`F{JTp?F612aqH`{OfI(_s`8zunhp60nborP)&r z3+i_8V*ZY!OcPj7Jf<}wRxK1be+OY22!o(k;SilGOG~%oEU-_W(5jWZ2E2MnRY^P9 z=Fx>&+7YI*fY@8d0l0el`RxHT&q=^yu>+FG_xm@;F_BRDL6$dPo9zXWe}BGm6mrt} zoqtVjZO#ez`)X7abe*NFn4}B z?2Go;m1D;hB$=5l$KF2z?PqOm4UZ#A+a;8dTTqF9x4pV+?>gI)ljOh6CMqh*#WjES zGjtVa1)6<24GoP>xLxRM>4z_{009~)Mz}FyV%vTLhr#)SVK5IE0pgU)sDhJ`@gW)C zgM}fMB;T$+Mj;`O#*hmbGF%f#*Iei`H45K($vmbzP!M4d$IyIvYF9O31;A3Xu=ok= zDXV)1zlY!k@p&Xf;$OGx6#!LKK)mR43m->FDR-UL4Fht|d?@_X0V4-nhl9f&WVD@) zMYD1{9VlaPccQjk%rV3euZD<|Y9aU6URu!*egqZrM}_;1;biF`LK2$Q;A+Ad`~K@Pmd`A4X; zyQ7dFKLnlX?&<;S z95#p87vu&m%lfnAr+x8y0Q<+1wFdRl$c`P2l@LX)8)Qm7c57pBTvB>t9i4Lf{=$%u z5OC0d1>2No|2%_0+|qD~D5fTqp#^_Pf!+&4=CZXsNkS`x&v&{TWuU5lqoD{J_gU?k7q;HsH@M>n00)-`Vz#e-=Z>QZ`wXt9wvNsk*nxUQrs1@gKkrHm%ouywLZ& zw3n0U25J%o2g;s4ecBjGg)e~j(*O$KZfUQ&1z22V&apIAT$$dRC^E8myJ?n-99#S+h* z{^3HhH6c*~FpuBYB%IN(0E&sv`kyzW)KpYdbac0nIk~yZOG}X+-abAtF)@R}aFX~Z zPZad^zb6nQj&#(ee2u(LPw3d-;rIJbWox7*2JCyuJcTB5>sDACDC?-BNL17!*Z3vd-+eLo?gl}8%9b(_KK-#`j^jH}ddlmP4w^6{dUah3D<7lwcu-z}&_^?w!@)sPxFjvNgBKTl-RWr|J6e};#?##e&SG9Ry*^W{3rc?4u?Oy z$UiKv4bsM;0c}Wb#V->>h(4lSB5KN{ew))URHcOl+klJ%Rg=8!|N7D zYWPxz1N1^CuBEQS4=nw9C}kr+LrO0;JvAllJjT^xWD0u?y_TGu9B-?5{gec1^)S@k zaFe6_)n|t)#A_hH=vwCk2I-v$q3ZCeF$Q~W{4}w+}VK{g_kd1*4Ea(bD#47 z>ER3&_jiW2mX;gNV-F1rRF#xKAADJYx`SuY#`kLl;=!ErS-)p1Dk37n&(AL;)aT&_ z=&mnmL@5p=I3_<~(9zzMvWcmL`?lU4s9UHJeqx z9I76A%S&f2i8zlz7Tl}nXJ(ciK%P0ne`H^&C@K~^c|a|49DaN9)G3&K@c^;}UGb8D zP2|wA!a@+2+k6a{X+^!excS8YQHTQO1atD_>yXDYz#toMgp|0E0~(Sb-bBZR^~R-m2rlW zbNWYVRv_vZxT9r=YXMmkG^U$N5_T;21kWVI+BfCVr$mp)w?PwXm?P&gPNMj=xL9x3 zo13N(G3)l$sug!rl=PAasGl<_WZrt!2V+wIQGq~C%pg<+NrkXI>WvvW zNUZR>vJxfyAwvTK@yOPe^qdxg;N_1p2jsbNXp~n8jzs9Y68t~wyo|8ZXSzFtgVa-f z5STQu_6aS8$bvpbG%fBewv8{MgXl=4z?};sX?AF*J*T1TPXpX5?z$7hz+Y$x8Bf`E(JG$w|+CCO3j7#x%9i5wu11HOMbP5JOA0)*-O{N5FP`?>UOW@m@Hm7-u{~+snXfv z9PmCjt&;rWz*FM-jX>-Oc81gzyCD({yQ!sS|9;7F{C?QT=LzX{!Th^9_DxX{O*vs> z=>t#Jo&FRAqX|+vZB~nS%$Jv!bMy1dPRhtA-oDL<`gEK39?ZAF-B!+JWoI|V$ck8C zpwQ|`OCKx0r*D4B9kMoL|zpqQAMVM7w2WGUnlRH@FL>q>3|FMyKA6m+{OVA3LZ_h5`* zS+AwamvAOhDqA-X4}ySjotFW`AZY&aM3}smw)X0$^Jdjt0EK?m#% zBKy(>9*b@DE`nL;q5j^tpYGrrS81gJ8xSs!op zL2b8{tcq){N{eZk3-?>+@7OT$O&q*gLkGB8Q1fd^65pZBncSNmRS}}}R`~6`t!KLU zRqT)w6|AG8m6%Ifd8=u1)d2h+O}uO#<;`98=e)*`9X8ntA0Ns)BDdwMAfsUsbaZsw zXM5PLU;nWm`Qi5Wx9)k2NFWjcV40sfdx>>r=$}Ert`YT4KXYas${*DUbC|EgM1qPr zKu9ED%%dl!<>TziypLn5=%}8d*=?=piz@Q8Fz5$;) zODpt@OjAoMt#fzlPI~uDdg=lRGH?l4BaCi-Yi(8j5P7Jc(MAXABnRFWdez$6I=|7| z)1yfH=+Pt4&bmC@-QA(G(mW`J_1RjP;_!D7JS;R!^>xXrbHmp&cSIL!TwBusOXuh2 zzQF51AcoNjz(&kPqR`u`Gp_r)UZ5>ZPuoSmdmYqFkIf}>nWxQ`>>M1le3nR* zWmo#m!}<<$DE|9fQ&8azi*J7bB1lU~nK?#rI1VIPb7uZ37?2E-{;;NmL3lQQBO#n@ z8ARdFU%s4|Atr2ic8f1PGlSPVsL((89{b)Sk%g3d(dnJ5gtPgRq5g4$>5Hz4H zI=>;OFd-)d;dRqDvgJ+Re~qgaQD~BHBNk_%>QlfU29w_ zJULtWK9ZVw`l8DTugUqpb`37QqXs!XyDmGM=`GhQNm^sQ%I^QBnp7b^5azVk%748~ zK0_g94>N5e|Hc-NuB4Gg{k@*%;?qGR&S z7Sx72FzNjJ_wV?&-_WO_kq9~#Lkq`XFraf8OqEMBx;@&iUr(#Jw$;fpr>lltl_1Fo ztSs^U#xdMKq}e@0*}7ADo~JvQSdzMC07-z>(ZF2}Ax<0jY3C6ZegNtS_^yS8 zh4={_EiJ9y*@L>1AhP@!solvds`H*octCMV#uz_f;-B8g=VDg5(MV-B1Y{6HR%_}6 z1Hts-b^&<8-!8VI0)tKo#7C&+c?)l|->|8!E^gi>yS_fa!$WA}5VatxVt?G@=HaOv z1)}$BX67c6jfZDreZ6A7#((d|M(H7`kX&9t+JC(udElG;fvygE3AaHBhV1A3yosJ3 z%Y1%b-pf=b{3tQveZ;QRbeaRd%S02XKSRql+S*b7)Lb{W)r9b3@*%tt;qS?V!?Rd! zvpPPEg@@TnrP|4I=b>(R+8K7rg^7| zmi>u|{}z-gD^Iyh;d`ihVg#vIM?HGz2Vu} zyZ$3D3=2$4EN_~a41)$EF1F8^ybWhkriJsXiGzlrChpF1WZC&sNVvT^*9x|B6lpNw zA)3@6LlTLT-Jtjfrsl{G2Wb8=CWZl~ZpRP3p>9WoLOUCTkc|xI-fRvO*?w?_{Oxj{ zJzQ?GRSvl#1F4pGQmN*ou^-Ez`Rnz^*H;1}^_s;qua!<9yF@krDrRZjSJtNkl+?!Yk?LtknPV82_WGo;XF>AMN!XYr|AWaylan*Mnz!^|b6K zd}V!zJAN4b3ghTXlV&ag^ZBa%9wA*ibeEcI%lw_jU#Fg3X$w8s?R2VW6nS?Y%@h4) zPS$sM-81Zo@;<|_>Z)B9eiAH-Ma^=v#cPs0MD;6q8Q<$r)u@A~g4Oe0uA%rnR=pfj zvPk~cTmI?)Oda`CXeYhLBU~FnSq%@F+PsyS!_LB_v5&5tte7G>!s;eTj676F?z-#P zv!#jVmmpigkeL$*h(YL7R#01uprHd1k&uw6ocnNTHg3hhxBG7Jhit)!rHv0VjNSAk@J$1URGYy;dtLH+RILzjoMvvUwQ?Hz$^o+Z!zuyi{A zj-*Zj>bABPT>%gb1oW%lO$fNTxXOpAdgj&$gT_7fCMGAZTX=#EAO-U;c~8d3&c>1F zYO{wnUUo3z#C`4$DA3KDw>iHjD<@~-`e_peg6g0F+tF%}#p!AcuUr6CkeV6LyP zucH%3Rp@?3P`%!YyDjE|2`O-+S{vmnmzavRUhZT3Oy!c#$f0Uqna*Af_Q0EOtG(V@Ru*_Y4J zQx76K47`GH24}%fO#LD4?eFI?C`k`E*oPnkBe7V`2Uhq81!QY4g#le?XZ?Uto7E5jq*cV-(qzp;b*Vdj`Ty)~SXv`}c$;8Ii zY{?g#8jHihFkR6PhTNPSB2vrmWI4Ttjpg(Ui zy?+i2tR{bo_!OAq8VG2G3ATxWzwZ-lwyBmt089|~sp$D?$p-^$4M}u{Fx-9+1PBs{;A% z`owb@6jSX<2fcb`TRS_V58N2l92^Sf$73pY9HA(!{rRy18rLoDNQdfpCr0Aar%P(} zz&?2YUTQt9V+a(nfPjDe%? zl$;522eg2R)nhk|S4c20>Q_Hi|{NM&qR8Ce_5qRvU`xKJz)1g&=b1-c5Ugf=3a2i!b0%>$YB61 zH6j!|oU>A5)hYqAcJ+JnPLModAt5e*ol|ZCH3C2I`DJ56!vUBNN20)s*6cD=QTYn} zj0hFT2##q0$W?`O1xx~Sv**Dk2lWHIOWGT5+1ex%FjMp9%^OXVEZ|J~obWu@3kWDs z5kB_@oqP+;5Da%HCE@^?G)u<7QW3HEge*7ogQ+Eu1mGbZJslmGY)CP7U3mcFB2*WE zStvACF(8=!x=T7()_`TZK+gXrTY3CqjN;kQ9WMMdz01-~^hD!rs+ z8HPr|r@D#(J!==PUQkdFF0G3}yg;S&ER-iic%Ls1Jbr=@IUEW5pJ#`{bwEhh()u;4 zfq3sA2zQAncn|A_f2K=D5uRJ~@~SS=%Im$#!g5{)V52XPK-;_U>C#YL1aP#)CQ-)C$N1GDHW`&KR_9U&7qT!MO2ZTka;Nj0{Hu@S3b}PK>ru? zB)(%}l2GuL1og?1k50^!myIn)nv^gI#mV`V`p(IRMtG@Wl9N&yJRQ8*-fLH6T&)R$ zOP!z3U?+q^7*(GwI_5@A2GqDCg_fuY@aNGKwIz1?8U6EF~01 z!ZUeGnEQx+AdXc`fs7!}CjYgIfxr^>R6PJAFXQgkAO|=1XA+rzpTRpotE({5#(|P$ z@4U+t9slBKs=k(1H$2?9LkLV8eajYsAO5Lgf+>fE{-UHZFqTpCUt3!6)|wxGv{E$G zu9q+G3~K4?Z{of6ssbe9+Y=Zde2@+gBEZB%BaREYuN|b^<@vAQz9ou2a16qMPx6}2 zN(rWz;SykE#o~>=sn2{lVI}dg_gm_*RAZ_-dU|I9#}*fP{A~E*gdB%h#m&l&g*Ljt zI01-t&{76?SWhCT;8w@(!2~$;L8;frZP correlation_length(ψ; sector = leftunit(ψ)), states), + p, Ds, correlation_length.(states), ylabel = "Correlation length", xlabel = "Bond dimension", xscale = :log10, yscale = :log10, inset = bbox(0.2, 0.51, 0.25, 0.25), @@ -285,13 +285,13 @@ quasicondensate_density = map(state -> abs2(expectation_value(state, (0,) => a_o ```` 7-element Vector{Float64}: - 0.31098779070601257 - 0.2881478589434881 - 0.2702000230423913 - 0.25712728516508654 - 0.24685385948652017 - 0.23539753899204166 - 0.22799654088348645 + 0.3097427792977986 + 0.2881478005839194 + 0.27020015650045337 + 0.257127287055965 + 0.24685385184650885 + 0.23539786293063855 + 0.22799664604968056 ```` We may now also visualize the momentum distribution function, which is obtained as the From 47ee88a9eeff35fb77727692db9b4f7827f0bb9c Mon Sep 17 00:00:00 2001 From: lkdvos Date: Sat, 4 Jul 2026 21:34:15 -0400 Subject: [PATCH 33/76] fix: correlator with i >= j now throws ArgumentError; document expectation_value unit-cell convention The i < j precondition previously only logged @error and continued into a meaningless contraction, while howto/observables.md promised an error. Also add a docstring note that expectation_value of an infinite operator returns the unit-cell total, not a per-site value. Co-Authored-By: Claude Fable 5 --- src/algorithms/correlators.jl | 5 +++-- src/algorithms/expval.jl | 5 +++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/algorithms/correlators.jl b/src/algorithms/correlators.jl index 4413ef63c..5ffac26b3 100644 --- a/src/algorithms/correlators.jl +++ b/src/algorithms/correlators.jl @@ -3,7 +3,8 @@ correlator(ψ, O12, i, j) Compute the 2-point correlator <ψ|O1[i]O2[j]|ψ> for inserting `O1` at `i` and `O2` at `j`. -Also accepts ranges for `j`. +Also accepts ranges for `j`. The sites must be ordered as `i < j`; other orderings throw an +`ArgumentError`. """ function correlator end @@ -14,7 +15,7 @@ end function correlator( state::AbstractMPS, O₁::MPOTensor, O₂::MPOTensor, i::Int, js::AbstractRange{Int} ) - first(js) > i || @error "i should be smaller than j ($i, $(first(js)))" + first(js) > i || throw(ArgumentError("i should be smaller than j ($i, $(first(js)))")) S₁ = _firstspace(O₁) isunitspace(S₁) || throw(ArgumentError("O₁ should start with a trivial leg.")) S₂ = _lastspace(O₂) diff --git a/src/algorithms/expval.jl b/src/algorithms/expval.jl index 0daf7dc03..f72ed173d 100644 --- a/src/algorithms/expval.jl +++ b/src/algorithms/expval.jl @@ -25,6 +25,11 @@ the operator is a `AbstractTensorMap` that acts on the physical space of a singl # Returns - `val::Number`: the (normalized) expectation value `⟨ψ|O|ψ⟩ / ⟨ψ|ψ⟩`. +!!! note "Infinite operators" + For an infinite state and an infinite operator (e.g. an `InfiniteMPOHamiltonian`), the + return value is the total over one unit cell; divide by `length(ψ)` to obtain a + per-site value. + # Examples ```jldoctest julia> ψ = FiniteMPS(ones(Float64, (ℂ^2)^4)); From b4628171b7c4fb95bc533d928698ea02f26109f8 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Sat, 4 Jul 2026 21:34:30 -0400 Subject: [PATCH 34/76] docs(w1): resolve maintainer-review flags in tutorials and TFIM example Maintainer decisions from the round-1 review walkthrough (2026-07-04): - delete the 22 confirmed REVIEW flags; physics framing stands as written - fix the DMRG log description (Galerkin error + energy, not 'improvement') - switch the finite magnetization sweeps (tutorial section 5 and the example's finite branch) from periodic_boundary_conditions to the open FiniteChain, and re-verify both empirically - rewrite the abs()/symmetry-breaking story: exact finite-L ground state is symmetric; DMRG lands on a broken branch because it carries less entanglement; genuine SSB only in the thermodynamic limit - align crossover prose with the verified runs: the finite-chain drop is an algorithm-selection effect below g = 1, the infinite curve pins the transition at g = 1 (two new REVIEW flags mark this changed story) - state correlation_length units; soften 'maximally entangled' - re-render the TFIM example (figures + index.md + notebook) Co-Authored-By: Claude Fable 5 --- docs/src/examples/index.md | 2 - .../quantum1d/0.tfim-groundstate/figure-1.png | Bin 22901 -> 23421 bytes .../quantum1d/0.tfim-groundstate/figure-3.png | Bin 18355 -> 18205 bytes .../quantum1d/0.tfim-groundstate/index.md | 67 ++++++++--------- .../quantum1d/0.tfim-groundstate/main.ipynb | 71 +++++++++--------- docs/src/tutorials/first_groundstate.md | 32 +++----- docs/src/tutorials/thermodynamic_limit.md | 22 ++---- examples/Cache.toml | 2 +- examples/quantum1d/0.tfim-groundstate/main.jl | 67 ++++++++--------- 9 files changed, 117 insertions(+), 146 deletions(-) diff --git a/docs/src/examples/index.md b/docs/src/examples/index.md index 67193a47a..39ad636ac 100644 --- a/docs/src/examples/index.md +++ b/docs/src/examples/index.md @@ -54,7 +54,6 @@ A useful, diagnostic-driven example for recognizing and debugging convergence fa Distinguishes the two symmetry-protected topological phases of the SU(2)-symmetric spin-1 Heisenberg chain by restricting the virtual `SU2Space` to integer or half-integer charges, then compares the two resulting ground states through their energy, transfer-matrix spectrum (`transferplot`), entanglement spectrum (`entanglementplot`), and entanglement entropy (`entropy`). Builds directly on the symmetry machinery introduced in the Haldane gap example. - **Level: intermediate/advanced.** ### [Hubbard chain at half filling](quantum1d/6.hubbard/index.md) @@ -79,7 +78,6 @@ A technical, comparison-heavy example built around `MPSKit.infinite_temperature_ The most comprehensive example in the gallery: works directly in the thermodynamic limit with a truncated bosonic local Hilbert space, extracts correlation functions and the correlation length as a function of bond dimension, computes the momentum distribution, and maps out the Mott-insulator/superfluid structure of the phase diagram from the ground-state response to an applied phase twist. Touches most of the ground-state toolbox (`InfiniteMPS`, `find_groundstate`, bond-dimension control, `expectation_value`-based observables) in a single, longer study. - **Level: advanced.** ## Classical (2+0)d diff --git a/docs/src/examples/quantum1d/0.tfim-groundstate/figure-1.png b/docs/src/examples/quantum1d/0.tfim-groundstate/figure-1.png index 0269c8380b7a8ded03f30682c412a200c5218979..bfa4562426ced60e0ab517e6f5c650ad17686a9b 100644 GIT binary patch literal 23421 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 literal 22901 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 diff --git a/docs/src/examples/quantum1d/0.tfim-groundstate/figure-3.png b/docs/src/examples/quantum1d/0.tfim-groundstate/figure-3.png index e6397bc9c1addeb10fc59f2eab14dddec950b8ee..83427b543fbbf72cd2559f54b07c5697b8d0aa40 100644 GIT binary patch literal 18205 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 literal 18355 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 H`TqX{XpE$f diff --git a/docs/src/examples/quantum1d/0.tfim-groundstate/index.md b/docs/src/examples/quantum1d/0.tfim-groundstate/index.md index 67e8d9ad0..ca4e888d0 100644 --- a/docs/src/examples/quantum1d/0.tfim-groundstate/index.md +++ b/docs/src/examples/quantum1d/0.tfim-groundstate/index.md @@ -27,13 +27,11 @@ dimensionless field ``g`` tunes the competition between the ``\sigma^z\sigma^z`` interaction and the transverse ``\sigma^x`` field. The model has a quantum critical point at ``g = 1``. - - Rather than looking at a single field value, we will scan ``g`` across the transition and diagnose it three independent ways, comparing a *finite* chain against a calculation performed *directly in the thermodynamic limit*: -1. the order parameter ``|\langle\sigma^z\rangle|``, computed both for a finite ring and +1. the order parameter ``|\langle\sigma^z\rangle|``, computed both for a finite chain and for an infinite chain, in one figure; 2. the entanglement entropy of the infinite state; 3. the correlation length of the infinite state. @@ -53,9 +51,8 @@ We fix a finite chain length `L`, a bond dimension `D` (the accuracy knob, see [Controlling bond dimension](@ref howto_bond_dimension)), and the set of field values to scan. `D` is kept modest so the whole page runs in a couple of minutes; increasing it sharpens -every curve below. - - +the infinite-state diagnostics below (the finite-chain curve responds to `D` in a less +obvious way, as we will see). ````julia L = 16 @@ -71,17 +68,17 @@ g_values = 0.1:0.1:2.0 We compute the order parameter ``|\langle\sigma^z\rangle|`` two ways at every field value. -For the **finite** calculation we place the chain on a ring with -[`periodic_boundary_conditions`](@ref) — this removes the open-end boundary effects and -gives a cleaner curve at fixed `L` — and optimize with [`DMRG`](@ref). -We average ``\langle\sigma^z_i\rangle`` over the sites and take the absolute value, because -a finite chain does not spontaneously break its symmetry and the raw sum can land on either -sign (see the discussion in [Your first ground state](@ref tutorial_first_groundstate)). +For the **finite** calculation we use an open chain of `L` sites, exactly as in the +tutorial, and optimize with [`DMRG`](@ref). +We average ``\langle\sigma^z_i\rangle`` over the sites and take the absolute value: the +exact finite-`L` ground state is symmetric, but DMRG lands on one of the two +symmetry-broken states with an arbitrary sign (see the discussion in +[Your first ground state](@ref tutorial_first_groundstate)). ````julia ψ₀_finite = FiniteMPS(L, ℂ^2, ℂ^D) M_finite = map(g_values) do g - H = periodic_boundary_conditions(transverse_field_ising(; g = g), L) + H = transverse_field_ising(FiniteChain(L); g = g) ψ, = find_groundstate(ψ₀_finite, H, DMRG(; verbosity = 0)) return abs(sum(expectation_value(ψ, i => σᶻ()) for i in 1:L)) / L end; @@ -102,9 +99,9 @@ end; ```` The order parameter of a translation-invariant state is just ``\langle\sigma^z\rangle`` on -a single site of the unit cell; we again take the absolute value. - - +a single site of the unit cell; we again take the absolute value, because on the ordered +side the infinite state settles into one of the two symmetry-broken ground states (see +[The thermodynamic limit](@ref tutorial_thermodynamic_limit)). ````julia M_infinite = [abs(expectation_value(ψ, 1 => σᶻ())) for ψ in states_infinite]; @@ -116,7 +113,7 @@ Plotting both curves in a single figure lets us compare them directly. p_magnetization = plot(; xlabel = "g", ylabel = "|⟨σᶻ⟩|", title = "TFIM order parameter", legend = :bottomleft ) -scatter!(p_magnetization, g_values, M_finite; label = "finite ring, L = $L, D = $D") +scatter!(p_magnetization, g_values, M_finite; label = "finite chain, L = $L, D = $D") scatter!(p_magnetization, g_values, M_infinite; label = "infinite, D = $D") vline!(p_magnetization, [1.0]; color = "gray", linestyle = :dash, label = "g = 1") p_magnetization @@ -124,13 +121,21 @@ p_magnetization ![](figure-1.png) -Both curves are large on the ordered side (small `g`) and fall toward zero on the -disordered side (large `g`), with the crossover near `g = 1`. -The finite ring rounds the transition off into a smooth crossover whose apparent location -is shifted away from `g = 1`, while the infinite calculation drops much more steeply near -the critical point because there is no finite size to smear it out. - - +Both calculations agree deep in either phase, but near the transition they tell very +different stories. +The infinite curve stays on its ordered branch essentially up to `g = 1` and then +collapses: it locates the critical point cleanly. +The finite-chain curve instead drops to zero far earlier — at this `L` and `D` the +variational optimum on the open chain switches from the symmetry-broken branch to the +exactly symmetric ground state, whose magnetization vanishes. +Where that switch happens is set by `L`, `D`, and even the random starting state, not by +the physics; the same sweep at `D = 4` in +[Your first ground state](@ref tutorial_first_groundstate) puts it elsewhere. +That is the real lesson of this panel: the finite-chain order parameter is dominated by +which state the algorithm selects, while the calculation performed directly in the +thermodynamic limit pins the transition at `g = 1`. + + ## 2. Entanglement entropy across the transition @@ -140,8 +145,6 @@ For an [`InfiniteMPS`](@ref), [`entropy`](@ref) returns the von Neumann entangle per bond, one value for each site of the unit cell. Our unit cell has a single site, so we take the one entry with `only`. - - ````julia S_infinite = [real(only(entropy(ψ))) for ψ in states_infinite] p_entropy = scatter( @@ -157,11 +160,9 @@ p_entropy The entropy peaks near `g = 1`. That peak is the entanglement signature of the phase transition: at criticality -correlations become long-ranged and the ground state is maximally entangled, whereas deep +correlations become long-ranged and the ground state is at its most entangled, whereas deep in either phase the state is closer to a simple product and the entropy is small. - - ## 3. Correlation length across the transition The [`correlation_length`](@ref) measures how far apart two spins can still influence each @@ -188,16 +189,12 @@ At a genuine critical point it would diverge, but a finite bond dimension `D` ca capture correlations out to a finite range, so what we measure is large-but-capped rather than infinite — the peak grows and sharpens as `D` is increased. - - ## What you now have Three independent diagnostics — the order parameter, the entanglement entropy, and the correlation length — all locate the transition of the transverse-field Ising model near -`g = 1`, and the finite-versus-infinite comparison shows concretely how working directly in -the thermodynamic limit removes the finite-size rounding. - - +`g = 1`, and the finite-versus-infinite comparison shows concretely why the thermodynamic +limit is the right place to measure it. From here the gallery goes further. The Ising CFT example extracts the momentum-resolved excitation spectrum right at diff --git a/docs/src/examples/quantum1d/0.tfim-groundstate/main.ipynb b/docs/src/examples/quantum1d/0.tfim-groundstate/main.ipynb index 2138941b8..212aa223d 100644 --- a/docs/src/examples/quantum1d/0.tfim-groundstate/main.ipynb +++ b/docs/src/examples/quantum1d/0.tfim-groundstate/main.ipynb @@ -25,13 +25,11 @@ "interaction and the transverse $\\sigma^x$ field.\n", "The model has a quantum critical point at $g = 1$.\n", "\n", - "\n", - "\n", "Rather than looking at a single field value, we will scan $g$ across the transition and\n", "diagnose it three independent ways, comparing a *finite* chain against a calculation\n", "performed *directly in the thermodynamic limit*:\n", "\n", - "1. the order parameter $|\\langle\\sigma^z\\rangle|$, computed both for a finite ring and\n", + "1. the order parameter $|\\langle\\sigma^z\\rangle|$, computed both for a finite chain and\n", " for an infinite chain, in one figure;\n", "2. the entanglement entropy of the infinite state;\n", "3. the correlation length of the infinite state.\n", @@ -66,9 +64,8 @@ "Controlling bond dimension), and the set of field values to\n", "scan.\n", "`D` is kept modest so the whole page runs in a couple of minutes; increasing it sharpens\n", - "every curve below.\n", - "\n", - "" + "the infinite-state diagnostics below (the finite-chain curve responds to `D` in a less\n", + "obvious way, as we will see)." ] }, { @@ -90,12 +87,12 @@ "\n", "We compute the order parameter $|\\langle\\sigma^z\\rangle|$ two ways at every field value.\n", "\n", - "For the **finite** calculation we place the chain on a ring with\n", - "`periodic_boundary_conditions` — this removes the open-end boundary effects and\n", - "gives a cleaner curve at fixed `L` — and optimize with `DMRG`.\n", - "We average $\\langle\\sigma^z_i\\rangle$ over the sites and take the absolute value, because\n", - "a finite chain does not spontaneously break its symmetry and the raw sum can land on either\n", - "sign (see the discussion in Your first ground state)." + "For the **finite** calculation we use an open chain of `L` sites, exactly as in the\n", + "tutorial, and optimize with `DMRG`.\n", + "We average $\\langle\\sigma^z_i\\rangle$ over the sites and take the absolute value: the\n", + "exact finite-`L` ground state is symmetric, but DMRG lands on one of the two\n", + "symmetry-broken states with an arbitrary sign (see the discussion in\n", + "Your first ground state)." ] }, { @@ -106,7 +103,7 @@ "source": [ "ψ₀_finite = FiniteMPS(L, ℂ^2, ℂ^D)\n", "M_finite = map(g_values) do g\n", - " H = periodic_boundary_conditions(transverse_field_ising(; g = g), L)\n", + " H = transverse_field_ising(FiniteChain(L); g = g)\n", " ψ, = find_groundstate(ψ₀_finite, H, DMRG(; verbosity = 0))\n", " return abs(sum(expectation_value(ψ, i => σᶻ()) for i in 1:L)) / L\n", "end;" @@ -141,9 +138,9 @@ "metadata": {}, "source": [ "The order parameter of a translation-invariant state is just $\\langle\\sigma^z\\rangle$ on\n", - "a single site of the unit cell; we again take the absolute value.\n", - "\n", - "" + "a single site of the unit cell; we again take the absolute value, because on the ordered\n", + "side the infinite state settles into one of the two symmetry-broken ground states (see\n", + "The thermodynamic limit)." ] }, { @@ -171,7 +168,7 @@ "p_magnetization = plot(;\n", " xlabel = \"g\", ylabel = \"|⟨σᶻ⟩|\", title = \"TFIM order parameter\", legend = :bottomleft\n", ")\n", - "scatter!(p_magnetization, g_values, M_finite; label = \"finite ring, L = $L, D = $D\")\n", + "scatter!(p_magnetization, g_values, M_finite; label = \"finite chain, L = $L, D = $D\")\n", "scatter!(p_magnetization, g_values, M_infinite; label = \"infinite, D = $D\")\n", "vline!(p_magnetization, [1.0]; color = \"gray\", linestyle = :dash, label = \"g = 1\")\n", "p_magnetization" @@ -181,13 +178,21 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Both curves are large on the ordered side (small `g`) and fall toward zero on the\n", - "disordered side (large `g`), with the crossover near `g = 1`.\n", - "The finite ring rounds the transition off into a smooth crossover whose apparent location\n", - "is shifted away from `g = 1`, while the infinite calculation drops much more steeply near\n", - "the critical point because there is no finite size to smear it out.\n", + "Both calculations agree deep in either phase, but near the transition they tell very\n", + "different stories.\n", + "The infinite curve stays on its ordered branch essentially up to `g = 1` and then\n", + "collapses: it locates the critical point cleanly.\n", + "The finite-chain curve instead drops to zero far earlier — at this `L` and `D` the\n", + "variational optimum on the open chain switches from the symmetry-broken branch to the\n", + "exactly symmetric ground state, whose magnetization vanishes.\n", + "Where that switch happens is set by `L`, `D`, and even the random starting state, not by\n", + "the physics; the same sweep at `D = 4` in\n", + "Your first ground state puts it elsewhere.\n", + "That is the real lesson of this panel: the finite-chain order parameter is dominated by\n", + "which state the algorithm selects, while the calculation performed directly in the\n", + "thermodynamic limit pins the transition at `g = 1`.\n", "\n", - "" + "" ] }, { @@ -200,9 +205,7 @@ "grows sharply as we approach it.\n", "For an `InfiniteMPS`, `entropy` returns the von Neumann entanglement entropy\n", "per bond, one value for each site of the unit cell.\n", - "Our unit cell has a single site, so we take the one entry with `only`.\n", - "\n", - "" + "Our unit cell has a single site, so we take the one entry with `only`." ] }, { @@ -227,10 +230,8 @@ "source": [ "The entropy peaks near `g = 1`.\n", "That peak is the entanglement signature of the phase transition: at criticality\n", - "correlations become long-ranged and the ground state is maximally entangled, whereas deep\n", - "in either phase the state is closer to a simple product and the entropy is small.\n", - "\n", - "" + "correlations become long-ranged and the ground state is at its most entangled, whereas deep\n", + "in either phase the state is closer to a simple product and the entropy is small." ] }, { @@ -269,9 +270,7 @@ "The correlation length peaks near `g = 1` as well.\n", "At a genuine critical point it would diverge, but a finite bond dimension `D` can only\n", "capture correlations out to a finite range, so what we measure is large-but-capped rather\n", - "than infinite — the peak grows and sharpens as `D` is increased.\n", - "\n", - "" + "than infinite — the peak grows and sharpens as `D` is increased." ] }, { @@ -282,10 +281,8 @@ "\n", "Three independent diagnostics — the order parameter, the entanglement entropy, and the\n", "correlation length — all locate the transition of the transverse-field Ising model near\n", - "`g = 1`, and the finite-versus-infinite comparison shows concretely how working directly in\n", - "the thermodynamic limit removes the finite-size rounding.\n", - "\n", - "\n", + "`g = 1`, and the finite-versus-infinite comparison shows concretely why the thermodynamic\n", + "limit is the right place to measure it.\n", "\n", "From here the gallery goes further.\n", "The Ising CFT example extracts the momentum-resolved excitation spectrum right at\n", diff --git a/docs/src/tutorials/first_groundstate.md b/docs/src/tutorials/first_groundstate.md index fe7faef41..f9a825b9e 100644 --- a/docs/src/tutorials/first_groundstate.md +++ b/docs/src/tutorials/first_groundstate.md @@ -17,8 +17,6 @@ The ground state of ``H`` lives in a Hilbert space of dimension ``2^L``, which i A *matrix product state* (MPS) sidesteps this by storing the state as a chain of small tensors, one per site, whose sizes we control directly; this is what makes the calculation below tractable. The details of that compression are the subject of the concept pages — here we simply use it. - - ## Loading the packages Every code block on this page shares one Julia session, so we only need to load packages once. @@ -44,8 +42,6 @@ The returned object is an `MPOHamiltonian`: the Hamiltonian written in matrix-pr You do not need to know its internals to use it — MPSKit's algorithms consume it directly. For other ways to build Hamiltonians see [Building Hamiltonians](@ref howto_hamiltonians). - - ## 2. Build the initial state DMRG is an optimization: it needs a starting state to improve. @@ -78,9 +74,7 @@ Now we run the calculation. ``` DMRG (the density-matrix renormalization group) sweeps back and forth along the chain, locally optimizing each tensor while holding the others fixed, and repeats until the state stops changing. -The lines printed above are the per-iteration convergence log (shown at the default `verbosity`); each reports how much the state improved on that sweep. - - +The lines printed above are the per-iteration convergence log (shown at the default `verbosity`); each reports the sweep number, the current energy, and a convergence measure (the same Galerkin residual returned as `ϵ` below). !!! note "The algorithm is optional" Calling `find_groundstate(ψ₀, H)` with no algorithm argument selects DMRG automatically for a finite input, so the explicit `DMRG()` above is only for clarity. @@ -119,21 +113,17 @@ variance(ψ, H) A small variance indicates the state is close to an eigenstate of `H`. More recipes for observables live in [Computing observables](@ref howto_observables). - - ## 5. Magnetization across the transition The payoff: we sweep the field `g` from 0 to 2 and, for each value, find the ground state and record its average magnetization. This traces out the phase transition. -For this sweep we place the chain on a ring rather than an open segment: `transverse_field_ising()` with no lattice argument builds the Hamiltonian for an infinite chain, and [`periodic_boundary_conditions`](@ref) wraps it onto a finite ring of `L` sites. - - +Each step of the sweep repeats the workflow of Sections 1–4 on the same open chain — only the value of `g` changes. ```@example first-groundstate g_values = 0:0.1:2 M = map(g_values) do g - Hg = periodic_boundary_conditions(transverse_field_ising(; g = g), L) + Hg = transverse_field_ising(FiniteChain(L); g = g) ψg, = find_groundstate(ψ₀, Hg; verbosity = 0) return abs(sum(expectation_value(ψg, i => σᶻ()) for i in 1:L)) / L end @@ -141,13 +131,15 @@ scatter(g_values, M; xlabel = "g", ylabel = "M", label = "D = $D", title = "TFIM ``` Here we take the **absolute value** of the mean magnetization. -A finite chain does not spontaneously break its symmetry, so the raw ``\sum_i\langle\sigma^z_i\rangle`` can land on either sign (or average toward zero); taking `abs` collapses the two symmetry-related ground states onto a single, well-defined order-parameter curve. - - - -The plot should show the magnetization large on the ordered side (small `g`) and dropping toward zero on the disordered side (large `g`), with the crossover near `g = 1`. - - +At finite `L` the exact ground state does not break the symmetry: it is the symmetric combination of the two oppositely magnetized states, and its raw magnetization ``\sum_i\langle\sigma^z_i\rangle`` is exactly zero. +DMRG at finite bond dimension, however, converges to one of the two symmetry-broken states instead, because either one carries far less entanglement than their symmetric superposition. +Which sign it lands on is arbitrary — it can differ from run to run and between values of `g` — so taking `abs` makes the order-parameter curve well-defined regardless of the branch. + +The plot shows the magnetization close to 1 deep on the ordered side, then dropping abruptly to zero — noticeably *below* the thermodynamic critical point `g = 1` (around `g ≈ 0.6` at these parameters). +Both features follow from how the state is computed rather than from the physics of the transition: on the ordered side DMRG sits on one symmetry-broken branch, and past the drop it recovers the exactly symmetric ground state, whose magnetization vanishes. +Exactly where the drop lands depends on `L`, `D`, and even the random starting state, so its location is *not* a measurement of the critical point. + +The honest way to locate the transition is the subject of the next tutorial, which performs this sweep directly in the thermodynamic limit. ## Where to go next diff --git a/docs/src/tutorials/thermodynamic_limit.md b/docs/src/tutorials/thermodynamic_limit.md index c8920f6dd..3f51bb745 100644 --- a/docs/src/tutorials/thermodynamic_limit.md +++ b/docs/src/tutorials/thermodynamic_limit.md @@ -60,8 +60,6 @@ We optimize with [`VUMPS`](@ref), the infinite-chain workhorse, passing it expli The lines printed above are VUMPS's per-iteration convergence log, shown at the default `verbosity`. VUMPS (the variational uniform matrix product state algorithm) optimizes the single repeated tensor directly in the thermodynamic limit, iterating until it reaches a fixed point. - - The return value has the same shape as on the finite chain: the optimized state `ψ`, the reusable `envs`, and a convergence-error measure `ϵ`. !!! note "The algorithm is optional here too" @@ -91,9 +89,7 @@ The infinite setting also unlocks an observable with no finite-chain analogue: t correlation_length(ψ) ``` - - -The correlation length tells us how far apart two spins can still "feel" each other. +The correlation length tells us how far apart two spins can still "feel" each other; it is measured in units of the lattice spacing. It grows as we approach the critical point `g = 1`, where correlations become long-ranged. We can see this by optimizing a second state right at criticality and comparing: @@ -103,12 +99,8 @@ H_crit = transverse_field_ising(; g = 1.0) correlation_length(ψ_crit) ``` - - At a genuine critical point the correlation length diverges, but a finite bond dimension `D` can only capture correlations out to a finite range, so what we measure is large but capped rather than infinite. - - ## 4. Magnetization across the transition As on the finite chain, we finish by sweeping the field `g` and recording the magnetization. @@ -124,15 +116,13 @@ end scatter(g_values, M; xlabel = "g", ylabel = "M", label = "D = $D", title = "TFIM magnetization (L = ∞)") ``` -Compared with the finite-chain curve, the transition here should look sharper and its crossover should sit closer to the thermodynamic critical point `g = 1`, because we have removed the finite-size rounding. - - +Compare this with the finite-chain sweep of the previous tutorial, where the magnetization dropped to zero well before `g = 1`, at a point set by the algorithm rather than by the physics. +The infinite curve instead tracks the transition itself: the magnetization stays on its ordered branch all the way up to the critical point and collapses to zero right at `g = 1`. +What little smearing remains around the critical point is a finite-bond-dimension effect, and it shrinks as `D` grows. We still take the **absolute value** of the magnetization, but for a subtly different reason than on the finite chain. -A finite chain cannot spontaneously break its symmetry, so there `abs` merely collapsed a sign that averaged toward zero. -An infinite MPS at finite bond dimension, by contrast, *can* settle into one of the two symmetry-broken ground states on the ordered side, landing on a definite nonzero magnetization of either sign; `abs` again puts both branches onto a single order-parameter curve. - - +On the finite chain the nonzero magnetization was an artifact of the algorithm: the exact ground state there is symmetric, and DMRG landed on a symmetry-broken state only because it carries less entanglement. +In the thermodynamic limit the symmetry breaking is genuine — the two oppositely magnetized states become true ground states — and an infinite MPS at finite bond dimension settles into one of them on the ordered side, landing on a definite nonzero magnetization of either sign; `abs` again puts both branches onto a single order-parameter curve. ## Where to go next diff --git a/examples/Cache.toml b/examples/Cache.toml index 905489698..c3645d920 100644 --- a/examples/Cache.toml +++ b/examples/Cache.toml @@ -10,4 +10,4 @@ "5.haldane-spt" = "c8fd3a8d406b9ff3ea9a34b596c5910d81e4eb710b665d7fa04e30f795a46086" "4.xxz-heisenberg" = "9033fb104c3f658ccb1b8e335b986b7abda59e0b5359be086d3b62e1cc32ebd6" "1.ising-cft" = "3d34757eee7b95120b746c5e30e713203a876a87353ecd9937798f29183c9916" -"0.tfim-groundstate" = "b42a582081dc9e3a92839360f92857d2cd5071184539fa658ef087eee40c5cee" +"0.tfim-groundstate" = "f436cb78f72c7ca59c99a192ab5649c57f912f9fc4838e33faa7440a025f0893" diff --git a/examples/quantum1d/0.tfim-groundstate/main.jl b/examples/quantum1d/0.tfim-groundstate/main.jl index 71bce351e..79565b9df 100644 --- a/examples/quantum1d/0.tfim-groundstate/main.jl +++ b/examples/quantum1d/0.tfim-groundstate/main.jl @@ -20,13 +20,11 @@ dimensionless field ``g`` tunes the competition between the ``\sigma^z\sigma^z`` interaction and the transverse ``\sigma^x`` field. The model has a quantum critical point at ``g = 1``. - - Rather than looking at a single field value, we will scan ``g`` across the transition and diagnose it three independent ways, comparing a *finite* chain against a calculation performed *directly in the thermodynamic limit*: -1. the order parameter ``|\langle\sigma^z\rangle|``, computed both for a finite ring and +1. the order parameter ``|\langle\sigma^z\rangle|``, computed both for a finite chain and for an infinite chain, in one figure; 2. the entanglement entropy of the infinite state; 3. the correlation length of the infinite state. @@ -46,9 +44,8 @@ We fix a finite chain length `L`, a bond dimension `D` (the accuracy knob, see [Controlling bond dimension](@ref howto_bond_dimension)), and the set of field values to scan. `D` is kept modest so the whole page runs in a couple of minutes; increasing it sharpens -every curve below. - - +the infinite-state diagnostics below (the finite-chain curve responds to `D` in a less +obvious way, as we will see). """ L = 16 @@ -60,17 +57,17 @@ md""" We compute the order parameter ``|\langle\sigma^z\rangle|`` two ways at every field value. -For the **finite** calculation we place the chain on a ring with -[`periodic_boundary_conditions`](@ref) — this removes the open-end boundary effects and -gives a cleaner curve at fixed `L` — and optimize with [`DMRG`](@ref). -We average ``\langle\sigma^z_i\rangle`` over the sites and take the absolute value, because -a finite chain does not spontaneously break its symmetry and the raw sum can land on either -sign (see the discussion in [Your first ground state](@ref tutorial_first_groundstate)). +For the **finite** calculation we use an open chain of `L` sites, exactly as in the +tutorial, and optimize with [`DMRG`](@ref). +We average ``\langle\sigma^z_i\rangle`` over the sites and take the absolute value: the +exact finite-`L` ground state is symmetric, but DMRG lands on one of the two +symmetry-broken states with an arbitrary sign (see the discussion in +[Your first ground state](@ref tutorial_first_groundstate)). """ ψ₀_finite = FiniteMPS(L, ℂ^2, ℂ^D) M_finite = map(g_values) do g - H = periodic_boundary_conditions(transverse_field_ising(; g = g), L) + H = transverse_field_ising(FiniteChain(L); g = g) ψ, = find_groundstate(ψ₀_finite, H, DMRG(; verbosity = 0)) return abs(sum(expectation_value(ψ, i => σᶻ()) for i in 1:L)) / L end; @@ -91,9 +88,9 @@ end; md""" The order parameter of a translation-invariant state is just ``\langle\sigma^z\rangle`` on -a single site of the unit cell; we again take the absolute value. - - +a single site of the unit cell; we again take the absolute value, because on the ordered +side the infinite state settles into one of the two symmetry-broken ground states (see +[The thermodynamic limit](@ref tutorial_thermodynamic_limit)). """ M_infinite = [abs(expectation_value(ψ, 1 => σᶻ())) for ψ in states_infinite]; @@ -105,19 +102,27 @@ Plotting both curves in a single figure lets us compare them directly. p_magnetization = plot(; xlabel = "g", ylabel = "|⟨σᶻ⟩|", title = "TFIM order parameter", legend = :bottomleft ) -scatter!(p_magnetization, g_values, M_finite; label = "finite ring, L = $L, D = $D") +scatter!(p_magnetization, g_values, M_finite; label = "finite chain, L = $L, D = $D") scatter!(p_magnetization, g_values, M_infinite; label = "infinite, D = $D") vline!(p_magnetization, [1.0]; color = "gray", linestyle = :dash, label = "g = 1") p_magnetization md""" -Both curves are large on the ordered side (small `g`) and fall toward zero on the -disordered side (large `g`), with the crossover near `g = 1`. -The finite ring rounds the transition off into a smooth crossover whose apparent location -is shifted away from `g = 1`, while the infinite calculation drops much more steeply near -the critical point because there is no finite size to smear it out. - - +Both calculations agree deep in either phase, but near the transition they tell very +different stories. +The infinite curve stays on its ordered branch essentially up to `g = 1` and then +collapses: it locates the critical point cleanly. +The finite-chain curve instead drops to zero far earlier — at this `L` and `D` the +variational optimum on the open chain switches from the symmetry-broken branch to the +exactly symmetric ground state, whose magnetization vanishes. +Where that switch happens is set by `L`, `D`, and even the random starting state, not by +the physics; the same sweep at `D = 4` in +[Your first ground state](@ref tutorial_first_groundstate) puts it elsewhere. +That is the real lesson of this panel: the finite-chain order parameter is dominated by +which state the algorithm selects, while the calculation performed directly in the +thermodynamic limit pins the transition at `g = 1`. + + """ md""" @@ -128,8 +133,6 @@ grows sharply as we approach it. For an [`InfiniteMPS`](@ref), [`entropy`](@ref) returns the von Neumann entanglement entropy per bond, one value for each site of the unit cell. Our unit cell has a single site, so we take the one entry with `only`. - - """ S_infinite = [real(only(entropy(ψ))) for ψ in states_infinite] @@ -144,10 +147,8 @@ p_entropy md""" The entropy peaks near `g = 1`. That peak is the entanglement signature of the phase transition: at criticality -correlations become long-ranged and the ground state is maximally entangled, whereas deep +correlations become long-ranged and the ground state is at its most entangled, whereas deep in either phase the state is closer to a simple product and the entropy is small. - - """ md""" @@ -174,8 +175,6 @@ The correlation length peaks near `g = 1` as well. At a genuine critical point it would diverge, but a finite bond dimension `D` can only capture correlations out to a finite range, so what we measure is large-but-capped rather than infinite — the peak grows and sharpens as `D` is increased. - - """ md""" @@ -183,10 +182,8 @@ md""" Three independent diagnostics — the order parameter, the entanglement entropy, and the correlation length — all locate the transition of the transverse-field Ising model near -`g = 1`, and the finite-versus-infinite comparison shows concretely how working directly in -the thermodynamic limit removes the finite-size rounding. - - +`g = 1`, and the finite-versus-infinite comparison shows concretely why the thermodynamic +limit is the right place to measure it. From here the gallery goes further. The Ising CFT example extracts the momentum-resolved excitation spectrum right at From 5ad6415f3ab48eeade477b4afbd6f476c3c35240 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Sat, 4 Jul 2026 21:34:43 -0400 Subject: [PATCH 35/76] docs(examples): silence inline solver logs, fill Hubbard citation, resolve xy-finiteT todos - verbosity = 0 for the log-dumping ground-state calls in 1.ising-cft, 3.ising-dqpt and 6.hubbard; verbosity = 1 in 4.xxz-heisenberg so the pedagogical convergence-failure warnings survive without the ~400-line iteration logs - cite Essler-Frahm-Goehmann-Kluemper-Korepin for the Lieb-Wu energy integral (the empty 'Eq. (6.82) in []()' link) - replace the two xy-finiteT derivation todos with Lieb-Schultz-Mattis (1961) references; drop the stale figure todo Rendered index.md pages intentionally not regenerated here (expensive); the examples pipeline will pick these up on its next run via Cache.toml. Co-Authored-By: Claude Fable 5 --- examples/quantum1d/1.ising-cft/main.jl | 2 +- examples/quantum1d/3.ising-dqpt/main.jl | 8 ++++---- examples/quantum1d/4.xxz-heisenberg/main.jl | 10 +++++----- examples/quantum1d/6.hubbard/main.jl | 4 ++-- examples/quantum1d/7.xy-finiteT/main.jl | 8 ++------ 5 files changed, 14 insertions(+), 18 deletions(-) diff --git a/examples/quantum1d/1.ising-cft/main.jl b/examples/quantum1d/1.ising-cft/main.jl index a3f45887e..571e6ec74 100644 --- a/examples/quantum1d/1.ising-cft/main.jl +++ b/examples/quantum1d/1.ising-cft/main.jl @@ -122,7 +122,7 @@ can reach higher system sizes. L_mps = 20 H_mps = periodic_boundary_conditions(transverse_field_ising(), L_mps) D = 64 -ψ, envs, δ = find_groundstate(FiniteMPS(L_mps, ℂ^2, ℂ^D), H_mps, DMRG()); +ψ, envs, δ = find_groundstate(FiniteMPS(L_mps, ℂ^2, ℂ^D), H_mps, DMRG(; verbosity = 0)); md""" Excitations on top of the ground state can be found through the use of the quasiparticle diff --git a/examples/quantum1d/3.ising-dqpt/main.jl b/examples/quantum1d/3.ising-dqpt/main.jl index 3d445cf58..5fdd4dd3a 100644 --- a/examples/quantum1d/3.ising-dqpt/main.jl +++ b/examples/quantum1d/3.ising-dqpt/main.jl @@ -28,7 +28,7 @@ First we construct the Hamiltonian in MPO form, and obtain the pre-quenched grou L = 20 H₀ = transverse_field_ising(FiniteChain(L); g = -0.5) ψ₀ = FiniteMPS(L, ℂ^2, ℂ^10) -ψ₀, _ = find_groundstate(ψ₀, H₀, DMRG()); +ψ₀, _ = find_groundstate(ψ₀, H₀, DMRG(; verbosity = 0)); md""" ## Finite MPS quenching @@ -57,7 +57,7 @@ Putting it all together, we get function finite_sim(L; dt = 0.05, finaltime = 5.0) ψ₀ = FiniteMPS(L, ℂ^2, ℂ^10) H₀ = transverse_field_ising(FiniteChain(L); g = -0.5) - ψ₀, _ = find_groundstate(ψ₀, H₀, DMRG()) + ψ₀, _ = find_groundstate(ψ₀, H₀, DMRG(; verbosity = 0)) H₁ = transverse_field_ising(FiniteChain(L); g = -2.0) ψₜ = deepcopy(ψ₀) @@ -85,7 +85,7 @@ Similarly we could start with an initial infinite state and find the pre-quench ψ₀ = InfiniteMPS([ℂ^2], [ℂ^10]) H₀ = transverse_field_ising(; g = -0.5) -ψ₀, _ = find_groundstate(ψ₀, H₀, VUMPS()); +ψ₀, _ = find_groundstate(ψ₀, H₀, VUMPS(; verbosity = 0)); md""" The dot product of two infinite matrix product states scales as ``\alpha ^N`` where ``α`` is the dominant eigenvalue of the transfer matrix. @@ -123,7 +123,7 @@ The final code is function infinite_sim(dt = 0.05, finaltime = 5.0) ψ₀ = InfiniteMPS([ℂ^2], [ℂ^10]) - ψ₀, _ = find_groundstate(ψ₀, H₀, VUMPS()) + ψ₀, _ = find_groundstate(ψ₀, H₀, VUMPS(; verbosity = 0)) ψₜ = deepcopy(ψ₀) envs = environments(ψₜ, H₁, ψₜ) diff --git a/examples/quantum1d/4.xxz-heisenberg/main.jl b/examples/quantum1d/4.xxz-heisenberg/main.jl index 8c684e911..fb7f0340e 100644 --- a/examples/quantum1d/4.xxz-heisenberg/main.jl +++ b/examples/quantum1d/4.xxz-heisenberg/main.jl @@ -31,7 +31,7 @@ md""" The ground state can then be found by calling `find_groundstate`. """ -groundstate, cache, delta = find_groundstate(state, H, VUMPS()); +groundstate, cache, delta = find_groundstate(state, H, VUMPS(; verbosity = 1)); md""" As you can see, VUMPS struggles to converge. @@ -39,7 +39,7 @@ On its own, that is already quite curious. Maybe we can do better using another algorithm, such as gradient descent. """ -groundstate, cache, delta = find_groundstate(state, H, GradientGrassmann(; maxiter = 20)); +groundstate, cache, delta = find_groundstate(state, H, GradientGrassmann(; maxiter = 20, verbosity = 1)); md""" Convergence is quite slow and even fails after sufficiently many iterations. @@ -72,7 +72,7 @@ Alternatively, the Hamiltonian can be constructed directly on a two-site unit ce ## H2 = repeat(H, 2); -- copies the one-site version H2 = heisenberg_XXX(ComplexF64, Trivial, InfiniteChain(2); spin = 1 // 2) groundstate, envs, delta = find_groundstate( - state, H2, VUMPS(; maxiter = 100, tol = 1.0e-12) + state, H2, VUMPS(; maxiter = 100, tol = 1.0e-12, verbosity = 1) ); md""" @@ -81,7 +81,7 @@ The reason behind this becomes more obvious at higher bond dimensions: """ groundstate, envs, delta = find_groundstate( - state, H2, IDMRG2(; trscheme = truncrank(50), maxiter = 20, tol = 1.0e-12) + state, H2, IDMRG2(; trscheme = truncrank(50), maxiter = 20, tol = 1.0e-12, verbosity = 1) ); entanglementplot(groundstate) @@ -125,4 +125,4 @@ Even though the bond dimension is higher than in the example without symmetry, c println(dim(V1)) println(dim(V2)) -groundstate, cache, delta = find_groundstate(state, H2, VUMPS(; maxiter = 400, tol = 1.0e-12)); +groundstate, cache, delta = find_groundstate(state, H2, VUMPS(; maxiter = 400, tol = 1.0e-12, verbosity = 1)); diff --git a/examples/quantum1d/6.hubbard/main.jl b/examples/quantum1d/6.hubbard/main.jl index 090c84324..9a5c84aaf 100644 --- a/examples/quantum1d/6.hubbard/main.jl +++ b/examples/quantum1d/6.hubbard/main.jl @@ -46,7 +46,7 @@ const U = 3.0 md""" For this case, the ground state energy has an analytic solution, which can be used to benchmark the numerical results. -It follows from Eq. (6.82) in [](). +It follows from Eq. (6.82) in [Essler, Frahm, Göhmann, Klümper & Korepin, The One-Dimensional Hubbard Model](https://doi.org/10.1017/CBO9780511534843). ```math e(u) = - u - 4 \int_0^{\infty} \frac{d\omega}{\omega} \frac{J_0(\omega) J_1(\omega)}{1 + \exp(2u \omega)} @@ -67,7 +67,7 @@ function compute_groundstate( expansionfactor = (1 / 10), expansioniter = 20 ) - verbosity = 2 + verbosity = 0 psi, = find_groundstate(psi, H; tol = svalue * 10, verbosity) for _ in 1:expansioniter D = maximum(x -> dim(left_virtualspace(psi, x)), 1:length(psi)) diff --git a/examples/quantum1d/7.xy-finiteT/main.jl b/examples/quantum1d/7.xy-finiteT/main.jl index 03ad41999..6b66b05c5 100644 --- a/examples/quantum1d/7.xy-finiteT/main.jl +++ b/examples/quantum1d/7.xy-finiteT/main.jl @@ -56,8 +56,7 @@ The Hamiltonian can be diagonalized in terms of fermionic creation and annihilat E_0 = -\frac{1}{\pi} \text{EllipticE}\left( \sqrt{1 - \gamma^2} \right) ``` -!!! todo - Show the derivation of the ground state energy by diagonalizing the Hamiltonian in terms of fermionic operators. +The derivation, via a Jordan-Wigner transformation to free fermions followed by a Bogoliubov rotation, can be found in [Lieb, Schultz & Mattis, Ann. Phys. 16, 407 (1961)](https://doi.org/10.1016/0003-4916(61)90115-4). """ function groundstate_energy(J, N) @@ -141,8 +140,7 @@ The resulting expression is Z(\beta) = \prod_{k=1}^{N} \left( 1 + e^{-\beta \epsilon_k} \right)^{1/N} ``` -!!! todo - Show the derivation of the partition function for the XY model. +This expression follows from the same free-fermion diagonalization as the ground-state energy above: each single-particle mode $\epsilon_k$ is independently occupied or empty, giving the usual free-fermion partition function (see again [Lieb, Schultz & Mattis (1961)](https://doi.org/10.1016/0003-4916(61)90115-4)). """ function partition_function(β::Number, J::Number, N::Number) @@ -274,8 +272,6 @@ Z(\beta) = In other words, we can compute the partition function at $\beta$ by computing the overlap of two states evolved for $\beta / 2$, as long as the Hamiltonian is Hermitian. Otherwise, we could still use the same trick, but we would have to compute the evolved states twice, once for $H$ and once for $H^\dagger$. -!!! todo - Add a figure to illustrate this trick. """ double_logpartition(ρ₁, ρ₂ = ρ₁) = log(real(dot(ρ₁, ρ₂))) / length(ρ₁) From e6bedab5582cbfaddd41e339d2581d548a9ccdaa Mon Sep 17 00:00:00 2001 From: lkdvos Date: Sat, 4 Jul 2026 21:34:58 -0400 Subject: [PATCH 36/76] docs: point community links at GitHub Discussions Maintainer decision 2026-07-04: Discussions (already enabled on the repo) is the community venue; questions go there, bugs to the issue tracker. Co-Authored-By: Claude Fable 5 --- README.md | 5 +++-- docs/src/index.md | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ce717e5ae..437dfd5bd 100644 --- a/README.md +++ b/README.md @@ -42,8 +42,9 @@ out the [examples](https://QuantumKitHub.github.io/MPSKit.jl/dev/examples/) for use-cases. This package is under active development and new algorithms are added regularly. -Nevertheless, the documentation is quite terse, so feel free to open an issue if you have -any questions. +Questions and general discussion are welcome on [GitHub +Discussions](https://github.com/QuantumKitHub/MPSKit.jl/discussions); if you think you have +found a bug, please open an issue. ## Installation diff --git a/docs/src/index.md b/docs/src/index.md index c54a17cbc..ee5125b18 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -98,5 +98,5 @@ All of these are part of the [QuantumKitHub](https://github.com/QuantumKitHub) o ## Community and support -Questions and bug reports are welcome on the [issue tracker](https://github.com/QuantumKitHub/MPSKit.jl/issues). +Questions and general discussion are welcome on [GitHub Discussions](https://github.com/QuantumKitHub/MPSKit.jl/discussions); bug reports belong on the [issue tracker](https://github.com/QuantumKitHub/MPSKit.jl/issues). If you would like to contribute, see [CONTRIBUTING.md](https://github.com/QuantumKitHub/MPSKit.jl/blob/main/CONTRIBUTING.md) on GitHub. From 6f89191ffd73da9711c1c932193abba686eeb5b0 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Sat, 4 Jul 2026 23:04:19 -0400 Subject: [PATCH 37/76] docs(examples): re-render de-spammed example pages; make RNG seeds actually apply Re-renders 1.ising-cft, 3.ising-dqpt, 4.xxz-heisenberg, 6.hubbard and 7.xy-finiteT with the verbosity/citation/todo changes: raw iteration logs are gone, the xxz failure demo keeps its one-line 'VUMPS cancel' / 'CG: not converged' warnings, and the Essler et al. and Lieb-Schultz-Mattis references render. The Random.seed! lines in 4.xxz-heisenberg and 6.hubbard were '#src'-only, which Literate strips from the executed markdown - renders were never seeded, and an unlucky draw NaN'd the xxz GradientGrassmann failure demo into a LAPACK error mid-pipeline. The seeds are now regular executed code. Co-Authored-By: Claude Fable 5 --- .../quantum1d/1.ising-cft/figure-1.png | Bin 15484 -> 15044 bytes .../quantum1d/1.ising-cft/figure-3.png | Bin 22799 -> 22801 bytes .../examples/quantum1d/1.ising-cft/index.md | 76 +--- .../examples/quantum1d/1.ising-cft/main.ipynb | 2 +- .../examples/quantum1d/3.ising-dqpt/index.md | 33 +- .../quantum1d/3.ising-dqpt/main.ipynb | 8 +- .../quantum1d/4.xxz-heisenberg/figure-1.png | Bin 11462 -> 11781 bytes .../quantum1d/4.xxz-heisenberg/figure-2.png | Bin 19339 -> 21619 bytes .../quantum1d/4.xxz-heisenberg/index.md | 400 +----------------- .../quantum1d/4.xxz-heisenberg/main.ipynb | 197 +++++---- .../examples/quantum1d/6.hubbard/figure-1.png | Bin 41850 -> 41850 bytes .../examples/quantum1d/6.hubbard/figure-2.png | Bin 40056 -> 40056 bytes .../src/examples/quantum1d/6.hubbard/index.md | 124 +----- .../examples/quantum1d/6.hubbard/main.ipynb | 24 +- .../quantum1d/7.xy-finiteT/figure-1.png | Bin 37795 -> 38310 bytes .../quantum1d/7.xy-finiteT/figure-2.png | Bin 36052 -> 40337 bytes .../quantum1d/7.xy-finiteT/figure-3.png | Bin 36103 -> 40669 bytes .../quantum1d/7.xy-finiteT/figure-4.png | Bin 34906 -> 37133 bytes .../quantum1d/7.xy-finiteT/figure-5.png | Bin 38446 -> 40664 bytes .../quantum1d/7.xy-finiteT/figure-6.png | Bin 42294 -> 42270 bytes .../examples/quantum1d/7.xy-finiteT/index.md | 19 +- .../quantum1d/7.xy-finiteT/main.ipynb | 194 ++++----- examples/Cache.toml | 10 +- examples/quantum1d/4.xxz-heisenberg/main.jl | 7 +- examples/quantum1d/6.hubbard/main.jl | 7 +- 25 files changed, 304 insertions(+), 797 deletions(-) diff --git a/docs/src/examples/quantum1d/1.ising-cft/figure-1.png b/docs/src/examples/quantum1d/1.ising-cft/figure-1.png index ec004e5a0b06d3d4b2e0ba997d9410a9b1332789..dc4c4239a270672cd30f0a4367c5c19564646a9d 100644 GIT binary patch literal 15044 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 OgqVo5Z~^kQ=YIo`O)ud9 literal 15484 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 Z#}kjwqDiCzL4HCA^Gm$V<$Le;-vB(=O@ROa diff --git a/docs/src/examples/quantum1d/1.ising-cft/figure-3.png b/docs/src/examples/quantum1d/1.ising-cft/figure-3.png index 8f76b9208301d347170614d6ceda14e34139883e..8b55ec3c9cff7942fa1f7d882c8e02fbda11652a 100644 GIT binary patch literal 22801 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 delta 20497 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 I(2rjH3$D6@RR910 literal 11462 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 Q7)(Z}C~DlwLp=!m4;1MVCjbBd diff --git a/docs/src/examples/quantum1d/4.xxz-heisenberg/figure-2.png b/docs/src/examples/quantum1d/4.xxz-heisenberg/figure-2.png index bd8dee7003b6750963e3ab40a66ea3455ec5d36f..c19958f0dda7cf9ab5398ecfbf727788c5aa04e3 100644 GIT binary patch literal 21619 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%0ANqjw8!nKh8z_X+% z!L`kGGQLD_%7HvYi@@=Hglt9ws`Q=fu~yx*0W-gzD+lU?mN|807&~a!8|fVQbXE1@ z@w0ipWeak#v0wb+K=@EVz+aSkpPMXFy^)sWJp2;#;G3J*NQ3sMGB&ho+fbyz?f`sB z(;?a;hj(W9KHg^sTbKXRulr=w=#msN2FzlXvTL_>wm@d5TxgEl4;r;9V0X%oQi`6q z_D^m<&!@xA&&xxvG4=@!YrUG3#(e)mM#kROR$5LDOy$6Cf_AB9jqW21)2Kt&O`qr* z^4asm$KB22Rah>W!qyZaaD2ZI{*p+@+r@SMm{V%DN?&k(vD^0K5}KdQd_?R_!87>A zM#akyg}4SfTIk~XAv|tmBHx^}Z(@NQ0ltLJ;hGU0yizA%7;SET&csx>HC4+Ick&jq zKVnB1LuAK9?uu<8wjt0_0gq%;oSsgxk`rnyCj*0JbF+C~#eLN^lez8U_Jw+ZdgmP7 zl<8ZWM5*Es4QRS}XBviFPXwp=&AZW>xKR2BpcITV)6?hO z=D&V5vEJn35M}f{5(>LJY7ZG#|BYueA|{60;im$Tz4p{r9bNa=1Ym_%ypYCe5~+~Q z22pFVJ`IhU2Hb<3;)CVUe+sO52RU*hOLp+@CbuW*QnUFMmiPMtHhkN`WrEV?G4^i-RV=L`CkE?h`Vt^Ck1&f&d?Kb4sV%p@d@6Ar zkoj!=_k1GqA_vFS*va}t)!Qjag;3JHw_CyMuJiW@7()(ZqQ7$5*NY^em<_VRIK+N( zyC+0P&ubayY^zEZ@|`Q%2>ap0AhegfGHOe;MUN~#QM3-M4BN3a!96B}&nUc+9&w)7nnlUyfKx@tWv8*P@9oxP zHSjIaF8h4Jf$r(*hQgv(((L5;q^SCshK7KY)Y8gYcxxt=hGmg9DS%^Z(c@}Q)uQpY zR9MZ#@#u<4zRjP(X-^GMA+MbfBK;?9R7R{1pp~NY1Fro>KulsFLgGu_6~7~)^Gr?1 zXueI!HSL8-FxYTQDlR8>={|oGqRfo=@-l~4xcGsYwfXLvqwjI4oWz@BJYzDk7dEZ- zrYzh4?4`Q9yOGQB5FW$7IDSnkygH1JCjqt?lXd=0 zUZoQKK}z2Ae3UUY$uN2v%|}hGuhy6D3QpT8n%OoK-y-(1-W;Ej2`hs)5sjXOMc8e~ zyD3orcw@?+;9Y+am$@WtRe9<83$xE~eRHC!?!BxgSTc6Hu&F>4U z*xs27%gmg~8*}i8NTJa)G6si)5a8i)@bJXO#4KGW-+K2MM8MCVJv?R0d|Bz}{OyY| zR8@yf$jNW~XUfW$_wL!8Deth!BCZ31gS-9EQ{t))!Nz(O5+u-)c3U?+MYqs4?z}`r zy+_ttN%vCRc=SD#q(_hSjD(keRcKqPG3)-=t5P1lwRZR6$|2X|j;`3AxcYa!-D+dR zK7@Y?9^r$lj`3SjVIka>Wk3vYz+aE|4?cLF*AYY)ta1eO$7Mc}o4uHviRlL0%(pKC zOT^u3{qh~bI@M0|O(!*hD97j_@@SNYTIocPyk_gUUv8;@|N zfcLVCuwjt~! z#^zQ^P-FYtk#{tEFn*tKfBo)1UpHrZyvGmOGLzYy}7Q1tjkC~or3RMKE7u- zVh_p4j0Y*gopth?yD$kTHi>zMBAK#8Rzku!I`W93V^B~~u044m2 zvE|t>%Y*d~T5CU?s@XTU4{1x}ba;O^Z*9j7W>G&m7}%ec`s|R=_g<-{d}WR0O`mRq zJvC$Af`7)pMZ&-E^oXDE>R6JwHKkMmaF#k2y> zEx9CIuhpYkpkY3sVp&vsAyPddnS&8P;J9t)+PU_3>g8^EB6_-a@Q&2=VynO|mBtGV9WP5Ej_Lse=0x89$lAU*vtDDo_| zC}aCW{kFlPb4QLpsgqH1>P*Oo+Kq(y{nwc_%*~<12CT4AU@jj1Ecx zs;o%gsfTW5Pi0*6(~Dk4b-0`#73PmNuXuSc^k8)+xl#7|w%-#ksD2~{NpRH4-@#@vgsYSJ~g?QhbSj_~r zQIcoSqOQ4?$(`9t2Hx4$Fw#+frBm8aPc&iI-WL11Ottbb;9kvmMvCclBI5DxbxRhO zBLLfvNrxQV+)L}sqVCXaBhdaVM*0(d{XSH6s5m7kvZ*jpQr_T$!!1j7!mBU%APx|F&Y<08u)drcw>{UOG0mnxA;l?<)1&jJ~&ERS~atMNyooa0s{iDNLSdMm&)IIJw`&q z1{%fZ$ml3IrN(3?vcBy7&pw*N3hLeWd-as=Rn`tpPHNq5Vt z%^dkcPL6C=P%x-SC(q)sVmxy!h4Wb>^Ez02`D%sjr(cx!@D?`)KNHgBwmq(t^PNC9 z6Tf-dwC2`US~@!CwV@8^LYiKKr^R_|HL8KNU?BBOD@pKDNgsq+DKl*#BoKV~un*6E zKP<8Vb_vy-(0Q|QNUW2Pn!Ibt0Ki{*vDLcyHZElZ`cH^7**4YMXkN!u8;Jt{F_5u1# zk+x<2w<8ytgOQPuEzQla$2r$f=_SUh@h^^uLW79-_`pZ_Pr>etgCR>BxtyH=0!Suj z)qw68T3W0L70O4fn?U>$&t?!cd6^XQa(j+oJl>4Hqh){l?rdNvm(1gvqR)GNpmWej$wK}Sl+dIxBm)@1{&s-n`q2R+&w8?f1Wc(F?zdE!C&eYgh^Dus+>g4Jhx_+1A{+Y$nJFNFKYA(#*$p92Ee*YaKS9l7os zru&-R(INv6cPg$a9o^}Ve7~M0=BKU66l+_Zt|!0^K$5MmLM^-nrtyC8;BNg84aK;c z&SXu(5$oJrU}h{I#fN?BbbcHB4$lYwmimv%Dp#?65<^LC9g7Ep!V`Ax8(W$rN^ZA8Gfk`W$(3H#dnQPM_O3z1e z@b}1p54kx))jA5yD%Sf^2z&OBmYeGUo zT3XtRE$n(Chzo=qw1ru;43c({KZ3e*_dlG~;)vZlOJUtwWIvnv*AYATFo$tn*ueq% z$m1JEuG0P~#*Z7yR74rV^zK8!yw{B^Sh~8>x)sld%nM^psl;vS0)t5ToaF|}F%xg+ zz)6{T)wlHcz(-$lP&L!1TP>>IZxp*!!*?)N=Lnl+eP25x|M+k2RiM-K#&sL@$2E8J z@EaybAz0e@yW^;OIMl4ee9d( z_Z}+g>$5c0A;@pSZHEFj6rOEPb}Gxt%h4R^x&~TtWx(D*x}nZtKG|h_(gG=C6TwGw1`)gHs9iY6G@zWjaLFwz$HQ1dix)F)fWJrwgiGj@&aI`2-mY7d9PB@QT zR!}oA$f(K6t1mCG3CK_W7&2iCj|y|cbLwo`+zauV|+I$_C9k zNv|j@3@pmeM7aW7Axwukfd1kwA($B4b3oAP- zWo@ zLxjY-I7#v~bI9d-91?;L6J&x*2zs6=scU&jF^@k{`eOS zeCq=|Tc~(qBbU4C*vE>>MfJK5XxNR0g-A`0L58m1kaG70h$TV_+i=|sW-96Jy$imK z7)iH>2QN=k`P=B#26Px5tum5&Y>r|a6Fh(J%Q+;Cy3LxkJT^Z5r#Z`2|0Dg)S6W=Q z_H3$CM0aCSI-pW!e&1e*h^>;8kN4Vcl|b6iApP_R8DXaVkZdC|#UB*z*r+In&2d#( z+2C*be70uG$)4WZtNN-lk9v({iTUjo=k}pa;u}Ytk$@lk(r8E62#fZvDHsZmr?$Y`%Bald zv%+4+mfp-trDR3-ch}rNxjQNS<-YNOpjIVq$D+q1hPZqBIe(czPIvS3BHa>?{B$}PI*|-S&J%A?WF`9?w3srw3`}A`b8{NqfD<$Nj5nr%JscM;_*Cj1#`4wn(9q(;Od6H1S)}*PYW&sG z(<8^m z)cf~M``=SRA&2jta9W*%FHDil83gB?rbOIN@gR0UM92eF*E=j|o}QktSqB3X^R!X| zK6sxb1QsY9Uj22~j z^nI>8?cnG%19P4HT9l6o3pY2_S59?(_%91P36bB zW*A~wO7!>`6}skT#nd#L75JjD$NJFB&rEh%*lrWkRGT{;zAKb1=v*nt zK%lAFZhbH!I1)%Bh;$qE6bB8d?wVzDR!)*AETFK9DhU?_&4v}$ znLc^i-~~rvqXQDRu=d*)I{kx)YINX27X(s;2WyaOP$oQVtcV{bVEmMxY+ULA;~~5~ z-0HexeyKz~8t^FU|3xpJ9Oh_gXyB+685PyHFzw${?y?@500{i?*X%F?E&amV)#DUs z4iuG@{f!m%5;RkFfM&MkY(z~}J-&ceg>qFe+$Hw>pu#vP(>z#~?EK|X35u+qMd1U_ zlBD&{%jsYD{2UI8B{&zoZE5i@mLQ0C??I!*Q~O`V{K2xv$e_dzLj`gIw87xGug$HA zULTiO;%Aca)DvQ-?WF=LR9oApc;34;Gh#G9PsL1RDfFoE4!0dw3Fqv{8wfO0l4uP2 zI5E)&BJq>k>i93b9~hv734N(^bi=D_#xLMg%Z>PT_I0(jD8Onb7ArxdAg6B!(jw1@ zuU1;nJ3Te!EKyTa6JgccEQ8B$V2+67z_z72bZkBEgEZ9v0NVELNz*ZFr_#BF&+$e@ zt5*ke5ee9OYNl>3?E22*p$rCwb|n>K2KlAzTH2i#J{Y6EsEKtwazB{(X!KQO&)W^( zAP56CX82mmP)Z8xPy-Z_G11ZF?8ax$-t_eF`TT<(t5gsUF)IB6OypFzNWdKtf?y8O zZNi6Jm7|!LosvYOeB8c5n%DpW%c6!^I~}}tCdt$!@|(nK#{6;=FKrdA-caI z0mJJ%Q4J2Q%DnNy7q&jjNn0k31BeA`vYyhTdqAhaJtyX;B?RF;tYq_icv7HdIq{rs z2z{6?h*(3z5Q{A3|2@yN*GXKqV#R)KnVr`B($Md~-< z@dj6$Q6B>q$aw6|&B5G*jY#QrSp=x8C5LfI@-jqrP4#$QU%wETZ*p?-&P*J|xwR3& zp`m5`WkLioJk(}`#tqHc*{6wWYFYv40;k9VH&$=tK?5TrY5jb#97lscs%gY=>LC|X zjh(eoleGH!L>eX(3W|#A@#KTmXo#|Vy%rOvN`j^YFQf(pOu*G-7NMyGymQ+&r+XbU z4-hJu8H`>^BqTegebIXgyKtDrnxvk^O_x3BTV_EfH}`g6$&dG+HLAxN-HYYmT=c%% zI~xcTmlbDCx>Z?e23qEqU!Kk#QNU=#J>PvKzT!CdKxH6_^u*7kv9XbfE~J(g>&G{C zU0of5CZKM5pN-8T5~yKOp~X>hpj=84Ha3ewEvqecjyy3>$!Gx=3z!fY7jId1#uJl< zqe5B)$q`HaNLp^QsHKGkOblS#aEAKt=LA>1h3W`hb-?G_?(g%a)175Oyb(t(;mTqp zxa#2Nn43eed{wgE-9VItOSb!#VVl4$_WDV1S-;2J-ldY%v-|Gx2bpe&SO*x$W05(N%fpfo)t2VAk|?qkfnWXfrVI_c_)C;yop+q>0uveyu}HiL zi;3}rY6Q`IK;pzvV+!TUV|Q>wlGNgolD?R~xp*KEBQN-V z$Xy7+_Lnb3Nw~0#-Ns_}l z#&em&ZYSi7ii$8;@nlUS5YFcgyu4$d3uCRS!67DOsf{X87a9lhJ4ORo{BoeK9En_GA2BnP#sc-z|9i|} z{U%0yywx?fT{9Imw3eYjvrau>Mn4kja^Zm{t!#M9-Ky9?BnTu;1((y)%@!u$3~`Lx zkDqg1R__4Br$!vBhT+MbSr%S}j*FCpuCEqK-+MDRx7+U|6uq`vot$35j)RFh~o{Jye*d{TEb&!XmJTgY(0} z`}6uL;U+kQ<~#LPhq5`GWXYTDBbBtzU`+*_uySRQ7ds87XSOg)#_nj@o8Nzz z8EeJwLU2HL^!f8_A3>9uA6e4&D|>ML-*1EAGy%62d3kwQar{Be(bm%&oaC(-k3+J6 zMP5^^zh}!tEH%dfqho9w;^X6xvkT#z3j>(7Olc}oTax_%EL`q?*LVK&5#10AamP04 zMKtkF(M2DFk-pH!1O; zZ7O2qHWR~`2N6q4hIh>tLP-GylBuiM&;2I83XU}>8h!}k$>_|s@3fwtnb~pD#LzG( zadW?rFrz4RtW!|as|>{LW|qf0VU`K8h3ntA<$Oc*eESx8%Ua0Y1U1mM(KB*~X2(l7 zxWl?de|@S`jpk@Hf4VC*OK;7Z9+(O=EN`S6ijkz{Vox&|t_KbjSQ?v}BK^O9DgKCp z>Z4CbcQ?F5l9RoQocDz6(Y>-zVRNCZ>9}9j!qYC8iJ`jVS@b%nGL|1%MeF5qm8GPp zqDKP)0{s1B29iuwrVEMm?SI;fZpa2ZU~g*+&xG*ENZ+zI3M{n_8JeG;H*ys_CCyW1yt;Ak U#)jALuttf^b~|hzP~A`e0}0flVgLXD literal 19339 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�}cQ4>?i4EU>ho9yQS)|3! z1RpZVP#*+wv;(h4ZC_kJBa@-Sz35n*7$0|bcFqD_l(VCibBea|D#Dc$XcxNwSY`8-V z+tjaSUkXF|z*-_G5Epr){qp4WN7kjUD5E32Pu#if<|0S@L`~aU3&fw90Xl?pu)kYV zpYgR%A*|TqlYSJB6Q3SAyY7`Nr7HQb#>*?RD)qMi`J+)`vsAxCExL=k9VdaL@P0%| zaJMciZ?N1<6V(cuiK@jIPQun`pc%wv!fLixtH+BPst4Vh7Uy`Lzn=+7Kk z+Pft{WWTEMOXB+FIN!S=58bji-GDdCpFGYqczrwkfIQoH%0x=*49!eZTmP!Ir8LlEqbw8Oe zrE(i%&_s<74eiTTD)^$1;pa+;Lf*%~+t^%b46HoZ{Ftrzxf&xw3@wope5>4UXJFL> zz~6+iK700u^^y6pkz3^H*%brqF;2@@B0cYCrltn}x>vDn5(~Kh1=rJ(llw|n2oi$t zUoffm=v59piT8e^rS;v5-tjV_aj>^#x031QhSt%T9~8kSyDMiW9JZ2YQY80fpg z7}z8&p?zIaT1@H~1^qMS-Eq zfR-QJmiwjX?Ni*{%p1k-4>fSk#i-+qXdQFEKQW~cjYGvnHUxYe`ESV={l zkjA^CyF`vojvHguK~4G-ZV#I+7O7vnG9F%#*kjKI8T#7QM6iIaQcobOTWNjVGh+5A z`VnNisEPX5=H{}<`#sBe!#4Df$^` zG5Wpd(cW)g>XHoEhdh#d@5RKLPu4GagItpea@ZSd)TSnNR2qm{v2tNL_A#Q`1A~J> zNQc%G95_*~B_n1tZv4VjQRU1?+t}8J!PBFfx4d|)WX;{>j|SXc@VwEm1R5(~re~2A z0yWEdr(^GS)Unyk`y^KSy$p6+@jhB9a~WOoV+;ciuA+Sj46suBG1!5u<~gj^gaGRt zy$x{4Y8U7hXJUQD`m^<$}N8P87m zSF7i~DcT**^mDEMl@W>(B$19pgZINxw7vNZMNtiXk@oZhXx5E8&Db8`>Y`F`P`>FO zBg@)P;^KVvHqA^-B!vnD(TVS06XeUt$yw_g7o#vHxZjQ0A=6t`XW90TKC0k!v6N6J z-sACIRoC6073Nb(sVa##Ko&{7;IVl$PpkyiD!MO29 zRngPo&*+H5Nci6EaH#ME&oeSJ?Tv>c!GT^``5bCUaPss9;so6*XSfu@<=CWu@rrU^ zA^?rAVMkUT>nbm_-ht8%PBmQd1Pii%{TUTHjm$eV(!8JX?S`K)H~#wNnN0fW+VjUZ z5XWgCi&&qZ_1x~CJc`)aC+hE?jfq+P4(#OTYxxPn)_dRwn2+)HZu-SD3_B7I2oFPH z3br9A9o1pKA+Vvv1`p_WnE>-c)US>=Nf{N4|7mOAoc^o7QQ8KkWAKAV)J_@ zNZ4}-=Y*`ems#2xf=9JGE!5~5OX+#qyitAW(=9W;$pHqx5r{iWx&u9iOx=m{Ljmi{Njj*|i>ZRV~snh3z=Lu5XMgDb^mV;`p@ z+pUr##Nu7_=H^`&8}2}9I(3Ch?lC`?cAf4LZ+8!Q>1k5`nw?lDkmhMVf2FAj zJu{Bj^0=eTK3WzvDed(F(UQ}{bzz%!LFCmkn@HN*+t<4)DPTk@$#;H?tGWF9jz3{) zGG(dx;f{InWy=e_B2T%%F-P;s;)w8lj0abv=b(J?qDrLZld^(w58cItkJS<@m2o-U z%Cp!fBT%fRCvcr@ZMRo|Lz2!Iw;mt|k@*NRy5uogYL2=eX2+L;Nlcc~wSCbzF~;(B z@Ilg)988=3_suEVHMR_G_o?POmlV~rWP2hdQa*2^UqeM*{6JCYZ5=zK#C3Eg!>a;_ z$}G!GHs<*(8&3~64MsSxc9_Y{u(n#;lftIx`wU#Fp_z=ii4!M0-< zD;W5kwc%)Sv;#dpGw4Qk*FBoMzFoHc2+GLqJS!Y8OY8iqtqE;bgGxr5yZ`^n4Ne<^ zCH4PvzmCu$+|M%Y$@I+4^JPwDA1RsREL`f|pT}R@SbgAdijt7D`(B}BgO+%<@(E)XI4;6boTT-;o`D8jtTsPg?i^@ZM$A*vds&LHF{G%&+{q? zt;Xx{Rk!f(O)cg=$=^GO(A-($WPf&b#h3-jrJ-Ul-t3EX#r&t`{eB{>qGzT+{WSg7btTIfYso#l#Vo!f?d zmQ8+KuwJMvQzBs%HO}oODMm7^dX>8~1)A?|5aPvYN^LUh2>?;(k_}zE;4DBwMUrEDK};*Aly$p#ZuyUY~fx4TYryp$aIY^hN?$8WYCfq44;ML zv173N#{4$(J|-(0RK87d8ceKPyK66-Ad_0aN561JQoQ-ybeQ&VqqXfM4QQPENxBm4 zp={iEnm>^$3+Wm=|KXvqh)ggx3Zt(~HgK%ewhhknL>7#FXXp7=7>=Y65h| zkp<4jiW+Bpo`rl?8J9w4Z`gJR$(a}#;bsjZaO($y5lm=MP6lD-sO=ZCPtF)_$*Fnf zb&*=!^Pa4KEI?+~3WdMont1>}p95Igz-AJez0>KqMtCBdo3XI(QlObJF{xg=txxs%mG}*GbRisO z+_G{%m8&9=0(RG|L$ z_SSB<>-%v405DZULxUtqg=@au-`{^`YiN6W`{U!I)%w%F68u6cm69Z>s;cV49RUD% zqrSer>FMdhHQyc{9*P-DJv}{RV`JUj-9_sN06+m{3}*m;V(0|Nt!qL|$a z0D$*0JqR5RM^O^zx@Gd3>q19?#UtfQHxw5h{H8s`S+k1U|ZC+mh0N&2rbA*kJjj>p)qod>X z&B4LJmzNiPSOfszYZ*Tg9v&WEU0vy)!{PAg=x8pNdtI=)y1Ku=uW6d$tpNadFXMwy zQ52WUrDtI<7_?X{!^6X`=T4i=77B&7wzdp!4FJG<86Sj^NW|y!b#`{Dsw#@&_V)JC z(UH&R%VaY7nm{0spBe!G_(Ep=MmRGw6OYFgMX9T+yScdu27_m3XY=#({r&yr<>i7P zJU>5+qG(2I007?3tX-qgXfzNAxLht(RV7K<+uMu9V!OM$vMlfH>_7&1TEW%JiWS0Dv!N*hHAgWV*V#&d<-QtE)X8PdpwM z1R)xY`g}f*$CFN{^)idaLJ9%^ejnoO?CgiXoXh3%PdLNjaBFMp;^N}n-CZ)7+}zx( zsi|=~ogR;;si{epWn 1)\n", "V1 = Rep[SU₂](1 // 2 => 10, 3 // 2 => 5, 5 // 2 => 2)\n", "V2 = Rep[SU₂](0 => 15, 1 => 10, 2 => 5)\n", "state = InfiniteMPS([P, P], [V1, V2]);" - ], - "metadata": {}, - "execution_count": null + ] }, { "cell_type": "markdown", + "metadata": {}, "source": [ "Even though the bond dimension is higher than in the example without symmetry, convergence is reached much faster:" - ], - "metadata": {} + ] }, { - "outputs": [], "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "println(dim(V1))\n", "println(dim(V2))\n", - "groundstate, cache, delta = find_groundstate(state, H2, VUMPS(; maxiter = 400, tol = 1.0e-12));" - ], - "metadata": {}, - "execution_count": null + "groundstate, cache, delta = find_groundstate(state, H2, VUMPS(; maxiter = 400, tol = 1.0e-12, verbosity = 1));" + ] }, { "cell_type": "markdown", + "metadata": {}, "source": [ "---\n", "\n", "*This notebook was generated using [Literate.jl](https://github.com/fredrikekre/Literate.jl).*" - ], - "metadata": {} + ] } ], - "nbformat_minor": 3, "metadata": { + "kernelspec": { + "display_name": "Julia 1.12.6", + "language": "julia", + "name": "julia-1.12" + }, "language_info": { "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", - "version": "1.12.4" - }, - "kernelspec": { - "name": "julia-1.12", - "display_name": "Julia 1.12.4", - "language": "julia" + "version": "1.12.6" } }, - "nbformat": 4 + "nbformat": 4, + "nbformat_minor": 3 } \ No newline at end of file diff --git a/docs/src/examples/quantum1d/6.hubbard/figure-1.png b/docs/src/examples/quantum1d/6.hubbard/figure-1.png index 87a4f10f89ffef8d0c689873e70c1b07dcb1d57b..73f21dcec67104f4325a647b53f56b5e2eb3b5c7 100644 GIT binary patch delta 63 zcmex$jOo`grVaj6SklhkZ=D=GMU{DF$g0WJQ(71=ZwBS3j3^P6 dim(left_virtualspace(psi, x)), 1:length(psi)) @@ -115,54 +121,10 @@ Groundstate energy: ```` ```` -[ Info: VUMPS init: obj = -1.450454615857e+00 err = 5.5193e-01 -[ Info: VUMPS conv 7: obj = -4.377048688339e+00 err = 8.8092806195e-03 time = 4.49 sec -[ Info: VUMPS init: obj = -4.377048688339e+00 err = 1.6440e-02 -[ Info: VUMPS conv 6: obj = -4.378747269347e+00 err = 1.3129004135e-04 time = 0.25 sec -[ Info: VUMPS init: obj = -4.378747269347e+00 err = 7.9951e-03 -[ Info: VUMPS conv 6: obj = -4.379161081627e+00 err = 1.5539751336e-04 time = 0.37 sec -[ Info: VUMPS init: obj = -4.379161081627e+00 err = 6.1111e-03 -[ Info: VUMPS conv 5: obj = -4.379452169384e+00 err = 1.6927654674e-04 time = 0.27 sec -[ Info: VUMPS init: obj = -4.379452169384e+00 err = 5.6959e-03 -[ Info: VUMPS conv 4: obj = -4.379651733231e+00 err = 1.8162083040e-04 time = 0.26 sec -[ Info: VUMPS init: obj = -4.379651733231e+00 err = 4.1039e-03 -[ Info: VUMPS conv 4: obj = -4.379735601762e+00 err = 1.3801495045e-04 time = 0.42 sec -[ Info: VUMPS init: obj = -4.379735601762e+00 err = 3.5769e-03 -[ Info: VUMPS conv 3: obj = -4.379797886653e+00 err = 1.3472741143e-04 time = 0.39 sec -[ Info: VUMPS init: obj = -4.379797886653e+00 err = 2.7707e-03 -[ Info: VUMPS conv 2: obj = -4.379838526805e+00 err = 1.7752552389e-04 time = 0.33 sec -[ Info: VUMPS init: obj = -4.379838526805e+00 err = 2.7291e-03 -[ Info: VUMPS conv 3: obj = -4.379878849406e+00 err = 1.9781894590e-04 time = 0.74 sec -[ Info: VUMPS init: obj = -4.379878849406e+00 err = 2.6911e-03 -[ Info: VUMPS conv 3: obj = -4.379929229387e+00 err = 1.7761427615e-04 time = 0.82 sec -[ Info: VUMPS init: obj = -4.379929229387e+00 err = 2.5553e-03 -[ Info: VUMPS conv 3: obj = -4.379968040382e+00 err = 1.8461546636e-04 time = 2.21 sec -[ Info: VUMPS init: obj = -4.379968040382e+00 err = 1.7682e-03 -[ Info: VUMPS conv 2: obj = -4.379986877757e+00 err = 1.9131369028e-04 time = 0.98 sec -[ Info: VUMPS init: obj = -4.379986877757e+00 err = 1.5838e-03 -[ Info: VUMPS conv 2: obj = -4.380001005486e+00 err = 1.9231335759e-04 time = 1.05 sec -[ Info: VUMPS init: obj = -4.380001005486e+00 err = 1.5109e-03 -[ Info: VUMPS conv 2: obj = -4.380013169634e+00 err = 1.5225084116e-04 time = 1.32 sec -[ Info: VUMPS init: obj = -4.380013169634e+00 err = 1.4234e-03 -[ Info: VUMPS conv 2: obj = -4.380024401012e+00 err = 1.7737882775e-04 time = 1.59 sec -[ Info: VUMPS init: obj = -4.380024401012e+00 err = 1.3330e-03 -[ Info: VUMPS conv 2: obj = -4.380038158990e+00 err = 1.5757417636e-04 time = 2.60 sec -[ Info: VUMPS init: obj = -4.380038158990e+00 err = 1.0032e-03 -[ Info: VUMPS conv 1: obj = -4.380043682260e+00 err = 1.6736593859e-04 time = 0.89 sec -[ Info: VUMPS init: obj = -4.380043682260e+00 err = 9.0999e-04 -[ Info: VUMPS conv 1: obj = -4.380048641018e+00 err = 1.8573996574e-04 time = 1.19 sec -[ Info: VUMPS init: obj = -4.380048641018e+00 err = 8.3081e-04 -[ Info: VUMPS conv 1: obj = -4.380053199895e+00 err = 1.8060836975e-04 time = 2.30 sec -[ Info: VUMPS init: obj = -4.380053199895e+00 err = 6.8144e-04 -[ Info: VUMPS conv 1: obj = -4.380057143242e+00 err = 1.8854132138e-04 time = 1.71 sec -[ Info: VUMPS init: obj = -4.380057143242e+00 err = 6.0293e-04 -[ Info: VUMPS conv 1: obj = -4.380060551312e+00 err = 1.8083344266e-04 time = 2.45 sec -[ Info: VUMPS init: obj = -4.379609468445e+00 err = 4.0958e-03 -[ Info: VUMPS conv 19: obj = -4.379763157256e+00 err = 9.9415625365e-06 time = 8.41 sec -[ Info: CG: initializing with f = -4.379763156901e+00, ‖∇f‖ = 3.1520e-05 -[ Info: CG: converged after 158 iterations and time 1.36 m: f = -4.379763361376e+00, ‖∇f‖ = 9.9957e-07 +[ Info: CG: initializing with f = -4.379763091095e+00, ‖∇f‖ = 3.1534e-05 +[ Info: CG: converged after 167 iterations and time 1.66 m: f = -4.379763081900e+00, ‖∇f‖ = 9.7406e-07 ┌ Info: Groundstate energy: -│ * numerical: -2.1899960609769664 +│ * numerical: -2.189996060974577 └ * analytic: -2.190038374277775 ```` @@ -196,56 +158,10 @@ Groundstate energy: ```` ```` -[ Info: VUMPS init: obj = +2.092499297284e-01 err = 8.6283e-01 -[ Info: VUMPS conv 1: obj = -4.000000000000e+00 err = 1.4030299342e-15 time = 2.40 sec -[ Info: VUMPS init: obj = -4.000000000000e+00 err = 3.3634e-01 -[ Info: VUMPS conv 4: obj = -4.289650419749e+00 err = 1.8514003381e-04 time = 0.09 sec -[ Info: VUMPS init: obj = -4.289650419749e+00 err = 1.1203e-01 -[ Info: VUMPS conv 6: obj = -4.359865567620e+00 err = 1.0046942911e-04 time = 0.29 sec -[ Info: VUMPS init: obj = -4.359865567619e+00 err = 4.3643e-02 -[ Info: VUMPS conv 6: obj = -4.372880928482e+00 err = 1.3025843115e-04 time = 2.61 sec -[ Info: VUMPS init: obj = -4.372880928482e+00 err = 3.2693e-02 -[ Info: VUMPS conv 4: obj = -4.375236954488e+00 err = 1.1814239608e-04 time = 0.20 sec -[ Info: VUMPS init: obj = -4.375236954488e+00 err = 2.9487e-02 -[ Info: VUMPS conv 7: obj = -4.378159084364e+00 err = 1.1896740056e-04 time = 0.60 sec -[ Info: VUMPS init: obj = -4.378159084364e+00 err = 1.9312e-02 -[ Info: VUMPS conv 5: obj = -4.379272966040e+00 err = 1.5785413165e-04 time = 0.50 sec -[ Info: VUMPS init: obj = -4.379272966040e+00 err = 9.9128e-03 -[ Info: VUMPS conv 4: obj = -4.379592229143e+00 err = 1.5550378745e-04 time = 0.51 sec -[ Info: VUMPS init: obj = -4.379592229143e+00 err = 6.4841e-03 -[ Info: VUMPS conv 4: obj = -4.379819377264e+00 err = 1.7492038571e-04 time = 0.56 sec -[ Info: VUMPS init: obj = -4.379819377264e+00 err = 3.8754e-03 -┌ Warning: VUMPS cancel 10: obj = -4.379964033305e+00 err = 2.1228930049e-04 time = 1.76 sec -└ @ MPSKit ~/Projects/MPSKit.jl/docs/src/algorithms/groundstate/vumps.jl:83 -[ Info: VUMPS init: obj = -4.379964033305e+00 err = 2.8978e-03 -[ Info: VUMPS conv 3: obj = -4.380010384710e+00 err = 1.4775284542e-04 time = 0.88 sec -[ Info: VUMPS init: obj = -4.380010384710e+00 err = 2.0609e-03 -[ Info: VUMPS conv 3: obj = -4.380041751503e+00 err = 1.6327798118e-04 time = 1.81 sec -[ Info: VUMPS init: obj = -4.380041751502e+00 err = 1.2364e-03 -[ Info: VUMPS conv 2: obj = -4.380055778759e+00 err = 1.8366845284e-04 time = 0.83 sec -[ Info: VUMPS init: obj = -4.380055778759e+00 err = 8.5857e-04 -[ Info: VUMPS conv 2: obj = -4.380064749427e+00 err = 1.3905442267e-04 time = 1.14 sec -[ Info: VUMPS init: obj = -4.380064749427e+00 err = 5.2502e-04 -[ Info: VUMPS conv 1: obj = -4.380067974777e+00 err = 1.5646700070e-04 time = 0.79 sec -[ Info: VUMPS init: obj = -4.380067974777e+00 err = 3.3275e-04 -[ Info: VUMPS conv 1: obj = -4.380070351418e+00 err = 1.3123916502e-04 time = 1.05 sec -[ Info: VUMPS init: obj = -4.380070351418e+00 err = 2.0348e-04 -[ Info: VUMPS conv 1: obj = -4.380072125256e+00 err = 1.1119707628e-04 time = 2.15 sec -[ Info: VUMPS init: obj = -4.380072125256e+00 err = 1.3635e-04 -[ Info: VUMPS conv 1: obj = -4.380073467831e+00 err = 8.5045032311e-05 time = 2.22 sec -[ Info: VUMPS init: obj = -4.380073467830e+00 err = 9.7226e-05 -[ Info: VUMPS conv 1: obj = -4.380074455763e+00 err = 6.4430026631e-05 time = 3.60 sec -[ Info: VUMPS init: obj = -4.380074455763e+00 err = 7.3787e-05 -[ Info: VUMPS conv 1: obj = -4.380075159887e+00 err = 6.2144398833e-05 time = 8.05 sec -[ Info: VUMPS init: obj = -4.380075159887e+00 err = 5.9899e-05 -[ Info: VUMPS conv 1: obj = -4.380075661721e+00 err = 4.2515939994e-05 time = 12.11 sec -[ Info: VUMPS init: obj = -4.379308795201e+00 err = 7.9930e-03 -┌ Warning: VUMPS cancel 100: obj = -4.379692711472e+00 err = 1.5979764572e-05 time = 27.91 sec -└ @ MPSKit ~/Projects/MPSKit.jl/docs/src/algorithms/groundstate/vumps.jl:83 [ Info: CG: initializing with f = -4.379692711472e+00, ‖∇f‖ = 5.7923e-05 -[ Info: CG: converged after 13 iterations and time 7.22 s: f = -4.379692712393e+00, ‖∇f‖ = 6.2087e-07 +[ Info: CG: converged after 13 iterations and time 14.39 s: f = -4.379692712393e+00, ‖∇f‖ = 6.2087e-07 ┌ Info: Groundstate energy: -│ * numerical: -2.1900153475144695 +│ * numerical: -2.190015347514472 └ * analytic: -2.190038374277775 ```` @@ -288,37 +204,37 @@ E_holon, ϕ_holon = excitations( [ Info: Found excitations for momentum = -2.552544031041707 [ Info: Found excitations for momentum = -2.356194490192345 [ Info: Found excitations for momentum = -2.1598449493429825 -[ Info: Found excitations for momentum = -1.7671458676442586 [ Info: Found excitations for momentum = -1.9634954084936207 +[ Info: Found excitations for momentum = -1.7671458676442586 [ Info: Found excitations for momentum = -1.5707963267948966 [ Info: Found excitations for momentum = -1.3744467859455345 -[ Info: Found excitations for momentum = -0.9817477042468103 [ Info: Found excitations for momentum = -1.1780972450961724 +[ Info: Found excitations for momentum = -0.9817477042468103 [ Info: Found excitations for momentum = -0.7853981633974483 [ Info: Found excitations for momentum = -0.5890486225480862 -[ Info: Found excitations for momentum = -0.19634954084936207 [ Info: Found excitations for momentum = -0.39269908169872414 +[ Info: Found excitations for momentum = -0.19634954084936207 [ Info: Found excitations for momentum = 0.0 [ Info: Found excitations for momentum = 0.19634954084936207 [ Info: Found excitations for momentum = 0.39269908169872414 [ Info: Found excitations for momentum = 0.5890486225480862 [ Info: Found excitations for momentum = 0.7853981633974483 [ Info: Found excitations for momentum = 0.9817477042468103 -[ Info: Found excitations for momentum = 1.3744467859455345 [ Info: Found excitations for momentum = 1.1780972450961724 +[ Info: Found excitations for momentum = 1.3744467859455345 [ Info: Found excitations for momentum = 1.5707963267948966 [ Info: Found excitations for momentum = 1.7671458676442586 -[ Info: Found excitations for momentum = 2.356194490192345 [ Info: Found excitations for momentum = 1.9634954084936207 [ Info: Found excitations for momentum = 2.1598449493429825 +[ Info: Found excitations for momentum = 2.356194490192345 [ Info: Found excitations for momentum = 2.552544031041707 [ Info: Found excitations for momentum = 2.748893571891069 [ Info: Found excitations for momentum = 2.945243112740431 [ Info: Found excitations for momentum = 3.141592653589793 [ Info: Found excitations for momentum = -3.141592653589793 +[ Info: Found excitations for momentum = -2.945243112740431 [ Info: Found excitations for momentum = -2.748893571891069 [ Info: Found excitations for momentum = -2.552544031041707 -[ Info: Found excitations for momentum = -2.945243112740431 [ Info: Found excitations for momentum = -2.356194490192345 [ Info: Found excitations for momentum = -2.1598449493429825 [ Info: Found excitations for momentum = -1.9634954084936207 @@ -346,8 +262,8 @@ E_holon, ϕ_holon = excitations( [ Info: Found excitations for momentum = 2.356194490192345 [ Info: Found excitations for momentum = 2.552544031041707 [ Info: Found excitations for momentum = 2.748893571891069 -[ Info: Found excitations for momentum = 3.141592653589793 [ Info: Found excitations for momentum = 2.945243112740431 +[ Info: Found excitations for momentum = 3.141592653589793 ```` diff --git a/docs/src/examples/quantum1d/6.hubbard/main.ipynb b/docs/src/examples/quantum1d/6.hubbard/main.ipynb index 4371e2364..eed773528 100644 --- a/docs/src/examples/quantum1d/6.hubbard/main.ipynb +++ b/docs/src/examples/quantum1d/6.hubbard/main.ipynb @@ -52,8 +52,24 @@ "using QuadGK: quadgk\n", "using Plots\n", "using Interpolations\n", - "using Optim\n", - "\n", + "using Optim" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For reproducibility of this page, we fix the seed of the random number generator:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "using Random\n", + "Random.seed!(123);\n", "\n", "const t = 1.0\n", "const mu = 0.0\n", @@ -65,7 +81,7 @@ "metadata": {}, "source": [ "For this case, the ground state energy has an analytic solution, which can be used to benchmark the numerical results.\n", - "It follows from Eq. (6.82) in []().\n", + "It follows from Eq. (6.82) in [Essler, Frahm, Göhmann, Klümper & Korepin, The One-Dimensional Hubbard Model](https://doi.org/10.1017/CBO9780511534843).\n", "\n", "$$\n", "e(u) = - u - 4 \\int_0^{\\infty} \\frac{d\\omega}{\\omega} \\frac{J_0(\\omega) J_1(\\omega)}{1 + \\exp(2u \\omega)}\n", @@ -92,7 +108,7 @@ " expansionfactor = (1 / 10),\n", " expansioniter = 20\n", " )\n", - " verbosity = 2\n", + " verbosity = 0\n", " psi, = find_groundstate(psi, H; tol = svalue * 10, verbosity)\n", " for _ in 1:expansioniter\n", " D = maximum(x -> dim(left_virtualspace(psi, x)), 1:length(psi))\n", diff --git a/docs/src/examples/quantum1d/7.xy-finiteT/figure-1.png b/docs/src/examples/quantum1d/7.xy-finiteT/figure-1.png index da451a216034047e9d29582904616a531e934c13..be692709ada39eafc159edc9a94082a7d0765ad3 100644 GIT binary patch literal 38310 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 HT*Utaz^K(2 literal 37795 zcmXtA1z1&S*S&;0U5`-}+@m;ix1uLMFE4OZ1U=6^f9A{2T`%vnUx~I)f4`KRUH^Bu z#@sC6{D=0(+PfhMvlKKuR1v&!-E7u$Bn&@l3=1iCJS|yW-G%L$YUjO$f4y-E83M_I z?x!QUlBo|~<=?)2+i7R^1M5LsoN=iz9_7-{Pbai!Gysxi*|2A7q`1tW-VPPSILPka}tM_&KGiR3A%%{={3VT1k97$4n!be><$BT;3Y|(B9K4fCrygWNnTYPG_^z~r1 zJ5@+VaVs$`t^ZTo)En>l(J%h9$W3{i!>U0z2 zMy3mSUxnRecKfqy-SC=`2*&wYCXua+b!23uFY)p9ZsXol=UuCm(S-%C{iQY}B&5iG zspjq3+LERwkG=%fOwUuzcNtTv=H?qPmSAksCno(Q)%9pNWJZRDV-LUhY4L~U9J>i7 z_U()nM9*kvWMr_$(iKLUSNra7PLyEyv6sUHUQcS%!wr?)+}-Eq<}7Px3luWLIt_$`gb-h=O^58?y+cAge$&F0zdfAo z|B^PgZ*5~^Ltb8Jq5^xwZOfuaxM zrQJ_9C$e9lBZNgnkW^$!6&WMmgyiPZ94S&!QAMwQ)|59(X@Py6D;bU9w|{s@#$%QA zlJ<#Q%!dyu%E~Kyd$yLA7fWp@`7QOfi!Fj~$AxQHzOy9N+T6^{ecj!rusHpVWRbtl zPqtwBB=KnZ_*{mwMEG{3(1r z?7sXjbW%?qJn-#ay>;uBn!37fiw8e1Z~d!sU44ChS-;Pp`SJ(yOouW&&yP786IWMP zABAl$G&fep=%sv5S+KbGyG}e$nIkhihjDC&oW}}*h#=(*%HQBL9SrF-sNT~*{P~?J zzSrSik!tVi!R}(~-tO+;N6b5SU_l%v_V&N}qHxJE(9?&b3ZN3&CNAmiHV6BA6FgYVq;^Yz-8dz80qfrPKxMT%iw#Pldxy> zJ(f=GU2JTu=onYjDue-(jp+N&&=4BUZnbawdfw9@AvicVJTFeUDUrlSxGg7>b}s%N ztQJ#w9ISM5$-SCOt2P^XXd=m$xV5rk;8wW3y`3TGoSXfx#ri+oz(_x!BR=>|A37(u3htAVVdrY0uh_iXLfmv`${*4D{f{f|S{OVYW_V>eoIB_hMZ!eG`; zCSLXL_76>EdS974Eui0_gd~7Xvfn#2r(T;V%x5}Cf%xja*DN{aU}W?&0FzKYLx7Z= zJT*4<@M5o()A|n9JvOd+ai;hx4LB!>MJfeX=Ue5@yFd87uRJ_FE{oMl5D1lg+0d(3 zUS7{%)8Q>NI@`AS-Rie(<}lXOBz^swy2`JY=zQb@p zzWN}o52lBQhtJhoCMq(D;r%?_nd>q#H#hGe;D^!8)!P;n6ufEm`d3oka{lv!f?3L7 zPY<8RUv>mFE$z3zfdcNQ5i?UPcyLa!b?AYa#>E6{{H>@;?Le=?K*4` zyil=+iG7jZy)JfmiNtqyc3LlX8zrMDJ3Bkev}(i7bn^1@WXb69;D}?O`gMligLHbe z*LvOJ_3x?N*t_+?TZrS``DYME85kIzKD`N|vLeGI7|C81u&Nvv)cr$-?k&c%;?zyf zdz43?UyZfaC>I@{oUGaL8%hJr?E-l~kuby~aoV;&xKJ zahmCM9_mWWWwU&AhVaRgNlc+9f9Ax3So-nhU4Q1&^ud9F$N>`}x8oizO);?mb6P`W z{fWiQhzM*VaXJDiaq+;nhHz%0yE*66X{8`>@T6LwKg&{Nw6d~-1f?0T(KtF8q(H)| zQK5Hrc~)&QK*nXJ2wS>FYX@Q_WF;+Y17Bfwt7-Oh`EFEB6=wBPv(3_9>+6dUI7UX^ zLcY(Rd-X{N6T$cHSA?cpwN2*o@-hOEzg8v13Y({+B4v>I!*|%|j0B-9hmimgh!GVA zowvt`!#BnX+}+$@Qxtssm_)Bzq35f}$aTf<@z-vc75T9KR4CKzF{=-SzV+D8K z(U5pT?DTlP=;Dz(Ydc5IYx8q$Es|2OLA%~Y?VV);4ywrW>&tgztoPV-vKTFX^(W^? zK8J{JlD?`)l+J5QDT3F}nRh_0$Vdb+#R%EyV%+3eAA9^N0zoAH%xRksQq|4QNlhP0 z<0rg(H$EjrOHnavY$L)wJ|Q9He!=V&b;8NqZ5H$x)j}RnS*_3y)LXZbuSlt=?jRT$8TBX`Ot(zfF%_?)&ONioRW{auF(mkDou;+O&FxAoOEt zscey|G%bM%P1LFt&m0%&SaqDuIltimCCR`bb7CJ7LUzrXW`wIuxk!U0VP+op>faeG zO07}EcWq9O2Ln>MBLbf1<1;fer3D<{mh8Wn)ECRrqaeO@cB-Y1h%yq9**>J7f$&rk z#SS?(Uya%%>HgU0sJ*>?aSJnXc&%0$2cEinDDsE7f}9*=1RfRDkN|SZ%F&rgeUrbx zzb09vL`Pc9rX>5^%F+_MetUpnchvmnw}ue0?@&GWIQ~5XN2VmG-zjeZO*B+Y*;+_1 zS(X?de|dZR^7jbM>OKM?Y;S)!kjk6N;eQ?d#Wy@GtiKLWWmwp4BJort2aQAJ>lb=V$1e#{#l*iTq9LmkGm2e|=meR6apqo9xpo050YV{DYa z3c3Gvwf$NzAc3j`BiYE`kh0P4Q2y{)9ZKTp&^Q|>=^se|=xa0I@QVJ^d0!W5lb;`Q z^^U8ntD5th&vwg|hTScRf3TuY zDScggIhmiShr346NL8I0^*3=saW!I5n?JX@vced)IbCU3+mXQ{$`t=(UQUkpIY26; z;LX`u<{*9eHkFbI?!2OlSKR`cU0q!%Hsf0-n3$MLi?*fzG+I2M{_3-xZ@7E!UcLJt zn`(OHLM>UtIcA0@MzQlPo{gbVivp5{WcUy+A6M_F)&B=Jh9Ncryf-m10dUs7u#mAq zHO``qLvr3+9I$?;}9bu6~{CncBE;8jhd8Xj6(F8e56x}&|l zx3@Q`fD=t_48jB|A}JE57%P@`i?6a660Lkeqti~xTN!=*<*R=eTkaAFpO>^`LS9Xx z*?Q++)MS|A4M`;l@HN?e0SH;RQuu3W0W~poTM%c=I8D6+Mkagq@>fv)jq$$<|a!OJ9v70`dIs z5(<&H^UkbV?Y>y75vzjZe1jtv4i3biN1Tj3vc|^7&GfvKPznSGcf-fZb(^(hY%C9d zrP_vduD}GP3_kE!>y1zOwW3*}ha`e$+kBEBn(cD^?~h!!BH5lu$yk#6aIAPFOp`(? z&w$lmCQb#tv3T=MC>gr@`nKT70j;HRn&Jj`e6d?@Z*bi5@bpX`{3pTv8Ylg!BLN0# z>%Y@EhD;BrK!yw|EmHVu-2d#71ntb#M-P~|ySnO=@BqlMF!h~jaJ1CWm@dflVoL1m zjv&odWr7EDyt;I?wcS&Ae)h2?Q>lE)kVHLEQwT^#ws42hb z*x1?GU0?khu#ckd@w#x@+f z&>r+b^sTI|6=Joifz~BFcnVFeoBl=bp>8G&@&o4T=3(fBE z`DgIJus?B0pM0B`;1&|Po~bsKjG`drG{NTVcmb8i)lufPn3&k{_RLZB(DN-Qc*Gul z@9hl>4}S*40L*!0HF2s4-cOh-GCsSd{$$R*`9@xgamL4w%OPgh)YJfW{QLLs_IzXg zE+_drzBIrM<`9q|OuVi#`VNqC{>Kj>JfOgEf?x0N@6T>^1d1--5xU%8aNonZ|I}f! zRMX4L3l8VaE%%o@N+L`5n*S`^d*jjO5NnEtPe!`e_VicNiCMp(ndct~8hsKc*yDhF zBqeTM$S}ok>TS|x>F279WnM>76NEx`uCkh`0t)1bHZBF9qBZsL>1k9%#3f_~9@~X} ztI(*ZPds=q^%s8@y)&OV?*g3wmEeFCB<>-IMiEDnT!9e97T_Nk5tYY2QnfK44u3Qp zHy9h49Tz-*>-Cj8ByE^ae*2#o)%fB{V<+)|)Omq-SnZDH%)NV$Rm+GBBl54u6%;7^ za8$+$6gXFrkr0D}gYVzJ??;rMz9>^qJ&lK)QOmWWuBv)@Jf_g~{-(@Y^u899ibWOS z`fN7ghvAoHp7JO`iAYVQEd(<`ZSg)V28`_{s=6MTtO{ZvU}hm5_;dUNLgt&n0q{0S z?@uIvOE9SXoG_}Pr?&(ZNCMmI2B>j?Eg`9g8jK^lx@*xmC4V5QqsAW(RsY9A`I}a_ zvFA*cF@O{};Uye-jg9WY!iWzMX9eY_B_u*#m%b?Iuw>PiQ*0*Xwypov3&vhIyTx}J zsL2VLkA8%*6VQaKi%U{ViFyeR+KbhD3}#;3^Y?Vv{=_TzhTM{A%g)XQOw5&<8~p{7 zbu_Pq%`C;_T!Wk{tRzpl$Y!x6Jw4sp((;+hz8=)_hllpbvcI;sS@1BDxPUKUkg7`1 z;)|3}(a?A~Rs+>?WF(FV9;A4@+ktBC@=$|AO^fge566n`hG-8t#-MWAN}fAi-g#@X z4DcyW>O4>k@Nmh3iOntteo)Y#O(a zIBQw1CMS$1rlj;ia84m1zJiM^hT0!k^uFZZe#A94uNjAsx%(sw_4*f3j|I_~MDg0K%!z zV5$DzA5q-=ID#=OEIQhBb_pgElE+MsXpls%{x2#t#LK)2-8nl>Blk>90W(>x8riFH z-0w|GPsc|+g96lP_s31%DX!kR*<29ax}&Lh$zPYLmkjKRSdJ9B$K-E7hKq=Zm|Zua zm3l%$^Md}vL@d;Sv=1J%S>?9rDV9u}kgP0P{C0R+ram|N#S8;5&!wNn{dj5dSRh2A)knc6GJ&`3{~EfWbD%e z|6)imlfd!Za7zGjV`J@s;eo9W706IBXSc({z0%TBD2WF%1hsQVJPyAzn9vZ-v0g5< z`NN6Zd?=P*Rb35hb`#W0`iN0QBrK;sIojDxH@nxvk&=~-n86mq`^M*W`4?#6NN)oY z9)QYlo+i2E6czEt1o+{D7E^iVnfnmSr$#Yx5W-`}z>@;0X0uI>ETZ_Xoqc;XTIlNU zYP9xK8pSPcy{|q%(lk2n5fc+L5#5HvQ&CY-EEkH8kB{N!@OyYUl6Rrdcp>fd*F>`f z46QFh*UgxE+>8s#D1CKNbj0U|hSRO7=<~!|Pv)AEBvhCO`2DEWQ{Gwj^Az&0Pfl+j zs+0koPp~Cf^wwbU8XboTCuL@~TF=!z9dxEn>;q2JV0(9Oc^RLKtoK+Wx6Cep{)4sU zwu7#9xl&1%ddZ`(s;;H%5wqd}r`HWOFYv~zbl-;CEHupk>j88h!UxVL!Y4CxQQNjz z&DsE-;QlkGn#xaelhc&`tDoc1M2W=9YPL?x9}kbzc}VV-sEFdJ-rH)G^s=F9vs#i!h5Q)6(M7Eu;(b;ZpXo#zLzg-$4s5TufReIW=S{!=q1e z@{~pbf=12F)6v!r@p;ho-zv4>>A%I}L0>*p!o8zkiH}RQysy}Tx4w^ud#6p4QNgET z8ey6%@W5{sBQ@CWGlu%qbiOK+(x)taDm>H4Hmyp7K;Wi4-4(W-y(p(3U$^j}Cz-^LEG_SdT$`eB>}(HY&J$Labpbu~97_D&pQ*n_D_%yAI&x zxd)@qKB0Aw-VKofd_UTJAv`C=xx(WA$vepJF7s*LRc1geapw;sklhD$=po!TOkOQR{C>J(PE64Meq7jk@iR#BbFlz4W`?StuM(G20Vo&eWWe^XOLgM{}*B zS4v!Yla?>TRLQT_uZiSJFz(`*(Pcj&!G71!y7jf%{bZ!X#~06!EaYR`DedOEZv`L5 z#GSlY^4{>CFoUX`q*6u>)r8opC-9@PYL=*W|0E^hjD8(%;mh{ZEx(zUFk4JShCBwt zVTqU@&7|{QS>k938Y|*S`_W=3ms7`~^=5IHaif*_K4El_Mv=2PCc9rm^RijGoJSF@ zR`-RXTe?UAouiv_ISev|sNyf*SGpvUTZQ)@g0_Y>y@Vh{JeM~V2#8i9xwl+}orG~O z7j>{rBQE2Y<1at7$Z`LhvHw=3r(5&A8Z7%$k7=P=n5KTAT!3NI>`@D%YEUSvy3qSazr>1fgUoE2p-C-A$@MUXfr(a|{zJ77&-6o77g7cO?kw;N44xI(JPBKp2n9-x?v4=im z@5sHD;d^U}w@GdG{GNSTj(cJ*$0(y+vjB&+}2|ratwZ&+2tOJCpvrq+Mhw}d7e$P!7$q@F~Po z%|>5ZtT4**6;(h%sJaRNMjA%J$I?R;M&MQBBM@N-Z60<{Bt(TVjqEkWb6h?Wgb$Br zVl<7Pw|{&vqT*_&m&WMdwWX|r^chYQ)!b`p3NEwZS8qH|fUSLXVPj&F51{gs^djhR zuN$3CpfDxn#Lx_ui~fH10VB5m4zl=$jQz=(=6RE>r*3`=b@*tZ#$X0Z5yS5GBW$d; zbV0jNPWBD+@BM$Y7mv)aX9*lN^FAr(m$6Ls8qG>4e^UOWS{$dtze~Ad?`Av7jQBx{wes zFT(g=JMh@h*oi_wY-Khc&O+kjH^3Y6^Ya7p#R1L*WQAnc5n!0?*9QS0PXG+XB&1K0Pf%A@wm<%@w2EvC zd<@iB6i}`K|1n{4@@pVM6`A*CX^^NYn^bR?S%KH5m>wOD=E>J z7qX}o8fjI<=BR#Ee@v`mpxqoGgCXdMixFutUE>$o`&OO5i&c0=0U=Sr(Tn!tFCW{t zY0)1+!D0Nu?GoQ8^!kvID8%~F>a3^@kjQx+R<#tJXwxub1+-oshL@C-L`M%%d0!rY zu&C4Obsu2|RX0#B0M7G4(Se^>n3)YtWI<{Eoh9P0!7>R&I0(3{XTQi--zJ^3ym8;D zt*Br}-0&Gx0xs<4qqI-4-h`md7GnoedM-H`eYdR zsL7nB@~Wz;8X6>WV?zIq$AC{46cEsbiGsuAdh{!KZ5a-e2JnvUfmlcgFh|IDv?BMM zTf516{vcg#-_4l}jf=M!TX8Ikb}+}pNbNYq`SllduIYL5+P2aKqhRuoHVE@8xvTNp_wNUXhXx61PwegNT#g2K zqbc|gp{_hTTIZB3G#{ZOCnu*%6T?E*vwXyw&O$Z? zl&5=MgZ4)ybw6JfGI^=TWPDK4$S4u*RdlcYrb)Ag@~HjoI3{0!M(IKQ#Fxruo$2z> z_w@l7Sn7Ip4<^SYG?bLu3@X1Fa3GdO^JKn!`BF>E#>`w@U2WJlI)!`J{A;Kzlk3CF0^5m~u7UK= zB|bPvW~R1bZg*{szItN(hzT#5u4GvKIrB^RjD$A{Wk2JV*`)7jw-YbB{SIVl*TweR zab5T!d~Z^bV{}RWET*<1UwHaPu>W@f-0j5J7-9E;kB^TQ!3_xv1h;7rA}A9pN~)-+2uf_&&=A**dhLK+?s|X6ty#BB{jo;HSC`w)&VPWtF{{-wiCmeU)?iEQ zqu2rV5;!+HI=YsY7Gx2WDUqPkS9D0H1xl5xWg7|R_sq0X&tKkmmrK3$*%{Lub`SWs z&7FTxuA}nykJQRhfPpUluWY+KA0J}Z;yi;LgmXbulP>`uHdAd_} zup_{IKTX(ls^uze1Sc(-)S|ldF`m|KPA)I7S+J(#_uMYT(R=m8btm%Fy|so3!0*~( zYl&g`TjT~Q`p3(t4u*A>II~IJ2ao<7rDIu9)ZiBOh^)~|NVwd=`4t_A)2KKwyB8^F z*cFj5h-}2|C7pNvEVqq7gThL`p~mGblL1Hk@hwkD{_-E;p|l7@naH21+>giTXEtX% z6w<={(xD}&L?W5^h)(IdYo?zBj2Osu z;^b?_Gu%p6$ptC&Y!wRIU{4RV_*O`+d3SpPWJ6KfAmFl~*vwb^0Gt(Q=If$dFluSbZxgo(lfr5seB;fkQkD6A>1{@N=ntxk4V+%{kVd)U*c8^7X$VB8FrvE=Uk`#T#OGw_W7!EniW zwt;$sxB+7OZ=mi$(?TGCZ!;7T@!enp>;%eqCg>WVB|%!+TWoDL?8c3y1vbqUEDe7a z+=pgnJXYvXMZo^U1EuzD#kx<(sw?}2S^p71;|0W;vu!oNTDz`>8ny7RxOQa4?q1#{s zj*rWzq}9;o)`M4NTDK6OPJ^or_Sxt;N%F`(-q@2b`St5pkZ)s2$vy)aT%7xe1U?Vq0f+(rdgGZR$@_YHK~vJ^KKK?&s84N0&Lf!L zvWd$)pAye=mc2donq>$Ptl+F9kjm-Jpt``~r1Z3~`Mw`qVjjGZoyz~c(0l8yRUQ3Pm-C53CJ#S z2?;b#$&~2mJDfQ6s!TX{?f{bh3m~+uG~EcS0^ir{e{qW|N#~6^V0*C^Y=KV=U>Hay z7C-D^J3}q@N-jAyb!%y9I79)h_BJ_T&tuW0Uj6|w$35w_vw!U^wlCFLn$uI_>#kzc zC3G%R{-LivtJWuE9giz*T*^^oWXCon+W|Lf42U5fmdovd?|$_^0x>@QNgO^UWs5;) zn1awhRTg3Zw8L;>hK7bd$B6I1KAfsHRWRHegMvUdiM{O!6`FK1e{Te4UXY6B{emm>*exA5uz$3aytDU)(1WL26%48@;!gv z0upS$C8`Kmggrt1Z18+ixKq2!ye~T=V+gI3NzRTx`W;~3RfyJhcWqK6az}cMo{Wv)cHP|s5dwxo z^Y9^P3<3fINo^rkJdOFYH!*|9zxL!wS}~FgMQ> zWD#nZH|d$%(Dlr)ZZMRo{9d_Bb$Vp6;UTgUu7)PM-^zT@(9n?5><;!xa9L03x({ej zqo@(j-^Bo=j#)^Le=vT?W+$GJFE$poRS?Hvy0dt_Vpi2|Y%B7G*Lk^#okBf8bYM^m zMSmwwdMyN>CTZjkp6Z*Tcn4XelOy42xz?g#x17r*H0j(G@0z3T57C$QoxQvi&&hsH zjh^|<7S)krK+@N7q^bT!t)oflmM0fo6#dLl)FqD#M@u1Y=S}coKr+h0(BI|In1P)p zmT%pm*PDV53e7cCsAc8kjDvjoBb5KkQLJ z1r1)BW7_80NeB)-zxO!dX}GUe2KOyd$Os?_qagmXEUk7$cCc@Q6Yy#!{4t2x|1K{f z+kl>sn3!1aeSLKk>SmZ37;eN}6Y=j5fqHs+K+gs=dE=!LSAr;BrghSWP9-KG0se*Z z)~i{r=GN9$Ri?;@2(H1k*Y_5^E?AFpKuiUM2K9N6Z$&)ws1G5j>Yn{Q~k#3;0Q(5CzC51X&xje^6n; zGY-lQR{UMfL<4y-JKVjTqopjSDTOJ!*1_S z;~%Rbuby)%2D$A7=1$-96vDJG^cvk+>q}H2Qq$1* zy}s@Yp>BM992}&eMN5c_gYQG3diuRZ0t2>v{4dHWzrN{lTXI@5Qy}kRJ-h4wqWcb>0(p|TQ*owR%;p0~Gd4Q^-;oaUk>$w(C z>A{0f(QW)hQ$$2WQE@np{~awSd>iqwW~h9+>+6hD$nw76-U7)*Z#E>{-;jbXEi7H?_!eUav+ zbEgD#*9~^5-wGD){P9O_p5ya#n$x5Fep%NeKkl>+B1>XXmStt>L2?F}7h)>{0Uj%p zUPVdCZlzp_``{&jm1mFC#;(+`DrKRQQUU{I#_;w?Bl*Etp4n`8T408;uy9RW|WT<7{b2$Yn2t`_i}1 zz2W83D)soL#vkkQ5i=0}&!cWEpg=Hn)f2O5>_g)QScj`SF^~{owbp8I*r+n@qoAMw z4ABIw8=js6Oq`ZgFcZVWimTtu;j}S>iu~vRM)VxW1h7(|p`lG)RErE)IzPF)8{||G z*eN3O@b29;$+}B@AtlvbssnQ>cl|GC^ zYM@=HF;{`*28&CQPWkAR5p7V`5F_&M;y+US?>t83y!@OAU!r#}qG} zU9pzhV$pz(>1TFDZ*i8_L25p9c+|}lgjoT}XmS#oPs#X$Xi0GTlI-0bE#uJP z2n`mVxf^%=HXuz1V%*{)2t?GX-42*fvkJaO(QZyjh=~+3%^!X1b$=DRai{k(gbpXn z4{zLRR+PGQ5?tU*p9Krqa6c-E5Da%9)!}Mk=f%ZS&Dg&e!escG!#@!%>6bN`YmL@! zVS1ukGO^^1&LfN`e#H(!jUt6jsA(;Km3>_&*rx9VJJEA};j(mYHB@jBL>EWt zu$A}ig4S$8STHft?Ea^{qr>}b?cQnvL?$|V`WE|c=2xF0DEOZ+G8O`n3GYOE@y~?7 zC#5YEyEpz0+RNqW+Rnn=H&SZ3b&vf%+kSE3ukmPngxVa-9ghJnBA|BA5Ix_&!!8?y zAe2lzpTB!cQA^7WnnU8^;=s1^gs|Yovyzju694S*>=Mq=^wd;+VWAnoaST7zMmMx^ zWitdoSEpm&PLc5J6S21V4|EO5XY<%pr+$W}54QB==tQ-(=fF$@uNKb>WCR##h$$(- zs|7R&gKSa-_#DCbanl>qHd|{M*{lzy2_BmtW=@4*hN6>6kWJ;;0fW3AntTlH7kD!m zJpj;_>3kVwY0k`i14=MF`|EP-;K0C0m4yCTB#eej zfq|H=HjP#<;htZEX#&^L8El$Gx2>{}kPsl3p>E>%U;{4d>)hz)#dW+J(2yb-LBe4< z$+F7Dh46vL0My@Xu>y_=jy2UUI^cfLRaJGk{Cf}*f`R4jQiyMcct}vlJzu(^SrMPh z)mxgx%r@(adnBO!^fAcsKy~4e9UctIrWF6_>HNB}%d;@yY_HkmQYn%9h>0l$8d9K4 zRaQ{}YiqJpJvuJMOT2GD7xfc|ghWJmtVZ%aKl@3D5Z2SnN=%#rPFDOOK4J;tu>NFe zVKEeY07P%_-c*^k>5rFq0W+h-*oLlLbaZQAxa$Y2AecP~ld{!UR%B8>eofVdX1s`% z*&-Jwmpp%i(AJu~BV>`2;Zk3`b^X`GXNqpcP>?XT<4^IiIf4-n9DP{0xWpK!_FtN^ zvZ$eX=zsn+U{`=@JUTiuq#x($?eFK3@7USg?3Ha8knMPVk#ht+LBA(TrgFr?BeXC7 z{R2ym4tHMVOcmJ5Ai2{@fsf?one03&pPR(jalyx%>_gkt>CSz{Z&WquV z-{y9nVAMAH&iQL?4Qv%R$yU~Nu%pBOQP|Af9CZ2AVPG^Y4l4=asb4g&%pf-3=WinZgyXEl4Va9udnL!rC$}EiPOeh zV~Xp$4l85RxmGGvSv!_TrcYM?w;U$%3g7sm=4NIdV65!y2!c8RWFB-NiAzetK_O-M zvo%*=-rW2TIRA*+IFIL<$v*Djp8!WFl<1A+<$JKBqNs!hu{&a3()O4BFwtNkR)MY! z7Z(>6sG$Z-rgWW*Kn?k^u&@B#iO{^zvFritCGpu`MVfim{C8@4#pP$IQ-=Xytw2nxl-~o%!2aGlV$0N!{uJE zq&YOw4{$E;g~$Xw^7>thkjcmsRA?w0>TCME7a~E$W4@!;H%NoRFmL0v^KR67>!L>O zEgwa-ixW7D0K2wA4z6|Z62bdOny>u=?_<6n{rJNb>5VvP_KsFoowG8r@3t5C19)yR zf@yL%Rmzj|5*mc>Umin0PRrS^RG`HQCp0fYv`GD`^eJlaAPuzkZL4|gl8f+lwc98(oz?QWyzMe97ZP7QsQMipX}NeVB3H#N1_> z8tu*MLtj(LpLQ>{SATw~CMV`D2<;Y+Grs>$4IEDsb{Wu)_;tXFi@)+?vGL~fk;vXe zS*I(hs1};0vKS@etm{{07Z{zCywnx{``;)J#@PfC$3|SogGKiJ>Pe&@F~{+@><{Nu zsBjsrrR3HIbQ%31=7s_xVNm>n0AInAC}8I6O4eErrEdM0!wJdu>?o;k zR+mMTFe4rY9Ef8#PtLSHzZ3`d@(nF{MU_6);q`Zg>neIAH6Ne-`4CSrhu>z`N!PQ< zt#bWkl6^zMQ**DBI3_s~b9_Zlwcn;)1@A6eiX@GOdl4;H+%M*d7UQe^8DtAAy$_h< zU2BXR?;aP@wP}o{i@wTM2xl7pURpYs%W-?}(!6|w-Ck@eVGsjV6M-F|NM3)y!QDz@ zG39W}o$TZNAxAR3zFOPfho;Q$uHSlP$R%g0{(zxVWBI%Y&#o&K#*sHx9-`;g$I%^( z2kWAWkkVLsPVEDGWvSN;FPx_bacc1^#4u`&$*De6qbNz*sN8>(QN+~rijuDbr6#cp zP{7Nxiw3cE9(|Xdk`JOW++gFdsJ_j;H2u!PH8J1fK9^ZfjiKw+hab~9r>fPWN{@!P zlW{u<^gjr`5mr3%yLoq=0R7?};q(*>(&zh^sx6-P-oLJpQ%TQK8_n;mc6{9_xLk-? zxO4NxsnWGeicf2sWK>=+-*WD)%?p_N?Nq-hYSq8U62_~qXeVQe>c@hHCR%7coAR<{ zHM-$2_2Z8G>%zV-Iuv{z_dDlQ=BUBC(8Ic9Bo*({NXmg(i@sB2jbgzoU90zoDSqGS zgU&)+hBW{2=!KkVhDu|qmB`uOsIvT$4!*?yCYgW*U(|ZIj@G{F@g|#Dtg_7HULf+T zsCPrBd@j_#ocwN2wN0RB^W2P~?9rHS^P}+7TI%xFj$ zyoIVsQc4y$o3a!7la^|HuIsQZ>tXq-tU}sU0AXFNR-7_D?T?*?wyPXPZ4}tP z`Egsqs<%(WjYDViD-A7AT8y(`y5uaJIX$g$l`%jR?@)Vh0uz0I6zvDXN?L#hT zq%pg=&y&T-(PPDZ(->YQK!TB7XDCU)KiCK3RF=%6^xXJUhb1{0mAIH|o}k`-SYx~4 zAsn;TriEJ=Sx77VlXG){ukX$1koQ3S4z&YDZSCLpWg*$L3Z?Jv{6-?j$mYRFfQx}7 z!C5}Trsc+p-rG{y_>zPB47J<(WrM4qUC5B;J?1X{AZn#<_Ta5})aj#$hNJwza#L&4 z_b2Z9>$esdOX#Rbji1Z_9SX859l>|d47F+Rkec6`b(+;Cwz$xv4w&^zS19DjFhkdt zAx1Y3lNU_c!rx`IvtB+4!u_v>MTw%@JjJF+xUl@&#HmAg8kt`T87xexE*+8+-G>rU zRu7JK9k#A7gl+`Pkn9)*$9a}fMQEYLjgAgD#7gKt zR#O3;QwN%T>F5B-_cN?Q`_%vbUI6{kk5bBytZ03-68AEc4F#0E-_wQrAIhqY_=gRz zUF}$GoTc7yI%nC6ztY@ zb=MAdC&$MTAtBUKvD6r`wB%{cbAKrDS$N5b%T$@jJz~(PG5qq)n{^k{7-}(YT*@Tj z#-6Lz;}*4TdcsOuB`l?G=p3JQ*rHljB)R}9beUA&W6@Al2?MryqU%>C_h$zAw9hal z;0WO5E5|d^e3q$b>z0E=Y<=Iui)k^tq=&8WEFnY4_9MGipT$<|`~X}poaQek~DHaVpdRg_>Z ztEM3X-9uS63U(1?p*`d_AIX+es zDZ0xOkoxXb^i440j&DF~2Xam}L*NX$u%H{8J5Rq-qpq&5OC1L~?|(5MI@m2QS--MJ zelG$&+oyjoaP*24q(3-JKJKKXp$K3*`6OPtfmPo_vlL0r3+zfR zF!{Fwffolv1`desE~>gH`wW3!31|3FXI+9}(VwQc)01&CNiK zbUBFM^l|C1@zUGb+gn`eh{il3MS94pMRBwLpNrAr;%ROASfeRvQIC9a+?+R9Q^K%7 z`<(gTYepT~Q5}9O{&ECHD@E`Xo@(lj)X%vDW?bThlHr8k$OXJxE|`}1*VOXSvyKN= zFQIhR#NylFF*5FTq&_6Q`)uJ!;-|Vem$yZQTMwyFt6T7&4^VHpW=ENN(u7bK>XzD$ z(~b{X%g{2oX731(Wf;I^wfo+Z3GXDJ|eAe!In$3fofbqbx>WqVb;Lb^%*p{AgP%&R!yLYVR z>YWMoc+aBg*HOrnd zjEPg{>&yL#2Svmh4G@C*QmTuE2*Y^MvP|hU&AK$l;EUJi9m$+;%Jz-fq;q$j>}L53 zcW!d@jxOWI*bH#^k?FYF8F_3CZ$|V}o|*YQ9YI!m?_1RpA7lCc{fTm$a*YEUbs_&( zVT@X*ElMRSC(#`;-ap|YGWquhcGx>3=TTSbG7|DV&i|wkI2LtA|L_aL>Z@TfmRU#k zOF^-s3DBy==Ktr88_!czS>{h#fJH09BgdipQ03G>tv^Vifz=MbuE?fv^EQsTr_8e# ziZ8wrJQy!7^Auyn?4pfi#!YyhP-4&h+*a$k;u`0x364Miign+jS-o4iuR$-TOLcgJdPn2aoF2MwYGAjF>gLbBa&PWW9fcfMG%W5v z)&0uWA2{87jO}KO(sc1-_2IueMIsx--jydJ$Ufs%?Ym&c>;9XGEJt@c{y(1HI}pqM zeIJ*MJ9}qlZ?g9mGP3t5dy{1EjFel*-h1z?5}^_jvPTrMvPE{`d*09c_xbtf@jRaU zzOL(ayF^=>4&rCfnI>ky%r_V9M`rikOXY|f>sbs`n{hVf3)~USv z_+sAorz+34lf;t#`m6b+&weIjwt1L@bF&;88m%n#ku(4)f{)TLPEcR`VmvbxOPPK? zAoS;rV&csO#)+xNndrg=Z{`>9(K;IU^vIkC^i#|1?W#?%MCWJJ@EAUGp`LN`J6Fm0 z>SE-RXv-XX?UhF1(!IIc6ocewR>Q^lUR++&c&B)G=lr8S5Af>#M6Jw&|2|a{&phpW z_Zxm(WMC=d^7Oy=elq;=toeUJwWMzuzx;jw6zlf6v-vW%!uR(y>W-)Xf z)8%)(RGv4xAvY=!D~ZgbPmCF8?~y_)Tw znIl|=P;WgpIg73%lfU9p`Hz1?i1C?tIVL$?4IFqj)fOyZ~Sat0$wXogh=y&iJrW9u0ZxqeX&f;43Ff=KbMBX!D zH{Tu>dW^Wow`N`wO$F3LV7^+Ud2c|aEBOx1jHTSNcV~!WVo9+*mT1M{=5Sp-)rOF_ z;v!`%?a1cJyU)fAvj^`ai0rT+o=!Uf4=93NlAwPlG&pwIu1dQ0gmQqVt(rL|HLRA< zXIHxT4-0&b+AzhyY5&S~Pj)%$a~sx^g-kWYCnLlq%ms)U<fZV5>#JVJ^f>AkF!-W0(nK>DmIhj%? zdE9oAIB3Gyb%<--r+Upl$pdP&eSDQY3lEoj?$xVlab=y5so{Q{^9W-zRoc-|82+P>A z9<7MZuF{wfQ@w3{CtbI|d=W{+zvv?yA{3YPLuum&-%qzJLswGLH(6S3+029Z?>bz} z2KL?E%%&dc``q(&$a_BIhtvM<45#5?o*o+$-wmY6J1U{Db#2U*#7lqmlF^$Etqt?ozd$#PT|aF3bQR%|}Z({5P z_8I=&nMwYDi(5V%rQ$xyeNQpUwv;D2Be|C|=S&3uyG7$Dd9Qd@oj{DuUlpG=ZgLjd zB$TufydD**)g{gx7r04ZDl<3gC6kW%XDF0Lljie_?Hsy{`0HqK5lRSQCH2C^n-iB> zQF_xp^n4D~QZy#7`78U)ud==O2HRt$f)t5cxPJfn(^{gye3zr~x;HLt6#Q?0;$7S# z+GaTtv2krqpLzzTD~O5&EL7A?OEI0)ZMA)$CE9c}V!VA>{N(;eYlU%v5nj~Oh4U$I zJxIJdG_naxKCs_s*Z(85epavURLGU zS+6!kHe9Q}Z@2H4kJW?>-m|E-RAP(FZ&^J4@@-x}+cdy1h*`3fr9LVus6zfko(aPx zomsKHsIu>R%FH)G`ZW!t-L2*7g$z@c+YkJMRyl?l@6(1=9IJT8Me!AiKWfKVr=8gd zpT+EA=xgH?_*=)Jo#f3s7xF@;%%U&rvH8mwig|+FwF&3vL0y~f3S!nwIf74!)8v1> zCuh{DPhdUl$KaaP9{oTltlW1?({tOs)WdK{R5FRp`1{)iDu6@ zmlL#tI0j<$BeTO7S#v3`^jeM7z6@EU$y$%kzYFxZ%N#hKe4jFU?RBnE2k*LId`e%- z5^5`EVZ{(t=-S=BV2HgeZYuh*|Fm*xn;nyP?X6+^^TA8wyK)q49$TGe$*Zp%5C{86K_x6@MuhjRay8uRksh-YS%zUkv8D2%BJ{xnscBjuw@#Ak$hSL~_&w zj`r`p9U z1V9dC^+39?2D}zU%D6+H^hrxvC**rww{h(4pL`AfDky*dQms%Q(@Bw8`J{pHrr-Tsi=E?z#QoKxDZf0O;4XdLmKcDP^Aa{3dsM0Wv`(7 zZvNU0QnQ2OW59Uji;(JRe(GaaM^si`!^=mL#3o_X!9}WQF!%eoKT5M{H<`~~Dmp>` zn_p$RDrYcFa!Omo4lp2n{6w^#J;f zoQ!NlxVGVa6}tqd=KI?YV1y{qG>heV;mFaV<9i!%;H#fCMtM=)TBd!Z*ckk{swCk`J$+?M&7cQASE=oq~46}H(I`byo$}~ifpFe|zn-ApEI7!TlOeNG8 zfoTE1?U}@!95-ugfq(-$$ozp!0!ZALnTug47kX(=pFM+iwGerp9)k0kU}TwYL2Q9D zS;b6N`ihm~_ko(tPb&J}-}ep5^J}Vgm7-M+quHen5ns1O^{dItZ~z(spSFDaxU{wP z6o8yChfXbEgONS}JB{b|?fBSOuSbteUb|80|K!xrt{QHNI-?H14R*|cvmr{B@@}nD z>4??wit9JGTh*a0$j{pWp8TcaA{E`}w6<>avX57uS690NUzw89r))6~z(_MOF+u%d zd1WPv$Yti$Pw0LY7ZqjTXq#G44SyskbHivuzr5ST-Avy$nH=H(m3TZ~; z*LoENW*^^rk4H;;@s$dhdO!R=uM3*kz~t9eS;+|$lmG>_ zL;bKQa!5)BLNBm88ea;ir-Co)?zc}>8|Qv)pw=<5VCpVGZ5|=mJd>wVnd&!-Jn^eL zX$OPuTl~|VdEA-Z=#glY)bMY2mQ`+W>i7FIj|~71Li-aK^nhA(+N0JB+ChM_`$B(L zNy&R-Oj&=Fv%Ex!p~wFJzL%WAx%rf;<=eB0#)7O8ljBRbwqHu@irQ}-&fbkh1iXo0 zYoVN*Dl4WJyW8jWn5@Zn;Z;b7AvtrKt2RK(%J}jW1>X!$4;Q zmzN8Xzyz5k(x{{0_EAmXXQlHF=}LKrz3T5Ff>g?NttaNpUegVl(S~9wEd|bIAL99u z_5EZG@=A*193zG!u4EGvy;q;<-5aLT4F5su@`+Qd>Bn6u4nx!#C@XJA(AGZ{`U>nT zjQsrk0NIk-8W9dT+B5{}Iy2eliY#d_DIta_W+0BBRwEq&-!?gKxUHJqG>3e-= zsLU$TpYGqDosIRumv~$eiRE_@DEvQ6P67N1P-nLQaRU`m#X=%RC0zpthc#e_0G^D^ zr6oad46;D%bil2csj6th0x|1*JSS>Qkw%uJ^PcN|ONRU0`Tw*jrXy^3Y|AEk>sh|P z+uuLleUO#y`GAwxtl1xsk-(S=KpAo(B8IND<;QQC5>-1RQd1{^jL_k0j^Hr&sDg{rCwZIOd{nFjrliU=ahf7mtgNiS@GLKn1IZ1Ah7^H-o+18*`2m4_>Mcd95A@-N=$ykvX4>sWi5hN<`STN=dqciTIeHZ1o;IO3*>`3P zb+GL|^`FDK` zc(1Zx@2kSFHfiaPelL3W1Wsw;orAwyetNfV|HS!G)5O(#Gc6$JR={G{vQ$uw7-O@C&5VTCT8&8qkeE~&Ac?4f zU=qL@-z;-;a_Sy*e6jFGe&mdZ09R8D=7{zC*8dL(>OW#sU1BFLJ;d5s!{T~EO8EU zOk!t?-#vbPhyXzOTv8e?881^Z=jR6`4S}87Ps&T%U5X|cC}NL*e(cOvHou-%qFxU} znc;Pj@o%&Vfky-gvKGE*!Rb4ZIbCmuRnHnvlPlv?zBL_^x6QG<#JQ;)_2QU%w!biU z^CQM&_&876tsIK$bWihP)E|&>~B_+QgYka^1H+?1mVU+0ym>`ZFn(PO3oa7P4N3;Y|iq z%ApjoK0xvVI8gOz6QE&&5a{*8AF~j(Sz21|w8dUGuwV6R>|(ymRl^qgFLu`Is3rSG z9k=e2@Y-}eTiabi%ST|!6!@Xuw6wG|GzbU^X32)MNg~^bg|i1Hs{>`wHktkb-Uc9Q z7gPB_g9P?R@y;E9y0-%(E7&7|HaQ8(>d?I7D@%A+9$_B#=dn%-w_01;j%@FP4{ClV zDs*2thb+H`QbZS&+f2H-xuH<`z|eB@rXRqdV9GJI3p3Wn^T>7C!Whj-p8Ny>?Hq41JD+*lMp7cu#&`x8m$AASXfhog{17dZk8$w6C$FvNb3o)slWHNzXjUP zYHF+8c9-VQJrk`-ef!@`ar_E6uD+;`znrp`VEmxLLO#vM%bTiR+Df7If}IG#)e+ve z`q=PDnIQ`Jl_2&NbDQ~HORky(cxMs8bK&V{nW!JdWJXf5fzOmA;OY!n6d@Wr5W~bo z508oIe`5qqng_4lOabG#qFq~41N1a2F|T-}T!;ghc;v**%wK(TGh|gvQql1Eq8Rp` zSChLdko%H@$Dh+lVpubA18ez!^tH-G=j$y!zk%q~I(Z_9$0mD~o?Dw}Mr*@l!WwW= zTk;X&;qgfMswU-#d)mPG(lY|O^V*$~(o)S#!KdA4hxTvV+wR1%YQDTbI3_Y(D~ zG$WFAhsKAJN4Y}Z(bCbK1&6{ir>2rCaxgL$0s?r!EE5>b0s~=q!Xi8)+!qmacXGMt zGCq}_9ISfz?~?YnAK%&gO@BSf+_g8IbEKM(rtRyJOPA3chrr_Nz(6~k8b2d1Z*OU6 zXgsxjwVAA&<)G`W~pc#VNS)FeXZF&uHXPfjS28(!JuXse!?8It+kYkLJWVXQX|4IfZlGHq>byl!A2Bvu6YrljXm zRB+tL$Vm4yLU?3A^!frv4}hg#VBrZn2CztcU(Ig1XD7!;R+7pkxKWpq#M{+gSF2gg zxO-thSFDA=!;^;52}qad;cw+(khuZ=LF-g|vI@J@AXH$cA= zg5bxG8)2TVq2YK^32X9C*^^7|#K0}%GsB2hoh*OOan~xZ)a2c<=kup_<+8C-wd8|> zCYr&rUGTyoS4xxH0pvUoni{lT6xoE6MJge@(-oCd5fM%!1>tRXuC;u5@yt%u^<&Xk zyO1zaD$V7jxU|rHl6m;j-$%NVgSGiDHSKt3J3)(*DUJbY_!Bhqu8OjS4@;mlSe*xuxNgDm(tW! zK=&yqAwzl5ZU{29MZ3zR?={RHrwSv>qJA+@fAguedG~2l%yEA0)Ast?y!V}Ai82-L z9Go%DuU@mDRiVcaF+}MgpUj^}2cLJTA7h8AJD+#Fqwu=lCHG*-ckBXp|0?Qewt(;s zRtr9B@grIXRjf8#5=MDMp(VXu)4S(bD&%4KY69dz!jnGFR^QJQHItR6?-cEXVxum$za$ z*jV4u=P6eP%Y3+_+v&@GJF2c2U96V}VK4%Ljy&7cCk?0=S;MwYY zLNcD|nOl=ZbMZ1`JbCy;sbVYiZ-R?U{KbmSzMqZ-$A!PZcu39luV-soOl+(gdo>%Q z1+MfrEk&N)m_QWszrd8kl=oAJe6FRjHZC=vG~Bt#d`I7V`zKk@LZEcJ$8m6>Q{YkL z&=LNYrjw}NkTv?zM-FsbCvpi@2q1 zKu>hPW4=V5dy!1xk<~i;f0rp%x93>A_O{%%M^dm+PjJ^iYmQ$kepKuv?yhrUSf^}5 zQ(qu6f%Z-~`Vq4eMHx2gnLdyg#+&^`y6F>cSsU*c?OkMg$CmZ3<*6(LTHkx{@BD7z zRy)rdp+;S=7xH%y$i+uT8BnR{eeYaw8_8W17Is$|zv^_yQT7Yp5Q!MI{Z;Kv2b{+A zdDEs>KkoVAiiz|=^|Rm`Z3wDp{+_axX+lC+as1XxZZl%vXiEzMoTg7|04}-p>q%Jg z^+I_r3tD2qF9Y?FA?9&PIKoi{H?Cj5URI3uMBpXD=WC&Ol}SYC{^?S6xt;g+DA}*h zsdJ-LvBZ9k$54-+7v+7{dNQt>A@7Aix?3U0ZNhh99}KSv{CJ(hU|Q2n_1pB2(!+#{aubUfleo?)$%u(kx3pMEJ2{?x}x| zo(tVF#C|}h!KH3G>Uk~x1A#tv14n#=fHxYvvpR&&=Zkyi`DBu_d$D}?^;qKMGS>t? zBp&%R=tdDK8k2s!(tOw6K8s{BO*0QV^Ql|_PmXE|=mlf-E3)%}xHH_T?HNR07 zFyeQf_9lBcj4$K`Uf!|R`+b4`As3x4Zbz7e*-GA;*b=FMsxYxBFiqT`*H|B_?|(&L zDI7`xbr0D=KlXwZ%kNLuvy=E_q3W=^2E1@UiL12WsOe@5Lx^=C7Z^I)aymh|} z(Vhq#Q|k8Dez;Sw-LukDzuo%sz14$TxxlWeMhl;D<_|8q-JYtoFkECwc=?Yv*@kQF z5pv-D`S}qS71^oBSVx#_)ZXsf@PUX3^EO4EBpu2jlm)&)Vx7yHQpkDIzaT~O?y>$a zwj50{Pm!AGsw9PQUDJ9$rCr>e&R&bI14Y*Ytt53j9X`amxH$S|&FXMJea)-9RR`L^ zK)v_cq;LP#UruwgQ_-;3b>*tTIPD|wk0D02Fz zr+{B0$Dg&@S^j#C{{A+5eY4fioyCn>w%2tF7ERXZYyB*CrPtN2jnKhrFi<@$lUB+O zMsQzfYj9A}1+nzJ?P>}4=`oK4mjtd%Aue?DTS0c&b<7qt-eMxCK(7lsQP)Pk?&z*< zb!wjb#dp$exe+aDu_a3GahWLmc4^*Ym*OF_47RJNijMh+Ad;z|32($1u9cOcC@D<6 z<8l?CwmVQ%gb}{=Qr*E6C**bd`~A1><<7Tdb>==3#X;gLi4TjXIO=o&Q5No z$*+g(lmEi`L!lfsc$|mRgoiE>@zIl_8Sh#y7PkETmnMqXT?~82w*3Q6`ht>|PHkS6 zu6O46cCT)fe0=&Q@|ozZk)C~Q2XxF9LM_tuYHD1xbu!f`vji2V%@Dy?5 z6yw7+;YI4Hzy7x?>5)xwhlbFK>7I^;HQ9%?k9%nFP;3=P$2~gAW5a)T9b|7WmOszI z4i%VYh+D@`cthjq-_@M+Ug<@_F_Y8lyj#!ycjOdz(o7WjVp*=%?|r6G#@r|>sWz=E z-ZE|#p*&t1zNheYjDBrV=N@iwOu>!#P*$(U*9xQx)Rba%g|i-|D+pZ%YCr=QI+DK=z1?)T0u}+u#6f=H_+uaE8*vkYgN|N>!Os z!&OH&?_6h2qNfcB^1bthyqA{Qp$MaeCe~q#Mo||NWqn+#GZX`Va35HuYsVEi6Te+j ztn|9#TcZw6z3|-{m)UB+-6Yy1N!RH+-Q&2E@}GZL)jm!< zx9|(Y&N(`xu(Hwpf(+{7-Qyn~8hrXzRl&WFNrFu!+OQs5{s(4^4tH&UTIQpXm0od0 z)i3EiwCbKTE(0Q0!MOa|2Cshm{%%fN?r=BbzsWX&4u;$Y51Mu53XW7eq^WoJkZk#c zHr9wyGB|mYU*;x?Vm!a$pjSTX|1lZ)YJDPj00(t$Yk8zQFe#D9LZTwEu zlWfFPhcSeQ0}4D*I?nMdP&A!pVHe%|livEbCtT5UfAcu@5uTQ({3KEXL-1ZNYBBLh z3a2oBCC>SlG3 zTUfOMJJ%#W-}u{q?GB>fP60NA!i){g&4S3LF+JXuwQ^ zha$jUu9!YMr1n5(gr52v;k(2d630^Km1Ng-c4-o3$1RH{$J^kbU3*f+(rSoCOBO2~$`p)Ku4bu6y4C6SHGS zM(vetF`wk*5U++T5x`FVaraw#T(0(QE%V2YN6^fLg5aQAjyw&7?ijZ0PrgPfnan*^ zO6;W-?#3;*JA^fGmom?23#+=GWS-TvIE7Rj>U;g>kAtXcL8)qGjoUUpnj|iXb?q@j z>^#jKWqb!)1na-luLAaSe%0(($*8Ulo%H99J?*+5nfN45eCq0oOc-dp#8VHHNml3; zcDFuN)hCSYt){Z1i&EPs@JA7mBqzO}tDc={jye!1VB_Fawif>HwW>z7OsD*{qsOkv zXEyq$n?aqo48h0ZB7zZFrg+Qk^-ohxcZv87%5dLedtqfAR5>0pf+;=gy$ZjlhrO?( zT6L(sINttL4XVS$W>jJhTu#mvRBx-e;K5TUrl_DwD*7pgwl3Xz*Mz2nv%pxI9ZcB< z<9SzPzwZy8A?mPAhNfRVA6AwohUB7&C{q%yiKy5-e*$^O7Fs9Orc4&R_Nl|S)_<)FTQqr zF1ISTyZE*~W~M9s!wb5w5ZDANv>7Vo6<8|P;<(f^u-CXh&aPU~l4stLqxsDB{Ac-( zAy?S}%wLO$!XVCslTPX8+P`KRAzo#+7(Uo4%c!vC58N8lzVhM6@|B@{6O&HyU4NHl zPlCWQx2TangT~qUyR)aZuZkP!#swlIG0PF3q9K{36ONmrU?Rb9SFUrt19-?cf0J|m znq{|AGes47EyGfqO*-q|5xR-G4!#yC2F=%KxH%;ga|~&Qj=@(k4^0LO?FJm!reqxu zg$Ym94)ltKYTjiK5KSmxD8D)^c!M|M^GMKydpoZ1mczLARiC z;fk$0I9F1Dj-jH7AGx^ciHZcH6`1TyIw|pQu=`!e&)DJWb$dy(OEk19CARv{*A`sE z4WIY?E{tGAv-^b3i zr}ScdDodmxw-wuWk?FMR?y~C6Rcbe|SKG8|3Iqa~8|zQBtn}S%Z;^4Kw-MAKGWQ#z zF3;+=2NRU~7o07GUfU9KBg>5BW(HXg(dRC3#?{e=taN!uNuf#%R>I&)rxN7mJdCB>lD9tzoa#McQ)ShA!S(|GD3bsKE&78;UD+r?^PR@)SMQ_K z$W}YKjw$z^G>oj3x5u)we#oV0e3W5v!%0tj#PeGn&@q}D!?XPU?{K08eL zyOJqtH41ygIFUVxeJ zgFawwKRh{^R<-zYmV$tJiIeGM^`B2F6Qu>HNwjt!#{3rQKbA8y6BdHBWqtg`P4l*A z@0Hr05P#H5#DnTb*3S30LSkaZmot5Rzd%K8uvee+AN-SmfB>47uJbT9`o^Q{!7_9# zHM4|0A3b{2+?)e?GRnGH33_vCoGUkP(`?;qUr=vwb8wsMUs~KECDhAz+s7AJqZFW{ z8_`YDBeo#kYz5Q;G$K(v@KAFErakf)Xb2*UV9?YPU=vVFhU$1Akh2`5T6P4A0F54- zW|sHvcN7esT-0areK^4IQ)Pa%dM-mN$+*S@_+3y8@h}VOcK#*R>2iV-*tm1MND{WsnTJe79CS z;R{(`nVayTdvu;eUuDA4hiP`Eq+4$L_uY#e2fdx-{bHbI#0=+k0-;=t-Y|Cc>FTOQ zqjU^}3O0Z=2)+o~fs;^_Csq{J1eiHcF782nbD_cZF7(nsqD}F6Q3WU_eD4eiLJ>EM zx}Ab(z`)%x7!QU~R#1O~2*7y**1w~p0|*u$+SoM0+%IZ|7M>sY=K&d_j7VewRv|*# zJ^;*zL4Oyzc21{PwdiTNxjz7?PNWDFJV1xw1GxM0a>sA^oX9UL!!k_ZOiOSo^*nPL17=yw2* z0>S~T2z16z!Av|FLBIn5HV&wf`0^2+w3fgm@IUqifJ+Do34s*YWv%gX_p zRl&1c6>Qn#4F{L_zALSxUX3Ars#z{3PW*RT?#9)_tg%=wmPwJA9cH)O= z_BZk-uP8tV;P2ta9~b}zU7ymjva}zAcM#uZXTQ+@_Lr8;Pau*6*b0m#fi#2j!-sh& zbuztugHV{eh891aZ15>+)*BtY^G_#GuswYE@PNmJ<`o`3{y-ij6;*0!gCHDTkf=L^ zjZ8{P3c75@p%*wnH3HMZ=EvV){K0qi3puLKaYN0;68D7?Q=xMkTSrvhuVtZIufArl z#5^Du%P|PM+G6$_zg4^S>Ry7~fFF+taf}j%!mDqyVn3^NI8yrUS}882aWNv))4kqW zP*j(Zhrn}z;6{3OwyV3ljNNAmY74XzBF*AdPl2g_$$YQ{N2S60KexxNQj{{sGOU&azXrVOm z=9cTiZ?piWiSg<+H+OpV^~4kVXSJu>eLb3v!s3a6yP>_wbTZSK)mLUOdu*JYnLc^u z46M4?GASYUCyY7*;m*b5%}q^F6#=QtWR)T8Ulz3kXg+`uG2XeWkMqD6N5{k@BPC@54AnuHmZoN@Gn}~Vj8WDm z&{Bgz`C<8tSvKt#=N8Oj8R=Ovg9llg!AwWrp-(m!o{~wS2LQvZ?W`{J!>cF+0+7MMdjPFTb&F#wv^SUr zjw?{UXxQF>!6RZt@pzDAN#nHu9m;3e*EwG$Mlh~DvQ!w%ltU7em)U&YTU_$6ix*i#8SGA*+)g!ReMoz$d!mvG0A~=m#Z_x&H1V`ZIg>j&qYH0QP-+FuS0o&lb$kV_hwQPG<8`YwQ(6a7U zGKYpJ*+>-Wj&eR^b|WOGjr|%ox807TG8DOoi--3wFsiY={VzP=N&?uyc|e^&m@y2K zZz$EK_S*EjL{Tv@YNj64U?>BOF=_j_)uLFU4`0m&-+j&F4?R@s%d3gz3$wAl66xFN zQs7IW`wPsVD(I(EVXaJ8#{73WxG-hdmt~Q6=F8jgYP#yzhavhkTA0+iOJ?8<`vS;^ z>R!G2=Unq&tJD;DTtHMd0J^sxtcrjp0dU+~#b+V`l9elVnIDO9C)czLK|b_WK<(Y6 z5;Liq$)s>>VDXTZl|ATuNlQ=;mLCtR+o7rYg1#=K+^l74*J;zY*>3VLS>LU+AdRcf z+`KcVw)}Pq1&EN4knws-st^}d4!Ls(s{7e=InqbWC!Gc08A&LkA@nJRMX9T+1LGSPA8+)7oKaz2fo;MWP*fmrH#P<; zz?&NzreZ-r!<^NXN9vpa>83f?-U{Y2!wSOC`J^d`J5*Xd9hLOno3I1Xi%Zuc3` zvV5eD87vL!WIC5&?P*I6@~cJP=4|@My(VA-^d_Od_11t@zH-TxX;UB+}L~4rOIe}`_OqZsB^&E6E3|#&m_P>TO}eJc!}K|^!_GDY6BCKzJ*0jULL5lo;R+ZpPye|UVe^}TRuu%dRnh=n|!Dcv^FGm8WETp+WRmZ_iYhpB7s|SoEdW!GPx?bFTWs&Ie&OAu>ia$cp=n_Et6{8eE zlm)vFpx|J$f!zu~e`cLEGoZ@y+GF7o7*x`E0h(DIJoXLz1?XFzou5-vQo=9&9z>Fo zlJJ7m7qmjhbuaya8VBfKuL6C$)q!0VMVJY3F9eb(E@A*47$zYE$kPs7A@0u2kLE0U znfKU;C@IBk1f=E;2csWy)5c8(-F!pc94M>En;RW7{Hxl7nyrV^2QQk>f9;^UI5x5c z>$-s!ez~IU%eI6MV60M8QVd#+%O3(oCkluG_EPw)3<(nCZeT7!Rk$TVp_R$tW7yeY zj!+LHC)M8EyI^^_@84`YO2aW>Pv~g!AnjfL4F$Zu#sR3o<-I+6Dyjg$M3&j=;;Kd= z15-5XCG^Qs^7fl2cX*0xa&to?51i$LbXj7?p(?2e94JQh4|dkp%B-%JO^tSna;N~h z%#VKfenw_!?MA?0-es*h5m>=V99#|6oTx8^^2FdF;La@_KcKi_&Hb)T-epVXG)d6( ze2J*`6^M}xk#^OyJ|<4M{y>vv=;Q{&D>L15x+gB&OX;8aQFYg70L=89a>H%`uK?sP z;ItL4U!H1$bNI+nG`PaTbAVeUl0EVQBUUOp{5^M7KPliz?A3TJ@4wX~c&7$)$= z_VrmX84V_9zyrv_?SL2!o(YUUC;+4qs)z%~97NrK$q;g>KR%Y@z&VQA3Q$`xkT!F5 zbp_aOz?CCV-&Gozi6-jfD>!C;(G|uCRSo>E&dNhl*SawO&8LIPxaa8WH7g=Z9rd4r z&?OdOWn&E}J^RwBo?q(GTl;PfH+~s%)8qYp;@BRbu7;xmNmFuty$58A5T^|}H2pa^ z2!$&HO8^*tpu>Ie0Ht*av{*p;c^_t_!Ex9-I(mT10$dE_CuJN}A8AZYOa^nM#5g$C zA>dt2$Hv5jdk-Twx&$^GU>!0E?S~K_Fj>@M4{Np^>&aL?sw3>3<`+J84kwXp%JI7E zx7O~sWa!_R5Gc~S5d#(PKry*_+2do2$*qw7XvdBov63-4*dij%V=F+^Wol{)k;1_~ z2_$k}Aa3cuUj$S2kjDf9TYM;`l;$|tI-nhT`;TH7f^-O+B|+sdN(VeWkYnxF@&g!t z{FQY#h$^I5&VWo_{oYNZj6fbXHV1ey@LvrkDfLyO$nDdLl-Y6b_LQlJTRt57;BKIw zp@}}BpqH5O>2uZe^%irvHxDkp2O4(deFO#iZxE8h8v;yrp^k|!sn!GUIbeH)`Uyl0 zyjMwpk55!JFyibT9c^%%J#Q>3PF>pfhp6pAvy(0qC%!2*nEdn6HfS)hI6j4X3M3da zAPWmFx#}+`cZAaEQ?awdy=P4-4vsk|;u7xYwF3;uY;4^ql5Q<&_<0NcO-@VHojO!3@LmmdBCI?9>sBAvlyXXs-F32-zI5|}W zH?qG4ZZVu>I;JR?9Dvn+Mx?H#wfn8<7rb2Zz1b>+YE=FY)v`Q#wN3T1=&MIkpTtHo z7As#}(xSB>?)KKaG_DYa2;5M%-FBg0Gy%mxapqRwj!0&zqAt{Pm z8Ity)!9l1ZfsSWJgh$`cN06GbY3F?h0jjek$RNU8S7G=c2t}LS=ca~+c%`Lj87Dv< z5*L>|mARNAP?+VOCB~r=T;M&btSh;J0PSW>3$~OwGgU#vX`1kLdo1fsOh} zUs&_o{Rs&4ifsV}BG|+FEUL!F)4*ZP-B{M>EkoQ(u7gcj>OJ_SbNb&@bEqxti!MLc zn@=PolSZGz00vo7YO09c=a-=D2}>hMo^GV41{ny`YPt=aeeP{_yiPkAd zMkNCeua`D}5X8;&`X-c;B?fwUbR-A}sA*}XsT-Q!RJ%#|^fcII`Spy7w#|HVm?W>2 zoq4+vYC(Dv5eggrxniOJ{HKhg3F+$=2iP^UQc_b5<4$%Ky5wSekTEfdavi~EjX?Lx z#CN#A@A>%g=J&Tv0P4f}#X421q{@8wD>o@U`#}b-<+82DO}s3d!OFI35;Pw|73=5t zCkUS(KwEAv2+Urf+jD0S~+4KC%*QcGUubG;xmGsgb-LtTzux+H_!t& zdtmASuL$C4K6A)vCCHQPLFpF~YC2k4*u;=qve)y#&{{vlYA@)drevZ+wYsXwpWOg!RpOj@cLc$7Wp(dW%CFvKT>& zv+g3Nr>LfpQbz@IL-D$+a+f?5+%Q-+H)qb33c@or7HrvGi^SapbRtRJiI+s|6E*vN-)1aPw2IpT?#nQBCz zU>6cALfsOW3&D`l3)p-D=I&9bFdP)$;6wti$RIeVw-$9kCafAX7>|CZ+H->#xsrLmf0<>kLeS^g=;&{D9aSs*+mFRf(p{L7$w-VZf9uKnC0}(?M zJO&OWAS@014e*H)Gpj%?*&VtmP%*RL0y7K02YhcG)^7$q<*2@8#wa+NZvgcBGL40Tq)S|RvD8vA&?bdkzi}15oF^z4HmY@Zbn4!l zMi^E&yG{{HPDu$y=zhtgQFq$Df%LOW0xz#WaF#g0$~VgrBTFUzMzo*a?o?gS6a!6GBm0f!Kp6guARQ~ex7`5lz2w6U${Pa9<^Y^6@3s^!th zJ{8R%2hp(66h8wYGdOg3Wwcs9wtXs6WB8@HSl1R#RlfBGmSHZ<8(rQHRKUTI=j6$9 zclc;4iBmvl!jsn2Bs8vDktoXgQIFFHG;#kaho`>O_=e;yo7mb|8}imcbD~EUA&~r{ zFe8MfXqJe;wE6ZnY~f&GrFE5>6ia!@0qg#G%XW7-fd`s_zOLtur~M}U0(@wQ!r2_e z8Pma1tskaGlZ976pc~@?fe@Y5k0yZ^&(R9XkVs5Hiw*Qtv7EypWAZ-MpD9`C&b`C@Ko8G_r$+-@lz#TnSG2(R5@&V~FYyEmdC(o4cDYyM=5d}}M! zCR#9$-NnIjsXHkFeNagt6Ws^<@|n&pZDqE0MC6cZIzj7}^*EvQ7l58s?=)Ztip{8qd!q__cQ30f?xk1fvz58d7o z_1)n7s1~KqBSVE-K7(QJ%;5EtQ6}f|vAcoi7}uH(new=B>C=rU7B#$XRo?HZ_JUNJ zM6($Pdp%B85)!i{1Wn*u%b=?$fR9x0PUIoleVw_T7mCLED_kVthQ^!oC@9z{{;$XJ z=7~{$9Eo(TbH87sV7BC2G05q3%$*ka2++{b3KU-=uA!l=3#&%KzjY_)8V6DjK=~Y?kR}K=2C~dq6H-1InfnYxPPQvRoXta_LBk9p z3|GH@MvAID_-`V|(Z)v4`fY4%EExITk56o0r9FYWb9szsBdi$~hTj7*CRyJ;&T=bg zC`Bn2!pKn7ys|BbrE?$~U%j%DBr1j3wMXJP^?uK1`GkbV!EcO=yxfpaNz2M|adz%s zHLBqe^8dXEtiw(`c;Z;DH~x3?1zehQ(!V&sS5W?NNTNw4}(PJuS+K9 zpOt=6pmi@R)*;gz2mke>*_kw<&sLIx^(6}xIk~-qgXsT;OKGM3Uryzf@t>)A-@7*m z5l5a}m@Ei_mocB?#VZVTkfs%fT^H=b{En6Q7VUT@=uB zyte>~e<%%mNC^1pVo6|NvQ!U@Yc}{HPBNTTKcn6R`eAPioJ<%PgsIWG);6N`nxO^2gAsYienUi;J_D zBvJ-}LD=>{kG}fr7rjj2#N?!ioLqhpN7-^!R`A!iuvb3kKb&o@gb;Etx`ZJBe;CRL zW5T>d2ne$vk;W>EL_Hxs>In@V<5le=LB^!CWf}T5MU}k^o(fp zGM^`dvDgt<9mw&8=q6APONn~eEL$CXs`F&{1Lzh3?;HpyLCcEAveP1Duhb0U5>OCN zc>eq|oa^CXzS}@?z*L$m7xtk2;RGKH)IpF7E5ktKy*(oU8YLUg$(V=`FXG~WkY0V< z8+62=$py8*OoB}zaV#o~z5<7e6-onJCJC z#`6?ZH`&9(1GbN%np!`+FCJdrt;uRghQ&cB%3BH9_IMQu!ic%Kxo_W|!3l7k3nl1d z(Eon}CdwJ0L^;3BQ)}v}6eHj?%hr9|E2LeNfTK5;7CqZ-aFnGH9xvXXHWLD%HnVOSs=>w@%D{*dKhjEHfV`@_Me& z;`MCi$C;^%t&Ks}E4?lObT~nDMr5_Qc>n#2I`YTJm3YGT_V(w`pU>1gIf)ynst)~| z^LKJ`YW3LEUnRviuhP}2FjiGnEh{eO;^LaBu}R{s|Is|>cf!WPvfdVW+1A#U+K3!e zDqc=~xyYu*px*K3&70diq0%FxqwlM$(>cvLJ|(kgKYTdda=x~<#-daHIz9d5<3x%FWLRVvS8H5nP1 z+>4UpVvR?SQe3^_%kQ6W;duYsDl0E1K<;sHJWx=Gh>mV@{rPF{_b?wX?{vej#l^+$ zXbSWNVt3rW9|j*p;$Kiuz;4_uC@82)PsGg3Oh6;r0B_>J+Ar|I^`{a%)YZT2EcM>R z591Y3tuyb&70zU*!SVjPlJoZM+c$5%+|HL?j*z6A-#a28AXsk1(kNcJO@NZxrNDVX zE%Iw&;gSU7-MiOr@o#j76M7$POue^?UgkgkyE>L)IW|5X8x@sk$VHi)l7fZ27WHz) zmTR}B5^~MUjSlEb`qO&hH}Y1N+6Xt#E}>OYVdA6rzgoL*<$Be>eth)iBw7?aU+4^9 zUS3{YG}qSFe(+!zejLr3oRwv4V6eWp2$#3LF;)E_TfDfa=5?WndMFMtrT~URpsi`?Rx3h;IC@E>`=+xKOGdd*< z|CaDSKZWJI5%zR_V(8m99Yw|BRFv=Op@x){Szr9^xVX5X4L>h0FGojq{1EuNl9QjG ze|mbFiHV7dptrL#ST6Vak(a2ktLuAM_{>ad6{dUl?y<9nMbp#McXf4{-k7L6|ZPV@bVBVxHS{A|f->)6Y*2cWi8I zSjh**$CK3xW-X!!SM&P|X?S$P0XfSs*vT_tjKbflr7(cRq*%N>k$ zZEd3L)=?|mEbPLsU%#-huwV~HMn*(wD&TzI55vDMB>m>yyLZ2bvtOm8z-fS!KRG&@ zcxs}{RaRE^)ZLw!nAo`0Z)j;P-fJY|NzD6C%{w-hN|!o#lN=b8|D?kBEo} zWFxo_2A4+YiU>a2XlVZw0t?o~_-JG*tb)o9Vt zPoF=RzkBEI?*33iBQi2lQAMT8MUfH$n!ayW1&d>VOy)Vu`Dj4$e@OU5pWfFRkolT3-2@9uD1r|MA`!$rFek84yA$Z$3 zao`olk|4qThuYd?LJ~25EqdebYMK^ix&8jEn$92FoEQ**1WHO8*A*2hG~n-+ZI%)t6Eo4n)$%hN-FqHc&B%A%Ta5nfd&9z2ZjLb+0&T5iA6UkkI7gbG{={ zZqv2^c#?Gs$vp-Jxn&Unety5xLoT5gRaI4qiKFQPP7zAt_LH1cy}rJ_mk>w*PoF&t zUxk2hPLQ}b)lycDZl3l#JO26eXM)avDW{66YPP7Cv?$3neEd_}!0S}Kg%7d`ki(@H z5|n3uR>ul2A@H6I**D=?K}(*nb6<?Y!sn;d6_kv8~52&4y=!Sd5%g%9AOB4o6+$0755XlOu?21E99C%!+kP4$OyDj9;; z5$8WYK3aR!y?;+^eTVZ#3?$q5QpVG(?1l}TuFDE219&Z@QUYYM&f(TkmN)|gR__kf z8vy}TO|^B7#XphSc$k(Rj8?{kv6EKNr{PxNl5|@(=xduFJHcd z|BJBaB+@r9fLOnPQwF(1!soCOl31v8V7Nx^?%p1)*mGXnulJBPI3K2pQPI&mPWT}c zkitAXDA)}nUc6{^UnR!Jmw!QX_x%6cBXx9BA>kN)qfAS<8m^wPSx zxIhetJzJJI-M+77g7fnA>mo=i@7^`rj1>qt{h+^lcXOux0n{fwy(3s28GZ{33*k&h zb93SwH#|3|YbPfs0iG;fU`gZQMN0)^88tZHhN6K&Vf60w^(o+nzAZ2JTkcDMa?tFx zXT7`Jk0A2$^1G>V?WRSgrFM399J-bBus-mFQ%Fx~9Gn=n^hEl)x;JjzfLjz07C!!* zDWa#RckS9WadB}ZfXkvs)aQ^Ba?Qc!%(l?kM43Tk_ulUA-~Ihn_v0us7Go#}aIHy< z57t&!HHyDJ9?s%3;XJ&5a(MW?#a9Gg2&t&jtqpQ>r09Q(k^cI1hN#yrEGXP^2%GRN zetWw2J4ZeZ?^;_gg0TrTwY1O~DSO|3x+by@>vB$LsBFFCENmP3ty|tlyFURwZEV;> zMitIHpK)rnvb4<0&v%%5FAJ$8%hHst%Z1AC_Rh}E^2dA3%;uao$jQl3-x@6U_xHuT z4=|A!T8ZP2CD*)V8#6y(pltq2l{L;Y;O7jc!9lwT*h}XRzq<_ z5c1)}2e^!(3@R@CV6zv39Oyj+jIn!#I&KMy%{D@2LMVhrDTg~2h@`V~r2_wsBu+&P z)DxM{Sm6ROG-7EAfq|86RAT(mnWzRvUY5ygdz9g_)RQ2fp`~SEZ~yM?Tj_`QZ{WcDqb5A4)hE&&hyBf&SFjmh1_$2(0!fut3Oc>g(VxV~pAE=a>t0w{StV3!KY9f4XJplV z@n2Y=dS3D`z`e0q#j-VGMCX6U9xU5q1O})T&P+}cF+rk2kloFf4dhtTy85om0j5nX zJJ;GIZx9jDB@RtYq^K3{9i0|LT?z-F&=7Gk(AFlYrIi%%lar{$?@XWm7JdlSDF()l zxsK1D)s{7pth@cM#5su|Hw$P>=P_|Uf_PXxuV_6##=8(8IzB#*VjZtAk=O}CQT6JS z8(u{MVx8>y4Wy)`l$DiFl|IkRqyu2%z?8+r!oomI?JiA00`Fra_tei8c~-8#ucf60 z_xRT6y0Oql-;+mh0oLCtOv3#;BySKCqY{TECtpkFL}YB?;^E0+nECpOiB3oI#Hin^ zdH??H*y@!lS5!Bd&i{DbZ!X|4Y9vLr=i4tIGUA8WO}x9_k9B#WNF!Hfbipm^*`FT? zBtldK%?Wpd#PCCA>KyC}LWoiRnO5Z{t!h4XH8mN~c^&Vs@BjU4`l(c>0wQw{YG!k@ zC_(uBWmXOj3O&N+xmQK+(GPA12ZtL9IDi-G>gxLY`ymXv+>{W+-jBYGaS-rgB70%q z5<~_po4kE}T^+xOh=HEohodYJw!cSvj}gSH;? z2^zWU&}bou>5YT22NIE|(Q>&^Xdde5bgp5;krrsAN$9+6eBaa4Gs1m*btD&i$0P_E zr?N7K+)~*V+uL2Yb&Cx6RblK6gcubbD(MapIqB zFI-Mm3bhF8zX&3$K3cpk<9A0qJ3A{&Eq5d$d@CN7wz`_fzJP)7bwWp~UIv8A%F2_& zFJyJeNf%F-dSZ*U3YqWSi@CvN4n?*r;Tc@kWMM)~L}sFvjt(|LCo#ovgOZYgk+E8r z)%C3cEwkt6?z<98frsvx51ErE9UUClkhZ?QqLI%|b0x)pFbg7lZZBFCwH{}}@?J*Z z(_hd^u%Da2{?fdVKP}G7!|ctAA`uczW3Fpy5f7EV&Qw=k?%3p`6Cs!|m*3KoHSklj z_$ySksK*d`J)HQb-Va|UC-Xgh$P15J*@lgu1Fvowsnh3=lwh8VnM0cu-ThYm-uBib z9|sh6UEgQd4~9s9!ZS8=Jy$wRBqSsRfbt2f7$;E&HQ;;~i>AX1sAQNJmy(qnYA9%S ztoXH?3q}`6+yUeyjPV`*(>KXGR#+HhRXfMX2@4B5+`&Ern27{H8`8P%{sgjZEKQdt z^58ur+Qo~Ye+CZOm~WW2WmsM3-%o8kdWUW~E-eM% z)8c<&oM%)>_JlXBq=flJuLXB%*=rYd$TLd$#Mg2#GrkHdRo2u{ahZ1kG$bJ=j){#$ zmvVVl-fBNc$IQtkZ{DbDYL3PQCz=(ue)^o#=qvT5X|RU&y@*ny&A zVn;sWr?=A<*VaCnauSn}^uJKnZ}CGUy;TiXR#%xwap#)7#-gl}U%oUnG=z_lDH#Tk zKR@&~B0io7X@k?NmMPr*dk=u*FyQ-xC&TRl(qONtSx|4=&H>gOJA=HttQLJ%*@QlfbcN;qor_?Q3zF0o$kt z8~{l9w*;aDoI2!$kbtzbX=r3V7&_+eJ>c_y*tQ=Y9v)3Q12}Q0rkKCF4w|;{Z{L8; z>Rj;IUvv1J0k47jO~R)^NA%95wPj>5S1$H_O^qn9A^@^(;P(JRZP6Ef{TPS`A90gq zld^IV1Q9%!S?2ZpyD|cM9e5c#N~K`r_HuGO{i%z{bgm?rClbI0AeDLdlvtwaH`i zctS~87kX}>mmKF>#C#67wM!oX+y+>G)B2x|K%emC%NNKR@YHE| z?^mx13k#v6)iy9lr|Q>_lg>eRB(P3+6zr_b%#>W_GG1OsP=W!y0%Z~$96V!epZ7E< zIJm;7=>TpLT39xNI(&~CpFe;0gCYo*35A@DjO-EubPJGCKR&oUmXqs&-VRpx5yW(A zDlnLO`udb4Bx7HX;daEJ_yP|8w=v~5UZTCVwG|Z=H8nK_Wy1e#U&r2_mFt0)GUk;l zMjxN=w+CaxI$ynZ4FFZX`aO6W@F@@;eZ#{}E&Y%}|BmJ>U!3kefWy7;Bn0SC2o4sO z(u@qM1b#2d*t#bpZ?pZ+KNJ*Le|pKJy3cV3@9NbLa1+2#KpWX|vL!-6L6M{WIw@%n z?k*xC0+x7!@1(-`|N4mF=rkz}j{8yO}}1-to*lf-pPaa!{TZbY{?V*640bVLuPxOoje};iC-Ai18?15_Ta2wg! z6a(}c=`JWLiWvBrmYy!KFWHcjlhe?kOGoqsy0W!33~z(=1Q@00jH8C-CdiGpqhIz3p`^z0jzK!DCLc&B=Hnf2s-Nl!ehuweCj|U8*`3;62B0z(l zK#~E1uCcMv(a~{nSTI!DOi}Ubi(V~F%^>PpXrnzvvtnbf2{CtS15ff^m-Wt_Txjbf z-2+O>%GfwKzKx7rU%jKFtJ}AKYnc z(4z0|+VVaIKnFz)@-8q_gF{0=+utTmO6xGMGB-CjP3Gn2KiJ-;t6xP!)`t(<_7Jb) zprD}ROH zUA?{X%jq0!Y-K=hb8%fyjncziW+Fm?oP#2u608IT1A5{pLV~M!c#y5t#G zN}{-jepX*B6l@WZrc0NxZrr>HA2s{Y`x$i8ko<4o4t$amSYJph?(EdtL$vT>^CH=tgLF;;;MdXE>J50Qd~wLI-sPflb$lW%SX`Rpah($ z!v9pkA=Xh>cXoAMgM+J39|?UKv|w;HfjvG<7q0ct`|pzIjP!rsRDXe1q{;#?ZU@of zjOOP^!rKJ7+x+hnC~-sJw+gSq{`c4Yc67_GA4HyQkt*8H>3pf>5UjP6fAv=J{ponW z>r`7S2koClU{Si~LRbeRGGZ=l-y1fo9aVp_ql112&5J3Rum5Ocr^X0;Gwvjnh@p4B zroY3jU3?ukG`5ALwiI~cn3xz+#g{w5O4h;G!pz?L3=ZrLe_Gnn-+k`vvP+3`9aD-Z z&*;tn`!fG8cQN{0mTJ2tXmliBk_Zz)h*_AtHYV^1Wdn(%^#8ozI4lz-#krohbd{5n zF)XFmQPnrE-rGiaq9^tiaG2jl@}FR4^aM#K^eFN`X%46Li|+`FpHcC7Q6HnGj>2P5 zc^#jfJ%@f;nAyXUmyVY^Iy*r&xGGqzYJ$(r zqfQbBsRY*O;9zS-)BQCB4w^qkzfqHlPY6?J91REWKxgNDEv@QYzolK;W3TL#o_RNC_y%l9{uOegXB*(F(gmq_}u;ET|Muq?F zZjbybG9r}{)@=GtfI*5gb3J>wm-Ah&a-c%zE6NN;Oh@5+M4!r`U(I(kCuJQ{2P#}k41s-Gy zCujJ>yE@Cgc4{nba{Eni3L;7cke0n&T`KAPW!FrQQB^nJ3sjYPy)(5AbAYr6n^&T(WA>)_yMWInIextbXr=vZ>$Yc^TUTP z>*@{w-WFGY(Q}HJpK%X6Y*3O zTrcSTt!ABAsJiP06xj@N1_rl&d>{r9HC2V7*+-6kQ$zfhg@T5KySq?h7W7+iR4k#0(4f522s)3Qw?C#HjxsTrR#|z~7J_o*PIqw`|Q`cl=b@?oK8y z%EuRuxVfK z>3l0QsE1wz^uZ(rDgnog*49=9wcU3|f^p#?A<(PMwfeVqH$~Ub5VQsRoIWNb#c2)9 zzFB)xA-RHdc>^B{k<`#|fuaNu;RkenuxrQ9KC#G0cBWgm^;^AK4~iuTU!FL1e&GG-Y#hV3nG)#w?FYNI=OLMDM?AS zPgYszz!}4@hjt!-BVE>>p%%G*M$dp)%W>wC4|Qf1`d+Fpi{_0Flfc`31$m?UxE1Fi>9- z@}U`n2w)(^b)iDzqC++#Ehr3-%At{qdqbfo7glr6Gvi|3bzX|+7ml=f{ zNsUO~y+9E5SKg4eP_sQfJp%)F;8wvSXC=DoBrGfpZE%q48&>jl=#-$_WBZ;_Te}ZQ z&n!OJxY_fzF|8RE`zsO0?}7#fGk4_U-h6&b{FLvOmPNop<}ZpX9dciu@Cs)VAg{Tt zaKk%YTwPtCJ_W^q;kO>Beo6g?HBYW5NEeQo<^F`U1IGj^5m3cIdq5oPx2%Gq@%r`a z8hXa?&Z#O3d1>jOxHy7PI4Sqgo}Htx_=yjlU2-|tA)~T|W1#jRrrl9w=tdqIeQ18g zL`D0&$T^HN;Pg>ZsTkv8*xruq3bbo@^r_ywUVNuHV=InTU;Se z2E0E`5#|5#*I=EugVWOu0Juv@1y)sYQEjT3a;L)DFP~5Ph|~H37zdXUGaK9ZmoIcQ zzn!LQii?L5Xg$E)^lf~+HZLBEv;4jWZuw&ieC8WA6Q7?FUFoRc;o~DyoPwMH|4oz| z&8YNpGR1Vs=WP&>{Nu^x{&LN%H)m`W99PR|A$ktDhn10B&^GO@rTzweS3|H(?J(+U zvCC#TWC2)S6V7Y_M-T+~Gj}PX;>OOd!kM=-QmMH)IWBv@RLv3bQ9apT=I+cl97fL3 zpFeR3g}0kTk2M8yl}|&2ySU+{2=s7S_f~yT=w}a*O7a9usFpIBe%B zEmFun-n=k`69{AoDiW@3D5ml5-rkf$r+=j-)?6I*L?T{z?jk`O$;M%=C2c#jdM|^SPl(j+c=XHiLun zGjHl+B`?9E5e+gk{XNO}6q9QbPAS~+wA#fr@PCh~DLrLnJU=yM<#a$-8Qe8FIhPP35|aBZE-_J2s9z;?AX8gH$^&B{ zAmC6YaC||DMjM;pq;;Dd@Y;;#LB960^IvakgF=lxJu~wFz!WqAAZK3u@|Dxa!k#y# z5tqXtWQ;F>zPMfZiM_qOgTv~~vzF)kQOz_| zy~7zofKW1k2?Y6~ql@uDmW-SnfCg?(PW4l(2T(Z)2nj2|YE*y$g$LNc&XExpXlsDs z0q$JzyuLg4>&~Nj<0n>v+0tk!3f&w&F$b3d~q~jx0u7rJ%c8|y-FENo=u$n!( zTfg3s`bBTLm^Xi@v|g*<8Qd9yfDj8;$oQ6;l$`tkP&?XeDJJGS-xdhy54Zrh7f~>+ zsG}e8Sy@?qVb2dXQeVBQhs_#F7f2f8Flm>Ex%txh^M|eb9l-DX{e&Kl!cA$Y_%}E=LM}l z=-0rT($Z$br2%9I!y>R5k?yoWB>aPDm~TD=u6|)*0d^5wNTD5Q4*(y9J~T%VYp`|F zGBTgOaCFTYtY37$bp zuVf`Cgnp+xyu3fsr{})i{R!~R{5U3mQ}i4zab2N!YSMyB17GwPI%<4 zA3@>P{_xh-Iuno2k_zAWCQKSH_sSObI$(qr+3YNxa zd2z+cz}mjIR8&=st*H0|K}EUwIjUxsnxUoenaBg{k*D`Q960b+@RPWLygp`yN>O8vNfp^UWt0;i|Wmy1IT=;hwKBH+Y8WlkhT($7A zvBMz|!$M_>h7P^ctH#6#1R$58#o1MmpTEB~I|F2I^De4v+b+mCn6dT@n=sM+Gc^5g zR%<#Br`Eq!fGSpy2kO8};Qt^B+WPOv0sMke2yj78My46GcS|OS_oyh`!w>J@Ys$-G z`<<`#MP0!o-vGyhD7&Dj=qX?V)YQi2WM9;XUV~qUlZa*l6$w!IKMZATYz!PX5OKjy>vvaHRsiEpPwOAPr+4)|U4w*Q zXYbnEp@N_tYGAWdhE}*MC@@Y}O_Z^^apZnp^n~^7g13}dgNg$@7 zF{TfT2m;2Rlk@T8$H2wUp+%RmA1Kv^&Mx^hjn$%Z_ZpxM1zq%wjHrDI=`796Mj(?4 zx&30*twcU6DSa6o-QC#<9NT`Rt(__E`y46&;HUijpTGtXQVYxEiGr%tEZ)I$A52xY zw#+@5Os=-cN424mw5Uoxzt(T15{_0KMnt=7Jd#7~}*- zK|x^UUW=~QH8u)2_k6E33kI$h=*QYxJ|8(8#FX=fYHXJ}fUYzZkoeZXZ1O{0YhL6v zxE5n$VnjtnfpV&}>`&z1;2q7IQL$%zE;;D}zckxhD$ykK}`ONj@1JKS`4Mc?AS06oF^m|M#!;*&pK*$I^m= zuz{aZ^icGGnf*_@e(3A_@lbO!u6GI0WTF<@(G9!fWb^>U@e{I=OlW2az6*!Hu*+~L zTIM@936un3Hs1iH=e|0c4@R{}`VOpqxWI$iN3yb4vWF=YzeB?U`8i#$1kfDlwN8qZ zvr!7#`gQhGkn~z??n>uWf>Fk3U_2|&tNg|p;e~Eg<#>!RK*7_c9-?oj~ zu=G=H^V?9mAK#F5<`SU@D`*T6$+1~cJBT!=O0D^Zj{8dpHxA07mBEz7$cA~eQR_Z%m}&0Ok+Ib>8bnfg%+=)nnh~LbiX5Vf zw#vZ5!y1D>$?e%QCwKPMFJIJwHv130Q0%gV0|xlDvGJ~;fZut(?cF=pt7L>y`Y3J+ zT8`9jEehbrf=u%b9^>Pnt?`AKEqX!ue(dB_0k1IcihwzR*9`!Hz$pxG2@z+$mAtlQ zYmf+Xl7iENcy@a`RNY`|0eiQOzfwsepb9sLC$L=s{?;l`xt{$B1mZI={=tu+bV12F zJ3RtPY~ZIFv}TZ5;OBrU?!Q=!CwSS}q5Q#JCoBw+TrIQk83M;%h4>sDv_hVw>05T!q z0ATI_!HyNEUPeMfLs!?=A6r^ZPSv`nNFxF7-@8gmw&{R7u?u|L^FDJ5w`K>sd-ar@ zJG>R)+`EH7Rb0&UU-JVIP8?|riQB`?Ex6*v56A}j`Jhx32L`q~wVq+|fHvCG-hP{l zE5Xw%C^lBLbRhTLJ9{gu@njQ{;RR+%g%xhEG;tIM?UzSc|5-e zuUXqt)Vo&wnO(Mjy9tmdBrL3B7^0~w!JN>+2^VDo4dEoRomrc1Zp}uXDi}gTl1@477_!8nT> z44Lmi{D+7C7zzkgVrG?@_F{v)=8+PtPfgsR#+0Jur5{xBLZt<7vk4`%o8Dt$Qfvr_ zh0jC%x*R-?-Rt7Y2ZsdJ>h~Zo%0(~(vP>x4=6vDXx30jTL3lt11G5~~&|ahd44_Yj zNsCXa=Y76dx#*afzq`AMQ^yL0W2^3s?ijbzht3O5Z-jxbS}yy~CydA}7C+TD!!;O6 zJ~YvDY26ssLE-t+-Q{Wnc^^QSXvS2=5;p19|IKVcbyZ7SY7GK79MvHyz*XCvW10b^xDl z{iFP@71Wb1?{OGAfDM-Uyg&3+mF9(jSqCP>>S9$W;9s9_1(A{cU?Bkn0jZ2K6Q>>; zw7|eX8ID^DDeHHVm9#Z95{CExfL%{je;ijA=cm>1%u7Ced+B6zC-y_YdCUaR~{?F?YQ^;+S7v#J#-pR zyRIG5w5tABW$xn;@OGwT zUkB4#s;}I=$n0b`r0&(xaPOBH!A!HLmfB)0@tpjF)$?s7vY}GH-xpq{~ z9|2>@owwGbVvsc3uM5qWK z#qy51WDB>Z{zoebWutTo;SCAF{h!^uF;~0l7|iXyKl#MXUwE_RR6!?vVV?c@5@wKs z@$+lvHADu>_uO3Mf8mDEX&$`C6nK=QTZ+D>#M(Po4c26|l0LRfaeD+u(P@VNqL3wG z>U+H8|J&3?%Zda4t%x*cx=axB zTKkbZtIhiuIV#Y?-EF?PeK~!LgK{|$$1R*zSAA$%Qx38){JeUHX`+anE&_9Wx1F|l z(pF%q?8$orZp?(5;c>xe!slxPE85IK?gXv=J*R_39+dA5Ml5T($))nInWIBrIq&#| zaT`fomnq-js{DP&!>m$ejsOFFm3lhWAb38cj0(mRXg_N;(ZDe91p?mIy>0@aK*GJlIklrDNaK9iax*i56wE` zYf*HWgXQ%0nN2=lxsLAL4XWYzYCac+bH-UEuSJu|q^8-q zDQ-C`Y0GIb-;S`fSMEw_8eJ}pLVq0FxA#>{Xu+61STB5Tpi??yne~02p3C(-wvx5> zbxog|E5aMsWl$arW_Z-a`nc3aaZdC)^%Xdy{NLOv6RaOa4)zuap}=l(uSMZJeJdTx6(FT-5- zNt=EBl_5E$l>WjWs=>MDz4~bL8$gvnF&t6J0#fPwcf*7(AVc8qKuNkpW0-8s%#2;~ z6rmtpHH`D=kxSKb;9Gv*edUUDUTH(x?9q&@o2x4fZ-PEz1#`VHJ+*@`o#Xs#Fcqw9 zFysdX#~H!yyks{wwxyV2@io|x<)O`3(N~lW&yZ_nIn>ZXE0Pjp90FB`?0-6JqCV)euV`D&;Nr19U^8y?3++9|LngVR5zJ6L$(+TJj`K|I1hJt5T z){7swjHi6V8&dN#mLytvPVfspvUda^7`odAHWxua7zcsU5Jn2=he61P`^+sUkjqgA zdc}2h6rA86J{(n=b(&&HNJtQbYZ)5@u*Sq(L3^kEN2m*=RJiUUO|@|rayDrcmm5h% zK`o`fWlPRKE@#Z4V^9PmgE=|vpFb0v1I%YUr{iQ~49@`N9^jB`7&H-2!8P#pE2(u| zZS7rdAoD>j=5MsgQP+j~os|djE%mc&304qqZrWdl)#KK63R|S*h+rPvN|eZCZ>SyxXj|G9>3Y7ivdQ23@i?pt7f z5X{SgUNm;WSPo;r>cu9-Cy)g)=W6ZkUwSb*QCva5g$}nz9-WWoieY$*mz$foA52c_ z+S*qnbRIo|OS-PH4Vd}TrAsh2v9r62;_m#x%gOUyCN~|-1vEmg^!88gR_d~v|9l@N zor9ifwWrG)c>>Un+9AT(HENmbxX2sLV&KS5U`7pK0vNZ!$*>O&0t^IH?w&Ym z7}8y&8JT z&cuWk0sGi!y;Jz>X3+co=X(K6C}XjZ6>!so-GqQzxa+5@|IyD^FfWQo`ud)Mu6hXp zx;$(hMkvDJ=0iifA;`eBs->-63ykL^EtwR~j0DcN4_Y?6eiAr{tTk;vKgWMyDZJk@ z5v{Z|Ha?dpEA|4-sFM?{j&bY?OO{7~7fbC1atm%hyHaXcyu^Cfbp%WoupwshiRG*) z6tL!+r#Ev3X&(On!IZ-3J6h%)F2a!1K=&yx65s#8l=T53MgJz^vbaYqIwQUZ(GtEK zz~il{fqPV@WITh6rP&f&ag7;i$=t*$FMryr*<$YP0UO) zN@iKLogwTKQN=2bElqT!J$MC5&79D)tQ2y^eacxdEdaR&tu=7Vt*!pB+nc~q-ehKB zfr)3JnGeAfk}#H(l=SVL-qO|<0TMsOxEW#C@G=rxS8H`8j7VyFJd1u|!||bSejK~} zNkX3@MrS1m8sG;v21^w1zrZbsz)4le0xH2_x~3oOeLgNgtHT#Bz$0NYl5P&OHX5bS zRO zWr~>~<)1f(#>QWTwTBWF#-0Fg1&;h4KO0-yj{3%$E|_Wrll~(#);6SXe zcZ|CFIdo~ozH2DUaikfjq5_RfOiT<6P9W~KhnJTv7s;Nm$>(drjH2ZMIc|cL(||KG zlGT`5)`(KTUbHa%BX1v?`vz|49Qyy_hqln~d3p+_5BWh?2Bk+`od|hTS?LViBozTR zqHbc64JFvnkd+7rE)pnz(=c#_fe8j!Yp|EYKjgf}=oI!)+*LMp_i#}P-i@y#pN?UQ zJ*}#EoGg$?DPCnYkRlsRo|={hWesd%b7-Cd{l2eXjz$V#vEc)CRtc8%hcihi_biLSEYoh2-?c&Hzemi>y^=y z;lKjRTF+lW;JY%=^(vKhrA8#oU6pXx#alHhx$!T?ZT5|j%oU;#`xESi2U`zIHcX7orN5L2Y=DE$ zotc8WD%E3Dq-2Wg*$2W~saiBr!m(YrqWP4A@#eL*wbK&*r4MXWIY@*i1u)@zKWM)X zcNXX?|0(*__1#QxKXLjOk<9UbV1If3N^?g23(iN$LBY>hQj(7{@5hs$h+yBcR2fg2 z$UEF$jYN>JzZt;`J|IOK0?66KQA4s%HA0;?%BqTl| ztrT8US@&LCOrzhf(w#q?ZuHe~kJGZba;Bx2%C_brrEBYxn2eD%zP@7`lmed7r!EFv z&E)*2tDoXN7B2F=E(s}^krOV14)Ew;)O+HKu;=B9qf=Bt3Ulq23zl{zA4*gRY3%z{e=>AGi8Gk&+3!2$QOC3i+`Bo6Z-A?+ z|FmxFC$+msguA)@CBc*+G1@z0moO-{OW8Na(`rIWMkk&XLq{aDwSX87cI8j7GvDJ_ zrm$vtCeML$U${&{vr?+(p|@&k3$>+Ki^>?6rU&hp18o4;eIH+&8%AP@=IvAdXr!ng zKR(u4!C$q9+lhGrKCj6avsS{wI7+)~#y=(qbbqkhC9N9C#-}vIM-FW<Oy0<&k|82gf$jZs{w z{ZneW#Xa<^UYZF`riPp?vyXAimwCHHOXrsy>^oJE!Kv)4_x5^So$}XMK;z$Ho&E*a z=oC3D**=wu&UO66N7x&Wh#n8VNEG~}5-Ia`gRQe8EBXlw~ zP;;$b^B+pnp{>EAnSe|~SN9NjE|{JnCnJMz!T<^gtUizuA1)EC9x~GY#%;S{Go&?% zoAFO0D9Sw3YklTf?Zu`uc;EXH?wp;T3Q~OrGy@}Gz!Ihpl~+_$6c>9zxdf{)AjNU|_LlTZS+x zuB7w{cy6GUx7OCC!LkJEaEF~1W`ePwdT;VaEEZkCnv=AP=u%)N;bCHg9&iG?p3Og3y1x2j!&nNp zz=}v-b`zIN*=NVJXMa5EPST*Gfv-OSk`0Czx-UvADkMB$Wh{DWL_J}kHyAFVD3vrJ zzAUnXwn=OCJtg+~7|AVe3CeOYhREcBzxcv9qcPPslT;#1s--=u5!SCKzg!!d@g0J- z1+VL&E&tP}`%oZ0%+|-zscYUnFUN0PWXUxnaw@8b5`05enen!WHFDqoE)jfh3eauf zo730VC%DNi^Ps|4jsvA|%S;f^ip1`#(Ic-4+XA=>wp#(Q!a`E=K8X*B3Zi5CSBVH{ zUy0KnZJ@R9Q*0Mxy<3>2IY|zaB{0tXcWYJzCOrW2T%!_Hw@sI81ee%3C#}fZo!n|H ze$H0srQB=&$M;>+4>^c%F)_ex0HP2e1mL6r@IaRa&K&gQ0(^}S@Zfqd`T^5aBTLU^ z$Q7#7Rc77#6PD7?w-Y>DD_Md3rX4)Wy+> zNSG>T=6^joHdv6B8qfFDPm(Swp-i0l5Uc)yo-9+2DExE% z8&1=F_|P5H1YpL+y>{t^guDO|fJO~U3=Td%X!sx#i+F4R&wswX5FCOV;O^p`7*gG+ zv7ZdhN$dgz&pJ9S8{S^Mc1D2%<`kGDI)u5=G4R~LBnSb)MeL*}eCJK3ngAbPvU@5~ zo|mQ_MfVjSj}5W$^CkNFs|-oS@GV%?zb_;L3?baIvS_?wFk|J$Mn^$7O)Jc!Eg$lmBBH-x%Q1#VORc&9mM`@(HyQI5O>Fx$e>5!K0Mkzs3y1OwD5D7sg1%NrnUz{RYZhZMdSTfQy)Gg4I?3P@bUqP3|V8^`*lTS!k;0KCXTDgTGZd$Z68xN-V}Igzg~P`^R<4IN`5Ibg!`MZ0he zbINmOH~USBiM;=my~74wCQQE~!+0Gxk6LukvxW_Ku z_EhdJ6H8>$M3dDiD`m3nvt+gvGtwv>0u|#eHi7dOLkqTUiMYBy*pf_S6$nYnIT%!$ z{O|Kg{R?~f29@xccW~F+i#xQVKR@}{pMK6QDERy)uni1Ipao)M2NRFb;_XM^l>vlb zAQHf+E!!##v|+C97XCxk!0Gq`e;bw^JY`ZKlQ>-Mzkz^(DtrM;1xBtwugrEBgE3V#9!0!*C;|n}rv5ZZJ7?aFivY4)@FJ(2!XNpgaQffZP>;%~ejh++zu< z&G|Pu;2MNMv`wkkiTKsQJa4V} zK>?xjRDNf-=;phuTW`)@i~B0R7^g;iGTVm+TJrC3dU?`-IQ{${?+iGsT)ho1D=mdB zD#nHa!N9_@k?+w{lYt4}yNQCr!^3j}0gWQC!yduv&(F_?KJVX2Zca{uO%5DcW8eB! zxQgHQosa~05ztCKRwI76R?1lx;U&qHp7P8VHLysY^3bQ?B=b%MfrJMCVDVE<I`Zn z^MU8GDC4x?)+tvKu<{jw9uTYPa**VW zCM@0pYbdI8OyCTIn4ldmR}4OFS30ya9V9pt+NFCYvfFxy#dch-m5-b@WW)vuYkxy~*0aG1!$ z@V!7k0_e^UA2x1@$Pz#$L%)Lw;(cLL@V)`cBq^5>umd8dNGk1gY)TVIk^n zTH@TqjQZyNs$DaNA};-W^70sak@{V+cAj8_NXq)gAe(w1=3`59E%VuSR~?*w;5HLC zGG4jbLyZKI$VsRUp+*8GAQGT}&jdZThsXG)_ww>G4Ci1|r2swzC8e{i+?taZrd|_s z?xByEMf+p5wMHu6znRYO=4DNREeAx1ISqNxo5TT08+g4@Fd337IRsxK*k$oBF+IJ! zZu9VfZsj2UbnDT&9ijPW<+R?rS-#q*G$edc((>U1u^PqNlmJfpB!fz%(0VnI&Gxcf{|YP6ik#4SRj_kiTM;9vD33GynKE@=p{Xvq+n$FRzf?VBi%a1tVc+ zt1I5Q8kKAoKpTR04{{=5yEp%udd_PBn1v4tb8xV7tf3TG`S4*6N^_uW&`Sq21F-@| zrBDMx(FApg9u(?`d-v~u0RkgZI|fKy(6LK+_%$K363yK(X-3Ar<>hW5bHIiPB9@u@ zC+$w;K8(aD(SE;J9+qM9(XILZtXY}VKUJK!iuDB!f}h{47YF9A8}WkQ+>GP!QY@UO zWU^v;mMp7YyoFO9X(6GOe-OwHuRtGmzQNg@(SZ-@SW=k zT>@mP4ftMf!0G{kK#wM*rR@fCCDJ7$7_1P-Ea zm~6Q4kt8b6|Gclo_)HCrv3ws*q~NY(iwRIYT>RCZNvGJqXT3b*S?(FI^GuN4)~0S1 zOj*Z{jq3D&=eq?sADoopz+c{v^}W(nWg(JWVa^<}15T9Pj|(HlBSr2)!NS=M4V9sJ zwdzdPeDa)>!qKB2v(GPw?OM0KGNU3wevPmLu@G8?1e@2^Sd#1)pl*p^Duvo9DdPe1ezPuMbJD;*E@k&hSmZuu zP;dPM@-0Uqy6oPuGWx|AO?LcAWn~I{il%(s0vEvUswxwS5X~S(0WfS&5K*3-z{hI& z_+En67N4uQVOZ85ulCOifh0pZr^KefL1}CA0j4R8MQ&qZ%I*yl+2qRE<}mLnH@z0N zI%bPrDp-@U3BUU5sL4)_I$4^mePn1s$!)eNn_yhH=pgBEr@y*H?A?gYDKju3d*O+I zs|I2~S}H2eXKJ^xZppgPj5=ueOb&7^mF{5n_mugr_)*LHGQ4`KQqNHN-R`P2uC6CA z&e^4JpX{DH#c>D+7+S%A23?BLwV+`ET3+xbBZ6fBT_3pso==??OP zP0){+ILgV+ka&c2pyq4ZkEnqbW85#HrdyqM^NImi@?TFhE4-pjPFY_BV4x3qZK*=_LkUbH%lQPHBtFo?jL&uzpBeR|+R z@X{>gG-_~rCByvVze^yBi7?kOCd^$v$Jy@sZrgqy$COYzEv1Pb+syq{>RVSz_cKi7 z5a3`#jUukWtmDJ<^l#YoUSs1pf6pYK3C21|Vd!RKQGYYm>1{3L%hFZM_W1E*7#W_w z6(+>|bw^Rpla0DkyIj{#hbZ`&&hV4-luF68>o1T|Wzd*(?{Z zFYfV6?`^T}ctI)*M&E!A0{E`L(m~paM(2QJy7?~cr&ESYo%AYJ#660aQ`PiIY87z0 zQ;E1_f)wj1tGb;aixFl)GgkwEsW_28aa=u0S?8FgGX4&Fuy> zEU+B}Ow}Mhu3g2vXqE93PO!Y$#hV+5shIo#zY4E!3biOTb%hEX*`v_#`T}Pk44-iN zgO2x(K}!I;5cGQ;CkY9da)l_no|RnksTM9~%u|Z67 z1%!8K_JAvQ0-SlMtUy&e$rGgTo<#iYH)#m}(?4Yu=Lfw{qVJ&KBw;LJ-nu2_wKf1c z4!AgiAj?|RvWRKtmeM;E(86J7er=ZL}w> zAkL30Pkdp>>Tx!0q)V%E`PC&DY;s_$23P@@jllSG`xFL`VH{9d-QAY~`hjD+x9c68 zUZ6sSjtInv#=(I=V}k7!+-PCEZD?Y$@SGxz%q3j%`L@>ia^GIK7A3}$ev=u0F64OF zY2>aY}^pU3sDpULk#fcK&$27?HcxbOboWK z>c2uvOz+0VG=D=~95vjiqH_S=obvSintiu~LcDD)e}>^=Su#C%4P;!?n8^ z37fhVScsgvGe7ipVmDpSUR+ksx{Mv%@1g@@7U#<%O90t$zf6E3 z((kd6noiwH2c<>fU=%46`l%-kkC-*QRjj32;Di@0F&bi zCka2N!C2D&_Tp=MHJ)5e_1?#aR~r@W?j*Bk!#B1-dj)qKDI5XYSZK)4z!!kJb@~Go z?qU}}o1+ToFI%PlVAl#9VTl0G5%X!XZP|i)QEkn${(2_h~8a?`1H(&UZSX6jNO#m!QV>`>{|=m<)w!PF`MZAP-R@s8#MZGsfAx zG2;)y!HW|9eD^PEJX(->#y^=P+fQCyxYl`xsyt}299|qKk5(gpX3Z4glxW;1J>v5C zC8*JhChU+ll>#=>-#0ee!H71B0Vec~IvjC0lt6HWRS$r+$al~u0jdICZs{tSV69_n ziiMyMa?pSs!N7nd#uF$3@JC)=-;i@6#{NR`!^c`1Ul$^tx~P5;3BqehW*94v`j+i@ zNbO+;o8$J0_nV;a{(s6P)6f~ezwv?F0tg?B1dv{qAp3R`rAFugKEE+SJcbPq0kyEx z1X4krnF)U=2IJTNn780opT%eO(9JCbT7GC2GDzs;#9rAlHIisOViO}wvSpIsS*&{f z|F{5mE=@vQ_0(kv)M!4%{H!d-A93fzWeh)3$t`e^3}Ks%6ecn4oH$HM`624a# zt;1WBboT77z2ajhlG%I9t%Q3cGv8F$Ld5gFSe5OZNTm2%8PF=2RjfA^w_zQ=DCv>p zNce)RsP(86MVyZ6v8IL!KE}y3G~*4i(DmzZJ{_4b*&=R51PKpw81(3I&4@>)EmhN&8Er@Z`F9P4>AhQ05grbh~sb=J`F(eKLkC-1jc zVv+yCqQ*0et3TnR#0}&pDY$E&yY%1H-7p{%p2v{2`)cZhDZ4?}c!0RXv#7=`8_{7> z;9%B^e84wCtBI~w3mqsWJ|1HeCTdAirR2-W)V00hAA!$X8J1WABs*+`G1Ou(?XQL- zQ1&VIpQyaaAze=T7I3OKD_d?TnT|GgeEYvQ71h@JOFnxtq_hHGK9QgVo#pLMa!*xq zqVUK7zh^8zUyl@zY>-AW81!K^@7~6#dM#<<=Rp143SNU4UPFX;LyimOu!b~u zwvU<}HyFn@&os>#HA-i*$#~)^%1w?2JT>|iz3h!#oLo5@95XoQ<&yVrd)BbSKd9An zUUOe(5YEJz!d^u^6Tpi5r)Nq#5K9_Wjq>L9sJU-hH9EWoT45$}pe_Gg;y{tr@p12y za~wyC-1Prmj)?)54P)K;&ffUZ~4_(^nKW5@b<-T8K2cy+d@siJzOE?jN#Z-)?`mlaV@Nn3t z=t_-ywDidws88sWrmmcS0;5|#9uH3BmtJKs3;^5gPuQ%itiWgrK3a=4;rkKNKIX5R0q6rKrSlU#G+=@BcnC7SA+H>AJ-=RCOPFh ztZGC&F?uGYlT0v4i-z~8;vJW~iu99M@^CTS!b$9NAF(k|>;v#22|Pc{lBOmPU|ImZ zexDRsvp`|?-(CouKqs2+V0 zJ=1cR_T0p}{7&e<8>o$qk}b2=hnaI?>FRYK_Atk2gRw$CM!t|Rjc@r8$epSFD$MyO!Lc^ z3w?d7%OZdULY-q&Z=%~~2V6!ltq2MdZph<8;+2V$zp8FB8gP(s8!c!2J~61TLff(_ z52@-iC!cw>`}C|gQ2mh_3ASW-1A!dPdsn`h>FIwvTFx)$b@=LZ@JHEOShK zj6{YZGj2Np2aj+QUgK-MvXN{w6o>2otDUF95+$0 z;F%U8l*62L@heFEIZq-!TzJ@0TA8n5xIq`4VyU!z9({ei!-2J4CS0`C^=vn_)Y(?q zEH{U#RPBaRC-e7Hw%2|}E1&hD^(nu6feGmdS65fipdb*>)ck&xb~m~x{aB^3b};&c|1P!B89+Mn~P0AHlaHE{94;HX_& z%kSH_EyR#ZCU$J(thNycU1EMkhnr+2xz+4-MrQX54p4yQi+kCEQG}WrcIta-5f>5! zgOJcPM5}O?r_>P*rs_H;ac~g^cwRfg~5qzJ9{E9V${_=z(A83bfy8X=xT+ zkI*nM{C_MQL01T!d&Qrz4hyKh%brs_tR$JSDlyUVbCC)k%A32i=7oKE_bFH63@3jD zv*~=>?EJOx54wTYdu<0%z=i}65l9e#o<5tq3l_(^nJ@gR-n6yM$i_RdMR3+o*Vu()~T%LP?!oXKYHu&1%LNL#k zHZ=B<_}~wZH1m*=Sy`rz@BjNlNcb7)Gf~!6eaWZd=z|z4woPmAynlaQ+3j(ng;SAn zUY(K90`v4=hM&Jhz-lq{@o_dX4-y$w)QuS!uR_rDhx8{T6fG<{-aPuUH_FrCV7HHd zufU$b+dTxE+~0vJ!-s*(lC37m8}?x~`vXk5j)S7NXmmKP%PWP^0h=vjmHm}%^|XGL zqG)E}waOfshMM<7QT&hD*m31J#9xg2e!Txgar)C2%qf~&xivkyk2xxRqcVY<3Kni%P)qCHMq~W`Py1;4KGMU>HPGPIBL$s{5^4eo9Y9r zVffX%{PrB@kJDb0ByjFAj#jd~oQRg4I(9o=VaJgUZrfkXX!S=eSro%MJH3O`_{qZ( z>(dXxoiEeHKH3)K8n@xa^xmWsIQo1uE>NXRP=L#&`O;a?j+0VKnc%}RpZ!KsAGfhZ zQ4#CWbv3qCeo9{1y7%pPs1}mOMm!6p`b)1&ar4wY9~OB{uvDs2yS$cN%sj}*r4FTZ zTP`e|-Hd&w9)C7%{GxAHT9-+oy-5XI%f7F|LZt@p!*o&gDE0(1v5G6{GxcFF{+4bn z?N4wXNOyh~4hUL$vm8NJbg$jxw@?U_WJxjcMVR+_#CylxK7Q#uOyiqEUqvuF8TAB^dbUz*1~3$oOxtCbR*OiQ5tWWB$osOG0bLp;*iF1B-V`@fGxs}g^5 zpJ@VpuT>}ToEXq{7&^S>&NPBruATeh_Ve{m&5R|I3Aa8d2&7jw1W8hq^AOkFJJUZa zE7H;))#0v|e3g9H-qf6~ilBp!aq*9t!t=36=Zz<^jN&imt5+zpB=YQUIu~@_c_00w zg4Q zAgsfQ(%T(D9pV?H1t?>rcj8gnZFqxm$T!F)uX2%rpY1z&m74T+Hp(Y>Y>3A#nzk!l zbS+*Xq_R${%3N>DKH)$iSKBK3bz#TxX{ys?9_q_?k24e56vW1x-Jjz~9#32~62_nl z#wgg~Y0R&lE$VPKN}p$ZcC-@sYb42)*@@iUQrI^YLMU6(VoC^0iZw#SKKOo=ZaAQn zb+SEXep$VsY(_N;Ec@d6&Q4(YA#N0_jI5(;XHtXGB%kX5mHBSF6 z;Mk_qXa2m9Fb2=g<#7MOnIl498Kss`VRmF6y&%Z*^~tPiAP+h$=dsc_>tp6Kb^Lw$ zktE~s&D~VZIL-NAVT3WFozn5$^#bA4v@(K>Nr?k!o0VnTdzCNAP-ijI9X=P~xxcio zj?PN8lWV9=TCf*AQjd#dBzWA><%3!hEqA*`id37Tp)8~MmtUSZ+m!b%p0Den#SXD- zo>uwI{HKRp^6l4LwLMo=g%%iEF?{Qf3UkkKI|0>t7Wk(k+$sYXRC9_qw_i3C;t|WH0m)#*b!IjVHq~NNDZ8OP_C zAej>^p<9|izqNvO-t`sMO?(F{pQ;y!z$GQXiqvzz{u5n=&L!d8s z6^d9Fw_OI8q@p_~Rgn%X+uFX$&I-R<8|5}x@cT^~D`I;8;tOUem!OErG3LYT%n_Dr zvBpO38swV0q@L;dWdjeHW{WhP)xjwL%)>U0fjTXBF=~$FaIYoc$QE?xFd~A%&0N6d}Li$jukLrj&Y|%TLlaH@$VL& zok$qUcFsQCwL)1W=bk z4m?Ei3ylwQm!&;W*KV!2)rTY+GSI9{(&&7g7$q?(IfxI41Y>uzKxoMIP$T5 zZqxV{^(%=v|4iSw#HNEfC9`r8^6PN=U8qC>ssppT@AZIA+d%6R=nJROscQ{5F-z1cN+r|I zRau_Kh4@;1apXBhY~3pv)E%E`vQjA;pa?&@dldW#5T|ydoX%Boz@%InSA_x5>*@Ja zX`*Nr=RRK2MJf6*{R=TkiJlS7qV-I8eNUZO4O)j_Ig1>`HxR^_aL<*$1{#fz&u{;E z!bF9C>+ z#_f9i!a&djatghgKcN-Y6hn2fV@mpS=_--Y_D7!Coz#y|9UoB#91HAx(a)DsB*-(p z!VH_tUA0wv=%+&xs$}>p?)0;*p1Sih71bEv6M-)}$fR}aW71#nV#)4@>i$mo6f0&r@Uq#P2+bb+dn6M8s6(Ap`+tXS3&wj zAMbTQD?7GMz?8lNops(nI}p?5inwM$LIBc9rK4jjy$`exAnFGR76e)X==U24MRRjb z^}c(XiHTNL-^|+=m6Z&iv%d+N3E6s4{eXHZ>9(gPJtcblM+aTMk^EZXYoVg9<}gjzW;&O$xX2zgF)>sXVC>^&Cq+b`8=>d*w~t;!>En!# zH+xg&T=Ew?eW_b>xB8p?5B6tYnI`CbwB7!jk zk-lfX+=*4DH;s*Hu(kt^MSmowR94DANM@qfD?yB|9bH~&be@FW{xuW-D>ELpX0s*c zs0sWVZ=?R51zA;gcRD)NXnH>68=4ZL707?Xw0JWUGacWQC_Y|ND9F@#U&Y9n#JFH_ zr05DaT7DYhj1;)=D&=daKKipC(Qv&EG|SDmx#NSIXIqmy5h}jX-MCGBs-CdDm>-m_ zbDJyGO^}YL_7v-Nu51=CJFmf6j^G_Q1>(?%A1;%^91$#A^kDJ=1ZrSn%za5rfbS(F z09^(Mq`yv1&=D#XQxF= z`8ngArQ}t2Eh8#}p1|AUUGHswqR(g=a6#o&vm%BS5WyolZ0V}py0Pj9?ZI*D^5P=n zuSV#*#sGIl+R8-$#TL0(0*Ou`W{&gO-iwv6e*TYOngxc3E1{>f*`t>$*H=jQPnhGN zAPT`<3Wl2yFEGXiMgUWn)XtM|$-OED`g-gNERH@*C9TZoYMOoQY?9K!ni7V3V1~IT zQ~Weyk9V)>rjuQYfi0twUxH!^@&Buzbc%nA>k}Q{Iq)(KL8DZFK<85$yYA2|D8S z`FMF7We%HOy$XabACA#XHTyAdpu_=T41st&mZNdLa2h7U{$zf{+>mY(^I5H+=Lh=$|9LR{mnc*T84Y9Nk2fee;h`t|F7> z^YD)a(lgW^kF=mx5zmM)wP8C!*mJijeR;D-&rBQvu}pt$B=b%tU}50I%!MbS85S_~ zd|LB8i=P>Pg~9zV(Q&dI-SpqV12~dAtes~8=CxuZFz_Ox|4$x`iXJB9e z>u~T>sPq380N^78w=|fxRXQYAcHz1!tH0;}v5a5!_aPa9|LCFPy2;q9Hatc{ z$cyUkzUt@$3GKF9-+Lp@(iQTG&28)U&Vi`(`bi| z@mCQiT23(j-KnCHd5H4an8f}2Sowm|6@ijWR(^|^O+!5F;-y2{JAfFqat;rCr9qTD zrQrh^pJzEa6k{s!!1vghs(9Si*5=R;f9WP-!}~8dlL%9T@VW-3nsgwy1iG6CxcZFz zb0O>rOThOTh;#C@KBt-$)8e#b%OAIV+%h37wHWUbGaODP{g%D+{muP$9~Q1w{W`vD zo4=bz=-HLHw;RUa1pfY1D6`aHE(Tt&jM6apatMU6H7GzpWQZha1stt`DHix|uu4e$ z1#_=F(w@tcC9vRzbY5VsLA)g}4CxRAgoG_&mq9=)0h_E6od6)GE`Fscz3&S+hKlsG zrM{Z`6#I*E{OgwcZ*XztWr^TP3a1^3sWBXwyjuLLTFs@-nR+!`^g7AjR9l@&jtGeP zurq?M->Udmm~-dFZ-QHG-};eo6L`YH*b0E@@B8}=xwzDbZ#z3@aN-RND1bEwaL2~p zfffT8Ya3fzkQa<(3;XVT6Rk5tb68=m(>2KYr4z8~Kg#!lUo&8FMG68_0aPD;X3a&v zDi+^@(>@ua%3()}5zbF1ZMrgReydBKD!R|w7jUmna@5rMi{W4t24AzL%HZZQt^NIE z*kiu2U~7o+*A4ZxLu(8eG?DUU)N1WF=k(sN(0Pi@Du?uCIOoXwH)ugCmm)qNt}-vZa94D>pihMnfdyM`}*gr(&~!|e1~;1 zD&M`vWf|sUxm4|T=RjNAPZr0!_bNMNW%^Bov(EbLO{ZiY2U1UnyQr8S`Uo1xH*3`S z7@;6$NC!*r&gG}%3?A)P!M{I+PmI5p4x@ehUXlO8_r#Qc|NV>frv z&4@WBbDRB9<=T6c9F2xK^jXruXTiM!J9o2|WOmkFna!f|l$IJ<@x6lO-C9H+;&NKb z)Jb-adatsPt-SsVS1u3Ev`mT+e?A8(X7@_jH?{2-FFbHih6F-%$z}lmS*q4I<$s-~ zLNVrY?M!g$DD+8y09D;J3_veah#hctt)iTj)0QPssyz%x+@Jm{9^X;WC@fS1pX!gAg zqO`{nFU%uE<>U!oN2BHhnah;Oh{~Gl``s)K`Q5tq?UaofCNmV}4WUe$5kxjHg(s}M zl_15Ow>-_o-WS2@UD1g^Z|yjyqi?X;5F!K({@M$ZXT&L4_e`CNr}PGsup9kPKg zA)6!aThqqhyUv{)Q&ohD6&BbAo)K9MtcgXN&W%z3QcN$k=YuTcj)|c+u zqf3c?=g(sMO7?uoQNXd_D?8m{5?p>Qw7!`9y`v)Q-^(47EZ9f2!z-B*eDytxL&9wn z@9+qDWD}c3xY7us8&_RJDHz9sP2_+kw=-ut$|u_9zV~S>iJ^h?#@lUwFCP@{`_!~{ zn6dS1JE;h{(Wa~S{1bZAT&1kAe$DK?`FE&#CZYwJB*@zcuuD(41dGhVI!Ke5liF`n z6WQcNycCL>y`cQyX`}eJ@8Fo`en3%Zq60@6BU}bh=i+oX7S2SrysO(aP170XOu59F z;T#=YqM%{siHm0t_GhD}3&mQ`TOOrC6n`A8K6_B6d)+dGGUUoEtnd%+WGt#0L5Rij z3i`hi^XWDQUJkyyXVHZj`Jd1DpCpE{t56f^D}<2RuVru`5VT~f3bF?A%J{Ai`CJhZ zELR?@75x_@>J$7izHwTf4VpDLIIkM<+WR|C+=6aB5!_ZBT=iTpR#m!GaupCoE$Mx! z$Fz}kuE9_z)D);$N&<;qe$HAnI>i?+O-*7dbFxw%2kQoGii( z#ucHY!RBw!vQAAyVSQ(`78^kkgnQjX{UF7hxUIOBrRkTa_|oK{%h97J%Rdsa3Ck5n z;2~;UGlz^TQAZ7T%sP+4tS`L-w@h6oYPwEJ<%eU5Y+OC-(lC>C4}Olh{Sv4T@mBZ! z9rO8Rtdl5KIqnByV%hma`qu(^LNb)RwYBH2T#dgD1Yk_9;%grg zqnJcK(sYiAw3VIBwfHb~vySgYYdviT9bMGK{nzk5X{~FlLJ`o0$39 z$Ybx*^Zms?Qs3V_j^Ef#9ditgM`v&=fk&l=lhoR_-K+@fXR2MU=v4|`W+DhJbnNbI zj$at{%9E$7D9Am*lyenO94L1>z7xLnQadjPZId!FYFg^pqPxN9hitdJIWOFw@^Wlj zIpI4kGMyu-pJR@S>_$#ew@O@)BA~m#c)^ ziaNJMnu|5W$L|oS#qi+Vczd$#2@tzK-8v*wV@+&*}Uz3zadHi22P$d}LkfaqZ=fUhA=J zV%i+T4Ltj|9omOFj!IMFMrFJ<&m{O_jPc~XIz}dHo;O}ORkN3mF(DSxZ@!T3PsM0P z7v1wRk4meMuJ3t-Gd(RsHRgj1bSk>kWRw_uG#5)Rvz*h=K6e z6NSmU>|TizzB|Ie3Cg@_E|ZD5TVa46rZtq>9V28xSwp-Ka*6JaHYlfhv9i`hz96bq zS++&-(oa5~cWP)eAz}Pr&70;6ZJ)Q8>%{84YQrgZfwiS=M6`{x_01RN2rBM|!} zyqqL3MD5u|qdCP|{~VA-`{G7CZ_KYJ>`&vvVFu?V9c=z_X}I&?URXIi`%I(@zi?La z(R+^_!e(o2d;a623e{+< z*u`079p|SE)*%(TW$QdsiW8c5`4=Mn5kQI}jQNyF@IyWNF59X+4Mpnv=I3{UlnK^; zwZDIQ7EZ#KAz|^)B<6CU(`!n#9J9MvL4}ePmE3zZ(l^IUQN!PcCG~+s2sc_Sb}Ov3 ziV=Lw*eBnY=WYAge7}InS_I;o8{P%mjZQK2`S{j1V|TqdRxAF_-o`J-63Y#7?JtZD zEE$D6W*$dW(kOdVnwu3)|6R9*5u97!2PkG!`hu|~7XSU%{jA#T7aekk8N z=eiyD^CrB&y<${l!Br3EiTm_4d!s)*{#~sD!Rjxc{kSdsS90HFhuXSj$Fb8-iWdFx z1c_RVmzaJ;H*+PJpl zg^MfTD*~3UQs5^ zJAe4%YbYx^I%U~gmVFd)bWYpNFN3nIoYJlU;o8t9cR|V^*e*j5%w6!N^`Dmjx+P57 zH@yQvzXK47$Vf5Bav*~QBmjVTLefoJ)pl>06EYXRswj*II~G7l3$S<3P`yNvpp;|U z6Y;u3PNwoU#9wIKGkP}MNAZhPb5w>@`(yU*Q!dt7R>I?qf9 zs&FYAF+CTwPXeKnukRlu)fCvoARLw?w}Nqg3V>8ko`ir!Eu`H5fCCD*a=n^3e0n-E zvQCib!Qa37J$@H*ZEmU(J}uY4D>Nd|9!(s;Ub7SswzfraYiZG15WQ>djyOKPrlm%2 zYShc#s#EhejFs3cov$suuc2+#R8Uu#(Y1SM8nl03=a+mQ1Mrc6zyiKhw{JTGkq7`^ zP&@r^B2lXN7^1^Kw+KN89`5ckNJo>mVEYV|9zZ9V0mg}rh8`Q3BXE@{si@9jIs$xZ zFxwp*7_fsFj?6cFXn1hyW&ipXdta{fX4&&*Pb-HA9wQ&^NF7dtScwl}xgW&%34dm5nRuyDrhh`gF}+v)J-tO)!k{f&oZ7N#`u~JXqZNvGZ_&Kp z|M3Iz_Gk&f84O8I1#lnK=la0~K+=MQNOjRA5_nwOFO@$clQgaZ&)OR6;H)#LM9~z5=PAz&m zO*y7?&sX<@M3dz(?FDm77&WW@R{VY?$ClCZ*^R7jl2lsHB?f}l0qx1lAdl`l{4d$C zrU3JqnmtHc!EIto8)j(3!zyEOBDdfH0#_nHA9OvKSWs9Zbg(cHsA^FR5%;j{To}@a z6}OL;_E-_%u7&XMMU{;??;qkXij2GO{=YPe@xW=h?XfL8cB&#Y? zlJ+d`FxP=hgZPfa$9|2E61EpozDeLd`I0z0N9`}`=%PvJ2W9$JbzT^6M$)h(gIC$QY-Ql1yr9!*!n%;{7 zeL=_l<|Z3rLEz7fhNxXLB0rkabKyJ)RFxW?jFn9iDH;^_gP*v56cljGIdr8rLPc;Q z3=k1YR}mF@w^P>J8wfvadSf!qM$V*u+D-~`jk(WzT6Ws0su}~5+^1%zrASXRNAAOG zjAsf=licJmOCyJ$04`6z(2Ndr_?DKM&^}i?I|J5ghZZVP4%2<>uU~II_-^CYJ@j*< z3_eqgj#cmE>Mo9Zz7#)>yk;3L1m0H~)opseV#A%MG4h+Mkw{NeU;+-3ynMeTM!gEl z)C?Z-8U(By?fm#bLqYKp2N2IzTF@ zy&zu+%y-@Mm2M=DlL8l0NwW-~dSG_x)qvv~H6krHR|4poi(Ie-0WSl?Yt1%@G>+Rc zYlY1L+_h%v!A%)dI8wd=2RSx4=w+X5Mg%5=L@ReGiDic!9y|aE0mR0_{PAPR zi<7yY(0}lI#=e7wTKmpl)c$73umT$lLt|s`#6uuMW3 zcDhr`62OKAP(6_U&=4f#+PlknsBmBoBa%K2rlco_EY^8yNrJzjr|dCgLp+ zO$+aaH|`E1W!pg3Cnq7fhY6gxlF!sp?Q*CR5R(oGh9D|}J^1SHHvQN;VC3Ud@ZbAw z#zBIPf$=*)8s>TMd*_hsK6{`d+S_lgt|H@cPWSKf@r_STwtRXAJM8eLw|g(?J_Hkn zgG0uw?hO9>BOvAJfsW=91WDlLxW};v`Kq8VlBq2_(}qt1G*cdKZn*B950`6AK^F00 z`?tsoGsYO0e1j49=1~9?7PH(em`tp!g8^2jCUfq?CfI_?|z0-J+eKsU~*4CIbQ7UCCRd*s&@s=bniNY;uwJtZi+l zngee0gCz=FDjizIOJFL3Xj9&g61QE&(X6dm7VL5~wl#4Q4pZR-=h_X!2_ubJfb4wFo@5)(IbMgr%(II z99|d#64UeZU13@>p5g+6M(|dF@xO2InL>pgIIFBcI57*+=cT3TT6IrIO@MU-##3PE z;=Dwk!wEYt%(U(JDg0hP)zhlbLn{A(@c~W;AQW#uSDYOl8wr=t^ zwKYM%y&0gon3rGlpfn5(Nc+HSZdpvJdgSX9tG@ba|whanzcrHQGJYXv@ zOE}94fhF2@S(%wSw4>&**EH1E19w;wLQU!E>1+D~M3LoU)VRsx5ZBM86e4oEJo*d5Y%&!rCusp=x@;z5;%}R2-d#7>M`Jli?p5m z`^U*1GE88soHq|P1Sfy~l#9}xgXxDDKmYLPC^IG#FK^2Dwt9tLZS?s#*wYL1WvW%= z=P!W)PEGQ*1$+ktLn6yWz;W4|DCvjmRgG631}Pg~+8k52j$x5PF6Kn_*zN-NgbAb_ z!3YS%W-xus%R@&)gSV8sS9~=M{NTJwGnnhe%E`J*`+*1xM!9fnktc zIUpRV%KcuD#Mufz0bSbm)>c+d&d%m0DIuY3(N_xakAN7G4`7+0z=R~dL$VGPJOH1#K`qb`UfKi^g?k ztD!^*C~D>){#}1r8E>ennwXJ6JS*F+$U+1>bl6}0;mR1i|CI%PW}kmn7#4kb(woY(T5v%O1UffX2w`wQo&o zD*mk34MYSS{E?Bez?!;&fJr(~&BB2nQLS56opK9I>}inH5ooQK%arkv;t?b@4*sL+ ziJ#M9_VxD%3#?h1V9sZpY-|p2!3;2t>1zxmy*GxTd~t)gtv!>y^OGeHqzn+!y1<%|uY`Cp+P$P$dX)L^rCh$LcK#>Je?g$3V zH85)S+mbFOh_ivS^bQ?$Fn{M$*%!cm>2aNJ1QQcZNl7yXf-hbEsdtj+VP^p@3??q_ zYz&g)Kh$aU9WrO%r{2912XEb4l)u^#DFQQWARYn}402E*R`UDSmXe>&wWQD1M|jd9 zAkM+X)6~tYL!@K9#V_?``-*PE)9Q z=8B4d1SvvHMko;@!WvQ{z_$$QCuF`G{0~Gt8bxeru%#nWm&bfP1dj(HOlb*dQSHvt zR6T)QsxgQN_(X6Q$NTzhpy^Kz%X_K;9Fy_U(Yn9Wi;GaNOp*-!z613$*e1VcFA9-^ zZ9fpc3%?bdWk9j)WC*4p5dQH8mZt=-zAwijsy6|5^ssH;UFc>)@BDGkcuP1p_XX0F@y*gX=^CZLC6M& zbTL{>Cj*yg3*^v#QXJ-@MlfC?q-;3wSlk*Tcg@DwW#V*}1>Jzr4IW zIXO8xIx3gTqH_UobbNeVDwWR8&Wgq2?d@$i9F9aHKk&mHzY>a&uj}jUudlC-jSXw) z_xp)R*L9(x0GKM5%N~zsX=%wC`u+Zoj}OBz#HL~bMaWmP*(4%amaU;RQ|NR$MP>rv zs@ZIQ-;6|bcXwyA*>FD&2NuilWlay;Y_@j0T`U$iH#cQjw!Z%Y0K;dUPX7A(S|}9a z@wlq06B84nL$QD&1e%_netUZ(qGU2THZ~?Y4gg=euFuTO5RoKFdwYAL<8Xl@1Ufi4 zXti4B=jU5nTc&C5?(T|C1i+Nr?M|oDtyU|W%`Pk~oSvR8FE5J@_4{G_1Yi66`;kbb z+wD3W4(rPH_I4tXsMqUmw_9vB0B%-SR}I6^G|d|J`+ZeaUtV6Go}R=8;{c0g;4f8G z2ZI3?ssRXRx7+9D=4!PXo>hhbMaZ3Ln%}=Gl?oAgJRWgz0Qh=;fB$#mV5L$~6vbLW z1OF9@kh?%2aB*?*{QR8H=VP&$&*z(*oD>}jfTL=)y0*4%E|*(bSrHwI z1uT}~PL^d=Rf%Y1WMqDR9!IPJh~jd&bY1s)y+kBQ()#*(G#V8hiUkxQcZEXX^Yha* zO+`^8NfI3gfUl{kDNWNFjYg-_Q50o#bX0UAE>MI(PNx$GSOEMGn41_r%nh!+Zl+U>UJ6ii`5Jpcf(hF7Bi0KgiG5C8yJLlFW10Be5$WpLL` TZ$IgM00000NkvXXu0mjfAjg11 literal 36052 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 literal 36103 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Í$YCWg}!&NI5sE88ru)1 zhE3Ntw5T{?c=Af}qmDdTB4>HG#O(&xH!uuyfWXmzZg#K) z4u!5Mr5SYBOd^ESELrLZ&h-}6qf*?P&*tYy%QAA_8H{)-dgzAUuefHOG`_k9^JZS3p)21$15G|q-P!*@X-X1=jRx0%H;YHHf+8~ z^IR`k*@HoPgzlXy0wnz5DApa=-mtoI>`lwqsXU`X`8%DG)Z-#~e`OE9-+G}l`RrmV z|K*QrRTFed+>s2t(k`!RaNds|J-QP(bu4; zhW(gsbe(>1*#oilwq=vu?Y4}qWxJI5Xb$XEW}r|JcI;q_KH&W97=Pr)=+d>S`O|zu z<4sS@UPT={dia8I+eZ^ka)DZG`Q#8XcIfG)-DF?H@Expe%Wst>jGjAp?h7^pasb>V z&h=v*Otzl;r^?>H)}Ff()H!uF>d2GB=T(B4ttP?~1)jkY>FHAq9P8ijuD+u`czAEr zp$I?8oxF~IL(a=^)7i9XQ%g&WS(Sw#Q)F6P=_$+oj%_{8mzCpcXKIt(4pfy8q&3b& zN{WikqX*=M-YlFbVeWSz_bxr(GE<0sP#8hm2fGlzWY@0LbgA=fyLMHZ*YZJBjPyyT zYgmj^y3?_O3LY{4YqhMHEd?s(Rz<~O6Cs&~45 zD<$kQUOC9Rcke@(2%xK5ZY%;*5VYVoZYlWPiH@c_*?w3q>U{hUUdB*18@PLNaB$#H zQgT3)7Pe(RdCB7k3U2acM^{=!)_k1HF+CRg$J5?ReRE^379aig?FYofGAZVAPJ;n~ zf$33YavzNHGH2Ndm*pZ=LMQ(esNYyzT!iyYSlFgP#>4lw3`HB=l=$U%dbx#-*5ss#@+n~N=Y$K z5ssw4LL{-DJM_g^n=Bky4@y21iIhaD!pF288#i180{HeEH zZd9S6Y=5INZ*T-)RMYe9*{K$PA2@yB0g&uZ1pXd}MT#Lyr+2Wf#9z(8>6-&q$3^F* z>Y660-Wm!rF0TB8(N*&W9b@C0#v)nAueM?h*De^B3?5{)PioV6Jjo$Q5-r|Dl}iO8 z3>&)m8|!PR;;!J?yww{Z;4hwZwv%)2RxGS)HlnD)9m56YJj{`e%`gZQvF@aJcNk|{rSF`We zZf_OcFBZJ4<`0Wfz4x1Sx*nyw>HC74>3v-4gP(XiFvM7bk0=O8F?)|&3A?nP@RejT zRIn5at+!C3bNHK(k(kJrFm#2MZRGyXn8o_)^DQ%SeoF3MU7KW!td6%owp)NP2_+!q z@0uNEj`)~hln^tkL~x|WTe(|!ko8h_-tA@KNyaI`YY$dmiU(#K=WFBLe!8eZ^~V0k zM3qJ2!ODqkgw;aDg63B(4^&E9f_lrR346T#Ht9y4cwRrhO=VG|lyh^iYn_^LZk3rn z$BX5ko*TRl#BJ`h*O_?Lc=&I`N3kMnAe4T*$T2){P3ZEeJ<HQO*`pl%#V~ zf$bk2#~tAH`cr=h5J*s}HYB_fT;>>_vOlA?T(*!e^Od}#*CCSVPWQjBk*TgJIP%}u z=#^S}$&~l&uUylH&Ckc18n6BL9ri|cQoe(#h`Vuq$(YET7MZ2^(YJSZ=Jq%?loCp6 zJc`rq+_{6h4*tDYJILFL4{N}8?$@{RH*lOmY}=zIAV(!Y@w(@6!k0_a9K)~U zx~lIgmFnxW+?(%6YEx;?Jymm1w6LhC^U0HSoL7`dO9?PS2Kf{QqBGvju-$!fta48U z!>RW-*9dhk%d`6n?lVh#rM>$s_;be-Cfon$S!RAgYip~&Vf!Kn^FB$*{=vbMaBnz$ zq_J#gSDhWLyw#>QacotAvWHj39frK6Hq$g-j}`35z!QKY63p;%;WDaB7Y^GljRa zme!U|^B=*zE9-n|Mc^5sneUI=#opweI&8)_~)iG!2WZ*(c{sZH%H+) zMd4f)>y-5s)PvLr-&0-{LjcFww{D&0C-KFwBkgJv>60`LIeBrhSuw5osK<`)LCy{F zgsq3Qw>hCc{`Kn@DzS8sJEtaLMEj`Juplup(V-`8VWDg9!x_(HEuU|1n-C`igoLc` z`)=oD0a^jSQ#fKFP+UR+hU79fqT6w3TS6}5E^0!?ws9qMbxvuv>62-CpXTga(+Iz% zwfS~SIp}C=J_AQVWbe?dx2S35A7Ev$B=p2Jj(fGWv`oLsH0S80-gob;t4zV8<|D%< z;?mbKn8<>P@`t4{;o|c64Z|dtRz|c*0+!^z}!ox93`W53Q`M;8zx(F*6&5Bl(f92NV<( zw(Q&kdQ(~VR^77)glTvEq={v}G!Q^T9iqZ#JN=tq)i6NOI?v{Nxk;t}eo^M=&cn>S zrNdc9&M{qd^G+I7oPB*M-aihX*9Z>lF*DI%ps6-m+mh2KMC@?6q)tpIG<|&i`#yqs z;kRlh5HGklRAj}_~3-5uxVRbkq4@J1{%kc$bzH2`o?R0f@g~f2eHs*ajnQ}i7L}9|Qw6Ne5cmE+# z)y_`wCXvb}x|x~RcO#`#_jK!ngJ+8fj`0qf^#2*1^!2&HU5&_l>C&aYe<+yc_wPCI z4`gIC?8{ryjmW2GQa+nf1qZ6@L-Ndd>w1}W^V;%JoB9PZ1Q}svH`1&ILNwQL_$Vz* z-kL0yP&I5cCschS)Tqu$i44t$S4sV?qv?8D-NUi-z1WWJk|n~HB4p4*ToQhLR3`sP zx*pNBtHJk(mqzd{*%V^lUKzp{gIrZ=MQ6dPwd!k?M?d~L^MZ@-)1? z36j-EeQvjs?Z*=?Bhz!}$WzhaE6|}aDInC4=A_Ci0>>k3qU9#3ET1H+Xc!QA3ykRn zNd$A=g3QH+vSW-)_MJDWm>WD(24mI!j|)(>TuqRcyDdP9QHoHH%DYQX_!3{OdU0`V zgKR&Ma@i-GRVetiyCCBnu8~-yf#~yI)Pyv{))Z&{ietkZcZ~9^SkjoyDAx#Wf*s|W z;ij#V$h2n(6EA3c(3nVErcwPt+(vm7REZ>2|L)i2DNMX&Rgx)+toIv^Ts029i$8Rb znlV62Bm^v&pHa&i`$_p@twHp!%k28}BKn@F%7+wv)Z!arj(DHIcTj*tNHfbVu(aw| zicsFfD|z&PUtLXcGi4E!TZ?aRA#Iapp#J&4zd@WfWZM7V->7JLE^PmJq3e|0PPd=e zX&Pfhac431o-m3G#brw%A$a&!wsT4rx{b;4j~OiruHA(2_p>Z*Q%I5CBUG#j?=Zd28O6V!yW(#*Qo1x@cWG?drOV}0^U zs^QH3O=%s;Z*8RK$eDh32sNidZl{PBJo!jXj_+?z4+$nrdk7w3Xtav3;k2eKWtDxt z;fagQ?0=)Fui-s&#>g{b#msX@l*!1@pLRw^x)a{(@CguGB81M#(-M@vh7lJ+Efekv z@h=eC(p4OX==>s2FWm~$oR)(1;#-`0>RmdzmT3iPn=c0&Q?UA z%_CEjOjdq;o$|7s8yG+8@1;H6#H(o58b^5JK9!|zltzO?BKAW?UCu1a^vNF@P9jy3 zY!Xp3OoPV(zrXPt$2EZffr>GY?bo-E+Jy1`qoh%}6P^q=%N(~nu^Lk3d!ZvK@nRvss$xOusgy8wb3-o-2lH7)d`|8|Y7;6yR_c1QU7&-FO< z@qZ@&;}yq^U*Mn)D&!>{_2$@2|FQd=C`-7upbsFK=&efM++grjTD)Eez1s z-MpT!70KY=O?cuV$e5@=5(!lyDm}_PepM0P_pp;zuo@JbK9#FlebhvbdOJDT!?G-n zC*Dx}jvb!NB8_6hj)GXqp$Az81@@~rZu3HhlxEK&87C!3QZd)$VWc*=4=-?}r>2T8 z!J$Xt0!(ZPfDr7D;OTUEzUm$(7SM#6W!$}|6g_6V#`96%<_nM+Av`|AGa>tUBGqN8 zty`~ydugor@!PjJ22XGAOi5c3T=*zPe92lcq8e*(T@^XvZ{)L^H+&XXLvswZg9jhu zTx`Ur1STxg+a&N;Q3XK4AulJFb?nNBw}O<^Pk6ZNYH4|Tc)Z4E!6y%wlCzcKxu@|M zuE0Y!7BTVgs7*>b`NC^XKb(ILDN0M~^!v?C`6J&-BRP4f9Cz#0G1>|6{V7zjJiA+h zkfK*IxbpWeWw?QaMD^kVO#FaXmkrNR+;jy5;E^`uzk=+-#nlxEwyaHCFp!JxbJa_{ z1i z0#0|}tL&@jiBu^SV(2Y-Y$wb}9n3&N_LB5G=j!g8TK34LDim@tZUUK}hK9yem~(ye z*rk4E?pcxQ#m;j$+ZP8%{%wogkdS(JFPo>~iPO^a?w8Ypb&}K{6tqN4B)N$Mim_g< zQJKztO!@#QedtjjUHJ|^fn`pkYSvd7lOu$o5avh&H%X%iA*S}iHv}HC0sO?^kEmPJ z23ZeK#%J`us~Til6832IjXaTTG?_QZy&4RETHPsI=YlV{1s&jJPl}Zzd z46xa0{o`w728tmc@b;rP`^a1Y#K(S&U3MBdF%} z2r2K?_#W4hE-IWPn2TDUw71|eI<3qh84|lGjF(DjQpLZG-hz=5u#7`)Yo!|g(~PUx zj<8eN7AZs8beq{gEQ`6c48v+_;PbX^Z+yORSUXQbjdxF^RrUGlB{otXWpcxg9R~en zx5rcp)Xc9j)NDDzl&388>6GVdvx?zs*RS`b9SoaQ>bagT?5p?WGKRsF8OwWoR4LwM zo8^qC-l2|@*b}~~%?pbz8xkq@H{FOuFhK)_FaX}%{(gg~(02LyQkjT&VNv7;4w8Ea zI$}+k=Sb|!)X{omLXEZZFcWW{2&3@Vbh@p<)3OOfj{?1?VTkof<@Jn-djbGHv0_VeVrgj95%=JeZa#t9rk!Qz0R( z{W3xFgGQu*#K(5^9fSs+Tq~BEZR$*Uh62I({L}IHi0$}vw#-sVf&G?`?;)iA!a$na zfERuHA5nfLi$+sYQzcF}e1Q*}+v7mk<3Z|%;%;Ufqc`d;#!)n+TK$2GDX{AntMB-k zni`Hcy~%-bs^6ZahKLZVY|9kFJ!n`nipI?4jrBmXfv4x4f`Woux41}-&@urQyfRyl zMj^I!tTq`+fERsz=!*c>;wH^Nz6s-I1-L_wo2{+=eh09dmY&{N7&f7d?*e|lKuG2E zxYWi&GNFxRsM$(+Ix%wjz^<{@z@se(9s6^!Qz?jzG7)Z|FnHA7mxKy&8)iBg`1v*I z>|>5xKc$!ptKvG>{Ly&`_bjkmp?vxqVOlZua|J%=K)C?sz?5%s1&u)1iVg#yo8RjS zsL#vO^QM*{X$F3u_}W=g=Xd1vMQQ~_E0=18`&OmJQ3qdj|2Q9}qE;JULUzKqNB?>l!+;8=Ti z=w`Z^t*08@ZB0#0>$wh`XT;Cn_f9Eg0a7Q_oS4 z9z|5acSSr$-1obDd1-D~^!V|dR+Z|}hrcJTAnX7otF)*BH=+xW?1bMmH@P2IE2jOx ztnmdGP%_F)4G0jAdw$ZGn#AxTbYq6~tWav=H|XAHQ4NG`J7ofa!PCflwSpn#hHWC5 zf41<(8+OF1q*bdPiJHGfETS&F5bdl>21f*ojgdYB&h;=oUutFpPH?Zjo?@KXpLgQw z-`Ns4ns%qYy?+TEHoR~?a%EN3JHP2HwA2P7-4XZd9hAp}aspnW|AQLVL@^D<;xGRk zU;T0yu>q~Pq50R;G9kT(f=zG&HC4>>$ z^iV%YTJM$)r$#e7+1`|g_3hJSnrS7E^W=w#T+%U)d% zNY*m>+JkTSGLnsVX)4t^8*@+4Gxa$xYa>KjqemjPQ%`^ts;(g@8IVr}2WZOMuxTTZ z8OHN&vhCT^ioJtgAevk=XkT69ii}t9 z7Pym|)8$9$f}feQsI?1EO&x{02@ygHzYO7KP!7lo29@A-6<$Iqd-czUt^QZ=9no2b z!!HIL;nfz29=MRgt=kGqY*;D}yg_u~*L-RGx#9%ORx7F=n0v8owUMGOPNouj6sz*I z=mAH1|ANv|M{r7V0)M5?>K{sXfh%(HIHp-(Fje{D zSxoO}neoNNC*w*-6N)rzSm-GQI!0q#@jSI}sE-igjrqDPiI$iDhSAep=OvRf@M=bW zirH!o8XCmG+F&;NCwhd2+JFB6iisqy529Ssjs`f5gNDIuJ5xSwb~(Ee*{`(dt|-WO zg6jhviukI}=HakTu5)|0j>w#xe895Nof0-1-E?$d#J%wQcgdxBxmg)iLqstxP0e-> z*pBz2{o?w#iYhE(ktsn`CwYhY<3(l)in&v>5Q4`%9H#RQ4t!)-n&V{a{x;u6M^~ZG zH{@Io6x_{{FB9|!OiM%SNc&xBcGAVvloTv&Jplhh>0dCAgZo%`ss(#WE>5 z#QH5U*M+Gn)&JOG_z-uCq2J4|NU$r+sv$DNb{-r*gnW57H+NO#I>$ODq4A`eZTRIG zm4TO#m6bKSS&)H*7APq%Ui`_*>Z;lOLVPXk8XRx8wF2Poje)B&EiE?fp`%t;ToJ6} z;^MXkjRo`epW0FrJ9Q~#V8(|ps>_?@Ko6$4QE%FW8C!n_)b}pq#Fmy4dF#-w?@qdi z@82>eFoxkfGw{?#=l&X2)@RPxU;GP3%~87R;CW$k0>&{^`4+%DKU>~M1p2r!kAi`S zQ3EeeJd{z9(J5C|x;D>qe%tn5(M7#;}vL1ByRWPFjreHTqG&9=5Lf*2>l__ z(@R$o7d~9ydl7T2KzG8M$&&T>h`}(MsoQY_j3AVt#7NsWJ~HbK?{hd~Q-*Otg?HuG z7r!6xmHmTNtgNg^q|h?qQ|VPzU%|UV5*Gv#KzG-ypL2QE15nNIMPI%_J%ot(w6|B$ z_Y1o~2OIg24U6WFyfW&V$SENbcW)jln^{fQ<@(Ro5nTnu{E-b##hi^tJCDQa{N~M@ zpQfiNm>=&@iT++8p%V1dV|L5k8PU9_nYbH+en=Yol44O}$jfKwQ6k^%!*nm%#LN+j zDIwoXF)b_W%%v|dh3@I=+W@+^OWYE(e-1~InZ2G_5FB}E#2$yJl#XtbOCkz#2jD-} zYaXreea34Jg!<3d*B4#bd6;_7Oj5`Sg>SH#%Vp>?tg5RsV+ELyzLngwmcC1`E1pUj z1Blg3R{yB3ruI_X%J^6B(eM4wPw|j3ERnJnyeF9Z@eVsu|U;hYq4rKITb2P)}8_Gn}ig+CBvxqzxelosU z8hst;ua+O2Id|?8coZ9d=OxacKmYeB@HAb&p~uowWsw$DrWM1I1CDg0lt(!qp!4#(a^)TFYmAWm3(eY|<3TR+C8&l&LPESNcuCkd zz0wgBqx4N%=p&+|5tjNoD- zjMyNv_6)qh#ka5F-OhkjsrfeQEb* zAsE}Ps0#L!GXKc18SrJ;wQCm>(;<{RSTreaI>$1^JQUxEq^g3MZDb;oEi;jpRtued zdD{Lv2>`EObuDU>)%f?lS8Bb=3Oc|s&rd{E!(x7nG{WI4UUl6kD98=Q1bU;`$HL;` zw*x-lT0$ms2h}|Em&My>aXn&?mFkO02-r6$!eV*xx47hSrmry|pZ*ppd&Tf7;%7{_z-8TF6&F2MWhUjr2jGZ)AyuzO)jkXv^c>u zgA%;mMgtvm(T7JiTRfgRK_|^(|9JoI$s5GM6B8*zvk;^I5;YT{!xqp4?as0_;Pp~X?hbPKO*hx*+*Ao0j_1`<0z{ps zcmI{FM8Tf|y;4gvKz8IkY>#!qJvd{_m2-8y>DH}VP9#He zKdPb#1`E)$Zgj1J@dGw2#wnEnm{-84AnZrVds<;B7Pq;IlpMU{XSwEW-(FdKAS>T!c$ zp%2n?p(}(O5-$_cv<_$*xQ-RWa{zwyGo+u{NPe1{T3GpqBWk*XFr?Cfq9XZK8ZSUU z438?nP**vx&jHBxiLlx4ufJecWE9B&lHpjR$Jw>LFElvpNw+K8Z<+>3H2u&!rvI6D zB5m~AbJauScjdM|ub9n1l(0s`8J zpjFr1U2AJ=XdW9M5U@bM9pna7Ex7l|4EfLFkkAF8p*G75KF%Gi#7@OO6l)4>w#p`+ zk601RQ^WmhAgti|=_%3)6o50wb<-q2WL=uzCFY}A!bmJ`Nt-t99LCgkM1DON9h5Jh zFvm~fa(X@SzkISgM|19|vaUmxxu z+AJR(y-Zm~F0T3a@B0ziSw&5G$ih+OGBH^bRdNk2Xsazrq#+rD_x@n4`^3Zq%B;h8 z9m0s=9q7ICkX85wa4TUtjl~7N2mZ_DIXQc?HV-`9eqBE68-_kMgCKp)7DMHHB+j#Q zaUBi%clqzeCklQ3ki8aa3Xmm8j*lZ4iM%07?+L0pKqP`uI8?0o)QTkQ6_^?_uq+3kusZezt246_{^H@c*J%wasR zPW5vo;N*F>1dVf&?9RvF8ZZ>_DBwr?R@8~e*uioFFaYUv`J`I%-jJ@zZQ-QB7Lnup zp*(YY6^<~L8<|HkJdn>atbXJpU(iZD>gbWx3oGnp3(M2R2lmcz%s5QG?B9Cs5F?`EXK0;C2Oq&v?8eya;fOC zk$l|MMM-~%c{t$@9MdpCaRZwa$8F}&ZpzRQ)sX%@*n1Vq_ zcuL&5!H9}5Q{)V16EKa{zkd}k|9D?NYE?0PhS)94re%H1LY!gcaQE&9s1AThqyA4Hxw81{ z*Aou~Y_9R~K%C}c^*`u^Zlb2{c=QN^A1D|;rd)PM>xBH}&%GN{R3Mc;mRr_#*ts&F zdeoR*nstlrW~;n|jE#0Q;RDbG~KO{(sC_23rjK3aNA2=hb57ANWlFpToKisTryY<cQ65{2}d+;E$Z<>Ort{Wh6 z8OPDUWFKr}wBx@ISL~vc72uvdH9oTXZex8EWmkd(;k*);t#;uNJLfP9*M5kv4;PCY zCA0r&95cv!A~JMsdIOuaK93}FQ&`3GLM@3mMfCB;#R!(FDZP;f&v0|`UC*ZM((BFh z81Ua5+MgeO8ve`uI|^{c3aYF7&CQrgnI)iklJ6hxUU+CVA~^*3Wk;d8>9?!s<%?T)L(7dow;!Ga(vg1-`B#AeD!i+ zLKVQ5@W4OkO03!-%qO~a%h@C_bRCu{(&aafVZ={Y3HtlI;o567yVwYTr=-Np>V(phf_i@QZ-?3$$TvhMB9ti`6b&dJJE z9Ya%TTH$3T*J!auM@om&EbL3)^PW3kYOYeBy(>NY zWSUjXtE#O7rL`k#aBwIjQGb6*%SU&sW+DX-#AE&isPpjZ24=FJMRrWbCRV!4sPk}& zkz`kU8HP0AR3JG+omO0X;joi*2Jke1!WnV&;Acg|*yS}Uw@CKD+DkFV`mSOPAGI_ic;LwTHA`B3UlK36p)C%n9{;>lIKsn%UKWaHL^v3*+kzjs$fbk4+; znWX(qZ`H9kII9+BWar9X+rW1EjYefM(}ki}7W->`@A?|Pl+(AXViCQ`R8;7^H#*~? zn^^G57!iZ2_Z|;=d(X|MaTRCWnUkiI!Dux4hAL6OrVyO>s&*FjwREE7TCS zJ%2+nlqW+#(pT}m14XLvp<{D#K`FOpB8{@Ks4J0%npL5ii9ldT)KpP6juRpot;JN= zggDt-bv`_$tLvsPn3{T4WcXp(ZJlb7N8Q`W?P~ePS~q3vE)+c;Gj%@8Z`hD>)bGtD z11-FiqAFu2e#4iWBB)*jME<~)$d~YR=y%`5grba0gOl3_-1;bCDTB$9cQW16ywFr% zcI#+GyufP#lY-qkWS4zdN2C2E`5h}QRcC`%Oi6=wBJ!$M&@&=055}+ zpp()xMhSZHbT>7AqtP@J2`jg(HsTnv_iuh{Y88i#H|KdQYo)vUU~+nkKlW{7ZEh}Q1{X$_m2iB!@F~G_|AQiejd^q_ z=kR-r`n=FR+e&1NOC{@_?iuw~7;p`3>Gb_}!76{@@!L5@ zp|Ix8KP|7Yb|r~hgfx^Rq`qL|3jduI(qUnzv z8evaLDlbj3(%-{KpWZfOpCuy~-Ig_7HA@jIA`@nHK$&e*(^6>Ny`$)6Q zn)@plOMFaNIAT`#RcRbk9@{7*O9;bDuH_|`Q>Gh~r6r$;%A`}pu zvBjV1bHv&|x9iksxK+u}-A(-FqT;j>Bf=|8ik_cw70ok#x{Hr2K#EM0AQ7Lb9#Xs^ z!4~nDx;9>-j!A1pq195L;9e(nZN16|flDk4sJz`hhKJZKWrvIEYH8rKHxUA3o7Y#G(z_<~IM7)!v zq(|N?J!gNaOF-{cSV*1~b~eKh&G`5>Zx)HipHmMb_eH;+ahF99h0E+3$10QYn9?p= z|L2F`a|U7!+#hLiAHxCan;9EF_GYQaY{BpF?&=Yv!w*wK6qqc^(^AKyn}u z+&RHyfj7E?;UgjV7iFMu+`ZfK>mSr<9FfySAR#6tCZc?ND9NpH07D*8|2VIozoUZk z8ld)3p;la#@frdEHY)<$Q8-Y*{FA(g@1eQ}<-PkmTcW^0`mfnU=h3!Qlpa zrKsUY)<cRsL$OYs-dgt^xE^P0;8C=8J*T=Ma$3cz&v`@mCl z!j12tF0wd%`uRDR-LsHDA}xeCE^SAluS?J=Z7nVI{V{GfpnrTk%j!}mA1fOhq`@Gc z$RzK)vvRn*ukVt(yUny%Ap13pUIVWV5BBxdzdLNKtav7qTRSW8TPWgzRZ_GTJm?5Y zCu(ai)8QY|&^o0o)fS4Q5TOLUSpuQWDHMaX4soB50>Y%=^_gCo!DT*Fl|cn#7ZJ#@ zqH`ZU@G=lV>1Tu3RZm01-Pe~bQbniBDBPlIeZKl35EMNImHO++x3aQ8dzp=ip$DY9Cjt*Tb#>*E!D$BjqMVl5|k^$%eP@y{tI-RXX*h_BS{Iheu&^*E zyPzslAOmeK3Nf-?pJOly6t^EE3BYbcZEa*+oP&Jnw9ejRc?QT-pElf}Or!=Lch{z! zx_DEWI4`eqk&$k;!U}c}M$7A5KbeIOHLWPR$F(qU)@-vkv;V(89#f|bEzg`m3e{ty zAmNGn0|SXc@{#0z>LsAri^~rrAfx^BrYwCuJ$1FU9Qf9FLD)p&crp|^H6`5k_#>c4 za~yWYs7Od20E_9UKMqb=95{-OsI&7N1m@{GKFJjffJ#~m26aPyH$NEyZ&upQV5&{9 z??wM_c7FZ}n&ZFfYS29aQ1AuN6=XK;?Y02OQ=6AiS7{TQe8^1;kX;BYFS(0gt`1 zoGf{ZZD9a<_fs1plmXiy28e(Eh;DFPOaP>2({mFDeX~6DSUk6y`%6gRajJmCWHi#Sir!vg|;M=6qu1BV_QHyo9r1K-2O_QYFkc7_ zhHTnOVPqj%{#;lXm|rd~dW|L8&BWBfSAe>O=Sb&-Dt+3 z%1_&Iodax`RO=v3eSMVcqe!qtk8m8ih@{xRWuop))#)RqtmaPa*C_7>8@1A+AU3}g zjpMGau6sDu3JR9usZ!jAtN@OpZrs=vse+Ee^6%en{q^|PNIrs7@4S+s+^M;WAZ-!| z@1->;H?Hh$=-?^d4*$BdWn%!Nq zH?pg$Tmb=tqSofEVo5bgRAyzrwt4GTh#G#)4L^63o&d`S@hqC{fStTJK`hg>B5*SH z2v!**j{(3WeK*|W1;O_>#&5q)NgPKHG4z@0a`A9u~$+GzJ7fxB>y%mGdHX}JQi?TA=-l(xzg6HTZ_X! z(%?(6{ileasPO-wODn~_gJ6j|{=?U=u?&eC0sy1ztHYFc%3d$6kiuP>*jLc$;&M3@Uu z4A4Gu^pC`rVa(O0n6KahM^AMOxGhi{ATN)+4G89~ptGT+i0oYook(1tc+J;tWcxvS zWq|AO1mdZZ5`m;4z@(cg>w#vE&eqMrQx^t{Uw}1%jlw_z=!||%|M@oxcx7{7HK3nq z0;to_5NCjwrQ;S2!3(IdrjAYk96|I-ye?h3ek1#J+g0h(EHvhll8~hn+T zHKWB7N`5*vEAu+_)|K;AB_&^nU@r*&lMa9c(wNd;=d6)8D$WK($i2$C9!;(K?Reb0 z=HoJPn{_Kl5CWrsK@s7nwYy2}An<`A6tLJrPSlN1H2f51?JsF*H&bcC&kq-0XyuPr z+ij4`nPrug!OxRxz8B+WqbVzGUb7P(4xtYZ547?rhijc{(_vshiPjBvN&&BP8uP%+ zOkEX~sc1sZ@A~aa`i(LQ3d`+29`D~LzrR^&^|(G>$xKbPz`Wgx6LvpYtyE#CFkWqP zGC5go-`?InGE>v#bNw^*RW$fVrLM>6diT~~TxxRi&x>Q+w{PFJdYp8)?8d(LbaT60 zZTG4A*lO;d2xAqMkU*@ZMZzLGw48-SAd7h%9tjEx-d`P|LD-36u20s4z0QAEbw0J& zEPP+k_chQZ~HRw1zIdLE)BOwv6o+}9mfVd2OFz~~}$LIC_YZ)kFNXW^- z;XGHOs;{rFY_IU^_V29no~yUBv-9)Q)U!PW3ltjL2ft1_9 zk8#y7$}E!LZbL32WDKI;J3HottMxV?q|-x01aOhjHUi)fSoNAj{CJ3B4t`Yr0#hk_ zUv55@X7uhhozr3>>#fTYw#)7L_Gl_wV*(+IF&9x(R8*_`(Y^?tZD?9r8uaw|8$!`EnQY#&Suad;Ig9t2@uPZQBq=MWBX955f~U) zQ&VGHvv|%FBbAt$`5G6sx3{-Q%}P&CPf>BaFA^t4%EZr45VHRCc<(Ee`Mrl_chBb}Lv>GR;0D&^kZo&sI1$H}U7{oQi23ox6G zjt(4pCEJ?!dGppdI5=pis1zaH-QCnu(Wj@U5XkTCZPkKq?8p!f1c*pGVzOLvZtltU zHXb&%@#Sk88X8kj#_w9>YUi)PkWo3G(asOvLzE}hZMM!CBDOeSv7&;mn z)8!^7&FxsR;#pccx}Du!aVYQ_Az;o(!P8O*|NZx${c0Oy>L>y{{6Gw`#ia{AFm@gu z;ELJ38+xtoES#K)O2uFy+Q0&jC+4GC>F8wWRAORclJVMSsW8+<$LHo&sg-(PA1fA2 zgI!JnHUxvdV%3v*tpD#n4pvsBJQWpgglwhBu`yQ{mjWVK679yuhNe}<^IV(Se?c_E zx{dZ`rlywlOH)%*PFn-bt*yFJL*wJ~mRx>!e<@`-C@Cq0g$kt>+)8yp0apWSmUD^%~y-X;dl^munUdvFOHzyhqajLgvA zy;u zJUG%7n3k@NepNCVf6mAtf^O`LXTm|i`$oOh1vknr9&gXkzId2%Pg5z*0g|Isirqli~PVX=EhGY5o_~@=ibsJ{!yP=BR%&9AL z`_p$mUJ-}H?_;v+w=Hs%0!zESyVH?6{#k3`?%rUQ1vUl(`LDK?B{yN%l#I{uYcjr= z5f{;iN*%Lg9P`N>yW0sY5}2_HvEMa5&)br znoMx%LFm$3Fod0#cflH0f&rII(0h(4bnVmqxU(7p1orZ!6A01aM05!<#wI3}pN`o& zA7(f(=Wm{X(@Dn=nZ_~&(6%WNw-x| zfyGG4%gb{%E=k9d{QO+16y$l3G#|Aq=mpxU*KRi02$1AXCbHlCvlZ@N9y?=% z7qm$*BqStfzO2iGg~9&*k1eiyV4=^>&T!}yAQ0PM4M&@6Dv}dw&`a;f{wVxX>?Z%` zPfR+#z5>afE|d?ay;yJ%BO@bvr7Q;E32|}7BfY?|$DJ4`(NR%1otw%1{;E1V|H~G| zO4+Cof;YwzuTN+g8TS?p{9iyMq@>hR^g2J03gyF45#hmugB-|0N%_yD=cc~L#l>ls zb4wSP_O7h>ji#{tbNk`pw?0>g`I1qefG0sWDs>x6ko_;`Ka5v>|Nb4bfhL5Jkr5p! zc-Yi_sg9AC_ZnCPxU%5bQd^Ue5*-cAXCo9u`KI`cj25RYDgJEWVXt4m*7c%4Jz1(X z=={|AbZ294e_SM=N~e?sg`^4kG|c0?Kt_)0-#q%&XwdAueZA(-#>A8#!p^_|Lc>un zmT;TrnX#Cd7>Gv0rbKUy5g~?SX>UGM>9a5}@Ohq6ydNr+B6vajFYJR9_YbT9Pg2U} zfB*jdd`owBdIQwR(a}*sVGM-b#Kc4_Qhrk|qSs7Jea3IHmHh9I8mkOCa}pCT04(|3 zZ%i`C_OZpZN~}n2@A&w5Z_i5GmNG=+k=^5XS(B`xu5PZk7l4lny=D$z1>lK+NnZW^TR3g0 z;U^}F0#@Rbb5g+NaIxn1@85~^$~~Q-?0kH{>YnbePn4CEgusG^uro47DizmiRRDCe z3lNN{Y1{e8YY0SGSh&oY-2y@~h=71#F_z}^aC7$iw`m#1(Qm#4*cY1H+ud9QNSeY< z@IH~;)j!u3gFwIp8a_XqkFp^^0O+#Cvu6y!1^$N&S?=^-WBQg1`!P4ip02>3ZU3`I zodH+lh47-ZUvI(rFLv#HBc>b>5dgke5Xfbra1a2VYNL5T_JoM& z>5*K%FV*-gK?Mf!%EJR_2_9m*+V+#Ftr@0fXHjnd4=lhzPCD+tzXb!!?*+j?l$_fS zx10ceSsGTXRLqHtjrhiLiUJ}6fC!!#3T2oP$hFmNS^wq%mXW2m^bj8p&n%tUjV(c@ zP_48CCI{VfZFygde@4MTc?hEKv%k8I4(jtOF$V{SP%$H~`8KZ$2*kkmEYxfrETj_& zIfp6qa^92!poHnYznQ!aI#RzH?1&+T0Q6L9)tiqKLApkgU$Y;$8*C|8s+#X5RBy%5#CWHh4OredW-|mgq%RV|mNE^}{ zhCvPO;h>`pfrEqFQ4@J%yT}e=DS1Xq>h@?cN7r1bx^B%Bic|H!paxdZb#JEVVrQHa zi^BKeY_L*~fP`dh>uk(`k@D}=Rl|tg6p~nz#UvS|t3tcBBHwPg=_TZJ;@yb~cmv3a zHJ_!D-ODqUKD)o{2@4C;%(-5yF@XeF&3>ylmLd*Sp-VI(po2k~r5Pzh<~q!`j9S=8RYzmLL32T*PLdc{Cjc1`N17`&f)Cw zdQG>#SZZh7PD>7I;JFd1$td?70n z6FelEm^b#WY<7>21T${XMt?)a1$8Hdl{O?Ci@YIPT}ulJ`Lo*II$z)Ua2}NmQwts9 zkOw>mz|fKshA%Yae+v~A6YQvYMqE6)Dv~ zg#ds%WyzJYVP$0n35bY*x>M_Z|&crmr zM8xeNZN~U(N4djw+i^y! zGcqzX?LnfqgLHv#U!l)d-~JznPaN^qHoWv;RO<;odU|Am_2M@7BON6rOzxx=@Bbo@ z6SA_FN6J*ouhSC~3l=nLQM<`DNs{-o*FcS+4i-~^7^gj^fbtFw{e`>z%#xB)h zN|3qneM(``t#|^@h5}(=VTp;2DQG6_(-;E8r&s0|ROw#ff6f>q{aj zA^-^0Yxm|B5O@HA5u|+h{~EJ-q1zm)$BGQe67p;D z+Q5&L(0u)aED0kcTzJUYdOmJm*=jeYkd&{E`I&Ss&@zj!?hdNx z>FG}Z=mD{qF3}1EAm&##-9ax{guWGd0m>6+u^QY%uA%?OwWYYYScA#V+L{B6k~{9# z=LDsQ;L!MPLxDfZ*>7ET_UFq1ZhQcK%HnbxOZqND+P)}qE>`6idxpne$&dWx_(p0C zRT^jyQ`Sg!94hzi+VaMP$>~>ou`i}}b}W{09%3t0l$3!>Q#1TnBS_=D<0-mF2zi<> ze;pS~aE0HofSvaM={sD?=VF{U)8laIOGjKB*8H=NSjk*|K|!f%w{&RPaYm|8q{NKC zIfz!8l{)nfYaPl$x4!|d2YLHqcd~Kmd^+DtJPh3`3T?PSoK_ysT3&$;hg*1aUvj|9 zFGh{i4iNY{jc(uvJHi9OUsFbT7vhln>#PZQ!uL-y8-JwBDk{E!`~{C26DG){!CQ12 ztS(*;9*E3R-*k>@Zs|C@qXk6!O}-o;l+X^Rr>7$Y=K=nhveG@++ctEMGFuaLSCg?| z*6_sma(wS+Eq&tf*w~mx`Fy2>&tca3!M~5!2{KFlx<xWy@V^=9^iI7CnO?Jawc{bF>c?A^W!iK;-wt;daCC9{QQ_Vl|<2VwzXzM zNsQ`?wpXR<#mtXMBirZCk0<^Ri1oLXS0N!GQx6oQw3`;lrfO><3kSs@A-!w4h|9lT9hu8PUBNa3lvv>)fGDw{T%hX!N9O-1O zb?Oa%x7(>Hj5Ks~fGqlWd1)Uz+fYjtoSiXS87wuTFCnw0z5{|tw$k;qG`aR;B#mq> z@;cB;!otJpX=$?o4E3U_jE*%VXt127I=!~uZ!lP-BEkG8$bc>AZyCy33MNV*BO?Qt z>3dbxT8mrxTNS3{2EM5m5UmDV!q}}$9=p#`Q3tE-@9NXa@etv=0Z@O>G;fjX_v5oy z<&^RK#`ZQhkeWb9IO%*|<;Y^%Ybd`Xi=<}^K6=aLz0nie?6Rw)n3q6f#YIGJLOVK? zK>Y?CJY}X9GeCv!8E`=u67o7P)MEZ#UT!0gI)~YbLClksoUE#DjP{DTI^&Rg@L?mI zeAWA)GF9Jucy<;~#Sj8!I+JH-1ab?Uuq!WUG2>9{@ zFxd0o!{r~Ua`>F6GRHv<=`+cBuld-dN2fpP}ia=uuZ zTqxH70D&)GoY%Vo!9=x=Z0xDkzbO#Db7!vq`8OC#2nvPD$jNy>KVHK@{#l;x7)>R} zCBKf>`rPXr2<2~j{La? zjg8r$!xxAvfL?&G22>qD0txwD8S48QC53L*g8}s;74+6%O6~wKd8Nf|*18_3IRALi zr$=vD*kAHz$S8G20IXXINbbD@8 zg8>(dl*3Pj*cXlNulX9f0f+@0L{?UIJTWFJs`fmR&vNQ(PmkCr zUy?;S&(hBh0a?O6!~1NNwPNL51Y}ID><=QakZwcE)jrMgd9~7{-i^8r-`Qfj+cy%VM?j05RfSXdYzS1g~`)YJsBM){=) zQZOYWW9iqg0o{gwfhZ2xtfrfUq$DuW!rxQTO2y@6Wgr0U%yAK6WRBa{u$60;J1jS; zs;P+;OoMWUv9U38=!59w&D5c)hKB3b07kML9=IbQ;^oYFDh#F^>BYqs2cJk85yr?2 zNQbDCMRiqlbga3E#KpyRZ8O#1{+OIR5gkzRdmI>$%2Of0#l;2MxhY5GPA)|Vh^+vN ze+S9v@)83BBPKG^YRkEKe}5l5TuTc-SsXqtE|*~!WK@7HS+4Zl-b)&4BrA)OI9z9o zuLi<T1x}Kiz!4H;ZJyu-Q;NakYUbMHMNR{yC@@{HMrF;`Cq&XK6 zAoVPn_vS$40GR>}4UG_8%GK2sDEt+xzFuC)^sD3qWawuncU_|~`&x=&G!ya6Bn)15-kK??U@ znJmH`@e=wnVo<^ef@iJu4IYn4i>bJBAFYptnNOMm)=(seFneHR&Fv>SW|AUG69Sd6 zfx$Ga47G6>)VrOz89sD7<1woTI^!Wi5HG3?$)KCYLg>+vVIN@7R*LzcIsP<#tl9nH zzuqz;Q)_4kN0{WT=v0&v6c9*2z*jX4`3w;&9On1kGjuB7g3OpyiURd*nUk(lcP?KU zB?h0W2!Zi}{N3phlI2ECg!tSL;m;5mVkp|lzWwOdbz`r`EQ@jcN^o!z$`aY*fzcb( zL;w*fnh|s-ln{&f<2rXB;)KJj*|SNfGJ`0eVJM3eZ~2v%7;P(9Md;NC0`+4xjEt-Y zK~!LFUYz0(15Q+lTA?(Uw~)OEGo{=xnx1D0E%W7PJFAg&~q7oqywEgV}|CgvPl!AtUrJR3_K2=0*Kk zd9?wn91S@E zzODS-fT$N?prf1ujZArXeRGMZ-5&YBZ}KBl3>Cp&^MTRHD{`ZE6@e<-^2ki~Xd; z+u$71_&QuG%1KW3WqOq9sRDupTnPuY|7ugxM;huPO$# zfPriva817;Z120}-~X;BS`3YgIqzNl6H87S^UI~@WD&I7_+|p}7>DHkvF>SwG!42E4GKABMQgMCHvH%A4QU4x< zPs^?Z&-NjK>J`rbxh_HE33;Rsf8&jIPzcQEH3dXc&QlkO)9f@B-JA!K{POCm%R8zX z&iHWqyQc$I^z%uuJU0>Y&pQ>Fo;eEcc}*gl*NXMY-}oa-mBh-DU6qAfJRmEhxn!`| z)-zH&T6iOR4JpSWq5;{VDD1_r;al*hvZ9Mu-G4>CtB>6ZG65Ss3X4Q+b_RaOY06$e zwrUrUV_Ol2{AvqDe=qF%tV`_nyQ+*#_L7FKRT(4i56ukg*U>Ym`J!?z*I%O${;UR~ zKeO8Vh0V6ZTT;F0dh(`9mJ59|)qpO6OyBx4rz&9g^-!HRpGI#`_hMw$rdzl|T;t3QbZ>ev5&FM$5yUzN7F@Q)twf;=JrP1CS& z%DqLRD; z&B&@}QrGh(2Jr0C3Hi&~6VG(uEV+z zCD=F?mG40dMZmwS7P|832(|)2xY&_4TthEHetTicCre=SI_5pClx$5+S)bNNIqUc6 zov<(i0&uU{T`TZn0*7x&4zZ`1Jz?D%L*Tt!4r{O;(NVKXwF`k=L}Twm+afs#;9xH( zn--u|8oj@DJll~nWccQg{g?1{VS(2dJp>ai*@1Iq(O--U3WpdNc{GyK3b(luczcDT zUrvQy|21uKU|8uzZhDXqf;YnXix`m@-5Nby&C0O$C*Nwb90qpJ z1R7ko9buae29C}8CDBY~FvfL19g=bG-$Cl7`=rFHAeEu$zOXm?k5&fy4xi>> z@Uqv95q-yq+OGzmy80y7{KlEYPEQ^dQy=yj-b6Al@4qQ6Z7Ah1dbA;;RMRDCe_Bh( z@pc@)FH}OedZsh|uKOL%|N}Bf3$i^lC{uJPI5a zyIa5plVnCkXwr}zkTuk!ol7*-gIw7{ueM>{0g09Ff!>v1ekv&r45PEDJ8+4Cgt)`# z$0L6GgwuzO39}rCn`bgr;nJUna-+UtA& zNB85}lj5#{3HkMDNR zFtN(hFJ~L)PTC=oyFfQk1 zn29_cc5moPpQgz9BWVw<7F|;NE}vPXpq9$Jw#TP6E?fK>#ktN3DuGNRi|VnP(3zZo z6AY}(s^-ZO`d3y|?9ZXfokttu7uXnjZ*1(h%L`}U23|0|7ao5@J;2vDuQKsojvv2K zVRu6r@BKCXjS@zRQ;$NzNaL{+&kxUh5bHobc53`?iEcNLCgL+Z!Ow#;rARPtAuhwZ zvgGe+Dod*FG1kRNrLX=W|B2@M>v}vlbWq?xqVWiO_jyFXu!j?1xyzZ# z1D?jY=v~E#9vsM)SYawduFY00%Nl;7bgbvw?f-3@l~L1#Oh{&9lDww#XQCO^a8$y7 zD4wo^!<-i`S=dKA**{+UvAaf>gi$dhbXd}HytO;i4~JQY8u$lY1TyiVtLneVRt!g3 z+#I2m=8vntFuu&CF3)Zk?mMfaghrFj$ITuvPLFL9i4>oC#--9=ixrC~2ds?@BU}&v z*5RXtt}Vv#@N_wSU!&yG#5*{jar4>>JHH=WXK>drm~MMN)&&i4zoCRRNSnZiqYksx z%JTAi7UK)GqD>tBrHz~8+H;0r?5hNyi(zXF z&*s-D=gfjhCux{pYrg4uut}!+jB083p~snD6LjUW#~ttO!c1ThO7b1>_RZqJl6R%o zd2@=w-yNW^UqQsgwR3pxzwsO(&6WOa4?7(kH(A9!K5Ffpsd3|MD*8)H&~-S;qFPLIvd+1 zWk12V)cL4X#&aLW${TY`I<&{#caa=}-l_5~6R-@1P1@6ocM^Hn75g#%*Id1-vsAG! zh%j1~xsFy2TCy}+l-cRMOK!5+{^WFA)#a&oc;2fOBeXgXt$3LxLE3&I`=B79jB%z<+^#XDDce)e|;cf6x#cNRz}M(Wir~g`H4HQ=-hW{ZwNZ~m61=Hq6XHZak%%>tQ3Ec|v-O$ho{pMg zx$>D|dJJ!(z~4L`)_?^I04Y0;Qw9M==rBr{+`7086T{n1^FO++&v^`)^OfW$d!>iR z2$zVUAQX>E1;eEOfcc!Lv|15*aK9;^&#%fhrIJxB+gUi?CUtS@big~}H!>QV@oa-8 z1N{}~iQ+39GnLWxEV;!dwI~TsIfrj%rM6YCJv=sbZ2u_b(@}Sodn+tv;e!UIZlht{ zwX5B?$Kh-svM3{9spD z$4xEem5NAWomh6tSJ~E(*0W}W!6xNTgq6<{6j`XDaJCAAn0Udw-T^_{=+{c@T;kU6 zmwtWVwn7=uiPY^(AVbsS3@#wCo1+d0IejBr9&Tg*lAEa7>Z>3PY`;EZ%w|8+9~*<) z{!!Y8<&og%S)3vZ13pOb_V<9Ru^L6nTMWb&kH7X5Auacf+>NaJ&T87Kezzv(|FvK^ z_ER@~oHPyx)F9XF%kJy-yN;X9?>uX`mL&`-YkXDhe#tL!hskeATCdf=r%l2lFei(c zn$GDcjRP-m_Ews_i7KhfDJZLE3k@{sp99~d*&__17I%hSAjb0SpNYQTr>2+)F*cyfrznU#SAJ2j1YD<}_d7 zu!j8N$}7oursn;-ll|W=fV@1^)V>u&%DZrQ3AOm9gYaXS>Wj?=ukv&b%6=NQ<(K)A z#K}^1R*qn*n;K3&L1ehLUU$y~m{7d9#)LCx*4f{rC{#ie?I zIG58`+}4>G^cX9_V7@MK%Sp0r(+F#VS*vg!$YPcZLmFUf*_wJIy>!})(Ex{;=J^S9 zBNiZO$XC6@=5}{Se>*gZ^p;fYqrJ{-aw4783x}K94)VkP=HnxOd@%0!-$NUl<%p@6 zU%t&yzaXuomf4>JMp*X!NootttC!Aa?74GdtAGF{k9$yl2yeJA|NG4(wX9UDh1-{@ z<&LGKQ?xF}PlxDAxf`TbJ%oXOO44Mi1*4X8Bz>m_!)j?_do&D+I-Eqau?Ii@8PC3b z#a4#3I&5yC!t#Kn#^Na$$)M3AOgDA!WrTzPXVglIiINDy2gfnP1P&@4o9Q({^p7Aa z(3k8^t>>G3YUtJ^`3AOs&Z!Yu9P>r&Sbg%QVpY=R8r1D$c}C$VC?BG7qlP@}u}51r z295WQd}Qdj{%9;rlwm8s32N~k)9pt;n9eDshCwrpXu2)Z`<|VL#}TZeTHLdguxS*4 z_m{oygeTdJ%bL*sFE8=_kF*%n7147S$*JhBD%SAbH*^f|_cJGDqx2vn>sL95DNVzm z`1vAmy9ShPKi98ZTge!$)n&4!60sLtZxI!LQ>Xn0#ZXjrb*E%j@76|thFZOXAzk6@CLx-Inrc1d8s^Sojhea`aY9q$5?#cPji!vkH@gQikgX&&S*Mi5XqT z+`Np{K5dw|8#FcIZb(`bRu};7}6z_w>|z*v8`R^+$yyn=t|%S$-p( zdSfT7Kyc`$eSBOIUvkZB^7NC>uF7vLt+^vN3XAPhWX1i2M(2<6hXPgo#t=CD?E~9-D3U zLv3dv8S-q=Z<3bP2cC_~Shr)cCP;aj6Hg*MY4}xF+OLIfKQTG^qWguM;8?grL4^NY zEBs&n-EGAq*;^Sf(o1O9!q4A3t$iIY|Dpu4Rs`N{`ixv4M-J#bH8n5O67yGk*b+}O zhQQ!YRgs*UV021((tpf09&w(;om z^?lyo{b%^C;RP)FDy|BYTwe?|;f-iEhHK*dlMpG(Rmq--s1@}c@@uzVVwwY)oj)71 zw;EI$AD`||R8=jLe-uocB3`g&q9e)xM{fDyR132{(fjbwk-D>SaJfYHyMFqWs|Y3N zS{Tg1pIdHO^fbrfbq`~AN7BI!cH}egf8@U00G*MbXJ`(zDwEp8*{J4);Y{LeA=Ch> z#+Ax69yX(QTeSuUk#y1gkIMVqQWmDXG>#ZGin#$51X4U8Xl@WcXZ3rqlUoi|vg(t< z1)3yNgd?{7TE|Cy{ZF8G67+q(TYB|@>H{XdK1IrP*E8Eva>@VN39PNXi-@BV6gcUL!zS+A)YG}1!? zelRPSW$kyAri)M%N_h;P{TX4{?M@UG)E&rXT@Aes_pSNIFl$ zqoYxG)u6E(^zedKO;6AiC;W6%fKcJe4N!gm>u>GUe-eZAzP&4IcTsdQ$D%GNzbNbpsjs4f<5BhI(+uHK-x_f&OASxOfrYTYquSr;G0J!-? zDo?(@MZ^TS*O2ltRT4(NS2@TC;O;IP9KA0p6RE?auodYCrh>fUvi30WUep_O^zP5h z+UyO=ym-kI)Njn9{a+#I^#YZc9g#?h^8sQ9(D6qOegu6}Cv6uK!K}HQ7D}K!^ZxJN zzjAn;+D_i#5Y<9)LMnZ07^+x-sMm($5&j9gc&ks<9a8Dn$33WEk2h)BD`{JD1>*BR z(uZY<&nj8J*fK6Ki?3C57sEtUn6;`Q5Xa-?x1(L47d{SjH-mydB!JuIM@V@1=(cm7 z%HqR$Q&UsJvLsXTcfDpc3YdyPa8QuY{UK)%1v(OfC`|bd-F?uIT?85uRV510rtQ*w-g50pPUR;u6)0Ty`<2cCu1#BsNvua|>ucc^i_rUmkaj%dL&=m8}0 zXczjTQ)&MuYutQx4@;Fl6<-Vi#hfM$2#;~z|6y|xZqs}0Mg7<3U}tiJ_-jZ2F(2>q z=g;1M|A_j5;}hmJTHu5TXoc`PLJM=WUJR~jVv3RY(j(`T2<7bDmvSA(^j%(xlng2ueH0rn|Dafi`x)AWvd+q0u&uk)X3Ri_ab!H!XWJou+^Vdfqj2qF zE?hw~?Rsmf-sAL?mJU>i0JN(Xex~nt@&MwoCoFOWyxMqzRtg`jnErg46nIr3#S~G^ z`QpV3(2hSpKM(pczzaM)JV?Op#jb_9IgrQ-LE#*9rR56y3oS7}6ZraO3TVjCDLGl= zaV4##+WV;+_)c0}vOcA0%e=@&{qXokXq+ZQ;Z&|sy4nE1;)mZ#X9t;!s*ko71n|>T zscZ(TZC;!q)!)C{g9!1jZxfOrCXeK3~!T!APvOH>z+w0^kTK4@FR3$B4lSc#Kbn3|{jnolP8K&;aJZPG2pJLfpDCn`_+VS) zb1N($1V6nB8W{ie=#KY-hL!ZJEL(pcek35@u+FaVy+qVXlkvU8Wr_dALrOC|U}8X2w7q)rDb!`f&XyDaBAheq8-3IS_Q)p! zd#*z`SuWZv>lR-%b}LGcKQz+1!Il^cI6aqE5`5&D#H$UWs!-xjPeB?(eGa~{Z+`Od zV1R0Cq^_Ies@d$G)8At;3viG^DWC6&JEr&2>qM99)&4_M8jMbUV?*qG;==BiJ3`(= zpOX5=?DskIDFkzbb+E8z*0{1BPl zyTniamG8blRE^=&W9J_d9K`%y3e{d&{D^1FLcuLx3%Pjy`iIo2n0d3H55h(-Tt%7w zFg4ATO(>%H01xB}G-=6(-gHo( z#?-{pb%WycC(4Wq*49B02!y>kC+cD%dK9`5=ISgt$%FA35CN+h*2oXGk~R`ABVzkn zc~ST=d9b{>274O9EK8C}7eg)(h0349|M6brGrl@mXrsg0r@wzx_b>h(swtAk*UgxN zzeOeZAiFc^?dhT7a*)5jZZ<#Q@NbNooe$f~pRW0uGV%48SKiIRhfhkMqhD(9d6*P&%;B3ISboS4f{}saG zqCX9Jf)Z5x(c14f9<&IG>eMjO2oAigbi<{0L1c`MDXjRVUq&(Qkzn3c51$9{-!75# zC7!cUGBYz*R8=*iqhMiyZrXpHnU?55z8Lj}Rf5)g(DsLh&uU8x=(-X6 zp?BJO_+DS}qmy@e(O1R|{DQik`^uv$4pgvB!7SQZp+x%Wo4BJAdDBy#55y+#Yp#D8 zObJZg4wIttCl2d@Hn2f*e?4{eT9ATYQMcc0M&;$@F(vPVE~3uor`DC|ckkt_6%3`c zY&c3rc6N-77HQ^27m)_*PND%#-;zOrLvti?y5&4u>j%APrh*_HDpflMob~ zh)yq!Q7H6Bae^-LM!fHO|F@-)uwGrkR}K*0X_MtmN+cL!NcBo$JwnoW6I#xLtQj6O zuK>f#lq_l3iDYn!Yo-8{9NwlzI)sY|(>tOUv2`ps8sa$gae=TK+wj5&=Z^+sOmy_` zi(7CG4fJr^kumc9`?$%ovZ`M?JUlEbW7@X?=Y~sE3!p*l1n6<9jL#ZDXz4c$Z0-8b z0R%L80&U5h?wEVTck427aovWF{X~S2uL}pD5mWX{EYI(R>4Qsxu;%=bgUh>D78n2# zWFK?bzs?Hp{}8z=Uc)HbwIQkE_GqiV{PN#Uw_LeZGeR@ZlwV%{{aaC5>h-0r&-e_S zxim3;;tp4UA!aM>I+9g>M21^TFcy#9Cx}>q?tGD%h!RZ78Q*Dw)|q1*YcJFemY^uK7`x?w(xBxosXSw z0=;Bm1oIQ7g4EfsUrsy=PGJ;>-3DSM^VZ;mu!>5&N#z@tuK~8>tpc)KPj!l?huE&0 zv|tdG%&rPV<3X5ClK3^yK(rsRo{f;CpcbrymX@ZiTfw`#y9f}_#R*Q@&R6R4O8-KD zKy+|!>XWjFpSr$$ZM)%|z;{NDsV#mFMeO-eAw!pQKA<1%_Ad86_*~cVsIVE(8fl>40{rGNsiibBila9YF^U|x} z)i=RinWO3LB3_bJCf^OW#tv#yOQfEOsf&vXa44-HKcCD^FzSfUF&7*l3ZSC|5B3o1 zxTKabHQFHs0tB&I!Hbhsnx`z8U4A9xdD&e+27vZ4hJL)yP7R9^}%M|7zM!miy>6ImQ4SQ_y4%dtztDgrN|W{K%fNIuy#1Em76smN0SOLs2?(~@~PXePzXYt{$==?lq#p!Bvmt(kAs0f8^_h4fre$S~s)qSNJ zC6UcR$D{Dm;?L#0#6x%W5VQ?kLC{&{7}0onC8}0z-*W!if75qxF$7#Fl7LOdO2hlN z-oWGE+IQRs-2c@m42nSBz!ghVLqm?rbVFv#UjIwdbBf{~@ox=ZRVYv{3{3eRy3Jvf zzMuEI4*V6M1%%XhE7%)Be4((_ieOFq`LDwza{Pnj!V9W&K>l{$b><$k4;b}XEM1~> z%eZ@PpG1vwCl9yAmayT|2P)oBQa9Z5@yq?=6;njlJfA!M5hldV1PaPMOPnlH?4WD4 z2)kgXl#gMOdD9fXY7+>T-}CvU3m%6%nvryB?bsurZl-SCbLR5X2& z((F@NaN^mAul(e2yaDN$#cULB;*Z7e$*ljem0u`l&(N`ZJEH^s7l%Kd1SlqnqVuLI z+=O%f{@_Msorseq_8cYek?<}%mr6D`y#(k|2iKj`^_~pKmp##Qct4P^qHl9F>xB`= z4R3RL*`s5ocF)_m3Xn}sEAO>&5q1xtpO1OAx+2N`x3O*>J#m`Wi0Y*xUiV@U%}9=g zWbe9atW36ZZ0`|w;J*c5{vNaG^uKcAiE3+erYek=iqB6K*7-uj8j47Gq8XkFWNYW- zQKJ^;efBvYLn!~v<@Z^-9$Dg`iKEw;v{0&&L)74bi0uds9ilNp+aaa=`RrQa5?z&9 zF8uOKdJ-x<7(J|qzlndxpn!H?_smkOGqHf9WZOGbZH;E(b@Cluk$x#V7r3u;wwM*T zzg&@M(HyT4soR?(PQZ7K0IxE@|md1f)|Xgi%3KI;2CoL!?6~ zr4dOfB?LsJMYwyuf8Dk2o#hf3m~+lsyZ7^4N*KBSYava+k0yI$jlg90>673siGz{M z_v@oGF+oMckxIlzYYBeaD@GW@=-)q0&^2P|tAaA_9hA$S!I#@VX8`LSy(4X-rCw}S}@RYmf`t=Ki3k*TaU ze|B^9%oeMEN3gHacwAYqz4x{xRhiIiYw$)`2eXy2(C6@)D#BBP@d(?6#rWP91}$)kYkXSOmT zq%kls*;!wuKE($(U%$o6WHmT&W83tMF%w;g`mM!~|H6^gM^-eBJ4;Z^==~e>tdh3n zAV@PZf?F6(eSWa@LsGotU8T_-t2ZUn>E7`8H5qS6jkgDWA=myM{Mp zzN|%AvgEOB7$egkuIVFv?%X>5YBp|gr?9ldNUh9J%CIz@Cu}x$eRb&I@Y|!mzn(nuS3dD<3k+CvTqIfc+(7P4 zUHg58bC>!)7_EmvLSO)tY5aGK61YXtRF5O+b``cMo534i|F+++@}p{)4`!dM7Z%i( zl-8EOoh;x^E~WP-OfEg?K(tq}jx=?+Mcr^~y)iO9@d+EdKN^w8xfdubXA*UASgjTG zT-SHc%V@fNo}Kbx{Pny)fOynu`ga5;x1^mA(YZ(Jl_<6oI$R)VtS*okFYciHthN-z z4>z!#FnxL!!sd5@Xun7uB|lgAifCs|S^n;5M~=K}!`4MRvlda)xJ4o`yz{~=$$GX- zTAg)_zypRb*_~z+Opu!^8B0C8pqH$`q8@lBBCpjz&$6_b&)CR_kDIVfJdTxYn+5*K z3c2gDeZA3t4e@{_ug;@Bd|MbtTHX=$SjP16)v?Flru*MW=P`S{Ci~pA6Lw+7Z^t)e z_uShnk^7;d-DEP~;7bM#4JwC=uZx*|eeOr3h>KwsiO0Mgp2+6;0zSpeiWLvzA3`tn zm38|jjLICT4b3|A{eJLqKYU>L*Z*Z+;ZA;x{7Virljl%dOI_c`;U~etQI(P$(gV96 zT@U{R9ek6znwI(V{?J<8*Q*thoDFL+VSY;Zl2Ih#QG||PKC7;B$JHh{L87_4|+^)6E9xx(AXux%d?9BhKA|0G%KdAoxJ|*Mtqhf8L_9C z_DWn+rB+<%rS8kN8uOZpwMWaJe&7yFUv{$;X??(UpcTd-MeHQ`?%QaQVl-9>;<=6J z2P)+VCOX9R!QMPK{cE+W@jIui$(K9O?d_MO9kH|6^f*5DY0RcV!)(&Wqtc(}%qg;V9>0v8LwQWYfAq*CV> z8pOQg58@z0UcZs_&bN-!>K091qJAv?F*p%>D*Ud++(f}uB>e^4xJ2n|iyVaI%Iluz z3Mqfqo9AydsB8VLme#p_lsac)R*h$5htGHz`_ST)XMiKObTTVe< zh@0P}t=8W(B{s_t*YXFOj<65}24cqt*k8v(U=dK{M&By!$k0ix=MsOXtR>&ctl%g1 z^S2xQ8=ZSuV|Pw>iL?Cc{%pev*u?Q7^7!lXS;dcIueNy6A{Xz8?V9GZifL3#J8<76G&>$M)Z6F1T3R zE#3c=6jxq;ch=%it>K1)@Sm&^Do@VmMa_Sv@0#1l6EU8qm&(YQq_gu|pb2^LN}Rk_ zuH>csfxVN(x9LB0*>C@JSOo7F4kq+2hha%vs+va`E*TYFf|Bxc8 z;_Vc9J&#ASyyrye=Njq`=YpRN&uvsPV(qEwe?|(@^M{dNfAaUu$i*yU(d84rK6KwL zR!S))#NblEIdlMj4ZipX0rKSJ~8{vh={U+iB z{+TAdg(Ai&y7pr%J+(OG4pY$@j$3|n{1XR%gXZk4w_cu~STp|i9R`(rx=fh%M!FfV zlX~RZ(LA)6@<4kQV7@`>3SUGP`oo}SjaMsO5<1)<85+r&Td%JvJ005c{N0=MeuItqgIzr!fx#2fDu0G&LtT zS>&?>p)u_G^>YBcI)`N4d!mmT+iG1sw)1tH6peQ^4j&>JZe+9BbkMR%6VM1#q^qRu zGdf&F>dec@Z7!8>ggn1{TJ>BA+1d+%Gl79nZAC@JFnm%Pb{4lkK7=)y%d0kd}uZhhY zL4=RJygs?%-jq@`;7qjPxfT)S^qdSMb)Ns3`x@*-Zm+o1@Ot81KvwY4g5T=O%5399 zfSvjR@Pv0}JGts*a7m+mby^$;+M}PJi}ZUxb$v^VFyz(ZAS&=e>T{D8KkiFC8Fmv~ z+&wgNu|Cn0K&ZwPZ9=;jJ}xe_u|XR#%(ENx6+@3~WK0a;qMeN8--iC`Ab_hV=}G(` zQ*st=B6EgS^ZIXE)A+k#Y^NYWMCtAHqOqJ7nf{IMg}$q2ltV?=uGa*bF#hU6EWKKU zT?&2O=TpX3NkiWNLn+|=WL=8k6Eyon6L|!g06#wjOFscTREm%(hfjg6hSc)ad-H7{ zR+R%X3imr3-%-+bsc76p#g_|(5ueC-*e9IuCLcru)LLy%tn?v51ffIrEo5`xD(vWU zXlib9ni9Bj1=CR7tplxlfHsKfTvW45{4ibOZxW@cx4Pz_@b=DBDJ4De#IvV~1rHbu z*UhaSwvZK7$Sl{azb8c?XsM~F(CGQOFKJu@>sgPr-%M;CJX*(<&d~avVo2W;m1l*|9Q-1C{+MHy@ULF;nWzI=Q4#Kgn^T|j7vPy`TxFjy;BgC79~ z7o6BefJCBD=1r5N)RtN01&^OZiOJ)X>aSbVinNd~3t8x|>F4kl5B^O=85 zv6pBq7itmUusW3yF2yQ#Fx7k2=vfb>Y?+|IWk21vHC zumJ8;7}-j|Vp7RbLk}$a<6lx{=VWsgA6R`S15YfJZf20hW#L4SdC(MM(U9Y|=iZKm zEablbn!~-i86656yy!bx$0d6V+@ce|0u3e_?R$83UlN9-$K_>bH|e3N2=Xq4fEBj+^GCEKXQ6q)Q!-eyoQn@_7%|_A3eWkGs2(;P$$2SWPgR8eLP}@ zeaH?#=>$1B`EYc=NcN4337s2|2GxT0e@IvA;|o5oy0aI@msX4SHCuypXVNEF1$1G1 z4x*U9h7uHO!AI?`UV^2|01^QRjI<(_XOIjy14Nw@zz)s4!GX*J@X$MePbTi59)?H! z@m?L;~#l$XvTcFM6V9oMA%N%kpcHQ z9~W0|^GZ6aeA0`%I22E(0)2P*jhUM_XVoI-8K@AhY=_qLj4$lN3#s6ar2YNp^hhCC3Rj4M-*X!p>S zyNwDbYYF4expG%$-roP`bpE0G+=pS#QR{EkE-?Y3iR>D=JQ;_HdM@UpPL%-k!_BR{ z#aCeCk#qUkTjv95w%#wtJux9&3D$~IOPO574Kqee(;| zFEKk^kY?^QR*gf7dFraGq7ldOt21X4Q<=BjPEVWztMqoG@ewld)~7hJvM&uH&4m$D z$?@?hJt|ajb@k}7J3t|(mJE|YbO+LVxZsMAFCqXM&eBH z`gbexvy)?Glhe`~A37xPTzrwRIozIc{#;Hj!%>rFvTrQ5YfvRGg__WLe9)$X`pLF; zk75$Zj5CRR>J}audAG(^`P(!gx+=c5=Gwn2ylWDxYy7VXHzTS0d(m`s@GQ3Cr6p-N zs4+{1)q)~>xLO&~fveFn1u>{ceRU^U%Tx3^)~63*cL&yyazeGFt?BSkOgKh*)gLJK z0#x!nKz2h#N|HQT>|Z(jqw-UON4IS%uWW`kdfm`L`F*}NQo36tRJ4GsIC zcvX~?G}FYtfl$_ev1-aqq%QoPxpYy{@%njm-*vC0n{dNH; z%?_j)px&8P_yU^N#owiDjvn{?X#S$>HP8V%(NA^|51nx_*aUrn5b) z6F)o)$=rJDxhlmeW=9SVnzcVUNwEqt1&lLV+M~tCKcktiN^@|aw%#focu6lV<~v1@ zNl5?s`2zL*$y#n4!d+yHlHKmrFI67O7B`9zCqOj(2$`q324}yu{#VDx{v|!HIxPeT z3p`quN`1)2J6H{*9^@k{f94j$XF*IjzflwNOhXvlf!1$;%n>nvySH68GMpjv6Hq|( zZ*w(L$~}p7PiqwjAoC)bsQS8@#j;zIgK(DsSrFC`NB21u(Vh!nQUe16FmH^q?n^~l z8D>qc3vigBItp5}HJH;?W7e0l49#sPADtBBxdztSB;2+l4DlnoL7tvOH>>w>O=LtTCPOE z#Fp`xs)myN-Y503%ebA<(16|udjf=ryGV=JY|El#;21u z5Bsj8^FE*7xYQ8;C0`}r#WSilUBtXLPr?D%bAWB3FrvX6`G#qv(iWe6#PnR2M&Vyz ztTIl>?QjdZRc5335C-<*Yfit+a}omH-Zr78$UUf%c)4^sII24G3VuqClO{0)_uB;>*ER9UZS2O@?su zE2O*e{SilR>h;G;bDLIKQAmUid54N)zO|zi!t$p+yX%f8N4>?xtx8gT70KU@stEt^ zjX?C5%H#xFT0%r|p5S}KRCUrG`w$&UDRNshvR9uFWR!oy)qCa1lmvML7DtSJzv&rTn4^LW@q@=R!*706^X+5oR^v6~U_(7Y$Pu{=xu@!LIuM<8 zx`>;G7Q&v*VPtlvAITkQaj$D_E2;J~C1T;3U@uLX>!1(UG|=kA8N!#cc|19KactGN zCy|%-oGN)yLno`VByHE2Nf9jEzR_glBuNyf6o@@bX_CS;4+&!$D{oC|4C?h@n6!f9&$j5Z4vg&FKI$Z*f);pgcMh%xKDRN&< z8UUytLZ@ZTv!(c8{9^Lqy8w9>ghEBA(p%4OgOKRFY9&teXTk656|?$c(4z2RbxqB3 zUmIx>51iYm2|k47wmP}1#q=|!@S20cpIe_T6j;d-SqB^6V_(019T!Jt!?+6);7w7H zQHy8>wg(QW6bjLr7Rl+bT{3NddQ-U#Nshwm%%_6tr(s&a=PXmXb6tZR=cyP?jM#_a zRi|o?FN)Sl>UVdpA`l9n-YYq_?ceZmhUss3x&pY0Nmk?x4Cw%?>@G`1sO;qA1cIaC za-B!N;vN?+=rEBaWjn0g>f63n)-G+H;{Jo;VzyYFJpzslZSKq6fEEF$NwLgVle4pR z^d>PFKjkJKP_y)Kt`S6C%3t`kliw!n=@pyt}eR>*x6zo8= z_YtDp+zy=~mrxu^NI)6X6Hajh%LSwtMx}gd6aAo)Uvun66InQqD@`IMULMN8j#wN# z@YU10YvRB-NkRRQ^R+^NXR`#A@+Yu=ULC!I`UwEA_~zNX_q(Q#RYsm)-mA^L~;T*-2^{`&$<3 z^HWhPI9UGhBtJLCrlnX;`uZa#_zv11LH6`2>sWDdF{p+{uFoA!|i?0J6KwY46DW-0c;@pWj$zQ1*A7ec*RxA6(iBh;WrjrSO0Zj0{CAZg`Tr-q{q$PxbmTQJGNVkq6>a zR!Ix3;Ku9F-ZW2uIA2mH4=NvLU{46TML(`vR7re!1EHJzRthz&GKe|FGVctI!`bse zei$Tt&I4WI*sFz3&BgrcXj$~#gWd`O3-eDwKg6frYH`ydmhzRf(Y{IZN1v}|d6bDY{4|`MhZxYCzft2D8ql!o;UJqw<_!OVPf1mYaQeFDLwE&pw)F)Y3clgj# zuoqYKYM|-ZHAMxu_sOxAd}3-{-IjE+Hz53sl1CuO=j+RGP@-xDdTuTM8)rr-r5KDOCtWcx608?zIB}`mt~} zn^TeEPfE;EgJi18imb373gg-HM}-N`p87|O4*zZ?;taej^b(-;-BAa zRdQ@dOQIu3zx`{0K(KtXkwSg^GP7;4!G_b26|R-~ae{-fR?V`zN z^Fva12p%y>!2ti#o-mWji4jw2WsZtthfkUl5i>gHkWxfKj7V!`(Dxh%5iT_hTlab4bBO!&3Sx zF$Mb`<%$Cj{(Zx|7cTo)h`9cq#x;k!J4pxm?_=-~{NX7`xnUIw!m*dwh_@@tQr!j) z|4e?ZUb^`tj|at#S!2y-QYe=u&mvpp1$TZpq%ItX`H*jh-rA z=4q!$xC!UlLv{M{DVz{mu^J?&z5mi>0dF#_4h~B&A)dm?wEULKjFu}Ibf*(1JbMPy zn#%sIx{ViMSuoC?4?b51S)EFMDb=VXVF+!>Ta|FJj0}1BAx8>A(0O6pNszhl6zM`I8ue2R3VW_s1oliN>vJV^@V7cUcp?tH=;P{ z`*0@oC@j?8Z+tih0I!iRUqXC~9Dt+f>6-y84p87ew+fNuV=Oa^g<5(eE+H`jQKi?f6|6f$z+aXd0bTF9@GhxnbGhdQfO9?s zL!7idW%Vr(D&#ur=8t{Z@ohpUI(Kympni=Qu}kx6>4}8K_0)ED#)eNyI<1o3-lKv^ zIWBpMjbCY6cMl+g!L9es`ZzT71K_ZGM57s`9(_-{AH#CZZ29pw&lBgWHfaD2gs5yg z07(N1m7j(x^>C&&Y?kFQ*XA3Dc2qe-F7{PqR-X3?6@Exlv-c(isu+s(9CYAG0aLOP z3QXBiNV`@rdZ4Sq;P?`aN{vk99bbA2N!uqF-7h*i&gftga!W&?ff0KctQH&F; z?e~-MzJURzsYNcvj_$*ajNthy5QSVz%6eyh($RLg^yA;f& z&r$I3o-%H96XLi5a3Htmnskb(FpL8IaqPCq=ho3=zE)W0Y6VJ;HEC+?E9?lwaTwsX z0u2MenD0P*IVLvt24Lr-9QQZIxYT@M&w;ND(AVz)9KV-{|8EzAjW&aeCh1w6YM4X0 zv>9gO_T2+;P1kwZ^&uXubT+hsz!VU*oWl7r5lV&vQz16CoAv%tLMY_sgN zf0cSV#2$rhG($s1l8LakDZ)P&Oj|Iqa&-Y!Rb$Os_Zg$;uh*P6?$9%E2Z;h`0s;GRbJH zr7Hr(HByll$a%i1mJ4vgW4*{cx!Ja)oK#_ll;)NA52S+1R6MwBNJ@{d+h0)Ijmp zm6|^T!BH#U)h}BY5bfRN;6}03Bw|T(mh;!moB;^1h-t0T*3Hg9XrK@iyME(Gh#-G~ zt(h7#E@GU_xti#nAtCJ4P7RMjTv&y(WRoz5xLde$6WB`?*40FN_icGl#h~AkM89jj z7r(_^vWmFLkjITO(sE)6WJcWde%*}LeL(Q+C$R)x=at?qPA-390z2kQdnyVai}262 z%9X-piE%M54Y{!yf*IYJ9Wf=T?k-Qw)or!{@NvE^7H6LH&&fM_o{;7 z^n&OX$36=I0l_k9Dj+6Dx&?zg1KOjz(Vn-X=*Vekl9Q6STQMc%Af#DODgh<1D-0j% zf8~9)>Ro1jZ;a(n@i7>LN_5BR{dY-U5;>%$R@b2T;tBweVtltGL1Vy=obCt?UdDi~ zX9-V33Ga^YdMJXZhc5cV?e<8URJbN|nv6?cgB$@Qw9-D^BfY(4^_F6T6DLS3QK_Hu zH5_zR^dhQi8vnl+2m-(+WMa}J>xJTLGeCidxC#b1R)_{Y3P`-tZj0Mbrh&hq{qJr| z?NN=15V$e`9rj3+EWoN?rG4-S; zm;2~qS#JbEbBj@#&*}aqz&%5*LU0&il67a};sT};9>ep!rDe>)V1x5}!L7nk?~%$Lr%oI(`cT?poz`lp z^t7^3v3CSp@SKs9gk%?(h#)AauAu?Qp(nsS!ik3ErD9-s1ky_}3~y(?`H$7bsWFJ{ zOt)oO*Xc?N48cqrz@1N($v}<=6cnHk;;>J`3V^GALnumS(LW!m-vRrT?{O_83&3mV z^K$?k)}eNQnZ1WXb%Va=Bc!?S&TC>td@LtMk(*>ghVqo-N0|oM8VSyn8|}J$hM?bX z@IU_^{Gg?$Ps`4>GBM$Moh|)v7DAp7v9AZ`7%*~E0yS)G*n32W4~hVMyd9V|mfxCV z3G#}H?m?5_-D>MD$dqLAf?^8Gpf52vO8KUtrL{BhW(3wBvPA|9Is^hCrg(Kxn)xa6 zWC$)!6;J~-+#)EsoYO|Puh%_Rlx*mRAeN=`T9*AatHiyJ0DtPYGwaY`2BwR};S~tY z74kt2sseO1G8cknfI`1~J9b{z9RkIS(k`+=XK(*}gr2}E%Qmy!TF9Khp2cHNeD!J! z;7Z{`ZTsUIQYWcPin`1=H=~ps8%Mc#;MB(fdxsAw2RrdJadGkMXM4BS1EN*n{;2>S z4TzD68g8D=7(iawXwWcq_ujqlpvD2*_@}LhQ^O;GAcv^ugU{t@?)MF*af)XVDDyEuD(d6Lny4{*6qRcqVH8PLlJO9g$eEMSgV zcZEXx;nga7cmhz}KwPq+Fj043CwJ^O{Dmd#QOKB7OgUi^d){O!%E}(*@BgJhe&B80 z)P7-#r93oey6@!&<3cSwkcC0}z&cJWNCy;$H!X-hwn1z952a|OjU+f1+)Ow)IG{Ia zhyQTij`3z;Rq%I*&MDcN`?ltVm(e9@vFs2Z^y9&iV7$75NzCfM#(lpgg8>DuebCJK;N@`483MRrb<4DU%pg1qDd#^WB~kFQiIGuPXiq~ zkm=eRf3Ms`jsmP?SOurCJZ1Q9y5g>JbY54Fdm%0+E!Gk7Dx2i4tP5n@P%9p=2y0Mmwd;4`r7I}D=)Vz22=F zve2Z{0Ae`;rein}ciX7+>GOKqSgUICF!!zK8@PU)y zNej{He~`JRjtPdgUcjZz4mvFXsBnl&Rc_tKrw*OjN3g+$>XU$!ldE#}HQV!=;X)SRi2<+SLjt6A%)zH~rkKuW4XlpsgL_zHRPZzp~`>4kMdRzGr~$ z^vQya-pv#4FaxUl7Z?-(2|gmK37KTr6Mq03+~BA#^slw_HH2z81AAGJwUzvm;dP)* z<>i^n1(e$=lf+-TdVeb^ z(PQ3WBrHA|H~H^WOa`}Y473Xx=;xXohG^DLYBRp>e(eZ`tQS0(R~E*=L1Vwn0}TpB zQ*G^0x&7)q*t?d=hjo?i(oe8qnN|#7%mZME5`@b7Zm0hF2sRc$DA_%& za*LK^HYBD2{uUUo5YZ4c_kvRnj<&M0^1;R!Cx{0qYjP#pglZJfX=E|5!0E4Eu`>Y` zLfiT2kEB*87Ye4rdj<7R(+561xWMiKi#ePE1`VY49!{+sI*9sVA)fL@#4SlCs-Qzd zet=K`#Y(dLwz_%`jx9U;k>CBDsWRFR$6!FfPQu{jkNi0~Il)*@a9zmDIXP_se6tZW z?%VX>>Gb+8bzWMxod+lV0!V7i1B`*80RAe8(3b8yyy4rfsjBK8gZ&%-Kd%UaJEUr8 z7!W2h(f+Z&U-m+#Y|3m(TsCw%ZuIts1sKDJpqB~KIK{*~j`xUvz_tXCeKS|7F`%W0Wt7>CmRUp+5ImTz$5al1-wu?Yl;q^F zovo15K=LzeI&=n`YVZ@=6X47PJqAeE^sKDGKwS!|mI%^B$9gcaV3E&*oeO50kY%fh z$?6=xpkNss>243uW~pL!4AL%if>-@tS8`me(ZHKunvJR>2&i=wvnBe!HcMA)Qi@;Gfa&xUap20f{hDR zqQF84HgF&?rXX`c{%EF(=5~idb0;uu-a?@;1X`evYQ44q@gX541w#T;JIxsV0s2I1 zL41Pp0cr*&(D?fLxeL&ppr&c=-6hB69?478{Q! z=fNpJ)py4NdBPsXx`GCF_yq_|e&fe>bShsavFsF}P7XE^H?TrBd);;v0s2UgGq9@f zfJg`kPpV6n!PQYA>jkSEb~wh%=il5K>dw=o47324};mQHd=!X zlUb1n<1z(NF8Q40zdBbu+h2>?bZ5A=pY&4dR13|4oUJtmjtuGR*B9^Afr1W(Nmnlv z2QoEb;mU2PZgYQ|o}yZ)p21+BlQGD9Z$Lo~?G>{E1A!KwA1ZnVKm-a}yOhD#6eJ-K zxq>kWr}hiXJ{*45*6)}QNTsa~oU<;|N2R5APx=AiQM)-o~1@O$?R3_o3F=@*|q%v>p->NayB z`7k{5CmQz}qtBbt2LH&i30@56AKSHVN;@NdK6UK}Net2YSD2jFwhoDBCnpTvG+2o_e->Jg1XHUJJWWzd z3}q>(%ez9!;3hjY%!0l**qIotw#3%Tw|v1C4wiz5W$WARbaAY(u2DF9wfD20{2qX? z*^}et7pOoa`~J-R?Du_r;N2QFm_tu+`R!zlN~~t{^Xgrh_3=fhpm_D_6}2TLBV$Hd znyH!D77;c3J}^f?O@{9Ao0cahp1IA2!YQ0+|16QC1??|S)Mf9PN`r+YAW-@;dmMkS z@R>LS5_UW7H0$cqavvlYnF@XymvkoAPZ@A6GL3xJFkb$?+f0b0EG_q$1l=!&XDYXy zq|~F$a`gob8J?NxY)z^+nB@}Y5Rsp{N24nAizf+_k|&F)of<;*`3)Y`hN5kyGkm7B zBwvD7UOdU$cJ*=~m=R-RvjzfhtB-f=>wL zENyXdaUhl+&eRreACg!80FN8CGqA&CB_`H`&jy+zr6mU@91}gTw9KlmQa05{79t=f z2KGl2a7N(HmdpRZZU>rBS(|P&)X2ng4M4qa43nHVFl~+I-U1HM4v-fZ=1@w?Ffu|S zA|eu!MG*fkE-oOTU;Fuk<^L77Gng&)V1Yo1Q^d=cTkuJ#>m|lLsS?yf2R;Qc*#4Z! zeyQ}cA5%XGJ-p{AaVx`gwm0>`b7`^qw894;P%y_0qeKtyJrH!Bcx6`c+tO%)Uy7kn zrEC&;AJuSh9#mo^IQ2;Xjb5n~q12|7v#ub>w%`4co?c!(-QE6KH@r7=!J#cP2pPD? zOP2ij6Fwd?7d+u>CYcP9j&apFj*$Bwgu;dXZ@(dKQx5hyc(;;Tz$=;wAuNZX-;A_C z>LEwTsH_M6s^7UI1i?`fn{WUz^f|y70}46@Jc9PeN5UvRQPI(vuZK{Y-~x*UwNxNd zK--aj{!Q}{lJdY=LGof16a@vLr*LP*#3ray9wrE=|ApvQs+<>3pGWsY%$$L!CuWwH z6cz^a!UsrHX)Djb9RpI~Kq#G3fkeTBakPUeS{GDp5OAVEDIhRv=7VekIy{=vC@3hF zrX%WR1lRnE0bd}M4kLlO7T0zWp3@AU1;)dV`3p){g-8~2 z?`(M&94-c{S7c2R;2%hKnd#?a-cl)RO*yMq|C+^iJCQLghRh5IEPzu?U0odu8=DvG zw}-R!V0J)(z#TfrcGm^@=%SU8d5Fqj>~tAPGOqQ7z;As6FZztD9m7-X=WT0DvBsm`}FXFFk3NZmF_uz6N)Uur)48D z7G-tRuc__S#U2zG>1?81-Yl*894Io3A5mn?xKtiWm~>gE!4g4$q;5M69H)1lRZ!^x zF6azBl!ko7KtPxzRxJ_K&6u|xb8#u4QPf=;qC~ekLrp9riZ%&HAc*)36-6Cb_EPXl zBEG^SQXw{it9^7kDx7xGvs#6|`4S`aJ4GEAl8ie%ly>@qiFkw7Y(9A4O7G+8SMfIZ zO!?SiaU2wA!_!GT(y!8gyC2wXTT@IGB(pP@8S4nq8>nz+Vq_F-g_HJq)0?E1Uv!z+ zD!FX%az}JL*QQ~FslANbqBqIxzO-4z=ce;lJuZ*bkPR~V3kFUyNm@QC9}Er^RQhjj z5*G~Lq{rfGdpe1)d&s zGEvP_y+`V-d}|7rp$3`oCM5TDXnmn;!Mf$lf>?xr37d`dzkCyB>D)ylCy8Y7qK>-s zx-H+Th4HQGf0;eIg)$Z9l*NSMm6Rt(^y~wh-_WF_)urzhvXB+hk*LJNHppoIS!c+d zvZ0j!qDf@oB$H0(RkC1T3y;AwY?r^lmBRmeCjlijd~>U(KKD~7!{sD7?83_hSl;$0 zn>KmG$p;lG)(8atS2ZO?gG;WfwR!{3>DKzCPn9vIq>&o*E=t{?JYT# zUGH*sMk{=O@R_4rLElNtjEROuPBW@nK0?`~s`sPW$EXv_-*%1?8f8?8+9gx3j*433 zE?ja*MXnm&><^AxyeY?`gBEg5uv10vjse9r#-f6dNs<-MN8*F`5j1pmRz!bG-ekqg zqf5Jl!c1E<^Zov2YDJkIPjq=1y_njqzU-VR>;K}tO+&5G)jkuGvMHOouXn{}oP55x zkT8BSD<^?>>|{ZxIwgXJu1GEeos>0BaHkO(j8dfyXp6_<%`)}NxTPNH^D^E1%2-Sg z%Zs||oHVrbH{~%Aqx8pSe|7FBO~J5Vks3Z4P`PvRS=02c$6^(^{K5|B#!rSX|5)X= zh5X!J#-tTK6EW<*r1ItCD3bl^{rhtGFXS#e`X%JAQaL4IRHeLrnGq;Y!k<9@?%`R+ua&w2?#AJ|@gFsb|m!c?t*{@%m6r{Q}_)^gXC8zEV3d>%gvjCI9ke zmjvH+f4uj`3HL`=!yG(4JwZLJZt5$r3knY1URQ^r&c7=z3TWU&G6PUU%oV{^29%A$ zm^|A(qL-vuiod4T=+Q-b@JK;Wr2t<#z7H4aB|8A`=y!M7!K_xVb?7g7Dk2=4mYJzF zQ7@vB1!VI;BPI45Xa#{h$SP{yUVH)Iv)I^j=1+j43L^F4G385V0$~oENFI>ufG_MmvXu}VV7%(<5=nC<%YP*T%GuPIwFCBu)M3nG zQ)l%1OJ@0yYDk6502r8C(^WUXHCkF)LZfj;sMl361-O!qqu|(jd3t_`Wvwz0fVjJ` zkFH@g-`%U2=bxW9Pj&Kfbw@gBhef407ZO4AL15G3#NE+fc+B9u;N4r_fGX z-2x_|OjX{fP(d&Q0+m0jE&+op@PvhRv9(Il z5y7Zuk%Y@a`_>KzP~ef1T0?q_&zXL4$NS81MsfJ<^F`6o;BpYyu7^VpKn6q z3G$K(#>tO&zINQ;5fME(oVow$Uft~>&wQwY zndZ-jEu??jz~KgDlb$?j1sU~p!2S_1Plkqt{eWzqO*c;Ddk!C^%2S9)Fi1I3K@bLb z*&ub}_ScVOB*$Qho=WRewqmSXPj78`&$4dW6w4LdNfNN>pfpqWPiDef)SS%>}~LkS8W diff --git a/docs/src/examples/quantum1d/7.xy-finiteT/figure-5.png b/docs/src/examples/quantum1d/7.xy-finiteT/figure-5.png index 733496a0c3a48294a87cece46ecaea09b2207085..cfd09fdbce9419f50e267c125f6fdc2415ee8473 100644 GIT binary patch literal 40664 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 bsA(eX+TArd{Iw$%pAmNLaImSc_KN!(=8yEZ literal 38446 zcmXt91z43!*FE&158d5JOG$T2NlJr+2oi#HA37zZOQfZgkZzFf?iM5kl;#`n|NQto zSFfJ)&b%{w_F8-GHIbU?ir5(B7!U{qTUkj?8v;QzfItuuporja?)4+bz;CFQs)}-u z$A7=_T8on)5L$?`oV1Q-)?v1Xr;hwm_+Hl0LdI9N&jd1o32>arNPad%6}-|YOC*kx zA5X4=&84NZ%s3*HwB)?;f}{c==;&;4#?OD-lm!R=c#rx9P_8(w5F#GhcqBD)b5*Vk z9A@n$KWk?j6AO`sA|M7y(ZW`UmRC_}VNhg53yr1%m}!frOK%jBi;D~Hu-EpF4@6J& zUcGwd7OcDbxv0qh;d;-h<*e^XRZC)8+Wdf`Q+P{D3;4+4TKn2+7haawCzUN(L)Xcll^XFEonu4eP$ z{Lj(S?VqD3+}sTxm8mwy^JTlku#MXN?>j@#;;BUS^z>%a6^nn2j;?;Q9c%UZ%Q5-J z-X46%<9v5yR0w^8@Zw-5dV#z<9Jit2HB>Hh{K&`C!{cud5*i`|3su(N{~?lqMLkFC zdc|X{_2!^F-s}qeoB#Dr>YKUB%bye7V&b&4=66?TZEbBu$yMzSBFxM-U2t@n{Bbc` zJG-A(XItW8V$^GCao^m3>4{|LBqZ>7p01CIRXzjD1wMaM@3{2o)2HDn6BCpEc$&3h z4H_S^FlXlr@77LpQbC8b=;&xK?~~QmBWrxbGpR!kxNI0!qvsj@<$^iS7qfQ%z0qti zm26Ru%A@VQ#=RV$uCBPx1Hn zpO~1iteL;lx33dnVNqnn4~4^(7{SJ-EiNvWz9=Tg3JVKEg-H4POXQ9f^C>DQ@R4Fg z%4r)Kl97`B+}Hp^@bU3&yFP=gKiuC=qhWQUVv{37O1^waR$^@RzWn-=O;1>+n2MXmGGkf`xJw>IvtIJc2Iwdh9WAGIp13kSC`^@$E-q6rc zYinz~A)yo$2@$a`j_TL$E-K{5$Vj0=NO@Tq>r)71T3(Yq#mmc! znwmN&D2UjDPEfGEq$EP2KweHRhU{sWLV;mchI%oDm}j+VRlD21HkgGHV+Q~0#P;?8 zQIei4uuAju^BEcBK~g;S(}8O-@d3=u?SGMq=V8?NUTUMCRuijQEkmPq%k= z*ir@~BB124?=KH#va%@iHNQJ7@Eug8q@?ij^75s}ct0KAzqq(?BOxIvLy$Ja$H%wS zD%#iJG*cl?VDtjfUR%o_t3W_V$p3nhF-XchhYrMHg&r;`Paxv}SlgBsu^NNByYsQs z+L4!Q&g-6lX7x!AZg-0e?X!Uri^2=H8-c#^;x3l=b!FM zTwgbbZtM)DB0#EIen-jsmuauGcugfELZBEJOch- z_Jb4vLOd8Ian?h?Sv9cm&6Wfb zLQbnfYra~qo)9x-iTlj@Y9m3$%k`_k zeoBm2mz9s(A{>lW-Ec!H31H_stR*>$X(l9B;G$Mbg!(L=jr!*SC0 z$i%(*A+%gvqtgc%7#N=(E-vTHGEMb#M0O~6U;TiwcOS1bBS1iotP`&6H2*nKfR;1> za???k1Hh6%1f=1SckkYbzCTR!qPACOr=#nfj>E;p4To{Ptc60HcZbOa{UMOJt)ghB zv&o2vh#vz3yxg;EYq<&qg`YpCy*%3Li+$6tgVtFCPheCoqt_xbA4p_!YQ3BV*$5oo z0FdfIs03vkiN4#7*=I?H-CSS02xnna2=?^!7=si!nk}kdX`IeyjR7(5kE2R`3@UTo zl_{Cp=Q3+ko9Vc}{rh5}(zsEEXjK~uU=#|0;^0X5-+5|jO{6^0FS+5d9i@ChtpdHj zzXu6qcO;VlAOBynf48d!>6ovvT54oIJ3C|1$U%m{!@{&bE;qSjN_>W4gvtmBHRzl9 z34mSY<^4duc=`MHq#b{eL$U)DIheccik^XiK~(g1x$)glDz~KTHWYpe<~kkOe)oH* zNLAm=4A+RD>+@$u)R4|se3JJUQ(0MAU>Dnd4?da38~Me~1n=zZ9Fw>`?2RT#N=g!P zT$C%GT5x!8ZEY<&hx~BeCif2x07e7akeZO-{BxWxq*GH%i;g&Y z-|Z&Tsm<%xY{lW>A%IRp4&p6g|H}j2sWEQT7Nvp-V-u5qZ$CXf4PyOyrXVjVmWGB# zS?m%qUpfarKVf%up=zpW^LtJqp}+Bx4|xg#!!yzNUF+-X`Lf}F647&VI*#Rt>*OAS zxGr*-nVA7cm7m-ZpgTBe!vh0=h?t3qi@Q(?Ik{-d;KN`rDk{IL(+!aD3KZjIpc>gC zC=gh5FCZFk0B*f}x!4toSt^vN4Bc^Ul%jR^@DQr1hshk=S37TXy;rZVt(_hjiS0CR zIUf}TQSkRsCtU|#m3t=)06&YFVa{5KU-I=0{Ocx+W>yk30FxWp*10s)w zk&#l&6DC7SL!(hVWymoL*o~{JE5J8X?|mkaGU9PBU3tVI!g06P*CW}Ye?h#VqoeCk zEOxrk(lILkJ|B}rgYcve*RKjBAId8#8hwU90Q^~fxDF*Tg+Pp(-;dC*7(>~ZHFB^Z zKgPxye!QlG*VWa5oU2}(>2dgqkL(h$)nyAcMFyP?vJTdi$9ihtO-Hr%tPTgMj|Oz_=F6guNZ*TUXdyMYR$hLW&iy>bC2d}LmSc^-(Ay*>NC;lnH% zoYn*%pE1E9fqu7t(u-fjn;96SdDTqUfVfCeVfy!>Z1o1aKlF>i_+6)`r=5>QwY7u~ z3~-RO`O=5)^v5J0#UShDRc(A40D5~|e0w7Bru7RZNGU1Ril+z&2u8jg&DS77PC*lgG^PZ-=O4a@<+Dj+C>=bxdmRwNkpNWzgetId zqXXbEl1*n>{qBO)&2v6V#sn`=h^2>iiLo%j|1sj1QoQ!ltdKx?nhcST*S*Em zfdC@wt@4p9ZRsw~&y5;gcfe%8$?=+kboJ8&ERW)Xv*sz5v;TzY-y#reP}By&Kt?8k z@B}>gMmuB*IwC?^E@zFV^;MuqNJyMtwdz(jpF0NW!mDd)YO>Gox8fxskZ(34_Wdz9 z82LKvy*z5HgcU2Vk^UzdLHdO`6Kzsok)ubv7MZ&&j~`h(K;gHuVV zoeK2vcI`3aQLaMon*m3@rkzVX?LVsC$)g5>0ScB3fV!Y#hCFqlcI1{PAV{Km*Ectt z!s;njI07E-C#&KI;GKz|AAI^m59#=`N}FFWEc*J@ z6(pZ&Tft0mo8dHpH?x`*Sdc)y^84LPCqTb-_4JrOC@CfK-)k06)fjM0&8@cjOzjIw zrUG6Efm}k;Wn;grwg;?<@p5ns(^CjIDT-^?cTY`C&CJwgZ)p<^TViZXfQDlZAx^ z@w-029r9w0yg)&Bc<5ly+I(+`=lCHZVLWcGr1x@obaZy#?fCc@U~0a+dZ-Kn9mkU= z0Kp4#kV|!LI?-qhURixxAl3+eh9CL4tSoA5FW{_~ggBt=%NJxw^2d(~3JMwcO93k2 zD+1)P4Gn+8uqilH3W(`bQ&Q5$#*IAPcXoCVATLcRqa7fDKYsl9z@TW_?k~>55EL#G3#D(W{&uq*Wg5Fhw_MsWE_x#J;W?#4yFY})D>`ugoFg!94`e9;uj>|bCo6_ z1u6izfr{Fe=4zKBKk8t;D%D zHQ#flIp5mZ@zh0*xVXE|{JMk$78Nl=q-<<#{QcYHsfnX!%HC0;6l##i7FGNP$l;}O ztHEYnp~LRD_L6{@rF_P|)PXZ#{%h@=sShU|odr00OASs!-46DB4N3+cKO%Tg2i0>yl@s0F z-8;zV;39Gk4jgrPg?@|PSTBn*IT{SmWW4Z}j`iqY%B)07hoG*2YB^|O)pINMBUN); z^2yGQ{N*DxL0RpOA4>K*rxy999-ME?bai!yhR^rL%$naH{Wp=JkC-G}pmybcS^L9s zK(Tx`mX!As10AC%jxL98=?E`*?DSp4H+{1HSOJxh+L275F=Lb`Po5a9#?Oz$qSS4v7yN7`WvfstIf|S|W z0|})_w7#gU?3wZi3aWefgJF#B*Pcegfe8j_b1> zW2?w#Kea68{J_c zou_sm4M={?c8&%O?Tls$X_U{rU2R#|)L>N3pohd$2yrnoGD=810Mg5e`P$YExw{%v zXCVPCrJ@hrdK=EdW8#0aOskwOO1K*V{?&hu?(jnNfj!4vHHmd;6QSewvY~(u}vw z`fIXh!tUc4vIQjErpDi$^Lq)&l@n1zHt@s@!I=oRn2)0p?Xh%mbE{QjUIHQ*plslO z{rvnCRr2(%{4ORG0l%J3o=;>_>0e~xF1YmFq zL5KNji|*}#B+19Sb08&w)rzGM66ELS07C3-Y6szzpP4el+=H^$ROQB#AtK~}E-~V096>(?J9N}VT7xBNl0^85( zF^GVK%0n6hDz`Jw7Et_>#|l~x5=LvuML90jgF@YLzFN9M55%`o!NlEZH!hISP9_Ta zZ%^7Et8G;b-%2DtbKU*{w2pw=qXq!ShTu?wBJRr9|MlzF+S-$##vaXjW>r(!7&4s3 zYqi-EIc+(GD|t6QHzx$PRr2u~7qSi_=glSEYnp8Jxw9+g`tBz8>M1~66^)ITK}`@H z6_o>u4%1feft}wVfI%8kX2iEgA{NPh0O?2rh=&Wdxh8e?GXT`@?(Xd0ya8Z>OCurX zx~(+W+n_4}CJyq&Bj9lOk=uo-rUz5S@d^cOY-~X1+XRe6MMZ^ra1p#P(8b(AvS(sq ziYDR4!NxB9BJOc)EH96;Q?mS3*>-b?yS>Hz*KE=AOu)FA)zUP9V7A^71j9q%*-r}W=k5N7Jjv;M{yI)-9{>4 zKMhzVAx7^P!*4(`1H{H;x%WLhM&}0Z<5AQlT3TBB`}@R^0ED`>K7OkB z!ME#se>u0y!b}`p1&YyYkM!B^Y4k(2ch87W`ov&bLqGTkL6oNGoAN$SeDT5BO=N|_ zsRiMs+{cBl*3pdtgmGK{lIOK6|BF{-m_8-_J0R+gvRuoDSZLuO#qPS~2vd&!lP{w< z3MTA^No1%%;Zb{PSX?`Jr|j(F@+{z?g{>RxFIaN507sUuY7P!xLKSex_{5T{K5&MdIoHzP|dq7xMC<@_96nKq*?D3YAaaf#^FF zXbY$?C&|3Q`275LAo4`d(uH>$*4lkw!@U$^WMRpCOd!VsYIwVsrLOJ_I5(WTIoG}q zpt4l99=8LkPjggM)W^P8*4A3seh^6N5C{VSfu>{lAV@jU}mP_NY=UG%>LvFKow_a zo=ehwx2Cc(cCOT=$@D2XD=UT_HThUxK_FoA^Lu)E)n%<$R8{G-5|W0YprQS`yaD2H ziptKfUvD;)m{U}?Ha9_$4VT#fG7Bd)POGVzq2atIQNx|%%J#$J{+Ww5D9*QBgqlk{ZZIuh26xF&Wu9Q!6Z;u@}r-u{YBz)COdr`SWMELc#Ub6~M-HOfRFo ztB(GHl9HbwDF97(Zq8%*y9;qV9Mq;Ng@A${^}Bz@;*s~QWB4y*UcWBwGzYSseVwDa z_&;9eNG5xEnVFFxNB;q+#jjp5CJof41q8!Zn?1N07-TE-e0+S+P*CLM<=w|kDgoo7 zqswn=%jw^`zP-f-VSSgLs>G<{CnQM^uLd(4c$LwB$u>ARn3$MIPC*eWLq`~+ zod3t>AP^=gVilq@R-cKfQ`Kg|L?m>I2gz81>Rwhf!bI?np!p#o@Nr_dToGX)zW|h@ z5q35Qhm$yf9Eex|WWZaL*s0VP`OHf9XA6QRR0P)mNT?q<4EfAEAVE@^nwr%fC#&F_ z;h~`;xsq$i;V-j1K>q+JKyr$T9&s4&jS^t=FsNKH=mB`|3=*9u<1r{uO8CzE^8W@R zV6lt?pqNHi_VizH@MVw@gMR9OR1IouRaI3A3JMg&PM~@kDcl;hc%FeX1Olp9Blp-X z=w%iTBOJ8CCQ5;BQDfDwO%YTVO5k9#6zbeYrUjlOMf(MMfJYCDk5I#9*Qr)RXHTxK zO|O4X3v1YPj+3HwfTBz1Q`+!%U5MOdYQ-C%eE`!ul9tk}2(!k}EQ0T_YgWQ{R1Auc zcT|9yw{C$Twm#O|LP|=2T}2D4S1dyNOTHn_Hf#s~OK$O=;9}GK!&?IyYTs><2skVV zGz<}gRfssW0<}>%bi1@sSYLGUF_q}a;tCS?+!~$J8`tbVc*1C|-tlfcR;i<^6o&OX zG`k@qo|Pm&*)U;inS)Lip5_qFzP5lrA>N6@#n`e;;Km-66%`99RmJT1kZ8ckb`)mSHlnl`H|tLXE}&!@ID?qXfypx zkf=LPX->-v+@xQ0(P7wU9bum4CkmUgVm$Hc9wM?b5zZ0^b+l%v=dXCcf2?V%$cUfh zrNxF~NS8o&!xprwo? z7f|}bK)}dTLtUh50j2Tj!puAjcO;DnN3W0^`zxH6iq;jxlaTkFYJ;u0+>X-_eZ(?nUhq+(Ep#8l{!TfA3 zT9{7L9iHg>gIx+<76q-K20FV;qyzLF zY#{Yq7`T@9aO2_yOzZ>qz8iKc*}9rGl^6QG>1{F0ZVe4uQ25A15^W=O-%JNZ-L@k- z)~?l-Z*^h*e0%}f``jZResIPeQ0l0ERuXCtnNLv!O+px!tD*WsDb>u=_M!_nQc7L( zth}?jANwn`r8|j8`vze);I8xmQKz9n*rT5!@?d(Evc&(HEjaAvM>)3;uxfAnMR{o4?{W2 zw)za8E{g%jD9y|B9YxzA^gwbGrs%Z~aObI+Qh5)<^% znzo7D@cF3T#1D8CF2t@)N!wNt9 zdr^J9$!7pT=l{F_<{@I$&!n#)Lc?qsQSg=lR<@@~?6Gx)sLF*}+Uf`VSQ-IMsWjbB zI;@@fSEk~*{`CID5u1ybGKhbP{r#n^X=QL~xe^X`=5{nEcJJTV-sb8ga(tPdZmqIF z6o5hG|kF}CLFs#rS$i=ttW~z zz2b!U{cCz$pUg-pH+EF~9@X_;mEXQ(tuJNOego?!~h(AF+^b%o658%!o4orO?9 zCebOZVfQagd}L&ti>Y&-u#Ba4+Y4lEhL2(Q{fV*B3>ulXS9-V3{+0nmBm@!&U-u_y zF-0OcSg&|#$GD-y?OQ8U|CvPM2a=Vr{jY>+R&3qgurhjC-I}(h9#*#EMsGfEp4WihL@D)t_;1~tZI&xDGn#$%7 zT#CI|&g0N~;f#%ung*8&Y5tl0Cm2{np*MpvvetBP#;Gcj?yA(Gja#(|khkp2I3oqcBkp@$dk2#-``H2R@tBo{S!&A%GXY4&&!!FFNCd8{rytmN$ zwvOZG{OGrz-;~Mt$p^KGnVIFpZwPlwChyNhi@K6ewUaz&tZxW{!nd?5;Vdc}HI`pB zacogGPvj?=|48{%i;*(IO^DN}jVqX~%FNZ6razb`a{qCot$%~OGS}H+lBZr!#W9__ zvp?kOUf9@CVtW(LhvfY(*K^RlGn3Vh3^*^?bxsX<#Y|<02R9CBeb3Dok!fO%OJ3aK zK=He{P>|Q(B8eFVo0X!F#fE8_&cBlM)s+-mp83#&D8;Z5g&9Bys&uc z(C&EfGuQjgMTZlh)34nMpWRGS`n|4f<3RJ+cp7rU7jomO_#9-E$cYDkoS8TZ2f`p{ z!f6HPq8Kq_xz#VB8rNHI7*0zcgbDW7tODWVk)_(5Ppwbg$kGka6g@4c?$1Du=0+%* zA%D%^QQd%n&sSP0tO}<6WR!1K|LMIq@4pe$-x<{s??oOuP$F(PNI~9CcOao`@ALge z*Kn|aKHMT_?VZ+SiC~u`B5?hkXxU4EiO?*JoVu}znJ9c@UFQ$Dn`yfmh>X*wiMiBm z`ov+P71qWYJ^jY8^FFO}qw<|T@15-P6$!vTG<8bWH)O6}P!DuQ_5hgLk8PaD%E5$r*&T)gF>n^-4OTTWgXRE~Ikq zjauLLXc|=xJ)hVu+>ZhyATG3`VdR>2VjaA>6rTWlMSS`4RFU`Eh|aJGK6cp?kSRrB zsed0L5?jd=VjqF`TS4z9FUFOhU}JkAEg0ZjDqbY*|48w#?seI;mkM9A@p=^P&Z^@BX#N@EFc?V1^7V9BmG0e=i{K94tCinFgXIJuB`xN=I67)z-kKpcEJP3bD! zKhp%}rT$frh0N;R!hINe5tn7CoPpo=d5~NCn-kI>*z14kUCpQs3s3<$PRyw{67!UG zZ2aS&D7Y7w|22XPf8baMF1h2?)EsXTBTd^RHe-L)e!H#VwJl8J`)IJJRP}ZagH?)|-M8pEW(*A;kC0&fplta%# zNK@>&Tvi0jGI4AF1+IJT%2WbuG0U6tiYs$DNi__;lj8o=FvydoDwrjO@3}$?^HXWF z#F0a?(fvob^Q=lnN8O89DcUBc2K$X7{!elUv+%8A=8ZUlhq)rDY=w7{%1L-tL(M~{ z*t-`2!H>JCabg?6@bR$iq4m`C?FoEWQyzaW@`~J&7ZlRqyd-_dYxJ1XH0(JRO%t_@ zy8VsION=oBmzt-<4~|Y*pTa8m2su$$9}9PTe?G^RU|%TstDc#`R6nf~%qWulNW@8C zlxTjb5)G89%%252s=ob5V|Vp(68mN7jhi}}Bqg)@SvgMN6%#4b&Y^#|r*G8$M@8NK#x|Epv< z7+^4~D$wWzUz^IaS@NOVPNBFWly(LKtdYo3Q~uY43EPq(c;m9atmqmhS}^;nEKIG=e*O$?EhD^xPmOWG)kx!cAtD0-+QdhbKAaW?OMSJTqf;=lqWhX&%O zl*G{mae8vmyF~j*2oK!BeB2k^{j`Y7$7ol7rXRM+x+5zWOeA2?!?OEQ*spR4WmE%W zk3mpqhU_t*MYw%;fUdOlI!L0}(rHM)o7?*Sn? zTvI=}RK4xffSNh#r8^mar{6x><0A+D%OxYAmI3B!in!J;%Zg<_MeD1sxyK!Lz@em_ znOdaYTr{F$iF)Zm#=q)5;Um1%yJ};I#t4t^4aES{LG15PL^>-*5-q?XWg;p|HgF%* zT@D?iy7_E=gZbl;AgCJCi|@Ncy4ssSqws%QJ4vg#SHL}{U)*DVyqeeO)rgft>wCjQ z-d^7NE&(P%&xY;1LiI@xTY_ql3?J%F?tb%Jca!N;&8+n)a(oI+!DRpx-fA}BFOHwiisCGogN7ZS4DrBAjt#)2TwfQMXZ#?{ls7m7t=? z=$)%#zYBCMO?h&jrfyiM;#z?8%J`z7a|ijxu#abkrvp|b%$lK$D1 zKcQokS!!AQXNA&6AK7&09GyWER1H|=;{N7VyvH}}Ij{z4wW#0OgLq_|-}3pD% z*_$7oCl2)u>FyE2fD-3pWP_Ff^p7MQ-;WBEY|M`Y@fWjI6L7O`Lb+Y8gGpz2ZM*YEi$NrS4e`MO0+nx0_sq9p|J4iNof8`uMCu!@6wz$m$Mc$-i)9;$wigYCs z=KUbp^({Ik^g#7%3i@81q4MEF_X=^_2o_F5gM1t!ewSW}UU!O6BsCChe%5pG`kUkxbNa`6yjV0*hS3ha!0(=6VJ z%izj5XFu)&wQw8?zKm*INUJl7LngwI$ zw2JLQnmWx?L&~nMi_T*Dvq@_IUEH}`*Z$BrL8O#0Au7H@tLj~Xs=r|J9~r0Oc>IDV z!#bScs}m-h7M5O zw)fFjv{8R-0?GxlX)SbmbM-|u@JF}ie#dOMwDd+zc6 zNzHGoX)ak>N`e%;7CepR((sz8pLlQ8OM}7&W#pIHOial=w%tx}0~ChnsFRLa;R5zN zw_hi6!wbi17M)Al_=~THP0jhgb9qJ+ky~fW;6dSa1Fyp{EAf$*tG5^2Dhb*i-B9*_ ztAdeh(cvxd{-x;t0Vr|0BmtkVsuaG)5!A_GZD42SHa4d zCaCdfp8Cru6Y6fH_Bql=s&$8-EQi;kCO7#Z0DW^ZLZEF~>*T15ANgiKK1zJSE z6>0pC>3larN&Wzzko^q1kJ0ukR_yf|Px=Z3Q}?b7O_K+c1v9ify^#RdwxM-&CBzDK zA#ab9A(qD^HAW=22`(Im87kwGx%CQA z@GnC>O57aQf-6N!5ihA6)uZmZr0vEri#RsrVil0o1-nYAqZCmPtDnVQ)xr8k^1{(+ z{wnk75DQYRVJmgr7d{^j|^w!<@f%1x&0CP7ujBUhn2dH=Sg@@BT>zJIQ8Z#V}r% zurzUK^#03;GTx}?gtZdCH$R@<9%weFr>F0-y_x+&#$yhFtOMKfKl{$A&q=F>#PuuC z*m}=5J}{r8`XH1de8cG156 zF?n0@)$dJ!ha6r|kLH~LnCV*J(&K|on6R?4M#RU1J^&3+?UUJFsO^K!0PuEHRaC^r z#rcDt)hLm6#3u*%oVfc zh-Dm5fcWNLG8({C$9bI@GyVu~$fA2$ou91${q8Rj4KLEI!I+eskR@R{^*Ba`d~a+V0lv4DCU-TPCr`TT9TpOEaz<^w zt$F|A^!O`?6j3sBpqk1Bj6_;yy_RR+UABG%RPSE9VK6GoKxt-wH){*uV)zzt|1o6@ zL%7WnQcffdbKjoVEY|9MEN$^0w4P@?LzCR3q(+7;p4dFwFF;(Zr#$JHcby}YK|>L{l?I4|f#Ch~&rQ)p?;5bRU$|zJ_mo&&)J(baX72nU@B= z!S~0@WJH%$^9sn)TlbL6W=67Y!U2RwH{GAq4c|u$M%`m zJ`4Li(l+Jmjk~g=|Ir3fs*iI*Vcko(;nlfPIO4aM^2oPa`eZ1S?&w4Aq zhXG+_GIObtMc2r5L~`>u;8sGmy6sKbgdMP`Q60J1w~f+!yh=>X{iG=J$J@)wPxpLZ z98iUc!<56*jX#2D2vTzdT|)TOZ{&2$GM27>3F@5$<(&Awfy~Rs4$#7IqjPi3z-5`s z#+n)}(7L_8UYKLFMMkVX#yQhRQS;2$9dkD(Vw_QtKh(O+9%?yzm++!QcB1gOCpG<* zt9Z+^kWpV`B1Uwt;gd4>c_rrRO>=tDoY9gL@}}7^aL9oE7wE-;<{}ynC8@Y~Z9_vt zYpg5Z1*3s)tlfCmRr>6*_Vl1sNt2(n{{{?TVwC(&pc@q(&`#Tj=?QEmJ#kMKm48qa zw)+NuGZ9<6jqCHM3v!P*9^C`3%_$8@U`d|XzhF>|a{$fG>)$(gcz93rzL4_UY354! zxxRZh2HX`+PqVS85OP{AUrp6uzM%2QuRa>rC*-HOrRg*GZh1&Ac#cNT+7tn^5$fJ? z>6=RWiGbVgs%NG}dv6^Lq{A*U?mRMSc&z97h>#g@%1r4`eR%+O61^%@6J1>a(6?61 zIXKDr3FYDbxXxE?)-O3LW3eP{pZps$eEPLZ*K5^@S^hXReOMPNXBv_0A*DLS*{RWC z8U90J_S(tKvQbvVhx%&lpuBZwVaIDn)PFypE}!9sFG6k11e4FOUv|5Z)kTxlb?MfiIa3(hmV8DNyT|}jhj&4WO!)o~Sgggn3KQ|`5D8H&gq|at zf>?CM%QIofg0c{IW!YT47IC?KEwX2!E~B4DxAIu}b79UHHSSybYbbKp4Orvbue`=^ zKgo<;O?oJ{_jRwCu5v1T>Z6OIIueBRkctiaOjEcVMy_1V5qISVtw>#`vxhS?f;ybA0_jcBHrDTdQXo}|n;Yo-)_ z)EgGUIdzO;&O#exywSLG^o=k=dU!l1*8Y4RD?C=Qjow=O>{qUpT7B$uSwQ=CmC)zk z$G1F7+TAB@Rw82}nv`9#lkuqf+g^aaeCUYNB_f;-V^&(P3f*qC6`AFOS6^SfweqXG znyFAi!Gjhv6pIhRsDEiSF+a~QEUfYl!&$YFhpAq@vPSadtro@ zpIQE>X@)y|%wDS+Y5rB?im5G)+_i5v8C1+oK!c0iEq>U}QqsoJ@V1{l=4kVJR7eS> znNfX;f#XG&EXu1t%Q)CkgWUI^W+$w=LG;*ITI2!yZ32Z7n+Zu!1-6o69JUAvDi2!W zl;c0R`W{f#G2oAtpX35tX+L8HPD z3#S^PO&OU)%02BxnUxxf&;_{~1h7& zJ~MXe)#}@utv3@{DO@21N7hJPrsHNlM|Hr-p;e&J3jA(EA32Tc9SlVqXY2(+CQ8p9 z1dH&E(6%n#zX_-RQzEUs(P(39OBM=>FJ)tFF$1a9?Cxp}TbNAmjMZSKt+?J>8&vp0 zFEZROAGlb7@y+k}MG~m<8Dm&nw-2=D}sQ&a=hpkjFxUutSAWu+8 z*J~?gZ^_I`O|O_N42&S(O3cxwPD!cw_p9PhOuKO*s{2LF7rUU0<^M2`LrhBvxdFGN zc(BgT&w=CbW;;nkj$Ug>E!Y3%wT%sP=E&+-Ys}oWU3~XKZ7*;i7;xSfX5cOZuxrcQ zb$7p1kgBE&U6#NKf0ZdIIIAo8(6n;Y8xL8##KSp*AVCpj>@F=u5e99R(f!&=6;T$w z@Gc9+XJzBIgu@mjWzxD45j^*qYd(_*PR!xxM9oEHcmH>ZL%})K^}ZT zNE-M&^F<8uYA3R<;XemqVUhMY*q72-@R6m9r=DenQ(Oi@4u1$9Q^~$_dHpS&IsQ7kZ>Kpf6UAX_v*_S;QVV5nI`G#}eq5dfbopK_$*!8ErYv6}{aPDV<2Aj$BZ2xWnva{!k?e0bwT+Js5 zqY{E$XIBAqI^{D*SU&Ih&gv54f_PUQ*|R{I4R(I6d2R7uI)y*iqUgLc*eu7ZUF{mJ z>>B(&6;hfS)mVq*$@XON0S_tUoB1Vb z2xOeJb3ohGLMih|?s|to*sO<2u=FYDsK93F>&Za_{*mH3&{=C1g&aFJTw)HeinZlP z9he1| zh`}t}5~S;@hu})iMRt zSrijT;9A>s66o!w^EDGCO?zzdkjI7yt^iO=+G2W@gY|&7LWYS}_ctjc?oh^uolYbU zX#_8ai>Y9_24WhG%AgFOlsW5+{s4y_HX6|dSyg8Ypq8~-Fh#3tEPbx{zOlUpy_ELT zmT&{dXgwIUCfDdW5YIb*4x%Z3EDnpl2~BWvXcybixc4^u43RX(HneR+U zmux2$j68}1?&0Dq^zN*MJ~gY2)&-&_Z|PLv$-5t%A&w7a6GUsN)XTdMT?%?*5A_nn zpQ1NdWjsp~e3?s95>(5s&fQL=Y&6Y$NWoT7r^ahXf{uNKnwJ5Q-+^E=u z`3tECuE+wYMfng~zG?aQ-{GgFh3|RMgQUcmulYQ`CL5DjFEvX0y;koYGg?md3-p!4 ziw~29TBKm8@K^5~hYV8Kg3c`v+)of=b$PKNEdJi7|kHhyef=+bWm*?~n)G^;21vymMt+6HF{wKmb8`SHU za>E6K5&X)RHxRJnXWbe*XW_0*RR#;_B5b0-j%BVDQL)PNS0R9$F~thCJJDzh*Q8JUJT$xK}O4X5cRqCj}f zS!%^_2M>b%6NWEA_n|xmc&O*Ro$Vy*CCA1aIN7gQqG2mk&^+xb?Vl+sttzGZrC98R zriJ_^Ba-D<>?x)d<4<%^>jv{aZC&_HwVmzU&M&xD|FY3X?R!*!m{K}rB-j&$L8 zd9pXtW&2>>?o%%@=G6Xm*L35DH5y}2tQ;17N_vb*x1YUOo4HU-xyL=W(v% z2)hygWnIvR2cICVeX^uZf^K-xW|Ocu=1Kpf!yP8$!T&^FU%b>6^7~jrwoJhPKI8}X z%wuHI*0R{^K-}Cr$JDH=xG|H4e$N=P$Sbs1r#Zjf36*)5yiIy}QLd}``WWs>DM6kt zsYmp(XZ0{$qB`17LyI0R$?xM2cl7Om(u6MQyejpFqpR=Gmqin|WD1eqPL>7f&y#CS z9ry=ZyObez(T79}B-aT$eE&S3Xf^UGy{j+lZd#otiBz~>qA$E{>6V>m$eOlI>XvQt zR=?LX%DO_eQoqmB?Sm=%G&>*S57(!JFB|XwV6$kntsbRIpj4K7_N4>fUf>$|6J$H> zyKj+GD*e47=CeT_Of&ifs+Hy5;}>F3&qWM+!5)Y;p9l7sH4*kY!Q`9$O&$qt^J>@+4sgtHC=yN%e*nBY3meL@M-_ zxL?I8Wm50=u3nGEmgUOjH0}*nz4Mzr#ZGTMDz(NZik+TL^-)iZS!b6U za&8DbGMQx{Qd#bH^|ZPn$7NP*tRY&j*hP+K2=~GE$Mwc?yKOW^8OVsnIaKl8?;>wsxcF(Ejk`t`k?pBHvtU!FJp_F9YhI#WqUBT95D)_`G-={=FP z@QctX0_J=rv3HyUzx>ZRYYni??(VRoeFjHTB7Oe7R}P*i_3*K)Jer;vEvS4EHzHb^ zX?e{jyD1kgFd{TnvQ?Pz*4Hycm6f6fhmL1&k49gEqMFl~bbWFumYcZQyU|saA$4T2 zo-r$Bm+D)FOO~BpodBs-@jJR>|8351EKybLC!{jbg}*Xt#k^*oWQ9CreuiXJQWPG$ z3c(xIKIiwIdJJ6Eh_iksXG`A&WA&aJ(& zjhQpjdsI=Qo>!Vwyv1DFgt>63`rDKbHFBmV8oZS=>bg*WA=Nx~Yr70-$K9;)dqG!K z;YV3YU0q+3QA&Y4dv4b|dFD|PU+2mqis|vp?aj|*;f)0OUBlUHa}Sr)%O<^Q4kGqq zz9LR25=!1zoC>^rEQX~25}R|q!hj8X^qLomOdZj;{wK-vOOi6j*_=EN@}z(N{A@cR zq{r@1N?JGBH%DDqAa7_~QLgtx@16uNTu5|!JbYtvm~j9uH+Up_+8i|ReUi3r^9 zRd3o{43(Kxq_WBpbVKuPtT@;b)6s;Pm0vABB+;()~UtnsS!kUJaApq5eCm_W=6s~9eeC+yr0>^2WI#4{LE za7ySEnNgleiVKR`O2ydU;HH{hYK!8QFfrL<`+2N1suwYm@l4amBAr^lw0!Nezl~Mf z`aIP8+sOo_LkkK~XVxnFswZ%!aOWa-?`uL>U6nplo!OgMJLYHFQDfuEdj)BhZ^>-< zXh`UIy6wS03+#J);0^)X6}F@98VndbXVcsn$$#lnM(W{_V#Zfr~! zmyt=NyI0#Nj3bv@gX)UI7t4a+geH}Orv+b)&z9NQVQF-`7>^gELjtk~;v>7PrfhND z!^ZMjE{`&PvQ(Z_b<_G1 zRQ`5$Ejc&!>iV}VPaXgLwtcmslH#jdl6_uF9(;Az(-7^Ft)twF*rGOk(p6d9p2UWX z#FSO0)o=}`2oz+oEvZDZCyW{MXuV7|RZb7b$#9L^ROJ~yC{7ZtrxP+2e_&Pkhugbl z#rf)e$r*N{?+2WBQg6}YQ&VY8@?mWzk%>{{Uch4I91U^nX zWLuxJwN&__Shaonlm`@qIwdFtuspU-0AMs+SiNs+8?ja{}g?O z7xO~+yUttx_j@@nrd-QkfF=3&<_vQ@IkfW_m^c!3iM0P?A0<={Om~sZLosu7^kx1C z>fSE1d}{ta?4q`6t|Rewz4x#IL3Uo-Cs923lMzzv{rw-Tk=a1hn4DSGXIieUlIIX9VD=>g+zU5(A{H9@m_`tetpEE zmBuWkeRWXmiSP$`kF$HN`(MIXI##dT(p$Ku^dP^2m<(}jy)SF9RQO9`_1!nqbK&)d zal?%V3n9KZ&!E8hk6w-OYeNiw&0Fj~mtn_78xb;1_~R?*Za&pLZnBF;QN2^ogJeII zbyID#k#S3bb`jM!FRz8~Vc~0AVgLL$hi}{9?fIzr_A5(cX$E>Jp+9C-4J3c4jJ$1J zl(umTFRtLiRqXf~F>6lTmT3MzS?AEA|2jx-4Ig}GFjDk<8(ed}+eA=aV!+3=LJ0Fj z3V1qNL9_uW0~PTOBO3HYob2MY6<==bo8e3xV4c`ZlcRdH(i{ubtYsHbkuC3%rC3GI!vF7%gV z2cJo|HkaPyoFu-kFEf9gj3Z~n$$_Bm$caoCQeu?MT*mVp+;Eo&6j*!r?(+PhjH0~o z?WUS(2C5aI2ir8AI?Nu1OW*(1d{Qe#r#7k3)gJY^<&5cHbJq)6n}42^IZ-anIHdcX zdpuUQRnEAaf)w$edAw{dy?7*{%tUtPSXG8d_Okbd?)Rm6o_(*R5}VrBgcK8BUg}@q zhWL=p`H;Eg=&QtzJ!UydZkr%mj-e#jRasZZf7-VHUk>l$Wy$%7U89LrOC!RT(61ip z@QS^Y@j|h0|M9=y6|Hm6OgAX*{1Jb6wSyXNN&{A)EM)!O?$K8&C{1QMwh?eQ7Un~{^9Vs7-38A z$0Fl?_MhiF8_w4W4!w`vPe`sf8GLmz-DdGx%=wad#C0UXsXB+wnvQU#X>i{d0xCiv zzrw-6>FVzG+Fyi=wNzE{2@1NyFf-hRD-bBb*r5o_@%dfn3~OQkioV8m`x}1Y9AmS; z^*j6CD0W2o5JBX~z@Y&4nyPQTmS5BZhd)W;8ZG| zna8U>O0}1v#GGr(Kr*#)TI-&4u4p#)cAN5^{~xHtztwns@9EdZsS0ELdnkT>SGWzB z+NOn3aTwkF9IvU$6(48i?r?YdGEM%=@MDggAOE>q2IW_4M2{E;7yr67mSA0MQpzci z;_v-j=i%l;T|kGNM8#r$J!wJCS9<95=6h=r~Z$^wF zUasnnq0-45humHmK9%|Qlbt;mmfs$V0nI`_pZ+Wtfo1jC;c`WE+4RVIKbZ7<ot4Kl zq$98IM)8@#v$A230WfPZ++;&fTO)clf;tmj5W@R-1yP{09q zi-?{xPj2Y9>0cl2dnRCiuMaX>^`YzJLlgG6a_U!pZ4H!CN~|!dGpc$b4g8+FwAqx0 zsz2&eJqJc)^qj2;T6xk>22T-JO|1mAYQ3+oOJ`jIiS(<|Gn_+IzHu_hh_1%rJh5U z7J4z{E_jn}Yh+YITFBgEXZ*g;0?lew*RTr)P>27mp za@@sk`Oo^R$s&Vq)C5VFCR~L!$V=R!HP3o{WDc(!pTKngC6EYVC_<$Pm;8?g;p_oT zqtw}t{ItiJeOhPOhHZeB7-GqPU3N^DF642_v+s$Oh$bhypHTkA}LpSkI;|8 zgHqNvHqOsdop!iVl*4b{z5tp*TOsOxT$UuhE#)` zF2W$1cF!y|k3e}pnfPyBqyDzmUESACO?9l>OB&;rbcr)^qk}m&4`YvmxR8!07|{lv zMIp5t8jpQ93&Dbn9!>%!=KiPiO0YIwQR))mf*+)hjl{HkJ>pBZ5giNjTPUn2a$dGX zzMDxyz7~&v8#17_Qd?^6!pfJ9eu=+*vv^M{9~*b33~OcvCh&n057_MPdikkcq z31U*Zta|}Xjg5bRQB2JJJANnRajju9o!poTdtNc!fm_cv?XsCHRsQBW!7xE2p+!{Y z6YbdAscm~7UGEB^qXrYB;cLH-Bh!iT94>;ypa^rDn79T?RzODee%55A?Ee;P#Kpyt zsJJzIw)<-nTP-em-+HIFavr$Wg>&a&w?*w#OA0w8B-EXGe0lG`_&IT4=@7|IH`71g zkbiyP5{F?McrM6p*nfBU1Pm> z@gZ*~=~O^Nsf#f1-NTHGVIVwH{70^y{I}-8(KlPR;%iyKl3}w3N#$qud9`t0#48i(xT449&HM3T#z)>}ADJozA&(+N zxC_kg%SDq*0!LkYdppps0n3Ypre=bb#bQB0!BXHQcpeuZoB~SXu$GXzNZ%bXX{)aV z`-OfQ0rT>(Nj%M2Wk{k68Vw)Xt;m{cyKd$BaTkT!cO)}}X&L>|@4q7NJ5#XSUany+SHr)re+pe<+f%^%`nIqzB{dZ|4q$}d*T-k} zuF!m+VD2~KPnnNtjnIy+pH8Qkhxy;l@xY3x|CQ|}5o6|_7S1?USp0YNdDk=&y~Wqo z4h&;P9F-q}eYvtmvd^R^#p%)>v=X?mm}{i+S0fc_W0D!rgz?&ey7hznbz|h4;#lB{E@x4+tpuS`Dd;m!W<7B!m)>-pEcOStkLlM^kpW^wEVK^bhn&fl1#3u*LOM)?Be~Lu%V}KC|{$7Z$)Ler)R& ztRkk9n>^23(Ct)my4j+qIQRX5@&(vr0DXFFO((vjl0d-6G@ zN(JBLVV=7FhrryKAE-gi!hS1FZ)`EiiihW5p&b{RCKq2AJl4K<+qjuMU*f^`Fr8K> zgYWVHT;-nALZaWbQ8C`6lCFyB`k-knwnmTE~9+RAK;1Ip-onsc)p8X z`Rly(smdN(Omx&HwnifK$c+l06;Wg+k{K%b3fdYvTus170)HiZM%kz>oD=K)ALYCc zde)FvIc~p3&UTobEzB z?#XX$bL{5K{f?$iQun=gnNhKZ)i%|ou2^fxyDs;M1#wJDN4HpOHx8UY8_;_iuof!{ zbgbt45nTxeu(A*mrmTfNTKp1=G|F zlruMP#sdqLf}GrcKWh?!S2;*nM{ zBk+EJCI#rFccEt(ns*IqEWaFYPlG4qG5u(}-&kIrDr}`HdV%_QrI#hvf059I2rOmJ zl#*;K8{**vfC{VrRG{Xgm3r>~>&GZ@WY;2*p$@lAA0=_1e)m0g83{zh{T;)68jFOe z=URwzf}R6lg@P-@uZj8fn5!wB{&lFheWaBldP_}|SW^BIo4O)mCSxX6FpgiD-Z*gNPPfY`uc5B7$vTU=F8sug$OK^}{+SS5ghKMezA~m)`)k&H_gmR)EoCqH z`l$*H@~L&O-i#^^`2AI-sxJr{QhwR6!v!B6asSsB0UGAcCozNw1>MYafv_$q(p^7u z;u0|w7Cm+~3Aipxv05aSi)>v9yM^M}l`}bMM#ksSBTS4aBJ5=sZ!{12Puhy#4a&p|O;3NkzS0-+@)KZ}&?qB$ z83vrTl?iKo-?ho3!}?g48}iGmaNJm~5m9o7kfRWB8`XkVGpiEnj~V`Z%3%bz{NSr> zF9VI1Kuz}$1tLh2NwTu9cysQmk1E%%=-_UJ9odMLn3&{9A1y?i1+Jh~PO&(V%!JW~lClu_LWM}2=#Vn6kk}R;#K0|9F^cgW^}T$z^3#*n!|$|R(YT1}hy?~& zO2#w^uXloopke_J|Kg^%-`|KIQ*V->%OqvN8;t5|eOrga0ha&g;UN&UWVxWvja~{Xc4L0Ki~kPqM{;>v;+cQ=mUDbk^OAz89zz1K}?FwG#i3|mvtfm;*og*E1>9egnxJ}dmgN2xu>Pt1L;t*yK1wJc#Fp4^}Unwv+v zJ?2OM{h+uSOJ%o-T@eQjzow=T>M$vRiw_MCpFTHdA?K%LO_7G(P;L36?6q*8>)T9< zh44XAQ3gbp&S#r8j4gq6hTfUhe<#MKra7uCw}1?JYqE^@@u!bqC=S+o{`WbfVu}6s zG|ATy5&c~Z+@XI|A8_r zFF(J`k2hxn2!ckhTnowVz-1xV65|cW>_aBZs+Cn_SvS38i!Zs%V@J?DCVMXr1URNE z5vnZ4wYH-cOPpZd0e#_UiR3N9=YdK?ij`qhohFaV zMNkqT%-?_KrY0u`hV>z@-MJJgHYS-+nHNyJPyLo4zh?b8dM+*jX(g~x7NeY4ki;TG z(*sn;f-ExV1f$*ZfD2)KLbovO@1`(LTG$KcoJA{eZN$1FIb`e@A(o0y`*>jvcRZHK z@O?eyrvL3yM6sk63Ce0J>G-if7NRN=pSJX=aLcBAB0jl#P`CP5a#Ug3PcWWs)w;&6 znHz(miBGPgY=6Nij+teX*3802^d#mgnCW@Oj?I?5GEwrq9zjQh$Ridd61W!GsE>n~ zh*4ludF+|1HRFoih}0S2sk;N$2`6o=6fl35#zuVF*7QvEFQZ>%NiSf=E$bla=ylMy&tc|8P1JC1xkn zPdc^9+OViR$cUsPKzPyHGkgC+vLplceMbgXnfF;PpQxu0Lgso8zw%_VGltWS z2dNM?%dxQ*n41zIG_Np*)RG=n)H3s8Zo9&3LkmGo<(k%TRI7>?2^RQe?mJ%<(>sDx z)_sU+)YE9fQDtqO?_^jA;o_$%rW}HX)cBEvjd%ydsCdG7EjQd4xDU3{Z1$ui9^ANE zP(+z|;T<{BMUQV`3F}wf3>0_}S9onrY(}!?G(rbv-J*!jcVTa!2xsi~B&r1OjAy zTwJi(r6xSD#azwTr_Cwrtp_tOxx~GN^X2vs;45uVR@5UP)TU}EKxyh+Yb1wb6?-61 zB45jiy)1^_@dS`_c)h`KR=~Uqi8`$?s5S?9pa_ytK#>0*l>pkxFypOK&FWyz!{FeQ;tm?!qwGxCCulO(w<0)d;}XMbjg42U z%3r*-i(A{Fl?xaVQX@nsU1aK?x*KOYD|A6T0)~5J9lPxcFlo{V+b92Q1hzTI3tAbb z(noM;K<_U6Dn0#g(E13-5BHW@c_m__qNs&z3D56`ChaG$qLg#2P7kk_lw0a$K26c6 zzmaO?lk+U$$(C%yEY*1A&-{*~ziS$ve0moN`E&nxBknjPcO;lxvp^$~KLlQWDk>`a zIn&=CZT2cS82j<#CEwOu7^MREH&^GNe?i}0BNo@cPNu-@HsFZ9&XSgPF5K?A^G{Vz z7TCfG|>cYLsER(OqxRZ!*DX?+-Bo0z*+snpdcU`@N39MXfB>4R|l_s(qoq&<-g%%9NR z^(ud*|1Jx;Ibdn0sKal8Xd{ZqKr+(^U4Ien`#s%;4_`%9H4DPVFf*8#Qb59+EPx~i z$jksDXodJ4+IZ!ndwSn!H?5|A)Fmg?zf!6A@rwXyVcKEJGsM+4W{lQH%FR_VNE@8M zHcLxQ6>;LQ*C~(U_7RU8`oQ>K7&*#C+?)kQp&|)`lz|Qse#w5a4I>DZyc1&liaq4Z z8zh5^`0BCVSh93*sVO}$<{Pfp2mn%_3BYY+AtFIp1j{0WLV8CIP-I5vs{c?fFcB^j zCz4R*1@=85S0QCe{eQ<^I5I7ra*9oQNZ$r4NWR2;nr(Pod~@s#+qoQ0&_YBS(r}9D zb5~~O6-2RgcfRpq&76!$B^vC7a3m}W#_S_f8opUYyWtL>O^aP^D~S}7@6E8n@rcEK z68Jl|_unYDPkNq7#|>hXixxvYQalMKEy_zAao>|IHBjK^OTX9LeT=zsNRt$A2%Fh4 zrWz?TIg|4#zTC<@`Un}%auRhNaZX(AkX%%N*4g8{c0a#|e4RK4jD9rndpX5^r61H+ z+lct(K8y(CnWTcnlkHc+d`!elp2RE6w~8Y*Q7?8kv0TI?tiIa`R=T}^Mvs`e&Lo2{ zq1ExYoe|QO0yiCDP)I|JLJ)*=qp@U`$7Ge!5;8R1r3K2aJlDac*0WJesU!4Rv>Aln zNAwt^lX6f2o(80Aa2LxYT@lPU1Np|c|AA8%%2xt-CYceDglm=pifDuwO+8y08eXZH zIkQZd4WBxTj?{%NBB=2R5z57NwGK%Ylh&`hYC?d}G?o~)zkz&q+ph-;7XKB})$|%T zn(LkRH(W!hlkT5BSZ?Z4L6Z*ke}jh&vUmYuNtZI3w3AU4FU1Ps!dJDAgJ58mX;D%* zTs6T%XkN#Bqd+W;|CNU}0m+6D!8#b&-I3fYJ+3DNI5R*rIRhlcHv4Q_k=#R!EmwAE zuOd#E;2AT15vMs4+1JfMcIV&e#%s(^D}(-%tSq`EzgViCO=GGyyComdmeWPeD74Ka zff}kqAnJNZ7sB~vmRGw{cH?Gi8#T4JyAxMRUooFmZ8XNQISN`Q8=!r;jsf=JDsSVU_B8a(( z1j?m@-@M9QFag?fUf$tFEkt-H`9}NVFGNHNlIlGUh25Zeel3te7b`b`2n>jOm^A+U zxzc&uh*1y8&&zxM?^u7O7Ch{XFhs z8^ibbX%X%f@|)>4Ig!!P50L*3`+08z4>8#DFhT}o=5G-gvfJ3$Xg&R&3529wu32l1 z6BD|rR=3YPfX)?&=Y{F%mm!D;#!eU@1>acjS^K7PCeLIHb1Xa=>X70?TrXs25TH>7 zMhm#-dwRl|lvWNP&przoN2qhDW(cu!a^65ef~5rW-NRDghhN!kSgQQ_5VT!>0CO=2 z=A`mIRv#CV!SH#4NCn_oPssQ#`D|q4Z9q1N1gF|&IOopQufX{j6of!)dU$w1Aqmo< zI`R9|Gt|b(Hz4NevL|x0X6M1|mNK-A3GMd47i2;CMJte)A%{ZWZ&- z2xQxi9C01L+z0}Tkx0nX!s!etpukrp+hvOQk7$|gvvWsc zdT5T%_jDjw{t4v5ii(O=H261eY{Tets9=BV12?xrPz3}2&)JVY?kRnRm%nLAjE&Ho zx>d})n3G5_Dlk?k%DD3*giO84dZP;Td8XfivX0&O+y9gjC59=;$w8lFAV;zpTnOyb zC2*cVX}W%>a4`$oMv(hK_ds;Y&A~CY>48K^Nwsd(ymRta2ocjnpdIU-}Am%j&|5SMA?zM;AU@_?cln2>z%jBdcRW1tKKLRjvE6fZ4 zp&WAk+czLfmKR&hlZ%FJ8VF;HekVJ?QLh@R59Fzq*4B9Of`Wnz80iIJ8D!6GL8Gs* zEkRGid8Vq}?Hk&DSe`g-ueD4elQ3R!529&meSHbTG4~81x10l`1s$yewhHT{%Pe<4K7mda(1%2y}5Y`km@<0JebzE-sQ#VYA0P!tjeH6xRRi1kriz{ zJw@PVk-0F%0Q}rJTN|2A!t;ah7d;yOll=O% z6sRlZkBR{k!0)BN+o%Fvj`>$=4GXFHYjH5$B!Wi}ts^1C2UH0dIFsvgQkGe+{YJ;Dzs5#P^V} zV>;&whsdBjwww*l;k@!B3}l7-WN;oh2MrC$-(THj;Dk@UjO^^g1OC zeDE8e%;Q-V6_GkMGb&i6_>J(WvH+w?9e%6c^@Oi?{jeu4B_eW7T+)e8fF-K%S8aRO ztI+G#-Kws&abr4MR^|iO-kWJRZ?ur+95y>J`p~fxz+R=emu`x;t+k^O4)`NGHoy`ZW zyUUCIW9jZX%u>!vPI6;MX{qQ6XtPKp5NlJR^i=e;W%6E@NHXsoo~eH!Ee=|e?Qj!13w zK1;OfpVF*km?BDD7x%oAt*t%$Jr(o#WvLGsNFS`%1t4?bNS>da;T4*8Sqf1*n5JOu zthc9r+{3uT@JRk`yO6lCO}qS@sT=X0wYgoI=HJ<`z%5*(Eu0?pMa@&$Uimx**W%VI zVN$+YqNz-(94W)C1%D}&9hKdzNM@VRu1nNqV{(JLQ%<&zR95dRK*rK~rXh z%gzvj>BE$iLqmX)8`KLb2m3Lt5HOCWmL*nQIsFLC)Zu!6gVQ_<*8nd&dt^jJW59WR zTAKbKuL)G@Azw)Z2?aIabkC2!S2{>~i=Gf2fZ^I2sX#Heb|5J0P>Z?H%lv>^0w(DN*dx}y`p>%+*q_5kKnPEF z$Ae9p5Ud~>*`#&wByehP48Pw0{yjA%WfD?h;4#!*-&>d(4W6@j(^qU^;ZvVHmXhIF z2=}_J%-#}L^S5GL>nuEQ+?Td6jYzvrw<5K4f;dIqn_jP!+1@$S=9O`kQR$fCB&;km zS%ydH*4Zsumzo%)tP+~0dlgjPBC9TdO<6e0m#_+2=q^ z4#GE3NySK(ybd@?|5*xpOr{^)tbj5h_4kSohASAF`f$}FOk*{zyningEB+F z;TKj=0tnb|`Q7)p3A8VP+5(CRS$90`cdyi!_khsZbI8%}Ew;>81tOkUIr8tQ@zyK2 z-74g)_}f!XLTt=lD9CRetIPeDUByB>MZVN4?ZZ_&Y;^ev{YuG%Hrb2zp^al!?dXJV zpAQ2UN&UOgfKPB`DMP0gUnv>(9+#1=6bf9Z(~GgdXDr8gx**7YL?sJ z`*v$8Zz{6~uKs zI*=LyP>qbkml569`aoX38)V#|QcX=rh`54|3*+ufk=J`9*Z#R$g407hHFX0VwJzK=F!f{&$xy-!G1pa)VuLirSi(Mq0fkO- zkw+|)qc_l6wKY<;Ry>g_?c+5PtP;Zf*104#{tX2qtW@Q=no?s0I%S1=&t}B-gMFu& zIIC7=mrk2tTuxXVRmfo*xwTc-O_;zhq zgaUJ)RKK+8tnG}`i;8R@aSXLgP=SE=%0ar2!)GP~3KAJ2PDU$w0K-k2JnZ150=Yf~ zw~>&~;kUWR2bf+P5dqQ|$PfWP#ANngklus(Qcr*XHY_82*QDB94seEJ+{SF8f5(Fz z+2Z_P_`{U8`RRphsbf0VqVmyKok&%1RjSltzI44(Vb4w%-e%8_OmMGj@G9kPv{*8o%{tmebT;8=dCJ#x+)ke zOhJKA284|O>gk#CNJwPmv8}kmATxvq$AUIP6K^|N;gpOOC_#cnObm0RxuqJBJ8|6H zJP$ef+))B)v_w%)4An<;uF)MJQ8^o)wV!tAotC``PzCwWp=p=O&(G5DD(LXmAmh6& ziG{WJRPQUcI1xeXmBvW^QJVZjHl-|GrDSax21ZM8fXa$w1t#9~TwPvCcBBO++*)6h z#3Pa7s3Tn;HpNg)8`*DxY|BuyZ)&;x8yX@ywe$M0rH+S*V1v6U0OU>}MGCsP9fYCC ztm+?Li!I;M0w2eeNpdMDW@#qe)Bq z2<>+lkcR}Sqn;se5^PtY1Lu>$KhC=lF2~8l)H>(I5HFtIdn{H0liQe0_1D{G?f@jQ zcNAm(TE4|+3MS80#FQ>bNp&xfa$2FGp+aiL|BT?sj&2{P#9#gz*GPT&xldU|1tg$Z zBrxKaN=iyCS76Q=-de@)ek=qcG6`wdEgR*QE02+aGc`5EG!L!!0^)4>_z{>zVhJJE z%>dN`@cl_FYH;E_mfNsaXj)9A0LVK#??V*n?dLa~eRtYXL_gq#uacr7Xnjf}AtKrZ z(V^5e(3F0MYO%7kG_WoMK^#V5;W~ASN7d$^p}ddoF*GzhE@mP?Al4&azGjGI!gnIG^2psxexz0w7AU@<2Z6c)_QS3wpq?zYs$ zr2b=QE@40i2M2@u!bo$&k0b};cJhG?AA~!Rk&(DJZp=ec4oofyMD#Q?pqpU6k_8pt zw0HDp1A@cJf#Kj;pzG2Spg;Vp4&Qco1d#V&M1xvnA#gWA^7yWh5GF{MArgtJ9i91Z5{2vZ4ih76=C?eNF?PQ4_nv>As06hh}f5ur;#hFIN!Gf zDSf&&e(X&j>*2`%DWMao0O`q(P2p%K#JXNAo^+wt3%UXWs-pZ~$eO5CN^NtwGbF3v8-Xt7eZ)0goRekfgV?u~8|s zB0G$cUjwn$zQ?Yh<$3)k-41A*g4qmB--BR>B#a5;mc0ppig%Yr?%lHO zOKij&R}w~|8X9KTQ(5n3HmA*!NzVYXxRuug25Trz&L&BCIiL;vzPQ*HY6mt$Sw4Ub zxoi$4K(AUuYXWMxkOP5n0%*2wy*xTOsr(rRyhVC(i`iG5 z3KAKfpbzq$-bx@{mqU+@6kK3R>z#lzkKDFF!0_k4Hg!-$Mt~fx;5Et6PBb=(tt=;L z-17me2Lgq$^6pT+MJH&NFd;$tTeoov?f{Cw01PU@2gt2j3 z-od#$hitRM1xS(dD8|StzPBcJ-;A0^=33{x^a~fR-KteC#N-U1wgSN|2@Q?Og$iX@ z1t6WCgM+xr^5G69j_ny^^f7E~Kp>95om-03WWct=*^J zd=I$5TwSZH7-h4IbvgQf=I}k#$BJ8c4K>Zm)d|_Rhfb|r8*q>>jrk0s`4ysr`j?W+o0Vk84n;Vez ztbo&X6e$%IrgjBSb^iNy+=qI*ah5xGd{;U`p+<+H$ipy9J&<-mAlNjL`DJ8PO#B2p z!hre%itZFL$WFfgp9XLkL#c8>+DGqgH}tsI*^XjV=K6<*K$~j;liV10p}7sLTZKB+ zV5w3+bphDN4e^4k9mGIqK-L1%=#XT*7!+MXvf@LkXC~1F%3vK5$(SCAFjY^4 zX92E&WT1|Y4pSq_gj2Vf__f^`Q!cU*|Yz3^a3gaE#$+aBOo4Gf-h)10+nW0 zctD7BK?ADFe;P`S?U?35NG`grcEP(xI)|Fg!14ZQJDLYQNAL>{v;@c!qb3SfDEi51 zpeZ$_Ap#qL;E#IR`gc8guqC7Aj`^qm2OoCD0OLzJ&DBEIX67#8Ew}Ex`62A6r_sa0 z(NCiVZmO}BE3?e5>dzdi(-^yh#X@ZvH0bdbpNy{>6wboTGJdi^jn zqHPqwU6g@1Q%4wN4h6%^I`CZEf$EPRALwPMWPU)llQPVVk|nL*xX%6v9Xp$DY+8d=0y~2qfs(FyiG3I$H3-2zEUVblgHV(A=fQ$vA9#K)zyLazG*Dp8sF60(O=E_!}%>!Ovy@VCz+f=y*n9hJMWX&Q6 zP?;al7N~{R)^!Rk1meD=ZZ;hI8z3`n>yrUD_bX`BwtQRIAVx>oET$?~2E^Qi9ZrA} zi4hI)nN-pj(p$HTS7?Iifd`SCl=K(8c2HA4f#1GDyd55XU8Wdp9BiJ;mGIkr&Ll7B zNEa4A1^7XBI>6r_z>WvVFhdFfocO$)gXuIF|hfnwd+(&YsOq#P+J|A2ke zuiO)HS-x*ZD=DX?lFDTVPYmx6j6MvS5XnFu14A%~j}LO*2_r7$njUv0C0k%3qr-Ti z$&(XoJ~(zjQII1JadA0V{frUT&GA1}0?-Bc0C#s94{*Ue^vZ)wHoU!}f&$noe^#TZ z1g()IrN4LQMFH@|t-*^DH0wZPBu3!_q2dm`=#|HTw1~D`y_d+x&rjDuTM$_`g@gHg zu=*e2M}UrK!a_E@T|A}ZLJ-3L4R0MRy$z|*ct>YW(gk^B0O)N`a;vw(DT2~FNQHss zIt>Yl&L?7HaE`XNKQLxV@rlIi0BPKzJK!4^QnBTEt{g@puZ zYRoo(-Jgp!rb}o-CE)DFRXS@N@YnAUXy# z+8X`&2Jc5cP?9`*6!O`-&P1=_)c<5D)Tl0n=%xHUdda%Ez&gcA?-J|K(Qgq#mob_48k;I0)2GlLs~eAPKDypa3%fv~@8 z2n3C^QFD3BK1bF7e(aAb+Br4I1q;H7o?PqWq`22)EHkh8tj0+>5R!*;5C77ih}HFi}d_RB(W3%?*pf*sZ# zd=;ve@Aim6N;D97c3~^f(9u1|3?zVS$HB>h4+iLh-?B@S>3bR>gz==(QsmLX<>0^k|g1pRV@11Qjhg@(cn zI?dL|{Ye+i9E72YZija*UI68`r{77P@4T=3fP-kuGhtaX5QG)$?ya^?6_%73qBK;g zw-}^RaV^NAC&NK?;)<*H;>v_2;RWk1qq8(^6}8m~-LmA92l8`-cYEjjT|PbA&uMLy z>Tv}l&eQtA$0<2ufN~X=t!aTTHE(`hvi`>j2-t$B1zuQCoAovO>M-&~nrx^7bOZDQFb;EXav zo#P1SAa@UboOj1+6kZg3H}00`(9+T+1aL0y?tVLgG>BMA1^1Yj7WiBimQ+{z`Dql6 zQj2a99MU}UBB-$8$6q0)NqbTdOrL^YcQy$oag+JZUPsf#OsT$#p+CUIf9I=OAOT65 z%<)oPxzSxP(|a@3`HhV;ot+jiDg#5I&-XrTzyp0g@^^IH0oRe-S4wg9q2W)_)8~6x z`Q!1b61uH_c92m|MNKR?ngXEz8|?Kt;B&IL2cu5&FY@N|stbf3y)+G0@xG>)Hqdvw zOQ~E&pp2u_tPzJIM_Cs~enL=R^5KK1r~3Sc-`Alg5AUS^_UXyIv%`@o03>Kwt3neK z5mf^O2=0(b>@4N#T3<$ICcNDY`xptz)TmvG5xEt(Y^GPe-%tFV-MNY{HH$3NlHpWTPqzE z6}tpzf@+mb;+recxub9Pds?MvJ60Tg=&)t8? zUn6WIX4GRY#*l);(_ZFSskBg#lIfuRUnJe%RJTQ^SJWLDk(xYd&meG>X^3erVD*_k z6TM2V$1~}o4P?t~Y`xHZVWW4iaPrfKhp6gste`%r0UTb3?i0pF%p9En?S@(LQxSYwC2 ze6OpvsR(DHE@6j|qM}`1wGT9=;1{qJwqPON&>3vCCkL!`UbVLxKa1tENFQ|eukzY$ zcYLn>g5+i*c?mu8D$0{JS*-e z|Bcn0Bso)JMjfZM-$n_LD=h2w_Cku^vsjdXb8(9@${ti8hdo`zkj)_Ok>vFs0*8LWNT_NXC{UO=Gckl4}Keeo&PMt0LK7pIll zsjllGV{Q%0-pj&D3G*1MLKE?fHA*^E7o0Op0(Z?&@b|LNL$O^m77L%aRU~^H5oHNI zVVt7)i4=RZ-fox^q{DwCaW}ZE0-7u*IPx*^tJMYe?c(X|+ASb)mZ5_I`A` zwfO^{C(rYIzu(X2{rMP4*gB$%JZ+`Xku9Ld zKDPp{1q;Ixh!z?OpI#5jhR=lYY}h)`+JuY*dGHurx;2Jic;(m_y%W|5;L+hp&Zr96 z2pT${Tz0#;W20ts+R^&>k)=RcSov@Gsnz(p0w=V657x2JFji$7HS1I`JTd|&gTSJk z(Ybn?Fp98T3S8|DaO*5IO2A%`NL}@y-*G(saKrd}tdXb4CTt4#pL-Wz0E01QTbznC zAWEU5C(MaNB9~zQggKbL*r%nj5%Kwt;XfEBCJx${mXyHav-a58Ms|4JD7l}a4!9V= zjk|FI0z@*Kec|_b>`!^orZy(ZDulzaQl%qdG`&@)SzBAHc9eW)i-tPSjX@z3wE3-J2#M$QAg{{L+fj2S8KQ%MlzrNc776zf7%Vx8Y)M~ZJFAQ|KR~l9SrcrY8hn@hnVE{7~9lh`|jO7DVQ zm_ zMH2`q;xZ5$!XrgX;BGoP$gMbS!687+AehCX`F|-_I_FUS8Gkh$LmfVdzL2RZ7MEqGueNPn-Y2!8riq=&-!v>*r^yO0W7h zHOudoK`GAS@up!WEIKe#C$J~p-F*R70gQcc3}^~|z}ZoAln~#No-Yo!k8CHWR!~IM$FV6A?VXE?RB-5SjXW0QcpRhw@=o%@6E|lC zWtw0U;&=)@UFz=!K>owrw$jotRDR$ap2D*^a8e0S5#?EI8bp-IkeU)Q$TL)Mi0J9X>%MC=#TQW` zYABcb;{3>`!&Ry~$0QG+LMKPq$-YWkuq>^3zjbHq*y8j7YRH*vGIVruV)!|)F)204 zWwWxCJOCn$4ktX1GcfUj9O_5@?QN#mG+w&*?apkKMe@&|*4$eSN6ih+2U<;fOK8d; zg`tWmT;-qo;+^&;i?wSMXkst6COw>2J3^`~rgHQ08hF6dq6AS^#jaOFnTo5kd~3TT?r=RDP8e-y3+?g_L|tM zN;Q?+t#x&V;0Mh z)XnWCR#8AY>){~6a6Dg`Fg$2zOFPeUwo;l7Ti|v(%h@84#n4ZR%7`_|g;b8Ys=E4c zrh=B9p8oag_U`VyrD_Y>H*a?SeucHOv-9@$t{!V|Ycm~6J2*NzD*PMu6+1`F2#Jb{s;jH(>XHPo(9@eA&e!QMO*t1-S6AQO-ezQw>+3Hi zbJ~EFE1KBd=u7C^u+JKSLV9|8Gskuy5RPPi`*kUZ(5Fv1Dg|Mop=-8Wh=IQf3%^rI z6L(isR1`QN2DTZt2fcvE$jCVIEF``&&S%%e!Nt{U_WW3^{t6C`iiT#Ey7=<)vc8^& zK078RCKQjEFud#f`nt|x%LspRA>F22^Yrxe&!0aKhbMyg z`p3q`n2=+8e?&zId5xP_<>cg$l9H~htPBhc-`2?+_rcXU)`&u?7eiwXm;@makvQeZ zk2fDy*Ve3BI_>xb1@+0%J32b(;{IXLDzI^KzIyeFS*KQs3e%}ZbpOYXA0{RyJsYRK zzP{jYmEd4CE30BTn$U;{+z_#(q@}+gsuU_3lpBRLypi zdi3}8Awh)D#k91vgoR%Sqen+ahlGSUOX4}@cXV~xbETZ0pEox0@uW5b|JUmZn|?!2 z&q^4+))n4v$H&cG2mX(o++df$XDn}TcUK~uFfK9i z%YwR=7GYH#_zk$x_wR^gWa-Px2D{qC-I9@{0|wLj>jkAe`akyZ!@Gd}PEYNjE8j3) zgI!{!{YN}zJ)DTMR_74>GH!kWCPGL^NF$fX;;`B8=Lb_UlM)qWz?w9e#;^VHBLODn zAIlk5^H$)%4qJol?Cc?8zrZaj8mezAW^|O4gmeXYd3Y33c_!xP`M?uGuxKyu$L8N~ zeX&|>B!HAT?Wxa&zzHk09D+f~13u&_RNZ-ad3p|}a2q%Dp^}0iBz;y}L{2a~pN8 z8o%)YI4>PbqkMLJbFU4*Uu|w-@dBb!P}x9WWMq{8V8i$(mBkR|VgeX&|5P4q69t8c zgHNrA(Z%2n%lALqjG?RX_+`_`_sPmdc~ z;0D6jD+**3lui}~US3`*s(_yY#$Cwf1qX9AbGmHLi<+ZirpxFA>Ho>T2h6j6;yTV} z(|FQV?482PK8|T9FOO1nlrQ-=ARqwTlMZ%PW##$qM3GI?1#WOV1{AKUs%la^Uko1; z6B8Z1%wnoUHi3zR+djLtmW!J^iKkQ{T_82(zfW|uFr!g2R9jm+Ha2#~vRaj1{t?M3 zGawa{LKuAeebTUEKHT5K!L+_DZH)Q(^Jjd#1WtKZS62+x zOuL;C3w~D^0W3tb+^F;BY)e)~29->J&-2EI za;lWb2nYzs$n#AeE?Qc%EA7EVL`2$JTKQYoC`26Vo12S`ZVq$RR&q44y(W4M&I9#Y z^cX<_0dhat%$^<}#?3vxO%7bJKL0fDvg8F=MWg4M;z~`Z~oUt9ukoC1l!9nop z?Vb7a2`RSs{PNP;+Pa#l`BNV*M99(c92n&L_wN8p3$ni4p6|d3pQCH)>5)cuui4kx zv^-o+6lt8DodKJ^L5J4rSlii^J8}5<_`v&PU}IOhU+ljBJg5WsR5<5i#@LRhKudA) z0MA??5*|KskS4<;i0&1C{#eh~o&eALqsgGCI205Fzh{Xb6w+x_u6chxrbxzZPsPvw zus>6Q-j<-}jsRgX?N0<)I59Dy+vsX{e|@5g5X_FDvUTeB5^4W2%IEPc9pXDA_|zCI zcnM+w8{t5EyD`{!AS{Ad1t<`Wf9vttS;ZrcDkX?L*ig73KqJ5&9vvMWOcz9Zk_l*S zZGEf$o6B)~7;uD0Qhr2=Y=s;U0AXLDs;a7H=jH1=AlBs`!Xfmjmk2o z@;L2+2(`1b!!NdnE=rF6c;K|F7F@+N1bVgLyO zkpH-1>2=)t3gSzf=Gx|LBr6*#MtO36KE8J`j!lo@?&dZl5YpB%s0Z(F=+Wel-VD%b zlGm}pY9Q%-H&38UfT5w`Bnkz8Mv1>85C6*1=0LLKfDm;XfXBH8vd~UU0)k!x7RyM= z>nWQnU`A!Kw{PF>IJz4cWau!}q+0Ea=0JR3OGccd<4?GDAHE2sM{!^N`s(+G{A8^L z|8R5BtB0$l4`c{__#Bq_sS1j+vK6V}^=va~b*lV5K`2C)pDoPH3|W)-NK12aI(f>o zvi#i{DriKYEBVSSdI31 zvU+=R!2*X6WHp+VU!o7h;$*0?5#J$KccW95IP}#_w35r2}Lj z$GwkHznPDoes?%i6zo%;?0PXA+2_4#efvv1bYG?@bp-%81oDjN)f=#D-I0oNa^qjv zzy_^KbpxAH_17=Jli**ynwp$+J{(-p1ibqhx-MR)52bTh5lY8Q8lQte4g=wPx<7MS zB;9HYM3Tv|2QFG&?8!}x>XaaQ!1Oj#sn+|!eNPg(JwI<^cXyYRLl}qP0R+P8)a|`J zSvA->5(JRrWMNjM0yduDPFcg_dCdY@p3u;*O0Bh9lZcjbJXsYl{64-*_H-SrJHtE* z8$)IBSW;3l=p2-w?>$rf=l*n~FD@?bnci7-PL=8_=8Y+)@`!ug1II-0o36FX3JwlF zuvCpZ=#8aq2+hmQrQzr2XJU$wNm2*1dC9h1WUXzx(I)}%l zWkY=Va~St;Et9agDD`>hyIce8%Z^yT$-SzywAAUBD!p!nY50QQ-c%{Av^^jTlWzbz zX#>s+Vp9WO&l|w7FD@>S@R%w&NHQ#^%U-mzG#s-adu+sM)ayhpoC8QPWBd8+l7t_b z5@aVHr&D+MNNvV)Q!-)CkeuP7xYrJ#`8T=l0Y3Ie&ly`2OL>FB7$$et2Vzf(QO z1j(qXigSnQ8yI-0`+(zRd$uVLfn3a6hVmeUe*bPstK#yY3qQGVJ7DTyXZJ3)cfP@; zbU{N^zYD~ej}@jLX`Nm0r{$-196{tIM(wudnMipC3^0T01a9*diYBUPDRA$SYE%2RuN&1ngIO`hU)( zyL45T1vza>1*)l2U27-%ZOdmj$JO1xyoksx&}Ds8?6DPH5nq_!$AUf~X` z+VuzteIrPQ23N{wEE|p+o1Q-nI+413HBPy~fq@_2LhrgkDp%U_$fIU7Xj*Y_scUS! z))9i0oSaOnka7(ozHE*PfE6~v8p|0G^neBTl%HC^^G^c?(Nx9@evN#wq;(d+&OZzr z?rm>(uF>7ID%C26hfG)1?~-TwpTDd=BOwyIV%J}AO))CE>w;#>T@Kd zs?&>$i>X8>&Nm+}hekF8_PuH7V{x#teA7O$nPtgO71DVRSi7TRfql6w|y%z_Vrq>}Aqs}w9? ze-%0&7De;An9%5sB-5{VH2e7Rqq+GmKp%JOuhIwojg5^lF_;adwK^rb4U>ncmdNe< zKLeL0b4s6v5`@#C+{6l7uYFHXy2&`%*{x>&1Qt?c{fLWG#@S?|z(#xlDK0K{R`eKO zFgo&pnP+N{GX=5zwv1z!%F@!Z@$41J9%^~Af_&W>2_-rd0s$}xmSL-FwI&cT*__KD z0V(z217)hRU^mFd1wjcwd+-uu-SYqkyfmMht`_eA)mjuz^wFLhQxt3hj81!S{zf6R zex99^6U42_thrf0HZ=f~znIbotjO_bu?f8mP?U3;Mm#-NLqJiypruLFhG$n->230z9R@MV9e4+h0Bgmz^ zj}s)dslh^fD1}OuXZnVrvreh$jR#5v<65;=;s@vriveDLH|&j#jjOb*goRs4O8((S zc87lZ#sVmK(Zm-vkT-%r7#Da+yX)I%zae8|+Sk*wJ$L*5{d*D>{-wSz4We;?Zn}wt; z^VMwuLE81yHWxpr2UUtR4R*jP0TTkec}6b{8NQu1-4h0qF$-CuDD0jfvS}RQe!J95 z_q#8F`4yz`IoH4f^&$Bx=yv8im{r^Nru~4@0;b10VKN(Wq2awAEtx2{Ii>HTtETpe z6HPjX|3`$FxVU_}KvPM{A;>=V4Ii4=KK;Wkq`bLW@;Pds-5g3+ywK|_nhNt$E)?H@^Z4Vv4ND?p(1rLV2WfnyViEa&+3e=Nl%d#R z1xu70LuFwEWE@v_M=c3)aj61c?trq^Tu^>Pz@mXbNZr<>L3PI#xC=jaSQwdL8u_;z z*#z&?URqE!J2=c}+$(7~tlLThKnFN;I=4e^e*PDL?W)29z&R!3*0|fl2;RfMz<_nT z9{-@2lbxNyWoI<-lYPnOsY&;&PLGh+c^`?nad>u?$80pa$>VBsYfB%P8&vs{d0ni< z#b2_cRqZXhu7v}F46F#QI6Salw*wJ?y-%;+affrs^Mk6Y<7R&nD3O4Y0SFKcddFU8 z_h&iVsdD4jo9{Ev8DJmu9e&%z!Jjm*K;Ect@I;ySa zun{}KST6h1(J?V9N=ml-)8!z`k&u*pwo0%(pvRI_m{zluI|X@ZJfMgrEG#S|^AEhw z)=>IW2bSWzdZiSBv%?L&*htVH-8mNz z#Vyuv@dmW{nH+s5 zH3M$w0^M|$WMp-&GI%a!TF6I)*qnA*KkRfwpu}T*fGQWW4mN|O$K4EgI;aW1Q42J<_zR1cKViOy zJQ@9IA0~^m2NXia+EKrvo3s7QOLPBM!VVYO`R8C)j6Eldhhgs5?XQ^!p&y{~)vfusr@&ppe;)MX7A-M|^d`@efA)k!m@$vD&&O6`?f)D3d?EX$BNrQbVB)bhdjO>VC zodWTL_|Jz$CsF?mo0=po2JfQd6Ia^ggR&@noD6-O^OR>V85rw^eaBFacfmFX4+wS}6! zTe}9aFIOSe+(oLgx_Z~K{_kHQj%2SsC`M?fimtAF-dKaj6r58>P;juzOd5@c{3S+nHr0q8wIH!qOc9hlBFx}6QC@?HUNcIZanrIOy<*Z{;wiT6DppC>pLm`p{W z_+3(BTCNFv#~DdwjlsD_HcsY~xw*N6Lxm7|B9Bwyf+cQf4&eW1Nr#sHTo{z#JOu)2 z(i1cv&j(WgRnLZGsVXfJOiYoyF$)WeRE-*6NV=M>9U$@(S*5;&5_wyE-0wY44m!crT-k* z?CI$N5I2M3>_06Wf)37v>@4yl{`Z^izc;Z)p#~F0?fP1I*!qx5X$B5E?qr`feRu2-*S|7vdX0lhhb&-eFa!pu4;j& z3{Vch#ls`xa~-xeTGDG=wrvoOtNNzZ#0Gt9W7ikGV<1sl zsWh-kODPBLgXgV1>M!v8CJ~Y0?BEGPrQ-5OvdJ&PMK5mc%2_C&n}+S3u#SnCa0D>6 znB#i}Rq*5YPL~s3z+ZagS$u;75rtULLgUUih{b>r_X!Y`GK1pGH4EU?2sLxQs+lWg z1*Tat=s?>7HEYrPPrFIUB#^Lt$pyMHUO;?jES;T}p{!#0{TV7KZ^z42U<=2~v|x+a zGNjQS+%#(;0SI6Y&MxRsyy3Qhzv;mv?;wZE&m-AcxFgYNv?Jm$X!s+t|5j>8WRD^+ ztVIvS{3?aPAs5C7{U!cQC;)wJSeJy!51AVgD_^PI9$e_pij#dP91iyl(=eKnK?U07 zVO&J{1w#a#@^9jx*`yyP#VQjNYR*=s`cg)%Y=7vFdSfT8R@{i4sfwiGGOhWuoU=V^CUzm{uQ8r@G3J?$ZdoN^Z%)qD;aASYR&hi5q zohfbef?7uNmtW_1!C3u3LSSD*BNn-^@E=BfZC^$x(J6(v(S%b(Y+i829p|17IUMI= zPJS^&Ckw^!$A8B$LgYd9okPd(=E7!h4^t+fM=7JiH(5qA+gBV>^S3W&T*eF}IHXMT z4er}k^&o$I1gk{o+OIVd;goi<=j-x)1AWqhz(vL#n!n*fV~vVl3;zzlW$e;~{nJNU z&qD4W83^~uTyyxv8LvSm47T%MT-Y!SV>=ZFh41|DiHRsW+X8(i(_ceZk*l;4m%vp* zX~eknz_lb0%cDuB>Ch~#kU8v?QvJd1@%NpFv)^D*L_OnO4tG|s!$sRP&f+U`MYEJ= z`<5_DDdxZVLo})tO4}+=-AED4xz5rMu9n~7hHUxc75+g8BTD-su`Cgjow{tiw=X6I zEBb_)VFdAFR4Xxee;h0ds-%ZO7JoT`_jK$^Ji?3n7pgr7nK@Y#qmu^aC7&e1OaeP= zdC1}HASrO-h>6tx9}ifx;X~tCRDHuQI=b8q&m=T+;ZB;kN>E4a;0HIr&cEPEoItHG z0hd+GQiP&*xf`uDmeB@}bh#R>v_1LEkA0ECGZmK7WH<)ld-hnRy8pT|Yx&_-zlq=&um;}L-PvL959uMDue%91Rq zh&on|<_O5OCT5Ez?W9H!v6X`L}^oAIleql z<@$krQO7u%eFO~l#FDEIwdqF=T53m5Cl8AlBs4)UQffcPOj)X=s+~uCuhrXE%u+-Ge^TBnFuf1i*UvI5$DDFm_NRee)CuKO zTaj0L9!xdd?pp3i$yA7o*4gjiYC7isv;ek;GC}&#E`xe58MwOlRB$g5T?+_uYuYMt zW4;=`e<*(=FzxXA%L!?I903Hl9qN=RBtfgE5;t)Yrf-6!6)AZo_~Ct;K)~gzbStl$So6aOQE0y)U^qf=pL`5@pu^-FVtX)u^M;O1hglh>xE?cw;2ge+lHbI2fyKruF2^%~7n7?y`C!6Mt<%l*VvS~z3O0Xt+0 zR|rO~Hy4I+UdW9miKPu9QxR8EdiFZTOF!Fu_eF33IE2IZ0cW$|4U_J-$V3ERPv3OnkBO+ZU?7ZTna$ zF4w{mwy~^*3t(2;Vzhk>U-rV3+MGO~|2J*a{9Ls4WK~TyH=FtjMP&OIqabh|GZ8r5BbrbkgnWe=nl&1>4mt zu&x=ol$mqtgBrdvFyi5K(kiv$WxF(g&lTA!8x`CPt7~HfpB|b8yRA3+L7IW(6!w%V zhY(T(uzlh8feG=hT_eWW0mR5p!JVgFL!aQqGlNolhI3i{u`br5wG!v0x@5{cM8D+W z4jWPXUk639?VjA)J6MI(m5l3XpxR-*<@!lLJdn(#|Htz6LRJfsJ&5{`T~fXd;m1lZ z&n({`wszqL8>GwSDxNtB_tKh;Cl!5{iwn#xqy$FWA!_@M-zuBfr+FQ~#ZuXlB^>2V z%lY+n)%wwdiNxEK4aEjQ>^n<(hcf4j*V2tSlR6G#I@(4hjOBE*AHQP!j>12j{yya#sUcM9r#iO{U^NTvSfXn=p&xIf#MfeFq5 z_RiehWLGZ&`Tbs0l0n2!oc_l29WtH_Ldz_%?a6U2E_GSb-$4Zf>&SwZX87Ut8{=P) z+aCY0*LuQ(*Xc>zqn zAEwt{1a7}0Qg%a&BeF>n+p$@7`D*X2e9>)+IW=$-3&C=|^rf1PKKXr&asLJh*xi3a z&sk~Ttm7RN%EZ=6_O{2^X&swv|0{I1=6#Zpx{np9NMre^W{efXz`Loqa+udM?Ojsw zRtAAx86&(HoT|BgcYVDN8^g&+lVW26X?%&hPsi~*AH=AVq1@ss26s*OUGh5D-30@jF|}vAh;SA56l)0;)O97-NQk%oFjHm9+o| z^|GwhVkd9ts(KjQb<@vzZISqb<#y#tESIr0et5|{#n8r1)iewG21ACvvGTh8eC7Gt z-k7_o5o)~>)B}Y~F|Hp4cE_^RNvaYYJAc>O%aB61->rIcZ;-Q1#Sw;<5`~s(ugmXm zm#0j_oy5>?V;((D^Y|f4eWFiPmGIVx>PUM*_~9df$ZpkmBs(l# zcVu3gukWsem6d9XL>;JpK!bDpijVhHPNf*RnSHB25kHjteZ;>+{)yZbV`)61CVIkN zuk?@Lov`Q9hy8E0ttyJX3f;KOQ*j4O{6gQu3XTZ1e(*Y^uvsy zpG^a=qRoi=#W%uNOYt!c-=)wvt|f`BoYsB4;i$$D*9P{wlBeW9apI>v z?kCy-xcSp2Su2Y3IQ)dPAQnjItt@xQOq+K%B9JJhi0pXFWei|W)H{fRxt-ExvqOGW zQE&O?nh4*6F5Etn+)Fj<>k}iD&u{W0gxm+#1c4Ec3;`ICFD1}@SR&gLu+P_;^vKepXj$K5pRCeO zE1%>aV+qsUkl0EJxaEHJqz_WBOxYQ7a1zq}Y8qRE=BOt=fBa#->v00^O*QqBm&5`#M(sM;n+gNes@UW^bpz#=#(jw?!ow_A~`> zs@X}%Vaw^a5j1zM*qjm(f=3g}!A)z69QM#kdiauk9;3bCqNWvYGiprAX>p#^jPE9S zC(LDouPL~cq?_a9yJX8>pY5zQro_OUbkQ$VnTQUG2f2{jjCyW1?TPEa5fc z911pQ$UR5aSHHBA`okU8rg%(Wuylw=5zqaY zrazWJS8**=hh*F!5Oc+M%o@(d1fzSe$7*fI;upz0CHAT*csbqMccU3=iXWHnW~UA( z9dL!MHIfjm>*Xp5T3hSR3!0e}z7CrVZ|RJGN~8F3(0FpzIBE0wHn5f>n*u`J_M$_? zFPruBz|u$!?qCz~RSS8DQm>PSg4tN)d)T(XGj%&jd55{d3h1b;JJNKtqNiJ|rx)8p z9T(w3j`XmOeo2G{)b_b&!ddSnT_QDQ+EGJPJc?RK3byb@s?Y+3jr$qnBDO3 z*c3?`0+Cu|YHWFVVy|OFtJVY2$}Dj$ZB%O1_3S6l4W3F7Zh!66+K7fS9wpok zN+5#eAQhOvWY@606Y?a&S0?=W!WrN65h#$fG|K{5 zmH&4XG%q`UU7)Af(vBQ9{DlqFq=Tbbh=u7Z zreRCrL|gC&C=;y7($KllDx969#a#tC+X0=+x#NNzYPkLIEv^nrZLdu?q3u)3DC#}uX$XVoY`3!2|h zFZICaD^eVVZZ0TeUDbm^7kenZOM|u!;YVPm$&v$<(qn%KoMGvb<1%~4yywdl zrEee^Zm;wFFg7k%x=tg?zg2hm zFte$XV@reqL2Yk$WAEOfD%PKJJD=mz+Mw+q{eY&@)nN#@kNjc(`q+Qmyd@-(r9}2L zsTsrA?80a>Pplg6NA9Iw;wL+ZiR4!vNi#}N$y=Crgz{kqW#Yt!!WwtsfrTDQ(gR*H zUZ1{qAgLqMEsVh1i~m+yB-vTc>ylQljd*FQIoHk=6$M>*UN!=miCeZYR>*_CYbX4} zagfYLbSXlWPUEujVIl$DOH^Ar44zI6&R!RrsL!~p5^m=wa4c##Z_o~Z$$I_g!X(?% z$LJjk*;RjWwixvlvX~u~ZJTu|RP8U4V1w@ae%+uUnlcD8f5XQHb8198?ct|3*)?+i zkhJDQ08HUQ*u4)fKvGJ;>P_{DDDm(6k@TaW$5JjeuwW&5Ty)O1W4p%Iz*@OT5;wRlZkMyJ5!?)IK%GxBk%-(+ckSVs! zlKegdlUh!1IzgibKa>@x<#1Cz<>;iR4}UDvCRY;O<-+*o%^?b_)4K&}H$^YsABw|vAnO4`cTEzl2ht?gZ&z24cMKF7-vQf@TIh+Q`9W9dBrSRqN-?+a zxGmt6AHr29R`>xpc$fP4o4Ov}g4~5Oq(c{uLi&zfsDY^c6#Z*+*dw zF$IeRya~t$9C_?kt-GKhYZc^~hf0r^bvaEVXT3F=hV3NH-q}x?Vy=1KB~&$AF$uV1 z57tHD_yP52uPz9>v)?{_{TW304OZ7C7)`H?IHeE&Xk(iJntAx|%|yu2bu6AM-z9yQ zZ7ztM|(D`qxH}XV>=J4tpf0`o9*hNPf%T z+ans%zFo;e=)q=_{(*TRPYSurh|b$dFEcMs5iSbI#9Ra!5}V;ru->0%h)qk%yw~)O zxOPPJIz4by7}Xcd?DAKnc&GBpiRcK+Ch0HO-}RlN z2?K`&1x&BuxNQe|{sN@b7lNcUip>-G6@TA8c=HM&^t5JZfSt36)9af8Eu3BL786#Q z<^ILHhKrqnR1G6MCR{&Ukzg2nX=w;ba{Qg-P?+L zntNTpN74HGj^vMs$ud}3jzsCQUA}TRs-^_S3Y3=#z|~^}YLj^F|5QA`g$YgTs7YTC z23s&2R-kF@>DACc74>4WfXQv(;tgVSD-4)K*#Z1Yd#4`ZL=mO3m-F}C9&j4GD2js& zU8Oo&AaCTJF3KVq779|T?rU}n-XYsPTeVh=KC)J#+%Hzaxi1XpuWQk$I(gpCBQ}j3 zmY;8fxp`UO>=ZfIkM}SE0&k`YBL6H3-B_~1>Tgu!vWbJG6om(|)8i#f8Aa+eYl(&p z!MHAWj=)3KRL~R4gUBrf2b`TK4a{$8YJnurWKkk#@pLa?H`mhcT|6$ke8hHn5QN_9 zCq%i!{3i0=!^8&!XW+*F`L$d#%g4|=K31=zV~Fgx^6v90#?*hfJ6SDSOm=4R8nG(6 z6A3w<)Iwff`Y3kFk33tP2G5T7G@L_r=6xtyAFS9C5JY~sZBBGw64tNlEZIbzF_V9P z$q&sO5_B2k@|5fhLY4pvKYOO}4S1(EDqUfN`{ob>-N|nHU-S-?Bxo5&__ZVb!WAl_ zxO9`m<;5Hunqcdna5^MPa9dk}yQ?T_OS)4i$tQ;95`mM{tK3K>Tru=K_t&BL8()i| zM;@8^Iaz9#6GVX4-gjCc#5fvQ_K*i+8Y-US9?yR=8gk^x>waO_fANV#&};o-95=|t zz$fr|(m-}lhq=jobQg$ZQxNBMVFSD*&>?<}>+tV%R4Wp7TUukfq})|ICaecNc2&>M zjitudUdu1lH7#3Sg8O$SEIKX`*c6?~@Ho}5ds^mbbWa#u`jLaX0+Fr#Ut@?sf%2)q z=gbxKjI?-9=l?@)u9wzpD$UasGgte=|Af16hR^9OBNz}sez-5i_=fYVWY(=Foq1tT zf=|tY!+^#9_DBQ@GQmE)Bqdw&fN@vYN6^UvF_^El1JW^bK}$y$j5@l2$@ZeH%o(b= zGn>V0w|i-qD^Wh^>fnFTUocIq<NeGWyo_ezKBbOVm>3=X z^JV1M#om;Ly831NrT{a|*2`g|j)gR*`l8Rr^{hMp+fR%tq@wyJ6K&Ubtc((RU_&r2^oD zhj$zykkHPb99BOMG*sKN#&&?}1OoZ3*W?aF#W*-PKomL{x>c0Cj;(K*UAb3*`V;x| zs9N^WgAj%KJNZM#0#tyJ(%rgxlDe@#EA6~w%NV$0&9GvKQr1Z0>A$z&sM)@b5A>JN z(S7@A%|?$bgzIz zcA&mf2GS_rzf#>{+enZT*73m+Kml66SxMB zw_)uAX#HDC*AihF0ulJ{C_xKU@Qsa|aI{PgXtzV-JN9*w(a|AJ9@w;X zziZw}?^|KP;O4C@8bcMC8R1{;R6K@h_o%B*8`*L6BX=j$_Gz>8G=PVPx3wHU0g^@@ zMX_56LztGSDC)P?TXyIooy@%NXte9^Kjw7?BD0ss1(;XO8kIxgV0N>V==Qg_Yh!VM zFduAqwW7z%2(xgBvAfU_&Ybv~?ss2won|IXiMzizwyrn4aNc6>fQLW`!{I526Y*pS z!#P-h#D$B4zVIu-9C=k~m=31MSzT(4T)u+m=V*2}8&9$fGMF894brzp<%yj}1*-JB zStq7v{7TWj(T1ubBBJ8x__HGl*tobrt{X*)ETke1HziJ2bBXQ2U`==Mltq&7a1FZ!SHK10T^40Pt*ecAVKY zHGK%K{rI@xe6rg8v2{ct9FZXAmKmcNbb11*%)57X|1|~x>37Akc$&0kL5XOZ}Mx^^FkRWL;d?=DuS8U#P-7l?GfO zx%KXu(Q|!oh`FPBR97HmDj{pJNh&=vNX_Rq2T=gutc8=I_+qw?minsHL0SsBng(JK zAkdC-r6mfk#&NsrSEP|G5%7=Vx0XU-?7Q|etWrY5Zfpb-1rKd?Z+DCo6T||^VZV!H zW<0h6VSQ6t%1SVzeGnPrZ#?5dP@~}6(cSsJmDv1cSwH(o33MR%>KFA)L|>A;2IJ;_ z_l%riuBV}aBao7#`Cx0yq82LXcDfEUdsA+6x4#nakJk0#z86Lu7=8lby? zqhntPabZyR;UB@1@hxwhL9OrQHhG-Pe#p9@!Gk~YVI93-0G+mVzNG$a_MI9wKGJ(H z{e`vts3;1w2@Jn5Tsjk&h6JXM>x^Bi7WX@$x;Qv~$ZSAVQ>0Pqy_1sw`u0+4;<8!o zy(~41c^^nR2EOYHME`b;=yEcmU|gjc#-g~c`tC{I_827O@R(t6YvdR~aVU{B@+`iq z{&4O2m@A)*kK6@XY<^{BftE`ao5jZGo)Bd<5ggSZB^c|Q1qypIsM?0U5^>Ni5ZLoOYH4m3?lG0K&!@H#`4UAijM8 zVNC+6p~0b{Ap+sFd|JHVc}gUawqMsbSSNoj*uG*d$$qcJaVdSxrzu`?>rqEn@L{iF z5XqF$Ne#FZGFJp>=me6V+`__tmmAYSrulDRp!oOiM#r5|Acu23S?y%P8|vx72kkDP zGb>L%83-de6czK%-|(ov!h5x}`YT)dG4ODukBGOA;05_%??O8C!_O7LwI}CQGZpWx z@YKLtR7%k>Rr-Z$EA6cWV_IrztA%=?_>##PWw)55qNW~5<8L@y1uYCWH#dag5)6k0 z+1WrXT~=lbG@O%fEGB;w2za{MEavFs!CJvf5HJ0na^XcAS31pl~)H9ZNvkT!I8f zN4v1M%v6%{!Vc|ZP1;vb@7b{T_xA@q8#cVkStIA0FIH8vHg@m{Qx^{g8o;6HsOkYY zM@aN1mCXO#`t`bGRuE84aV!>4rUz{Lh6X4}hD z3M~vbYmy^pi~0Yw0Kdl)s|YL9jVH|pv=~dWa=*yeyJfzog^O@<3afe1UIvI3*g3nY z(?EsV9)#i`P4$_mw^tys?2h;|L$k#0I4INJzN72Vt#zX8k7+$vdwN10w|yPQY0a@M z{*{&WM-;kwKVg-0);o&{)9~5siTfL$;;!H2n|$Cmc8eXhdf#5WKX5SdLOqyJP0tsh z%qAyZ*Nd5c8A4w_@ZfOCBrtbB>z08)_Z{fN2JO1fVFL90Fohh5k?3HLKCF=k6k;uf z;t8T!Pwc)BzWwWkWf+V=C(rV4Rs~)})cWVv*ikJTT}QMnj7HKpeT9V8C|x*xoOCg( z*|=%dY_{6d1seF*I}35k%x~1#QQXZR5f1XXa7JDX_D zEP4AI3E#h$;Hw_ecdo!Ynl=Uk;;oA(MW4-|$-cctx50HRRM}VOwZev~^pA2j=7Guu zYz1mGRsZtUlg4FYWj?8_!7&*jby`M$W5lco#H`lr$GtiA3X*+$1_rrS z{GAYJpx+8XhBpSGufgT$@X7V}ACqDKaPg4(M;vlP<@6in+htQ#Eq|^MBHFggmZ~2k zOH$9L0&TA7Z(%THvb4-pdQnJZvSbWZpTA?Z%v9fm{X_Lvv6>ua`T0tca^)MfWpv`} z_%d-lok%I^#Kh(#4HulZ6(4ud;eeU`Kp9*=CSH+7}C>5iY37T zuj6eyNQtFusZ`r=Wx0)TTanL^4aP_WSKqJFckeBiywT-!3#RekoG;beOS!%kg|pie zt2JIt$2rRV&R5^#ze2J-8x@3^BRyfLRK53!1YSH@uY`qu?t(Q?S^OcrZ{5{Cn^dQO zR)c;;s|iG?uFkwYeVt_Q6cYX*0{oec z8t5vz^-t(0iHt784t*!gTcU*8FWYT%0kODsnOVBb7Gr%I?rzC?G@Nv^7k`|abgY$* z6Lru^#*?>pdZTZTn?%Hf5xlebYcZKi@?J@fipFAfED#s@Bl($yF=_jYt(|b* z^3rq+)S5kSFgOcYf*6){{Yy8y1Pf8ZM5t5`%6D~L?PP_?+=QyVjpF)hXa7cB=BY$B zQXMq1v^>tCzRB~lf>%hEH`@!7pbnwcRccdl~hvepIlQ z##x=Tt*qy(h9yQRAkr6fg^Qo6fSQt3vJ z4v~f{5&|M6At@zqo!|ex$GBtMd&j*Tzq7x+*IsL`x#p~tot>+2o?P}7|J2C2)St4q z(|@YCPfh%bd}a9bJ-Vxgq_w?9`kNta=@657O#|zZU+1?+nU}V%OYpo_i^G5q z^-3fR3-Ov{Uf)}`ZNv46{7-L++6KkRi4y03hu3p6w$93LB{xS7k4XQX-+6h3`D(H# z;Sxja)k`z=4@b|39eHQoq~iDZ0Gms}VRixi1$qBj!d_o$i3QP$$8IX}dz6IT8w)9H zggN`Cuh@|kzn|ZmT0ZxEVHH$dsyS)=@tNZkKVM14Ed>nZ<&BVkXg4|pKBk^o)LvnJ z5_`!h6q>ys`zBulP2Sfd?k3%{858mKTJq_6hO5uigcf=i*NutXKa2kKwV11viZReV z9j~7$rF7IeKHloXdZAs}^4Xjl>kfLL?3*`I*MI(5?UF7MG9IK$UXbgkPM2Y!ElWL69f5PXE9|pxa#{W+5D#{8<{(dGV8V89UKJ zZD0MLqu0UK2@OSt21W&CAN6M7kKN{rB4`khAtGYKq4epP8amqt}580I977ioR^=1;QRy#kHpI+zj;mi zT*tfQFT`njM4PSXza)Q_FW^ET@-!vpd2@G#*05xgYKo;aO^PZi;SroDL!VZ>I=koTzO8NR@ z+<=}*xyO8e!}uP*a*y@?20MPxLkr8J4$&d(OUcHYx%nTmks~jP3e~#F#TM_=(LEc0 zH!x#10x+A~tfwYDUB#2f$q&kggxH3Ob&08`@j6)?yn`7%DxP14r{2$7F~ zAn#U39Z@za2UlX5)Bk(QYW0EB?!=G&>2&=b&~OT&BlX*Vdjx*q47 zytjglT4TD+CA(YXUk3(xKMlab><(TLRk_waTPE3{uDLMj(O>(H;tzY^|2?triyLRtmi5yOwi$Rg`brWOt;$q&XVt z|FlWIPI&4N9`UCqG24$m`~W8&CC8-X87#e@3Qt0Uo0wrieW+a`nWwdiBZ+x_e|^I8 zn1v^!hKI7Y#^^w*_w(viUj_BCLgwi{-ANhkTahn$>4H7suXAN?S=|p1X2kBD{l;y@ z-SXWe1#i}^6S zjp`k<<*CcijiUHca$ZYHJ#81QY;}uF1ucj*_fd#S@$0Y0HnqXn#jijAoP=$e71T0D z*O;eu*S|S+e~*)uo5W*F8?_<#hPsa)odf#aV1mjZM(2E5i|bL7>4K{XKJzgmjdkL zIsNDq9+a*PfjD^Ajd6=_nrmX031vu?S`BVUW)^MB!0fKJw)Ww{fi({~$O9Z7XYo2r zfJlzFh^cu0x<1nlE(gSg_{pv?d$^M`;&0lwv~Qo3_u9itO3Wqclzvkbd|q@f_{{i< zTb5Auaj`L9pUg+ar`57ns=SVo5B1nVr%Fas!q@JNbFFrVcwYsE2HG3Ulgn%opHK_i zbra%6(H+q)74m4}ZvtY+$!-O|6n+g}IRt!rr^|r;_OkJsx$@w7I1P2B+LRU!(2r?k3|@I?PY)=XhSviYxQn|NL(a_aQN^ z^$5-VE|94B0w5gZ&aa?GzJ>(#cyp3jKtP{94uOE7lK6y#(H!v(nANVTs(NDTvj)&= z!th%1oz^%NcDx7#;`LCoy0@rju}Yfe;c(>wbM4otTdyo;H}3Kn&$-cw(O6mE4Pla| zQ%t@!7{fTsA{C|l`&L@5{xY2_Qd{x&tuSh|C$x1Y?8DDsX7zY$8tOmNVJ`W*BsaLBkiC*s5i3GdXrco};>-l0>>81r6Xeq=OIQ&MkRlU_wZ z0d~^Jz`*{&L76K6c%Y;KKZaH2l9rY$F#ZohP=SHz<~x#i7z|A5r4R@m&vX$t{hd2? ziMz9jOE^XMD3`_UzYpZ-SPn-fa5E|=YfbwJMBQh?kYzjx{vylnjxX$8#(09mLwYOx zbK&eOkfu<}6ySzIM1KAgz)Qm-BRxD`PWk1erIFve*8!uupk8&Cg4Z7A%#lpOMYi;y|26CE7bv@a!%?j{*Lr;DYI52x9bspc^K@C>+ zMN?nEPMc0!2C*jif%-i;E9(jr29lDK8x~~rTbn4-+zh@2)D^9~smOdWLP0#ER+VJ) zdR>-3=45}>``Pe_$<5t+XSt_Fq6;mLy~vpEn#2`9=qR6FkJrIeEpaVP(ElYfklE{* zrK2S;^)yKQN;lVYy_eJsHCvhEn+9WbpmbzJoBhkZ{L(Bemf^04TDm}0Ii_@A#W!sN zI@L)S^c@`<0wsv(urOB_`|p&U=>oL)w=&c)Qq_~mlt^=~N#v{Vc7JM2;h&vy?ildRGotN%5=&=W8`Ric9g)C|8AaB;@4)oY#v{3PS?#M z-BoEh)h)6J-eX3>?A7BlYuWS<^r|0+`PteE`6Um2IMCeoVwIpFSqL@2^R0oy0)wZ5 z4;~En_uKv5Uv_qV`l%sfE!Q^!k0bLnJM2ztvf}4UpSrBmDk>^aGAH-M{|zNQ2>5qq zr=s!&9twszulgvT7Zw)kbIsey)JR2esV>@KAbxl{%uOgi=-54Vm4Ew#$qx$`Tei4N z#a}l46TK>PHS^OzBAQX*lFOeimdY31JWQcw`KpFPI*Js$Y!`TeF8;}+>?|z$Aaau> z>;=FQ>MY-bTqpEP4?k z{V>c%g|{?s;P#M?WE?S(fuy*|hr&T6__vHQd+nnAfb4bG>f6jZP5Sq{h~F%jX_rvu zAYsrE28mh2Z{NKu>VJL&7}fddUQR-SJLqRY*aA^Fc-LPu9)GN4?lPhfn>rak(qP-> zDATa={F)qjtL9k@frYQHZ{xECP`E=N*peIvq&*&Kq z7Sq_!MSdjl=UiR=xq}vT(R6BmR6g$8aPSGXhMDV={)x;v^=E{Pr~c!zPw%{Msgt8p z&WN;0to~xn{)k+ORm+MeIU{n7s5CEfEwOrD#*w8UblpJ8Qd!|CGVCs0b?<#gsR|~> z1~xxCsfxZ{$7O5|y=BXKq#tj^{i!T(lDD|`_$i{GhSx5i=2e9`Vt;sVdu@km`ub#u zPEh&-<$&mS?@Bq7Vv;8ow|p zEH2xqTl|MxLz~P^@gk(~Q!r05`7s3gv_XBPt#FlVYq4a00xjX{sqEM}MQfbkDK++b z?Qb{n2`H<3qGRU>wTz@JBbG_Z8B&vyK;xxMuNy~%Y9d>B1-f zi)>*pwI(q}#=?>NvV?bDmhI-a_a=mE&tRJ@=6>V07EE$)D?E}b>XLROWI2s_q3f+^ z(fl>Jhes}mzoU&&JHg0-Cy~tKjLAPt^NBf6B79AeQAMJ!1Zf5Ozi5+M-`SivUf|j7 z{R{4a??yOGg;aD>r-_b^hSM>=eJu5jDInmwsi_IhM+T>W%a7MOY|ifDUVIRwIL|I? zS(4Y&0&g}6v$LQZOccocmnZ!e#>-)oJ|9YCjcGjx83cf}@S_1C6bB5{7Pm?_t$AqVzfyCr7Kn8imc$>ZG~A@7W6dP+pxiiWg^c&Tk|$oW_1pzQB}o z7AxhnCQs1WlvAK0a>T8kS1dlNa^GaqZ3?r&(F(Z}+Sr~Rz$YUw@5Gx9s2(WA+=*E0 z?(R;2a}y7IQ8WzbdGL0Q-)=JwwU9o~irn}F?eCnssi_C_GW7CA&M)dP z9q;|Ce`yKdAc0ABXmF7A;Y0teti{F356ENfG<}yLrq!z|!9~YWUlTLQ^(?lBpY)a| zhB+>SXjQPZ%@Zuh3qJ7}nWZ_G49z@QBP(;etLua1%pvVyql8;Jp<3pWR4Ve@xJ8+m zgQuufW|^LMbM6m`rkI!*Y~ytCfPXOLE)ZRQm<~#5!NC~I-dE?x&fNH>)F#d~zRT$I z)BSGM5_pJu(y0QLt(~0(k_2P_SoV_6=3Sa)_4fD~ZlCwVw+V-`TD}K&+#lC-}oT2D%nrvQuMP?^JA`wuYhe-a!6II3Fu}-?_VYlYk48 zA7ePyP_?DuGFvSnZ@O@sm%Jq$8v~#9>B}{KvD@{H30~sjlxEFy%Jgq1*X~8oBJbV1 zrz}5Cun~AO9!LG!{I=xC*7))&Vl9>SAX-OG_PR-Ar za0^7yi2A~93wemAyF1~h-ouw5sRlx1p1=Qd1$k7E`=}omBOfa4J`?)t&YR+2*Tf~c zI<-)IaU=D{cAslq!{sX*2S=O1ouP^Eb2Yr-6&iDxWz<3}J3*Nu1&Ix4JoU_hopDog zb08fFx<4p&LFRy=$e0*VWg10w^7zf3MOmdyy!_H^ihhDO^^)eQ4;Kdq?!f~PebK8l zqmzJmO*SM~_F8Lj_=BSQHQRmNsKuj&{ ziGhg;9~eXasQAf8Q)q>O4(VzWD3XF0LT`Wn-hA^Rq-(WyqbEmC56^-)zCu+(FJQ4L z0ZaO^7&nj>A{$C(1J(~Tn4o86prsXPky=~p4pM1w)$OgUSe8m;V5pMs2VAd^)X;K} zVygam9dW~;PshNmylvmt^{Y)5)3ip?d(RE?)v0fbmG1*)pXi)?p1xBmq55@l@(|=@ z;UY1rcbtYfb^CNI#5)=KWSfvXI&9O>dWB}@?62>Epd!3+L%@c}k$7tt9sBle$9v)q zd{uR5>*YIvShci>^P!5G%Lg`?PxwM+%Z7GKf1^8_w0vtly}NVRFvNkBwBU4A1{qWM z`A|^-FG^iaje~=u&vm}Hw+OCVQNI(Sh;5qXXAxwn$h?_6w2ogO`Uk0XclY;wBFneJ7}cxvhMSvPH>`!mA?gT1x>HK+AZgUQG8tkSYFf{5Oo(r>329-kq) z%uZ-ZXjGCck7PUsCPy`tOp-xZ28_A3y*yY{?<$z@=p_{q+vTu+6?>ANLi@x|*jMKK zMcShKe=(IETgB5`unU}kF9BL12!wvJKU8yeUsA`5lu4EQr;ogcdi0VlaYpO>88G<5 z(!*RpZ7hY;jE4W|e{kID%|G9W=$U%y9omC`^e_9RR0yV;$MY0}Sbkmj6CZxLY~|Xn zQ;-qxk@X9SynFAmUEk4eb1XO1!oagPoEQXRcX;q8LJU%CnI)DjDF+T5nWVhDPGLiS zI+=3<5gipJB@i46Qn9TzaY&~cO*kp6Wzr`7W1%5D95{F2he_Ul=h5{H5wmd9vBw`u zvU&FpU05f=l9fc6Jh$sNkPTo+OZduWmf5sMjn(8*|Q zL`k2})6;wIEm9Ls(lB{_i=~&(YE;f?SX3NHS!4b+f5mY9&mvNz=_d9bw?}=YJ84q` zwWIV#7rU&+ z^}>C3x8J4NZhvEgyEVxZEg9#wqvaB08=$x|Vun&&$$5F8czj1oTiZyaq*$I*z@_M1~0Dsk&2+70xevtJwb_CHfOhsdu*oO8QAYG&lb zwecO!d{i#CN&6c>gZ~SCJ>J$Zh`Xy{j|r=7mamv zri#mjZ^2#Hq%52kfm2ULvoEBCi{Ki=N?uoCm#romu9geMK-jZVcXQF5Nbbr6mGg?U zJ0-3*!D3&cwCx(4ACX~$sHz;pqJ&fD0Rk;je~RL<;flV{#n(l@C$l#Ym#v=&xIKtN z8@Gb*)<+Hv4MDN=Y_5)#jt)&$6GW^*OGo+UG)8LR&6;Od52-Pyj6D*wR|Tmn?F429 z$Q+WntCW#F7*u(v4)>ept`+-wT(Aez?URf3hkCTwM=9(X5E6Hfp$)u%mdUM~`ux*{VZQQ!Sr&3$2Eqf(vF&`{H6x1#C* zo@6^qwD2*@iWj=B*7p9tMs`j=e9-)M(<|z1V*Jt21ioal-M^z|{|nD{(|ZI22Ow%R zlFGdbWhSb-?ct&N8Zr?Ri-;;>d>)d)Sl)hEv)&0JBlSXN$McG7b)twWNC<#?Ad^g+L{;pa~;E z!8I&l9!;8?m5KY>EHI3lh%llj7|E<*92qA2P9ap>--lOLGs^Gc1*23vBPgynJzHpj zrY)spEU1Hkpq)LW1yJBTn-mXbyrU7!BvW}GU&~tdJSwMFyFt+RWb=_@M3lCjvOI=? zsj2BA)OjHMo|B#Z%+Bty%}^pJj>yW2UV2Xzi-)CG6W>Rw<+>%o;bj)co}9#DkiK22 zEWkA;$KYHjV5m;15L&2j2w%?F=BvA*lDunO7&olK4Lov=By$3)-o#)j1rr`)x!hFj zlrZiu79+jg{UZtKY?1YE|4#9=UjeLZAMExRck;oUX3! zH0Wxf)ZZrx6+z!M`Su5gH2v4K*l&zpIT?iV&v!KZ`*(b-CWd~YE|OdI2K~*LG;oF< zva?4N8i9(`I~Poj6m!dJ1@`VDE%;ZYAV-3^Wxf8^2M^*oYb7bk zcP>&gEG~j{UH4OEqK7pK(Rv%^miV2o&$%>1@om6cSpeNyzCdfrzi>dGX4KVE@7CpB+Inw>tmCS&NKuMUj8BN}yEiUU9FkDlOOp7YrgdQiyzGBh;T5zrx( z7pqkC=FOYr+vS3>>_712jANpI{rbE<|IKUrk|4?7WopCOv0o#-*dV!HgG=K9uyq)* zRodW|gK$I5Yd?0hIVm4SA&cj1{!LwU922((jf4z|M=&A&h)18nidQo+d!m5M(OMzB zAcV@+k~N;rA$fcfD|)>yQ7yGpvYM!OLdbB`B{Fv3K3WgYjjFdORVG}~1)qbr!-ePx z!R@?q4atEWSx?K~7Q!kDR$Yy-&Fu51$(=8pUew$2waSIiodYz)Y1$?LvOsfn4p2vd zk3o&jOVxoMG@2?)WsfMmn~c(nasPa-8J!j2ETlh7=^9HpQ>HE=ory|i#!F|OL`T#m z;vhN?GUNDfAcB3Uem%jnbwO_4l$O;}VN+R=K+yLxV#q0Q--?C<&u+}{xrd;-$6%L5 zO7^yKbRIo92ZIa-UDsL@HfiVxO-^?%|GHTip6ocJ!0-c>4#4Me0!bv4h%qFYz#4>l za%ScUXB_qqjc8g!4;vwA$_aviFA9qjdF#g4A3oA5e5aHPW$zjub^-yj!}U>ds2u>W z0AHCJYC#%C0Jpq zAs{S6pp)KMxd92+zp_~Cf75oIxtn%BJ~e4DypzdC;k%Ul75Vv=fXV>g+wQrOUKHf3 zcc-ti&I5^e#HpUfIt9T1Aa*fM&OJ!9tE;P>eQ`3vFxk7pj0$D#d6Lb9c(-@gu4SVy zn=f+Lxb8@e4)pagad7N{lqysV^&aeaQ;Sm%s_`+np*)FWkOxt{$6gX6Z>@bOmW^of zNkj!+9RC$L?Zg*-d-bkM6Qe}&#opq=1f7J2-((euX@;q`y(L=EesB{xA)WMQ{OBvw zO#g=ds(VzT^cj07gANUChfeyThG=W}zbvcs(@Z<^8P|Fm-XLDTnN;gyM}j=KUfnWx zM<`GAYq>Z26YRYeuo~(@$F8&M*W38KHG-!1K&Hu&X(kcr5G^f{kfOip!@qVJpDBEC z{^_W^(%tVtKRSHMu7M^!Z@P!K_Q&ADf$-tCW~=&JXRPwQS{F>OUVxHP$(g}88J+63 zD~UrF>6ET@_B^-B&KS4vZ<Ap)4b>7MYY7p310!jK*>oZ7)W66)v{VZdl29wP(%w! z7#tkzxIBm`FW-jjv}dL7X_3shTpMdkAfN0Y>A%!PzF$tTw4?tVVWGxqS6QODYv^6A zUJW+($#?_N6Os)0JtkgW9fe>ZvB6EN4^SewC9JNjG(7z_@h-*29=%W8sd;LmZ8!zz z(}e$++vDrJ(Z5>oc{7oGt|I-9Ad~T)>2c*99iJ~qU^iz?F7S!|We~q6n9c2m`>{|U zdf9+*xb`)7jmU5<(OUu*HmNpw!RC{vF3P2ROkHAtdTvhI4JFE3JqJ#FDzAeU#6%sP z#KuOiRnIL;at562Ql~oh>!Bj)M}ATIs~hCU>>p9DL(Y{~-pL?7Um$&*EV{s_uk-dz zs*$UUpW=4*Y62f#X(@QKgqri2irOfqt89d7zpmXQ2C}2U+14?Sl% z+=i7LMjc^gK7kk9jCZ_WTfS2W4@ZtCXs7gKmt=nkwo+l^$sr2U#Bd&RxE$?@58DS( zO-Qq!m*m9#lkQei3Tu}wGv3ClWT(V(3Ec8-brAU0V zxW5)Wgo+wO^41(HZ=bBNgwxSiBk|wJH?FdTi+(YR+D>p9Nq>O9b$kxVT0YBM?Rp2l zHP{K9!?6W+A1IA81GgS{v*&H;Q105=G9g~CpJirJ;o`=~1@~~v-I_=}9X|ZM*0Jbv z^n3f>i5tVSx3nb-grTMSlik5bTn=fdHy=-IXc8H>N}f#|Pu|Tfx0^GpAAQDL&Mm@( zPe&H`13_p7FG-6i_niy83i=z8G9@lrTd(uU!U=GNvA9c-lK62LvfLQ=HI@sDuFdB{ zZ54wlA3u8u?i16F^(iS&EG_fTE+N!({5#(U#dimg{|51I<7!LUti~t0x+q3|RnCLZlL>ij>@Rl%Yx;Zn6V4>1>31ap(T>Km_7j`xg2}rF^L9~9q=C75(FKBi z1JmE!^(*hht=q%7dErTU`(_MQU17e^1vYmYGAZ8@`{RPTJY`Ov&qH z*c0%Gi;IgH{LY50o|SN@;hM?bw+{tL<0uz)g0QmpD%lLTsGe{54Yt*{3tSj~>5)dx z@%L%dl}uYkvRj$oJ2grENpm-F|24N*i`Kwn+>UOvWNS2p)Zz^h^GGU$#DIR6HUc+z zGejaaec(W3w3hKE0*{GGtPLAsQAWpf^}hYS96t7EMqKSgg}{7z8AeI&G=%}{cLOiU z!xhKgrtRhY#;n&IIT&8}{5kJr5YSa6#&|fx2*mut0$>NO5aUr*{YeruZUJ zPbu})fjgMuKn=aRzHTRW2;#uU+ovu%F*b_Wqz?6S=N)keml3S%DaTaJ359s^j-64* zl9Rl{HN2{icZT_IWvSV1;?a~(_c49ZXLuLj+{>OYD3fnzQaAZ*ektMOFt^xlEB&o- z+UuW$80Hi50nen)eY_)Y#K~YF@F=tp2$j$q2n}p$SKx{($|BH^;Yj77U`_7Vw5b@F z2xO^plgeN6M1}MwJn^Ytb;b{v#l@Ev78WjxT3h`fU!N31UF6V_4!Amga-0z3OXh7D z7_q(dy>smR`=5KKR4qe;4+|YuiRupSb}+gqFJ3rT zzeh(Pa`$~>4wFcYM>+zU+>hRmP(b*_vvz%$f&|+p17qWtkOCqk{x5Zh?8NXl7!+mO z73#O2(+MWG_+BnlrG7+)wKNyNMHk3kZqSDW1_RVD7a;No4pAr~Ga!eM^cP1(jR0M` zAEa`D?Fq`b{?HGkqZ{ElIS~-aWz=tX94lf%!I{lBv7hh8qI|I;oRVcqv`WEL2z~(V zLn637#{EUPSsiV}rKXaRl0F$NI#PXiGZG`)dk{2H~7`n5uohh;EPH=*8e6uu$J2-<5d zf)!S);LX{`E0*=@8^Ot8x8dv62so7{OVuD~E64)0=zr>OJzK#YuNFqDAOJ%lYrcvi zS;!~eR#~c?2Rqeho&G2ALQBxYzPjXpU!^u#MxjOoS71faq~P+(X*;mX%&9pQ{!^}A zry)TeM*Dh|4<9FiRnScn=r$*_4vLDt#d~nb~3CpoY@c9Y976=}`)vCAw9xUTH`A zl_VCfYHdM&jDhdi2?$WXLh-*}5imO(N&cDnmTwxCup+bmX}8QIRz;4gu&nWZGey^H@K%`F`P!01i_NRMC7qLD>ye_&+C6A6^ zsUbjg9#T1%VMnHJ6JJV6TUBMtD6CvR`xoCL6+Q(3_CsQL1dWT%YF<^{@nW{Q!Xniq z?4klzYUyoqCHV|Ca-~roxzL%(Vzy-N8f?Y1GJ#NQat7xKG=xj_4dO7_RHE*+5@a`$ zI54+KAD)s!5AC&i@C{jRe5TL6ju?`}4X+Rgd?s002qt*t2-tH&3|b*k&ly%4lVt|D z4>LzZ|XYI14hk{s_g^9$1Co`78 zKB0&%JfFg=V46`Xxgrj!?DkdIw-ZeY);e)eLyAI4(Vx4Nlb>8kLArWS!MvZ(IMf>!X?^S3D>8t+Xe~$}k338XEi;ZTO7#3kf_)2i zm10%ophi;V$02T=UmN9a*j)j0FT>eW*o=#AKTaExE_2bGI~VdfNgBv1RPw6+LbKaw zWy=>9Thuc>bBAO-)BWi8oyO%5+7jnweWmwq4&^v%uYaF*pEjnYTWk{CUr~-d13D?@k{innyakMbpVk#O*w(h#F7MG z?>RdzYl_g{7*c23JqXuUI^;)!5%>{y4Hh8!|C&3MKMb=@2QmHZc)wUuvSP$ zfqbF-ScJt@M=a~YLuzWB1UMcN$}YDMxn=CC!HUrC0vHZDF9jdJaC{XrN_qMTUx+MhCbwO@P=*+VVNgyRPgu7im3{0gYe}x4etzuWYAB02v zoag(c95(+Ae&N^#enHxSl?fA(_%qWBm&#((1@83k_DV*nV4b(B?>ghqJU2TX;PMgQ z$vIPMnQ^pXz>$E?yf7F8p`qteuYBE`jB_(Emp`ny4jL1O6FA8~ODV_o7$L|2d^p(BDth@1$!ZOVKC{ zjr~twD6{VYCnqP|%OLGaa&bQ6r2Px#p5^7`y*9@3@JB04O7>4qz}OFg2($1HmzqfHVk< z)wIUsc-CDn4!ycl=)R&MAl-#gC9SxeoFy1|+j75vE=5*W7G)f=8o?LukMut(4 z(gz(qy&85WyC?1;+7=d&z3_d#iG_t?A42k!q_DMEUaN*0om^;rjL5C4<7Hvl0DF?4 zo46mYckrex1){$;*IxfSet~VXzs=LG+|ldYa*A}sEC1{L%o5NLq?B3$@y^~oFIYin zjf#U?8HiB>c7%=qLL@`sz0WY5a|o6*mDKKg93B?N%Fd2~$Q1G6;pIIl zf;tEuDd6%?KZQDw5^v$)`~%Mc3Ze`_?3*`lLRAaALb*0cq@x~oWrvsZLR?gPt@f#B z___T+zzTY|U1NtC(HNn=azw1;8<~o+#$p+7_Lz@_e|=5or*UrS%r4AbfN|f#{5%42 z6Nf4lST9gBn)z-PfpGW*n8^TP?NOQv3Wf4Hus${-;WUk;Rq*u{3eSfKZ~!$?2RIEP zI$_Eb!Ueyj%)&N%3cCT&+G2sFS#&-K9!K5)WAS~!Mj{2k&nJqOk75MCr|q*>bS0Rn zkv5x;`G3wYZf+1yulJ5X$aqMNZ%qy_Q^A3uJmWeMqatO5Qwocxf`_7jT40xR6* z!^!!v-$oK4AtNILK4~2nyRBQzD5KGr>selo#;k2M2H^b$|Mz3(Ih|HYl0f#r;yUPT zD0Wm2^8E-&RSX!KUWDCN!?>*gDWZl19?y`@xNq{O4^fVR)J2mM6OgZyJTxStrjE+r zfO^k99gY-?=$o{9ng9gT@?smjAWc?33=JtAhD!4D^Mh-W2yBV$^pa0d^ukoXu6i=0 z-FW9#4DD4jw8V}eD(bN{9qlgttr++A8;1|ZVh-OF15UPz|Y^% zX96abXzA3$WQEBi3cgik`! z;IiBWxCyajEX5-OQz*Xxvup>`p!&vYlPdGiQ>EHPTC9?ID5H^Z;s;yTJ)qQnD}(hm zEGqnLwZ&V2K_?k>gfA~I0m-~g3M%%s|3(9Ii}P7qT(9nnp800 zQ+SX;_kcxfvUnCh{di*>8UyGE-;>|X(4&E)JooJzOo6@t_<-zWe~(v4h@!g++zJm( zP^uIP3P^K<@Bd3z4Os<`jMR^3Ks1JL9sGqk6)bhnn&2ftcqsdq4w%CA*=WGlOJhKI$^rzz z74IA)%tHUzo3^C)5AL&_rWdcm?Dk9OICJ`Y*_8Xy>$OnFsSs^d6M?XCd~Q+@Lr6dn zxcV2Gst>7=7zS9SoS%GOW)Er*P`66&kU4I;j&Fh5`&Muplazb|;TdR@P8FQN zxlHofa~XD|q;@&me3tD&!kKB9(-FFiQt3?GrZREF-jsW!U;(-Tm=PKR_~u~P)Acte zCT0|73%A`bfL;RzOB8WP)Y@4O#@~Z53VF><#LxA0c^R3h_Zuf*tx{fA2Bwr+T3Rkt z;xD!mE1kdpd+^$@HatF2`KFocNf^1n4rAzSCi`8<7_0kXWAD)LWgU^O-*-vD)ux4O zxkzq&2QIF5(>-ug!^1#y+VdWWJU8W&)Jz<-)?#ydmanIw(a9AFzPS7MyScD}z}cke z{rd+*;S}ZQ0Ft6!JJ6E~PAnst|AW?1EW1H6u%=NDZwh?YzBYHHZ~A;)&|@|K{{R4v z$&E{n#&oo*uw>#MN$0|FdaNzyv@umW2_UlVNc!6L_JfL2akroEs`O1!W92A6#Pf#$ z3&7cif4&4F3haMYkH&21r^C9Sx(4E}+BAIYTA(`uELE^A^ zmkSTdpJ!jS?QQHpQy|Km_@PuN9XG9`vynPk!iu23t|%wdrSS4s(-*I{A$o%G*Z*w$ z+5jSjK>)z;GNFkLn^{ICc-(&elfU1~moJZv#I7&hZ{B>1>b%O1149vyxQ&IS!?C0cx*-&T2EIl6lT%ZmaqbAW; zoDhmZHUhfgbQg^Gh6WKDS1T2E0dWvya6$M4o($k>K8h&7^&gQg;M~1?^(*5!#EB=Z zrjdH(x-3Lp)mo)fn;uf*JMX_*8?<@5dVBu`!y|LCL+}vIgss_U1NNRk1PODY0>J_b z3L$9B0iOWg@62NDtw4%?jU+$MJ$>MbVT8`IKfsl|Ye^gyyUfBJu3fBTJVCQnuIu&h z@~otU#R6*tFwl{86B84lmY>0u{ug*+D3*3qtCW-!P*x@ypPL~h;Gcm3xn#qLJyZ#4Q8Ca=23E zm&w!;DAFbtCaQU>_xJbVoueH4;KGQi1jyYVNR4~#r`Z}wbuB3WC?Mz}!Ld9ZWmN=D zh-KG=;@}GocHoC8(8VSuaLmHOCgZXmz$?=7fuRn_Xev)aRq>{f=R?2UJEHDj2aJeU z?B>75o1%pfX^`E8A4xy_&QsHs5`jlf&ibYEHylJbC_w4M6&7xVTiki+(}J-_D;ykw zXt*BBf3+^YJXFm)1_D3_u;YF&w5C|3!um+FK>s!WJD8*Z=R;Xpx!i7i2gsm6dxz`< zlB}kd7P0Rap|rWvg*o4aKS+-@UUu2)3z3v$RmIB;{Gd1RGZY&KLLtQHJN@Wb*j%G7 z+@#I62A;qOhl>jb8=H5D@71OEp{u^Wew5FHW6lia!z-M2LwLoUCi|51XE3>)sl4(~sf(q3-Q*hEH6{y9b0?j3&0Dz3Yn%sW9{Fy_7VicUrvOGw~g z2)M4uC@O}Xsc34B!@v@JE*b(lWd9=^uJk~{0*iPV{~78NT7;sEq)z#gJugKJm0%6r zoZpe56VWmcZhZm@?>_dJ6=8#YL-8(R^XNq(LaxkOf4Fnj0n{!-`99{w)D%<6Wg~c-LyWrKMBacuEilZ^u z2avHT3ot37$V+$cQaYj{47kK1fY1Hn#fy=_L5IQjcEH@~2q;{yx`#i-Cg+|@VoQ8o zCeZm#mWoafP2=OVTcrVznBcQeM%XI?YMN8PPxn1}SvMQ0R79XhxY+E@%**QmO*}Bx z0Z-|3=z4SjAqFrnt}oENhmkQ4$b7aqhYw%M%7#={I)fd0zbnXsAP`_{4K|vwv3M32 zj6t7Y=a0oQv+jbPY zeg-pOI=Z@;SXj3)KaqzjDl1zV@N;o#c(<5-d@Qcak#Z9gQB>=IPgeid(6V!zna+>jzbmv#!8H54>kj8{NcX@6)4ZfW%?Kh} zqLK|bMFTxvhJGA&31?q)G5{oiPf~fQ;Nh)QbUqsJ55+n`bV5bP6Y%d6>Sf5K zKs(nz0)uhL;hZWQ@V91Weyyy4 zcNjYrWP$bnDUlU?pj{p-$CrLm`n&S3{;Fk`S|iv}hv&mw5Bz0#7}|2f%gc+DG=%~zk6~-( zN(RB!)X~uRv9ogpc{7+f##y9xc6LHb91IUd1-oGIW*5pqU_n83Pi$F&KLPX>O`qDmwMU`5QfB{55XbVX#aVo~Mgb!KQBqkE&IW)mi!x2Cg|8SWOLP^u z-^CB275Fl`!ij;~3SJz%H5_st8U6cdF!pnHU;{*Mn8Sd?vpVm)eVri61r&Y}J_AOd zVpCJ?#ZZ+5#5=a6AsBK1C7MXe$Gfg+A47pJ{3YY@9@uAtPoNfC5})U$qu7&}(ZlV7 znuyWEhlc_KLI$$*Kk9kmEtV}jn}K*JKTc*>(Zbh;HHAKt?OJIyBiMCU*LVcXX;|k;IRoG zQx$@?K5&SqeeTL?0%c*Y&8K$1XzUIfK^WLCHbDvomS0(FUXZFVi>!eaFd7=#^73+5 zD;dB5Kok#=A)};x;IR)zXm_N`b~1v3y5TVbAbZ;q%@G+L1;6!uY08ru($rm4U6E^7^3d) z;BK^qx#Gya7g>u(>u`FUMg|K$Ol}_i?97g=7fIgRMI| zm|&|hvKj^cD|B`vL@rT*%kX7c6tdsY^r-!n#ygK#>(k+-mlM01lm32sZap0l@ zJIcAnx52?W&*g8UMub4i>U3~)WO%sMWmyWiJ0YB!L|4CSN8uXR9JOqi=1$~4`?6B? zrW_lK5K$buXnK!VwU+(6(6#8s@wwb(UVWqK8!GAgP;4`heg!^6%7K1#v+lO$m zukroIXMn8%gb?!pLwf;kXt=jp{Z5}9n!bjP?w`|B0JyxQ?`{3~5u204NwoxC%_o=y zVZp_lLVKzT3V7+Mkm$ldTje1|lG57xI=~2}TfO#RoM`5~jA_vk0a?w~XqjkG2b>dD zR#wAGy;7Y6kpPfvnlq9ysD+>o&d2F~$Q$VB87~_uBO;Vx3>bjo4(K^v&p13T{al zpOM{t!ys~*pYzJW>Q

    hM&E&clPu8+7?6Sr!Sbg&h4+mV%N}u4v^338F%c44B(l{ z_W1r_z^(-b0kB?v!9If{g?H~>0Gvf25GZdjKaGWZ*%exzG&D3qS*YV*&$%&OJ_~lH zpc4nX)ySXY0m2-Dvs?3gU*9i?KJ$Pgt0y98FMkcLD?VyCGv#VNoxu~KUU(jUyh zvaz$zLrQOL&4{3-rR|(IHUipjP!Kx894OUryx}rbQdWi>N+3KR=2lTjB)ovE%uJZb z@_>E2oD5tvDpB9M+*}DVJd-x>YL{1#2t$8cQB93T$fKlr+ZzJkuMa-})cE$TJ|{-z z?#j=fh2!>L%p7?s-0#_zcU2!9cP#ClUk12VZ*4x22Ex<#IC!y60J`w0*(N#Obf)(C z^P}9L@l>C&j6&~&v7pzkF$^Q+0}mhWZ^uoRbcoco(5zri7_{D$_y-23uWsSuJ`Mmo zO+`Ez0|WBWL-t`IVc{GRpBjf8{q<3EAj}4t{ygb@zIv+a+>%QZk1tendx3wXg{YSDZwNnCf@m0yACmsA_|Z`QK>q^8f z+e#&Cb=TZdkb}9urstD+@c$;*O##=h;Minl(r`d+%iadCEf~%M>jn}zt~Fq+i;Igx zhu|;@$SZJEAW49{2HtH&d(FOq3K+#gSy{my@x_{F1kM{kRxue(nJ~T$Tu;F85eRrr zfH0jbQmgQH;rl@Vv>7(1T#18hGh_Rco}H7^1puveFGY^6ONLlSl;4q^i!0x}VUTjN zM9-UwO%_uZRLR^aF58HD$A@VE{poVHpeAP^!S}z|X@ug-e>LjuaO`N7@cP~!iroa2 zzq2cD!l_5sb%V~+887g*Q`S6|G~7KEmK8Zy~ATO ze(=cUp*tWUu+%Op@zzlf*?B2c;r&5cB_}6mV34NI{txUagMXQunr6cp7#eDU>|)%$ z;;LA$Lf;~LV2BGwUzAX&iQRoBCa@n4PXStW$gLO;#gNG8wnq!dr^Pcuu@|!NF}Ju& zqviKh`#%$?Mezo<>aIU%GT0=#u!kyY*0EloKkQvx`~_bu`^8X6lLH9UZZG7jM!UN2h` z8z0~C-#@E-TXVsop|@olQSiH!6;R1)YY!pA0<4ykXaWAHM<`$$CAA4w?XYhr?Rf#N zvDwN0zCHW#`e%YVJp%)PlkZj1=snv1t&3l4vJk<;LN){`?|b!}57i}5YpQ`kv;On! z)KnC?8TwfNz>^(Vws1uP(;HqTh9m$L%P53xFW~wCNrb4VD6psh!W=#FyRXFPuH+C7 z^T+iTThm^*Mwvve3<$%I|=Fi~&5bHM|Zry0M9gww9J-1)Y_FCqRjiD8c%`Dna%O zg1SWgu7H?<-ry+MsU|SIbQ^cZkc9Qd$2bG0WfBhKzc95keMS#eG>x!lMb)QR3o;_v zHMcWJ3_`TMPXa0Ad(J^+!b|0vQ{Wkv9-5;b5Ch5S|a= z$*9&=^;n!2(Fr&{c&K{rPz2IK@JRKJgM`XE z5k)g@Ws50NNj60WDc2E7Q%0hcw%lSglfR5x5^|}?JzY(?j)>ZBMa?cM6#r-T{-1Tu zI%gfrnzb-%{APaN_rA~jywCf53!>;xeAy3LmecAVZLFV=xm3`cer+7p+5@x`#Y``* z7}a0)v~@nF`z~CNi!wzuitCY#gtdRy2CEiN`@-O`vWLF4gyJ^OE(!97%luR zae1k+QxX?sM6JZkInBW_jjjekpHjj9m#Z2v!bfGTUN3q65+f)R4T7 z#g2%WJE>cK|GtH}xl^f+#ENS7eX+izmDiZJdu=Ke&s}$zv|($QSZ=wuz*>1ssi(bk zu{H_F=ZzTOT5}xK8#~(Dn|CZgGY2`gH)latD?j)Ym~;$ui*rOLR9U~ z+z%%*nRPx8@8L|}?#DqO)cSu#dWbt*E$P{R5nXP|jb1`@l~bC!o{`SVwVS-L&ScZS z*aJf9>EaJZU!)Fw{5S~$#CYrpiW?9#)A*r(6BL$aK0ZD%4&1Tc!9hmavLk79+e4g) zJG1+{pQ2yd)-EZq%CduzaVwt(enAVK5d$~QbiaJL0Uj5poYus*hS>vBimTRVcYF0e z&3&0o*}BzHL!oYOx_wS?8qP`YNAYI-qbD4P&nGPn`q--J;+Sxg5B&jAnm%~IF1}mf z@v3X4g*fI}7Edpv>{>iG&0ErIW%fMaJ$HdO+N|P`0qBbYez3jZJ+|I$bgj`-%>4A* zo`c7Z4Wp&0qM}mlFoL;tuixcVR32i!7s=1k=wG|aDoJmVMWsMhwy{Bkg{ z6<~zG9bid-2Y3q<<^OWqqQ#3p4h-x&a3C0Q?`u4Q*5``J<3OpfZt*he0F=WwicD9q z1NfD{pI>&x)w=oX9Ew&M7&v6U9z#bH-k0A$Q(Sz|!=W?CF$D*S_&+@#jvHNdVbgeVv5QhebhR$mcQx5cI zL)gk-KZs2&(6c}bJT5hLo#P#Vk&Hca2`7=~v3ogjaqoM3DOY#gJKp8_sZ7j#v+EWh z*UGOLnk6YY&(=VKfIto;HH$!6ym_6G(G*CZR}38#eA{;y;l`k6ryusSG%~UQejpKh zTnH>=?zAobn67?PRYm2|lOl02)%XAaHmHtW&_;thp%Ipb{osv{z=9y<%5!8c6wzm< zr@wvDHPgI{5x{OBuW9Ekja5HT3+vv_0<3s<$fBiQ|=%x26Xs!q!}!sJ_`*BNU`tAlXk= zyg;V)etFKUB!1tTS;T4`vW>RranJ!R&s-1!%uAQ$`JIry{nBn{gN8FI?FCv z`{qmgz>e?l)txdpGfqCA+7LrF3{*JW)5G6AHMqsjz4YQ0@mD6NI&4r#?o@3lkD2>< znoh_mm^N=0c*JU{EJ>xGI19Gm^^BAisNImMhW*mvcColKfbI|<>yPhTr6`4g7OTiS$1<^O2Du$*O^GyjbN%IOJkAVO zTuf74of~G>fPc4@d=YpS1Nq`3lZv3JDcA1XA@AYFPBm1~V6)Bh3c6DkEn0N3?j4uA zjCO&>gI8{)U!SG5wKZJcUj~-Lb8P9tg-0JM5o`q9)lxSql9^J3?3g>ai*3T^fCHDK zHx|lXq_1);_Ke3AxLECiN&&zt>D!*cM854xIYZ;{(i)4vz%kI#Xfn57Y?P6aLCNy` z*|VQe@>u0umuPYuW}LXa&+_4)zm`flyXh?M6>GJDT+{M@OireFvlXITL07P2@e!Mu zo7>yjkxm85Y76FStT(ZFdKy3;)H2pAhLl}1ZIY%|X=-{SIRMZdjf|f`{~q+b(jxS{ zuc&{UD0VNIXP>hz@PnPN?_aon#7Sp^&`snRd`8F*W22*Q?z&xcT#tZdK6SmjGj2t}{13aJG^v27Che{2 ztQl448N%$#J3*P7IcL|^X9K~))dXU}9`#&4Uq57&k2XCDWAO!q{7S!KB&P1CeodZ% z-vD~Sh!OBRD*TLYile=Kt3cq3b&8M-iZwMgmBnHq94=qI+JjzMQD?fr?@nCA`du^r z{<5+$QxmMsfAD3r@>P(@&9G@H)))@|IRALxYio(^7vjl0$MwdL!$Ywot7709QULo3 zXo0YIkUfCC>mir{J*0Q6-T9kJNcR)6_F+>R?HtBtPM`h-tcs%zZj6>`YHETjKr<~(IGD)VuRprsw%_b0)~zf>ES0QtgN$dU-rx1DooG1?MmNtj*#2H{7&o` z8ARi$BU2y{0IAy;l%6O_*&6Iuxm3{IeY?eT*GwN%wcU1hiuWtXK|&jM_mv|==LOKr znWq=DRq9;b!8UK-XL~5>>)?O}Gbn4$`PH4e)#c>|QKs+Sz0y5ywkCe+Tj!?k=+`wh z>RY$Mg~a&t_`3~lhK?37LuDUy4uxNzl&FERhHpTCtKOH0%o=H0k7B20LH~yjo?1#) ziK`AeI2%z2ny1>zazlenY#ydaV~y5 z^NLjM{@bMJY?5}gg%86m84c#5;$nH)C3E!}t;5=j5<^>t0wp%ri7eR%9qNSYVt(=qLIUNdJ`N1=2GT_S21+_-1WU|5Do(Z z12Z_)TVEV~{c)^Foh18Qx<(A6-q@Tj(f+@~|5ygHqvNU;+5`DdEobby^K$IY` z+M51;9QIUo!Hq$P4_PmA(NZdM(9}!(SsL`&DKvBvIxjQB3(Ba{w{7EuL+E($pe|Wj z?+h1~`^)4;g^pG{I^-M)_8Ofg(nf3l^DkS7i!>cfi6~Zw#&0_0$qPfSRZSN#AnwSsTZ8&LBt|;@w{!tIplEAaX6%uX3C<+yGPIj}xTK6Z zBjcBRPyu*&c;IZE6!iM+?H7*dccF<1q2wQliQmEe%#oBtd-o#qW;Ys07#J!+EslTU zkNgHp0uaw>MyIda=BR-1g**lFrGdUaq&HvY&cpcl97wwQt4#8!_10aO_GxU~nJ&;G zq5IT_Xf_yNAmo(;YNQJu8##g5&dIN^)U(+zHZ}&qDPVI5iujRrT|g+Q9L~k)XojS= zIsz;5&G7s0-Jv!-Iz6Ul0iSx2H%HRzf-a-PosC4n!GT02C3+NBu*U3I3CVOn6byvKKCG(*+b4YD^aWk zIDXve-Z5pYh%CG8{{DW51UFRtP%|)?2$wbDa`>H~AmN(_jt9&VXlvu2A`@YhzJxAA zxtTlr{Qhueajk<5gnY~7lG38<-d(;d6CFJ9%Ci{YBy6O(O=13g4@iaHym>$qKB9s-O>su7EbHf%V7+fZa8h$I&gu(SSo zf1v#k_HSjPZ$G@8e3{|lf#a~K=*)vEW4I3`q@?^t>_97?@+a~Q4p0Dd{{HcIOl{|j zL_Xi5EkIR(g}P?B+#=csX%WTF{!$+b#dJ+PYP(JbdzLOkzM1PLerKJ;foI8upji?U z7P`B;V_2iPS;y^(BGyFFy?ZN`FOPsIrL!b|VBgUX3JMCCt!yy5otFm^4a{8T;>JJW zZl`}z#I16U-66Kh;OFOm|N1puCHvz3b*&%AhL3Qp8>%Ay$l5OLK+t6*Q(C!Qo2#*8 zfiYpRwH`I;-~8kepy(o#K!|irP|qS@Uf1;^QjkBy)952~ww%J>5~U|b6#%~`CNqQ9 zE5k2DoV>tzSzB3c#U=$Ch9%en##x}Yw~v(H(%>-x3S z)MMnahS{L2Cg7qmmjbK+mWQVjxt1Poa+bX08n2nVO%KcoE6kUF1M__Cs$>cx4Eg_g zyxwKamwd`^`A}V5U0+|14rFbuX_P6=P@Yi9o#QPVBUjGR_f=cI+-yZ0?#3I)JXXX( z?Ta-2>c#9wi}=(vT0GVA@yW@_i3xPJ1&xha6%}D{X$9~@xy|LwV{M>^+x4hY0)j<7 zCi4fWa58GiJRRNTxr>B?ABb=P2yJH@i z5}p}F>)c$ z=D<&D{p!_QpnL)S&@uU~$V5U!^lYkcBJxTg+GXnHLlIM7Tf1b7pKITf`2YH|&lR~e z1`0EzT$qtD^YKtrErbw-N7si^ zK`0akbq6;H1lmSMY0OmwRjRZQH)HEjh|gfN8uBnrPC-fOBudzUw9w1{^9cyZSf07r z*)4 ql)?vg&jl&PsYdyK-+kfq%!_d^&pnzTPQt2;u+z-i^ft};+`j>?Mk}WP literal 42294 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 diff --git a/docs/src/examples/quantum1d/7.xy-finiteT/index.md b/docs/src/examples/quantum1d/7.xy-finiteT/index.md index 264ebade7..b05342a1e 100644 --- a/docs/src/examples/quantum1d/7.xy-finiteT/index.md +++ b/docs/src/examples/quantum1d/7.xy-finiteT/index.md @@ -66,8 +66,7 @@ The Hamiltonian can be diagonalized in terms of fermionic creation and annihilat E_0 = -\frac{1}{\pi} \text{EllipticE}\left( \sqrt{1 - \gamma^2} \right) ``` -!!! todo - Show the derivation of the ground state energy by diagonalizing the Hamiltonian in terms of fermionic operators. +The derivation, via a Jordan-Wigner transformation to free fermions followed by a Bogoliubov rotation, can be found in [Lieb, Schultz & Mattis, Ann. Phys. 16, 407 (1961)](https://doi.org/10.1016/0003-4916(61)90115-4). ````julia function groundstate_energy(J, N) @@ -125,11 +124,11 @@ println("Exact (N=Inf):\t", groundstate_energy(J, Inf)) ```` ```` -[ Info: DMRG2 1: obj = -5.004084801485e+00 err = 9.7485774328e-01 time = 1.43 min -[ Info: DMRG2 2: obj = -5.004096940647e+00 err = 1.1899230994e-06 time = 1.27 sec -[ Info: DMRG2 3: obj = -5.004096975044e+00 err = 2.2262868216e-09 time = 0.80 sec -[ Info: DMRG2 conv 4: obj = -5.004096975044e+00 err = 1.1612932838e-13 time = 1.47 min -Numerical: -0.15637803047010942 +[ Info: DMRG2 1: obj = -5.004084869795e+00 err = 9.8826020061e-01 time = 1.04 min +[ Info: DMRG2 2: obj = -5.004096937587e+00 err = 1.1541480959e-06 time = 0.42 sec +[ Info: DMRG2 3: obj = -5.004096975044e+00 err = 2.5015824967e-09 time = 0.72 sec +[ Info: DMRG2 conv 4: obj = -5.004096975044e+00 err = 1.8118839762e-13 time = 1.07 min +Numerical: -0.15637803047010948 Exact (N=32): -0.15637803047254015 Exact (N=Inf): -0.15915494309189535 @@ -173,8 +172,7 @@ The resulting expression is Z(\beta) = \prod_{k=1}^{N} \left( 1 + e^{-\beta \epsilon_k} \right)^{1/N} ``` -!!! todo - Show the derivation of the partition function for the XY model. +This expression follows from the same free-fermion diagonalization as the ground-state energy above: each single-particle mode $\epsilon_k$ is independently occupied or empty, giving the usual free-fermion partition function (see again [Lieb, Schultz & Mattis (1961)](https://doi.org/10.1016/0003-4916(61)90115-4)). ````julia function partition_function(β::Number, J::Number, N::Number) @@ -308,9 +306,6 @@ Z(\beta) = In other words, we can compute the partition function at $\beta$ by computing the overlap of two states evolved for $\beta / 2$, as long as the Hamiltonian is Hermitian. Otherwise, we could still use the same trick, but we would have to compute the evolved states twice, once for $H$ and once for $H^\dagger$. -!!! todo - Add a figure to illustrate this trick. - ````julia double_logpartition(ρ₁, ρ₂ = ρ₁) = log(real(dot(ρ₁, ρ₂))) / length(ρ₁) diff --git a/docs/src/examples/quantum1d/7.xy-finiteT/main.ipynb b/docs/src/examples/quantum1d/7.xy-finiteT/main.ipynb index c6a7df3ce..b6633cbb1 100644 --- a/docs/src/examples/quantum1d/7.xy-finiteT/main.ipynb +++ b/docs/src/examples/quantum1d/7.xy-finiteT/main.ipynb @@ -1,8 +1,10 @@ { "cells": [ { - "outputs": [], "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "using Markdown\n", "using TensorKit\n", @@ -14,12 +16,11 @@ "using Plots\n", "using LinearAlgebra\n", "using BenchmarkFreeFermions" - ], - "metadata": {}, - "execution_count": null + ] }, { "cell_type": "markdown", + "metadata": {}, "source": [ "# Finite temperature XY model\n", "\n", @@ -33,19 +34,20 @@ "$$\n", "\n", "Here we will consider the anti-ferromagnetic ($J > 0$) chain, and restrict ourselves to $J = 1/2$." - ], - "metadata": {} + ] }, { "cell_type": "markdown", + "metadata": {}, "source": [ "Parameters" - ], - "metadata": {} + ] }, { - "outputs": [], "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "J = 1 / 2\n", "T = ComplexF64\n", @@ -63,12 +65,11 @@ " end\n", " end\n", "end" - ], - "metadata": {}, - "execution_count": null + ] }, { "cell_type": "markdown", + "metadata": {}, "source": [ "## Diagonalization of the Hamiltonian\n", "\n", @@ -79,15 +80,14 @@ " E_0 = -\\frac{1}{\\pi} \\text{EllipticE}\\left( \\sqrt{1 - \\gamma^2} \\right)\n", "$$\n", "\n", - "> **Todo**\n", - ">\n", - "> Show the derivation of the ground state energy by diagonalizing the Hamiltonian in terms of fermionic operators." - ], - "metadata": {} + "The derivation, via a Jordan-Wigner transformation to free fermions followed by a Bogoliubov rotation, can be found in [Lieb, Schultz & Mattis, Ann. Phys. 16, 407 (1961)](https://doi.org/10.1016/0003-4916(61)90115-4)." + ] }, { - "outputs": [], "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "function groundstate_energy(J, N)\n", " isfinite(N) || return -J / π\n", @@ -95,22 +95,22 @@ " ϵ = SingleParticleSpectrum(T)\n", " return Energy(ϵ, Inf, 0) / N\n", "end" - ], - "metadata": {}, - "execution_count": null + ] }, { "cell_type": "markdown", + "metadata": {}, "source": [ "### Exact diagonalization\n", "\n", "We can check our results by comparing them to the exact diagonalization of the Hamiltonian." - ], - "metadata": {} + ] }, { - "outputs": [], "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "N_exact = 6\n", "H = open_boundary_conditions(XY_hamiltonian(T, symmetry; J, N = Inf), N_exact)\n", @@ -121,22 +121,22 @@ "println(\"Numerical:\\t\", minimum(real(vals)))\n", "println(\"Exact (N=$(N_exact)):\\t\", groundstate_energy(J, N_exact))\n", "println(\"Exact (N=Inf):\\t\", groundstate_energy(J, Inf))" - ], - "metadata": {}, - "execution_count": null + ] }, { "cell_type": "markdown", + "metadata": {}, "source": [ "### Finite MPS\n", "\n", "If we wish to increase the system size, we can use the finite MPS representation." - ], - "metadata": {} + ] }, { - "outputs": [], "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "N = 32\n", "H = XY_hamiltonian(T, symmetry; J, N)\n", @@ -150,12 +150,11 @@ "println(\"Numerical:\\t\", real(E_0))\n", "println(\"Exact (N=$N):\\t\", groundstate_energy(J, N))\n", "println(\"Exact (N=Inf):\\t\", groundstate_energy(J, Inf))" - ], - "metadata": {}, - "execution_count": null + ] }, { "cell_type": "markdown", + "metadata": {}, "source": [ "## Finite temperature properties\n", "\n", @@ -195,15 +194,14 @@ " Z(\\beta) = \\prod_{k=1}^{N} \\left( 1 + e^{-\\beta \\epsilon_k} \\right)^{1/N}\n", "$$\n", "\n", - "> **Todo**\n", - ">\n", - "> Show the derivation of the partition function for the XY model." - ], - "metadata": {} + "This expression follows from the same free-fermion diagonalization as the ground-state energy above: each single-particle mode $\\epsilon_k$ is independently occupied or empty, giving the usual free-fermion partition function (see again [Lieb, Schultz & Mattis (1961)](https://doi.org/10.1016/0003-4916(61)90115-4))." + ] }, { - "outputs": [], "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "function partition_function(β::Number, J::Number, N::Number)\n", " T = diagm(1 => J / 2 * ones(N - 1), -1 => J / 2 * ones(N - 1))\n", @@ -220,12 +218,11 @@ "\n", "Z_analytic = partition_function.(βs, J, N);\n", "F_analytic = free_energy.(βs, J, N);" - ], - "metadata": {}, - "execution_count": null + ] }, { "cell_type": "markdown", + "metadata": {}, "source": [ "### MPO approach\n", "\n", @@ -235,12 +232,13 @@ "In order to build the time-evolution operator, we can repurpose the `make_time_mpo` function, which constructs the time-evolution operator for the ground state.\n", "However, since we are interested in $e^{-\\beta H}$, instead of $e^{-iH dt}$, we work with $dt = -i \\beta$.\n", "In particular, we can approximate the exponential using a Taylor series through the `TaylorCluster` algorithm." - ], - "metadata": {} + ] }, { - "outputs": [], "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "expansion_orders = 1:3\n", "\n", @@ -274,22 +272,21 @@ " plot!(p2, βs, F_taylor; label = labels)\n", " plot(p1, p2)\n", "end" - ], - "metadata": {}, - "execution_count": null + ] }, { "cell_type": "markdown", + "metadata": {}, "source": [ "Some observations:\n", "- The first order approximation fails to capture the behavior of the partition function.\n", "- The higher order approximations are in good agreement with the analytical result, as long as $\\beta$ is not too large.\n", "- The computational cost of the approximations does not depend on $\\beta$, but on the order of the approximation." - ], - "metadata": {} + ] }, { "cell_type": "markdown", + "metadata": {}, "source": [ "To address the first point, we can have a look at the particular form of the time-evolution operator.\n", "Here we see that for this particular Hamiltonian, all the terms with factors $d\\tau$ are either zero or have trace zero.\n", @@ -312,12 +309,13 @@ "\n", "Therefore, we will exclude the first order approximation from now on.\n", "Zooming in on the differences with the analytical result, we find:" - ], - "metadata": {} + ] }, { - "outputs": [], "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "expansion_orders = 2:3\n", "Z_taylor = Z_taylor[:, 2:end]\n", @@ -340,12 +338,11 @@ " )\n", " plot(p1, p2)\n", "end" - ], - "metadata": {}, - "execution_count": null + ] }, { "cell_type": "markdown", + "metadata": {}, "source": [ "We can now clearly see that, somewhat unsurprisingly, the error increases the larger $\\beta$ becomes.\n", "Given that we are computing Taylor expansions around $\\beta = 0$, this is to be expected.\n", @@ -360,17 +357,14 @@ "$$\n", "\n", "In other words, we can compute the partition function at $\\beta$ by computing the overlap of two states evolved for $\\beta / 2$, as long as the Hamiltonian is Hermitian.\n", - "Otherwise, we could still use the same trick, but we would have to compute the evolved states twice, once for $H$ and once for $H^\\dagger$.\n", - "\n", - "> **Todo**\n", - ">\n", - "> Add a figure to illustrate this trick." - ], - "metadata": {} + "Otherwise, we could still use the same trick, but we would have to compute the evolved states twice, once for $H$ and once for $H^\\dagger$." + ] }, { - "outputs": [], "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "double_logpartition(ρ₁, ρ₂ = ρ₁) = log(real(dot(ρ₁, ρ₂))) / length(ρ₁)\n", "\n", @@ -403,12 +397,11 @@ " )\n", " plot(p1, p2)\n", "end" - ], - "metadata": {}, - "execution_count": null + ] }, { "cell_type": "markdown", + "metadata": {}, "source": [ "### MPO multiplication approach (linear)\n", "\n", @@ -436,12 +429,13 @@ "> In particular, the truncation of the MPO is now happening in the Frobenius norm, rather than the operator norm.\n", "> While for small truncations this might still work, this is not guaranteed to be the case for larger truncations.\n", "> As a result, the truncated object might not be positive semidefinite, spoiling its interpretation as a density matrix." - ], - "metadata": {} + ] }, { - "outputs": [], "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "Z_mpo_mul = zeros(length(βs))\n", "D_max = 64\n", @@ -489,12 +483,11 @@ " )\n", " plot(p1, p2)\n", "end" - ], - "metadata": {}, - "execution_count": null + ] }, { "cell_type": "markdown", + "metadata": {}, "source": [ "This approach clearly improves the accuracy of the results, indicating that we can indeed compute partition functions at larger $\\beta$ values.\n", "However, the computational cost of this approach (at fixed maximal bond dimension) is now linear in $\\beta$, since we need to compute the partition function at each $\\beta$ value.\n", @@ -509,11 +502,11 @@ "The accuracy of the initial density matrix can be improved by increasing the order of the Taylor expansion, but this will result in a larger MPO bond dimension.\n", "On the other hand, if we improve the accuracy of the initial density matrix, we could also increase the step size, which would reduce the number of iterations required to reach a certain $\\beta$ value.\n", "Keeping these parameters in balance is necessary to obtain accurate results, and this might require some trial and error." - ], - "metadata": {} + ] }, { "cell_type": "markdown", + "metadata": {}, "source": [ "### MPO multiplication approach (exponential)\n", "\n", @@ -529,12 +522,13 @@ "$$\n", "\n", "In other words, we can scan a range of exponentially increasing $\\beta$ values by squaring the density matrix at each step." - ], - "metadata": {} + ] }, { - "outputs": [], "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "βs_exp = 2.0 .^ (-3:3)\n", "Z_analytic_exp = partition_function.(βs_exp, J, N)\n", @@ -582,12 +576,11 @@ " plot!(p2, βs_exp, abs.(F_mpo_mul_exp .- F_analytic_exp); label = \"MPO multiplication exp\")\n", " plot(p1, p2)\n", "end" - ], - "metadata": {}, - "execution_count": null + ] }, { "cell_type": "markdown", + "metadata": {}, "source": [ "Clearly, the exponential approach allows us to reach larger $\\beta$ values much quicker, but there is again a trade-off.\n", "Since the size of the steps are increasing, we need to be more careful with the accuracy of our approximations.\n", @@ -596,11 +589,11 @@ ">\n", "> Again, using MPS techniques to approximate the multiplication of density matrices might lead to unphysical truncated density matrices.\n", "> Increasing the stepsize could make this happen sooner, so we need to be careful with the maximal bond dimension." - ], - "metadata": {} + ] }, { "cell_type": "markdown", + "metadata": {}, "source": [ "### Time evolution approach\n", "\n", @@ -615,12 +608,13 @@ "\n", "The starting point for this approach could be either achieved through one of the techniques we have already discussed, but we can also start from the infinite temperature state directly.\n", "In particular, this state is given by the identity MPO, and we can evolve this state to compute the partition function at any $\\beta$ value." - ], - "metadata": {} + ] }, { - "outputs": [], "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "Z_tdvp = zeros(length(βs))\n", "\n", @@ -666,43 +660,41 @@ "\n", " plot(p1, p2)\n", "end" - ], - "metadata": {}, - "execution_count": null + ] }, { "cell_type": "markdown", + "metadata": {}, "source": [ "> **Note**\n", ">\n", "> We could further improve the accuracy of the TDVP approach by evolving with $(H \\otimes \\mathbb{1} + \\mathbb{1} \\otimes H^\\dagger)$, rather than $H \\otimes \\mathbb{1}$ which is the current implementation.\n", "> This is known to improve the stability of the positive semidefinite property of the density matrix, and could lead to more accurate results." - ], - "metadata": {} + ] }, { "cell_type": "markdown", + "metadata": {}, "source": [ "---\n", "\n", "*This notebook was generated using [Literate.jl](https://github.com/fredrikekre/Literate.jl).*" - ], - "metadata": {} + ] } ], - "nbformat_minor": 3, "metadata": { + "kernelspec": { + "display_name": "Julia 1.12.6", + "language": "julia", + "name": "julia-1.12" + }, "language_info": { "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", - "version": "1.12.4" - }, - "kernelspec": { - "name": "julia-1.12", - "display_name": "Julia 1.12.4", - "language": "julia" + "version": "1.12.6" } }, - "nbformat": 4 + "nbformat": 4, + "nbformat_minor": 3 } \ No newline at end of file diff --git a/examples/Cache.toml b/examples/Cache.toml index c3645d920..a3da16c71 100644 --- a/examples/Cache.toml +++ b/examples/Cache.toml @@ -3,11 +3,11 @@ [quantum1d] "2.haldane" = "c5a0eb70f0930d38053535c659ab39a87121b6ebda040ceadd9deb5f30921315" -"6.hubbard" = "cef140a6224350345735aac889ee7e33724fc0af9ce94f68be47a7e40107c09c" -"7.xy-finiteT" = "0f330a157bea739a43a82a937791c680b2fa6e5e479171ee5ef318d1fdae7bcf" +"6.hubbard" = "8e45bc248cafbabb296d56dc88165c6d7670be2f37b680508de42596042435c0" +"7.xy-finiteT" = "0d21f7556fee8409edb58ab0ea04a77bd90feb2dffec424f0a5962d11dfdfc65" "8.bose-hubbard" = "ba9ec53721371aab311dadbe05a31a3c95cb1b8a394abb7f81ee97e15b84d503" -"3.ising-dqpt" = "a2900eed23de7655f600943fae72d1dc35f87f33d11947f707d302ce245399fe" +"3.ising-dqpt" = "056423a189e1b1d4110bebc4eb6129a957ecdbf8e9a679eca10cf0391494b944" "5.haldane-spt" = "c8fd3a8d406b9ff3ea9a34b596c5910d81e4eb710b665d7fa04e30f795a46086" -"4.xxz-heisenberg" = "9033fb104c3f658ccb1b8e335b986b7abda59e0b5359be086d3b62e1cc32ebd6" -"1.ising-cft" = "3d34757eee7b95120b746c5e30e713203a876a87353ecd9937798f29183c9916" +"4.xxz-heisenberg" = "5fa4242290b0a9ae658caf54f6919a8e04c97af80b9fcc6b936c2f45c7c8efdd" +"1.ising-cft" = "ebcae1e501347cb00a46d0889df1355707be77cf962f9ee0d16416393492529b" "0.tfim-groundstate" = "f436cb78f72c7ca59c99a192ab5649c57f912f9fc4838e33faa7440a025f0893" diff --git a/examples/quantum1d/4.xxz-heisenberg/main.jl b/examples/quantum1d/4.xxz-heisenberg/main.jl index fb7f0340e..a4b4c3d0d 100644 --- a/examples/quantum1d/4.xxz-heisenberg/main.jl +++ b/examples/quantum1d/4.xxz-heisenberg/main.jl @@ -7,9 +7,10 @@ The necessary packages to follow this tutorial are: using MPSKit, MPSKitModels, TensorKit, Plots -#src # for reproducibility: -#src using Random -#src Random.seed!(123) +# For reproducibility of this page, we fix the seed of the random number generator: + +using Random +Random.seed!(123); md""" ## Failure diff --git a/examples/quantum1d/6.hubbard/main.jl b/examples/quantum1d/6.hubbard/main.jl index 9a5c84aaf..3c41222ae 100644 --- a/examples/quantum1d/6.hubbard/main.jl +++ b/examples/quantum1d/6.hubbard/main.jl @@ -36,9 +36,10 @@ using Plots using Interpolations using Optim -#src # for reproducibility: -#src using Random -#src Random.seed!(123) +# For reproducibility of this page, we fix the seed of the random number generator: + +using Random +Random.seed!(123); const t = 1.0 const mu = 0.0 From ca76bf49d1f44b68ec75d1e6dec263c1c697c252 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Sun, 5 Jul 2026 06:42:26 -0400 Subject: [PATCH 38/76] small improvements --- docs/src/tutorials/first_groundstate.md | 13 ++++++------ examples/quantum1d/0.tfim-groundstate/main.jl | 21 ++++++------------- examples/quantum1d/6.hubbard/main.jl | 16 +++++++------- 3 files changed, 21 insertions(+), 29 deletions(-) diff --git a/docs/src/tutorials/first_groundstate.md b/docs/src/tutorials/first_groundstate.md index f9a825b9e..65cc4545f 100644 --- a/docs/src/tutorials/first_groundstate.md +++ b/docs/src/tutorials/first_groundstate.md @@ -135,15 +135,16 @@ At finite `L` the exact ground state does not break the symmetry: it is the symm DMRG at finite bond dimension, however, converges to one of the two symmetry-broken states instead, because either one carries far less entanglement than their symmetric superposition. Which sign it lands on is arbitrary — it can differ from run to run and between values of `g` — so taking `abs` makes the order-parameter curve well-defined regardless of the branch. -The plot shows the magnetization close to 1 deep on the ordered side, then dropping abruptly to zero — noticeably *below* the thermodynamic critical point `g = 1` (around `g ≈ 0.6` at these parameters). -Both features follow from how the state is computed rather than from the physics of the transition: on the ordered side DMRG sits on one symmetry-broken branch, and past the drop it recovers the exactly symmetric ground state, whose magnetization vanishes. -Exactly where the drop lands depends on `L`, `D`, and even the random starting state, so its location is *not* a measurement of the critical point. - -The honest way to locate the transition is the subject of the next tutorial, which performs this sweep directly in the thermodynamic limit. +The plot shows the magnetization close to 1 deep on the ordered side, then dropping to zero — noticeably *below* the thermodynamic critical point `g = 1` (around `g ≈ 0.6` at these parameters). +Both features follow from how the state is computed rather than from the physics of the transition: +on the ordered side DMRG sits on one symmetry-broken branch, and past the drop it recovers the exactly symmetric ground state, whose magnetization vanishes. +Exactly where the drop lands depends on `L`, and `D`, so its location by itself is *not yet* a measurement of the critical point. +The honest way to locate the transition is by performing scaling analasys, taking the limit of infinite size and bond dimension. ## Where to go next You have run a full MPSKit workflow: build a model, optimize an MPS ground state, measure observables, and scan a parameter. -A natural next step is [The thermodynamic limit](@ref tutorial_thermodynamic_limit): the same calculation performed directly at infinite system size with an `InfiniteMPS`, which removes the finite-size effects seen above and lets you locate the critical point more cleanly. +A natural next step is [The thermodynamic limit](@ref tutorial_thermodynamic_limit): +the same calculation performed directly at infinite system size with an `InfiniteMPS`, which removes the finite-size effects seen above and lets you locate the critical point more cleanly. To go deeper on the individual steps, see [Constructing states](@ref howto_states), [Building Hamiltonians](@ref howto_hamiltonians), [Computing observables](@ref howto_observables), [Controlling bond dimension](@ref howto_bond_dimension), and [Entanglement entropy and spectrum](@ref howto_entanglement); the algorithm reference is [Ground-state algorithms](@ref lib_groundstate). diff --git a/examples/quantum1d/0.tfim-groundstate/main.jl b/examples/quantum1d/0.tfim-groundstate/main.jl index 79565b9df..478e42ccf 100644 --- a/examples/quantum1d/0.tfim-groundstate/main.jl +++ b/examples/quantum1d/0.tfim-groundstate/main.jl @@ -108,21 +108,12 @@ vline!(p_magnetization, [1.0]; color = "gray", linestyle = :dash, label = "g = 1 p_magnetization md""" -Both calculations agree deep in either phase, but near the transition they tell very -different stories. -The infinite curve stays on its ordered branch essentially up to `g = 1` and then -collapses: it locates the critical point cleanly. -The finite-chain curve instead drops to zero far earlier — at this `L` and `D` the -variational optimum on the open chain switches from the symmetry-broken branch to the -exactly symmetric ground state, whose magnetization vanishes. -Where that switch happens is set by `L`, `D`, and even the random starting state, not by -the physics; the same sweep at `D = 4` in -[Your first ground state](@ref tutorial_first_groundstate) puts it elsewhere. -That is the real lesson of this panel: the finite-chain order parameter is dominated by -which state the algorithm selects, while the calculation performed directly in the -thermodynamic limit pins the transition at `g = 1`. - - +Both calculations agree deep in either phase, but near the transition they tell very different stories. +The infinite curve stays on its ordered branch essentially up to `g = 1` and then collapses: it locates the critical point cleanly. +The finite-chain curve instead drops to zero far earlier — at this `L` and `D` the variational optimum on the open chain switches from the symmetry-broken branch to the exactly symmetric ground state, whose magnetization vanishes. +Where that switch happens is set by `L`, `D`, not by the physics; the same sweep at `D = 4` in [Your first ground state](@ref tutorial_first_groundstate) puts it elsewhere. +That is the real lesson of this panel: the finite-chain order parameter is dominated by which state the algorithm selects, while the calculation performed directly in the thermodynamic limit pins the transition at `g = 1`. + """ md""" diff --git a/examples/quantum1d/6.hubbard/main.jl b/examples/quantum1d/6.hubbard/main.jl index 3c41222ae..3dab08047 100644 --- a/examples/quantum1d/6.hubbard/main.jl +++ b/examples/quantum1d/6.hubbard/main.jl @@ -9,7 +9,7 @@ a kinetic term that allows electrons to hop between neighboring sites, and a pot Often, a third term is included which serves as a chemical potential to control the number of electrons in the system. ```math -H = -t \sum_{\langle i, j \rangle, \sigma} c^{\dagger}_{i,\sigma} c_{j,\sigma} + U \sum_i n_{i,\uparrow} n_{i,\downarrow} - \mu \sum_{i,\sigma} n_{i,\sigma} +H = -t ∑_{⟨i, j⟩, σ} c^{†}_{i,σ} c_{j,σ} + U ∑_i n_{i,↑} n_{i,↓} - μ ∑_{i,σ} n_{i,σ} ``` At half-filling, the system exhibits particle-hole symmetry, which can be made explicit by rewriting the Hamiltonian slightly. @@ -17,13 +17,13 @@ First, we fix the overall energy scale by setting `t = 1`, and then shift the to This results in the following Hamiltonian: ```math -H = - \sum_{\langle i, j \rangle, \sigma} c^{\dagger}_{i,\sigma} c_{j,\sigma} + U / 4 \sum_i (1 - 2 n_{i,\uparrow}) (1 - 2 n_{i,\downarrow}) - \mu \sum_{i,\sigma} n_{i,\sigma} +H = - ∑_{⟨i, j⟩, σ} c^{†}_{i,σ} c_{j,σ} + U / 4 ∑_i (1 - 2 n_{i,↑}) (1 - 2 n_{i,↓}) - μ ∑_{i,σ} n_{i,σ} ``` Finally, setting `\mu = 0` and defining `u = U / 4` we obtain the Hubbard model at half-filling. ```math -H = - \sum_{\langle i, j \rangle, \sigma} c^{\dagger}_{i,\sigma} c_{j,\sigma} + u \sum_i (1 - 2 n_{i,\uparrow}) (1 - 2 n_{i,\downarrow}) +H = - ∑_{⟨i, j⟩, σ} c^{†}_{i,σ} c_{j,σ} + u ∑_i (1 - 2 n_{i,↑}) (1 - 2 n_{i,↓}) ``` """ @@ -50,7 +50,7 @@ For this case, the ground state energy has an analytic solution, which can be us It follows from Eq. (6.82) in [Essler, Frahm, Göhmann, Klümper & Korepin, The One-Dimensional Hubbard Model](https://doi.org/10.1017/CBO9780511534843). ```math -e(u) = - u - 4 \int_0^{\infty} \frac{d\omega}{\omega} \frac{J_0(\omega) J_1(\omega)}{1 + \exp(2u \omega)} +e(u) = - u - 4 ∫₀^{∞} \frac{dω}{ω} \frac{J₀(ω) J₁(ω)}{1 + \exp(2u ω)} ``` We can easily verify this by comparing the numerical results to the analytic solution. @@ -58,7 +58,7 @@ We can easily verify this by comparing the numerical results to the analytic sol function hubbard_energy(u; rtol = 1.0e-12) integrandum(ω) = besselj0(ω) * besselj1(ω) / (1 + exp(2u * ω)) / ω - int, err = quadgk(integrandum, 0, Inf; rtol = rtol) + int, err = quadgk(integrandum, 0, Inf; rtol) return -u - 4 * int end @@ -108,7 +108,7 @@ md""" ## Symmetries The Hubbard model has a rich symmetry structure, which can be exploited to speed up simulations. -Apart from the fermionic parity, the model also has a $U(1)$ particle number symmetry, along with a $SU(2)$ spin symmetry. +Apart from the fermionic parity, the model also has a ``U(1)`` particle number symmetry, along with a ``SU(2)`` spin symmetry. Explicitly imposing these symmetries on the tensors can greatly reduce the computational cost of the simulation. Naively imposing these symmetries however, is not compatible with our desire to work at half-filling. @@ -140,7 +140,7 @@ The elementary excitations are known as spinons and holons, which are domain wal The fact that the spin and charge sectors are separate is a phenomenon known as spin-charge separation. The domain walls can be constructed by noticing that there are two equivalent groundstates, which differ by a translation over a single site. -In other words, the groundstates are ``\psi_{AB}` and ``\psi_{BA}``, where ``A`` and ``B`` are the two sites. +In other words, the groundstates are ``\psi_{AB}`` and ``\psi_{BA}``, where ``A`` and ``B`` are the two sites. These excitations can be constructed as follows: """ @@ -216,7 +216,7 @@ md""" The plot shows some discrepancies between the numerical and analytic results. First and foremost, we must realize that in the thermodynamic limit, the momentum of a domain wall is actually not well-defined. Concretely, only the difference in momentum between the two groundstates is well-defined, as we can always shift the momentum by multiplying one of the groundstates by a phase. -Here, we can fix this shift by realizing that our choice of shifting the groundstates by a single site, differs from the formula by a factor ``\pi/2``. +Here, we can fix this shift by realizing that our choice of shifting the groundstates by a single site, differs from the formula by a factor ``π/2``. """ momenta_shifted = rem2pi.(momenta .- π / 2, RoundNearest) From b2a705a28fbbe6d47a7df0311db5153be4e1abc1 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Sun, 5 Jul 2026 06:56:23 -0400 Subject: [PATCH 39/76] docs: fix typos in crossover prose (analasys -> analysis, list grammar) Co-Authored-By: Claude Fable 5 --- docs/src/tutorials/first_groundstate.md | 4 ++-- examples/quantum1d/0.tfim-groundstate/main.jl | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/src/tutorials/first_groundstate.md b/docs/src/tutorials/first_groundstate.md index 65cc4545f..3b2473b74 100644 --- a/docs/src/tutorials/first_groundstate.md +++ b/docs/src/tutorials/first_groundstate.md @@ -138,8 +138,8 @@ Which sign it lands on is arbitrary — it can differ from run to run and betwee The plot shows the magnetization close to 1 deep on the ordered side, then dropping to zero — noticeably *below* the thermodynamic critical point `g = 1` (around `g ≈ 0.6` at these parameters). Both features follow from how the state is computed rather than from the physics of the transition: on the ordered side DMRG sits on one symmetry-broken branch, and past the drop it recovers the exactly symmetric ground state, whose magnetization vanishes. -Exactly where the drop lands depends on `L`, and `D`, so its location by itself is *not yet* a measurement of the critical point. -The honest way to locate the transition is by performing scaling analasys, taking the limit of infinite size and bond dimension. +Exactly where the drop lands depends on `L` and `D`, so its location by itself is *not yet* a measurement of the critical point. +The honest way to locate the transition is by performing a scaling analysis, taking the limit of infinite size and bond dimension. ## Where to go next diff --git a/examples/quantum1d/0.tfim-groundstate/main.jl b/examples/quantum1d/0.tfim-groundstate/main.jl index 478e42ccf..09b3ae7e5 100644 --- a/examples/quantum1d/0.tfim-groundstate/main.jl +++ b/examples/quantum1d/0.tfim-groundstate/main.jl @@ -111,7 +111,7 @@ md""" Both calculations agree deep in either phase, but near the transition they tell very different stories. The infinite curve stays on its ordered branch essentially up to `g = 1` and then collapses: it locates the critical point cleanly. The finite-chain curve instead drops to zero far earlier — at this `L` and `D` the variational optimum on the open chain switches from the symmetry-broken branch to the exactly symmetric ground state, whose magnetization vanishes. -Where that switch happens is set by `L`, `D`, not by the physics; the same sweep at `D = 4` in [Your first ground state](@ref tutorial_first_groundstate) puts it elsewhere. +Where that switch happens is set by `L` and `D`, not by the physics; the same sweep at `D = 4` in [Your first ground state](@ref tutorial_first_groundstate) puts it elsewhere. That is the real lesson of this panel: the finite-chain order parameter is dominated by which state the algorithm selects, while the calculation performed directly in the thermodynamic limit pins the transition at `g = 1`. """ From aec722fb2661aa236b987b9b4d4d4ed09b4550a7 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Sun, 5 Jul 2026 07:33:04 -0400 Subject: [PATCH 40/76] docs(examples): re-render tfim + hubbard pages after prose edits Co-Authored-By: Claude Fable 5 --- .../quantum1d/0.tfim-groundstate/figure-3.png | Bin 18205 -> 18340 bytes .../quantum1d/0.tfim-groundstate/index.md | 20 +++++------------- .../quantum1d/0.tfim-groundstate/main.ipynb | 20 +++++------------- .../src/examples/quantum1d/6.hubbard/index.md | 20 +++++++++--------- .../examples/quantum1d/6.hubbard/main.ipynb | 14 ++++++------ examples/Cache.toml | 4 ++-- 6 files changed, 29 insertions(+), 49 deletions(-) diff --git a/docs/src/examples/quantum1d/0.tfim-groundstate/figure-3.png b/docs/src/examples/quantum1d/0.tfim-groundstate/figure-3.png index 83427b543fbbf72cd2559f54b07c5697b8d0aa40..31b1c357adea7161ca03ae63e8282e49e96a0b6d 100644 GIT binary patch literal 18340 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 aoPzYtDXupMF*j&V2q`gn(Hx|~>;DBP5i>CW literal 18205 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 diff --git a/docs/src/examples/quantum1d/0.tfim-groundstate/index.md b/docs/src/examples/quantum1d/0.tfim-groundstate/index.md index ca4e888d0..40ccedabd 100644 --- a/docs/src/examples/quantum1d/0.tfim-groundstate/index.md +++ b/docs/src/examples/quantum1d/0.tfim-groundstate/index.md @@ -121,21 +121,11 @@ p_magnetization ![](figure-1.png) -Both calculations agree deep in either phase, but near the transition they tell very -different stories. -The infinite curve stays on its ordered branch essentially up to `g = 1` and then -collapses: it locates the critical point cleanly. -The finite-chain curve instead drops to zero far earlier — at this `L` and `D` the -variational optimum on the open chain switches from the symmetry-broken branch to the -exactly symmetric ground state, whose magnetization vanishes. -Where that switch happens is set by `L`, `D`, and even the random starting state, not by -the physics; the same sweep at `D = 4` in -[Your first ground state](@ref tutorial_first_groundstate) puts it elsewhere. -That is the real lesson of this panel: the finite-chain order parameter is dominated by -which state the algorithm selects, while the calculation performed directly in the -thermodynamic limit pins the transition at `g = 1`. - - +Both calculations agree deep in either phase, but near the transition they tell very different stories. +The infinite curve stays on its ordered branch essentially up to `g = 1` and then collapses: it locates the critical point cleanly. +The finite-chain curve instead drops to zero far earlier — at this `L` and `D` the variational optimum on the open chain switches from the symmetry-broken branch to the exactly symmetric ground state, whose magnetization vanishes. +Where that switch happens is set by `L` and `D`, not by the physics; the same sweep at `D = 4` in [Your first ground state](@ref tutorial_first_groundstate) puts it elsewhere. +That is the real lesson of this panel: the finite-chain order parameter is dominated by which state the algorithm selects, while the calculation performed directly in the thermodynamic limit pins the transition at `g = 1`. ## 2. Entanglement entropy across the transition diff --git a/docs/src/examples/quantum1d/0.tfim-groundstate/main.ipynb b/docs/src/examples/quantum1d/0.tfim-groundstate/main.ipynb index 212aa223d..12748dde4 100644 --- a/docs/src/examples/quantum1d/0.tfim-groundstate/main.ipynb +++ b/docs/src/examples/quantum1d/0.tfim-groundstate/main.ipynb @@ -178,21 +178,11 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Both calculations agree deep in either phase, but near the transition they tell very\n", - "different stories.\n", - "The infinite curve stays on its ordered branch essentially up to `g = 1` and then\n", - "collapses: it locates the critical point cleanly.\n", - "The finite-chain curve instead drops to zero far earlier — at this `L` and `D` the\n", - "variational optimum on the open chain switches from the symmetry-broken branch to the\n", - "exactly symmetric ground state, whose magnetization vanishes.\n", - "Where that switch happens is set by `L`, `D`, and even the random starting state, not by\n", - "the physics; the same sweep at `D = 4` in\n", - "Your first ground state puts it elsewhere.\n", - "That is the real lesson of this panel: the finite-chain order parameter is dominated by\n", - "which state the algorithm selects, while the calculation performed directly in the\n", - "thermodynamic limit pins the transition at `g = 1`.\n", - "\n", - "" + "Both calculations agree deep in either phase, but near the transition they tell very different stories.\n", + "The infinite curve stays on its ordered branch essentially up to `g = 1` and then collapses: it locates the critical point cleanly.\n", + "The finite-chain curve instead drops to zero far earlier — at this `L` and `D` the variational optimum on the open chain switches from the symmetry-broken branch to the exactly symmetric ground state, whose magnetization vanishes.\n", + "Where that switch happens is set by `L` and `D`, not by the physics; the same sweep at `D = 4` in Your first ground state puts it elsewhere.\n", + "That is the real lesson of this panel: the finite-chain order parameter is dominated by which state the algorithm selects, while the calculation performed directly in the thermodynamic limit pins the transition at `g = 1`." ] }, { diff --git a/docs/src/examples/quantum1d/6.hubbard/index.md b/docs/src/examples/quantum1d/6.hubbard/index.md index afb6b4c8a..f4fb35746 100644 --- a/docs/src/examples/quantum1d/6.hubbard/index.md +++ b/docs/src/examples/quantum1d/6.hubbard/index.md @@ -18,7 +18,7 @@ a kinetic term that allows electrons to hop between neighboring sites, and a pot Often, a third term is included which serves as a chemical potential to control the number of electrons in the system. ```math -H = -t \sum_{\langle i, j \rangle, \sigma} c^{\dagger}_{i,\sigma} c_{j,\sigma} + U \sum_i n_{i,\uparrow} n_{i,\downarrow} - \mu \sum_{i,\sigma} n_{i,\sigma} +H = -t ∑_{⟨i, j⟩, σ} c^{†}_{i,σ} c_{j,σ} + U ∑_i n_{i,↑} n_{i,↓} - μ ∑_{i,σ} n_{i,σ} ``` At half-filling, the system exhibits particle-hole symmetry, which can be made explicit by rewriting the Hamiltonian slightly. @@ -26,13 +26,13 @@ First, we fix the overall energy scale by setting `t = 1`, and then shift the to This results in the following Hamiltonian: ```math -H = - \sum_{\langle i, j \rangle, \sigma} c^{\dagger}_{i,\sigma} c_{j,\sigma} + U / 4 \sum_i (1 - 2 n_{i,\uparrow}) (1 - 2 n_{i,\downarrow}) - \mu \sum_{i,\sigma} n_{i,\sigma} +H = - ∑_{⟨i, j⟩, σ} c^{†}_{i,σ} c_{j,σ} + U / 4 ∑_i (1 - 2 n_{i,↑}) (1 - 2 n_{i,↓}) - μ ∑_{i,σ} n_{i,σ} ``` Finally, setting `\mu = 0` and defining `u = U / 4` we obtain the Hubbard model at half-filling. ```math -H = - \sum_{\langle i, j \rangle, \sigma} c^{\dagger}_{i,\sigma} c_{j,\sigma} + u \sum_i (1 - 2 n_{i,\uparrow}) (1 - 2 n_{i,\downarrow}) +H = - ∑_{⟨i, j⟩, σ} c^{†}_{i,σ} c_{j,σ} + u ∑_i (1 - 2 n_{i,↑}) (1 - 2 n_{i,↓}) ``` ````julia @@ -65,7 +65,7 @@ For this case, the ground state energy has an analytic solution, which can be us It follows from Eq. (6.82) in [Essler, Frahm, Göhmann, Klümper & Korepin, The One-Dimensional Hubbard Model](https://doi.org/10.1017/CBO9780511534843). ```math -e(u) = - u - 4 \int_0^{\infty} \frac{d\omega}{\omega} \frac{J_0(\omega) J_1(\omega)}{1 + \exp(2u \omega)} +e(u) = - u - 4 ∫₀^{∞} \frac{dω}{ω} \frac{J₀(ω) J₁(ω)}{1 + \exp(2u ω)} ``` We can easily verify this by comparing the numerical results to the analytic solution. @@ -73,7 +73,7 @@ We can easily verify this by comparing the numerical results to the analytic sol ````julia function hubbard_energy(u; rtol = 1.0e-12) integrandum(ω) = besselj0(ω) * besselj1(ω) / (1 + exp(2u * ω)) / ω - int, err = quadgk(integrandum, 0, Inf; rtol = rtol) + int, err = quadgk(integrandum, 0, Inf; rtol) return -u - 4 * int end @@ -122,7 +122,7 @@ Groundstate energy: ```` [ Info: CG: initializing with f = -4.379763091095e+00, ‖∇f‖ = 3.1534e-05 -[ Info: CG: converged after 167 iterations and time 1.66 m: f = -4.379763081900e+00, ‖∇f‖ = 9.7406e-07 +[ Info: CG: converged after 167 iterations and time 1.75 m: f = -4.379763081900e+00, ‖∇f‖ = 9.7406e-07 ┌ Info: Groundstate energy: │ * numerical: -2.189996060974577 └ * analytic: -2.190038374277775 @@ -132,7 +132,7 @@ Groundstate energy: ## Symmetries The Hubbard model has a rich symmetry structure, which can be exploited to speed up simulations. -Apart from the fermionic parity, the model also has a $U(1)$ particle number symmetry, along with a $SU(2)$ spin symmetry. +Apart from the fermionic parity, the model also has a ``U(1)`` particle number symmetry, along with a ``SU(2)`` spin symmetry. Explicitly imposing these symmetries on the tensors can greatly reduce the computational cost of the simulation. Naively imposing these symmetries however, is not compatible with our desire to work at half-filling. @@ -159,7 +159,7 @@ Groundstate energy: ```` [ Info: CG: initializing with f = -4.379692711472e+00, ‖∇f‖ = 5.7923e-05 -[ Info: CG: converged after 13 iterations and time 14.39 s: f = -4.379692712393e+00, ‖∇f‖ = 6.2087e-07 +[ Info: CG: converged after 13 iterations and time 14.35 s: f = -4.379692712393e+00, ‖∇f‖ = 6.2087e-07 ┌ Info: Groundstate energy: │ * numerical: -2.190015347514472 └ * analytic: -2.190038374277775 @@ -173,7 +173,7 @@ The elementary excitations are known as spinons and holons, which are domain wal The fact that the spin and charge sectors are separate is a phenomenon known as spin-charge separation. The domain walls can be constructed by noticing that there are two equivalent groundstates, which differ by a translation over a single site. -In other words, the groundstates are ``\psi_{AB}` and ``\psi_{BA}``, where ``A`` and ``B`` are the two sites. +In other words, the groundstates are ``\psi_{AB}`` and ``\psi_{BA}``, where ``A`` and ``B`` are the two sites. These excitations can be constructed as follows: ````julia @@ -321,7 +321,7 @@ end The plot shows some discrepancies between the numerical and analytic results. First and foremost, we must realize that in the thermodynamic limit, the momentum of a domain wall is actually not well-defined. Concretely, only the difference in momentum between the two groundstates is well-defined, as we can always shift the momentum by multiplying one of the groundstates by a phase. -Here, we can fix this shift by realizing that our choice of shifting the groundstates by a single site, differs from the formula by a factor ``\pi/2``. +Here, we can fix this shift by realizing that our choice of shifting the groundstates by a single site, differs from the formula by a factor ``π/2``. ````julia momenta_shifted = rem2pi.(momenta .- π / 2, RoundNearest) diff --git a/docs/src/examples/quantum1d/6.hubbard/main.ipynb b/docs/src/examples/quantum1d/6.hubbard/main.ipynb index eed773528..a204f45d3 100644 --- a/docs/src/examples/quantum1d/6.hubbard/main.ipynb +++ b/docs/src/examples/quantum1d/6.hubbard/main.ipynb @@ -21,7 +21,7 @@ "Often, a third term is included which serves as a chemical potential to control the number of electrons in the system.\n", "\n", "$$\n", - "H = -t \\sum_{\\langle i, j \\rangle, \\sigma} c^{\\dagger}_{i,\\sigma} c_{j,\\sigma} + U \\sum_i n_{i,\\uparrow} n_{i,\\downarrow} - \\mu \\sum_{i,\\sigma} n_{i,\\sigma}\n", + "H = -t ∑_{⟨i, j⟩, σ} c^{†}_{i,σ} c_{j,σ} + U ∑_i n_{i,↑} n_{i,↓} - μ ∑_{i,σ} n_{i,σ}\n", "$$\n", "\n", "At half-filling, the system exhibits particle-hole symmetry, which can be made explicit by rewriting the Hamiltonian slightly.\n", @@ -29,13 +29,13 @@ "This results in the following Hamiltonian:\n", "\n", "$$\n", - "H = - \\sum_{\\langle i, j \\rangle, \\sigma} c^{\\dagger}_{i,\\sigma} c_{j,\\sigma} + U / 4 \\sum_i (1 - 2 n_{i,\\uparrow}) (1 - 2 n_{i,\\downarrow}) - \\mu \\sum_{i,\\sigma} n_{i,\\sigma}\n", + "H = - ∑_{⟨i, j⟩, σ} c^{†}_{i,σ} c_{j,σ} + U / 4 ∑_i (1 - 2 n_{i,↑}) (1 - 2 n_{i,↓}) - μ ∑_{i,σ} n_{i,σ}\n", "$$\n", "\n", "Finally, setting `\\mu = 0` and defining `u = U / 4` we obtain the Hubbard model at half-filling.\n", "\n", "$$\n", - "H = - \\sum_{\\langle i, j \\rangle, \\sigma} c^{\\dagger}_{i,\\sigma} c_{j,\\sigma} + u \\sum_i (1 - 2 n_{i,\\uparrow}) (1 - 2 n_{i,\\downarrow})\n", + "H = - ∑_{⟨i, j⟩, σ} c^{†}_{i,σ} c_{j,σ} + u ∑_i (1 - 2 n_{i,↑}) (1 - 2 n_{i,↓})\n", "$$" ] }, @@ -84,7 +84,7 @@ "It follows from Eq. (6.82) in [Essler, Frahm, Göhmann, Klümper & Korepin, The One-Dimensional Hubbard Model](https://doi.org/10.1017/CBO9780511534843).\n", "\n", "$$\n", - "e(u) = - u - 4 \\int_0^{\\infty} \\frac{d\\omega}{\\omega} \\frac{J_0(\\omega) J_1(\\omega)}{1 + \\exp(2u \\omega)}\n", + "e(u) = - u - 4 ∫₀^{∞} \\frac{dω}{ω} \\frac{J₀(ω) J₁(ω)}{1 + \\exp(2u ω)}\n", "$$\n", "\n", "We can easily verify this by comparing the numerical results to the analytic solution." @@ -98,7 +98,7 @@ "source": [ "function hubbard_energy(u; rtol = 1.0e-12)\n", " integrandum(ω) = besselj0(ω) * besselj1(ω) / (1 + exp(2u * ω)) / ω\n", - " int, err = quadgk(integrandum, 0, Inf; rtol = rtol)\n", + " int, err = quadgk(integrandum, 0, Inf; rtol)\n", " return -u - 4 * int\n", "end\n", "\n", @@ -194,7 +194,7 @@ "The fact that the spin and charge sectors are separate is a phenomenon known as spin-charge separation.\n", "\n", "The domain walls can be constructed by noticing that there are two equivalent groundstates, which differ by a translation over a single site.\n", - "In other words, the groundstates are $\\psi_{AB}` and $\\psi_{BA}$, where $A$ and $B$ are the two sites.\n", + "In other words, the groundstates are $\\psi_{AB}$ and $\\psi_{BA}$, where $A$ and $B$ are the two sites.\n", "These excitations can be constructed as follows:" ] }, @@ -290,7 +290,7 @@ "The plot shows some discrepancies between the numerical and analytic results.\n", "First and foremost, we must realize that in the thermodynamic limit, the momentum of a domain wall is actually not well-defined.\n", "Concretely, only the difference in momentum between the two groundstates is well-defined, as we can always shift the momentum by multiplying one of the groundstates by a phase.\n", - "Here, we can fix this shift by realizing that our choice of shifting the groundstates by a single site, differs from the formula by a factor $\\pi/2$." + "Here, we can fix this shift by realizing that our choice of shifting the groundstates by a single site, differs from the formula by a factor $π/2$." ] }, { diff --git a/examples/Cache.toml b/examples/Cache.toml index a3da16c71..1183f3fd4 100644 --- a/examples/Cache.toml +++ b/examples/Cache.toml @@ -3,11 +3,11 @@ [quantum1d] "2.haldane" = "c5a0eb70f0930d38053535c659ab39a87121b6ebda040ceadd9deb5f30921315" -"6.hubbard" = "8e45bc248cafbabb296d56dc88165c6d7670be2f37b680508de42596042435c0" +"6.hubbard" = "50cb64102c2e3a61600df279a9cae45cd3b024e82e6f695d3ed713b0fd3f9283" "7.xy-finiteT" = "0d21f7556fee8409edb58ab0ea04a77bd90feb2dffec424f0a5962d11dfdfc65" "8.bose-hubbard" = "ba9ec53721371aab311dadbe05a31a3c95cb1b8a394abb7f81ee97e15b84d503" "3.ising-dqpt" = "056423a189e1b1d4110bebc4eb6129a957ecdbf8e9a679eca10cf0391494b944" "5.haldane-spt" = "c8fd3a8d406b9ff3ea9a34b596c5910d81e4eb710b665d7fa04e30f795a46086" "4.xxz-heisenberg" = "5fa4242290b0a9ae658caf54f6919a8e04c97af80b9fcc6b936c2f45c7c8efdd" "1.ising-cft" = "ebcae1e501347cb00a46d0889df1355707be77cf962f9ee0d16416393492529b" -"0.tfim-groundstate" = "f436cb78f72c7ca59c99a192ab5649c57f912f9fc4838e33faa7440a025f0893" +"0.tfim-groundstate" = "a87cc89caf8df47285e25f6cec4ff130ea6ed88d4f73d59f8e7dc2e799ece1b0" From 869459696da33f8f36cea455fbb754aad7ef974c Mon Sep 17 00:00:00 2001 From: lkdvos Date: Sun, 5 Jul 2026 07:33:04 -0400 Subject: [PATCH 41/76] docs: list example pages in the sidebar make.jl computed quantum_pages/classic_pages from readdir but never used them; the Examples nav entry was a single leaf page, so the rendered site showed no children in the sidebar, unlike every other section. Wire the lists in as Overview + Quantum (1+1)d + Classical (2+0)d groups (verified against the generated VitePress sidebar config). Co-Authored-By: Claude Fable 5 --- docs/make.jl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/make.jl b/docs/make.jl index f8a741973..ce000dc31 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -70,7 +70,11 @@ makedocs(; "howto/observables.md", "howto/entanglement.md", ], - "Examples" => "examples/index.md", + "Examples" => [ + "Overview" => "examples/index.md", + "Quantum (1+1)d" => quantum_pages, + "Classical (2+0)d" => classic_pages, + ], "Library" => [ "lib/public.md", "lib/states.md", From b946b54db9f406c576318c2ce4a4947eac68ddcd Mon Sep 17 00:00:00 2001 From: lkdvos Date: Sun, 5 Jul 2026 08:55:58 -0400 Subject: [PATCH 42/76] docs(howto): group FiniteMPS construction recipes under one section Collapse the five top-level FiniteMPS sections into a single '## 1. A finite MPS' section with '###' subheadings, matching the structure of the infinite, window, and multiline sections, and renumber the remaining sections. Co-Authored-By: Claude Fable 5 --- docs/src/howto/states.md | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/docs/src/howto/states.md b/docs/src/howto/states.md index d4a65d3cd..3ea69ea04 100644 --- a/docs/src/howto/states.md +++ b/docs/src/howto/states.md @@ -14,7 +14,9 @@ For background on what these types represent and how gauging works, see the [Sta --- -## 1. A finite MPS from length, physical space, and maximum bond dimension +## 1. A finite MPS + +### From length, physical space, and maximum bond dimension The most common starting point: give the chain length `N`, the local physical `VectorSpace`, and the maximum allowed virtual space. The constructor fills the tensors with random `ComplexF64` entries and trims the actual bond dimensions to full rank, so passing an over-large `maxVspace` is safe. @@ -38,9 +40,7 @@ dim(left_virtualspace(ψ, 3)) # bond dimension between sites 2 and 3 physicalspace(ψ, 1) # local Hilbert space at site 1 ``` ---- - -## 2. Choosing the initializer and element type +### Choosing the initializer and element type Pass an initializer function (`rand` or `randn`) and an element type as the first two arguments: @@ -51,9 +51,7 @@ Pass an initializer function (`rand` or `randn`) and an element type as the firs The element type sets the scalar type of the tensors, e.g. `ComplexF64` (the default) or `Float64` for a real-valued state. ---- - -## 3. Per-site physical and virtual spaces +### Per-site physical and virtual spaces When the physical space varies from site to site — or you want fine control over which bond gets which maximum dimension — pass vectors instead of scalars. The `maxVspaces` vector must have length `N - 1` (one entry per bond): @@ -69,9 +67,7 @@ maxVspaces = [ℂ^8, ℂ^8, ℂ^8, ℂ^8] # one per bond (length N-1) physicalspace(ψ_het, 2) # ℂ^3 ``` ---- - -## 4. A product state (trivial virtual space) +### A product state (trivial virtual space) A product (bond-dimension-1) state has no entanglement: each site carries its own single-site state, independent of the others (with `rand`, a random such state per site). Achieve this by passing `oneunit(d)` — the one-dimensional unit space of the same symmetry sector — as the maximum virtual space: @@ -85,9 +81,7 @@ dim(left_virtualspace(ψ_prod, 5)) # should be 1 `oneunit(V)` returns the one-dimensional trivial space matching the symmetry type of `V`. For plain complex spaces, `oneunit(ℂ^2) == ℂ^1`. ---- - -## 5. From your own site tensors +### From your own site tensors If you already have a vector of `TensorMap` objects with the correct index structure (virtual ⊗ physical ← virtual), pass them directly. The constructor performs a left-to-right QR sweep to bring the state into a canonical form: @@ -106,7 +100,7 @@ Set `normalize = true` to also normalize the state during construction (the defa --- -## 6. An infinite MPS +## 2. An infinite MPS ### Scalar convenience form @@ -154,7 +148,7 @@ inf_tensors = [rand(ComplexF64, ℂ^4 ⊗ ℂ^2 ← ℂ^4)] --- -## 7. A window MPS +## 3. A window MPS A [`WindowMPS`](@ref) embeds a mutable finite window inside two infinite environments. @@ -202,7 +196,7 @@ finite_part = FiniteMPS(6, ℂ^2, ℂ^8; left = ℂ^8, right = ℂ^8) --- -## 8. A multiline MPS +## 4. A multiline MPS [`MultilineMPS`](@ref) stacks several [`InfiniteMPS`](@ref) rows and is used in boundary-MPS methods for 2D classical partition functions. @@ -232,7 +226,7 @@ Dspaces = fill(ℂ^8, 2, 2) --- -## 9. States with symmetries +## 5. States with symmetries All constructors accept TensorKit graded spaces. Pass a `Rep[G]` physical space and a `Rep[G]` maximum virtual space; the constructor automatically selects the consistent fusion channels. From 1af573245e9d3457585677ee362343c22bb49093 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Sun, 5 Jul 2026 08:04:34 -0400 Subject: [PATCH 43/76] docs(howto): add ground-state algorithms recipe page Task recipes for find_groundstate: keyword-form heuristic, explicit DMRG/DMRG2/VUMPS/IDMRG/IDMRG2/GradientGrassmann configuration, &-chaining, verbosity/tolerance control. All 12 @example blocks verified against real MPSKit; physics claims salvaged from man/algorithms.md carry REVIEW flags. Co-Authored-By: Claude Fable 5 --- docs/make.jl | 1 + docs/src/howto/groundstate_algorithms.md | 207 +++++++++++++++++++++++ 2 files changed, 208 insertions(+) create mode 100644 docs/src/howto/groundstate_algorithms.md diff --git a/docs/make.jl b/docs/make.jl index ce000dc31..84be91baa 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -66,6 +66,7 @@ makedocs(; "How-to" => [ "howto/states.md", "howto/hamiltonians.md", + "howto/groundstate_algorithms.md", "howto/bond_dimension.md", "howto/observables.md", "howto/entanglement.md", diff --git a/docs/src/howto/groundstate_algorithms.md b/docs/src/howto/groundstate_algorithms.md new file mode 100644 index 000000000..4cb753a73 --- /dev/null +++ b/docs/src/howto/groundstate_algorithms.md @@ -0,0 +1,207 @@ +# [Ground-state algorithms](@id howto_groundstate_algorithms) + +The examples on this page use MPSKit.jl, MPSKitModels.jl, TensorKit.jl, and TensorKitTensors.jl. +See [Installation](@ref tutorial_installation) for how to add these packages to your environment. + +[`find_groundstate`](@ref) is the single entry point for optimizing an MPS towards the ground state of a Hamiltonian. +This page shows how to pick and configure the algorithm it runs, for both finite and infinite systems. +For what each algorithm actually does and why you would choose one over another, see [Ground-state algorithms](@ref lib_groundstate). +All examples share a single namespace: + +```@example groundstate_algs +using MPSKit, MPSKitModels, TensorKit +using TensorKitTensors.SpinOperators: σˣ, σᶻ +``` + +--- + +## 1. Get a ground state with defaults + +Called with just a state and a Hamiltonian, `find_groundstate` inspects the type of the initial state and picks a matching algorithm for you. +For a `FiniteMPS` it runs [`DMRG`](@ref) with the keywords you pass through (`tol`, `maxiter`, `verbosity`): + +```@example groundstate_algs +L = 8 +ψ₀ = FiniteMPS(L, ℂ^2, ℂ^8) +H = transverse_field_ising(FiniteChain(L); g = 0.5) + +ψ, envs, ϵ = find_groundstate(ψ₀, H; tol = 1.0e-8, maxiter = 50, verbosity = 0) +ϵ +``` + +For an `InfiniteMPS` it instead runs [`VUMPS`](@ref), and if the requested `tol` is tighter than `1e-4` it chains a [`GradientGrassmann`](@ref) pass afterwards to polish the last few digits (see [§4](#4-refine-convergence-with-gradientgrassmann)): + +```@example groundstate_algs +ψ₀_inf = InfiniteMPS(ℂ^2, ℂ^6) +H_inf = transverse_field_ising(; g = 0.5) + +ψ_inf, envs_inf, ϵ_inf = find_groundstate(ψ₀_inf, H_inf; verbosity = 0) +ϵ_inf +``` + +Passing a `trscheme` keyword switches on a two-site pre-pass that can grow the bond dimension before the single-site algorithm takes over. +On a `FiniteMPS` this prepends [`DMRG2`](@ref); on an `InfiniteMPS` it prepends [`IDMRG2`](@ref) (which needs a unit cell of at least two sites, see [§3](#3-configure-infinite-system-algorithms)). + +```@example groundstate_algs +ψ_auto, envs_auto, ϵ_auto = find_groundstate( + ψ₀, H; + trscheme = truncrank(16), verbosity = 0 +) +ϵ_auto +``` + +!!! note "When to reach for an explicit algorithm" + The keyword form above covers the common cases. + Reach for an explicit algorithm struct (`DMRG`, `DMRG2`, `VUMPS`, `IDMRG`, `IDMRG2`, `GradientGrassmann`), or a chain of them with `&`, whenever you need finer control than the heuristic provides — the rest of this page shows how. + +--- + +## 2. Configure finite-system DMRG + +Pass a [`DMRG`](@ref) struct explicitly to set `tol`, `maxiter`, and `verbosity` directly: + +```@example groundstate_algs +ψ_dmrg, envs_dmrg, ϵ_dmrg = find_groundstate( + ψ₀, H, + DMRG(; tol = 1.0e-8, maxiter = 50, verbosity = 0) +) +ϵ_dmrg +``` + +`DMRG` updates one site at a time, so with its defaults it cannot change the bond dimension: whatever bond dimension `ψ₀` starts with is what it keeps. + +[`DMRG2`](@ref) optimizes two sites at once and truncates back down, which lets it grow (or shrink) the bond dimension as it sweeps, at extra cost per step. +Unlike `DMRG`, `DMRG2` has no default truncation scheme, so `trscheme` is required: + +```@example groundstate_algs +ψ_dmrg2, envs_dmrg2, ϵ_dmrg2 = find_groundstate( + ψ₀, H, + DMRG2(; trscheme = truncrank(16), maxiter = 5, verbosity = 0) +) +ϵ_dmrg2 +``` + +A common pattern is to warm up with `DMRG2` to grow the bond dimension, then refine with the cheaper single-site `DMRG`. +The `&` chaining operator runs the first algorithm to completion, then feeds its result into the second: + +```@example groundstate_algs +warmup_then_refine = DMRG2(; trscheme = truncrank(16), maxiter = 3, verbosity = 0) & + DMRG(; tol = 1.0e-8, maxiter = 30, verbosity = 0) + +ψ_c, envs_c, ϵ_c = find_groundstate(ψ₀, H, warmup_then_refine) +ϵ_c +``` + +For more on choosing `trscheme` and growing bond dimension in general, see [Controlling bond dimension](@ref howto_bond_dimension). + +--- + +## 3. Configure infinite-system algorithms + +[`VUMPS`](@ref) is the default single-site algorithm for an `InfiniteMPS`, and takes the same `tol`/`maxiter`/`verbosity` keywords: + +```@example groundstate_algs +ψ_v, envs_v, ϵ_v = find_groundstate( + ψ₀_inf, H_inf, + VUMPS(; tol = 1.0e-8, maxiter = 50, verbosity = 0) +) +ϵ_v +``` + + +[`IDMRG`](@ref) is the infinite analogue of `DMRG`: it grows the system by repeatedly inserting sites in the middle and re-optimizing, until boundary effects wash out. + +```@example groundstate_algs +ψ_i, envs_i, ϵ_i = find_groundstate( + ψ₀_inf, H_inf, + IDMRG(; tol = 1.0e-8, maxiter = 50, verbosity = 0) +) +ϵ_i +``` + + + +In practice, prefer `VUMPS` unless you specifically need `IDMRG`'s ability to change the bond dimension one site at a time. + +[`IDMRG2`](@ref) is the two-site, bond-dimension-changing variant, and mirrors `DMRG2`: `trscheme` is required, and it needs a unit cell of at least two sites. + +!!! warning "Unit cell size" + `IDMRG2` throws an `ArgumentError` on a single-site `InfiniteMPS`. + Build the initial state and Hamiltonian with a unit cell of two (or more) sites instead. + +```@example groundstate_algs +J = 1.0 +g = 0.5 +X = σˣ() +Z = σᶻ() + +lattice_2 = PeriodicVector([ℂ^2, ℂ^2]) +H_inf_2 = InfiniteMPOHamiltonian( + lattice_2, + (1, 2) => -J * X ⊗ X, + (2, 3) => -J * X ⊗ X, + (1,) => -g * Z, + (2,) => -g * Z, +) +ψ₀_2 = InfiniteMPS([ℂ^2, ℂ^2], [ℂ^2, ℂ^2]) + +ψ_i2, envs_i2, ϵ_i2 = find_groundstate( + ψ₀_2, H_inf_2, + IDMRG2(; trscheme = truncrank(16), maxiter = 5, verbosity = 0) +) +ϵ_i2 +``` + +--- + +## 4. Refine convergence with GradientGrassmann + +[`GradientGrassmann`](@ref) performs Riemannian gradient descent directly on the manifold of (finite or infinite) MPS, using an optimizer from OptimKit (`ConjugateGradient` by default via the `method` keyword). + +Chain it after `VUMPS` (or `DMRG`) with `&` to combine both regimes in one call — this is exactly what `find_groundstate`'s heuristic does once `tol` is tighter than `1e-4`: + +```@example groundstate_algs +refine = VUMPS(; tol = 1.0e-6, maxiter = 20, verbosity = 0) & + GradientGrassmann(; tol = 1.0e-10, maxiter = 50, verbosity = 0) + +ψ_g, envs_g, ϵ_g = find_groundstate(ψ₀_inf, H_inf, refine) +ϵ_g +``` + +Since `GradientGrassmann` is also a single-site algorithm, it cannot change the bond dimension either: grow it beforehand with `DMRG2`/`IDMRG2` or the `changebonds` recipes in [Controlling bond dimension](@ref howto_bond_dimension). + +--- + +## 5. Control output and tolerances + +Every algorithm accepts a `verbosity` keyword as a plain integer: + +| `verbosity` | Output | +|:-----------:|:-------| +| `0` | nothing | +| `1` | warnings only | +| `2` | convergence information | +| `3` | per-iteration information (the default) | +| `4` | everything | + +`find_groundstate` returns `(ψ, envs, ϵ)`. +`ϵ` is the final convergence-error measure (a Galerkin residual) of whichever algorithm ran last — it quantifies how well the sweeps converged, not the error in the energy itself. + +The optional third positional argument to `find_groundstate` lets you reuse `envs` from a previous call instead of recomputing it, which is useful when tightening the tolerance on a state you already optimized: + +```@example groundstate_algs +ψ_v2, envs_v2, ϵ_v2 = find_groundstate( + ψ_v, H_inf, + VUMPS(; tol = 1.0e-10, maxiter = 50, verbosity = 0), + envs_v +) +ϵ_v2 +``` + +--- + +## Where to go next + +For growing, shrinking, and inspecting bond dimension during or between these calculations, see [Controlling bond dimension](@ref howto_bond_dimension). +For background on when each algorithm applies and how it relates to the others, see [Ground-state algorithms](@ref lib_groundstate). +To see `find_groundstate` used end to end on a finite chain, start from [Your first ground state](@ref tutorial_first_groundstate); for the infinite-system counterpart, see [The thermodynamic limit](@ref tutorial_thermodynamic_limit). From ef7b88b7eeb16e9f01ba440831a646573bccb1f3 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Sun, 5 Jul 2026 08:22:31 -0400 Subject: [PATCH 44/76] docs(howto): add time evolution recipe page Recipes for timestep/time_evolve with TDVP/TDVP2, bond growth during evolution, infinite-state evolution, imaginary time, and time-evolution MPOs (WII/TaylorCluster/WI) applied via approximate. All 11 @example blocks verified against real MPSKit; physics claims carry REVIEW flags. Co-Authored-By: Claude Fable 5 --- docs/make.jl | 1 + docs/src/howto/time_evolution.md | 158 +++++++++++++++++++++++++++++++ 2 files changed, 159 insertions(+) create mode 100644 docs/src/howto/time_evolution.md diff --git a/docs/make.jl b/docs/make.jl index 84be91baa..1a1acb1da 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -68,6 +68,7 @@ makedocs(; "howto/hamiltonians.md", "howto/groundstate_algorithms.md", "howto/bond_dimension.md", + "howto/time_evolution.md", "howto/observables.md", "howto/entanglement.md", ], diff --git a/docs/src/howto/time_evolution.md b/docs/src/howto/time_evolution.md new file mode 100644 index 000000000..36e5061d3 --- /dev/null +++ b/docs/src/howto/time_evolution.md @@ -0,0 +1,158 @@ +# [Time evolution](@id howto_time_evolution) + +The examples on this page use MPSKit.jl, MPSKitModels.jl, TensorKit.jl, and TensorKitTensors.jl. +See [Installation](@ref tutorial_installation) for how to add these packages to your environment. + +MPSKit solves the (real- or imaginary-time) Schrödinger equation `i ∂ψ/∂t = H ψ` in two ways: by projecting the equation onto the MPS tangent space at every step ([`TDVP`](@ref)/[`TDVP2`](@ref)), or by first building an approximate evolution operator as an MPO ([`make_time_mpo`](@ref)) and repeatedly applying it. +This page gives task recipes for both routes. +All examples share a single namespace: + +```@example time_evo +using MPSKit, MPSKitModels, TensorKit +using TensorKitTensors.SpinOperators: σˣ, σᶻ +``` + +--- + +## 1. Evolve a state through one time step + +[`timestep`](@ref) advances a state by a single `dt` under a Hamiltonian, using whichever [`TDVP`](@ref)-family algorithm you pass. +Its argument order is state, Hamiltonian, current time, time step, algorithm: + +```@example time_evo +L = 8 +g₀ = 0.5 +H₀ = transverse_field_ising(FiniteChain(L); g = g₀) + +ψ₀ = FiniteMPS(L, ℂ^2, ℂ^8) +ψ₀, = find_groundstate(ψ₀, H₀, DMRG(; verbosity = 0)) +expectation_value(ψ₀, 4 => σᶻ()) +``` + +Now quench to a different transverse field `g₁` and take a single step: + +```@example time_evo +g₁ = 2.0 +H₁ = transverse_field_ising(FiniteChain(L); g = g₁) + +dt = 0.05 +ψ₁, envs₁ = timestep(ψ₀, H₁, 0.0, dt, TDVP()) +expectation_value(ψ₁, 4 => σᶻ()) +``` + +`timestep` returns the updated state together with an `envs` cache; reuse `envs₁` in the next call to avoid recomputation. +An in-place `timestep!` also exists, but only for finite MPS. + +--- + +## 2. Evolve over a time span + +[`time_evolve`](@ref) steps through an explicit vector of time points instead of a single `dt`, carrying the algorithm and environments through the whole span: + +```@example time_evo +t_span = 0:dt:(4dt) +ψ_span, envs_span = time_evolve(ψ₀, H₁, t_span, TDVP(); verbosity = 0) +expectation_value(ψ_span, 4 => σᶻ()) +``` + +`t_span` need not be uniformly spaced — `time_evolve` steps pairwise between consecutive entries, so any `AbstractVector` of increasing times works. +There is no exported `time_evolve!`; use `time_evolve` and rebind the result. + +--- + +## 3. Grow the bond dimension while evolving + +Single-site `TDVP` cannot change the bond dimension: whatever `ψ₀` starts with is what it keeps. +After a quench, entanglement typically grows and a fixed bond dimension eventually becomes insufficient. + +[`TDVP2`](@ref) updates two sites at a time and truncates back down, so it can grow (or shrink) the bond dimension as it evolves. +Unlike `TDVP`, `TDVP2` requires `trscheme` — there is no default: + +```@example time_evo +ψ_tdvp2, envs_tdvp2 = timestep(ψ₀, H₁, 0.0, dt, TDVP2(; trscheme = truncrank(16))) +dim(left_virtualspace(ψ_tdvp2, 4)) +``` + +`TDVP2` only has a finite-MPS method. +For finite systems, an alternative to switching algorithms entirely is single-site `TDVP` with `alg_expand` set to a bond-expansion algorithm such as [`OptimalExpand`](@ref) (Controlled Bond Expansion, "CBE-TDVP"); see [Controlling bond dimension](@ref howto_bond_dimension) for `OptimalExpand` and other `changebonds` recipes. + +--- + +## 4. Evolve an infinite state + +Single-site `TDVP` also works directly on an `InfiniteMPS`: + +```@example time_evo +ψ₀_inf = InfiniteMPS(ℂ^2, ℂ^8) +H₀_inf = transverse_field_ising(; g = g₀) +ψ₀_inf, = find_groundstate(ψ₀_inf, H₀_inf, VUMPS(; verbosity = 0)) + +H₁_inf = transverse_field_ising(; g = g₁) +ψ₁_inf, envs₁_inf = timestep(ψ₀_inf, H₁_inf, 0.0, dt, TDVP()) +expectation_value(ψ₁_inf, 1 => σᶻ()) +``` + +`TDVP2` has no `InfiniteMPS` method, and single-site `TDVP` cannot change the bond dimension on an infinite state either. +Grow the bond dimension beforehand with `changebonds` (e.g. `OptimalExpand` or `VUMPSSvdCut`) — see [Controlling bond dimension](@ref howto_bond_dimension) — then evolve at the fixed, larger bond dimension. + +--- + +## 5. Imaginary-time evolution + +Passing `imaginary_evolution = true` evolves under `exp(-H dt)` instead of `exp(-iH dt)`, using the same real `dt`: + +```@example time_evo +ψ_im, envs_im = timestep(ψ₀, H₁, 0.0, dt, TDVP(); imaginary_evolution = true) +norm(ψ_im) +``` + +Imaginary-time evolution renormalizes the state at every step, so `norm(ψ_im)` stays `1` regardless of how the un-normalized weight would otherwise change. +Repeated imaginary-time steps damp excited-state components faster than the ground state, so this is often used as a (slower) alternative to `find_groundstate` for driving a state towards the ground state of `H₁`. + +`time_evolve` accepts the same `imaginary_evolution` keyword for a span of imaginary-time steps. + +--- + +## 6. Build a time-evolution MPO + +When `H` is time-independent and `dt` is fixed, an alternative to repeated `timestep` calls is to build the evolution operator once as an MPO with [`make_time_mpo`](@ref), then apply it repeatedly with [`approximate`](@ref). + + +[`WII`](@ref) builds a low-order MPO approximation and works for both finite and infinite Hamiltonians: + +```@example time_evo +O = make_time_mpo(H₁, dt, WII()) +``` + +[`TaylorCluster`](@ref) gives higher-order control via its `N` keyword (and accepts an additional `tol` keyword in `make_time_mpo`): + +```@example time_evo +O_taylor = make_time_mpo(H₁, dt, TaylorCluster(; N = 2); tol = 1.0e-10) +``` + +[`WI`](@ref) is a ready-made first-order `TaylorCluster` constant, so it is used as a value, not called as a constructor: + +```@example time_evo +O_wi = make_time_mpo(H₁, dt, WI) +``` + +Applying the MPO to a finite state uses [`approximate`](@ref) with a finite ground-state-style algorithm such as [`DMRG2`](@ref), which returns a 3-tuple including the final convergence error: + +```@example time_evo +ψ_mpo, envs_mpo, ϵ_mpo = approximate( + ψ₀, (O, ψ₀), DMRG2(; trscheme = truncrank(16), verbosity = 0) +) +expectation_value(ψ_mpo, 4 => σᶻ()) +``` + +Repeat the `approximate` call with the same `O` for successive time steps to build up a longer evolution. +Imaginary-time MPOs are built the same way, by passing `imaginary_evolution = true` to `make_time_mpo`; a real `dt` is promoted internally, so no manual complex conversion is needed. + +--- + +## Where to go next + +For choosing and configuring ground-state algorithms to prepare the pre-quench state, see [Ground-state algorithms](@ref howto_groundstate_algorithms). +For growing or shrinking bond dimension between or during evolution steps, see [Controlling bond dimension](@ref howto_bond_dimension). +For extracting expectation values and correlators from the evolved state, see [Computing observables](@ref howto_observables). +For background on the TDVP and time-evolution-MPO approaches and how they relate, see [Time evolution](@ref lib_time_evolution). From 2550ddc870db51776538ab962430eb436f5e21c5 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Sun, 5 Jul 2026 09:22:26 -0400 Subject: [PATCH 45/76] docs(howto): add excited-states recipe page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Recipes for QuasiparticleAnsatz (infinite gap, dispersion scan, charged Z2 sector), finite-chain excitations (finite QP, FiniteExcited, ChepigaAnsatz/2), and variance quality checks; domain-wall usage is prose-only pending in-repo test coverage. All 11 @example blocks verified against real MPSKit. Note: verification exposed a numerical bug — find_groundstate on InfiniteMPS at g=10, chi=12 hits a LAPACK SVD ArgumentError inside the auto-chained GradientGrassmann step (over-parametrized bond dimension on a near-product state); reproducible across seeds and single-threaded. The recipe uses g=2.0 to avoid it. Co-Authored-By: Claude Fable 5 --- docs/make.jl | 2 + docs/src/howto/excitations.md | 168 ++++++++++++++++++++++++++++++++++ 2 files changed, 170 insertions(+) create mode 100644 docs/src/howto/excitations.md diff --git a/docs/make.jl b/docs/make.jl index 1a1acb1da..144796803 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -64,6 +64,7 @@ makedocs(; "man/parallelism.md", ], "How-to" => [ + "howto/index.md", "howto/states.md", "howto/hamiltonians.md", "howto/groundstate_algorithms.md", @@ -71,6 +72,7 @@ makedocs(; "howto/time_evolution.md", "howto/observables.md", "howto/entanglement.md", + "howto/excitations.md", ], "Examples" => [ "Overview" => "examples/index.md", diff --git a/docs/src/howto/excitations.md b/docs/src/howto/excitations.md new file mode 100644 index 000000000..39b3b03ec --- /dev/null +++ b/docs/src/howto/excitations.md @@ -0,0 +1,168 @@ +# [Excited states](@id howto_excitations) + +The examples on this page use MPSKit.jl, MPSKitModels.jl, and TensorKit.jl. +See [Installation](@ref tutorial_installation) for how to add these packages to your environment. + +[`excitations`](@ref) is the single entry point for computing energy eigenstates beyond the ground state. +This page shows how to call it for a gap, a full dispersion relation, a charged excitation, and a handful of excited states on a finite chain. +For what each algorithm actually does and why you would choose one over another, see [Excitations](@ref lib_excitations). +All examples share a single namespace: + +```@example excitations_howto +using MPSKit, MPSKitModels, TensorKit +``` + +--- + +## 1. Get a single excitation gap on an infinite chain + +On an `InfiniteMPS`, [`QuasiparticleAnsatz`](@ref) perturbs every site of the unit cell in a plane-wave superposition with a fixed `momentum`, given as a `Real` in radians per unit cell. +Pass the ground state and (optionally) its environments straight through from [`find_groundstate`](@ref): + +```@example excitations_howto +g = 2.0 +H_inf = transverse_field_ising(; g) +ψ₀_inf = InfiniteMPS(ℂ^2, ℂ^12) +ψ_inf, envs_inf, = find_groundstate(ψ₀_inf, H_inf; verbosity = 0) + +Es_inf, ϕs_inf = excitations(H_inf, QuasiparticleAnsatz(), 0.0, ψ_inf, envs_inf; num = 1) +Es_inf[1] +``` + +The values in `Es_inf` are excitation *gaps* above the ground-state energy density, not total energies: internally the ground-state energy per site is subtracted before diagonalizing. +`ϕs_inf` holds the corresponding quasiparticle states (`num` of them), which behave like normal vectors for `eigsolve`-style post-processing but are not `FiniteMPS`/`InfiniteMPS` objects themselves. +Raise `num` to get more than one state at the same momentum, e.g. `num = 3` for the three lowest excitations at that momentum. + +--- + +## 2. Scan the dispersion relation + +Pass a range (or any vector) of momenta instead of a single number to sweep the whole Brillouin zone in one call: + +```@example excitations_howto +momenta = range(0, π, 5) +Es_disp, ϕs_disp = excitations( + H_inf, QuasiparticleAnsatz(), momenta, ψ_inf, envs_inf; + num = 1, verbosity = 0 +) +size(Es_disp) +``` + +With a vector of `length(momenta)` momenta, `Es_disp` and `ϕs_disp` come back as `(length(momenta), num)` matrices rather than plain vectors — index `Es_disp[:, n]` for the dispersion of the `n`-th branch, or use `vec(Es_disp)` when `num = 1`. +`verbosity = 0` silences the per-momentum `@info` line that this method otherwise prints; raise it to see progress on a longer scan. +Momenta are independent of each other, so this method also accepts `parallel = true` (the default) to distribute them over available threads/workers; pass `parallel = false` to force sequential evaluation. + +--- + +## 3. Target a symmetry sector + +By default the optimization looks for the lowest excitation with trivial (vacuum) total charge, `sector = leftunit(ψ)`. +Passing a different `TensorKit` sector targets a quasiparticle with that charge instead — only `QuasiparticleAnsatz` supports this keyword. +Build the ground state with symmetric tensors first, then request the sector on the excitation call: + +```@example excitations_howto +g = 10.0 +L = 12 +H_Z2 = transverse_field_ising(Z2Irrep, FiniteChain(L); g) +ψ₀_Z2 = FiniteMPS(L, Z2Space(0 => 1, 1 => 1), Z2Space(0 => 8, 1 => 8)) +ψ_Z2, envs_Z2, = find_groundstate(ψ₀_Z2, H_Z2; verbosity = 0) + +Es_triv, = excitations(H_Z2, QuasiparticleAnsatz(), ψ_Z2, envs_Z2; num = 1) +Es_charged, ϕs_charged = excitations( + H_Z2, QuasiparticleAnsatz(), ψ_Z2, envs_Z2; + num = 1, sector = Z2Irrep(1) +) +Es_triv[1], Es_charged[1] +``` + +Here the `Z2Irrep(1)` excitation corresponds to a single flipped spin, the lowest physical excitation of the transverse-field Ising model. +[`ChepigaAnsatz`](@ref)/[`ChepigaAnsatz2`](@ref) do not support charged excitations at all: passing a nontrivial `sector` to either raises an error, and [`FiniteExcited`](@ref) has no `sector` keyword in the first place. + +--- + +## 4. Excited states on a finite chain + +Momentum is not a conserved quantity on a finite chain, so the finite method of `excitations` has no momentum argument; drop it entirely and call `QuasiparticleAnsatz` on the ground state directly: + +```@example excitations_howto +L = 12 +H_fin = transverse_field_ising(FiniteChain(L); g) +ψ₀_fin = FiniteMPS(L, ℂ^2, ℂ^16) +ψ_fin, envs_fin, = find_groundstate(ψ₀_fin, H_fin; verbosity = 0) + +Es_qp, ϕs_qp = excitations(H_fin, QuasiparticleAnsatz(), ψ_fin, envs_fin; num = 1) +Es_qp[1] +``` + +[`FiniteExcited`](@ref) takes a different approach: it repeatedly finds the ground state of `H + weight * Σᵢ |ψᵢ⟩⟨ψᵢ|`, penalizing overlap with the ground state and any excited states already found, and returns full `FiniteMPS` objects instead of quasiparticle states: + +```@example excitations_howto +fe_alg = FiniteExcited(; gsalg = DMRG(; verbosity = 0), weight = 10.0) +Es_fe, ψs_fe = excitations(H_fin, fe_alg, ψ_fin; num = 2) +Es_fe +``` + +Unlike `QuasiparticleAnsatz`, the values in `Es_fe` are total energies of the excited states, directly comparable to `expectation_value(ψ_fin, H_fin)` on the ground state. + +Because each call to `FiniteExcited` reruns a full ground-state optimization under the hood, it scales worse with `num` than the other methods here; reach for it when you need excited states of a genuinely different character than the ground state (so the projector penalty, rather than a local perturbation, is what finds them). + +[`ChepigaAnsatz`](@ref) is a cheaper alternative for excitations that are qualitatively similar to the ground state: it diagonalizes the effective Hamiltonian at a single site `pos` (default the middle of the chain) using the ground-state environments, with no extra sweeping: + +```@example excitations_howto +Es_ch, ψs_ch = excitations(H_fin, ChepigaAnsatz(), ψ_fin, envs_fin; num = 1, pos = L ÷ 2) +Es_ch[1] +``` + +[`ChepigaAnsatz2`](@ref) does the same with a two-site block at `pos, pos + 1`, which costs more but is typically more accurate; it truncates the optimized two-site tensor back down with a `trscheme` keyword (`notrunc()` by default): + +```@example excitations_howto +Es_ch2, ψs_ch2 = excitations(H_fin, ChepigaAnsatz2(; trscheme = truncrank(16)), ψ_fin, envs_fin; num = 1) +Es_ch2[1] +``` + +Like `FiniteExcited`, the energies returned by both Chepiga variants are total energies, not gaps. + + +--- + +## 5. Check excitation quality + +[`variance`](@ref) accepts a quasiparticle state directly and reports the variance of the energy, with smaller values indicating a better-converged excitation: + +```@example excitations_howto +variance(ϕs_qp[1], H_fin) +``` + +It also works on the infinite quasiparticle states from §1–§3: + +```@example excitations_howto +variance(ϕs_inf[1], H_inf) +``` + +!!! warning "Variance of infinite quasiparticle states" + `variance` on an infinite quasiparticle state carries an unresolved implementation note in `src/algorithms/toolbox.jl` and may be unreliable; verify its output before relying on it as a convergence diagnostic. + It also throws an `ArgumentError` for domain-wall (topological) excitations, where it is not implemented at all. + +To measure other observables on a finite quasiparticle state, convert it to a plain `FiniteMPS` first: + +```@example excitations_howto +excited_state = convert(FiniteMPS, ϕs_qp[1]) +real(expectation_value(excited_state, H_fin)) +``` + +--- + +## 6. Domain-wall excitations + +`excitations` also accepts two *different* ground states, `excitations(H, QuasiparticleAnsatz(), momentum, ψ_left, envs_left, ψ_right, envs_right; ...)`, which builds a quasiparticle that interpolates between them — a domain-wall (topological) excitation rather than a local perturbation on top of a single ground state. +This is real, exported functionality, but it has no dedicated test or example in the repository at the time of writing, and constructing two genuinely distinct, well-converged ground states to feed it (for instance the two symmetry-broken ground states of an ordered phase) is itself nontrivial to set up reliably in a short recipe. + + +--- + +## Where to go next + +For growing the bond dimension of the ground states these recipes start from, see [Controlling bond dimension](@ref howto_bond_dimension). +For background on the quasiparticle ansatz and the other algorithms used here, see [Excitations](@ref lib_excitations). +For general expectation values and correlators, including on the converted excited states from §5, see [Computing observables](@ref howto_observables). +Spectral functions built from these excitations (`propagator`, `DynamicalDMRG`, and related solvers) are a separate topic covered in the "Linear problems and spectral functions" section of the [Public API](@ref public_api) reference. From cf43650dadbecd87cfd83224cfe628fb2c1d7cda Mon Sep 17 00:00:00 2001 From: lkdvos Date: Sun, 5 Jul 2026 09:23:17 -0400 Subject: [PATCH 46/76] docs(howto): add browsable recipe index as How-to landing page Router page listing every how-to page and its numbered recipes, grouped by theme, with a missing-recipe issue invitation. All @ref anchors verified; no code blocks. Co-Authored-By: Claude Fable 5 --- docs/make.jl | 3 ++ docs/src/howto/index.md | 84 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 docs/src/howto/index.md diff --git a/docs/make.jl b/docs/make.jl index 144796803..e0e25daac 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -74,6 +74,9 @@ makedocs(; "howto/entanglement.md", "howto/excitations.md", ], + "Concepts" => [ + "concepts/algorithm_landscape.md", + ], "Examples" => [ "Overview" => "examples/index.md", "Quantum (1+1)d" => quantum_pages, diff --git a/docs/src/howto/index.md b/docs/src/howto/index.md new file mode 100644 index 000000000..bc821b6ec --- /dev/null +++ b/docs/src/howto/index.md @@ -0,0 +1,84 @@ +# [How-to guides](@id howto_index) + +These pages are task recipes: short, runnable answers to "how do I do X?". +They assume you already know the basics — if you are new to MPSKit, start with [Your first ground state](@ref tutorial_first_groundstate) instead. +Each recipe below stands on its own, so feel free to jump straight to the one you need. + +## States and operators + +**[Constructing states](@ref howto_states)** — building `FiniteMPS`, `InfiniteMPS`, `WindowMPS`, and `MultilineMPS` objects. +- A finite MPS from length, physical space, and maximum bond dimension — the default random-state constructor. +- Choosing the initializer and element type — `rand`/`randn` and real vs. complex tensors. +- Per-site physical and virtual spaces — heterogeneous lattices via vectors of spaces. +- A product state (trivial virtual space) — an unentangled bond-dimension-1 state. +- From your own site tensors — wrap existing `TensorMap`s into a canonical-form MPS. +- An infinite MPS — single- and multi-site unit cells, from spaces or from tensors. +- A window MPS — a mutable finite region embedded in infinite environments. +- A multiline MPS — stacking `InfiniteMPS` rows for boundary-MPS methods. +- States with symmetries — building MPS with `Rep[G]` graded spaces. + +**[Building Hamiltonians](@ref howto_hamiltonians)** — assembling MPO Hamiltonians from local operators. +- Finite Hamiltonian from local terms — `FiniteMPOHamiltonian` from `inds => operator` pairs. +- Infinite (translation-invariant) Hamiltonian — `InfiniteMPOHamiltonian` on a unit cell. +- Converting between boundary conditions — open vs. periodic finite chains from an infinite Hamiltonian. +- A window Hamiltonian — carving a finite interval out of an infinite Hamiltonian with `WindowMPOHamiltonian`. + +## Finding ground states + +**[Ground-state algorithms](@ref howto_groundstate_algorithms)** — configuring `find_groundstate`. +- Get a ground state with defaults — letting `find_groundstate` pick an algorithm for you. +- Configure finite-system DMRG — explicit `DMRG`/`DMRG2`, and chaining them with `&`. +- Configure infinite-system algorithms — `VUMPS`, `IDMRG`, and `IDMRG2`. +- Refine convergence with GradientGrassmann — Riemannian gradient descent after a cheaper warm-up. +- Control output and tolerances — `verbosity` levels and reusing `envs` between calls. + +**[Controlling bond dimension](@ref howto_bond_dimension)** — inspecting, growing, and shrinking bond dimension. +- Inspecting the current bond dimension — `left_virtualspace`/`right_virtualspace` and `dim`. +- Growing bond dimension — `RandExpand` (no Hamiltonian needed) and `OptimalExpand`. +- Reducing bond dimension — `SvdCut` and the in-place `changebonds!`. +- Truncation schemes — `truncrank`, `trunctol`, `notrunc`, `truncspace`, and combining them with `&`. +- Growing during finite MPS optimization — `DMRG2` and the `trscheme` keyword of `find_groundstate`. +- Growing during infinite MPS optimization — `IDMRG2` and `VUMPSSvdCut`. +- Chaining algorithms — composing bond-change and ground-state algorithms with `&`. + +## Dynamics + +**[Time evolution](@ref howto_time_evolution)** — real- and imaginary-time evolution of an MPS. +- Evolve a state through one time step — `timestep` with `TDVP`. +- Evolve over a time span — `time_evolve` across a vector of time points. +- Grow the bond dimension while evolving — `TDVP2` with a mandatory `trscheme`. +- Evolve an infinite state — single-site `TDVP` on an `InfiniteMPS`. +- Imaginary-time evolution — `imaginary_evolution = true` to cool towards the ground state. +- Build a time-evolution MPO — `make_time_mpo` (`WII`, `TaylorCluster`, `WI`) plus `approximate`. + +## Measurements + +**[Computing observables](@ref howto_observables)** — extracting physical quantities from an MPS. +- Local (one-site) expectation value — `expectation_value(ψ, i => O)`. +- Multi-site (contiguous) expectation value — tensor-product operators on an index tuple. +- Energy (full-MPO expectation value) — `expectation_value(ψ, H)` for a Hamiltonian MPO. +- Two-point correlators — `correlator`, including a full correlation profile over a range. +- Energy variance as a convergence check — `variance` as a diagnostic after a ground-state search. + +**[Entanglement entropy and spectrum](@ref howto_entanglement)** — reading off entanglement from the gauge tensors. +- Entanglement entropy at a single cut — `entropy(ψ, site)`. +- Entropy profile across every cut — collecting `entropy` over all sites. +- The entanglement spectrum — `entanglement_spectrum` as a sector-resolved vector. +- Sector-resolved spectrum — indexing the spectrum by symmetry sector with `keys`/`pairs`. +- Entanglement of an infinite MPS — `entropy`/`entanglement_spectrum` per unit-cell site. +- Plotting the spectrum — the `entanglementplot` recipe (requires Plots.jl). + +## Excitations + +**[Excited states](@ref howto_excitations)** — computing energy eigenstates beyond the ground state. +- Get a single excitation gap on an infinite chain — `QuasiparticleAnsatz` at a fixed momentum. +- Scan the dispersion relation — passing a range of momenta in one call. +- Target a symmetry sector — a charged quasiparticle via the `sector` keyword. +- Excited states on a finite chain — `QuasiparticleAnsatz`, `FiniteExcited`, and the Chepiga ansätze. +- Check excitation quality — `variance` on a quasiparticle state. +- Domain-wall excitations — quasiparticles interpolating between two distinct ground states. + +## Missing a recipe? + +If the task you're after isn't listed here, please open an issue at [QuantumKitHub/MPSKit.jl](https://github.com/QuantumKitHub/MPSKit.jl/issues) describing what you're trying to do. +Concrete task descriptions make the best new recipes. From cfa83e6b6cdab5c43161c9c0a60ce8326e2915e7 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Sun, 5 Jul 2026 09:23:32 -0400 Subject: [PATCH 47/76] docs(concepts): draft algorithm landscape decision guide New Concepts section with the finite/infinite x task decision table and per-task prose salvaged from man/algorithms.md. Zero code blocks. Every physics/convergence claim carries a REVIEW flag (26 total) for maintainer vetting per CLAUDE.md; dropped-claim inventory in a trailing comment. Co-Authored-By: Claude Fable 5 --- docs/src/concepts/algorithm_landscape.md | 141 +++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 docs/src/concepts/algorithm_landscape.md diff --git a/docs/src/concepts/algorithm_landscape.md b/docs/src/concepts/algorithm_landscape.md new file mode 100644 index 000000000..161e3a31d --- /dev/null +++ b/docs/src/concepts/algorithm_landscape.md @@ -0,0 +1,141 @@ +# [The algorithm landscape](@id concept_algorithm_landscape) + +MPSKit deliberately separates *what* you want to compute from *how* it gets computed. +Entry points such as [`find_groundstate`](@ref), [`timestep`](@ref), [`excitations`](@ref), [`leading_boundary`](@ref), and [`approximate`](@ref) each accept several interchangeable algorithm structs, and the package ships more than a dozen of them. +That flexibility exists because no single algorithm wins everywhere: some only apply to finite or only to infinite systems, some can grow the bond dimension while others cannot, and their relative performance depends on the model at hand. + + +This page is the decision guide. +It starts from a table that maps each task onto the algorithm(s) of choice, and then walks through the reasoning behind each row. +It explains *why* you would pick one algorithm over another; for the *how* — the actual calls, keywords, and worked recipes — follow the links into the how-to pages. + +## The decision table + +| Task | Finite system | Infinite system | +|:-----|:--------------|:----------------| +| **Ground state** ([`find_groundstate`](@ref)) | [`DMRG`](@ref) (workhorse, fixed bond dimension); [`DMRG2`](@ref) (grows bond dimension, requires `trscheme`); [`GradientGrassmann`](@ref) (final polish) | [`VUMPS`](@ref) (workhorse, needs a unique ground state); [`IDMRG`](@ref) / [`IDMRG2`](@ref) (two-site requires `trscheme` and a unit cell of at least two sites); [`GradientGrassmann`](@ref) (final polish) | +| **Time evolution** ([`timestep`](@ref) / [`time_evolve`](@ref)) | [`TDVP`](@ref) (fixed bond dimension); [`TDVP2`](@ref) (grows bond dimension, requires `trscheme`); or [`make_time_mpo`](@ref) ([`WI`](@ref) / [`WII`](@ref) / [`TaylorCluster`](@ref)) applied with [`approximate`](@ref) | [`TDVP`](@ref) (no two-site variant exists); or [`make_time_mpo`](@ref) applied with [`approximate`](@ref) | +| **Excitations** ([`excitations`](@ref)) | [`QuasiparticleAnsatz`](@ref) (the only one supporting charged `sector`s); [`FiniteExcited`](@ref) (penalty method); [`ChepigaAnsatz`](@ref) / [`ChepigaAnsatz2`](@ref) (cheap, from ground-state environments) | [`QuasiparticleAnsatz`](@ref) (momentum-resolved, the only choice) | +| **Boundary / statistical mechanics** ([`leading_boundary`](@ref)) | apply the transfer MPO row by row with [`approximate`](@ref) | [`VUMPS`](@ref); [`VOMPS`](@ref) (power method); [`IDMRG`](@ref) / [`IDMRG2`](@ref); [`GradientGrassmann`](@ref) (hermitian, positive transfer matrices) | +| **Compression / approximation** ([`approximate`](@ref), [`changebonds`](@ref)) | [`approximate`](@ref) with [`DMRG`](@ref) / [`DMRG2`](@ref); [`SvdCut`](@ref) via [`changebonds`](@ref) for local truncation | [`approximate`](@ref) with [`IDMRG`](@ref) / [`IDMRG2`](@ref) / [`VOMPS`](@ref); [`SvdCut`](@ref) via [`changebonds`](@ref) for local truncation | + + + +A few structural facts hold across the whole table and are worth internalizing early. +Every two-site algorithm (`DMRG2`, `IDMRG2`, `TDVP2`) requires an explicit `trscheme` keyword and can change the bond dimension as it runs; the single-site variants with their default settings cannot. +`IDMRG2` additionally needs a unit cell of at least two sites, and `TDVP2` exists only for finite MPS. +Finally, algorithms compose: the `&` operator chains two algorithms into one, running the first to completion and handing its result to the second, which is how two-site warm-up passes and gradient-descent polishing stages are combined with a workhorse algorithm in a single call. + +## Ground states + +The classic approach is alternating local optimization: [`DMRG`](@ref) sweeps through a finite chain, optimizing one site while all others are held fixed. + +The catch is the fixed bond dimension: a single-site update can never enlarge the virtual spaces, so the precision of the calculation is locked in by the initial state. +This bites hardest when symmetries are involved, because then not just the total bond dimension but its distribution over charge sectors is frozen, and a poor initial distribution cannot be repaired. + +[`DMRG2`](@ref) fixes this by optimizing two neighbouring sites jointly and truncating back down, which lets the bond dimension (and its sector distribution) adapt, at a higher cost per sweep. + + +For infinite systems, two philosophies compete. +[`IDMRG`](@ref) grows the system from the middle outwards, repeatedly inserting and optimizing new sites until the boundary is no longer felt; [`IDMRG2`](@ref) is its two-site, bond-growing variant. + +Because convergence requires the effective system to outgrow the correlation length, IDMRG can be slow to converge for critical systems, where that length diverges. + +[`VUMPS`](@ref) instead works with a genuinely uniform state: each local update is followed by a re-gauging step that replaces *every* tensor in the infinite chain with the updated one, so the effect of an update is felt throughout the system immediately. + +This often gives VUMPS a higher convergence rate than IDMRG, which is why it is the default infinite-system workhorse. + +The price is an injectivity requirement: VUMPS assumes a unique ground state, and it is not the right tool when the state it should converge to is non-injective. + +Like DMRG, VUMPS is single-site and cannot alter the bond dimension. + +[`GradientGrassmann`](@ref) approaches the problem from a third direction: the MPS tensors form a Riemannian manifold (a Grassmann manifold), and one can run gradient descent directly on it, for finite and infinite states alike. +Its niche is the tail of the optimization: close to convergence its rate is often the best of the lot, while far from convergence the sweeping algorithms tend to make faster progress. + +The practical consequence is the chaining pattern: run a cheap workhorse first, then hand over to gradient descent, e.g. `VUMPS(...) & GradientGrassmann(...)`. + +This pattern is baked into `find_groundstate` itself: called with only keywords, it picks `DMRG` for a finite state and `VUMPS` for an infinite one, appends a `GradientGrassmann` stage on infinite states when the requested tolerance is tighter than `1e-4`, and prepends a two-site pass (`DMRG2` or `IDMRG2`) whenever you supply a `trscheme`. +Since gradient descent is also a single-site method, growing the bond dimension remains the job of that two-site pre-pass or of [`changebonds`](@ref). + +For call syntax, keyword tables, and worked chaining examples, see [Ground-state algorithms](@ref howto_groundstate_algorithms). + +## Time evolution + +MPSKit solves the time-dependent Schrödinger equation along two distinct routes, and the choice between them is a genuine trade-off rather than a finite/infinite split. + +The first route, [`TDVP`](@ref), never builds the evolution operator at all. +It projects the Schrödinger equation onto the tangent space of the current MPS, solves the projected equation for a small time step, and repeats. + +Its two-site variant [`TDVP2`](@ref) plays the same role as `DMRG2` does for `DMRG`: it lets the bond dimension grow to absorb the entanglement generated by the evolution, at extra cost, and it exists only for finite systems. + + +The second route splits the problem in two: first approximate the evolution operator ``\exp(-iH\,dt)`` itself as an MPO using [`make_time_mpo`](@ref) — with [`WI`](@ref), [`WII`](@ref), or [`TaylorCluster`](@ref) as the approximation scheme — and then apply that MPO to the state with [`approximate`](@ref). +The appeal is amortization: for a time-independent Hamiltonian and a fixed step size the MPO is built once and reused for every step, and the accuracy of the operator approximation is controlled independently of the accuracy of its application. + + + +Both routes accept an `imaginary_evolution` keyword for evolution in imaginary time. +For step-by-step recipes along either route, see [Time evolution](@ref howto_time_evolution). + +## Excitations + +Resolving states deep in the spectrum is generally out of reach, but three families of algorithms target the low-lying part, each with a distinct character. + + +The [`QuasiparticleAnsatz`](@ref) is the most broadly applicable: it works for finite and infinite systems, and it is the only algorithm that can target excitations carrying a nontrivial symmetry charge, via the `sector` keyword. +It builds an excited state by replacing a single tensor of the ground-state MPS — summed over all positions on a finite chain, or in a momentum-carrying plane-wave superposition on an infinite one — and solves the resulting eigenvalue problem. + +Because the variational class consists of local perturbations on top of the ground state, it is the natural choice for quasiparticle-like excitations, and on infinite systems it is the only option, giving direct access to dispersion relations. + + +[`FiniteExcited`](@ref) takes a brute-force approach available only on finite chains: it reruns a full ground-state optimization on a modified Hamiltonian that carries an energy penalty for overlapping with all previously found states. +Each new excited state therefore costs another complete ground-state search, and the orthogonality to earlier states is only approximate (enforced by the penalty `weight`, not exactly). + +Its advantage is that it makes no assumption about the *form* of the excited state: since each state is a fully variational `FiniteMPS`, it can capture excitations that are not well described as a local perturbation of the ground state. + + +The [`ChepigaAnsatz`](@ref) (and its two-site refinement [`ChepigaAnsatz2`](@ref)) is the cheapest of the three, also finite-only. +It observes that the gauged ground-state MPS tensors act as isometries projecting the Hamiltonian into a low-energy subspace, so the low-lying spectrum can be read off by diagonalizing the effective Hamiltonian already available from the ground-state environments, with no additional sweeping. + +This works best precisely where excitations are hard for the other methods: in critical systems with long-range correlations, where the excitation weight is spread across the whole chain. + + +For the call signatures, momentum scans, and sector-targeting recipes, see [Excited states](@ref howto_excitations). + +## Boundaries and statistical mechanics + +MPS algorithms are not limited to Hamiltonian problems. +A two-dimensional classical partition function can be written as an infinite power of a row-to-row transfer MPO, and contracting the network amounts to finding that operator's dominant eigenvector — a boundary MPS. + +This is the job of [`leading_boundary`](@ref), which accepts a familiar cast: [`VUMPS`](@ref) and [`IDMRG`](@ref)/[`IDMRG2`](@ref) carry over directly from the ground-state problem, [`GradientGrassmann`](@ref) applies when the transfer MPO is hermitian and positive, and [`VOMPS`](@ref) is a power method specific to this setting, which iteratively approximates the operator-times-state product by a new state of the same bond dimension. + + + +## Compression and changing bond dimension + +Two mechanisms round out the landscape by manipulating states rather than solving for new ones. +[`approximate`](@ref) variationally fits a new MPS, typically of different bond dimension, to the result of applying an MPO to a state; the sweeping ground-state algorithms (`DMRG`/`DMRG2` for finite, `IDMRG`/`IDMRG2`/`VOMPS` for infinite) double as its optimization engines. +This is the same machinery that applies time-evolution MPOs, and combined with [`SvdCut`](@ref) it yields a globally optimal truncation of a state. + +[`changebonds`](@ref), by contrast, performs direct local surgery on a state: truncating with [`SvdCut`](@ref), or expanding with [`OptimalExpand`](@ref), [`RandExpand`](@ref), or [`VUMPSSvdCut`](@ref) so that the single-site algorithms above have room to work with. +The trade-offs between those expansion schemes, and recipes for when to grow, are covered in [Controlling bond dimension](@ref howto_bond_dimension). + +## Where to go next + +The how-to pages turn each row of the table into runnable recipes: [Ground-state algorithms](@ref howto_groundstate_algorithms), [Time evolution](@ref howto_time_evolution), and [Excited states](@ref howto_excitations), with [Controlling bond dimension](@ref howto_bond_dimension) supporting all three. +For the complete signatures, keyword lists, and docstrings of every algorithm named here, see the library reference: [Ground-state algorithms](@ref lib_groundstate), [Time evolution](@ref lib_time_evolution), and [Excitations](@ref lib_excitations). + + From d09601b80c027f7d8ab5ca23d17e28e93a5387a6 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Sun, 5 Jul 2026 09:31:19 -0400 Subject: [PATCH 48/76] docs(tutorials): add quantum quench time-evolution tutorial Hand-held TDVP quench: TFIM ground state at g=0.5, quench to g=2.0, explicit 40-step timestep loop tracking mid-chain transverse magnetization, plotted with Plots. Verified end-to-end twice: the initial sigma-z story was rewritten to track sigma-x after verification showed DMRG at D=16 converges to the symmetric ground state (flat sigma-z trace); the sigma-x trace shows order-1 relaxation dynamics (0.26 -> peak 0.61 -> plateau 0.49). Co-Authored-By: Claude Fable 5 --- docs/make.jl | 1 + docs/src/tutorials/time_evolution.md | 138 +++++++++++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 docs/src/tutorials/time_evolution.md diff --git a/docs/make.jl b/docs/make.jl index e0e25daac..94e6912a4 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -54,6 +54,7 @@ makedocs(; "tutorials/installation.md", "tutorials/first_groundstate.md", "tutorials/thermodynamic_limit.md", + "tutorials/time_evolution.md", ], "Manual" => [ "man/intro.md", diff --git a/docs/src/tutorials/time_evolution.md b/docs/src/tutorials/time_evolution.md new file mode 100644 index 000000000..cff01897a --- /dev/null +++ b/docs/src/tutorials/time_evolution.md @@ -0,0 +1,138 @@ +# [A quantum quench](@id tutorial_time_evolution) + +The previous tutorials computed ground states — static snapshots of a model at its lowest energy. +This tutorial adds the time axis: we take a state that is *not* an eigenstate of its Hamiltonian and watch it evolve under the Schrödinger equation, + +```math +|\psi(t)\rangle = e^{-iHt}\,|\psi(0)\rangle , +``` + +tracking one local observable as a function of time. +The protocol we use is the simplest and most common one in the field, a *global quench*, and the workhorse algorithm is [`TDVP`](@ref), the time-dependent variational principle, driven one step at a time through [`timestep`](@ref). + +We stay with the transverse-field Ising model from [Your first ground state](@ref tutorial_first_groundstate), so the model-building and ground-state steps below should look familiar. + +## Loading the packages + +Every code block on this page shares one Julia session, so we load the packages once. +As before, the model comes from MPSKitModels, the local spin operators from TensorKitTensors, and `Plots` draws the final figure. + +```@example time-evolution +using MPSKit, MPSKitModels, TensorKit +using TensorKitTensors.SpinOperators: σˣ, σᶻ +using Plots +``` + +## 1. Prepare the initial state + +Time evolution needs a definite starting state, and the standard choice is the ground state of some Hamiltonian. +We take a chain of `L = 12` sites with a transverse field `g₀ = 0.5` — the ordered side of the model — and find its ground state exactly as in [the first tutorial](@ref tutorial_first_groundstate), silencing the convergence log with `verbosity = 0`. +The bond dimension `D = 16` is comfortably large for a ground state of this size; we will see below why time evolution wants more headroom than a ground-state calculation. + +```@example time-evolution +L = 12 +D = 16 +g₀ = 0.5 +H₀ = transverse_field_ising(FiniteChain(L); g = g₀) +ψ₀ = FiniteMPS(L, ℂ^2, ℂ^D) +ψ, = find_groundstate(ψ₀, H₀, DMRG(; verbosity = 0)) +nothing # hide +``` + +The observable we will track through the evolution is the transverse magnetization ``\langle\sigma^x\rangle`` at the middle of the chain, away from the open ends. + +We measure its baseline value in the pre-quench ground state: + +```@example time-evolution +i_mid = L ÷ 2 +real(expectation_value(ψ, i_mid => σˣ())) +``` + +## 2. The quench + +A *global quench* is the sudden change of a parameter of the Hamiltonian, everywhere at once: we prepare the ground state of `H₀`, then at `t = 0` switch the Hamiltonian to a different `H₁` and let the state evolve under it. +Because `ψ` is an eigenstate of `H₀` but not of `H₁`, it is no longer stationary — the quench injects energy into the system, and nontrivial dynamics follows. + +Our quench takes the transverse field from `g₀ = 0.5` all the way across the phase transition to `g₁ = 2.0`: + +```@example time-evolution +g₁ = 2.0 +H₁ = transverse_field_ising(FiniteChain(L); g = g₁) +``` + + + +## 3. A single time step + +The elementary move of real-time evolution in MPSKit is [`timestep`](@ref), which advances a state by one small increment `dt`. +Its arguments are, in order: the state, the Hamiltonian to evolve under, the current time, the step size, and the algorithm. +Here we take the very first step, from `t = 0.0` to `t = dt`, with single-site [`TDVP`](@ref): + +```@example time-evolution +dt = 0.05 +ψ_t, envs = timestep(ψ, H₁, 0.0, dt, TDVP()) +real(expectation_value(ψ_t, i_mid => σˣ())) +``` + +TDVP integrates the Schrödinger equation projected onto the space of MPS with the current bond dimension, which is why it slots so naturally into an MPS workflow. + +`timestep` returns two things: + +- `ψ_t` — the evolved state at time `dt` (a new state; `ψ` is left untouched). +- `envs` — the environments, cached partial contractions belonging to the new state and `H₁`. + +The `envs` are the reason evolution loops are cheap to keep running: passing them back into the next `timestep` call lets it start from the cached contractions instead of recomputing them from scratch. + +The transverse magnetization has already moved slightly away from its `t = 0` value — the state is on its way. + +## 4. Evolving in a loop + +Real-time evolution is nothing more than this single step, repeated. +We already took step 1 above, so the loop below performs the remaining steps, up to `n_steps = 40` in total (a final time of `t = 2.0`), recording the transverse magnetization at the middle of the chain after every step. +Note how each iteration feeds the previous `envs` back in as the optional last argument, and how the current time `(n - 1) * dt` advances with the loop. + +```@example time-evolution +n_steps = 40 +times = (0:n_steps) .* dt +m = zeros(n_steps + 1) +m[1] = real(expectation_value(ψ, i_mid => σˣ())) # t = 0, before the quench dynamics +m[2] = real(expectation_value(ψ_t, i_mid => σˣ())) # t = dt, from the single step above +for n in 2:n_steps + global ψ_t, envs + ψ_t, envs = timestep(ψ_t, H₁, (n - 1) * dt, dt, TDVP(), envs) + m[n + 1] = real(expectation_value(ψ_t, i_mid => σˣ())) +end +m[end] +``` + +(The `global` keyword is needed because the loop rebinds `ψ_t` and `envs`, which live outside it; inside a function you would not need it.) + +Writing the loop by hand like this keeps every moving part visible, which is the point of a tutorial. +For production use, [`time_evolve`](@ref) wraps exactly this loop and steps through a whole vector of time points in one call — see [Time evolution](@ref howto_time_evolution). + +## 5. Magnetization over time + +The payoff: the transverse magnetization at the middle of the chain, as a function of time after the quench. + +```@example time-evolution +plot(times, m; + xlabel = "t", ylabel = "⟨σˣ⟩ at site $i_mid", + label = "TDVP, D = $D", title = "TFIM transverse magnetization after a quench") +``` + +The curve shows how the observable responds to the sudden change in the field: starting from its pre-quench value, ``\langle\sigma^x\rangle`` relaxes towards a new value set by `H₁`, with oscillations along the way. + + +!!! warning "Fixed bond dimension means finite reach in time" + Single-site TDVP keeps the bond dimension fixed at whatever the initial state has. + After a quench, however, the entanglement of the evolving state grows with time, so a fixed bond dimension can only follow the true dynamics faithfully up to some finite time — beyond it, the simulation quietly loses accuracy rather than failing loudly. + + The practical checks and remedies — two-site [`TDVP2`](@ref), which grows the bond dimension as it truncates, and bond-expansion options for single-site TDVP — are collected in [Time evolution](@ref howto_time_evolution). + +## Where to go next + +You have run your first dynamics simulation: prepare a ground state, quench the Hamiltonian, step the state forward in time, and read off an observable at every step. + +The natural reference for everything this page glossed over is the [Time evolution](@ref howto_time_evolution) how-to: evolving over a time span in one call, growing the bond dimension during evolution, imaginary time, and evolving infinite states. +Speaking of which — everything here was done on a finite chain, but `timestep` works just as well on the `InfiniteMPS` states introduced in [The thermodynamic limit](@ref tutorial_thermodynamic_limit). +And for measuring more than a single local magnetization on the evolved states, see [Computing observables](@ref howto_observables). From 12733a3fb1e18546250217e57847883b2e80a87a Mon Sep 17 00:00:00 2001 From: lkdvos Date: Sun, 5 Jul 2026 09:38:31 -0400 Subject: [PATCH 49/76] docs(tutorials): add quasiparticle excitations tutorial Hand-held dispersion walk-through on the infinite TFIM at g=2: single momentum gap, 16-momentum sweep, plot against the exact Jordan-Wigner dispersion. Verified end-to-end; the k=0 gap matches 2(g-1) to 1e-11. Physics claims (phase, ansatz framing, exact formula) carry REVIEW flags. Co-Authored-By: Claude Fable 5 --- docs/make.jl | 1 + docs/src/tutorials/excitations.md | 116 ++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 docs/src/tutorials/excitations.md diff --git a/docs/make.jl b/docs/make.jl index 94e6912a4..d4d47a949 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -55,6 +55,7 @@ makedocs(; "tutorials/first_groundstate.md", "tutorials/thermodynamic_limit.md", "tutorials/time_evolution.md", + "tutorials/excitations.md", ], "Manual" => [ "man/intro.md", diff --git a/docs/src/tutorials/excitations.md b/docs/src/tutorials/excitations.md new file mode 100644 index 000000000..fa77470da --- /dev/null +++ b/docs/src/tutorials/excitations.md @@ -0,0 +1,116 @@ +# [Quasiparticle excitations](@id tutorial_excitations) + +The previous tutorials ended with a ground state: the lowest-energy state of the transverse-field Ising model, first on a finite chain and then directly in [the thermodynamic limit](@ref tutorial_thermodynamic_limit). +The natural next question is what lies *above* it: how much energy does it cost to excite the system? +For a translation-invariant chain the answer is organized by momentum — for each momentum ``k`` there is a lowest excitation energy ``\Delta E(k)``, and the resulting curve is the **dispersion relation** of the model. +Its minimum over all momenta is the **energy gap**, one of the most basic characterizations of a quantum phase. + + +In this tutorial we compute the dispersion relation of the infinite transverse-field Ising chain with MPSKit's quasiparticle ansatz, and finish with a plot of ``\Delta E(k)`` across the Brillouin zone — compared against the exact solution. + +## Loading the packages + +As in the previous tutorials, every code block on this page shares one Julia session, so we load the packages once. + +```@example excitations +using MPSKit, MPSKitModels, TensorKit +using Plots +``` + +## 1. Find the ground state + +Excitations are computed *on top of* a ground state, so the first step is the calculation you already know from [The thermodynamic limit](@ref tutorial_thermodynamic_limit): build the infinite Hamiltonian, make a random `InfiniteMPS`, and converge it with `VUMPS`. + +This time we set the field to `g = 2.0`, deep in the paramagnetic phase, where the model is **gapped**: the lowest excitation costs a finite amount of energy, which is exactly what we want to measure. + + +```@example excitations +g = 2.0 +H = transverse_field_ising(; g) +ψ₀ = InfiniteMPS(ℂ^2, ℂ^12) +ψ, envs, ϵ = find_groundstate(ψ₀, H, VUMPS(; verbosity = 0)) +``` + +We keep all three return values this time: the optimized state `ψ` and the environments `envs` both feed directly into the excitation calculation below, so nothing has to be recomputed. + +## 2. One excitation at one momentum + +The **quasiparticle ansatz** builds an excited state directly on top of the uniform ground state. +The idea is simple to picture: take the converged ground state and perturb it locally, replacing the tensor at one site with a new one that we get to optimize. +Because the chain is infinite and translation invariant, we do not place this perturbation at any particular site; instead we superpose it across *all* sites with a plane-wave phase, which gives the excitation a definite momentum ``k``. +Optimizing the perturbation then yields the lowest excited state at that momentum. + + +The call is [`excitations`](@ref) with the [`QuasiparticleAnsatz`](@ref) algorithm, a momentum (a real number, in radians per site), and the ground state with its environments. +Let us ask for the excitation at the edge of the Brillouin zone, ``k = \pi``: + +```@example excitations +E, ϕ = excitations(H, QuasiparticleAnsatz(), π, ψ, envs) +E +``` + +Two things to note about the return values: + +- `E` is a *vector* of excitation energies, of length `num` — the keyword controlling how many excitations to compute at this momentum, which defaults to `num = 1`, so here it has a single entry. +- The entries of `E` are energies **above the ground state** — gaps at this momentum, not total energies. The ground-state energy is subtracted internally, so you can read them off directly. + +The second return value `ϕ` holds the corresponding quasiparticle states, which can be used for further post-processing; we will not need them in this tutorial. + +## 3. The full dispersion + +To trace out the whole dispersion relation we simply pass a *range* of momenta instead of a single number. +By symmetry it is enough to scan from ``0`` to ``\pi``, and we use 16 points to keep the runtime modest. + + +```@example excitations +momenta = range(0, π, 16) +Es, ϕs = excitations(H, QuasiparticleAnsatz(), momenta, ψ, envs; verbosity = 0) +size(Es) +``` + +With a range of momenta the energies come back as a matrix of size `(length(momenta), num)` — here `(16, 1)`, one row per momentum and one column because we kept the default `num = 1`. +We pass `verbosity = 0` to silence the progress line this method otherwise prints for every momentum. +The momenta are independent of one another, so MPSKit works on them in parallel by default. + +## 4. Plot the dispersion + +Now for the payoff. +This particular model is exactly solvable, so we can plot our numerical dispersion right on top of the known answer: + +```math +\Delta E(k) = 2\sqrt{1 + g^2 - 2 g \cos k}. +``` + + + +For this Hermitian problem the computed energies come back as real numbers; the `real.(...)` below is a harmless safeguard for the general case, where the eigenvalue solver may return a complex number type with numerically vanishing imaginary parts. + +```@example excitations +k_exact = range(0, π, 200) +ΔE_exact = @. 2 * sqrt(1 + g^2 - 2g * cos(k_exact)) +plot(k_exact, ΔE_exact; label = "exact", xlabel = "momentum k", ylabel = "ΔE(k)", title = "TFIM dispersion (g = $g)") +scatter!(momenta, real.(Es); label = "quasiparticle ansatz (D = 12)") +``` + +The 16 computed points fall right on the exact curve. +The dispersion rises monotonically from ``k = 0`` to ``k = \pi``, so its minimum — the gap — sits at zero momentum, where the exact value is ``\Delta E(0) = 2(g - 1)``. +Our first matrix entry is precisely that point, so we can close with a numerical check: + +```@example excitations +real(Es[1, 1]), 2 * (g - 1) +``` + +A ground state at bond dimension 12 plus a variational quasiparticle on top reproduces the exact gap of the model — that is the quasiparticle ansatz working as intended. + + +## Where to go next + +You have computed a full dispersion relation on top of an infinite ground state and read off the energy gap. + +The [`excitations`](@ref) entry point can do considerably more than what we used here: it can target excitations carrying a nontrivial symmetry charge, build topological (domain-wall) excitations that interpolate between two different ground states, and compute excited states of *finite* chains, where momentum is no longer a good quantum number and different algorithms take over. +All of these are recipes in [Excited states](@ref howto_excitations). +For what each excitation algorithm actually does and when to choose it, see the library reference [Excitations](@ref lib_excitations). + + From 6c06cba39b2ef76090da0bd8be2b3f0b78621dea Mon Sep 17 00:00:00 2001 From: lkdvos Date: Sun, 5 Jul 2026 09:39:21 -0400 Subject: [PATCH 50/76] docs(tutorials): add using-symmetries tutorial; wire tutorial stubs Flagship TFIM redone with explicit Z2 symmetry: graded spaces, energy agreement with the trivial run (1e-14), sector-resolved virtual space and entanglement spectrum, and the charged-sector excitation payoff. Plan deviation noted in-file: MPSKitModels' transverse_field_ising only supports Trivial/Z2Irrep/FermionParity, so the plan's U(1) framing is replaced by Z2; U(1)/SU(2) are pointed to via states how-to and examples. All 13 @example blocks verified twice (unseeded RNG). Also replaces the two TODO(link) stubs in thermodynamic_limit.md with real links to the new excitations and using-symmetries tutorials. Co-Authored-By: Claude Fable 5 --- docs/make.jl | 1 + docs/src/tutorials/thermodynamic_limit.md | 5 +- docs/src/tutorials/using_symmetries.md | 197 ++++++++++++++++++++++ 3 files changed, 199 insertions(+), 4 deletions(-) create mode 100644 docs/src/tutorials/using_symmetries.md diff --git a/docs/make.jl b/docs/make.jl index d4d47a949..17475edc9 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -56,6 +56,7 @@ makedocs(; "tutorials/thermodynamic_limit.md", "tutorials/time_evolution.md", "tutorials/excitations.md", + "tutorials/using_symmetries.md", ], "Manual" => [ "man/intro.md", diff --git a/docs/src/tutorials/thermodynamic_limit.md b/docs/src/tutorials/thermodynamic_limit.md index 3f51bb745..0be68f69e 100644 --- a/docs/src/tutorials/thermodynamic_limit.md +++ b/docs/src/tutorials/thermodynamic_limit.md @@ -129,9 +129,6 @@ In the thermodynamic limit the symmetry breaking is genuine — the two opposite You have now run the same TFIM calculation twice — once at finite size, once directly at `L = ∞` — and seen how little the code had to change. From here you can go beyond ground states. -A natural next step is to compute the excitations above this infinite ground state (the model's quasiparticle spectrum), or to exploit the symmetries of the model to make the calculation cheaper and more accurate. - - - +A natural next step is to [compute the excitations above this infinite ground state](@ref tutorial_excitations) (the model's quasiparticle spectrum), or to [exploit the symmetries of the model](@ref tutorial_using_symmetries) to make the calculation cheaper and more accurate. To go deeper on the individual steps used here, see [Constructing states](@ref howto_states), [Controlling bond dimension](@ref howto_bond_dimension), and [Entanglement entropy and spectrum](@ref howto_entanglement); the algorithm reference is [Ground-state algorithms](@ref lib_groundstate). diff --git a/docs/src/tutorials/using_symmetries.md b/docs/src/tutorials/using_symmetries.md new file mode 100644 index 000000000..6a394f676 --- /dev/null +++ b/docs/src/tutorials/using_symmetries.md @@ -0,0 +1,197 @@ + + +# [Using symmetries](@id tutorial_using_symmetries) + +In [Your first ground state](@ref tutorial_first_groundstate) and [The thermodynamic limit](@ref tutorial_thermodynamic_limit) we treated the transverse-field Ising model (TFIM) as a generic spin chain. +But the TFIM is not generic: it has a symmetry, and in this tutorial we teach MPSKit about it. + +Recall the Hamiltonian, + +```math +H = -J\left(\sum_{\langle i,j\rangle} \sigma^z_i\,\sigma^z_j + g\sum_i \sigma^x_i\right), +``` + +and consider the *global spin flip* ``P = \prod_i \sigma^x_i``, which flips every spin at once. +Conjugating by ``P`` sends ``\sigma^z_i \to -\sigma^z_i``, so the interaction term ``\sigma^z_i\sigma^z_j`` picks up two minus signs and is unchanged, while the field term ``\sigma^x_i`` commutes with ``P`` trivially. +Hence ``H`` commutes with ``P``. +Since ``P^2 = 1``, this is a ``\mathbb{Z}_2`` symmetry, and every eigenstate of ``H`` can be labelled by a parity quantum number: *even* (``P = +1``) or *odd* (``P = -1``). + +MPSKit, through the TensorKit tensor backend, can bake this symmetry directly into the tensors of the MPS. +Doing so buys you two things. +First, the tensors become **block-sparse**: at the same total bond dimension the computer multiplies smaller dense blocks, which is faster. +Second, every state you compute carries an explicit **sector label**, so "the lowest odd-parity excitation" becomes something you can ask for directly. +This tutorial demonstrates both, by redoing the finite-chain TFIM calculation once without and once with the symmetry. + +## Loading the packages + +Every code block on this page shares one Julia session, so we load the packages once. +`Z2Irrep` and `Z2Space`, the symmetry-aware building blocks used below, come from TensorKit. + +```@example using-symmetries +using MPSKit, MPSKitModels, TensorKit +``` + +## 1. Recap: the ground state without symmetry + +We start from the workflow of the first tutorial: a chain of `L = 16` sites, a random `FiniteMPS`, and a DMRG ground-state search. +Two small changes from before: we set the field to `g = 2.0`, and we use a total bond dimension of 16. + + +Why `g = 2.0`? +This puts us deep in the paramagnetic phase, where the ground state respects the spin-flip symmetry. +That matters for what comes next: an MPS built from symmetric tensors lives in exactly one parity sector and *cannot* spontaneously break the symmetry, so a fair comparison needs a point where the true ground state is symmetric to begin with. + +```@example using-symmetries +L = 16 +H = transverse_field_ising(FiniteChain(L); g = 2.0) +ψ₀ = FiniteMPS(L, ℂ^2, ℂ^16) +ψ, envs, ϵ = find_groundstate(ψ₀, H, DMRG(; verbosity = 0)) +E = expectation_value(ψ, H) +``` + +This is our reference number: the ground-state energy computed with plain, symmetry-oblivious tensors. + +## 2. The same model, with the symmetry made explicit + +To exploit the symmetry we change two lines: the Hamiltonian and the initial state. + +For the Hamiltonian, we pass the symmetry as an extra first argument. +`transverse_field_ising(Z2Irrep, ...)` builds the *same* Hamiltonian as before, but out of tensors that manifestly commute with the spin flip: + +```@example using-symmetries +H_Z2 = transverse_field_ising(Z2Irrep, FiniteChain(L); g = 2.0) +``` + +For the state, the plain spaces `ℂ^2` and `ℂ^16` are replaced by *graded* spaces that keep track of parity: + +```@example using-symmetries +ψ₀_Z2 = FiniteMPS(L, Z2Space(0 => 1, 1 => 1), Z2Space(0 => 8, 1 => 8)) +``` + +The syntax reads as a list of `sector => dimension` pairs, where sector `0` is the even (``P = +1``) irrep of ``\mathbb{Z}_2`` and sector `1` is the odd (``P = -1``) one: + +- The physical space `Z2Space(0 => 1, 1 => 1)` is the familiar two-dimensional spin-1/2 site, now split into its symmetry content: one even state and one odd state. + +- The virtual space `Z2Space(0 => 8, 1 => 8)` says the bond carries 8 states of even parity and 8 of odd parity — 16 in total, matching the `ℂ^16` of the plain run, so the two calculations have exactly the same variational power. + +From here the workflow is unchanged: + +```@example using-symmetries +ψ_Z2, envs_Z2, ϵ_Z2 = find_groundstate(ψ₀_Z2, H_Z2, DMRG(; verbosity = 0)) +E_Z2 = expectation_value(ψ_Z2, H_Z2) +``` + +Both runs found the same ground state, and the two energies agree to numerical precision: + +```@example using-symmetries +E, E_Z2 +``` + +!!! note "Same physics, different bookkeeping" + Nothing about the model changed — only the way its tensors are stored. + The symmetric calculation restricts the search to states of definite (here: even) parity, and stores only the tensor blocks the symmetry allows to be nonzero. + +## 3. The payoff, part 1: block-sparse tensors + +Where did the symmetry go? +Into the *structure* of the state. +Ask for the virtual space at the central bond and you no longer get an anonymous `ℂ^16`, but a space that knows its sector decomposition: + +```@example using-symmetries +V = left_virtualspace(ψ_Z2, L ÷ 2) +``` + +Its total dimension is still 16: + +```@example using-symmetries +dim(V) +``` + +The same sector labels show up in every quantity derived from the state. +The entanglement spectrum at the central cut, for instance, now comes back resolved by sector — compare [Entanglement entropy and spectrum](@ref howto_entanglement), where the same call on an unsymmetric state produced a single `Trivial()` block: + +```@example using-symmetries +spectrum = entanglement_spectrum(ψ_Z2, L ÷ 2) +collect(keys(spectrum)) +``` + +Iterating `pairs` gives each sector together with its singular values: + +```@example using-symmetries +collect(pairs(spectrum)) +``` + + +This block structure is where the speedup comes from: instead of multiplying one dense 16-dimensional bond index, the computer multiplies two independent blocks of roughly half that size, and the forbidden matrix elements between the sectors are never stored or touched at all. +At bond dimension 16 the difference is negligible, but the saving grows with the bond dimension and with the size of the symmetry group. + +## 4. The payoff, part 2: sectors label the physics + +The sector labels are not just an implementation detail — they classify the eigenstates of ``H``, and MPSKit lets you target a sector directly. + + +In the paramagnetic phase the lowest excitation of the TFIM is, roughly speaking, a single flipped spin. +Flipping one spin changes the parity of the state, so this excitation lives in the *odd* sector — a different sector than the (even) ground state. + +The [`excitations`](@ref) function computes excited states on top of a converged ground state; on a finite chain it takes the Hamiltonian, an algorithm, the ground state, and its environments, and returns energies measured *above* the ground state. +By default it searches the trivial (even) sector: + +```@example using-symmetries +Es_even, ϕs_even = excitations(H_Z2, QuasiparticleAnsatz(), ψ_Z2, envs_Z2; num = 1) +Es_even[1] +``` + +The `sector` keyword redirects the search to the odd sector: + +```@example using-symmetries +Es_odd, ϕs_odd = excitations( + H_Z2, QuasiparticleAnsatz(), ψ_Z2, envs_Z2; + num = 1, sector = Z2Irrep(1) +) +Es_odd[1] +``` + +The odd-sector excitation is indeed the lower one: + +```@example using-symmetries +Es_odd[1] < Es_even[1] +``` + +Without the symmetry built into the tensors, this question could not even be posed: the plain calculation of Section 1 has no notion of parity to select on. +More ways to use `excitations` — dispersion relations, other algorithms, infinite chains — are collected in [Excited states](@ref howto_excitations). + +## Where to go next + +You have run the flagship TFIM calculation with its ``\mathbb{Z}_2`` symmetry made explicit: the same physics at the same total bond dimension, but with block-sparse tensors and sector labels on everything the calculation produces. + +The same syntax scales up to larger symmetry groups, where the payoff grows. +For a U(1) symmetry (particle number, magnetization) the graded spaces list integer or half-integer charges instead of parities — worked constructions are in [Constructing states](@ref howto_states), Section 9. + +For non-abelian symmetries such as SU(2) the gains are more dramatic still, because each symmetric block then represents an entire multiplet of states; the spin-1 Haldane chain and XXZ Heisenberg pages in the examples gallery show this in action. + +To continue the tutorial track, [Quasiparticle excitations](@ref tutorial_excitations) develops the excitation calculation of Section 4 into a full dispersion relation; the recipe collection for excited states is [Excited states](@ref howto_excitations), and the one for building symmetric states is [Constructing states](@ref howto_states). + + From de04a1b8a64970e1fed9242c05b7a15ed0d3968c Mon Sep 17 00:00:00 2001 From: lkdvos Date: Mon, 6 Jul 2026 13:36:34 -0400 Subject: [PATCH 51/76] docs(howto): sync recipe index with regrouped states sections content-wave1 folded the five FiniteMPS construction recipes into one section; mirror that in the index listing. Co-Authored-By: Claude Fable 5 --- docs/src/howto/index.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/docs/src/howto/index.md b/docs/src/howto/index.md index bc821b6ec..b7e17e2b0 100644 --- a/docs/src/howto/index.md +++ b/docs/src/howto/index.md @@ -7,11 +7,7 @@ Each recipe below stands on its own, so feel free to jump straight to the one yo ## States and operators **[Constructing states](@ref howto_states)** — building `FiniteMPS`, `InfiniteMPS`, `WindowMPS`, and `MultilineMPS` objects. -- A finite MPS from length, physical space, and maximum bond dimension — the default random-state constructor. -- Choosing the initializer and element type — `rand`/`randn` and real vs. complex tensors. -- Per-site physical and virtual spaces — heterogeneous lattices via vectors of spaces. -- A product state (trivial virtual space) — an unentangled bond-dimension-1 state. -- From your own site tensors — wrap existing `TensorMap`s into a canonical-form MPS. +- A finite MPS — random states, initializers and element types, per-site spaces, product states, and wrapping your own site tensors. - An infinite MPS — single- and multi-site unit cells, from spaces or from tensors. - A window MPS — a mutable finite region embedded in infinite environments. - A multiline MPS — stacking `InfiniteMPS` rows for boundary-MPS methods. From c8cfb73cd07cfbd2339a51a469ef354a8a28629d Mon Sep 17 00:00:00 2001 From: lkdvos Date: Tue, 7 Jul 2026 16:18:31 -0400 Subject: [PATCH 52/76] docs(home): revamp landing page for at-a-glance selling points - lead the hero tagline and feature cards with the finite/infinite and symmetry differentiators; drop emoji icons; add a performance card - rebuild the example as build -> optimize -> measure sections, using a from-scratch FiniteMPOHamiltonian and an entanglement-entropy plot - add a "Beyond this example" section hinting at infinite systems, symmetries, and fermions, and a "Citing MPSKit" section - lead the where-next and beyond bullets with their links; tighten the intro; drop TensorOperations from install (@tensor is re-exported) Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/src/index.md | 129 +++++++++++++++++++++++++++++++++------------- 1 file changed, 94 insertions(+), 35 deletions(-) diff --git a/docs/src/index.md b/docs/src/index.md index ee5125b18..98f3e4cbc 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -6,7 +6,7 @@ layout: home hero: name: MPSKit.jl text: Matrix product states in Julia - tagline: Efficient and versatile tools for working with matrix product states + tagline: Finite and infinite systems through one interface, with abelian, non-abelian, fermionic, and anyonic symmetries built in. image: src: /logo.svg alt: MPSKit.jl @@ -22,24 +22,20 @@ hero: link: https://github.com/QuantumKitHub/MPSKit.jl features: - - icon: 🔗 - title: States - details: Construct and manipulate finite and infinite matrix product states (MPS). - - icon: 📏 - title: Observables - details: Measure expectation values, correlations, and other observables. - - icon: 🎯 - title: Optimization - details: Ground states, time evolution, and excitations via DMRG, VUMPS, and more. - - icon: ⚛️ - title: Symmetries - details: Abelian, non-Abelian, fermionic, and anyonic symmetries out of the box. + - title: Finite & infinite, one interface + details: Run the same calculation on a finite chain or directly in the thermodynamic limit. FiniteMPS and InfiniteMPS share an API, so switching between them is a one-line change. + - title: Every symmetry + details: Abelian, non-Abelian, fermionic, and anyonic symmetries out of the box via the TensorKit backend — smaller bond dimensions and exact quantum numbers. + - title: A complete algorithm suite + details: Ground states with DMRG, VUMPS, and IDMRG; real- and imaginary-time evolution with TDVP; and momentum-resolved excitations via the quasiparticle ansatz. + # REVIEW: make the "faster than ITensors" comparison explicit here once the benchmark results are published. + - title: Fast by design + details: Type-stable code paths and deliberate allocation strategies keep calculations quick out of the box, and non-Abelian symmetries such as SU(2) shrink the tensors you store and contract. --- ``` -MPSKit.jl is a Julia library for simulating one-dimensional quantum many-body systems with matrix product states and operators. -It provides both finite and infinite MPS, a range of ground-state, time-evolution, and excitation algorithms, and support for arbitrary symmetries through the [TensorKit.jl](https://github.com/Jutho/TensorKit.jl) tensor backend. -It is aimed at researchers and students who want to run tensor-network calculations without reimplementing the underlying machinery. +MPSKit.jl simulates one-dimensional quantum many-body systems with matrix product states and operators, at finite size or directly in the thermodynamic limit. +Built on the [TensorKit.jl](https://github.com/Jutho/TensorKit.jl) tensor backend, it is aimed at researchers and students who want tensor-network calculations without reimplementing the underlying machinery. ## Installation @@ -47,14 +43,13 @@ MPSKit.jl is a part of the general registry. Together with the packages used throughout this documentation, it can be installed via the package manager as: ``` -pkg> add MPSKit TensorKit TensorOperations MPSKitModels TensorKitTensors Plots +pkg> add MPSKit TensorKit MPSKitModels TensorKitTensors Plots ``` - `MPSKit` provides the matrix product state and operator types, together with the ground-state, time-evolution, and bond-dimension algorithms. - `TensorKit` supplies the tensor backend (`TensorMap`s and vector spaces) that MPSKit is - built on; installing it alongside MPSKit also gives access to truncation-scheme - constructors such as `truncrank`, which TensorKit re-exports from MatrixAlgebraKit. -- `TensorOperations` provides the `@tensor` macro for contracting tensors by hand. + built on; it also re-exports the `@tensor` macro for contracting tensors by hand, along + with truncation-scheme constructors such as `truncrank` (from MatrixAlgebraKit). - `MPSKitModels` collects pre-defined Hamiltonians and local operators for common physical models. - `TensorKitTensors` provides ready-made local operators, such as the Pauli operators used throughout the documentation. @@ -62,33 +57,80 @@ pkg> add MPSKit TensorKit TensorOperations MPSKitModels TensorKitTensors Plots For a step-by-step walkthrough that sets up a dedicated environment and verifies the installation, see [Installation](@ref tutorial_installation). -## A 30-second example +## A first calculation -Finding the ground state of the transverse-field Ising chain takes a handful of lines. +Almost every MPSKit calculation follows the same three steps: build a Hamiltonian, optimize a state, and read off observables. +The transverse-field Ising chain (TFIM) makes each step concrete in a few lines. + +### 1. Build a Hamiltonian + +MPO Hamiltonians are assembled directly from local operators, so an arbitrary model — not just the built-in ones — takes only a couple of lines. +Here the single-site Pauli operators come from TensorKitTensors, and the TFIM is a nearest-neighbour `σᶻσᶻ` coupling plus a transverse `σˣ` field: + +```@example index +using MPSKit, TensorKit +using TensorKitTensors.SpinOperators: σˣ, σᶻ + +L = 16 +g = 0.5 +lattice = fill(ℂ^2, L) +H = FiniteMPOHamiltonian(lattice, (i, i + 1) => -(σᶻ() ⊗ σᶻ()) for i in 1:(L - 1)) + + FiniteMPOHamiltonian(lattice, (i,) => -g * σˣ() for i in 1:L) +``` + +See [Building Hamiltonians](@ref howto_hamiltonians) for infinite lattices, longer-range terms, and boundary conditions. + +### 2. Optimize a state + +Start from an initial [`FiniteMPS`](@ref) of bond dimension 16 and pass it, together with the Hamiltonian, to [`find_groundstate`](@ref). +The algorithm — here [`DMRG`](@ref) — is an ordinary argument, and its keywords (tolerance, iteration count, verbosity) tune the optimization: + +```@example index +ψ₀ = FiniteMPS(L, ℂ^2, ℂ^16) +ψ, envs, ϵ = find_groundstate(ψ₀, H, DMRG(; tol = 1e-10, verbosity = 0)) +ϵ # final convergence error +``` + +Choosing a different optimizer such as [`VUMPS`](@ref), or raising the bond dimension, is a one-line change; see [Ground-state algorithms](@ref howto_groundstate_algorithms). + +### 3. Read off observables + +Expectation values are a single call. +The ground-state energy is just the Hamiltonian evaluated on the state: ```@example index -using MPSKit, MPSKitModels, TensorKit -H = transverse_field_ising(FiniteChain(16); g = 0.5) -ψ₀ = FiniteMPS(16, ℂ^2, ℂ^4) -ψ, envs, ϵ = find_groundstate(ψ₀, H, DMRG(; verbosity = 0)) E = expectation_value(ψ, H) ``` -For a guided version of this calculation that explains each step and measures more observables, see [Your first ground state](@ref tutorial_first_groundstate). +Local operators, correlators, and entanglement measures work the same way. +For instance, the von Neumann [`entropy`](@ref) across each bond traces out the entanglement profile of the chain: -## Where next +```@example index +using Plots +S = [real(entropy(ψ, i)) for i in 1:(L - 1)] +plot( + 1:(L - 1), S; xlabel = "cut position", ylabel = "entanglement entropy", + marker = :circle, legend = false, title = "Entanglement across the chain" +) +``` + +See [Computing observables](@ref howto_observables) and [Entanglement entropy and spectrum](@ref howto_entanglement) for the full set, and [Your first ground state](@ref tutorial_first_groundstate) for a guided walkthrough of this calculation. -**Tutorials** walk you through complete calculations from scratch. -Start with [Installation](@ref tutorial_installation), then run [Your first ground state](@ref tutorial_first_groundstate), and continue to [The thermodynamic limit](@ref tutorial_thermodynamic_limit) to work directly at infinite system size. +## Beyond this example -**How-to guides** are focused task recipes for when you already know what you want to do. -See [Constructing states](@ref howto_states), [Building Hamiltonians](@ref howto_hamiltonians), and [Computing observables](@ref howto_observables), among others. +The same three steps carry over to harder problems, usually by changing only the vector spaces or the state type: -**The manual** explains the concepts behind the library — the [States](@ref um_states), [Operators](@ref um_operators), and [Algorithms](@ref um_algorithms) that make up MPSKit. +- [**The thermodynamic limit**](@ref tutorial_thermodynamic_limit) works at infinite system size: replace `FiniteMPS` with an [`InfiniteMPS`](@ref) and `DMRG` with [`VUMPS`](@ref), and the rest of the code is unchanged. +- [**Using symmetries**](@ref tutorial_using_symmetries) imposes abelian or non-abelian symmetries by swapping the plain `ℂ^2` spaces for symmetric ones (for example an `SU2Space`), which also shrinks the bond dimension; see also the [Haldane gap](examples/quantum1d/2.haldane/index.md) example. +- [**The Hubbard model**](examples/quantum1d/6.hubbard/index.md) treats fermions with the same machinery, through TensorKit's graded vector spaces. -**The examples** gallery collects longer, fully worked scripts covering symmetries, infinite systems, and less common algorithms; browse it at [Examples](@ref). +## Where next -**The library** is the API reference; the curated, stable entry point is the [Public API](@ref public_api). +- [**Installation**](@ref tutorial_installation) and [**Your first ground state**](@ref tutorial_first_groundstate) open the tutorial track, walking through complete calculations from scratch. +- [**How-to guides**](@ref howto_index) are focused recipes for a known task, such as [constructing states](@ref howto_states), [building Hamiltonians](@ref howto_hamiltonians), and [computing observables](@ref howto_observables). +- [**The manual**](man/intro.md) explains the concepts behind the library, including [States](@ref um_states), [Operators](@ref um_operators), and [Algorithms](@ref um_algorithms). +- [**The examples gallery**](examples/index.md) collects longer, fully worked case studies across symmetries, infinite systems, and less common algorithms. +- [**The public API**](@ref public_api) is the curated, stable entry point to the full library reference. ## Ecosystem @@ -100,3 +142,20 @@ All of these are part of the [QuantumKitHub](https://github.com/QuantumKitHub) o Questions and general discussion are welcome on [GitHub Discussions](https://github.com/QuantumKitHub/MPSKit.jl/discussions); bug reports belong on the [issue tracker](https://github.com/QuantumKitHub/MPSKit.jl/issues). If you would like to contribute, see [CONTRIBUTING.md](https://github.com/QuantumKitHub/MPSKit.jl/blob/main/CONTRIBUTING.md) on GitHub. + +## Citing MPSKit + +If MPSKit.jl is useful for your research, please consider citing it — a citation is the most direct way to support the project and helps others find it. +The package is archived on Zenodo under the DOI [10.5281/zenodo.10654900](https://doi.org/10.5281/zenodo.10654900). +The [`CITATION.cff`](https://github.com/QuantumKitHub/MPSKit.jl/blob/main/CITATION.cff) file in the repository always holds the up-to-date metadata, or you can use the BibTeX entry below: + +```bibtex +@software{mpskitjl, + author = {Devos, Lukas and Van Damme, Maarten and Haegeman, Jutho}, + title = {{MPSKit.jl}}, + version = {v0.13.13}, + doi = {10.5281/zenodo.10654900}, + url = {https://github.com/QuantumKitHub/MPSKit.jl}, + year = {2026} +} +``` From fdb3464a206048f52c117b93dc6af139ceac50a1 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Wed, 8 Jul 2026 13:29:51 -0400 Subject: [PATCH 53/76] docs(home): add feature-card icons and an MPS diagram - author four green SVG line icons (finite/infinite, symmetry, algorithm suite, performance) and wire them into the hero features frontmatter as icon.src; VitePress renders them in its default soft icon box - add an MPS tensor-network diagram (assets/mps.svg) after the "A first calculation" intro, with colours that work in both themes Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/src/assets/icons/algorithms.svg | 9 ++++++++ docs/src/assets/icons/fast.svg | 4 ++++ docs/src/assets/icons/finite-infinite.svg | 18 ++++++++++++++++ docs/src/assets/icons/symmetry.svg | 10 +++++++++ docs/src/assets/mps.svg | 22 +++++++++++++++++++ docs/src/index.md | 26 +++++++++++++++++++---- 6 files changed, 85 insertions(+), 4 deletions(-) create mode 100644 docs/src/assets/icons/algorithms.svg create mode 100644 docs/src/assets/icons/fast.svg create mode 100644 docs/src/assets/icons/finite-infinite.svg create mode 100644 docs/src/assets/icons/symmetry.svg create mode 100644 docs/src/assets/mps.svg diff --git a/docs/src/assets/icons/algorithms.svg b/docs/src/assets/icons/algorithms.svg new file mode 100644 index 000000000..d7b749faf --- /dev/null +++ b/docs/src/assets/icons/algorithms.svg @@ -0,0 +1,9 @@ + + + + + + diff --git a/docs/src/assets/icons/fast.svg b/docs/src/assets/icons/fast.svg new file mode 100644 index 000000000..ac12db491 --- /dev/null +++ b/docs/src/assets/icons/fast.svg @@ -0,0 +1,4 @@ + + + diff --git a/docs/src/assets/icons/finite-infinite.svg b/docs/src/assets/icons/finite-infinite.svg new file mode 100644 index 000000000..ba8c7c887 --- /dev/null +++ b/docs/src/assets/icons/finite-infinite.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/docs/src/assets/icons/symmetry.svg b/docs/src/assets/icons/symmetry.svg new file mode 100644 index 000000000..9d5ee9341 --- /dev/null +++ b/docs/src/assets/icons/symmetry.svg @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/docs/src/assets/mps.svg b/docs/src/assets/mps.svg new file mode 100644 index 000000000..25ee1cb68 --- /dev/null +++ b/docs/src/assets/mps.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/src/index.md b/docs/src/index.md index 98f3e4cbc..c7bea3209 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -22,14 +22,26 @@ hero: link: https://github.com/QuantumKitHub/MPSKit.jl features: - - title: Finite & infinite, one interface + - icon: + src: /assets/icons/finite-infinite.svg + alt: A finite chain above an infinite one + title: Finite & infinite, one interface details: Run the same calculation on a finite chain or directly in the thermodynamic limit. FiniteMPS and InfiniteMPS share an API, so switching between them is a one-line change. - - title: Every symmetry + - icon: + src: /assets/icons/symmetry.svg + alt: A symmetric hexagon + title: Every symmetry details: Abelian, non-Abelian, fermionic, and anyonic symmetries out of the box via the TensorKit backend — smaller bond dimensions and exact quantum numbers. - - title: A complete algorithm suite + - icon: + src: /assets/icons/algorithms.svg + alt: An energy minimum + title: A complete algorithm suite details: Ground states with DMRG, VUMPS, and IDMRG; real- and imaginary-time evolution with TDVP; and momentum-resolved excitations via the quasiparticle ansatz. # REVIEW: make the "faster than ITensors" comparison explicit here once the benchmark results are published. - - title: Fast by design + - icon: + src: /assets/icons/fast.svg + alt: A lightning bolt + title: Fast by design details: Type-stable code paths and deliberate allocation strategies keep calculations quick out of the box, and non-Abelian symmetries such as SU(2) shrink the tensors you store and contract. --- ``` @@ -62,6 +74,12 @@ For a step-by-step walkthrough that sets up a dedicated environment and verifies Almost every MPSKit calculation follows the same three steps: build a Hamiltonian, optimize a state, and read off observables. The transverse-field Ising chain (TFIM) makes each step concrete in a few lines. +```@raw html +A matrix product state: a chain of tensors joined by virtual bonds, each with a physical leg +``` + +A matrix product state is a chain of tensors: the horizontal bonds carry the virtual indices, and the leg hanging off each site is its physical index. + ### 1. Build a Hamiltonian MPO Hamiltonians are assembled directly from local operators, so an arbitrary model — not just the built-in ones — takes only a couple of lines. From b0b6447092a0a05acb0092544c8785479b41fa51 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Wed, 8 Jul 2026 16:28:49 -0400 Subject: [PATCH 54/76] docs(lib): document find_groundstate + add jldoctests to first-touch entry points Reference-depth pass (IMPROVEMENT_PLAN W4). find_groundstate now documents its keyword defaults, the previously undocumented `trscheme` keyword, and the full automatic algorithm-selection heuristic. Adds runnable jldoctest examples to the first-touch entry points that lacked them: FiniteMPS, InfiniteMPS, FiniteMPOHamiltonian/InfiniteMPOHamiltonian, changebonds, and timestep. Every golden value is a real run; the whole doctest(MPSKit) suite passes. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/algorithms/changebonds/changebonds.jl | 20 ++++++++ .../groundstate/find_groundstate.jl | 49 ++++++++++++++++--- src/algorithms/timestep/time_evolve.jl | 21 ++++++++ src/operators/mpohamiltonian.jl | 19 +++++-- src/states/finitemps.jl | 15 ++++++ src/states/infinitemps.jl | 18 +++++++ 6 files changed, 132 insertions(+), 10 deletions(-) diff --git a/src/algorithms/changebonds/changebonds.jl b/src/algorithms/changebonds/changebonds.jl index 29152111b..c36f9c271 100644 --- a/src/algorithms/changebonds/changebonds.jl +++ b/src/algorithms/changebonds/changebonds.jl @@ -8,6 +8,26 @@ changedbonds! can modify both the provided state and environments, depending on For FiniteMPS, changebonds also modifies the environments. See also: [`SvdCut`](@ref), [`RandExpand`](@ref), [`VUMPSSvdCut`](@ref), [`OptimalExpand`](@ref) + +# Examples +Growing the bond dimension of a product state with [`OptimalExpand`](@ref), which enriches +each bond with directions orthogonal to the current state (using the environments of `H`): + +```jldoctest +julia> X = TensorMap(Float64[0 1; 1 0], ℂ^2, ℂ^2); + +julia> ψ = FiniteMPS(ones(Float64, (ℂ^2)^4)); + +julia> H = FiniteMPOHamiltonian(fill(ℂ^2, 4), ((i, i + 1) => X ⊗ X for i in 1:3)); + +julia> dim(left_virtualspace(ψ, 3)) +1 + +julia> ψ′, envs = changebonds(ψ, H, OptimalExpand(; trscheme = truncrank(4))); + +julia> dim(left_virtualspace(ψ′, 3)) +2 +``` """ changebonds, changebonds! function changebonds end function changebonds! end diff --git a/src/algorithms/groundstate/find_groundstate.jl b/src/algorithms/groundstate/find_groundstate.jl index cfd44352e..9d5b203e5 100644 --- a/src/algorithms/groundstate/find_groundstate.jl +++ b/src/algorithms/groundstate/find_groundstate.jl @@ -1,9 +1,10 @@ """ find_groundstate(ψ₀, H, [environments]; kwargs...) -> (ψ, environments, ϵ) - find_groundstate(ψ₀, H, algorithm, environments) -> (ψ, environments, ϵ) + find_groundstate(ψ₀, H, algorithm, [environments]) -> (ψ, environments, ϵ) -Compute the ground state for Hamiltonian `H` with initial guess `ψ`. If not specified, an -optimization algorithm will be attempted based on the supplied keywords. +Compute the ground state for Hamiltonian `H` with initial guess `ψ₀`. If no `algorithm` is +specified, one is selected automatically from the type of `ψ₀` and the supplied keywords +(see the automatic-selection notes below). # Arguments - `ψ₀::AbstractMPS`: initial guess @@ -12,14 +13,50 @@ optimization algorithm will be attempted based on the supplied keywords. - `algorithm`: optimization algorithm # Keyword Arguments -- `tol::Float64`: tolerance for convergence criterium -- `maxiter::Int`: maximum amount of iterations -- `verbosity::Int`: display progress information +- `tol::Float64=$(Defaults.tol)`: tolerance for the convergence criterion +- `maxiter::Int=$(Defaults.maxiter)`: maximum number of iterations +- `verbosity::Int=$(Defaults.verbosity)`: display progress information +- `trscheme=nothing`: if supplied, a truncation scheme that enables bond-dimension growth + through a two-site algorithm (see below) + +# Automatic algorithm selection +When no `algorithm` is passed, the choice depends on the type of `ψ₀`: +- `InfiniteMPS`: [`VUMPS`](@ref) (with its tolerance floored at `1e-4`), refined by + [`GradientGrassmann`](@ref) when `tol < 1e-4`. If `trscheme` is given, an [`IDMRG2`](@ref) + stage is prepended to grow the bond dimension. +- `AbstractFiniteMPS`: [`DMRG`](@ref). If `trscheme` is given, a [`DMRG2`](@ref) stage is + prepended to grow the bond dimension. + +Because single-site [`DMRG`](@ref) preserves the bond dimension of `ψ₀`, passing a +`trscheme` (or an explicit two-site `algorithm`) is the usual way to converge from a +low-bond-dimension initial guess such as a product state. # Returns - `ψ::AbstractMPS`: converged ground state - `environments`: environments corresponding to the converged state - `ϵ::Float64`: final convergence error upon terminating the algorithm + +# Examples +Ground state of a 4-site transverse-field Ising chain, `H = -∑ XₖXₖ₊₁ - ∑ Zₖ`, starting +from a product state and letting `DMRG2` grow the bond dimension: + +```jldoctest +julia> X = TensorMap(Float64[0 1; 1 0], ℂ^2, ℂ^2); + +julia> Z = TensorMap(Float64[1 0; 0 -1], ℂ^2, ℂ^2); + +julia> L = 4; lattice = fill(ℂ^2, L); + +julia> H = FiniteMPOHamiltonian(lattice, ((i, i + 1) => -(X ⊗ X) for i in 1:(L - 1))) + + FiniteMPOHamiltonian(lattice, ((i,) => -Z for i in 1:L)); + +julia> ψ₀ = FiniteMPS(ones(Float64, (ℂ^2)^L)); + +julia> ψ, envs, ϵ = find_groundstate(ψ₀, H; verbosity = 0, trscheme = truncrank(16)); + +julia> round(real(expectation_value(ψ, H)); digits = 4) +-4.7588 +``` """ function find_groundstate( ψ::AbstractMPS, H, envs::AbstractMPSEnvironments = environments(ψ, H, ψ); diff --git a/src/algorithms/timestep/time_evolve.jl b/src/algorithms/timestep/time_evolve.jl index 5465d7f6b..319788689 100644 --- a/src/algorithms/timestep/time_evolve.jl +++ b/src/algorithms/timestep/time_evolve.jl @@ -79,6 +79,27 @@ solving the Schroedinger equation: ``i ∂ψ/∂t = H ψ``. - `ψ`: the time-stepped state - `envs`: the updated environment manager + +# Examples +Real-time evolution of the `|+···+⟩` product state under a transverse field `H = ∑ Zₖ`. +Each spin precesses independently, so `⟨Xₖ(t)⟩ = cos(2t)`; after a step `dt = 0.1` this is +`cos(0.2) ≈ 0.980067`. The initial state must be complex, since real-time evolution +multiplies by `-i`: + +```jldoctest +julia> X = TensorMap(ComplexF64[0 1; 1 0], ℂ^2, ℂ^2); + +julia> Z = TensorMap(ComplexF64[1 0; 0 -1], ℂ^2, ℂ^2); + +julia> ψ₀ = FiniteMPS(ones(ComplexF64, (ℂ^2)^4)); + +julia> H = FiniteMPOHamiltonian(fill(ℂ^2, 4), ((i,) => Z for i in 1:4)); + +julia> ψ, envs = timestep(ψ₀, H, 0.0, 0.1, TDVP()); + +julia> round(real(expectation_value(ψ, 2 => X)); digits = 6) +0.980067 +``` """ function timestep end, function timestep! end diff --git a/src/operators/mpohamiltonian.jl b/src/operators/mpohamiltonian.jl index 66b71b10f..e2eae8c6a 100644 --- a/src/operators/mpohamiltonian.jl +++ b/src/operators/mpohamiltonian.jl @@ -32,11 +32,22 @@ with a set of `inds => operator` pairs describing the local terms: - `D`: on-site terms # Examples -For example, constructing a nearest-neighbour Hamiltonian would look like this: +A nearest-neighbour term is a two-element index tuple `(i, i + 1) => O₁₂`; an on-site term +is a one-element tuple `(i,) => O`. For the finite variant the lattice lists every site; for +the infinite variant it is a single unit cell and indices wrap around it periodically. -```julia -lattice = fill(ℂ^2, 10) -H = FiniteMPOHamiltonian(lattice, (i, i+1) => O for i in 1:length(lattice)-1) +```jldoctest +julia> X = TensorMap(Float64[0 1; 1 0], ℂ^2, ℂ^2); + +julia> Hf = FiniteMPOHamiltonian(fill(ℂ^2, 3), ((i, i + 1) => X ⊗ X for i in 1:2)); + +julia> Hf isa FiniteMPOHamiltonian, length(Hf) +(true, 3) + +julia> Hi = InfiniteMPOHamiltonian(fill(ℂ^2, 1), (1, 2) => X ⊗ X, (1,) => X); + +julia> Hi isa InfiniteMPOHamiltonian, length(Hi) +(true, 1) ``` # See also diff --git a/src/states/finitemps.jl b/src/states/finitemps.jl index 9d87e874c..62db94a67 100644 --- a/src/states/finitemps.jl +++ b/src/states/finitemps.jl @@ -50,6 +50,21 @@ By convention, we have that: - `AL[i] * C[i]` = `AC[i]` = `C[i-1] * AR[i]` - `AL[i]' * AL[i] = 1` - `AR[i] * AR[i]' = 1` + +# Examples +Building a 3-site spin-1/2 MPS from a dense array and checking that its left-gauged tensors +are isometries (the state is kept in canonical form even though the raw data is not +normalized): + +```jldoctest +julia> ψ = FiniteMPS(ones(Float64, (ℂ^2)^3)); + +julia> length(ψ) +3 + +julia> ψ.AL[1]' * ψ.AL[1] ≈ id(left_virtualspace(ψ, 2)) +true +``` """ struct FiniteMPS{A <: GenericMPSTensor, B <: MPSBondTensor} <: AbstractFiniteMPS ALs::Vector{Union{Missing, A}} diff --git a/src/states/infinitemps.jl b/src/states/infinitemps.jl index 4c6051c5d..aead98a0d 100644 --- a/src/states/infinitemps.jl +++ b/src/states/infinitemps.jl @@ -37,6 +37,24 @@ By convention, we have that: - `AL[i] * C[i]` = `AC[i]` = `C[i-1] * AR[i]` - `AL[i]' * AL[i] = 1` - `AR[i] * AR[i]' = 1` + +# Examples +A one-site unit cell built from an explicit `(V_left ⊗ P ← V_right)` tensor. Here the bond +dimension is one, so this is the `|+⟩` product state, for which `⟨X⟩ = 1`: + +```jldoctest +julia> A = TensorMap(ones(Float64, 2, 1), ℂ^1 ⊗ ℂ^2, ℂ^1); + +julia> ψ = InfiniteMPS([A]); + +julia> length(ψ) +1 + +julia> X = TensorMap(Float64[0 1; 1 0], ℂ^2, ℂ^2); + +julia> round(real(expectation_value(ψ, 1 => X)); digits = 6) +1.0 +``` """ struct InfiniteMPS{A <: GenericMPSTensor, B <: MPSBondTensor} <: AbstractMPS AL::PeriodicVector{A} From 68801692da91487c28a6f9cbc248052ef1d2e3bf Mon Sep 17 00:00:00 2001 From: lkdvos Date: Wed, 8 Jul 2026 17:24:09 -0400 Subject: [PATCH 55/76] docs(concepts,howto): split man/parallelism into concept + how-to MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Begins retiring the man/ section (IMPROVEMENT_PLAN W4). Splits man/parallelism.md along the Diátaxis seam: - concepts/parallelism_model.md — the Julia/BLAS thread interaction, where MPSKit parallelizes (OhMyThreads over sites), sector-level parallelism, and why memory pressure arises. - howto/parallelism_gpu.md — recipes for BLAS threads, set_scheduler!, threadinfo diagnostics, OutOfMemory mitigation, and an experimental Adapt-based GPU note (marked with a warning admonition). Wires both into the nav and the how-to recipe index; unwires man/parallelism.md (kept on disk pending review). Physics/performance claims carry flags for maintainer sign-off. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/make.jl | 3 +- docs/src/concepts/parallelism_model.md | 80 ++++++++++++ docs/src/howto/index.md | 9 ++ docs/src/howto/parallelism_gpu.md | 161 +++++++++++++++++++++++++ 4 files changed, 252 insertions(+), 1 deletion(-) create mode 100644 docs/src/concepts/parallelism_model.md create mode 100644 docs/src/howto/parallelism_gpu.md diff --git a/docs/make.jl b/docs/make.jl index 17475edc9..f5a3d1043 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -64,7 +64,6 @@ makedocs(; "man/operators.md", "man/algorithms.md", # "man/environments.md", - "man/parallelism.md", ], "How-to" => [ "howto/index.md", @@ -76,9 +75,11 @@ makedocs(; "howto/observables.md", "howto/entanglement.md", "howto/excitations.md", + "howto/parallelism_gpu.md", ], "Concepts" => [ "concepts/algorithm_landscape.md", + "concepts/parallelism_model.md", ], "Examples" => [ "Overview" => "examples/index.md", diff --git a/docs/src/concepts/parallelism_model.md b/docs/src/concepts/parallelism_model.md new file mode 100644 index 000000000..f3cc51568 --- /dev/null +++ b/docs/src/concepts/parallelism_model.md @@ -0,0 +1,80 @@ +# [The parallelism model](@id concept_parallelism_model) + +Julia has excellent [parallelism infrastructure](https://julialang.org/blog/2019/07/multithreading/), +but there is a caveat that touches every algorithm in MPSKit: Julia's own threads do not +compose cleanly with the threads that BLAS uses internally for linear algebra. +Since `gemm` (general matrix-matrix multiplication) is a core routine throughout MPSKit, +this interaction has a real effect on performance. + +This page explains the model behind the settings, so that the recipes on +[Parallelism and GPU support](@ref howto_parallelism_gpu) are more than a list of magic +incantations. + +## Julia threads versus BLAS threads + +Much of the confusion here comes from the fact that BLAS threading behaviour is not +consistent between vendors, and that performance depends strongly on the hardware, the +specifics of the problem, and the availability of resources such as total memory and memory +bandwidth. +There is no one-size-fits-all setting, which is why the how-to page frames its advice as +starting points to be measured rather than guarantees. + +The two vendors most commonly used with Julia treat the BLAS thread count differently. +With OpenBLAS (the default), the configured number of BLAS threads is the **total** size of a +single thread pool that is shared by all Julia threads: 4 Julia threads and 4 BLAS threads +means all 4 Julia threads draw from the same pool of 4 BLAS threads. +Setting the BLAS thread count to `1` instead frees OpenBLAS to run its work on the Julia +threads themselves, so that MPSKit's Julia-level parallelism is the thing that scales. + + +With [MKL.jl](https://github.com/JuliaLinearAlgebra/MKL.jl), which often outperforms OpenBLAS, +the count is instead the number of threads spawned by **each** Julia thread: 4 Julia threads +with 4 BLAS threads each gives 16 BLAS threads in total. +Getting this wrong oversubscribes the physical cores — more software threads than hardware +can run — which degrades rather than improves performance. + + +## Where MPSKit parallelizes + +When Julia is started with more than one thread, MPSKit uses +[OhMyThreads.jl](https://juliafolds2.github.io/OhMyThreads.jl/stable/) to parallelize its +algorithms wherever possible. +In practice this happens where a unit cell (or a chain of sites) lets local updates run +independently: the work is distributed across the sites of the system, with the tensor at +each site updated in parallel. + +This is exactly why setting the BLAS thread count to `1` on OpenBLAS tends to help: it keeps +the Julia threads free to work through the sites, rather than contending with a shared BLAS +pool. + +The amount of speedup you can expect therefore tracks how much independent per-site work an +algorithm exposes. + + +## Parallelism over symmetry sectors + +There is a second, orthogonal layer of parallelism for tensors that carry an internal +symmetry. +Such tensors are block-diagonal over their symmetry sectors, and the work can be spread +across those blocks. +This is handled by [TensorKit](https://quantumkithub.github.io/TensorKit.jl/stable/) at the +level of the individual tensor operations, below MPSKit's site-level parallelism, so the two +layers are independent of one another. + + +## Why memory pressure arises + +The same task-based parallelism that speeds MPSKit up can also drive its memory usage high. +The algorithms spawn tasks in a nested fashion, and each of those tasks allocates and +deallocates a fair amount of memory in a tight loop. +This can produce enough garbage, quickly enough, that the garbage collector cannot keep up; +in the worst case memory is exhausted and an `OutOfMemory` error is thrown before the garbage +can be cleared. + + +The most memory-intensive step is reportedly the application of the `derivatives` — the +effective local operators built during the sweeps — which is why the practical mitigation is +to disable MPSKit's multithreading there. + +The concrete recipe for doing so is on +[Parallelism and GPU support](@ref howto_parallelism_gpu). diff --git a/docs/src/howto/index.md b/docs/src/howto/index.md index b7e17e2b0..909df5151 100644 --- a/docs/src/howto/index.md +++ b/docs/src/howto/index.md @@ -74,6 +74,15 @@ Each recipe below stands on its own, so feel free to jump straight to the one yo - Check excitation quality — `variance` on a quasiparticle state. - Domain-wall excitations — quasiparticles interpolating between two distinct ground states. +## Performance and hardware + +**[Parallelism and GPU support](@ref howto_parallelism_gpu)** — tuning how MPSKit uses the hardware. +- Setting BLAS threads — `BLAS.set_num_threads` and the OpenBLAS/MKL difference. +- Setting the MPSKit scheduler — `MPSKit.Defaults.set_scheduler!` with `:serial`/`:greedy`/`:dynamic`. +- Diagnosing the thread layout — ThreadPinning.jl `threadinfo`. +- Reducing memory usage — disabling multithreading to avoid `OutOfMemory`. +- GPU support — the experimental Adapt-based path for moving states onto a GPU. + ## Missing a recipe? If the task you're after isn't listed here, please open an issue at [QuantumKitHub/MPSKit.jl](https://github.com/QuantumKitHub/MPSKit.jl/issues) describing what you're trying to do. diff --git a/docs/src/howto/parallelism_gpu.md b/docs/src/howto/parallelism_gpu.md new file mode 100644 index 000000000..a13430a98 --- /dev/null +++ b/docs/src/howto/parallelism_gpu.md @@ -0,0 +1,161 @@ +# [Parallelism and GPU support](@id howto_parallelism_gpu) + +This page collects the practical knobs for controlling how MPSKit uses the hardware: +how to set BLAS threads, how to pick the MPSKit multithreading scheduler, how to inspect +the resulting thread layout, and what to do when a calculation runs out of memory. +It closes with a short, experimental note on moving states onto a GPU. + +For the reasoning behind these settings — why Julia threads and BLAS threads interact the +way they do, and where MPSKit actually parallelizes — see +[The parallelism model](@ref concept_parallelism_model). + +!!! note + Threading performance depends heavily on the hardware, the BLAS vendor, the size of + the problem, and the availability of memory and memory bandwidth. + There is no single setting that is optimal everywhere; the recipes below are sensible + starting points, and you should measure on your own machine. + +## Setting the number of BLAS threads + +Most of the heavy linear algebra in MPSKit ends up in BLAS routines (in particular `gemm`, +general matrix-matrix multiplication). +The number of BLAS threads is controlled through `LinearAlgebra.BLAS.set_num_threads`: + +```julia +using LinearAlgebra: BLAS +BLAS.set_num_threads(1) +``` + +With OpenBLAS (the default vendor), `set_num_threads` sets the **total** number of BLAS +threads held in a shared pool across all Julia threads. +When Julia is started with multiple threads, setting this to `1` lets MPSKit drive the +parallelism through its own (Julia-thread) machinery instead, which is often the best +option for OpenBLAS. + + +With [MKL.jl](https://github.com/JuliaLinearAlgebra/MKL.jl) the semantics differ: the BLAS +thread count applies **per Julia thread**, so 4 Julia threads with 4 BLAS threads each spawn +16 BLAS threads in total. +In that case you typically want to lower the BLAS thread count to avoid oversubscribing the +physical cores. + + +## Setting the MPSKit scheduler + +When Julia runs with multiple threads, MPSKit parallelizes parts of its algorithms through +[OhMyThreads.jl](https://juliafolds2.github.io/OhMyThreads.jl/stable/). +The behaviour is controlled by a global scheduler, set with `MPSKit.Defaults.set_scheduler!`: + +```julia +MPSKit.Defaults.set_scheduler!(:serial) # disable multithreading +MPSKit.Defaults.set_scheduler!(:greedy) # multithreading with greedy load-balancing +MPSKit.Defaults.set_scheduler!(:dynamic) # multithreading with dynamic load-balancing +``` + +`set_scheduler!` also accepts an `OhMyThreads.Scheduler` directly, or a symbol together with +keyword arguments that are forwarded to the corresponding OhMyThreads scheduler. +When left unset, the default is a serial scheduler if Julia was started with a single thread, +and a dynamic scheduler otherwise. +For the full list of schedulers and their keyword arguments, see the +[OhMyThreads.jl documentation](https://juliafolds2.github.io/OhMyThreads.jl/stable/refs/api/#Schedulers). + +## Diagnosing the thread layout + +Because the interaction between Julia threads and BLAS threads is easy to get wrong, it helps +to inspect the actual layout. +[ThreadPinning.jl](https://github.com/carstenbauer/ThreadPinning.jl) provides `threadinfo`, +which reports the Julia threads, their CPU mapping, and the BLAS backend and thread count: + +```julia-repl +julia> Threads.nthreads() +4 + +julia> using ThreadPinning; threadinfo(; blas = true, hints = true) + +System: 8 cores (2-way SMT), 1 sockets, 1 NUMA domains + +| 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 | + +# = Julia thread, # = HT, # = Julia thread on HT, | = Socket separator + +Julia threads: 4 +├ Occupied CPU-threads: 4 +└ Mapping (Thread => CPUID): 1 => 8, 2 => 5, 3 => 9, 4 => 2, + +BLAS: libopenblas64_.so +└ openblas_get_num_threads: 8 + +[ Info: jlthreads != 1 && blasthreads < cputhreads. You should either set BLAS.set_num_threads(1) (recommended!) or at least BLAS.set_num_threads(16). +[ Info: jlthreads < cputhreads. Perhaps increase number of Julia threads to 16? +``` + +Passing `hints = true` makes ThreadPinning emit the advisory messages shown above. +Loading a different BLAS backend changes the report; with MKL, for example, `threadinfo` +reports `libmkl_rt.so` and warns when the per-Julia-thread BLAS thread count exceeds the +available CPU threads per Julia thread: + +```julia-repl +julia> using MKL; threadinfo(; blas = true, hints = true) + +System: 8 cores (2-way SMT), 1 sockets, 1 NUMA domains + +| 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 | + +# = Julia thread, # = HT, # = Julia thread on HT, | = Socket separator + +Julia threads: 4 +├ Occupied CPU-threads: 4 +└ Mapping (Thread => CPUID): 1 => 11, 2 => 12, 3 => 1, 4 => 2, + +BLAS: libmkl_rt.so +├ mkl_get_num_threads: 8 +└ mkl_get_dynamic: true + +┌ Warning: blasthreads_per_jlthread > cputhreads_per_jlthread. You should decrease the number of MKL threads, i.e. BLAS.set_num_threads(4). +└ @ ThreadPinning ~/.julia/packages/ThreadPinning/qV2Cd/src/threadinfo.jl:256 +[ Info: jlthreads < cputhreads. Perhaps increase number of Julia threads to 16? +``` + +## Reducing memory usage + +MPSKit's multithreading spawns tasks in a nested fashion, each allocating and deallocating +memory in a tight loop. +This can put enough pressure on the garbage collector that memory usage climbs and, in the +worst case, an `OutOfMemory` error occurs before the garbage can be cleared. + + +If you hit this, the most effective remedy is usually to disable MPSKit's multithreading, +by setting the scheduler to serial: + +```julia +MPSKit.Defaults.set_scheduler!(:serial) +``` + +The `derivatives` (the effective local operators applied during the sweeps) are reported to +be the most memory-intensive part, so this is where switching off multithreading helps most. + + +For why this pressure arises, see +[Why memory pressure arises](@ref concept_parallelism_model). + +## GPU support + +!!! warning "Experimental" + GPU support in MPSKit is **experimental and minimal**. + There are no GPU-specific algorithms, kernels, or tuning options; the only surface is + an [Adapt.jl](https://github.com/JuliaGPU/Adapt.jl)-based mechanism for moving a state + or operator onto a different array type. + Treat this as preparatory infrastructure rather than a supported workflow. + +The package extension `MPSKitAdaptExt` defines `Adapt.adapt_structure` for `FiniteMPS`, +`InfiniteMPS`, `MPO`, and `MPOHamiltonian`. +This lets you convert the underlying tensors to a GPU array type with `Adapt.adapt`, after +which the algorithms dispatch through that array type. +A move onto a CUDA array would look like the following: + +```julia +using Adapt, CUDA +ψ_gpu = adapt(CuArray, ψ) +``` + + From 209b9c4fbaa76a0806cb104037ccc104d5e5a59f Mon Sep 17 00:00:00 2001 From: lkdvos Date: Wed, 8 Jul 2026 17:29:35 -0400 Subject: [PATCH 56/76] docs(concepts): add environments concept page, retire man/environments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces the (already build-disabled) man/environments.md with a Diátaxis concept page: what environment objects are (cached partial contractions), why algorithms take and return an optional environments argument, the finite ===-identity cache and its in-place-mutation pitfall, and how infinite environments differ (iterative fixed-point solves, no auto-recompute). Re-derives the current API against src/ — the legacy page carried stale calls (poison!(state,i), recalculate!(cache,state), cache.tol) that are dropped or reframed to the real internal signatures. Uncertain points (infinite-env precision control, exact invalidation route) carry flags. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/make.jl | 1 + docs/src/concepts/environments.md | 104 ++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 docs/src/concepts/environments.md diff --git a/docs/make.jl b/docs/make.jl index f5a3d1043..005ce644e 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -79,6 +79,7 @@ makedocs(; ], "Concepts" => [ "concepts/algorithm_landscape.md", + "concepts/environments.md", "concepts/parallelism_model.md", ], "Examples" => [ diff --git a/docs/src/concepts/environments.md b/docs/src/concepts/environments.md new file mode 100644 index 000000000..0969c6db9 --- /dev/null +++ b/docs/src/concepts/environments.md @@ -0,0 +1,104 @@ +# [Environments](@id concept_environments) + +Almost every MPS algorithm spends most of its time contracting the same tensor network over and over. +In DMRG, optimizing the tensor on one site requires the sum of all Hamiltonian contributions sitting to its left and to its right; in time evolution the same partial contractions reappear at every step. +Recomputing them from scratch each time would be wasteful, because moving attention from one site to a neighbour changes only a little of the network. +The *environment* objects are what let MPSKit avoid that waste. + +This page explains what environments are and why they exist, so that the optional `environments` argument that appears throughout the API stops looking like a mystery. +It is about understanding, not tuning: for the mechanics of a particular algorithm follow the links into the how-to pages. + +## What an environment is + +An environment is a partially contracted piece of a tensor network — the part that does not change when you shift your focus by one site. +Consider the network whose value an algorithm ultimately wants: a state `below` (the bra), an operator, and a state `above` (the ket), all contracted together. +Fixing attention on a single site splits that network into three parts: the tensor at the site itself, everything to its left, and everything to its right. +The left and right parts are exactly the *left environment* and *right environment* of that site. + +The key observation is that these two blocks are shared between neighbouring sites. +The left environment at site `i+1` is the left environment at site `i` with a single extra column contracted onto it. +So once you have paid to build the environment at one site, advancing to the next is cheap: you add one new contribution instead of recontracting the whole chain. +Caching the environments and reusing them across a sweep is what turns an algorithm that would be quadratic in the system size into a linear one. + +In MPSKit these cached blocks live in an environment object, constructed with the exported [`environments`](@ref) function. +The canonical form sandwiches an operator between two states, + +```julia +using MPSKit, MPSKitModels, TensorKit + +state = FiniteMPS(20, ℂ^2, ℂ^10) +H = transverse_field_ising(FiniteChain(20); g = 0.5) +envs = environments(state, H, state) +``` + +while the two-argument form `environments(below, above)` builds the operator-free *overlap* environments between two states. +The individual blocks are then queried with the exported [`leftenv`](@ref) and [`rightenv`](@ref) functions, + +```julia +GL = leftenv(envs, 10, state) # everything to the left of site 10 +GR = rightenv(envs, 10, state) # everything to the right of site 10 +``` + +each of which returns a tensor gauge-compatible with the state tensor at that site, ready to be contracted onto it. + +## Why you rarely build them yourself + +Most of the time you never touch an environment object at all. +The high-level entry points — [`find_groundstate`](@ref), [`timestep`](@ref), [`excitations`](@ref), and the rest — build whatever environments they need internally. +What they also do, uniformly, is accept an *optional* environments argument and return an updated environment object alongside their main result. + +That return value is the reason to care about environments even when you never construct one. +Handing the environments from one call into the next lets the algorithm reuse the cached blocks instead of rebuilding them from nothing. +For iterated procedures such as time evolution — where each step starts from a state only slightly different from the last — feeding the updated environments back in every step avoids repeating work that the previous step already did. + +The [Time evolution](@ref howto_time_evolution) how-to shows this threading pattern in a concrete recipe. + +## Finite environments and the `===` cache + +For a finite state the environment object manages its own validity automatically, and understanding how is worthwhile because it comes with one sharp edge. + +When it computes a left environment, the cache records *which* state tensors it contracted to get there — the gauged tensors of `state` up to that site. +On a later query it compares the tensors it would need now against the ones it used before, testing them with Julia's identity operator `===`. +If they are the same objects, the cached block is still valid and is returned immediately. +If some differ, the cache recomputes only the affected part of the network and updates its record. +This is what makes repeated queries during a sweep cheap: the first `leftenv` at a far site pays for the full contraction, and neighbouring queries reuse almost all of it. + +The sharp edge is that `===` tests object identity, not numerical equality. +If you mutate a state tensor *in place* — changing its data while keeping the same object — the cache still sees the same object under `===` and concludes, wrongly, that its stored environment is still valid. +It will then hand back a block computed from the old data. +Building a *new* tensor and assigning it into the state is fine, because that is a different object and the `===` check catches it; only in-place mutation defeats the mechanism. +Because algorithms that use the public API replace tensors rather than mutating them, this is rarely a problem in normal use, but it is the thing to suspect if a hand-written routine that mutates tensors starts returning stale results. + +!!! warning "In-place mutation is invisible to the cache" + The finite-environment cache detects changes by object identity (`===`), so mutating a + state tensor in place leaves the cache convinced its stored environment is still current. + The internal, non-exported helper `MPSKit.poison!(envs, i)` marks the dependencies at + site `i` as stale so the next query recomputes them; needing it is a sign that a tensor + was mutated in place rather than replaced. + + + +## Infinite environments + +Infinite environments serve the same role but are computed differently, and the difference matters for how you use them. + +A finite chain has genuine boundaries, so its environments can be built by contracting inward from the ends in a finite number of steps. +An infinite chain has no ends. +Its environments are instead the fixed points of the transfer operator — the object you get by contracting one repeating unit cell — and finding a fixed point means solving a linear or eigenvalue problem. +Those problems are solved *iteratively*, to a finite tolerance, rather than by an exact finite contraction. +Building an infinite environment is therefore a small numerical solve, and its result is only as accurate as the tolerance of that solve. + +The precision of that solve is a setting of the environment computation, controlled through the arguments passed to [`environments`](@ref) rather than being read or written on the environment object afterwards. + + +The second difference is that infinite environments are **not** recomputed automatically. +The finite cache re-validates itself against the current state on every query; the infinite one does not. +If the state changes, the stored fixed points no longer correspond to it, and there is no automatic re-solve. +Bringing an infinite environment up to date for a changed state is an explicit step, handled internally by the non-exported `MPSKit.recalculate!`. + +In practice the high-level algorithms perform this recomputation for you as part of their own iteration, which is again why threading the returned environments through successive calls is the efficient pattern. + +## Where to go next + +For the full signatures and docstrings of the environment functions, see [`environments`](@ref), [`leftenv`](@ref), and [`rightenv`](@ref) in the library reference. +For the algorithm-facing side — how ground-state and time-evolution routines consume and return environments — see [Ground-state algorithms](@ref howto_groundstate_algorithms) and [Time evolution](@ref howto_time_evolution). From 3f2b37d118bdc9dbee1eff8e0cb9264c5d125fba Mon Sep 17 00:00:00 2001 From: lkdvos Date: Wed, 8 Jul 2026 17:51:20 -0400 Subject: [PATCH 57/76] docs(concepts): add matrix product states concept page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Salvages the conceptual heart of man/states.md into a Diátaxis concept page on MPS gauge freedom and canonical forms: the C·C⁻¹ gauge insertion, the left/right isometry forms (AL/AR), the center bond tensor C and center-site AC = AL·C = C·AR, automatic ("automagic") gauge management, and the center-gauge overlap insight (dot(state,state) = dot(C,C) at any bond). The gauge-relation checks are exact identities for any valid gauged MPS, so they are written as jldoctest blocks returning `true` and verified by the full doctest suite (green). Construction recipes and type reference are left to howto/states.md and lib/states.md respectively; internal field-layout details are dropped. Two diagrams copied in with text descriptions; image leg convention and the finite-vs-infinite recompute wording carry REVIEW flags. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/make.jl | 1 + docs/src/concepts/finite_mps_definition.png | Bin 0 -> 2622 bytes docs/src/concepts/matrix_product_states.md | 132 ++++++++++++++++++++ docs/src/concepts/mps_gauge_freedom.png | Bin 0 -> 6206 bytes 4 files changed, 133 insertions(+) create mode 100644 docs/src/concepts/finite_mps_definition.png create mode 100644 docs/src/concepts/matrix_product_states.md create mode 100644 docs/src/concepts/mps_gauge_freedom.png diff --git a/docs/make.jl b/docs/make.jl index 005ce644e..fd3817edd 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -78,6 +78,7 @@ makedocs(; "howto/parallelism_gpu.md", ], "Concepts" => [ + "concepts/matrix_product_states.md", "concepts/algorithm_landscape.md", "concepts/environments.md", "concepts/parallelism_model.md", diff --git a/docs/src/concepts/finite_mps_definition.png b/docs/src/concepts/finite_mps_definition.png new file mode 100644 index 0000000000000000000000000000000000000000..9ad9776b4c33c3d067c73d4f844dbf42ccb3274f GIT binary patch literal 2622 zcmb_eX;2gC7VRV^ku9<)OIQU&Q4xg%Bw$dMkjSPigX{qW!V&~U1Oy4AjtB%09D#sF zBnm+g6a+>Qn-Rr@W!QI!IvQdSQ1*bs>%4k@-miI8^Qx=vJ?GXveY?KuKDVzPbF!0> z#7Y7HAVVSBxBvj01!1?%C@5;jfqET}Wu{oF`=>>!-39a(N9mMg-;sSC^B55b#weo|~#K*9LEn}E< zU5GVHT5MC-2IYAu-ns50ujU-7&ar90o>V5dG^G{PC=-8>V8iGKpQhSfJd?>aCx9vM zv9DVEX)PfLVX1YU;3)4{Y#PQJRjjIhN2UwzVRL134eEq4MAphfk~`6Qq${)+Q5BwS zdu7cPX4e4Gt*PhdTB~ z;&xDSuU}@~)1~A-s_DM2OL0;BA4Rt2%+I>ifElgCi9`mndpquq0Mr+!La=yB7JJ-~ zOWIwQ0MnZfr}0YT(Cmis76-)wqTkYv_{DuH)Nlk~d>%n9VHJ%V0#LPQsVrhM7#nxXfA} z!xT7${s|}>BqD}}hfjnD7}a3n_biGWDt|Pb|JjK9;EEf&0SL|gVjO>gF8P-8q!4_{ zFok7Mls>kg>G`rRiySMugp6P??63z-8_%+?=(;RjoqaaFL3TwpT7zqHCW5WG*}m^~ z(Zb2+SzBjtyjI1OC{%PD`V78EDSn#l3*KjBkWF79rIQaT<1&Us3n&fqo=q~d~du##?`8>1u)2t zh4PWuyZxq)jzPBX8jOVok8`Bv9D2-f zF3BNs-faEUwk+JWh0{Tb0yV6lV+eZWUInP@5JxWsQ)(&Qv9q4|K0@~5LQW@JB{NAz zpzVv;61Uq;YE3nzKql!ru48!%Zx>gJh+1##eZ%r0;U~j8QN-h;vq&Q88Lxi>56c3Mnkq^A7ygo%SS}Lq#n)u5A|M7OgmkKYoOy5Syk|)@~ z!Sk7m38;7q`3Z`7>h&$4*=IB{bs4CJ-7xxIgge^_2=J?moSm=jDM|vOkB%!U8^|B5 zx8*DvRcql()0g*0+tQzJS<#v^;voaB_R)4OiYkGLEtNYQ*Yqb$dJdtfc!6js&?4n+ zpz2)e$X~3Hzrq72ahj$s2s0q5q<-erA}%LnPz%pmgV)j;*UC+A-X{;5|JrtA1jQAM$rT`JvyPt*(_PIDd5yX` z`CWQfWl3O=9v>11yf_3;TjsL;h1>t(2mQA$kTD}2)Ct?SFTTAWT$a+PtxyE24ddHC zA+tS#?HTiu8nxBDZxxZq=%|(;sH|4DFw=mBRd5K60sM*p6VZ7wnQ! zI}?%`MgtbP<`gBR)M)==!Iv@0{+-0sb(&O@6v;NTjwedT$Fc{aL7m zhgg{z*ri@WyvxV_pKS1NPwl@A_em+DPT&uccvNUfEMg#2Jwpg`8 zmJtk108M_bv_zvnM>hgP8cL2F?3hEv8wyx5GJq&XOlM{2@zlY7@Ca2=FcPO+AYJUf z<{3l8L~8x$T=C;c^x&hkYt#X7QN>_Jj>R1aJ{isSWg!97J#|TjpHCNs*uG*g5rQU!V>Y5Xc z$*CN@>H25iYO(=w^hn}cw@Mw37w&0x?C*O9V7H&Y|m<*dgZ3bVjde5&qNcYo&)G29_ zcW$5{!}KR1kK6y~6Mn2qSRHeGMsz9?rkpkjJG!(V8qj^2leZ3tL1GW0#jn`Ju(U-m zKMt<*_F`xDaIWw#h)dovBR&mJ|61$djIErJj3|fz4xDi)wCaH3F)RQt+V-c`L0R=(r=c8G%wbs pF)J@^&i6veq>FW%Y`1;WOvx$wO83S{K|h25#n#E@ffe=Ve*xTs!w3KX literal 0 HcmV?d00001 diff --git a/docs/src/concepts/matrix_product_states.md b/docs/src/concepts/matrix_product_states.md new file mode 100644 index 000000000..b59214507 --- /dev/null +++ b/docs/src/concepts/matrix_product_states.md @@ -0,0 +1,132 @@ +```@meta +DocTestSetup = quote + using MPSKit, TensorKit +end +``` + +# [Matrix product states](@id concept_matrix_product_states) + +A matrix product state (MPS) represents the wavefunction of a one-dimensional quantum system as a chain of tensors, one per site, contracted along shared *virtual* bonds. +The physical indices carry the local degrees of freedom, while the virtual bonds carry the entanglement between the two halves of the system that meet at that bond. + +```@raw html +A finite MPS drawn as a chain of tensors, each with one physical leg pointing out and virtual legs joining it to its neighbours. +``` + +*The diagram shows a finite MPS as a row of site tensors, each carrying a physical index and linked to its neighbours through virtual bonds; the two ends carry trivial (dimension-one) boundary bonds.* + + +This page explains the *gauge freedom* inherent in that representation and the *canonical forms* MPSKit uses to fix it, so that the `AL`, `AR`, `C`, and `AC` you see throughout the API stop looking like arbitrary labels. +It is about understanding rather than construction: for how to *build* a state see [Constructing states](@ref howto_states), and for the full type signatures see the [States](@ref lib_states) reference. + +## Gauge freedom + +The tensors that make up an MPS are not uniquely determined by the physical state they encode. +On any virtual bond you can insert an invertible matrix `C` together with its inverse `C⁻¹`, since their product is the identity and leaves the contracted network unchanged. +Absorbing `C` into the tensor on one side of the bond and `C⁻¹` into the tensor on the other redefines both local tensors while representing exactly the same physical state. + +```@raw html +Inserting C times its inverse on a virtual bond and reabsorbing each factor into the neighbouring tensor, leaving the physical state unchanged. +``` + +*The diagram shows an identity `C · C⁻¹` inserted on a virtual bond, with each factor then absorbed into the tensor on its side of the bond — a change of representation that leaves the physical state untouched.* + +This freedom is not a nuisance to be tolerated; it is a resource. +Because the local tensors can be reshaped at will, we can choose the gauge on every bond to give the tensors especially convenient properties, without ever changing the state they describe. +The two choices below are the ones that matter in practice. + +## Canonical forms + +At each site there are two particularly convenient gauges, the *left*- and *right-canonical* forms. + +In the left-canonical form a site tensor is a **left isometry**: contracting it with its own conjugate over the left virtual and physical indices yields the identity on the right virtual space. +By convention these tensors are called `AL`. + +```jldoctest mps_states +julia> state = FiniteMPS(rand, ComplexF64, 10, ℂ^2, ℂ^4); + +julia> al = state.AL[3]; + +julia> al' * al ≈ id(right_virtualspace(al)) +true +``` + +In the right-canonical form a site tensor is instead a **right isometry**, an identity when contracted over its right virtual and physical indices; these are called `AR`. +The check uses TensorKit's `repartition` to regroup the tensor's indices so that the isometry contraction can be written directly. + +```jldoctest mps_states +julia> ar = state.AR[3]; + +julia> repartition(ar, 1, 2) * repartition(ar, 1, 2)' ≈ id(left_virtualspace(ar)) +true +``` + +The two forms can be mixed: every tensor to the left of a chosen bond is put in the left gauge and every tensor to its right in the right gauge. +The gauge transformation sitting on that one bond can no longer be absorbed without spoiling the isometry property on one side, so it remains as an explicit **center bond tensor** `C`. +`C` is exactly the transformation that relates the left- and right-gauged tensors across its bond. +For convenience a single site tensor can also be left in the *center-site* form `AC`, which is the center tensor absorbed into the neighbouring isometry from either side: + +```jldoctest mps_states +julia> al * state.C[3] ≈ state.AC[3] +true +``` + +Equivalently, absorbing the center tensor on bond `2` into the right isometry at site `3` reproduces the same center-site tensor: + +```jldoctest mps_states +julia> repartition(state.C[2] * repartition(ar, 1, 2), 2, 1) ≈ state.AC[3] +true +``` + +These relations — `AL' * AL = 1`, `AR * AR' = 1`, and `AC = AL · C = C · AR` — hold for any validly gauged MPS, which is why the checks above return `true` even for a random state. + +## Automatic gauge management + +MPS algorithms move through these forms constantly: a DMRG sweep, for instance, carries the center site across the chain, gauging each tensor as it goes. +Doing that bookkeeping by hand would be tedious and error-prone, so the state objects do it for you. +A [`FiniteMPS`](@ref) (and likewise an [`InfiniteMPS`](@ref)) behaves as an automatic gauge manager: querying `state.AL`, `state.AR`, `state.C`, or `state.AC` returns the requested form, computing and caching it on demand and recomputing it when the underlying tensors have changed. +The intended experience is that you never think about how the state is gauged — it is handled automagically. + +!!! warning "In-place mutation defeats the cache" + A `FiniteMPS` detects that a form needs recomputing only when a tensor is *replaced* through an indexing assignment. + Changing a tensor's data in place keeps the same object, so the automatic recomputation is not triggered and stale gauged tensors may be returned. + Assign a new tensor rather than mutating an existing one. + +### The center-gauge overlap insight + +The payoff of the mixed gauge is visible in a computation as basic as the norm. +To compute the overlap of a state with itself, bring any bond into the center gauge. +Everything to the left of that bond is built from left isometries and contracts to the identity, everything to the right is built from right isometries and does the same, and the entire network collapses to the overlap of the center bond tensor `C` with itself. +The overlap is therefore the same whichever bond you pick: + +```jldoctest mps_states +julia> using LinearAlgebra + +julia> d = dot(state, state); + +julia> all(c -> dot(c, c) ≈ d, state.C) +true +``` + +This is not a special trick for the norm; the same collapse-to-the-center reasoning is what makes environments (see [Environments](@ref concept_environments)) and local expectation values cheap to evaluate in the canonical gauge. + +## Finite versus infinite gauging + +The gauge machinery is shared between finite and infinite states, but the way the forms are kept current differs, because the two have very different structure. + +A [`FiniteMPS`](@ref) has genuine boundaries and mutable per-site tensors, so it gauges *lazily*: each form is recomputed only for the tensors it actually depends on, and invalidation is decided by object identity (`===`) — replacing a tensor marks the left-gauged tensors to its right and the right-gauged tensors to its left as stale, leaving the rest cached. +An [`InfiniteMPS`](@ref) instead repeats a finite unit cell periodically, so there is no left or right end to anchor a partial recompute: every tensor lies both to the right and to the left of any change, and all forms are recomputed together whenever a tensor changes. + + +## Variants + +Two further state types reuse the same canonical-form vocabulary for more specialized settings: + +- A [`WindowMPS`](@ref) represents a finite window of mutable tensors embedded in an infinite environment on both sides — a finite region living inside two [`InfiniteMPS`](@ref) tails. +- A [`MultilineMPS`](@ref) is a stack of [`InfiniteMPS`](@ref) objects used to represent the two-dimensional networks that arise in boundary-MPS methods. + +## Where to go next + +- To build states from tensors, from spaces, or as product states, see [Constructing states](@ref howto_states). +- For the full type signatures and docstrings, see the [States](@ref lib_states) reference. +- For how the canonical gauge makes contractions cheap, see [Environments](@ref concept_environments). diff --git a/docs/src/concepts/mps_gauge_freedom.png b/docs/src/concepts/mps_gauge_freedom.png new file mode 100644 index 0000000000000000000000000000000000000000..15dc6648fa4e099335538e6df73afd8f081301b5 GIT binary patch literal 6206 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 Date: Wed, 8 Jul 2026 17:57:14 -0400 Subject: [PATCH 58/76] docs(concepts): add operators and Hamiltonians concept page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Salvages the conceptual core of man/operators.md into a Diátaxis concept page: what an MPO is (finite vs infinite, two physical + two virtual legs), the gauge non-uniqueness caveat, virtual-dimension growth under products/sums, and — the centrepiece — the Jordan-block MPO-Hamiltonian structure presented as math with the finite-state-automaton reading (D→1-site, C·B→2-site, C·Aᵏ·B→(k+2)-site), the explicit TFIM W matrix, boundary vectors, and H = V_L W^⊗N V_R. Keeps the Symbolics expansion as a run-verified @example, and covers the sparse BlockTensorMap/JordanMPOTensor block structure. Construction recipes (incl. the 2D lattice example) are left to howto/hamiltonians.md; type reference to lib/operators.md; the legacy WIP-stub section is dropped. Physics/convention claims (virtual-dim growth law, automaton index convention, long-range decay/power-law approximation) carry REVIEW flags. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/make.jl | 1 + .../concepts/operators_and_hamiltonians.md | 153 ++++++++++++++++++ 2 files changed, 154 insertions(+) create mode 100644 docs/src/concepts/operators_and_hamiltonians.md diff --git a/docs/make.jl b/docs/make.jl index fd3817edd..cd07fe991 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -79,6 +79,7 @@ makedocs(; ], "Concepts" => [ "concepts/matrix_product_states.md", + "concepts/operators_and_hamiltonians.md", "concepts/algorithm_landscape.md", "concepts/environments.md", "concepts/parallelism_model.md", diff --git a/docs/src/concepts/operators_and_hamiltonians.md b/docs/src/concepts/operators_and_hamiltonians.md new file mode 100644 index 000000000..cf71f8295 --- /dev/null +++ b/docs/src/concepts/operators_and_hamiltonians.md @@ -0,0 +1,153 @@ +# [Operators and Hamiltonians](@id concept_operators_and_hamiltonians) + +Just as a matrix product state factorises a wavefunction into a chain of local tensors, an operator on a one-dimensional system can be factorised in exactly the same way. +The result is a *matrix product operator* (MPO): the operator analogue of an MPS. +This page explains what that factorisation is, why the local tensors are not unique, and — above all — the particular upper-triangular *Jordan-block* structure that lets a sum of local terms be written as a single MPO. +It is about understanding rather than construction: for how to *build* a Hamiltonian see [Building Hamiltonians](@ref howto_hamiltonians), and for the full type signatures see the [Operators](@ref lib_operators) reference. + +## What an MPO is + +An MPO is a collection of local [`MPOTensor`](@ref MPSKit.MPOTensor) objects contracted along a line. +Where an MPS site tensor has one physical leg and two virtual legs, an MPO site tensor has *two* physical legs — one incoming and one outgoing — because it maps states to states, and again two virtual legs that thread the operator together along the chain. + +```@raw html +An MPO drawn as a chain of tensors, each with an incoming and an outgoing physical leg and virtual legs joining it to its neighbours. +``` + +*The diagram shows an MPO as a row of site tensors, each carrying a pair of physical indices (one in, one out) and linked to its neighbours through virtual bonds.* + +As with states, the construction comes in a finite and an infinite flavour. +A [`FiniteMPO`](@ref) is a plain vector of `MPOTensor` objects with trivial (dimension-one) virtual spaces at the two ends, so that the network describes a genuine operator on a finite chain. +An [`InfiniteMPO`](@ref) instead repeats a finite unit cell periodically, and is therefore stored as a periodic array of `MPOTensor` objects rather than an ordinary vector. + +### Gauge non-uniqueness + +The local tensors of an MPO are not uniquely determined by the operator they encode. +Exactly as for an MPS, an invertible gauge transformation can be inserted on any virtual bond and reabsorbed into the two neighbouring tensors without changing the contracted network. +The individual site tensors are therefore defined only up to this virtual-space gauge freedom. + +!!! warning "Element-wise comparison is unsafe" + Because two different sets of local tensors can represent the very same operator, comparing MPOs tensor-by-tensor is not meaningful. + Test for equality through gauge-invariant quantities instead. + +### Products and sums grow the virtual dimension + +MPOs support the usual linear-algebra operations — addition, subtraction, and multiplication, either among themselves or acting on an MPS. +Each such operation combines the virtual spaces of its operands, so the virtual dimension of the result is (generically) the *product* or *sum* of the input dimensions rather than staying fixed. +Composing operators naively therefore makes the representation grow, and the growth compounds under repeated multiplication. + +This growth is precisely what motivates the *approximate* algorithms that re-express a product or sum within a bounded virtual dimension; see the [algorithm landscape](@ref concept_algorithm_landscape) for where those methods fit. + +## MPO Hamiltonians and the Jordan-block form + +A quantum Hamiltonian is a *sum* of local terms rather than a single dense operator, yet it too can be written as one MPO. +The trick is a characteristic upper-triangular block structure, so distinctive that the resulting object is usually called a *Jordan-block MPO*. +In MPSKit this is the [`MPOHamiltonian`](@ref) family — [`FiniteMPOHamiltonian`](@ref) and [`InfiniteMPOHamiltonian`](@ref) — and it is what the Hamiltonian constructors assemble under the hood. + +In its most general form, the per-site block matrix ``W`` reads + +```math +W = \begin{pmatrix} +1 & C & D \\ +0 & A & B \\ +0 & 0 & 1 +\end{pmatrix} +``` + +where the corner entries `1` are identity operators and ``A``, ``B``, ``C``, ``D`` are (blocks of) local operators. +The Hamiltonian on ``N`` sites is recovered by contracting one copy of ``W`` per site between two boundary vectors, + +```math +v_L = \begin{pmatrix} 1 & 0 & 0 \end{pmatrix}, +\qquad +v_R = \begin{pmatrix} 0 \\ 0 \\ 1 \end{pmatrix}, +\qquad +H = V_L\, W^{\otimes N}\, V_R . +``` + +### A finite-state automaton + +The upper-triangular shape makes ``W`` behave like a finite-state automaton that reads the chain from left to right. +The boundary vector ``v_L`` starts in the top-left "identity" state; the automaton may stay there (the leading `1`), it may *finish* immediately by placing a single-site term through ``D``, or it may *start* an interaction through ``C``, propagate it across intermediate sites through ``A``, and *close* it through ``B`` into the bottom-right "identity" state selected by ``v_R``. +Every complete left-to-right path through the block matrix contributes one term of the Hamiltonian: + +- ``D`` alone generates the single-site terms, +- ``C \cdot B`` generates the two-site terms, +- ``C \cdot A \cdot B`` generates the three-site terms, +- and in general ``C \cdot A^{k} \cdot B`` generates a term spanning ``k+2`` sites. + + + +The repeated ``A`` block is what makes longer-range interactions possible at fixed virtual dimension: choosing ``A`` to be (a multiple of) the identity gives every additional site the same weight, while a decaying ``A`` gives geometrically decaying couplings. +A sum of such geometric series can approximate a power-law interaction to any desired accuracy, which is how (exponentially decaying) infinite-range and approximate power-law couplings are represented. + + +### The transverse-field Ising Hamiltonian + +For the [transverse-field Ising model](https://en.wikipedia.org/wiki/Transverse-field_Ising_model), + +```math +H = -J \sum_{\langle i, j \rangle} X_i X_j - h \sum_j Z_j , +``` + +the block matrix specialises to + +```math +W = \begin{pmatrix} +1 & X & -hZ \\ +0 & 0 & -JX \\ +0 & 0 & 1 +\end{pmatrix} . +``` + +Here ``D = -hZ`` is the single-site field term, and the nearest-neighbour coupling ``-J X_i X_{i+1}`` is produced by ``C = X`` on one site meeting ``B = -JX`` on the next. +The middle block ``A = 0`` truncates the automaton after two sites, which is exactly what a nearest-neighbour model needs — there are no longer-range paths. + +### Verifying the expansion symbolically + +Because ``H = V_L\, W^{\otimes N}\, V_R`` is just repeated matrix multiplication, the term-generation rule above can be checked with a symbolic algebra system. +Filling ``W`` with abstract symbols ``A``, ``B``, ``C``, ``D`` on each site and expanding the product exposes exactly which combinations survive. + +```@example operators +using Symbolics +L = 4 +# generate W matrices, one per site +@variables A[1:L] B[1:L] C[1:L] D[1:L] +Ws = map(1:L) do l + return [1 C[l] D[l] + 0 A[l] B[l] + 0 0 1] +end + +# left and right boundary vectors +Vₗ = [1, 0, 0]' +Vᵣ = [0, 0, 1] + +# expand the contraction H = V_L W^{⊗L} V_R +expand(Vₗ * prod(Ws) * Vᵣ) +``` + +Reading off the result, the lone ``D`` terms are the single-site contributions, the ``C \cdot B`` products are the two-site terms, the ``C \cdot A \cdot B`` products are the three-site terms, and so on — precisely the automaton paths described above. + +## Sparse and block structure + +Because an [`MPOHamiltonian`](@ref) is an MPO with the extra Jordan-block structure, its virtual space is not a single space but a *direct sum* of spaces, one for each row (or column) of the block matrix ``W``. +The site tensors are therefore stored as [`BlockTensorMap`](@extref BlockTensorKit.BlockTensorMap) objects rather than ordinary dense tensor maps, with each block occupying one cell of the ``W`` matrix. +MPSKit exposes the specialised [`JordanMPOTensor`](@ref) for exactly this layout. + +!!! note "Sparsity is what keeps it efficient" + Most cells of ``W`` are zero — the whole lower-left triangle, and typically much of the interior ``A`` block. + Storing only the non-zero blocks is what makes the Jordan-block representation compact, so the cost tracks the number of distinct interaction terms rather than the nominal size of ``W``. + +The [`JordanMPOTensor`](@ref) type and its internal accessors are implementation detail and may change; treat them as unstable and prefer the public constructors and `@ref`-documented interface. + +## Beyond nearest-neighbour, 1D chains + +The same machinery is not limited to nearest-neighbour couplings or to strictly one-dimensional systems: quasi-1D cylinders and 2D lattices are obtained by snaking the MPO through a multi-dimensional array of physical spaces, and longer-range interactions slot into the ``A`` block as described above. +See [Building Hamiltonians](@ref howto_hamiltonians) for the construction recipes and [MPSKitModels.jl](https://quantumkithub.github.io/MPSKitModels.jl/dev/) for ready-made lattices and models. + +## Where to go next + +- To build Hamiltonians from local terms, in 1D or on lattices, see [Building Hamiltonians](@ref howto_hamiltonians). +- For the full type signatures and docstrings, see the [Operators](@ref lib_operators) reference. +- For the approximate algorithms that keep MPO products and sums bounded, see the [algorithm landscape](@ref concept_algorithm_landscape). From 5a9cff4acf553dc7ccfc60a604e7c03ed87f1316 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Wed, 8 Jul 2026 18:12:27 -0400 Subject: [PATCH 59/76] docs(concepts): add "TensorKit for MPS users" vector spaces page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces man/intro.md with a Diátaxis concept page that lowers the TensorKit cliff. Part A takes the positive path first — TensorMap as a linear map, the spin-1/2 ℂ^2 running example, then the ℤ₂ symmetric-tensor payoff — and only afterwards introduces the domain/codomain partition mismatch as a diagnostic (reframing the legacy page, which opened with two errors). Part B leads with the planarity/fermion-sign rationale for the Vₗ ⊗ P ← P ⊗ Vᵣ ordering, then shows the MPS/bond/MPO tensor diagrams, each with a math leg-order fallback. All code is verified: four jldoctest blocks pass the full doctest suite and the three @example blocks were run standalone. Fixes a latent legacy bug (the old permute(t2,(1,2,3),()) does not actually make the addition succeed). The planarity/fermion claim and the three image conventions carry REVIEW flags. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/make.jl | 1 + docs/src/concepts/vector_spaces.md | 186 +++++++++++++++++++++++++++++ 2 files changed, 187 insertions(+) create mode 100644 docs/src/concepts/vector_spaces.md diff --git a/docs/make.jl b/docs/make.jl index cd07fe991..79cb92756 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -78,6 +78,7 @@ makedocs(; "howto/parallelism_gpu.md", ], "Concepts" => [ + "concepts/vector_spaces.md", "concepts/matrix_product_states.md", "concepts/operators_and_hamiltonians.md", "concepts/algorithm_landscape.md", diff --git a/docs/src/concepts/vector_spaces.md b/docs/src/concepts/vector_spaces.md new file mode 100644 index 000000000..286ae9aa8 --- /dev/null +++ b/docs/src/concepts/vector_spaces.md @@ -0,0 +1,186 @@ +```@meta +DocTestSetup = quote + using MPSKit, TensorKit +end +``` + +# [TensorKit for MPS users](@id concept_vector_spaces) + +Every tensor in MPSKit is a TensorKit [`TensorMap`](https://quantumkithub.github.io/TensorKit.jl/stable/), and this single choice is what makes the library generic over symmetry. +The same MPS and MPO code runs for a plain complex vector space, an abelian symmetry such as ℤ₂ or U(1), a non-abelian symmetry such as SU(2), and for fermionic or anyonic systems, because the symmetry lives inside the tensor rather than in the algorithms. +This page builds the mental model you need to read that API comfortably: what a `TensorMap` is, how its indices are typed by vector *spaces*, and the index conventions MPSKit adopts for its state and operator tensors. +It is about understanding rather than construction: once the tensors introduced here feel familiar they are put to work in [Matrix product states](@ref concept_matrix_product_states) and [Operators and Hamiltonians](@ref concept_operators_and_hamiltonians). + +## Tensors as linear maps + +The mental shift from a multi-dimensional array to a `TensorMap` is small but important. +An array is a bag of numbers indexed by integer sizes; a `TensorMap` is a **linear map** from one space to another, and its indices carry *types* — vector spaces — rather than bare sizes. +The legs are partitioned into a **codomain** (the outputs of the map) and a **domain** (its inputs), so that a tensor with codomain `W` and domain `V` is read as a map `W ← V`. + +Throughout this page we use a single running example: the two-dimensional complex space of a spin-1/2 degree of freedom. +It is written `ℂ^2` (the `ℂ` is typed `\bbC`), which constructs a [`ComplexSpace`](https://quantumkithub.github.io/TensorKit.jl/stable/) of dimension two. + +```jldoctest vspace +julia> V = ℂ^2 +ℂ^2 + +julia> dim(V) +2 +``` + +A space knows its dimension, and that dimension — not a Julia integer — is what a tensor's legs are built from. + +## Building tensors + +Constructing a tensor mirrors constructing an array, with the `axes`/`size` specifiers replaced by spaces. +The two most common constructors are `rand` and `zeros`, which take a scalar type followed by the codomain and domain. +The domain and codomain can be passed as two separate arguments, or joined with the `←` arrow (typed `\leftarrow`): + +```jldoctest vspace +julia> t = rand(Float64, V ⊗ V, V); + +julia> space(t) +(ℂ^2 ⊗ ℂ^2) ← ℂ^2 + +julia> codomain(t) +(ℂ^2 ⊗ ℂ^2) +``` + +Here `t` is a map from one spin-1/2 space to two of them, built with `⊗` (typed `\otimes`) to combine spaces. +Querying [`space`](https://quantumkithub.github.io/TensorKit.jl/stable/), [`codomain`](https://quantumkithub.github.io/TensorKit.jl/stable/), and [`domain`](https://quantumkithub.github.io/TensorKit.jl/stable/) always prints deterministically, even though the tensor's entries are random. +The `zeros` form takes the codomain and domain as separate positional arguments: + +```jldoctest vspace +julia> z = zeros(ComplexF64, V, V); + +julia> space(z) +ℂ^2 ← ℂ^2 +``` + +## Symmetric tensors: the payoff + +The reason for all of this typing of indices is that the very same interface represents *symmetric* tensors, at no extra cost to the code that uses them. +Instead of `ℂ^2` we hand the constructor a space that has been split into charge **sectors**. +For a ℤ₂ symmetry, `Z2Space(0 => 1, 1 => 1)` is a two-dimensional space whose dimension is distributed as one dimension in the even (charge `0`) sector and one in the odd (charge `1`) sector: + +```jldoctest vspace +julia> V2 = Z2Space(0 => 1, 1 => 1) +Rep[ℤ₂](…) of dim 2: + 0 => 1 + 1 => 1 + +julia> dim(V2) +2 +``` + +A tensor built on this space is a genuinely block-sparse, symmetry-respecting object, yet it is constructed and queried exactly like the plain one above: + +```jldoctest vspace +julia> t3 = rand(Float64, V2 ⊗ V2, V2); + +julia> space(t3) +(Rep[ℤ₂](0 => 1, 1 => 1) ⊗ Rep[ℤ₂](0 => 1, 1 => 1)) ← Rep[ℤ₂](0 => 1, 1 => 1) +``` + +Only the space changed; the tensor stores just the symmetry-allowed blocks and enforces charge conservation for you. +Swapping `Z2Space` for a U(1), SU(2), or fermionic space would be an equally local change, and this is exactly why MPSKit's algorithms never mention a symmetry: it is carried entirely by the spaces. +See [Using symmetries](@ref tutorial_using_symmetries) for the full progression of symmetry types. + +## Reading a partition error + +One feature of `TensorMap`s has no counterpart in plain arrays and is worth meeting deliberately, because it produces an error message that is puzzling the first time. +The partition of legs into codomain and domain is *part of a tensor's type*: two tensors are compatible for addition only when their codomains and domains match, arrows included. +Take a tensor and re-partition it so that every leg sits in the codomain (moving a leg across the `←` also flips its arrow to the dual space): + +```@example vspace +using MPSKit, TensorKit # hide +V = ℂ^2 # hide +t = rand(Float64, V ⊗ V, V) +t2 = permute(t, ((1, 2, 3), ())) +space(t), space(t2) +``` + +`t` and `t2` describe the same legs but with different partitions, so adding them directly fails: + +```@example vspace +try #hide +t + t2 # partitions do not match +catch err; Base.showerror(stderr, err); end #hide +``` + + + +The fix is [`permute`](https://quantumkithub.github.io/TensorKit.jl/stable/), which regroups the legs into a chosen partition. +Bringing `t2` back to the partition of `t` makes the addition well-defined again: + +```@example vspace +space(t + permute(t2, ((1, 2), (3,)))) +``` + +The lesson is not to avoid re-partitioning but to read such an error as "the same legs, grouped differently" and reach for `permute`. + +## MPSKit's index conventions + +With the `TensorMap` model in hand, we can state the leg conventions MPSKit uses for its own tensors — and, more importantly, *why* it uses them. + +An MPS site tensor has a left virtual space `Vₗ`, one or more physical spaces `P`, and a right virtual space `Vᵣ`, and MPSKit orders them so that the left virtual and physical legs form the codomain while the right virtual leg forms the domain, i.e. `Vₗ ⊗ P ← Vᵣ` (an MPO tensor, with an incoming and an outgoing physical leg, reads `Vₗ ⊗ P ← P ⊗ Vᵣ`). +At first glance this ordering looks arbitrary, but it is chosen to keep the tensor networks **planar**: the legs run left-to-right without any lines having to cross. +Planarity is what lets the algorithms be written without spurious crossings, and this matters most for **fermionic systems**, where every extra line crossing carries a sign and unnecessary crossings would reintroduce a sign problem. + + + +### The MPS tensor + +```@raw html +An MPS tensor drawn as a box: a left virtual leg and one or more physical legs on the left, a right virtual leg on the right. +``` + +The diagram encodes the ordering + +```math +V_\ell \otimes P_1 \otimes \cdots \otimes P_{k} \leftarrow V_r, +``` + +i.e. leg 1 is the left virtual space, the physical spaces come next (the picture labels them `physical (2:N-1)`), and the final leg is the right virtual space. + + +Crucially, an MPS tensor may carry an **arbitrary number of physical legs**, and both [`FiniteMPS`](@ref) and [`InfiniteMPS`](@ref) handle the resulting objects. +This is what allows, for example, boundary tensors in PEPS code, which carry two physical legs. + +### The bond tensor + +```@raw html +A bond tensor drawn as a box with one virtual leg on the left and one virtual leg on the right. +``` + +A bond tensor sits between two MPS site tensors and has only the two virtual legs, ordered + +```math +V_\ell \leftarrow V_r, +``` + +i.e. the left virtual space is the codomain and the right virtual space is the domain. + + +### The MPO tensor + +```@raw html +An MPO tensor drawn as a box: a left virtual leg and an outgoing physical leg on the left, an incoming physical leg and a right virtual leg on the right. +``` + +An MPO tensor, used to represent both quantum Hamiltonians and classical statistical-mechanics problems, carries two physical legs (one outgoing, one incoming) and two virtual legs, ordered + +```math +V_\ell \otimes P \leftarrow P \otimes V_r. +``` + +The picture labels these `virtual (1)` and `physical (2)` in the codomain, and `physical (3)` and `virtual (4)` in the domain. + + +## Where to go next + +- To see these tensors assembled into states and gauged into canonical form, read [Matrix product states](@ref concept_matrix_product_states). +- For the operator side and the Jordan-block structure of Hamiltonians, read [Operators and Hamiltonians](@ref concept_operators_and_hamiltonians). +- For the full range of symmetry types and when each pays off, see [Using symmetries](@ref tutorial_using_symmetries). +- For the underlying tensor library, consult the [TensorKit documentation](https://quantumkithub.github.io/TensorKit.jl/stable/). +``` From d8f5a3812de37daa17fc50dfbe4c10476502ff27 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Wed, 8 Jul 2026 19:08:28 -0400 Subject: [PATCH 60/76] docs: retire the man/ section MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Manual pages have been superseded by the tutorials, how-to guides, concept pages, and library reference built over waves 1-3: - intro.md → concepts/vector_spaces.md - states.md → concepts/matrix_product_states.md - operators.md → concepts/operators_and_hamiltonians.md - algorithms.md → concepts/algorithm_landscape.md + how-tos + lib/ - environments.md → concepts/environments.md - parallelism.md → concepts/parallelism_model.md + howto/parallelism_gpu.md Removes the Manual group from the nav, deletes the man/ sources and their images (finite_mps_definition/mps_gauge_freedom copied into concepts/; the D_*_strided/blas threading plots were unreferenced), and repoints the landing page "Where next" router from the manual to the concept pages. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/make.jl | 7 - docs/src/index.md | 2 +- docs/src/man/D_100_strided.png | Bin 25345 -> 0 bytes docs/src/man/D_500_blas.png | Bin 17064 -> 0 bytes docs/src/man/D_500_strided.png | Bin 21638 -> 0 bytes docs/src/man/algorithms.md | 399 ------------------------- docs/src/man/environments.md | 66 ---- docs/src/man/finite_mps_definition.png | Bin 2622 -> 0 bytes docs/src/man/intro.md | 93 ------ docs/src/man/mps_gauge_freedom.png | Bin 6206 -> 0 bytes docs/src/man/operators.md | 276 ----------------- docs/src/man/parallelism.md | 116 ------- docs/src/man/states.md | 174 ----------- 13 files changed, 1 insertion(+), 1132 deletions(-) delete mode 100644 docs/src/man/D_100_strided.png delete mode 100644 docs/src/man/D_500_blas.png delete mode 100644 docs/src/man/D_500_strided.png delete mode 100644 docs/src/man/algorithms.md delete mode 100644 docs/src/man/environments.md delete mode 100644 docs/src/man/finite_mps_definition.png delete mode 100644 docs/src/man/intro.md delete mode 100644 docs/src/man/mps_gauge_freedom.png delete mode 100644 docs/src/man/operators.md delete mode 100644 docs/src/man/parallelism.md delete mode 100644 docs/src/man/states.md diff --git a/docs/make.jl b/docs/make.jl index 79cb92756..0f48ed51e 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -58,13 +58,6 @@ makedocs(; "tutorials/excitations.md", "tutorials/using_symmetries.md", ], - "Manual" => [ - "man/intro.md", - "man/states.md", - "man/operators.md", - "man/algorithms.md", - # "man/environments.md", - ], "How-to" => [ "howto/index.md", "howto/states.md", diff --git a/docs/src/index.md b/docs/src/index.md index c7bea3209..ae1ac5599 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -146,7 +146,7 @@ The same three steps carry over to harder problems, usually by changing only the - [**Installation**](@ref tutorial_installation) and [**Your first ground state**](@ref tutorial_first_groundstate) open the tutorial track, walking through complete calculations from scratch. - [**How-to guides**](@ref howto_index) are focused recipes for a known task, such as [constructing states](@ref howto_states), [building Hamiltonians](@ref howto_hamiltonians), and [computing observables](@ref howto_observables). -- [**The manual**](man/intro.md) explains the concepts behind the library, including [States](@ref um_states), [Operators](@ref um_operators), and [Algorithms](@ref um_algorithms). +- [**Concepts**](@ref concept_vector_spaces) explain the ideas behind the library, from [vector spaces and TensorKit](@ref concept_vector_spaces) through [matrix product states](@ref concept_matrix_product_states), [operators and Hamiltonians](@ref concept_operators_and_hamiltonians), and [the algorithm landscape](@ref concept_algorithm_landscape). - [**The examples gallery**](examples/index.md) collects longer, fully worked case studies across symmetries, infinite systems, and less common algorithms. - [**The public API**](@ref public_api) is the curated, stable entry point to the full library reference. diff --git a/docs/src/man/D_100_strided.png b/docs/src/man/D_100_strided.png deleted file mode 100644 index 585beb543f81cfec9e7c1cad28c894c2f93da66e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25345 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

    %`^Li!QKx2$H-r*-qm^A|bK1W{c2h-@Eq0db z!R?hEq>Aa!JVAE6eqR4c;D*<|Ed{Iq()3*phtyKxXL~06O)pR1^O6KDX)t?`zM_Kv zQBJPjD4wa&8pk-ZSX=W>?X-tk1%a>|EJ1Gtj{yuN;CLwnI;3PSw&U>VKFoGka*4x#ychn3=K(vUFvsi@7L0HF#lR)GsdkLu)pR)MLs? zr?G-(u1rHE61cxkYzwCHD>c!++($53zJwPhtyBP`W;7F9E(4O@tuRb0tIeQb-YBv| zHq$s)I<^gw#IhwIMaXR%%%@z#FNA9@rI@7A8DZ;{z^upDYqEehzAkln5HCE{}_vA<^c5W`z zWYW*F!(XX(D#Vjhqkkgjb#mBYrFCdtlTWGH9nVHjQh&for;YW}e&Nm^u7ANlt$&$0s^{ z|80{&z@VvSMvq=(<@oG&*~U~BmE_p&WXbZUwTLfYz5tLon8L|KODk0|og$MD&UAHk zy?{dw$781jlybJpgj^z0<;Un7>>O-4tiQM`QVB2ip_Fm8VQTIos$NM81<@{7G2Qo6UPOZRL-BJ|q^e_2}KU$P94u%af zkkpKtRkb;j7Zr8B_o^Ysmhd~YegPScIKv=(ocx>NoO9YzV`TT6bMzo@yBjAes7S=T z@mgS{GA#j&r$hIF>d(2RPp>XvLVX1W-t?@7 zFR|gX&TNT{GR`U0fB9iEUl(zg!eKMltBliKbBSuJa{LA1uj1Y-MC(|~d9fj{)SV>8 z)m02oG>PX<(xWMOOf`FyG8iV~BcSo&XgH+(Xk&Md3Fm9((S%5JWBw&)`ct5&_x;n; zU6#`s85lNF>n$hy?;L?d8-z@_J6&^h zc5Ou-*Zb8YuyAnt&8{|Jd?&F}xEu^0AMRuRSEJh8pRLZx&c@UK4x0q0#jD%9Hn$r6 zJdB28Y-zw+Hnmv(0N^biTMo))RNneO296fsNMtDSe0%G9JqEi5eXIc-aC;^fS(S*7VIDPg4N zJ^U64sXcgTbR#`#|A+F}t6zxdaWlvof74HSL-Y;y8Zqf|udS`1kH-8$9OYzgz2~XDQXF%mzpXlB(LK z&a!ui>}_AJzV`Jx|2VWn_G;eaecklgCbN6{SMi+66K(M!SL15G`S3S7Sx|F&I=bpV z2sR%G**iNsg?oVLfQn{fY@C~$`~Gy0m64GVH0hI~qN19bn*WNHib`y1>U-yHh0}p7 zkszY?pMG2z78MnZ@Leu|2uev$*SoFH@O`*mixSW~XQ86ny57q0y*;Rx&){F|4Yxy= zQALS&Y5jt{dFm-*otZTvCh|C~tK;0FxYn%0n3ESmziKt!Nj`Q=Lb~U(Slp4U*A`!t z&;nJy`>mP(fzvkygo%L$yL8bSk-^?nSx8}KCJ9j1NJ)hX#*uJY0)hw2VnHPnsho|8 zDJuBPqxCwkqN3tDZFjEDh8Gk;Mn^|6sN}kOdJaL^_2=hjs_lG$iUZ*c$a0>i(m?6~ z>xuLBC@J^vcD%O#^8#=;`aV89kzzpN_wKg)`}^bQ)O&vaPSNk_?jB0vtmt@-q1aGu z-=v`KTrC=S$_t8t=-*;uno?$BKeFNB8j0uN!42tTl;bX`t$+QFPQkxu&L;KUn1$Un zGUV2O+h4SRn6)4Fc5+d?pX;EN%;#JA^%0hVA#a^+Cg$EyNHA?-mt*6Gh_in5Ma6F! zyPjV5-Q*n9(cFP@WnX6=4+zq@-y3`~RFk3phMHghHWq zt>;sqP79`gaYF+a3JMCDl&ma8_RpU`VFhLu8ndga#!}N@{X2$+%6eFGB%;ba&hlOM zrljNPuP^59N_?6<&UZsFsMK7{2)OM3{PcSxLj)rp9a76$~yX>)+ho zPCsn(G@`w1sMLwEiY?gvKH7qd7VuO#oYjm#x$V*azUhp$xDe~E)Z-;y($1-Z6y|Z_ zHWKP-h4eB(yJxxpT8w$PCL=HU>akJUoMP+o%+zj))o&=wCEkLb$O(bNVxVv|o{gXF zbNy-EItL3}R+>u$d3Mk1K($NdoD8qOeF3j9>g<*e*Vd{He!-rmfN^uVy*L2&4Llu- z{|b}C!-xM0lO`rFL1D7m3zW?+4i~l0tANgSe{&83tHfz#dwY9?|8`%l1pWUsBBVD} zbsEGzH(y6*wOz`PHVG|!$>(cRE$atWU!>8;io;pO(k4@frk+yTB*Bqy+ZD((I|f2K zo~wGIPQ1@_y0e#cBev2Z|LQS1h{45*||c$ zeQ6=uWuqVKv=i2U1?bPkH<)A~@KdU*PXS6OSt`<+F=i>#t}nmoe1n-o1<+#HOl(I_ zU~oAH`=@;BCr~*ZDaD=VWkH6xeD+)SXHt`@e_8Ao(+bz=QvQ+hSk9JQqke|9-{mKs z^W27pee03SDj+j5>NctP7Jw-pp?|d69R`Ff_wCWF($Z4D7jVfX=Ae|1!gn_6eYv=` zv2i{sf&$8=%*YW&=M&9MyoTPPiql2Ou_Sz8uGJa{=`%=uJplS2q(dMr|a=;ANyTW!o= z>gS#I8F08Ji21281iy+*Ecp^!oq@TYrl$n)Fh&0 zU?MWC7HvUnM&q!=+#jyq=TLd0S{^@4fj-9YN$1<1E2VIpZBx$_Mccjc83Y|NjfpZ* zAozuahI*`qP$3g={d6b9$^nauUHiT3{!ArEf+i*=Nab^rlPqHl!lKZ}aQ$Sp;_>^D(vG{RN(j`8u0< z5L1zayvYRywDj~cK*;pEvbV6<0rr;RbiVm=UEY_73>bceCH3~j(Q73B@gSO(4k8dQ z;T|ayX78a|8J$>B@FKk|i$ax)@a>w{uYu>Pp@$6IV)pX20vA@0Q zi9q;xf`!*_b8A$@k{q;L2{4czXC!39*T9dGmX3cS1zQwY2T1gaqEl$0su8izw!vzu#1*7>CI_ z_K{{|Z2-WSbi3MDOm zal|3~xi#W*K7tF}3dp^O`}?WizXK=|U(5*#GC(Ya&aooSC26!q2Tv)Q$5%iZY5lRY zy8%0r`j+EMH(lUR6V{&_IphI~3w)jz^!jZrz`C%>?`sNb9e+~wo1FVXyOklZTK=2d z-f7tCN&*5Ca15ojk?BYI?ppyO>IjH*=8sq$%$P#dVNL$g%xa#A*8UxWqILYqSfZBNeFe}| zE6@&SDn)=2EH189;Vcy_G)~PnkpDW;RWS)vrxt9J>j{BoVe!dCRYCxyq1)}8sJ6fT zbRMls3vQhs-&rpO?H zqEpjo^qQhVn3&Y&((Q#a^1?M|b80Re%llz=sO3SURec3>yGay;uWsUvmxAS|h-a+g zhT7EBWD9B&V5WiPr3F;;f`WeQx-GKXE^xsmRWpk-y(NXuf^tEpv9B(^A-jF4t14&? zCQj!_qyICNN}!0;CbgxH^b1OnbJLSV42&s141SfWVV=K(%Nomrq&QG#G@HLWj@#E^ zV-pb9aZaTOx6f3$;>)mtsc9N0@x#-TluE0eVfAaZYe14t}*7*9iD*K zq+eS)Se`__aW$>0US13h40x`8lK_C0@BRC;`fA5(OfPQ}rO0^O!7}EFe7jE(t zqcmREz($Zb%sKjH=}z>6)h{1wyu#h}0f~WQOuo_D(i0|Ye|M$}U?mJnnL_@Bx)-5S zh#@bfu%D~g$upwZP&f+?__+XWwJhi=zIB;qA+_W16()045Z1(E-7&~r%Yd1n@L&B2 zMk8NXSSWt91filvlh|o^4lwm^!jV^auMV=M+_{u=l6wK=U!I(@tq`6nsBB!cch(eH z6iQ4@^*UT=1ZEmlS#ga(CtkbAcVXrX>-e84ziII<O3{+&?F}@GX!EWP9E^ zCE|5ZSmT@OZTlFOcc(&1Oc+j5^OYx(v}a~8iFI*d0r1GD>g8U7B$B8fV4VdB%=26e z&_jZyK52N1Kyp!BR^H&FG~;Hct6&n|g_rnaS3obC^%F-{P$CopM$(M5w0mHa;@bSd zqH5?J@D_%20e4O;E)Q)xf@n46cP^Tcs|L+NbdMU6_-idmLVY79CMI=t^|C4Cs4~h9 zK`VtQgpfM3>OO-8Ii;~P`^pJX0iBxqqn(iFdWPB08W8H^dA^KxcW=y^Wq_J>Bh4%(1C;|)9nc-#3o|5sRj0_W!CvO;Ya1|K6W%v=dncE|ay4QE zWwhi2Dj(5Y4Si7Q*Ot_*&?xNL-!G0oRQ`p@7US#Y zjH@>E=Y2>*8?;UJE(Y4*XaH6DoI za_y9PbGA3w*iTgA$-8z!NUg5&vg_&Pp2Bi7|C`US35KvkvC=os`By|dH=AFEqF}Ky z`e5PUAIhZ?eswI|uslJ+@$pkT-&=e%m+jGxQ{-5>;^*%~m?kc4-h^4vdGONdA~!5% zrzh7(&U=B@;mwI*+3yjp0E91ae>U!Oe}e`Eb#VnXwS1kT39>QeUbvxD2Y1raBU-mD!uUj&o;17 z0C36Z`)z^(tc`DGK3O4Z3{S~$kbMwE^y2|M9#jUtI%~Ho2fHffO|(KmVP8){!HK60 z2vl>62nR$x34XgA`PDls=0pk=^_~`QGCqpqhj*^y-$`-Lo|GzCP6d=iEiC8|6BA#D zX3JH=3t#{wHyW;p>gS)@klS0+tksdw)6(|$_L7iEeg}St(9qCgpN-X37Qj^1 z^}Q$OUaBN7CB07z7))tth0Ff&Y`$tHTt7FrZ|;L90pV`7@l;P>er7@SF48duk0*2& z^FqZeWmfa{Z$m+3_POg-cjc@4mn%;|3MjN?6<^Ede1Vo^uXkKt|mV;k&!n`Xk%(Pe{Qkg@gXI|=2rPK zU%+`ARq2ORX;gH;i3#4{vu8UU@GD_i$zCsP>h7QMTYfqyJQIYgEa7DQYAuq%AzZ3= zr5VK$|A2Bq z3ZG4`<1<)OR%5VMe z01@k4#rQt9QT1Am?b6M{fhi&(W=za4e|v@e>=Z*St=dm&<%TWt(7(TP%1%QD#MG^ev-_fDQTmP~B(A7g=~L^M z3msDo=C94!KhE*<(F$V{>~EU*Ql}UW^|xj=SZ>-6>j^*b57!hXY$m<;{5*q$?%%oR~Snxx7jtjzUUIK(nfe+tpiyOG%eiauza}~__!(m_(K5o=5g=om` z;_8F`^2YkdW*qq#yZ?EZDeg}9-7?L7h4*oIIMUuK#cLEy0q&A9#Hv#CbhSYVm=!5$ z1NctykduzC0CsP$ud44nvgQdkYJxYoFeWJ$SYq*fi>L z-z^{|kH6GMO~Kxw2}gb-z*E*EwE|lcR{Y{ZC}%sZs5U0rW&A>J+wmQbx8gb`Mp2w^38V~b(o9y~)=V;TDS2Xp59E{}UvE$2flEi1- z>c7fcmPGC(Sm;z_^G3VOonSplo?~klf41{9TIo&D6TSv!iL`2V7YwA5lYm?2vB;fy&2aHV|2nL4>+)1IjQITbV(s?Z^i@(_W zc4yezcmm7t7E<9p=+vGW_?|GqB;Dg{>!mE=@d>o;3K=Zyd>s!%muzRp!ET_oSso7kSlKkvGod1@~J}+ z-_RGHZ2sLC0NWFedvp@5bO0I!`q|Fvl3_h}J2B`T(sL6@az(u}_>AI^I9cGmoo zA=9Si1|Yq=Bk21ix1yJf9X+-yC&qkWh8c0g%B zHddZY0jfP7i*fMv)|2-7&x6JZECX-fQ2TNh1*=DXVD>Q38YnjqAR=KDpfHImbimiE z$mEQY^d+7M2>SeUv&JO{uG35NCs16UZ0AoI1Prep5ZL}_RucxsrIwZ! zUT~W1-m57iXKa1nm1>#3`~F2rbqzcI;6KxveLo*aw{x_)ww;Y zoZdq7>ovlejKl%!?Mx48Jnq&nb2gTqaB;-agUPiyhmMJkqU_w<4Lap?sCn$$K4Zr} z`FFgZYGW)!zFtl6J3>dR74vCG2m4<%ug60}tmGV)U~362fJ4x02H4*aot&I7x?wLW z>4mm;ceNB9_P9;_JN|5{Ib{|%I&CHUe%eej1Ay=n2oNp6<>t})knwm|aD5N@Iue)F zbfq&;t8A*TugEgcrMxUut%Q)-unTAyLrnMg_j{TRMILaYkr;zRLvwz)la`W=B=qdi z)Ew){kIcO#jb+)B^!t*07&A;S=Wgkt(jx=`!@~?VMm(PWc8$GqvSSU6Gkx@sO;)W* zUDv|Zb>kZ+?D12++S}8s+k${;jGaEY&T8G#X@#Wd;ewj2C8A>dX7G&i@;6t>B~t%w zy0EvmcXj31(m{nG10qr~zxPern>R37(g}=>jg9O}M^k0mVq)Frd(-!KcK{gy>zt9H z;h+^FGIHDaoTy@WcsK#GVL;$R+`RK;UaqhtY8f9@l)D6nsayX_x5(HJ!IdS{0k5X8 z4;jelM6+~@7`YC1Cs4B@2G*l!3q|>ejFkHYLQJu5PUREKIi{<`Utz~a1!a{;A8$3M z9IDwEMZNNxXJ(}@m@dCMk5j#1R}%fm)!|=t0~lPea3Tu z4TDP12DPidS8AUuopH(EHwiMXTgMqr*Hu381eWyWW$#AyHNF?dzeyaz*09CpL)!>m z_6>$2mcUvm~r%b^|D&dYP8XQR^kTqNu1SkX#lP7v)pAP5{J8EC~n8-3C~TcwP5Dfkp$X zE?9vR)w%4JS^#@FKU!|DsZjwXRbpaQ(NYw!+hR1|nW|owlXmCC8)ST0D`__>jU|1I z=1Hy+{~5^##N(T|l(nYz1n> z^b>`n60DvXD8n$$ry{6V=mB-d8kG1xe$2d18ygz~nm1sIsEV4JvtZ2wWh+q48=T~? z20LK(_pL##85Ffu+v!YMlE6Z+xxPNp>gl#J3^xX<3D{tRj@d9l(nArjBA}!lTe_8` zv&VU8m`)M(jl}WqGY#~P6Q`L1Pryj)Tzo2~mQU32kdcxWvki`^U5?cn(Mnq4lYv)d zBz{FyVCy()_ybUuLFyZEncQY@zKwQ3STw(JsL3y>$IBVjJ3{058cuEw#79a-#_}6p zz}CUBnE|-2$K|2!Z3U=bfy1)BV$u=|S0Vo^PV2Evya-zar7>`lT!lzF5|WO%Vom2( z$?oj?Y}_1}Bpmy`tv147j(oj9hKhuO{uRyw1Mym5xTIzgL-EPtj8uq8>7G>j)9!*c^O`5l3OsAYX3PJQnF`s>u8z9TK<={;K`?O zl9Pwly5wXnYyP<){i>?WupgJdvreN!zhQE*#JdO5*(_n8kI!F9(F~5xR#K3I``@#l zIx))At}}_R(Lv5n+@1y&+iVwjDl=|%cjG>4rSyl(61&WhKriUOI)qKU^31cSAro^) zFe{&T%CncHm8M&@JFDrjsiyE|!yli0Ria)c3j|PV?-_mP%K8+45=1j3P%lnT&(@uj zsJ?!VxM;59tOGW+$-PP{t;iVNM?(-&gYTq#auZze5-ZEm_+I}wyH<#ZQAI{-Wo-qZ zZR;Mr`tXged;H6WF)l=xNEkR$1h)4dX84twjbbkxam8#n9^Bhwl_m;}umQdON;q!J z?6DG?21`oi;gxabr7p{)zqiQYNiQ`KQghRCp5M^VRM4IttA;FUf|^{^9QDKU$L0j4 zt~MuLRqM)pkUEm{9|YnkM5fx#NDCI;ax@>0cwP3lUj~HJr=`ocne0ey zLv-YUl3^$3q$Z}aR)|5=57b_of19`C=k-zN2UkRlJTjUrt&7I04Kl@n9YN-P3QW!v zwvjkMSom|(dDG^QU(4xQ)=5V@j)1fRS8=rGT}svbikT3 zz9e$}`RZ11$df9Mz&$x_nV)eHpX{t|^+n~MKUzE6jpeH$l5@5=YO;%{0Yhj;5<*wQ zl6?aq54n+&!NA)l;PytJ$NE~zz!FVArGM!#(99T;NvWFpU@d3HL|W2C1gpiX`18>r zzKp0id#dv>Y?5Gj3rI=FE+g-96g>wGvBX9I6DEQ8U>DeQ~(`f{d^c{$at^*6@bFP7FXOs+iG@kA_$BDN`7+Uw$M3)%*L;|IA+#@%vML=){-HGFIHkMb^}J@w7q(4lRvFlAnGxFr0o4yF31c) zDtR)K8q-@WTHRnu+TvV+d)j-e;GTKSoou$wXo!LN=i|eWO}1ztQQXUFEy+9odiMpQ zzyxD(I=kv60|FC_X*hCSQhuk&JzGYGS)c4t(O*rLQwP#G&d2AU@&2$uy_oqqI7E&v ztm~Mfm=1C-#G$))x;y7Y$pshEvU8(>ST$DxHQDV9_XUtA9(LM2H!(Ut{rYUe=Rz#C zXVVnUyQ$hddV8RT60Cx|iWa7D%vyG=So#nJ)Gt4-c|2bwQ7n9Uk=eVOw4AGn);S89 zAAnWN1S8wxmAF`FJ@JpXOtsJ=E8kBl? zKo^dJwZt`bECxrF?5Uu&puHAYtXt zxz+ri7hw2fPzA@2+IATu&WJOdeBT$J#eZFAi&-0H)>2(0J&bAYkM~^QiItqX=C@x! z-#ZB!x-Bi4PA?+QfFVb{dEU|F7$wRXQ+sDypT^D0 zax)EMOxGr`gX0r1CImBp#QGbKivU-$drZ5ds1}A96$TT$XvXV_76+Mrri!(Cz~S|2 z_FMT~Pb!{&##$+bl07TWMWd;g$T+nG|D`YHrVm9vBu3$zvO-%mw zK;;1n85$F%DG2|I)LHdbrWFw~6hvdGRUB4tze36RAvayT_s;Q#1r+%#t^7kd#6+!D zb{JQsgOaL0$h)HRdSvs!LxuwOw&NYqi$tula8F_S%r-Q49_*Qas_r=US{syZ8k638 zh-u)IBwL|Eeh3w!X??!tFhC(zRgtpAvruK>lQrlQ1ucU=`8V^S5>F;yNNhGSNoaET8S->i6_+ud(juneVGXKKFFujz2e4 zJ^iyir!v(Y=5fO#>H;>-k)Z~>8J&s{^9z#a80snhW^y; z0m0~|Rw5r{Dv-t9-(lPqMS+Y0M|M~UbX>9|imPe0hONZ^exv~gLP88~g=s`grLI`; z$oMq=0a(|ZnhmI)L)eIiv*L|6t`qrXO>@3NV)E3F9$)1amb zkg4U}1+c7v&Hu8K17;cCpd8+iolVBi?*ocy6ciL-Z_m@-mY^UwGzu!J3eD<#%N2lX zr}eV%61R--aE&93i=(%5#`l{Q8+hR%qhyYg@Q>#ezMyz(1$Nh*0F{8nxED|)D|&md zcl}_#-t$o?2l`JA0QepYAD`EtGXRkENFu&uC%OM~mT74eDDRMee*!tRmH}4Enr_6q zEB?DA5W%pgUrlK9dNPIO10W4(%CgU`4KQ*76{f6G#@Kir6pf49$H7iIfXfqoiTJ%5 zqN3!1*GfYJ2kpt7qM;E8>d2wvg9yZ3T;89Oy*Y3ug&?2fzf-^i=K$Ed&H4W`WAQi_ zUKnnTWcUIi`{Z{58xnhaKaimZXrHH~rV^yd0g7+r{nbjq`axIt3oDM*wHzTqZv|IZ5KM(E?n^(edx+XD>Kx7d|a}Urt^_ z!QMBpJq!3&fN3r)49GL--H#m}0S(-QBMb+dCVjAD|Jw&x?6Gwp)0EKkfr0`S(I=FF z1ur6;IR{$!^lJqF*{718epVsz;pvwEejBqSq2T8s8XADzUfDB(lcMn?&Mqz#*`c8b zoSd9wEI6+LSzwRHWw!)=!kj??V1=^m`%VE&4y^59#~}E{h_lN}-@UT>!K2p%Tt8?j z!Ij&?=A$JV_*$(4usxGXF4f!z7Zr81Sd~ut!47F>NnDEE{IO<;)oz&Pw zUhd=j_>G~ftsI9FHYQZ!4 zCwFJ#g$7qDPemd32}T-g>8LH6XK8#JQh4&gJ#PFYoHAdD|XG zp_e5#vnC%MuJVHh6a}Vx1aW)U>oYkqJ7oC5aA*qM3Na`RGr#M@?5XMLBj272qoVcw z+c&@EzT*lC3J{T@2#9>QhP+4;8h#e^2Sx)ZIy~|I;%w2Ir=Nz5?J!hv*xZLjL`3%O z+b1Y!g~voOa*DJp;*z=k{bYr2-<`|bh(^)}x@N5N{JcE=L*6etI`Z*Y(@Mg^!l($K zF&*vL5zmKlge=w+e;`xsrbpL#&*8%j>wcT5sG=P~-@&eU<}syfWo3mGxe|F|Ky>JW zto#$hlN<7tl@4z|_g5nZ9`gEhmg9khL&kNdFowx4Nqt)bA6BznTQ?DsTlHOU@0b(ripn|v!l`S^DuccG zW}-}tI%}#^ad|Z|Ki7nn#G|spNLZbwRqsj^rj3bP_NDWe*FMs~$jOg}?tozG1@W!NXA*_54RKE}! z%r41s=`V<6{yH6p&=Wkhi`LG%X(Ws-pTi+M*?CoQ6G3#TvAk%$b`*lRrOSCoH#kjp z!aN{M@YXR@9Zbb&#|%jHM#{g1h~UF`V|IGoDe=>Rz9(KkIux0l;&|moeZL88c;u0f@9rpCY|WYOg2ev zwfLtg_5?wEYc@G2E%jOVj>XIGQ{^4XBn;Yf`WchjD@&Y)|J0P%Qk6*QU^oY@C^xOe zP2U&hde1li$eun+xAa2%NaErCE&f{xHSYrhFW^z&XmP1|DxcCsvwTT8WK^lMVzV34 zJk!dCv@P#C;DC7zLkp^&$MXNIWZ6?s>~R=s_##W$FiDO{(!qx*Y3>&NpNVwQ8-cgK z@a81sYr<@2yK|U4ozw1HCw>)XZ40VcSAjIAk@EG=g$mwEP-Fihb=UdI+=Eu9AL6SX z4Bm7^@XGkzy``dYGLH_1Zh6wD7IYTRRlN16Sg9z^%lx5h#&7wki82Z5ta{RN+!x)N zB{n5_?tUhOa-v9`zT>EstMh*g_k=7RS813@y&T}NM;Ha;-7VkPc52AdMS(YQxm6XoWm;US6FmGhT)?z z{kfo+_U`oZ<;NF+3dWgf)!%H>e7D?OFy~bnkIJ%4&!d?-k_-WN_y3 zV4t1N-;d*92|H(a^LN2E zZDQ@4D1u*wzRPtfX5t>*0X{Pwf99;A=kyXE8xjHDPRB6f_e=)_%%auMnp>OReCXEo zoyi1omfFE~F1nANp6Nud_dpFv7Q1Lbjm6X;*23y;#(bK}1GS{38DMcjYFWu#|ddl5{xt)nAJp6b?L0xpIt( z&Ncj)PNO(=fg2ff-op3TtlxKo>m^SPozKKDcx!z;KjG-gqJJQ}mM-Cc@EuHZvlrx4YjJ^S;g+GpNcpU;UZ zGmO}zuH7uPLom#kEGjWQ6o_2NnM>B1I1yfdRKpZMg~9N%G8wIMU6bZhK2?>6^)FHyp7O1gmd1ofSs0l zdcW;(AFQR6l|kIJ!40fY&<^!WRmGRGUjns{&6u~6P!c!QuM_p*J8ljiZ`9jN|0yST_P&@(cE zbh$T9OX1%)wVn>1o(hsnTW&k7ruI2kZP~JAWo1P^MN&Zl&I#Ku zDFfF920pE-T4|5tpm^bczfMBM5$;?J72>#MsengmS)2dE(4bQn_(XAFpcQFR+ZPt*zbM z+}K~dv>XjM64dq&M;WCikK_4rt@+>kfSq4sk5*%WzTz&4q{936Mc_RJYH92F5>8Ie zy!`x3WiQ>VQy6D|KfmUp5aHympry1iXiD~oh-gZ3CTicmb&EYQ?T@RtgajL1ILg-- z8vOQ2!*1z4AT{jBzAg2tmR_hE?CFtKQMo%bhbAYm53pMBKyWaT$n7RC+gf?QxcFsT zn_YbXpf7kSdDR{Dii(O0WEEjL!-7}s?bGloE0bWSJE5zqM;cZXf|N^6?s9zq@Zs&p z_RnoS&Yan9LGgG3pV{i*u3gpu@HFcwDJen;w6{ymYu|tRR5;+Q4TcTOlyp%W$pJB~1Y7)~)VGaG1Y-_Xq!ef%PpfteW%!D3j5 zDJkvX`M%%+W^h^>&-ISbf${P2hzOd*5yz95dJu1UC~3%Ea|JX?IIHa4xp{aNyBoK? z*3!_RdRS)FbZui}V|3IaG1c*+ECVp*VAxhV<@EWI>QPfgHl~^uizjT`kC! zz|e0t5VL2We!BY@*MEb9(-RX3$;l4p`lYXt`TZ<+R=AG5)dW07V70M85j54g zjqL9qwzEg4*%PK)lgc25_V&uCs*Wj&rm%*Voc8zsi3FtC15|4$141^?vh@qG1%Zy8mp!U`y=BFUps@an2I6C5(Zz1ro6|oF)dkpQq1Ie)rSZ`CFeDpD^%Rq*dbvXn zp*5q<6xsjwt?NBXma{hUA0}T`HrV=(X$fac8xrDuxmBW62b-N*;ox!SPqb-CyX@zF z167a%4@Owar^I&KV}gBre3&AUTi9Go)Yr7P&%?0h=jY>ZZIR~h?r>atJsi)lkTQF1cBMOH7T?^MAnaN`@}XJ=;_Xj(w21FiUp|M!OnXBJ$cjZ}&{ zPjjRc0fLmxay>sC^mS|NT@ltuOmg}hRrs%Kh{`ULyb&BU0w=%e z{jK+5olWKaQIx|jhGt6_eo!}OAC3S2op2v$S#cU#_fak-;LDbC zFknqKqj6C3!N8|)-@c&%3l;0e4uSf*xdeDtkpju0#zV3J=p=V01|CD77hQxSh-V#2!C{GxeelxfLr-CVy03o-VKBagesrCiz_ z=m;(zoFq(2#A-e3sE~QkdaO!k*cgJbvw6(W8D{>E+8XG?+l}DwtW>Non z2S|h_21ve9Avp%_XG3!|0?(Z^C(Uk z3pm0Y1)WaO;@&OnD%{#`7NB+#Nco?(FOguPUVM zPKv{@JH4g5`_@>!Z(PB2HN3eI$rwPh6`cq2>y2^^G4{#_50<}ig;o%7Iy)Q)2qlyp!vcI=pb%NvvZ^Yt zidjK>(P_UCrOk`Rt)z0qV=PCQUtYNI4sCRTAg30hu0}M%1oHA#vDx|g2qQ?g=I8lg z4+)U+-+$0os2<4_;N-l0=Z-PZ-KkUKA3v^jsBW-IFf%f4BJQTAqabMnzO{)-tyR~(RO`}B!qV^dOG3{%q0W+;{*PHfqH6kox}h$EvvSUVsNC$v5WOS2Ib+1xUw~(t znwpA@+cdfO`O6nDgsfdooS=`>GOMuFF)=Z*v6;jUD=8@f2)3R>sSq+U)O6r+iNK?- zp>e_7oQt77%#wt32h1r=O=?BvJQ;0W-3lP(l@+Le95KkKmT3tkY^=Y2)-3(H)N(6P zQ&;zA)*z_x!Gkpv^_Kmv0^5YE>zq9K^zx*Zk&%(H@tvF;VZFOy)*b?JUl!- zJ&kp+XHWi}J6vxgKrlhDvbD3@r=&D9J^hWWVrDi1J_zk&9GSgPfo5l`3niRAe?C7q zxBC?@eN^Y)4a^$TMi8WHSvPL5sO+3L%R7N1N|BqfcwPOjr7oXQMWWR zGn)+D(Nc!|k&1vp@3SUnb@gkI{n@@_=2O-bO|&+Zrb2$SiI8>TrB-fkY*Y)7=89nD z%hD6gIVA?od9xWk9c;2|DAnqNnY{vhd~F=>CnrrL2XP|FGW>k^HLzpCeL-&uOG!`E zQ~r3A^&N2V!3|e~k=X7{#De)vu83&O>@D=1jq+E*T8pF-J6+w}5^vs&@4#ib5r5VJ z9nk(rP4)BlXY?Kbyt1(owtyL{DKN6_ZAB#|mnu^d+Yfm5U9NqLqz8ttD&9iSKefny zu739W%im-Uv*+iUj52zFG>ziEeY01dz$DfD+t0B-NUtUa1OnHrK@3Bbs|jneVqjug zU0z-w*8@~WL`F{jD05UqkRED_*&*P<#tPK9K36(9fYA>PPQ^Vb3CZp%Q{WoLhe4Da z<2S-9C^&ZVDJS#6Qp`A46rS>shnpLsHqE=PAbR?LZP?mnD-X70?arM$>B1?gimdEH zw0+2(ojAwu49ceHkp>0_IaP%N{+pN8nILbwtQLAtmnqV7<&zOXFjPG6={e%@f%bG0 z!m>PkimruDhaRvziVc*@us{k|j<7HG@Y{)ky+U%I`g9Br&C&n(HqQ|9=^(T6_I5BbiV$7kd>sLr55+s#SYXa37OO7Jt4!;)2 zBSpJxC!BG9+<-&wUILfE;uWq|UT`{F1WqZZGZAq;Wr@}_?4m^P(jvwXjsrn1DAQhk81!3&;K4 z$Dck-*t)-cI~SL>P(oB%it4WgD*hijLJ6EwrdKw8`H~0W(_$G=URlZh`n97X&OWUp z@me{D6MQF4Djiu<^fErL`*?eACQzGq-zG=P85r8yX;I^D{Ywz8Ygt)Y5LBk`bK#WZ z=dj*}1xB_=Q4M-pR5XX3il76#@8sLJSMPV6okZ%PqpQo!#RYPu-%PsCE!`=!8VCZn zK^s6!T>MSVWgCD0I^Eox+9KHWE5Ho-2QbSsSYiNQWJnZYs||xh1Y4TWO_|rol0cZM z?&HCzb~qzvYVh^-#od6_aef-4Bqbqi8(CVaCgn>(oQ5_B3@_0VLxxpYRHWoK9Ck@z zGht|Gc;C&ciMO=b#`=l*@og0mL29(KUIYYzb~{$TcJK7DcyS6@Uf2~HsL0c2RJ z;R#VQT%O101X&V=IAeYUJPko*YJ31`G5^KXO$3}q>E5x)IkPh-bjUK$oC|=tLd^&0 zw5W;aQy!oHWNZ0+84mB51}slk@x8e=OR?{ZiJ{-9Zkce$5nz1=gMqiZ1}FoSpe(k= zR0wRMug^H@tm3?kMptXU{-sM_DW7*q|HO%<<>gA)eiBI1$$P$o=eYg2EIEKgCUafq zsleK17Jq*_hbsbIy`#tJFT1-NKMOoOnwpXleW>U8^XK|$`*%ij10r2`az(t}GcG2k zMOIQ=yi-k8Ts*ps)FdCvjh(ey!m(-?RBP&aSq)0=9^;N|7TK8?1@&HCTd*dG4VD;l zY0C=RZLYa}j)+aj>mJ61glu|0Ul|vtZ*I=ZpmfZbNyPPAvaTRYzd)7g)tMeX?l|Dt zpaMC-NWfD{FK8DBOM^uax<%#Xa!ipelZ&yL^e44}^c)=a0NpMvDR{&xWnj^Jd3!T4 zFksdfegu46&7f_txb*J{p#%m-#_o*6X<9k@L%BIQ8q&!MTnv{kUE(qeLxt@ZYEi(| z;7snR`cM#JS*?{bu}G##I8GOyjg%iH64f=udnG0MS*Iw(?*?&A>Ey9zL7AFD+o(5_ z`D4q({#S+U`M+|rziHh;bxPsVSn)Zl(EmHV+t~W_ky_XF-UmrYzzCgVCp90cTV4A< DicEex diff --git a/docs/src/man/D_500_blas.png b/docs/src/man/D_500_blas.png deleted file mode 100644 index 6e29383760dbb7952f4fbf40640ce6398841583a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17064 zcmaic1yohvx9&kv51?=a5eb1Kf|P)Cmnceir-GD-bV>a103y;U5+V)KA&mmkEg+4A zbT?9O9{=~=|GVS9H!eB`oXy^A&$ZT!Z_fEG0+bY_ui#VQBM^uyj~_{?AQ0!Y5D1)5 z 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 diff --git a/docs/src/man/D_500_strided.png b/docs/src/man/D_500_strided.png deleted file mode 100644 index d7a896e8cb2417cebb90057c3a90853a72f3cb62..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21638 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 KIbO97Nd6Dy$y=`g diff --git a/docs/src/man/algorithms.md b/docs/src/man/algorithms.md deleted file mode 100644 index aa84d909e..000000000 --- a/docs/src/man/algorithms.md +++ /dev/null @@ -1,399 +0,0 @@ -```@meta -DocTestSetup = :(using MPSKit, TensorKit, MPSKitModels) -``` - -# [Algorithms](@id um_algorithms) - -Here is a collection of the algorithms that have been added to MPSKit.jl. -If a particular algorithm is missing, feel free to let us know via an issue, or contribute via a PR. - -## Groundstates - -One of the most prominent use-cases of MPS is to obtain the ground state of a given (quasi-) one-dimensional quantum Hamiltonian. -In MPSKit.jl, this can be achieved through `find_groundstate`: - -```@docs; canonical=false -find_groundstate -``` - -There are a variety of algorithms that have been developed over the years, and many of them have been implemented in MPSKit. -Keep in mind that some of them are exclusive to finite or infinite systems, while others may work for both. -Many of these algorithms have different advantages and disadvantages, and figuring out the optimal algorithm is not always straightforward, since this may strongly depend on the model. -Here, we enumerate some of their properties in hopes of pointing you in the right direction. For convenience, the full list of algorithms is: - -- [DMRG](@ref) -- [DMRG2](@ref) -- [VUMPS](@ref) -- [Gradient descent](@ref) -- [TDVP](@ref) -- [Time evolution MPO](@ref) -- [Quasiparticle Ansatz](@ref) -- [Finite excitations](@ref) -- ["Chepiga Ansatz"](@ref) - -### DMRG - -Probably the most widely used algorithm for optimizing groundstates with MPS is [`DMRG`](@ref) and its variants. -This algorithm sweeps through the system, optimizing a single site or pair of sites while keeping all others fixed. -Since this local problem can be solved efficiently, the global optimal state follows by alternating through the system. -However, because of the single-site nature of this algorithm, this can never alter the bond dimension of the state, such that there is no way of dynamically increasing the precision. -This can become particularly relevant in the cases where symmetries are involved, since then finding a good distribution of charges is also required. -To circumvent this, it is also possible to optimize over two sites at the same time with [`DMRG2`](@ref), followed by a truncation back to the single site states. -This can dynamically change the bond dimension but comes at an increase in cost. - -```@docs; canonical=false -DMRG -DMRG2 -``` - -For infinite systems, a similar approach can be used by dynamically adding new sites to the middle of the system and optimizing over them. -This gradually increases the system size until the boundary effects are no longer felt. -However, because of this approach, for critical systems this algorithm can be quite slow to converge, since the number of steps needs to be larger than the correlation length of the system. -Again, both a single-site and a two-site version are implemented, to have the option to dynamically increase the bonddimension at a higher cost. - -```@docs; canonical=false -IDMRG -IDMRG2 -``` - -### VUMPS - -[`VUMPS`](@ref) is an (I)DMRG inspired algorithm that can be used to variationally find the ground state as a Uniform (infinite) Matrix Product State. -In particular, a local update is followed by a re-gauging procedure that effectively replaces the entire network with the newly updated tensor. -Compared to IDMRG, this often achieves a higher rate of convergence, since updates are felt throughout the system immediately. -Nevertheless, this algorithm only works whenever the state is injective, i.e. there is a unique ground state. -Since VUMPS is a single-site algorithm, it cannot alter the bond dimension. - -```@docs; canonical=false -VUMPS -``` - -### Gradient descent - -Both finite and infinite matrix product states can be parametrized by a set of isometric tensors, -which we can optimize over. -Making use of the geometry of the manifold (a Grassmann manifold), we can greatly outperform naive optimization strategies. -Compared to the other algorithms, quite often the convergence rate in the tail of the optimization procedure is higher, such that often the fastest method combines a different algorithm far from convergence with this algorithm close to convergence. -Since this is again a single-site algorithm, there is no way to alter the bond dimension. - -```@docs; canonical=false -GradientGrassmann -``` - -## Time evolution - -Given a particular state, it can also often be useful to examine the evolution of certain properties over time. -To that end, there are two main approaches to solving the Schrödinger equation in MPSKit. - -```math -i \hbar \frac{d}{dt} \Psi = H \Psi \implies \Psi(t) = \exp{\left(-iH(t - t_0)\right)} \Psi(t_0) -``` - -```@docs; canonical=false -timestep -time_evolve -make_time_mpo -``` - -### TDVP - -The first is focused around approximately solving the equation for a small timestep, and repeating this until the desired evolution is achieved. -This can be achieved by projecting the equation onto the tangent space of the MPS, and then solving the results. -This procedure is commonly referred to as the [`TDVP`](@ref) algorithm, which again has a two-site variant to allow for dynamically altering the bond dimension. - -```@docs; canonical=false -TDVP -TDVP2 -``` - -### Time evolution MPO - -The other approach instead tries to first approximately represent the evolution operator, and only then attempts to apply this operator to the initial state. -Typically the first step happens through [`make_time_mpo`](@ref), while the second can be achieved through [`approximate`](@ref). -Here, there are several algorithms available - -```@docs; canonical=false -WI -WII -TaylorCluster -``` - -## Excitations - -It might also be desirable to obtain information beyond the lowest energy state of a given system, and study the dispersion relation. -While it is typically not feasible to resolve states in the middle of the energy spectrum, there are several ways to target a few of the lowest-lying energy states. - -```@docs; canonical=false -excitations -``` - -```@setup excitations -using TensorKit, MPSKit, MPSKitModels -``` - -### Quasiparticle Ansatz - -The Quasiparticle Ansatz offers an approach to compute low-energy eigenstates in quantum -systems, playing a key role in both finite and infinite systems. It leverages localized -perturbations for approximations, as detailed in [haegeman2013](@cite). - -#### Finite Systems: - -In finite systems, we approximate low-energy states by altering a single tensor in the -Matrix Product State (MPS) for each site, and summing these across all sites. This method -introduces additional gauge freedoms, utilized to ensure orthogonality to the ground state. -Optimizing within this framework translates to solving an eigenvalue problem. For example, -in the transverse field Ising model, we calculate the first excited state as shown in the -provided code snippet, and check the accuracy against theoretical values. Some deviations -are expected, both due to finite-bond-dimension and finite-size effects. - -```@example excitations -# Model parameters -g = 10.0 -L = 16 -H = transverse_field_ising(FiniteChain(L); g) - -# Finding the ground state -ψ₀ = FiniteMPS(L, ℂ^2, ℂ^32) -ψ, = find_groundstate(ψ₀, H; verbosity=0) - -# Computing excitations using the Quasiparticle Ansatz -Es, ϕs = excitations(H, QuasiparticleAnsatz(), ψ; num=1) -isapprox(Es[1], 2(g - 1); rtol=1e-2) -``` - -#### Infinite Systems: - -The ansatz in infinite systems maintains translational invariance by perturbing every site -in the unit cell in a plane-wave superposition, requiring momentum specification. The -[Haldane gap](https://iopscience.iop.org/article/10.1088/0953-8984/1/19/001) computation in -the Heisenberg model illustrates this approach. - -```@example excitations -# Setting up the model and momentum -momentum = π -H = heisenberg_XXX() - -# Ground state computation -ψ₀ = InfiniteMPS(ℂ^3, ℂ^48) -ψ, = find_groundstate(ψ₀, H; verbosity=0) - -# Excitation calculations -Es, ϕs = excitations(H, QuasiparticleAnsatz(), momentum, ψ) -isapprox(Es[1], 0.41047925; atol=1e-4) -``` - -#### Charged excitations: - -When dealing with symmetric systems, the default optimization is for eigenvectors with -trivial total charge. However, quasiparticles with different charges can be obtained using -the sector keyword. For instance, in the transverse field Ising model, we consider an -excitation built up of flipping a single spin, aligning with `Z2Irrep(1)`. - -```@example excitations -g = 10.0 -L = 16 -H = transverse_field_ising(Z2Irrep, FiniteChain(L); g) -ψ₀ = FiniteMPS(L, Z2Space(0 => 1, 1 => 1), Z2Space(0 => 16, 1 => 16)) -ψ, = find_groundstate(ψ₀, H; verbosity=0) -Es, ϕs = excitations(H, QuasiparticleAnsatz(), ψ; num=1, sector=Z2Irrep(1)) -isapprox(Es[1], 2(g - 1); rtol=1e-2) # infinite analytical result -``` - -```@docs; canonical=false -QuasiparticleAnsatz -``` - -### Finite excitations - -For finite systems we can also do something else - find the state that minimizes the energy of a -modified Hamiltonian - -```math -H_n = H + \text{weight} \sum_{i < n} | \psi_i ⟩ ⟨ \psi_i | -``` - -which adds an energy penalty for overlapping with the ground state and all previously found -excited states ``\psi_i``, ``i < n``. -This pushes the optimization towards higher excited states while enforcing (approximate) -orthogonality with the ones already found. -This is also supported by calling - -```@example excitations -# Model parameters -g = 10.0 -L = 16 -H = transverse_field_ising(FiniteChain(L); g) - -# Finding the ground state -ψ₀ = FiniteMPS(L, ℂ^2, ℂ^32) -ψ, = find_groundstate(ψ₀, H; verbosity=0) - -Es, ϕs = excitations(H, FiniteExcited(), ψ; num=1) -isapprox(Es[1], 2(g - 1); rtol=1e-2) -``` - -```@docs; canonical=false -FiniteExcited -``` - -### "Chepiga Ansatz" - -Computing excitations in critical systems poses a significant challenge due to the diverging -correlation length, which requires very large bond dimensions. However, we can leverage this -long-range correlation to effectively identify excitations. In this context, the left/right -gauged MPS, serving as isometries, are effectively projecting the Hamiltonian into the -low-energy sector. This projection method is particularly effective in long-range systems, -where excitations are distributed throughout the entire system. Consequently, the low-lying -energy spectrum can be extracted by diagonalizing the effective Hamiltonian (without any -additional DMRG costs!). The states of these excitations are then represented by the ground -state MPS, with one site substituted by the corresponding eigenvector. This approach is -often referred to as the 'Chepiga ansatz', named after one of the authors of this paper -[chepiga2017](@cite). - -This is supported via the following syntax: - -```@example excitations -g = 10.0 -L = 16 -H = transverse_field_ising(FiniteChain(L); g) -ψ₀ = FiniteMPS(L, ComplexSpace(2), ComplexSpace(32)) -ψ, envs, = find_groundstate(ψ₀, H; verbosity=0) -E₀ = real(sum(expectation_value(ψ, H, envs))) -Es, ϕs = excitations(H, ChepigaAnsatz(), ψ, envs; num=1) -isapprox(Es[1] - E₀, 2(g - 1); rtol=1e-2) # infinite analytical result -``` - -In order to improve the accuracy, a two-site version also exists, which varies two -neighbouring sites: - -```@example excitations -Es, ϕs = excitations(H, ChepigaAnsatz2(), ψ, envs; num=1) -isapprox(Es[1] - E₀, 2(g - 1); rtol=1e-2) # infinite analytical result -``` - -## `changebonds` - -Many of the previously mentioned algorithms do not possess a way to dynamically change to -bond dimension. This is often a problem, as the optimal bond dimension is often not a priori -known, or needs to increase because of entanglement growth throughout the course of a -simulation. [`changebonds`](@ref) exposes a way to change the bond dimension of a given -state. - -```@docs; canonical=false -changebonds -``` - -There are several different algorithms implemented, each having their own advantages and -disadvantages: - -* [`SvdCut`](@ref): The simplest method for changing the bonddimension is found by simply - locally truncating the state using an SVD decomposition. This yields a (locally) optimal - truncation, but clearly cannot be used to increase the bond dimension. Note that a - globally optimal truncation can be obtained by using the [`SvdCut`](@ref) algorithm in - combination with [`approximate`](@ref). Since the output of this method might have a - truncated bonddimension, the new state might not be identical to the input state. - The truncation is controlled through `trscheme`, which dictates how the singular values of - the original state are truncated. - - -* [`OptimalExpand`](@ref): This algorithm is based on the idea of expanding the bond - dimension by investigating the two-site derivative, and adding the most important blocks - which are orthogonal to the current state. From the point of view of a local two-site - update, this procedure is *optimal*, but it requires to evaluate a two-site derivative, - which can be costly when the physical space is large. The state will remain unchanged, but - a one-site scheme will now be able to push the optimization further. The subspace used for - expansion can be truncated through `trscheme`, which dictates how many singular values will - be added. - -* [`RandExpand`](@ref): This algorithm similarly adds blocks orthogonal to the current - state, but does not attempt to select the most important ones, and rather just selects - them at random. The advantage here is that this is much cheaper than the optimal expand, - and if the bond dimension is grown slow enough, this still obtains a very good expansion - scheme. Again, The state will remain unchanged and a one-site scheme will now be able to - push the optimization further. The subspace used for expansion can be truncated through - `trscheme`, which dictates how many orthogonal vectors will be added. - -* [`VUMPSSvdCut`](@ref): This algorithm is based on the [`VUMPS`](@ref) algorithm, and - consists of performing a two-site update, and then truncating the state back down. Because - of the two-site update, this can again become expensive, but the algorithm has the option - of both expanding as well as truncating the bond dimension. Here, `trscheme` controls the - truncation of the full state after the two-site update. - -## Leading boundary - -For statistical mechanics partition functions we want to find the approximate leading -boundary MPS. Again this can be done with VUMPS: - -```julia -th = nonsym_ising_mpo() -ts = InfiniteMPS([ℂ^2],[ℂ^20]); -(ts,envs,_) = leading_boundary(ts,th,VUMPS(maxiter=400,verbosity=0)); -``` - -If the mpo satisfies certain properties (positive and hermitian), it may also be possible to -use GradientGrassmann. - -```@docs; canonical=false -leading_boundary -``` - -## `approximate` - -Often, it is useful to approximate a given MPS by another, typically by one of a different -bond dimension. This is achieved by approximating an application of an MPO to the initial -state, by a new state. - -```@docs; canonical=false -approximate -``` - -## Varia - -What follows is a medley of lesser known (or used) algorithms and don't entirely fit under -one of the above categories. - -### Dynamical DMRG - -Dynamical DMRG has been described in other papers and is a way to find the propagator. The -basic idea is that to calculate ``G(z) = ⟨ V | (H-z)^{-1} | V ⟩ `` , one can variationally -find ``(H-z) |W ⟩ = | V ⟩ `` and then the propagator simply equals ``G(z) = ⟨ V | W ⟩``. - -```@docs; canonical=false -propagator -DynamicalDMRG -NaiveInvert -Jeckelmann -``` - -### fidelity susceptibility - -The fidelity susceptibility measures how much the ground state changes when tuning a -parameter in your Hamiltonian. Divergences occur at phase transitions, making it a valuable -measure when no order parameter is known. - -```@docs; canonical=false -fidelity_susceptibility -``` - -### Boundary conditions - -You can impose periodic or open boundary conditions on an infinite Hamiltonian, to generate a finite counterpart. -In particular, for periodic boundary conditions we still return an MPO that does not form a closed loop, such that it can be used with regular matrix product states. -This is straightforward to implement but, and while this effectively squares the bond dimension, it is still competitive with more advanced periodic MPS algorithms. - -```@docs; canonical=false -open_boundary_conditions -periodic_boundary_conditions -``` - -### Exact diagonalization - -As a side effect, our code supports exact diagonalization. The idea is to construct a finite -matrix product state with maximal bond dimension, and then optimize the middle site. Because -we never truncate the bond dimension, this single site effectively parametrizes the entire -Hilbert space. - -```@docs; canonical=false -exact_diagonalization -``` diff --git a/docs/src/man/environments.md b/docs/src/man/environments.md deleted file mode 100644 index 6d431e05e..000000000 --- a/docs/src/man/environments.md +++ /dev/null @@ -1,66 +0,0 @@ -# [Environments](@id um_environments) - -In many tensor network algorithms we encounter partially contracted tensor networks. -In DMRG for example, one needs to know the sum of all the Hamiltonian contributions left and right of the site that we want to optimize. -If you then optimize the neighboring site to the right, you only need to add one new contribution to the previous sum of Hamiltonian contributions. - -This kind of information is stored in the environment objects. -The goal is that the user should preferably never have to deal with these objects, but being aware of the inner workings may allow you to write more efficient code. -That is why they are nonetheless included in the manual. - -## Finite Environments - -When you create a state and a Hamiltonian: - -```julia -state = FiniteMPS(rand, ComplexF64, 20, ℂ^2, ℂ^10); -operator = nonsym_ising_ham(); -``` - -an environment object can be created by calling -```julia -envs = environments(state, operator, state) -``` - -The partially contracted mpohamiltonian left of site i can then be queried using: - -```julia -@time leftenv(envs, i, state) -``` - -This may take some time, but a subsequent call should be a lot quicker - -```julia -@time leftenv(envs, i - 1, state) -``` - -Behind the scenes the `envs` stored all tensors it used to calculate leftenv (state.AL[1 .. i]) and when queried again, it checks if the tensors it previously used are identical (using ===). If so, it can simply return the previously stored results. If not, it will recalculate again. If you update a tensor in-place, the caches cannot know using === that the actual tensors have changed. If you do this, you have to call poison!(state,i). - -As an optional argument, many algorithms allow you to pass in an environment object, and they also return an updated one. Therefore, for time evolution code, it is more efficient to give it the updated caches every time step, instead of letting it recalculate. - -## Infinite Environments - -Infinite Environments are very similar : -```julia -state = InfiniteMPS(ℂ^2, ℂ^10) -operator = transverse_field_ising() -envs = environments(state, operator, state) -``` - -There are also some notable differences. Infinite environments typically require solving linear problems or eigenvalue problems iteratively with finite precision. To find out what precision we used we can type: -```julia -(cache.tol,cache.maxiter) -``` - -To recalculate with a different precision : -```julia -cache.tol=1e-8; -recalculate!(cache,state) -``` - -Unlike their finite counterparts, recalculating is not done automatically. To get the environment for a different state one has to recalculate explicitly! -```julia -different_state = InfiniteMPS([ℂ^2],[ℂ^10]); -recalculate!(cache,different_state) -leftenv(cache,3,different_state) -``` diff --git a/docs/src/man/finite_mps_definition.png b/docs/src/man/finite_mps_definition.png deleted file mode 100644 index 9ad9776b4c33c3d067c73d4f844dbf42ccb3274f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2622 zcmb_eX;2gC7VRV^ku9<)OIQU&Q4xg%Bw$dMkjSPigX{qW!V&~U1Oy4AjtB%09D#sF zBnm+g6a+>Qn-Rr@W!QI!IvQdSQ1*bs>%4k@-miI8^Qx=vJ?GXveY?KuKDVzPbF!0> z#7Y7HAVVSBxBvj01!1?%C@5;jfqET}Wu{oF`=>>!-39a(N9mMg-;sSC^B55b#weo|~#K*9LEn}E< zU5GVHT5MC-2IYAu-ns50ujU-7&ar90o>V5dG^G{PC=-8>V8iGKpQhSfJd?>aCx9vM zv9DVEX)PfLVX1YU;3)4{Y#PQJRjjIhN2UwzVRL134eEq4MAphfk~`6Qq${)+Q5BwS zdu7cPX4e4Gt*PhdTB~ z;&xDSuU}@~)1~A-s_DM2OL0;BA4Rt2%+I>ifElgCi9`mndpquq0Mr+!La=yB7JJ-~ zOWIwQ0MnZfr}0YT(Cmis76-)wqTkYv_{DuH)Nlk~d>%n9VHJ%V0#LPQsVrhM7#nxXfA} z!xT7${s|}>BqD}}hfjnD7}a3n_biGWDt|Pb|JjK9;EEf&0SL|gVjO>gF8P-8q!4_{ zFok7Mls>kg>G`rRiySMugp6P??63z-8_%+?=(;RjoqaaFL3TwpT7zqHCW5WG*}m^~ z(Zb2+SzBjtyjI1OC{%PD`V78EDSn#l3*KjBkWF79rIQaT<1&Us3n&fqo=q~d~du##?`8>1u)2t zh4PWuyZxq)jzPBX8jOVok8`Bv9D2-f zF3BNs-faEUwk+JWh0{Tb0yV6lV+eZWUInP@5JxWsQ)(&Qv9q4|K0@~5LQW@JB{NAz zpzVv;61Uq;YE3nzKql!ru48!%Zx>gJh+1##eZ%r0;U~j8QN-h;vq&Q88Lxi>56c3Mnkq^A7ygo%SS}Lq#n)u5A|M7OgmkKYoOy5Syk|)@~ z!Sk7m38;7q`3Z`7>h&$4*=IB{bs4CJ-7xxIgge^_2=J?moSm=jDM|vOkB%!U8^|B5 zx8*DvRcql()0g*0+tQzJS<#v^;voaB_R)4OiYkGLEtNYQ*Yqb$dJdtfc!6js&?4n+ zpz2)e$X~3Hzrq72ahj$s2s0q5q<-erA}%LnPz%pmgV)j;*UC+A-X{;5|JrtA1jQAM$rT`JvyPt*(_PIDd5yX` z`CWQfWl3O=9v>11yf_3;TjsL;h1>t(2mQA$kTD}2)Ct?SFTTAWT$a+PtxyE24ddHC zA+tS#?HTiu8nxBDZxxZq=%|(;sH|4DFw=mBRd5K60sM*p6VZ7wnQ! zI}?%`MgtbP<`gBR)M)==!Iv@0{+-0sb(&O@6v;NTjwedT$Fc{aL7m zhgg{z*ri@WyvxV_pKS1NPwl@A_em+DPT&uccvNUfEMg#2Jwpg`8 zmJtk108M_bv_zvnM>hgP8cL2F?3hEv8wyx5GJq&XOlM{2@zlY7@Ca2=FcPO+AYJUf z<{3l8L~8x$T=C;c^x&hkYt#X7QN>_Jj>R1aJ{isSWg!97J#|TjpHCNs*uG*g5rQU!V>Y5Xc z$*CN@>H25iYO(=w^hn}cw@Mw37w&0x?C*O9V7H&Y|m<*dgZ3bVjde5&qNcYo&)G29_ zcW$5{!}KR1kK6y~6Mn2qSRHeGMsz9?rkpkjJG!(V8qj^2leZ3tL1GW0#jn`Ju(U-m zKMt<*_F`xDaIWw#h)dovBR&mJ|61$djIErJj3|fz4xDi)wCaH3F)RQt+V-c`L0R=(r=c8G%wbs pF)J@^&i6veq>FW%Y`1;WOvx$wO83S{K|h25#n#E@ffe=Ve*xTs!w3KX diff --git a/docs/src/man/intro.md b/docs/src/man/intro.md deleted file mode 100644 index ee6c3ddeb..000000000 --- a/docs/src/man/intro.md +++ /dev/null @@ -1,93 +0,0 @@ -# Prerequisites - -The following sections describe the prerequisites for using MPSKit. If you are already -familiar with the concepts of MPSKit and TensorKit, you can skip to the [Conventions](@ref) -sections. - -## TensorKit - -```@example tensorkit -using TensorKit -``` - -MPSKit uses the tensors defined in [TensorKit.jl](https://github.com/Jutho/TensorKit.jl) as -its underlying data structure. This is what allows the library to be generic with respect to -the symmetry of the tensors. The main difference with regular multi-dimensional arrays is -the notion of a partition of the dimensions in **incoming** and **outgoing**, which are -respectively called **domain** and **codomain**. In other words, a `TensorMap` can be -interpreted as a linear map from its domain to its codomain. Additionally, as generic -symmetries are supported, in general the structure of the indices are not just integers, but -are given by spaces. - -The general syntax for creating a tensor is similar to the creation of arrays, where the -`axes` or `size` specifiers are replaced with `VectorSpace` objects: -```julia -zeros(scalartype, codomain, domain) -rand(scalartype, codomain ← domain) # ← is the `\leftarrow` operator -``` - -For example, the following creates a random tensor with three legs, each of which has -dimension two, however with different partitions. - -```@example tensorkit -V1 = ℂ^2 # ℂ is the `\bbC` operator, equivalent to ComplexSpace(10) -t1 = rand(Float64, V1 ⊗ V1 ⊗ V1) # all spaces in codomain -t2 = rand(Float64, V1, V1 ⊗ V1) # one space in codomain, two in domain -``` - -We can now no longer trivially add them together: - -```@example tensorkit -try #hide -t1 + t2 # incompatible partition -catch err; Base.showerror(stderr, err); end #hide -``` -But this can be resolved by permutation: - -```@example tensorkit -try #hide -t1 + permute(t2, (1, 2, 3), ()) # incompatible arrows -catch err; Base.showerror(stderr, err); end #hide -``` - -These abstract objects can represent not only plain arrays but also symmetric tensors. The -following creates a symmetric tensor with ℤ₂ symmetry, again with three legs of dimension -two. However, now the dimension two is now split over even and odd sectors of ℤ₂. - -```@example tensorkit -V2 = Z2Space(0 => 1, 1 => 1) -t3 = rand(Float64, V2 ⊗ V2, V2) -``` - -For more information, check out the [TensorKit documentation](https://quantumkithub.github.io/TensorKit.jl/stable/)! - -## Conventions - -The general definition of an MPS tensor is as follows: - -```@raw html -convention MPSTensor -``` - -These tensors are allowed to have an arbitrary number of physical legs, and both `FiniteMPS` -as well as `InfiniteMPS` will be able to handle the resulting objects. This allows for -example for the definition of boundary tensors in PEPS code, which have two physical legs. - -Similarly, the definition of a bond tensor, appearing in between two MPS tensors, is as -follows: - -```@raw html -convention BondTensor -``` - -Finally, the definition of a MPO tensor, which is used to represent statistical mechanics -problems as well as quantum Hamiltonians, is represented as: - -```@raw html -convention MPOTensor -``` - -While this results at first glance in the not very intuitive ordering of spaces as $V_l -\otimes P \leftarrow P \otimes V_r$, this is actually the most natural ordering for keeping -the algorithms planar. In particular, this is relevant for dealing with fermionic systems, -where additional crossings would lead to sign problems. diff --git a/docs/src/man/mps_gauge_freedom.png b/docs/src/man/mps_gauge_freedom.png deleted file mode 100644 index 15dc6648fa4e099335538e6df73afd8f081301b5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6206 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 -``` - -```@example operators -using TensorKit, MPSKit, MPSKitModels -using TensorKitTensors.SpinOperators: σˣ, σᶻ - -X = σˣ() -Z = σᶻ() -O_xzx = FiniteMPO(X ⊗ Z ⊗ X); -``` - -The individual tensors are accessible via regular indexing. Note that the tensors are -internally converted to the `MPOTensor` objects, thus having four indices. In this specific -case, the left- and right virtual spaces are trivial, but this is not a requirement. - -```@example operators -O_xzx[1] -``` - -!!! warning - The local tensors are defined only up to a gauge transformation of the virtual spaces. - This means that the tensors are not uniquely defined, and special care must be taken - when comparing MPOs on an element-wise basis. - -For convenience, a number of utility functions are defined for probing the structure of the -constructed MPO. For example, the spaces can be queried as follows: - -```@example operators -left_virtualspace(O_xzx, 2) -right_virtualspace(O_xzx, 2) -physicalspace(O_xzx, 2) -``` - -MPOs also support a range of linear algebra operations, such as addition, subtraction and -multiplication, either among themselves or with a finite MPS. Here, it is important to note -that these operations will increase the virtual dimension of the resulting MPO or MPS, and -this naive application is thus typically not optimal. For approximate operations that do not -increase the virtual dimension, the more advanced algorithms in the [um_algorithms](@ref) -sections should be used. - -```@example operators -O_xzx² = O_xzx * O_xzx -println("Virtual dimension of O_xzx²: ", left_virtualspace(O_xzx², 2)) -O_xzx_sum = 0.1 * O_xzx + O_xzx² -println("Virtual dimension of O_xzx_sum: ", left_virtualspace(O_xzx_sum, 2)) -``` - -```@example operators -O_xzx_sum * FiniteMPS(3, ℂ^2, ℂ^4) -``` - -!!! note - The virtual spaces of the resulting MPOs typically grow exponentially with the - number of multiplications. Nevertheless, a number of optimizations are in place that - make sure that the virtual spaces do not increase past the maximal virtual space that - is dictated by the requirement of being full-rank tensors. - -## InfiniteMPO - -This construction can again be extended to the infinite case, where the tensors are repeated periodically. -Therefore, an [`InfiniteMPO`](@ref) is simply a `PeriodicVector` of `MPOTensor` objects. -These can only be constructed from vectors of `MPOTensor`s, since it is impossible to create the infinite operators directly. - -```@example operators -mpo = InfiniteMPO(O_xzx[1:2]) -``` - -Otherwise, their behavior is mostly similar to that of their finite counterparts. - -## FiniteMPOHamiltonian - -We can also represent quantum Hamiltonians in the same form. This is done by converting a -sum of local operators into a single MPO operator. The resulting operator has a very -specific structure, and is often referred to as a *Jordan block MPO*. - -This object can be constructed as an MPO by using the [`FiniteMPOHamiltonian`](@ref) constructor, -which takes two crucial pieces of information: - -1. An array of `VectorSpace` objects, which determines the local Hilbert spaces of the - system. The resulting MPO will snake through the array in linear indexing order. - -2. A set of local operators, which are characterised by a number of indices that specify on - which sites the operator acts, along with an operator to define the action. These are - specified as a `inds => operator` pairs, or any other iterable collection thereof. The - `inds` should be tuples of valid indices for the array of `VectorSpace` objects, or a - single integer for single-site operators. - -As a concrete example, we consider the -[Transverse-field Ising model](https://en.wikipedia.org/wiki/Transverse-field_Ising_model) -defined by the Hamiltonian - -```math -H = -J \sum_{\langle i, j \rangle} X_i X_j - h \sum_j Z_j -``` - -```@example operators -J = 1.0 -h = 0.5 -chain = fill(ℂ^2, 3) # a finite chain of 3 sites, each with a 2-dimensional Hilbert space -single_site_operators = [1 => -h * Z, 2 => -h * Z, 3 => -h * Z] -two_site_operators = [(1, 2) => -J * X ⊗ X, (2, 3) => -J * X ⊗ X] -H_ising = FiniteMPOHamiltonian(chain, single_site_operators..., two_site_operators...) -``` - -Various alternative constructions are possible, such as using a `Dict` with key-value pairs -that specify the operators, or using generator expressions to simplify the construction. - -```@example operators -H_ising′ = -J * FiniteMPOHamiltonian(chain, - (i, i + 1) => X ⊗ X for i in 1:(length(chain) - 1)) - - h * FiniteMPOHamiltonian(chain, i => Z for i in 1:length(chain)) -isapprox(H_ising, H_ising′; atol=1e-6) -``` - -Note that this construction is not limited to nearest-neighbour interactions, or 1D systems. -In particular, it is possible to construct quasi-1D realisations of 2D systems, by using -different arrays of [`VectorSpace`](@extref TensorKit.VectorSpace) objects. -For example, the 2D Ising model on a square lattice can be constructed as follows: - -```@example operators -square = fill(ℂ^2, 3, 3) # a 3x3 square lattice -operators = Dict() - -local_operators = Dict() -for I in eachindex(square) - local_operators[(I,)] = -h * Z # single site operators still require tuples of indices -end - -# horizontal and vertical interactions are easier using Cartesian indices -horizontal_operators = Dict() -I_horizontal = CartesianIndex(0, 1) -for I in eachindex(IndexCartesian(), square) - if I[2] < size(square, 2) - horizontal_operators[(I, I + I_horizontal)] = -J * X ⊗ X - end -end - -vertical_operators = Dict() -I_vertical = CartesianIndex(1, 0) -for I in eachindex(IndexCartesian(), square) - if I[1] < size(square, 1) - vertical_operators[(I, I + I_vertical)] = -J * X ⊗ X - end -end - -H_ising_2d = FiniteMPOHamiltonian(square, local_operators) + - FiniteMPOHamiltonian(square, horizontal_operators) + - FiniteMPOHamiltonian(square, vertical_operators); -``` - -There are various utility functions available for constructing more advanced lattices, for -which the [MPSKitModels.jl](https://quantumkithub.github.io/MPSKitModels.jl/dev/) -documentation should be consulted. - -## InfiniteMPOHamiltonian - -Again, this construction can be extended straightforwardly to the infinite case. -To that end, we simply need to specify all interactions per unit cell. -In particular, an [`InfiniteMPOHamiltonian`](@ref) for the Ising model is obtained via - -```@example operators -J = 1.0 -h = 0.5 -infinite_chain = PeriodicVector([ℂ^2]) # an infinite chain of a local 2-dimensional Hilbert space -H_ising_infinite = InfiniteMPOHamiltonian(infinite_chain, 1 => -h * Z, (1, 2) => -J * X ⊗ X) -``` - -### Expert mode - -The `MPOHamiltonian` constructor is in fact an automated way of constructing the -aforementioned *Jordan block MPO*. In its most general form, the matrix $W$ takes on the -form of the following block matrix: - -```math -\begin{pmatrix} -1 & C & D \\ -0 & A & B \\ -0 & 0 & 1 -\end{pmatrix} -``` - -which generates all single-site local operators $D$, all two-site operators $CB$, three-site -operators $CAB$, and so on. Additionally, this machinery can also be used to construct -interaction that are of (exponentially decaying) infinite range, and to approximate -power-law interactions. - -In order to illustrate this, consider the following explicit example of the Transverse-field -Ising model: - -```math -W = \begin{pmatrix} -1 & X & -hZ \\ -0 & 0 & -JX \\ -0 & 0 & 1 -\end{pmatrix} -``` - -If we add in the left and right boundary vectors - -```math -v_L = \begin{pmatrix} -1 & 0 & 0 -\end{pmatrix} -, \qquad -v_R = \begin{pmatrix} -0 \\ 0 \\ 1 -\end{pmatrix} -``` - -One can easily check that the Hamiltonian on $N$ sites is given by the contraction - -```math -H = V_L W^{\otimes N} V_R -``` - -We can even verify this symbolically: - -```@example operators -using Symbolics -L = 4 -# generate W matrices -@variables A[1:L] B[1:L] C[1:L] D[1:L] -Ws = map(1:L) do l - return [1 C[l] D[l] - 0 A[l] B[l] - 0 0 1] -end - -# generate boundary vectors -Vₗ = [1, 0, 0]' -Vᵣ = [0, 0, 1] - -# expand the MPO -expand(Vₗ * prod(Ws) * Vᵣ) -``` - -The [`FiniteMPOHamiltonian`](@ref) constructor can also be used to construct the operator from this most -general form, by supplying a vector of [`BlockTensorMap`](@extref BlockTensorKit.BlockTensorMap) objects -to the constructor. Here, the vector specifies the sites in the unit cell, while the blocktensors contain -the rows and columns of the matrix. We can verify this explicitly: - -```@example operators -H_ising[2] # print the blocktensor -``` - -### Working with `MPOHamiltonian` objects - -!!! warning - This part is still a work in progress - -Because of the discussion above, the `FiniteMPOHamiltonian` object is in fact just an `AbstractMPO`, -with some additional structure. This means that similar operations and properties are -available, such as the virtual spaces, or the individual tensors. However, the block -structure of the operator means that now the virtual spaces are not just a single space, but -a collection (direct sum) of spaces, one for each row/column. - -```@example operators -left_virtualspace(H_ising, 1), right_virtualspace(H_ising, 1), physicalspace(H_ising, 1) -``` diff --git a/docs/src/man/parallelism.md b/docs/src/man/parallelism.md deleted file mode 100644 index c7911ae7c..000000000 --- a/docs/src/man/parallelism.md +++ /dev/null @@ -1,116 +0,0 @@ -# Parallelism in julia - -Julia has great -[parallelism infrastructure](https://julialang.org/blog/2019/07/multithreading/), but there -is a caveat that is relevant for all algorithms implemented in MPSKit. The Julia threads do -not play nicely together with the BLAS threads, which are the threads used for many of the -linear algebra routines, and in particular for `gemm` (general matrix-matrix -multiplication). As this is a core routine in MPSKit, this has a significant impact on the -overall performance. - -## Julia threads vs BLAS threads - -A lot of the confusion stems from the fact that the BLAS threading behaviour is not -consistent between different vendors. Additionally, performance behaviour is severely -dependent on hardware, the specifics of the problem, and the availability of other resources -such as total memory, or memory bandwidth. This means that there is no one size fits all -solution, and that you will have to experiment with the settings to get optimal performance. -Nevertheless, there are some general guidelines that can be followed, which seem to at least -work well in most cases. - -The number of threads that are set by `BLAS.set_num_threads()`, in the case of OpenBLAS (the -default vendor), is equal to the **total number** of BLAS threads that is kept in a pool, -which is then shared by all Julia threads. This means that if you have 4 julia threads and 4 -BLAS threads, then all julia threads will share the same 4 BLAS threads. On the other hand, -using `BLAS.set_num_threads(1)`, OpenBLAS will now utilize the julia threads to run the BLAS -jobs. Thus, for OpenBLAS, very often setting the number of BLAS threads to 1 is the best -option, which will then maximally utilize the julia threading infrastructure of MPSKit. - -In the case of [MKL.jl](https://github.com/JuliaLinearAlgebra/MKL.jl), which often outperforms OpenBLAS, the situation is a bit -different. Here, the number of BLAS threads corresponds to the number of threads that are -spawned by **each** julia thread. Thus, if you have 4 julia threads and 4 BLAS threads, then -each julia thread will spawn 4 BLAS threads, for a total of 16 BLAS threads. As such, it -might become necessary to adapt the settings to avoid oversubscription of the cores. - -A careful analysis of the different cases and benefits can be inspected by making use of -[`ThreadPinning.jl`](https://github.com/carstenbauer/ThreadPinning.jl)'s tool -`threadinfo(; blas=true, info=true)`. In particular, the following might demonstrate the -difference between OpenBLAS and MKL: - -```julia-repl -julia> Threads.nthreads() -4 - -julia> using ThreadPinning; threadinfo(; blas=true, hints=true) - -System: 8 cores (2-way SMT), 1 sockets, 1 NUMA domains - -| 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 | - -# = Julia thread, # = HT, # = Julia thread on HT, | = Socket separator - -Julia threads: 4 -├ Occupied CPU-threads: 4 -└ Mapping (Thread => CPUID): 1 => 8, 2 => 5, 3 => 9, 4 => 2, - -BLAS: libopenblas64_.so -└ openblas_get_num_threads: 8 - -[ Info: jlthreads != 1 && blasthreads < cputhreads. You should either set BLAS.set_num_threads(1) (recommended!) or at least BLAS.set_num_threads(16). -[ Info: jlthreads < cputhreads. Perhaps increase number of Julia threads to 16? -julia> using MKL; threadinfo(; blas=true, hints=true) - -System: 8 cores (2-way SMT), 1 sockets, 1 NUMA domains - -| 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 | - -# = Julia thread, # = HT, # = Julia thread on HT, | = Socket separator - -Julia threads: 4 -├ Occupied CPU-threads: 4 -└ Mapping (Thread => CPUID): 1 => 11, 2 => 12, 3 => 1, 4 => 2, - -BLAS: libmkl_rt.so -├ mkl_get_num_threads: 8 -└ mkl_get_dynamic: true - -┌ Warning: blasthreads_per_jlthread > cputhreads_per_jlthread. You should decrease the number of MKL threads, i.e. BLAS.set_num_threads(4). -└ @ ThreadPinning ~/.julia/packages/ThreadPinning/qV2Cd/src/threadinfo.jl:256 -[ Info: jlthreads < cputhreads. Perhaps increase number of Julia threads to 16? -``` - -## MPSKit multithreading - -Within MPSKit, when Julia is started with multiple threads, by default the `OhMyThreads.jl` -machinery will be used to parallelize the code as much as possible. In particular, this mostly -occurs whenever there is a unitcell and local updates can take place at each site in parallel. - -The multithreading behaviour can be controlled through a global `scheduler`, which can be set -using the `MPSKit.Defaults.set_scheduler!(arg; kwargs...)` function. This function accepts -either a `Symbol`, an `OhMyThreads.Scheduler` or keywords to determine a scheduler automatically. - -```julia -MPSKit.Defaults.set_scheduler!(:serial) # disable multithreading -MPSKit.Defaults.set_scheduler!(:greedy) # multithreading with greedy load-balancing -MPSKit.Defaults.set_scheduler!(:dynamic) # default: multithreading with some load-balancing -``` - -For further reference on the available schedulers and finer control, please refer to the -[`OhMyThreads.jl` documentation](https://juliafolds2.github.io/OhMyThreads.jl/stable/) - -## TensorKit multithreading - -Finally, when dealing with tensors that have some internal symmetry, it is also possible to -parallelize over the symmetry sectors. This is handled by TensorKit, and more information -can be found in its documentation (Soon TM). - -## Memory management - -Because of the way julia threads work, it is possible that the total memory usage of your -program becomes rather high. This seems to be because of the fact that MPSKit spawns several -tasks (in a nested way), which each allocate and deallocate quite a bit of memory in a tight -loop. This seems to lead to a situation where the garbage collector is not able to keep up, -and can even fail to clear the garbage before an `OutOfMemory` error occurs. In this case, -often the best thing to do is disable the multithreading of MPSKit, specifically for the -`derivatives`, as this seems to be the most memory intensive part. This is something that is -under investigation, and hopefully will be fixed in the future. diff --git a/docs/src/man/states.md b/docs/src/man/states.md deleted file mode 100644 index 168b2117c..000000000 --- a/docs/src/man/states.md +++ /dev/null @@ -1,174 +0,0 @@ -# [States](@id um_states) - -```@setup states -using MPSKit -using TensorKit -using LinearAlgebra: dot -``` - -## FiniteMPS - -A [`FiniteMPS`](@ref) is - at its core - a chain of mps tensors. - -```@raw html -finite MPS -``` - -### Usage - -A `FiniteMPS` can be created by passing in a vector of tensormaps: - -```@example states -L = 10 -data = [rand(ComplexF64, ℂ^1 ⊗ ℂ^2 ← ℂ^1) for _ in 1:L]; -state = FiniteMPS(data) -``` - -Or alternatively by specifying its structure - -```@example states -max_bond_dimension = ℂ^4 -physical_space = ℂ^2 -state = FiniteMPS(rand, ComplexF64, L, physical_space, max_bond_dimension) -``` - -You can take dot products, renormalize!, expectation values,.... - -### Gauging and canonical forms - -An MPS representation is not unique: for every virtual bond we can insert $C \cdot C^{-1}$ without altering the state. -Then, by redefining the tensors on both sides of the bond to include one factor each, we can change the representation. - -```@raw html -MPS gauge freedom -``` - -There are two particularly convenient choices for the gauge at a site, the so-called left and right canonical form. -For the left canonical form, all tensors to the left of a site are gauged such that they become left-isometries. -By convention, we call these tensors `AL`. - -```@example states -al = state.AL[3] -al' * al ≈ id(right_virtualspace(al)) -``` - -Similarly, the right canonical form turns the tensors into right-isometries. -By convention, these are called `AR`. - -```@example states -ar = state.AR[3] -repartition(ar, 1, 2) * repartition(ar, 1, 2)' ≈ id(left_virtualspace(ar)) -``` - -It is also possible to mix and match these two forms, where all tensors to the left of a given site are in the left gauge, while all tensors to the right are in the right gauge. -In this case, the final gauge transformation tensor can no longer be absorbed, since that would spoil the gauge either to the left or the right. -This center-gauged tensor is called `C`, which is also the gauge transformation to relate left- and right-gauged tensors. -Finally, for convenience it is also possible to leave a single MPS tensor in the center gauge, which we call `AC = AL * C` - -```@example states -c = state.C[3] # to the right of site 3 -c′ = state.C[2] # to the left of site 3 -al * c ≈ state.AC[3] ≈ repartition(c′ * repartition(ar, 1, 2), 2, 1) -``` - -These forms are often used throughout MPS algorithms, and the [`FiniteMPS`](@ref) object acts as an automatic manager for this. -It will automatically compute and cache the different forms, and detect when to recompute whenever needed. -For example, in order to compute the overlap of an MPS with itself, we can choose any site and bring that into the center gauge. -Since then both the left and right side simplify to the identity, this simply becomes the overlap of the gauge tensors: - -```@example states -d = dot(state, state) -all(c -> dot(c, c) ≈ d, state.C) -``` - -### Implementation details - -Behind the scenes, a `FiniteMPS` has 4 fields - -```julia -ALs::Vector{Union{Missing,A}} -ARs::Vector{Union{Missing,A}} -ACs::Vector{Union{Missing,A}} -Cs::Vector{Union{Missing,B}} -``` - -and calling `AL`, `AR`, `C` or `AC` returns lazy views over these vectors that instantiate the tensors whenever they are requested. -Similarly, changing a tensor will poison the `ARs` to the left of that tensor, and the `ALs` to the right. -The idea behind this construction is that one never has to worry about how the state is gauged, as this gets handled automagically. - -!!! warning - While a `FiniteMPS` can automatically detect when to recompute the different gauges, this requires that one of the tensors is set using an indexing operation. - In particular, in-place changes to the different tensors will not trigger the recomputation. - -## InfiniteMPS - -An [`InfiniteMPS`](@ref) can be thought of as being very similar to a finite mps, where the set of tensors is repeated periodically. - -It can also be created by passing in a vector of `TensorMap`s: - -```@example states -data = [rand(ComplexF64, ℂ^4 ⊗ ℂ^2 ← ℂ^4) for _ in 1:2] -state = InfiniteMPS(data) -``` - -or by initializing it from given spaces - -```@example states -phys_spaces = fill(ℂ^2, 2) -virt_spaces = [ℂ^4, ℂ^5] # by convention to the right of a site -state = InfiniteMPS(phys_spaces, virt_spaces) -``` - -Note that the code above creates an `InfiniteMPS` with a two-site unit cell, where the given virtual spaces are located to the right of their respective sites. - -### Gauging and canonical forms - -Much like for `FiniteMPS`, we can again query the gauged tensors `AL`, `AR`, `C` and `AC`. -Here however, the implementation is much easier, since they all have to be recomputed whenever a single tensor changes. -This is a result of periodically repeating the tensors, every `AL` is to the right of the changed site, and every `AR` is to the left. -As a result, the fields are simply - -```julia -AL::PeriodicArray{A,1} -AR::PeriodicArray{A,1} -C::PeriodicArray{B,1} -AC::PeriodicArray{A,1} -``` - -## WindowMPS - -A [`WindowMPS`](@ref) or segment MPS can be seen as a mix between an [`InfiniteMPS`](@ref) and a [`FiniteMPS`](@ref). -It represents a window of mutable tensors (a finite MPS), embedded in an infinite environment (two infinite MPSs). -It can therefore be created accordingly, ensuring that the edges match: - -```@example states -infinite_state = InfiniteMPS(ℂ^2, ℂ^4) -finite_state = FiniteMPS(5, ℂ^2, ℂ^4; left=ℂ^4, right=ℂ^4) -window = WindowMPS(infinite_state, finite_state, infinite_state) -``` - -Algorithms will then act on this window of tensors, while leaving the left and right infinite states invariant. - -## MultilineMPS - -A two-dimensional classical partition function can often be represented by an infinite tensor network. -There are many ways to evaluate such a network, but here we focus on the so-called boundary MPS methods. -These first reduce the problem from contracting a two-dimensional network to the contraction of a one-dimensional MPS, by finding the fixed point of the row-to-row (or column-to-column) transfer matrix. -In these cases however, there might be a non-trivial periodicity in both the horizontal as well as vertical direction. -Therefore, in MPSKit they are represented by [`MultilineMPS`](@ref), which are simply a repeating set of [`InfiniteMPS`](@ref). - -```@example states -state = MultilineMPS(fill(infinite_state, 2)) -``` - -They offer some convenience functionality for using cartesian indexing (row - column): - -You can access properties by calling -```@example states -row = 2 -col = 2 -al = state.AL[row, col]; -``` - -These objects are also used extensively in the context of [PEPSKit.jl](https://github.com/QuantumKitHub/PEPSKit.jl). - From 0bbf414a5dfafade49fbe24c3d28160abf1edb07 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Wed, 8 Jul 2026 19:53:20 -0400 Subject: [PATCH 61/76] docs(home): fix mps.svg image path so VitePress bundles it The landing-page MPS diagram used a bare relative `assets/mps.svg`, which Rollup treats as a module import and fails to resolve, breaking the full VitePress build. Use an explicit-relative `./assets/mps.svg` (base-path independent, unlike an absolute `/assets/...`), matching the pattern the concept pages use for `../assets/...`. Full `makedocs` build now completes. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/src/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/index.md b/docs/src/index.md index ae1ac5599..0f47057ef 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -75,7 +75,7 @@ Almost every MPSKit calculation follows the same three steps: build a Hamiltonia The transverse-field Ising chain (TFIM) makes each step concrete in a few lines. ```@raw html -A matrix product state: a chain of tensors joined by virtual bonds, each with a physical leg +A matrix product state: a chain of tensors joined by virtual bonds, each with a physical leg ``` A matrix product state is a chain of tensors: the horizontal bonds carry the virtual indices, and the leg hanging off each site is its physical index. From 19e9ad50bf2e64af1d9690dd14426b050944abc6 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Thu, 9 Jul 2026 09:03:55 -0400 Subject: [PATCH 62/76] docs: resolve verified REVIEW flags (code/image/numerics-backed) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clears 13 REVIEW flags that could be verified directly, leaving the physics- judgment ones for maintainer review: - tensor-diagram leg conventions (MPS/bond/MPO/finite-chain) checked against the actual PNGs and the code's Vₗ⊗P ← P⊗Vᵣ ordering - environments: poison!(envs, ind) and recalculate! signatures confirmed; infinite-env precision prose made concrete (tol/maxiter/krylovdim keywords → Arnoldi/GMRES); env-reuse-across-timesteps backed by time_evolve's loop - Jordan-block automaton reading confirmed by the page's own Symbolics expansion and the MPOHamiltonian docstring; MPO product/sum dim arithmetic checked numerically (O+O² → dim 2 = 1+1) - TFIM dispersion is the standard 2√(1+g²-2g cos k); D=12 reproduces the g=2 gap 2(g-1)=2 to 3e-11 (verified numerically) - partition-error note (illustrative, version-dependent text) Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/src/concepts/environments.md | 14 ++++---------- docs/src/concepts/matrix_product_states.md | 2 -- docs/src/concepts/operators_and_hamiltonians.md | 6 +----- docs/src/concepts/parallelism_model.md | 4 +--- docs/src/concepts/vector_spaces.md | 8 -------- docs/src/tutorials/excitations.md | 4 ---- 6 files changed, 6 insertions(+), 32 deletions(-) diff --git a/docs/src/concepts/environments.md b/docs/src/concepts/environments.md index 0969c6db9..6db50030e 100644 --- a/docs/src/concepts/environments.md +++ b/docs/src/concepts/environments.md @@ -49,9 +49,7 @@ What they also do, uniformly, is accept an *optional* environments argument and That return value is the reason to care about environments even when you never construct one. Handing the environments from one call into the next lets the algorithm reuse the cached blocks instead of rebuilding them from nothing. -For iterated procedures such as time evolution — where each step starts from a state only slightly different from the last — feeding the updated environments back in every step avoids repeating work that the previous step already did. - -The [Time evolution](@ref howto_time_evolution) how-to shows this threading pattern in a concrete recipe. +For iterated procedures such as time evolution — where each step starts from a state only slightly different from the last — feeding the updated environments back in every step avoids repeating work that the previous step already did.The [Time evolution](@ref howto_time_evolution) how-to shows this threading pattern in a concrete recipe. ## Finite environments and the `===` cache @@ -76,8 +74,6 @@ Because algorithms that use the public API replace tensors rather than mutating site `i` as stale so the next query recomputes them; needing it is a sign that a tensor was mutated in place rather than replaced. - - ## Infinite environments Infinite environments serve the same role but are computed differently, and the difference matters for how you use them. @@ -88,15 +84,13 @@ Its environments are instead the fixed points of the transfer operator — the o Those problems are solved *iteratively*, to a finite tolerance, rather than by an exact finite contraction. Building an infinite environment is therefore a small numerical solve, and its result is only as accurate as the tolerance of that solve. -The precision of that solve is a setting of the environment computation, controlled through the arguments passed to [`environments`](@ref) rather than being read or written on the environment object afterwards. - +The precision of that solve is controlled by the `tol`, `maxiter`, and `krylovdim` keyword arguments to [`environments`](@ref), which configure the underlying iterative solver — an Arnoldi eigensolver for a transfer-matrix fixed point, or GMRES for the linear problem that arises with an `InfiniteMPOHamiltonian`. +It is fixed when the environments are built, rather than read from or written to the environment object afterwards. The second difference is that infinite environments are **not** recomputed automatically. The finite cache re-validates itself against the current state on every query; the infinite one does not. If the state changes, the stored fixed points no longer correspond to it, and there is no automatic re-solve. -Bringing an infinite environment up to date for a changed state is an explicit step, handled internally by the non-exported `MPSKit.recalculate!`. - -In practice the high-level algorithms perform this recomputation for you as part of their own iteration, which is again why threading the returned environments through successive calls is the efficient pattern. +Bringing an infinite environment up to date for a changed state is an explicit step, handled internally by the non-exported `MPSKit.recalculate!`.In practice the high-level algorithms perform this recomputation for you as part of their own iteration, which is again why threading the returned environments through successive calls is the efficient pattern. ## Where to go next diff --git a/docs/src/concepts/matrix_product_states.md b/docs/src/concepts/matrix_product_states.md index b59214507..34a7e178a 100644 --- a/docs/src/concepts/matrix_product_states.md +++ b/docs/src/concepts/matrix_product_states.md @@ -14,8 +14,6 @@ The physical indices carry the local degrees of freedom, while the virtual bonds ``` *The diagram shows a finite MPS as a row of site tensors, each carrying a physical index and linked to its neighbours through virtual bonds; the two ends carry trivial (dimension-one) boundary bonds.* - - This page explains the *gauge freedom* inherent in that representation and the *canonical forms* MPSKit uses to fix it, so that the `AL`, `AR`, `C`, and `AC` you see throughout the API stop looking like arbitrary labels. It is about understanding rather than construction: for how to *build* a state see [Constructing states](@ref howto_states), and for the full type signatures see the [States](@ref lib_states) reference. diff --git a/docs/src/concepts/operators_and_hamiltonians.md b/docs/src/concepts/operators_and_hamiltonians.md index cf71f8295..3899e22f1 100644 --- a/docs/src/concepts/operators_and_hamiltonians.md +++ b/docs/src/concepts/operators_and_hamiltonians.md @@ -34,9 +34,7 @@ The individual site tensors are therefore defined only up to this virtual-space MPOs support the usual linear-algebra operations — addition, subtraction, and multiplication, either among themselves or acting on an MPS. Each such operation combines the virtual spaces of its operands, so the virtual dimension of the result is (generically) the *product* or *sum* of the input dimensions rather than staying fixed. -Composing operators naively therefore makes the representation grow, and the growth compounds under repeated multiplication. - -This growth is precisely what motivates the *approximate* algorithms that re-express a product or sum within a bounded virtual dimension; see the [algorithm landscape](@ref concept_algorithm_landscape) for where those methods fit. +Composing operators naively therefore makes the representation grow, and the growth compounds under repeated multiplication.This growth is precisely what motivates the *approximate* algorithms that re-express a product or sum within a bounded virtual dimension; see the [algorithm landscape](@ref concept_algorithm_landscape) for where those methods fit. ## MPO Hamiltonians and the Jordan-block form @@ -76,8 +74,6 @@ Every complete left-to-right path through the block matrix contributes one term - ``C \cdot A \cdot B`` generates the three-site terms, - and in general ``C \cdot A^{k} \cdot B`` generates a term spanning ``k+2`` sites. - - The repeated ``A`` block is what makes longer-range interactions possible at fixed virtual dimension: choosing ``A`` to be (a multiple of) the identity gives every additional site the same weight, while a decaying ``A`` gives geometrically decaying couplings. A sum of such geometric series can approximate a power-law interaction to any desired accuracy, which is how (exponentially decaying) infinite-range and approximate power-law couplings are represented. diff --git a/docs/src/concepts/parallelism_model.md b/docs/src/concepts/parallelism_model.md index f3cc51568..0adc77e57 100644 --- a/docs/src/concepts/parallelism_model.md +++ b/docs/src/concepts/parallelism_model.md @@ -41,9 +41,7 @@ When Julia is started with more than one thread, MPSKit uses algorithms wherever possible. In practice this happens where a unit cell (or a chain of sites) lets local updates run independently: the work is distributed across the sites of the system, with the tensor at -each site updated in parallel. - -This is exactly why setting the BLAS thread count to `1` on OpenBLAS tends to help: it keeps +each site updated in parallel.This is exactly why setting the BLAS thread count to `1` on OpenBLAS tends to help: it keeps the Julia threads free to work through the sites, rather than contending with a shared BLAS pool. diff --git a/docs/src/concepts/vector_spaces.md b/docs/src/concepts/vector_spaces.md index 286ae9aa8..cfeaf4c67 100644 --- a/docs/src/concepts/vector_spaces.md +++ b/docs/src/concepts/vector_spaces.md @@ -108,8 +108,6 @@ t + t2 # partitions do not match catch err; Base.showerror(stderr, err); end #hide ``` - - The fix is [`permute`](https://quantumkithub.github.io/TensorKit.jl/stable/), which regroups the legs into a chosen partition. Bringing `t2` back to the partition of `t` makes the addition well-defined again: @@ -142,8 +140,6 @@ V_\ell \otimes P_1 \otimes \cdots \otimes P_{k} \leftarrow V_r, ``` i.e. leg 1 is the left virtual space, the physical spaces come next (the picture labels them `physical (2:N-1)`), and the final leg is the right virtual space. - - Crucially, an MPS tensor may carry an **arbitrary number of physical legs**, and both [`FiniteMPS`](@ref) and [`InfiniteMPS`](@ref) handle the resulting objects. This is what allows, for example, boundary tensors in PEPS code, which carry two physical legs. @@ -160,8 +156,6 @@ V_\ell \leftarrow V_r, ``` i.e. the left virtual space is the codomain and the right virtual space is the domain. - - ### The MPO tensor ```@raw html @@ -175,8 +169,6 @@ V_\ell \otimes P \leftarrow P \otimes V_r. ``` The picture labels these `virtual (1)` and `physical (2)` in the codomain, and `physical (3)` and `virtual (4)` in the domain. - - ## Where to go next - To see these tensors assembled into states and gauged into canonical form, read [Matrix product states](@ref concept_matrix_product_states). diff --git a/docs/src/tutorials/excitations.md b/docs/src/tutorials/excitations.md index fa77470da..3ca65832a 100644 --- a/docs/src/tutorials/excitations.md +++ b/docs/src/tutorials/excitations.md @@ -81,8 +81,6 @@ This particular model is exactly solvable, so we can plot our numerical dispersi \Delta E(k) = 2\sqrt{1 + g^2 - 2 g \cos k}. ``` - - For this Hermitian problem the computed energies come back as real numbers; the `real.(...)` below is a harmless safeguard for the general case, where the eigenvalue solver may return a complex number type with numerically vanishing imaginary parts. ```@example excitations @@ -101,8 +99,6 @@ real(Es[1, 1]), 2 * (g - 1) ``` A ground state at bond dimension 12 plus a variational quasiparticle on top reproduces the exact gap of the model — that is the quasiparticle ansatz working as intended. - - ## Where to go next You have computed a full dispersion relation on top of an infinite ground state and read off the energy gap. From 5dd2b88aaca74461aacc1ffad014fa88a4160861 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Thu, 9 Jul 2026 09:14:37 -0400 Subject: [PATCH 63/76] docs: clear parallelism/threading REVIEW flags; fix sentence merges MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Maintainer confirmed the threading/memory/GPU guidance (migrated from man/parallelism.md) still holds, so its REVIEW flags are removed from concepts/parallelism_model.md and howto/parallelism_gpu.md. Also repairs three sentence-boundary merges introduced when the previous commit stripped inline REVIEW comments (parallel.→This, did.→The, multiplication.→This). Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/src/concepts/environments.md | 3 ++- docs/src/concepts/operators_and_hamiltonians.md | 3 ++- docs/src/concepts/parallelism_model.md | 9 ++------- docs/src/howto/parallelism_gpu.md | 5 ----- 4 files changed, 6 insertions(+), 14 deletions(-) diff --git a/docs/src/concepts/environments.md b/docs/src/concepts/environments.md index 6db50030e..6f4ea355c 100644 --- a/docs/src/concepts/environments.md +++ b/docs/src/concepts/environments.md @@ -49,7 +49,8 @@ What they also do, uniformly, is accept an *optional* environments argument and That return value is the reason to care about environments even when you never construct one. Handing the environments from one call into the next lets the algorithm reuse the cached blocks instead of rebuilding them from nothing. -For iterated procedures such as time evolution — where each step starts from a state only slightly different from the last — feeding the updated environments back in every step avoids repeating work that the previous step already did.The [Time evolution](@ref howto_time_evolution) how-to shows this threading pattern in a concrete recipe. +For iterated procedures such as time evolution — where each step starts from a state only slightly different from the last — feeding the updated environments back in every step avoids repeating work that the previous step already did. +The [Time evolution](@ref howto_time_evolution) how-to shows this threading pattern in a concrete recipe. ## Finite environments and the `===` cache diff --git a/docs/src/concepts/operators_and_hamiltonians.md b/docs/src/concepts/operators_and_hamiltonians.md index 3899e22f1..cb099b6a2 100644 --- a/docs/src/concepts/operators_and_hamiltonians.md +++ b/docs/src/concepts/operators_and_hamiltonians.md @@ -34,7 +34,8 @@ The individual site tensors are therefore defined only up to this virtual-space MPOs support the usual linear-algebra operations — addition, subtraction, and multiplication, either among themselves or acting on an MPS. Each such operation combines the virtual spaces of its operands, so the virtual dimension of the result is (generically) the *product* or *sum* of the input dimensions rather than staying fixed. -Composing operators naively therefore makes the representation grow, and the growth compounds under repeated multiplication.This growth is precisely what motivates the *approximate* algorithms that re-express a product or sum within a bounded virtual dimension; see the [algorithm landscape](@ref concept_algorithm_landscape) for where those methods fit. +Composing operators naively therefore makes the representation grow, and the growth compounds under repeated multiplication. +This growth is precisely what motivates the *approximate* algorithms that re-express a product or sum within a bounded virtual dimension; see the [algorithm landscape](@ref concept_algorithm_landscape) for where those methods fit. ## MPO Hamiltonians and the Jordan-block form diff --git a/docs/src/concepts/parallelism_model.md b/docs/src/concepts/parallelism_model.md index 0adc77e57..e8e3bccbc 100644 --- a/docs/src/concepts/parallelism_model.md +++ b/docs/src/concepts/parallelism_model.md @@ -25,14 +25,12 @@ single thread pool that is shared by all Julia threads: 4 Julia threads and 4 BL means all 4 Julia threads draw from the same pool of 4 BLAS threads. Setting the BLAS thread count to `1` instead frees OpenBLAS to run its work on the Julia threads themselves, so that MPSKit's Julia-level parallelism is the thing that scales. - With [MKL.jl](https://github.com/JuliaLinearAlgebra/MKL.jl), which often outperforms OpenBLAS, the count is instead the number of threads spawned by **each** Julia thread: 4 Julia threads with 4 BLAS threads each gives 16 BLAS threads in total. Getting this wrong oversubscribes the physical cores — more software threads than hardware can run — which degrades rather than improves performance. - ## Where MPSKit parallelizes @@ -41,13 +39,13 @@ When Julia is started with more than one thread, MPSKit uses algorithms wherever possible. In practice this happens where a unit cell (or a chain of sites) lets local updates run independently: the work is distributed across the sites of the system, with the tensor at -each site updated in parallel.This is exactly why setting the BLAS thread count to `1` on OpenBLAS tends to help: it keeps +each site updated in parallel. +This is exactly why setting the BLAS thread count to `1` on OpenBLAS tends to help: it keeps the Julia threads free to work through the sites, rather than contending with a shared BLAS pool. The amount of speedup you can expect therefore tracks how much independent per-site work an algorithm exposes. - ## Parallelism over symmetry sectors @@ -58,7 +56,6 @@ across those blocks. This is handled by [TensorKit](https://quantumkithub.github.io/TensorKit.jl/stable/) at the level of the individual tensor operations, below MPSKit's site-level parallelism, so the two layers are independent of one another. - ## Why memory pressure arises @@ -68,11 +65,9 @@ deallocates a fair amount of memory in a tight loop. This can produce enough garbage, quickly enough, that the garbage collector cannot keep up; in the worst case memory is exhausted and an `OutOfMemory` error is thrown before the garbage can be cleared. - The most memory-intensive step is reportedly the application of the `derivatives` — the effective local operators built during the sweeps — which is why the practical mitigation is to disable MPSKit's multithreading there. - The concrete recipe for doing so is on [Parallelism and GPU support](@ref howto_parallelism_gpu). diff --git a/docs/src/howto/parallelism_gpu.md b/docs/src/howto/parallelism_gpu.md index a13430a98..dd5b6fe9c 100644 --- a/docs/src/howto/parallelism_gpu.md +++ b/docs/src/howto/parallelism_gpu.md @@ -31,14 +31,12 @@ threads held in a shared pool across all Julia threads. When Julia is started with multiple threads, setting this to `1` lets MPSKit drive the parallelism through its own (Julia-thread) machinery instead, which is often the best option for OpenBLAS. - With [MKL.jl](https://github.com/JuliaLinearAlgebra/MKL.jl) the semantics differ: the BLAS thread count applies **per Julia thread**, so 4 Julia threads with 4 BLAS threads each spawn 16 BLAS threads in total. In that case you typically want to lower the BLAS thread count to avoid oversubscribing the physical cores. - ## Setting the MPSKit scheduler @@ -122,7 +120,6 @@ MPSKit's multithreading spawns tasks in a nested fashion, each allocating and de memory in a tight loop. This can put enough pressure on the garbage collector that memory usage climbs and, in the worst case, an `OutOfMemory` error occurs before the garbage can be cleared. - If you hit this, the most effective remedy is usually to disable MPSKit's multithreading, by setting the scheduler to serial: @@ -133,7 +130,6 @@ MPSKit.Defaults.set_scheduler!(:serial) The `derivatives` (the effective local operators applied during the sweeps) are reported to be the most memory-intensive part, so this is where switching off multithreading helps most. - For why this pressure arises, see [Why memory pressure arises](@ref concept_parallelism_model). @@ -158,4 +154,3 @@ using Adapt, CUDA ψ_gpu = adapt(CuArray, ψ) ``` - From f3fc9868a11105df6629e35c6c4d1578e0016878 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Thu, 9 Jul 2026 09:37:06 -0400 Subject: [PATCH 64/76] docs: resolve ground-state-algorithm + verified excitation REVIEW flags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Maintainer-confirmed the ground-state algorithm characterizations (DMRG/DMRG2, IDMRG middle-growth + critical slowdown, VUMPS re-gauging/injectivity, gradient descent in the tail); cleared their flags in algorithm_landscape.md and groundstate_algorithms.md. Softened the DMRG description to "in practice converges to the ground state" rather than implying a guaranteed global optimum. Also cleared three excitation-tutorial flags that are textbook/verifiable: the dispersion/gap framing, the TFIM transition at g=1 (g=2 gapped, confirmed numerically), and the [0,π] scan using the k→−k symmetry of an even dispersion. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/src/concepts/algorithm_landscape.md | 12 +----------- docs/src/howto/groundstate_algorithms.md | 5 ----- docs/src/tutorials/excitations.md | 3 --- 3 files changed, 1 insertion(+), 19 deletions(-) diff --git a/docs/src/concepts/algorithm_landscape.md b/docs/src/concepts/algorithm_landscape.md index 161e3a31d..afbcace4e 100644 --- a/docs/src/concepts/algorithm_landscape.md +++ b/docs/src/concepts/algorithm_landscape.md @@ -28,32 +28,22 @@ Finally, algorithms compose: the `&` operator chains two algorithms into one, ru ## Ground states -The classic approach is alternating local optimization: [`DMRG`](@ref) sweeps through a finite chain, optimizing one site while all others are held fixed. - +The classic approach is alternating local optimization: [`DMRG`](@ref) sweeps back and forth through a finite chain, optimizing one site while all others are held fixed, which in practice converges to the ground state. The catch is the fixed bond dimension: a single-site update can never enlarge the virtual spaces, so the precision of the calculation is locked in by the initial state. This bites hardest when symmetries are involved, because then not just the total bond dimension but its distribution over charge sectors is frozen, and a poor initial distribution cannot be repaired. - [`DMRG2`](@ref) fixes this by optimizing two neighbouring sites jointly and truncating back down, which lets the bond dimension (and its sector distribution) adapt, at a higher cost per sweep. - For infinite systems, two philosophies compete. [`IDMRG`](@ref) grows the system from the middle outwards, repeatedly inserting and optimizing new sites until the boundary is no longer felt; [`IDMRG2`](@ref) is its two-site, bond-growing variant. - Because convergence requires the effective system to outgrow the correlation length, IDMRG can be slow to converge for critical systems, where that length diverges. - [`VUMPS`](@ref) instead works with a genuinely uniform state: each local update is followed by a re-gauging step that replaces *every* tensor in the infinite chain with the updated one, so the effect of an update is felt throughout the system immediately. - This often gives VUMPS a higher convergence rate than IDMRG, which is why it is the default infinite-system workhorse. - The price is an injectivity requirement: VUMPS assumes a unique ground state, and it is not the right tool when the state it should converge to is non-injective. - Like DMRG, VUMPS is single-site and cannot alter the bond dimension. [`GradientGrassmann`](@ref) approaches the problem from a third direction: the MPS tensors form a Riemannian manifold (a Grassmann manifold), and one can run gradient descent directly on it, for finite and infinite states alike. Its niche is the tail of the optimization: close to convergence its rate is often the best of the lot, while far from convergence the sweeping algorithms tend to make faster progress. - The practical consequence is the chaining pattern: run a cheap workhorse first, then hand over to gradient descent, e.g. `VUMPS(...) & GradientGrassmann(...)`. - This pattern is baked into `find_groundstate` itself: called with only keywords, it picks `DMRG` for a finite state and `VUMPS` for an infinite one, appends a `GradientGrassmann` stage on infinite states when the requested tolerance is tighter than `1e-4`, and prepends a two-site pass (`DMRG2` or `IDMRG2`) whenever you supply a `trscheme`. Since gradient descent is also a single-site method, growing the bond dimension remains the job of that two-site pre-pass or of [`changebonds`](@ref). diff --git a/docs/src/howto/groundstate_algorithms.md b/docs/src/howto/groundstate_algorithms.md index 4cb753a73..98124df19 100644 --- a/docs/src/howto/groundstate_algorithms.md +++ b/docs/src/howto/groundstate_algorithms.md @@ -69,7 +69,6 @@ Pass a [`DMRG`](@ref) struct explicitly to set `tol`, `maxiter`, and `verbosity` ``` `DMRG` updates one site at a time, so with its defaults it cannot change the bond dimension: whatever bond dimension `ψ₀` starts with is what it keeps. - [`DMRG2`](@ref) optimizes two sites at once and truncates back down, which lets it grow (or shrink) the bond dimension as it sweeps, at extra cost per step. Unlike `DMRG`, `DMRG2` has no default truncation scheme, so `trscheme` is required: @@ -108,7 +107,6 @@ For more on choosing `trscheme` and growing bond dimension in general, see [Cont ϵ_v ``` - [`IDMRG`](@ref) is the infinite analogue of `DMRG`: it grows the system by repeatedly inserting sites in the middle and re-optimizing, until boundary effects wash out. ```@example groundstate_algs @@ -119,8 +117,6 @@ For more on choosing `trscheme` and growing bond dimension in general, see [Cont ϵ_i ``` - - In practice, prefer `VUMPS` unless you specifically need `IDMRG`'s ability to change the bond dimension one site at a time. [`IDMRG2`](@ref) is the two-site, bond-dimension-changing variant, and mirrors `DMRG2`: `trscheme` is required, and it needs a unit cell of at least two sites. @@ -157,7 +153,6 @@ H_inf_2 = InfiniteMPOHamiltonian( ## 4. Refine convergence with GradientGrassmann [`GradientGrassmann`](@ref) performs Riemannian gradient descent directly on the manifold of (finite or infinite) MPS, using an optimizer from OptimKit (`ConjugateGradient` by default via the `method` keyword). - Chain it after `VUMPS` (or `DMRG`) with `&` to combine both regimes in one call — this is exactly what `find_groundstate`'s heuristic does once `tol` is tighter than `1e-4`: ```@example groundstate_algs diff --git a/docs/src/tutorials/excitations.md b/docs/src/tutorials/excitations.md index 3ca65832a..b515af267 100644 --- a/docs/src/tutorials/excitations.md +++ b/docs/src/tutorials/excitations.md @@ -4,7 +4,6 @@ The previous tutorials ended with a ground state: the lowest-energy state of the The natural next question is what lies *above* it: how much energy does it cost to excite the system? For a translation-invariant chain the answer is organized by momentum — for each momentum ``k`` there is a lowest excitation energy ``\Delta E(k)``, and the resulting curve is the **dispersion relation** of the model. Its minimum over all momenta is the **energy gap**, one of the most basic characterizations of a quantum phase. - In this tutorial we compute the dispersion relation of the infinite transverse-field Ising chain with MPSKit's quasiparticle ansatz, and finish with a plot of ``\Delta E(k)`` across the Brillouin zone — compared against the exact solution. @@ -22,7 +21,6 @@ using Plots Excitations are computed *on top of* a ground state, so the first step is the calculation you already know from [The thermodynamic limit](@ref tutorial_thermodynamic_limit): build the infinite Hamiltonian, make a random `InfiniteMPS`, and converge it with `VUMPS`. This time we set the field to `g = 2.0`, deep in the paramagnetic phase, where the model is **gapped**: the lowest excitation costs a finite amount of energy, which is exactly what we want to measure. - ```@example excitations g = 2.0 @@ -60,7 +58,6 @@ The second return value `ϕ` holds the corresponding quasiparticle states, which To trace out the whole dispersion relation we simply pass a *range* of momenta instead of a single number. By symmetry it is enough to scan from ``0`` to ``\pi``, and we use 16 points to keep the runtime modest. - ```@example excitations momenta = range(0, π, 16) From c04d474d4d94f568b79bf15ccf7c7c258cb60cdf Mon Sep 17 00:00:00 2001 From: lkdvos Date: Thu, 9 Jul 2026 09:55:22 -0400 Subject: [PATCH 65/76] docs: resolve time-evolution, excitation, boundary REVIEW flags Maintainer-confirmed the time-evolution (TDVP/TDVP2, MPO route, imaginary-time cooling), excitation (quasiparticle ansatz, FiniteExcited, Chepiga), and boundary/statmech (transfer-matrix framing, GradientGrassmann conditions, SvdCut+approximate) characterizations; cleared their flags in algorithm_landscape.md and the time-evolution/excitation how-tos. The MPO-vs-TDVP and VUMPS-vs-VOMPS choices are kept deliberately neutral. Softened the FiniteExcited "qualitatively different excitations" niche to an "in principle" motivation rather than an asserted fact. Kept: the intro framing flag (performance depends on the model) and the "future worked example" TODO in howto/excitations, pending separate review. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/src/concepts/algorithm_landscape.md | 18 +----------------- docs/src/howto/excitations.md | 2 -- docs/src/howto/time_evolution.md | 3 --- 3 files changed, 1 insertion(+), 22 deletions(-) diff --git a/docs/src/concepts/algorithm_landscape.md b/docs/src/concepts/algorithm_landscape.md index afbcace4e..4d49a43af 100644 --- a/docs/src/concepts/algorithm_landscape.md +++ b/docs/src/concepts/algorithm_landscape.md @@ -19,7 +19,6 @@ It explains *why* you would pick one algorithm over another; for the *how* — t | **Boundary / statistical mechanics** ([`leading_boundary`](@ref)) | apply the transfer MPO row by row with [`approximate`](@ref) | [`VUMPS`](@ref); [`VOMPS`](@ref) (power method); [`IDMRG`](@ref) / [`IDMRG2`](@ref); [`GradientGrassmann`](@ref) (hermitian, positive transfer matrices) | | **Compression / approximation** ([`approximate`](@ref), [`changebonds`](@ref)) | [`approximate`](@ref) with [`DMRG`](@ref) / [`DMRG2`](@ref); [`SvdCut`](@ref) via [`changebonds`](@ref) for local truncation | [`approximate`](@ref) with [`IDMRG`](@ref) / [`IDMRG2`](@ref) / [`VOMPS`](@ref); [`SvdCut`](@ref) via [`changebonds`](@ref) for local truncation | - A few structural facts hold across the whole table and are worth internalizing early. Every two-site algorithm (`DMRG2`, `IDMRG2`, `TDVP2`) requires an explicit `trscheme` keyword and can change the bond dimension as it runs; the single-site variants with their default settings cannot. @@ -55,14 +54,10 @@ MPSKit solves the time-dependent Schrödinger equation along two distinct routes The first route, [`TDVP`](@ref), never builds the evolution operator at all. It projects the Schrödinger equation onto the tangent space of the current MPS, solves the projected equation for a small time step, and repeats. - Its two-site variant [`TDVP2`](@ref) plays the same role as `DMRG2` does for `DMRG`: it lets the bond dimension grow to absorb the entanglement generated by the evolution, at extra cost, and it exists only for finite systems. - The second route splits the problem in two: first approximate the evolution operator ``\exp(-iH\,dt)`` itself as an MPO using [`make_time_mpo`](@ref) — with [`WI`](@ref), [`WII`](@ref), or [`TaylorCluster`](@ref) as the approximation scheme — and then apply that MPO to the state with [`approximate`](@ref). The appeal is amortization: for a time-independent Hamiltonian and a fixed step size the MPO is built once and reused for every step, and the accuracy of the operator approximation is controlled independently of the accuracy of its application. - - Both routes accept an `imaginary_evolution` keyword for evolution in imaginary time. For step-by-step recipes along either route, see [Time evolution](@ref howto_time_evolution). @@ -70,25 +65,18 @@ For step-by-step recipes along either route, see [Time evolution](@ref howto_tim ## Excitations Resolving states deep in the spectrum is generally out of reach, but three families of algorithms target the low-lying part, each with a distinct character. - The [`QuasiparticleAnsatz`](@ref) is the most broadly applicable: it works for finite and infinite systems, and it is the only algorithm that can target excitations carrying a nontrivial symmetry charge, via the `sector` keyword. It builds an excited state by replacing a single tensor of the ground-state MPS — summed over all positions on a finite chain, or in a momentum-carrying plane-wave superposition on an infinite one — and solves the resulting eigenvalue problem. - Because the variational class consists of local perturbations on top of the ground state, it is the natural choice for quasiparticle-like excitations, and on infinite systems it is the only option, giving direct access to dispersion relations. - [`FiniteExcited`](@ref) takes a brute-force approach available only on finite chains: it reruns a full ground-state optimization on a modified Hamiltonian that carries an energy penalty for overlapping with all previously found states. Each new excited state therefore costs another complete ground-state search, and the orthogonality to earlier states is only approximate (enforced by the penalty `weight`, not exactly). - -Its advantage is that it makes no assumption about the *form* of the excited state: since each state is a fully variational `FiniteMPS`, it can capture excitations that are not well described as a local perturbation of the ground state. - +Its advantage is that it makes no assumption about the *form* of the excited state: since each state is a fully variational `FiniteMPS`, it can in principle capture excitations that a local perturbation of the ground state would describe poorly. The [`ChepigaAnsatz`](@ref) (and its two-site refinement [`ChepigaAnsatz2`](@ref)) is the cheapest of the three, also finite-only. It observes that the gauged ground-state MPS tensors act as isometries projecting the Hamiltonian into a low-energy subspace, so the low-lying spectrum can be read off by diagonalizing the effective Hamiltonian already available from the ground-state environments, with no additional sweeping. - This works best precisely where excitations are hard for the other methods: in critical systems with long-range correlations, where the excitation weight is spread across the whole chain. - For the call signatures, momentum scans, and sector-targeting recipes, see [Excited states](@ref howto_excitations). @@ -96,17 +84,13 @@ For the call signatures, momentum scans, and sector-targeting recipes, see [Exci MPS algorithms are not limited to Hamiltonian problems. A two-dimensional classical partition function can be written as an infinite power of a row-to-row transfer MPO, and contracting the network amounts to finding that operator's dominant eigenvector — a boundary MPS. - This is the job of [`leading_boundary`](@ref), which accepts a familiar cast: [`VUMPS`](@ref) and [`IDMRG`](@ref)/[`IDMRG2`](@ref) carry over directly from the ground-state problem, [`GradientGrassmann`](@ref) applies when the transfer MPO is hermitian and positive, and [`VOMPS`](@ref) is a power method specific to this setting, which iteratively approximates the operator-times-state product by a new state of the same bond dimension. - - ## Compression and changing bond dimension Two mechanisms round out the landscape by manipulating states rather than solving for new ones. [`approximate`](@ref) variationally fits a new MPS, typically of different bond dimension, to the result of applying an MPO to a state; the sweeping ground-state algorithms (`DMRG`/`DMRG2` for finite, `IDMRG`/`IDMRG2`/`VOMPS` for infinite) double as its optimization engines. This is the same machinery that applies time-evolution MPOs, and combined with [`SvdCut`](@ref) it yields a globally optimal truncation of a state. - [`changebonds`](@ref), by contrast, performs direct local surgery on a state: truncating with [`SvdCut`](@ref), or expanding with [`OptimalExpand`](@ref), [`RandExpand`](@ref), or [`VUMPSSvdCut`](@ref) so that the single-site algorithms above have room to work with. The trade-offs between those expansion schemes, and recipes for when to grow, are covered in [Controlling bond dimension](@ref howto_bond_dimension). diff --git a/docs/src/howto/excitations.md b/docs/src/howto/excitations.md index 39b3b03ec..b74366987 100644 --- a/docs/src/howto/excitations.md +++ b/docs/src/howto/excitations.md @@ -103,7 +103,6 @@ Es_fe ``` Unlike `QuasiparticleAnsatz`, the values in `Es_fe` are total energies of the excited states, directly comparable to `expectation_value(ψ_fin, H_fin)` on the ground state. - Because each call to `FiniteExcited` reruns a full ground-state optimization under the hood, it scales worse with `num` than the other methods here; reach for it when you need excited states of a genuinely different character than the ground state (so the projector penalty, rather than a local perturbation, is what finds them). [`ChepigaAnsatz`](@ref) is a cheaper alternative for excitations that are qualitatively similar to the ground state: it diagonalizes the effective Hamiltonian at a single site `pos` (default the middle of the chain) using the ground-state environments, with no extra sweeping: @@ -121,7 +120,6 @@ Es_ch2[1] ``` Like `FiniteExcited`, the energies returned by both Chepiga variants are total energies, not gaps. - --- diff --git a/docs/src/howto/time_evolution.md b/docs/src/howto/time_evolution.md index 36e5061d3..f6d85c450 100644 --- a/docs/src/howto/time_evolution.md +++ b/docs/src/howto/time_evolution.md @@ -64,7 +64,6 @@ There is no exported `time_evolve!`; use `time_evolve` and rebind the result. Single-site `TDVP` cannot change the bond dimension: whatever `ψ₀` starts with is what it keeps. After a quench, entanglement typically grows and a fixed bond dimension eventually becomes insufficient. - [`TDVP2`](@ref) updates two sites at a time and truncates back down, so it can grow (or shrink) the bond dimension as it evolves. Unlike `TDVP`, `TDVP2` requires `trscheme` — there is no default: @@ -108,7 +107,6 @@ norm(ψ_im) Imaginary-time evolution renormalizes the state at every step, so `norm(ψ_im)` stays `1` regardless of how the un-normalized weight would otherwise change. Repeated imaginary-time steps damp excited-state components faster than the ground state, so this is often used as a (slower) alternative to `find_groundstate` for driving a state towards the ground state of `H₁`. - `time_evolve` accepts the same `imaginary_evolution` keyword for a span of imaginary-time steps. --- @@ -116,7 +114,6 @@ Repeated imaginary-time steps damp excited-state components faster than the grou ## 6. Build a time-evolution MPO When `H` is time-independent and `dt` is fixed, an alternative to repeated `timestep` calls is to build the evolution operator once as an MPO with [`make_time_mpo`](@ref), then apply it repeatedly with [`approximate`](@ref). - [`WII`](@ref) builds a low-order MPO approximation and works for both finite and infinite Hamiltonians: From fbf5b967af5dece09742966b95123e938c7c7c0c Mon Sep 17 00:00:00 2001 From: lkdvos Date: Thu, 9 Jul 2026 09:57:11 -0400 Subject: [PATCH 66/76] docs: clear duplicate QP flag; restore blank lines before headings Clears the excitations-tutorial quasiparticle-ansatz framing flag (same claim as the maintainer-approved landscape C2). Also restores three blank lines lost before headings when inline REVIEW comments were stripped (excitations "Where to go next"; vector_spaces "The MPO tensor" and "Where to go next"). Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/src/concepts/vector_spaces.md | 2 ++ docs/src/tutorials/excitations.md | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/src/concepts/vector_spaces.md b/docs/src/concepts/vector_spaces.md index cfeaf4c67..3d2e4970f 100644 --- a/docs/src/concepts/vector_spaces.md +++ b/docs/src/concepts/vector_spaces.md @@ -156,6 +156,7 @@ V_\ell \leftarrow V_r, ``` i.e. the left virtual space is the codomain and the right virtual space is the domain. + ### The MPO tensor ```@raw html @@ -169,6 +170,7 @@ V_\ell \otimes P \leftarrow P \otimes V_r. ``` The picture labels these `virtual (1)` and `physical (2)` in the codomain, and `physical (3)` and `virtual (4)` in the domain. + ## Where to go next - To see these tensors assembled into states and gauged into canonical form, read [Matrix product states](@ref concept_matrix_product_states). diff --git a/docs/src/tutorials/excitations.md b/docs/src/tutorials/excitations.md index b515af267..4ab533c41 100644 --- a/docs/src/tutorials/excitations.md +++ b/docs/src/tutorials/excitations.md @@ -37,7 +37,6 @@ The **quasiparticle ansatz** builds an excited state directly on top of the unif The idea is simple to picture: take the converged ground state and perturb it locally, replacing the tensor at one site with a new one that we get to optimize. Because the chain is infinite and translation invariant, we do not place this perturbation at any particular site; instead we superpose it across *all* sites with a plane-wave phase, which gives the excitation a definite momentum ``k``. Optimizing the perturbation then yields the lowest excited state at that momentum. - The call is [`excitations`](@ref) with the [`QuasiparticleAnsatz`](@ref) algorithm, a momentum (a real number, in radians per site), and the ground state with its environments. Let us ask for the excitation at the edge of the Brillouin zone, ``k = \pi``: @@ -96,6 +95,7 @@ real(Es[1, 1]), 2 * (g - 1) ``` A ground state at bond dimension 12 plus a variational quasiparticle on top reproduces the exact gap of the model — that is the quasiparticle ansatz working as intended. + ## Where to go next You have computed a full dispersion relation on top of an infinite ground state and read off the energy gap. From 03ab94a99a8fc58fd99044bcc2a557d1f66a68b2 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Thu, 9 Jul 2026 10:41:39 -0400 Subject: [PATCH 67/76] docs: resolve remaining physics REVIEW flags (symmetry, quench, structural) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Maintainer-confirmed and cleared the final physics-judgment flags: - symmetry tutorial: g=2 symmetric GS, even/odd↔σˣ eigenstates, 8⊕8 block-sparsity speedup, paramagnetic single-spin-flip excitation, SU(2) multiplet gains - quench tutorial: tracking ⟨σˣ⟩ (⟨σᶻ⟩=0 by unbroken symmetry), relaxation with oscillations, post-quench entanglement growth capping the time window - structural: finite lazy vs infinite full gauge recompute; A=c·𝟙 → geometric/ power-law couplings; Vₗ⊗P←P⊗Vᵣ planarity/fermion rationale; "no algorithm wins everywhere" framing Only two non-physics notes remain (benchmark placeholder in index.md; a future-worked-example TODO in howto/excitations). Also restored a blank line before the gauge-freedom paragraph in matrix_product_states. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/src/concepts/algorithm_landscape.md | 1 - docs/src/concepts/matrix_product_states.md | 2 +- docs/src/concepts/operators_and_hamiltonians.md | 1 - docs/src/concepts/vector_spaces.md | 1 - docs/src/tutorials/time_evolution.md | 4 ---- docs/src/tutorials/using_symmetries.md | 16 ---------------- 6 files changed, 1 insertion(+), 24 deletions(-) diff --git a/docs/src/concepts/algorithm_landscape.md b/docs/src/concepts/algorithm_landscape.md index 4d49a43af..d042be916 100644 --- a/docs/src/concepts/algorithm_landscape.md +++ b/docs/src/concepts/algorithm_landscape.md @@ -3,7 +3,6 @@ MPSKit deliberately separates *what* you want to compute from *how* it gets computed. Entry points such as [`find_groundstate`](@ref), [`timestep`](@ref), [`excitations`](@ref), [`leading_boundary`](@ref), and [`approximate`](@ref) each accept several interchangeable algorithm structs, and the package ships more than a dozen of them. That flexibility exists because no single algorithm wins everywhere: some only apply to finite or only to infinite systems, some can grow the bond dimension while others cannot, and their relative performance depends on the model at hand. - This page is the decision guide. It starts from a table that maps each task onto the algorithm(s) of choice, and then walks through the reasoning behind each row. diff --git a/docs/src/concepts/matrix_product_states.md b/docs/src/concepts/matrix_product_states.md index 34a7e178a..89eabfa25 100644 --- a/docs/src/concepts/matrix_product_states.md +++ b/docs/src/concepts/matrix_product_states.md @@ -14,6 +14,7 @@ The physical indices carry the local degrees of freedom, while the virtual bonds ``` *The diagram shows a finite MPS as a row of site tensors, each carrying a physical index and linked to its neighbours through virtual bonds; the two ends carry trivial (dimension-one) boundary bonds.* + This page explains the *gauge freedom* inherent in that representation and the *canonical forms* MPSKit uses to fix it, so that the `AL`, `AR`, `C`, and `AC` you see throughout the API stop looking like arbitrary labels. It is about understanding rather than construction: for how to *build* a state see [Constructing states](@ref howto_states), and for the full type signatures see the [States](@ref lib_states) reference. @@ -114,7 +115,6 @@ The gauge machinery is shared between finite and infinite states, but the way th A [`FiniteMPS`](@ref) has genuine boundaries and mutable per-site tensors, so it gauges *lazily*: each form is recomputed only for the tensors it actually depends on, and invalidation is decided by object identity (`===`) — replacing a tensor marks the left-gauged tensors to its right and the right-gauged tensors to its left as stale, leaving the rest cached. An [`InfiniteMPS`](@ref) instead repeats a finite unit cell periodically, so there is no left or right end to anchor a partial recompute: every tensor lies both to the right and to the left of any change, and all forms are recomputed together whenever a tensor changes. - ## Variants diff --git a/docs/src/concepts/operators_and_hamiltonians.md b/docs/src/concepts/operators_and_hamiltonians.md index cb099b6a2..469d90b58 100644 --- a/docs/src/concepts/operators_and_hamiltonians.md +++ b/docs/src/concepts/operators_and_hamiltonians.md @@ -77,7 +77,6 @@ Every complete left-to-right path through the block matrix contributes one term The repeated ``A`` block is what makes longer-range interactions possible at fixed virtual dimension: choosing ``A`` to be (a multiple of) the identity gives every additional site the same weight, while a decaying ``A`` gives geometrically decaying couplings. A sum of such geometric series can approximate a power-law interaction to any desired accuracy, which is how (exponentially decaying) infinite-range and approximate power-law couplings are represented. - ### The transverse-field Ising Hamiltonian diff --git a/docs/src/concepts/vector_spaces.md b/docs/src/concepts/vector_spaces.md index 3d2e4970f..38beb36da 100644 --- a/docs/src/concepts/vector_spaces.md +++ b/docs/src/concepts/vector_spaces.md @@ -125,7 +125,6 @@ An MPS site tensor has a left virtual space `Vₗ`, one or more physical spaces At first glance this ordering looks arbitrary, but it is chosen to keep the tensor networks **planar**: the legs run left-to-right without any lines having to cross. Planarity is what lets the algorithms be written without spurious crossings, and this matters most for **fermionic systems**, where every extra line crossing carries a sign and unnecessary crossings would reintroduce a sign problem. - ### The MPS tensor diff --git a/docs/src/tutorials/time_evolution.md b/docs/src/tutorials/time_evolution.md index cff01897a..21e8474e4 100644 --- a/docs/src/tutorials/time_evolution.md +++ b/docs/src/tutorials/time_evolution.md @@ -40,7 +40,6 @@ nothing # hide ``` The observable we will track through the evolution is the transverse magnetization ``\langle\sigma^x\rangle`` at the middle of the chain, away from the open ends. - We measure its baseline value in the pre-quench ground state: ```@example time-evolution @@ -60,7 +59,6 @@ g₁ = 2.0 H₁ = transverse_field_ising(FiniteChain(L); g = g₁) ``` - ## 3. A single time step @@ -121,12 +119,10 @@ plot(times, m; ``` The curve shows how the observable responds to the sudden change in the field: starting from its pre-quench value, ``\langle\sigma^x\rangle`` relaxes towards a new value set by `H₁`, with oscillations along the way. - !!! warning "Fixed bond dimension means finite reach in time" Single-site TDVP keeps the bond dimension fixed at whatever the initial state has. After a quench, however, the entanglement of the evolving state grows with time, so a fixed bond dimension can only follow the true dynamics faithfully up to some finite time — beyond it, the simulation quietly loses accuracy rather than failing loudly. - The practical checks and remedies — two-site [`TDVP2`](@ref), which grows the bond dimension as it truncates, and bond-expansion options for single-site TDVP — are collected in [Time evolution](@ref howto_time_evolution). ## Where to go next diff --git a/docs/src/tutorials/using_symmetries.md b/docs/src/tutorials/using_symmetries.md index 6a394f676..220dacce3 100644 --- a/docs/src/tutorials/using_symmetries.md +++ b/docs/src/tutorials/using_symmetries.md @@ -40,9 +40,6 @@ using MPSKit, MPSKitModels, TensorKit We start from the workflow of the first tutorial: a chain of `L = 16` sites, a random `FiniteMPS`, and a DMRG ground-state search. Two small changes from before: we set the field to `g = 2.0`, and we use a total bond dimension of 16. - Why `g = 2.0`? This puts us deep in the paramagnetic phase, where the ground state respects the spin-flip symmetry. That matters for what comes next: an MPS built from symmetric tensors lives in exactly one parity sector and *cannot* spontaneously break the symmetry, so a fair comparison needs a point where the true ground state is symmetric to begin with. @@ -77,8 +74,6 @@ For the state, the plain spaces `ℂ^2` and `ℂ^16` are replaced by *graded* sp The syntax reads as a list of `sector => dimension` pairs, where sector `0` is the even (``P = +1``) irrep of ``\mathbb{Z}_2`` and sector `1` is the odd (``P = -1``) one: - The physical space `Z2Space(0 => 1, 1 => 1)` is the familiar two-dimensional spin-1/2 site, now split into its symmetry content: one even state and one odd state. - - The virtual space `Z2Space(0 => 8, 1 => 8)` says the bond carries 8 states of even parity and 8 of odd parity — 16 in total, matching the `ℂ^16` of the plain run, so the two calculations have exactly the same variational power. From here the workflow is unchanged: @@ -128,10 +123,6 @@ Iterating `pairs` gives each sector together with its singular values: collect(pairs(spectrum)) ``` - This block structure is where the speedup comes from: instead of multiplying one dense 16-dimensional bond index, the computer multiplies two independent blocks of roughly half that size, and the forbidden matrix elements between the sectors are never stored or touched at all. At bond dimension 16 the difference is negligible, but the saving grows with the bond dimension and with the size of the symmetry group. @@ -139,10 +130,6 @@ At bond dimension 16 the difference is negligible, but the saving grows with the The sector labels are not just an implementation detail — they classify the eigenstates of ``H``, and MPSKit lets you target a sector directly. - In the paramagnetic phase the lowest excitation of the TFIM is, roughly speaking, a single flipped spin. Flipping one spin changes the parity of the state, so this excitation lives in the *odd* sector — a different sector than the (even) ground state. @@ -179,9 +166,6 @@ You have run the flagship TFIM calculation with its ``\mathbb{Z}_2`` symmetry ma The same syntax scales up to larger symmetry groups, where the payoff grows. For a U(1) symmetry (particle number, magnetization) the graded spaces list integer or half-integer charges instead of parities — worked constructions are in [Constructing states](@ref howto_states), Section 9. - For non-abelian symmetries such as SU(2) the gains are more dramatic still, because each symmetric block then represents an entire multiplet of states; the spin-1 Haldane chain and XXZ Heisenberg pages in the examples gallery show this in action. To continue the tutorial track, [Quasiparticle excitations](@ref tutorial_excitations) develops the excitation calculation of Section 4 into a full dispersion relation; the recipe collection for excited states is [Excited states](@ref howto_excitations), and the one for building symmetric states is [Constructing states](@ref howto_states). From e7581196d8d971a26371b33d716ce9fb93e885ae Mon Sep 17 00:00:00 2001 From: lkdvos Date: Thu, 9 Jul 2026 15:39:57 -0400 Subject: [PATCH 68/76] docs: fix landing-page feature icons via public/ dir MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The home-page feature icons (finite-infinite, symmetry, algorithms, fast) 404'd: they were referenced by absolute URL /assets/icons/*.svg, but VitePress only serves absolute URLs from the public/ directory, and DocumenterVitepress auto-copies only top-level logo*/favicon* files from assets/ into public/ — so the icons/ subfolder was never published. Introduce the idiomatic VitePress public/ dir (Documenter mirrors the source tree, so docs/src/public/ lands at build/.documenter/public/, served at root). Move logo.svg, favicon.ico, and icons/*.svg there (creating src/public makes DocumenterVitepress skip its logo/favicon auto-copy, so those move too) and point the frontmatter icons at /icons/*.svg. logo_readme.svg stays in assets/ for the repo README. Verified with a full make.jl build: all six assets resolve at the site root and every index.html reference points to a real file. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/src/index.md | 8 ++++---- docs/src/{assets => public}/favicon.ico | Bin docs/src/{assets => public}/icons/algorithms.svg | 0 docs/src/{assets => public}/icons/fast.svg | 0 .../{assets => public}/icons/finite-infinite.svg | 0 docs/src/{assets => public}/icons/symmetry.svg | 0 docs/src/{assets => public}/logo.svg | 0 7 files changed, 4 insertions(+), 4 deletions(-) rename docs/src/{assets => public}/favicon.ico (100%) rename docs/src/{assets => public}/icons/algorithms.svg (100%) rename docs/src/{assets => public}/icons/fast.svg (100%) rename docs/src/{assets => public}/icons/finite-infinite.svg (100%) rename docs/src/{assets => public}/icons/symmetry.svg (100%) rename docs/src/{assets => public}/logo.svg (100%) diff --git a/docs/src/index.md b/docs/src/index.md index 0f47057ef..25b99ec8a 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -23,23 +23,23 @@ hero: features: - icon: - src: /assets/icons/finite-infinite.svg + src: /icons/finite-infinite.svg alt: A finite chain above an infinite one title: Finite & infinite, one interface details: Run the same calculation on a finite chain or directly in the thermodynamic limit. FiniteMPS and InfiniteMPS share an API, so switching between them is a one-line change. - icon: - src: /assets/icons/symmetry.svg + src: /icons/symmetry.svg alt: A symmetric hexagon title: Every symmetry details: Abelian, non-Abelian, fermionic, and anyonic symmetries out of the box via the TensorKit backend — smaller bond dimensions and exact quantum numbers. - icon: - src: /assets/icons/algorithms.svg + src: /icons/algorithms.svg alt: An energy minimum title: A complete algorithm suite details: Ground states with DMRG, VUMPS, and IDMRG; real- and imaginary-time evolution with TDVP; and momentum-resolved excitations via the quasiparticle ansatz. # REVIEW: make the "faster than ITensors" comparison explicit here once the benchmark results are published. - icon: - src: /assets/icons/fast.svg + src: /icons/fast.svg alt: A lightning bolt title: Fast by design details: Type-stable code paths and deliberate allocation strategies keep calculations quick out of the box, and non-Abelian symmetries such as SU(2) shrink the tensors you store and contract. diff --git a/docs/src/assets/favicon.ico b/docs/src/public/favicon.ico similarity index 100% rename from docs/src/assets/favicon.ico rename to docs/src/public/favicon.ico diff --git a/docs/src/assets/icons/algorithms.svg b/docs/src/public/icons/algorithms.svg similarity index 100% rename from docs/src/assets/icons/algorithms.svg rename to docs/src/public/icons/algorithms.svg diff --git a/docs/src/assets/icons/fast.svg b/docs/src/public/icons/fast.svg similarity index 100% rename from docs/src/assets/icons/fast.svg rename to docs/src/public/icons/fast.svg diff --git a/docs/src/assets/icons/finite-infinite.svg b/docs/src/public/icons/finite-infinite.svg similarity index 100% rename from docs/src/assets/icons/finite-infinite.svg rename to docs/src/public/icons/finite-infinite.svg diff --git a/docs/src/assets/icons/symmetry.svg b/docs/src/public/icons/symmetry.svg similarity index 100% rename from docs/src/assets/icons/symmetry.svg rename to docs/src/public/icons/symmetry.svg diff --git a/docs/src/assets/logo.svg b/docs/src/public/logo.svg similarity index 100% rename from docs/src/assets/logo.svg rename to docs/src/public/logo.svg From c7abd12d78c9cbe7ec0c4c1b244f2d52d3fdee28 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Fri, 10 Jul 2026 09:28:33 -0400 Subject: [PATCH 69/76] docs: add symmetries concept page; reorganize examples gallery topic-first MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - concepts/symmetries.md: flagship symmetry concept page (abelian / non-abelian / fermionic / anyonic, sectors, "when does SU(2) pay off"); every @example verified against real MPSKit; 4 REVIEW flags left for maintainer physics review. Anyonic section points at the hard-hexagon Fibonacci example. - examples gallery regrouped by computational task (groundstates / excitations / dynamics / statmech), replacing the quantum1d/classic2d split. Both make.jl files now auto-discover groups; Cache.toml re-keyed to new paths so the 10 existing examples are not rebuilt; embedded source paths + landing-page links updated. - new excitations/1.su3-heisenberg example reproducing the SU(3) [3 0 0] Heisenberg chain (devos2022) via SUNRepresentations.jl (added to the shared examples env). Hamiltonian built by hand (Casimir identity); computed [210] dispersion minimum is at k=2π/3 but ~-0.04, not the paper's +0.0263 — flagged, not hardcoded, pending maintainer physics review. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/make.jl | 22 +- docs/src/concepts/symmetries.md | 170 ++++++++++ .../0.ising-dqpt}/finite_timeev.png | Bin .../0.ising-dqpt}/index.md | 8 +- .../0.ising-dqpt}/infinite_timeev.png | Bin .../0.ising-dqpt}/main.ipynb | 0 .../1.xy-finiteT}/figure-1.png | Bin .../1.xy-finiteT}/figure-2.png | Bin .../1.xy-finiteT}/figure-3.png | Bin .../1.xy-finiteT}/figure-4.png | Bin .../1.xy-finiteT}/figure-5.png | Bin .../1.xy-finiteT}/figure-6.png | Bin .../1.xy-finiteT}/index.md | 8 +- .../1.xy-finiteT}/main.ipynb | 0 .../0.haldane}/figure-1.png | Bin .../0.haldane}/figure-2.png | Bin .../0.haldane}/figure-3.png | Bin .../0.haldane}/index.md | 8 +- .../0.haldane}/main.ipynb | 0 .../excitations/1.su3-heisenberg/figure-1.png | Bin 0 -> 28848 bytes .../excitations/1.su3-heisenberg/index.md | 275 +++++++++++++++ .../excitations/1.su3-heisenberg/main.ipynb | 312 ++++++++++++++++++ .../0.tfim-groundstate/figure-1.png | Bin .../0.tfim-groundstate/figure-2.png | Bin .../0.tfim-groundstate/figure-3.png | Bin .../0.tfim-groundstate/index.md | 8 +- .../0.tfim-groundstate/main.ipynb | 0 .../1.xxz-heisenberg}/figure-1.png | Bin .../1.xxz-heisenberg}/figure-2.png | Bin .../1.xxz-heisenberg}/index.md | 8 +- .../1.xxz-heisenberg}/main.ipynb | 0 .../2.hubbard}/figure-1.png | Bin .../2.hubbard}/figure-2.png | Bin .../2.hubbard}/figure-3.png | Bin .../2.hubbard}/index.md | 8 +- .../2.hubbard}/main.ipynb | 0 .../3.bose-hubbard}/figure-1.png | Bin .../3.bose-hubbard}/figure-2.png | Bin .../3.bose-hubbard}/figure-3.png | Bin .../3.bose-hubbard}/figure-4.png | Bin .../3.bose-hubbard}/figure-5.png | Bin .../3.bose-hubbard}/figure-6.png | Bin .../3.bose-hubbard}/index.md | 8 +- .../3.bose-hubbard}/main.ipynb | 0 .../4.haldane-spt}/figure-1.png | Bin .../4.haldane-spt}/figure-2.png | Bin .../4.haldane-spt}/figure-3.png | Bin .../4.haldane-spt}/index.md | 8 +- .../4.haldane-spt}/main.ipynb | 0 .../4.haldane-spt}/spt-tensors.svg | 0 .../5.ising-cft}/figure-1.png | Bin .../5.ising-cft}/figure-2.png | Bin .../5.ising-cft}/figure-3.png | Bin .../5.ising-cft}/index.md | 8 +- .../5.ising-cft}/main.ipynb | 0 .../5.ising-cft}/translation_mpo.svg | 0 docs/src/examples/index.md | 105 +++--- .../0.hard-hexagon}/figure-1.png | Bin .../0.hard-hexagon}/hexagon.svg | 0 .../0.hard-hexagon}/index.md | 8 +- .../0.hard-hexagon}/main.ipynb | 0 docs/src/index.md | 4 +- examples/Cache.toml | 27 +- examples/Project.toml | 1 + .../0.ising-dqpt}/finite_timeev.png | Bin .../0.ising-dqpt}/infinite_timeev.png | Bin .../0.ising-dqpt}/main.jl | 0 .../1.xy-finiteT}/main.jl | 0 .../0.haldane}/main.jl | 0 examples/excitations/1.su3-heisenberg/main.jl | 200 +++++++++++ .../0.tfim-groundstate/main.jl | 0 .../1.xxz-heisenberg}/main.jl | 0 .../2.hubbard}/main.jl | 0 .../3.bose-hubbard}/main.jl | 0 .../4.haldane-spt}/main.jl | 0 .../4.haldane-spt}/spt-tensors.svg | 0 .../5.ising-cft}/main.jl | 0 .../5.ising-cft}/translation_mpo.svg | 0 examples/make.jl | 8 +- .../0.hard-hexagon}/hexagon.svg | 0 .../0.hard-hexagon}/main.jl | 0 81 files changed, 1095 insertions(+), 109 deletions(-) create mode 100644 docs/src/concepts/symmetries.md rename docs/src/examples/{quantum1d/3.ising-dqpt => dynamics/0.ising-dqpt}/finite_timeev.png (100%) rename docs/src/examples/{quantum1d/3.ising-dqpt => dynamics/0.ising-dqpt}/index.md (95%) rename docs/src/examples/{quantum1d/3.ising-dqpt => dynamics/0.ising-dqpt}/infinite_timeev.png (100%) rename docs/src/examples/{quantum1d/3.ising-dqpt => dynamics/0.ising-dqpt}/main.ipynb (100%) rename docs/src/examples/{quantum1d/7.xy-finiteT => dynamics/1.xy-finiteT}/figure-1.png (100%) rename docs/src/examples/{quantum1d/7.xy-finiteT => dynamics/1.xy-finiteT}/figure-2.png (100%) rename docs/src/examples/{quantum1d/7.xy-finiteT => dynamics/1.xy-finiteT}/figure-3.png (100%) rename docs/src/examples/{quantum1d/7.xy-finiteT => dynamics/1.xy-finiteT}/figure-4.png (100%) rename docs/src/examples/{quantum1d/7.xy-finiteT => dynamics/1.xy-finiteT}/figure-5.png (100%) rename docs/src/examples/{quantum1d/7.xy-finiteT => dynamics/1.xy-finiteT}/figure-6.png (100%) rename docs/src/examples/{quantum1d/7.xy-finiteT => dynamics/1.xy-finiteT}/index.md (98%) rename docs/src/examples/{quantum1d/7.xy-finiteT => dynamics/1.xy-finiteT}/main.ipynb (100%) rename docs/src/examples/{quantum1d/2.haldane => excitations/0.haldane}/figure-1.png (100%) rename docs/src/examples/{quantum1d/2.haldane => excitations/0.haldane}/figure-2.png (100%) rename docs/src/examples/{quantum1d/2.haldane => excitations/0.haldane}/figure-3.png (100%) rename docs/src/examples/{quantum1d/2.haldane => excitations/0.haldane}/index.md (95%) rename docs/src/examples/{quantum1d/2.haldane => excitations/0.haldane}/main.ipynb (100%) create mode 100644 docs/src/examples/excitations/1.su3-heisenberg/figure-1.png create mode 100644 docs/src/examples/excitations/1.su3-heisenberg/index.md create mode 100644 docs/src/examples/excitations/1.su3-heisenberg/main.ipynb rename docs/src/examples/{quantum1d => groundstates}/0.tfim-groundstate/figure-1.png (100%) rename docs/src/examples/{quantum1d => groundstates}/0.tfim-groundstate/figure-2.png (100%) rename docs/src/examples/{quantum1d => groundstates}/0.tfim-groundstate/figure-3.png (100%) rename docs/src/examples/{quantum1d => groundstates}/0.tfim-groundstate/index.md (96%) rename docs/src/examples/{quantum1d => groundstates}/0.tfim-groundstate/main.ipynb (100%) rename docs/src/examples/{quantum1d/4.xxz-heisenberg => groundstates/1.xxz-heisenberg}/figure-1.png (100%) rename docs/src/examples/{quantum1d/4.xxz-heisenberg => groundstates/1.xxz-heisenberg}/figure-2.png (100%) rename docs/src/examples/{quantum1d/4.xxz-heisenberg => groundstates/1.xxz-heisenberg}/index.md (94%) rename docs/src/examples/{quantum1d/4.xxz-heisenberg => groundstates/1.xxz-heisenberg}/main.ipynb (100%) rename docs/src/examples/{quantum1d/6.hubbard => groundstates/2.hubbard}/figure-1.png (100%) rename docs/src/examples/{quantum1d/6.hubbard => groundstates/2.hubbard}/figure-2.png (100%) rename docs/src/examples/{quantum1d/6.hubbard => groundstates/2.hubbard}/figure-3.png (100%) rename docs/src/examples/{quantum1d/6.hubbard => groundstates/2.hubbard}/index.md (98%) rename docs/src/examples/{quantum1d/6.hubbard => groundstates/2.hubbard}/main.ipynb (100%) rename docs/src/examples/{quantum1d/8.bose-hubbard => groundstates/3.bose-hubbard}/figure-1.png (100%) rename docs/src/examples/{quantum1d/8.bose-hubbard => groundstates/3.bose-hubbard}/figure-2.png (100%) rename docs/src/examples/{quantum1d/8.bose-hubbard => groundstates/3.bose-hubbard}/figure-3.png (100%) rename docs/src/examples/{quantum1d/8.bose-hubbard => groundstates/3.bose-hubbard}/figure-4.png (100%) rename docs/src/examples/{quantum1d/8.bose-hubbard => groundstates/3.bose-hubbard}/figure-5.png (100%) rename docs/src/examples/{quantum1d/8.bose-hubbard => groundstates/3.bose-hubbard}/figure-6.png (100%) rename docs/src/examples/{quantum1d/8.bose-hubbard => groundstates/3.bose-hubbard}/index.md (98%) rename docs/src/examples/{quantum1d/8.bose-hubbard => groundstates/3.bose-hubbard}/main.ipynb (100%) rename docs/src/examples/{quantum1d/5.haldane-spt => groundstates/4.haldane-spt}/figure-1.png (100%) rename docs/src/examples/{quantum1d/5.haldane-spt => groundstates/4.haldane-spt}/figure-2.png (100%) rename docs/src/examples/{quantum1d/5.haldane-spt => groundstates/4.haldane-spt}/figure-3.png (100%) rename docs/src/examples/{quantum1d/5.haldane-spt => groundstates/4.haldane-spt}/index.md (95%) rename docs/src/examples/{quantum1d/5.haldane-spt => groundstates/4.haldane-spt}/main.ipynb (100%) rename docs/src/examples/{quantum1d/5.haldane-spt => groundstates/4.haldane-spt}/spt-tensors.svg (100%) rename docs/src/examples/{quantum1d/1.ising-cft => groundstates/5.ising-cft}/figure-1.png (100%) rename docs/src/examples/{quantum1d/1.ising-cft => groundstates/5.ising-cft}/figure-2.png (100%) rename docs/src/examples/{quantum1d/1.ising-cft => groundstates/5.ising-cft}/figure-3.png (100%) rename docs/src/examples/{quantum1d/1.ising-cft => groundstates/5.ising-cft}/index.md (95%) rename docs/src/examples/{quantum1d/1.ising-cft => groundstates/5.ising-cft}/main.ipynb (100%) rename docs/src/examples/{quantum1d/1.ising-cft => groundstates/5.ising-cft}/translation_mpo.svg (100%) rename docs/src/examples/{classic2d/1.hard-hexagon => statmech/0.hard-hexagon}/figure-1.png (100%) rename docs/src/examples/{classic2d/1.hard-hexagon => statmech/0.hard-hexagon}/hexagon.svg (100%) rename docs/src/examples/{classic2d/1.hard-hexagon => statmech/0.hard-hexagon}/index.md (94%) rename docs/src/examples/{classic2d/1.hard-hexagon => statmech/0.hard-hexagon}/main.ipynb (100%) rename examples/{quantum1d/3.ising-dqpt => dynamics/0.ising-dqpt}/finite_timeev.png (100%) rename examples/{quantum1d/3.ising-dqpt => dynamics/0.ising-dqpt}/infinite_timeev.png (100%) rename examples/{quantum1d/3.ising-dqpt => dynamics/0.ising-dqpt}/main.jl (100%) rename examples/{quantum1d/7.xy-finiteT => dynamics/1.xy-finiteT}/main.jl (100%) rename examples/{quantum1d/2.haldane => excitations/0.haldane}/main.jl (100%) create mode 100644 examples/excitations/1.su3-heisenberg/main.jl rename examples/{quantum1d => groundstates}/0.tfim-groundstate/main.jl (100%) rename examples/{quantum1d/4.xxz-heisenberg => groundstates/1.xxz-heisenberg}/main.jl (100%) rename examples/{quantum1d/6.hubbard => groundstates/2.hubbard}/main.jl (100%) rename examples/{quantum1d/8.bose-hubbard => groundstates/3.bose-hubbard}/main.jl (100%) rename examples/{quantum1d/5.haldane-spt => groundstates/4.haldane-spt}/main.jl (100%) rename examples/{quantum1d/5.haldane-spt => groundstates/4.haldane-spt}/spt-tensors.svg (100%) rename examples/{quantum1d/1.ising-cft => groundstates/5.ising-cft}/main.jl (100%) rename examples/{quantum1d/1.ising-cft => groundstates/5.ising-cft}/translation_mpo.svg (100%) rename examples/{classic2d/1.hard-hexagon => statmech/0.hard-hexagon}/hexagon.svg (100%) rename examples/{classic2d/1.hard-hexagon => statmech/0.hard-hexagon}/main.jl (100%) diff --git a/docs/make.jl b/docs/make.jl index 0f48ed51e..9d225afc7 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -12,13 +12,19 @@ using DocumenterVitepress using DocumenterCitations using DocumenterInterLinks -# examples +# examples — grouped by computational task; each group is a subdirectory of src/examples/ example_dir = joinpath(@__DIR__, "src", "examples") -classic_pages = map(readdir(joinpath(example_dir, "classic2d"))) do dir - return joinpath("examples", "classic2d", dir, "index.md") -end -quantum_pages = map(readdir(joinpath(example_dir, "quantum1d"))) do dir - return joinpath("examples", "quantum1d", dir, "index.md") +example_groups = [ + "Ground states" => "groundstates", + "Excitations & dispersions" => "excitations", + "Dynamics & finite temperature" => "dynamics", + "Statistical mechanics" => "statmech", +] +example_pages = map(example_groups) do (title, group) + pages = map(readdir(joinpath(example_dir, group))) do dir + return joinpath("examples", group, dir, "index.md") + end + return title => pages end # bibliography @@ -74,14 +80,14 @@ makedocs(; "concepts/vector_spaces.md", "concepts/matrix_product_states.md", "concepts/operators_and_hamiltonians.md", + "concepts/symmetries.md", "concepts/algorithm_landscape.md", "concepts/environments.md", "concepts/parallelism_model.md", ], "Examples" => [ "Overview" => "examples/index.md", - "Quantum (1+1)d" => quantum_pages, - "Classical (2+0)d" => classic_pages, + example_pages..., ], "Library" => [ "lib/public.md", diff --git a/docs/src/concepts/symmetries.md b/docs/src/concepts/symmetries.md new file mode 100644 index 000000000..78849f6ee --- /dev/null +++ b/docs/src/concepts/symmetries.md @@ -0,0 +1,170 @@ +```@meta +DocTestSetup = quote + using MPSKit, MPSKitModels, TensorKit +end +``` + +# [Symmetries](@id concept_symmetries) + +[TensorKit for MPS users](@ref concept_vector_spaces) already showed the key fact: a symmetry in MPSKit is not a flag passed to an algorithm, it is a property of the vector *spaces* that a tensor is built from, and every algorithm is written once, generically, for any such space. +That page built the mental model of a `TensorMap` and introduced graded spaces through a single ℤ₂ example. +This page stays at the same level of abstraction but widens the lens: what kinds of symmetry a graded space can encode, what changes qualitatively as you move from an abelian group to a non-abelian one or to fermionic or anyonic statistics, and — the question every user eventually asks — when the extra bookkeeping of a bigger symmetry group is actually worth it. +For the hands-on version of the ℤ₂ case worked all the way through a ground-state search, see [Using symmetries](@ref tutorial_using_symmetries); this page explains the reasoning behind that recipe and extends it to the other symmetry classes MPSKit supports. + +As on the sibling page, none of the symmetry machinery lives in `MPSKit` or `MPSKitModels` itself: `using MPSKit` does not bring a single sector or space type into scope, and neither does `using MPSKitModels`. +Every symmetric object — `Z2Irrep`, `U1Irrep`, `SU2Irrep`, `Z2Space`, `U1Space`, and so on — comes from `TensorKit`, so every example on this page loads all three packages explicitly. + +```@example symmetries +using MPSKit, MPSKitModels, TensorKit +``` + +## Sectors, charges, and block-sparsity + +A **sector** is a label for an irreducible representation of the symmetry: for a group symmetry it is one irrep, and a graded space is built by declaring how many copies ("degeneracy" or "multiplicity") of each sector it contains. +[TensorKit for MPS users](@ref concept_vector_spaces) did this for ℤ₂ with `Z2Space(0 => 1, 1 => 1)`; the same `sector => degeneracy` syntax works for every symmetry, so a U(1)-graded space that keeps track of, say, a conserved particle number or magnetization from `-1` to `1` reads: + +```@example symmetries +V = U1Space(-1 => 1, 0 => 1, 1 => 1) +dim(V) +``` + +The space still knows its full sector content, queryable with [`sectors`](https://quantumkithub.github.io/TensorKit.jl/stable/) and [`dim`](https://quantumkithub.github.io/TensorKit.jl/stable/) applied to a specific sector: + +```@example symmetries +collect(sectors(V)) +``` + +```@example symmetries +[dim(V, c) for c in sectors(V)] +``` + +Charge conservation is the statement that a symmetric tensor may only have nonzero entries between sectors whose charges add up correctly (for a Hamiltonian term, incoming and outgoing charge must match). +Concretely this means the tensor is **block-diagonal** in the sector label: what would be one dense array for a plain `ℂ^n` space becomes a handful of smaller, independent dense blocks, one per allowed sector combination, and the entries that connect different sectors are not merely zero — they are never allocated or touched at all. +This is the mechanism behind everything that follows: the *type* of symmetry only changes what the sector labels are and how they combine (their *fusion rules*); the block-sparse storage and the charge-conservation bookkeeping are handled identically underneath. + +## A taxonomy of symmetry types + +MPSKitModels' [`heisenberg_XXX`](https://quantumkithub.github.io/MPSKitModels.jl/stable/) model is a convenient single thread through the taxonomy, because the same Heisenberg Hamiltonian can be built with a trivial symmetry or with any of the three main non-trivial types below, purely by passing a different sector type as the first argument: + +```@example symmetries +H_triv = heisenberg_XXX(FiniteChain(4); spin = 1 // 2) +H_Z2 = heisenberg_XXX(Z2Irrep, FiniteChain(4); spin = 1 // 2) +H_U1 = heisenberg_XXX(U1Irrep, FiniteChain(4); spin = 1 // 2) +H_SU2 = heisenberg_XXX(SU2Irrep, FiniteChain(4); spin = 1 // 2) +``` + +Four `Hamiltonian`s, four different tensor structures, one physical model. + +### Abelian symmetries: ℤ_N and U(1) + +`Z2Irrep`, `Z3Irrep`, `Z4Irrep`, and the general `ZNIrrep`, together with `U1Irrep`, are the abelian family: their sectors are literally the elements of ℤ_N or of the integers (or half-integers), and two sectors fuse by addition modulo N, or ordinary addition for U(1). +Every irrep is one-dimensional, so an abelian symmetry buys exactly the block-sparsity described above and nothing more: `H_Z2` above encodes the same spin-flip parity used throughout [Using symmetries](@ref tutorial_using_symmetries), while `H_U1` encodes conservation of total magnetization ``S^z_{\mathrm{tot}}``, with sectors running over the possible values of ``S^z_{\mathrm{tot}}``. +`transverse_field_ising` is a useful reminder that not every model has every symmetry available: it accepts `Trivial`, `Z2Irrep`, or `FermionParity`, but raises an error for `U1Irrep`, because the transverse-field Ising model genuinely only has the ℤ₂ spin-flip symmetry — there is no conserved U(1) charge to exploit. + +### Non-abelian symmetries: SU(2) + +`SU2Irrep` sectors are labelled by a total spin ``j = 0, \tfrac12, 1, \tfrac32, \dots``, and fusing two of them follows the angular-momentum addition (Clebsch–Gordan) rule rather than simple addition: fusing spin ``j_1`` and ``j_2`` can produce any ``j`` from ``|j_1-j_2|`` to ``j_1+j_2``. +The qualitative difference from the abelian case is that each sector ``j`` is not one-dimensional but ``(2j+1)``-dimensional, and a symmetric tensor need only store the multiplicity of each ``j`` — the internal ``(2j+1)`` structure of every multiplet is fixed by representation theory and is never stored explicitly. +`H_SU2` above is built exactly this way: it is the same Heisenberg chain, only now every eigenstate additionally carries a total-spin label, and the tensors only ever store one number per multiplet rather than one number per individual magnetic sublevel. +The next section makes this saving concrete. + +### Fermionic symmetries and product sectors + +`FermionParity` grades a space into an even and an odd fermion-number sector, and — crucially — TensorKit's fermionic tensor category attaches the anticommutation sign directly to the braiding of `FermionParity`-graded legs, so that once physical and virtual legs carry this sector, index permutations automatically pick up the correct fermionic signs instead of requiring the sign rule to be implemented by hand in every algorithm [mortier2025](@cite). +Models with more than one physical species combine sectors with `⊠` (typed `\boxtimes`) into a `ProductSector`, for instance an odd fermion paired with unit U(1) charge: + +```@example symmetries +FermionParity(1) ⊠ U1Irrep(1) +``` + +`hubbard_model` exercises this directly: it takes an independent *particle* symmetry and *spin* symmetry, and assembles the physical space internally out of `FermionParity ⊠ (particle symmetry)` and `FermionParity ⊠ (spin symmetry)` pieces. +Choosing U(1) for particle number and SU(2) for spin gives the maximally symmetric Hubbard chain: + +```@example symmetries +H_hub = hubbard_model(ComplexF64, U1Irrep, SU2Irrep, FiniteChain(4); t = 1.0, U = 8.0) +``` + +The first argument is the scalar element type, required here because a lattice is given explicitly; the two symmetry types then set the particle-number and spin symmetries in that order. + +By contrast, `bose_hubbard_model` only accepts `Trivial` or `U1Irrep`: bosons carry no parity grading, so there is no fermionic sign to encode and no spin degree of freedom to make non-abelian. +At the far end of this spectrum, `quantum_chemistry_hamiltonian` does not expose a symmetry choice at all — it always builds its tensors with the fixed, maximal ``U(1) \boxtimes SU(2) \boxtimes \mathrm{FermionParity}`` symmetry (particle number, total spin, and fermionic sign), because for realistic molecular Hamiltonians that full symmetry is essentially always worth imposing. + +### Anyonic symmetries + +The generality goes further than groups. +Sectors such as `FibonacciAnyon` or `IsingAnyon` are not group representations at all — their fusion rules come from a modular tensor category — yet because every MPSKit algorithm is written against the abstract `Sector` interface, they are handled by exactly the same code paths, with no special-casing. +The [hard-hexagon model](@ref "The Hard Hexagon model") example puts this to work: its transfer matrix is built from `FibonacciAnyon`-graded tensors (`Vect[FibonacciAnyon](:I => …, :τ => …)`), and the standard statistical-mechanics workflow computes its partition function just as it would for an ordinary symmetry. + + +## When does SU(2) pay off + +Two distinct effects are at play whenever a symmetry is switched on, and it is worth separating them because only one of them scales with the size of the symmetry group. + +The first effect is the block-sparsity already described: at a fixed total bond dimension, the computer multiplies several smaller dense blocks instead of one large one, and the (forbidden) cross-sector entries are never stored. +[Using symmetries](@ref tutorial_using_symmetries) demonstrates this concretely for ℤ₂: the same 16-dimensional bond becomes two roughly-8-dimensional blocks. +This first effect is present for *any* symmetry, abelian or not, and its benefit grows with the number of distinct sectors the bond dimension gets spread over. + +The second effect is specific to non-abelian symmetries and is qualitatively larger: because a whole ``(2j+1)``-dimensional multiplet is represented by a single stored block, the *number of stored parameters* needed to reach a given *total*, physical bond dimension shrinks. +This can be checked directly: build a graded SU(2) space and compare its total dimension against the multiplicities it actually stores per sector. + +```@example symmetries +V_SU2 = SU2Space(0 => 2, 1 // 2 => 4) +dim(V_SU2) +``` + +```@example symmetries +[dim(V_SU2, c) for c in sectors(V_SU2)] +``` + +The total dimension `dim(V_SU2)` is `10`, because each spin-``j`` sector contributes its ``(2j+1)``-fold multiplet: ``2 \times (2\cdot 0 + 1) + 4 \times (2\cdot\tfrac12 + 1) = 2 + 8 = 10``. +But `dim(V_SU2, c)` returns the *stored* multiplicity of each sector — here `[2, 4]`, just six numbers in total — because the ``(2j+1)`` internal structure of every multiplet is fixed by representation theory and never stored. +For an abelian symmetry the two coincide (every irrep is one-dimensional, so the multiplicities and the total dimension agree, as with the U(1) space above); it is precisely for a non-abelian group that the stored count falls below the physical dimension. + + + +The gap between the physical dimension (`10`) and the six numbers actually stored is the source of SU(2)'s reputation for letting DMRG reach much larger effective bond dimensions at the same computational cost — the same principle used to push non-abelian symmetric uniform MPS to large SU(3) bond dimensions in practice [devos2022](@cite). + + + +None of this is free. +Every symmetric block carries the overhead of tracking fusion trees and recombining Clebsch–Gordan coefficients whenever legs are permuted or contracted, and for a non-abelian group this bookkeeping is genuinely more expensive per block than for an abelian one. + +In practice this means SU(2) (or any non-abelian symmetry) is worth reaching for when the physics genuinely has that symmetry — a spin chain with full rotational invariance, for instance — and when the bond dimension is large enough that the multiplet-reduction saving dominates the per-block overhead; for small bond dimensions, or for a symmetry the Hamiltonian does not actually have, the abelian or even trivial case is often simpler and just as fast. + +## Fixing the total charge + +Sector labels are not only a storage optimization: they are physical quantum numbers, and MPSKit lets a calculation target a specific one directly. + +For an MPS, the total charge is fixed by giving the state a non-trivial `left` or `right` virtual space, rather than the default unit (trivial-charge) one: + +```@example symmetries +ψ_odd = FiniteMPS( + 4, Z2Space(0 => 1, 1 => 1), Z2Space(0 => 2, 1 => 2); + left = Z2Space(1 => 1) +) +left_virtualspace(ψ_odd, 1) +``` + +Every tensor in `ψ_odd` is now forced, by charge conservation, to represent a state of odd total parity — there is no way for a symmetric MPS built this way to drift into the even sector. +The same idea appears for excited states and for transfer-matrix spectra: the `sector` keyword of [`excitations`](@ref) and of `transfer_spectrum` restricts the search to a chosen total charge instead of the default trivial one, exactly as used to isolate the odd-parity excitation of the TFIM in [Using symmetries](@ref tutorial_using_symmetries). +[Excited states](@ref howto_excitations) collects further recipes for working with `sector`, and [Constructing states](@ref howto_states) collects the analogous recipes for building states with a prescribed symmetry and charge. + +## Where to go next + +- For the tensor mechanics underneath all of this — spaces, `TensorMap`s, index conventions — see [TensorKit for MPS users](@ref concept_vector_spaces). +- For the fully worked ℤ₂ example, from Hamiltonian to ground state to a sector-targeted excitation, see [Using symmetries](@ref tutorial_using_symmetries). +- For how symmetric tensors assemble into states and operators, see [Matrix product states](@ref concept_matrix_product_states) and [Operators and Hamiltonians](@ref concept_operators_and_hamiltonians). +- For task recipes that use a `sector` or a charged virtual space, see [Constructing states](@ref howto_states), [Excited states](@ref howto_excitations), and [Entanglement entropy and spectrum](@ref howto_entanglement). + + diff --git a/docs/src/examples/quantum1d/3.ising-dqpt/finite_timeev.png b/docs/src/examples/dynamics/0.ising-dqpt/finite_timeev.png similarity index 100% rename from docs/src/examples/quantum1d/3.ising-dqpt/finite_timeev.png rename to docs/src/examples/dynamics/0.ising-dqpt/finite_timeev.png diff --git a/docs/src/examples/quantum1d/3.ising-dqpt/index.md b/docs/src/examples/dynamics/0.ising-dqpt/index.md similarity index 95% rename from docs/src/examples/quantum1d/3.ising-dqpt/index.md rename to docs/src/examples/dynamics/0.ising-dqpt/index.md index c92c48efa..e5d202b36 100644 --- a/docs/src/examples/quantum1d/3.ising-dqpt/index.md +++ b/docs/src/examples/dynamics/0.ising-dqpt/index.md @@ -1,10 +1,10 @@ ```@meta -EditURL = "../../../../../examples/quantum1d/3.ising-dqpt/main.jl" +EditURL = "../../../../../examples/dynamics/0.ising-dqpt/main.jl" ``` -[![](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/QuantumKitHub/MPSKit.jl/gh-pages?filepath=dev/examples/quantum1d/3.ising-dqpt/main.ipynb) -[![](https://img.shields.io/badge/show-nbviewer-579ACA.svg)](https://nbviewer.jupyter.org/github/QuantumKitHub/MPSKit.jl/blob/gh-pages/dev/examples/quantum1d/3.ising-dqpt/main.ipynb) -[![](https://img.shields.io/badge/download-project-orange)](https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/QuantumKitHub/MPSKit.jl/examples/tree/gh-pages/dev/examples/quantum1d/3.ising-dqpt) +[![](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/QuantumKitHub/MPSKit.jl/gh-pages?filepath=dev/examples/dynamics/0.ising-dqpt/main.ipynb) +[![](https://img.shields.io/badge/show-nbviewer-579ACA.svg)](https://nbviewer.jupyter.org/github/QuantumKitHub/MPSKit.jl/blob/gh-pages/dev/examples/dynamics/0.ising-dqpt/main.ipynb) +[![](https://img.shields.io/badge/download-project-orange)](https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/QuantumKitHub/MPSKit.jl/examples/tree/gh-pages/dev/examples/dynamics/0.ising-dqpt) # DQPT in the Ising model diff --git a/docs/src/examples/quantum1d/3.ising-dqpt/infinite_timeev.png b/docs/src/examples/dynamics/0.ising-dqpt/infinite_timeev.png similarity index 100% rename from docs/src/examples/quantum1d/3.ising-dqpt/infinite_timeev.png rename to docs/src/examples/dynamics/0.ising-dqpt/infinite_timeev.png diff --git a/docs/src/examples/quantum1d/3.ising-dqpt/main.ipynb b/docs/src/examples/dynamics/0.ising-dqpt/main.ipynb similarity index 100% rename from docs/src/examples/quantum1d/3.ising-dqpt/main.ipynb rename to docs/src/examples/dynamics/0.ising-dqpt/main.ipynb diff --git a/docs/src/examples/quantum1d/7.xy-finiteT/figure-1.png b/docs/src/examples/dynamics/1.xy-finiteT/figure-1.png similarity index 100% rename from docs/src/examples/quantum1d/7.xy-finiteT/figure-1.png rename to docs/src/examples/dynamics/1.xy-finiteT/figure-1.png diff --git a/docs/src/examples/quantum1d/7.xy-finiteT/figure-2.png b/docs/src/examples/dynamics/1.xy-finiteT/figure-2.png similarity index 100% rename from docs/src/examples/quantum1d/7.xy-finiteT/figure-2.png rename to docs/src/examples/dynamics/1.xy-finiteT/figure-2.png diff --git a/docs/src/examples/quantum1d/7.xy-finiteT/figure-3.png b/docs/src/examples/dynamics/1.xy-finiteT/figure-3.png similarity index 100% rename from docs/src/examples/quantum1d/7.xy-finiteT/figure-3.png rename to docs/src/examples/dynamics/1.xy-finiteT/figure-3.png diff --git a/docs/src/examples/quantum1d/7.xy-finiteT/figure-4.png b/docs/src/examples/dynamics/1.xy-finiteT/figure-4.png similarity index 100% rename from docs/src/examples/quantum1d/7.xy-finiteT/figure-4.png rename to docs/src/examples/dynamics/1.xy-finiteT/figure-4.png diff --git a/docs/src/examples/quantum1d/7.xy-finiteT/figure-5.png b/docs/src/examples/dynamics/1.xy-finiteT/figure-5.png similarity index 100% rename from docs/src/examples/quantum1d/7.xy-finiteT/figure-5.png rename to docs/src/examples/dynamics/1.xy-finiteT/figure-5.png diff --git a/docs/src/examples/quantum1d/7.xy-finiteT/figure-6.png b/docs/src/examples/dynamics/1.xy-finiteT/figure-6.png similarity index 100% rename from docs/src/examples/quantum1d/7.xy-finiteT/figure-6.png rename to docs/src/examples/dynamics/1.xy-finiteT/figure-6.png diff --git a/docs/src/examples/quantum1d/7.xy-finiteT/index.md b/docs/src/examples/dynamics/1.xy-finiteT/index.md similarity index 98% rename from docs/src/examples/quantum1d/7.xy-finiteT/index.md rename to docs/src/examples/dynamics/1.xy-finiteT/index.md index b05342a1e..c157158a9 100644 --- a/docs/src/examples/quantum1d/7.xy-finiteT/index.md +++ b/docs/src/examples/dynamics/1.xy-finiteT/index.md @@ -1,10 +1,10 @@ ```@meta -EditURL = "../../../../../examples/quantum1d/7.xy-finiteT/main.jl" +EditURL = "../../../../../examples/dynamics/1.xy-finiteT/main.jl" ``` -[![](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/QuantumKitHub/MPSKit.jl/gh-pages?filepath=dev/examples/quantum1d/7.xy-finiteT/main.ipynb) -[![](https://img.shields.io/badge/show-nbviewer-579ACA.svg)](https://nbviewer.jupyter.org/github/QuantumKitHub/MPSKit.jl/blob/gh-pages/dev/examples/quantum1d/7.xy-finiteT/main.ipynb) -[![](https://img.shields.io/badge/download-project-orange)](https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/QuantumKitHub/MPSKit.jl/examples/tree/gh-pages/dev/examples/quantum1d/7.xy-finiteT) +[![](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/QuantumKitHub/MPSKit.jl/gh-pages?filepath=dev/examples/dynamics/1.xy-finiteT/main.ipynb) +[![](https://img.shields.io/badge/show-nbviewer-579ACA.svg)](https://nbviewer.jupyter.org/github/QuantumKitHub/MPSKit.jl/blob/gh-pages/dev/examples/dynamics/1.xy-finiteT/main.ipynb) +[![](https://img.shields.io/badge/download-project-orange)](https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/QuantumKitHub/MPSKit.jl/examples/tree/gh-pages/dev/examples/dynamics/1.xy-finiteT) ````julia using Markdown diff --git a/docs/src/examples/quantum1d/7.xy-finiteT/main.ipynb b/docs/src/examples/dynamics/1.xy-finiteT/main.ipynb similarity index 100% rename from docs/src/examples/quantum1d/7.xy-finiteT/main.ipynb rename to docs/src/examples/dynamics/1.xy-finiteT/main.ipynb diff --git a/docs/src/examples/quantum1d/2.haldane/figure-1.png b/docs/src/examples/excitations/0.haldane/figure-1.png similarity index 100% rename from docs/src/examples/quantum1d/2.haldane/figure-1.png rename to docs/src/examples/excitations/0.haldane/figure-1.png diff --git a/docs/src/examples/quantum1d/2.haldane/figure-2.png b/docs/src/examples/excitations/0.haldane/figure-2.png similarity index 100% rename from docs/src/examples/quantum1d/2.haldane/figure-2.png rename to docs/src/examples/excitations/0.haldane/figure-2.png diff --git a/docs/src/examples/quantum1d/2.haldane/figure-3.png b/docs/src/examples/excitations/0.haldane/figure-3.png similarity index 100% rename from docs/src/examples/quantum1d/2.haldane/figure-3.png rename to docs/src/examples/excitations/0.haldane/figure-3.png diff --git a/docs/src/examples/quantum1d/2.haldane/index.md b/docs/src/examples/excitations/0.haldane/index.md similarity index 95% rename from docs/src/examples/quantum1d/2.haldane/index.md rename to docs/src/examples/excitations/0.haldane/index.md index 71bcad85e..d2ba848bb 100644 --- a/docs/src/examples/quantum1d/2.haldane/index.md +++ b/docs/src/examples/excitations/0.haldane/index.md @@ -1,10 +1,10 @@ ```@meta -EditURL = "../../../../../examples/quantum1d/2.haldane/main.jl" +EditURL = "../../../../../examples/excitations/0.haldane/main.jl" ``` -[![](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/QuantumKitHub/MPSKit.jl/gh-pages?filepath=dev/examples/quantum1d/2.haldane/main.ipynb) -[![](https://img.shields.io/badge/show-nbviewer-579ACA.svg)](https://nbviewer.jupyter.org/github/QuantumKitHub/MPSKit.jl/blob/gh-pages/dev/examples/quantum1d/2.haldane/main.ipynb) -[![](https://img.shields.io/badge/download-project-orange)](https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/QuantumKitHub/MPSKit.jl/examples/tree/gh-pages/dev/examples/quantum1d/2.haldane) +[![](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/QuantumKitHub/MPSKit.jl/gh-pages?filepath=dev/examples/excitations/0.haldane/main.ipynb) +[![](https://img.shields.io/badge/show-nbviewer-579ACA.svg)](https://nbviewer.jupyter.org/github/QuantumKitHub/MPSKit.jl/blob/gh-pages/dev/examples/excitations/0.haldane/main.ipynb) +[![](https://img.shields.io/badge/download-project-orange)](https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/QuantumKitHub/MPSKit.jl/examples/tree/gh-pages/dev/examples/excitations/0.haldane) # The Haldane gap diff --git a/docs/src/examples/quantum1d/2.haldane/main.ipynb b/docs/src/examples/excitations/0.haldane/main.ipynb similarity index 100% rename from docs/src/examples/quantum1d/2.haldane/main.ipynb rename to docs/src/examples/excitations/0.haldane/main.ipynb diff --git a/docs/src/examples/excitations/1.su3-heisenberg/figure-1.png b/docs/src/examples/excitations/1.su3-heisenberg/figure-1.png new file mode 100644 index 0000000000000000000000000000000000000000..ac9a559d576d9700a6fd9e6cad649ce33e886918 GIT binary patch literal 28848 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 LtfN$bv3mA@j*pW8 literal 0 HcmV?d00001 diff --git a/docs/src/examples/excitations/1.su3-heisenberg/index.md b/docs/src/examples/excitations/1.su3-heisenberg/index.md new file mode 100644 index 000000000..d995a1103 --- /dev/null +++ b/docs/src/examples/excitations/1.su3-heisenberg/index.md @@ -0,0 +1,275 @@ +```@meta +EditURL = "../../../../../examples/excitations/1.su3-heisenberg/main.jl" +``` + +[![](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/QuantumKitHub/MPSKit.jl/gh-pages?filepath=dev/examples/excitations/1.su3-heisenberg/main.ipynb) +[![](https://img.shields.io/badge/show-nbviewer-579ACA.svg)](https://nbviewer.jupyter.org/github/QuantumKitHub/MPSKit.jl/blob/gh-pages/dev/examples/excitations/1.su3-heisenberg/main.ipynb) +[![](https://img.shields.io/badge/download-project-orange)](https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/QuantumKitHub/MPSKit.jl/examples/tree/gh-pages/dev/examples/excitations/1.su3-heisenberg) + +# The SU(3) Haldane gap + +The spin-1 Heisenberg chain famously has a gapped, symmetry-protected topological ground +state: the Haldane phase. +A natural question is what happens when the ``SU(2)`` symmetry of the spins is promoted to a +larger ``SU(N)`` symmetry. +In this example we study the ``SU(3)`` generalization introduced in [devos2022](@cite): a +uniform chain where every site carries the fully-symmetric ``[3\,0\,0]`` irrep of ``SU(3)`` +(the ten-dimensional representation), coupled by a nearest-neighbour ``SU(3)``-invariant +Heisenberg interaction + +```math +H = J \sum_{\langle i, j \rangle} \sum_{a=1}^{8} T^a_i T^a_j , +``` + +where the ``T^a`` are the eight generators of ``SU(3)``. +This is the direct analog of the spin-1 chain, with the three generators of ``SU(2)`` +replaced by the eight generators of ``SU(3)``. + + + +Working with the full non-abelian ``SU(3)`` symmetry is what makes this tractable. +Just as ``SU(2)`` symmetry drastically shrinks the spin-1 problem (see +[Symmetries](@ref concept_symmetries)), imposing ``SU(3)`` block-diagonalizes every tensor +along its irreducible representations, so that a modest number of variational parameters +already captures a large physical bond dimension. +The Clebsch–Gordan coefficients that this requires are provided by +[SUNRepresentations.jl](https://github.com/QuantumKitHub/SUNRepresentations.jl), whose +`SU3Irrep` sectors plug directly into TensorKit's graded vector spaces. + +!!! warning "First-run cost" + SUNRepresentations.jl computes ``SU(N)`` Clebsch–Gordan coefficients on demand and + caches them both in memory and on disk (via `Scratch.jl`). + The **first** time a given coefficient is needed the computation can be slow; later runs + reuse the on-disk cache. + On a machine without a persisted scratch cache — such as a fresh continuous-integration + runner — this example therefore pays the full coefficient-generation cost once. + +````julia +using TensorKit +using SUNRepresentations +using MPSKit +using Plots +```` + +```` +Precompiling packages... + 1277.5 ms ✓ SparseArrayKit + 7318.1 ms ✓ SUNRepresentations + 2 dependencies successfully precompiled in 10 seconds. 62 already precompiled. +Precompiling packages... + 2203.1 ms ✓ SparseArrayKit → SparseArrayKitSparseArrays + 1 dependency successfully precompiled in 2 seconds. 20 already precompiled. + +```` + +For reproducibility of this page, we fix the seed of the random number generator: + +````julia +using Random +Random.seed!(4321); +```` + +## The model + +Each site carries the ``[3\,0\,0]`` irrep, which we obtain from its highest weight and +represent as a one-dimensional graded space. + +````julia +I300 = SU3Irrep(3, 0, 0) +Vphys = Vect[SU3Irrep](I300 => 1) +@show dim(I300) +```` + +```` +10 +```` + +To build the interaction we use the same Casimir trick as for the ``SU(2)`` chain. +Writing ``C_2 = \sum_a T^a T^a`` for the quadratic Casimir operator, the two-site coupling is +diagonal in the total ``SU(3)`` charge ``c`` of a bond: + +```math +\sum_a T^a_i T^a_j = \tfrac{1}{2}\left( C_2(c) - C_2([3\,0\,0]) - C_2([3\,0\,0]) \right). +``` + +SUNRepresentations.jl provides the quadratic Casimir through `casimir(2, irrep)`. +Its normalization is the standard one with ``\mathrm{tr}(T^a T^b) = \tfrac{1}{2}\delta^{ab}``: +the fundamental ``[1\,0\,0]`` has ``C_2 = 4/3 = (N^2-1)/(2N)``. + +````julia +@show casimir(2, SU3Irrep(1, 0, 0)) +@show casimir(2, I300) +```` + +```` +6//1 +```` + +The nearest-neighbour term is then a single TensorKit operator that acts as a scalar on each +fusion channel of ``[3\,0\,0] \otimes [3\,0\,0]``. +Constructing it by iterating over the blocks — one block per total charge ``c`` — mirrors the +``SU(2)`` construction, but now with `casimir(2, ⋅)` supplying the eigenvalues. + +````julia +function su3_heisenberg(Vphys; J = 1.0) + site = SU3Irrep(3, 0, 0) + c2_site = casimir(2, site) + SS = zeros(ComplexF64, Vphys ⊗ Vphys ← Vphys ⊗ Vphys) + for (c, data) in blocks(SS) + coupling = (casimir(2, c) - 2 * c2_site) / 2 + for i in axes(data, 1) + data[i, i] = J * coupling + end + end + return InfiniteMPOHamiltonian(SS) +end + +H = su3_heisenberg(Vphys) +```` + +```` +1-site InfiniteMPOHamiltonian(ComplexF64, Rep[SU₃]) with maximal dimension 10: +| ⋮ +| (((0, 0, 0)=>1) ⊞ ((2, 1, 0)=>1) ⊞ ((0, 0, 0)=>1)) +┼─[1]─ ((3, 0, 0) => 1) +│ (((0, 0, 0)=>1) ⊞ ((2, 1, 0)=>1) ⊞ ((0, 0, 0)=>1)) +| ⋮ + +```` + +We can read off the physics directly from the fusion channels. +The product ``[3\,0\,0] \otimes [3\,0\,0]`` decomposes into four irreps, and the +antiferromagnetic coupling (``J > 0``) favours the channels of lowest Casimir: + +````julia +for (c, n) in directproduct(I300, I300) + coupling = (casimir(2, c) - 2 * casimir(2, I300)) / 2 + println(rpad(string(c), 22), " dim = ", rpad(dim(c), 4), " coupling = ", coupling) +end +```` + +```` +Irrep[SU₃]((6, 0, 0)) dim = 28 coupling = 3//1 +Irrep[SU₃]((5, 1, 0)) dim = 35 coupling = 0//1 +Irrep[SU₃]((4, 2, 0)) dim = 27 coupling = -2//1 +Irrep[SU₃]((3, 3, 0)) dim = 10 coupling = -3//1 + +```` + +## Ground state + +The ``[3\,0\,0]`` irrep has trivial triality (congruency class ``0``), so — like the +integer-spin Haldane chain — a translation-invariant state on a single-site unit cell is +admissible. +Because the physical charge has triality ``0`` it cannot shift the triality of the virtual +bonds, so every virtual space must sit in a single congruency class; here we use the trivial +class ``0``, which we found to give the lowest variational energy. +Following [devos2022](@cite), we seed the optimization with a random ``SU(3)``-symmetric +uniform state and optimize with VUMPS. + + + +````julia +Vvirt = Vect[SU3Irrep]( + SU3Irrep(0, 0, 0) => 8, + SU3Irrep(2, 1, 0) => 6, + SU3Irrep(3, 0, 0) => 3, + SU3Irrep(3, 3, 0) => 3, + SU3Irrep(4, 2, 0) => 2, +) +@show dim(Vvirt) + +ψ₀ = InfiniteMPS([Vphys], [Vvirt]) +ψ, envs, δ = find_groundstate(ψ₀, H, VUMPS(; maxiter = 200, tol = 1.0e-10, verbosity = 1)) +E₀ = real(expectation_value(ψ, H)) +println("ground-state energy per site: E₀ = $E₀") +```` + +```` +dim(Vvirt) = 170 +┌ Warning: Constructing an MPS from tensors that are not full rank +└ @ MPSKit ~/Projects/MPSKit.jl/docs/src/states/infinitemps.jl:180 +ground-state energy per site: E₀ = -2.573505652431292 + +```` + +## The excitation spectrum + +Excitations above the ground state are computed with the quasiparticle ansatz. +In the thermodynamic limit each excitation carries a definite momentum ``k`` and a definite +``SU(3)`` charge; reference [devos2022](@cite) reports that the lowest branch — whose minimum +is the Haldane gap — lives in the adjoint ``[2\,1\,0]`` sector, with its minimum at momentum +``k = 2\pi/3``. +We scan this branch across half of the Brillouin zone (the other half follows by reflection). + + + +````julia +sector = SU3Irrep(2, 1, 0) +kspace = range(0, π, 10) +Es, _ = excitations(H, QuasiparticleAnsatz(), kspace, ψ, envs; sector) + +Δ, idx = findmin(real.(Es)) +println("branch minimum ΔE/J = $Δ at k = $(kspace[idx])") +```` + +```` +[ Info: Found excitations for momentum = 0.0 +[ Info: Found excitations for momentum = 0.3490658503988659 +[ Info: Found excitations for momentum = 0.6981317007977318 +[ Info: Found excitations for momentum = 1.0471975511965976 +[ Info: Found excitations for momentum = 1.3962634015954636 +[ Info: Found excitations for momentum = 1.7453292519943295 +[ Info: Found excitations for momentum = 2.0943951023931953 +[ Info: Found excitations for momentum = 2.443460952792061 +[ Info: Found excitations for momentum = 2.792526803190927 +[ Info: Found excitations for momentum = 3.141592653589793 +branch minimum ΔE/J = -0.041856660250392086 at k = 2.0943951023931953 + +```` + +````julia +plot( + kspace, real.(Es); + xaxis = "momentum k", yaxis = "ΔE / J", label = "[2 1 0] branch", + title = "SU(3) [3 0 0] excitation dispersion" +) +hline!([0.0]; color = :gray, linestyle = :dash, label = "") +vline!([2π / 3]; color = :gray, linestyle = :dot, label = "k = 2π/3") +```` + +![](figure-1.png) + +The branch has a pronounced soft mode at ``k = 2\pi/3``, exactly the momentum at which +[devos2022](@cite) locates the Haldane gap. +That reference reports a gap of ``\Delta / J = 0.0263`` there. + +This value is *very* small, and reproducing it faithfully is demanding: it requires a +carefully converged, large-bond-dimension uniform ``SU(3)`` MPS. +The lightweight calculation here — a modest virtual space chosen so the page builds quickly — +resolves the *location* of the soft mode but not the tiny gap itself: near ``k = 2\pi/3`` the +computed branch comes out close to zero and can even dip slightly negative, a sign that the +uniform ground state is not converged to the accuracy needed to pin down a gap this small. + + + +--- + +*This page was generated using [Literate.jl](https://github.com/fredrikekre/Literate.jl).* + diff --git a/docs/src/examples/excitations/1.su3-heisenberg/main.ipynb b/docs/src/examples/excitations/1.su3-heisenberg/main.ipynb new file mode 100644 index 000000000..ce642adf7 --- /dev/null +++ b/docs/src/examples/excitations/1.su3-heisenberg/main.ipynb @@ -0,0 +1,312 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# The SU(3) Haldane gap\n", + "\n", + "The spin-1 Heisenberg chain famously has a gapped, symmetry-protected topological ground\n", + "state: the Haldane phase.\n", + "A natural question is what happens when the $SU(2)$ symmetry of the spins is promoted to a\n", + "larger $SU(N)$ symmetry.\n", + "In this example we study the $SU(3)$ generalization introduced in [devos2022](@cite): a\n", + "uniform chain where every site carries the fully-symmetric $[3\\,0\\,0]$ irrep of $SU(3)$\n", + "(the ten-dimensional representation), coupled by a nearest-neighbour $SU(3)$-invariant\n", + "Heisenberg interaction\n", + "\n", + "$$\n", + "H = J \\sum_{\\langle i, j \\rangle} \\sum_{a=1}^{8} T^a_i T^a_j ,\n", + "$$\n", + "\n", + "where the $T^a$ are the eight generators of $SU(3)$.\n", + "This is the direct analog of the spin-1 chain, with the three generators of $SU(2)$\n", + "replaced by the eight generators of $SU(3)$.\n", + "\n", + "\n", + "\n", + "Working with the full non-abelian $SU(3)$ symmetry is what makes this tractable.\n", + "Just as $SU(2)$ symmetry drastically shrinks the spin-1 problem (see\n", + "Symmetries), imposing $SU(3)$ block-diagonalizes every tensor\n", + "along its irreducible representations, so that a modest number of variational parameters\n", + "already captures a large physical bond dimension.\n", + "The Clebsch–Gordan coefficients that this requires are provided by\n", + "[SUNRepresentations.jl](https://github.com/QuantumKitHub/SUNRepresentations.jl), whose\n", + "`SU3Irrep` sectors plug directly into TensorKit's graded vector spaces.\n", + "\n", + "> **First-run cost**\n", + ">\n", + "> SUNRepresentations.jl computes $SU(N)$ Clebsch–Gordan coefficients on demand and\n", + "> caches them both in memory and on disk (via `Scratch.jl`).\n", + "> The **first** time a given coefficient is needed the computation can be slow; later runs\n", + "> reuse the on-disk cache.\n", + "> On a machine without a persisted scratch cache — such as a fresh continuous-integration\n", + "> runner — this example therefore pays the full coefficient-generation cost once." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "using TensorKit\n", + "using SUNRepresentations\n", + "using MPSKit\n", + "using Plots" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For reproducibility of this page, we fix the seed of the random number generator:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "using Random\n", + "Random.seed!(4321);" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## The model\n", + "\n", + "Each site carries the $[3\\,0\\,0]$ irrep, which we obtain from its highest weight and\n", + "represent as a one-dimensional graded space." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "I300 = SU3Irrep(3, 0, 0)\n", + "Vphys = Vect[SU3Irrep](I300 => 1)\n", + "@show dim(I300)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To build the interaction we use the same Casimir trick as for the $SU(2)$ chain.\n", + "Writing $C_2 = \\sum_a T^a T^a$ for the quadratic Casimir operator, the two-site coupling is\n", + "diagonal in the total $SU(3)$ charge $c$ of a bond:\n", + "\n", + "$$\n", + "\\sum_a T^a_i T^a_j = \\tfrac{1}{2}\\left( C_2(c) - C_2([3\\,0\\,0]) - C_2([3\\,0\\,0]) \\right).\n", + "$$\n", + "\n", + "SUNRepresentations.jl provides the quadratic Casimir through `casimir(2, irrep)`.\n", + "Its normalization is the standard one with $\\mathrm{tr}(T^a T^b) = \\tfrac{1}{2}\\delta^{ab}$:\n", + "the fundamental $[1\\,0\\,0]$ has $C_2 = 4/3 = (N^2-1)/(2N)$." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "@show casimir(2, SU3Irrep(1, 0, 0))\n", + "@show casimir(2, I300)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The nearest-neighbour term is then a single TensorKit operator that acts as a scalar on each\n", + "fusion channel of $[3\\,0\\,0] \\otimes [3\\,0\\,0]$.\n", + "Constructing it by iterating over the blocks — one block per total charge $c$ — mirrors the\n", + "$SU(2)$ construction, but now with `casimir(2, ⋅)` supplying the eigenvalues." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "function su3_heisenberg(Vphys; J = 1.0)\n", + " site = SU3Irrep(3, 0, 0)\n", + " c2_site = casimir(2, site)\n", + " SS = zeros(ComplexF64, Vphys ⊗ Vphys ← Vphys ⊗ Vphys)\n", + " for (c, data) in blocks(SS)\n", + " coupling = (casimir(2, c) - 2 * c2_site) / 2\n", + " for i in axes(data, 1)\n", + " data[i, i] = J * coupling\n", + " end\n", + " end\n", + " return InfiniteMPOHamiltonian(SS)\n", + "end\n", + "\n", + "H = su3_heisenberg(Vphys)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can read off the physics directly from the fusion channels.\n", + "The product $[3\\,0\\,0] \\otimes [3\\,0\\,0]$ decomposes into four irreps, and the\n", + "antiferromagnetic coupling ($J > 0$) favours the channels of lowest Casimir:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for (c, n) in directproduct(I300, I300)\n", + " coupling = (casimir(2, c) - 2 * casimir(2, I300)) / 2\n", + " println(rpad(string(c), 22), \" dim = \", rpad(dim(c), 4), \" coupling = \", coupling)\n", + "end" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Ground state\n", + "\n", + "The $[3\\,0\\,0]$ irrep has trivial triality (congruency class $0$), so — like the\n", + "integer-spin Haldane chain — a translation-invariant state on a single-site unit cell is\n", + "admissible.\n", + "Because the physical charge has triality $0$ it cannot shift the triality of the virtual\n", + "bonds, so every virtual space must sit in a single congruency class; here we use the trivial\n", + "class $0$, which we found to give the lowest variational energy.\n", + "Following [devos2022](@cite), we seed the optimization with a random $SU(3)$-symmetric\n", + "uniform state and optimize with VUMPS.\n", + "\n", + "" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "Vvirt = Vect[SU3Irrep](\n", + " SU3Irrep(0, 0, 0) => 8,\n", + " SU3Irrep(2, 1, 0) => 6,\n", + " SU3Irrep(3, 0, 0) => 3,\n", + " SU3Irrep(3, 3, 0) => 3,\n", + " SU3Irrep(4, 2, 0) => 2,\n", + ")\n", + "@show dim(Vvirt)\n", + "\n", + "ψ₀ = InfiniteMPS([Vphys], [Vvirt])\n", + "ψ, envs, δ = find_groundstate(ψ₀, H, VUMPS(; maxiter = 200, tol = 1.0e-10, verbosity = 1))\n", + "E₀ = real(expectation_value(ψ, H))\n", + "println(\"ground-state energy per site: E₀ = $E₀\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## The excitation spectrum\n", + "\n", + "Excitations above the ground state are computed with the quasiparticle ansatz.\n", + "In the thermodynamic limit each excitation carries a definite momentum $k$ and a definite\n", + "$SU(3)$ charge; reference [devos2022](@cite) reports that the lowest branch — whose minimum\n", + "is the Haldane gap — lives in the adjoint $[2\\,1\\,0]$ sector, with its minimum at momentum\n", + "$k = 2\\pi/3$.\n", + "We scan this branch across half of the Brillouin zone (the other half follows by reflection).\n", + "\n", + "" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sector = SU3Irrep(2, 1, 0)\n", + "kspace = range(0, π, 10)\n", + "Es, _ = excitations(H, QuasiparticleAnsatz(), kspace, ψ, envs; sector)\n", + "\n", + "Δ, idx = findmin(real.(Es))\n", + "println(\"branch minimum ΔE/J = $Δ at k = $(kspace[idx])\")\n", + "plot(\n", + " kspace, real.(Es);\n", + " xaxis = \"momentum k\", yaxis = \"ΔE / J\", label = \"[2 1 0] branch\",\n", + " title = \"SU(3) [3 0 0] excitation dispersion\"\n", + ")\n", + "hline!([0.0]; color = :gray, linestyle = :dash, label = \"\")\n", + "vline!([2π / 3]; color = :gray, linestyle = :dot, label = \"k = 2π/3\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The branch has a pronounced soft mode at $k = 2\\pi/3$, exactly the momentum at which\n", + "[devos2022](@cite) locates the Haldane gap.\n", + "That reference reports a gap of $\\Delta / J = 0.0263$ there.\n", + "\n", + "This value is *very* small, and reproducing it faithfully is demanding: it requires a\n", + "carefully converged, large-bond-dimension uniform $SU(3)$ MPS.\n", + "The lightweight calculation here — a modest virtual space chosen so the page builds quickly —\n", + "resolves the *location* of the soft mode but not the tiny gap itself: near $k = 2\\pi/3$ the\n", + "computed branch comes out close to zero and can even dip slightly negative, a sign that the\n", + "uniform ground state is not converged to the accuracy needed to pin down a gap this small.\n", + "\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "\n", + "*This notebook was generated using [Literate.jl](https://github.com/fredrikekre/Literate.jl).*" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Julia 1.12.6", + "language": "julia", + "name": "julia-1.12" + }, + "language_info": { + "file_extension": ".jl", + "mimetype": "application/julia", + "name": "julia", + "version": "1.12.6" + } + }, + "nbformat": 4, + "nbformat_minor": 3 +} \ No newline at end of file diff --git a/docs/src/examples/quantum1d/0.tfim-groundstate/figure-1.png b/docs/src/examples/groundstates/0.tfim-groundstate/figure-1.png similarity index 100% rename from docs/src/examples/quantum1d/0.tfim-groundstate/figure-1.png rename to docs/src/examples/groundstates/0.tfim-groundstate/figure-1.png diff --git a/docs/src/examples/quantum1d/0.tfim-groundstate/figure-2.png b/docs/src/examples/groundstates/0.tfim-groundstate/figure-2.png similarity index 100% rename from docs/src/examples/quantum1d/0.tfim-groundstate/figure-2.png rename to docs/src/examples/groundstates/0.tfim-groundstate/figure-2.png diff --git a/docs/src/examples/quantum1d/0.tfim-groundstate/figure-3.png b/docs/src/examples/groundstates/0.tfim-groundstate/figure-3.png similarity index 100% rename from docs/src/examples/quantum1d/0.tfim-groundstate/figure-3.png rename to docs/src/examples/groundstates/0.tfim-groundstate/figure-3.png diff --git a/docs/src/examples/quantum1d/0.tfim-groundstate/index.md b/docs/src/examples/groundstates/0.tfim-groundstate/index.md similarity index 96% rename from docs/src/examples/quantum1d/0.tfim-groundstate/index.md rename to docs/src/examples/groundstates/0.tfim-groundstate/index.md index 40ccedabd..9552cde5e 100644 --- a/docs/src/examples/quantum1d/0.tfim-groundstate/index.md +++ b/docs/src/examples/groundstates/0.tfim-groundstate/index.md @@ -1,10 +1,10 @@ ```@meta -EditURL = "../../../../../examples/quantum1d/0.tfim-groundstate/main.jl" +EditURL = "../../../../../examples/groundstates/0.tfim-groundstate/main.jl" ``` -[![](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/QuantumKitHub/MPSKit.jl/gh-pages?filepath=dev/examples/quantum1d/0.tfim-groundstate/main.ipynb) -[![](https://img.shields.io/badge/show-nbviewer-579ACA.svg)](https://nbviewer.jupyter.org/github/QuantumKitHub/MPSKit.jl/blob/gh-pages/dev/examples/quantum1d/0.tfim-groundstate/main.ipynb) -[![](https://img.shields.io/badge/download-project-orange)](https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/QuantumKitHub/MPSKit.jl/examples/tree/gh-pages/dev/examples/quantum1d/0.tfim-groundstate) +[![](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/QuantumKitHub/MPSKit.jl/gh-pages?filepath=dev/examples/groundstates/0.tfim-groundstate/main.ipynb) +[![](https://img.shields.io/badge/show-nbviewer-579ACA.svg)](https://nbviewer.jupyter.org/github/QuantumKitHub/MPSKit.jl/blob/gh-pages/dev/examples/groundstates/0.tfim-groundstate/main.ipynb) +[![](https://img.shields.io/badge/download-project-orange)](https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/QuantumKitHub/MPSKit.jl/examples/tree/gh-pages/dev/examples/groundstates/0.tfim-groundstate) # The transverse-field Ising model: a complete ground-state study diff --git a/docs/src/examples/quantum1d/0.tfim-groundstate/main.ipynb b/docs/src/examples/groundstates/0.tfim-groundstate/main.ipynb similarity index 100% rename from docs/src/examples/quantum1d/0.tfim-groundstate/main.ipynb rename to docs/src/examples/groundstates/0.tfim-groundstate/main.ipynb diff --git a/docs/src/examples/quantum1d/4.xxz-heisenberg/figure-1.png b/docs/src/examples/groundstates/1.xxz-heisenberg/figure-1.png similarity index 100% rename from docs/src/examples/quantum1d/4.xxz-heisenberg/figure-1.png rename to docs/src/examples/groundstates/1.xxz-heisenberg/figure-1.png diff --git a/docs/src/examples/quantum1d/4.xxz-heisenberg/figure-2.png b/docs/src/examples/groundstates/1.xxz-heisenberg/figure-2.png similarity index 100% rename from docs/src/examples/quantum1d/4.xxz-heisenberg/figure-2.png rename to docs/src/examples/groundstates/1.xxz-heisenberg/figure-2.png diff --git a/docs/src/examples/quantum1d/4.xxz-heisenberg/index.md b/docs/src/examples/groundstates/1.xxz-heisenberg/index.md similarity index 94% rename from docs/src/examples/quantum1d/4.xxz-heisenberg/index.md rename to docs/src/examples/groundstates/1.xxz-heisenberg/index.md index 5ade1179e..907f74f7d 100644 --- a/docs/src/examples/quantum1d/4.xxz-heisenberg/index.md +++ b/docs/src/examples/groundstates/1.xxz-heisenberg/index.md @@ -1,10 +1,10 @@ ```@meta -EditURL = "../../../../../examples/quantum1d/4.xxz-heisenberg/main.jl" +EditURL = "../../../../../examples/groundstates/1.xxz-heisenberg/main.jl" ``` -[![](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/QuantumKitHub/MPSKit.jl/gh-pages?filepath=dev/examples/quantum1d/4.xxz-heisenberg/main.ipynb) -[![](https://img.shields.io/badge/show-nbviewer-579ACA.svg)](https://nbviewer.jupyter.org/github/QuantumKitHub/MPSKit.jl/blob/gh-pages/dev/examples/quantum1d/4.xxz-heisenberg/main.ipynb) -[![](https://img.shields.io/badge/download-project-orange)](https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/QuantumKitHub/MPSKit.jl/examples/tree/gh-pages/dev/examples/quantum1d/4.xxz-heisenberg) +[![](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/QuantumKitHub/MPSKit.jl/gh-pages?filepath=dev/examples/groundstates/1.xxz-heisenberg/main.ipynb) +[![](https://img.shields.io/badge/show-nbviewer-579ACA.svg)](https://nbviewer.jupyter.org/github/QuantumKitHub/MPSKit.jl/blob/gh-pages/dev/examples/groundstates/1.xxz-heisenberg/main.ipynb) +[![](https://img.shields.io/badge/download-project-orange)](https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/QuantumKitHub/MPSKit.jl/examples/tree/gh-pages/dev/examples/groundstates/1.xxz-heisenberg) # The XXZ model diff --git a/docs/src/examples/quantum1d/4.xxz-heisenberg/main.ipynb b/docs/src/examples/groundstates/1.xxz-heisenberg/main.ipynb similarity index 100% rename from docs/src/examples/quantum1d/4.xxz-heisenberg/main.ipynb rename to docs/src/examples/groundstates/1.xxz-heisenberg/main.ipynb diff --git a/docs/src/examples/quantum1d/6.hubbard/figure-1.png b/docs/src/examples/groundstates/2.hubbard/figure-1.png similarity index 100% rename from docs/src/examples/quantum1d/6.hubbard/figure-1.png rename to docs/src/examples/groundstates/2.hubbard/figure-1.png diff --git a/docs/src/examples/quantum1d/6.hubbard/figure-2.png b/docs/src/examples/groundstates/2.hubbard/figure-2.png similarity index 100% rename from docs/src/examples/quantum1d/6.hubbard/figure-2.png rename to docs/src/examples/groundstates/2.hubbard/figure-2.png diff --git a/docs/src/examples/quantum1d/6.hubbard/figure-3.png b/docs/src/examples/groundstates/2.hubbard/figure-3.png similarity index 100% rename from docs/src/examples/quantum1d/6.hubbard/figure-3.png rename to docs/src/examples/groundstates/2.hubbard/figure-3.png diff --git a/docs/src/examples/quantum1d/6.hubbard/index.md b/docs/src/examples/groundstates/2.hubbard/index.md similarity index 98% rename from docs/src/examples/quantum1d/6.hubbard/index.md rename to docs/src/examples/groundstates/2.hubbard/index.md index f4fb35746..6e7f372f1 100644 --- a/docs/src/examples/quantum1d/6.hubbard/index.md +++ b/docs/src/examples/groundstates/2.hubbard/index.md @@ -1,10 +1,10 @@ ```@meta -EditURL = "../../../../../examples/quantum1d/6.hubbard/main.jl" +EditURL = "../../../../../examples/groundstates/2.hubbard/main.jl" ``` -[![](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/QuantumKitHub/MPSKit.jl/gh-pages?filepath=dev/examples/quantum1d/6.hubbard/main.ipynb) -[![](https://img.shields.io/badge/show-nbviewer-579ACA.svg)](https://nbviewer.jupyter.org/github/QuantumKitHub/MPSKit.jl/blob/gh-pages/dev/examples/quantum1d/6.hubbard/main.ipynb) -[![](https://img.shields.io/badge/download-project-orange)](https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/QuantumKitHub/MPSKit.jl/examples/tree/gh-pages/dev/examples/quantum1d/6.hubbard) +[![](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/QuantumKitHub/MPSKit.jl/gh-pages?filepath=dev/examples/groundstates/2.hubbard/main.ipynb) +[![](https://img.shields.io/badge/show-nbviewer-579ACA.svg)](https://nbviewer.jupyter.org/github/QuantumKitHub/MPSKit.jl/blob/gh-pages/dev/examples/groundstates/2.hubbard/main.ipynb) +[![](https://img.shields.io/badge/download-project-orange)](https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/QuantumKitHub/MPSKit.jl/examples/tree/gh-pages/dev/examples/groundstates/2.hubbard) ````julia using Markdown diff --git a/docs/src/examples/quantum1d/6.hubbard/main.ipynb b/docs/src/examples/groundstates/2.hubbard/main.ipynb similarity index 100% rename from docs/src/examples/quantum1d/6.hubbard/main.ipynb rename to docs/src/examples/groundstates/2.hubbard/main.ipynb diff --git a/docs/src/examples/quantum1d/8.bose-hubbard/figure-1.png b/docs/src/examples/groundstates/3.bose-hubbard/figure-1.png similarity index 100% rename from docs/src/examples/quantum1d/8.bose-hubbard/figure-1.png rename to docs/src/examples/groundstates/3.bose-hubbard/figure-1.png diff --git a/docs/src/examples/quantum1d/8.bose-hubbard/figure-2.png b/docs/src/examples/groundstates/3.bose-hubbard/figure-2.png similarity index 100% rename from docs/src/examples/quantum1d/8.bose-hubbard/figure-2.png rename to docs/src/examples/groundstates/3.bose-hubbard/figure-2.png diff --git a/docs/src/examples/quantum1d/8.bose-hubbard/figure-3.png b/docs/src/examples/groundstates/3.bose-hubbard/figure-3.png similarity index 100% rename from docs/src/examples/quantum1d/8.bose-hubbard/figure-3.png rename to docs/src/examples/groundstates/3.bose-hubbard/figure-3.png diff --git a/docs/src/examples/quantum1d/8.bose-hubbard/figure-4.png b/docs/src/examples/groundstates/3.bose-hubbard/figure-4.png similarity index 100% rename from docs/src/examples/quantum1d/8.bose-hubbard/figure-4.png rename to docs/src/examples/groundstates/3.bose-hubbard/figure-4.png diff --git a/docs/src/examples/quantum1d/8.bose-hubbard/figure-5.png b/docs/src/examples/groundstates/3.bose-hubbard/figure-5.png similarity index 100% rename from docs/src/examples/quantum1d/8.bose-hubbard/figure-5.png rename to docs/src/examples/groundstates/3.bose-hubbard/figure-5.png diff --git a/docs/src/examples/quantum1d/8.bose-hubbard/figure-6.png b/docs/src/examples/groundstates/3.bose-hubbard/figure-6.png similarity index 100% rename from docs/src/examples/quantum1d/8.bose-hubbard/figure-6.png rename to docs/src/examples/groundstates/3.bose-hubbard/figure-6.png diff --git a/docs/src/examples/quantum1d/8.bose-hubbard/index.md b/docs/src/examples/groundstates/3.bose-hubbard/index.md similarity index 98% rename from docs/src/examples/quantum1d/8.bose-hubbard/index.md rename to docs/src/examples/groundstates/3.bose-hubbard/index.md index 53ec267d2..2441e8df2 100644 --- a/docs/src/examples/quantum1d/8.bose-hubbard/index.md +++ b/docs/src/examples/groundstates/3.bose-hubbard/index.md @@ -1,10 +1,10 @@ ```@meta -EditURL = "../../../../../examples/quantum1d/8.bose-hubbard/main.jl" +EditURL = "../../../../../examples/groundstates/3.bose-hubbard/main.jl" ``` -[![](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/QuantumKitHub/MPSKit.jl/gh-pages?filepath=dev/examples/quantum1d/8.bose-hubbard/main.ipynb) -[![](https://img.shields.io/badge/show-nbviewer-579ACA.svg)](https://nbviewer.jupyter.org/github/QuantumKitHub/MPSKit.jl/blob/gh-pages/dev/examples/quantum1d/8.bose-hubbard/main.ipynb) -[![](https://img.shields.io/badge/download-project-orange)](https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/QuantumKitHub/MPSKit.jl/examples/tree/gh-pages/dev/examples/quantum1d/8.bose-hubbard) +[![](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/QuantumKitHub/MPSKit.jl/gh-pages?filepath=dev/examples/groundstates/3.bose-hubbard/main.ipynb) +[![](https://img.shields.io/badge/show-nbviewer-579ACA.svg)](https://nbviewer.jupyter.org/github/QuantumKitHub/MPSKit.jl/blob/gh-pages/dev/examples/groundstates/3.bose-hubbard/main.ipynb) +[![](https://img.shields.io/badge/download-project-orange)](https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/QuantumKitHub/MPSKit.jl/examples/tree/gh-pages/dev/examples/groundstates/3.bose-hubbard) ````julia using Markdown diff --git a/docs/src/examples/quantum1d/8.bose-hubbard/main.ipynb b/docs/src/examples/groundstates/3.bose-hubbard/main.ipynb similarity index 100% rename from docs/src/examples/quantum1d/8.bose-hubbard/main.ipynb rename to docs/src/examples/groundstates/3.bose-hubbard/main.ipynb diff --git a/docs/src/examples/quantum1d/5.haldane-spt/figure-1.png b/docs/src/examples/groundstates/4.haldane-spt/figure-1.png similarity index 100% rename from docs/src/examples/quantum1d/5.haldane-spt/figure-1.png rename to docs/src/examples/groundstates/4.haldane-spt/figure-1.png diff --git a/docs/src/examples/quantum1d/5.haldane-spt/figure-2.png b/docs/src/examples/groundstates/4.haldane-spt/figure-2.png similarity index 100% rename from docs/src/examples/quantum1d/5.haldane-spt/figure-2.png rename to docs/src/examples/groundstates/4.haldane-spt/figure-2.png diff --git a/docs/src/examples/quantum1d/5.haldane-spt/figure-3.png b/docs/src/examples/groundstates/4.haldane-spt/figure-3.png similarity index 100% rename from docs/src/examples/quantum1d/5.haldane-spt/figure-3.png rename to docs/src/examples/groundstates/4.haldane-spt/figure-3.png diff --git a/docs/src/examples/quantum1d/5.haldane-spt/index.md b/docs/src/examples/groundstates/4.haldane-spt/index.md similarity index 95% rename from docs/src/examples/quantum1d/5.haldane-spt/index.md rename to docs/src/examples/groundstates/4.haldane-spt/index.md index 28f90de21..1f3fb8891 100644 --- a/docs/src/examples/quantum1d/5.haldane-spt/index.md +++ b/docs/src/examples/groundstates/4.haldane-spt/index.md @@ -1,10 +1,10 @@ ```@meta -EditURL = "../../../../../examples/quantum1d/5.haldane-spt/main.jl" +EditURL = "../../../../../examples/groundstates/4.haldane-spt/main.jl" ``` -[![](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/QuantumKitHub/MPSKit.jl/gh-pages?filepath=dev/examples/quantum1d/5.haldane-spt/main.ipynb) -[![](https://img.shields.io/badge/show-nbviewer-579ACA.svg)](https://nbviewer.jupyter.org/github/QuantumKitHub/MPSKit.jl/blob/gh-pages/dev/examples/quantum1d/5.haldane-spt/main.ipynb) -[![](https://img.shields.io/badge/download-project-orange)](https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/QuantumKitHub/MPSKit.jl/examples/tree/gh-pages/dev/examples/quantum1d/5.haldane-spt) +[![](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/QuantumKitHub/MPSKit.jl/gh-pages?filepath=dev/examples/groundstates/4.haldane-spt/main.ipynb) +[![](https://img.shields.io/badge/show-nbviewer-579ACA.svg)](https://nbviewer.jupyter.org/github/QuantumKitHub/MPSKit.jl/blob/gh-pages/dev/examples/groundstates/4.haldane-spt/main.ipynb) +[![](https://img.shields.io/badge/download-project-orange)](https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/QuantumKitHub/MPSKit.jl/examples/tree/gh-pages/dev/examples/groundstates/4.haldane-spt) # Spin 1 Heisenberg model diff --git a/docs/src/examples/quantum1d/5.haldane-spt/main.ipynb b/docs/src/examples/groundstates/4.haldane-spt/main.ipynb similarity index 100% rename from docs/src/examples/quantum1d/5.haldane-spt/main.ipynb rename to docs/src/examples/groundstates/4.haldane-spt/main.ipynb diff --git a/docs/src/examples/quantum1d/5.haldane-spt/spt-tensors.svg b/docs/src/examples/groundstates/4.haldane-spt/spt-tensors.svg similarity index 100% rename from docs/src/examples/quantum1d/5.haldane-spt/spt-tensors.svg rename to docs/src/examples/groundstates/4.haldane-spt/spt-tensors.svg diff --git a/docs/src/examples/quantum1d/1.ising-cft/figure-1.png b/docs/src/examples/groundstates/5.ising-cft/figure-1.png similarity index 100% rename from docs/src/examples/quantum1d/1.ising-cft/figure-1.png rename to docs/src/examples/groundstates/5.ising-cft/figure-1.png diff --git a/docs/src/examples/quantum1d/1.ising-cft/figure-2.png b/docs/src/examples/groundstates/5.ising-cft/figure-2.png similarity index 100% rename from docs/src/examples/quantum1d/1.ising-cft/figure-2.png rename to docs/src/examples/groundstates/5.ising-cft/figure-2.png diff --git a/docs/src/examples/quantum1d/1.ising-cft/figure-3.png b/docs/src/examples/groundstates/5.ising-cft/figure-3.png similarity index 100% rename from docs/src/examples/quantum1d/1.ising-cft/figure-3.png rename to docs/src/examples/groundstates/5.ising-cft/figure-3.png diff --git a/docs/src/examples/quantum1d/1.ising-cft/index.md b/docs/src/examples/groundstates/5.ising-cft/index.md similarity index 95% rename from docs/src/examples/quantum1d/1.ising-cft/index.md rename to docs/src/examples/groundstates/5.ising-cft/index.md index 43b819d94..e61ab7587 100644 --- a/docs/src/examples/quantum1d/1.ising-cft/index.md +++ b/docs/src/examples/groundstates/5.ising-cft/index.md @@ -1,10 +1,10 @@ ```@meta -EditURL = "../../../../../examples/quantum1d/1.ising-cft/main.jl" +EditURL = "../../../../../examples/groundstates/5.ising-cft/main.jl" ``` -[![](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/QuantumKitHub/MPSKit.jl/gh-pages?filepath=dev/examples/quantum1d/1.ising-cft/main.ipynb) -[![](https://img.shields.io/badge/show-nbviewer-579ACA.svg)](https://nbviewer.jupyter.org/github/QuantumKitHub/MPSKit.jl/blob/gh-pages/dev/examples/quantum1d/1.ising-cft/main.ipynb) -[![](https://img.shields.io/badge/download-project-orange)](https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/QuantumKitHub/MPSKit.jl/examples/tree/gh-pages/dev/examples/quantum1d/1.ising-cft) +[![](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/QuantumKitHub/MPSKit.jl/gh-pages?filepath=dev/examples/groundstates/5.ising-cft/main.ipynb) +[![](https://img.shields.io/badge/show-nbviewer-579ACA.svg)](https://nbviewer.jupyter.org/github/QuantumKitHub/MPSKit.jl/blob/gh-pages/dev/examples/groundstates/5.ising-cft/main.ipynb) +[![](https://img.shields.io/badge/download-project-orange)](https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/QuantumKitHub/MPSKit.jl/examples/tree/gh-pages/dev/examples/groundstates/5.ising-cft) # The Ising CFT spectrum diff --git a/docs/src/examples/quantum1d/1.ising-cft/main.ipynb b/docs/src/examples/groundstates/5.ising-cft/main.ipynb similarity index 100% rename from docs/src/examples/quantum1d/1.ising-cft/main.ipynb rename to docs/src/examples/groundstates/5.ising-cft/main.ipynb diff --git a/docs/src/examples/quantum1d/1.ising-cft/translation_mpo.svg b/docs/src/examples/groundstates/5.ising-cft/translation_mpo.svg similarity index 100% rename from docs/src/examples/quantum1d/1.ising-cft/translation_mpo.svg rename to docs/src/examples/groundstates/5.ising-cft/translation_mpo.svg diff --git a/docs/src/examples/index.md b/docs/src/examples/index.md index 39ad636ac..4e4579df5 100644 --- a/docs/src/examples/index.md +++ b/docs/src/examples/index.md @@ -3,88 +3,101 @@ This gallery collects the full worked examples that ship with MPSKit.jl. Each one is a complete, runnable script (also available as a Jupyter notebook, linked from the example page itself) that goes well beyond the short snippets in the how-to guides. -Within each physics grouping below, the examples are listed roughly in order of increasing difficulty: start at the top if you are new to MPSKit, and work down as you get comfortable with symmetries, infinite systems, and the less common algorithms. +The examples are grouped by the kind of computation they demonstrate rather than by the physical system. +Within each group they are listed roughly in order of increasing difficulty: start at the top if you are new to MPSKit, and work down as you get comfortable with symmetries, infinite systems, and the less common algorithms. -## Quantum (1+1)d +## Ground states -### [The transverse-field Ising model: a complete ground-state study](quantum1d/0.tfim-groundstate/index.md) +### [The transverse-field Ising model: a complete ground-state study](groundstates/0.tfim-groundstate/index.md) -![](quantum1d/0.tfim-groundstate/figure-1.png) +![](groundstates/0.tfim-groundstate/figure-1.png) Assembles the tools from the tutorials into one case study of the TFIM phase transition: finite-ring `DMRG` versus infinite-chain `VUMPS` magnetization curves in a single figure, plus the entanglement entropy and correlation length of the infinite state across the transition. The natural first example after finishing the tutorial track. **Level: introductory.** -### [The Ising CFT spectrum](quantum1d/1.ising-cft/index.md) +### [The XXZ model](groundstates/1.xxz-heisenberg/index.md) -![](quantum1d/1.ising-cft/figure-2.png) +![](groundstates/1.xxz-heisenberg/figure-2.png) -Extracts the finite-size conformal spectrum of the critical transverse-field Ising chain, first by brute-force `exact_diagonalization` on a small periodic chain, then by extending to larger sizes with finite `DMRG` and the `QuasiparticleAnsatz`, using a translation MPO to assign a momentum label to each state. -No symmetries are used, which makes this a good entry point into the finite-MPS workflow. -**Level: introductory.** - -### [DQPT in the Ising model](quantum1d/3.ising-dqpt/index.md) - -![](quantum1d/3.ising-dqpt/infinite_timeev.png) - -Quenches the transverse-field Ising chain across its critical point and tracks the Loschmidt echo in search of non-analyticities (dynamical quantum phase transitions), on both a finite chain (`TDVP2`/`TDVP`) and directly in the thermodynamic limit (`changebonds` with `OptimalExpand`, then `TDVP`). -A compact introduction to real-time evolution and environment reuse, still without symmetries. -**Level: introductory/intermediate.** +Walks through a ground-state search that first goes wrong: single-site `VUMPS` and `GradientGrassmann` stall on the spin-1/2 Heisenberg antiferromagnet, and `transferplot`/`entanglementplot` reveal a near-non-injective state with several almost-degenerate transfer-matrix eigenvalues. +The fix is a two-site unit cell together with the `SU2Irrep`-symmetric Hamiltonian, after which `IDMRG2` and `VUMPS` converge cleanly. +A useful, diagnostic-driven example for recognizing and debugging convergence failures. +**Level: intermediate.** -### [The Haldane gap](quantum1d/2.haldane/index.md) +### [Hubbard chain at half filling](groundstates/2.hubbard/index.md) -![](quantum1d/2.haldane/figure-3.png) +![](groundstates/2.hubbard/figure-2.png) -Computes the Haldane gap of the spin-1 Heisenberg antiferromagnet in two complementary ways: finite-size `DMRG` with the `QuasiparticleAnsatz`, extrapolated over system size, and a direct infinite-chain `VUMPS` calculation with a momentum-resolved excitation scan. -Introduces `SU2Irrep`/`SU2Space` symmetric tensors for both `FiniteMPS` and `InfiniteMPS`. -**Level: intermediate.** +Studies the 1D Hubbard model at half filling with fermionic `InfiniteMPS`, first benchmarking a plain `VUMPS`/`GradientGrassmann` ground-state search against the exact Bethe-ansatz integral for the energy, then imposing the full particle-number and spin symmetry (`U1Irrep`, `SU2Irrep`, with `MPSKit.add_physical_charge` to pin the filling) and constructing the spinon/holon excitation spectrum with the `QuasiparticleAnsatz`. +Combines fermionic symmetry sectors with a more elaborate ground-state recipe (staged bond-dimension growth via `changebonds`/`OptimalExpand`, `SvdCut`, and mixed `VUMPS`/`GradientGrassmann` refinement). +**Level: advanced.** -### [The XXZ model](quantum1d/4.xxz-heisenberg/index.md) +### [1D Bose-Hubbard model](groundstates/3.bose-hubbard/index.md) -![](quantum1d/4.xxz-heisenberg/figure-2.png) +![](groundstates/3.bose-hubbard/figure-6.png) -Walks through a ground-state search that first goes wrong: single-site `VUMPS` and `GradientGrassmann` stall on the spin-1/2 Heisenberg antiferromagnet, and `transferplot`/`entanglementplot` reveal a near-non-injective state with several almost-degenerate transfer-matrix eigenvalues. -The fix is a two-site unit cell together with the `SU2Irrep`-symmetric Hamiltonian, after which `IDMRG2` and `VUMPS` converge cleanly. -A useful, diagnostic-driven example for recognizing and debugging convergence failures. -**Level: intermediate.** +The most comprehensive ground-state example in the gallery: works directly in the thermodynamic limit with a truncated bosonic local Hilbert space, extracts correlation functions and the correlation length as a function of bond dimension, computes the momentum distribution, and maps out the Mott-insulator/superfluid structure of the phase diagram from the ground-state response to an applied phase twist. +Touches most of the ground-state toolbox (`InfiniteMPS`, `find_groundstate`, bond-dimension control, `expectation_value`-based observables) in a single, longer study. +**Level: advanced.** -### [Spin 1 Heisenberg model](quantum1d/5.haldane-spt/index.md) +### [Spin 1 Heisenberg model](groundstates/4.haldane-spt/index.md) -![](quantum1d/5.haldane-spt/figure-3.png) +![](groundstates/4.haldane-spt/figure-3.png) Distinguishes the two symmetry-protected topological phases of the SU(2)-symmetric spin-1 Heisenberg chain by restricting the virtual `SU2Space` to integer or half-integer charges, then compares the two resulting ground states through their energy, transfer-matrix spectrum (`transferplot`), entanglement spectrum (`entanglementplot`), and entanglement entropy (`entropy`). Builds directly on the symmetry machinery introduced in the Haldane gap example. **Level: intermediate/advanced.** -### [Hubbard chain at half filling](quantum1d/6.hubbard/index.md) +### [The Ising CFT spectrum](groundstates/5.ising-cft/index.md) -![](quantum1d/6.hubbard/figure-2.png) +![](groundstates/5.ising-cft/figure-2.png) -Studies the 1D Hubbard model at half filling with fermionic `InfiniteMPS`, first benchmarking a plain `VUMPS`/`GradientGrassmann` ground-state search against the exact Bethe-ansatz integral for the energy, then imposing the full particle-number and spin symmetry (`U1Irrep`, `SU2Irrep`, with `MPSKit.add_physical_charge` to pin the filling) and constructing the spinon/holon excitation spectrum with the `QuasiparticleAnsatz`. -Combines fermionic symmetry sectors with a more elaborate ground-state recipe (staged bond-dimension growth via `changebonds`/`OptimalExpand`, `SvdCut`, and mixed `VUMPS`/`GradientGrassmann` refinement). -**Level: advanced.** +Extracts the finite-size conformal spectrum of the critical transverse-field Ising chain, first by brute-force `exact_diagonalization` on a small periodic chain, then by extending to larger sizes with finite `DMRG` and the `QuasiparticleAnsatz`, using a translation MPO to assign a momentum label to each state. +No symmetries are used, which makes this a good entry point into the finite-MPS workflow. +**Level: introductory.** -### [Finite temperature XY model](quantum1d/7.xy-finiteT/index.md) +## Excitations & dispersions -![](quantum1d/7.xy-finiteT/figure-1.png) +### [The Haldane gap](excitations/0.haldane/index.md) -Simulates the finite-temperature XY chain by purifying the infinite-temperature density matrix and evolving it in imaginary time, then compares the resulting partition function and free energy against exact diagonalization and, via BenchmarkFreeFermions.jl, the exact free-fermion solution. -A technical, comparison-heavy example built around `MPSKit.infinite_temperature_density_matrix` and imaginary-time evolution rather than ground-state search. +![](excitations/0.haldane/figure-3.png) + +Computes the Haldane gap of the spin-1 Heisenberg antiferromagnet in two complementary ways: finite-size `DMRG` with the `QuasiparticleAnsatz`, extrapolated over system size, and a direct infinite-chain `VUMPS` calculation with a momentum-resolved excitation scan. +Introduces `SU2Irrep`/`SU2Space` symmetric tensors for both `FiniteMPS` and `InfiniteMPS`. +**Level: intermediate.** + +### [The SU(3) Haldane gap](excitations/1.su3-heisenberg/index.md) + +![](excitations/1.su3-heisenberg/figure-1.png) + +Reproduces the setup of the SU(3) `[3 0 0]` Heisenberg chain [devos2022](@cite): the physical site carries the ten-dimensional `[3 0 0]` irrep, the SU(3)-invariant nearest-neighbour coupling is assembled by hand with [SUNRepresentations.jl](https://github.com/QuantumKitHub/SUNRepresentations.jl) (MPSKitModels has no built-in SU(N) Heisenberg), the uniform ground state is found with `VUMPS`, and the `[2 1 0]`-sector excitation dispersion is scanned across the Brillouin zone. +The natural non-abelian counterpart to the spin-1 Haldane gap example, and the only gallery example using an SU(N>2) symmetry. **Level: advanced.** -### [1D Bose-Hubbard model](quantum1d/8.bose-hubbard/index.md) +## Dynamics & finite temperature -![](quantum1d/8.bose-hubbard/figure-6.png) +### [DQPT in the Ising model](dynamics/0.ising-dqpt/index.md) -The most comprehensive example in the gallery: works directly in the thermodynamic limit with a truncated bosonic local Hilbert space, extracts correlation functions and the correlation length as a function of bond dimension, computes the momentum distribution, and maps out the Mott-insulator/superfluid structure of the phase diagram from the ground-state response to an applied phase twist. -Touches most of the ground-state toolbox (`InfiniteMPS`, `find_groundstate`, bond-dimension control, `expectation_value`-based observables) in a single, longer study. +![](dynamics/0.ising-dqpt/infinite_timeev.png) + +Quenches the transverse-field Ising chain across its critical point and tracks the Loschmidt echo in search of non-analyticities (dynamical quantum phase transitions), on both a finite chain (`TDVP2`/`TDVP`) and directly in the thermodynamic limit (`changebonds` with `OptimalExpand`, then `TDVP`). +A compact introduction to real-time evolution and environment reuse, still without symmetries. +**Level: introductory/intermediate.** + +### [Finite temperature XY model](dynamics/1.xy-finiteT/index.md) + +![](dynamics/1.xy-finiteT/figure-1.png) + +Simulates the finite-temperature XY chain by purifying the infinite-temperature density matrix and evolving it in imaginary time, then compares the resulting partition function and free energy against exact diagonalization and, via BenchmarkFreeFermions.jl, the exact free-fermion solution. +A technical, comparison-heavy example built around `MPSKit.infinite_temperature_density_matrix` and imaginary-time evolution rather than ground-state search. **Level: advanced.** -## Classical (2+0)d +## Statistical mechanics -### [The Hard Hexagon model](classic2d/1.hard-hexagon/index.md) +### [The Hard Hexagon model](statmech/0.hard-hexagon/index.md) -![](classic2d/1.hard-hexagon/figure-1.png) +![](statmech/0.hard-hexagon/figure-1.png) Extracts the central charge of the hard hexagon lattice gas by finding the leading boundary MPS of its transfer matrix with `VUMPS` (using Fibonacci-anyon virtual spaces), then fitting the CFT-predicted scaling relation between entanglement entropy and correlation length as the bond dimension is increased. The only classical statistical-mechanics example in the gallery, and the only one demonstrating non-abelian anyonic symmetries (`FibonacciAnyon`) in MPSKit. diff --git a/docs/src/examples/classic2d/1.hard-hexagon/figure-1.png b/docs/src/examples/statmech/0.hard-hexagon/figure-1.png similarity index 100% rename from docs/src/examples/classic2d/1.hard-hexagon/figure-1.png rename to docs/src/examples/statmech/0.hard-hexagon/figure-1.png diff --git a/docs/src/examples/classic2d/1.hard-hexagon/hexagon.svg b/docs/src/examples/statmech/0.hard-hexagon/hexagon.svg similarity index 100% rename from docs/src/examples/classic2d/1.hard-hexagon/hexagon.svg rename to docs/src/examples/statmech/0.hard-hexagon/hexagon.svg diff --git a/docs/src/examples/classic2d/1.hard-hexagon/index.md b/docs/src/examples/statmech/0.hard-hexagon/index.md similarity index 94% rename from docs/src/examples/classic2d/1.hard-hexagon/index.md rename to docs/src/examples/statmech/0.hard-hexagon/index.md index 59c72eca4..7ca7f3440 100644 --- a/docs/src/examples/classic2d/1.hard-hexagon/index.md +++ b/docs/src/examples/statmech/0.hard-hexagon/index.md @@ -1,10 +1,10 @@ ```@meta -EditURL = "../../../../../examples/classic2d/1.hard-hexagon/main.jl" +EditURL = "../../../../../examples/statmech/0.hard-hexagon/main.jl" ``` -[![](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/QuantumKitHub/MPSKit.jl/gh-pages?filepath=dev/examples/classic2d/1.hard-hexagon/main.ipynb) -[![](https://img.shields.io/badge/show-nbviewer-579ACA.svg)](https://nbviewer.jupyter.org/github/QuantumKitHub/MPSKit.jl/blob/gh-pages/dev/examples/classic2d/1.hard-hexagon/main.ipynb) -[![](https://img.shields.io/badge/download-project-orange)](https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/QuantumKitHub/MPSKit.jl/examples/tree/gh-pages/dev/examples/classic2d/1.hard-hexagon) +[![](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/QuantumKitHub/MPSKit.jl/gh-pages?filepath=dev/examples/statmech/0.hard-hexagon/main.ipynb) +[![](https://img.shields.io/badge/show-nbviewer-579ACA.svg)](https://nbviewer.jupyter.org/github/QuantumKitHub/MPSKit.jl/blob/gh-pages/dev/examples/statmech/0.hard-hexagon/main.ipynb) +[![](https://img.shields.io/badge/download-project-orange)](https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/QuantumKitHub/MPSKit.jl/examples/tree/gh-pages/dev/examples/statmech/0.hard-hexagon) # The Hard Hexagon model diff --git a/docs/src/examples/classic2d/1.hard-hexagon/main.ipynb b/docs/src/examples/statmech/0.hard-hexagon/main.ipynb similarity index 100% rename from docs/src/examples/classic2d/1.hard-hexagon/main.ipynb rename to docs/src/examples/statmech/0.hard-hexagon/main.ipynb diff --git a/docs/src/index.md b/docs/src/index.md index 25b99ec8a..b46d02b27 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -139,8 +139,8 @@ See [Computing observables](@ref howto_observables) and [Entanglement entropy an The same three steps carry over to harder problems, usually by changing only the vector spaces or the state type: - [**The thermodynamic limit**](@ref tutorial_thermodynamic_limit) works at infinite system size: replace `FiniteMPS` with an [`InfiniteMPS`](@ref) and `DMRG` with [`VUMPS`](@ref), and the rest of the code is unchanged. -- [**Using symmetries**](@ref tutorial_using_symmetries) imposes abelian or non-abelian symmetries by swapping the plain `ℂ^2` spaces for symmetric ones (for example an `SU2Space`), which also shrinks the bond dimension; see also the [Haldane gap](examples/quantum1d/2.haldane/index.md) example. -- [**The Hubbard model**](examples/quantum1d/6.hubbard/index.md) treats fermions with the same machinery, through TensorKit's graded vector spaces. +- [**Using symmetries**](@ref tutorial_using_symmetries) imposes abelian or non-abelian symmetries by swapping the plain `ℂ^2` spaces for symmetric ones (for example an `SU2Space`), which also shrinks the bond dimension; see also the [Haldane gap](examples/excitations/0.haldane/index.md) example. +- [**The Hubbard model**](examples/groundstates/2.hubbard/index.md) treats fermions with the same machinery, through TensorKit's graded vector spaces. ## Where next diff --git a/examples/Cache.toml b/examples/Cache.toml index 1183f3fd4..71449659e 100644 --- a/examples/Cache.toml +++ b/examples/Cache.toml @@ -1,13 +1,18 @@ -[classic2d] -"1.hard-hexagon" = "71d189b9138f98545c4239ed80a922cc4182e934db30af5ba867a0cee57305d0" +[excitations] +"1.su3-heisenberg" = "4dae7d3680a9f760a058ca3f5f1a617f8a9879fd649ea80334afaef940bfa07b" +"0.haldane" = "c5a0eb70f0930d38053535c659ab39a87121b6ebda040ceadd9deb5f30921315" -[quantum1d] -"2.haldane" = "c5a0eb70f0930d38053535c659ab39a87121b6ebda040ceadd9deb5f30921315" -"6.hubbard" = "50cb64102c2e3a61600df279a9cae45cd3b024e82e6f695d3ed713b0fd3f9283" -"7.xy-finiteT" = "0d21f7556fee8409edb58ab0ea04a77bd90feb2dffec424f0a5962d11dfdfc65" -"8.bose-hubbard" = "ba9ec53721371aab311dadbe05a31a3c95cb1b8a394abb7f81ee97e15b84d503" -"3.ising-dqpt" = "056423a189e1b1d4110bebc4eb6129a957ecdbf8e9a679eca10cf0391494b944" -"5.haldane-spt" = "c8fd3a8d406b9ff3ea9a34b596c5910d81e4eb710b665d7fa04e30f795a46086" -"4.xxz-heisenberg" = "5fa4242290b0a9ae658caf54f6919a8e04c97af80b9fcc6b936c2f45c7c8efdd" -"1.ising-cft" = "ebcae1e501347cb00a46d0889df1355707be77cf962f9ee0d16416393492529b" +[dynamics] +"0.ising-dqpt" = "056423a189e1b1d4110bebc4eb6129a957ecdbf8e9a679eca10cf0391494b944" +"1.xy-finiteT" = "0d21f7556fee8409edb58ab0ea04a77bd90feb2dffec424f0a5962d11dfdfc65" + +[statmech] +"0.hard-hexagon" = "71d189b9138f98545c4239ed80a922cc4182e934db30af5ba867a0cee57305d0" + +[groundstates] +"4.haldane-spt" = "c8fd3a8d406b9ff3ea9a34b596c5910d81e4eb710b665d7fa04e30f795a46086" +"2.hubbard" = "50cb64102c2e3a61600df279a9cae45cd3b024e82e6f695d3ed713b0fd3f9283" +"3.bose-hubbard" = "ba9ec53721371aab311dadbe05a31a3c95cb1b8a394abb7f81ee97e15b84d503" +"1.xxz-heisenberg" = "5fa4242290b0a9ae658caf54f6919a8e04c97af80b9fcc6b936c2f45c7c8efdd" "0.tfim-groundstate" = "a87cc89caf8df47285e25f6cec4ff130ea6ed88d4f73d59f8e7dc2e799ece1b0" +"5.ising-cft" = "ebcae1e501347cb00a46d0889df1355707be77cf962f9ee0d16416393492529b" diff --git a/examples/Project.toml b/examples/Project.toml index 2e29ddd9c..1d6ade97b 100644 --- a/examples/Project.toml +++ b/examples/Project.toml @@ -12,6 +12,7 @@ Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" Polynomials = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" QuadGK = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" +SUNRepresentations = "1a50b95c-7aac-476d-a9ce-2bfc675fc617" TensorKit = "07d1fe3e-3e46-537d-9eac-e9e13d0d4cec" TensorOperations = "6aa20fa7-93e2-5fca-9bc0-fbd0db3c71a2" diff --git a/examples/quantum1d/3.ising-dqpt/finite_timeev.png b/examples/dynamics/0.ising-dqpt/finite_timeev.png similarity index 100% rename from examples/quantum1d/3.ising-dqpt/finite_timeev.png rename to examples/dynamics/0.ising-dqpt/finite_timeev.png diff --git a/examples/quantum1d/3.ising-dqpt/infinite_timeev.png b/examples/dynamics/0.ising-dqpt/infinite_timeev.png similarity index 100% rename from examples/quantum1d/3.ising-dqpt/infinite_timeev.png rename to examples/dynamics/0.ising-dqpt/infinite_timeev.png diff --git a/examples/quantum1d/3.ising-dqpt/main.jl b/examples/dynamics/0.ising-dqpt/main.jl similarity index 100% rename from examples/quantum1d/3.ising-dqpt/main.jl rename to examples/dynamics/0.ising-dqpt/main.jl diff --git a/examples/quantum1d/7.xy-finiteT/main.jl b/examples/dynamics/1.xy-finiteT/main.jl similarity index 100% rename from examples/quantum1d/7.xy-finiteT/main.jl rename to examples/dynamics/1.xy-finiteT/main.jl diff --git a/examples/quantum1d/2.haldane/main.jl b/examples/excitations/0.haldane/main.jl similarity index 100% rename from examples/quantum1d/2.haldane/main.jl rename to examples/excitations/0.haldane/main.jl diff --git a/examples/excitations/1.su3-heisenberg/main.jl b/examples/excitations/1.su3-heisenberg/main.jl new file mode 100644 index 000000000..46e70d794 --- /dev/null +++ b/examples/excitations/1.su3-heisenberg/main.jl @@ -0,0 +1,200 @@ +md""" +# The SU(3) Haldane gap + +The spin-1 Heisenberg chain famously has a gapped, symmetry-protected topological ground +state: the Haldane phase. +A natural question is what happens when the ``SU(2)`` symmetry of the spins is promoted to a +larger ``SU(N)`` symmetry. +In this example we study the ``SU(3)`` generalization introduced in [devos2022](@cite): a +uniform chain where every site carries the fully-symmetric ``[3\,0\,0]`` irrep of ``SU(3)`` +(the ten-dimensional representation), coupled by a nearest-neighbour ``SU(3)``-invariant +Heisenberg interaction + +```math +H = J \sum_{\langle i, j \rangle} \sum_{a=1}^{8} T^a_i T^a_j , +``` + +where the ``T^a`` are the eight generators of ``SU(3)``. +This is the direct analog of the spin-1 chain, with the three generators of ``SU(2)`` +replaced by the eight generators of ``SU(3)``. + + + +Working with the full non-abelian ``SU(3)`` symmetry is what makes this tractable. +Just as ``SU(2)`` symmetry drastically shrinks the spin-1 problem (see +[Symmetries](@ref concept_symmetries)), imposing ``SU(3)`` block-diagonalizes every tensor +along its irreducible representations, so that a modest number of variational parameters +already captures a large physical bond dimension. +The Clebsch–Gordan coefficients that this requires are provided by +[SUNRepresentations.jl](https://github.com/QuantumKitHub/SUNRepresentations.jl), whose +`SU3Irrep` sectors plug directly into TensorKit's graded vector spaces. + +!!! warning "First-run cost" + SUNRepresentations.jl computes ``SU(N)`` Clebsch–Gordan coefficients on demand and + caches them both in memory and on disk (via `Scratch.jl`). + The **first** time a given coefficient is needed the computation can be slow; later runs + reuse the on-disk cache. + On a machine without a persisted scratch cache — such as a fresh continuous-integration + runner — this example therefore pays the full coefficient-generation cost once. +""" + +using TensorKit +using SUNRepresentations +using MPSKit +using Plots + +# For reproducibility of this page, we fix the seed of the random number generator: + +using Random +Random.seed!(4321); + +md""" +## The model + +Each site carries the ``[3\,0\,0]`` irrep, which we obtain from its highest weight and +represent as a one-dimensional graded space. +""" + +I300 = SU3Irrep(3, 0, 0) +Vphys = Vect[SU3Irrep](I300 => 1) +@show dim(I300) + +md""" +To build the interaction we use the same Casimir trick as for the ``SU(2)`` chain. +Writing ``C_2 = \sum_a T^a T^a`` for the quadratic Casimir operator, the two-site coupling is +diagonal in the total ``SU(3)`` charge ``c`` of a bond: + +```math +\sum_a T^a_i T^a_j = \tfrac{1}{2}\left( C_2(c) - C_2([3\,0\,0]) - C_2([3\,0\,0]) \right). +``` + +SUNRepresentations.jl provides the quadratic Casimir through `casimir(2, irrep)`. +Its normalization is the standard one with ``\mathrm{tr}(T^a T^b) = \tfrac{1}{2}\delta^{ab}``: +the fundamental ``[1\,0\,0]`` has ``C_2 = 4/3 = (N^2-1)/(2N)``. +""" + +@show casimir(2, SU3Irrep(1, 0, 0)) +@show casimir(2, I300) + +md""" +The nearest-neighbour term is then a single TensorKit operator that acts as a scalar on each +fusion channel of ``[3\,0\,0] \otimes [3\,0\,0]``. +Constructing it by iterating over the blocks — one block per total charge ``c`` — mirrors the +``SU(2)`` construction, but now with `casimir(2, ⋅)` supplying the eigenvalues. +""" + +function su3_heisenberg(Vphys; J = 1.0) + site = SU3Irrep(3, 0, 0) + c2_site = casimir(2, site) + SS = zeros(ComplexF64, Vphys ⊗ Vphys ← Vphys ⊗ Vphys) + for (c, data) in blocks(SS) + coupling = (casimir(2, c) - 2 * c2_site) / 2 + for i in axes(data, 1) + data[i, i] = J * coupling + end + end + return InfiniteMPOHamiltonian(SS) +end + +H = su3_heisenberg(Vphys) + +md""" +We can read off the physics directly from the fusion channels. +The product ``[3\,0\,0] \otimes [3\,0\,0]`` decomposes into four irreps, and the +antiferromagnetic coupling (``J > 0``) favours the channels of lowest Casimir: +""" + +for (c, n) in directproduct(I300, I300) + coupling = (casimir(2, c) - 2 * casimir(2, I300)) / 2 + println(rpad(string(c), 22), " dim = ", rpad(dim(c), 4), " coupling = ", coupling) +end + +md""" +## Ground state + +The ``[3\,0\,0]`` irrep has trivial triality (congruency class ``0``), so — like the +integer-spin Haldane chain — a translation-invariant state on a single-site unit cell is +admissible. +Because the physical charge has triality ``0`` it cannot shift the triality of the virtual +bonds, so every virtual space must sit in a single congruency class; here we use the trivial +class ``0``, which we found to give the lowest variational energy. +Following [devos2022](@cite), we seed the optimization with a random ``SU(3)``-symmetric +uniform state and optimize with VUMPS. + + +""" + +Vvirt = Vect[SU3Irrep]( + SU3Irrep(0, 0, 0) => 8, + SU3Irrep(2, 1, 0) => 6, + SU3Irrep(3, 0, 0) => 3, + SU3Irrep(3, 3, 0) => 3, + SU3Irrep(4, 2, 0) => 2, +) +@show dim(Vvirt) + +ψ₀ = InfiniteMPS([Vphys], [Vvirt]) +ψ, envs, δ = find_groundstate(ψ₀, H, VUMPS(; maxiter = 200, tol = 1.0e-10, verbosity = 1)) +E₀ = real(expectation_value(ψ, H)) +println("ground-state energy per site: E₀ = $E₀") + +md""" +## The excitation spectrum + +Excitations above the ground state are computed with the quasiparticle ansatz. +In the thermodynamic limit each excitation carries a definite momentum ``k`` and a definite +``SU(3)`` charge; reference [devos2022](@cite) reports that the lowest branch — whose minimum +is the Haldane gap — lives in the adjoint ``[2\,1\,0]`` sector, with its minimum at momentum +``k = 2\pi/3``. +We scan this branch across half of the Brillouin zone (the other half follows by reflection). + + +""" + +sector = SU3Irrep(2, 1, 0) +kspace = range(0, π, 10) +Es, _ = excitations(H, QuasiparticleAnsatz(), kspace, ψ, envs; sector) + +Δ, idx = findmin(real.(Es)) +println("branch minimum ΔE/J = $Δ at k = $(kspace[idx])") + +#+ + +plot( + kspace, real.(Es); + xaxis = "momentum k", yaxis = "ΔE / J", label = "[2 1 0] branch", + title = "SU(3) [3 0 0] excitation dispersion" +) +hline!([0.0]; color = :gray, linestyle = :dash, label = "") +vline!([2π / 3]; color = :gray, linestyle = :dot, label = "k = 2π/3") + +md""" +The branch has a pronounced soft mode at ``k = 2\pi/3``, exactly the momentum at which +[devos2022](@cite) locates the Haldane gap. +That reference reports a gap of ``\Delta / J = 0.0263`` there. + +This value is *very* small, and reproducing it faithfully is demanding: it requires a +carefully converged, large-bond-dimension uniform ``SU(3)`` MPS. +The lightweight calculation here — a modest virtual space chosen so the page builds quickly — +resolves the *location* of the soft mode but not the tiny gap itself: near ``k = 2\pi/3`` the +computed branch comes out close to zero and can even dip slightly negative, a sign that the +uniform ground state is not converged to the accuracy needed to pin down a gap this small. + + +""" diff --git a/examples/quantum1d/0.tfim-groundstate/main.jl b/examples/groundstates/0.tfim-groundstate/main.jl similarity index 100% rename from examples/quantum1d/0.tfim-groundstate/main.jl rename to examples/groundstates/0.tfim-groundstate/main.jl diff --git a/examples/quantum1d/4.xxz-heisenberg/main.jl b/examples/groundstates/1.xxz-heisenberg/main.jl similarity index 100% rename from examples/quantum1d/4.xxz-heisenberg/main.jl rename to examples/groundstates/1.xxz-heisenberg/main.jl diff --git a/examples/quantum1d/6.hubbard/main.jl b/examples/groundstates/2.hubbard/main.jl similarity index 100% rename from examples/quantum1d/6.hubbard/main.jl rename to examples/groundstates/2.hubbard/main.jl diff --git a/examples/quantum1d/8.bose-hubbard/main.jl b/examples/groundstates/3.bose-hubbard/main.jl similarity index 100% rename from examples/quantum1d/8.bose-hubbard/main.jl rename to examples/groundstates/3.bose-hubbard/main.jl diff --git a/examples/quantum1d/5.haldane-spt/main.jl b/examples/groundstates/4.haldane-spt/main.jl similarity index 100% rename from examples/quantum1d/5.haldane-spt/main.jl rename to examples/groundstates/4.haldane-spt/main.jl diff --git a/examples/quantum1d/5.haldane-spt/spt-tensors.svg b/examples/groundstates/4.haldane-spt/spt-tensors.svg similarity index 100% rename from examples/quantum1d/5.haldane-spt/spt-tensors.svg rename to examples/groundstates/4.haldane-spt/spt-tensors.svg diff --git a/examples/quantum1d/1.ising-cft/main.jl b/examples/groundstates/5.ising-cft/main.jl similarity index 100% rename from examples/quantum1d/1.ising-cft/main.jl rename to examples/groundstates/5.ising-cft/main.jl diff --git a/examples/quantum1d/1.ising-cft/translation_mpo.svg b/examples/groundstates/5.ising-cft/translation_mpo.svg similarity index 100% rename from examples/quantum1d/1.ising-cft/translation_mpo.svg rename to examples/groundstates/5.ising-cft/translation_mpo.svg diff --git a/examples/make.jl b/examples/make.jl index c6c9cfd72..0cb2093a0 100644 --- a/examples/make.jl +++ b/examples/make.jl @@ -103,5 +103,9 @@ end # Scripts # ---------------------------------------------------------------------------------------- # -build("classic2d") -build("quantum1d") +# build every topic group: each subdirectory of examples/ is one group +for group in readdir(@__DIR__) + startswith(group, '.') && continue + isdir(joinpath(@__DIR__, group)) || continue + build(group) +end diff --git a/examples/classic2d/1.hard-hexagon/hexagon.svg b/examples/statmech/0.hard-hexagon/hexagon.svg similarity index 100% rename from examples/classic2d/1.hard-hexagon/hexagon.svg rename to examples/statmech/0.hard-hexagon/hexagon.svg diff --git a/examples/classic2d/1.hard-hexagon/main.jl b/examples/statmech/0.hard-hexagon/main.jl similarity index 100% rename from examples/classic2d/1.hard-hexagon/main.jl rename to examples/statmech/0.hard-hexagon/main.jl From 0dc5ac079c9f3e4ab639f11a3214f0397c9c58ab Mon Sep 17 00:00:00 2001 From: lkdvos Date: Fri, 10 Jul 2026 10:35:56 -0400 Subject: [PATCH 70/76] docs: add remaining plan pages (concepts, how-to, lib reference, meta) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Completes the RESTRUCTURE_PLAN page tree. Each page was drafted against the real API (grepped/confirmed in src/), every @example executed against MPSKit, and the whole site verified with a full Documenter build (no broken @ref / checkdocs / duplicate-canonical / @example errors). Uncertain physics is marked with REVIEW comments for maintainer review. Concepts: - finite_vs_infinite.md — unit cells; per-site normalization (transfer-spectrum=1) - numerics.md — truncation (truncrank/trunctol/truncerror), convergence criteria, precision, pitfalls; defaults sourced from src/utility/defaults.jl How-to: - convergence_troubleshooting.md — symptom→diagnostic→fix recipes (variance check, changebonds, algorithm mixing, unit-cell/sector diagnostics) - statmech.md — transfer matrices, leading_boundary, MultilineMPS/MPO - quasi_1d_geometries.md — cylinders/ladders via MPSKitModels; ordering choices - saving_loading.md — stdlib Serialization + JLD2 round-trips (no bespoke MPSKit API) Library: - lib/environments.md, lib/internals.md — @docs canonical=false matching lib.md; internals marked non-public/unstable Meta: - migration.md, contributing.md, citing.md — grounded in CHANGELOG / CITATION.cff / Zenodo DOI / repo config (no invented facts) All new pages wired into docs/make.jl nav. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/make.jl | 11 + docs/src/citing.md | 51 +++ docs/src/concepts/finite_vs_infinite.md | 112 ++++++ docs/src/concepts/numerics.md | 168 +++++++++ docs/src/contributing.md | 87 +++++ docs/src/howto/convergence_troubleshooting.md | 333 ++++++++++++++++++ docs/src/howto/quasi_1d_geometries.md | 157 +++++++++ docs/src/howto/saving_loading.md | 142 ++++++++ docs/src/howto/statmech.md | 169 +++++++++ docs/src/lib/environments.md | 34 ++ docs/src/lib/internals.md | 53 +++ docs/src/migration.md | 51 +++ 12 files changed, 1368 insertions(+) create mode 100644 docs/src/citing.md create mode 100644 docs/src/concepts/finite_vs_infinite.md create mode 100644 docs/src/concepts/numerics.md create mode 100644 docs/src/contributing.md create mode 100644 docs/src/howto/convergence_troubleshooting.md create mode 100644 docs/src/howto/quasi_1d_geometries.md create mode 100644 docs/src/howto/saving_loading.md create mode 100644 docs/src/howto/statmech.md create mode 100644 docs/src/lib/environments.md create mode 100644 docs/src/lib/internals.md create mode 100644 docs/src/migration.md diff --git a/docs/make.jl b/docs/make.jl index 9d225afc7..65aff1c14 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -74,16 +74,22 @@ makedocs(; "howto/observables.md", "howto/entanglement.md", "howto/excitations.md", + "howto/statmech.md", + "howto/quasi_1d_geometries.md", + "howto/convergence_troubleshooting.md", "howto/parallelism_gpu.md", + "howto/saving_loading.md", ], "Concepts" => [ "concepts/vector_spaces.md", "concepts/matrix_product_states.md", + "concepts/finite_vs_infinite.md", "concepts/operators_and_hamiltonians.md", "concepts/symmetries.md", "concepts/algorithm_landscape.md", "concepts/environments.md", "concepts/parallelism_model.md", + "concepts/numerics.md", ], "Examples" => [ "Overview" => "examples/index.md", @@ -98,10 +104,15 @@ makedocs(; "lib/time_evolution.md", "lib/excitations.md", "lib/observables.md", + "lib/environments.md", + "lib/internals.md", "lib/lib.md", ], "References" => "references.md", "Changelog" => "changelog.md", + "Migration" => "migration.md", + "Contributing" => "contributing.md", + "Citing" => "citing.md", ], checkdocs = :exports, doctest = true, diff --git a/docs/src/citing.md b/docs/src/citing.md new file mode 100644 index 000000000..0f517735f --- /dev/null +++ b/docs/src/citing.md @@ -0,0 +1,51 @@ +# Citing MPSKit + +If you use MPSKit.jl in your research, please cite it. +Doing so supports the maintainers and helps others find the tools you relied on. + +## How to cite the software + +The canonical citation metadata lives in the +[`CITATION.cff`](https://github.com/QuantumKitHub/MPSKit.jl/blob/master/CITATION.cff) +file at the repository root, which GitHub also exposes through the "Cite this repository" button. +The software is archived on Zenodo under the concept DOI +[`10.5281/zenodo.10654900`](https://doi.org/10.5281/zenodo.10654900), +which always resolves to the latest release. + +A ready-to-use BibTeX entry: + +```bibtex +@software{mpskitjl, + author = {Devos, Lukas and Van Damme, Maarten and Haegeman, Jutho}, + title = {{MPSKit.jl}}, + version = {v0.13.13}, + doi = {10.5281/zenodo.10654900}, + url = {https://github.com/QuantumKitHub/MPSKit.jl}, + year = {2026} +} +``` + + + +## Citing the underlying methods + +MPSKit implements algorithms developed in the tensor-network literature. +When a specific method is central to your results, please also cite the original method paper. +Some of the key references, all included in the [References](@ref) bibliography, are: + +- **DMRG / tangent-space methods** — [vanderstraeten2019](@cite), a review of tangent-space methods for uniform matrix product states. +- **VUMPS** — [zauner-stauber2018](@cite), variational optimization algorithms for uniform matrix product states. +- **TDVP (time evolution)** — [haegeman2011](@cite), the time-dependent variational principle for quantum lattices. +- **Quasiparticle excitations** — [haegeman2013](@cite), elementary excitations in gapped quantum spin systems. + + + +The full bibliography, including works that have used MPSKit, is on the [References](@ref) page. diff --git a/docs/src/concepts/finite_vs_infinite.md b/docs/src/concepts/finite_vs_infinite.md new file mode 100644 index 000000000..2c4fccecb --- /dev/null +++ b/docs/src/concepts/finite_vs_infinite.md @@ -0,0 +1,112 @@ +```@meta +DocTestSetup = quote + using MPSKit, TensorKit +end +``` + +# [Finite versus infinite MPS](@id concept_finite_vs_infinite) + +The [matrix product state](@ref concept_matrix_product_states) machinery — the site tensors, the virtual bonds, the canonical gauge — is shared by two rather different physical objects, and MPSKit gives each its own type. +A [`FiniteMPS`](@ref) is the wavefunction of a chain with a definite number of sites and two open ends: a genuine vector in a finite-dimensional Hilbert space. +An [`InfiniteMPS`](@ref) instead stores a small, repeating *unit cell* of tensors and imagines it tiled forever along the chain, so that it represents a translation-invariant state directly in the thermodynamic limit `L = ∞`. +This page explains what that difference *means* — why the two share almost all of their code yet answer subtly different questions, and in particular why an infinite state is always normalized to one while a finite state is not. +It is about understanding rather than construction: to *build* either kind of state see [Constructing states](@ref howto_states), and for the type signatures see the [States](@ref lib_states) reference. + +## Two different objects + +A [`FiniteMPS`](@ref) is what you reach for whenever the system genuinely has a fixed size and boundaries: a chain of `N` sites, each a separate mutable tensor, with trivial (dimension-one) bonds capping the two ends. +It is a literal, if compressed, representation of a state vector `|ψ⟩` living in the tensor-product Hilbert space of those `N` sites, and every question you could ask of an ordinary state vector — its norm, its overlap with another state, an expectation value at a particular site — has a finite, exactly computable answer. +The open ends are part of the physics: sites near a boundary are in a different environment from sites in the bulk, and any measured quantity still carries a dependence on the length `N`. + +An [`InfiniteMPS`](@ref) throws both of those features away on purpose. +It represents a state that is exactly invariant under translation by one unit cell, so there is no boundary anywhere and no length `N` left to depend on. +What is actually stored is a finite list of tensors — the unit cell — together with the gauge data needed to treat the infinite periodic contraction; indexing the state is periodic, so `ψ.AL[i]` and `ψ.AL[i + length(ψ)]` return the same tensor. +This is the representation used throughout [The thermodynamic limit](@ref tutorial_thermodynamic_limit), where the payoff — no boundary effects, no finite-size extrapolation — is put to work on the transverse-field Ising model. + +## The unit cell + +The single number that characterizes the periodicity of an [`InfiniteMPS`](@ref) is its unit-cell length, returned by `length`. +The most common choice is a one-site unit cell, in which a single tensor is repeated across the whole chain: + +```@example finite-infinite +using MPSKit, TensorKit # hide +ψ_infinite = InfiniteMPS(ℂ^2, ℂ^8) +length(ψ_infinite) +``` + +A larger unit cell is specified by passing a vector of physical and virtual spaces, one entry per site of the cell: + +```@example finite-infinite +ψ_cell = InfiniteMPS([ℂ^2, ℂ^2], [ℂ^8, ℂ^8]) +length(ψ_cell) +``` + +The unit-cell length is not a free accuracy knob like the bond dimension; it is a physical statement about the *period* of the state you intend to represent. +A translation-invariant ansatz of period `L` can only capture states whose own spatial period divides `L`. + +Choosing a cell that is commensurate with the physical period of the model — the magnetic period of an ordered phase, or a period imposed by the Hamiltonian's own unit cell — is therefore a modelling decision, not a numerical one, and picking too small a cell forces the algorithm to approximate a state it structurally cannot represent. +A [`FiniteMPS`](@ref), by contrast, has no notion of a unit cell at all: its `length` is simply the number of physical sites, and each of those sites carries its own independent tensor. + +## Why an infinite MPS is normalized to one + +The sharpest practical consequence of the finite/infinite distinction shows up in the norm, and it is worth understanding rather than memorizing. + +For a [`FiniteMPS`](@ref) the norm is exactly the Euclidean norm `√⟨ψ|ψ⟩` of the state vector it represents — a genuine, finite number. +The space-based constructors normalize by default, so a freshly built state has norm one, but nothing forces that: the norm is a real degree of freedom you can set at will, and rescaling the state rescales it in the obvious way. + +```@example finite-infinite +ψ_finite = FiniteMPS(rand, ComplexF64, 16, ℂ^2, ℂ^8) +norm(ψ_finite) +``` + +```@example finite-infinite +norm(3 * ψ_finite) +``` + +For an [`InfiniteMPS`](@ref) that same quantity does not exist. +The overlap `⟨ψ|ψ⟩` of an infinite state is, formally, a product of one transfer-matrix factor per unit cell, so for a chain of `n` cells it grows (or decays) like `λⁿ`, where `λ` is the leading eigenvalue of the transfer matrix. +As `n → ∞` this is `0` if `λ < 1` and `∞` if `λ > 1`, and the *only* value that yields a finite, well-defined state is `λ = 1`. + +MPSKit therefore fixes the gauge so that the transfer matrix has leading eigenvalue exactly one, which we can read straight off its spectrum: + +```@example finite-infinite +first(transfer_spectrum(ψ_infinite)) ≈ 1 +``` + +With that fixed, `norm` of an [`InfiniteMPS`](@ref) is defined *per site* rather than globally: it is the norm of a single center-gauged unit-cell tensor, and it is always one. + +```@example finite-infinite +norm(ψ_infinite) ≈ 1 +``` + +```@example finite-infinite +norm(ψ_infinite) ≈ norm(ψ_infinite.AC[1]) +``` + +Because the normalization is intensive, it does not grow with the unit cell: a two-site cell is normalized to one just as a one-site cell is. + +```@example finite-infinite +norm(ψ_cell) ≈ 1 +``` + +This is why scalar multiplication of an [`InfiniteMPS`](@ref) is simply not defined — there is no overall amplitude to rescale — and why every physically meaningful quantity in the infinite setting is a *density*. +The energy returned for the state is an energy per site, an order parameter is measured at one representative site of the cell, and quantities with no finite-chain analogue, such as the [`correlation_length`](@ref), are extracted from the transfer-matrix spectrum of the uniform state rather than from any global overlap. + +## The same algorithms, two settings + +Because the two types share the canonical-form vocabulary, most of MPSKit's high-level entry points accept either one, and it is the *algorithm* passed to them that is specialized to the finite or the infinite case. +Ground-state search is the clearest example: [`find_groundstate`](@ref) dispatches on the state it is handed, running [`DMRG`](@ref) — which sweeps back and forth across a chain with two ends — for a [`FiniteMPS`](@ref), and [`VUMPS`](@ref) or [`IDMRG`](@ref)/[`IDMRG2`](@ref) — which converge a single uniform unit cell — for an [`InfiniteMPS`](@ref). +The distinction is not incidental: a boundary-sweeping method like DMRG has no meaning without ends to sweep between, while VUMPS' re-gauging step, which replaces every tensor in the chain at once, only makes sense for a genuinely translation-invariant state. +Some routines instead span both worlds: [`TDVP`](@ref) time-evolves finite and infinite states alike, its two-site bond-growing variant existing only for the finite case. +For which algorithm fits which task — and why one is preferred over another within each column — see [The algorithm landscape](@ref concept_algorithm_landscape). + +Two further state types sit between the finite and infinite poles rather than at them, reusing the same machinery: a [`WindowMPS`](@ref) embeds a finite, mutable window inside two infinite environments, and a [`MultilineMPS`](@ref) stacks several infinite states to represent two-dimensional networks. +Both are introduced in [Constructing states](@ref howto_states). + +## Where to go next + +- For the flagship finite-then-infinite walkthrough of the same model, see [The thermodynamic limit](@ref tutorial_thermodynamic_limit). +- For the gauge and canonical-form machinery both types share, see [Matrix product states](@ref concept_matrix_product_states). +- For choosing the right algorithm in each setting, see [The algorithm landscape](@ref concept_algorithm_landscape). +- For how to construct each state type, see [Constructing states](@ref howto_states); for type signatures, the [States](@ref lib_states) reference. +``` diff --git a/docs/src/concepts/numerics.md b/docs/src/concepts/numerics.md new file mode 100644 index 000000000..a410b518a --- /dev/null +++ b/docs/src/concepts/numerics.md @@ -0,0 +1,168 @@ +```@meta +DocTestSetup = quote + using MPSKit, TensorKit +end +``` + +# [Numerical considerations](@id concept_numerics) + +Every MPSKit calculation is an approximation controlled by a handful of numerical knobs, and understanding what those knobs actually measure is what separates a trustworthy result from a plausible-looking one. +A ground state is only approached to a finite tolerance; a bond dimension only captures so much entanglement; a floating-point number only stores so many digits. +This page explains the three quantities that govern accuracy — the *truncation error* that bounds how well the ansatz can represent a state, the *convergence criterion* that tells an iterative algorithm when to stop, and the *precision* of the underlying element type — and then surveys the failure modes that these considerations give rise to. +It is about understanding *why* a calculation is or is not accurate; for the diagnostic recipe when one goes wrong, follow the links into [Convergence troubleshooting](@ref howto_convergence_troubleshooting). + +## Truncation and the bond dimension + +The single most important approximation in the whole framework is truncation. +An MPS represents the wavefunction as a chain of tensors joined along virtual bonds, and the dimension of those bonds — the *bond dimension* — is the ansatz's capacity: it is the number of Schmidt coefficients kept when the state is split into two halves at that bond. +Cutting the chain at one bond and performing a singular value decomposition of the resulting bipartition yields exactly the Schmidt decomposition, whose singular values are the Schmidt coefficients. +Keeping only the largest of them is the truncation, and the bond dimension is the number kept. + +The quality of that truncation is measured by the *discarded weight*: the sum of the squares of the Schmidt coefficients that were thrown away. +Because the Schmidt coefficients of a normalized state satisfy ``\sum_i \lambda_i^2 = 1``, the discarded weight is the fraction of the state's norm that the truncation sacrifices, and it is the natural error measure of the approximation. +A small discarded weight means the kept bond dimension already captures almost all of the state's entanglement across that cut, so enlarging it further buys little. + +We can watch this directly. +After optimizing a ground state we read off its Schmidt spectrum at the central bond with [`entanglement_spectrum`](@ref), and see how quickly the coefficients decay: + +```@example numerics +using MPSKit, MPSKitModels, TensorKit +ψ = FiniteMPS(16, ℂ^2, ℂ^24) +H = transverse_field_ising(FiniteChain(16); g = 1.0) +ψ, envs, ϵ = find_groundstate(ψ, H, DMRG(; tol = 1e-10, verbosity = 0)) +schmidt = sort(collect(entanglement_spectrum(ψ, 8)); rev = true) +round.(schmidt[1:6]; digits = 4) +``` + +The tail beyond the first few coefficients is tiny, so truncating the bond back down to keep only the six largest discards only a small weight: + +```@example numerics +discarded = sum(abs2, schmidt[7:end]) +``` + +Performing that truncation with [`SvdCut`](@ref) through [`changebonds`](@ref) and comparing the energy before and after shows the corresponding cost in the observable of interest: + +```@example numerics +ψcut = changebonds(ψ, SvdCut(; trscheme = truncrank(6))) +ΔE = real(expectation_value(ψcut, H) - expectation_value(ψ, H, envs)) +``` + +The bond dimension is thus a genuine accuracy/cost dial: a larger bond dimension lowers the discarded weight and the truncation error, at the price of more expensive tensor contractions. + + +How much bond dimension a state actually *needs* is set by its entanglement. +Ground states of gapped, local one-dimensional Hamiltonians obey an entanglement *area law* — their bipartite entanglement entropy saturates to a constant as the system grows — which is precisely why a finite bond dimension can represent them efficiently; at a critical point the entropy instead grows without bound and no fixed bond dimension suffices. + + +### Choosing what to truncate + +The rule for *which* coefficients to discard is a truncation scheme. +MPSKit itself does not define these; they come from the tensor backend, so the schemes below require `using TensorKit` (which re-exports them from `MatrixAlgebraKit`) rather than `using MPSKit` alone. +The ones you will meet most often are: + +- `truncrank(n)` — keep a fixed number of coefficients (a hard bond-dimension cap). +- `trunctol(; atol)` — discard every coefficient below a threshold. +- `truncerror(; atol)` — keep as many coefficients as needed to hold the discarded weight below a target. +- `truncspace(V)` — truncate to a prescribed vector space, used mostly internally to match bond spaces. +- `notrunc()` — keep everything; this is the default `trscheme` of the bond-preserving single-site algorithms. + +These schemes compose with `&`, so `trunctol(; atol = 1e-8) & truncrank(16)` applies both bounds at once. + + + +Every bond-growing algorithm — [`DMRG2`](@ref), [`IDMRG2`](@ref), [`TDVP2`](@ref) — and every explicit bond-surgery tool — [`SvdCut`](@ref), [`OptimalExpand`](@ref) — requires a `trscheme` keyword, because their whole job is to decide a new bond dimension. +The single-site workhorses ([`DMRG`](@ref), [`VUMPS`](@ref), [`TDVP`](@ref)) default to `notrunc()` and keep the bond dimension fixed. +The recipes for growing and shrinking bonds live in [Controlling bond dimension](@ref howto_bond_dimension). + +## Convergence criteria + +Every iterative algorithm needs a rule for when it has done enough, and "converged" means something specific and measurable rather than "looks stable." +For the single-site variational algorithms the measure is the **Galerkin error**: the norm of the component of the local energy gradient that points out of the current tangent space of the MPS. +Intuitively, it is how far the exact update at a site wants to push the state in a direction the fixed-bond-dimension ansatz cannot follow; when it is small everywhere, the state is a fixed point of the update to within the ansatz's reach. +This is the quantity [`DMRG`](@ref), [`VUMPS`](@ref), and [`VOMPS`](@ref) drive to zero, and it is returned to you as the third output of the entry point: + +```@example numerics +ϵ +``` + +That returned `ϵ` is the final Galerkin error, and convergence is declared when it drops below the algorithm's `tol`. +The default tolerance is `1e-10`, defined together with the other numerical defaults in the (public but unexported) `MPSKit.Defaults` module, alongside a default `maxiter` of `200` and a default Krylov dimension of `30`: + +```@example numerics +MPSKit.Defaults.tol +``` + +Not every algorithm reports the same measure, and the differences matter when comparing runs: + +- The two-site [`DMRG2`](@ref) does not use the Galerkin error during its sweep; it monitors instead the local infidelity between each two-site tensor before and after truncation, which is a different — and generally less directly interpretable — proxy for convergence. + +- [`IDMRG`](@ref) and [`IDMRG2`](@ref) judge convergence by the change in the bond matrix between successive iterations, ``\lVert C - C_\text{old}\rVert``, rather than by a gradient norm. + +- [`GradientGrassmann`](@ref) converges on the Riemannian gradient norm reported by its underlying optimizer, with `tol` passed through as the gradient tolerance. + +A subtlety worth knowing is that these tolerances are, by default, *dynamic*: MPSKit tightens the tolerances of the inner linear and eigenvalue solvers as the outer iteration converges, so that early iterations are not over-solved and late ones are not under-solved. +This adaptive behavior is on by default (`dynamic_tols = true` in `Defaults`) and is why the inner solvers do not simply run at the outer `tol` from the first sweep. + + +The Galerkin error certifies that the algorithm reached a fixed point of *its own* update, which is necessary but not sufficient for the state to be a good eigenstate. +An independent check is the energy [`variance`](@ref) ``\langle H^2\rangle - \langle H\rangle^2``, which vanishes exactly for a true eigenstate and does not rely on the ansatz's tangent space: + +```@example numerics +variance(ψ, H, envs) +``` + + + +## Precision and the element type + +Underneath the tensors is an ordinary floating-point element type, and by default it is complex double precision, `ComplexF64`. +A randomly initialized state carries that type unless you ask for another: + +```@example numerics +scalartype(FiniteMPS(16, ℂ^2, ℂ^24)) +``` + +Double precision is the right default: at `Float64` the relative rounding error is about ``10^{-16}``, comfortably below the `1e-10` convergence tolerance, so floating-point noise is rarely what limits an MPSKit result — truncation and incomplete convergence dominate long before precision does. + + +The choice between a real and a complex element type is occasionally load-bearing rather than cosmetic. +Real-time evolution and the ``W^{II}`` time-evolution MPO intrinsically require complex arithmetic, so a real-valued state must be promoted before it can be evolved; MPSKit provides `Base.complex` on an MPS for exactly this, and it is a no-op when the state is already complex. +Conversely, a purely real problem — a real Hamiltonian with a real ground state — can in principle be run in `Float64` to save memory and time, but this is an optimization to reach for deliberately, not the default. + + +## Common pitfalls + +Most non-convergence has one of a small number of causes, and recognizing them conceptually is half the battle; the concrete diagnostics are collected in [Convergence troubleshooting](@ref howto_convergence_troubleshooting). + +**Too small a bond dimension.** +If the state genuinely needs more entanglement than the bond dimension can hold, no amount of iterating will converge it — the discarded weight is bounded away from zero by the ansatz itself. +This is aggravated by the single-site algorithms, which cannot enlarge the bond dimension: with a symmetry, a single-site sweep freezes not only the total bond dimension but its distribution over charge sectors, so a poor initial distribution cannot be repaired without a two-site pass or an explicit [`changebonds`](@ref) expansion. + +**Local minima.** +The variational optimization is non-convex, and an algorithm can settle into a state that is a fixed point of its update but not the global ground state. +The single-site methods are more prone to this than bond-growing ones, which is part of why a two-site warm-up (or a gradient-descent polishing stage, chained with `&`) is often used before or after a single-site run. + + +**Symmetry-sector trapping.** +When the state carries a conserved quantum number, the optimization runs within a fixed set of symmetry sectors on each bond. +If the true ground state lives in a sector distribution the initial state does not span, the algorithm converges — cleanly, by its own criterion — to the best state in the *wrong* variational space. +This is a sharper, symmetry-specific version of the too-small-bond-dimension trap, and it is why the sector structure of the initial state matters. + + +**Non-injectivity and a near-degenerate transfer matrix (infinite systems).** +[`VUMPS`](@ref) assumes a unique, injective fixed point. +When the state it should converge to is non-injective — for instance a cat state superposing symmetry-broken sectors, or a genuinely degenerate ground space — the transfer matrix has more than one eigenvalue of magnitude one, and the algorithm has no well-defined single fixed point to find. +MPSKit's [`correlation_length`](@ref) machinery detects this: it is computed from the gap between the leading and next-to-leading transfer-matrix eigenvalues (the correlation length is the inverse of that gap), and [`transfer_spectrum`](@ref) exposes the spectrum directly. +Internally the routine emits a `"Non-injective mps?"` warning when it finds more than one eigenvalue near magnitude one at the same complex angle — a heuristic flag, not a hard error, so it is worth watching for. + + +**Finite-entanglement effects at criticality.** +At or near a critical point the true correlation length diverges, but a finite bond dimension can only support a finite correlation length, so the simulated correlation length saturates at a value set by the bond dimension rather than by the physics. +Extracting critical data therefore requires studying how results drift as the bond dimension grows, rather than trusting any single bond dimension. + + +## Where to go next + +For the step-by-step diagnosis of a calculation that will not converge, see [Convergence troubleshooting](@ref howto_convergence_troubleshooting). +For the mechanics of changing the bond dimension, see [Controlling bond dimension](@ref howto_bond_dimension), and for the reasoning behind each algorithm's convergence behavior see [The algorithm landscape](@ref concept_algorithm_landscape). +The full signatures of the diagnostic functions named here — [`entanglement_spectrum`](@ref), [`entropy`](@ref), [`variance`](@ref), [`correlation_length`](@ref), and [`transfer_spectrum`](@ref) — are in the library reference. diff --git a/docs/src/contributing.md b/docs/src/contributing.md new file mode 100644 index 000000000..e28cf54c5 --- /dev/null +++ b/docs/src/contributing.md @@ -0,0 +1,87 @@ +# Contributing + +Contributions to MPSKit.jl are welcome, from bug reports and questions to documentation +fixes and new algorithms. +This page summarizes the practical workflow; the authoritative version is the +[`CONTRIBUTING.md`](https://github.com/QuantumKitHub/MPSKit.jl/blob/master/CONTRIBUTING.md) +file in the repository. + +## Asking questions and reporting bugs + +Questions and bug reports both go through +[GitHub issues](https://github.com/QuantumKitHub/MPSKit.jl/issues), which provides two +templates: a **bug report** for things that do not work as expected, and a **question** for +anything else. +General discussion is also welcome on +[GitHub Discussions](https://github.com/QuantumKitHub/MPSKit.jl/discussions). + +A good bug report includes a minimal working example (the smallest snippet that reproduces +the problem), the full error message and stacktrace, and version information for MPSKit, +TensorKit, and Julia: + +```julia-repl +julia> using Pkg +julia> Pkg.status(["MPSKit", "TensorKit"]) + +julia> versioninfo() +``` + +## Development setup + +Fork and clone the repository, then develop the package against your local checkout from the +Julia REPL: + +```julia-repl +pkg> dev /path/to/your/clone/MPSKit.jl +``` + +## Running the tests + +The repository root is a Julia workspace whose `Project.toml` lists `test`, `docs`, and +`examples` as workspace projects. +Run the full test suite from the repository root with: + +``` +julia --project=test test/runtests.jl +``` + +The tests are organized by topic under `test/` (`algorithms/`, `states/`, `operators/`, +`misc/`, `gpu/`). +GPU tests only run when a functional CUDA/cuTENSOR install is detected, so most contributors +exercise only the CPU tests. +A `--fast` flag is available for a quicker, reduced run while iterating. + +## Code formatting + +The repository is formatted with [Runic](https://github.com/fredrikekre/Runic.jl). +Formatting is checked automatically on pull requests, and a +[pre-commit](https://pre-commit.com/) hook (`.pre-commit-config.yaml`) runs Runic locally if +you use pre-commit. +Please format any Julia files you touch before opening a pull request. + +## Building the documentation + +The documentation uses [Documenter.jl](https://github.com/JuliaDocs/Documenter.jl) with the +[DocumenterVitepress](https://github.com/LuxDL/DocumenterVitepress.jl) backend, so a full site +render needs Node.js (with `npm`) in addition to Julia. +For routine verification of code examples, doctests run on the Documenter side and need no +Node: + +``` +julia --project=docs -e 'using Documenter, MPSKit; doctest(MPSKit)' +``` + +A full local site build is: + +``` +julia --project=docs docs/make.jl +``` + +## Opening a pull request + +Keep pull requests small and focused. +Describe what the change does and why, link any related issues, and fill in the checklist in +the PR template. +If your change is user-facing (a new feature, behavior change, bug fix, deprecation, or +removal), add an entry under the `[Unreleased]` section of the [Changelog](@ref) in the +category that matches your change. diff --git a/docs/src/howto/convergence_troubleshooting.md b/docs/src/howto/convergence_troubleshooting.md new file mode 100644 index 000000000..afe088f5c --- /dev/null +++ b/docs/src/howto/convergence_troubleshooting.md @@ -0,0 +1,333 @@ +# [Troubleshooting convergence](@id howto_convergence_troubleshooting) + +```@meta +DocTestSetup = quote + using MPSKit, MPSKitModels, TensorKit +end +``` + +When [`find_groundstate`](@ref), [`leading_boundary`](@ref), or a time-evolution call does +not converge, the fix is almost always one of a handful of causes: too few iterations, a +bond dimension that is too small, a bad initial state, or a mismatch between the ansatz and +the physics (wrong unit cell, wrong symmetry sector). +This page is a diagnostic checklist: each section is a symptom, the diagnostic that +confirms it, and the concrete API knob that fixes it. +It assumes you already know how to run the algorithms — see +[Ground-state algorithms](@ref howto_groundstate_algorithms) and +[Controlling bond dimension](@ref howto_bond_dimension) for that. + +All examples share a single namespace: + +```@example conv +using MPSKit, MPSKitModels, TensorKit +``` + +--- + +## 1. Read the convergence report + +Every optimizer returns three things, `(ψ, envs, ϵ)`, and `ϵ` is your primary diagnostic: + +```@example conv +L = 16 +H = transverse_field_ising(FiniteChain(L); g = 1.0) +ψ₀ = FiniteMPS(L, ℂ^2, ℂ^16) + +ψ, envs, ϵ = find_groundstate(ψ₀, H, DMRG(; tol = 1.0e-10, maxiter = 30, verbosity = 0)) +ϵ +``` + +`ϵ` is the convergence-error measure of whichever algorithm ran last, compared against its +`tol` each sweep. +The algorithm has converged when `ϵ < tol`; if it stops because it hit `maxiter` first, `ϵ` +tells you how far it still had to go. +What `ϵ` actually measures differs by algorithm: + +| Algorithm | What `ϵ` measures | +|:----------|:------------------| +| [`DMRG`](@ref), [`VUMPS`](@ref) | Galerkin residual (norm of the projected gradient) | +| [`DMRG2`](@ref) | `1 - abs(overlap)` of the two-site tensor across the truncation | +| [`IDMRG`](@ref), [`IDMRG2`](@ref) | change in the bond matrix `C` between iterations | +| [`GradientGrassmann`](@ref) | norm of the Riemannian gradient | + + + +Because the measures differ, a raw `ϵ` value is only meaningful *within* one algorithm; do +not compare `ϵ` from a `DMRG2` warm-up against `ϵ` from the following `DMRG` refinement. + +To watch convergence as it happens rather than after the fact, raise `verbosity`. +The levels are shared by every algorithm and documented in +[Ground-state algorithms](@ref howto_groundstate_algorithms); the named constants +`MPSKit.VERBOSE_NONE` (`0`) through `MPSKit.VERBOSE_ALL` (`4`) are public but not exported. +`verbosity = 2` prints one convergence line per sweep, which is usually enough to see +whether `ϵ` is dropping, plateauing, or oscillating. + +--- + +## 2. Converged but wrong: check the variance + +A small `ϵ` does **not** by itself guarantee a good ground state. +At a fixed bond dimension the optimizer converges to the best MPS *within that manifold*, and +its convergence measure can drop below `tol` while the state is still far from the true +ground state. +The independent check is the energy variance +``\langle H^2 \rangle - \langle H \rangle^2``, which is zero only for an exact eigenstate: + +```@example conv +ψ_small, _, ϵ_small = find_groundstate( + FiniteMPS(L, ℂ^2, ℂ^2), H, DMRG(; tol = 1.0e-10, maxiter = 30, verbosity = 0) +) +(ϵ_small, variance(ψ_small, H)) +``` + +Here `ϵ` sits comfortably below `tol` — the run reports success — yet the variance is large: +a bond dimension of 2 simply cannot represent this (critical) ground state. +Grow the bond dimension and the variance collapses: + +```@example conv +ψ_big, _, ϵ_big = find_groundstate( + FiniteMPS(L, ℂ^2, ℂ^32), H, DMRG(; tol = 1.0e-10, maxiter = 30, verbosity = 0) +) +(ϵ_big, variance(ψ_big, H)) +``` + +!!! tip "Variance is your ground-truth check" + Whenever a result looks suspicious despite a small `ϵ`, compute [`variance`](@ref). + A variance that will not drop as you add bond dimension points at an undersized ansatz, + not at an unconverged optimization. + + + +The fix is to grow the bond dimension: use [`DMRG2`](@ref)/[`IDMRG2`](@ref), or expand +explicitly with [`changebonds`](@ref) and [`OptimalExpand`](@ref)/[`RandExpand`](@ref). +See [Controlling bond dimension](@ref howto_bond_dimension) for the full set of recipes. + +--- + +## 3. `ϵ` is still dropping, or stalls just above `tol` + +If the algorithm stopped on `maxiter` with `ϵ` still decreasing, it simply needs more +iterations — raise `maxiter`: + +```@example conv +ψ_more, _, ϵ_more = find_groundstate( + ψ₀, H, DMRG(; tol = 1.0e-10, maxiter = 100, verbosity = 0) +) +ϵ_more +``` + +You can also resume from an already-optimized state instead of restarting, passing the +previous environments as the optional fourth argument so they are reused rather than +recomputed: + +```@example conv +ψ_resume, _, ϵ_resume = find_groundstate( + ψ, H, DMRG(; tol = 1.0e-12, maxiter = 50, verbosity = 0), envs +) +ϵ_resume +``` + +If instead `ϵ` *plateaus* well above `tol` and more iterations do not help, the ansatz is +the bottleneck, not the iteration count: check the variance and grow the bond dimension as in +[§2](#2-converged-but-wrong-check-the-variance), or treat it as a local minimum +([§4](#4-stuck-in-a-local-minimum)). + +!!! note "Adaptive sub-tolerances" + By default MPSKit tightens the tolerances of the inner eigensolver, gauge, and + environment solvers automatically as the outer error `ϵ` shrinks (the `DynamicTol` + mechanism). + You therefore rarely need to touch `alg_eigsolve`/`alg_gauge`/`alg_environments` by + hand; set the outer `tol` and let the inner solvers follow. + + + +--- + +## 4. Stuck in a local minimum + +Symptom: `ϵ` plateaus above `tol`, adding bond dimension does not help, and the variance +stays stubbornly high. +Variational optimizers can get trapped in local minima, especially from an unlucky random +start or a symmetry-frustrated initial state. + + + +Things to try, roughly in order: + +- **Restart from a different initial state.** `FiniteMPS`/`InfiniteMPS` with a size argument + produce a *random* state, so simply rebuilding the initial guess reseeds the search: + + ```@example conv + ψ_restart, _, ϵ_restart = find_groundstate( + FiniteMPS(L, ℂ^2, ℂ^16), H, DMRG(; tol = 1.0e-10, maxiter = 100, verbosity = 0) + ) + ϵ_restart + ``` + +- **Mix algorithms.** Different optimizers have different failure modes, so chaining them + with `&` often escapes a minimum that traps one of them. + A robust infinite-system default is a [`VUMPS`](@ref) pass to get close, polished by + [`GradientGrassmann`](@ref) — exactly what `find_groundstate` does automatically once + `tol` is tighter than `1e-4`: + + ```@example conv + H_inf = transverse_field_ising(; g = 0.5) + ψ_inf, _, ϵ_inf = find_groundstate( + InfiniteMPS(ℂ^2, ℂ^6), H_inf, + VUMPS(; tol = 1.0e-8, maxiter = 50, verbosity = 0) & + GradientGrassmann(; tol = 1.0e-10, maxiter = 50, verbosity = 0) + ) + ϵ_inf + ``` + +- **Inject noise, then re-optimize.** Padding the state with orthogonal random directions via + [`RandExpand`](@ref) perturbs it off the current (possibly stuck) point without changing + what it represents, giving the next optimization new directions to explore: + + ```@example conv + ψ_noisy = changebonds(ψ_small, RandExpand(; trscheme = truncrank(8))) + ψ_kick, _, ϵ_kick = find_groundstate( + ψ_noisy, H, DMRG(; tol = 1.0e-10, maxiter = 100, verbosity = 0) + ) + (ϵ_kick, variance(ψ_kick, H)) + ``` + + A two-site algorithm ([`DMRG2`](@ref)) or the Hamiltonian-aware + [`OptimalExpand`](@ref)/CBE variants achieve a similar effect while also improving the + energy, and are usually the better first choice — see + [Controlling bond dimension](@ref howto_bond_dimension). + +--- + +## 5. Infinite MPS won't converge — look at the transfer matrix + +A distinctive infinite-system failure is a state whose transfer matrix has several +eigenvalues crowding the unit circle. +This signals that the state is close to *non-injective* — a superposition of several +injective states — which is numerically ill-conditioned and usually means the unit cell is +too small for the order you are trying to represent. + +Diagnose it with [`transfer_spectrum`](@ref) (the leading transfer-matrix eigenvalues) or its +distilled form [`correlation_length`](@ref): + +```@example conv +ψ_gs, _, _ = find_groundstate( + InfiniteMPS(ℂ^2, ℂ^16), transverse_field_ising(; g = 2.0), + VUMPS(; tol = 1.0e-10, maxiter = 100, verbosity = 0) +) +correlation_length(ψ_gs) +``` + +```@example conv +abs.(transfer_spectrum(ψ_gs; num_vals = 5)) +``` + +The leading eigenvalue is `1` (a normalized state); the *gap* between it and the next +eigenvalue sets the correlation length. +When several eigenvalues sit almost at `1`, the correlation length diverges and the state is +near-degenerate. + + + +!!! tip "The fix is usually a larger unit cell" + If the transfer spectrum is near-degenerate, rebuild the initial state and the + Hamiltonian on a larger unit cell (e.g. `InfiniteMPS(fill(ℂ^2, 2), fill(ℂ^16, 2))` and a + matching two-site `InfiniteMPOHamiltonian`) and re-optimize. + The gallery example [The XXZ model](@ref "The XXZ model") walks through exactly this + diagnostic — a VUMPS run that refuses to converge, a `transferplot` revealing + near-degeneracy, and the fix of moving to a two-site unit cell. + +For extracting a physically meaningful correlation length from the finite-bond-dimension +spectrum, [`marek_gap`](@ref) implements the standard finite-entanglement-scaling gap +extrapolation. + + + +--- + +## 6. Wrong symmetry sector + +With a symmetric Hamiltonian, an MPS is confined to the symmetry sector fixed by its virtual +spaces at construction time. +The optimizer never leaves that sector, so if you build the initial state in the wrong one +you converge to the lowest state *of that sector*, not the global ground state. + +Inspect the sector content of a state through its virtual spaces: + +```@example conv +using TensorKit: sectors +L2 = 12 +H_z2 = transverse_field_ising(Z2Irrep, FiniteChain(L2); g = 0.5) +ψ_z2 = FiniteMPS(L2, Z2Space(0 => 1, 1 => 1), Z2Space(0 => 8, 1 => 8)) +collect(sectors(left_virtualspace(ψ_z2, 1))) +``` + +If the sectors present are not the ones the physics requires, rebuild the initial state with +the intended sectors in its physical and virtual spaces (see +[Using symmetries](@ref tutorial_using_symmetries) and +[Constructing states](@ref howto_states) for the `sector => dimension` syntax) before +optimizing. + + + +--- + +## 7. `leading_boundary` and time evolution + +[`leading_boundary`](@ref) reuses the same infinite-MPS optimizers ([`VUMPS`](@ref), +[`VOMPS`](@ref), [`IDMRG`](@ref), and friends) and returns the same `(ψ, envs, ϵ)` triple, so +every recipe above applies: read `ϵ`, raise `maxiter`/`tol`, grow the bond dimension, and +watch the transfer-matrix spectrum of the boundary MPS. + +For time evolution, "non-convergence" instead means accumulated error over the trajectory. +The knobs are different: + +- **Time step.** A smaller `dt` reduces the per-step integration and (for + [`make_time_mpo`](@ref) with [`WII`](@ref)/[`TaylorCluster`](@ref)) Trotter-type error. +- **Bond dimension.** Real-time evolution grows entanglement, so a fixed bond dimension + eventually cannot follow the state. + Use the two-site [`TDVP2`](@ref) (which takes a `trscheme`) or a CBE-enabled + [`TDVP`](@ref) to let the bond dimension grow during evolution. + + + +See [Time evolution](@ref howto_time_evolution) for the full time-evolution interface. + +--- + +## Where to go next + +For growing and inspecting bond dimension, the most common single fix, see +[Controlling bond dimension](@ref howto_bond_dimension). +For choosing and chaining the ground-state algorithms referenced here, see +[Ground-state algorithms](@ref howto_groundstate_algorithms). +For the reasoning behind when each algorithm applies and how they compare, see +[The algorithm landscape](@ref concept_algorithm_landscape). diff --git a/docs/src/howto/quasi_1d_geometries.md b/docs/src/howto/quasi_1d_geometries.md new file mode 100644 index 000000000..64765632f --- /dev/null +++ b/docs/src/howto/quasi_1d_geometries.md @@ -0,0 +1,157 @@ +# [Quasi-1D geometries](@id howto_quasi_1d_geometries) + +```@meta +DocTestSetup = quote + using MPSKit, MPSKitModels, TensorKit +end +``` + +MPSKit works with matrix product states, which are intrinsically one-dimensional objects. +A two-dimensional lattice can still be studied by winding it onto a single chain: the sites of the 2D lattice are placed in a linear order, and a 2D coupling becomes a (possibly long-ranged) coupling between two positions on that chain. +This is the standard "quasi-1D" or "cylinder" approach to 2D systems with tensor networks. + +This page collects recipes for building such geometries. +The lattice types and the `@mpoham` helper used here come from [MPSKitModels.jl](https://quantumkithub.github.io/MPSKitModels.jl/dev/), a companion package that supplies lattices, local operators, and ready-made model Hamiltonians. +For the underlying one-dimensional Hamiltonian construction see [Building Hamiltonians](@ref howto_hamiltonians); for the algorithms that consume the resulting operator see [Ground-state algorithms](@ref lib_groundstate). + +```@example quasi1d +using MPSKit, MPSKitModels, TensorKit +``` + +--- + +## Available lattice geometries + +MPSKitModels exposes a small family of lattice types, all subtypes of `AbstractLattice`. +The one-dimensional lattices are `FiniteChain` and `InfiniteChain`. +The genuinely two-dimensional geometries, wrapped for use on a 1D chain, are: + +- `FiniteCylinder(L, N)` and `InfiniteCylinder(L, N)` — a strip of circumference `L` rolled into a tube, so the two edges in the transverse direction are identified (periodic around the circumference). +- `FiniteStrip(L, N)` and `InfiniteStrip(L, N)` — the same rectangular patch but with *open* boundaries in the transverse direction (no wrap-around). +- `FiniteLadder(N)` and `InfiniteLadder(N)` — convenience constructors for the width-2 strip, i.e. `FiniteStrip(2, N)` / `InfiniteStrip(2, N)`. +- `FiniteHelix(L, N)` and `InfiniteHelix(L, N)` — a helical winding of the cylinder. +- `HoneycombYC(L, N)` — a honeycomb lattice on an infinite cylinder. + +For the square-lattice geometries the two integer arguments are the circumference `L` (number of sites per rung) and the total number of sites `N`; `N` must be a multiple of `L`, and it defaults to `L` (a single rung). +Constructing a lattice does not build any operator; it only fixes the geometry and the site ordering. + +```@example quasi1d +InfiniteCylinder(3) # circumference 3, one rung per unit cell +``` + +```@example quasi1d +InfiniteLadder(4) # a two-leg ladder, four sites per unit cell +``` + +!!! note + The `Finite*` variants describe a finite patch and produce a [`FiniteMPOHamiltonian`](@ref); the `Infinite*` variants describe a unit cell that repeats along the chain axis and produce an [`InfiniteMPOHamiltonian`](@ref). + Choose the pair that matches the state you intend to optimize. + +--- + +## Building a Hamiltonian on a cylinder + +The model builders in MPSKitModels accept a lattice as an optional positional argument, so switching from a chain to a cylinder is a one-word change. +Here is the transverse-field Ising model on an infinite cylinder of circumference 3: + +```@example quasi1d +H_cyl = transverse_field_ising(InfiniteCylinder(3); g = 3.0) +``` + +The result is an ordinary [`InfiniteMPOHamiltonian`](@ref) with one MPO tensor per site of the unit cell. +It is used exactly like a chain Hamiltonian: pair it with an [`InfiniteMPS`](@ref) whose unit cell has the same length and feed it to `find_groundstate` (see [Ground-state algorithms](@ref lib_groundstate)). +Because the cylinder wraps a 2D coupling onto the chain, the bond dimension required for a converged result grows quickly with the circumference; see the note at the end of this page. + + + +--- + +## Building a Hamiltonian on a ladder + +The same model builders work for a ladder: + +```@example quasi1d +H_ladder = heisenberg_XXX(InfiniteLadder(4); spin = 1 // 2) +``` + +For couplings that are not covered by a ready-made model, assemble the Hamiltonian directly with the `@mpoham` macro. +It sums single-site and two-site local operators over the vertices and bonds that the lattice reports. +The building blocks are `vertices(lattice)` (all sites) and `nearest_neighbours(lattice)` (all nearest-neighbour bonds, including the transverse rung and wrap-around bonds): + +```@example quasi1d +lat = InfiniteLadder(4) +H_manual = @mpoham sum(σᶻᶻ(){i, j} for (i, j) in nearest_neighbours(lat)) + + sum(2.0 * σˣ(){i} for i in vertices(lat)) +``` + +The `O{i, j}` syntax marks `O` as a local operator acting on sites `i` and `j`, where the indices are lattice points; `@mpoham` handles their placement on the 1D chain. +This is the two-dimensional counterpart of the manual chain construction in [Building Hamiltonians](@ref howto_hamiltonians). + +--- + +## How the 2D lattice maps onto the 1D chain + +Each 2D lattice defines a linear order on its sites through `linearize_index`, which turns a `(row, column)` coordinate into a single position along the MPS chain. +For a cylinder the sites of one rung are numbered first, then the next rung, and so on. +The rung index runs fastest: + +```@example quasi1d +cyl = InfiniteCylinder(3) +linearize_index.(collect(vertices(cyl))) +``` + +The bonds that `nearest_neighbours` returns reveal how far apart coupled sites end up on the chain. +Listing them as linear-index pairs for the same circumference-3 cylinder: + +```@example quasi1d +[linearize_index(i) => linearize_index(j) for (i, j) in nearest_neighbours(cyl)] +``` + +Two kinds of bonds appear. +Bonds along the chain axis connect a site to the corresponding site one rung over, at chain distance `L` (here `1 => 4`, `2 => 5`, `3 => 6`). +Bonds around the circumference connect neighbours within a rung; the bond that closes the ring connects the first and last site of a rung (here `3 => 1`), spanning `L - 1` sites on the chain. +This wrap-around bond is the longest-ranged coupling in the problem, and it is what makes a wider cylinder more expensive: the MPO must carry that coupling across `L - 1` sites, and the entanglement cut through the chain now spans the whole circumference. + +!!! warning "Circumference controls the cost" + The bond dimension needed for a given accuracy grows rapidly with the circumference `L`, because the entanglement across a cut scales with the length of the boundary it severs (the circumference). + Keep `L` small in exploratory runs and increase it while watching convergence. + + + +--- + +## Choosing the site ordering + +The default ordering above is not the only option: any permutation of the sites is a valid 1D chain, and a better ordering can shorten the longest-ranged bonds. +`SnakePattern` wraps a lattice together with a permutation function that maps the lattice's natural linear index to its position on the chain. +The wrapped lattice reports the same vertices and bonds, but re-indexed through the pattern. + +The example below reverses the site order within every second rung of a finite circumference-3 cylinder — a "boustrophedon" (back-and-forth) snake that keeps successive rungs adjacent: + +```@example quasi1d +finite_cyl = FiniteCylinder(3, 6) +pattern = i -> [1, 2, 3, 6, 5, 4][i] # reverse the second rung +snake = SnakePattern(finite_cyl, pattern) + +before = [linearize_index(i) => linearize_index(j) for (i, j) in nearest_neighbours(finite_cyl)] +after = [linearize_index(i) => linearize_index(j) for (i, j) in nearest_neighbours(snake)] +(before, after) +``` + +Passing `snake` to `@mpoham` (in place of `finite_cyl`) then builds the Hamiltonian in this reordered basis. +A `SnakePattern` built without a pattern, `SnakePattern(lattice)`, uses the identity ordering. + +!!! warning "Ordering helpers" + MPSKitModels also exports `backandforth_pattern` and `frontandback_pattern` as pre-built orderings for cylinders. + At the pinned MPSKitModels version these helpers did not execute for me (they index a lazy iterator), so this page shows an explicit permutation instead. + + + + Any custom permutation must be defined for every linear index that the lattice's bonds reference. + On an *infinite* lattice the nearest-neighbour bonds reach into the next unit cell, so a permutation defined only on `1:N` will error there; the finite cylinder above avoids this. + + + +```@meta +DocTestSetup = nothing +``` diff --git a/docs/src/howto/saving_loading.md b/docs/src/howto/saving_loading.md new file mode 100644 index 000000000..917d4a9ee --- /dev/null +++ b/docs/src/howto/saving_loading.md @@ -0,0 +1,142 @@ +# [Saving and loading](@id howto_saving_loading) + +The examples on this page use MPSKit.jl and TensorKit.jl. +See [Installation](@ref tutorial_installation) for how to add these packages to your environment. + +MPSKit does **not** ship its own save/load functions. +States such as [`FiniteMPS`](@ref) and [`InfiniteMPS`](@ref) are ordinary Julia objects that wrap TensorKit `TensorMap`s, so any general-purpose Julia serializer stores and restores them. +Two options cover essentially all use cases: + +- **`Serialization`** — a standard-library module, always available, no extra dependency. + Best for quick "save a result and pick it up in the next session" workflows. + Its file format is **not** guaranteed stable across Julia or package versions (see [Caveats](@ref howto_saving_loading_caveats)). +- **[JLD2.jl](https://github.com/JuliaIO/JLD2.jl)** — a widely used HDF5-compatible format with named datasets and better long-term robustness. + Recommended when you want to archive data or share files between machines. + JLD2 is a separate package you must add with `] add JLD2`. + +The runnable recipes below use `Serialization` so they execute with no extra dependency. +The JLD2 variants are shown separately and are equivalent in what they store. + +```@example saveload +using MPSKit, TensorKit +using Serialization +``` + +--- + +## 1. Save and reload a finite MPS + +[`serialize`](https://docs.julialang.org/en/v1/stdlib/Serialization/#Serialization.serialize) writes any object to a file; `deserialize` reads it back. +Here we write to a temporary path and check that the reloaded state is identical by taking the overlap `⟨ψ | ψ_loaded⟩`, which is `1` (up to rounding) when the two states coincide. + +```@example saveload +ψ = FiniteMPS(10, ℂ^2, ℂ^16) + +path = tempname() # a fresh temporary file path +serialize(path, ψ) + +ψ_loaded = deserialize(path) +abs(dot(ψ, ψ_loaded)) # ≈ 1: the reloaded state equals the original +``` + +The reloaded object is a genuine [`FiniteMPS`](@ref), ready for any further computation: + +```@example saveload +ψ_loaded isa FiniteMPS +``` + +Nothing here is specific to a *random* state — the same holds for a state returned by [`find_groundstate`](@ref) or [`timestep`](@ref). +Save the state you actually care about the moment you have it. + +## 2. Save and reload an infinite MPS + +[`InfiniteMPS`](@ref) works exactly the same way. +Because an infinite state is normalized by its gauge, the overlap check above is not the natural diagnostic; instead compare the gauged tensors directly. + +```@example saveload +ψ∞ = InfiniteMPS(ℂ^2, ℂ^16) + +path∞ = tempname() +serialize(path∞, ψ∞) + +ψ∞_loaded = deserialize(path∞) +ψ∞_loaded.AL[1] ≈ ψ∞.AL[1] # left-gauged tensors match +``` + +## 3. Store several objects together + +To keep a state alongside metadata (parameters, a description, the energy you measured), serialize a `NamedTuple` or `Dict` in one file. +This keeps everything that belongs together in a single artifact. + +```@example saveload +result = (state = ψ, χ = 16, note = "TFIM ground state") + +path_result = tempname() +serialize(path_result, result) + +back = deserialize(path_result) +back.note +``` + +```@example saveload +abs(dot(back.state, ψ)) # the embedded state round-trips too +``` + +## 4. The JLD2 variant + +[JLD2.jl](https://github.com/JuliaIO/JLD2.jl) stores objects under string keys and is the more portable choice for archival data. +Add it with `] add JLD2` first. +The following is equivalent to the `Serialization` recipes above; it is not executed here because JLD2 is not a dependency of this documentation build. + +```julia +using JLD2 + +# save one or more named objects +jldsave("state.jld2"; ψ, χ = 16, note = "TFIM ground state") + +# load them back by name +ψ_loaded = load("state.jld2", "ψ") +note = load("state.jld2", "note") +``` + +Symmetric states round-trip through JLD2 without any extra work: the `TensorMap`s carry their own symmetry sectors and vector spaces, so a state built on, e.g., `Z2Space` is restored with its full symmetry structure intact. + +--- + +## Environments + +Cached [environments](@ref concept_environments) (the objects returned by `environments`, held inside the value from [`find_groundstate`](@ref) and friends) are serializable in exactly the same way as states — they are also just tensors. +In practice, however, **it is usually not worth saving them**: environments are derived data, tied to one specific state, and recomputing them from a stored state is cheap compared to the optimization that produced the state. + +The recommended workflow is therefore to save only the *state* and rebuild the environments after loading: + +```@example saveload +using MPSKitModels # for the Hamiltonian +H = transverse_field_ising(FiniteChain(10)) + +envs = environments(ψ_loaded, H, ψ_loaded) # rebuilt from the reloaded state +nothing # hide +``` + + + +If you do have a reason to persist environments (e.g. to resume an expensive iterative build), `serialize`/`deserialize` them just like a state. + +## [Caveats](@id howto_saving_loading_caveats) + +- **Version compatibility.** + `Serialization` files are **not** guaranteed to be readable by a different Julia version, nor after MPSKit or TensorKit change their internal type layout. + Treat `Serialization` output as a scratch artifact within one environment; use **JLD2** for anything you need to reopen weeks later or on another machine. + + +- **Symmetric tensors are self-describing.** + A saved state carries the vector spaces and symmetry sectors of every tensor, so you do not need to record the symmetry separately — loading reconstructs the full space structure. + This was verified for a `Z2`-symmetric state round-tripping through both `Serialization` and JLD2. + +- **File size.** + A stored state is roughly the size of its tensors, which grows with the bond dimension (and, for symmetric states, the sector structure). + For large-bond-dimension states these files can be substantial; write them to scratch/bulk storage rather than a quota-limited home directory, and consider saving only the final state rather than every intermediate. + +- **What to save.** + Prefer saving the state (and the parameters needed to rebuild its Hamiltonian) over saving derived caches like environments. + A state plus its model definition is enough to reconstruct everything else. diff --git a/docs/src/howto/statmech.md b/docs/src/howto/statmech.md new file mode 100644 index 000000000..3d850316e --- /dev/null +++ b/docs/src/howto/statmech.md @@ -0,0 +1,169 @@ +# [Statistical mechanics](@id howto_statmech) + +```@meta +DocTestSetup = quote + using MPSKit, MPSKitModels, TensorKit +end +``` + +This page collects recipes for the *boundary-MPS* (transfer-matrix) approach to two-dimensional classical statistical mechanics. +The partition function of a classical lattice model is written as a contraction of a two-dimensional tensor network, one row of which is an [`InfiniteMPO`](@ref) — the *transfer matrix*. +Contracting the network in the thermodynamic limit amounts to finding the leading eigenvector of that transfer matrix, which MPSKit approximates by an [`InfiniteMPS`](@ref) via [`leading_boundary`](@ref). + +The examples on this page use MPSKit.jl, MPSKitModels.jl, and TensorKit.jl. +See [Installation](@ref tutorial_installation) for how to add these packages to your environment. + +```@example statmech +using MPSKit, MPSKitModels, TensorKit +``` + +For the structure of MPOs see [Operators and Hamiltonians](@ref concept_operators_and_hamiltonians). +For a full worked case using anyonic symmetries, see the gallery example [The Hard Hexagon model](@ref "The Hard Hexagon model"). + +--- + +## 1. Build the transfer matrix + +MPSKitModels ships ready-made transfer-matrix MPOs for several classical models. +The two-dimensional classical Ising model is provided by `classical_ising`; other options include `sixvertex` and `hard_hexagon`. + +```@example statmech +mpo = classical_ising() +``` + +The returned object is an `InfiniteMPO` with a single-site unit cell: one tensor whose four legs are the two horizontal (virtual) and two vertical (physical) bonds of the Boltzmann-weight tensor. +Its physical space is read off with `physicalspace`: + +```@example statmech +P = physicalspace(mpo, 1) +``` + +By default `classical_ising` uses the inverse temperature `beta = log(1 + sqrt(2)) / 2`. + + + +--- + +## 2. Find the leading boundary MPS + +[`leading_boundary`](@ref) approximates the dominant eigenvector of the transfer matrix by an `InfiniteMPS`. +Supply an initial guess with a chosen bond dimension and an optimization algorithm — [`VUMPS`](@ref) is the usual choice. + +The transfer matrix of a classical model is generally **not Hermitian**, so pass a non-Hermitian eigensolver to `VUMPS`: + +```@example statmech +alg = VUMPS(; + verbosity = 0, + alg_eigsolve = MPSKit.Defaults.alg_eigsolve(; ishermitian = false), +) + +ψ₀ = InfiniteMPS([P], [ℂ^16]) # initial guess, bond dimension 16 +ψ, envs, ϵ = leading_boundary(ψ₀, mpo, alg) +ϵ # final convergence error +``` + +`leading_boundary` returns a triple `(ψ, environments, ϵ)`: the converged boundary MPS, its environment manager, and the final convergence error. +Reuse the returned `envs` in subsequent calls to avoid recomputing environments. + +!!! note + The initial guess sets the bond dimension `D` of the boundary MPS. + A larger `D` gives a better approximation of the leading eigenvector; near a critical point the accessible correlation length grows with `D` (see [Controlling bond dimension](@ref howto_bond_dimension) for growing `D` on the fly). + +--- + +## 3. Free energy and partition function per site + +The expectation value of the transfer matrix in the converged boundary MPS is the partition function per site ``\Lambda = \mathcal{Z}^{1/N}`` in the thermodynamic limit: + +```@example statmech +Λ = expectation_value(ψ, mpo) +``` + +For a Hermitian-normalised model the imaginary part is zero up to floating-point noise. +The free energy per site follows from ``f = -\tfrac{1}{\beta}\log\Lambda``: + +```@example statmech +β = log(1 + sqrt(2)) / 2 +f = -1 / β * log(real(Λ)) +``` + + + +--- + +## 4. Correlation length and entanglement entropy + +The boundary MPS encodes the correlations of the two-dimensional system. +[`correlation_length`](@ref) returns the (largest) correlation length of the transfer matrix, and [`entropy`](@ref) the entanglement entropy of the boundary MPS across a virtual bond: + +```@example statmech +ξ = correlation_length(ψ) +``` + +```@example statmech +S = real(first(entropy(ψ))) +``` + +At a critical point the true correlation length diverges; the finite bond dimension of the boundary MPS cuts it off at a finite value that grows with `D`. +This finite-entanglement scaling of `S` against `log(ξ)` is exactly what the gallery example [The Hard Hexagon model](@ref "The Hard Hexagon model") exploits to extract a central charge. + + + +--- + +## 5. Symmetric transfer matrices + +When the classical model has a global symmetry, the transfer matrix can be built from symmetric tensors, which makes the boundary computation cheaper and more stable. +`classical_ising` accepts a symmetry type; the ``\mathbb{Z}_2`` spin-flip symmetry gives a `Z2Irrep`-graded MPO: + +```@example statmech +mpo_z2 = classical_ising(Z2Irrep) +P_z2 = physicalspace(mpo_z2, 1) +``` + +The workflow is identical — only the virtual space of the initial guess is now a graded space: + +```@example statmech +V_z2 = Z2Space(0 => 8, 1 => 8) +ψ_z2, = leading_boundary(InfiniteMPS([P_z2], [V_z2]), mpo_z2, alg) +real(expectation_value(ψ_z2, mpo_z2)) +``` + +For anyonic (non-invertible) symmetries the same recipe applies with a `Vect[FibonacciAnyon]` virtual space — this is the case worked out in [The Hard Hexagon model](@ref "The Hard Hexagon model"). +See [Symmetries](@ref concept_symmetries) for how to choose graded spaces. + +--- + +## 6. Multi-row unit cells + +If the transfer matrix has a unit cell spanning several rows, the boundary object becomes a [`MultilineMPS`](@ref) and the operator a [`MultilineMPO`](@ref). +`repeat` stacks copies of a single-row MPO into a multi-row transfer matrix: + +```@example statmech +mmpo = repeat(mpo, 2, 1) # 2 rows × 1 column +``` + +Build a `MultilineMPS` with one `InfiniteMPS` per row and call `leading_boundary` exactly as before; the returned environments are a `MultilineEnvironments`: + +```@example statmech +mψ = MultilineMPS([InfiniteMPS([P], [ℂ^12]), InfiniteMPS([P], [ℂ^12])]) +mψ, menvs, = leading_boundary(mψ, mmpo, alg) +real(expectation_value(mψ, mmpo)) +``` + +The `expectation_value` of a multi-row transfer matrix is the product of the per-site weights over the rows of the unit cell; divide `log` of it by the number of rows to recover the per-site free energy. + + + +--- + +## See also + +- [The Hard Hexagon model](@ref "The Hard Hexagon model") — a full worked study (central charge from finite-entanglement scaling) using an anyonic transfer matrix. +- [Operators and Hamiltonians](@ref concept_operators_and_hamiltonians) — MPO structure and construction. +- [Controlling bond dimension](@ref howto_bond_dimension) — growing the boundary-MPS bond dimension. +- [Computing observables](@ref howto_observables) — `expectation_value`, `correlation_length`, and related tools. + +```@meta +DocTestSetup = nothing +``` diff --git a/docs/src/lib/environments.md b/docs/src/lib/environments.md new file mode 100644 index 000000000..98ccf7720 --- /dev/null +++ b/docs/src/lib/environments.md @@ -0,0 +1,34 @@ +# [Environments](@id lib_environments) + +Reference for MPSKit's environment machinery — the caches that store the partially contracted tensor networks reused throughout the algorithms. +For an explanation of what environments are and why they exist see the concept page on [Environments](@ref concept_environments); this page only lists the API. +The full, canonical docstrings for the whole package live in the [Library](@ref lib_index) index. + +```@meta +CurrentModule = MPSKit +``` + +## Constructing environments + +```@docs; canonical=false +environments +``` + +## Querying environments + +```@docs; canonical=false +leftenv +rightenv +``` + +## Environment types + +The concrete environment types below are returned by [`environments`](@ref) and are managed automatically by the algorithms. +They are implementation details — you normally obtain them from `environments` rather than constructing them directly — and are not part of the public API. + +```@docs; canonical=false +AbstractMPSEnvironments +FiniteEnvironments +InfiniteEnvironments +InfiniteQPEnvironments +``` diff --git a/docs/src/lib/internals.md b/docs/src/lib/internals.md new file mode 100644 index 000000000..ba9402633 --- /dev/null +++ b/docs/src/lib/internals.md @@ -0,0 +1,53 @@ +# [Internals](@id lib_internals) + +!!! warning "Non-public API" + The symbols documented on this page are **internal**: they are unexported, not + part of the public API, and may change or be removed in any release without notice + or a deprecation cycle. They are collected here as a reference for contributors and + advanced users reading the source, not as a stable interface to build on. For the + supported surface see the [Public API](@ref public_api). Experimental features (for + example the current GPU support, discussed in [Parallelism and GPU support](@ref howto_parallelism_gpu)) are + likewise unstable and subject to change. + +```@meta +CurrentModule = MPSKit +``` + +## Effective (derivative) operators + +The local eigenvalue and time-evolution problems solved by DMRG, VUMPS, TDVP and friends are phrased in terms of effective "derivative" operators acting on a single gauge tensor. +These are built internally from the Hamiltonian and the surrounding [environments](@ref lib_environments). + +```@docs; canonical=false +DerivativeOperator +C_hamiltonian +AC_hamiltonian +AC2_hamiltonian +``` + +## Transfer matrices + +Low-level application of (regularized) transfer matrices to boundary vectors, used when building infinite-MPS environments. + +```@docs; canonical=false +transfer_left +transfer_right +``` + +## Environment algorithm resolution + +Helpers that pick and instantiate the iterative solver used to compute environments for a given bra/operator/ket combination. + +```@docs; canonical=false +environment_alg +resolve_environment_solver +``` + +## Defaults and scheduling + +Global configuration lives in the `MPSKit.Defaults` submodule, including the multi-threading scheduler used across the package. + +```@docs +Defaults +Defaults.set_scheduler! +``` diff --git a/docs/src/migration.md b/docs/src/migration.md new file mode 100644 index 000000000..1ab0cc2bd --- /dev/null +++ b/docs/src/migration.md @@ -0,0 +1,51 @@ +# Migration guide + +This page collects notes for upgrading between MPSKit releases when a change requires action +on your side. +It summarizes the breaking changes recorded in the [Changelog](@ref); consult that page for +the complete, per-version list of changes. + +## Unreleased + +### `environments` now uses a single positional contract + +[`environments`](@ref) now follows one positional contract for every state and operator kind: + +``` +environments(below, operator, above, alg) +``` + +where `alg` (slot 4) is the environment algorithm. +The operator form requires an explicit `above` argument. +Auxiliary inputs are now keyword-only: `leftstart`/`rightstart` for finite and window +environments, and `lenvs`/`renvs` for window and quasiparticle environments. + +The two-argument form `environments(below, above)` (two states) is reserved for the +operator-free overlap environments. +There is no two-argument `environments(below, operator)` shorthand: a two-argument call is +always interpreted as an overlap, because the second argument cannot be disambiguated between +a ket and an operator (this is undecidable for density matrices, where states and operators +share a representation). +If you previously relied on a two-argument operator call, pass the operator explicitly with an +`above` state. +See [#436](https://github.com/QuantumKitHub/MPSKit.jl/pull/436). + + + +## Earlier releases + +The [Changelog](@ref) records further changes across the 0.13.x series, including a refactor +of the `IDMRG` implementation to the `IterativeSolver` interface +([#348](https://github.com/QuantumKitHub/MPSKit.jl/pull/348)), fixes to `changebonds` +consistency ([#415](https://github.com/QuantumKitHub/MPSKit.jl/pull/415)), and a refactor of +time-evolution MPO construction +([#422](https://github.com/QuantumKitHub/MPSKit.jl/pull/422)). + + From 388208dfc7bb475e3c61d5aa46ddeb734d3f2515 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Sat, 11 Jul 2026 13:23:56 -0400 Subject: [PATCH 71/76] docs: resolve maintainer REVIEW flags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - accept textbook-fact claims (D³ cost, area law, finite-entanglement scaling, SU(2) multiplet-reduction payoff) and clear their flags; clear the remaining source-verified wording flags across numerics, convergence, finite_vs_infinite, symmetries, statmech, saving_loading - migration.md kept as a scaffold (changelog pointer); citing.md flags cleared - SU(3) example reframed off the gap: retitled "The SU(3) Heisenberg chain" and explains the dispersion is not a variational bound because the ground state is not converged tightly enough; regenerated via examples/make.jl - quasi_1d: document backandforth_pattern/frontandback_pattern as broken at MPSKitModels v0.4.7 (closure indexes a lazy iterator) plus the infinite-cylinder periodic-wrap caveat - keep the two forward-looking TODO comments (index benchmark, excitations example) Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/src/citing.md | 23 +----- docs/src/concepts/finite_vs_infinite.md | 2 - docs/src/concepts/numerics.md | 15 ---- docs/src/concepts/symmetries.md | 6 -- .../excitations/1.su3-heisenberg/index.md | 79 +++++++------------ .../excitations/1.su3-heisenberg/main.ipynb | 66 +++++++--------- docs/src/examples/index.md | 2 +- docs/src/howto/convergence_troubleshooting.md | 44 ----------- docs/src/howto/quasi_1d_geometries.md | 17 ++-- docs/src/howto/saving_loading.md | 3 - docs/src/howto/statmech.md | 8 -- docs/src/migration.md | 11 --- examples/Cache.toml | 2 +- examples/excitations/1.su3-heisenberg/main.jl | 68 +++++++--------- 14 files changed, 95 insertions(+), 251 deletions(-) diff --git a/docs/src/citing.md b/docs/src/citing.md index 0f517735f..dcd14251a 100644 --- a/docs/src/citing.md +++ b/docs/src/citing.md @@ -25,27 +25,8 @@ A ready-to-use BibTeX entry: } ``` - - ## Citing the underlying methods MPSKit implements algorithms developed in the tensor-network literature. -When a specific method is central to your results, please also cite the original method paper. -Some of the key references, all included in the [References](@ref) bibliography, are: - -- **DMRG / tangent-space methods** — [vanderstraeten2019](@cite), a review of tangent-space methods for uniform matrix product states. -- **VUMPS** — [zauner-stauber2018](@cite), variational optimization algorithms for uniform matrix product states. -- **TDVP (time evolution)** — [haegeman2011](@cite), the time-dependent variational principle for quantum lattices. -- **Quasiparticle excitations** — [haegeman2013](@cite), elementary excitations in gapped quantum spin systems. - - - -The full bibliography, including works that have used MPSKit, is on the [References](@ref) page. +When a specific method is central to your results, please also consider citing the original method papers. +Some of the key references of the algorithms in this library are included in the [References](@ref) page. diff --git a/docs/src/concepts/finite_vs_infinite.md b/docs/src/concepts/finite_vs_infinite.md index 2c4fccecb..99de33e2e 100644 --- a/docs/src/concepts/finite_vs_infinite.md +++ b/docs/src/concepts/finite_vs_infinite.md @@ -43,7 +43,6 @@ length(ψ_cell) The unit-cell length is not a free accuracy knob like the bond dimension; it is a physical statement about the *period* of the state you intend to represent. A translation-invariant ansatz of period `L` can only capture states whose own spatial period divides `L`. - Choosing a cell that is commensurate with the physical period of the model — the magnetic period of an ordered phase, or a period imposed by the Hamiltonian's own unit cell — is therefore a modelling decision, not a numerical one, and picking too small a cell forces the algorithm to approximate a state it structurally cannot represent. A [`FiniteMPS`](@ref), by contrast, has no notion of a unit cell at all: its `length` is simply the number of physical sites, and each of those sites carries its own independent tensor. @@ -66,7 +65,6 @@ norm(3 * ψ_finite) For an [`InfiniteMPS`](@ref) that same quantity does not exist. The overlap `⟨ψ|ψ⟩` of an infinite state is, formally, a product of one transfer-matrix factor per unit cell, so for a chain of `n` cells it grows (or decays) like `λⁿ`, where `λ` is the leading eigenvalue of the transfer matrix. As `n → ∞` this is `0` if `λ < 1` and `∞` if `λ > 1`, and the *only* value that yields a finite, well-defined state is `λ = 1`. - MPSKit therefore fixes the gauge so that the transfer matrix has leading eigenvalue exactly one, which we can read straight off its spectrum: ```@example finite-infinite diff --git a/docs/src/concepts/numerics.md b/docs/src/concepts/numerics.md index a410b518a..dac47e3d9 100644 --- a/docs/src/concepts/numerics.md +++ b/docs/src/concepts/numerics.md @@ -48,11 +48,9 @@ Performing that truncation with [`SvdCut`](@ref) through [`changebonds`](@ref) a ``` The bond dimension is thus a genuine accuracy/cost dial: a larger bond dimension lowers the discarded weight and the truncation error, at the price of more expensive tensor contractions. - How much bond dimension a state actually *needs* is set by its entanglement. Ground states of gapped, local one-dimensional Hamiltonians obey an entanglement *area law* — their bipartite entanglement entropy saturates to a constant as the system grows — which is precisely why a finite bond dimension can represent them efficiently; at a critical point the entropy instead grows without bound and no fixed bond dimension suffices. - ### Choosing what to truncate @@ -68,8 +66,6 @@ The ones you will meet most often are: These schemes compose with `&`, so `trunctol(; atol = 1e-8) & truncrank(16)` applies both bounds at once. - - Every bond-growing algorithm — [`DMRG2`](@ref), [`IDMRG2`](@ref), [`TDVP2`](@ref) — and every explicit bond-surgery tool — [`SvdCut`](@ref), [`OptimalExpand`](@ref) — requires a `trscheme` keyword, because their whole job is to decide a new bond dimension. The single-site workhorses ([`DMRG`](@ref), [`VUMPS`](@ref), [`TDVP`](@ref)) default to `notrunc()` and keep the bond dimension fixed. The recipes for growing and shrinking bonds live in [Controlling bond dimension](@ref howto_bond_dimension). @@ -95,14 +91,11 @@ MPSKit.Defaults.tol Not every algorithm reports the same measure, and the differences matter when comparing runs: - The two-site [`DMRG2`](@ref) does not use the Galerkin error during its sweep; it monitors instead the local infidelity between each two-site tensor before and after truncation, which is a different — and generally less directly interpretable — proxy for convergence. - - [`IDMRG`](@ref) and [`IDMRG2`](@ref) judge convergence by the change in the bond matrix between successive iterations, ``\lVert C - C_\text{old}\rVert``, rather than by a gradient norm. - - [`GradientGrassmann`](@ref) converges on the Riemannian gradient norm reported by its underlying optimizer, with `tol` passed through as the gradient tolerance. A subtlety worth knowing is that these tolerances are, by default, *dynamic*: MPSKit tightens the tolerances of the inner linear and eigenvalue solvers as the outer iteration converges, so that early iterations are not over-solved and late ones are not under-solved. This adaptive behavior is on by default (`dynamic_tols = true` in `Defaults`) and is why the inner solvers do not simply run at the outer `tol` from the first sweep. - The Galerkin error certifies that the algorithm reached a fixed point of *its own* update, which is necessary but not sufficient for the state to be a good eigenstate. An independent check is the energy [`variance`](@ref) ``\langle H^2\rangle - \langle H\rangle^2``, which vanishes exactly for a true eigenstate and does not rely on the ansatz's tangent space: @@ -111,8 +104,6 @@ An independent check is the energy [`variance`](@ref) ``\langle H^2\rangle - \la variance(ψ, H, envs) ``` - - ## Precision and the element type Underneath the tensors is an ordinary floating-point element type, and by default it is complex double precision, `ComplexF64`. @@ -123,12 +114,10 @@ scalartype(FiniteMPS(16, ℂ^2, ℂ^24)) ``` Double precision is the right default: at `Float64` the relative rounding error is about ``10^{-16}``, comfortably below the `1e-10` convergence tolerance, so floating-point noise is rarely what limits an MPSKit result — truncation and incomplete convergence dominate long before precision does. - The choice between a real and a complex element type is occasionally load-bearing rather than cosmetic. Real-time evolution and the ``W^{II}`` time-evolution MPO intrinsically require complex arithmetic, so a real-valued state must be promoted before it can be evolved; MPSKit provides `Base.complex` on an MPS for exactly this, and it is a no-op when the state is already complex. Conversely, a purely real problem — a real Hamiltonian with a real ground state — can in principle be run in `Float64` to save memory and time, but this is an optimization to reach for deliberately, not the default. - ## Common pitfalls @@ -141,25 +130,21 @@ This is aggravated by the single-site algorithms, which cannot enlarge the bond **Local minima.** The variational optimization is non-convex, and an algorithm can settle into a state that is a fixed point of its update but not the global ground state. The single-site methods are more prone to this than bond-growing ones, which is part of why a two-site warm-up (or a gradient-descent polishing stage, chained with `&`) is often used before or after a single-site run. - **Symmetry-sector trapping.** When the state carries a conserved quantum number, the optimization runs within a fixed set of symmetry sectors on each bond. If the true ground state lives in a sector distribution the initial state does not span, the algorithm converges — cleanly, by its own criterion — to the best state in the *wrong* variational space. This is a sharper, symmetry-specific version of the too-small-bond-dimension trap, and it is why the sector structure of the initial state matters. - **Non-injectivity and a near-degenerate transfer matrix (infinite systems).** [`VUMPS`](@ref) assumes a unique, injective fixed point. When the state it should converge to is non-injective — for instance a cat state superposing symmetry-broken sectors, or a genuinely degenerate ground space — the transfer matrix has more than one eigenvalue of magnitude one, and the algorithm has no well-defined single fixed point to find. MPSKit's [`correlation_length`](@ref) machinery detects this: it is computed from the gap between the leading and next-to-leading transfer-matrix eigenvalues (the correlation length is the inverse of that gap), and [`transfer_spectrum`](@ref) exposes the spectrum directly. Internally the routine emits a `"Non-injective mps?"` warning when it finds more than one eigenvalue near magnitude one at the same complex angle — a heuristic flag, not a hard error, so it is worth watching for. - **Finite-entanglement effects at criticality.** At or near a critical point the true correlation length diverges, but a finite bond dimension can only support a finite correlation length, so the simulated correlation length saturates at a value set by the bond dimension rather than by the physics. Extracting critical data therefore requires studying how results drift as the bond dimension grows, rather than trusting any single bond dimension. - ## Where to go next diff --git a/docs/src/concepts/symmetries.md b/docs/src/concepts/symmetries.md index 78849f6ee..bcc27e7b0 100644 --- a/docs/src/concepts/symmetries.md +++ b/docs/src/concepts/symmetries.md @@ -94,7 +94,6 @@ At the far end of this spectrum, `quantum_chemistry_hamiltonian` does not expose The generality goes further than groups. Sectors such as `FibonacciAnyon` or `IsingAnyon` are not group representations at all — their fusion rules come from a modular tensor category — yet because every MPSKit algorithm is written against the abstract `Sector` interface, they are handled by exactly the same code paths, with no special-casing. The [hard-hexagon model](@ref "The Hard Hexagon model") example puts this to work: its transfer matrix is built from `FibonacciAnyon`-graded tensors (`Vect[FibonacciAnyon](:I => …, :τ => …)`), and the standard statistical-mechanics workflow computes its partition function just as it would for an ordinary symmetry. - ## When does SU(2) pay off @@ -120,15 +119,10 @@ The total dimension `dim(V_SU2)` is `10`, because each spin-``j`` sector contrib But `dim(V_SU2, c)` returns the *stored* multiplicity of each sector — here `[2, 4]`, just six numbers in total — because the ``(2j+1)`` internal structure of every multiplet is fixed by representation theory and never stored. For an abelian symmetry the two coincide (every irrep is one-dimensional, so the multiplicities and the total dimension agree, as with the U(1) space above); it is precisely for a non-abelian group that the stored count falls below the physical dimension. - - The gap between the physical dimension (`10`) and the six numbers actually stored is the source of SU(2)'s reputation for letting DMRG reach much larger effective bond dimensions at the same computational cost — the same principle used to push non-abelian symmetric uniform MPS to large SU(3) bond dimensions in practice [devos2022](@cite). - - None of this is free. Every symmetric block carries the overhead of tracking fusion trees and recombining Clebsch–Gordan coefficients whenever legs are permuted or contracted, and for a non-abelian group this bookkeeping is genuinely more expensive per block than for an abelian one. - In practice this means SU(2) (or any non-abelian symmetry) is worth reaching for when the physics genuinely has that symmetry — a spin chain with full rotational invariance, for instance — and when the bond dimension is large enough that the multiplet-reduction saving dominates the per-block overhead; for small bond dimensions, or for a symmetry the Hamiltonian does not actually have, the abelian or even trivial case is often simpler and just as fast. ## Fixing the total charge diff --git a/docs/src/examples/excitations/1.su3-heisenberg/index.md b/docs/src/examples/excitations/1.su3-heisenberg/index.md index d995a1103..21d067a47 100644 --- a/docs/src/examples/excitations/1.su3-heisenberg/index.md +++ b/docs/src/examples/excitations/1.su3-heisenberg/index.md @@ -6,7 +6,7 @@ EditURL = "../../../../../examples/excitations/1.su3-heisenberg/main.jl" [![](https://img.shields.io/badge/show-nbviewer-579ACA.svg)](https://nbviewer.jupyter.org/github/QuantumKitHub/MPSKit.jl/blob/gh-pages/dev/examples/excitations/1.su3-heisenberg/main.ipynb) [![](https://img.shields.io/badge/download-project-orange)](https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/QuantumKitHub/MPSKit.jl/examples/tree/gh-pages/dev/examples/excitations/1.su3-heisenberg) -# The SU(3) Haldane gap +# The SU(3) Heisenberg chain The spin-1 Heisenberg chain famously has a gapped, symmetry-protected topological ground state: the Haldane phase. @@ -24,11 +24,10 @@ H = J \sum_{\langle i, j \rangle} \sum_{a=1}^{8} T^a_i T^a_j , where the ``T^a`` are the eight generators of ``SU(3)``. This is the direct analog of the spin-1 chain, with the three generators of ``SU(2)`` replaced by the eight generators of ``SU(3)``. - - +The goal of this example is to exercise the full ``SU(N)`` toolchain end to end — building the +symmetric Hamiltonian, optimizing a uniform ground state with VUMPS, and scanning an +excitation dispersion — rather than to pin down the model's (very small) gap to high accuracy; +we return to that point in the closing discussion. Working with the full non-abelian ``SU(3)`` symmetry is what makes this tractable. Just as ``SU(2)`` symmetry drastically shrinks the spin-1 problem (see @@ -54,17 +53,6 @@ using MPSKit using Plots ```` -```` -Precompiling packages... - 1277.5 ms ✓ SparseArrayKit - 7318.1 ms ✓ SUNRepresentations - 2 dependencies successfully precompiled in 10 seconds. 62 already precompiled. -Precompiling packages... - 2203.1 ms ✓ SparseArrayKit → SparseArrayKitSparseArrays - 1 dependency successfully precompiled in 2 seconds. 20 already precompiled. - -```` - For reproducibility of this page, we fix the seed of the random number generator: ````julia @@ -169,12 +157,7 @@ bonds, so every virtual space must sit in a single congruency class; here we use class ``0``, which we found to give the lowest variational energy. Following [devos2022](@cite), we seed the optimization with a random ``SU(3)``-symmetric uniform state and optimize with VUMPS. - - +The bond dimension is kept deliberately modest here so that the page builds quickly. ````julia Vvirt = Vect[SU3Irrep]( @@ -202,16 +185,12 @@ ground-state energy per site: E₀ = -2.573505652431292 ## The excitation spectrum -Excitations above the ground state are computed with the quasiparticle ansatz. +On top of the ground state we compute excitations with the quasiparticle ansatz. In the thermodynamic limit each excitation carries a definite momentum ``k`` and a definite -``SU(3)`` charge; reference [devos2022](@cite) reports that the lowest branch — whose minimum -is the Haldane gap — lives in the adjoint ``[2\,1\,0]`` sector, with its minimum at momentum -``k = 2\pi/3``. -We scan this branch across half of the Brillouin zone (the other half follows by reflection). - - +``SU(3)`` charge. +Following [devos2022](@cite), we look in the adjoint ``[2\,1\,0]`` sector, where that reference +finds the lowest branch, and scan across half of the Brillouin zone (the other half follows by +reflection). ````julia sector = SU3Irrep(2, 1, 0) @@ -250,24 +229,24 @@ vline!([2π / 3]; color = :gray, linestyle = :dot, label = "k = 2π/3") ![](figure-1.png) The branch has a pronounced soft mode at ``k = 2\pi/3``, exactly the momentum at which -[devos2022](@cite) locates the Haldane gap. -That reference reports a gap of ``\Delta / J = 0.0263`` there. - -This value is *very* small, and reproducing it faithfully is demanding: it requires a -carefully converged, large-bond-dimension uniform ``SU(3)`` MPS. -The lightweight calculation here — a modest virtual space chosen so the page builds quickly — -resolves the *location* of the soft mode but not the tiny gap itself: near ``k = 2\pi/3`` the -computed branch comes out close to zero and can even dip slightly negative, a sign that the -uniform ground state is not converged to the accuracy needed to pin down a gap this small. - - +[devos2022](@cite) locates the minimum of the dispersion, where that reference reports a gap +of ``\Delta / J = 0.0263``. + +The soft-mode *location* is reproduced cleanly, but the gap *value* is not, and it is worth +being precise about why. +The quasiparticle energies plotted above are a genuine variational upper bound on the +excitation energies only when they are measured relative to the *exact* ground state. +Here the ground state is a deliberately lightweight, modest-bond-dimension uniform ``SU(3)`` +MPS, and for this near-critical model it is not converged to that accuracy. +Because the reference state sits slightly too high in energy, the ansatz can find "excitations" +that lie below it, so near ``k = 2\pi/3`` the computed branch drops to essentially zero and even +slightly negative. +The dispersion here is therefore *not* a variational estimate of the true gap: the small value +``\Delta / J = 0.0263`` is quoted from [devos2022](@cite) and would require a carefully +converged, large-bond-dimension calculation to reproduce. +What this example does show is the complete ``SU(3)``-symmetric workflow — Hamiltonian +construction, VUMPS ground state, and a momentum-resolved excitation scan — with the soft mode +correctly located at ``k = 2\pi/3``. --- diff --git a/docs/src/examples/excitations/1.su3-heisenberg/main.ipynb b/docs/src/examples/excitations/1.su3-heisenberg/main.ipynb index ce642adf7..5989a95f6 100644 --- a/docs/src/examples/excitations/1.su3-heisenberg/main.ipynb +++ b/docs/src/examples/excitations/1.su3-heisenberg/main.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# The SU(3) Haldane gap\n", + "# The SU(3) Heisenberg chain\n", "\n", "The spin-1 Heisenberg chain famously has a gapped, symmetry-protected topological ground\n", "state: the Haldane phase.\n", @@ -22,11 +22,10 @@ "where the $T^a$ are the eight generators of $SU(3)$.\n", "This is the direct analog of the spin-1 chain, with the three generators of $SU(2)$\n", "replaced by the eight generators of $SU(3)$.\n", - "\n", - "\n", + "The goal of this example is to exercise the full $SU(N)$ toolchain end to end — building the\n", + "symmetric Hamiltonian, optimizing a uniform ground state with VUMPS, and scanning an\n", + "excitation dispersion — rather than to pin down the model's (very small) gap to high accuracy;\n", + "we return to that point in the closing discussion.\n", "\n", "Working with the full non-abelian $SU(3)$ symmetry is what makes this tractable.\n", "Just as $SU(2)$ symmetry drastically shrinks the spin-1 problem (see\n", @@ -191,12 +190,7 @@ "class $0$, which we found to give the lowest variational energy.\n", "Following [devos2022](@cite), we seed the optimization with a random $SU(3)$-symmetric\n", "uniform state and optimize with VUMPS.\n", - "\n", - "" + "The bond dimension is kept deliberately modest here so that the page builds quickly." ] }, { @@ -226,16 +220,12 @@ "source": [ "## The excitation spectrum\n", "\n", - "Excitations above the ground state are computed with the quasiparticle ansatz.\n", + "On top of the ground state we compute excitations with the quasiparticle ansatz.\n", "In the thermodynamic limit each excitation carries a definite momentum $k$ and a definite\n", - "$SU(3)$ charge; reference [devos2022](@cite) reports that the lowest branch — whose minimum\n", - "is the Haldane gap — lives in the adjoint $[2\\,1\\,0]$ sector, with its minimum at momentum\n", - "$k = 2\\pi/3$.\n", - "We scan this branch across half of the Brillouin zone (the other half follows by reflection).\n", - "\n", - "" + "$SU(3)$ charge.\n", + "Following [devos2022](@cite), we look in the adjoint $[2\\,1\\,0]$ sector, where that reference\n", + "finds the lowest branch, and scan across half of the Brillouin zone (the other half follows by\n", + "reflection)." ] }, { @@ -264,24 +254,24 @@ "metadata": {}, "source": [ "The branch has a pronounced soft mode at $k = 2\\pi/3$, exactly the momentum at which\n", - "[devos2022](@cite) locates the Haldane gap.\n", - "That reference reports a gap of $\\Delta / J = 0.0263$ there.\n", - "\n", - "This value is *very* small, and reproducing it faithfully is demanding: it requires a\n", - "carefully converged, large-bond-dimension uniform $SU(3)$ MPS.\n", - "The lightweight calculation here — a modest virtual space chosen so the page builds quickly —\n", - "resolves the *location* of the soft mode but not the tiny gap itself: near $k = 2\\pi/3$ the\n", - "computed branch comes out close to zero and can even dip slightly negative, a sign that the\n", - "uniform ground state is not converged to the accuracy needed to pin down a gap this small.\n", + "[devos2022](@cite) locates the minimum of the dispersion, where that reference reports a gap\n", + "of $\\Delta / J = 0.0263$.\n", "\n", - "" + "The soft-mode *location* is reproduced cleanly, but the gap *value* is not, and it is worth\n", + "being precise about why.\n", + "The quasiparticle energies plotted above are a genuine variational upper bound on the\n", + "excitation energies only when they are measured relative to the *exact* ground state.\n", + "Here the ground state is a deliberately lightweight, modest-bond-dimension uniform $SU(3)$\n", + "MPS, and for this near-critical model it is not converged to that accuracy.\n", + "Because the reference state sits slightly too high in energy, the ansatz can find \"excitations\"\n", + "that lie below it, so near $k = 2\\pi/3$ the computed branch drops to essentially zero and even\n", + "slightly negative.\n", + "The dispersion here is therefore *not* a variational estimate of the true gap: the small value\n", + "$\\Delta / J = 0.0263$ is quoted from [devos2022](@cite) and would require a carefully\n", + "converged, large-bond-dimension calculation to reproduce.\n", + "What this example does show is the complete $SU(3)$-symmetric workflow — Hamiltonian\n", + "construction, VUMPS ground state, and a momentum-resolved excitation scan — with the soft mode\n", + "correctly located at $k = 2\\pi/3$." ] }, { diff --git a/docs/src/examples/index.md b/docs/src/examples/index.md index 4e4579df5..a88b9368c 100644 --- a/docs/src/examples/index.md +++ b/docs/src/examples/index.md @@ -67,7 +67,7 @@ Computes the Haldane gap of the spin-1 Heisenberg antiferromagnet in two complem Introduces `SU2Irrep`/`SU2Space` symmetric tensors for both `FiniteMPS` and `InfiniteMPS`. **Level: intermediate.** -### [The SU(3) Haldane gap](excitations/1.su3-heisenberg/index.md) +### [The SU(3) Heisenberg chain](excitations/1.su3-heisenberg/index.md) ![](excitations/1.su3-heisenberg/figure-1.png) diff --git a/docs/src/howto/convergence_troubleshooting.md b/docs/src/howto/convergence_troubleshooting.md index afe088f5c..a8473efe6 100644 --- a/docs/src/howto/convergence_troubleshooting.md +++ b/docs/src/howto/convergence_troubleshooting.md @@ -50,12 +50,6 @@ What `ϵ` actually measures differs by algorithm: | [`IDMRG`](@ref), [`IDMRG2`](@ref) | change in the bond matrix `C` between iterations | | [`GradientGrassmann`](@ref) | norm of the Riemannian gradient | - - Because the measures differ, a raw `ϵ` value is only meaningful *within* one algorithm; do not compare `ϵ` from a `DMRG2` warm-up against `ϵ` from the following `DMRG` refinement. @@ -100,13 +94,6 @@ Grow the bond dimension and the variance collapses: A variance that will not drop as you add bond dimension points at an undersized ansatz, not at an unconverged optimization. - - The fix is to grow the bond dimension: use [`DMRG2`](@ref)/[`IDMRG2`](@ref), or expand explicitly with [`changebonds`](@ref) and [`OptimalExpand`](@ref)/[`RandExpand`](@ref). See [Controlling bond dimension](@ref howto_bond_dimension) for the full set of recipes. @@ -148,11 +135,6 @@ the bottleneck, not the iteration count: check the variance and grow the bond di You therefore rarely need to touch `alg_eigsolve`/`alg_gauge`/`alg_environments` by hand; set the outer `tol` and let the inner solvers follow. - - --- ## 4. Stuck in a local minimum @@ -162,11 +144,6 @@ stays stubbornly high. Variational optimizers can get trapped in local minima, especially from an unlucky random start or a symmetry-frustrated initial state. - - Things to try, roughly in order: - **Restart from a different initial state.** `FiniteMPS`/`InfiniteMPS` with a size argument @@ -242,11 +219,6 @@ eigenvalue sets the correlation length. When several eigenvalues sit almost at `1`, the correlation length diverges and the state is near-degenerate. - - !!! tip "The fix is usually a larger unit cell" If the transfer spectrum is near-degenerate, rebuild the initial state and the Hamiltonian on a larger unit cell (e.g. `InfiniteMPS(fill(ℂ^2, 2), fill(ℂ^16, 2))` and a @@ -259,11 +231,6 @@ For extracting a physically meaningful correlation length from the finite-bond-d spectrum, [`marek_gap`](@ref) implements the standard finite-entanglement-scaling gap extrapolation. - - --- ## 6. Wrong symmetry sector @@ -289,11 +256,6 @@ the intended sectors in its physical and virtual spaces (see [Constructing states](@ref howto_states) for the `sector => dimension` syntax) before optimizing. - - --- ## 7. `leading_boundary` and time evolution @@ -313,12 +275,6 @@ The knobs are different: Use the two-site [`TDVP2`](@ref) (which takes a `trscheme`) or a CBE-enabled [`TDVP`](@ref) to let the bond dimension grow during evolution. - - See [Time evolution](@ref howto_time_evolution) for the full time-evolution interface. --- diff --git a/docs/src/howto/quasi_1d_geometries.md b/docs/src/howto/quasi_1d_geometries.md index 64765632f..1142de805 100644 --- a/docs/src/howto/quasi_1d_geometries.md +++ b/docs/src/howto/quasi_1d_geometries.md @@ -62,8 +62,6 @@ The result is an ordinary [`InfiniteMPOHamiltonian`](@ref) with one MPO tensor p It is used exactly like a chain Hamiltonian: pair it with an [`InfiniteMPS`](@ref) whose unit cell has the same length and feed it to `find_groundstate` (see [Ground-state algorithms](@ref lib_groundstate)). Because the cylinder wraps a 2D coupling onto the chain, the bond dimension required for a converged result grows quickly with the circumference; see the note at the end of this page. - - --- ## Building a Hamiltonian on a ladder @@ -116,8 +114,6 @@ This wrap-around bond is the longest-ranged coupling in the problem, and it is w The bond dimension needed for a given accuracy grows rapidly with the circumference `L`, because the entanglement across a cut scales with the length of the boundary it severs (the circumference). Keep `L` small in exploratory runs and increase it while watching convergence. - - --- ## Choosing the site ordering @@ -141,16 +137,13 @@ after = [linearize_index(i) => linearize_index(j) for (i, j) in nearest_neighbou Passing `snake` to `@mpoham` (in place of `finite_cyl`) then builds the Hamiltonian in this reordered basis. A `SnakePattern` built without a pattern, `SnakePattern(lattice)`, uses the identity ordering. -!!! warning "Ordering helpers" - MPSKitModels also exports `backandforth_pattern` and `frontandback_pattern` as pre-built orderings for cylinders. - At the pinned MPSKitModels version these helpers did not execute for me (they index a lazy iterator), so this page shows an explicit permutation instead. - - +!!! warning "Ordering helpers are broken at v0.4.7" + MPSKitModels also exports `backandforth_pattern` and `frontandback_pattern` as pre-built cylinder orderings, but at the pinned version (v0.4.7) they error: the returned closure indexes a lazy `Iterators.flatten` object, which has no `getindex` method. + This is a known upstream bug, so this page shows an explicit permutation instead. Any custom permutation must be defined for every linear index that the lattice's bonds reference. - On an *infinite* lattice the nearest-neighbour bonds reach into the next unit cell, so a permutation defined only on `1:N` will error there; the finite cylinder above avoids this. - - + On an *infinite* lattice the nearest-neighbour bonds reach into the next unit cell, so a permutation defined only on `1:N` errors there with a `BoundsError`; a pattern for an infinite cylinder has to wrap periodically, e.g. `pattern(i) = ((i - 1) ÷ N) * N + perm[mod1(i, N)]`. + The finite cylinder above sidesteps this. ```@meta DocTestSetup = nothing diff --git a/docs/src/howto/saving_loading.md b/docs/src/howto/saving_loading.md index 917d4a9ee..8c4ebeba7 100644 --- a/docs/src/howto/saving_loading.md +++ b/docs/src/howto/saving_loading.md @@ -118,8 +118,6 @@ envs = environments(ψ_loaded, H, ψ_loaded) # rebuilt from the reloaded state nothing # hide ``` - - If you do have a reason to persist environments (e.g. to resume an expensive iterative build), `serialize`/`deserialize` them just like a state. ## [Caveats](@id howto_saving_loading_caveats) @@ -127,7 +125,6 @@ If you do have a reason to persist environments (e.g. to resume an expensive ite - **Version compatibility.** `Serialization` files are **not** guaranteed to be readable by a different Julia version, nor after MPSKit or TensorKit change their internal type layout. Treat `Serialization` output as a scratch artifact within one environment; use **JLD2** for anything you need to reopen weeks later or on another machine. - - **Symmetric tensors are self-describing.** A saved state carries the vector spaces and symmetry sectors of every tensor, so you do not need to record the symmetry separately — loading reconstructs the full space structure. diff --git a/docs/src/howto/statmech.md b/docs/src/howto/statmech.md index 3d850316e..469c333ba 100644 --- a/docs/src/howto/statmech.md +++ b/docs/src/howto/statmech.md @@ -40,8 +40,6 @@ P = physicalspace(mpo, 1) By default `classical_ising` uses the inverse temperature `beta = log(1 + sqrt(2)) / 2`. - - --- ## 2. Find the leading boundary MPS @@ -87,8 +85,6 @@ The free energy per site follows from ``f = -\tfrac{1}{\beta}\log\Lambda``: f = -1 / β * log(real(Λ)) ``` - - --- ## 4. Correlation length and entanglement entropy @@ -107,8 +103,6 @@ S = real(first(entropy(ψ))) At a critical point the true correlation length diverges; the finite bond dimension of the boundary MPS cuts it off at a finite value that grows with `D`. This finite-entanglement scaling of `S` against `log(ξ)` is exactly what the gallery example [The Hard Hexagon model](@ref "The Hard Hexagon model") exploits to extract a central charge. - - --- ## 5. Symmetric transfer matrices @@ -153,8 +147,6 @@ real(expectation_value(mψ, mmpo)) The `expectation_value` of a multi-row transfer matrix is the product of the per-site weights over the rows of the unit cell; divide `log` of it by the number of rows to recover the per-site free energy. - - --- ## See also diff --git a/docs/src/migration.md b/docs/src/migration.md index 1ab0cc2bd..f5b7c7fc8 100644 --- a/docs/src/migration.md +++ b/docs/src/migration.md @@ -30,12 +30,6 @@ If you previously relied on a two-argument operator call, pass the operator expl `above` state. See [#436](https://github.com/QuantumKitHub/MPSKit.jl/pull/436). - - ## Earlier releases The [Changelog](@ref) records further changes across the 0.13.x series, including a refactor @@ -44,8 +38,3 @@ of the `IDMRG` implementation to the `IterativeSolver` interface consistency ([#415](https://github.com/QuantumKitHub/MPSKit.jl/pull/415)), and a refactor of time-evolution MPO construction ([#422](https://github.com/QuantumKitHub/MPSKit.jl/pull/422)). - - diff --git a/examples/Cache.toml b/examples/Cache.toml index 71449659e..7507f5043 100644 --- a/examples/Cache.toml +++ b/examples/Cache.toml @@ -1,5 +1,5 @@ [excitations] -"1.su3-heisenberg" = "4dae7d3680a9f760a058ca3f5f1a617f8a9879fd649ea80334afaef940bfa07b" +"1.su3-heisenberg" = "0676c035ac8894112f3ea95852759182e113da06105f66bb79e7e829546c3e21" "0.haldane" = "c5a0eb70f0930d38053535c659ab39a87121b6ebda040ceadd9deb5f30921315" [dynamics] diff --git a/examples/excitations/1.su3-heisenberg/main.jl b/examples/excitations/1.su3-heisenberg/main.jl index 46e70d794..ff6d705d0 100644 --- a/examples/excitations/1.su3-heisenberg/main.jl +++ b/examples/excitations/1.su3-heisenberg/main.jl @@ -1,5 +1,5 @@ md""" -# The SU(3) Haldane gap +# The SU(3) Heisenberg chain The spin-1 Heisenberg chain famously has a gapped, symmetry-protected topological ground state: the Haldane phase. @@ -17,11 +17,10 @@ H = J \sum_{\langle i, j \rangle} \sum_{a=1}^{8} T^a_i T^a_j , where the ``T^a`` are the eight generators of ``SU(3)``. This is the direct analog of the spin-1 chain, with the three generators of ``SU(2)`` replaced by the eight generators of ``SU(3)``. - - +The goal of this example is to exercise the full ``SU(N)`` toolchain end to end — building the +symmetric Hamiltonian, optimizing a uniform ground state with VUMPS, and scanning an +excitation dispersion — rather than to pin down the model's (very small) gap to high accuracy; +we return to that point in the closing discussion. Working with the full non-abelian ``SU(3)`` symmetry is what makes this tractable. Just as ``SU(2)`` symmetry drastically shrinks the spin-1 problem (see @@ -123,12 +122,7 @@ bonds, so every virtual space must sit in a single congruency class; here we use class ``0``, which we found to give the lowest variational energy. Following [devos2022](@cite), we seed the optimization with a random ``SU(3)``-symmetric uniform state and optimize with VUMPS. - - +The bond dimension is kept deliberately modest here so that the page builds quickly. """ Vvirt = Vect[SU3Irrep]( @@ -148,16 +142,12 @@ println("ground-state energy per site: E₀ = $E₀") md""" ## The excitation spectrum -Excitations above the ground state are computed with the quasiparticle ansatz. +On top of the ground state we compute excitations with the quasiparticle ansatz. In the thermodynamic limit each excitation carries a definite momentum ``k`` and a definite -``SU(3)`` charge; reference [devos2022](@cite) reports that the lowest branch — whose minimum -is the Haldane gap — lives in the adjoint ``[2\,1\,0]`` sector, with its minimum at momentum -``k = 2\pi/3``. -We scan this branch across half of the Brillouin zone (the other half follows by reflection). - - +``SU(3)`` charge. +Following [devos2022](@cite), we look in the adjoint ``[2\,1\,0]`` sector, where that reference +finds the lowest branch, and scan across half of the Brillouin zone (the other half follows by +reflection). """ sector = SU3Irrep(2, 1, 0) @@ -179,22 +169,22 @@ vline!([2π / 3]; color = :gray, linestyle = :dot, label = "k = 2π/3") md""" The branch has a pronounced soft mode at ``k = 2\pi/3``, exactly the momentum at which -[devos2022](@cite) locates the Haldane gap. -That reference reports a gap of ``\Delta / J = 0.0263`` there. - -This value is *very* small, and reproducing it faithfully is demanding: it requires a -carefully converged, large-bond-dimension uniform ``SU(3)`` MPS. -The lightweight calculation here — a modest virtual space chosen so the page builds quickly — -resolves the *location* of the soft mode but not the tiny gap itself: near ``k = 2\pi/3`` the -computed branch comes out close to zero and can even dip slightly negative, a sign that the -uniform ground state is not converged to the accuracy needed to pin down a gap this small. - - +[devos2022](@cite) locates the minimum of the dispersion, where that reference reports a gap +of ``\Delta / J = 0.0263``. + +The soft-mode *location* is reproduced cleanly, but the gap *value* is not, and it is worth +being precise about why. +The quasiparticle energies plotted above are a genuine variational upper bound on the +excitation energies only when they are measured relative to the *exact* ground state. +Here the ground state is a deliberately lightweight, modest-bond-dimension uniform ``SU(3)`` +MPS, and for this near-critical model it is not converged to that accuracy. +Because the reference state sits slightly too high in energy, the ansatz can find "excitations" +that lie below it, so near ``k = 2\pi/3`` the computed branch drops to essentially zero and even +slightly negative. +The dispersion here is therefore *not* a variational estimate of the true gap: the small value +``\Delta / J = 0.0263`` is quoted from [devos2022](@cite) and would require a carefully +converged, large-bond-dimension calculation to reproduce. +What this example does show is the complete ``SU(3)``-symmetric workflow — Hamiltonian +construction, VUMPS ground state, and a momentum-resolved excitation scan — with the soft mode +correctly located at ``k = 2\pi/3``. """ From 319a01f28d49f5cbae81050c46ece62621223385 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Sat, 11 Jul 2026 14:14:20 -0400 Subject: [PATCH 72/76] docs: adapt transfer_spectrum/correlation_length usage to #452 API After rebasing onto main (#452, sector-centered transfer spectrum): - transfer_spectrum keyword `num_vals` was renamed to `howmany` - correlation_length now returns a per-sector `SectorDict`; take the largest entry (`maximum(values(...))`) to recover the scalar correlation length the prose describes Fixes the two @example blocks (convergence_troubleshooting, statmech) that used the pre-#452 API. Full Documenter build is green. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/src/howto/convergence_troubleshooting.md | 4 ++-- docs/src/howto/statmech.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/src/howto/convergence_troubleshooting.md b/docs/src/howto/convergence_troubleshooting.md index a8473efe6..c8deee887 100644 --- a/docs/src/howto/convergence_troubleshooting.md +++ b/docs/src/howto/convergence_troubleshooting.md @@ -207,11 +207,11 @@ distilled form [`correlation_length`](@ref): InfiniteMPS(ℂ^2, ℂ^16), transverse_field_ising(; g = 2.0), VUMPS(; tol = 1.0e-10, maxiter = 100, verbosity = 0) ) -correlation_length(ψ_gs) +maximum(values(correlation_length(ψ_gs))) ``` ```@example conv -abs.(transfer_spectrum(ψ_gs; num_vals = 5)) +abs.(transfer_spectrum(ψ_gs; howmany = 5)) ``` The leading eigenvalue is `1` (a normalized state); the *gap* between it and the next diff --git a/docs/src/howto/statmech.md b/docs/src/howto/statmech.md index 469c333ba..ff41f49c5 100644 --- a/docs/src/howto/statmech.md +++ b/docs/src/howto/statmech.md @@ -93,7 +93,7 @@ The boundary MPS encodes the correlations of the two-dimensional system. [`correlation_length`](@ref) returns the (largest) correlation length of the transfer matrix, and [`entropy`](@ref) the entanglement entropy of the boundary MPS across a virtual bond: ```@example statmech -ξ = correlation_length(ψ) +ξ = maximum(values(correlation_length(ψ))) ``` ```@example statmech From 1a006cd3c133e48aa55658f34c89d1306f6452b8 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Mon, 13 Jul 2026 13:13:30 -0400 Subject: [PATCH 73/76] docs: add restructure/improvement plans and round-1 review summary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Track the planning documents that guided the docs overhaul: RESTRUCTURE_PLAN.md (page tree + Diátaxis types, source of truth), IMPROVEMENT_PLAN.md (accessibility/adoption workstreams W0–W6), and REVIEW_SUMMARY.md (maintainer sign-off items from round 1). Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/IMPROVEMENT_PLAN.md | 274 +++++++++++++++++++++++++++++++++++++++ docs/RESTRUCTURE_PLAN.md | 148 +++++++++++++++++++++ docs/REVIEW_SUMMARY.md | 43 ++++++ 3 files changed, 465 insertions(+) create mode 100644 docs/IMPROVEMENT_PLAN.md create mode 100644 docs/RESTRUCTURE_PLAN.md create mode 100644 docs/REVIEW_SUMMARY.md diff --git a/docs/IMPROVEMENT_PLAN.md b/docs/IMPROVEMENT_PLAN.md new file mode 100644 index 000000000..3fc12aa41 --- /dev/null +++ b/docs/IMPROVEMENT_PLAN.md @@ -0,0 +1,274 @@ +# MPSKit.jl Accessibility & Adoption Plan + +Companion to `RESTRUCTURE_PLAN.md`. +That file defines *where content lives* — the Diátaxis page tree — and remains the source of truth for structure. +This file defines *what to improve, why, and in what order* to flatten the learning curve and make the package more attractive to adopt. +Every content action below is tagged with its Diátaxis mode (**Tutorial** / **How-to** / **Concept** / **Reference**, plus **Meta** for the out-of-quadrant pages like changelog and citing) and, where applicable, its target page in the planned tree. +Nothing here invents structure outside that plan, with one deliberate, flagged addition: a `benchmarks.md` meta page (§4). + +Basis: a full review of the current docs (`man/`, `howto/`, `lib/`, `examples/`, landing page), the README, the entry-point docstrings, the error-message surface in `src/`, project metadata, and a survey of how ITensor(MPS.jl), TeNPy, and quimb onboard their users. + +--- + +## 1. Diagnosis: why the learning curve is steep + +### 1.1 There is no happy path (the dominant problem) + +The reader is asked to climb from reference prose directly to research-grade case studies, with nothing in between. + +- The landing page (`docs/src/index.md`), immediately after the hero, has the reader contracting gauge tensors with `@tensor` and verifying isometry conditions — before they have ever run a ground-state search. +- The Manual entry point (`man/intro.md`, "Prerequisites") teaches TensorKit by deliberately triggering two errors ("incompatible partition", "incompatible arrows") before the reader can *do* anything, and buries its one motivating sentence (planarity, fermion signs) at the bottom. +- The examples ladder starts at research grade: the first quantum example extracts a CFT spectrum with a translation MPO, the first 2D example uses Fibonacci anyons. + There is no beginner rung. +- The five existing how-to pages cover *setup* (states, Hamiltonians, bond dimension, observables, entanglement) but none of the headline workflows a newcomer arrives for: ground state end-to-end, time evolution, excitations. +- `man/algorithms.md` — where the first runnable `find_groundstate` should be — is a wall of `@docs` blocks; the first runnable ground-state call appears ~140 lines in, as scaffolding for excitations. + +**Fix**: the Tutorials quadrant of the plan, which is currently the empty one. +This is the single highest-leverage work (§5, W1). + +### 1.2 The TensorKit cliff is unmanaged + +- TensorKit vocabulary (`ℂ^2`, `⊗`, domain/codomain, sectors, `Rep[U₁]`, `repartition`, `oneunit`, `id`, `right_virtualspace`) is assumed on essentially every page, with no point-of-use links. + The `@extref` mechanism is set up and used correctly in exactly two spots of `operators.md` — the fix pattern exists but is not applied. +- The load-bearing index-ordering convention ($V_l \otimes P \leftarrow P \otimes V_r$) is conveyed *only* through three PNG images with no text/math fallback. +- Operators like `σˣ()`, `σᶻ()` materialize from hidden `@setup` blocks, so the rendered page never shows where they come from. + +**Fix**: `concepts/vector_spaces.md` written as "TensorKit for MPS users" with a spin-1/2 running example (§5, W3), plus systematic `@extref` links and visible setup code everywhere. + +### 1.3 Breadth reads as intimidation, not power + +MPSKit's real differentiators — many algorithms, finite *and* infinite MPS, generic symmetries up to anyons — are presented as an undifferentiated list. +`man/algorithms.md` itself admits "figuring out the optimal algorithm is not always straightforward", then provides no decision guidance. +The genuinely useful comparison prose that exists (DMRG vs DMRG2 bond-dimension behaviour, VUMPS vs IDMRG convergence, "gradient descent is best in the tail", the four `changebonds` trade-offs) is buried between docstring dumps. + +**Fix**: `concepts/algorithm_landscape.md` with a decision table, plus how-to recipes for each headline workflow (§5, W2). + +### 1.4 Trust-eroding defects + +Small things that individually are minor but together signal "unfinished" to an evaluating user: + +- `man/lattices.md` is an empty "Coming soon!" stub — and `man/operators.md` *actively directs readers to it* right after a hard 30-line manual 2D-indexing example. +- Three how-to pages ship stale `` blocks in their source, including the admission "none of the numeric outputs above have been hand-verified against a real build". +- `man/environments.md` mixes `envs` and `cache` for the same object, uses two different model constructors, and its `@time` examples — whose entire point is showing the caching speedup — display no output. +- Assorted: an off-by-one comment (`fill(ℂ^2, 3) # a finite chain of 4 sites` in `operators.md`), garbled LaTeX in the finite-excitations formula in `algorithms.md`, an empty `[MKL.jl]()` link in `parallelism.md`. +- The docs code depends on packages the install instructions never mention (§1.5). + +**Fix**: workstream W0 — a one-time sweep, largely mechanical, that should land before anything else because it is cheap and the payoff is credibility. + +### 1.5 The out-of-docs surface undersells the package + +- **Install instructions are incomplete.** The how-tos require `TensorKitTensors` (spin operators) and rely on `truncrank` from MatrixAlgebraKit; the README quickstart needs `MPSKitModels`, `Plots`, `ProgressMeter`. + No page lists the actual working environment. + A newcomer copy-pasting the first how-to hits `Package TensorKitTensors not found`. +- **Docstrings have no runnable examples.** Of the ~10 first-touch entry points, only `expectation_value` has a `jldoctest`. + `find_groundstate` — the most important function — does not list keyword defaults, and its docstring says "an optimization algorithm will be attempted based on the supplied keywords" without documenting the actual heuristic (VUMPS→GradientGrassmann for infinite, DMRG/DMRG2 for finite, the `trscheme` branches). +- **Error messages are bimodal.** MPO-construction paths interpolate site/level context nicely, but core plumbing throws `error("Invalid state")`, `error("method ambiguity")`, `ArgumentError("dimension mismatch")` with no values, and message-less `@assert`s that surface as raw `AssertionError` to users. +- **Project metadata gaps.** The changelog lives only inside the docs tree (invisible on GitHub); no `CONTRIBUTING.md`; no issue/PR templates; `CITATION.cff` is stale relative to `Project.toml`; no BibTeX snippet in the README. +- **Version-resolution friction.** Many tightly-pinned pre-1.0 ecosystem deps (`TensorKit = "0.17"`, `BlockTensorKit = "0.3.14"`, …) mean a user with slightly older ecosystem versions hits resolver dead-ends. + +--- + +## 2. Assets to build on (do not rewrite these) + +- **The README quickstart** — two complete runnable examples with rendered magnetization plots — is currently the best onboarding asset in the whole project. + The docs landing page should mirror it, not the other way round. +- **The examples content** is genuinely attractive: real research workflows, Literate.jl pages with captured output, plots, SVG diagrams, Binder/nbviewer badges. + The problem is discoverability (a bare auto-generated index, no difficulty ordering, no beginner rung), not quality. +- **The five `howto/` pages are the right shape**: numbered task recipes, short prose, runnable `@example` blocks, consistent TFIM running example. + `howto/bond_dimension.md` (truncation-scheme table, `&`-chaining, "warm up with DMRG2, refine with DMRG") is the template to copy. +- **`lib/public.md` is a real API contract** — curated, grouped, with an explicit stability note. + Promote it; fill its hollow categories (§5, W4). +- **`DOCSTRING_STYLE.md` and its three templates** already solve the docstring-consistency problem on paper; W4 is mostly *applying* them. +- **Hidden gems in `man/` prose** that must survive the migration as concept material: the gauge "automagic" framing and the overlap-via-center-gauge example (`man/states.md`), the algorithm-comparison paragraphs and `changebonds` trade-off list (`man/algorithms.md`), the DMRG environment-reuse motivation (`man/environments.md`), the OpenBLAS-vs-MKL threading explanation (`man/parallelism.md`). + +--- + +## 3. Competitor practices worth adopting — mapped into Diátaxis + +Survey targets: ITensor / ITensorMPS.jl, TeNPy, quimb. +All three share: a ground-state hero example visible within one screen (with *real output*), a named tutorial track separate from a recipe collection, heavy use of tensor-network diagrams as core onboarding, a citable pedagogical paper, and a visible Q&A venue. + +| Practice | Seen at | Diátaxis home in our tree | +|---|---|---| +| Hero example with real convergence output on the first screen | ITensorMPS.jl README (Heisenberg DMRG, energies shown) | Landing `index.md` + README (Meta) | +| Browsable one-page recipe index ("code formulas"), with "suggest a recipe" invitation | itensor.org formulas page | `howto/` section index (How-to) | +| "Protocol for reliable (i)DMRG" best-practices page | TeNPy | `howto/convergence_troubleshooting.md` (How-to) + `concepts/numerics.md` (Concept) | +| Progressive worked-example gallery, easy → hard | quimb (16 notebooks), TeNPy notebooks | `examples/` gallery curation | +| Diagrams as onboarding, not decoration | itensor.org animations, quimb `.draw()` | Concept pages (static SVGs; asset precedent already exists in `examples/`) | +| Per-topic FAQ mined from recurring user questions | ITensor (DMRG FAQ, QN FAQ) | **Not a standalone FAQ page** — see note below | +| Community venue linked prominently | ITensor Discourse, TeNPy forum | README + landing (Meta) | +| Citable pedagogical paper doubling as library paper | TeNPy SciPost Lecture Notes | Long-term; `citing.md` neighborhood (Meta) | +| "Papers using X" showcase | itensor.org | New meta page near `citing.md` (Meta) | + +**Diátaxis note on FAQs**: a standalone FAQ is a mode-blending dumping ground. +Instead, mine GitHub issues for recurring questions and route each answer to its proper home: task-shaped answers become how-to recipes (most will land in `convergence_troubleshooting.md`), understanding-shaped answers become sections of the relevant concept page. +If discoverability demands it, a short *routing list* of question → link can live on the how-to index, but the content itself lives in-quadrant. + +--- + +## 4. Benchmarks: performance as a headline feature + +MPSKit is believed to be significantly faster than ITensor across the board. + +If the numbers bear that out, this is the single most compelling adoption argument for the target audience and is currently advertised nowhere. +Speed claims only convert people when they are reproducible and fair, so the suite and the guardrails matter as much as the numbers. + +### 4.1 Where it lives (Diátaxis) + +- A top-level **`benchmarks.md` meta page** in the docs, alongside `references.md` / `changelog.md` / `citing.md` — factual, reference-toned, versioned. + This is the one deliberate addition to the `RESTRUCTURE_PLAN.md` page tree. +- One **headline chart** in the README and one feature bullet on the landing hero ("Fast: see the benchmarks"). + Marketing lives in Meta surfaces; tutorials and how-tos never carry comparative claims. +- Scripts in a public **`MPSKitBenchmarks` repo** (or `benchmark/` workspace project) so every published number is one `julia --project` away from being checked. + +### 4.2 Proposed suites + +Ordered by marketing value per unit of implementation effort. + +1. **Finite DMRG time-to-solution** — spin-1 Heisenberg chain and TFIM, N = 100, no symmetries: wall time to reach fixed accuracy (e.g. `ΔE/E ≤ 1e-8` vs a reference energy) and time per sweep, at χ ∈ {64, 128, 256, 512, 1024}. + Competitors: ITensorMPS.jl, TeNPy. +2. **Abelian symmetry** — same models with U(1) conservation. + Competitors: ITensorMPS.jl (QN), TeNPy. +3. **Non-abelian SU(2)** — spin-1 Heisenberg with full SU(2). + ITensor and TeNPy support only abelian QNs, so this row is a *capability* advertisement; benchmark against MPSKit's own U(1) run to show the effective-χ payoff. +4. **Infinite MPS: VUMPS / IDMRG** — infinite Heisenberg and TFIM time-to-tolerance. + VUMPS as a first-class citizen is itself a differentiator; compare against TeNPy iDMRG where a comparison exists. +5. **TDVP throughput** — global quench on N = 100 chain, cost per unit time evolved at fixed χ. +6. **Quasi-2D DMRG** — Heisenberg or Hubbard cylinder (width 4–6), time per sweep; this is the workload reviewers of "serious" packages look for. +7. **Thread scaling** — speedup vs `nthreads` for suite 1, since the multithreaded environment/derivative code is an MPSKit strength worth showing. + +### 4.3 Methodology guardrails (non-negotiable for credibility) + +- Compare **time-to-accuracy**, not time-per-iteration — sweep/iteration semantics differ across libraries. +- Identical Hamiltonians, χ schedules, truncation thresholds, BLAS backend, and thread counts; pinned versions of every package; hardware documented. +- Use each competitor's *official* example/recommended settings as the starting point, so nobody can call it a strawman; ideally have the comparison scripts sanity-checked by someone fluent in that library. +- Publish everything: scripts, environment manifests, raw timings, and the plotting code. +- Report losses as honestly as wins; a table where MPSKit wins 9 of 11 rows is *more* persuasive than a table where it wins 11 of 11. +- Re-run and re-date the page per MPSKit minor release (automate as far as practical). + +### 4.4 Result placeholders + +To be filled by the benchmark runs; the page ships only when at least suites 1–2 are populated. + +**Suite 1 — Finite DMRG, spin-1 Heisenberg, N = 100, time to ΔE/E ≤ 1e-8 (seconds, lower is better):** + +| χ | MPSKit.jl | ITensorMPS.jl | TeNPy | speedup vs best competitor | +|---|---|---|---|---| +| 64 | _tbd_ | _tbd_ | _tbd_ | _tbd_ | +| 128 | _tbd_ | _tbd_ | _tbd_ | _tbd_ | +| 256 | _tbd_ | _tbd_ | _tbd_ | _tbd_ | +| 512 | _tbd_ | _tbd_ | _tbd_ | _tbd_ | +| 1024 | _tbd_ | _tbd_ | _tbd_ | _tbd_ | + +**Suite 2 — same, with U(1) symmetry:** (same table shape) + +**Suite 3 — SU(2) capability payoff (MPSKit only):** + +| symmetry | effective χ | wall time | memory | +|---|---|---|---| +| none | _tbd_ | _tbd_ | _tbd_ | +| U(1) | _tbd_ | _tbd_ | _tbd_ | +| SU(2) | _tbd_ | _tbd_ | _tbd_ | + +Headline README chart: log–log wall-time vs χ for suite 1, one line per library. + +--- + +## 5. Workstreams, prioritized + +### W0 — Trust and correctness sweep (cheap, do first, independent of restructure) + +- [ ] List the *actual* working environment everywhere installation is discussed: `MPSKit`, `TensorKit`, `MPSKitModels`, `TensorKitTensors`, `Plots` (+ note that `truncrank` etc. come from MatrixAlgebraKit). + Targets: `index.md` now, `tutorials/installation.md` when it exists. (Tutorial/Meta) +- [ ] Strip the stale `` blocks from `howto/observables.md`, `howto/entanglement.md`, `howto/hamiltonians.md` after running their outputs through doctest verification. (How-to) +- [ ] Kill the `man/lattices.md` dead end: remove from nav or write the minimal real content; fix the forward reference in `man/operators.md`. (Reference) +- [ ] `man/environments.md` (currently commented out of the build): unify `envs`/`cache` naming, one model constructor, convert to `@example` blocks with real shown output — or keep it out of nav until its concept-page successor exists. (Concept-to-be) +- [ ] Mechanical fixes: off-by-one comment in `man/operators.md`; broken LaTeX in `man/algorithms.md` finite-excitations formula; empty `[MKL.jl]()` link in `man/parallelism.md`; make hidden `@setup` imports visible in rendered pages. +- [ ] Metadata: root `CHANGELOG.md` (copy or symlink from docs), `CONTRIBUTING.md`, `.github/ISSUE_TEMPLATE/` + PR template, bump `CITATION.cff` and automate it in the release process, BibTeX snippet in README. (Meta) + +### W1 — The happy path (Tutorials + landing + examples ladder) — highest leverage + +- [ ] Rewrite `index.md`: keep the VitePress hero, replace the gauge-tensor walkthrough with a ≤20-line TFIM ground-state example showing real printed output (mirror the README quickstart), route the action buttons to the tutorial track instead of "Manual", add the "where next" router to the four sections. (Meta/landing) +- [ ] `tutorials/installation.md` — full environment + verify snippet. (Tutorial) +- [ ] `tutorials/first_groundstate.md` — the flagship; the single most important page in the plan. (Tutorial) +- [ ] `tutorials/thermodynamic_limit.md` — the "near-identical code for infinite systems" payoff, MPSKit's wow moment. (Tutorial) +- [ ] Examples gallery: add one beginner rung (e.g. TFIM magnetization across the transition — bridges directly from the flagship tutorial), and curate `examples/index.md` with one-line descriptions, difficulty ordering, and thumbnail plots; suppress the 40-line `[ Info: DMRG …]` log dumps in rendered pages. (Examples showcase) + +### W2 — Decision guidance (converts breadth from intimidating to attractive) + +- [ ] `concepts/algorithm_landscape.md` with an explicit decision table (finite/infinite × ground state/time evolution/excitations/boundary), salvaging the comparison prose buried in `man/algorithms.md`. (Concept) +- [ ] `howto/groundstate_algorithms.md`, `howto/time_evolution.md`, `howto/excitations.md` — the headline workflows currently missing task recipes. (How-to) +- [ ] Make the How-to section index a browsable recipe list à la ITensor's code formulas, with a "missing a recipe? open an issue" invitation. (How-to) + +### W3 — The TensorKit bridge + +- [ ] `concepts/vector_spaces.md` replaces `man/intro.md`'s TensorKit section: motivated by a spin-1/2 chain, positive-path examples first (errors shown later, as diagnostics), the planarity/fermion "why" up front, keep the ℤ₂ sector example. (Concept) +- [ ] Conventions (index ordering, MPS/MPO tensor definitions) become a reference page with a text + math fallback next to each image. (Reference) +- [ ] Apply `@extref` TensorKit links at point of first use on every page; the pattern already exists in `man/operators.md`. (All modes) +- [ ] Every tutorial and how-to page opens with a visible "packages used" line. (Tutorial/How-to) + +### W4 — Reference depth and docstrings + +- [ ] Add `jldoctest` examples to the first-touch entry points, copying the `expectation_value` pattern per `DOCSTRING_STYLE.md` Template B — priority order: `find_groundstate`, `FiniteMPS`, `InfiniteMPS`, `FiniteMPOHamiltonian`/`InfiniteMPOHamiltonian`, `DMRG`, `VUMPS`, `timestep`/`time_evolve`, `TDVP`, `changebonds`. (Reference) +- [ ] `find_groundstate`: document keyword defaults and the automatic algorithm-selection heuristic explicitly. (Reference) +- [ ] Fill the hollow `lib/public.md` categories — Environments, `approximate`, `leading_boundary`/`VOMPS`, spectral functions (`propagator`, `DynamicalDMRG`, …) currently live only in the `lib.md` autodocs dump. (Reference) +- [ ] Split the remaining `man/` pages along the concept/reference seam and retire `man/` (per the plan's migration note): `states.md` → `concepts/matrix_product_states.md` + lib; `operators.md` → `concepts/operators_and_hamiltonians.md` + lib; `algorithms.md` prose → `algorithm_landscape.md` + how-tos, its `@docs` → lib; `parallelism.md` → `concepts/parallelism_model.md` + `howto/parallelism_gpu.md`; `environments.md` → `concepts/environments.md`. (Concept/Reference) +- [ ] Error-message pass in `src/`: replace bare `error()` / `error("Invalid state")` / generic `"dimension mismatch"` with messages that interpolate the offending values and suggest a fix; add messages to `@assert`s on user-reachable paths; keep developer-voice asserts internal. (Code, not docs — but part of the perceived learning curve) + +### W5 — Reliability content (the TeNPy move) + +- [ ] `howto/convergence_troubleshooting.md`: symptom → diagnosis → fix recipes (not converging, sector starvation with U(1), bond dimension saturating, TDVP norm drift, …). (How-to) +- [ ] `concepts/numerics.md`: truncation error, convergence criteria, extrapolation in χ, precision pitfalls. (Concept) +- [ ] Mine closed GitHub issues for recurring questions and route each into the two pages above or the relevant concept page (see FAQ note in §3). (How-to/Concept) +- [ ] These pages are physics-heavy: maintainer-led per the REVIEW workflow in `CLAUDE.md`. + +### W6 — Adoption surface and community + +- [ ] Benchmarks per §4: build the suite, populate `benchmarks.md`, headline chart in README. (Meta) +- [ ] README: add a short "How MPSKit compares" positioning paragraph — generic symmetries up to non-abelian/fermionic/anyonic, infinite MPS/VUMPS as first-class citizens, Julia-native composability, speed (link benchmarks). (Meta) +- [ ] Pick and prominently link one community Q&A venue (GitHub Discussions or a #quantumkithub channel) from README and landing. (Meta) +- [ ] "Publications using MPSKit" page near `citing.md`. (Meta) +- [ ] Static tensor-network SVG diagrams on the concept pages (MPS/gauge structure, environments, sweep); the examples tree already contains style precedents (`translation_mpo.svg`, `spt-tensors.svg`). (Concept) +- [ ] Loosen the tightest pre-1.0 `[compat]` pins where feasible to reduce resolver dead-ends. (Code) +- [ ] Long-term: a pedagogical lecture-notes-style paper à la TeNPy's SciPost notes, doubling as the citable library paper. (Meta) + +--- + +## 6. Diátaxis guardrails while executing + +- One mode per page, no exceptions: tutorials never survey options (they link to the how-to/concept instead); how-tos assume competence and *link* to concepts rather than teaching them; concept pages contain no `@docs` dumps; reference pages contain no narrative. +- The `man/` migration is *splitting, not rewriting* — nearly every `man/` page is good prose fused to API dumps; pull them apart along that seam (see W4). +- Troubleshooting and FAQ material is expressed as how-to recipes and concept sections, never as a standalone mixed-mode page. +- Benchmarks and comparisons are Meta: factual on `benchmarks.md`, promotional only in README/landing hero, absent from tutorials and how-tos. +- Internals and experimental features (`SketchedExpand`, GPU, everything in `lib/internals.md`) stay quarantined behind `!!! warning`, per the hard rules. + +## 7. Suggested sequencing + +| Order | Work | Rationale | +|---|---|---| +| 1 | W0 | Cheap, restores credibility, unblocks nothing | +| 2 | W1 | The missing quadrant; biggest learning-curve payoff | +| 3 | W2 + W3 | Matches plan priority (3)–(4): decision guide + TensorKit cliff | +| 4 | W4 | Reference depth; large but parallelizable page-by-page | +| 5 | W5 | Physics-heavy, maintainer-led sessions | +| 6 | W6 | Adoption layer; benchmarks can start earlier in parallel since they are independent of docs restructuring | + +--- + +## Appendix A — file-level defect list (from the review) + +- `docs/src/index.md` — gauge-tensor walkthrough before any ground-state search; action buttons route to Manual; install section omits `TensorKitTensors`/`Plots`; "Additional Resources" admits the docs are a work in progress. +- `docs/src/man/intro.md` — error-first TensorKit teaching; motivation buried at the bottom; TensorKit link only at line ~62 after all confusing material; conventions conveyed only via images. +- `docs/src/man/states.md` — capability list with trailing ellipsis and zero examples; `repartition` unexplained; `Union{Missing, A}` implementation details interrupt intro-level flow; good gauge prose worth salvaging. +- `docs/src/man/operators.md` — hidden `@setup` imports; "Jordan block" used ~90 lines before definition; off-by-one comment (`fill(ℂ^2, 3)` / "4 sites"); forward reference to empty lattices page; `!!! warning` work-in-progress section shipped; excellent Ising example and Symbolics verification worth salvaging. +- `docs/src/man/algorithms.md` — `@docs` wall; no top-level runnable ground-state example; no decision table; garbled LaTeX in finite-excitations formula; `verbosity=false` vs `verbosity=0` inconsistency; valuable comparison prose and `changebonds` section worth salvaging. +- `docs/src/man/environments.md` — non-running ` ```julia ` blocks; `envs` vs `cache` naming drift; two different model constructors; `@time` examples show no output; currently commented out of `make.jl`. +- `docs/src/man/lattices.md` — empty stub in nav. +- `docs/src/man/parallelism.md` — empty `[MKL.jl]()` link; advanced material unlabeled as such; threading explanation worth keeping as-is. +- `docs/src/howto/{observables,entanglement,hamiltonians}.md` — stale maintainer-comment blocks incl. "outputs not verified" admissions. +- `docs/src/howto/*` (all) — depend on `TensorKitTensors`/MatrixAlgebraKit never mentioned in install docs; no prerequisite links up to concept material. +- `docs/src/lib/public.md` — categories promised without category pages (Environments, spectral functions, `leading_boundary`, `VOMPS`, `approximate`). +- `docs/src/lib/observables.md` — two `!!! warning`s exposing unreliable methods (`expectation_value(::MultilineMPS, …)` "TODO: fix environments"; `variance(::InfiniteQP, …)` "may be unreliable"): fix or quarantine. +- `docs/src/examples/index.md` — bare auto-generated title list; no descriptions, ordering, or thumbnails; no beginner example; verbose solver logs dumped into rendered pages. +- `src/` error messages — bare `error()`, `error("Invalid state")`, `error("method ambiguity")`, `ArgumentError("dimension mismatch")`, message-less `@assert`s on user-reachable paths. +- Repo metadata — no root `CHANGELOG.md`/`CONTRIBUTING.md`/issue templates; `CITATION.cff` version stale vs `Project.toml`. diff --git a/docs/RESTRUCTURE_PLAN.md b/docs/RESTRUCTURE_PLAN.md new file mode 100644 index 000000000..477635afa --- /dev/null +++ b/docs/RESTRUCTURE_PLAN.md @@ -0,0 +1,148 @@ +# MPSKit.jl Documentation Restructure Plan + +## Problem diagnosis +The current Manual is organized around the library's **type taxonomy** (States, +Operators, Algorithms, Lattices), which mirrors the architecture rather than the +reader's goals. Content answers "what is a `FiniteMPS`" instead of "how do I get a +ground state and a plot." The docs read as "terse" not because of word count but +because they're reference content lacking a learning path and a conceptual layer. + +## Organizing principle: Diátaxis +Sort every piece of content by the reader's mode, and don't blend modes: +- **Tutorials** — learning-oriented, hand-held, sequential +- **How-to guides** — task recipes, assume competence +- **Concepts** — understanding-oriented prose (the "why") +- **Reference** — lookup, mostly auto-generated + +Current state: heavy on reference, thin on how-to, missing tutorials and concepts. + +## Target page tree (`docs/src/`) + +``` +docs/src/ +├── index.md # Landing / router (VitePress hero frontmatter) +│ +├── tutorials/ # LEARNING — sequential, hand-held +│ ├── installation.md +│ ├── first_groundstate.md # FLAGSHIP +│ ├── thermodynamic_limit.md +│ ├── time_evolution.md +│ ├── excitations.md +│ └── using_symmetries.md +│ +├── howto/ # TASK RECIPES +│ ├── states.md +│ ├── hamiltonians.md +│ ├── groundstate_algorithms.md +│ ├── bond_dimension.md +│ ├── observables.md +│ ├── entanglement.md +│ ├── time_evolution.md +│ ├── excitations.md +│ ├── statmech.md +│ ├── quasi_1d_geometries.md +│ ├── convergence_troubleshooting.md +│ ├── parallelism_gpu.md +│ └── saving_loading.md +│ +├── concepts/ # UNDERSTANDING +│ ├── vector_spaces.md +│ ├── matrix_product_states.md +│ ├── finite_vs_infinite.md +│ ├── operators_and_hamiltonians.md +│ ├── symmetries.md +│ ├── algorithm_landscape.md +│ ├── environments.md +│ ├── parallelism_model.md +│ └── numerics.md +│ +├── examples/ # SHOWCASE — full case studies +│ ├── index.md +│ ├── haldane_gap.md +│ ├── hubbard_model.md +│ ├── classical_ising_2d.md +│ └── heisenberg_dispersion.md +│ +├── lib/ # REFERENCE — mostly @autodocs +│ ├── public.md # curated stable API surface +│ ├── states.md +│ ├── operators.md +│ ├── groundstate.md +│ ├── time_evolution.md +│ ├── excitations.md +│ ├── bond_dimension.md +│ ├── observables.md +│ ├── environments.md +│ ├── internals.md # non-public, marked unstable +│ └── index.md # symbol index +│ +├── references.md +├── changelog.md +├── migration.md # breaking-change / upgrade guide +├── contributing.md +└── citing.md +``` + +## Per-page contents + +### Landing +- **index.md** — what MPSKit is + who for, key features, install, one 30-sec runnable + example, a "where next" router to the four sections, and an ecosystem map. Use the + VitePress home-page hero layout (YAML frontmatter: hero title, tagline, action + buttons linking to the four Diátaxis sections). + +### Tutorials (each runnable end-to-end, no forward references) +- **installation.md** — full env: MPSKit + TensorKit + MPSKitModels + optional plotting; verify snippet. +- **first_groundstate.md** — FLAGSHIP: FiniteMPS -> TFIM Hamiltonian -> find_groundstate/DMRG -> observable -> magnetization plot. +- **thermodynamic_limit.md** — same physics with InfiniteMPS + VUMPS; the "near-identical code" payoff. +- **time_evolution.md** — simple quench with TDVP/timestep, one observable over time. +- **excitations.md** — quasiparticle ansatz, plot a dispersion. +- **using_symmetries.md** — redo flagship with U(1); sector syntax + bond-dim benefit. + +### How-to (task-shaped) +- **states.md** — construct FiniteMPS/InfiniteMPS/WindowMPS/MultilineMPS; from tensors, product, random, with sectors. +- **hamiltonians.md** — Finite/InfiniteMPOHamiltonian via @mpoham, manual, longer-range, boundary conditions. +- **groundstate_algorithms.md** — DMRG/DMRG2/VUMPS/IDMRG/GradientGrassmann config + tolerances. +- **bond_dimension.md** — changebonds, OptimalExpand/RandExpand/SvdCut, dynamic expansion. +- **observables.md** — local/multi-site expectation values, correlators. +- **entanglement.md** — entanglement entropy + spectrum from gauge tensors. +- **time_evolution.md** — real/imaginary time; TDVP/TDVP2; make_time_mpo (WI/WII). +- **excitations.md** — QuasiparticleAnsatz/FiniteExcited; momentum-resolved; dispersions. +- **statmech.md** — 2D classical/transfer matrix; leading_boundary; MultilineMPS. +- **quasi_1d_geometries.md** — cylinders/ladders via MPSKitModels; ordering choices. +- **convergence_troubleshooting.md** — diagnostic recipe for non-convergence. +- **parallelism_gpu.md** — threading settings; GPU state/caveats (mark experimental). +- **saving_loading.md** — serialize/reload states and environments. + +### Concepts (prose, the "why") +- **vector_spaces.md** — TensorKit mental model; the steepest cliff. +- **matrix_product_states.md** — gauging/canonical forms; AL/AR/AC/C meaning. +- **finite_vs_infinite.md** — unit cells; why infinite MPS normalize to 1. +- **operators_and_hamiltonians.md** — MPO structure, Jordan-block form, sparse vs dense. +- **symmetries.md** — abelian/non-abelian/fermionic/anyonic; sectors; "when does SU(2) pay off." Differentiator — make it the most polished. +- **algorithm_landscape.md** — DMRG vs VUMPS vs IDMRG vs TDVP vs gradient: decision guide. +- **environments.md** — what caches are, why stored/reused, API impact. +- **parallelism_model.md** — internal structure, what scales. +- **numerics.md** — truncation error, convergence criteria, precision, pitfalls. + +### Examples (full literate case studies) +- gallery index + Haldane gap (SU(2)), Hubbard (fermionic), 2D classical Ising (statmech), Heisenberg dispersion (excitations). + +### Reference (mostly @autodocs, split by category) +- **public.md** is the curated stable surface (the API contract). Category pages group docstrings. **internals.md** = unstable. **index.md** = alphabetical symbol index. + +### Meta +- references (DocumenterCitations), changelog, migration, contributing, citing (Zenodo DOI). + +## Process notes +- **Migration is mostly *splitting*, not rewriting**: existing Manual pages map onto + concepts/ (prose) + lib/ (API). Split each along that seam. +- **Incremental, not big-bang**: keep old pages live, build the new layer alongside, + then narrow the Manual's role to pure reference once the learning path exists. +- **Self-testing docs**: wire every code block in tutorials/ and examples/ through + Documenter @example/jldoctest and gate in CI. Doubles as integration tests. +- **Rendering backend**: DocumenterVitepress (VitePress). This does not change the + content plan; it changes build/preview/deploy plumbing only. +- **Priority order**: (1) re-sort existing content; (2) flagship tutorial; + (3) algorithm_landscape.md + vector_spaces.md; (4) symmetry progression; + (5) convert examples to tested doctests + CI gating. diff --git a/docs/REVIEW_SUMMARY.md b/docs/REVIEW_SUMMARY.md new file mode 100644 index 000000000..6ae603e1f --- /dev/null +++ b/docs/REVIEW_SUMMARY.md @@ -0,0 +1,43 @@ +# Maintainer review summary — docs improvement round 1 + +Round 1 of `docs/IMPROVEMENT_PLAN.md` (W0 trust sweep + W1 happy path + benchmark scaffold), executed 2026-07-04 on `docs/content-wave1`. +Everything below either needs your physics judgment or records a decision deferred to you. + +## 1. REVIEW flags awaiting physics sign-off + +**`docs/src/tutorials/first_groundstate.md` (7 flags)** — ferromagnetic framing of the −J σᶻσᶻ term; g = 0.5 as the ordered side; the DMRG sweep description; σᶻ as order parameter + variance phrasing; PBC-vs-OBC rationale for the sweep; the `abs(...)` symmetry argument; crossover-shape claims. +Empirical input for the last one: the verified run shows a **sharp step** at g ≈ 1 (M > 0.8 for g ≤ 0.9, ~1e-8 for g ≥ 1.0), not a smooth crossover — consistent with DMRG locking onto one symmetry-broken state; align the prose accordingly. + +**`docs/src/tutorials/thermodynamic_limit.md` (6 flags)** — VUMPS one-line characterization; `correlation_length` description/units; growth toward criticality (verified numerically: ξ = 0.58 at g = 0.5 → 7.45 at g = 1.0); finite-D capping; sharper-than-finite comparison; the finite-D spontaneous-symmetry-breaking framing (the writer's least-confident claim). + +**`examples/quantum1d/0.tfim-groundstate/main.jl` (8 flags)** — critical point/framing; D-sharpens-everything; abs() for the infinite branch; finite-vs-infinite rounding; `entropy(::InfiniteMPS)` shape assumption; entropy-peak interpretation; correlation-length capping; the three-diagnostics-agree summary. + +**`docs/src/examples/index.md` (2 flags)** — Haldane-SPT teaser rigor; Bose-Hubbard "Mott/superfluid" gloss. + +**`benchmark/suites/suite2_dmrg_u1.jl` (1 flag, blocking for suite-2 numbers)** — the hand-rolled U(1) virtual-sector allocation (uniform over charges −4:4) is demonstrably suboptimal: ITensor's automatic allocation reached −26.8188 at χ=8 where this split reached −26.4027. Fix before any suite-2 timing is published. + +## 2. Code/doc mismatches found (pick a side) + +- `correlator(ψ, O₁₂, i, js)` with `first(js) ≤ i` logs `@error` but does NOT throw (`src/algorithms/correlators.jl:17`); `howto/observables.md` says "will throw an error". Fix code or wording. +- `expectation_value(::InfiniteMPS, ::InfiniteMPOHamiltonian)` returns a scalar (unit-cell sum); the old `sum(real(E0))/length(mps)` idiom was a no-op sum on a scalar. New pages state it correctly; the convention is worth a docstring note. +- `howto/bond_dimension.md` documented a nonexistent `truncbelow(x)` scheme and twice credited MPSKit with re-exporting `truncrank` (it's TensorKit). Fixed (commit `ad646a7`), but this survived wave-1 review — a quick grep-audit of other wave-1 tables for phantom symbols is cheap insurance. + +## 3. Content debt observed, not touched this round + +- CHANGELOG entries stop at 0.13.11 though tags reach v0.13.13. +- Example pages dump raw solver logs inline (`1.ising-cft`, `3.ising-dqpt`, `4.xxz-heisenberg` ~400 lines, `6.hubbard`); suggest verbosity = 0 in their `main.jl`. +- `6.hubbard/index.md` has an empty citation link `Eq. (6.82) in []()`; `7.xy-finiteT` has an unresolved `!!! todo`. +- `find_groundstate`'s docstring still omits keyword defaults and the auto-selection heuristic; only `expectation_value` has a docstring doctest (the whole package has exactly one). This is workstream W4. + +## 4. Deferred decisions (from the approved plan) + +- Fate of `man/environments.md` (still commented out of the build). +- The `!!! warning`s in `lib/observables.md` (`expectation_value(::MultilineMPS)`, `variance(::InfiniteQP)`): fix or keep quarantined. +- Loosening pre-1.0 `[compat]` pins. +- Community venue (GitHub Discussions vs a chat channel) — README/landing link slots are ready when chosen. + +## 5. Benchmark status + +Harness + ITensorMPS parity scripts are smoke-verified end-to-end; energies agree to leading digits; every parity judgment call is documented in `benchmark/comparisons/itensor/README.md` and deliberately favors ITensor where exact parity is impossible (two-site vs single-site, Float64 vs ComplexF64). +Before full runs: fix the suite-2 sector allocation (above), tune `nsweeps`, and decide on ramp-up schedules. +No numbers are published anywhere, per the plan. From 8af06d4ac394bbb83423180a72262c6c31f4dd47 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Mon, 13 Jul 2026 13:14:54 -0400 Subject: [PATCH 74/76] docs: add competitor-review inspiration notes Distilled review (2026-07) of quimb, TeNPy, and ITensor docs, with actionable items cross-referenced to RESTRUCTURE_PLAN.md. Companion to IMPROVEMENT_PLAN.md; salvaged from the docs-inspiration worktree before pruning it. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/DOCS_INSPIRATION.md | 162 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 docs/DOCS_INSPIRATION.md diff --git a/docs/DOCS_INSPIRATION.md b/docs/DOCS_INSPIRATION.md new file mode 100644 index 000000000..5bbe63e1f --- /dev/null +++ b/docs/DOCS_INSPIRATION.md @@ -0,0 +1,162 @@ +# Documentation inspiration from quimb, TeNPy, and ITensor + +Actionable ideas for the MPSKit.jl docs, distilled from a structured review (2026-07) of the documentation of three peer libraries: +[quimb](https://quimb.readthedocs.io/), [TeNPy](https://tenpy.readthedocs.io/), and [ITensor / ITensorMPS.jl](https://itensor.org). +Each item names its source and its relation to `RESTRUCTURE_PLAN.md` (the source of truth for structure — nothing here overrides it; items either reinforce a planned page, sharpen its spec, or propose an addition for maintainer sign-off). + +Legend: **[quick win]** doable within the current content waves · **[plan addition]** new page/section, needs a plan edit · **[needs package work]** blocked on code, not prose. + +--- + +## 1. What the review validates about the current plan + +No action needed — these confirm choices already made, and are listed so we don't relitigate them. + +- **The Diátaxis split is the right call.** + None of the three does it cleanly, and in each case the blending is a named weakness: TeNPy's "Introductions" is a 12-page grab-bag mixing explanation, how-to, and reference detail; quimb's guides mix hand-holding with option dumps; only ITensor separates tutorials / code examples / reference in the sidebar, and it reads best. +- **Executing every example at build time is a real edge — keep the CI gate.** + quimb commits notebook outputs (`nb_execution_mode = "off"`), so outputs silently rot; TeNPy renders its `.py` scripts and toycodes as dead source listings with no output at all. + MPSKit's Literate + `@example` pipeline already avoids the exact failure mode both of them have. +- **A runnable example on the landing page (planned in `index.md`) is proven, not speculative.** + ITensorMPS.jl puts a complete ~20-line Heisenberg DMRG with its real final energy on page one; quimb and TeNPy both lack front-page code and it is their most-felt onboarding gap. +- **`symmetries.md` as the most-polished differentiator is well aimed.** + TeNPy's charge-conservation page is one of its most-visited docs despite being a 4000-line monolith — there is demand; serving it with several well-scoped pages is the opportunity. + +--- + +## 2. Quick wins (content style, current waves) + +- [ ] **Give how-to recipes imperative, search-shaped titles.** *(ITensor "code formulas")* + Section headings like "Compute the entanglement entropy of an MPS", "Write and read an MPS to disk", "Target an excited state" — titles that match what users type into a search box. + The planned `howto/` pages are topical (good); the actionable delta is at the *section* level within them, plus a flat index page listing every recipe title as a link so the how-to layer doubles as a self-service FAQ. +- [ ] **Make every recipe self-contained with visible output.** *(ITensor + quimb)* + Each recipe includes the short setup that produces the state it measures (or shares one via `@setup`), ends with real printed output, and cross-links down to the `lib/` docstrings it uses (`@ref expectation_value` etc.). +- [ ] **Show real convergence logs, not sanitized snippets.** *(quimb)* + quimb's 1D-algorithms page prints per-sweep energies and progress output so readers learn what healthy convergence *looks like*. + In the flagship tutorial and the ground-state how-to, keep (a trimmed slice of) the actual iteration log in the rendered output instead of suppressing verbosity. +- [ ] **Upgrade the examples index from a bare list to an annotated gallery.** *(quimb's weakness)* + One line per example: the physics question, the MPSKit features it exercises (e.g. "SU(2) symmetry, quasiparticle excitations"), and a rough difficulty/runtime marker. + No VitePress components needed — plain Markdown descriptions already fix quimb's "numbered list with no descriptions" problem. +- [ ] **Group optional dependencies by capability on the install page.** *(quimb)* + "For plotting: …; for saving states: JLD2; for GPU (experimental): CUDA" — grouped by what the user wants to do, not alphabetically. + Add the performance notes users actually need at install time: BLAS threading interaction (`OMP_NUM_THREADS` vs Julia threads), and a short HPC/cluster note (ITensor documents cluster installs and precompile latency explicitly because that's where their users run — ours too). +- [ ] **Put a minimal runnable ground-state example and a BibTeX block in the GitHub README.** *(ITensor strength, explicit TeNPy gap)* + TeNPy's README has install commands but zero code; ITensor's front page shows the flagship calculation in seconds. + A GitHub visitor should see `find_groundstate` working before clicking anything. +- [ ] **Add redirects for every page the restructure moves.** *(quimb's weakness)* + quimb's guide URLs churned and old links 404 while search engines still index them. + As `man/` pages dissolve into `concepts/` + `lib/`, ship redirects (or stub pages with a link) from the old URLs — cheap now, impossible to retrofit into other people's bookmarks and forum answers later. +- [ ] **Coin one design-thesis sentence and repeat it verbatim everywhere.** *(ITensor)* + ITensor's "interface independent of memory layout / inspired by tensor diagrams" line appears identically on the front page, in the type docstring, and in the paper — it *is* their brand. + MPSKit's equivalent (roughly: symmetries as first-class citizens via TensorKit, with the same code driving finite and infinite systems) should be crafted once and reused on `index.md`, the README, and `citing.md`. + + +--- + +## 3. Sharpen pages already in the plan + +- [ ] **Model `convergence_troubleshooting.md` on TeNPy's "Protocol for using (i)DMRG" — the single best page in any of the three doc sets.** + Its structure: (1) verify the model is correct *before* trusting any run (contract the MPO to a dense operator for small N and cross-check against exact diagonalization); (2) cheap preliminary runs; (3) production runs; (4) explicit convergence confirmation. + It names concrete warning signs (non-monotonic energy or entropy, premature termination, sensitivity to parameters) and pairs each with remedies keyed to *actual config options*. + The MPSKit version should key every remedy to real keywords/algorithms (`tol`, `maxiter`, schedules of `changebonds`, switching DMRG ↔ DMRG2, unit-cell size for incommensurate order) and be honest about limits (critical states vs the area law). + +- [ ] **Spec `migration.md` + `changelog.md` concretely.** *(all three)* + Changelog entries grouped per version with **"Breaking changes" as the first section**, hyperlinks from each entry into the `lib/` page of the touched symbol (quimb does this and it turns the changelog into a "what's new to learn" feed), and issue/PR links. + Per-breaking-release upgrade guides à la ITensor (0.2→0.3→0.4), including the "run the previous version first to surface deprecation warnings" trick from TeNPy. +- [ ] **Make `index.md`'s ecosystem map an architecture diagram with drill-down.** *(TeNPy Overview)* + TeNPy's best onboarding page draws the layer stack (simulations → algorithms → networks → models → linalg) then walks each layer with a runnable snippet. + The MPSKit version is the TensorKit → MPSKit → MPSKitModels stack; each layer gets one sentence plus one line of code, ending with explicit "where next" routing. +- [ ] **Cite theory out, don't re-derive it, in `concepts/` pages.** *(TeNPy + ITensor)* + TeNPy delegates derivations to the Hauschild–Pollmann lecture notes; ITensor delegates to tensornetwork.org; both keep package docs lean and give readers an authoritative "why". + MPSKit has a natural companion in the tangent-space lecture notes (Vanderstraeten–Haegeman–Verstraete, SciPost Phys. Lect. Notes 7) — concept pages should follow the pattern "physics concept → why it matters computationally → exact API mapping → pitfalls" and cite the notes for the derivations. + +- [ ] **Systematic bidirectional cross-linking between layers.** *(TeNPy)* + TeNPy's `dmrg` module reference links *up* to the DMRG-protocol guide; guide pages link down to class references. + Adopt as a checklist rule per page: every `lib/` category page links to its how-to and concept page and vice versa (Documenter `@ref`s, already the convention — the delta is doing it *systematically*, including from docstrings in `src/`). + +--- + +## 4. Plan additions (maintainer sign-off needed) + +- [ ] **A symptom-first Troubleshooting & FAQ page, separate from convergence troubleshooting.** + *(TeNPy `troubleshooting.html` + ITensor's FAQ sidebar sections)* + Headings phrased as symptoms — "I get an error when …", "the run is much slower than expected", "results changed after updating" — covering environment issues (threading/BLAS), precompilation latency, and common TensorKit space mismatches. + FAQ sections capture forum-shaped knowledge before it has to be asked; symptom-first headings match how users search. +- [ ] **A failure-mode example page.** *(TeNPy's "Why you need the Mixer in DMRG" notebook)* + An example whose entire point is a documented failure and its fix — e.g. single-site DMRG/VUMPS getting stuck at fixed bond dimension and how `changebonds`/two-site variants escape, shown with real (bad and good) convergence curves. + Teaching a failure mode is more convincing than asserting a best practice. + +- [ ] **An algorithm-options ("all the knobs") reference.** *(TeNPy's Config system — their reference layer's standout)* + TeNPy auto-generates per-class options tables, marks inherited options with their origin, and maintains two global config indices; options are the *real* API surface of a physics code. + MPSKit analogue: every algorithm struct's `lib/` entry gets a complete keyword table (meaning, default, when to touch it), shared knobs (`tol`, `maxiter`, `verbosity`) documented once and referenced, plus one index page listing every keyword across all algorithms. + Start manual; consider generating from the structs later. +- [ ] **Document extension points with a reference page + paired recipe.** *(ITensor's Observer system docs)* + ITensor documents its observer contract (what you may access, when hooks fire, result shapes) *and* ships a worked custom-observer recipe. + MPSKit analogue: whatever hooks actually exist (e.g. the `finalize!` machinery, custom `changebonds` schedules, swapping Krylov solvers via alg structs) — each gets both a `lib/` contract description and a how-to recipe. + Hard rule 1 applies doubly here: establish the real hook API via `api-explorer` before writing a word. +- [ ] **A "Papers using MPSKit" page.** *(TeNPy: ~311 papers; ITensor: ~800+)* + Social proof, a discovery tool ("someone already did my model"), and a motivation loop for maintainers; populated via a GitHub issue template so it costs contributors one click. + Group by topic or year from day one — TeNPy's flat chronological list of 311 entries has become unnavigable. + Pairs with the planned `citing.md`: zero-friction BibTeX directly feeds this page. +- [ ] **A curated, opinionated literature page.** *(TeNPy `literature.html`)* + Beyond the planned DocumenterCitations `references.md`: a short curated section with categories (introductions, algorithm papers, reviews, lecture notes) and one-line guidance ("start here", "encyclopedic but long"), so every `[cite]` in the docs resolves somewhere useful. +- [ ] **Designate one Q&A surface and link it from every page footer.** *(ITensor Discourse)* + ITensor's forum has a "DMRG and Numerical Methods" category distinct from library questions — the forum hosts "is my physics right?" and its Google-indexed threads become permanent long-tail documentation. + For MPSKit that likely means GitHub Discussions with a methods category; the docs action is a consistent "where to ask" pointer plus a habit of harvesting recurring questions back into the FAQ page. + + +--- + +## 5. Needs package work first + +- [ ] **Rich terminal display of states: bond dimensions + canonical form at a glance.** *(quimb's `.show()` — the single cheapest-per-payoff idea in the review)* + quimb prints an ASCII schematic of an MPS with bond dimensions and orthogonality-center arrows; it renders in terminals, docstrings, and docs alike with zero dependencies, and the docs use it on nearly every page to *show* the object being discussed. + An `MPS`/`show` method (or a `summary`-style function) printing per-bond dimensions and gauge structure would let every tutorial *display* what `FiniteMPS` did instead of describing it. +- [ ] **A self-illustrating docs culture.** *(quimb throughout; tensornetwork.org's diagram-heavy style)* + quimb draws the tensor network under discussion, inline, on essentially every guide page — the docs double as the gallery for the visualization feature. + Short of full TN drawing, MPSKit pages can standardize cheap plots where they teach: entanglement spectra, bond-dimension profiles along the chain, convergence-vs-sweep curves; concepts pages need actual tensor-diagram figures (static SVGs are fine). +- [ ] **Interop examples as first-class docs.** *(quimb's torch/jax/flax pages)* + Examples embedding MPSKit in the wider ecosystem: JLD2/HDF5 serialization round-trip (feeds the planned `saving_loading.md`), CUDA.jl usage (marked experimental per hard rule 5), DifferentialEquations/Optimisers-style composition if and only if it genuinely works. + Signals ecosystem citizenship and gets indexed by searches for the *other* package. + +--- + +## 6. Anti-patterns observed (do not copy) + +- **Mega-pages.** TeNPy's `np_conserved` intro is ~4000 lines mixing what a beginner must know with internal storage formats; split beginner path from internals across pages (directly relevant to how `symmetries.md` + `vector_spaces.md` get scoped). +- **Dead source listings.** Example code rendered without executed output (TeNPy scripts/toycodes) rots invisibly and teaches nothing about what running it looks like. +- **Committed rather than build-time-executed outputs** (quimb) — same rot, one level up. +- **Type-of-page ambiguity in the nav.** TeNPy's "Introductions" heading hides how-to, explanation, and reference under one label; users can't tell what kind of page they're clicking into. +- **Multi-site fragmentation and duplicated content.** ITensor's five loosely-joined surfaces scatter search results, and every C++/Julia duplicated formula ages independently. +- **Package-split churn breaking documented examples.** The ITensors.jl → ITensorMPS.jl extraction invalidated years of `using ITensors`-only snippets; when MPSKit moves API across package boundaries, budget an upgrade guide in the same PR. +- **Bare example indices** (quimb) and **flat unnavigable community lists** (TeNPy's papers page) — annotate and group from the start. +- **Landing pages without code** (quimb, TeNPy) — the plan's `index.md` example is the fix; don't let it get cut for space. + +--- + +## Appendix: what each library is best at (one paragraph each) + +**quimb** — presentation and immediacy. +Executed-notebook guides with real convergence output on every page, a self-illustrating `draw()`/`.show()` culture, a clean furo theme with dark mode and copy buttons, capability-grouped install instructions, and a changelog that hyperlinks into the API reference. +Weakest at: conceptual explanation (physics is assumed, never explained), example-index curation, and URL stability. + +**TeNPy** — pedagogy and the options layer. +The DMRG-protocol methodology page, physics-pedagogy introductions that map every concept to an API object (Jordan-Wigner, charge conservation), a summer-school teaching track (toycodes + exercises + solutions + Colab), the Config/options system with per-class option tables and global indices, symptom-first troubleshooting, and the literature + papers-using pages. +Weakest at: page scoping (monoliths), landing page/README (no code), page-type labeling, and dead script listings. + +**ITensor** — onboarding and the how-to layer. +Flagship DMRG with real output on the landing page, imperative task-titled code formulas that double as a search-term FAQ, first-class FAQ/upgrade-guide/operational docs (clusters, memory, HDF5), documented extension points (observers), a one-sentence design thesis repeated everywhere, and the citing → papers-using growth loop plus a methods-friendly Discourse. +Weakest at: fragmentation across five sites, C++/Julia duplication, and reference gaps for constructors. + +### Key source pages + +- TeNPy DMRG protocol: https://tenpy.readthedocs.io/en/latest/intro/dmrg-protocol.html +- TeNPy options system: https://tenpy.readthedocs.io/en/latest/intro/options.html +- TeNPy troubleshooting: https://tenpy.readthedocs.io/en/latest/troubleshooting.html +- TeNPy literature: https://tenpy.readthedocs.io/en/latest/literature.html +- quimb 1D algorithms (the `.show()` + real-output pattern): https://quimb.readthedocs.io/en/latest/tensor/tensor-1d.html +- quimb design/data-model explanation page: https://quimb.readthedocs.io/en/latest/tensor/tensor-design.html +- ITensor code formulas: https://itensor.org/docs.cgi?page=formulas +- ITensorMPS.jl landing page (DMRG on page one): https://itensor.github.io/ITensorMPS.jl/dev/ +- ITensorMPS.jl recipe pages: https://itensor.github.io/ITensorMPS.jl/dev/examples/DMRG.html +- tensornetwork.org MPS article (concept-page gold standard): https://tensornetwork.org/mps/ From 3ad7f2e0e2754e18eb993f636f5af2432fdd772c Mon Sep 17 00:00:00 2001 From: lkdvos Date: Mon, 13 Jul 2026 13:36:23 -0400 Subject: [PATCH 75/76] docs(examples): silence inline solver logs in rendered pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add verbosity = 0 to the solver calls whose stderr logs leaked into four rendered example pages: the per-momentum "Found excitations" notices (hubbard, su3-heisenberg, haldane), the GradientGrassmann CG log (hubbard), and the DMRG2 groundstate sweep log (xy-finiteT). verbosity only controls logging, so computed results, plots and the intentional "┌ Info: Groundstate energy" summaries are unchanged. The obsolete log lines are stripped from the committed index.md artifacts (an emptied excitations output block in hubbard is removed) and the same edits are mirrored into the code-only main.ipynb notebooks, so the tree matches a fresh build. bose-hubbard keeps its 2-line VUMPS convergence summary (verbosity = 2) as an intentional healthy-convergence demonstration. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../examples/dynamics/1.xy-finiteT/index.md | 4 - .../examples/dynamics/1.xy-finiteT/main.ipynb | 2 +- .../examples/excitations/0.haldane/index.md | 16 ---- .../examples/excitations/0.haldane/main.ipynb | 2 +- .../excitations/1.su3-heisenberg/index.md | 10 --- .../excitations/1.su3-heisenberg/main.ipynb | 2 +- .../examples/groundstates/2.hubbard/index.md | 74 ------------------- .../groundstates/2.hubbard/main.ipynb | 6 +- examples/dynamics/1.xy-finiteT/main.jl | 2 +- examples/excitations/0.haldane/main.jl | 2 +- examples/excitations/1.su3-heisenberg/main.jl | 2 +- examples/groundstates/2.hubbard/main.jl | 6 +- 12 files changed, 12 insertions(+), 116 deletions(-) diff --git a/docs/src/examples/dynamics/1.xy-finiteT/index.md b/docs/src/examples/dynamics/1.xy-finiteT/index.md index c157158a9..65273fc52 100644 --- a/docs/src/examples/dynamics/1.xy-finiteT/index.md +++ b/docs/src/examples/dynamics/1.xy-finiteT/index.md @@ -124,10 +124,6 @@ println("Exact (N=Inf):\t", groundstate_energy(J, Inf)) ```` ```` -[ Info: DMRG2 1: obj = -5.004084869795e+00 err = 9.8826020061e-01 time = 1.04 min -[ Info: DMRG2 2: obj = -5.004096937587e+00 err = 1.1541480959e-06 time = 0.42 sec -[ Info: DMRG2 3: obj = -5.004096975044e+00 err = 2.5015824967e-09 time = 0.72 sec -[ Info: DMRG2 conv 4: obj = -5.004096975044e+00 err = 1.8118839762e-13 time = 1.07 min Numerical: -0.15637803047010948 Exact (N=32): -0.15637803047254015 Exact (N=Inf): -0.15915494309189535 diff --git a/docs/src/examples/dynamics/1.xy-finiteT/main.ipynb b/docs/src/examples/dynamics/1.xy-finiteT/main.ipynb index b6633cbb1..7527287c5 100644 --- a/docs/src/examples/dynamics/1.xy-finiteT/main.ipynb +++ b/docs/src/examples/dynamics/1.xy-finiteT/main.ipynb @@ -144,7 +144,7 @@ "V_init = symmetry === Trivial ? ℂ^32 : U1Space(i => 10 for i in -1:(1 // 2):1)\n", "psi_init = FiniteMPS(N, physicalspace(H, 1), V_init)\n", "trscheme = truncrank(D)\n", - "psi, envs, = find_groundstate(psi_init, H, DMRG2(; trscheme, maxiter = 5));\n", + "psi, envs, = find_groundstate(psi_init, H, DMRG2(; trscheme, maxiter = 5, verbosity = 0));\n", "E_0 = expectation_value(psi, H, envs) / N\n", "\n", "println(\"Numerical:\\t\", real(E_0))\n", diff --git a/docs/src/examples/excitations/0.haldane/index.md b/docs/src/examples/excitations/0.haldane/index.md index d2ba848bb..32e03b360 100644 --- a/docs/src/examples/excitations/0.haldane/index.md +++ b/docs/src/examples/excitations/0.haldane/index.md @@ -136,22 +136,6 @@ println("minimum @k = $(kspace[idx]):\t ΔE = $(ΔE)") ```` ```` -[ Info: Found excitations for momentum = 0.0 -[ Info: Found excitations for momentum = 0.20943951023931953 -[ Info: Found excitations for momentum = 0.41887902047863906 -[ Info: Found excitations for momentum = 0.6283185307179586 -[ Info: Found excitations for momentum = 1.4660765716752369 -[ Info: Found excitations for momentum = 1.2566370614359172 -[ Info: Found excitations for momentum = 0.8377580409572781 -[ Info: Found excitations for momentum = 1.0471975511965976 -[ Info: Found excitations for momentum = 1.6755160819145563 -[ Info: Found excitations for momentum = 1.8849555921538759 -[ Info: Found excitations for momentum = 2.0943951023931953 -[ Info: Found excitations for momentum = 2.303834612632515 -[ Info: Found excitations for momentum = 2.5132741228718345 -[ Info: Found excitations for momentum = 2.9321531433504737 -[ Info: Found excitations for momentum = 2.722713633111154 -[ Info: Found excitations for momentum = 3.141592653589793 minimum @k = 3.141592653589793: ΔE = 0.41047924848831047 ```` diff --git a/docs/src/examples/excitations/0.haldane/main.ipynb b/docs/src/examples/excitations/0.haldane/main.ipynb index 2084d50d9..a2c095d53 100644 --- a/docs/src/examples/excitations/0.haldane/main.ipynb +++ b/docs/src/examples/excitations/0.haldane/main.ipynb @@ -164,7 +164,7 @@ "ψ_inf, envs_inf, delta_inf = find_groundstate(ψ₀_inf, H; verbosity = 0)\n", "\n", "kspace = range(0, π, 16)\n", - "Es, _ = excitations(H, QuasiparticleAnsatz(), kspace, ψ_inf, envs_inf; sector = SU2Irrep(1))\n", + "Es, _ = excitations(H, QuasiparticleAnsatz(), kspace, ψ_inf, envs_inf; sector = SU2Irrep(1), verbosity = 0)\n", "\n", "ΔE, idx = findmin(real.(Es))\n", "println(\"minimum @k = $(kspace[idx]):\\t ΔE = $(ΔE)\")\n", diff --git a/docs/src/examples/excitations/1.su3-heisenberg/index.md b/docs/src/examples/excitations/1.su3-heisenberg/index.md index 21d067a47..9d6168197 100644 --- a/docs/src/examples/excitations/1.su3-heisenberg/index.md +++ b/docs/src/examples/excitations/1.su3-heisenberg/index.md @@ -202,16 +202,6 @@ println("branch minimum ΔE/J = $Δ at k = $(kspace[idx])") ```` ```` -[ Info: Found excitations for momentum = 0.0 -[ Info: Found excitations for momentum = 0.3490658503988659 -[ Info: Found excitations for momentum = 0.6981317007977318 -[ Info: Found excitations for momentum = 1.0471975511965976 -[ Info: Found excitations for momentum = 1.3962634015954636 -[ Info: Found excitations for momentum = 1.7453292519943295 -[ Info: Found excitations for momentum = 2.0943951023931953 -[ Info: Found excitations for momentum = 2.443460952792061 -[ Info: Found excitations for momentum = 2.792526803190927 -[ Info: Found excitations for momentum = 3.141592653589793 branch minimum ΔE/J = -0.041856660250392086 at k = 2.0943951023931953 ```` diff --git a/docs/src/examples/excitations/1.su3-heisenberg/main.ipynb b/docs/src/examples/excitations/1.su3-heisenberg/main.ipynb index 5989a95f6..7c9958a7f 100644 --- a/docs/src/examples/excitations/1.su3-heisenberg/main.ipynb +++ b/docs/src/examples/excitations/1.su3-heisenberg/main.ipynb @@ -236,7 +236,7 @@ "source": [ "sector = SU3Irrep(2, 1, 0)\n", "kspace = range(0, π, 10)\n", - "Es, _ = excitations(H, QuasiparticleAnsatz(), kspace, ψ, envs; sector)\n", + "Es, _ = excitations(H, QuasiparticleAnsatz(), kspace, ψ, envs; sector, verbosity = 0)\n", "\n", "Δ, idx = findmin(real.(Es))\n", "println(\"branch minimum ΔE/J = $Δ at k = $(kspace[idx])\")\n", diff --git a/docs/src/examples/groundstates/2.hubbard/index.md b/docs/src/examples/groundstates/2.hubbard/index.md index 6e7f372f1..9ea4de640 100644 --- a/docs/src/examples/groundstates/2.hubbard/index.md +++ b/docs/src/examples/groundstates/2.hubbard/index.md @@ -121,8 +121,6 @@ Groundstate energy: ```` ```` -[ Info: CG: initializing with f = -4.379763091095e+00, ‖∇f‖ = 3.1534e-05 -[ Info: CG: converged after 167 iterations and time 1.75 m: f = -4.379763081900e+00, ‖∇f‖ = 9.7406e-07 ┌ Info: Groundstate energy: │ * numerical: -2.189996060974577 └ * analytic: -2.190038374277775 @@ -158,8 +156,6 @@ Groundstate energy: ```` ```` -[ Info: CG: initializing with f = -4.379692711472e+00, ‖∇f‖ = 5.7923e-05 -[ Info: CG: converged after 13 iterations and time 14.35 s: f = -4.379692712393e+00, ‖∇f‖ = 6.2087e-07 ┌ Info: Groundstate energy: │ * numerical: -2.190015347514472 └ * analytic: -2.190038374277775 @@ -197,76 +193,6 @@ E_holon, ϕ_holon = excitations( ); ```` -```` -[ Info: Found excitations for momentum = -3.141592653589793 -[ Info: Found excitations for momentum = -2.945243112740431 -[ Info: Found excitations for momentum = -2.748893571891069 -[ Info: Found excitations for momentum = -2.552544031041707 -[ Info: Found excitations for momentum = -2.356194490192345 -[ Info: Found excitations for momentum = -2.1598449493429825 -[ Info: Found excitations for momentum = -1.9634954084936207 -[ Info: Found excitations for momentum = -1.7671458676442586 -[ Info: Found excitations for momentum = -1.5707963267948966 -[ Info: Found excitations for momentum = -1.3744467859455345 -[ Info: Found excitations for momentum = -1.1780972450961724 -[ Info: Found excitations for momentum = -0.9817477042468103 -[ Info: Found excitations for momentum = -0.7853981633974483 -[ Info: Found excitations for momentum = -0.5890486225480862 -[ Info: Found excitations for momentum = -0.39269908169872414 -[ Info: Found excitations for momentum = -0.19634954084936207 -[ Info: Found excitations for momentum = 0.0 -[ Info: Found excitations for momentum = 0.19634954084936207 -[ Info: Found excitations for momentum = 0.39269908169872414 -[ Info: Found excitations for momentum = 0.5890486225480862 -[ Info: Found excitations for momentum = 0.7853981633974483 -[ Info: Found excitations for momentum = 0.9817477042468103 -[ Info: Found excitations for momentum = 1.1780972450961724 -[ Info: Found excitations for momentum = 1.3744467859455345 -[ Info: Found excitations for momentum = 1.5707963267948966 -[ Info: Found excitations for momentum = 1.7671458676442586 -[ Info: Found excitations for momentum = 1.9634954084936207 -[ Info: Found excitations for momentum = 2.1598449493429825 -[ Info: Found excitations for momentum = 2.356194490192345 -[ Info: Found excitations for momentum = 2.552544031041707 -[ Info: Found excitations for momentum = 2.748893571891069 -[ Info: Found excitations for momentum = 2.945243112740431 -[ Info: Found excitations for momentum = 3.141592653589793 -[ Info: Found excitations for momentum = -3.141592653589793 -[ Info: Found excitations for momentum = -2.945243112740431 -[ Info: Found excitations for momentum = -2.748893571891069 -[ Info: Found excitations for momentum = -2.552544031041707 -[ Info: Found excitations for momentum = -2.356194490192345 -[ Info: Found excitations for momentum = -2.1598449493429825 -[ Info: Found excitations for momentum = -1.9634954084936207 -[ Info: Found excitations for momentum = -1.7671458676442586 -[ Info: Found excitations for momentum = -1.5707963267948966 -[ Info: Found excitations for momentum = -1.3744467859455345 -[ Info: Found excitations for momentum = -1.1780972450961724 -[ Info: Found excitations for momentum = -0.9817477042468103 -[ Info: Found excitations for momentum = -0.7853981633974483 -[ Info: Found excitations for momentum = -0.5890486225480862 -[ Info: Found excitations for momentum = -0.39269908169872414 -[ Info: Found excitations for momentum = -0.19634954084936207 -[ Info: Found excitations for momentum = 0.0 -[ Info: Found excitations for momentum = 0.19634954084936207 -[ Info: Found excitations for momentum = 0.39269908169872414 -[ Info: Found excitations for momentum = 0.5890486225480862 -[ Info: Found excitations for momentum = 0.7853981633974483 -[ Info: Found excitations for momentum = 0.9817477042468103 -[ Info: Found excitations for momentum = 1.1780972450961724 -[ Info: Found excitations for momentum = 1.3744467859455345 -[ Info: Found excitations for momentum = 1.5707963267948966 -[ Info: Found excitations for momentum = 1.7671458676442586 -[ Info: Found excitations for momentum = 1.9634954084936207 -[ Info: Found excitations for momentum = 2.1598449493429825 -[ Info: Found excitations for momentum = 2.356194490192345 -[ Info: Found excitations for momentum = 2.552544031041707 -[ Info: Found excitations for momentum = 2.748893571891069 -[ Info: Found excitations for momentum = 2.945243112740431 -[ Info: Found excitations for momentum = 3.141592653589793 - -```` - Again, we can compare the numerical results to the analytic solution. Here, the formulae for the excitation energies are expressed in terms of dressed momenta: diff --git a/docs/src/examples/groundstates/2.hubbard/main.ipynb b/docs/src/examples/groundstates/2.hubbard/main.ipynb index a204f45d3..e2b0ec26b 100644 --- a/docs/src/examples/groundstates/2.hubbard/main.ipynb +++ b/docs/src/examples/groundstates/2.hubbard/main.ipynb @@ -127,7 +127,7 @@ " psi, = find_groundstate(\n", " psi, H,\n", " VUMPS(; tol = svalue / 100, verbosity, maxiter = 100) &\n", - " GradientGrassmann(; tol = svalue / 1000)\n", + " GradientGrassmann(; tol = svalue / 1000, verbosity)\n", " )\n", "\n", " return psi\n", @@ -214,13 +214,13 @@ "spinon_charge = FermionParity(0) ⊠ U1Irrep(0) ⊠ SU2Irrep(1 // 2)\n", "E_spinon, ϕ_spinon = excitations(\n", " H_u1_su2, alg, momenta, psi_AB, envs_AB, psi_BA, envs_BA;\n", - " sector = spinon_charge, num = 1\n", + " sector = spinon_charge, num = 1, verbosity = 0\n", ");\n", "\n", "holon_charge = FermionParity(1) ⊠ U1Irrep(-1) ⊠ SU2Irrep(0)\n", "E_holon, ϕ_holon = excitations(\n", " H_u1_su2, alg, momenta, psi_AB, envs_AB, psi_BA, envs_BA;\n", - " sector = holon_charge, num = 1\n", + " sector = holon_charge, num = 1, verbosity = 0\n", ");" ] }, diff --git a/examples/dynamics/1.xy-finiteT/main.jl b/examples/dynamics/1.xy-finiteT/main.jl index 6b66b05c5..1c913060d 100644 --- a/examples/dynamics/1.xy-finiteT/main.jl +++ b/examples/dynamics/1.xy-finiteT/main.jl @@ -94,7 +94,7 @@ D = 64 V_init = symmetry === Trivial ? ℂ^32 : U1Space(i => 10 for i in -1:(1 // 2):1) psi_init = FiniteMPS(N, physicalspace(H, 1), V_init) trscheme = truncrank(D) -psi, envs, = find_groundstate(psi_init, H, DMRG2(; trscheme, maxiter = 5)); +psi, envs, = find_groundstate(psi_init, H, DMRG2(; trscheme, maxiter = 5, verbosity = 0)); E_0 = expectation_value(psi, H, envs) / N println("Numerical:\t", real(E_0)) diff --git a/examples/excitations/0.haldane/main.jl b/examples/excitations/0.haldane/main.jl index 98ac72a0e..8ce58e3cf 100644 --- a/examples/excitations/0.haldane/main.jl +++ b/examples/excitations/0.haldane/main.jl @@ -106,7 +106,7 @@ virtual_space_inf = Rep[SU₂](1 // 2 => 16, 3 // 2 => 16, 5 // 2 => 8, 7 // 2 = ψ_inf, envs_inf, delta_inf = find_groundstate(ψ₀_inf, H; verbosity = 0) kspace = range(0, π, 16) -Es, _ = excitations(H, QuasiparticleAnsatz(), kspace, ψ_inf, envs_inf; sector = SU2Irrep(1)) +Es, _ = excitations(H, QuasiparticleAnsatz(), kspace, ψ_inf, envs_inf; sector = SU2Irrep(1), verbosity = 0) ΔE, idx = findmin(real.(Es)) println("minimum @k = $(kspace[idx]):\t ΔE = $(ΔE)") diff --git a/examples/excitations/1.su3-heisenberg/main.jl b/examples/excitations/1.su3-heisenberg/main.jl index ff6d705d0..3c244f281 100644 --- a/examples/excitations/1.su3-heisenberg/main.jl +++ b/examples/excitations/1.su3-heisenberg/main.jl @@ -152,7 +152,7 @@ reflection). sector = SU3Irrep(2, 1, 0) kspace = range(0, π, 10) -Es, _ = excitations(H, QuasiparticleAnsatz(), kspace, ψ, envs; sector) +Es, _ = excitations(H, QuasiparticleAnsatz(), kspace, ψ, envs; sector, verbosity = 0) Δ, idx = findmin(real.(Es)) println("branch minimum ΔE/J = $Δ at k = $(kspace[idx])") diff --git a/examples/groundstates/2.hubbard/main.jl b/examples/groundstates/2.hubbard/main.jl index 3dab08047..a4c1ea9dc 100644 --- a/examples/groundstates/2.hubbard/main.jl +++ b/examples/groundstates/2.hubbard/main.jl @@ -87,7 +87,7 @@ function compute_groundstate( psi, = find_groundstate( psi, H, VUMPS(; tol = svalue / 100, verbosity, maxiter = 100) & - GradientGrassmann(; tol = svalue / 1000) + GradientGrassmann(; tol = svalue / 1000, verbosity) ) return psi @@ -154,13 +154,13 @@ envs_BA = environments(psi_BA, H_u1_su2, psi_BA); spinon_charge = FermionParity(0) ⊠ U1Irrep(0) ⊠ SU2Irrep(1 // 2) E_spinon, ϕ_spinon = excitations( H_u1_su2, alg, momenta, psi_AB, envs_AB, psi_BA, envs_BA; - sector = spinon_charge, num = 1 + sector = spinon_charge, num = 1, verbosity = 0 ); holon_charge = FermionParity(1) ⊠ U1Irrep(-1) ⊠ SU2Irrep(0) E_holon, ϕ_holon = excitations( H_u1_su2, alg, momenta, psi_AB, envs_AB, psi_BA, envs_BA; - sector = holon_charge, num = 1 + sector = holon_charge, num = 1, verbosity = 0 ); md""" From 62503ab62e8cb0d7e55e5c2d0dda2108fe32f751 Mon Sep 17 00:00:00 2001 From: lkdvos Date: Mon, 13 Jul 2026 22:04:44 -0400 Subject: [PATCH 76/76] docs: flesh out lib/public.md, add README positioning, clean stale cross-refs Add one-line descriptions to each lib/public.md category so it reads as a curated surface instead of a bare symbol list, add a short "How MPSKit compares" section to the README, and remove dead maintainer comments left over from the restructure (a resolved TODO(link) cross-reference, now wired via a real @id/@ref anchor on the examples gallery). --- README.md | 14 ++++++++++++++ docs/src/examples/index.md | 2 +- docs/src/lib/public.md | 22 ++++++++++++++++++++++ docs/src/tutorials/excitations.md | 4 ---- docs/src/tutorials/using_symmetries.md | 7 +------ 5 files changed, 38 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 437dfd5bd..b61972425 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,20 @@ Questions and general discussion are welcome on [GitHub Discussions](https://github.com/QuantumKitHub/MPSKit.jl/discussions); if you think you have found a bug, please open an issue. +## How MPSKit compares + +Finite and infinite systems are one interface, not two. +`FiniteMPS` and `InfiniteMPS` share the same algorithms, so a calculation moves from a +finite chain to the thermodynamic limit with a one-line change, as the two examples below +show. +Symmetries are first-class rather than an add-on: abelian, non-abelian, fermionic, and +anyonic symmetries are all available through the [TensorKit.jl](https://github.com/jutho/TensorKit.jl) +backend, including symmetry groups that most tensor-network codebases do not support at +all. +The whole toolbox — states, operators, and algorithms — is native Julia and composes +directly with the TensorKit ecosystem, so extending it does not mean dropping into a +different language. + ## Installation The package can be installed through the Julia general registry, via the package manager: diff --git a/docs/src/examples/index.md b/docs/src/examples/index.md index a88b9368c..c1fe9ad9b 100644 --- a/docs/src/examples/index.md +++ b/docs/src/examples/index.md @@ -1,4 +1,4 @@ -# Examples +# [Examples](@id examples_index) This gallery collects the full worked examples that ship with MPSKit.jl. Each one is a complete, runnable script (also available as a Jupyter notebook, linked from the example page itself) that goes well beyond the short snippets in the how-to guides. diff --git a/docs/src/lib/public.md b/docs/src/lib/public.md index c8e5fd8b9..788c269d1 100644 --- a/docs/src/lib/public.md +++ b/docs/src/lib/public.md @@ -10,44 +10,66 @@ The category reference pages ([States](@ref lib_states), [Operators](@ref lib_op ## States +The matrix product state types — finite, infinite, windowed, and multi-line. + [`FiniteMPS`](@ref), [`InfiniteMPS`](@ref), [`WindowMPS`](@ref), [`MultilineMPS`](@ref) ## Operators and Hamiltonians +Matrix product operators and Hamiltonians, finite and infinite, plus the wrappers used to build time-dependent and summed operators. + [`AbstractMPO`](@ref), [`MPO`](@ref), [`FiniteMPO`](@ref), [`InfiniteMPO`](@ref), [`MultilineMPO`](@ref), [`MPOHamiltonian`](@ref), [`FiniteMPOHamiltonian`](@ref), [`InfiniteMPOHamiltonian`](@ref), [`JordanMPOTensor`](@ref), [`MultipliedOperator`](@ref), [`TimedOperator`](@ref), [`UntimedOperator`](@ref), [`LazySum`](@ref) ## Environments +The caches that store partially contracted tensor networks and are reused throughout the algorithms; see the concept page on [Environments](@ref concept_environments) for why they exist. + [`environments`](@ref) ## Ground states and boundaries +The ground-state search and 2D leading-boundary interface, and the DMRG/VUMPS/IDMRG family of algorithms that implement it. + [`find_groundstate`](@ref), [`leading_boundary`](@ref), [`approximate`](@ref), [`VUMPS`](@ref), [`VOMPS`](@ref), [`DMRG`](@ref), [`DMRG2`](@ref), [`IDMRG`](@ref), [`IDMRG2`](@ref), [`GradientGrassmann`](@ref) ## Bond dimension +Expanding or truncating a state's virtual spaces, and the algorithms that drive it. + [`changebonds`](@ref), [`OptimalExpand`](@ref), [`RandExpand`](@ref), [`SvdCut`](@ref), [`VUMPSSvdCut`](@ref) ## Time evolution +Real- and imaginary-time evolution drivers and the algorithms and MPO approximations that implement them. + [`time_evolve`](@ref), [`timestep`](@ref), [`make_time_mpo`](@ref), [`TDVP`](@ref), [`TDVP2`](@ref), [`WI`](@ref), [`WII`](@ref), [`TaylorCluster`](@ref) ## Excitations +The excitation interface and the quasiparticle-ansatz and finite-excited-state algorithms that produce excited states on top of a ground state. + [`excitations`](@ref), [`FiniteExcited`](@ref), [`QuasiparticleAnsatz`](@ref), [`ChepigaAnsatz`](@ref), [`ChepigaAnsatz2`](@ref) ## Linear problems and spectral functions +Solving the MPS linear problems behind dynamical/spectral quantities, such as propagators and susceptibilities. + [`propagator`](@ref), [`DynamicalDMRG`](@ref), [`NaiveInvert`](@ref), [`Jeckelmann`](@ref), [`exact_diagonalization`](@ref), [`fidelity_susceptibility`](@ref) ## Observables and analysis +Extracting physical quantities and analysis diagnostics from an MPS — expectation values, correlators, spectra, and entanglement. + [`expectation_value`](@ref), [`correlator`](@ref), [`variance`](@ref), [`correlation_length`](@ref), [`marek_gap`](@ref), [`transfer_spectrum`](@ref), [`entropy`](@ref), [`entanglement_spectrum`](@ref) ## Boundary conditions +Converting an infinite MPO into a finite one of a given length, either wrapping it (periodic) or truncating it (open). + [`open_boundary_conditions`](@ref), [`periodic_boundary_conditions`](@ref) ## Utility +Periodic and windowed array containers, virtual/physical space accessors, and a compact "braille" visualization of an MPO's sparsity structure. + [`PeriodicArray`](@ref), [`PeriodicVector`](@ref), [`PeriodicMatrix`](@ref), [`WindowArray`](@ref), [`left_virtualspace`](@ref), [`right_virtualspace`](@ref), [`physicalspace`](@ref), [`braille`](@ref) diff --git a/docs/src/tutorials/excitations.md b/docs/src/tutorials/excitations.md index 4ab533c41..a34346485 100644 --- a/docs/src/tutorials/excitations.md +++ b/docs/src/tutorials/excitations.md @@ -103,7 +103,3 @@ You have computed a full dispersion relation on top of an infinite ground state The [`excitations`](@ref) entry point can do considerably more than what we used here: it can target excitations carrying a nontrivial symmetry charge, build topological (domain-wall) excitations that interpolate between two different ground states, and compute excited states of *finite* chains, where momentum is no longer a good quantum number and different algorithms take over. All of these are recipes in [Excited states](@ref howto_excitations). For what each excitation algorithm actually does and when to choose it, see the library reference [Excitations](@ref lib_excitations). - - diff --git a/docs/src/tutorials/using_symmetries.md b/docs/src/tutorials/using_symmetries.md index 220dacce3..653737a00 100644 --- a/docs/src/tutorials/using_symmetries.md +++ b/docs/src/tutorials/using_symmetries.md @@ -166,16 +166,11 @@ You have run the flagship TFIM calculation with its ``\mathbb{Z}_2`` symmetry ma The same syntax scales up to larger symmetry groups, where the payoff grows. For a U(1) symmetry (particle number, magnetization) the graded spaces list integer or half-integer charges instead of parities — worked constructions are in [Constructing states](@ref howto_states), Section 9. -For non-abelian symmetries such as SU(2) the gains are more dramatic still, because each symmetric block then represents an entire multiplet of states; the spin-1 Haldane chain and XXZ Heisenberg pages in the examples gallery show this in action. +For non-abelian symmetries such as SU(2) the gains are more dramatic still, because each symmetric block then represents an entire multiplet of states; the spin-1 Haldane chain and XXZ Heisenberg pages in the [examples gallery](@ref examples_index) show this in action. To continue the tutorial track, [Quasiparticle excitations](@ref tutorial_excitations) develops the excitation calculation of Section 4 into a full dispersion relation; the recipe collection for excited states is [Excited states](@ref howto_excitations), and the one for building symmetric states is [Constructing states](@ref howto_states).