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.
  • Performance for performance improvements.

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

Unreleased

Added

  • Enzyme rules for planartrace!, with a pullback that also supports adjoint tensors
  • twist(src, inds; inv = false) for fusion tree pairs and blocks, returning src together with the scalar twist factor of the legs inds, which can be given as indices or as a Bool mask
  • twist!(tdst, tsrc, inds, α = 1, β = 0, [backend], [allocator]; inv = false) computing tdst = β * tdst + α * twist(tsrc, inds; inv), in line with permute! and braid!, together with Mooncake and Enzyme rules; twist now also accepts backend and allocator keywords

Changed

  • planartrace! precomputes and caches a TraceTransformer with the subblock positions and recoupling coefficients, and executes it with a kernel shared by all sectortypes, analogous to the index manipulations; planar_trace is now also defined for FusionTreeBlocks, and GPU tensors use a dedicated kernel (internal)

Deprecated

Removed

Fixed

Performance

  • twist! and twist on a TensorMap, a DiagonalTensorMap or their adjoints use a cached tree transformer and the index manipulation kernel instead of a loop over all fusion trees, which removes the per-subblock bookkeeping and turns a twist of a GPU tensor, diagonal or not, into a single kernel launch (#595)

0.17.3 - 2026-10-30

Added

  • Batched SVD: svd_full, svd_compact and svd_vals now hand all blocks at once to MatrixAlgebraKit's ragged-batch drivers whenever the algorithm, driver and storage type support it, e.g. for GPU-backed tensors (#567)
  • Enzyme forward and reverse rules for factorizations (qr, lq, eig, eigh, svd, polar decompositions, and project_hermitian/project_antihermitian), including pushforward and pullback for svd_vals, with tests (#464)
  • Enzyme forward rules for permute, transpose and braid (#573)
  • ChainRules rule for TensorMap(::DiagonalTensorMap) (#553)
  • Re-export NamedSector and @NamedSector from TensorKitSectors (#566)
  • Support for MatrixAlgebraKit's TruncationMultiplets strategy, exported as truncmultiplets, which avoids truncating within multiplets of degenerate values, also when they are spread across different blocks (#602)
  • Precompilation workloads now cover planar contractions and traces for sector types without symmetric braiding, index manipulations of AdjointTensorMaps, and the remaining factorization entry points (#557, #558)
  • The test suite runs JET's package analysis on Julia 1.12 and later (#570)

Changed

  • Extend VectorInterface compat to include v0.7 (#560)
  • Require TensorKitSectors v0.3.10 (#566)
  • Require MatrixAlgebraKit v0.6.13 (#602)
  • norm accepts scalar types that are not subtypes of Real (#576)
  • @cached can be used from other modules, such as package extensions, which then own the cache of the methods they add; these caches are shown with their module in global_cache_info after registration in __init__ (internal) (#556)
  • The TreeTransformers used in index manipulations are now constructed and cached per storagetype of the destination tensor, which is also a dispatch point for storage-specific transformers with their own cache (internal) (#556)
  • The Enzyme extension drops rules that Enzyme derives correctly by itself, marks the fusion tree transformer constructors as inactive, and respects runtime-inactive arguments in the blas_contract! rule (#575, #574, #590)

Deprecated

Removed

  • The DefaultAlgorithm forwarding for schur_full and schur_vals, which have no tensor implementation (#570)

Fixed

  • norm(t, Inf) and normalize!(t, Inf) no longer rely on scalar indexing, so they work for GPU-backed tensors (#586)
  • Fixed the promote_storagetype call in the planar preprocessor (#577)
  • @planar with an explicit order, the _extract_contraction_pairs error message, a nonexistent DimensionError thrown in linalg.jl and malformed MethodErrors in the numout/numin fallbacks: fixed various errors on untested paths reported by JET (#570)
  • Restored the custom Enzyme rule for twist, as Enzyme's own derivation segfaults on Julia 1.10 (#559)
  • The Enzyme rules for permute and transpose no longer alias the input when the permutation is trivial, such that all Enzyme rules also work on Julia 1.10 (#579)
  • Documentation build failing on TensorKitSectors doctests (#566)

Performance

  • add_transform! for GPU-backed tensors is reimplemented as KernelAbstractions kernels that parallelize over the output data instead of over fusion tree blocks, for Abelian and general symmetries, making index manipulations of symmetric tensors on the GPU orders of magnitude faster (#533, #509)
  • Constructing a FusionTreeBlock only takes the fusion product of the shorter side, and fusionblocks groups the cached fusion trees of the space instead of constructing a block for every combination of sectors (internal) (#581)
  • Recoupling matrices are stored such that they can leverage BLAS, also for mixed complex tensor with real recoupling coefficients (#556)
  • Fusion tree block manipulations of (named) product sectors are computed as Kronecker products of the manipulations of their parts, splitting off the UniqueFusion sectors, such that they share the caches of the individual sectors (#592)
  • The TensorOperations ChainRules rules no longer copy or retain C when β = Zero(), as is the case for every tensor allocated by @tensor (#555)
  • The Enzyme norm rule reuses the cached primal and the tr rule avoids an unnecessary copy (#554)

0.17.2 - 2026-09-20

Added

  • Precompilation workloads for common tensor construction, contraction, index manipulation, and factorization patterns, to reduce time-to-first-use (#487)
  • TimerOutputs-based timers for internal kernels, and documentation for the global cache API, to aid profiling and debugging (#525, #507)
  • Enzyme forward/reverse rules for flip, insertleftunit, insertrightunit, and removeunit, and for planar operations (#488, #489, #474)
  • planarcontract! now supports an arbitrary (cyclic) output permutation pAB, in the same way as the non-planar tensorcontract!, along with the new helper TensorKit.planar_contract_indices, which @planar uses to emit canonical index tuples. (#531)

Changed

  • For sector types with GenericUnit such that colorings are not unique, GradedSpace, ProductSpace and HomSpace now check for this compatibility. In particular, this prevents the construction of TensorMaps with incompatible colorings, which previously either errored or produced empty tensors inconsistently. (#515)
  • TensorOperations.tensorcontract_structure now requires the index tuples pA and pB to be planar (cyclic) partitions for sector types with GenericUnit(); hand-written planar kernels should canonicalize their index tuples with TensorKit.planar_contract_indices before allocating. (#531)
  • The allocator is now threaded through transpose! in planar operations and through additional @planar call sites (#502, #529)
  • Index manipulations use a single kernel operating on subblocks addressed by position: StridedSubblocks (sector-independent views into the flat data of a TensorMap) or SubblockIterator (any AbstractTensorMap, through subblock). The TreeTransformers store the mapping between subblock positions and recoupling coefficients and are cached for every tensor type; conjugated and adjoint operands are handled through this mechanism instead of through AdjointTensorMap wrappers (internal) (#516)

Deprecated

  • The type alias ZNSpace{N} is deprecated in favour of Vect[ZNIrrep{N}] or Rep[ℤ{N}]: a type alias cannot compute the storage type from N, so the two only agree for small N. (#511)

Removed

Fixed

  • Fixed bugs in the GradedSpace constructor and in similar for SectorVector (#498)
  • braid for anyonic sectors no longer silently accepts duplicate levels (#503)
  • Fixed backend and allocator insertion in the @planar macro (#505)
  • permute and transpose ChainRules rules now support all keyword arguments (#513)
  • Added a hash method for FusionTreeBlock to fix a caching bug affecting permute on AdjointTensorMaps (#518)
  • @planar and hand-written planar kernels now canonicalize index partitions before allocating the contraction destination, fixing incorrect/erroring allocation for non-planar pAB, for @planar contractions whose leg-wise partitions are non-planar by themselves, and for contracting operands with different spacetypes (e.g. a BlockTensorMap with a TensorMap) (#532)
  • braid!, permute! and transpose! with a BraidingTensor source now use the cached fusion tree transformers (#516)
  • Made the ChainRules extension's rules consistent with the corresponding Mooncake and Enzyme rules (#535)
  • isunitspace, GradedSpace ⊕/supremum, isconj(::ComplexSpace), multi_associator, split, repartition, the Mooncake scalar rule, rand/randn/randexp/randisometry with an explicit rng, pinv(::DiagonalTensorMap), and t1 / t2: fixed various small bugs found during a pre-release audit (#537, #538, #539, #540, #541, #542, #543, #544, #545, #546)

Performance

  • GradedSpace operations (dim, flip, ⊕, ⊖, fuse, infimum, supremum, truncation) are now specialised on the storage type of the degeneracy dimensions, and tuple storage is used only for sector types with at most TensorKit._NTUPLE_STORAGE_THRESHOLD sectors so that sector types with many sectors no longer burden the compiler. (#511)
  • Fixed a performance regression for non-abelian index manipulations, and reduced memory usage of twist (#521, #501)
  • More error strings marked as lazy to reduce runtime overhead in non-error paths (#492)
  • Use vector multiplication instead of an explicit loop for truncation error computation (#443)
  • In-place permute!, braid! and transpose! with AdjointTensorMap sources or destinations, as well as @tensor expressions with conj, now use the same cached and sector-independent kernel as plain TensorMaps; other tensor types (e.g. DiagonalTensorMap) also use the cached fusion tree transformers, and subblocks iterates without repeating any space-level lookup (#516, #519, #520)

0.17.1 - 2026-07-13

Added

  • Enzyme AD support: forward and reverse rules (with tests) for TensorOperations contractions, linear algebra, and VectorInterface operations, and reverse rules for index manipulations (#436, #437, #440, #449, #451, #466)
  • exponential and exponential! for the matrix exponential of tensors (#465)
  • Docstrings for catdomain and catcodomain (#485)

Changed

  • Consolidated duplicated GPU logic into a new GPUArrays extension (#460)
  • Removed explicit dependence on cuTENSOR for the CUDA extension; importing cuTENSOR is still recommended for best performance, as it enables the corresponding TensorOperations extension (#455)
  • Improved DimensionMismatch error message in the TensorMap constructor (#456)

Fixed

  • Added missing zero-derivatives and an in-place rrule test for svd_trunc (#448)

Performance

  • Reduced overhead in the TensorMap constructor and in sectorequal/sectorhash for trivial symmetries (#476)
  • Further trivial-symmetry improvements and reduced respecialization for contract! (#479)
  • Fast path for trivial tensors into the TensorOperations machinery (#463)
  • Marked more error strings as lazy to reduce runtime overhead (#478)

0.17.0 - 2026-06-03

Added

  • Allow BraidingTensor to have a custom storage type (#393)
  • remove_gauge_dependence! overloads (#419)
  • Mooncake forward rules for linear algebra functions (#434)
  • Support for broadcasting and mapping over HomSpace and ProductSpace, where broadcasting over ProductSpace now returns a tuple (#430, #431)

Changed

  • Reworked the index manipulation API, adding backend and allocator support while uniformizing the API, with accompanying documentation (#416, #438)
  • Bumped minimum version of CUDA and cuTENSOR (#404)

Fixed

  • Correct Artin braid image (#441)
  • Fix cache miss due to ignored dual flag in foldright (#442)
  • Improvements to bypass scalar indexing and improve GPU support (#375)
  • Compatibility with SUNRepresentations v0.4 type parameter change (#426)

0.16.5 - 2026-05-01

Added

  • Implement DefaultAlgorithm support (#422)

Fixed

  • BraidingTensor planarcontract! fixes (#418)
  • Fix checksquare error message (#417)

0.16.4 - 2026-04-23

Added

  • Partial tensor support for AMDGPU via a new extension (#341)
  • Define spacetype for TruncationSpace (#403)

Changed

  • Updated MatrixAlgebraKit dependency to v0.6.5 with corresponding API updates (#390)

Fixed

  • Fix ignored adjoint flag in BraidingTensor (#392)
  • Fix MethodError for certain tensor operations (#406)
  • Add square checks for project_(anti)hermitian and eigenvalue decompositions (#408)

Performance

  • Vectorize fusiontree manipulations (#261)
  • Avoid generic matmul fallback in transformation kernel (#378)
  • Reduce cache footprint by decoupling degeneracy-dependent data (#387)

0.16.3 - 2026-02-22

Added

  • Expanded set of Mooncake AD rules (#356)
  • Adapt support for BraidingTensor (#374)

Changed

  • Documentation improvements and updates (#345)

Fixed

  • Small fixes for upstream compatibility and CUDA support, including Base.ones/zeros accepting CuArray (#373)

0.16.2 - 2026-02-10

Added

  • A more robust promotion system for storagetypes to better handle working with unions and other abstract tensor map types (#370).

Fixed

  • Fix findtruncated with truncspace (#369)
  • Fix truncrank when kept rank is larger than input (#368)
  • Added missing similar definition for SectorVector (#367)
  • Small fixes for CUDA support (#366)

0.16.1 - 2026-02-05

Added

  • Extended support for selecting storage types in the TensorMap constructors (#327)
  • similar_diagonal to handle storage types when constructing diagonals (#330)
  • Support for CUDA.jl (#336,#325)
  • Support for Adapt.jl (#344)
  • Preliminary support for Mooncake (#352)
  • Export TimeReversed symbol (#337)

Fixed

  • Issue with using relative tolerances in truncation schemes (#314)
  • Using scalartype instead of eltype in BLAS contraction (#326)
  • Divide by zero error in show for empty tensors (#329)
  • svd_vals(::DiagonalTensorMap) correctly outputs SectorVector and implementation fix. (#333)
  • Fix handling of real tensors with complex scalartype (#360)
  • Sorted diagonal eigenvalues to ensure consistent ordering (#350)
  • Adding tensors of different types now correctly promotes (#364)

Changed

  • convert(TensorMap, t) now retains storagetype when converting (#357)
  • transpose specialization for DiagonalTensorMap for improved correctness/performance (#335)
  • Uniformized CartesianSpace and ComplexSpace constructors (#334)

Performance

  • GPU-friendly truncation implementations (#349)
  • norm performance optimizations (#351)
  • TensorOperations ChainRules performance improvements (#343)
  • Type-stability and small test fixes (various commits)

0.16.0 - 2025-12-08

Added

  • rrule for transpose operation (#319)
  • New functions for multifusion support: unitspace, zerospace, leftunitspace, rightunitspace, isunitspace (#291)
  • Support for projections and orthogonal complements (#312)

Changed

  • Improvements to the default printing of tensors, where only a (possibly compressed) representation of the (possibly truncated) list of diagonal blocks is printed. Use blocks(t) and subblocks(t) for a full inspection of the tensor data (#304, #322))
  • Updated left_orth, right_orth, left_null and right_null interfaces for MatrixAlgebraKit v0.6 (#312)
  • Updated ishermitian and isisometric implementations (#312)
  • Sector functions now by default use unit instead of one, isunit instead of isone, and dual instead of conj (#291)
  • Reworked TensorOperations implementation to use backend and allocator system (#311)
  • Major documentation update/overhaul (#289)
  • Added symmetric tensor tutorial as appendix (#316)
  • Improved error messages throughout codebase (#309)
  • eigvals and svdvals now output SectorVector objects, which do behave as AbstractVector but also have the option of iterating the blocks through Base.pairs. (#324

Deprecated

Removed

  • All deprecations from v0.15: old factorization function names (leftorth, rightorth, tsvd, eig, eigh)
  • Old truncation strategy names (truncdim, truncbelow)
  • Old factorization struct types (OrthogonalFactorization)
  • Old constructor syntaxes and deprecated rand* function names

Fixed

  • Avoid unnecessary copy in twist for tensors with bosonic braiding (#305)
  • Small fixes and typos (#295)
  • eig_vals, svd_vals, etc now all output SectorVector objects instead of DiagonalTensorMaps, in line with how MatrixAlgebraKit returns Vectors instead of Diagonals (#324

0.15.3 - 2025-10-30

Fixed

  • Fixed typo in show(::GradedSpace) (#308)
  • Updated printing of ProductSpace{<:Any,0}
  • Added tests for show methods

0.15.2 - 2025-10-28

Added

  • subblocks iterator for easier inspection of tensor data (#304)

Changed

  • Tensors no longer print their data by default, only their spaces. Use blocks(t) or subblocks(t) to inspect data (#304)
  • Updated compatibility to TensorKitSectors v0.3 (#290)
  • Refactored test suite and split into groups (#298)

Fixed

  • Fixed TruncationIntersection implementation and test (#300)
  • Avoided unnecessary allocations in rrules for contractions and tensor products (#306)

0.15.1 - 2025-10-09

Fixed

  • Small fixes and typo corrections (#295)

0.15.0 - 2025-10-03

Added

  • MatrixAlgebraKit as new backend for tensor factorizations (#230)
  • foreachblock(f, t::AbstractTensorMap...) - uniform interface to iterate through tensor blocks
  • eig_trunc and eigh_trunc - truncated eigenvalue decompositions
  • ominus (and unicode ⊖) - compute orthogonal complement of a space
  • Backend selection for factorizations - swap algorithms or implementations

Changed

  • left_orth and right_orth now always output tensors with a single connecting space
  • left_orth and right_orth now always have connecting space with isdual=false
  • Code formatter is now Runic.jl

Deprecated

  • Factorization functions leftorth, rightorth, tsvd, eig, eigh in favor of MatrixAlgebraKit variants (left_orth, right_orth, svd_compact, eig_full, eigh_full)
  • Truncation strategies: truncdim (use truncrank) and truncbelow (use trunctol)
  • OrthogonalFactorization structs (constructors deprecated to return equivalent MatrixAlgebraKit algorithm structs)

Removed

  • Direct permute-and-factorize operations (incompatible with permute vs braid distinction)
  • Polar decomposition behavior for left_orth/right_orth (use left_polar/right_polar instead for isposdef R factors)

0.14.0 - 2024-12-19

Added

  • DiagonalTensorMap type for representing tensor maps with diagonal blocks
  • reduceddim(V) function that sums up degeneracy dimensions for each sector
  • New index manipulation functions:
    • flip(t, i)
    • insertleftunit(t, i)
    • insertrightunit(t, i)
    • removeunit(t, i)

Changed

  • Singular values and eigenvalues now explicitly represented as DiagonalTensorMap instances
  • SVD truncation now guarantees smaller singular values are removed first, irrespective of sector quantum dimension

0.13.0 - 2024-11-24

Added

  • Refactored TensorMap constructors to align with Julia Array constructors
  • Convenience constructors: ones, zeros, rand, randn for tensors
  • TensorOperations v5 support

Changed

  • Scalar type as parameter to AbstractTensorMap type: AbstractTensorMap{E, S, N₁, N₂}
  • Default way to create uninitialized tensors is now TensorMap{E}(undef, codomain ← domain)
  • Behavior of copy for BraidingTensor to properly instantiate a TensorMap
  • TensorKitSectors promoted to separate package
  • TensorMap data structure now consists of single vector with blocks as views
  • FusionTree vertices now only use Int labels for GenericFusion sectors