Skip to content

Changelog ​

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

Guidelines for updating this changelog ​

When making changes to this project, please update the "Unreleased" section with your changes under the appropriate category:

  • Added for new features.

  • Changed for changes in existing functionality.

  • Deprecated for soon-to-be removed features.

  • Removed for now removed features.

  • Fixed for any bug fixes.

When releasing a new version, move the "Unreleased" changes to a new version section with the release date.

Unreleased ​

Added ​

  • ClusterExpansion time-evolution algorithm for make_time_mpo, constructing evolution MPOs for finite and infinite nearest-neighbor Hamiltonians through a nonperturbative cluster expansion that matches exact exponentials on clusters of up to N sites. (#252)

  • In-place timestep! for an InfiniteMPS with TDVP, which also enables time_evolve! on infinite states. (#537)

  • changebonds(::InfiniteMPOHamiltonian, ::SvdCut) compresses infinite Hamiltonians with the almost-Schmidt decomposition of Parker et al., and left_canonicalize!/right_canonicalize! bring an InfiniteMPOHamiltonian into canonical form. (#539)

  • linear_solve/linear_solve! for solving (a₀ + a₁·A)·x = b with finite MPS x and b, using the DMRG-style sweeps DMRGSolve and DMRGSolve2; see linear_solve for details.

  • DynamicalDMRG gained a trunc field for a bond-adaptive propagator; see DynamicalDMRG.

Changed ​

  • left_canonicalize!/right_canonicalize!(::FiniteMPOHamiltonian) now sweep over the whole chain instead of a single site, and return the gauge transformations alongside the operator, matching the infinite versions. (#539)

  • Internal: the finite DMRG/DMRG2 ground-state search and approximation, DynamicalDMRG, multiline IDMRG/IDMRG2 approximation and leading_boundary, and time_evolve now run as iterators whose iterations are a forward and a backward half-sweep (or a single time step), sharing one structure across solvers. Finite TDVP, TDVP2 and BUG steps share a single sweep over per-site local updates, and infinite TDVP steps are split into local update, gauge and environment steps on the same step state. Results and logging are unchanged. (#537)

  • time_evolve with finite TDVP, TDVP2 or BUG, or infinite TDVP, copies (or promotes to complex) the initial state once and then takes every step in place, reusing one step state and its allocator across steps, rather than copying the state at every step. A finalize callback that keeps the state of an earlier step therefore sees it updated by later steps, as with time_evolve!. (#537)

  • propagator/DynamicalDMRG are now implemented on top of linear_solve, which changes the default convergence criterion, tol and local solver; Jeckelmann now throws for real z.

Deprecated ​

Removed ​

Fixed ​

  • convert(TensorMap, H) for single-site FiniteMPOHamiltonians no longer contracts the site tensor with itself. (#252)

  • show methods for finite MPS/MPOs no longer check unit space condition through oneunit, which is not defined for multifusion spaces. (#538)

  • The canonical forms of MPOHamiltonians, and therefore SvdCut compression, are now correct when interactions contain identity components or redundant channels. (#539)

  • InfiniteMPS(C, AR) no longer throws a MethodError, which also fixes infinite TDVP with leftorthflag = false. (#537)

  • Real-time infinite TDVP from a real InfiniteMPS with a real Hamiltonian no longer fails with an InexactError: the environments are now rebuilt for the complex state, as for finite MPS. (#537)

  • TDVP, TDVP2 and BUG promote a real state to complex for imaginary-time evolution with a complex time step, rather than failing. (#537)

Performance ​

0.14.0 - 2026-10-05 ​

Added ​

  • WindowMPOHamiltonian, enabling propagators and dynamical DMRG on WindowMPS. (#417, #447)

  • SketchedExpand for randomized controlled bond expansion in DMRG and TDVP. (#438, #464)

  • DMRG3S for single-site DMRG with subspace expansion and configurable noise schedules. (#460)

  • leftunit/rightunit for MultilineMPS and MultilineMPO. (#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, #460)

  • changebond/changebond! for expanding a single finite-MPS bond in a chosen sweep direction. (#438)

  • A keyword-based approximate(ψ₀, (O, ψ); tol, maxiter, verbosity, trunc) convenience method and sequential approximation algorithms composed with &. (#469)

  • Adapt support for Multiline and PeriodicArray objects, including multiline MPS/MPO networks. (#406)

  • Custom hasconverged and shouldstop callbacks on GradientGrassmann. (#510, #512)

  • DynamicTols.adapt_solver and AdaptiveKrylov for adapting eigensolver tolerances and Krylov budgets to local gradients and truncation errors. (#455)

  • Addition of FiniteMPS/FiniteMPO with different scalar types, through a new Base.similar(ψ, ::Type{S}) for S <: Number on FiniteMPS. (#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). (#470, #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). (#468)

  • A backend setting on every algorithm, for its tensor contractions and index manipulations, defaulting to MPSKit.Defaults.backend(). (#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)

  • 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)

  • *(::MultilineMPO, ::InfiniteMPS), which pushes the boundary MPS through every row of the network in turn, advancing it by one full period. (#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. (#508)

  • InfiniteMultilineMPS/FiniteMultilineMPS and InfiniteMultilineMPO/FiniteMultilineMPO aliases for multiline objects with infinite or finite lines. (#508)

Changed ​

  • Algorithm logging now uses named initialization, iteration, convergence, and non-convergence 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, #512)

  • JordanMPOTensor now stores non-identity blocks and scalar identity contributions separately, with revised type parameters and constructors. (#444)

  • Dependency compatibility now includes OptimKit 0.5 and VectorInterface 0.7; OptimKit 0.3 is no longer supported. (#456, #460, #530)

  • Environment solver settings are forwarded more consistently through VUMPS/VOMPS, lazy sums, and quasiparticle calculations; gauge updates honor the configured orthogonalization algorithm. (#436)

  • Hamiltonian matrix constructors accept AbstractMatrix entries, and similar for MPOs and MPO Hamiltonians also accepts a storage type. (#406)

  • Raised minimum TensorKit and TensorOperations versions to 0.17.1 and 5.6.2, respectively. (#444, #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)

  • find_groundstate(!), leading_boundary, approximate(!), timestep(!) and time_evolve(!) 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. convergence_measure(info) extracts the algorithm-specific stopping measure. (#512)

  • The manual has a new section on Errors and accuracy covering definitions and interpretations of the various returned measures. (#512)

  • Convergence tolerances are now compared with <= everywhere, so an error exactly equal to tol counts as converged for DMRG/DMRG2 in approximate, the IDMRG/IDMRG2 variants of approximate and leading_boundary, and the gauge fixing of InfiniteMPS, as it already did for the other algorithms. (#512)

  • Renormalization during time evolution is now controlled by an explicit normalize keyword on timestep/time_evolve (default false), decoupled from imaginary_evolution. By default the 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). (#438, #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: leftstart/rightstart for finite and window environments, and lenvs/renvs for window and quasiparticle environments. The two-argument form environments(below, above) (with two states) is reserved for the operator-free overlap environments. There is no two-argument environments(below, operator) shorthand: a two-argument call is always the overlap, since the second argument cannot be disambiguated between a ket and an operator (undecidable for density matrices, where states and operators share a representation). (#436)

  • transfer_spectrum now computes the spectrum for all sectors of the transfer space at once, returning a TensorKit.SectorVector that can be indexed per sector. The sector keyword is removed; a specific selection of sectors (with per-sector counts) can be requested by passing howmany as an AbstractDict/iterable of sector => count pairs. The below state and the eigensolver algorithm are optional positional arguments, and the 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. (#452)

  • All trscheme keyword arguments are renamed to trunc (#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)

  • 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. (#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]. (#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 MultilineMPOs was removed. (#508)

Deprecated ​

  • DynamicTols.updatetol(alg, iter, ϵ); use DynamicTols.adapt_solver(alg; iter, g_global = ϵ) instead. (#455)

Removed ​

  • The custom MPSTensor constructors; construct TensorMaps with explicit TensorMapSpaces instead. (#475)

  • JordanMPOTensorMap; use JordanMPOTensor instead. (#444)

  • Support for TimerOutputs 0.5. (#495)

  • expectation_value for a MultilineMPS/MultilineMPO pair entirely, replaced by leading_eigenvalue. (#508)

  • *(::MultilineMPO, ::MultilineMPS) and *(::MultilineMPO, ::MultilineMPO), as these were not meaningful operations. Neither method had ever been callable previously. (#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)

  • GradientGrassmann preconditioning could cease to be a descent direction on nearly rank-deficient bonds; the regularized inverse is now applied in factored form. (#532)

  • variance and Hamiltonian arithmetic now support mixed scalar types; finite-state variance is evaluated using the energy-shifted Hamiltonian to reduce cancellation. (#529)

  • canonicalize! no longer raises a SpaceMismatch for partially decoupled Hamiltonian sites. (#526)

  • Infinite-MPO quasiparticle environments now use the correct bond indices when virtual spaces vary within the unit cell. (#492)

  • remove_orphans! now terminates correctly when infinite-MPO virtual channels stop changing. (#485)

  • periodic_boundary_conditions no longer raises a SpaceMismatch for non-self-dual virtual spaces. (#462)

  • FiniteExcited returns excitations in ascending energy order. (#443)

  • Precomputed bond derivatives now allocate contractions consistently with TensorKit multifusion space checks. (#528)

  • time_evolve logging no longer references an undefined time or passes integer placeholders to floating-point logging methods. (#469, #515)

  • MPO multiplication, physical-charge insertion, and Jordan-tensor scalar conversion preserve GPU storage instead of constructing CPU intermediates. (#406, #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)). (#519)

  • changebonds(::FiniteMPOHamiltonian, ::SvdCut) threw a BoundsError for Hamiltonians with long-range terms. (#519)

  • SvdCut now warns when a truncation empties a bond, instead of silently returning a zero operator. (#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. (#508)

  • size/axes for a CView over a Multiline with finite lines were missing. (#508)

  • excitations(::InfiniteMPO, ::QuasiparticleAnsatz, ::InfiniteQP, lenvs, renvs) referenced H_eff before assigning. (#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₀ instead of ~0. The lazy gauge sweep in CView.getindex re-derived AL/C entries that were already cached, and since different code paths install different factorizations (a truncated SVD from DMRG vs. a positive QR from the sweep) the replacement differed by a bond unitary, so + combined tensors belonging to two different gauges. The same staleness was latent in every consumer that reads several gauge tensors across a center move, dot included. (#473, #484)

  • Addition of single-site operands. FiniteMPS + FiniteMPS asserted length > 1, and FiniteMPO + FiniteMPO threw a space error, because both split the chain into a left and a right block and fuse them at the seam — of which there is none at length 1. Such an operand has no internal bond to fuse, so the sum is now simply the sum of the two tensors. (#484)

  • convert(TensorMap, ::FiniteMPO) on a single-site MPO stripped the left virtual leg of mpo[1] and the right virtual leg of mpo[end] and contracted the two — which at length 1 is the same tensor, so it returned O * O on twice the physical space instead of O. (#484)

  • leading_boundary with IDMRG2 didn't update the left edge of the AC tensor, which could result in space mismatches depending on the truncation scheme. This is corrected for in (#516).

  • Fix hardcoding of number of physical spaces in the changebonds implementations for FiniteMPS, enabling its use for systems with composite physical spaces (#514)

  • Fix density matrix methods with anyonic symmetries through consistency of braid orientation. This affected approximate, DMRG2, and timestep on density matrices for anyonic sector types. (#509)

  • _mpo_to_mps threw a SpaceMismatch when converting a block/Jordan-structured MPO tensor (e.g. from make_time_mpo) into an MPS, since it braided the physical leg directly against a SumSpace virtual leg. It now densifies the tensor first, which the function already did to its return value regardless, so this adds no extra cost. (#509)

  • make_time_mpo with TaylorCluster on a Hamiltonian whose virtual bond dimension varies along the chain are now correctly handled. (#511)

  • The converting constructor of JordanMPO_AC_Hamiltonian assigned the "finished" block E to the "ending" field B whenever B was absent, raising a convert MethodError from deep inside AC_hamiltonian. This is reached when an MPOHamiltonian whose scalartype differs from the state's has an on-site term on a site where no interaction ends, such as a long-range one. (#493)

  • 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 scalartypes) could silently drop data instead of erroring. (#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)

  • leading_boundary with GradientGrassmann ignored the algorithm's hasconverged and shouldstop criteria, always using the optimizer's defaults instead. (#512)

  • isfinite(::MultilineMPO) threw (isfinite(typeof(m)) had no matching type-level method for Multiline). (#508)

  • changebonds(::MultilineMPO, ::SvdCut) threw (convert(MultilineMPS, ::MultilineMPO) has no method). (#508)

  • axes(m::Multiline, i) threw for i > 2, but now returns Base.OneTo(1) for every trailing dimension, matching Base's own convention. (#508)

Performance ​

  • dot on identical FiniteMPS objects uses a norm-based shortcut, also avoiding redundant contractions in expectation values. (#491)

  • Improved two-site effective-Hamiltonian contractions for long-range interactions. (#505)

  • Extended scratch-allocator use to additional derivative contractions and TDVP bond updates. (#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)

  • TDVP2 now performs its two-site split through the shared gauge2! (as two-site DMRG already did), avoiding unnecessary re-orthogonalisation and complexification where applicable). (#517)

0.13.11 - 2026-05-04 ​

Added ​

  • MultilineMPO space getters (#407)

Changed ​

  • Refactored time-evolution MPO construction (#422)

  • Updated TensorKitManifolds compat to 0.8 (#421)

  • Updated MatrixAlgebraKit algorithm specification (#418)

  • Preparations for GPU / non-CPU array support (#375, #392)

  • Generalized calc_galerkin to AbstractMPS (#395)

  • Removed explicit call to InfiniteMPS in VUMPS (#396)

  • Generalized regauge! to AbstractVector (#393)

Fixed ​

  • Various fixes for compatibility with latest TensorKit versions (#416)

  • changebonds inconsistencies (#415)

  • Small fixes for density operators (#409)

  • Tolerance on positivity test (#398)

Performance ​

  • Benchmarks and AC/AC2 contraction improvements (#345)

0.13.10 - 2026-02-26 ​

Added ​

  • expectation_value for local MPO tensors (#327)

  • Base.copy for MPS types now performs a deep copy (#387)

Changed ​

  • entropy can now also be called directly on a spectrum (singular value vector) (#377)

  • Updated compat bounds to remove broken package versions

Fixed ​

  • Fixed Adapt extension for GPU support (#389)

0.13.9 - 2026-02-03 ​

Added ​

  • LocalPreferences.toml file to ensure TensorOperations properly precompiles on testing infrastructure

  • GeometryStyle and OperatorStyle traits for dispatching on finite/infinite geometry and operator types (#352, #354)

  • Base.isfinite methods for MPS types (#347)

  • Bose-Hubbard example (#342)

  • WindowMPS example update (#350)

  • Multifusion category compatibility (#297)

Fixed ​

  • Dynamic tolerances yielded NaN during the initialization stage due to 1 / sqrt(iter) where iter = 0 (#335)

  • InfiniteMPOHamiltonian environments with low bond dimension and high Krylov dimension now are properly clamped (#335)

  • Logical operator precedence in getproperty function (#346)

  • Typo in VUMPSSvdCut (#361)

  • Typo in time formatting for logs (#336)

  • Domain/codomain of MPODerivativeOperator (#370)

  • In-place operations handled more carefully (#337)

  • Orthogonalization algorithms now use correct methods (#373)

Changed ​

  • The changebonds(state, ::RandExpand) algorithm now no longer has to perform a truncated SVD to obtain the desired spaces, and instead sample the space directly and then generates a random isometry. This should be slightly more performant, but otherwise equivalent (#335)

  • IDMRG refactored to follow the IterativeSolver interface and share code between IDMRG and IDMRG2 (#348)

  • Bumped compatibility for TensorKit 0.16 and MatrixAlgebraKit 0.6 (#365)

  • Removed _left_orth and _right_orth workarounds in favor of new orthogonalization methods

  • Reduced allocation while computing Galerkin error (#366)

  • Updated show methods to reflect new TensorKit printing (#341)

  • More informative errors for finite MPS (#367)

  • Minor documentation and docstring improvements (#363, #372, #371)

Deprecated ​

Removed ​

0.13.8 - 2024-10-31 ​

See full history and previous releases on GitHub.