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.

[Unreleased]#

Deprecated#

  • Deprecated the ignored atol and eps arguments of direct_greens_function. They will be removed in version 2.4.0.

  • Deprecated solver_options["atol"] and solver_options["eps"] for the implicit direct solver. They will be removed in version 2.4.0.

  • Deprecated the legacy one-argument custom Sylvester callback form solve_sylvester(Y). Use solve_sylvester(Y, index) instead. The legacy form will be removed in version 2.4.0.

Changed#

  • Raised minimum versions to Python 3.12, NumPy 2.2, SciPy 1.15, and SymPy 1.14 following the September 2026 SPEC 0 support window.

  • Reworked the implicit direct solver to constrain known degenerate kernels using QR-selected pivot equations instead of relying on MUMPS singularity detection, and added a SciPy sparse-LU fallback when python-mumps is unavailable.

  • Reduced the number of matrix products in selective Hermitian diagonalization by evaluating the selected auxiliary directly, and in non-Hermitian diagonalization by exploiting the selected structure of the transformed residual.

Fixed#

  • Fixed implicit projectors on SciPy 1.18 by initializing the LinearOperator base class.

  • Fixed the Andreev supercurrent tutorial’s fermionic matrix conversion for SymPy 1.14.

  • Fixed chained and nested custom-algorithm division failing on the zero sentinel by recursively transforming division operands.

  • Fixed nested custom-algorithm callbacks receiving missing or duplicated indices, including diagonal wrappers around off-diagonal expressions.

  • Fixed KPM Green’s functions with small moment budgets; positive integer budgets produce an approximation and invalid budgets raise a clear error.

  • Fixed Cauchy products for BlockSeries with no perturbation dimensions; these now reduce to ordinary block-matrix products.

  • Fixed second-quantized immutable and sparse SymPy matrices falling through input conversion and producing a misleading error.

  • Fixed symbolic dictionary input with the documented Python integer constant key 1, without mutating the input mapping.

  • Fixed one-block custom Sylvester solvers accessing uninitialized diagonal information during automatic full diagonalization.

  • Made numerical Sylvester degeneracy checks use the supplied absolute tolerance, independent of the common energy offset.

  • Made hashes of equal NumberOrderedForm expressions independent of unused operators and stored term order, restoring set and dictionary lookup. Cache the expression hash and avoid repeated sum construction during conversion.

  • Stopped simplifying inverse and sign-unknown powers of fermion and spin number operators using the positive-power idempotence rule.

  • Fixed MUMPS silently treating real nonsymmetric matrices as symmetric in direct Green’s functions.

  • Fixed direct Green’s functions with distinct left and right nullspaces by selecting redundant equations and constrained coordinates independently.

  • Fixed non-Hermitian second-quantized diagonalization discarding asymmetric couplings by solving the full Sylvester equation.

  • Reject invalid powers of unmatched operators in NumberOrderedForm immediately; non-negative integer powers and existing positive symbolic bosonic masks remain supported.

  • Fixed multiplication of NumberOrderedForm by Python scalar numbers on the right.

  • Fixed multi-block KPM failing when no explicit solver tolerance is supplied.

  • Fixed second-quantized Sylvester equations with zero diagonal blocks, including rectangular right-hand sides.

  • Corrected the KPM auxiliary-vector option to auxiliary_vectors throughout documentation and tests, and verified that auxiliary vectors are used.

  • Corrected the number-operator shifts in the documented boson and ladder multiplication rules.

  • Fixed division by zero in fermion and spin Sylvester equations when both the right-hand side and the energy difference vanish.

  • Fixed incorrect number-dependent coefficients in products of fermion and spin operators.

  • Fixed extra minus signs in products containing annihilation operators for multiple fermion modes.

  • Fixed incorrect shifts of number-dependent coefficients when multiplying boson and ladder expressions by creation operators.

  • Fixed nondeterministic perturbation indices for SymPy input without explicit symbols by sorting inferred symbols by name.

  • Reject distinct symbols with the same name and different assumptions in symbolic input, including when symbols is supplied explicitly.

  • Fixed BlockSeries accepting negative perturbative orders, which now raise IndexError instead of potentially returning an incorrect term.

  • Made randomized tests reproducible with pytest-randomly without using NumPy’s legacy global random number generator.

Added#

  • Added a non-Hermitian similarity-transform algorithm via block_diagonalize(..., hermitian=False), including support for asymmetric selective masks, symbolic inputs, and biorthogonal subspace_eigenvectors=[(right, left), ...] in the explicit and implicit direct paths. The implicit KPM solver remains unsupported in the non-Hermitian path.

[2.2.1] - 2026-03-09#

Changed#

  • Made python-mumps an optional dependency, only required for the implicit solver.

  • When SymPy cannot determine whether an off-diagonal zeroth-order block is zero, emit a warning and proceed instead of erroring.

Removed#

  • Dropped support for Python 3.11, numpy 1.26, and scipy 1.12 according to the SPEC-0.

[2.2.0] - 2025-06-05#

Added#

  • Added a reference implementation of arbitrary order Schrieffer-Wolff transformation to the documentation and a comparison of its convergence radius with Pymablock algorithm.

  • Added support for bosonic, fermionic, spin, and ladder (Floquet) second-quantized Hamiltonians in the operator formalism.

  • Added a tutorial on the Rabi model with a periodic drive.

  • Added documentation for the second quantization formalism.

  • Added a comparison with Schrieffer-Wolff and a demonstration of the convergence radius.

Changed#

  • If the Hamiltonian contains only one block, fully_diagonalize can be provided as value instead of {0: value}.

  • Updated the dispersive shift tutorial to include the second quantization approach.

  • Updated the Jaynes-Cummings tutorial to the new second quantization API.

Removed#

  • Dropped support for Numpy 1.25, Scipy 1.11, and Sympy 1.12 according to the SPEC-0.

[2.1.0] - 2024-11-19#

Added#

  • Generalized the algorithm to support an arbitrary number of blocks. To specify multiple blocks, provide either a list with eigenvectors of each block in subspace_eigenvectors, or a list marking to which block each basis state belongs in subspace_indices.

  • Implemented full diagonalization of the Hamiltonian within blocks except for degenerate eigensubspaces. In case of one block with non-degenerate eigenvalues, this implements the Rayleigh-Schrödinger perturbation theory.

  • Implemented selective diagonalization of the Hamiltonian within blocks, which can eliminate any subset of the off-diagonal elements within a block.

  • Implemented functionality for making optimized series algorithms, see series_computation and a domain-specific language to define those. This is an advanced and an experimental feature, subject to change.

  • Added a function operator_to_BlockSeries to transform operators to the same representation as the Hamiltonian, and illustrated its use in the tutorial.

  • Included a tutorial on how to manipulate complex symbolic Hamiltonians and demonstrate multi-block diagonalization.

  • Included a tutorial on how to compute the dispersive shift in a transmon-resonator system.

Changed#

  • Auxiliary vectors for the implicit KPM solver should now be passed using solver_options["auxiliary_vectors"] rather than as the last entry in subspace_eigenvectors.

  • Further reduced the number of matrix products by around 30% for high orders and down to a guaranteed minimum for 3rd order.

  • Improved the efficiency of the MUMPS solver on real Hamiltonians.

  • Allowed subspaces to have degenerate eigenvalues if the corresponding energy denominators are never used. This may happen in multiblock perturbation theory.

Fixed#

  • Fix incorrect shape of BlockSeries blocks if \(H_0\) has a zero block (#127).

Removed#

  • Dropped support for Python 3.10 and sympy 1.11 according to the SPEC-0.

[2.0.0] - 2024-02-03#

Changed#

  • Switched to the python-mumps wrapper for the direct solver, which is available on all platforms and is more feature-complete.

  • The implicit KPM solver now guarantees reaching a requested accuracy.

  • A new algorithm that has optimal scaling while avoiding multiplication by \(H_0\), and supports implicit data. This combines advantages of all previous algorithms, and therefore supersedes them.

  • Sped up cauchy_dot_product when there are more than 3 series by reusing intermediate results.

  • Optimized memory usage of ~pymablock.block_diagonalize by deleting intermediate results when they are no longer needed.

Added#

  • A complete description of the algorithm to the documentation, see documentation.

  • String representation of BlockSeries for readability.

Removed#

  • expanded, symbolic, implicit, and general functions and algorithms (functionality taken over by the new general algorithm, with block_diagonalize the main interface).

  • the algorithm argument from block_diagonalize (there is only one algorithm now).

  • exclude_last argument of cauchy_dot_product (instead we check whtether other terms lack 0th order).

[1.0.0] - 2023-06-05#

  • First release of Pymablock.