diff --git a/CITATION.cff b/CITATION.cff index edb2b2ac9..4619b26c0 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -12,9 +12,9 @@ authors: orcid: "https://orcid.org/0000-0002-0858-291X" title: "MPSKit" -version: 0.13.13 +version: 0.14.0 doi: 10.5281/zenodo.10654900 -date-released: 2026-06-09 +date-released: 2026-10-05 url: "https://github.com/QuantumKitHub/MPSKit.jl" references: diff --git a/Project.toml b/Project.toml index 6cedf7583..6ea720fb6 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "MPSKit" uuid = "bb1c41ca-d63c-52ed-829e-0820dda26502" -version = "0.13.13" +version = "0.14.0" authors = "Lukas Devos, Maarten Van Damme and contributors" [workspace] diff --git a/docs/Project.toml b/docs/Project.toml index 87a66b634..b23a99f72 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -8,11 +8,11 @@ DocumenterVitepress = "4710194d-e776-4893-9690-8d956a29c365" KrylovKit = "0b1a1467-8014-51b9-945f-bf0ae24f4b77" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" MPSKit = "bb1c41ca-d63c-52ed-829e-0820dda26502" -MPSKitModels = "ca635005-6f8c-4cd1-b51d-8491250ef2ab" 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] @@ -23,3 +23,4 @@ Documenter = "1.11" DocumenterCitations = "1.5" DocumenterInterLinks = "1" DocumenterVitepress = "0.3.7" +TensorKitTensors = "0.3.1" diff --git a/docs/make.jl b/docs/make.jl index 710318cab..582b21dbc 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -12,6 +12,7 @@ using DocumenterVitepress using DocumenterCitations using DocumenterInterLinks include("overrides.jl") +include("src/assets/models.jl") # examples example_dir = joinpath(@__DIR__, "src", "examples") @@ -48,8 +49,7 @@ links = InterLinks( "TensorOperations" => "https://quantumkithub.github.io/TensorOperations.jl/stable/", "KrylovKit" => "https://jutho.github.io/KrylovKit.jl/stable/", "BlockTensorKit" => "https://quantumkithub.github.io/BlockTensorKit.jl/dev/", - "MatrixAlgebraKit" => "https://quantumkithub.github.io/MatrixAlgebraKit.jl/stable/", - "MPSKitModels" => "https://quantumkithub.github.io/MPSKitModels.jl/dev/" + "MatrixAlgebraKit" => "https://quantumkithub.github.io/MatrixAlgebraKit.jl/stable/" ) # include MPSKit in all doctests diff --git a/docs/src/assets/models.jl b/docs/src/assets/models.jl new file mode 100644 index 000000000..530e8552d --- /dev/null +++ b/docs/src/assets/models.jl @@ -0,0 +1,104 @@ +# Model constructors for the MPSKit documentation and examples. +# Adapted from MPSKitModels.jl v0.4.7, src/models/{hamiltonians,transfermatrices}.jl: +# https://github.com/QuantumKitHub/MPSKitModels.jl/tree/v0.4.7/src/models +# Operators come from TensorKitTensors; chain assembly uses MPSKit directly. +# +# MIT License +# Copyright (c) 2021 Maarten Van Damme +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +module ExampleModels + +using MPSKit, TensorKit +using TensorKitTensors: SpinOperators, BosonOperators, HubbardOperators + +export chain_hamiltonian, transverse_field_ising, heisenberg_XXX +export hubbard_model, bose_hubbard_model, hard_hexagon + +# L specifies an open finite chain; otherwise unitcell specifies an infinite chain. +function chain_hamiltonian(twosite, onesite = nothing; L = nothing, unitcell::Integer = 1) + nsites = isnothing(L) ? unitcell : L + nsites isa Integer && nsites > 0 || throw(ArgumentError("chain length must be a positive integer")) + nbonds = isnothing(L) ? nsites : nsites - 1 + terms = Pair[(i, i + 1) => twosite for i in 1:nbonds] + if !isnothing(onesite) + append!(terms, [i => onesite for i in 1:nsites]) + end + spaces = fill(space(twosite, 1), nsites) + constructor = isnothing(L) ? InfiniteMPOHamiltonian : FiniteMPOHamiltonian + return constructor(spaces, terms) +end + +# H = -J sum(σz_i σz_{i+1} + g σx_i). +function transverse_field_ising( + T::Type{<:Number} = ComplexF64, symmetry::Type{<:Sector} = Trivial; + J = 1.0, g = 1.0, kwargs... + ) + ZZ = 4 * SpinOperators.S_z_S_z(T, symmetry; spin = 1 // 2) + X = SpinOperators.σˣ(T, symmetry) + return chain_hamiltonian(-J * ZZ, -J * g * X; kwargs...) +end +transverse_field_ising(symmetry::Type{<:Sector}; kwargs...) = + transverse_field_ising(ComplexF64, symmetry; kwargs...) + +# H = J sum(S_i ⋅ S_{i+1}); preserve the examples' spin-1 default. +function heisenberg_XXX( + T::Type{<:Number} = ComplexF64, symmetry::Type{<:Sector} = Trivial; + J = 1.0, spin = 1, kwargs... + ) + term = J * SpinOperators.S_exchange(T, symmetry; spin) + return chain_hamiltonian(term; kwargs...) +end +heisenberg_XXX(symmetry::Type{<:Sector}; kwargs...) = + heisenberg_XXX(ComplexF64, symmetry; kwargs...) + +# H = -t sum(e⁺_i e⁻_{i+1} + h.c.) + U sum(n↑ n↓) - mu sum(n). +function hubbard_model( + T::Type{<:Number} = ComplexF64, particle_symmetry::Type{<:Sector} = Trivial, + spin_symmetry::Type{<:Sector} = Trivial; + t = 1.0, U = 1.0, mu = 0.0, kwargs... + ) + # e_hopping includes the fermionic reordering sign and is Hermitian. + hopping = HubbardOperators.e_hopping(T, particle_symmetry, spin_symmetry) + interaction = HubbardOperators.ud_num(T, particle_symmetry, spin_symmetry) + N = HubbardOperators.e_num(T, particle_symmetry, spin_symmetry) + return chain_hamiltonian(-t * hopping, U * interaction - mu * N; kwargs...) +end + +# H = -t sum(b⁺_i b⁻_{i+1} + h.c.) + U/2 sum(n(n-1)) - mu sum(n). +function bose_hubbard_model( + T::Type{<:Number} = ComplexF64, symmetry::Type{<:Sector} = Trivial; + cutoff::Integer = 5, t = 1.0, U = 1.0, mu = 0.0, kwargs... + ) + hopping = BosonOperators.b_plus_b_min(T, symmetry; cutoff) + + BosonOperators.b_min_b_plus(T, symmetry; cutoff) + N = BosonOperators.b_num(T, symmetry; cutoff) + interaction = N * (N - id(domain(N))) + return chain_hamiltonian(-t * hopping, U / 2 * interaction - mu * N; kwargs...) +end + +function hard_hexagon(T::Type{<:Number} = ComplexF64) + P = Vect[FibonacciAnyon](:τ => 1) + O = ones(T, P ⊗ P ← P ⊗ P) + block(O, FibonacciAnyon(:I)) .*= 0 + return InfiniteMPO([O]) +end + +end diff --git a/docs/src/changelog.md b/docs/src/changelog.md index c14908b1d..c0fcf73b6 100644 --- a/docs/src/changelog.md +++ b/docs/src/changelog.md @@ -17,35 +17,59 @@ When making changes to this project, please update the "Unreleased" section with When releasing a new version, move the "Unreleased" changes to a new version section with the release date. -## [Unreleased](https://github.com/QuantumKitHub/MPSKit.jl/compare/v0.13.11...HEAD) +## [Unreleased](https://github.com/QuantumKitHub/MPSKit.jl/compare/v0.14.0...HEAD) ### Added +### Changed + +### Deprecated + +### Removed + +### Fixed + +### Performance + +## [0.14.0](https://github.com/QuantumKitHub/MPSKit.jl/compare/v0.13.13...v0.14.0) - 2026-10-05 + +### Added + +- `WindowMPOHamiltonian`, enabling propagators and dynamical DMRG on `WindowMPS`. ([#417](https://github.com/QuantumKitHub/MPSKit.jl/pull/417), [#447](https://github.com/QuantumKitHub/MPSKit.jl/pull/447)) +- `SketchedExpand` for randomized controlled bond expansion in DMRG and TDVP. ([#438](https://github.com/QuantumKitHub/MPSKit.jl/pull/438), [#464](https://github.com/QuantumKitHub/MPSKit.jl/pull/464)) +- `DMRG3S` for single-site DMRG with subspace expansion and configurable noise schedules. ([#460](https://github.com/QuantumKitHub/MPSKit.jl/pull/460)) +- `leftunit`/`rightunit` for `MultilineMPS` and `MultilineMPO`. ([#453](https://github.com/QuantumKitHub/MPSKit.jl/pull/453)) +- Controlled bond expansion for finite single-site `DMRG` and `TDVP` via `alg_expand`, with configurable QR/SVD gauging through `alg_svd`, `alg_orth`, and `trunc`. ([#438](https://github.com/QuantumKitHub/MPSKit.jl/pull/438), [#460](https://github.com/QuantumKitHub/MPSKit.jl/pull/460)) +- `changebond`/`changebond!` for expanding a single finite-MPS bond in a chosen sweep direction. ([#438](https://github.com/QuantumKitHub/MPSKit.jl/pull/438)) +- A keyword-based `approximate(ψ₀, (O, ψ); tol, maxiter, verbosity, trunc)` convenience method and sequential approximation algorithms composed with `&`. ([#469](https://github.com/QuantumKitHub/MPSKit.jl/pull/469)) +- `Adapt` support for `Multiline` and `PeriodicArray` objects, including multiline MPS/MPO networks. ([#406](https://github.com/QuantumKitHub/MPSKit.jl/pull/406)) +- Custom `hasconverged` and `shouldstop` callbacks on `GradientGrassmann`. ([#510](https://github.com/QuantumKitHub/MPSKit.jl/pull/510), [#512](https://github.com/QuantumKitHub/MPSKit.jl/pull/512)) +- `DynamicTols.adapt_solver` and `AdaptiveKrylov` for adapting eigensolver tolerances and Krylov budgets to local gradients and truncation errors. ([#455](https://github.com/QuantumKitHub/MPSKit.jl/pull/455)) - Addition of `FiniteMPS`/`FiniteMPO` with different scalar types, through a new `Base.similar(ψ, ::Type{S})` for `S <: Number` on `FiniteMPS`. ([#484](https://github.com/QuantumKitHub/MPSKit.jl/pull/484)) - `Zipup`, an algorithm for `approximate`/`approximate!` that compresses a finite MPO-MPS product in a single sweep, optionally followed by a sweep in the opposite direction that imposes the final truncation. The sweep direction is selected by the `left_to_right` keyword. Both `approximate((O, ϕ), alg)` and `approximate!(ψ, (O, ϕ), alg)` are supported, where the destination - `ψ` is a write target rather than an initial guess and may alias `ϕ`; they return `(ψ, info)`. + `ψ` is a write target rather than an initial guess and may alias `ϕ`; they return `(ψ, info)`. ([#470](https://github.com/QuantumKitHub/MPSKit.jl/pull/470), [#513](https://github.com/QuantumKitHub/MPSKit.jl/pull/513)) - `BUG` time-evolution algorithm: a Basis-Update & Galerkin integrator for finite MPS. Unlike `TDVP` it has no backward-in-time substep (stable for imaginary-time evolution), and passing a truncating `trunc` enables rank-adaptivity (the bond dimension grows and shrinks - automatically to track entanglement). + automatically to track entanglement). ([#468](https://github.com/QuantumKitHub/MPSKit.jl/pull/468)) - A `backend` setting on every algorithm, for its tensor contractions and index manipulations, defaulting to `MPSKit.Defaults.backend()`. ([#467](https://github.com/QuantumKitHub/MPSKit.jl/pull/467)) - Local updates now serve their intermediate tensors from a dedicated allocator, selected internally by `MPSKit.default_allocator`, instead of leaving them to the garbage collector (two-site DMRG: -64% allocations, -57% GC time, -23% wall time). Disable with `MPSKit.Defaults.set_buffering!(false)`. ([#467](https://github.com/QuantumKitHub/MPSKit.jl/pull/467)) -- Custom `show`/`summary` for `MultilineMPS`/`MultilineMPO`. Each row is now rendered via each row's own display, and row shifting is shown explicitly for `MultilineMPO`. +- Custom `show`/`summary` for `MultilineMPS`/`MultilineMPO`. Each row is now rendered via each row's own display, and row shifting is shown explicitly for `MultilineMPO`. ([#508](https://github.com/QuantumKitHub/MPSKit.jl/pull/508)) - `*(::MultilineMPO, ::InfiniteMPS)`, which pushes the boundary MPS through every row of the - network in turn, advancing it by one full period. + network in turn, advancing it by one full period. ([#508](https://github.com/QuantumKitHub/MPSKit.jl/pull/508)) - `leading_eigenvalue(ψ, O, [environments])`, the eigenvalue of the transfer operator `O` for the boundary MPS `ψ`, i.e. the partition function density. - `expectation_value(::InfiniteMPS, ::InfiniteMPO)` forwards here. + `expectation_value(::InfiniteMPS, ::InfiniteMPO)` forwards here. ([#508](https://github.com/QuantumKitHub/MPSKit.jl/pull/508)) - `InfiniteMultilineMPS`/`FiniteMultilineMPS` and `InfiniteMultilineMPO`/`FiniteMultilineMPO` - aliases for multiline objects with infinite or finite lines. + aliases for multiline objects with infinite or finite lines. ([#508](https://github.com/QuantumKitHub/MPSKit.jl/pull/508)) ### Changed @@ -53,14 +77,20 @@ When releasing a new version, move the "Unreleased" changes to a new version sec groups, replacing the deprecated LoggingExtras verbosity APIs. LoggingExtras 1.1 and 1.2 are supported alongside 1.0. Canonicalization now logs initialization at verbosity 2 and non-convergence warnings at verbosity 1, consistently with the other algorithms. +- `DMRG`/`DMRG2` use Galerkin error for convergence and `AdaptiveKrylov` for adaptive local eigensolvers; truncating runs can converge once the Galerkin error reaches the truncation-error floor. `FiniteExcited` perturbs its default initial guess to avoid starting at an already-converged eigenstate. ([#455](https://github.com/QuantumKitHub/MPSKit.jl/pull/455), [#512](https://github.com/QuantumKitHub/MPSKit.jl/pull/512)) +- `JordanMPOTensor` now stores non-identity blocks and scalar identity contributions separately, with revised type parameters and constructors. ([#444](https://github.com/QuantumKitHub/MPSKit.jl/pull/444)) +- Dependency compatibility now includes OptimKit 0.5 and VectorInterface 0.7; OptimKit 0.3 is no longer supported. ([#456](https://github.com/QuantumKitHub/MPSKit.jl/pull/456), [#460](https://github.com/QuantumKitHub/MPSKit.jl/pull/460), [#530](https://github.com/QuantumKitHub/MPSKit.jl/pull/530)) +- Environment solver settings are forwarded more consistently through VUMPS/VOMPS, lazy sums, and quasiparticle calculations; gauge updates honor the configured orthogonalization algorithm. ([#436](https://github.com/QuantumKitHub/MPSKit.jl/pull/436)) +- Hamiltonian matrix constructors accept `AbstractMatrix` entries, and `similar` for MPOs and MPO Hamiltonians also accepts a storage type. ([#406](https://github.com/QuantumKitHub/MPSKit.jl/pull/406)) +- Raised minimum TensorKit and TensorOperations versions to 0.17.1 and 5.6.2, respectively. ([#444](https://github.com/QuantumKitHub/MPSKit.jl/pull/444), [#467](https://github.com/QuantumKitHub/MPSKit.jl/pull/467)) - `FiniteMPOHamiltonian`/`InfiniteMPOHamiltonian` constructed from a set of local terms now share virtual channels between terms that start out with the same operators, up to a scalar factor, and add up terms that are linearly dependent. The resulting Hamiltonian is unchanged, but its bond dimension is generally smaller ([#518](https://github.com/QuantumKitHub/MPSKit.jl/pull/518)) - `find_groundstate(!)`, `leading_boundary`, `approximate(!)`, `timestep(!)` and `time_evolve(!)` - now have the return signature `(ψ, envs, info)` with `info` an `AlgorithmInfo` that contains + now return diagnostics through `AlgorithmInfo` (normally `(ψ, envs, info)`; `Zipup` returns `(ψ, info)`). The `info` object contains diagnostics about the run and convergence. See the updated docs or `AlgorithmInfo`'s - docstring for more information. ([#512](https://github.com/QuantumKitHub/MPSKit.jl/pull/512)) + docstring for more information. `convergence_measure(info)` extracts the algorithm-specific stopping measure. ([#512](https://github.com/QuantumKitHub/MPSKit.jl/pull/512)) - The manual has a new section on [Errors and accuracy](@ref) covering definitions and interpretations of the various returned measures. ([#512](https://github.com/QuantumKitHub/MPSKit.jl/pull/512)) - Convergence tolerances are now compared with `<=` everywhere, so an error exactly equal to `tol` @@ -72,7 +102,7 @@ When releasing a new version, move the "Unreleased" changes to a new version sec norm is preserved, so it retains useful information (the accumulated truncation error in real time, or the decaying weight in imaginary time). Previously imaginary-time evolution always renormalized every step; **to recover that behavior, pass `normalize = true`** (e.g. for ground-state or - thermal-state search via imaginary-time evolution). + thermal-state search via imaginary-time evolution). ([#438](https://github.com/QuantumKitHub/MPSKit.jl/pull/438), [#469](https://github.com/QuantumKitHub/MPSKit.jl/pull/469)) - `environments` now follows a single positional contract for every state and operator kind: `environments(below, operator, above, alg)`, where `alg` is the environment algorithm (slot 4). The operator form requires an explicit `above`. Auxiliary inputs are keyword-only: @@ -91,48 +121,58 @@ When releasing a new version, move the "Unreleased" changes to a new version sec algorithm can be resolved per sector. The Krylov dimension adapts to the number of values requested in each sector, controlled by the new `oversampling` and `oversampling_factor` keywords. Accordingly, `marek_gap` and `correlation_length` now return a `TensorKit.SectorDict` of - per-sector results by default; pass `sector = ...` to obtain a single sector's result as before. + per-sector results by default; pass `sector = ...` to obtain a single sector's result as before. ([#452](https://github.com/QuantumKitHub/MPSKit.jl/pull/452)) - All `trscheme` keyword arguments are renamed to `trunc` ([#482](https://github.com/QuantumKitHub/MPSKit.jl/pull/482)). - `correlator` now throws an `ArgumentError` when the sites are not ordered as `i < j`. Previously such a call only logged an `@error` and then continued into a contraction that is not the requested correlator. ([#489](https://github.com/QuantumKitHub/MPSKit.jl/pull/489)) - TimerOutputs 1.x is now required. The timing tables printed at `verbosity > 3` use the new - layout (tree guides, heat bars) and additionally report per-section GC time. + layout (tree guides, heat bars) and additionally report per-section GC time. ([#495](https://github.com/QuantumKitHub/MPSKit.jl/pull/495)) - `Multiline` (and therefore `MultilineMPS`/`MultilineMPO`) now consistently behaves as a vector of the lines it stores: `length`/`size`/`axes`/`eachindex`/`eltype`/`iterate`/`m[i]` all refer to the lines, so `size(m) == (length(m),)`. Previously `length` counted `nrows * ncols` and `size` returned the `(nrows, ncols)` lattice shape. The `AL`/`AR`/`AC`/`C` views still index - the lattice as `[row, col]`. + the lattice as `[row, col]`. ([#508](https://github.com/QuantumKitHub/MPSKit.jl/pull/508)) - `MultilineMPS` lines may now be any `AbstractMPS` rather than only `InfiniteMPS`, so that for example finite multiline networks can be built and inspected. No algorithm supports them yet: `leading_boundary` only accepts an `InfiniteMultilineMPS` (and an `InfiniteMultilineMPO`). - The `AbstractMatrix` constructor that silently built finite-line `MultilineMPO`s was removed. + The `AbstractMatrix` constructor that silently built finite-line `MultilineMPO`s was removed. ([#508](https://github.com/QuantumKitHub/MPSKit.jl/pull/508)) ### Deprecated +- `DynamicTols.updatetol(alg, iter, ϵ)`; use `DynamicTols.adapt_solver(alg; iter, g_global = ϵ)` instead. ([#455](https://github.com/QuantumKitHub/MPSKit.jl/pull/455)) ### Removed -- Support for TimerOutputs 0.5. -- `expectation_value(::MultilineMPS, ::MultilineMPO, envs...)` fallback method, which silently - computed a meaningless value (`prod` instead of `sum`, no row shift, `envs` ignored) for any - `MultilineMPO` line type not covered by the guarded method, such as `InfiniteMPOHamiltonian`. -- `expectation_value` for a `MultilineMPS`/`MultilineMPO` pair entirely, replaced by `leading_eigenvalue`. +- The custom `MPSTensor` constructors; construct `TensorMap`s with explicit `TensorMapSpace`s instead. ([#475](https://github.com/QuantumKitHub/MPSKit.jl/pull/475)) +- `JordanMPOTensorMap`; use `JordanMPOTensor` instead. ([#444](https://github.com/QuantumKitHub/MPSKit.jl/pull/444)) +- Support for TimerOutputs 0.5. ([#495](https://github.com/QuantumKitHub/MPSKit.jl/pull/495)) +- `expectation_value` for a `MultilineMPS`/`MultilineMPO` pair entirely, replaced by `leading_eigenvalue`. ([#508](https://github.com/QuantumKitHub/MPSKit.jl/pull/508)) - `*(::MultilineMPO, ::MultilineMPS)` and `*(::MultilineMPO, ::MultilineMPO)`, as these - were not meaningful operations. Neither method had ever been callable previously. + were not meaningful operations. Neither method had ever been callable previously. ([#508](https://github.com/QuantumKitHub/MPSKit.jl/pull/508)) ### Fixed +- `entropy`, `entanglement_spectrum`, and `entanglementplot` now accept the left boundary (`site = 0`) of a finite MPS; the plot uses the selected bond to label its dimension. ([#504](https://github.com/QuantumKitHub/MPSKit.jl/pull/504)) +- `GradientGrassmann` preconditioning could cease to be a descent direction on nearly rank-deficient bonds; the regularized inverse is now applied in factored form. ([#532](https://github.com/QuantumKitHub/MPSKit.jl/pull/532)) +- `variance` and Hamiltonian arithmetic now support mixed scalar types; finite-state variance is evaluated using the energy-shifted Hamiltonian to reduce cancellation. ([#529](https://github.com/QuantumKitHub/MPSKit.jl/pull/529)) +- `canonicalize!` no longer raises a `SpaceMismatch` for partially decoupled Hamiltonian sites. ([#526](https://github.com/QuantumKitHub/MPSKit.jl/pull/526)) +- Infinite-MPO quasiparticle environments now use the correct bond indices when virtual spaces vary within the unit cell. ([#492](https://github.com/QuantumKitHub/MPSKit.jl/pull/492)) +- `remove_orphans!` now terminates correctly when infinite-MPO virtual channels stop changing. ([#485](https://github.com/QuantumKitHub/MPSKit.jl/pull/485)) +- `periodic_boundary_conditions` no longer raises a `SpaceMismatch` for non-self-dual virtual spaces. ([#462](https://github.com/QuantumKitHub/MPSKit.jl/pull/462)) +- `FiniteExcited` returns excitations in ascending energy order. ([#443](https://github.com/QuantumKitHub/MPSKit.jl/pull/443)) +- Precomputed bond derivatives now allocate contractions consistently with TensorKit multifusion space checks. ([#528](https://github.com/QuantumKitHub/MPSKit.jl/pull/528)) +- `time_evolve` logging no longer references an undefined time or passes integer placeholders to floating-point logging methods. ([#469](https://github.com/QuantumKitHub/MPSKit.jl/pull/469), [#515](https://github.com/QuantumKitHub/MPSKit.jl/pull/515)) +- MPO multiplication, physical-charge insertion, and Jordan-tensor scalar conversion preserve GPU storage instead of constructing CPU intermediates. ([#406](https://github.com/QuantumKitHub/MPSKit.jl/pull/406), [#444](https://github.com/QuantumKitHub/MPSKit.jl/pull/444)) - `changebonds(::FiniteMPO, ::SvdCut)` truncated long chains down to a zero operator. It now gauges in a separate sweep, spreads the operator norm evenly over the sites, and truncates against the - per-bond reference scale `‖O‖^(2/length(mpo))`. + per-bond reference scale `‖O‖^(2/length(mpo))`. ([#519](https://github.com/QuantumKitHub/MPSKit.jl/pull/519)) - `changebonds(::FiniteMPOHamiltonian, ::SvdCut)` threw a `BoundsError` for Hamiltonians with - long-range terms. -- `SvdCut` now warns when a truncation empties a bond, instead of silently returning a zero operator. -- `isfinite(::WindowMPOHamiltonian)` was undefined. ([#489](https://github.com/QuantumKitHub/MPSKit.jl/pull/489)) + long-range terms. ([#519](https://github.com/QuantumKitHub/MPSKit.jl/pull/519)) +- `SvdCut` now warns when a truncation empties a bond, instead of silently returning a zero operator. ([#519](https://github.com/QuantumKitHub/MPSKit.jl/pull/519)) - `checkbounds` on the `AL`/`AR`/`AC`/`C` views of a `Multiline` now delegates the column to the matching tensors of a line, and accepts any row due to periodicity. - `checkbounds(Bool, ::PeriodicArray, I...)` now also accepts any index, matching `getindex`. -- `size`/`axes` for a `CView` over a `Multiline` with finite lines were missing. + `checkbounds(Bool, ::PeriodicArray, I...)` now also accepts any index, matching `getindex`. ([#508](https://github.com/QuantumKitHub/MPSKit.jl/pull/508)) +- `size`/`axes` for a `CView` over a `Multiline` with finite lines were missing. ([#508](https://github.com/QuantumKitHub/MPSKit.jl/pull/508)) - `excitations(::InfiniteMPO, ::QuasiparticleAnsatz, ::InfiniteQP, lenvs, renvs)` referenced `H_eff` before assigning. ([#489](https://github.com/QuantumKitHub/MPSKit.jl/pull/489)) - `Base.:+`/`-` on `FiniteMPS` returned a wrong state for near-parallel operands carried by different tensor networks, e.g. `norm(E₀ * gs - H * gs)` coming out as `2 * norm(gs) * E₀` @@ -172,21 +212,24 @@ When releasing a new version, move the "Unreleased" changes to a new version sec - Raised the `BlockTensorKit` compat lower bound to 0.3.19, which fixes a silent data-loss bug: with `TensorKit` 0.17.2 and `BlockTensorKit` <= 0.3.18, a permuted contraction into a sparse block tensor (e.g. an environment sweep near a `FiniteMPS` chain boundary when the operator and state - have different `scalartype`s) could silently drop data instead of erroring. + have different `scalartype`s) could silently drop data instead of erroring. ([#493](https://github.com/QuantumKitHub/MPSKit.jl/pull/493)) - `approximate` with `IDMRG2` on a `MultilineMPS` with more than one row wrote the right-to-left edge update into the wrong row and refreshed the unit cell edge of the first row only, so the rows ended up mixed. ([#512](https://github.com/QuantumKitHub/MPSKit.jl/pull/512)) - `leading_boundary` with `GradientGrassmann` ignored the algorithm's `hasconverged` and `shouldstop` criteria, always using the optimizer's defaults instead. ([#512](https://github.com/QuantumKitHub/MPSKit.jl/pull/512)) - `isfinite(::MultilineMPO)` threw (`isfinite(typeof(m))` had no matching type-level method for - `Multiline`). + `Multiline`). ([#508](https://github.com/QuantumKitHub/MPSKit.jl/pull/508)) - `changebonds(::MultilineMPO, ::SvdCut)` threw (`convert(MultilineMPS, ::MultilineMPO)` has no - method). + method). ([#508](https://github.com/QuantumKitHub/MPSKit.jl/pull/508)) - `axes(m::Multiline, i)` threw for `i > 2`, but now returns `Base.OneTo(1)` for every trailing - dimension, matching Base's own convention. + dimension, matching Base's own convention. ([#508](https://github.com/QuantumKitHub/MPSKit.jl/pull/508)) ### Performance +- `dot` on identical `FiniteMPS` objects uses a norm-based shortcut, also avoiding redundant contractions in expectation values. ([#491](https://github.com/QuantumKitHub/MPSKit.jl/pull/491)) +- Improved two-site effective-Hamiltonian contractions for long-range interactions. ([#505](https://github.com/QuantumKitHub/MPSKit.jl/pull/505)) +- Extended scratch-allocator use to additional derivative contractions and TDVP bond updates. ([#520](https://github.com/QuantumKitHub/MPSKit.jl/pull/520)) - Reorganised the test suite to reduce CI wall time, as well as added the `--fast` test flag to test fewer sector and scalar types. ([#517](https://github.com/QuantumKitHub/MPSKit.jl/pull/517)) - `TDVP2` now performs its two-site split through the shared `gauge2!` (as two-site DMRG already diff --git a/docs/src/examples/classic2d/1.hard-hexagon/figure-1.png b/docs/src/examples/classic2d/1.hard-hexagon/figure-1.png index 78d2bc359..7a590f3bf 100644 Binary files a/docs/src/examples/classic2d/1.hard-hexagon/figure-1.png and b/docs/src/examples/classic2d/1.hard-hexagon/figure-1.png differ diff --git a/docs/src/examples/classic2d/1.hard-hexagon/index.md b/docs/src/examples/classic2d/1.hard-hexagon/index.md index 71637c3bc..ed983612b 100644 --- a/docs/src/examples/classic2d/1.hard-hexagon/index.md +++ b/docs/src/examples/classic2d/1.hard-hexagon/index.md @@ -17,14 +17,15 @@ Because TensorKit supports anyonic symmetries, so does MPSKit. To follow the tutorial you need the following packages. ````julia -using MPSKit, MPSKitModels, TensorKit, Plots, Polynomials +using MPSKit, TensorKit, Plots, Polynomials +using .ExampleModels ```` The [hard hexagon model](https://en.wikipedia.org/wiki/Hard_hexagon_model) is a 2-dimensional lattice model of a gas, where particles are allowed to be on the vertices of a triangular lattice, but no two particles may be adjacent. -This can be encoded in a transfer matrix with a local MPO tensor using anyonic symmetries, and the resulting MPO has been implemented in MPSKitModels. +This can be encoded in a transfer matrix with a local MPO tensor using anyonic symmetries, and the resulting MPO is defined in our shared [model helpers](https://github.com/QuantumKitHub/MPSKit.jl/blob/main/docs/src/assets/models.jl). In order to use these anyonic symmetries, we need to generalise the notion of the bond dimension and define how it interacts with the symmetry. -Thus, we implement away of converting integers to symmetric spaces of the given dimension, which provides a crude guess for how the final MPS would distribute its Schmidt spectrum. +Thus, we implement a way of converting integers to symmetric spaces of the given dimension, which provides a crude guess for how the final MPS would distribute its Schmidt spectrum. ````julia mpo = hard_hexagon() @@ -48,7 +49,7 @@ Additionally, we can compute the entanglement entropy as well as the correlation D = 10 V = virtual_space(D) ψ₀ = InfiniteMPS([P], [V]) -ψ, envs, = leading_boundary( +ψ, envs, info = leading_boundary( ψ₀, mpo, VUMPS(; verbosity = 0, alg_eigsolve = MPSKit.Defaults.alg_eigsolve(; ishermitian = false)) ) # use non-hermitian eigensolver @@ -59,7 +60,7 @@ println("F = $F\tS = $S\tξ = $ξ") ```` ```` -F = 0.12340715308061609 S = 1.2807829621826905 ξ = 13.849682581482702 +F = 0.12340715308061671 S = 1.2807829622015565 ξ = 13.849682582674015 ```` @@ -69,7 +70,7 @@ The dominant eigenvector is of course only an approximation. The finite bond dimension enforces a finite correlation length, which effectively introduces a length scale in the system. This can be exploited to formulate a scaling hypothesis [pollmann2009](@cite), which in turn allows to extract the central charge. -First we need to know the entropy and correlation length at a bunch of different bond dimensions. +First we need to know the entropy and correlation length at several different bond dimensions. Our approach will be to re-use the previous approximated dominant eigenvector, and then expanding its bond dimension and re-running VUMPS. According to the scaling hypothesis we should have ``S ∝ \frac{c}{6} log(ξ)``. Therefore we should find ``c`` using @@ -81,7 +82,7 @@ function scaling_simulations( entropies = similar(Ds, Float64) correlations = similar(Ds, Float64) alg = VUMPS(; verbosity, tol, alg_eigsolve) - sector = unit(sectortype(mpo)) # dominant correlation functions are in the trivial sector + sector = unit(sectortype(mpo)) # in this example the dominant correlation functions are in the trivial sector ψ, envs, = leading_boundary(ψ₀, mpo, alg) entropies[1] = real(entropy(ψ)[1]) @@ -105,7 +106,7 @@ c = f.coeffs[2] ```` ```` -0.802524639544328 +0.8025302932613355 ```` ````julia diff --git a/docs/src/examples/classic2d/1.hard-hexagon/main.ipynb b/docs/src/examples/classic2d/1.hard-hexagon/main.ipynb index 129e5589a..d8cbd100d 100644 --- a/docs/src/examples/classic2d/1.hard-hexagon/main.ipynb +++ b/docs/src/examples/classic2d/1.hard-hexagon/main.ipynb @@ -21,7 +21,113 @@ "metadata": {}, "outputs": [], "source": [ - "using MPSKit, MPSKitModels, TensorKit, Plots, Polynomials" + "using MPSKit, TensorKit, Plots, Polynomials\n", + "# Model constructors for the MPSKit documentation and examples.\n", + "# Adapted from MPSKitModels.jl v0.4.7, src/models/{hamiltonians,transfermatrices}.jl:\n", + "# https://github.com/QuantumKitHub/MPSKitModels.jl/tree/v0.4.7/src/models\n", + "# Operators come from TensorKitTensors; chain assembly uses MPSKit directly.\n", + "#\n", + "# MIT License\n", + "# Copyright (c) 2021 Maarten Van Damme\n", + "#\n", + "# Permission is hereby granted, free of charge, to any person obtaining a copy\n", + "# of this software and associated documentation files (the \"Software\"), to deal\n", + "# in the Software without restriction, including without limitation the rights\n", + "# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n", + "# copies of the Software, and to permit persons to whom the Software is\n", + "# furnished to do so, subject to the following conditions:\n", + "#\n", + "# The above copyright notice and this permission notice shall be included in all\n", + "# copies or substantial portions of the Software.\n", + "#\n", + "# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n", + "# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n", + "# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n", + "# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n", + "# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n", + "# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n", + "# SOFTWARE.\n", + "\n", + "module ExampleModels\n", + "\n", + "using MPSKit, TensorKit\n", + "using TensorKitTensors: SpinOperators, BosonOperators, HubbardOperators\n", + "\n", + "export chain_hamiltonian, transverse_field_ising, heisenberg_XXX\n", + "export hubbard_model, bose_hubbard_model, hard_hexagon\n", + "\n", + "# L specifies an open finite chain; otherwise unitcell specifies an infinite chain.\n", + "function chain_hamiltonian(twosite, onesite = nothing; L = nothing, unitcell::Integer = 1)\n", + " nsites = isnothing(L) ? unitcell : L\n", + " nsites isa Integer && nsites > 0 || throw(ArgumentError(\"chain length must be a positive integer\"))\n", + " nbonds = isnothing(L) ? nsites : nsites - 1\n", + " terms = Pair[(i, i + 1) => twosite for i in 1:nbonds]\n", + " if !isnothing(onesite)\n", + " append!(terms, [i => onesite for i in 1:nsites])\n", + " end\n", + " spaces = fill(space(twosite, 1), nsites)\n", + " constructor = isnothing(L) ? InfiniteMPOHamiltonian : FiniteMPOHamiltonian\n", + " return constructor(spaces, terms)\n", + "end\n", + "\n", + "# H = -J sum(σz_i σz_{i+1} + g σx_i).\n", + "function transverse_field_ising(\n", + " T::Type{<:Number} = ComplexF64, symmetry::Type{<:Sector} = Trivial;\n", + " J = 1.0, g = 1.0, kwargs...\n", + " )\n", + " ZZ = 4 * SpinOperators.S_z_S_z(T, symmetry; spin = 1 // 2)\n", + " X = SpinOperators.σˣ(T, symmetry)\n", + " return chain_hamiltonian(-J * ZZ, -J * g * X; kwargs...)\n", + "end\n", + "transverse_field_ising(symmetry::Type{<:Sector}; kwargs...) =\n", + " transverse_field_ising(ComplexF64, symmetry; kwargs...)\n", + "\n", + "# H = J sum(S_i ⋅ S_{i+1}); preserve the examples' spin-1 default.\n", + "function heisenberg_XXX(\n", + " T::Type{<:Number} = ComplexF64, symmetry::Type{<:Sector} = Trivial;\n", + " J = 1.0, spin = 1, kwargs...\n", + " )\n", + " term = J * SpinOperators.S_exchange(T, symmetry; spin)\n", + " return chain_hamiltonian(term; kwargs...)\n", + "end\n", + "heisenberg_XXX(symmetry::Type{<:Sector}; kwargs...) =\n", + " heisenberg_XXX(ComplexF64, symmetry; kwargs...)\n", + "\n", + "# H = -t sum(e⁺_i e⁻_{i+1} + h.c.) + U sum(n↑ n↓) - mu sum(n).\n", + "function hubbard_model(\n", + " T::Type{<:Number} = ComplexF64, particle_symmetry::Type{<:Sector} = Trivial,\n", + " spin_symmetry::Type{<:Sector} = Trivial;\n", + " t = 1.0, U = 1.0, mu = 0.0, kwargs...\n", + " )\n", + " # e_hopping includes the fermionic reordering sign and is Hermitian.\n", + " hopping = HubbardOperators.e_hopping(T, particle_symmetry, spin_symmetry)\n", + " interaction = HubbardOperators.ud_num(T, particle_symmetry, spin_symmetry)\n", + " N = HubbardOperators.e_num(T, particle_symmetry, spin_symmetry)\n", + " return chain_hamiltonian(-t * hopping, U * interaction - mu * N; kwargs...)\n", + "end\n", + "\n", + "# H = -t sum(b⁺_i b⁻_{i+1} + h.c.) + U/2 sum(n(n-1)) - mu sum(n).\n", + "function bose_hubbard_model(\n", + " T::Type{<:Number} = ComplexF64, symmetry::Type{<:Sector} = Trivial;\n", + " cutoff::Integer = 5, t = 1.0, U = 1.0, mu = 0.0, kwargs...\n", + " )\n", + " hopping = BosonOperators.b_plus_b_min(T, symmetry; cutoff) +\n", + " BosonOperators.b_min_b_plus(T, symmetry; cutoff)\n", + " N = BosonOperators.b_num(T, symmetry; cutoff)\n", + " interaction = N * (N - id(domain(N)))\n", + " return chain_hamiltonian(-t * hopping, U / 2 * interaction - mu * N; kwargs...)\n", + "end\n", + "\n", + "function hard_hexagon(T::Type{<:Number} = ComplexF64)\n", + " P = Vect[FibonacciAnyon](:τ => 1)\n", + " O = ones(T, P ⊗ P ← P ⊗ P)\n", + " block(O, FibonacciAnyon(:I)) .*= 0\n", + " return InfiniteMPO([O])\n", + "end\n", + "\n", + "end\n", + "\n", + "using .ExampleModels" ] }, { @@ -29,10 +135,10 @@ "metadata": {}, "source": [ "The [hard hexagon model](https://en.wikipedia.org/wiki/Hard_hexagon_model) is a 2-dimensional lattice model of a gas, where particles are allowed to be on the vertices of a triangular lattice, but no two particles may be adjacent.\n", - "This can be encoded in a transfer matrix with a local MPO tensor using anyonic symmetries, and the resulting MPO has been implemented in MPSKitModels.\n", + "This can be encoded in a transfer matrix with a local MPO tensor using anyonic symmetries, and the resulting MPO is defined in our shared [model helpers](https://github.com/QuantumKitHub/MPSKit.jl/blob/main/docs/src/assets/models.jl).\n", "\n", "In order to use these anyonic symmetries, we need to generalise the notion of the bond dimension and define how it interacts with the symmetry.\n", - "Thus, we implement away of converting integers to symmetric spaces of the given dimension, which provides a crude guess for how the final MPS would distribute its Schmidt spectrum." + "Thus, we implement a way of converting integers to symmetric spaces of the given dimension, which provides a crude guess for how the final MPS would distribute its Schmidt spectrum." ] }, { @@ -59,7 +165,7 @@ "\n", "One way to study statistical mechanics in infinite systems with tensor networks is by approximating the dominant eigenvector of the transfer matrix by an MPS.\n", "This dominant eigenvector contains a lot of hidden information.\n", - "For example, the free energy can be extracted by computing the expectation value of the mpo.\n", + "For example, the free energy density can be extracted by computing the dominant eigenvalue of the transfer matrix.\n", "Additionally, we can compute the entanglement entropy as well as the correlation length of the state:" ] }, @@ -72,11 +178,11 @@ "D = 10\n", "V = virtual_space(D)\n", "ψ₀ = InfiniteMPS([P], [V])\n", - "ψ, envs, = leading_boundary(\n", + "ψ, envs, info = leading_boundary(\n", " ψ₀, mpo,\n", " VUMPS(; verbosity = 0, alg_eigsolve = MPSKit.Defaults.alg_eigsolve(; ishermitian = false))\n", ") # use non-hermitian eigensolver\n", - "F = real(expectation_value(ψ, mpo))\n", + "F = -log(real(leading_eigenvalue(ψ, mpo)))\n", "S = real(first(entropy(ψ)))\n", "ξ = correlation_length(ψ; sector = leftunit(ψ))\n", "println(\"F = $F\\tS = $S\\tξ = $ξ\")" @@ -92,7 +198,7 @@ "The finite bond dimension enforces a finite correlation length, which effectively introduces a length scale in the system.\n", "This can be exploited to formulate a scaling hypothesis [pollmann2009](@cite), which in turn allows to extract the central charge.\n", "\n", - "First we need to know the entropy and correlation length at a bunch of different bond dimensions.\n", + "First we need to know the entropy and correlation length at several different bond dimensions.\n", "Our approach will be to re-use the previous approximated dominant eigenvector, and then expanding its bond dimension and re-running VUMPS.\n", "According to the scaling hypothesis we should have $S ∝ \\frac{c}{6} log(ξ)$. Therefore we should find $c$ using" ] @@ -110,7 +216,7 @@ " entropies = similar(Ds, Float64)\n", " correlations = similar(Ds, Float64)\n", " alg = VUMPS(; verbosity, tol, alg_eigsolve)\n", - " sector = unit(sectortype(mpo)) # dominant correlation functions are in the trivial sector\n", + " sector = unit(sectortype(mpo)) # in this example the dominant correlation functions are in the trivial sector\n", "\n", " ψ, envs, = leading_boundary(ψ₀, mpo, alg)\n", " entropies[1] = real(entropy(ψ)[1])\n", @@ -148,15 +254,15 @@ ], "metadata": { "kernelspec": { - "display_name": "Julia 1.12.6", + "display_name": "Julia 1.13.1", "language": "julia", - "name": "julia-1.12" + "name": "julia-1.13" }, "language_info": { "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", - "version": "1.12.6" + "version": "1.13.1" } }, "nbformat": 4, diff --git a/docs/src/examples/index.md b/docs/src/examples/index.md index d56cc7397..2d4a5a970 100644 --- a/docs/src/examples/index.md +++ b/docs/src/examples/index.md @@ -1,5 +1,17 @@ # Examples +The downloadable notebooks include the model constructors used in these examples. +Their operator definitions come from +[TensorKitTensors.jl](https://github.com/QuantumKitHub/TensorKitTensors.jl). +To run individual code snippets, first download the shared +[models.jl](https://github.com/QuantumKitHub/MPSKit.jl/blob/main/docs/src/assets/models.jl) +file and load it in Julia: + +```julia +include("models.jl") +using .ExampleModels +``` + ## Quantum (1+1)d ```@contents @@ -12,4 +24,4 @@ Depth = 1 ```@contents Pages = map(file -> joinpath("classic2d", file, "index.md"), readdir("classic2d")) Depth = 1 -``` \ No newline at end of file +``` 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 8f76b9208..a2e28ecb3 100644 Binary files a/docs/src/examples/quantum1d/1.ising-cft/figure-3.png and b/docs/src/examples/quantum1d/1.ising-cft/figure-3.png differ diff --git a/docs/src/examples/quantum1d/1.ising-cft/index.md b/docs/src/examples/quantum1d/1.ising-cft/index.md index f634da5ff..e8d76048e 100644 --- a/docs/src/examples/quantum1d/1.ising-cft/index.md +++ b/docs/src/examples/quantum1d/1.ising-cft/index.md @@ -13,7 +13,8 @@ do this by first employing an exact diagonalization technique, and then extendin analysis to larger system sizes through the use of MPS techniques. ````julia -using MPSKit, MPSKitModels, TensorKit, Plots, KrylovKit +using MPSKit, TensorKit, Plots, KrylovKit +using .ExampleModels using LinearAlgebra: eigvals, diagm, Hermitian ```` @@ -126,24 +127,24 @@ append!(momenta, fix_degeneracies(states[17:18])) ```` 18-element Vector{Float64}: - 1.0963150642957372e-17 - -2.4157081442786943e-17 - 9.150251499481629e-18 - -0.523598775598299 + 3.4795649708338624e-17 + 2.1864186746744933e-17 + 1.0296022899642392e-18 + -0.5235987755982991 0.5235987755982987 + 1.047197551196598 + -1.0471975511965972 + -0.5235987755982991 + 0.5235987755982987 + 1.047197551196598 -1.0471975511965979 + 1.0708451244677254e-16 + -1.570796326794897 + 1.5707963267948968 + -1.0471975511965987 1.0471975511965976 - 0.5235987755982989 - -0.5235987755982993 - 1.047197551196598 - -1.0471975511965976 - 1.4597368636872088e-17 + 1.5707963267948968 -1.5707963267948966 - 1.5707963267948963 - 1.0471975511965976 - -1.0471975511965976 - -1.570796326794897 - 1.5707963267948963 ```` We can compute the scaling dimensions $\Delta_n$ of the operators in the CFT from the @@ -177,52 +178,56 @@ 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, info = find_groundstate(FiniteMPS(L_mps, ℂ^2, ℂ^D), H_mps, DMRG()); ```` ```` -[ Info: DMRG init: obj = -1.946908612087e+01 err = 7.7434e-02 -[ Info: DMRG 1: obj = -2.549098951719e+01 err = 8.0439536934e-03 time = 2.57 sec -[ Info: DMRG 2: obj = -2.549098968635e+01 err = 1.0703227324e-06 time = 0.80 sec -[ Info: DMRG 3: obj = -2.549098968636e+01 err = 1.4373447563e-07 time = 0.98 sec -[ Info: DMRG 4: obj = -2.549098968636e+01 err = 1.4665972881e-08 time = 0.42 sec -[ Info: DMRG 5: obj = -2.549098968636e+01 err = 6.8081026722e-09 time = 0.44 sec -[ Info: DMRG 6: obj = -2.549098968636e+01 err = 3.7573810815e-09 time = 0.43 sec -[ Info: DMRG 7: obj = -2.549098968636e+01 err = 2.5698292651e-09 time = 0.43 sec -[ Info: DMRG 8: obj = -2.549098968636e+01 err = 2.0113551709e-09 time = 0.43 sec -[ Info: DMRG 9: obj = -2.549098968636e+01 err = 1.6427286008e-09 time = 0.89 sec -[ Info: DMRG 10: obj = -2.549098968636e+01 err = 1.3479784013e-09 time = 0.55 sec -[ Info: DMRG 11: obj = -2.549098968636e+01 err = 1.2769471445e-09 time = 0.44 sec -[ Info: DMRG 12: obj = -2.549098968636e+01 err = 1.4168057275e-09 time = 0.48 sec -[ Info: DMRG 13: obj = -2.549098968636e+01 err = 1.5595217750e-09 time = 0.42 sec -[ Info: DMRG 14: obj = -2.549098968636e+01 err = 1.6950091915e-09 time = 0.41 sec -[ Info: DMRG 15: obj = -2.549098968636e+01 err = 1.8105744613e-09 time = 0.40 sec -[ Info: DMRG 16: obj = -2.549098968636e+01 err = 1.8924908787e-09 time = 0.96 sec -[ Info: DMRG 17: obj = -2.549098968636e+01 err = 1.9288336151e-09 time = 0.49 sec -[ Info: DMRG 18: obj = -2.549098968636e+01 err = 1.9133807885e-09 time = 0.31 sec -[ Info: DMRG 19: obj = -2.549098968636e+01 err = 1.8713994972e-09 time = 0.38 sec -[ Info: DMRG 20: obj = -2.549098968636e+01 err = 1.7813737815e-09 time = 0.41 sec -[ Info: DMRG 21: obj = -2.549098968636e+01 err = 1.6542099689e-09 time = 0.40 sec -[ Info: DMRG 22: obj = -2.549098968636e+01 err = 1.5039369007e-09 time = 0.40 sec -[ Info: DMRG 23: obj = -2.549098968636e+01 err = 1.3441838671e-09 time = 0.90 sec -[ Info: DMRG 24: obj = -2.549098968636e+01 err = 1.1858446625e-09 time = 0.28 sec -[ Info: DMRG 25: obj = -2.549098968636e+01 err = 1.0362811206e-09 time = 0.34 sec -[ Info: DMRG 26: obj = -2.549098968636e+01 err = 8.9963099646e-10 time = 0.35 sec -[ Info: DMRG 27: obj = -2.549098968636e+01 err = 7.7760121034e-10 time = 0.41 sec -[ Info: DMRG 28: obj = -2.549098968636e+01 err = 6.7030150822e-10 time = 0.40 sec -[ Info: DMRG 29: obj = -2.549098968636e+01 err = 5.7691780289e-10 time = 0.41 sec -[ Info: DMRG 30: obj = -2.549098968636e+01 err = 4.9618146296e-10 time = 0.91 sec -[ Info: DMRG 31: obj = -2.549098968636e+01 err = 4.2666435281e-10 time = 0.36 sec -[ Info: DMRG 32: obj = -2.549098968636e+01 err = 3.6694816435e-10 time = 0.40 sec -[ Info: DMRG 33: obj = -2.549098968636e+01 err = 3.1571200436e-10 time = 0.36 sec -[ Info: DMRG 34: obj = -2.549098968636e+01 err = 2.7176974363e-10 time = 0.38 sec -[ Info: DMRG 35: obj = -2.549098968636e+01 err = 2.3407977700e-10 time = 0.40 sec -[ Info: DMRG 36: obj = -2.549098968636e+01 err = 2.0173966270e-10 time = 0.40 sec -[ Info: DMRG 37: obj = -2.549098968636e+01 err = 1.7397391951e-10 time = 0.40 sec -[ Info: DMRG 38: obj = -2.549098968636e+01 err = 1.5011934910e-10 time = 0.87 sec -[ Info: DMRG 39: obj = -2.549098968636e+01 err = 1.2961022917e-10 time = 0.35 sec -[ Info: DMRG 40: obj = -2.549098968636e+01 err = 1.1196457020e-10 time = 0.38 sec -[ Info: DMRG conv 41: obj = -2.549098968636e+01 err = 9.6771723038e-11 time = 22.14 sec +[ Info: DMRG init: obj = -1.943771844888e+01 err = 1.0000e+00 +[ Info: DMRG 1: obj = -2.548965337401e+01 err = 1.5606788288e-02 time = 1.50 sec +[ Info: DMRG 2: obj = -2.549098968590e+01 err = 4.2297557187e-04 time = 0.79 sec +[ Info: DMRG 3: obj = -2.549098968636e+01 err = 1.0167456345e-06 time = 0.41 sec +[ Info: DMRG 4: obj = -2.549098968636e+01 err = 2.4867732855e-08 time = 0.30 sec +[ Info: DMRG 5: obj = -2.549098968636e+01 err = 7.4062863713e-09 time = 0.47 sec +[ Info: DMRG 6: obj = -2.549098968636e+01 err = 3.8191851769e-09 time = 1.41 sec +[ Info: DMRG 7: obj = -2.549098968636e+01 err = 2.6647921898e-09 time = 0.31 sec +[ Info: DMRG 8: obj = -2.549098968636e+01 err = 2.1927504209e-09 time = 0.31 sec +[ Info: DMRG 9: obj = -2.549098968636e+01 err = 1.9177066057e-09 time = 0.29 sec +[ Info: DMRG 10: obj = -2.549098968636e+01 err = 1.6969297883e-09 time = 0.29 sec +[ Info: DMRG 11: obj = -2.549098968636e+01 err = 1.6032558073e-09 time = 0.28 sec +[ Info: DMRG 12: obj = -2.549098968636e+01 err = 1.6496928155e-09 time = 0.30 sec +[ Info: DMRG 13: obj = -2.549098968636e+01 err = 1.6728447005e-09 time = 0.30 sec +[ Info: DMRG 14: obj = -2.549098968636e+01 err = 1.6689081338e-09 time = 0.28 sec +[ Info: DMRG 15: obj = -2.549098968636e+01 err = 1.6377730200e-09 time = 0.32 sec +[ Info: DMRG 16: obj = -2.549098968636e+01 err = 1.5799295265e-09 time = 0.31 sec +[ Info: DMRG 17: obj = -2.549098968636e+01 err = 1.5009049285e-09 time = 0.30 sec +[ Info: DMRG 18: obj = -2.549098968636e+01 err = 1.4066215762e-09 time = 0.30 sec +[ Info: DMRG 19: obj = -2.549098968636e+01 err = 1.5081205257e-09 time = 0.29 sec +[ Info: DMRG 20: obj = -2.549098968636e+01 err = 1.6810911856e-09 time = 0.30 sec +[ Info: DMRG 21: obj = -2.549098968636e+01 err = 1.8220210461e-09 time = 0.29 sec +[ Info: DMRG 22: obj = -2.549098968636e+01 err = 1.9139702907e-09 time = 0.29 sec +[ Info: DMRG 23: obj = -2.549098968636e+01 err = 1.9442171571e-09 time = 0.28 sec +[ Info: DMRG 24: obj = -2.549098968636e+01 err = 1.9087464599e-09 time = 1.38 sec +[ Info: DMRG 25: obj = -2.549098968636e+01 err = 1.8142533073e-09 time = 0.28 sec +[ Info: DMRG 26: obj = -2.549098968636e+01 err = 1.6750776273e-09 time = 0.28 sec +[ Info: DMRG 27: obj = -2.549098968636e+01 err = 1.5098703467e-09 time = 0.30 sec +[ Info: DMRG 28: obj = -2.549098968636e+01 err = 1.3360360659e-09 time = 0.20 sec +[ Info: DMRG 29: obj = -2.549098968636e+01 err = 1.1657760958e-09 time = 0.16 sec +[ Info: DMRG 30: obj = -2.549098968636e+01 err = 1.0073242984e-09 time = 0.18 sec +[ Info: DMRG 31: obj = -2.549098968636e+01 err = 8.6474907924e-10 time = 0.24 sec +[ Info: DMRG 32: obj = -2.549098968636e+01 err = 7.3927413439e-10 time = 0.28 sec +[ Info: DMRG 33: obj = -2.549098968636e+01 err = 6.3048094041e-10 time = 0.28 sec +[ Info: DMRG 34: obj = -2.549098968636e+01 err = 5.3702960640e-10 time = 0.29 sec +[ Info: DMRG 35: obj = -2.549098968636e+01 err = 4.5722500117e-10 time = 0.30 sec +[ Info: DMRG 36: obj = -2.549098968636e+01 err = 3.8930325414e-10 time = 0.29 sec +[ Info: DMRG 37: obj = -2.549098968636e+01 err = 3.3159981587e-10 time = 0.28 sec +[ Info: DMRG 38: obj = -2.549098968636e+01 err = 2.8261201613e-10 time = 0.29 sec +[ Info: DMRG 39: obj = -2.549098968636e+01 err = 2.4102587357e-10 time = 0.34 sec +[ Info: DMRG 40: obj = -2.549098968636e+01 err = 2.0570571140e-10 time = 0.30 sec +[ Info: DMRG 41: obj = -2.549098968636e+01 err = 1.7569292481e-10 time = 0.29 sec +[ Info: DMRG 42: obj = -2.549098968636e+01 err = 1.5016721096e-10 time = 0.28 sec +[ Info: DMRG 43: obj = -2.549098968636e+01 err = 1.2843977109e-10 time = 0.31 sec +[ Info: DMRG 44: obj = -2.549098968636e+01 err = 1.0992971958e-10 time = 0.44 sec +[ Info: DMRG conv 45: obj = -2.549098968636e+01 err = 9.4147444802e-11 time = 18.09 sec ```` diff --git a/docs/src/examples/quantum1d/1.ising-cft/main.ipynb b/docs/src/examples/quantum1d/1.ising-cft/main.ipynb index 54e1b0ed7..db7b248c7 100644 --- a/docs/src/examples/quantum1d/1.ising-cft/main.ipynb +++ b/docs/src/examples/quantum1d/1.ising-cft/main.ipynb @@ -17,7 +17,113 @@ "metadata": {}, "outputs": [], "source": [ - "using MPSKit, MPSKitModels, TensorKit, Plots, KrylovKit\n", + "using MPSKit, TensorKit, Plots, KrylovKit\n", + "# Model constructors for the MPSKit documentation and examples.\n", + "# Adapted from MPSKitModels.jl v0.4.7, src/models/{hamiltonians,transfermatrices}.jl:\n", + "# https://github.com/QuantumKitHub/MPSKitModels.jl/tree/v0.4.7/src/models\n", + "# Operators come from TensorKitTensors; chain assembly uses MPSKit directly.\n", + "#\n", + "# MIT License\n", + "# Copyright (c) 2021 Maarten Van Damme\n", + "#\n", + "# Permission is hereby granted, free of charge, to any person obtaining a copy\n", + "# of this software and associated documentation files (the \"Software\"), to deal\n", + "# in the Software without restriction, including without limitation the rights\n", + "# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n", + "# copies of the Software, and to permit persons to whom the Software is\n", + "# furnished to do so, subject to the following conditions:\n", + "#\n", + "# The above copyright notice and this permission notice shall be included in all\n", + "# copies or substantial portions of the Software.\n", + "#\n", + "# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n", + "# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n", + "# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n", + "# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n", + "# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n", + "# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n", + "# SOFTWARE.\n", + "\n", + "module ExampleModels\n", + "\n", + "using MPSKit, TensorKit\n", + "using TensorKitTensors: SpinOperators, BosonOperators, HubbardOperators\n", + "\n", + "export chain_hamiltonian, transverse_field_ising, heisenberg_XXX\n", + "export hubbard_model, bose_hubbard_model, hard_hexagon\n", + "\n", + "# L specifies an open finite chain; otherwise unitcell specifies an infinite chain.\n", + "function chain_hamiltonian(twosite, onesite = nothing; L = nothing, unitcell::Integer = 1)\n", + " nsites = isnothing(L) ? unitcell : L\n", + " nsites isa Integer && nsites > 0 || throw(ArgumentError(\"chain length must be a positive integer\"))\n", + " nbonds = isnothing(L) ? nsites : nsites - 1\n", + " terms = Pair[(i, i + 1) => twosite for i in 1:nbonds]\n", + " if !isnothing(onesite)\n", + " append!(terms, [i => onesite for i in 1:nsites])\n", + " end\n", + " spaces = fill(space(twosite, 1), nsites)\n", + " constructor = isnothing(L) ? InfiniteMPOHamiltonian : FiniteMPOHamiltonian\n", + " return constructor(spaces, terms)\n", + "end\n", + "\n", + "# H = -J sum(σz_i σz_{i+1} + g σx_i).\n", + "function transverse_field_ising(\n", + " T::Type{<:Number} = ComplexF64, symmetry::Type{<:Sector} = Trivial;\n", + " J = 1.0, g = 1.0, kwargs...\n", + " )\n", + " ZZ = 4 * SpinOperators.S_z_S_z(T, symmetry; spin = 1 // 2)\n", + " X = SpinOperators.σˣ(T, symmetry)\n", + " return chain_hamiltonian(-J * ZZ, -J * g * X; kwargs...)\n", + "end\n", + "transverse_field_ising(symmetry::Type{<:Sector}; kwargs...) =\n", + " transverse_field_ising(ComplexF64, symmetry; kwargs...)\n", + "\n", + "# H = J sum(S_i ⋅ S_{i+1}); preserve the examples' spin-1 default.\n", + "function heisenberg_XXX(\n", + " T::Type{<:Number} = ComplexF64, symmetry::Type{<:Sector} = Trivial;\n", + " J = 1.0, spin = 1, kwargs...\n", + " )\n", + " term = J * SpinOperators.S_exchange(T, symmetry; spin)\n", + " return chain_hamiltonian(term; kwargs...)\n", + "end\n", + "heisenberg_XXX(symmetry::Type{<:Sector}; kwargs...) =\n", + " heisenberg_XXX(ComplexF64, symmetry; kwargs...)\n", + "\n", + "# H = -t sum(e⁺_i e⁻_{i+1} + h.c.) + U sum(n↑ n↓) - mu sum(n).\n", + "function hubbard_model(\n", + " T::Type{<:Number} = ComplexF64, particle_symmetry::Type{<:Sector} = Trivial,\n", + " spin_symmetry::Type{<:Sector} = Trivial;\n", + " t = 1.0, U = 1.0, mu = 0.0, kwargs...\n", + " )\n", + " # e_hopping includes the fermionic reordering sign and is Hermitian.\n", + " hopping = HubbardOperators.e_hopping(T, particle_symmetry, spin_symmetry)\n", + " interaction = HubbardOperators.ud_num(T, particle_symmetry, spin_symmetry)\n", + " N = HubbardOperators.e_num(T, particle_symmetry, spin_symmetry)\n", + " return chain_hamiltonian(-t * hopping, U * interaction - mu * N; kwargs...)\n", + "end\n", + "\n", + "# H = -t sum(b⁺_i b⁻_{i+1} + h.c.) + U/2 sum(n(n-1)) - mu sum(n).\n", + "function bose_hubbard_model(\n", + " T::Type{<:Number} = ComplexF64, symmetry::Type{<:Sector} = Trivial;\n", + " cutoff::Integer = 5, t = 1.0, U = 1.0, mu = 0.0, kwargs...\n", + " )\n", + " hopping = BosonOperators.b_plus_b_min(T, symmetry; cutoff) +\n", + " BosonOperators.b_min_b_plus(T, symmetry; cutoff)\n", + " N = BosonOperators.b_num(T, symmetry; cutoff)\n", + " interaction = N * (N - id(domain(N)))\n", + " return chain_hamiltonian(-t * hopping, U / 2 * interaction - mu * N; kwargs...)\n", + "end\n", + "\n", + "function hard_hexagon(T::Type{<:Number} = ComplexF64)\n", + " P = Vect[FibonacciAnyon](:τ => 1)\n", + " O = ones(T, P ⊗ P ← P ⊗ P)\n", + " block(O, FibonacciAnyon(:I)) .*= 0\n", + " return InfiniteMPO([O])\n", + "end\n", + "\n", + "end\n", + "\n", + "using .ExampleModels\n", "using LinearAlgebra: eigvals, diagm, Hermitian" ] }, @@ -197,7 +303,7 @@ "L_mps = 20\n", "H_mps = periodic_boundary_conditions(transverse_field_ising(), L_mps)\n", "D = 64\n", - "ψ, envs, δ = find_groundstate(FiniteMPS(L_mps, ℂ^2, ℂ^D), H_mps, DMRG());" + "ψ, envs, info = find_groundstate(FiniteMPS(L_mps, ℂ^2, ℂ^D), H_mps, DMRG());" ] }, { @@ -256,15 +362,15 @@ ], "metadata": { "kernelspec": { - "display_name": "Julia 1.12.6", + "display_name": "Julia 1.13.1", "language": "julia", - "name": "julia-1.12" + "name": "julia-1.13" }, "language_info": { "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", - "version": "1.12.6" + "version": "1.13.1" } }, "nbformat": 4, diff --git a/docs/src/examples/quantum1d/2.haldane/figure-2.png b/docs/src/examples/quantum1d/2.haldane/figure-2.png index 786b45fd2..87ebf95e3 100644 Binary files a/docs/src/examples/quantum1d/2.haldane/figure-2.png and b/docs/src/examples/quantum1d/2.haldane/figure-2.png differ diff --git a/docs/src/examples/quantum1d/2.haldane/index.md b/docs/src/examples/quantum1d/2.haldane/index.md index 71bcad85e..e888595d3 100644 --- a/docs/src/examples/quantum1d/2.haldane/index.md +++ b/docs/src/examples/quantum1d/2.haldane/index.md @@ -12,7 +12,9 @@ In this tutorial we will calculate the Haldane gap (the energy gap in the ``S = To follow the tutorial you need the following packages: ````julia -using MPSKit, MPSKitModels, TensorKit, Plots, Polynomials +using MPSKit, TensorKit, Plots, Polynomials +using .ExampleModels +using TensorKitTensors.SpinOperators: S_exchange ```` The Heisenberg model is defined by the following Hamiltonian: @@ -47,13 +49,12 @@ This can be done as follows. ````julia L = 11 -chain = FiniteChain(L) -H = heisenberg_XXX(symmetry, chain; J, spin) +H = heisenberg_XXX(symmetry; L, J, spin) physical_space = SU2Space(1 => 1) virtual_space = SU2Space(0 => 12, 1 => 12, 2 => 5, 3 => 3) ψ₀ = FiniteMPS(L, physical_space, virtual_space) -ψ, envs, delta = find_groundstate(ψ₀, H, DMRG(; verbosity = 0)) +ψ, envs, info = find_groundstate(ψ₀, H, DMRG(; verbosity = 0)) E₀ = real(expectation_value(ψ, H)) En_1, st_1 = excitations(H, QuasiparticleAnsatz(), ψ, envs; sector = SU2Irrep(1)) En_2, st_2 = excitations(H, QuasiparticleAnsatz(), ψ, envs; sector = SU2Irrep(2)) @@ -61,7 +62,7 @@ En_2, st_2 = excitations(H, QuasiparticleAnsatz(), ψ, envs; sector = SU2Irrep(2 ```` ```` -0.7989253589480472 +0.7989253589480417 ```` We can go even further and doublecheck the claim that ``S = 1`` is an edge excitation, by plotting the energy density. @@ -88,8 +89,8 @@ Ls = 12:4:30 ΔEs = map(Ls) do L @info "computing L = $L" ψ₀ = FiniteMPS(L, physical_space, virtual_space) - H = heisenberg_XXX(symmetry, FiniteChain(L); J, spin) - ψ, envs, delta = find_groundstate(ψ₀, H, DMRG(; verbosity = 0)) + H = heisenberg_XXX(symmetry; L, J, spin) + ψ, envs, info = find_groundstate(ψ₀, H, DMRG(; verbosity = 0)) En_1, st_1 = excitations(H, QuasiparticleAnsatz(), ψ, envs; sector = SU2Irrep(1)) En_2, st_2 = excitations(H, QuasiparticleAnsatz(), ψ, envs; sector = SU2Irrep(2)) return real(En_2[1] - En_1[1]) @@ -100,7 +101,7 @@ f = fit(Ls .^ (-2), ΔEs, 1) ```` ```` -0.4517340158583749 +0.4517340158582783 ```` ````julia @@ -122,11 +123,10 @@ In contrast with the finite size case, we now should specify a momentum label to This way, it is possible to scan the dispersion relation over the entire momentum space. ````julia -chain = InfiniteChain(1) -H = heisenberg_XXX(symmetry, chain; J, spin) +H = heisenberg_XXX(symmetry; J, spin) virtual_space_inf = Rep[SU₂](1 // 2 => 16, 3 // 2 => 16, 5 // 2 => 8, 7 // 2 => 4) ψ₀_inf = InfiniteMPS([physical_space], [virtual_space_inf]) -ψ_inf, envs_inf, delta_inf = find_groundstate(ψ₀_inf, H; verbosity = 0) +ψ_inf, envs_inf, info_inf = find_groundstate(ψ₀_inf, H; verbosity = 0) kspace = range(0, π, 16) Es, _ = excitations(H, QuasiparticleAnsatz(), kspace, ψ_inf, envs_inf; sector = SU2Irrep(1)) @@ -140,19 +140,19 @@ println("minimum @k = $(kspace[idx]):\t ΔE = $(ΔE)") [ 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.2566370614359172 +[ Info: Found excitations for momentum = 1.4660765716752369 [ 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 = 2.9321531433504737 [ Info: Found excitations for momentum = 3.141592653589793 -minimum @k = 3.141592653589793: ΔE = 0.41047924848831047 +minimum @k = 3.141592653589793: ΔE = 0.4104792486506801 ```` diff --git a/docs/src/examples/quantum1d/2.haldane/main.ipynb b/docs/src/examples/quantum1d/2.haldane/main.ipynb index 2084d50d9..537558604 100644 --- a/docs/src/examples/quantum1d/2.haldane/main.ipynb +++ b/docs/src/examples/quantum1d/2.haldane/main.ipynb @@ -16,7 +16,114 @@ "metadata": {}, "outputs": [], "source": [ - "using MPSKit, MPSKitModels, TensorKit, Plots, Polynomials" + "using MPSKit, TensorKit, Plots, Polynomials\n", + "# Model constructors for the MPSKit documentation and examples.\n", + "# Adapted from MPSKitModels.jl v0.4.7, src/models/{hamiltonians,transfermatrices}.jl:\n", + "# https://github.com/QuantumKitHub/MPSKitModels.jl/tree/v0.4.7/src/models\n", + "# Operators come from TensorKitTensors; chain assembly uses MPSKit directly.\n", + "#\n", + "# MIT License\n", + "# Copyright (c) 2021 Maarten Van Damme\n", + "#\n", + "# Permission is hereby granted, free of charge, to any person obtaining a copy\n", + "# of this software and associated documentation files (the \"Software\"), to deal\n", + "# in the Software without restriction, including without limitation the rights\n", + "# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n", + "# copies of the Software, and to permit persons to whom the Software is\n", + "# furnished to do so, subject to the following conditions:\n", + "#\n", + "# The above copyright notice and this permission notice shall be included in all\n", + "# copies or substantial portions of the Software.\n", + "#\n", + "# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n", + "# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n", + "# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n", + "# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n", + "# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n", + "# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n", + "# SOFTWARE.\n", + "\n", + "module ExampleModels\n", + "\n", + "using MPSKit, TensorKit\n", + "using TensorKitTensors: SpinOperators, BosonOperators, HubbardOperators\n", + "\n", + "export chain_hamiltonian, transverse_field_ising, heisenberg_XXX\n", + "export hubbard_model, bose_hubbard_model, hard_hexagon\n", + "\n", + "# L specifies an open finite chain; otherwise unitcell specifies an infinite chain.\n", + "function chain_hamiltonian(twosite, onesite = nothing; L = nothing, unitcell::Integer = 1)\n", + " nsites = isnothing(L) ? unitcell : L\n", + " nsites isa Integer && nsites > 0 || throw(ArgumentError(\"chain length must be a positive integer\"))\n", + " nbonds = isnothing(L) ? nsites : nsites - 1\n", + " terms = Pair[(i, i + 1) => twosite for i in 1:nbonds]\n", + " if !isnothing(onesite)\n", + " append!(terms, [i => onesite for i in 1:nsites])\n", + " end\n", + " spaces = fill(space(twosite, 1), nsites)\n", + " constructor = isnothing(L) ? InfiniteMPOHamiltonian : FiniteMPOHamiltonian\n", + " return constructor(spaces, terms)\n", + "end\n", + "\n", + "# H = -J sum(σz_i σz_{i+1} + g σx_i).\n", + "function transverse_field_ising(\n", + " T::Type{<:Number} = ComplexF64, symmetry::Type{<:Sector} = Trivial;\n", + " J = 1.0, g = 1.0, kwargs...\n", + " )\n", + " ZZ = 4 * SpinOperators.S_z_S_z(T, symmetry; spin = 1 // 2)\n", + " X = SpinOperators.σˣ(T, symmetry)\n", + " return chain_hamiltonian(-J * ZZ, -J * g * X; kwargs...)\n", + "end\n", + "transverse_field_ising(symmetry::Type{<:Sector}; kwargs...) =\n", + " transverse_field_ising(ComplexF64, symmetry; kwargs...)\n", + "\n", + "# H = J sum(S_i ⋅ S_{i+1}); preserve the examples' spin-1 default.\n", + "function heisenberg_XXX(\n", + " T::Type{<:Number} = ComplexF64, symmetry::Type{<:Sector} = Trivial;\n", + " J = 1.0, spin = 1, kwargs...\n", + " )\n", + " term = J * SpinOperators.S_exchange(T, symmetry; spin)\n", + " return chain_hamiltonian(term; kwargs...)\n", + "end\n", + "heisenberg_XXX(symmetry::Type{<:Sector}; kwargs...) =\n", + " heisenberg_XXX(ComplexF64, symmetry; kwargs...)\n", + "\n", + "# H = -t sum(e⁺_i e⁻_{i+1} + h.c.) + U sum(n↑ n↓) - mu sum(n).\n", + "function hubbard_model(\n", + " T::Type{<:Number} = ComplexF64, particle_symmetry::Type{<:Sector} = Trivial,\n", + " spin_symmetry::Type{<:Sector} = Trivial;\n", + " t = 1.0, U = 1.0, mu = 0.0, kwargs...\n", + " )\n", + " # e_hopping includes the fermionic reordering sign and is Hermitian.\n", + " hopping = HubbardOperators.e_hopping(T, particle_symmetry, spin_symmetry)\n", + " interaction = HubbardOperators.ud_num(T, particle_symmetry, spin_symmetry)\n", + " N = HubbardOperators.e_num(T, particle_symmetry, spin_symmetry)\n", + " return chain_hamiltonian(-t * hopping, U * interaction - mu * N; kwargs...)\n", + "end\n", + "\n", + "# H = -t sum(b⁺_i b⁻_{i+1} + h.c.) + U/2 sum(n(n-1)) - mu sum(n).\n", + "function bose_hubbard_model(\n", + " T::Type{<:Number} = ComplexF64, symmetry::Type{<:Sector} = Trivial;\n", + " cutoff::Integer = 5, t = 1.0, U = 1.0, mu = 0.0, kwargs...\n", + " )\n", + " hopping = BosonOperators.b_plus_b_min(T, symmetry; cutoff) +\n", + " BosonOperators.b_min_b_plus(T, symmetry; cutoff)\n", + " N = BosonOperators.b_num(T, symmetry; cutoff)\n", + " interaction = N * (N - id(domain(N)))\n", + " return chain_hamiltonian(-t * hopping, U / 2 * interaction - mu * N; kwargs...)\n", + "end\n", + "\n", + "function hard_hexagon(T::Type{<:Number} = ComplexF64)\n", + " P = Vect[FibonacciAnyon](:τ => 1)\n", + " O = ones(T, P ⊗ P ← P ⊗ P)\n", + " block(O, FibonacciAnyon(:I)) .*= 0\n", + " return InfiniteMPO([O])\n", + "end\n", + "\n", + "end\n", + "\n", + "using .ExampleModels\n", + "using TensorKitTensors.SpinOperators: S_exchange" ] }, { @@ -67,13 +174,12 @@ "outputs": [], "source": [ "L = 11\n", - "chain = FiniteChain(L)\n", - "H = heisenberg_XXX(symmetry, chain; J, spin)\n", + "H = heisenberg_XXX(symmetry; L, J, spin)\n", "\n", "physical_space = SU2Space(1 => 1)\n", "virtual_space = SU2Space(0 => 12, 1 => 12, 2 => 5, 3 => 3)\n", "ψ₀ = FiniteMPS(L, physical_space, virtual_space)\n", - "ψ, envs, delta = find_groundstate(ψ₀, H, DMRG(; verbosity = 0))\n", + "ψ, envs, info = find_groundstate(ψ₀, H, DMRG(; verbosity = 0))\n", "E₀ = real(expectation_value(ψ, H))\n", "En_1, st_1 = excitations(H, QuasiparticleAnsatz(), ψ, envs; sector = SU2Irrep(1))\n", "En_2, st_2 = excitations(H, QuasiparticleAnsatz(), ψ, envs; sector = SU2Irrep(2))\n", @@ -122,8 +228,8 @@ "ΔEs = map(Ls) do L\n", " @info \"computing L = $L\"\n", " ψ₀ = FiniteMPS(L, physical_space, virtual_space)\n", - " H = heisenberg_XXX(symmetry, FiniteChain(L); J, spin)\n", - " ψ, envs, delta = find_groundstate(ψ₀, H, DMRG(; verbosity = 0))\n", + " H = heisenberg_XXX(symmetry; L, J, spin)\n", + " ψ, envs, info = find_groundstate(ψ₀, H, DMRG(; verbosity = 0))\n", " En_1, st_1 = excitations(H, QuasiparticleAnsatz(), ψ, envs; sector = SU2Irrep(1))\n", " En_2, st_2 = excitations(H, QuasiparticleAnsatz(), ψ, envs; sector = SU2Irrep(2))\n", " return real(En_2[1] - En_1[1])\n", @@ -157,11 +263,10 @@ "metadata": {}, "outputs": [], "source": [ - "chain = InfiniteChain(1)\n", - "H = heisenberg_XXX(symmetry, chain; J, spin)\n", + "H = heisenberg_XXX(symmetry; J, spin)\n", "virtual_space_inf = Rep[SU₂](1 // 2 => 16, 3 // 2 => 16, 5 // 2 => 8, 7 // 2 => 4)\n", "ψ₀_inf = InfiniteMPS([physical_space], [virtual_space_inf])\n", - "ψ_inf, envs_inf, delta_inf = find_groundstate(ψ₀_inf, H; verbosity = 0)\n", + "ψ_inf, envs_inf, info_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", @@ -183,15 +288,15 @@ ], "metadata": { "kernelspec": { - "display_name": "Julia 1.12.6", + "display_name": "Julia 1.13.1", "language": "julia", - "name": "julia-1.12" + "name": "julia-1.13" }, "language_info": { "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", - "version": "1.12.6" + "version": "1.13.1" } }, "nbformat": 4, diff --git a/docs/src/examples/quantum1d/3.ising-dqpt/index.md b/docs/src/examples/quantum1d/3.ising-dqpt/index.md index c60dc700d..98f515216 100644 --- a/docs/src/examples/quantum1d/3.ising-dqpt/index.md +++ b/docs/src/examples/quantum1d/3.ising-dqpt/index.md @@ -12,7 +12,8 @@ In this tutorial we will try to reproduce the results from [this paper](https://arxiv.org/pdf/1206.2505.pdf). The needed packages are ````julia -using MPSKit, MPSKitModels, TensorKit +using MPSKit, TensorKit +using .ExampleModels ```` Dynamical quantum phase transitions (DQPT in short) are signatures of equilibrium phase transitions in a dynamical quantity - the Loschmidt echo. @@ -33,25 +34,28 @@ First we construct the Hamiltonian in MPO form, and obtain the pre-quenched grou ````julia L = 20 -H₀ = transverse_field_ising(FiniteChain(L); g = -0.5) +H₀ = transverse_field_ising(; L, g = -0.5) ψ₀ = FiniteMPS(L, ℂ^2, ℂ^10) ψ₀, _ = find_groundstate(ψ₀, H₀, DMRG()); ```` ```` -[ Info: DMRG init: obj = +9.979013604153e+00 err = 1.4988e-01 -[ Info: DMRG 1: obj = -2.040021714911e+01 err = 6.6274818897e-04 time = 4.21 sec -[ Info: DMRG 2: obj = -2.040021715179e+01 err = 4.7025708686e-07 time = 0.30 sec -[ Info: DMRG 3: obj = -2.040021786572e+01 err = 3.1050733385e-05 time = 0.09 sec -[ Info: DMRG 4: obj = -2.040021786702e+01 err = 1.7208246127e-06 time = 0.04 sec -[ Info: DMRG 5: obj = -2.040021786703e+01 err = 3.5080300899e-08 time = 0.04 sec -[ Info: DMRG conv 6: obj = -2.040021786703e+01 err = 3.6868374475e-11 time = 4.71 sec +[ Info: DMRG init: obj = +9.789608054020e+00 err = 1.0000e+00 +[ Info: DMRG 1: obj = -2.040016740045e+01 err = 1.7077445107e-02 time = 0.01 sec +[ Info: DMRG 2: obj = -2.040021715177e+01 err = 3.5394180072e-05 time = 0.01 sec +[ Info: DMRG 3: obj = -2.040021715349e+01 err = 2.1033336427e-06 time = 0.02 sec +[ Info: DMRG 4: obj = -2.040021748658e+01 err = 1.5656718877e-05 time = 0.02 sec +[ Info: DMRG 5: obj = -2.040021759890e+01 err = 8.8241952375e-06 time = 0.01 sec +[ Info: DMRG 6: obj = -2.040021767905e+01 err = 1.1092508692e-05 time = 0.01 sec +[ Info: DMRG 7: obj = -2.040021786701e+01 err = 2.4581655330e-06 time = 0.01 sec +[ Info: DMRG 8: obj = -2.040021786703e+01 err = 9.9647269587e-09 time = 0.01 sec +[ Info: DMRG conv 9: obj = -2.040021786703e+01 err = 8.2188000056e-11 time = 0.12 sec ```` ## Finite MPS quenching -We can define a helper function that measures the loschmith echo +We can define a helper function that measures the Loschmidt echo: ````julia echo(ψ₀::FiniteMPS, ψₜ::FiniteMPS) = -2 * log(abs(dot(ψ₀, ψₜ))) / length(ψ₀) @@ -61,10 +65,10 @@ echo(ψ₀::FiniteMPS, ψₜ::FiniteMPS) = -2 * log(abs(dot(ψ₀, ψₜ))) / le We will initially use a two-site TDVP scheme to dynamically increase the bond dimension while time evolving, and later on switch to a faster one-site scheme. A single timestep can be done using ````julia -H₁ = transverse_field_ising(FiniteChain(L); g = -2.0) +H₁ = transverse_field_ising(; L, g = -2.0) ψₜ = deepcopy(ψ₀) dt = 0.01 -ψₜ, envs = timestep(ψₜ, H₁, 0, dt, TDVP2(; trunc = truncrank(20))); +ψₜ, envs, info = timestep(ψₜ, H₁, 0, dt, TDVP2(; trunc = truncrank(20))); ```` "envs" is a kind of cache object that keeps track of all environments in `ψ`. It is often advantageous to re-use the environment, so that MPSKit doesn't need to recalculate everything. @@ -74,10 +78,10 @@ Putting it all together, we get ````julia function finite_sim(L; dt = 0.05, finaltime = 5.0) ψ₀ = FiniteMPS(L, ℂ^2, ℂ^10) - H₀ = transverse_field_ising(FiniteChain(L); g = -0.5) + H₀ = transverse_field_ising(; L, g = -0.5) ψ₀, _ = find_groundstate(ψ₀, H₀, DMRG()) - H₁ = transverse_field_ising(FiniteChain(L); g = -2.0) + H₁ = transverse_field_ising(; L, g = -2.0) ψₜ = deepcopy(ψ₀) envs = environments(ψₜ, H₁, ψₜ) @@ -86,7 +90,7 @@ function finite_sim(L; dt = 0.05, finaltime = 5.0) for t in times[2:end] alg = t > 3 * dt ? TDVP() : TDVP2(; trunc = truncrank(50)) - ψₜ, envs = timestep(ψₜ, H₁, 0, dt, alg, envs) + ψₜ, envs, info = timestep(ψₜ, H₁, 0, dt, alg, envs) push!(echos, echo(ψₜ, ψ₀)) end @@ -111,14 +115,13 @@ H₀ = transverse_field_ising(; g = -0.5) ```` ```` -[ Info: VUMPS init: obj = +4.970192050239e-01 err = 3.8858e-01 -[ Info: VUMPS 1: obj = -1.049521519045e+00 err = 9.6762771022e-02 time = 1.62 sec -[ Info: VUMPS 2: obj = -1.063544398670e+00 err = 1.0462983506e-04 time = 0.02 sec -[ Info: VUMPS 3: obj = -1.063544409966e+00 err = 3.0128180222e-06 time = 0.01 sec -[ Info: VUMPS 4: obj = -1.063544409973e+00 err = 5.4785900416e-08 time = 0.01 sec -[ Info: VUMPS 5: obj = -1.063544409973e+00 err = 3.5329191510e-09 time = 0.01 sec -[ Info: VUMPS 6: obj = -1.063544409973e+00 err = 3.7796484550e-10 time = 0.01 sec -[ Info: VUMPS conv 7: obj = -1.063544409973e+00 err = 2.9001138645e-11 time = 1.69 sec +[ Info: VUMPS init: obj = +4.958532341527e-01 err = 4.0184e-01 +[ Info: VUMPS 1: obj = -1.014182971769e+00 err = 1.6819729194e-01 time = 9.57 sec +[ Info: VUMPS 2: obj = -1.063544208631e+00 err = 4.2583303913e-04 time = 0.01 sec +[ Info: VUMPS 3: obj = -1.063544409973e+00 err = 6.1082631880e-07 time = 0.01 sec +[ Info: VUMPS 4: obj = -1.063544409973e+00 err = 2.0420569870e-08 time = 0.00 sec +[ Info: VUMPS 5: obj = -1.063544409973e+00 err = 8.6924174444e-10 time = 0.00 sec +[ Info: VUMPS conv 6: obj = -1.063544409973e+00 err = 5.3767504258e-11 time = 9.59 sec ```` @@ -130,7 +133,7 @@ dot(ψ₀, ψ₀) ```` ```` -0.9999999999999996 + 3.8955006105253705e-16im +0.9999999999999998 + 2.8068402690374434e-16im ```` so the Loschmidt echo takes on the pleasant form @@ -154,7 +157,7 @@ a single timestep is easy ````julia dt = 0.01 -ψₜ, envs = timestep(ψₜ, H₁, 0, dt, TDVP(), envs); +ψₜ, envs, info = timestep(ψₜ, H₁, 0, dt, TDVP(), envs); ```` With performance in mind we should once again try to re-use these "envs" cache objects. @@ -175,7 +178,7 @@ function infinite_sim(dt = 0.05, finaltime = 5.0) if t < 50dt # if t is sufficiently small, we increase the bond dimension ψₜ, envs = changebonds(ψₜ, H₁, OptimalExpand(; trunc = truncrank(1)), envs) end - ψₜ, envs = timestep(ψₜ, H₁, 0, dt, TDVP(), envs) + ψₜ, envs, info = timestep(ψₜ, H₁, 0, dt, TDVP(), envs) push!(echos, echo(ψₜ, ψ₀)) end diff --git a/docs/src/examples/quantum1d/3.ising-dqpt/main.ipynb b/docs/src/examples/quantum1d/3.ising-dqpt/main.ipynb index e3418901c..1d4893fb7 100644 --- a/docs/src/examples/quantum1d/3.ising-dqpt/main.ipynb +++ b/docs/src/examples/quantum1d/3.ising-dqpt/main.ipynb @@ -16,7 +16,113 @@ "metadata": {}, "outputs": [], "source": [ - "using MPSKit, MPSKitModels, TensorKit" + "using MPSKit, TensorKit\n", + "# Model constructors for the MPSKit documentation and examples.\n", + "# Adapted from MPSKitModels.jl v0.4.7, src/models/{hamiltonians,transfermatrices}.jl:\n", + "# https://github.com/QuantumKitHub/MPSKitModels.jl/tree/v0.4.7/src/models\n", + "# Operators come from TensorKitTensors; chain assembly uses MPSKit directly.\n", + "#\n", + "# MIT License\n", + "# Copyright (c) 2021 Maarten Van Damme\n", + "#\n", + "# Permission is hereby granted, free of charge, to any person obtaining a copy\n", + "# of this software and associated documentation files (the \"Software\"), to deal\n", + "# in the Software without restriction, including without limitation the rights\n", + "# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n", + "# copies of the Software, and to permit persons to whom the Software is\n", + "# furnished to do so, subject to the following conditions:\n", + "#\n", + "# The above copyright notice and this permission notice shall be included in all\n", + "# copies or substantial portions of the Software.\n", + "#\n", + "# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n", + "# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n", + "# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n", + "# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n", + "# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n", + "# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n", + "# SOFTWARE.\n", + "\n", + "module ExampleModels\n", + "\n", + "using MPSKit, TensorKit\n", + "using TensorKitTensors: SpinOperators, BosonOperators, HubbardOperators\n", + "\n", + "export chain_hamiltonian, transverse_field_ising, heisenberg_XXX\n", + "export hubbard_model, bose_hubbard_model, hard_hexagon\n", + "\n", + "# L specifies an open finite chain; otherwise unitcell specifies an infinite chain.\n", + "function chain_hamiltonian(twosite, onesite = nothing; L = nothing, unitcell::Integer = 1)\n", + " nsites = isnothing(L) ? unitcell : L\n", + " nsites isa Integer && nsites > 0 || throw(ArgumentError(\"chain length must be a positive integer\"))\n", + " nbonds = isnothing(L) ? nsites : nsites - 1\n", + " terms = Pair[(i, i + 1) => twosite for i in 1:nbonds]\n", + " if !isnothing(onesite)\n", + " append!(terms, [i => onesite for i in 1:nsites])\n", + " end\n", + " spaces = fill(space(twosite, 1), nsites)\n", + " constructor = isnothing(L) ? InfiniteMPOHamiltonian : FiniteMPOHamiltonian\n", + " return constructor(spaces, terms)\n", + "end\n", + "\n", + "# H = -J sum(σz_i σz_{i+1} + g σx_i).\n", + "function transverse_field_ising(\n", + " T::Type{<:Number} = ComplexF64, symmetry::Type{<:Sector} = Trivial;\n", + " J = 1.0, g = 1.0, kwargs...\n", + " )\n", + " ZZ = 4 * SpinOperators.S_z_S_z(T, symmetry; spin = 1 // 2)\n", + " X = SpinOperators.σˣ(T, symmetry)\n", + " return chain_hamiltonian(-J * ZZ, -J * g * X; kwargs...)\n", + "end\n", + "transverse_field_ising(symmetry::Type{<:Sector}; kwargs...) =\n", + " transverse_field_ising(ComplexF64, symmetry; kwargs...)\n", + "\n", + "# H = J sum(S_i ⋅ S_{i+1}); preserve the examples' spin-1 default.\n", + "function heisenberg_XXX(\n", + " T::Type{<:Number} = ComplexF64, symmetry::Type{<:Sector} = Trivial;\n", + " J = 1.0, spin = 1, kwargs...\n", + " )\n", + " term = J * SpinOperators.S_exchange(T, symmetry; spin)\n", + " return chain_hamiltonian(term; kwargs...)\n", + "end\n", + "heisenberg_XXX(symmetry::Type{<:Sector}; kwargs...) =\n", + " heisenberg_XXX(ComplexF64, symmetry; kwargs...)\n", + "\n", + "# H = -t sum(e⁺_i e⁻_{i+1} + h.c.) + U sum(n↑ n↓) - mu sum(n).\n", + "function hubbard_model(\n", + " T::Type{<:Number} = ComplexF64, particle_symmetry::Type{<:Sector} = Trivial,\n", + " spin_symmetry::Type{<:Sector} = Trivial;\n", + " t = 1.0, U = 1.0, mu = 0.0, kwargs...\n", + " )\n", + " # e_hopping includes the fermionic reordering sign and is Hermitian.\n", + " hopping = HubbardOperators.e_hopping(T, particle_symmetry, spin_symmetry)\n", + " interaction = HubbardOperators.ud_num(T, particle_symmetry, spin_symmetry)\n", + " N = HubbardOperators.e_num(T, particle_symmetry, spin_symmetry)\n", + " return chain_hamiltonian(-t * hopping, U * interaction - mu * N; kwargs...)\n", + "end\n", + "\n", + "# H = -t sum(b⁺_i b⁻_{i+1} + h.c.) + U/2 sum(n(n-1)) - mu sum(n).\n", + "function bose_hubbard_model(\n", + " T::Type{<:Number} = ComplexF64, symmetry::Type{<:Sector} = Trivial;\n", + " cutoff::Integer = 5, t = 1.0, U = 1.0, mu = 0.0, kwargs...\n", + " )\n", + " hopping = BosonOperators.b_plus_b_min(T, symmetry; cutoff) +\n", + " BosonOperators.b_min_b_plus(T, symmetry; cutoff)\n", + " N = BosonOperators.b_num(T, symmetry; cutoff)\n", + " interaction = N * (N - id(domain(N)))\n", + " return chain_hamiltonian(-t * hopping, U / 2 * interaction - mu * N; kwargs...)\n", + "end\n", + "\n", + "function hard_hexagon(T::Type{<:Number} = ComplexF64)\n", + " P = Vect[FibonacciAnyon](:τ => 1)\n", + " O = ones(T, P ⊗ P ← P ⊗ P)\n", + " block(O, FibonacciAnyon(:I)) .*= 0\n", + " return InfiniteMPO([O])\n", + "end\n", + "\n", + "end\n", + "\n", + "using .ExampleModels" ] }, { @@ -47,7 +153,7 @@ "outputs": [], "source": [ "L = 20\n", - "H₀ = transverse_field_ising(FiniteChain(L); g = -0.5)\n", + "H₀ = transverse_field_ising(; L, g = -0.5)\n", "ψ₀ = FiniteMPS(L, ℂ^2, ℂ^10)\n", "ψ₀, _ = find_groundstate(ψ₀, H₀, DMRG());" ] @@ -58,7 +164,7 @@ "source": [ "## Finite MPS quenching\n", "\n", - "We can define a helper function that measures the loschmith echo" + "We can define a helper function that measures the Loschmidt echo:" ] }, { @@ -84,10 +190,10 @@ "metadata": {}, "outputs": [], "source": [ - "H₁ = transverse_field_ising(FiniteChain(L); g = -2.0)\n", + "H₁ = transverse_field_ising(; L, g = -2.0)\n", "ψₜ = deepcopy(ψ₀)\n", "dt = 0.01\n", - "ψₜ, envs = timestep(ψₜ, H₁, 0, dt, TDVP2(; trunc = truncrank(20)));" + "ψₜ, envs, info = timestep(ψₜ, H₁, 0, dt, TDVP2(; trunc = truncrank(20)));" ] }, { @@ -107,10 +213,10 @@ "source": [ "function finite_sim(L; dt = 0.05, finaltime = 5.0)\n", " ψ₀ = FiniteMPS(L, ℂ^2, ℂ^10)\n", - " H₀ = transverse_field_ising(FiniteChain(L); g = -0.5)\n", + " H₀ = transverse_field_ising(; L, g = -0.5)\n", " ψ₀, _ = find_groundstate(ψ₀, H₀, DMRG())\n", "\n", - " H₁ = transverse_field_ising(FiniteChain(L); g = -2.0)\n", + " H₁ = transverse_field_ising(; L, g = -2.0)\n", " ψₜ = deepcopy(ψ₀)\n", " envs = environments(ψₜ, H₁, ψₜ)\n", "\n", @@ -119,7 +225,7 @@ "\n", " for t in times[2:end]\n", " alg = t > 3 * dt ? TDVP() : TDVP2(; trunc = truncrank(50))\n", - " ψₜ, envs = timestep(ψₜ, H₁, 0, dt, alg, envs)\n", + " ψₜ, envs, info = timestep(ψₜ, H₁, 0, dt, alg, envs)\n", " push!(echos, echo(ψₜ, ψ₀))\n", " end\n", "\n", @@ -222,7 +328,7 @@ "outputs": [], "source": [ "dt = 0.01\n", - "ψₜ, envs = timestep(ψₜ, H₁, 0, dt, TDVP(), envs);" + "ψₜ, envs, info = timestep(ψₜ, H₁, 0, dt, TDVP(), envs);" ] }, { @@ -253,7 +359,7 @@ " if t < 50dt # if t is sufficiently small, we increase the bond dimension\n", " ψₜ, envs = changebonds(ψₜ, H₁, OptimalExpand(; trunc = truncrank(1)), envs)\n", " end\n", - " ψₜ, envs = timestep(ψₜ, H₁, 0, dt, TDVP(), envs)\n", + " ψₜ, envs, info = timestep(ψₜ, H₁, 0, dt, TDVP(), envs)\n", " push!(echos, echo(ψₜ, ψ₀))\n", " end\n", "\n", @@ -280,15 +386,15 @@ ], "metadata": { "kernelspec": { - "display_name": "Julia 1.12.6", + "display_name": "Julia 1.13.1", "language": "julia", - "name": "julia-1.12" + "name": "julia-1.13" }, "language_info": { "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", - "version": "1.12.6" + "version": "1.13.1" } }, "nbformat": 4, diff --git a/docs/src/examples/quantum1d/4.xxz-heisenberg/figure-1.png b/docs/src/examples/quantum1d/4.xxz-heisenberg/figure-1.png index f5e4a5ec2..3a2bcd6d4 100644 Binary files a/docs/src/examples/quantum1d/4.xxz-heisenberg/figure-1.png and b/docs/src/examples/quantum1d/4.xxz-heisenberg/figure-1.png differ 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 bd8dee700..f25ecb820 100644 Binary files a/docs/src/examples/quantum1d/4.xxz-heisenberg/figure-2.png and b/docs/src/examples/quantum1d/4.xxz-heisenberg/figure-2.png differ diff --git a/docs/src/examples/quantum1d/4.xxz-heisenberg/index.md b/docs/src/examples/quantum1d/4.xxz-heisenberg/index.md index d1b18bb75..b7192038c 100644 --- a/docs/src/examples/quantum1d/4.xxz-heisenberg/index.md +++ b/docs/src/examples/quantum1d/4.xxz-heisenberg/index.md @@ -12,7 +12,8 @@ In this file we will give step by step instructions on how to analyze the spin 1 The necessary packages to follow this tutorial are: ````julia -using MPSKit, MPSKitModels, TensorKit, Plots +using MPSKit, TensorKit, Plots +using .ExampleModels ```` ## Failure @@ -54,212 +55,14 @@ state = InfiniteMPS(2, 20) The ground state can then be found by calling `find_groundstate`. ````julia -groundstate, cache, delta = find_groundstate(state, H, VUMPS()); +groundstate, cache, info = find_groundstate(state, H, VUMPS()); +info ```` ```` -[ Info: VUMPS init: obj = +2.499992657736e-01 err = 2.3659e-03 -[ Info: VUMPS 1: obj = -1.113720211054e-01 err = 3.4044919149e-01 time = 7.00 sec -[ Info: VUMPS 2: obj = -7.257521722207e-02 err = 3.7501747094e-01 time = 0.29 sec -[ Info: VUMPS 3: obj = -4.083234386194e-02 err = 4.0906387666e-01 time = 0.08 sec -[ Info: VUMPS 4: obj = -1.575841447054e-01 err = 3.6917648883e-01 time = 0.03 sec -[ Info: VUMPS 5: obj = -1.988657390936e-01 err = 3.6791056420e-01 time = 0.03 sec -[ Info: VUMPS 6: obj = -3.197413863086e-01 err = 3.3258645953e-01 time = 0.04 sec -[ Info: VUMPS 7: obj = -7.087435895207e-02 err = 3.8002416604e-01 time = 0.03 sec -[ Info: VUMPS 8: obj = -1.207743137267e-01 err = 3.8655168695e-01 time = 0.02 sec -[ Info: VUMPS 9: obj = -2.086746007253e-01 err = 3.8866997285e-01 time = 0.08 sec -[ Info: VUMPS 10: obj = -2.135149067167e-02 err = 3.9998107520e-01 time = 0.02 sec -[ Info: VUMPS 11: obj = +7.890476682466e-02 err = 3.9662516712e-01 time = 0.02 sec -[ Info: VUMPS 12: obj = +8.179378380698e-02 err = 3.6865902322e-01 time = 0.04 sec -[ Info: VUMPS 13: obj = -3.389058286591e-01 err = 3.3592003962e-01 time = 0.07 sec -[ Info: VUMPS 14: obj = -6.936331877678e-02 err = 4.1384132520e-01 time = 0.02 sec -[ Info: VUMPS 15: obj = -2.095570913077e-01 err = 3.7672687907e-01 time = 0.03 sec -[ Info: VUMPS 16: obj = -8.547010074293e-02 err = 4.0253817589e-01 time = 0.02 sec -[ Info: VUMPS 17: obj = -1.633131236641e-01 err = 3.7085752764e-01 time = 0.01 sec -[ Info: VUMPS 18: obj = -2.440483461804e-01 err = 3.5634709811e-01 time = 0.02 sec -[ Info: VUMPS 19: obj = -2.227348354782e-01 err = 3.6670163212e-01 time = 0.07 sec -[ Info: VUMPS 20: obj = -1.647291995688e-01 err = 3.9547116130e-01 time = 0.03 sec -[ Info: VUMPS 21: obj = -2.272417561286e-01 err = 3.6276621476e-01 time = 0.02 sec -[ Info: VUMPS 22: obj = -3.388919076523e-01 err = 3.1579827529e-01 time = 0.02 sec -[ Info: VUMPS 23: obj = -3.915604574764e-01 err = 2.5208735300e-01 time = 0.07 sec -[ Info: VUMPS 24: obj = -2.716952795096e-01 err = 3.4825332817e-01 time = 0.04 sec -[ Info: VUMPS 25: obj = -2.511746372453e-01 err = 3.6715895791e-01 time = 0.03 sec -[ Info: VUMPS 26: obj = -2.731262108428e-02 err = 3.8195721702e-01 time = 0.04 sec -[ Info: VUMPS 27: obj = -8.401004965257e-02 err = 4.1219830163e-01 time = 0.03 sec -[ Info: VUMPS 28: obj = -5.593112558648e-02 err = 3.7991678397e-01 time = 0.07 sec -[ Info: VUMPS 29: obj = -1.039939899261e-01 err = 4.1791684367e-01 time = 0.04 sec -[ Info: VUMPS 30: obj = +3.646055386088e-02 err = 3.6884640674e-01 time = 0.02 sec -[ Info: VUMPS 31: obj = -1.745961021141e-01 err = 3.7601676764e-01 time = 0.02 sec -[ Info: VUMPS 32: obj = +6.528773402406e-03 err = 3.9555076806e-01 time = 0.02 sec -[ Info: VUMPS 33: obj = -6.925592993288e-02 err = 3.7990669074e-01 time = 0.08 sec -[ Info: VUMPS 34: obj = -1.493711283015e-01 err = 3.9233769652e-01 time = 0.02 sec -[ Info: VUMPS 35: obj = -8.418199500312e-02 err = 3.6340380458e-01 time = 0.02 sec -[ Info: VUMPS 36: obj = -2.276410296255e-02 err = 3.7714183538e-01 time = 0.02 sec -[ Info: VUMPS 37: obj = -1.746306414275e-02 err = 4.3071643087e-01 time = 0.03 sec -[ Info: VUMPS 38: obj = -1.078530946206e-01 err = 4.0554246549e-01 time = 0.08 sec -[ Info: VUMPS 39: obj = -4.201824689181e-03 err = 3.8332228055e-01 time = 0.03 sec -[ Info: VUMPS 40: obj = -1.695196954544e-01 err = 4.0646048881e-01 time = 0.03 sec -[ Info: VUMPS 41: obj = -3.991123357010e-01 err = 2.6404691766e-01 time = 0.03 sec -[ Info: VUMPS 42: obj = -3.731927178774e-04 err = 4.0618023904e-01 time = 0.02 sec -[ Info: VUMPS 43: obj = -1.361859934319e-01 err = 3.8083035475e-01 time = 0.07 sec -[ Info: VUMPS 44: obj = -4.351467677687e-02 err = 3.6067072767e-01 time = 0.01 sec -[ Info: VUMPS 45: obj = +2.036960334903e-02 err = 4.0236374802e-01 time = 0.02 sec -[ Info: VUMPS 46: obj = -2.564786609196e-01 err = 3.6550194687e-01 time = 0.02 sec -[ Info: VUMPS 47: obj = -2.794914053758e-02 err = 3.8554065921e-01 time = 0.03 sec -[ Info: VUMPS 48: obj = -1.456926586076e-01 err = 3.8815324507e-01 time = 0.02 sec -[ Info: VUMPS 49: obj = -1.424477861718e-02 err = 3.7358256943e-01 time = 0.06 sec -[ Info: VUMPS 50: obj = -4.121215827673e-02 err = 3.7267277980e-01 time = 0.02 sec -[ Info: VUMPS 51: obj = -3.082552784588e-01 err = 3.3162188490e-01 time = 0.02 sec -[ Info: VUMPS 52: obj = -2.583717562047e-01 err = 3.6414628453e-01 time = 0.03 sec -[ Info: VUMPS 53: obj = +1.080952855580e-01 err = 3.5691712848e-01 time = 0.02 sec -[ Info: VUMPS 54: obj = -2.388241333550e-01 err = 3.6671504144e-01 time = 0.06 sec -[ Info: VUMPS 55: obj = -2.158989432818e-01 err = 3.5252639302e-01 time = 0.02 sec -[ Info: VUMPS 56: obj = -2.846028253281e-01 err = 3.4280944784e-01 time = 0.02 sec -[ Info: VUMPS 57: obj = -2.844144756572e-01 err = 3.5771158117e-01 time = 0.04 sec -[ Info: VUMPS 58: obj = -3.296915296031e-01 err = 3.4124297389e-01 time = 0.07 sec -[ Info: VUMPS 59: obj = -3.428588110821e-01 err = 3.1055543978e-01 time = 0.05 sec -[ Info: VUMPS 60: obj = -3.689645262669e-01 err = 2.6709254795e-01 time = 0.04 sec -[ Info: VUMPS 61: obj = -1.926296113920e-01 err = 3.9051008708e-01 time = 0.04 sec -[ Info: VUMPS 62: obj = -2.083013559580e-01 err = 3.8360309501e-01 time = 0.09 sec -[ Info: VUMPS 63: obj = -2.330751889106e-01 err = 3.5874442855e-01 time = 0.04 sec -[ Info: VUMPS 64: obj = -1.170346482791e-01 err = 3.8356655434e-01 time = 0.03 sec -[ Info: VUMPS 65: obj = -5.200963578316e-02 err = 3.6833174183e-01 time = 0.03 sec -[ Info: VUMPS 66: obj = -2.197891431095e-02 err = 4.0124794245e-01 time = 0.02 sec -[ Info: VUMPS 67: obj = -1.169084572818e-01 err = 3.9681625944e-01 time = 0.07 sec -[ Info: VUMPS 68: obj = -3.187497224181e-01 err = 3.5389927614e-01 time = 0.03 sec -[ Info: VUMPS 69: obj = -5.774837074080e-02 err = 4.0555259098e-01 time = 0.05 sec -[ Info: VUMPS 70: obj = -1.385925677140e-01 err = 3.5902899521e-01 time = 0.02 sec -[ Info: VUMPS 71: obj = -1.618893406115e-01 err = 3.7624779484e-01 time = 0.02 sec -[ Info: VUMPS 72: obj = -1.501259513086e-01 err = 3.9017543257e-01 time = 0.08 sec -[ Info: VUMPS 73: obj = -2.344578406890e-01 err = 3.7629861390e-01 time = 0.02 sec -[ Info: VUMPS 74: obj = -9.559035249277e-02 err = 3.7722338357e-01 time = 0.02 sec -[ Info: VUMPS 75: obj = -3.559605422071e-01 err = 3.0031220801e-01 time = 0.02 sec -[ Info: VUMPS 76: obj = -1.954426659903e-01 err = 3.7999614851e-01 time = 0.02 sec -[ Info: VUMPS 77: obj = -2.469742715213e-01 err = 3.5932526830e-01 time = 0.07 sec -[ Info: VUMPS 78: obj = +1.378130557437e-02 err = 3.7598886038e-01 time = 0.02 sec -[ Info: VUMPS 79: obj = -1.211793491665e-02 err = 3.6307721624e-01 time = 0.02 sec -[ Info: VUMPS 80: obj = -1.280208560452e-01 err = 4.0740026676e-01 time = 0.03 sec -[ Info: VUMPS 81: obj = -2.377846434769e-01 err = 3.7798079849e-01 time = 0.02 sec -[ Info: VUMPS 82: obj = -3.480513403032e-01 err = 3.1094392423e-01 time = 0.06 sec -[ Info: VUMPS 83: obj = -3.231666531453e-01 err = 3.5795237816e-01 time = 0.03 sec -[ Info: VUMPS 84: obj = -3.230617723979e-01 err = 3.5338137372e-01 time = 0.08 sec -[ Info: VUMPS 85: obj = -1.391043781959e-01 err = 3.7699469945e-01 time = 0.02 sec -[ Info: VUMPS 86: obj = -3.434600465182e-01 err = 3.1162050408e-01 time = 0.08 sec -[ Info: VUMPS 87: obj = -2.896970610423e-01 err = 3.4715325464e-01 time = 0.03 sec -[ Info: VUMPS 88: obj = -3.473500689819e-01 err = 3.0203627103e-01 time = 0.03 sec -[ Info: VUMPS 89: obj = -3.920852749773e-01 err = 2.4261851491e-01 time = 0.04 sec -[ Info: VUMPS 90: obj = -2.323120265885e-03 err = 3.9363699208e-01 time = 0.08 sec -[ Info: VUMPS 91: obj = +6.597719659994e-03 err = 3.6444377682e-01 time = 0.02 sec -[ Info: VUMPS 92: obj = +2.842708237132e-02 err = 3.8036913669e-01 time = 0.02 sec -[ Info: VUMPS 93: obj = +8.866987029294e-02 err = 3.6998433554e-01 time = 0.03 sec -[ Info: VUMPS 94: obj = -5.099903063388e-02 err = 3.6527413192e-01 time = 0.02 sec -[ Info: VUMPS 95: obj = -1.724607412056e-01 err = 3.6271311572e-01 time = 0.06 sec -[ Info: VUMPS 96: obj = -1.359620364521e-01 err = 3.7163521224e-01 time = 0.03 sec -[ Info: VUMPS 97: obj = -2.487229212367e-01 err = 3.5559482532e-01 time = 0.03 sec -[ Info: VUMPS 98: obj = -3.363768011366e-01 err = 3.0691942472e-01 time = 0.02 sec -[ Info: VUMPS 99: obj = -2.349190816289e-01 err = 3.8040603712e-01 time = 0.07 sec -[ Info: VUMPS 100: obj = -2.501766365990e-01 err = 3.3899797906e-01 time = 0.02 sec -[ Info: VUMPS 101: obj = -3.944006951029e-01 err = 2.5365404140e-01 time = 0.02 sec -[ Info: VUMPS 102: obj = -2.995031953737e-02 err = 3.9078970987e-01 time = 0.03 sec -[ Info: VUMPS 103: obj = -1.496727054580e-01 err = 3.8887820541e-01 time = 0.03 sec -[ Info: VUMPS 104: obj = -1.651964515037e-01 err = 3.8482074585e-01 time = 0.06 sec -[ Info: VUMPS 105: obj = -2.136080092702e-01 err = 3.7086717496e-01 time = 0.02 sec -[ Info: VUMPS 106: obj = +2.076780492509e-03 err = 3.7971063787e-01 time = 0.02 sec -[ Info: VUMPS 107: obj = -1.801409094443e-01 err = 3.7203262354e-01 time = 0.02 sec -[ Info: VUMPS 108: obj = -2.824910448641e-01 err = 3.5387251865e-01 time = 0.02 sec -[ Info: VUMPS 109: obj = -1.603436420431e-01 err = 3.9841222680e-01 time = 0.07 sec -[ Info: VUMPS 110: obj = +2.717881863352e-02 err = 3.9583169447e-01 time = 0.02 sec -[ Info: VUMPS 111: obj = +3.649162587405e-02 err = 3.2986973402e-01 time = 0.03 sec -[ Info: VUMPS 112: obj = -1.931191472770e-01 err = 3.8832602682e-01 time = 0.02 sec -[ Info: VUMPS 113: obj = -8.595612263509e-02 err = 3.9456614625e-01 time = 0.02 sec -[ Info: VUMPS 114: obj = -2.052894924418e-01 err = 3.7916182480e-01 time = 0.08 sec -[ Info: VUMPS 115: obj = -1.566623408265e-01 err = 3.7572169212e-01 time = 0.02 sec -[ Info: VUMPS 116: obj = -2.697925193842e-01 err = 3.5224872666e-01 time = 0.03 sec -[ Info: VUMPS 117: obj = -1.653547727749e-01 err = 3.6580445508e-01 time = 0.02 sec -[ Info: VUMPS 118: obj = -3.099498644207e-01 err = 3.3813063847e-01 time = 0.02 sec -[ Info: VUMPS 119: obj = -1.249709134848e-01 err = 3.9297526101e-01 time = 0.07 sec -[ Info: VUMPS 120: obj = -1.759792403391e-01 err = 3.9286117967e-01 time = 0.03 sec -[ Info: VUMPS 121: obj = -1.531238685880e-01 err = 3.7741746395e-01 time = 0.02 sec -[ Info: VUMPS 122: obj = -2.607981777457e-02 err = 4.0319496740e-01 time = 0.03 sec -[ Info: VUMPS 123: obj = -6.592234489034e-02 err = 4.0591425677e-01 time = 0.06 sec -[ Info: VUMPS 124: obj = -6.634520512325e-02 err = 3.5661784954e-01 time = 0.02 sec -[ Info: VUMPS 125: obj = -8.713375234031e-02 err = 3.8753642064e-01 time = 0.03 sec -[ Info: VUMPS 126: obj = -1.125202000113e-01 err = 3.9947548666e-01 time = 0.02 sec -[ Info: VUMPS 127: obj = -7.695667111350e-02 err = 3.8370863324e-01 time = 0.02 sec -[ Info: VUMPS 128: obj = -1.626394492619e-01 err = 3.6111268034e-01 time = 0.06 sec -[ Info: VUMPS 129: obj = -3.049948899402e-01 err = 3.4403324168e-01 time = 0.02 sec -[ Info: VUMPS 130: obj = -1.258602194339e-01 err = 3.9449464476e-01 time = 0.03 sec -[ Info: VUMPS 131: obj = -1.104762253188e-01 err = 3.7940891591e-01 time = 0.03 sec -[ Info: VUMPS 132: obj = +1.961617781097e-01 err = 3.5498814846e-01 time = 0.04 sec -[ Info: VUMPS 133: obj = -5.045117087438e-02 err = 3.9852508192e-01 time = 0.06 sec -[ Info: VUMPS 134: obj = -1.456650620925e-01 err = 3.7944737703e-01 time = 0.02 sec -[ Info: VUMPS 135: obj = -8.263613090518e-02 err = 3.9519353274e-01 time = 0.02 sec -[ Info: VUMPS 136: obj = -1.765342573210e-01 err = 3.8095369610e-01 time = 0.02 sec -[ Info: VUMPS 137: obj = -1.324964043868e-01 err = 3.9563235756e-01 time = 0.02 sec -[ Info: VUMPS 138: obj = -5.801528053563e-03 err = 3.9895803654e-01 time = 0.07 sec -[ Info: VUMPS 139: obj = +3.411995954756e-02 err = 3.7915180484e-01 time = 0.02 sec -[ Info: VUMPS 140: obj = -5.243883424994e-02 err = 3.6892061143e-01 time = 0.02 sec -[ Info: VUMPS 141: obj = -2.240214467858e-01 err = 3.6441762460e-01 time = 0.02 sec -[ Info: VUMPS 142: obj = -2.299190776747e-01 err = 3.6831318301e-01 time = 0.03 sec -[ Info: VUMPS 143: obj = -1.957936901383e-01 err = 3.9355611293e-01 time = 0.06 sec -[ Info: VUMPS 144: obj = -3.444003971032e-01 err = 3.1223261647e-01 time = 0.02 sec -[ Info: VUMPS 145: obj = -4.206622251723e-01 err = 1.7712997133e-01 time = 0.03 sec -[ Info: VUMPS 146: obj = -3.152511465401e-01 err = 3.4248220688e-01 time = 0.04 sec -[ Info: VUMPS 147: obj = -2.523905778375e-01 err = 3.7740870895e-01 time = 0.07 sec -[ Info: VUMPS 148: obj = -4.278492688890e-02 err = 3.5715350579e-01 time = 0.02 sec -[ Info: VUMPS 149: obj = -1.324003340205e-01 err = 4.0013050853e-01 time = 0.02 sec -[ Info: VUMPS 150: obj = -1.068985749883e-01 err = 4.0722208139e-01 time = 0.02 sec -[ Info: VUMPS 151: obj = -2.083862397081e-01 err = 3.6731256501e-01 time = 0.02 sec -[ Info: VUMPS 152: obj = -1.440078983653e-01 err = 3.7426441705e-01 time = 0.06 sec -[ Info: VUMPS 153: obj = -2.520133076021e-01 err = 3.7507045206e-01 time = 0.02 sec -[ Info: VUMPS 154: obj = -1.034831359402e-01 err = 3.3452358556e-01 time = 0.02 sec -[ Info: VUMPS 155: obj = -6.618164126260e-02 err = 3.5135937268e-01 time = 0.03 sec -[ Info: VUMPS 156: obj = -8.742999239375e-02 err = 3.8534304068e-01 time = 0.02 sec -[ Info: VUMPS 157: obj = -1.259714263689e-01 err = 3.9638882368e-01 time = 0.07 sec -[ Info: VUMPS 158: obj = -9.181298201303e-02 err = 3.6918229891e-01 time = 0.02 sec -[ Info: VUMPS 159: obj = -3.681891440506e-01 err = 2.7888162226e-01 time = 0.02 sec -[ Info: VUMPS 160: obj = -3.357053644322e-01 err = 3.2800086170e-01 time = 0.03 sec -[ Info: VUMPS 161: obj = -3.215096951929e-03 err = 3.6664749423e-01 time = 0.07 sec -[ Info: VUMPS 162: obj = +2.646903240101e-03 err = 3.8676335475e-01 time = 0.02 sec -[ Info: VUMPS 163: obj = +7.709386278480e-02 err = 3.5056948614e-01 time = 0.01 sec -[ Info: VUMPS 164: obj = -1.446953476068e-01 err = 3.4180912676e-01 time = 0.02 sec -[ Info: VUMPS 165: obj = -3.581100223225e-01 err = 3.1025051513e-01 time = 0.02 sec -[ Info: VUMPS 166: obj = -2.406814929481e-01 err = 3.8072841015e-01 time = 0.07 sec -[ Info: VUMPS 167: obj = -3.531848910098e-01 err = 3.1053005603e-01 time = 0.02 sec -[ Info: VUMPS 168: obj = -3.297669874782e-01 err = 3.2648804299e-01 time = 0.03 sec -[ Info: VUMPS 169: obj = -1.800883981792e-01 err = 3.7239998435e-01 time = 0.03 sec -[ Info: VUMPS 170: obj = -4.056383454871e-02 err = 3.8301203586e-01 time = 0.03 sec -[ Info: VUMPS 171: obj = -4.448126315315e-02 err = 3.9634205142e-01 time = 0.07 sec -[ Info: VUMPS 172: obj = -3.109186702795e-01 err = 3.4936775901e-01 time = 0.02 sec -[ Info: VUMPS 173: obj = -1.687932549901e-01 err = 3.9713516798e-01 time = 0.02 sec -[ Info: VUMPS 174: obj = -1.703811557590e-01 err = 3.7182890670e-01 time = 0.02 sec -[ Info: VUMPS 175: obj = -1.360221590893e-01 err = 3.7750383659e-01 time = 0.02 sec -[ Info: VUMPS 176: obj = -1.746982448560e-01 err = 3.8728329904e-01 time = 0.07 sec -[ Info: VUMPS 177: obj = -9.378022642433e-02 err = 3.9508912967e-01 time = 0.02 sec -[ Info: VUMPS 178: obj = -1.283340267182e-01 err = 3.8629991015e-01 time = 0.02 sec -[ Info: VUMPS 179: obj = -8.976213980219e-02 err = 4.0495071985e-01 time = 0.02 sec -[ Info: VUMPS 180: obj = -2.669351107647e-01 err = 3.3526515364e-01 time = 0.07 sec -[ Info: VUMPS 181: obj = -3.341709529585e-02 err = 3.8011147844e-01 time = 0.02 sec -[ Info: VUMPS 182: obj = -3.109125460864e-01 err = 3.4567156611e-01 time = 0.03 sec -[ Info: VUMPS 183: obj = -2.183171915980e-01 err = 3.7747243244e-01 time = 0.02 sec -[ Info: VUMPS 184: obj = -2.372842132147e-01 err = 3.7374609557e-01 time = 0.03 sec -[ Info: VUMPS 185: obj = -2.543753578738e-01 err = 3.5816792692e-01 time = 0.07 sec -[ Info: VUMPS 186: obj = -2.469096804733e-01 err = 3.7131984627e-01 time = 0.03 sec -[ Info: VUMPS 187: obj = -1.830902139527e-01 err = 3.9043241343e-01 time = 0.02 sec -[ Info: VUMPS 188: obj = -1.574766929467e-01 err = 3.7319600051e-01 time = 0.03 sec -[ Info: VUMPS 189: obj = -6.991335970984e-02 err = 3.9222107611e-01 time = 0.07 sec -[ Info: VUMPS 190: obj = -1.792846142089e-01 err = 3.6356547438e-01 time = 0.02 sec -[ Info: VUMPS 191: obj = -1.225042448135e-01 err = 3.7360289247e-01 time = 0.02 sec -[ Info: VUMPS 192: obj = -2.129551247072e-01 err = 3.8299381445e-01 time = 0.02 sec -[ Info: VUMPS 193: obj = -8.283800637018e-02 err = 3.8500403241e-01 time = 0.02 sec -[ Info: VUMPS 194: obj = -2.897858859525e-01 err = 3.5007431093e-01 time = 0.06 sec -[ Info: VUMPS 195: obj = -5.369820439974e-02 err = 4.1837283102e-01 time = 0.02 sec -[ Info: VUMPS 196: obj = -2.800880298694e-01 err = 3.7189978262e-01 time = 0.03 sec -[ Info: VUMPS 197: obj = -1.669323399699e-01 err = 3.9481332800e-01 time = 0.03 sec -[ Info: VUMPS 198: obj = -6.212304176188e-02 err = 4.2526435790e-01 time = 0.03 sec -[ Info: VUMPS 199: obj = -4.204616169557e-02 err = 3.7541303170e-01 time = 0.07 sec -┌ Warning: VUMPS cancel 200: obj = -1.383333715979e-01 err = 3.7699700566e-01 time = 14.12 sec -└ @ MPSKit /home/ldevos/LocalProjects/MPSKit.jl/src/algorithms/groundstate/vumps.jl:76 +AlgorithmInfo: + converged = false after 200 iterations + galerkin = 0.362154 ```` @@ -268,13 +71,14 @@ On its own, that is already quite curious. Maybe we can do better using another algorithm, such as gradient descent. ````julia -groundstate, cache, delta = find_groundstate(state, H, GradientGrassmann(; maxiter = 20)); +groundstate, cache, info = find_groundstate(state, H, GradientGrassmann(; maxiter = 20)); +info ```` ```` -[ Info: CG: initializing with f = 2.499992657736e-01, ‖∇f‖ = 1.6729e-03 -┌ Warning: CG: not converged to requested tol after 20 iterations and time 8.29 s: f = -4.426111048892e-01, ‖∇f‖ = 5.5480e-03 -└ @ OptimKit ~/.julia/packages/OptimKit/OEwMx/src/cg.jl:174 +AlgorithmInfo: + converged = false after 20 iterations + gradientnorm = 0.0112804 ```` @@ -314,119 +118,119 @@ state = InfiniteMPS(fill(2, 2), fill(20, 2)) In MPSKit, we require that the periodicity of the Hamiltonian equals that of the state it is applied to. This is not a big obstacle, you can simply repeat the original Hamiltonian. -Alternatively, the Hamiltonian can be constructed directly on a two-site unit cell by making use of MPSKitModels.jl's `@mpoham`. +Alternatively, our model helper can construct the Hamiltonian directly on a two-site unit cell. ````julia # H2 = repeat(H, 2); -- copies the one-site version -H2 = heisenberg_XXX(ComplexF64, Trivial, InfiniteChain(2); spin = 1 // 2) -groundstate, envs, delta = find_groundstate( +H2 = heisenberg_XXX(ComplexF64, Trivial; unitcell = 2, spin = 1 // 2) +groundstate, envs, info = find_groundstate( state, H2, VUMPS(; maxiter = 100, tol = 1.0e-12) ); ```` ```` -[ Info: VUMPS init: obj = +4.987085387825e-01 err = 7.4815e-02 -[ Info: VUMPS 1: obj = -4.070483296483e-02 err = 3.8421207912e-01 time = 0.42 sec -[ Info: VUMPS 2: obj = -8.588956105873e-01 err = 1.4311389089e-01 time = 0.04 sec -[ Info: VUMPS 3: obj = -8.846913958875e-01 err = 1.6288696714e-02 time = 0.03 sec -[ Info: VUMPS 4: obj = -8.858742904256e-01 err = 6.3271162473e-03 time = 0.03 sec -[ Info: VUMPS 5: obj = -8.860994898111e-01 err = 4.7506122055e-03 time = 0.07 sec -[ Info: VUMPS 6: obj = -8.861800643367e-01 err = 2.9027017342e-03 time = 0.04 sec -[ Info: VUMPS 7: obj = -8.862112267309e-01 err = 2.2025348252e-03 time = 0.05 sec -[ Info: VUMPS 8: obj = -8.862256494201e-01 err = 1.5437281695e-03 time = 0.08 sec -[ Info: VUMPS 9: obj = -8.862322270149e-01 err = 1.2285599184e-03 time = 0.05 sec -[ Info: VUMPS 10: obj = -8.862354505034e-01 err = 9.5416020728e-04 time = 0.09 sec -[ Info: VUMPS 11: obj = -8.862369964136e-01 err = 7.5140552439e-04 time = 0.06 sec -[ Info: VUMPS 12: obj = -8.862377649153e-01 err = 6.2947047843e-04 time = 0.06 sec -[ Info: VUMPS 13: obj = -8.862381482190e-01 err = 5.3567155770e-04 time = 0.08 sec -[ Info: VUMPS 14: obj = -8.862383501305e-01 err = 4.9726432030e-04 time = 0.05 sec -[ Info: VUMPS 15: obj = -8.862384635741e-01 err = 4.7373205998e-04 time = 0.04 sec -[ Info: VUMPS 16: obj = -8.862385365416e-01 err = 4.7834381662e-04 time = 0.08 sec -[ Info: VUMPS 17: obj = -8.862385914623e-01 err = 4.9010937476e-04 time = 0.06 sec -[ Info: VUMPS 18: obj = -8.862386397747e-01 err = 5.1562261789e-04 time = 0.09 sec -[ Info: VUMPS 19: obj = -8.862386887080e-01 err = 5.4370412689e-04 time = 0.07 sec -[ Info: VUMPS 20: obj = -8.862387403517e-01 err = 5.8200261169e-04 time = 0.06 sec -[ Info: VUMPS 21: obj = -8.862388009252e-01 err = 6.1775277631e-04 time = 0.11 sec -[ Info: VUMPS 22: obj = -8.862388688746e-01 err = 6.6580030857e-04 time = 0.06 sec -[ Info: VUMPS 23: obj = -8.862389551333e-01 err = 7.0184437921e-04 time = 0.06 sec -[ Info: VUMPS 24: obj = -8.862390538865e-01 err = 7.5533855251e-04 time = 0.09 sec -[ Info: VUMPS 25: obj = -8.862391870753e-01 err = 7.7812725098e-04 time = 0.08 sec -[ Info: VUMPS 26: obj = -8.862393378986e-01 err = 8.2535209132e-04 time = 0.10 sec -[ Info: VUMPS 27: obj = -8.862395466874e-01 err = 8.0853992627e-04 time = 0.05 sec -[ Info: VUMPS 28: obj = -8.862397673707e-01 err = 8.2479835919e-04 time = 0.06 sec -[ Info: VUMPS 29: obj = -8.862400528237e-01 err = 7.3793510189e-04 time = 0.07 sec -[ Info: VUMPS 30: obj = -8.862403146804e-01 err = 6.9781267895e-04 time = 0.05 sec -[ Info: VUMPS 31: obj = -8.862405935152e-01 err = 5.6033545341e-04 time = 0.06 sec -[ Info: VUMPS 32: obj = -8.862408144890e-01 err = 4.7977846041e-04 time = 0.09 sec -[ Info: VUMPS 33: obj = -8.862410054255e-01 err = 3.7069947399e-04 time = 0.06 sec -[ Info: VUMPS 34: obj = -8.862411519178e-01 err = 3.0069863398e-04 time = 0.08 sec -[ Info: VUMPS 35: obj = -8.862412707892e-01 err = 2.4560744504e-04 time = 0.06 sec -[ Info: VUMPS 36: obj = -8.862413665434e-01 err = 2.0272830003e-04 time = 0.06 sec -[ Info: VUMPS 37: obj = -8.862414453558e-01 err = 1.7669114346e-04 time = 0.09 sec -[ Info: VUMPS 38: obj = -8.862415101392e-01 err = 1.4966363352e-04 time = 0.06 sec -[ Info: VUMPS 39: obj = -8.862415632632e-01 err = 1.3429888391e-04 time = 0.09 sec -[ Info: VUMPS 40: obj = -8.862416064083e-01 err = 1.1453939487e-04 time = 0.06 sec -[ Info: VUMPS 41: obj = -8.862416411106e-01 err = 1.0327940645e-04 time = 0.09 sec -[ Info: VUMPS 42: obj = -8.862416687158e-01 err = 8.8267214320e-05 time = 0.06 sec -[ Info: VUMPS 43: obj = -8.862416904652e-01 err = 7.8860063320e-05 time = 0.06 sec -[ Info: VUMPS 44: obj = -8.862417074438e-01 err = 6.7541649023e-05 time = 0.08 sec -[ Info: VUMPS 45: obj = -8.862417205990e-01 err = 5.9561454565e-05 time = 0.04 sec -[ Info: VUMPS 46: obj = -8.862417307234e-01 err = 5.0969707803e-05 time = 0.08 sec -[ Info: VUMPS 47: obj = -8.862417384749e-01 err = 4.4565392480e-05 time = 0.05 sec -[ Info: VUMPS 48: obj = -8.862417443833e-01 err = 3.8093480996e-05 time = 0.06 sec -[ Info: VUMPS 49: obj = -8.862417488723e-01 err = 3.3125644419e-05 time = 0.07 sec -[ Info: VUMPS 50: obj = -8.862417522738e-01 err = 2.8298971982e-05 time = 0.06 sec -[ Info: VUMPS 51: obj = -8.862417548472e-01 err = 2.4528466837e-05 time = 0.10 sec -[ Info: VUMPS 52: obj = -8.862417567915e-01 err = 2.0959047274e-05 time = 0.04 sec -[ Info: VUMPS 53: obj = -8.862417582599e-01 err = 1.8137306177e-05 time = 0.03 sec -[ Info: VUMPS 54: obj = -8.862417593686e-01 err = 1.5513404897e-05 time = 0.06 sec -[ Info: VUMPS 55: obj = -8.862417602060e-01 err = 1.3420069417e-05 time = 0.05 sec -[ Info: VUMPS 56: obj = -8.862417608389e-01 err = 1.1498110058e-05 time = 0.08 sec -[ Info: VUMPS 57: obj = -8.862417613176e-01 err = 9.9527379200e-06 time = 0.05 sec -[ Info: VUMPS 58: obj = -8.862417616801e-01 err = 8.5468069101e-06 time = 0.09 sec -[ Info: VUMPS 59: obj = -8.862417619550e-01 err = 7.4079343001e-06 time = 0.04 sec -[ Info: VUMPS 60: obj = -8.862417621636e-01 err = 6.3789249797e-06 time = 0.05 sec -[ Info: VUMPS 61: obj = -8.862417623223e-01 err = 5.5392243963e-06 time = 0.08 sec -[ Info: VUMPS 62: obj = -8.862417624431e-01 err = 4.7843861025e-06 time = 0.05 sec -[ Info: VUMPS 63: obj = -8.862417625353e-01 err = 4.1638877981e-06 time = 0.09 sec -[ Info: VUMPS 64: obj = -8.862417626056e-01 err = 3.6081493661e-06 time = 0.06 sec -[ Info: VUMPS 65: obj = -8.862417626595e-01 err = 3.1478809644e-06 time = 0.06 sec -[ Info: VUMPS 66: obj = -8.862417627008e-01 err = 2.7367561575e-06 time = 0.09 sec -[ Info: VUMPS 67: obj = -8.862417627324e-01 err = 2.3936907479e-06 time = 0.06 sec -[ Info: VUMPS 68: obj = -8.862417627568e-01 err = 2.0878342869e-06 time = 0.09 sec -[ Info: VUMPS 69: obj = -8.862417627755e-01 err = 1.8307028023e-06 time = 0.07 sec -[ Info: VUMPS 70: obj = -8.862417627899e-01 err = 1.6017548673e-06 time = 0.04 sec -[ Info: VUMPS 71: obj = -8.862417628011e-01 err = 1.4078813339e-06 time = 0.08 sec -[ Info: VUMPS 72: obj = -8.862417628097e-01 err = 1.2353984722e-06 time = 0.05 sec -[ Info: VUMPS 73: obj = -8.862417628163e-01 err = 1.0883299189e-06 time = 0.09 sec -[ Info: VUMPS 74: obj = -8.862417628215e-01 err = 9.5754695615e-07 time = 0.06 sec -[ Info: VUMPS 75: obj = -8.862417628254e-01 err = 8.4531618087e-07 time = 0.06 sec -[ Info: VUMPS 76: obj = -8.862417628285e-01 err = 7.4553090808e-07 time = 0.08 sec -[ Info: VUMPS 77: obj = -8.862417628309e-01 err = 6.5939726315e-07 time = 0.05 sec -[ Info: VUMPS 78: obj = -8.862417628328e-01 err = 5.8281301292e-07 time = 0.06 sec -[ Info: VUMPS 79: obj = -8.862417628343e-01 err = 5.1635751307e-07 time = 0.05 sec -[ Info: VUMPS 80: obj = -8.862417628354e-01 err = 4.5725918727e-07 time = 0.05 sec -[ Info: VUMPS 81: obj = -8.862417628363e-01 err = 4.0573779114e-07 time = 0.10 sec -[ Info: VUMPS 82: obj = -8.862417628370e-01 err = 3.5990703959e-07 time = 0.05 sec -[ Info: VUMPS 83: obj = -8.862417628375e-01 err = 3.1978939846e-07 time = 0.09 sec -[ Info: VUMPS 84: obj = -8.862417628379e-01 err = 2.8408974871e-07 time = 0.06 sec -[ Info: VUMPS 85: obj = -8.862417628382e-01 err = 2.5273008172e-07 time = 0.06 sec -[ Info: VUMPS 86: obj = -8.862417628385e-01 err = 2.2481213666e-07 time = 0.08 sec -[ Info: VUMPS 87: obj = -8.862417628387e-01 err = 2.0021375141e-07 time = 0.06 sec -[ Info: VUMPS 88: obj = -8.862417628389e-01 err = 1.7830492076e-07 time = 0.08 sec -[ Info: VUMPS 89: obj = -8.862417628390e-01 err = 1.5895093159e-07 time = 0.06 sec -[ Info: VUMPS 90: obj = -8.862417628391e-01 err = 1.4170464909e-07 time = 0.05 sec -[ Info: VUMPS 91: obj = -8.862417628391e-01 err = 1.2643555469e-07 time = 0.08 sec -[ Info: VUMPS 92: obj = -8.862417628392e-01 err = 1.1282240133e-07 time = 0.06 sec -[ Info: VUMPS 93: obj = -8.862417628393e-01 err = 1.0074688630e-07 time = 0.08 sec -[ Info: VUMPS 94: obj = -8.862417628393e-01 err = 8.9975370500e-08 time = 0.04 sec -[ Info: VUMPS 95: obj = -8.862417628393e-01 err = 8.0404798877e-08 time = 0.06 sec -[ Info: VUMPS 96: obj = -8.862417628393e-01 err = 7.1863230951e-08 time = 0.08 sec -[ Info: VUMPS 97: obj = -8.862417628394e-01 err = 6.4263171589e-08 time = 0.05 sec -[ Info: VUMPS 98: obj = -8.862417628394e-01 err = 5.7476665744e-08 time = 0.07 sec -[ Info: VUMPS 99: obj = -8.862417628394e-01 err = 5.1430713814e-08 time = 0.04 sec -┌ Warning: VUMPS cancel 100: obj = -8.862417628394e-01 err = 4.6029104045e-08 time = 6.81 sec -└ @ MPSKit /home/ldevos/LocalProjects/MPSKit.jl/src/algorithms/groundstate/vumps.jl:76 +[ Info: VUMPS init: obj = +4.997527111444e-01 err = 3.2696e-02 +[ Info: VUMPS 1: obj = -4.467165998476e-01 err = 3.1609479029e-01 time = 0.02 sec +[ Info: VUMPS 2: obj = -8.771683852570e-01 err = 6.2050493215e-02 time = 0.01 sec +[ Info: VUMPS 3: obj = -8.851498316480e-01 err = 1.1961437282e-02 time = 0.01 sec +[ Info: VUMPS 4: obj = -8.859041509393e-01 err = 6.3855220428e-03 time = 0.01 sec +[ Info: VUMPS 5: obj = -8.861046661398e-01 err = 4.2618759637e-03 time = 0.01 sec +[ Info: VUMPS 6: obj = -8.861780680439e-01 err = 2.8925460191e-03 time = 0.13 sec +[ Info: VUMPS 7: obj = -8.862081622654e-01 err = 2.2292422649e-03 time = 0.02 sec +[ Info: VUMPS 8: obj = -8.862224756657e-01 err = 1.6435394411e-03 time = 0.02 sec +[ Info: VUMPS 9: obj = -8.862294034930e-01 err = 1.3092870547e-03 time = 0.02 sec +[ Info: VUMPS 10: obj = -8.862329064156e-01 err = 9.9464595759e-04 time = 0.02 sec +[ Info: VUMPS 11: obj = -8.862346804992e-01 err = 8.0850406574e-04 time = 0.02 sec +[ Info: VUMPS 12: obj = -8.862355904749e-01 err = 6.4946824659e-04 time = 0.02 sec +[ Info: VUMPS 13: obj = -8.862360590666e-01 err = 5.4465159459e-04 time = 0.02 sec +[ Info: VUMPS 14: obj = -8.862363024838e-01 err = 4.6490637106e-04 time = 0.02 sec +[ Info: VUMPS 15: obj = -8.862364302780e-01 err = 4.0282057210e-04 time = 0.02 sec +[ Info: VUMPS 16: obj = -8.862364987557e-01 err = 3.5830647316e-04 time = 0.02 sec +[ Info: VUMPS 17: obj = -8.862365362487e-01 err = 3.1735310901e-04 time = 0.02 sec +[ Info: VUMPS 18: obj = -8.862365577473e-01 err = 2.8785456855e-04 time = 0.02 sec +[ Info: VUMPS 19: obj = -8.862365705090e-01 err = 2.5781877596e-04 time = 0.02 sec +[ Info: VUMPS 20: obj = -8.862365786770e-01 err = 2.3555411931e-04 time = 0.02 sec +[ Info: VUMPS 21: obj = -8.862365840895e-01 err = 2.1202440035e-04 time = 0.02 sec +[ Info: VUMPS 22: obj = -8.862365879952e-01 err = 1.9412564250e-04 time = 0.02 sec +[ Info: VUMPS 23: obj = -8.862365908485e-01 err = 1.7507326697e-04 time = 0.02 sec +[ Info: VUMPS 24: obj = -8.862365930912e-01 err = 1.6034513739e-04 time = 0.02 sec +[ Info: VUMPS 25: obj = -8.862365948285e-01 err = 1.4470698602e-04 time = 0.10 sec +[ Info: VUMPS 26: obj = -8.862365962571e-01 err = 1.3251239826e-04 time = 0.02 sec +[ Info: VUMPS 27: obj = -8.862365973948e-01 err = 1.1960733073e-04 time = 0.02 sec +[ Info: VUMPS 28: obj = -8.862365983500e-01 err = 1.0950376923e-04 time = 0.02 sec +[ Info: VUMPS 29: obj = -8.862365991198e-01 err = 9.8841277504e-05 time = 0.02 sec +[ Info: VUMPS 30: obj = -8.862365997728e-01 err = 9.0477029620e-05 time = 0.02 sec +[ Info: VUMPS 31: obj = -8.862366003020e-01 err = 8.1667414680e-05 time = 0.02 sec +[ Info: VUMPS 32: obj = -8.862366007537e-01 err = 7.4749996341e-05 time = 0.02 sec +[ Info: VUMPS 33: obj = -8.862366011212e-01 err = 6.7475286046e-05 time = 0.02 sec +[ Info: VUMPS 34: obj = -8.862366014364e-01 err = 6.1759302086e-05 time = 0.02 sec +[ Info: VUMPS 35: obj = -8.862366016936e-01 err = 5.5756232982e-05 time = 0.02 sec +[ Info: VUMPS 36: obj = -8.862366019155e-01 err = 5.1036052619e-05 time = 0.02 sec +[ Info: VUMPS 37: obj = -8.862366020972e-01 err = 4.6085571441e-05 time = 0.02 sec +[ Info: VUMPS 38: obj = -8.862366022548e-01 err = 4.2189530975e-05 time = 0.02 sec +[ Info: VUMPS 39: obj = -8.862366023846e-01 err = 3.8109078449e-05 time = 0.02 sec +[ Info: VUMPS 40: obj = -8.862366024978e-01 err = 3.4894596256e-05 time = 0.02 sec +[ Info: VUMPS 41: obj = -8.862366025917e-01 err = 3.1532851418e-05 time = 0.02 sec +[ Info: VUMPS 42: obj = -8.862366026742e-01 err = 2.8881208593e-05 time = 0.05 sec +[ Info: VUMPS 43: obj = -8.862366027431e-01 err = 2.6112378900e-05 time = 0.02 sec +[ Info: VUMPS 44: obj = -8.862366028041e-01 err = 2.3925599243e-05 time = 0.02 sec +[ Info: VUMPS 45: obj = -8.862366028556e-01 err = 2.1645498079e-05 time = 0.02 sec +[ Info: VUMPS 46: obj = -8.862366029016e-01 err = 1.9842772827e-05 time = 0.02 sec +[ Info: VUMPS 47: obj = -8.862366029409e-01 err = 1.7965352398e-05 time = 0.02 sec +[ Info: VUMPS 48: obj = -8.862366029763e-01 err = 1.6479776112e-05 time = 0.02 sec +[ Info: VUMPS 49: obj = -8.862366030070e-01 err = 1.4934164897e-05 time = 0.02 sec +[ Info: VUMPS 50: obj = -8.862366030349e-01 err = 1.3711041185e-05 time = 0.02 sec +[ Info: VUMPS 51: obj = -8.862366030594e-01 err = 1.2438715217e-05 time = 0.02 sec +[ Info: VUMPS 52: obj = -8.862366030820e-01 err = 1.1432932435e-05 time = 0.02 sec +[ Info: VUMPS 53: obj = -8.862366031022e-01 err = 1.0385875308e-05 time = 0.02 sec +[ Info: VUMPS 54: obj = -8.862366031209e-01 err = 9.5604213133e-06 time = 0.02 sec +[ Info: VUMPS 55: obj = -8.862366031379e-01 err = 8.6992460003e-06 time = 0.04 sec +[ Info: VUMPS 56: obj = -8.862366031539e-01 err = 8.0238879246e-06 time = 0.02 sec +[ Info: VUMPS 57: obj = -8.862366031686e-01 err = 7.3163045808e-06 time = 0.02 sec +[ Info: VUMPS 58: obj = -8.862366031826e-01 err = 6.7662395359e-06 time = 0.02 sec +[ Info: VUMPS 59: obj = -8.862366031957e-01 err = 6.1858182842e-06 time = 0.02 sec +[ Info: VUMPS 60: obj = -8.862366032082e-01 err = 5.7405851073e-06 time = 0.02 sec +[ Info: VUMPS 61: obj = -8.862366032201e-01 err = 5.2657759313e-06 time = 0.02 sec +[ Info: VUMPS 62: obj = -8.862366032316e-01 err = 4.9086532906e-06 time = 0.02 sec +[ Info: VUMPS 63: obj = -8.862366032426e-01 err = 4.5216221699e-06 time = 0.02 sec +[ Info: VUMPS 64: obj = -8.862366032533e-01 err = 4.2388065454e-06 time = 0.02 sec +[ Info: VUMPS 65: obj = -8.862366032637e-01 err = 3.9249530862e-06 time = 0.02 sec +[ Info: VUMPS 66: obj = -8.862366032738e-01 err = 3.7047993738e-06 time = 0.04 sec +[ Info: VUMPS 67: obj = -8.862366032837e-01 err = 3.4517513192e-06 time = 0.02 sec +[ Info: VUMPS 68: obj = -8.862366032935e-01 err = 3.2843770942e-06 time = 0.02 sec +[ Info: VUMPS 69: obj = -8.862366033031e-01 err = 3.0817221596e-06 time = 0.02 sec +[ Info: VUMPS 70: obj = -8.862366033126e-01 err = 2.9584112144e-06 time = 0.02 sec +[ Info: VUMPS 71: obj = -8.862366033220e-01 err = 2.7971587484e-06 time = 0.02 sec +[ Info: VUMPS 72: obj = -8.862366033313e-01 err = 2.7102153339e-06 time = 0.02 sec +[ Info: VUMPS 73: obj = -8.862366033406e-01 err = 2.5825604765e-06 time = 0.02 sec +[ Info: VUMPS 74: obj = -8.862366033498e-01 err = 2.5250442735e-06 time = 0.02 sec +[ Info: VUMPS 75: obj = -8.862366033589e-01 err = 2.4242363359e-06 time = 0.04 sec +[ Info: VUMPS 76: obj = -8.862366033681e-01 err = 2.3900277294e-06 time = 0.02 sec +[ Info: VUMPS 77: obj = -8.862366033772e-01 err = 2.3102610808e-06 time = 0.02 sec +[ Info: VUMPS 78: obj = -8.862366033863e-01 err = 2.2940867965e-06 time = 0.02 sec +[ Info: VUMPS 79: obj = -8.862366033954e-01 err = 2.2305152062e-06 time = 0.02 sec +[ Info: VUMPS 80: obj = -8.862366034046e-01 err = 2.2279952080e-06 time = 0.02 sec +[ Info: VUMPS 81: obj = -8.862366034137e-01 err = 2.1766874277e-06 time = 0.02 sec +[ Info: VUMPS 82: obj = -8.862366034229e-01 err = 2.1843045604e-06 time = 0.02 sec +[ Info: VUMPS 83: obj = -8.862366034321e-01 err = 2.1421521997e-06 time = 0.02 sec +[ Info: VUMPS 84: obj = -8.862366034413e-01 err = 2.1571782976e-06 time = 0.02 sec +[ Info: VUMPS 85: obj = -8.862366034506e-01 err = 2.1217886209e-06 time = 0.04 sec +[ Info: VUMPS 86: obj = -8.862366034599e-01 err = 2.1421645111e-06 time = 0.02 sec +[ Info: VUMPS 87: obj = -8.862366034693e-01 err = 2.1117287888e-06 time = 0.02 sec +[ Info: VUMPS 88: obj = -8.862366034787e-01 err = 2.1359334516e-06 time = 0.02 sec +[ Info: VUMPS 89: obj = -8.862366034881e-01 err = 2.1182010907e-06 time = 0.02 sec +[ Info: VUMPS 90: obj = -8.862366034976e-01 err = 2.1360357707e-06 time = 0.02 sec +[ Info: VUMPS 91: obj = -8.862366035072e-01 err = 2.1293906978e-06 time = 0.02 sec +[ Info: VUMPS 92: obj = -8.862366035168e-01 err = 2.1406884482e-06 time = 0.02 sec +[ Info: VUMPS 93: obj = -8.862366035265e-01 err = 2.1413862999e-06 time = 0.02 sec +[ Info: VUMPS 94: obj = -8.862366035362e-01 err = 2.1486037196e-06 time = 0.04 sec +[ Info: VUMPS 95: obj = -8.862366035460e-01 err = 2.1540387251e-06 time = 0.02 sec +[ Info: VUMPS 96: obj = -8.862366035558e-01 err = 2.1588561110e-06 time = 0.02 sec +[ Info: VUMPS 97: obj = -8.862366035657e-01 err = 2.1672377887e-06 time = 0.02 sec +[ Info: VUMPS 98: obj = -8.862366035757e-01 err = 2.1707822036e-06 time = 0.02 sec +[ Info: VUMPS 99: obj = -8.862366035858e-01 err = 2.1808977510e-06 time = 0.02 sec +┌ Warning: VUMPS cancel 100: obj = -8.862366035959e-01 err = 2.1839074149e-06 time = 2.16 sec +└ @ MPSKit ~/Projects/MPSKit.jl/ld-release/src/algorithms/groundstate/vumps.jl:96 ```` @@ -434,7 +238,7 @@ We get convergence, but it takes an enormous amount of iterations. The reason behind this becomes more obvious at higher bond dimensions: ````julia -groundstate, envs, delta = find_groundstate( +groundstate, envs, info = find_groundstate( state, H2, IDMRG2(; trunc = truncrank(50), maxiter = 20, tol = 1.0e-12) ); entanglementplot(groundstate) @@ -456,7 +260,7 @@ The XXZ Heisenberg Hamiltonian is SU(2) symmetric and we can exploit this to gre It is cumbersome to construct symmetric Hamiltonians, but luckily SU(2) symmetric XXZ is already implemented: ````julia -H2 = heisenberg_XXX(ComplexF64, SU2Irrep, InfiniteChain(2); spin = 1 // 2); +H2 = heisenberg_XXX(ComplexF64, SU2Irrep; unitcell = 2, spin = 1 // 2); ```` Our initial state should also be SU(2) symmetric. @@ -476,7 +280,7 @@ state = InfiniteMPS([P, P], [V1, V2]); ```` ┌ Warning: Constructing an MPS from tensors that are not full rank -└ @ MPSKit /home/ldevos/LocalProjects/MPSKit.jl/src/states/infinitemps.jl:160 +└ @ MPSKit ~/Projects/MPSKit.jl/ld-release/src/states/infinitemps.jl:188 ```` @@ -485,80 +289,81 @@ Even though the bond dimension is higher than in the example without symmetry, c ````julia println(dim(V1)) println(dim(V2)) -groundstate, cache, delta = find_groundstate(state, H2, VUMPS(; maxiter = 400, tol = 1.0e-12)); +groundstate, cache, info = find_groundstate(state, H2, VUMPS(; maxiter = 400, tol = 1.0e-12)); ```` ```` 52 70 -[ Info: VUMPS init: obj = +8.454690130663e-02 err = 3.6812e-01 -[ Info: VUMPS 1: obj = -8.807747096663e-01 err = 7.4524923622e-02 time = 3.77 sec -[ Info: VUMPS 2: obj = -8.858788324414e-01 err = 6.9171953600e-03 time = 0.05 sec -[ Info: VUMPS 3: obj = -8.861621536444e-01 err = 2.6767683452e-03 time = 0.04 sec -[ Info: VUMPS 4: obj = -8.862392626495e-01 err = 1.6032192901e-03 time = 0.04 sec -[ Info: VUMPS 5: obj = -8.862672547653e-01 err = 9.5323528320e-04 time = 0.05 sec -[ Info: VUMPS 6: obj = -8.862784830480e-01 err = 7.0061763044e-04 time = 0.05 sec -[ Info: VUMPS 7: obj = -8.862834114803e-01 err = 5.7030493713e-04 time = 0.06 sec -[ Info: VUMPS 8: obj = -8.862857129161e-01 err = 4.5154675114e-04 time = 0.15 sec -[ Info: VUMPS 9: obj = -8.862868209497e-01 err = 3.5140725914e-04 time = 0.05 sec -[ Info: VUMPS 10: obj = -8.862873648329e-01 err = 2.6806862728e-04 time = 0.13 sec -[ Info: VUMPS 11: obj = -8.862876338388e-01 err = 2.0070574932e-04 time = 0.11 sec -[ Info: VUMPS 12: obj = -8.862877672196e-01 err = 1.4816530119e-04 time = 0.07 sec -[ Info: VUMPS 13: obj = -8.862878333408e-01 err = 1.0821757653e-04 time = 0.15 sec -[ Info: VUMPS 14: obj = -8.862878660733e-01 err = 7.8417469213e-05 time = 0.06 sec -[ Info: VUMPS 15: obj = -8.862878822601e-01 err = 5.6494124158e-05 time = 0.07 sec -[ Info: VUMPS 16: obj = -8.862878902612e-01 err = 4.0537829957e-05 time = 0.06 sec -[ Info: VUMPS 17: obj = -8.862878942156e-01 err = 2.9004225089e-05 time = 0.07 sec -[ Info: VUMPS 18: obj = -8.862878961706e-01 err = 2.0708366147e-05 time = 0.07 sec -[ Info: VUMPS 19: obj = -8.862878971378e-01 err = 1.4762413368e-05 time = 0.13 sec -[ Info: VUMPS 20: obj = -8.862878976166e-01 err = 1.0511055800e-05 time = 0.03 sec -[ Info: VUMPS 21: obj = -8.862878978539e-01 err = 7.4778223881e-06 time = 0.03 sec -[ Info: VUMPS 22: obj = -8.862878979715e-01 err = 5.3158051331e-06 time = 0.07 sec -[ Info: VUMPS 23: obj = -8.862878980299e-01 err = 3.7764425487e-06 time = 0.07 sec -[ Info: VUMPS 24: obj = -8.862878980589e-01 err = 2.6814072095e-06 time = 0.14 sec -[ Info: VUMPS 25: obj = -8.862878980733e-01 err = 1.9030014616e-06 time = 0.06 sec -[ Info: VUMPS 26: obj = -8.862878980805e-01 err = 1.3500577199e-06 time = 0.06 sec -[ Info: VUMPS 27: obj = -8.862878980841e-01 err = 9.5735794398e-07 time = 0.06 sec -[ Info: VUMPS 28: obj = -8.862878980859e-01 err = 6.7863772480e-07 time = 0.06 sec -[ Info: VUMPS 29: obj = -8.862878980867e-01 err = 4.8090393886e-07 time = 0.14 sec -[ Info: VUMPS 30: obj = -8.862878980872e-01 err = 3.4067956729e-07 time = 0.06 sec -[ Info: VUMPS 31: obj = -8.862878980874e-01 err = 2.4127441738e-07 time = 0.05 sec -[ Info: VUMPS 32: obj = -8.862878980875e-01 err = 1.7082422697e-07 time = 0.05 sec -[ Info: VUMPS 33: obj = -8.862878980876e-01 err = 1.2091935762e-07 time = 0.06 sec -[ Info: VUMPS 34: obj = -8.862878980876e-01 err = 8.5574898934e-08 time = 0.05 sec -[ Info: VUMPS 35: obj = -8.862878980876e-01 err = 6.0549094354e-08 time = 0.13 sec -[ Info: VUMPS 36: obj = -8.862878980877e-01 err = 4.2833729305e-08 time = 0.05 sec -[ Info: VUMPS 37: obj = -8.862878980877e-01 err = 3.0296142094e-08 time = 0.06 sec -[ Info: VUMPS 38: obj = -8.862878980877e-01 err = 2.1424846144e-08 time = 0.06 sec -[ Info: VUMPS 39: obj = -8.862878980877e-01 err = 1.5148957750e-08 time = 0.06 sec -[ Info: VUMPS 40: obj = -8.862878980877e-01 err = 1.0709953737e-08 time = 0.12 sec -[ Info: VUMPS 41: obj = -8.862878980877e-01 err = 7.5707891268e-09 time = 0.03 sec -[ Info: VUMPS 42: obj = -8.862878980877e-01 err = 5.3510570418e-09 time = 0.04 sec -[ Info: VUMPS 43: obj = -8.862878980877e-01 err = 3.7817943502e-09 time = 0.07 sec -[ Info: VUMPS 44: obj = -8.862878980877e-01 err = 2.6724193960e-09 time = 0.06 sec -[ Info: VUMPS 45: obj = -8.862878980877e-01 err = 1.8882939261e-09 time = 0.07 sec -[ Info: VUMPS 46: obj = -8.862878980877e-01 err = 1.3341314150e-09 time = 0.11 sec -[ Info: VUMPS 47: obj = -8.862878980877e-01 err = 9.4252990942e-10 time = 0.06 sec -[ Info: VUMPS 48: obj = -8.862878980877e-01 err = 6.6582278922e-10 time = 0.06 sec -[ Info: VUMPS 49: obj = -8.862878980877e-01 err = 4.7032251942e-10 time = 0.06 sec -[ Info: VUMPS 50: obj = -8.862878980877e-01 err = 3.3220639408e-10 time = 0.06 sec -[ Info: VUMPS 51: obj = -8.862878980878e-01 err = 2.3463502230e-10 time = 0.12 sec -[ Info: VUMPS 52: obj = -8.862878980878e-01 err = 1.6571486183e-10 time = 0.05 sec -[ Info: VUMPS 53: obj = -8.862878980878e-01 err = 1.1703442495e-10 time = 0.05 sec -[ Info: VUMPS 54: obj = -8.862878980878e-01 err = 8.2650109655e-11 time = 0.06 sec -[ Info: VUMPS 55: obj = -8.862878980878e-01 err = 5.8367474734e-11 time = 0.05 sec -[ Info: VUMPS 56: obj = -8.862878980878e-01 err = 4.1213417017e-11 time = 0.12 sec -[ Info: VUMPS 57: obj = -8.862878980878e-01 err = 2.9101697547e-11 time = 0.04 sec -[ Info: VUMPS 58: obj = -8.862878980878e-01 err = 2.0551179926e-11 time = 0.06 sec -[ Info: VUMPS 59: obj = -8.862878980878e-01 err = 1.4510549999e-11 time = 0.06 sec -[ Info: VUMPS 60: obj = -8.862878980878e-01 err = 1.0245548104e-11 time = 0.05 sec -[ Info: VUMPS 61: obj = -8.862878980878e-01 err = 7.2325909689e-12 time = 0.06 sec -[ Info: VUMPS 62: obj = -8.862878980878e-01 err = 5.1092588216e-12 time = 0.12 sec -[ Info: VUMPS 63: obj = -8.862878980878e-01 err = 3.6043616497e-12 time = 0.02 sec -[ Info: VUMPS 64: obj = -8.862878980878e-01 err = 2.5462748087e-12 time = 0.04 sec -[ Info: VUMPS 65: obj = -8.862878980878e-01 err = 1.7984804673e-12 time = 0.03 sec -[ Info: VUMPS 66: obj = -8.862878980878e-01 err = 1.2696913652e-12 time = 0.02 sec -[ Info: VUMPS conv 67: obj = -8.862878980879e-01 err = 8.9456922075e-13 time = 8.25 sec +[ Info: VUMPS init: obj = +1.095066760899e-02 err = 3.8232e-01 +[ Info: VUMPS 1: obj = -8.684099588789e-01 err = 1.4192144156e-01 time = 0.04 sec +[ Info: VUMPS 2: obj = -8.856573419610e-01 err = 9.8872106961e-03 time = 0.03 sec +[ Info: VUMPS 3: obj = -8.861205883550e-01 err = 3.1733701748e-03 time = 0.02 sec +[ Info: VUMPS 4: obj = -8.862275964002e-01 err = 1.5516807918e-03 time = 0.02 sec +[ Info: VUMPS 5: obj = -8.862625967019e-01 err = 1.0267980767e-03 time = 0.03 sec +[ Info: VUMPS 6: obj = -8.862756220945e-01 err = 1.1282651615e-03 time = 0.03 sec +[ Info: VUMPS 7: obj = -8.862824937091e-01 err = 6.9628740468e-04 time = 0.04 sec +[ Info: VUMPS 8: obj = -8.862853415694e-01 err = 5.0842789444e-04 time = 0.04 sec +[ Info: VUMPS 9: obj = -8.862866503123e-01 err = 3.8421438111e-04 time = 0.04 sec +[ Info: VUMPS 10: obj = -8.862872825540e-01 err = 2.8867805561e-04 time = 0.04 sec +[ Info: VUMPS 11: obj = -8.862875933596e-01 err = 2.1457518770e-04 time = 0.04 sec +[ Info: VUMPS 12: obj = -8.862877471486e-01 err = 1.5782954819e-04 time = 0.04 sec +[ Info: VUMPS 13: obj = -8.862878233469e-01 err = 1.1508389249e-04 time = 0.04 sec +[ Info: VUMPS 14: obj = -8.862878610880e-01 err = 8.3336988600e-05 time = 0.04 sec +[ Info: VUMPS 15: obj = -8.862878797702e-01 err = 6.0038192052e-05 time = 0.04 sec +[ Info: VUMPS 16: obj = -8.862878890168e-01 err = 4.3094839313e-05 time = 0.04 sec +[ Info: VUMPS 17: obj = -8.862878935931e-01 err = 3.0849559494e-05 time = 0.04 sec +[ Info: VUMPS 18: obj = -8.862878958589e-01 err = 2.2040393489e-05 time = 0.04 sec +[ Info: VUMPS 19: obj = -8.862878969816e-01 err = 1.5724344210e-05 time = 0.04 sec +[ Info: VUMPS 20: obj = -8.862878975383e-01 err = 1.1207061829e-05 time = 0.04 sec +[ Info: VUMPS 21: obj = -8.862878978145e-01 err = 7.9802923961e-06 time = 0.05 sec +[ Info: VUMPS 22: obj = -8.862878979518e-01 err = 5.6786905881e-06 time = 0.04 sec +[ Info: VUMPS 23: obj = -8.862878980200e-01 err = 4.0384681808e-06 time = 0.04 sec +[ Info: VUMPS 24: obj = -8.862878980539e-01 err = 2.8706728032e-06 time = 0.05 sec +[ Info: VUMPS 25: obj = -8.862878980708e-01 err = 2.0396825400e-06 time = 0.04 sec +[ Info: VUMPS 26: obj = -8.862878980792e-01 err = 1.4486713999e-06 time = 0.04 sec +[ Info: VUMPS 27: obj = -8.862878980834e-01 err = 1.0285324661e-06 time = 0.04 sec +[ Info: VUMPS 28: obj = -8.862878980855e-01 err = 7.2999868426e-07 time = 0.04 sec +[ Info: VUMPS 29: obj = -8.862878980866e-01 err = 5.1797460190e-07 time = 0.04 sec +[ Info: VUMPS 30: obj = -8.862878980871e-01 err = 3.6739836299e-07 time = 0.25 sec +[ Info: VUMPS 31: obj = -8.862878980874e-01 err = 2.6052111260e-07 time = 0.04 sec +[ Info: VUMPS 32: obj = -8.862878980875e-01 err = 1.8468688278e-07 time = 0.04 sec +[ Info: VUMPS 33: obj = -8.862878980876e-01 err = 1.3089495633e-07 time = 0.04 sec +[ Info: VUMPS 34: obj = -8.862878980876e-01 err = 9.2749261799e-08 time = 0.04 sec +[ Info: VUMPS 35: obj = -8.862878980876e-01 err = 6.5706029833e-08 time = 0.04 sec +[ Info: VUMPS 36: obj = -8.862878980877e-01 err = 4.6538615080e-08 time = 0.04 sec +[ Info: VUMPS 37: obj = -8.862878980877e-01 err = 3.2956500195e-08 time = 0.04 sec +[ Info: VUMPS 38: obj = -8.862878980877e-01 err = 2.3334242105e-08 time = 0.04 sec +[ Info: VUMPS 39: obj = -8.862878980877e-01 err = 1.6518729926e-08 time = 0.04 sec +[ Info: VUMPS 40: obj = -8.862878980877e-01 err = 1.1691719289e-08 time = 0.04 sec +[ Info: VUMPS 41: obj = -8.862878980877e-01 err = 8.2744103020e-09 time = 0.04 sec +[ Info: VUMPS 42: obj = -8.862878980877e-01 err = 5.8551948016e-09 time = 0.04 sec +[ Info: VUMPS 43: obj = -8.862878980877e-01 err = 4.1428084059e-09 time = 0.04 sec +[ Info: VUMPS 44: obj = -8.862878980877e-01 err = 2.9308969106e-09 time = 0.04 sec +[ Info: VUMPS 45: obj = -8.862878980877e-01 err = 2.0733038404e-09 time = 0.04 sec +[ Info: VUMPS 46: obj = -8.862878980877e-01 err = 1.4665094165e-09 time = 0.04 sec +[ Info: VUMPS 47: obj = -8.862878980877e-01 err = 1.0372149373e-09 time = 0.04 sec +[ Info: VUMPS 48: obj = -8.862878980877e-01 err = 7.3354405997e-10 time = 0.04 sec +[ Info: VUMPS 49: obj = -8.862878980877e-01 err = 5.1872860630e-10 time = 0.04 sec +[ Info: VUMPS 50: obj = -8.862878980877e-01 err = 3.6679629721e-10 time = 0.04 sec +[ Info: VUMPS 51: obj = -8.862878980878e-01 err = 2.5934803265e-10 time = 0.04 sec +[ Info: VUMPS 52: obj = -8.862878980878e-01 err = 1.8336362201e-10 time = 0.04 sec +[ Info: VUMPS 53: obj = -8.862878980878e-01 err = 1.2963594600e-10 time = 0.04 sec +[ Info: VUMPS 54: obj = -8.862878980878e-01 err = 9.1643274941e-11 time = 0.04 sec +[ Info: VUMPS 55: obj = -8.862878980878e-01 err = 6.4784009585e-11 time = 0.04 sec +[ Info: VUMPS 56: obj = -8.862878980878e-01 err = 4.5794931902e-11 time = 0.04 sec +[ Info: VUMPS 57: obj = -8.862878980878e-01 err = 3.2368796597e-11 time = 0.04 sec +[ Info: VUMPS 58: obj = -8.862878980878e-01 err = 2.2877874652e-11 time = 0.04 sec +[ Info: VUMPS 59: obj = -8.862878980878e-01 err = 1.6173234498e-11 time = 0.18 sec +[ Info: VUMPS 60: obj = -8.862878980878e-01 err = 1.1431584803e-11 time = 0.03 sec +[ Info: VUMPS 61: obj = -8.862878980878e-01 err = 8.0783379889e-12 time = 0.03 sec +[ Info: VUMPS 62: obj = -8.862878980878e-01 err = 5.7086349534e-12 time = 0.03 sec +[ Info: VUMPS 63: obj = -8.862878980878e-01 err = 4.0356697275e-12 time = 0.03 sec +[ Info: VUMPS 64: obj = -8.862878980878e-01 err = 2.8491662815e-12 time = 0.03 sec +[ Info: VUMPS 65: obj = -8.862878980878e-01 err = 2.0151560945e-12 time = 0.03 sec +[ Info: VUMPS 66: obj = -8.862878980878e-01 err = 1.4247184277e-12 time = 0.03 sec +[ Info: VUMPS 67: obj = -8.862878980878e-01 err = 1.0046235154e-12 time = 0.02 sec +[ Info: VUMPS conv 68: obj = -8.862878980879e-01 err = 7.1313164474e-13 time = 2.95 sec ```` diff --git a/docs/src/examples/quantum1d/4.xxz-heisenberg/main.ipynb b/docs/src/examples/quantum1d/4.xxz-heisenberg/main.ipynb index ce74387d6..2f4d6379c 100644 --- a/docs/src/examples/quantum1d/4.xxz-heisenberg/main.ipynb +++ b/docs/src/examples/quantum1d/4.xxz-heisenberg/main.ipynb @@ -2,182 +2,291 @@ "cells": [ { "cell_type": "markdown", + "metadata": {}, "source": [ "# The XXZ model\n", "\n", "In this file we will give step by step instructions on how to analyze the spin 1/2 XXZ model.\n", "The necessary packages to follow this tutorial are:" - ], - "metadata": {} + ] }, { - "outputs": [], "cell_type": "code", - "source": [ - "using MPSKit, MPSKitModels, TensorKit, Plots" - ], + "execution_count": null, "metadata": {}, - "execution_count": null + "outputs": [], + "source": [ + "using MPSKit, TensorKit, Plots\n", + "# Model constructors for the MPSKit documentation and examples.\n", + "# Adapted from MPSKitModels.jl v0.4.7, src/models/{hamiltonians,transfermatrices}.jl:\n", + "# https://github.com/QuantumKitHub/MPSKitModels.jl/tree/v0.4.7/src/models\n", + "# Operators come from TensorKitTensors; chain assembly uses MPSKit directly.\n", + "#\n", + "# MIT License\n", + "# Copyright (c) 2021 Maarten Van Damme\n", + "#\n", + "# Permission is hereby granted, free of charge, to any person obtaining a copy\n", + "# of this software and associated documentation files (the \"Software\"), to deal\n", + "# in the Software without restriction, including without limitation the rights\n", + "# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n", + "# copies of the Software, and to permit persons to whom the Software is\n", + "# furnished to do so, subject to the following conditions:\n", + "#\n", + "# The above copyright notice and this permission notice shall be included in all\n", + "# copies or substantial portions of the Software.\n", + "#\n", + "# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n", + "# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n", + "# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n", + "# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n", + "# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n", + "# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n", + "# SOFTWARE.\n", + "\n", + "module ExampleModels\n", + "\n", + "using MPSKit, TensorKit\n", + "using TensorKitTensors: SpinOperators, BosonOperators, HubbardOperators\n", + "\n", + "export chain_hamiltonian, transverse_field_ising, heisenberg_XXX\n", + "export hubbard_model, bose_hubbard_model, hard_hexagon\n", + "\n", + "# L specifies an open finite chain; otherwise unitcell specifies an infinite chain.\n", + "function chain_hamiltonian(twosite, onesite = nothing; L = nothing, unitcell::Integer = 1)\n", + " nsites = isnothing(L) ? unitcell : L\n", + " nsites isa Integer && nsites > 0 || throw(ArgumentError(\"chain length must be a positive integer\"))\n", + " nbonds = isnothing(L) ? nsites : nsites - 1\n", + " terms = Pair[(i, i + 1) => twosite for i in 1:nbonds]\n", + " if !isnothing(onesite)\n", + " append!(terms, [i => onesite for i in 1:nsites])\n", + " end\n", + " spaces = fill(space(twosite, 1), nsites)\n", + " constructor = isnothing(L) ? InfiniteMPOHamiltonian : FiniteMPOHamiltonian\n", + " return constructor(spaces, terms)\n", + "end\n", + "\n", + "# H = -J sum(σz_i σz_{i+1} + g σx_i).\n", + "function transverse_field_ising(\n", + " T::Type{<:Number} = ComplexF64, symmetry::Type{<:Sector} = Trivial;\n", + " J = 1.0, g = 1.0, kwargs...\n", + " )\n", + " ZZ = 4 * SpinOperators.S_z_S_z(T, symmetry; spin = 1 // 2)\n", + " X = SpinOperators.σˣ(T, symmetry)\n", + " return chain_hamiltonian(-J * ZZ, -J * g * X; kwargs...)\n", + "end\n", + "transverse_field_ising(symmetry::Type{<:Sector}; kwargs...) =\n", + " transverse_field_ising(ComplexF64, symmetry; kwargs...)\n", + "\n", + "# H = J sum(S_i ⋅ S_{i+1}); preserve the examples' spin-1 default.\n", + "function heisenberg_XXX(\n", + " T::Type{<:Number} = ComplexF64, symmetry::Type{<:Sector} = Trivial;\n", + " J = 1.0, spin = 1, kwargs...\n", + " )\n", + " term = J * SpinOperators.S_exchange(T, symmetry; spin)\n", + " return chain_hamiltonian(term; kwargs...)\n", + "end\n", + "heisenberg_XXX(symmetry::Type{<:Sector}; kwargs...) =\n", + " heisenberg_XXX(ComplexF64, symmetry; kwargs...)\n", + "\n", + "# H = -t sum(e⁺_i e⁻_{i+1} + h.c.) + U sum(n↑ n↓) - mu sum(n).\n", + "function hubbard_model(\n", + " T::Type{<:Number} = ComplexF64, particle_symmetry::Type{<:Sector} = Trivial,\n", + " spin_symmetry::Type{<:Sector} = Trivial;\n", + " t = 1.0, U = 1.0, mu = 0.0, kwargs...\n", + " )\n", + " # e_hopping includes the fermionic reordering sign and is Hermitian.\n", + " hopping = HubbardOperators.e_hopping(T, particle_symmetry, spin_symmetry)\n", + " interaction = HubbardOperators.ud_num(T, particle_symmetry, spin_symmetry)\n", + " N = HubbardOperators.e_num(T, particle_symmetry, spin_symmetry)\n", + " return chain_hamiltonian(-t * hopping, U * interaction - mu * N; kwargs...)\n", + "end\n", + "\n", + "# H = -t sum(b⁺_i b⁻_{i+1} + h.c.) + U/2 sum(n(n-1)) - mu sum(n).\n", + "function bose_hubbard_model(\n", + " T::Type{<:Number} = ComplexF64, symmetry::Type{<:Sector} = Trivial;\n", + " cutoff::Integer = 5, t = 1.0, U = 1.0, mu = 0.0, kwargs...\n", + " )\n", + " hopping = BosonOperators.b_plus_b_min(T, symmetry; cutoff) +\n", + " BosonOperators.b_min_b_plus(T, symmetry; cutoff)\n", + " N = BosonOperators.b_num(T, symmetry; cutoff)\n", + " interaction = N * (N - id(domain(N)))\n", + " return chain_hamiltonian(-t * hopping, U / 2 * interaction - mu * N; kwargs...)\n", + "end\n", + "\n", + "function hard_hexagon(T::Type{<:Number} = ComplexF64)\n", + " P = Vect[FibonacciAnyon](:τ => 1)\n", + " O = ones(T, P ⊗ P ← P ⊗ P)\n", + " block(O, FibonacciAnyon(:I)) .*= 0\n", + " return InfiniteMPO([O])\n", + "end\n", + "\n", + "end\n", + "\n", + "using .ExampleModels" + ] }, { "cell_type": "markdown", + "metadata": {}, "source": [ "## Failure\n", "\n", "First we should define the Hamiltonian we want to work with.\n", "Then we specify an initial guess, which we then further optimize.\n", "Working directly in the thermodynamic limit, this is achieved as follows:" - ], - "metadata": {} + ] }, { - "outputs": [], "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "H = heisenberg_XXX(; spin = 1 // 2)" - ], - "metadata": {}, - "execution_count": null + ] }, { "cell_type": "markdown", + "metadata": {}, "source": [ "We then need an initial state, which we shall later optimize. In this example we work directly in the thermodynamic limit." - ], - "metadata": {} + ] }, { - "outputs": [], "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "state = InfiniteMPS(2, 20)" - ], - "metadata": {}, - "execution_count": null + ] }, { "cell_type": "markdown", + "metadata": {}, "source": [ "The ground state can then be found by calling `find_groundstate`." - ], - "metadata": {} + ] }, { - "outputs": [], "cell_type": "code", - "source": [ - "groundstate, cache, delta = find_groundstate(state, H, VUMPS());" - ], + "execution_count": null, "metadata": {}, - "execution_count": null + "outputs": [], + "source": [ + "groundstate, cache, info = find_groundstate(state, H, VUMPS());\n", + "info" + ] }, { "cell_type": "markdown", + "metadata": {}, "source": [ "As you can see, VUMPS struggles to converge.\n", "On its own, that is already quite curious.\n", "Maybe we can do better using another algorithm, such as gradient descent." - ], - "metadata": {} + ] }, { - "outputs": [], "cell_type": "code", - "source": [ - "groundstate, cache, delta = find_groundstate(state, H, GradientGrassmann(; maxiter = 20));" - ], + "execution_count": null, "metadata": {}, - "execution_count": null + "outputs": [], + "source": [ + "groundstate, cache, info = find_groundstate(state, H, GradientGrassmann(; maxiter = 20));\n", + "info" + ] }, { "cell_type": "markdown", + "metadata": {}, "source": [ "Convergence is quite slow and even fails after sufficiently many iterations.\n", "To understand why, we can look at the transfer matrix spectrum." - ], - "metadata": {} + ] }, { - "outputs": [], "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "transferplot(groundstate, groundstate)" - ], - "metadata": {}, - "execution_count": null + ] }, { "cell_type": "markdown", + "metadata": {}, "source": [ "We can clearly see multiple eigenvalues close to the unit circle.\n", "Our state is close to being non-injective, and represents the sum of multiple injective states.\n", "This is numerically very problematic, but also indicates that we used an incorrect ansatz to approximate the groundstate.\n", "We should retry with a larger unit cell." - ], - "metadata": {} + ] }, { "cell_type": "markdown", + "metadata": {}, "source": [ "## Success\n", "\n", "Let's initialize a different initial state, this time with a 2-site unit cell:" - ], - "metadata": {} + ] }, { - "outputs": [], "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "state = InfiniteMPS(fill(2, 2), fill(20, 2))" - ], - "metadata": {}, - "execution_count": null + ] }, { "cell_type": "markdown", + "metadata": {}, "source": [ "In MPSKit, we require that the periodicity of the Hamiltonian equals that of the state it is applied to.\n", "This is not a big obstacle, you can simply repeat the original Hamiltonian.\n", - "Alternatively, the Hamiltonian can be constructed directly on a two-site unit cell by making use of MPSKitModels.jl's `@mpoham`." - ], - "metadata": {} + "Alternatively, our model helper can construct the Hamiltonian directly on a two-site unit cell." + ] }, { - "outputs": [], "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "# H2 = repeat(H, 2); -- copies the one-site version\n", - "H2 = heisenberg_XXX(ComplexF64, Trivial, InfiniteChain(2); spin = 1 // 2)\n", - "groundstate, envs, delta = find_groundstate(\n", + "H2 = heisenberg_XXX(ComplexF64, Trivial; unitcell = 2, spin = 1 // 2)\n", + "groundstate, envs, info = find_groundstate(\n", " state, H2, VUMPS(; maxiter = 100, tol = 1.0e-12)\n", ");" - ], - "metadata": {}, - "execution_count": null + ] }, { "cell_type": "markdown", + "metadata": {}, "source": [ "We get convergence, but it takes an enormous amount of iterations.\n", "The reason behind this becomes more obvious at higher bond dimensions:" - ], - "metadata": {} + ] }, { - "outputs": [], "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ - "groundstate, envs, delta = find_groundstate(\n", + "groundstate, envs, info = find_groundstate(\n", " state, H2, IDMRG2(; trunc = truncrank(50), maxiter = 20, tol = 1.0e-12)\n", ");\n", "entanglementplot(groundstate)" - ], - "metadata": {}, - "execution_count": null + ] }, { "cell_type": "markdown", + "metadata": {}, "source": [ "We see that some eigenvalues clearly belong to a group, and are almost degenerate.\n", "This implies 2 things:\n", @@ -185,31 +294,31 @@ "- poor convergence if we cut off within such a subspace\n", "\n", "It are precisely those problems that we can solve by using symmetries." - ], - "metadata": {} + ] }, { "cell_type": "markdown", + "metadata": {}, "source": [ "## Symmetries\n", "\n", "The XXZ Heisenberg Hamiltonian is SU(2) symmetric and we can exploit this to greatly speed up the simulation.\n", "\n", "It is cumbersome to construct symmetric Hamiltonians, but luckily SU(2) symmetric XXZ is already implemented:" - ], - "metadata": {} + ] }, { - "outputs": [], "cell_type": "code", - "source": [ - "H2 = heisenberg_XXX(ComplexF64, SU2Irrep, InfiniteChain(2); spin = 1 // 2);" - ], + "execution_count": null, "metadata": {}, - "execution_count": null + "outputs": [], + "source": [ + "H2 = heisenberg_XXX(ComplexF64, SU2Irrep; unitcell = 2, spin = 1 // 2);" + ] }, { "cell_type": "markdown", + "metadata": {}, "source": [ "Our initial state should also be SU(2) symmetric.\n", "It now becomes apparent why we have to use a two-site periodic state.\n", @@ -218,62 +327,61 @@ "The staggering thus happens on the virtual level.\n", "\n", "An alternative constructor for the initial state is" - ], - "metadata": {} + ] }, { - "outputs": [], "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "P = Rep[SU₂](1 // 2 => 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, info = find_groundstate(state, H2, VUMPS(; maxiter = 400, tol = 1.0e-12));" + ] }, { "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.13.1", + "language": "julia", + "name": "julia-1.13" + }, "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.13.1" } }, - "nbformat": 4 + "nbformat": 4, + "nbformat_minor": 3 } \ No newline at end of file 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 5d8edbbce..3316bbcdf 100644 Binary files a/docs/src/examples/quantum1d/5.haldane-spt/figure-1.png and b/docs/src/examples/quantum1d/5.haldane-spt/figure-1.png differ 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 1df134303..6848d9b4b 100644 Binary files a/docs/src/examples/quantum1d/5.haldane-spt/figure-2.png and b/docs/src/examples/quantum1d/5.haldane-spt/figure-2.png differ diff --git a/docs/src/examples/quantum1d/5.haldane-spt/figure-3.png b/docs/src/examples/quantum1d/5.haldane-spt/figure-3.png index 8dfdfe224..f04065c2a 100644 Binary files a/docs/src/examples/quantum1d/5.haldane-spt/figure-3.png and b/docs/src/examples/quantum1d/5.haldane-spt/figure-3.png differ diff --git a/docs/src/examples/quantum1d/5.haldane-spt/index.md b/docs/src/examples/quantum1d/5.haldane-spt/index.md index 8fb8dee4d..1dfc56414 100644 --- a/docs/src/examples/quantum1d/5.haldane-spt/index.md +++ b/docs/src/examples/quantum1d/5.haldane-spt/index.md @@ -97,7 +97,7 @@ non-injective MPS. ℋ = SU2Space(1 => 1) V_wrong = SU2Space(0 => 8, 1 // 2 => 8, 1 => 3, 3 // 2 => 3) ψ = InfiniteMPS(ℋ, V_wrong) -ψ, environments, δ = find_groundstate(ψ, H, VUMPS(; maxiter = 10)) +ψ, environments, info = find_groundstate(ψ, H, VUMPS(; maxiter = 10)) sectors = SU2Irrep[0, 1 // 2, 1, 3 // 2] transferplot(ψ; sectors, title = "Transfer matrix spectrum", legend = :outertop) ```` @@ -128,7 +128,7 @@ E_plus = expectation_value(ψ_plus, H) ```` ```` --1.4014193313393009 - 3.851708855717825e-17im +-1.4014193313393015 - 5.56966055557632e-18im ```` ````julia @@ -139,7 +139,7 @@ E_minus = expectation_value(ψ_minus, H) ```` ```` --1.4014839739630844 - 5.800167584873572e-17im +-1.4014839739630829 - 1.0846362574075293e-16im ```` ````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.5486227235391343 +S_plus = 1.5450323530587475 ```` diff --git a/docs/src/examples/quantum1d/5.haldane-spt/main.ipynb b/docs/src/examples/quantum1d/5.haldane-spt/main.ipynb index f85c243c3..3f0c3574d 100644 --- a/docs/src/examples/quantum1d/5.haldane-spt/main.ipynb +++ b/docs/src/examples/quantum1d/5.haldane-spt/main.ipynb @@ -101,7 +101,7 @@ "ℋ = SU2Space(1 => 1)\n", "V_wrong = SU2Space(0 => 8, 1 // 2 => 8, 1 => 3, 3 // 2 => 3)\n", "ψ = InfiniteMPS(ℋ, V_wrong)\n", - "ψ, environments, δ = find_groundstate(ψ, H, VUMPS(; maxiter = 10))\n", + "ψ, environments, info = find_groundstate(ψ, H, VUMPS(; maxiter = 10))\n", "sectors = SU2Irrep[0, 1 // 2, 1, 3 // 2]\n", "transferplot(ψ; sectors, title = \"Transfer matrix spectrum\", legend = :outertop)" ] @@ -200,15 +200,15 @@ ], "metadata": { "kernelspec": { - "display_name": "Julia 1.12.6", + "display_name": "Julia 1.13.1", "language": "julia", - "name": "julia-1.12" + "name": "julia-1.13" }, "language_info": { "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", - "version": "1.12.6" + "version": "1.13.1" } }, "nbformat": 4, diff --git a/docs/src/examples/quantum1d/6.hubbard/figure-1.png b/docs/src/examples/quantum1d/6.hubbard/figure-1.png index 87a4f10f8..667b26219 100644 Binary files a/docs/src/examples/quantum1d/6.hubbard/figure-1.png and b/docs/src/examples/quantum1d/6.hubbard/figure-1.png differ diff --git a/docs/src/examples/quantum1d/6.hubbard/figure-2.png b/docs/src/examples/quantum1d/6.hubbard/figure-2.png index f28bef941..ec55e8749 100644 Binary files a/docs/src/examples/quantum1d/6.hubbard/figure-2.png and b/docs/src/examples/quantum1d/6.hubbard/figure-2.png differ diff --git a/docs/src/examples/quantum1d/6.hubbard/index.md b/docs/src/examples/quantum1d/6.hubbard/index.md index 60a81e622..3c1031042 100644 --- a/docs/src/examples/quantum1d/6.hubbard/index.md +++ b/docs/src/examples/quantum1d/6.hubbard/index.md @@ -38,7 +38,7 @@ H = - \sum_{\langle i, j \rangle, \sigma} c^{\dagger}_{i,\sigma} c_{j,\sigma} + ````julia using TensorKit using MPSKit -using MPSKitModels +using .ExampleModels using SpecialFunctions: besselj0, besselj1 using QuadGK: quadgk using Plots @@ -102,7 +102,7 @@ function compute_groundstate( return psi end -H = hubbard_model(InfiniteChain(2); U, t, mu = U / 2) +H = hubbard_model(; unitcell = 2, U, t, mu = U / 2) Vspaces = fill(Vect[fℤ₂](0 => 10, 1 => 10), 2) psi = InfiniteMPS(physicalspace(H), Vspaces) psi = compute_groundstate(psi, H) @@ -115,54 +115,54 @@ 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: VUMPS init: obj = -1.468489418346e+00 err = 5.1975e-01 +[ Info: VUMPS conv 9: obj = -4.377078635243e+00 err = 8.8168808972e-03 time = 9.43 sec +[ Info: VUMPS init: obj = -4.377078635243e+00 err = 1.6735e-02 +[ Info: VUMPS conv 6: obj = -4.378747252024e+00 err = 1.2361295846e-04 time = 0.12 sec +[ Info: VUMPS init: obj = -4.378747252024e+00 err = 8.0159e-03 +[ Info: VUMPS conv 6: obj = -4.379161083149e+00 err = 1.5147591757e-04 time = 0.35 sec +[ Info: VUMPS init: obj = -4.379161083149e+00 err = 6.1111e-03 +[ Info: VUMPS conv 5: obj = -4.379452158515e+00 err = 1.6672074243e-04 time = 0.27 sec +[ Info: VUMPS init: obj = -4.379452158515e+00 err = 5.6947e-03 +[ Info: VUMPS conv 4: obj = -4.379651693858e+00 err = 1.7048574253e-04 time = 0.25 sec +[ Info: VUMPS init: obj = -4.379651693858e+00 err = 4.1022e-03 +[ Info: VUMPS conv 3: obj = -4.379734900757e+00 err = 1.9568406227e-04 time = 0.22 sec +[ Info: VUMPS init: obj = -4.379734900757e+00 err = 3.5559e-03 +[ Info: VUMPS conv 3: obj = -4.379797739218e+00 err = 1.3879489646e-04 time = 0.28 sec +[ Info: VUMPS init: obj = -4.379797739218e+00 err = 2.7576e-03 +[ Info: VUMPS conv 2: obj = -4.379838449668e+00 err = 1.7162678551e-04 time = 0.23 sec +[ Info: VUMPS init: obj = -4.379838449668e+00 err = 2.7243e-03 +[ Info: VUMPS conv 3: obj = -4.379878835235e+00 err = 1.9410242419e-04 time = 0.37 sec +[ Info: VUMPS init: obj = -4.379878835235e+00 err = 2.6897e-03 +[ Info: VUMPS conv 3: obj = -4.379929227787e+00 err = 1.6816048594e-04 time = 0.48 sec +[ Info: VUMPS init: obj = -4.379929227787e+00 err = 2.5535e-03 +[ Info: VUMPS conv 3: obj = -4.379968042520e+00 err = 1.7686227682e-04 time = 0.58 sec +[ Info: VUMPS init: obj = -4.379968042520e+00 err = 1.7669e-03 +[ Info: VUMPS conv 2: obj = -4.379986883462e+00 err = 1.8114981456e-04 time = 0.53 sec +[ Info: VUMPS init: obj = -4.379986883462e+00 err = 1.5826e-03 +[ Info: VUMPS conv 2: obj = -4.380000785141e+00 err = 1.8783202881e-04 time = 2.59 sec +[ Info: VUMPS init: obj = -4.380000785141e+00 err = 1.5050e-03 +[ Info: VUMPS conv 2: obj = -4.380013154815e+00 err = 1.5341277502e-04 time = 0.66 sec +[ Info: VUMPS init: obj = -4.380013154815e+00 err = 1.4211e-03 +[ Info: VUMPS conv 2: obj = -4.380024394664e+00 err = 1.7785454577e-04 time = 0.86 sec +[ Info: VUMPS init: obj = -4.380024394664e+00 err = 1.3317e-03 +[ Info: VUMPS conv 2: obj = -4.380038147448e+00 err = 1.5752544479e-04 time = 1.16 sec +[ Info: VUMPS init: obj = -4.380038147448e+00 err = 1.0028e-03 +[ Info: VUMPS conv 1: obj = -4.380043676003e+00 err = 1.6642351068e-04 time = 0.69 sec +[ Info: VUMPS init: obj = -4.380043676003e+00 err = 9.0907e-04 +[ Info: VUMPS conv 1: obj = -4.380048631245e+00 err = 1.8550023124e-04 time = 0.99 sec +[ Info: VUMPS init: obj = -4.380048631245e+00 err = 8.3047e-04 +[ Info: VUMPS conv 1: obj = -4.380053194046e+00 err = 1.7976862986e-04 time = 1.02 sec +[ Info: VUMPS init: obj = -4.380053194046e+00 err = 6.8098e-04 +[ Info: VUMPS conv 1: obj = -4.380057135166e+00 err = 1.8942646284e-04 time = 3.55 sec +[ Info: VUMPS init: obj = -4.380057135166e+00 err = 6.0296e-04 +[ Info: VUMPS conv 1: obj = -4.380060542793e+00 err = 1.8183804864e-04 time = 1.50 sec +[ Info: VUMPS init: obj = -4.379609680843e+00 err = 4.0950e-03 +[ Info: VUMPS conv 19: obj = -4.379763262608e+00 err = 9.9349957478e-06 time = 5.15 sec +[ Info: CG: initializing with f = -4.379763262252e+00, ‖∇f‖ = 3.1505e-05 +[ Info: CG: converged after 74 iterations and time 31.48 s: f = -4.379763378976e+00, ‖∇f‖ = 9.7995e-07 ┌ Info: Groundstate energy: -│ * numerical: -2.1899960609769664 +│ * numerical: -2.1899959892263503 └ * analytic: -2.190038374277775 ```` @@ -179,7 +179,7 @@ In order to work at half-filling, we need to effectively inject one particle per In MPSKit, this is achieved by the `add_physical_charge` function, which shifts the physical spaces of the tensors to the desired charge sector. ````julia -H_u1_su2 = hubbard_model(ComplexF64, U1Irrep, SU2Irrep, InfiniteChain(2); U, t, mu = U / 2); +H_u1_su2 = hubbard_model(ComplexF64, U1Irrep, SU2Irrep; unitcell = 2, U, t, mu = U / 2); charges = fill(FermionParity(1) ⊠ U1Irrep(1) ⊠ SU2Irrep(0), 2); H_u1_su2 = MPSKit.add_physical_charge(H_u1_su2, charges); @@ -196,56 +196,56 @@ 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 = +2.614696817226e-01 err = 8.5807e-01 +[ Info: VUMPS conv 1: obj = -4.000000000000e+00 err = 1.3727089486e-15 time = 8.05 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 conv 4: obj = -4.289650419749e+00 err = 1.8514003381e-04 time = 0.03 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: VUMPS conv 6: obj = -4.359777339602e+00 err = 1.0863018801e-04 time = 0.08 sec +[ Info: VUMPS init: obj = -4.359777339602e+00 err = 4.4013e-02 +[ Info: VUMPS conv 6: obj = -4.372880960804e+00 err = 1.2173013239e-04 time = 2.01 sec +[ Info: VUMPS init: obj = -4.372880960804e+00 err = 3.2691e-02 +[ Info: VUMPS conv 4: obj = -4.375236954195e+00 err = 1.1823474657e-04 time = 0.12 sec +[ Info: VUMPS init: obj = -4.375236954195e+00 err = 2.9487e-02 +[ Info: VUMPS conv 7: obj = -4.378159084338e+00 err = 1.1896655123e-04 time = 0.24 sec +[ Info: VUMPS init: obj = -4.378159084337e+00 err = 1.9312e-02 +[ Info: VUMPS conv 5: obj = -4.379272965967e+00 err = 1.5785504511e-04 time = 0.22 sec +[ Info: VUMPS init: obj = -4.379272965967e+00 err = 9.9128e-03 +[ Info: VUMPS conv 4: obj = -4.379592229097e+00 err = 1.5550466620e-04 time = 0.22 sec +[ Info: VUMPS init: obj = -4.379592229097e+00 err = 6.4841e-03 +[ Info: VUMPS conv 4: obj = -4.379819377211e+00 err = 1.7492244997e-04 time = 0.27 sec +[ Info: VUMPS init: obj = -4.379819377210e+00 err = 3.8754e-03 +┌ Warning: VUMPS cancel 10: obj = -4.379964033314e+00 err = 2.1228913871e-04 time = 1.09 sec +└ @ MPSKit ~/Projects/MPSKit.jl/ld-release/src/algorithms/groundstate/vumps.jl:96 +[ Info: VUMPS init: obj = -4.379964033314e+00 err = 2.8978e-03 +[ Info: VUMPS conv 3: obj = -4.380010384690e+00 err = 1.4775313775e-04 time = 0.45 sec +[ Info: VUMPS init: obj = -4.380010384690e+00 err = 2.0609e-03 +[ Info: VUMPS conv 3: obj = -4.380041751472e+00 err = 1.6327804840e-04 time = 0.79 sec +[ Info: VUMPS init: obj = -4.380041751471e+00 err = 1.2364e-03 +[ Info: VUMPS conv 2: obj = -4.380055778730e+00 err = 1.8367318970e-04 time = 0.63 sec +[ Info: VUMPS init: obj = -4.380055778730e+00 err = 8.5857e-04 +[ Info: VUMPS conv 2: obj = -4.380064749403e+00 err = 1.3905483353e-04 time = 0.86 sec +[ Info: VUMPS init: obj = -4.380064749403e+00 err = 5.2502e-04 +[ Info: VUMPS conv 1: obj = -4.380067974756e+00 err = 1.5646749713e-04 time = 0.61 sec +[ Info: VUMPS init: obj = -4.380067974756e+00 err = 3.3275e-04 +[ Info: VUMPS conv 1: obj = -4.380070351398e+00 err = 1.3124347695e-04 time = 0.90 sec +[ Info: VUMPS init: obj = -4.380070351398e+00 err = 2.0349e-04 +[ Info: VUMPS conv 1: obj = -4.380072125236e+00 err = 1.1121064710e-04 time = 1.33 sec +[ Info: VUMPS init: obj = -4.380072125236e+00 err = 1.3635e-04 +[ Info: VUMPS conv 1: obj = -4.380073467820e+00 err = 8.5044825938e-05 time = 1.86 sec +[ Info: VUMPS init: obj = -4.380073467820e+00 err = 9.7229e-05 +[ Info: VUMPS conv 1: obj = -4.380074455754e+00 err = 6.4434476042e-05 time = 3.04 sec +[ Info: VUMPS init: obj = -4.380074455754e+00 err = 7.3791e-05 +[ Info: VUMPS conv 1: obj = -4.380075159877e+00 err = 6.2156890313e-05 time = 7.86 sec +[ Info: VUMPS init: obj = -4.380075159877e+00 err = 5.9911e-05 +[ Info: VUMPS conv 1: obj = -4.380075661717e+00 err = 4.2516777791e-05 time = 9.17 sec +[ Info: VUMPS init: obj = -4.379308796614e+00 err = 7.9930e-03 +┌ Warning: VUMPS cancel 100: obj = -4.379692711577e+00 err = 1.5979759574e-05 time = 18.31 sec +└ @ MPSKit ~/Projects/MPSKit.jl/ld-release/src/algorithms/groundstate/vumps.jl:96 +[ Info: CG: initializing with f = -4.379692711577e+00, ‖∇f‖ = 5.7923e-05 +[ Info: CG: converged after 13 iterations and time 6.61 s: f = -4.379692712497e+00, ‖∇f‖ = 6.2098e-07 ┌ Info: Groundstate energy: -│ * numerical: -2.1900153475144695 +│ * numerical: -2.190015347514464 └ * analytic: -2.190038374277775 ```` @@ -288,37 +288,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 +346,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 9b64a7960..b1630b942 100644 --- a/docs/src/examples/quantum1d/6.hubbard/main.ipynb +++ b/docs/src/examples/quantum1d/6.hubbard/main.ipynb @@ -47,7 +47,112 @@ "source": [ "using TensorKit\n", "using MPSKit\n", - "using MPSKitModels\n", + "# Model constructors for the MPSKit documentation and examples.\n", + "# Adapted from MPSKitModels.jl v0.4.7, src/models/{hamiltonians,transfermatrices}.jl:\n", + "# https://github.com/QuantumKitHub/MPSKitModels.jl/tree/v0.4.7/src/models\n", + "# Operators come from TensorKitTensors; chain assembly uses MPSKit directly.\n", + "#\n", + "# MIT License\n", + "# Copyright (c) 2021 Maarten Van Damme\n", + "#\n", + "# Permission is hereby granted, free of charge, to any person obtaining a copy\n", + "# of this software and associated documentation files (the \"Software\"), to deal\n", + "# in the Software without restriction, including without limitation the rights\n", + "# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n", + "# copies of the Software, and to permit persons to whom the Software is\n", + "# furnished to do so, subject to the following conditions:\n", + "#\n", + "# The above copyright notice and this permission notice shall be included in all\n", + "# copies or substantial portions of the Software.\n", + "#\n", + "# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n", + "# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n", + "# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n", + "# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n", + "# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n", + "# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n", + "# SOFTWARE.\n", + "\n", + "module ExampleModels\n", + "\n", + "using MPSKit, TensorKit\n", + "using TensorKitTensors: SpinOperators, BosonOperators, HubbardOperators\n", + "\n", + "export chain_hamiltonian, transverse_field_ising, heisenberg_XXX\n", + "export hubbard_model, bose_hubbard_model, hard_hexagon\n", + "\n", + "# L specifies an open finite chain; otherwise unitcell specifies an infinite chain.\n", + "function chain_hamiltonian(twosite, onesite = nothing; L = nothing, unitcell::Integer = 1)\n", + " nsites = isnothing(L) ? unitcell : L\n", + " nsites isa Integer && nsites > 0 || throw(ArgumentError(\"chain length must be a positive integer\"))\n", + " nbonds = isnothing(L) ? nsites : nsites - 1\n", + " terms = Pair[(i, i + 1) => twosite for i in 1:nbonds]\n", + " if !isnothing(onesite)\n", + " append!(terms, [i => onesite for i in 1:nsites])\n", + " end\n", + " spaces = fill(space(twosite, 1), nsites)\n", + " constructor = isnothing(L) ? InfiniteMPOHamiltonian : FiniteMPOHamiltonian\n", + " return constructor(spaces, terms)\n", + "end\n", + "\n", + "# H = -J sum(σz_i σz_{i+1} + g σx_i).\n", + "function transverse_field_ising(\n", + " T::Type{<:Number} = ComplexF64, symmetry::Type{<:Sector} = Trivial;\n", + " J = 1.0, g = 1.0, kwargs...\n", + " )\n", + " ZZ = 4 * SpinOperators.S_z_S_z(T, symmetry; spin = 1 // 2)\n", + " X = SpinOperators.σˣ(T, symmetry)\n", + " return chain_hamiltonian(-J * ZZ, -J * g * X; kwargs...)\n", + "end\n", + "transverse_field_ising(symmetry::Type{<:Sector}; kwargs...) =\n", + " transverse_field_ising(ComplexF64, symmetry; kwargs...)\n", + "\n", + "# H = J sum(S_i ⋅ S_{i+1}); preserve the examples' spin-1 default.\n", + "function heisenberg_XXX(\n", + " T::Type{<:Number} = ComplexF64, symmetry::Type{<:Sector} = Trivial;\n", + " J = 1.0, spin = 1, kwargs...\n", + " )\n", + " term = J * SpinOperators.S_exchange(T, symmetry; spin)\n", + " return chain_hamiltonian(term; kwargs...)\n", + "end\n", + "heisenberg_XXX(symmetry::Type{<:Sector}; kwargs...) =\n", + " heisenberg_XXX(ComplexF64, symmetry; kwargs...)\n", + "\n", + "# H = -t sum(e⁺_i e⁻_{i+1} + h.c.) + U sum(n↑ n↓) - mu sum(n).\n", + "function hubbard_model(\n", + " T::Type{<:Number} = ComplexF64, particle_symmetry::Type{<:Sector} = Trivial,\n", + " spin_symmetry::Type{<:Sector} = Trivial;\n", + " t = 1.0, U = 1.0, mu = 0.0, kwargs...\n", + " )\n", + " # e_hopping includes the fermionic reordering sign and is Hermitian.\n", + " hopping = HubbardOperators.e_hopping(T, particle_symmetry, spin_symmetry)\n", + " interaction = HubbardOperators.ud_num(T, particle_symmetry, spin_symmetry)\n", + " N = HubbardOperators.e_num(T, particle_symmetry, spin_symmetry)\n", + " return chain_hamiltonian(-t * hopping, U * interaction - mu * N; kwargs...)\n", + "end\n", + "\n", + "# H = -t sum(b⁺_i b⁻_{i+1} + h.c.) + U/2 sum(n(n-1)) - mu sum(n).\n", + "function bose_hubbard_model(\n", + " T::Type{<:Number} = ComplexF64, symmetry::Type{<:Sector} = Trivial;\n", + " cutoff::Integer = 5, t = 1.0, U = 1.0, mu = 0.0, kwargs...\n", + " )\n", + " hopping = BosonOperators.b_plus_b_min(T, symmetry; cutoff) +\n", + " BosonOperators.b_min_b_plus(T, symmetry; cutoff)\n", + " N = BosonOperators.b_num(T, symmetry; cutoff)\n", + " interaction = N * (N - id(domain(N)))\n", + " return chain_hamiltonian(-t * hopping, U / 2 * interaction - mu * N; kwargs...)\n", + "end\n", + "\n", + "function hard_hexagon(T::Type{<:Number} = ComplexF64)\n", + " P = Vect[FibonacciAnyon](:τ => 1)\n", + " O = ones(T, P ⊗ P ← P ⊗ P)\n", + " block(O, FibonacciAnyon(:I)) .*= 0\n", + " return InfiniteMPO([O])\n", + "end\n", + "\n", + "end\n", + "\n", + "using .ExampleModels\n", "using SpecialFunctions: besselj0, besselj1\n", "using QuadGK: quadgk\n", "using Plots\n", @@ -117,7 +222,7 @@ " return psi\n", "end\n", "\n", - "H = hubbard_model(InfiniteChain(2); U, t, mu = U / 2)\n", + "H = hubbard_model(; unitcell = 2, U, t, mu = U / 2)\n", "Vspaces = fill(Vect[fℤ₂](0 => 10, 1 => 10), 2)\n", "psi = InfiniteMPS(physicalspace(H), Vspaces)\n", "psi = compute_groundstate(psi, H)\n", @@ -151,7 +256,7 @@ "metadata": {}, "outputs": [], "source": [ - "H_u1_su2 = hubbard_model(ComplexF64, U1Irrep, SU2Irrep, InfiniteChain(2); U, t, mu = U / 2);\n", + "H_u1_su2 = hubbard_model(ComplexF64, U1Irrep, SU2Irrep; unitcell = 2, U, t, mu = U / 2);\n", "charges = fill(FermionParity(1) ⊠ U1Irrep(1) ⊠ SU2Irrep(0), 2);\n", "H_u1_su2 = MPSKit.add_physical_charge(H_u1_su2, charges);\n", "\n", @@ -381,15 +486,15 @@ ], "metadata": { "kernelspec": { - "display_name": "Julia 1.12.6", + "display_name": "Julia 1.13.1", "language": "julia", - "name": "julia-1.12" + "name": "julia-1.13" }, "language_info": { "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", - "version": "1.12.6" + "version": "1.13.1" } }, "nbformat": 4, 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 da451a216..be692709a 100644 Binary files a/docs/src/examples/quantum1d/7.xy-finiteT/figure-1.png and b/docs/src/examples/quantum1d/7.xy-finiteT/figure-1.png differ diff --git a/docs/src/examples/quantum1d/7.xy-finiteT/figure-2.png b/docs/src/examples/quantum1d/7.xy-finiteT/figure-2.png index 94ec71854..508b94015 100644 Binary files a/docs/src/examples/quantum1d/7.xy-finiteT/figure-2.png and b/docs/src/examples/quantum1d/7.xy-finiteT/figure-2.png differ diff --git a/docs/src/examples/quantum1d/7.xy-finiteT/figure-3.png b/docs/src/examples/quantum1d/7.xy-finiteT/figure-3.png index 9daa46501..9df578602 100644 Binary files a/docs/src/examples/quantum1d/7.xy-finiteT/figure-3.png and b/docs/src/examples/quantum1d/7.xy-finiteT/figure-3.png differ diff --git a/docs/src/examples/quantum1d/7.xy-finiteT/figure-4.png b/docs/src/examples/quantum1d/7.xy-finiteT/figure-4.png index e15988a40..701d842e0 100644 Binary files a/docs/src/examples/quantum1d/7.xy-finiteT/figure-4.png and b/docs/src/examples/quantum1d/7.xy-finiteT/figure-4.png differ 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 733496a0c..cfd09fdbc 100644 Binary files a/docs/src/examples/quantum1d/7.xy-finiteT/figure-5.png and b/docs/src/examples/quantum1d/7.xy-finiteT/figure-5.png differ diff --git a/docs/src/examples/quantum1d/7.xy-finiteT/figure-6.png b/docs/src/examples/quantum1d/7.xy-finiteT/figure-6.png index c2680aed3..16501b948 100644 Binary files a/docs/src/examples/quantum1d/7.xy-finiteT/figure-6.png and b/docs/src/examples/quantum1d/7.xy-finiteT/figure-6.png differ diff --git a/docs/src/examples/quantum1d/7.xy-finiteT/index.md b/docs/src/examples/quantum1d/7.xy-finiteT/index.md index a897a94b2..f55c6a9c3 100644 --- a/docs/src/examples/quantum1d/7.xy-finiteT/index.md +++ b/docs/src/examples/quantum1d/7.xy-finiteT/index.md @@ -8,10 +8,11 @@ EditURL = "../../../../../examples/quantum1d/7.xy-finiteT/main.jl" ````julia using Markdown +using TensorKitTensors.SpinOperators: S_plus_S_min, S_min_S_plus using TensorKit using MPSKit +using .ExampleModels using MPSKit: infinite_temperature_density_matrix -using MPSKitModels using QuadGK: quadgk using SpecialFunctions: ellipe using Plots @@ -43,13 +44,8 @@ function XY_hamiltonian( ::Type{T} = ComplexF64, ::Type{S} = Trivial; J = 1 / 2, N ) where {T <: Number, S <: Sector} spin = 1 // 2 - term = J * (S_xx(T, S; spin) + S_yy(T, S; spin)) - lattice = isfinite(N) ? FiniteChain(N) : InfiniteChain(1) - return @mpoham begin - sum(nearest_neighbours(lattice)) do (i, j) - return term{i, j} - end - end + term = J / 2 * (S_plus_S_min(T, S; spin) + S_min_S_plus(T, S; spin)) + return chain_hamiltonian(term; L = isfinite(N) ? Int(N) : nothing) end ```` @@ -125,11 +121,12 @@ 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 init: obj = +4.372173567940e+00 err = 1.0000e+00 +[ Info: DMRG2 1: obj = -5.003682441423e+00 err = 3.0044527697e-02 time = 1.23 min +[ Info: DMRG2 2: obj = -5.004096972575e+00 err = 4.0291060276e-04 time = 0.44 sec +[ Info: DMRG2 3: obj = -5.004096975044e+00 err = 4.3913120671e-06 time = 0.18 sec +[ Info: DMRG2 conv 4: obj = -5.004096975044e+00 err = 7.5912983728e-07 time = 1.24 min +Numerical: -0.1563780304701152 Exact (N=32): -0.15637803047254015 Exact (N=Inf): -0.15915494309189535 diff --git a/docs/src/examples/quantum1d/7.xy-finiteT/main.ipynb b/docs/src/examples/quantum1d/7.xy-finiteT/main.ipynb index 26798bd0e..f46ed94fe 100644 --- a/docs/src/examples/quantum1d/7.xy-finiteT/main.ipynb +++ b/docs/src/examples/quantum1d/7.xy-finiteT/main.ipynb @@ -1,25 +1,132 @@ { "cells": [ { - "outputs": [], "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "using Markdown\n", + "using TensorKitTensors.SpinOperators: S_plus_S_min, S_min_S_plus\n", "using TensorKit\n", "using MPSKit\n", + "# Model constructors for the MPSKit documentation and examples.\n", + "# Adapted from MPSKitModels.jl v0.4.7, src/models/{hamiltonians,transfermatrices}.jl:\n", + "# https://github.com/QuantumKitHub/MPSKitModels.jl/tree/v0.4.7/src/models\n", + "# Operators come from TensorKitTensors; chain assembly uses MPSKit directly.\n", + "#\n", + "# MIT License\n", + "# Copyright (c) 2021 Maarten Van Damme\n", + "#\n", + "# Permission is hereby granted, free of charge, to any person obtaining a copy\n", + "# of this software and associated documentation files (the \"Software\"), to deal\n", + "# in the Software without restriction, including without limitation the rights\n", + "# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n", + "# copies of the Software, and to permit persons to whom the Software is\n", + "# furnished to do so, subject to the following conditions:\n", + "#\n", + "# The above copyright notice and this permission notice shall be included in all\n", + "# copies or substantial portions of the Software.\n", + "#\n", + "# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n", + "# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n", + "# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n", + "# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n", + "# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n", + "# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n", + "# SOFTWARE.\n", + "\n", + "module ExampleModels\n", + "\n", + "using MPSKit, TensorKit\n", + "using TensorKitTensors: SpinOperators, BosonOperators, HubbardOperators\n", + "\n", + "export chain_hamiltonian, transverse_field_ising, heisenberg_XXX\n", + "export hubbard_model, bose_hubbard_model, hard_hexagon\n", + "\n", + "# L specifies an open finite chain; otherwise unitcell specifies an infinite chain.\n", + "function chain_hamiltonian(twosite, onesite = nothing; L = nothing, unitcell::Integer = 1)\n", + " nsites = isnothing(L) ? unitcell : L\n", + " nsites isa Integer && nsites > 0 || throw(ArgumentError(\"chain length must be a positive integer\"))\n", + " nbonds = isnothing(L) ? nsites : nsites - 1\n", + " terms = Pair[(i, i + 1) => twosite for i in 1:nbonds]\n", + " if !isnothing(onesite)\n", + " append!(terms, [i => onesite for i in 1:nsites])\n", + " end\n", + " spaces = fill(space(twosite, 1), nsites)\n", + " constructor = isnothing(L) ? InfiniteMPOHamiltonian : FiniteMPOHamiltonian\n", + " return constructor(spaces, terms)\n", + "end\n", + "\n", + "# H = -J sum(σz_i σz_{i+1} + g σx_i).\n", + "function transverse_field_ising(\n", + " T::Type{<:Number} = ComplexF64, symmetry::Type{<:Sector} = Trivial;\n", + " J = 1.0, g = 1.0, kwargs...\n", + " )\n", + " ZZ = 4 * SpinOperators.S_z_S_z(T, symmetry; spin = 1 // 2)\n", + " X = SpinOperators.σˣ(T, symmetry)\n", + " return chain_hamiltonian(-J * ZZ, -J * g * X; kwargs...)\n", + "end\n", + "transverse_field_ising(symmetry::Type{<:Sector}; kwargs...) =\n", + " transverse_field_ising(ComplexF64, symmetry; kwargs...)\n", + "\n", + "# H = J sum(S_i ⋅ S_{i+1}); preserve the examples' spin-1 default.\n", + "function heisenberg_XXX(\n", + " T::Type{<:Number} = ComplexF64, symmetry::Type{<:Sector} = Trivial;\n", + " J = 1.0, spin = 1, kwargs...\n", + " )\n", + " term = J * SpinOperators.S_exchange(T, symmetry; spin)\n", + " return chain_hamiltonian(term; kwargs...)\n", + "end\n", + "heisenberg_XXX(symmetry::Type{<:Sector}; kwargs...) =\n", + " heisenberg_XXX(ComplexF64, symmetry; kwargs...)\n", + "\n", + "# H = -t sum(e⁺_i e⁻_{i+1} + h.c.) + U sum(n↑ n↓) - mu sum(n).\n", + "function hubbard_model(\n", + " T::Type{<:Number} = ComplexF64, particle_symmetry::Type{<:Sector} = Trivial,\n", + " spin_symmetry::Type{<:Sector} = Trivial;\n", + " t = 1.0, U = 1.0, mu = 0.0, kwargs...\n", + " )\n", + " # e_hopping includes the fermionic reordering sign and is Hermitian.\n", + " hopping = HubbardOperators.e_hopping(T, particle_symmetry, spin_symmetry)\n", + " interaction = HubbardOperators.ud_num(T, particle_symmetry, spin_symmetry)\n", + " N = HubbardOperators.e_num(T, particle_symmetry, spin_symmetry)\n", + " return chain_hamiltonian(-t * hopping, U * interaction - mu * N; kwargs...)\n", + "end\n", + "\n", + "# H = -t sum(b⁺_i b⁻_{i+1} + h.c.) + U/2 sum(n(n-1)) - mu sum(n).\n", + "function bose_hubbard_model(\n", + " T::Type{<:Number} = ComplexF64, symmetry::Type{<:Sector} = Trivial;\n", + " cutoff::Integer = 5, t = 1.0, U = 1.0, mu = 0.0, kwargs...\n", + " )\n", + " hopping = BosonOperators.b_plus_b_min(T, symmetry; cutoff) +\n", + " BosonOperators.b_min_b_plus(T, symmetry; cutoff)\n", + " N = BosonOperators.b_num(T, symmetry; cutoff)\n", + " interaction = N * (N - id(domain(N)))\n", + " return chain_hamiltonian(-t * hopping, U / 2 * interaction - mu * N; kwargs...)\n", + "end\n", + "\n", + "function hard_hexagon(T::Type{<:Number} = ComplexF64)\n", + " P = Vect[FibonacciAnyon](:τ => 1)\n", + " O = ones(T, P ⊗ P ← P ⊗ P)\n", + " block(O, FibonacciAnyon(:I)) .*= 0\n", + " return InfiniteMPO([O])\n", + "end\n", + "\n", + "end\n", + "\n", + "using .ExampleModels\n", "using MPSKit: infinite_temperature_density_matrix\n", - "using MPSKitModels\n", "using QuadGK: quadgk\n", "using SpecialFunctions: ellipe\n", "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 +140,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", @@ -55,20 +163,14 @@ " ::Type{T} = ComplexF64, ::Type{S} = Trivial; J = 1 / 2, N\n", " ) where {T <: Number, S <: Sector}\n", " spin = 1 // 2\n", - " term = J * (S_xx(T, S; spin) + S_yy(T, S; spin))\n", - " lattice = isfinite(N) ? FiniteChain(N) : InfiniteChain(1)\n", - " return @mpoham begin\n", - " sum(nearest_neighbours(lattice)) do (i, j)\n", - " return term{i, j}\n", - " end\n", - " end\n", + " term = J / 2 * (S_plus_S_min(T, S; spin) + S_min_S_plus(T, S; spin))\n", + " return chain_hamiltonian(term; L = isfinite(N) ? Int(N) : nothing)\n", "end" - ], - "metadata": {}, - "execution_count": null + ] }, { "cell_type": "markdown", + "metadata": {}, "source": [ "## Diagonalization of the Hamiltonian\n", "\n", @@ -82,12 +184,13 @@ "> **Todo**\n", ">\n", "> Show the derivation of the ground state energy by diagonalizing the Hamiltonian in terms of fermionic operators." - ], - "metadata": {} + ] }, { - "outputs": [], "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "function groundstate_energy(J, N)\n", " isfinite(N) || return -J / π\n", @@ -95,22 +198,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 +224,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 +253,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", @@ -198,12 +300,13 @@ "> **Todo**\n", ">\n", "> Show the derivation of the partition function for the XY model." - ], - "metadata": {} + ] }, { - "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 +323,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 +337,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 +377,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 +414,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 +443,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", @@ -365,12 +467,13 @@ "> **Todo**\n", ">\n", "> Add a figure to illustrate this trick." - ], - "metadata": {} + ] }, { - "outputs": [], "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "double_logpartition(ρ₁, ρ₂ = ρ₁) = log(real(dot(ρ₁, ρ₂))) / length(ρ₁)\n", "\n", @@ -403,12 +506,11 @@ " )\n", " plot(p1, p2)\n", "end" - ], - "metadata": {}, - "execution_count": null + ] }, { "cell_type": "markdown", + "metadata": {}, "source": [ "### MPO multiplication approach (linear)\n", "\n", @@ -436,12 +538,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 +592,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 +611,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 +631,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 +685,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 +698,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 +717,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 +769,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.13.1", + "language": "julia", + "name": "julia-1.13" + }, "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.13.1" } }, - "nbformat": 4 + "nbformat": 4, + "nbformat_minor": 3 } \ No newline at end of file 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 2ab23add4..f3e51f8c6 100644 Binary files a/docs/src/examples/quantum1d/8.bose-hubbard/figure-1.png and b/docs/src/examples/quantum1d/8.bose-hubbard/figure-1.png differ diff --git a/docs/src/examples/quantum1d/8.bose-hubbard/figure-3.png b/docs/src/examples/quantum1d/8.bose-hubbard/figure-3.png index 523496c7a..47fe594f5 100644 Binary files a/docs/src/examples/quantum1d/8.bose-hubbard/figure-3.png and b/docs/src/examples/quantum1d/8.bose-hubbard/figure-3.png differ diff --git a/docs/src/examples/quantum1d/8.bose-hubbard/figure-4.png b/docs/src/examples/quantum1d/8.bose-hubbard/figure-4.png index addf62c5a..5587376b0 100644 Binary files a/docs/src/examples/quantum1d/8.bose-hubbard/figure-4.png and b/docs/src/examples/quantum1d/8.bose-hubbard/figure-4.png differ 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 a33028f2e..822de68c4 100644 Binary files a/docs/src/examples/quantum1d/8.bose-hubbard/figure-5.png and b/docs/src/examples/quantum1d/8.bose-hubbard/figure-5.png differ 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 805386dc7..6582cc87c 100644 Binary files a/docs/src/examples/quantum1d/8.bose-hubbard/figure-6.png and b/docs/src/examples/quantum1d/8.bose-hubbard/figure-6.png differ diff --git a/docs/src/examples/quantum1d/8.bose-hubbard/index.md b/docs/src/examples/quantum1d/8.bose-hubbard/index.md index 0472fcdcb..80d5af64f 100644 --- a/docs/src/examples/quantum1d/8.bose-hubbard/index.md +++ b/docs/src/examples/quantum1d/8.bose-hubbard/index.md @@ -8,7 +8,9 @@ EditURL = "../../../../../examples/quantum1d/8.bose-hubbard/main.jl" ````julia using Markdown -using MPSKit, MPSKitModels, TensorKit +using TensorKitTensors.BosonOperators: b_min, b_plus_b_min, b_min_b_plus, b_num +using MPSKit, TensorKit +using .ExampleModels using Plots, LaTeXStrings @@ -113,23 +115,23 @@ initial_state = InfiniteMPS(ℂ^(cutoff + 1), ℂ^D) This simply initializes a tensor filled with random entries (check out the documentation for other useful constructors). Next, we need the creation and annihilation operators. While we could construct them from scratch, here we will use -[`MPSKitModels.jl`](https://github.com/QuantumKitHub/MPSKitModels.jl) instead that has -predefined operators and models for most well-known lattice models. In particular, we can -use [`MPSKitModels.a_min`](@extref) to create the bosonic annihilation operator. +[TensorKitTensors.jl](https://github.com/QuantumKitHub/TensorKitTensors.jl), which provides +predefined operators. In particular, `BosonOperators.b_min` creates the bosonic annihilation +operator. ````julia -a_op = a_min(cutoff = cutoff) # creates a bosonic annihilation operator without any symmetries +a_op = b_min(cutoff = cutoff) # creates a bosonic annihilation operator without any symmetries display(a_op[]) display((a_op' * a_op)[]) ```` The [] accessor lets us see the underlying array, and indeed the operators are exactly what -we require. Similarly, the Bose Hubbard model is also predefined in -[`MPSKitModels.bose_hubbard_model`](@extref) (although we will construct our own variant -later on). +we require. The shared [model helpers](https://github.com/QuantumKitHub/MPSKit.jl/blob/main/docs/src/assets/models.jl) define +`bose_hubbard_model` using these operators, although we will construct our own variant +later on. ````julia -hamiltonian = bose_hubbard_model(InfiniteChain(1); cutoff = cutoff, U = 1, mu = 0.5, t = 0.2) # It is not strictly required to pass InfiniteChain() and is only included for clarity; one may instead pass FiniteChain(N) as well +hamiltonian = bose_hubbard_model(; cutoff = cutoff, U = 1, mu = 0.5, t = 0.2) # Infinite chain by default; pass L = N for an open finite chain ```` ```` @@ -154,9 +156,9 @@ println("Energy: ", expectation_value(ground_state, hamiltonian)) ```` ```` -[ Info: VUMPS init: obj = +3.450895756898e-01 err = 6.6224e-01 -[ Info: VUMPS conv 72: obj = -6.756981551609e-01 err = 9.5394492271e-07 time = 2.91 sec -Energy: -0.6756981551608794 - 1.967768893425733e-17im +[ Info: VUMPS init: obj = +4.779985577791e-01 err = 6.1432e-01 +[ Info: VUMPS conv 29: obj = -6.757777651157e-01 err = 9.0419343636e-07 time = 6.50 sec +Energy: -0.6757777651156838 + 2.90085953191521e-17im ```` @@ -166,7 +168,7 @@ reached. Let us wrap all this into a convenient function. ````julia function get_ground_state(mu, t, cutoff, D; kwargs...) - hamiltonian = bose_hubbard_model(InfiniteChain(); cutoff = cutoff, U = 1, mu = mu, t = t) + hamiltonian = bose_hubbard_model(; cutoff = cutoff, U = 1, mu = mu, t = t) state = InfiniteMPS(ℂ^(cutoff + 1), ℂ^D) state, _, _ = find_groundstate(state, hamiltonian, VUMPS(; kwargs...)) @@ -238,7 +240,7 @@ end npoints = 400 two_point_correlation = zeros(length(Ds), npoints) -a_op = a_min(cutoff = cutoff) +a_op = b_min(cutoff = cutoff) Threads.@threads for idx in eachindex(Ds) two_point_correlation[idx, :] .= real.(expectation_value(states[idx], (1, i) => a_op' ⊗ a_op) for i in 1:npoints) @@ -285,13 +287,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.30974278056400306 + 0.28814773292057094 + 0.27020018663546547 + 0.25712728281504493 + 0.24685386187635147 + 0.23539733364228202 + 0.2279965627270329 ```` We may now also visualize the momentum distribution function, which is obtained as the @@ -375,32 +377,25 @@ $$\frac{E[\Phi] - E[0]}{L} \approx \frac{1}{2} \Upsilon(L) \bigg (\frac{\Phi}{L} In order to find the ground state under these twisted boundary conditions, we must construct our own variant of the Bose-Hubbard Hamiltonian. Typically you would want to take a peek at the -[source code](https://github.com/QuantumKitHub/MPSKitModels.jl/blob/f4c36d9660a9eab05fa253ffd5c20dc6b7df44cc/src/models/hamiltonians.jl#L379-L409) -of `MPSKitModels.jl` to see how these models are defined and tweak it as per your needs. +[model helper source](https://github.com/QuantumKitHub/MPSKit.jl/blob/main/docs/src/assets/models.jl) to see how these models are defined and tweak it as per your needs. Here we see that applying twisted boundary conditions is equivalent to adding a prefactor of $e^{\pm i\phi}$ in front of the hopping amplitudes. ````julia function bose_hubbard_model_twisted_bc( - elt::Type{<:Number} = ComplexF64, symmetry::Type{<:Sector} = Trivial, - lattice::AbstractLattice = InfiniteChain(1); + elt::Type{<:Number} = ComplexF64, symmetry::Type{<:Sector} = Trivial; cutoff::Integer = 5, t = 1.0, U = 1.0, mu = 0.0, phi = 0 ) - a_pm = a_plusmin(elt, symmetry; cutoff = cutoff) - a_mp = a_minplus(elt, symmetry; cutoff = cutoff) - N = a_number(elt, symmetry; cutoff = cutoff) + a_pm = b_plus_b_min(elt, symmetry; cutoff = cutoff) + a_mp = b_min_b_plus(elt, symmetry; cutoff = cutoff) + N = b_num(elt, symmetry; cutoff = cutoff) interaction_term = N * (N - id(domain(N))) - return H = @mpoham begin - sum(nearest_neighbours(lattice)) do (i, j) - return -t * (exp(1im * phi) * a_pm{i, j} + exp(1im * -phi) * a_mp{i, j}) - end + - sum(vertices(lattice)) do i - return U / 2 * interaction_term{i} - mu * N{i} - end - end + hopping = -t * (exp(1im * phi) * a_pm + exp(-1im * phi) * a_mp) + onsite = U / 2 * interaction_term - mu * N + return chain_hamiltonian(hopping, onsite) end function superfluid_stiffness_profile(t, mu, D, cutoff, ϵ = 1.0e-4, npoints = 11) @@ -442,11 +437,11 @@ cutoff, D = 4, 10 mus = range(0, 0.75, 40) ts = range(0, 0.3, 40) -a_op = a_min(cutoff = cutoff) +a_op = b_min(cutoff = cutoff) order_parameters = zeros(length(ts), length(mus)) Threads.@threads for (i, j) in collect(Iterators.product(eachindex(mus), eachindex(ts))) - hamiltonian = bose_hubbard_model(InfiniteChain(); cutoff = cutoff, U = 1, mu = mus[i], t = ts[j]) + hamiltonian = bose_hubbard_model(; cutoff = cutoff, U = 1, mu = mus[i], t = ts[j]) init_state = InfiniteMPS(ℂ^(cutoff + 1), ℂ^D) state, _, _ = find_groundstate(init_state, hamiltonian, VUMPS(; tol = 1.0e-8, verbosity = 0)) order_parameters[i, j] = abs(expectation_value(state, 0 => a_op)) diff --git a/docs/src/examples/quantum1d/8.bose-hubbard/main.ipynb b/docs/src/examples/quantum1d/8.bose-hubbard/main.ipynb index 615cea4a7..47d1e89ed 100644 --- a/docs/src/examples/quantum1d/8.bose-hubbard/main.ipynb +++ b/docs/src/examples/quantum1d/8.bose-hubbard/main.ipynb @@ -7,7 +7,114 @@ "outputs": [], "source": [ "using Markdown\n", - "using MPSKit, MPSKitModels, TensorKit\n", + "using TensorKitTensors.BosonOperators: b_min, b_plus_b_min, b_min_b_plus, b_num\n", + "using MPSKit, TensorKit\n", + "# Model constructors for the MPSKit documentation and examples.\n", + "# Adapted from MPSKitModels.jl v0.4.7, src/models/{hamiltonians,transfermatrices}.jl:\n", + "# https://github.com/QuantumKitHub/MPSKitModels.jl/tree/v0.4.7/src/models\n", + "# Operators come from TensorKitTensors; chain assembly uses MPSKit directly.\n", + "#\n", + "# MIT License\n", + "# Copyright (c) 2021 Maarten Van Damme\n", + "#\n", + "# Permission is hereby granted, free of charge, to any person obtaining a copy\n", + "# of this software and associated documentation files (the \"Software\"), to deal\n", + "# in the Software without restriction, including without limitation the rights\n", + "# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n", + "# copies of the Software, and to permit persons to whom the Software is\n", + "# furnished to do so, subject to the following conditions:\n", + "#\n", + "# The above copyright notice and this permission notice shall be included in all\n", + "# copies or substantial portions of the Software.\n", + "#\n", + "# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n", + "# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n", + "# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n", + "# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n", + "# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n", + "# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n", + "# SOFTWARE.\n", + "\n", + "module ExampleModels\n", + "\n", + "using MPSKit, TensorKit\n", + "using TensorKitTensors: SpinOperators, BosonOperators, HubbardOperators\n", + "\n", + "export chain_hamiltonian, transverse_field_ising, heisenberg_XXX\n", + "export hubbard_model, bose_hubbard_model, hard_hexagon\n", + "\n", + "# L specifies an open finite chain; otherwise unitcell specifies an infinite chain.\n", + "function chain_hamiltonian(twosite, onesite = nothing; L = nothing, unitcell::Integer = 1)\n", + " nsites = isnothing(L) ? unitcell : L\n", + " nsites isa Integer && nsites > 0 || throw(ArgumentError(\"chain length must be a positive integer\"))\n", + " nbonds = isnothing(L) ? nsites : nsites - 1\n", + " terms = Pair[(i, i + 1) => twosite for i in 1:nbonds]\n", + " if !isnothing(onesite)\n", + " append!(terms, [i => onesite for i in 1:nsites])\n", + " end\n", + " spaces = fill(space(twosite, 1), nsites)\n", + " constructor = isnothing(L) ? InfiniteMPOHamiltonian : FiniteMPOHamiltonian\n", + " return constructor(spaces, terms)\n", + "end\n", + "\n", + "# H = -J sum(σz_i σz_{i+1} + g σx_i).\n", + "function transverse_field_ising(\n", + " T::Type{<:Number} = ComplexF64, symmetry::Type{<:Sector} = Trivial;\n", + " J = 1.0, g = 1.0, kwargs...\n", + " )\n", + " ZZ = 4 * SpinOperators.S_z_S_z(T, symmetry; spin = 1 // 2)\n", + " X = SpinOperators.σˣ(T, symmetry)\n", + " return chain_hamiltonian(-J * ZZ, -J * g * X; kwargs...)\n", + "end\n", + "transverse_field_ising(symmetry::Type{<:Sector}; kwargs...) =\n", + " transverse_field_ising(ComplexF64, symmetry; kwargs...)\n", + "\n", + "# H = J sum(S_i ⋅ S_{i+1}); preserve the examples' spin-1 default.\n", + "function heisenberg_XXX(\n", + " T::Type{<:Number} = ComplexF64, symmetry::Type{<:Sector} = Trivial;\n", + " J = 1.0, spin = 1, kwargs...\n", + " )\n", + " term = J * SpinOperators.S_exchange(T, symmetry; spin)\n", + " return chain_hamiltonian(term; kwargs...)\n", + "end\n", + "heisenberg_XXX(symmetry::Type{<:Sector}; kwargs...) =\n", + " heisenberg_XXX(ComplexF64, symmetry; kwargs...)\n", + "\n", + "# H = -t sum(e⁺_i e⁻_{i+1} + h.c.) + U sum(n↑ n↓) - mu sum(n).\n", + "function hubbard_model(\n", + " T::Type{<:Number} = ComplexF64, particle_symmetry::Type{<:Sector} = Trivial,\n", + " spin_symmetry::Type{<:Sector} = Trivial;\n", + " t = 1.0, U = 1.0, mu = 0.0, kwargs...\n", + " )\n", + " # e_hopping includes the fermionic reordering sign and is Hermitian.\n", + " hopping = HubbardOperators.e_hopping(T, particle_symmetry, spin_symmetry)\n", + " interaction = HubbardOperators.ud_num(T, particle_symmetry, spin_symmetry)\n", + " N = HubbardOperators.e_num(T, particle_symmetry, spin_symmetry)\n", + " return chain_hamiltonian(-t * hopping, U * interaction - mu * N; kwargs...)\n", + "end\n", + "\n", + "# H = -t sum(b⁺_i b⁻_{i+1} + h.c.) + U/2 sum(n(n-1)) - mu sum(n).\n", + "function bose_hubbard_model(\n", + " T::Type{<:Number} = ComplexF64, symmetry::Type{<:Sector} = Trivial;\n", + " cutoff::Integer = 5, t = 1.0, U = 1.0, mu = 0.0, kwargs...\n", + " )\n", + " hopping = BosonOperators.b_plus_b_min(T, symmetry; cutoff) +\n", + " BosonOperators.b_min_b_plus(T, symmetry; cutoff)\n", + " N = BosonOperators.b_num(T, symmetry; cutoff)\n", + " interaction = N * (N - id(domain(N)))\n", + " return chain_hamiltonian(-t * hopping, U / 2 * interaction - mu * N; kwargs...)\n", + "end\n", + "\n", + "function hard_hexagon(T::Type{<:Number} = ComplexF64)\n", + " P = Vect[FibonacciAnyon](:τ => 1)\n", + " O = ones(T, P ⊗ P ← P ⊗ P)\n", + " block(O, FibonacciAnyon(:I)) .*= 0\n", + " return InfiniteMPO([O])\n", + "end\n", + "\n", + "end\n", + "\n", + "using .ExampleModels\n", "using Plots, LaTeXStrings\n", "\n", "\n", @@ -116,9 +223,9 @@ "This simply initializes a tensor filled with random entries (check out the documentation for\n", "other useful constructors). Next, we need the creation and annihilation operators. While we\n", "could construct them from scratch, here we will use\n", - "[`MPSKitModels.jl`](https://github.com/QuantumKitHub/MPSKitModels.jl) instead that has\n", - "predefined operators and models for most well-known lattice models. In particular, we can\n", - "use `MPSKitModels.a_min` to create the bosonic annihilation operator." + "[TensorKitTensors.jl](https://github.com/QuantumKitHub/TensorKitTensors.jl), which provides\n", + "predefined operators. In particular, `BosonOperators.b_min` creates the bosonic annihilation\n", + "operator." ] }, { @@ -127,7 +234,7 @@ "metadata": {}, "outputs": [], "source": [ - "a_op = a_min(cutoff = cutoff) # creates a bosonic annihilation operator without any symmetries\n", + "a_op = b_min(cutoff = cutoff) # creates a bosonic annihilation operator without any symmetries\n", "display(a_op[])\n", "display((a_op' * a_op)[])" ] @@ -137,9 +244,9 @@ "metadata": {}, "source": [ "The [] accessor lets us see the underlying array, and indeed the operators are exactly what\n", - "we require. Similarly, the Bose Hubbard model is also predefined in\n", - "`MPSKitModels.bose_hubbard_model` (although we will construct our own variant\n", - "later on)." + "we require. The shared [model helpers](https://github.com/QuantumKitHub/MPSKit.jl/blob/main/docs/src/assets/models.jl) define\n", + "`bose_hubbard_model` using these operators, although we will construct our own variant\n", + "later on." ] }, { @@ -148,7 +255,7 @@ "metadata": {}, "outputs": [], "source": [ - "hamiltonian = bose_hubbard_model(InfiniteChain(1); cutoff = cutoff, U = 1, mu = 0.5, t = 0.2) # It is not strictly required to pass InfiniteChain() and is only included for clarity; one may instead pass FiniteChain(N) as well" + "hamiltonian = bose_hubbard_model(; cutoff = cutoff, U = 1, mu = 0.5, t = 0.2) # Infinite chain by default; pass L = N for an open finite chain" ] }, { @@ -188,7 +295,7 @@ "outputs": [], "source": [ "function get_ground_state(mu, t, cutoff, D; kwargs...)\n", - " hamiltonian = bose_hubbard_model(InfiniteChain(); cutoff = cutoff, U = 1, mu = mu, t = t)\n", + " hamiltonian = bose_hubbard_model(; cutoff = cutoff, U = 1, mu = mu, t = t)\n", " state = InfiniteMPS(ℂ^(cutoff + 1), ℂ^D)\n", " state, _, _ = find_groundstate(state, hamiltonian, VUMPS(; kwargs...))\n", "\n", @@ -276,7 +383,7 @@ "\n", "npoints = 400\n", "two_point_correlation = zeros(length(Ds), npoints)\n", - "a_op = a_min(cutoff = cutoff)\n", + "a_op = b_min(cutoff = cutoff)\n", "\n", "Threads.@threads for idx in eachindex(Ds)\n", " two_point_correlation[idx, :] .= real.(expectation_value(states[idx], (1, i) => a_op' ⊗ a_op) for i in 1:npoints)\n", @@ -422,8 +529,7 @@ "In order to find the ground state under these twisted boundary conditions, we must construct\n", "our own variant of the Bose-Hubbard Hamiltonian. Typically you would want to take a peek at\n", "the\n", - "[source code](https://github.com/QuantumKitHub/MPSKitModels.jl/blob/f4c36d9660a9eab05fa253ffd5c20dc6b7df44cc/src/models/hamiltonians.jl#L379-L409)\n", - "of `MPSKitModels.jl` to see how these models are defined and tweak it as per your needs.\n", + "[model helper source](https://github.com/QuantumKitHub/MPSKit.jl/blob/main/docs/src/assets/models.jl) to see how these models are defined and tweak it as per your needs.\n", "Here we see that applying twisted boundary conditions is equivalent to adding a prefactor of\n", "$e^{\\pm i\\phi}$ in front of the hopping amplitudes." ] @@ -435,25 +541,19 @@ "outputs": [], "source": [ "function bose_hubbard_model_twisted_bc(\n", - " elt::Type{<:Number} = ComplexF64, symmetry::Type{<:Sector} = Trivial,\n", - " lattice::AbstractLattice = InfiniteChain(1);\n", + " elt::Type{<:Number} = ComplexF64, symmetry::Type{<:Sector} = Trivial;\n", " cutoff::Integer = 5, t = 1.0, U = 1.0, mu = 0.0, phi = 0\n", " )\n", "\n", - " a_pm = a_plusmin(elt, symmetry; cutoff = cutoff)\n", - " a_mp = a_minplus(elt, symmetry; cutoff = cutoff)\n", - " N = a_number(elt, symmetry; cutoff = cutoff)\n", + " a_pm = b_plus_b_min(elt, symmetry; cutoff = cutoff)\n", + " a_mp = b_min_b_plus(elt, symmetry; cutoff = cutoff)\n", + " N = b_num(elt, symmetry; cutoff = cutoff)\n", "\n", " interaction_term = N * (N - id(domain(N)))\n", "\n", - " return H = @mpoham begin\n", - " sum(nearest_neighbours(lattice)) do (i, j)\n", - " return -t * (exp(1im * phi) * a_pm{i, j} + exp(1im * -phi) * a_mp{i, j})\n", - " end +\n", - " sum(vertices(lattice)) do i\n", - " return U / 2 * interaction_term{i} - mu * N{i}\n", - " end\n", - " end\n", + " hopping = -t * (exp(1im * phi) * a_pm + exp(-1im * phi) * a_mp)\n", + " onsite = U / 2 * interaction_term - mu * N\n", + " return chain_hamiltonian(hopping, onsite)\n", "end\n", "\n", "function superfluid_stiffness_profile(t, mu, D, cutoff, ϵ = 1.0e-4, npoints = 11)\n", @@ -503,11 +603,11 @@ "mus = range(0, 0.75, 40)\n", "ts = range(0, 0.3, 40)\n", "\n", - "a_op = a_min(cutoff = cutoff)\n", + "a_op = b_min(cutoff = cutoff)\n", "order_parameters = zeros(length(ts), length(mus))\n", "\n", "Threads.@threads for (i, j) in collect(Iterators.product(eachindex(mus), eachindex(ts)))\n", - " hamiltonian = bose_hubbard_model(InfiniteChain(); cutoff = cutoff, U = 1, mu = mus[i], t = ts[j])\n", + " hamiltonian = bose_hubbard_model(; cutoff = cutoff, U = 1, mu = mus[i], t = ts[j])\n", " init_state = InfiniteMPS(ℂ^(cutoff + 1), ℂ^D)\n", " state, _, _ = find_groundstate(init_state, hamiltonian, VUMPS(; tol = 1.0e-8, verbosity = 0))\n", " order_parameters[i, j] = abs(expectation_value(state, 0 => a_op))\n", @@ -539,15 +639,15 @@ ], "metadata": { "kernelspec": { - "display_name": "Julia 1.12.6", + "display_name": "Julia 1.13.1", "language": "julia", - "name": "julia-1.12" + "name": "julia-1.13" }, "language_info": { "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", - "version": "1.12.6" + "version": "1.13.1" } }, "nbformat": 4, diff --git a/docs/src/index.md b/docs/src/index.md index 2b9265209..26d608715 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -64,9 +64,10 @@ pkg> add MPSKit 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. +[TensorKitTensors.jl](https://github.com/QuantumKitHub/TensorKitTensors.jl). The former defines +the tensor backend which is used throughout MPSKit, while the latter provides common +operators. The documentation examples use shared [model constructors](https://github.com/QuantumKitHub/MPSKit.jl/blob/main/docs/src/assets/models.jl) +built from those operators. ```julia using TensorOperations @@ -135,8 +136,8 @@ println(" = $N2") ``` 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: +Using TensorKit operators and MPSKit’s Hamiltonian constructors, we can find the ground +state of the transverse field Ising model: ```@example finitemps J = 1.0 @@ -211,8 +212,8 @@ println(" = $N2") 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: +We can construct its Hamiltonian directly and find the ground state of the transverse field +Ising model: ```@example infinitemps J = 1.0 @@ -235,4 +236,3 @@ Keep in mind that the documentation is still a work in progress, and that some f 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. - diff --git a/docs/src/man/algorithms.md b/docs/src/man/algorithms.md index efd092418..7b4a1e1fb 100644 --- a/docs/src/man/algorithms.md +++ b/docs/src/man/algorithms.md @@ -1,5 +1,5 @@ ```@meta -DocTestSetup = :(using MPSKit, TensorKit, MPSKitModels) +DocTestSetup = :(using MPSKit, TensorKit, Main.ExampleModels) ``` # [Algorithms](@id um_algorithms) @@ -138,9 +138,12 @@ excitations ``` ```@setup excitations -using TensorKit, MPSKit, MPSKitModels +using TensorKit, MPSKit, Main.ExampleModels ``` +The following examples use the shared [model constructors](https://github.com/QuantumKitHub/MPSKit.jl/blob/main/docs/src/assets/models.jl), built from +TensorKitTensors operators and MPSKit Hamiltonians. + ### 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. @@ -158,7 +161,7 @@ Some deviations are expected, both due to finite-bond-dimension and finite-size # Model parameters g = 10.0 L = 16 -H = transverse_field_ising(FiniteChain(L); g) +H = transverse_field_ising(; L, g) # Finding the ground state ψ₀ = FiniteMPS(L, ℂ^2, ℂ^32) @@ -197,7 +200,7 @@ For instance, in the transverse field Ising model, we consider an excitation bui ```@example excitations g = 10.0 L = 16 -H = transverse_field_ising(Z2Irrep, FiniteChain(L); g) +H = transverse_field_ising(Z2Irrep; 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)) @@ -217,7 +220,7 @@ This is also supported by calling # Model parameters g = 10.0 L = 16 -H = transverse_field_ising(FiniteChain(L); g) +H = transverse_field_ising(; L, g) # Finding the ground state ψ₀ = FiniteMPS(L, ℂ^2, ℂ^32) @@ -246,7 +249,7 @@ This is supported via the following syntax: ```@example excitations g = 10.0 L = 16 -H = transverse_field_ising(FiniteChain(L); g) +H = transverse_field_ising(; L, g) ψ₀ = FiniteMPS(L, ComplexSpace(2), ComplexSpace(32)) ψ, envs, = find_groundstate(ψ₀, H; verbosity=0) E₀ = real(sum(expectation_value(ψ, H, envs))) diff --git a/docs/src/man/operators.md b/docs/src/man/operators.md index 133e82aab..cb5f1bacb 100644 --- a/docs/src/man/operators.md +++ b/docs/src/man/operators.md @@ -18,7 +18,7 @@ product of local tensors. ``` ```@setup operators -using TensorKit, MPSKit, MPSKitModels +using TensorKit, MPSKit ``` ```@example operators diff --git a/examples/Cache.toml b/examples/Cache.toml index 1b15ac166..b7b4b67b6 100644 --- a/examples/Cache.toml +++ b/examples/Cache.toml @@ -1,12 +1,12 @@ -[classic2d] -"1.hard-hexagon" = "059f9a5162d75323c7104a8fb178458f965db7bda1481021ae51d4fb8ec9cde9" - [quantum1d] -"2.haldane" = "c5a0eb70f0930d38053535c659ab39a87121b6ebda040ceadd9deb5f30921315" -"6.hubbard" = "cef140a6224350345735aac889ee7e33724fc0af9ce94f68be47a7e40107c09c" -"7.xy-finiteT" = "0f330a157bea739a43a82a937791c680b2fa6e5e479171ee5ef318d1fdae7bcf" -"8.bose-hubbard" = "cf0d9a543e784dc6053e413780d19e1b59bf956dd4598752fdf664804dd68ce6" -"3.ising-dqpt" = "a2900eed23de7655f600943fae72d1dc35f87f33d11947f707d302ce245399fe" -"5.haldane-spt" = "c8fd3a8d406b9ff3ea9a34b596c5910d81e4eb710b665d7fa04e30f795a46086" -"4.xxz-heisenberg" = "9033fb104c3f658ccb1b8e335b986b7abda59e0b5359be086d3b62e1cc32ebd6" -"1.ising-cft" = "3d34757eee7b95120b746c5e30e713203a876a87353ecd9937798f29183c9916" +"5.haldane-spt" = "036357a831de62bc8c11b47d1459cc4025d82907c093405a54f8dff58199c217" +"4.xxz-heisenberg" = "e233902efef4a795d219cdaa33cb7062ae10343d53d50f59a720888a4c5ac108" +"2.haldane" = "3731b764455869cd544549d5960607e6ef9e478772d38e1176622e944d32da94" +"6.hubbard" = "7b2755b20106bf7396873d98eb17c3e6eafff8911b25402bc1d3a8656a276827" +"1.ising-cft" = "f47f09646cd0f5ee1d64df56ba63e65641aeef677854ebe538ced17800f63ba1" +"8.bose-hubbard" = "b85f1b30afd2e8560aeb1f5f146c713805bfc4fa28a16d987800cee52bbe5c7c" +"3.ising-dqpt" = "036eef5420674454faa9ba2311c3230ce3b10b7a1db103d8fe554439a03ded6d" +"7.xy-finiteT" = "c1e7b05098090b86af3bf2b266392890d986821259b4c60e10aead3559d421fc" + +[classic2d] +"1.hard-hexagon" = "3891f44506135f70a1ce2b05349e61754b5d57abf23da2f61fcea5594180a8fa" diff --git a/examples/Project.toml b/examples/Project.toml index 2e29ddd9c..827d34e2e 100644 --- a/examples/Project.toml +++ b/examples/Project.toml @@ -6,14 +6,17 @@ LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306" MPSKit = "bb1c41ca-d63c-52ed-829e-0820dda26502" -MPSKitModels = "ca635005-6f8c-4cd1-b51d-8491250ef2ab" Optim = "429524aa-4258-5aef-a3af-852621145aeb" Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" Polynomials = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" QuadGK = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" TensorKit = "07d1fe3e-3e46-537d-9eac-e9e13d0d4cec" +TensorKitTensors = "41b62e7d-e9d1-4e23-942c-79a97adf954b" TensorOperations = "6aa20fa7-93e2-5fca-9bc0-fbd0db3c71a2" [sources] MPSKit = {path = ".."} + +[compat] +TensorKitTensors = "0.3.1" diff --git a/examples/classic2d/1.hard-hexagon/main.jl b/examples/classic2d/1.hard-hexagon/main.jl index 4478428d2..864ad1785 100644 --- a/examples/classic2d/1.hard-hexagon/main.jl +++ b/examples/classic2d/1.hard-hexagon/main.jl @@ -10,7 +10,9 @@ Because TensorKit supports anyonic symmetries, so does MPSKit. To follow the tutorial you need the following packages. """ -using MPSKit, MPSKitModels, TensorKit, Plots, Polynomials +using MPSKit, TensorKit, Plots, Polynomials +include(joinpath(@__DIR__, "..", "..", "..", "docs", "src", "assets", "models.jl")) #hide +using .ExampleModels #src # for reproducibility: #src using Random @@ -18,7 +20,7 @@ using MPSKit, MPSKitModels, TensorKit, Plots, Polynomials md""" The [hard hexagon model](https://en.wikipedia.org/wiki/Hard_hexagon_model) is a 2-dimensional lattice model of a gas, where particles are allowed to be on the vertices of a triangular lattice, but no two particles may be adjacent. -This can be encoded in a transfer matrix with a local MPO tensor using anyonic symmetries, and the resulting MPO has been implemented in MPSKitModels. +This can be encoded in a transfer matrix with a local MPO tensor using anyonic symmetries, and the resulting MPO is defined in our shared [model helpers](https://github.com/QuantumKitHub/MPSKit.jl/blob/main/docs/src/assets/models.jl). In order to use these anyonic symmetries, we need to generalise the notion of the bond dimension and define how it interacts with the symmetry. Thus, we implement a way of converting integers to symmetric spaces of the given dimension, which provides a crude guess for how the final MPS would distribute its Schmidt spectrum. diff --git a/examples/make.jl b/examples/make.jl index c6c9cfd72..de842a665 100644 --- a/examples/make.jl +++ b/examples/make.jl @@ -18,6 +18,8 @@ include(joinpath(@__DIR__, "figure_externalization.jl")) # ---------------------------------------------------------------------------------------- # const CACHEFILE = joinpath(@__DIR__, "Cache.toml") +const MODELSFILE = joinpath(@__DIR__, "..", "docs", "src", "assets", "models.jl") +const MODEL_INCLUDE = "include(joinpath(@__DIR__, \"..\", \"..\", \"..\", \"docs\", \"src\", \"assets\", \"models.jl\")) #hide" getcache() = isfile(CACHEFILE) ? TOML.parsefile(CACHEFILE) : Dict{String, Any}() @@ -43,9 +45,22 @@ end function checksum(root, name) example_path = joinpath(@__DIR__, root, name, "main.jl") @assert isfile(example_path) - return open(example_path, "r") do io - return bytes2hex(sha256(io)) + inputs = ( + example_path, MODELSFILE, @__FILE__, joinpath(@__DIR__, "Project.toml"), + joinpath(@__DIR__, "..", "Project.toml"), + ) + return bytes2hex(sha256(mapreduce(read, vcat, inputs))) +end + +# Inline the shared constructors so exported notebooks run without repository-relative paths. +# Hide their implementation in the rendered page; the source is available as a docs asset. +function inline_models(str; hide = false) + contains(str, MODEL_INCLUDE) || return str + source = replace(read(MODELSFILE, String), r"(?m)^(\h*)#" => s"\1##") + if hide + source = join((line * " #hide" for line in split(source, '\n')), '\n') end + return replace(str, MODEL_INCLUDE => source) end # ---------------------------------------------------------------------------------------- # @@ -73,7 +88,7 @@ function build_example(root, name) return if !iscached(root, name) Literate.markdown( source_file, target_dir; execute = true, name = "index", - preprocess = attach_notebook_badge(root, name), + preprocess = str -> attach_notebook_badge(root, name, inline_models(str; hide = true)), postprocess = content -> externalize_figures(content, target_dir), mdstrings = true, nbviewer_root_url = "https://nbviewer.jupyter.org/github/QuantumKitHub/MPSKit.jl/blob/gh-pages/dev", @@ -83,7 +98,7 @@ function build_example(root, name) ) Literate.notebook( source_file, target_dir; execute = false, name = "main", - preprocess = str -> replace(str, r"(? "\$"), + preprocess = str -> replace(inline_models(str), r"(? "\$"), mdstrings = true, credits = false ) diff --git a/examples/quantum1d/1.ising-cft/main.jl b/examples/quantum1d/1.ising-cft/main.jl index c2434cfc1..c6fc12487 100644 --- a/examples/quantum1d/1.ising-cft/main.jl +++ b/examples/quantum1d/1.ising-cft/main.jl @@ -6,7 +6,9 @@ do this by first employing an exact diagonalization technique, and then extendin analysis to larger system sizes through the use of MPS techniques. """ -using MPSKit, MPSKitModels, TensorKit, Plots, KrylovKit +using MPSKit, TensorKit, Plots, KrylovKit +include(joinpath(@__DIR__, "..", "..", "..", "docs", "src", "assets", "models.jl")) #hide +using .ExampleModels using LinearAlgebra: eigvals, diagm, Hermitian md""" diff --git a/examples/quantum1d/2.haldane/main.jl b/examples/quantum1d/2.haldane/main.jl index 4cb689e66..a7213b12a 100644 --- a/examples/quantum1d/2.haldane/main.jl +++ b/examples/quantum1d/2.haldane/main.jl @@ -5,7 +5,10 @@ In this tutorial we will calculate the Haldane gap (the energy gap in the ``S = To follow the tutorial you need the following packages: """ -using MPSKit, MPSKitModels, TensorKit, Plots, Polynomials +using MPSKit, TensorKit, Plots, Polynomials +include(joinpath(@__DIR__, "..", "..", "..", "docs", "src", "assets", "models.jl")) #hide +using .ExampleModels +using TensorKitTensors.SpinOperators: S_exchange md""" The Heisenberg model is defined by the following Hamiltonian: @@ -36,8 +39,7 @@ This can be done as follows. """ L = 11 -chain = FiniteChain(L) -H = heisenberg_XXX(symmetry, chain; J, spin) +H = heisenberg_XXX(symmetry; L, J, spin) physical_space = SU2Space(1 => 1) virtual_space = SU2Space(0 => 12, 1 => 12, 2 => 5, 3 => 3) @@ -71,7 +73,7 @@ Ls = 12:4:30 ΔEs = map(Ls) do L @info "computing L = $L" ψ₀ = FiniteMPS(L, physical_space, virtual_space) - H = heisenberg_XXX(symmetry, FiniteChain(L); J, spin) + H = heisenberg_XXX(symmetry; L, J, spin) ψ, envs, info = find_groundstate(ψ₀, H, DMRG(; verbosity = 0)) En_1, st_1 = excitations(H, QuasiparticleAnsatz(), ψ, envs; sector = SU2Irrep(1)) En_2, st_2 = excitations(H, QuasiparticleAnsatz(), ψ, envs; sector = SU2Irrep(2)) @@ -99,8 +101,7 @@ In contrast with the finite size case, we now should specify a momentum label to This way, it is possible to scan the dispersion relation over the entire momentum space. """ -chain = InfiniteChain(1) -H = heisenberg_XXX(symmetry, chain; J, spin) +H = heisenberg_XXX(symmetry; J, spin) virtual_space_inf = Rep[SU₂](1 // 2 => 16, 3 // 2 => 16, 5 // 2 => 8, 7 // 2 => 4) ψ₀_inf = InfiniteMPS([physical_space], [virtual_space_inf]) ψ_inf, envs_inf, info_inf = find_groundstate(ψ₀_inf, H; verbosity = 0) diff --git a/examples/quantum1d/3.ising-dqpt/main.jl b/examples/quantum1d/3.ising-dqpt/main.jl index 8c9219526..6545ae1f5 100644 --- a/examples/quantum1d/3.ising-dqpt/main.jl +++ b/examples/quantum1d/3.ising-dqpt/main.jl @@ -5,7 +5,9 @@ In this tutorial we will try to reproduce the results from [this paper](https://arxiv.org/pdf/1206.2505.pdf). The needed packages are """ -using MPSKit, MPSKitModels, TensorKit +using MPSKit, TensorKit +include(joinpath(@__DIR__, "..", "..", "..", "docs", "src", "assets", "models.jl")) #hide +using .ExampleModels md""" Dynamical quantum phase transitions (DQPT in short) are signatures of equilibrium phase transitions in a dynamical quantity - the Loschmidt echo. @@ -26,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) +H₀ = transverse_field_ising(; L, g = -0.5) ψ₀ = FiniteMPS(L, ℂ^2, ℂ^10) ψ₀, _ = find_groundstate(ψ₀, H₀, DMRG()); @@ -43,7 +45,7 @@ md""" We will initially use a two-site TDVP scheme to dynamically increase the bond dimension while time evolving, and later on switch to a faster one-site scheme. A single timestep can be done using """ -H₁ = transverse_field_ising(FiniteChain(L); g = -2.0) +H₁ = transverse_field_ising(; L, g = -2.0) ψₜ = deepcopy(ψ₀) dt = 0.01 ψₜ, envs, info = timestep(ψₜ, H₁, 0, dt, TDVP2(; trunc = truncrank(20))); @@ -56,10 +58,10 @@ 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) + H₀ = transverse_field_ising(; L, g = -0.5) ψ₀, _ = find_groundstate(ψ₀, H₀, DMRG()) - H₁ = transverse_field_ising(FiniteChain(L); g = -2.0) + H₁ = transverse_field_ising(; L, g = -2.0) ψₜ = deepcopy(ψ₀) envs = environments(ψₜ, H₁, ψₜ) diff --git a/examples/quantum1d/4.xxz-heisenberg/main.jl b/examples/quantum1d/4.xxz-heisenberg/main.jl index 53d7c9e00..51c8ba027 100644 --- a/examples/quantum1d/4.xxz-heisenberg/main.jl +++ b/examples/quantum1d/4.xxz-heisenberg/main.jl @@ -5,7 +5,9 @@ In this file we will give step by step instructions on how to analyze the spin 1 The necessary packages to follow this tutorial are: """ -using MPSKit, MPSKitModels, TensorKit, Plots +using MPSKit, TensorKit, Plots +include(joinpath(@__DIR__, "..", "..", "..", "docs", "src", "assets", "models.jl")) #hide +using .ExampleModels #src # for reproducibility: #src using Random @@ -68,11 +70,11 @@ state = InfiniteMPS(fill(2, 2), fill(20, 2)) md""" In MPSKit, we require that the periodicity of the Hamiltonian equals that of the state it is applied to. This is not a big obstacle, you can simply repeat the original Hamiltonian. -Alternatively, the Hamiltonian can be constructed directly on a two-site unit cell by making use of MPSKitModels.jl's `@mpoham`. +Alternatively, our model helper can construct the Hamiltonian directly on a two-site unit cell. """ ## H2 = repeat(H, 2); -- copies the one-site version -H2 = heisenberg_XXX(ComplexF64, Trivial, InfiniteChain(2); spin = 1 // 2) +H2 = heisenberg_XXX(ComplexF64, Trivial; unitcell = 2, spin = 1 // 2) groundstate, envs, info = find_groundstate( state, H2, VUMPS(; maxiter = 100, tol = 1.0e-12) ); @@ -104,7 +106,7 @@ The XXZ Heisenberg Hamiltonian is SU(2) symmetric and we can exploit this to gre It is cumbersome to construct symmetric Hamiltonians, but luckily SU(2) symmetric XXZ is already implemented: """ -H2 = heisenberg_XXX(ComplexF64, SU2Irrep, InfiniteChain(2); spin = 1 // 2); +H2 = heisenberg_XXX(ComplexF64, SU2Irrep; unitcell = 2, spin = 1 // 2); md""" Our initial state should also be SU(2) symmetric. diff --git a/examples/quantum1d/6.hubbard/main.jl b/examples/quantum1d/6.hubbard/main.jl index 0c4057484..c3653cf2f 100644 --- a/examples/quantum1d/6.hubbard/main.jl +++ b/examples/quantum1d/6.hubbard/main.jl @@ -29,7 +29,8 @@ H = - \sum_{\langle i, j \rangle, \sigma} c^{\dagger}_{i,\sigma} c_{j,\sigma} + using TensorKit using MPSKit -using MPSKitModels +include(joinpath(@__DIR__, "..", "..", "..", "docs", "src", "assets", "models.jl")) #hide +using .ExampleModels using SpecialFunctions: besselj0, besselj1 using QuadGK: quadgk using Plots @@ -92,7 +93,7 @@ function compute_groundstate( return psi end -H = hubbard_model(InfiniteChain(2); U, t, mu = U / 2) +H = hubbard_model(; unitcell = 2, U, t, mu = U / 2) Vspaces = fill(Vect[fℤ₂](0 => 10, 1 => 10), 2) psi = InfiniteMPS(physicalspace(H), Vspaces) psi = compute_groundstate(psi, H) @@ -116,7 +117,7 @@ In order to work at half-filling, we need to effectively inject one particle per In MPSKit, this is achieved by the `add_physical_charge` function, which shifts the physical spaces of the tensors to the desired charge sector. """ -H_u1_su2 = hubbard_model(ComplexF64, U1Irrep, SU2Irrep, InfiniteChain(2); U, t, mu = U / 2); +H_u1_su2 = hubbard_model(ComplexF64, U1Irrep, SU2Irrep; unitcell = 2, U, t, mu = U / 2); charges = fill(FermionParity(1) ⊠ U1Irrep(1) ⊠ SU2Irrep(0), 2); H_u1_su2 = MPSKit.add_physical_charge(H_u1_su2, charges); diff --git a/examples/quantum1d/7.xy-finiteT/main.jl b/examples/quantum1d/7.xy-finiteT/main.jl index 473006179..a44fa8121 100644 --- a/examples/quantum1d/7.xy-finiteT/main.jl +++ b/examples/quantum1d/7.xy-finiteT/main.jl @@ -1,8 +1,10 @@ using Markdown +using TensorKitTensors.SpinOperators: S_plus_S_min, S_min_S_plus using TensorKit using MPSKit +include(joinpath(@__DIR__, "..", "..", "..", "docs", "src", "assets", "models.jl")) #hide +using .ExampleModels using MPSKit: infinite_temperature_density_matrix -using MPSKitModels using QuadGK: quadgk using SpecialFunctions: ellipe using Plots @@ -37,13 +39,8 @@ function XY_hamiltonian( ::Type{T} = ComplexF64, ::Type{S} = Trivial; J = 1 / 2, N ) where {T <: Number, S <: Sector} spin = 1 // 2 - term = J * (S_xx(T, S; spin) + S_yy(T, S; spin)) - lattice = isfinite(N) ? FiniteChain(N) : InfiniteChain(1) - return @mpoham begin - sum(nearest_neighbours(lattice)) do (i, j) - return term{i, j} - end - end + term = J / 2 * (S_plus_S_min(T, S; spin) + S_min_S_plus(T, S; spin)) + return chain_hamiltonian(term; L = isfinite(N) ? Int(N) : nothing) end md""" diff --git a/examples/quantum1d/8.bose-hubbard/main.jl b/examples/quantum1d/8.bose-hubbard/main.jl index 86edb774d..51f7b67a6 100644 --- a/examples/quantum1d/8.bose-hubbard/main.jl +++ b/examples/quantum1d/8.bose-hubbard/main.jl @@ -1,5 +1,8 @@ using Markdown -using MPSKit, MPSKitModels, TensorKit +using TensorKitTensors.BosonOperators: b_min, b_plus_b_min, b_min_b_plus, b_num +using MPSKit, TensorKit +include(joinpath(@__DIR__, "..", "..", "..", "docs", "src", "assets", "models.jl")) #hide +using .ExampleModels using Plots, LaTeXStrings #src # for reproducibility: @@ -97,25 +100,25 @@ md""" This simply initializes a tensor filled with random entries (check out the documentation for other useful constructors). Next, we need the creation and annihilation operators. While we could construct them from scratch, here we will use -[`MPSKitModels.jl`](https://github.com/QuantumKitHub/MPSKitModels.jl) instead that has -predefined operators and models for most well-known lattice models. In particular, we can -use [`MPSKitModels.a_min`](@extref) to create the bosonic annihilation operator. +[TensorKitTensors.jl](https://github.com/QuantumKitHub/TensorKitTensors.jl), which provides +predefined operators. In particular, `BosonOperators.b_min` creates the bosonic annihilation +operator. """ -a_op = a_min(cutoff = cutoff) # creates a bosonic annihilation operator without any symmetries +a_op = b_min(cutoff = cutoff) # creates a bosonic annihilation operator without any symmetries display(a_op[]) display((a_op' * a_op)[]) md""" The [] accessor lets us see the underlying array, and indeed the operators are exactly what -we require. Similarly, the Bose Hubbard model is also predefined in -[`MPSKitModels.bose_hubbard_model`](@extref) (although we will construct our own variant -later on). +we require. The shared [model helpers](https://github.com/QuantumKitHub/MPSKit.jl/blob/main/docs/src/assets/models.jl) define +`bose_hubbard_model` using these operators, although we will construct our own variant +later on. """ -hamiltonian = bose_hubbard_model(InfiniteChain(1); cutoff = cutoff, U = 1, mu = 0.5, t = 0.2) # It is not strictly required to pass InfiniteChain() and is only included for clarity; one may instead pass FiniteChain(N) as well +hamiltonian = bose_hubbard_model(; cutoff = cutoff, U = 1, mu = 0.5, t = 0.2) # Infinite chain by default; pass L = N for an open finite chain md""" This has created the Hamiltonian operator as a [matrix product operator](@ref @@ -135,7 +138,7 @@ reached. Let us wrap all this into a convenient function. """ function get_ground_state(mu, t, cutoff, D; kwargs...) - hamiltonian = bose_hubbard_model(InfiniteChain(); cutoff = cutoff, U = 1, mu = mu, t = t) + hamiltonian = bose_hubbard_model(; cutoff = cutoff, U = 1, mu = mu, t = t) state = InfiniteMPS(ℂ^(cutoff + 1), ℂ^D) state, _, _ = find_groundstate(state, hamiltonian, VUMPS(; kwargs...)) @@ -194,7 +197,7 @@ end npoints = 400 two_point_correlation = zeros(length(Ds), npoints) -a_op = a_min(cutoff = cutoff) +a_op = b_min(cutoff = cutoff) Threads.@threads for idx in eachindex(Ds) two_point_correlation[idx, :] .= real.(expectation_value(states[idx], (1, i) => a_op' ⊗ a_op) for i in 1:npoints) @@ -316,32 +319,25 @@ $$\frac{E[\Phi] - E[0]}{L} \approx \frac{1}{2} \Upsilon(L) \bigg (\frac{\Phi}{L} In order to find the ground state under these twisted boundary conditions, we must construct our own variant of the Bose-Hubbard Hamiltonian. Typically you would want to take a peek at the -[source code](https://github.com/QuantumKitHub/MPSKitModels.jl/blob/f4c36d9660a9eab05fa253ffd5c20dc6b7df44cc/src/models/hamiltonians.jl#L379-L409) -of `MPSKitModels.jl` to see how these models are defined and tweak it as per your needs. +[model helper source](https://github.com/QuantumKitHub/MPSKit.jl/blob/main/docs/src/assets/models.jl) to see how these models are defined and tweak it as per your needs. Here we see that applying twisted boundary conditions is equivalent to adding a prefactor of $e^{\pm i\phi}$ in front of the hopping amplitudes. """ function bose_hubbard_model_twisted_bc( - elt::Type{<:Number} = ComplexF64, symmetry::Type{<:Sector} = Trivial, - lattice::AbstractLattice = InfiniteChain(1); + elt::Type{<:Number} = ComplexF64, symmetry::Type{<:Sector} = Trivial; cutoff::Integer = 5, t = 1.0, U = 1.0, mu = 0.0, phi = 0 ) - a_pm = a_plusmin(elt, symmetry; cutoff = cutoff) - a_mp = a_minplus(elt, symmetry; cutoff = cutoff) - N = a_number(elt, symmetry; cutoff = cutoff) + a_pm = b_plus_b_min(elt, symmetry; cutoff = cutoff) + a_mp = b_min_b_plus(elt, symmetry; cutoff = cutoff) + N = b_num(elt, symmetry; cutoff = cutoff) interaction_term = N * (N - id(domain(N))) - return H = @mpoham begin - sum(nearest_neighbours(lattice)) do (i, j) - return -t * (exp(1im * phi) * a_pm{i, j} + exp(1im * -phi) * a_mp{i, j}) - end + - sum(vertices(lattice)) do i - return U / 2 * interaction_term{i} - mu * N{i} - end - end + hopping = -t * (exp(1im * phi) * a_pm + exp(-1im * phi) * a_mp) + onsite = U / 2 * interaction_term - mu * N + return chain_hamiltonian(hopping, onsite) end function superfluid_stiffness_profile(t, mu, D, cutoff, ϵ = 1.0e-4, npoints = 11) @@ -381,11 +377,11 @@ cutoff, D = 4, 10 mus = range(0, 0.75, 40) ts = range(0, 0.3, 40) -a_op = a_min(cutoff = cutoff) +a_op = b_min(cutoff = cutoff) order_parameters = zeros(length(ts), length(mus)) Threads.@threads for (i, j) in collect(Iterators.product(eachindex(mus), eachindex(ts))) - hamiltonian = bose_hubbard_model(InfiniteChain(); cutoff = cutoff, U = 1, mu = mus[i], t = ts[j]) + hamiltonian = bose_hubbard_model(; cutoff = cutoff, U = 1, mu = mus[i], t = ts[j]) init_state = InfiniteMPS(ℂ^(cutoff + 1), ℂ^D) state, _, _ = find_groundstate(init_state, hamiltonian, VUMPS(; tol = 1.0e-8, verbosity = 0)) order_parameters[i, j] = abs(expectation_value(state, 0 => a_op)) diff --git a/examples/windowmps.jl b/examples/windowmps.jl index 8e012ef5b..cb3ffdccb 100644 --- a/examples/windowmps.jl +++ b/examples/windowmps.jl @@ -1,4 +1,6 @@ -using MPSKit, MPSKitModels, TensorKit, Plots +using MPSKit, TensorKit, Plots +include(joinpath(@__DIR__, "..", "docs", "src", "assets", "models.jl")) +using .ExampleModels let #defining the Hamiltonian diff --git a/src/algorithms/unionalg.jl b/src/algorithms/unionalg.jl index 801ffa606..0f38c0f02 100644 --- a/src/algorithms/unionalg.jl +++ b/src/algorithms/unionalg.jl @@ -38,7 +38,7 @@ function find_groundstate(state, H, alg::UnionAlg, envs = environments(state, H, return find_groundstate(state, H, alg.alg2, envs) end -function approximate(state, toapprox, alg::UnionAlg, envs = enviroments(state, toapprox...)) +function approximate(state, toapprox, alg::UnionAlg, envs = environments(state, toapprox...)) state, envs = approximate(state, toapprox, alg.alg1, envs) return approximate(state, toapprox, alg.alg2, envs) end