API Reference
Main Functions
Schrieffer-Wolff Transformation
UnitaryTransformations.schrieffer_wolff — Function
schrieffer_wolff(H::QuExpr, P::Subspace; order::Int=2)Perform the Schrieffer-Wolff transformation on Hamiltonian H with respect to the low-energy subspace P.
The transformation finds a unitary U = e^S such that H_eff = e^S H e^{-S} is block-diagonal with respect to P and Q = 1-P, up to the specified order in perturbation theory.
Arguments
H: The full Hamiltonian to transformP: The low-energy subspace definitionorder: Perturbation theory order in the coupling strength (default: 2).- order=2: Standard SW, captures g² corrections (dispersive shifts)
- order=4: Includes g⁴ corrections (Kerr nonlinearity, Bloch-Siegert, etc.)
simplify_generator: Whether to simplify the generator S (default: false). Simplifying S can be slow at high orders. Set totrueif you need simplified S.simplify_mode: Simplification mode for final output (default::fast).:none- No simplification (fastest):fast- Expansion only (default, very fast, recommended):standard- Basic algebraic simplification with expansion:fractions- Simplify fractions with GCD (slow on complex expressions):aggressive- Full simplification (slowest)
diagonal_only: If true, only compute H_eff (skip computing higher-order generators). This is much faster for high orders when you only need the effective Hamiltonian. Note: This uses a simplified algorithm that only uses S₁.parallel: If true, use multi-threading for orders > 3 (default: false). Requires Julia to be started with multiple threads (e.g.,julia -t 4). For best performance, use 4-8 threads; more threads can cause lock contention. Parallelization is most beneficial for orders 4-6 with complex Hamiltonians.
Returns
- Named tuple
(H_eff, S, H_P)where:H_eff: The full block-diagonal effective HamiltonianS: The generator of the transformation (S = S₁ + S₂ + ... where Sₙ is O(gⁿ)) Note: Ifdiagonal_only=true, S contains only S₁.H_P: The effective Hamiltonian projected onto subspace P
Algorithm
The SW transformation uses S = S₁ + S₂ + S₃ + ... where each Sₙ is order gⁿ. At each order, the off-diagonal terms from the BCH expansion determine Sₙ, and the diagonal terms contribute to H_eff.
Key commutator rules (D=diagonal, O=off-diagonal):
- [O, O] → D
- [O, D] → O
- [D, D] → D
Example
using QuantumAlgebra, UnitaryTransformations, Symbolics
# Jaynes-Cummings in dispersive regime
@variables ω Δ g # ω = cavity frequency, Δ = qubit splitting, g = coupling strength
H = ω * a'()*a() + Δ/2 * σz() + g * (a'()*σm() + a()*σp())
# Transform to eliminate qubit-photon coupling
P = Subspace(σz() => -1) # qubit ground state
result = schrieffer_wolff(H, P; order=2)
# For 4th order corrections (Kerr effect, etc.) - parallel computation
result4 = schrieffer_wolff(H, P; order=4, parallel=true)schrieffer_wolff(H::SymExpr, P::Subspace; order::Int=2, ...)Perform the Schrieffer-Wolff transformation on a Hamiltonian expressed with symbolic sums (SymExpr).
This extends the standard SW transformation to handle Hamiltonians like the Tavis-Cummings model:
H = ω_c a†a + Σᵢ (Δ/2)σz(i) + Σᵢ g(a†σ⁻(i) + aσ⁺(i))The key capability is correct handling of:
- Same-site contributions: Σᵢ [Aᵢ, Bᵢ]
- Cross-site contributions: Σᵢ Σⱼ≠ᵢ [Aᵢ, Bⱼ] (exchange interactions)
Arguments
Same as the schrieffer_wolff(H::QuExpr, ...) method.
Returns
- Named tuple
(H_eff, S, H_P)where H_eff and S may be SymExpr types.
Example
using QuantumAlgebra, UnitaryTransformations, Symbolics
import QuantumAlgebra: sumindex, SymSum, SymExpr
@variables ω_c Δ g
i = sumindex(1)
H = SymExpr(ω_c * a'()*a()) +
SymSum(Δ/2 * σz(i), i) +
SymSum(g * (a'()*σm(i) + a()*σp(i)), i)
P = Subspace(a'()*a() => 0) # Zero photon sector
result = schrieffer_wolff(H, P; order=2)Notes
- Currently only supports order=2 for SymExpr inputs
- The effective Hamiltonian includes both same-site and cross-site terms
- For higher orders, expand the SymSum to explicit indices first
schrieffer_wolff(H::SymSum, P::Subspace; order::Int=2, ...)Convenience method: wrap a single SymSum in a SymExpr and call the main method.
UnitaryTransformations.sw_generator — Function
sw_generator(H::QuExpr, P::Subspace; order::Int=1)Compute only the generator S for the Schrieffer-Wolff transformation, without computing the full effective Hamiltonian.
This is useful when you only need S, or want to manually compute the transformation using bch_transform.
Magnus Expansion (Floquet Systems)
UnitaryTransformations.magnus_expansion — Function
magnus_expansion(H::FourierHamiltonian; order::Int=2, check_hermitian::Bool=true)Compute the Magnus expansion for a periodically driven system to arbitrary order.
Arguments
H: AFourierHamiltonianrepresenting H(t) = Σₙ Hₙ e^{inωt}order: Maximum order of the expansion (default: 2, no upper limit)check_hermitian: Whether to verify H is Hermitian (default: true)
Returns
A MagnusResult containing:
H_eff: The effective time-independent Hamiltonianorders: Dict mapping order k to ΩₖΩ1,Ω2, ...: Direct access to individual contributions
Example
using QuantumAlgebra, UnitaryTransformations, Symbolics
QuantumAlgebra.use_σpm(true)
@variables Δ Ω ω
modes = Dict(0 => Δ/2*σz(), 1 => Ω/2*σp(), -1 => Ω/2*σm())
result = magnus_expansion(modes, ω; order=5)
println("Order 5: ", result.Ω5)UnitaryTransformations.FourierHamiltonian — Type
FourierHamiltonianRepresents a time-periodic Hamiltonian in Fourier representation: H(t) = Σₙ Hₙ e^{inωt}
The modes are stored as a Dict{Int, QuExpr} mapping Fourier index n to operator Hₙ.
For Hermiticity, we require H₋ₙ = Hₙ†.
UnitaryTransformations.check_hermiticity — Function
check_hermiticity(H::FourierHamiltonian; warn_only::Bool=false)Check that the Fourier Hamiltonian satisfies H₋ₙ = Hₙ† for all modes.
Returns true if Hermitian, throws an error otherwise.
UnitaryTransformations.MagnusResult — Type
MagnusResultResult type for Magnus expansion containing H_eff and individual order contributions.
Subspace Definition
UnitaryTransformations.Subspace — Type
Subspace(constraints...)Define a low-energy subspace P by specifying constraints on operators.
Examples
# Spin-down subspace
P = Subspace(σz() => -1)
# Vacuum subspace (zero bosons)
P = Subspace(a'()*a() => 0)
# Product state: spin-down AND zero bosons
P = Subspace(σz() => -1, a'()*a() => 0)
# Indexed systems
P = Subspace(σz(:i) => -1) # All spins downUnitaryTransformations.OperatorConstraint — Type
OperatorConstraintA single constraint defining a sector: an operator and its eigenvalue in that sector.
Hamiltonian Decomposition
UnitaryTransformations.decompose — Function
decompose(H::QuExpr, P::Subspace)Decompose H into diagonal and off-diagonal parts with respect to subspace P.
Returns (Hd, Hod) where:
- H_d is the block-diagonal part
- H_od is the off-block-diagonal part
- H = Hd + Hod
decompose(s::SymSum, P::Subspace)Decompose a symbolic sum into diagonal and off-diagonal parts. The decomposition is applied to the inner expression of the sum.
Returns (SymSumd, SymSumod) where both are SymSum with the same index.
decompose(s::SymProd, P::Subspace)Decompose a symbolic product. Products are generally treated as off-diagonal unless explicitly simplified.
decompose(e::SymExpr, P::Subspace)Decompose a symbolic expression containing sums, products, and regular terms. Returns (SymExprd, SymExprod).
UnitaryTransformations.diagonal_part — Function
diagonal_part(H::QuExpr, P::Subspace)Extract the block-diagonal part of H with respect to subspace P. This includes terms that preserve P (P·H·P) and terms that preserve Q (Q·H·Q).
Note: Terms classified as MIXED (like σx when not using σpm mode) are skipped. For proper handling, ensure Hamiltonians are expressed in the σ± basis.
diagonal_part(s::SymSum, P::Subspace)Extract the diagonal part of a symbolic sum.
diagonal_part(e::SymExpr, P::Subspace)Extract the diagonal part of a symbolic expression.
UnitaryTransformations.off_diagonal_part — Function
off_diagonal_part(H::QuExpr, P::Subspace)Extract the off-block-diagonal part of H with respect to subspace P. This includes terms that couple P to Q (P·H·Q + Q·H·P).
Note: MIXED terms (like σx in σz basis, or off-diagonal Lie algebra generators) are included in the off-diagonal part since they contain off-diagonal components that couple different subspaces.
off_diagonal_part(s::SymSum, P::Subspace)Extract the off-diagonal part of a symbolic sum.
off_diagonal_part(e::SymExpr, P::Subspace)Extract the off-diagonal part of a symbolic expression.
UnitaryTransformations.is_diagonal — Function
is_diagonal(expr::QuExpr, P::Subspace)Check if an expression is purely block-diagonal with respect to subspace P.
is_diagonal(s::SymSum, P::Subspace)Check if a symbolic sum is purely diagonal.
is_diagonal(e::SymExpr, P::Subspace)Check if a symbolic expression is purely diagonal.
UnitaryTransformations.is_off_diagonal — Function
is_off_diagonal(expr::QuExpr, P::Subspace)Check if an expression is purely off-block-diagonal with respect to subspace P.
Generator Solution
The core operation in Schrieffer-Wolff is solving $[S, H_d] = -V_{od}$ for the generator $S$.
Main Function
UnitaryTransformations.solve_for_generator — Function
solve_for_generator(H_d::QuExpr, V_od::QuExpr, P::Subspace)Solve [S, Hd] = -Vod for the generator S.
This is the core equation in Schrieffer-Wolff: we need to find S such that the commutator with the diagonal part cancels the off-diagonal perturbation.
The fundamental solution in the energy eigenbasis is: S{ij} = V{ij} / (Ei - Ej)
Two methods are automatically selected based on operator types:
Eigenoperator method (TLS, bosons, N-level transitions): For operators O where [H_d, O] = ε·O, the solution is S = V/ε directly.
Matrix-element method (SU(N) Lie algebras): Convert to the Cartan-Weyl (transition) basis where operators ARE eigenoperators, apply S{ij} = V{ij}/(Ei - Ej), then convert back.
Uses Symbolics.jl for proper symbolic division, allowing denominators like (Δ - ω).
Arguments
H_d: The diagonal (unperturbed) HamiltonianV_od: The off-diagonal perturbation to be eliminatedP: The subspace defining the block structure
Returns
S: The generator of the transformation
solve_for_generator(H_d::QuExpr, V_od::SymSum, P::Subspace)Solve [S, Hd] = -Vod for the generator S when V_od is a symbolic sum.
For a symbolic sum Σᵢ V(i), the generator is also a symbolic sum Σᵢ S(i) where each S(i) is computed using the eigenoperator method.
Key insight
For operators with sum indices, [Hd, Σᵢ O(i)] = Σᵢ [Hd, O(i)] since H_d typically doesn't depend on the sum index. The generator is then: S = Σᵢ V(i)/ε(i) where ε(i) is the energy denominator for each term.
solve_for_generator(H_d::QuExpr, V_od::SymExpr, P::Subspace)Solve [S, Hd] = -Vod for the generator S when V_od is a symbolic expression.
For a symbolic expression with multiple terms, solve for each term separately and combine the results.
solve_for_generator(H_d::SymExpr, V_od::QuExpr, P::Subspace)Solve when Hd is a SymExpr and Vod is a regular QuExpr. Extract the scalar (QuExpr) part of H_d for the generator equation.
solve_for_generator(H_d::SymExpr, V_od::SymSum, P::Subspace)Solve when both Hd and Vod involve symbolic sums.
solve_for_generator(H_d::SymExpr, V_od::SymExpr, P::Subspace)Solve when both Hd and Vod are symbolic expressions.
Method-Specific Functions
Two methods are available, automatically selected based on the operator types:
UnitaryTransformations.solve_for_generator_eigenoperator — Function
solve_for_generator_eigenoperator(H_d::QuExpr, V_od::QuExpr, P::Subspace)Solve [S, Hd] = -Vod using the eigenoperator method.
This method works for operators O where [H_d, O] = ε·O (eigenoperators of the adjoint action). The solution is simply S = V/ε.
Examples of eigenoperators:
- σ± for TLS with H_d ∝ σz: [σz, σ±] = ±2σ±
- a, a† for bosons with H_d ∝ a†a: [a†a, a] = -a, [a†a, a†] = a†
- |i⟩⟨j| for N-level with diagonal Hd: [Hd, |i⟩⟨j|] = (Ei - Ej)|i⟩⟨j|
For each term in Vod, the corresponding term in S is Vterm / ε.
UnitaryTransformations.solve_for_generator_lie — Function
solve_for_generator_lie(H_d::QuExpr, V_od::QuExpr, N::Int, generators::Tuple;
algebra_id=SU3_ALGEBRA_ID)Solve [S, Hd] = -Vod for the generator S by building the commutator matrix in the off-diagonal generator basis and solving a linear system.
This matches QuantumAlgebra's normal-form commutator semantics, which can differ from the ideal matrix-element method for SU(3).
Arguments
H_d: The diagonal Hamiltonian (in diagonal generators only)V_od: The off-diagonal perturbation to be eliminatedN: Dimension of the representation (2 for SU(2), 3 for SU(3))generators: Tuple of SU(N) generators (from su_generators)algebra_id: The algebra identifier (default: SU3ALGEBRAID)
Returns
S: The generator of the transformation
The eigenoperator method works when $[H_d, O] = \varepsilon \cdot O$ (TLS, bosons, N-level transitions).
The Lie algebra method works for SU(N) systems by converting to the Cartan-Weyl basis where generators become eigenoperators.
Supporting Functions
UnitaryTransformations.compute_energy_denominator — Function
compute_energy_denominator(H_d::QuExpr, term::QuTerm, P::Subspace)Compute the energy denominator for a given off-diagonal term.
For an off-diagonal operator O, computes ε where [Hd, O] = ε·O. This is the energy difference Ei - E_j for the transition that O represents.
Returns the energy denominator as a Symbolics Num expression, or nothing if the operator commutes with H_d (degenerate case).
UnitaryTransformations.compute_energy_eigenvalues — Function
compute_energy_eigenvalues(H_d::QuExpr, N::Int, algebra_id::UInt16)Compute energy eigenvalues for an N-level system from a diagonal Hamiltonian expressed in terms of Lie algebra generators.
For SU(N), the diagonal generators (Cartan subalgebra) have known eigenvalues. This function extracts the coefficients from H_d and computes Eᵢ for each state.
Returns a vector of symbolic expressions [E₁, E₂, ..., Eₙ].
UnitaryTransformations.detect_lie_algebra_system — Function
detect_lie_algebra_system(V_od::QuExpr)Detect if V_od contains Lie algebra generators and return information about the algebra.
Returns nothing if no Lie algebra operators found, or a NamedTuple with:
N: dimension of the algebra (2 for SU(2), 3 for SU(3))algebra_id: the UInt16 algebra identifiername: the generator name (e.g., :λ)inds: the indices tuple
Projection
UnitaryTransformations.project_to_subspace — Function
project_to_subspace(H::QuExpr, P::Subspace)Project an operator onto the subspace P.
This replaces diagonal operators by their eigenvalues in P:
- σz → eigenvalue (e.g., -1 for spin down)
- σ⁺σ⁻ → 0 for spin down, 1 for spin up
- a†a → eigenvalue (e.g., 0 for vacuum)
And removes any remaining off-diagonal terms.
project_to_subspace(s::SymSum, P::Subspace)Project a symbolic sum onto the subspace P.
The projection is applied to the inner expression of the sum. If the inner expression projects to zero (e.g., σ⁺σ⁻ in spin-down subspace), the entire sum becomes zero.
Example
For Σᵢ σ⁺(i)σ⁻(i) with P = Subspace(σz() => -1):
- The inner term σ⁺σ⁻ → 0 for spin-down
- Therefore the entire sum → 0
project_to_subspace(s::SymProd, P::Subspace)Project a symbolic product onto the subspace P.
project_to_subspace(e::SymExpr, P::Subspace)Project a symbolic expression onto the subspace P.
This applies project_to_subspace to both the scalar (QuExpr) part and all symbolic aggregate terms (SymSum, SymProd).
Notes
- Cross-site terms like
Σᵢ≠ⱼ σ⁺(i)σ⁻(j)are kept (they don't involve single-site projections that would set them to zero) - Same-site terms like
Σᵢ σ⁺(i)σ⁻(i)become zero if P is spin-down
Example
using QuantumAlgebra, UnitaryTransformations
import QuantumAlgebra: sumindex, SymSum, SymExpr
i = sumindex(1)
H = SymExpr(a'()*a()) + SymSum(σz(i)/2, i)
P = Subspace(a'()*a() => 0, σz() => -1)
H_P = project_to_subspace(H, P)
# H_P will have a†a → 0 and Σᵢ σz(i)/2 → Σᵢ(-1/2) = -N/2 (symbolic)Projection with Symbolic Sums
The project_to_subspace function supports SymExpr, SymSum, and SymProd types for multi-atom systems:
using QuantumAlgebra, UnitaryTransformations
import QuantumAlgebra: sumindex, SymSum, SymExpr
i = sumindex(1)
H_eff = SymExpr(ω_c * a'()*a()) + SymSum(Δ/2 * σz(i), i)
P = Subspace(a'()*a() => 0, σz() => -1)
H_P = project_to_subspace(H_eff, P)
# σz(i) → -1 for spin-down subspace
# Symbolic sums are preserved in the resultSupported types:
QuExpr— standard quantum expressionsSymSum— symbolic sums over site indicesSymProd— symbolic products over site indicesSymExpr— combinations of the above
BCH Expansion
The Baker-Campbell-Hausdorff expansion is used to compute $e^S H e^{-S}$.
UnitaryTransformations.bch_transform — Function
bch_transform(S::QuExpr, A::QuExpr; order::Int=4)Compute e^S A e^{-S} using the BCH formula to the specified order.
This computes the adjoint action of e^S on an operator A: e^S A e^{-S} = A + [S,A] + (1/2!)[S,[S,A]] + (1/3!)[S,[S,[S,A]]] + ...
Arguments
S: The generator (typically anti-Hermitian: S† = -S)A: The operator to transform (e.g., a Hamiltonian)order: Number of nested commutators to include (default: 4)
Example
using QuantumAlgebra, UnitaryTransformations, Symbolics
@variables g Δ
# Generator from SW transformation
S = (g/Δ) * (a'()*σm() - a()*σp())
# Transform the Hamiltonian
H = Δ/2 * σz() + g * (a'()*σm() + a()*σp())
H_transformed = bch_transform(S, H; order=2)UnitaryTransformations.commutator_series — Function
commutator_series(S::QuExpr, H::QuExpr, order::Int)Compute the BCH expansion of e^S H e^{-S} to the given order.
e^S H e^{-S} = Σₙ (1/n!) [S, [S, [..., [S, H]...]]] (n nested commutators)
The expansion is truncated at order nested commutators.
Arguments
S: The generator of the unitary transformation (anti-Hermitian: S† = -S)H: The operator to transformorder: Maximum number of nested commutators to include
Returns
- The transformed operator as a QuExpr
UnitaryTransformations.nested_commutator — Function
nested_commutator(S::QuExpr, H::QuExpr, n::Int)Compute the n-fold nested commutator [S, [S, [..., [S, H]...]]] with S appearing n times.
- n=0 returns H
- n=1 returns [S, H]
- n=2 returns [S, [S, H]]
- etc.
nested_commutator(operators::Vector{QuExpr})Compute the left-nested commutator [...[[A₁, A₂], A₃], ..., Aₙ].
nested_commutator(H::FourierHamiltonian, indices)Compute the nested commutator for given Fourier indices.
Symbolic Utilities
Coefficient Manipulation
UnitaryTransformations.simplify_coefficients — Function
simplify_coefficients(expr::QuExpr; mode::Symbol=:fast)Simplify all Symbolics coefficients in a QuExpr. Returns a new QuExpr with simplified coefficients.
Modes
:none- No simplification (fastest, for internal computations):fast- Basic expansion only (default, very fast):standard- Usesimplify(; expand=true)(slower but more thorough):fractions- Usesimplify_fractions(slow, simplifies rational expressions):aggressive- Use fullsimplify(slowest, most thorough)
Note: The :fractions and :aggressive modes can be extremely slow on complex expressions due to polynomial GCD and rewriting computations. Use :fast for most cases - it flattens expressions and combines like terms efficiently.
UnitaryTransformations.substitute_values — Function
substitute_values(expr::QuExpr, values::Dict{Symbol, Number})Substitute numerical values for symbolic parameters in a QuExpr.
Arguments
expr: A QuExpr with symbolic coefficientsvalues: Dict mapping parameter symbols to numerical values
Example
H_P = result.H_P
values = Dict(:g => 0.1, :Δ => 1.0)
H_numeric = substitute_values(H_P, values)UnitaryTransformations.extract_coefficient — Function
extract_coefficient(expr::QuExpr, target_ops::QuExpr)Extract the coefficient of a specific operator structure from a QuExpr.
Arguments
expr: The full QuExpr to searchtarget_ops: The operator structure to match (e.g.,a'()*a())
Returns
- The coefficient (Num or Number) if found, nothing otherwise
UnitaryTransformations.collect_terms — Function
collect_terms(expr::QuExpr)Collect and display all terms in a QuExpr with their simplified coefficients. Returns a vector of (operatorstring, simplifiedcoefficient) pairs.
Simplification Modes
The simplify_coefficients function supports several modes for different speed/quality trade-offs:
| Mode | Description | Speed |
|---|---|---|
:none | No simplification | Fastest |
:fast | Expansion only (flattens nested expressions) | Fast (default) |
:standard | Full algebraic simplification with expansion | Moderate |
:fractions | Simplify rational expressions with GCD | Slow |
:aggressive | Maximum simplification | Slowest |
# For exploration and debugging (fastest)
result = schrieffer_wolff(H, P; order=4, simplify_mode=:none)
# For final results (default, good balance)
result = schrieffer_wolff(H, P; order=4, simplify_mode=:fast)
# For publication-ready expressions
H_simplified = simplify_coefficients(result.H_P; mode=:standard)LaTeX Output
UnitaryTransformations.to_latex — Function
to_latex(expr::QuExpr; simplify_coeff::Bool=true)Convert a QuExpr to a LaTeX string with simplified coefficients.
Arguments
expr: The quantum expression to convertsimplify_coeff: Whether to simplify coefficients first (default: true)
Returns
A LaTeX string representation of the expression.
Example
H = Δ/2 * σz() + g * (a'() * σm() + a() * σp())
println(to_latex(H))to_latex(result::NamedTuple; simplify_coeff::Bool=true)Convert a Schrieffer-Wolff result to LaTeX strings.
Returns
A NamedTuple with LaTeX strings for each component:
H_eff: The effective HamiltonianS: The generatorH_P: The projected Hamiltonian
Example
result = schrieffer_wolff(H, P; order=2)
latex_result = to_latex(result)
println(latex_result.H_P)UnitaryTransformations.print_latex — Function
print_latex(expr::QuExpr; name::String="", display::Bool=true, simplify_coeff::Bool=true)Print a QuExpr as LaTeX, optionally wrapped in display math environment.
Arguments
expr: The quantum expression to printname: Optional name to show (e.g., "H_{eff}")display: If true, wrap in\[ ... \]for display mathsimplify_coeff: Whether to simplify coefficients first
Example
print_latex(result.H_P; name="H_P")
# Output: H_P = - \frac{1}{2} \Delta + ...UnitaryTransformations.show_result — Function
show_result(result::NamedTuple; display::Bool=false, simplify_coeff::Bool=true)Pretty-print all components of a Schrieffer-Wolff result in LaTeX.
Arguments
result: The result fromschrieffer_wolffdisplay: If true, wrap each in display math environmentsimplify_coeff: Whether to simplify coefficients
Example
result = schrieffer_wolff(H, P; order=2)
show_result(result)Parameter Conversion
Functions for converting between QuantumAlgebra's Param and Symbolics.jl variables:
UnitaryTransformations.param_to_symbolic — Function
param_to_symbolic(p::Param)Convert a QuantumAlgebra Param to a Symbolics variable. Caches variables to ensure the same param always maps to the same variable.
UnitaryTransformations.symbolic_coefficient — Function
symbolic_coefficient(term::QuTerm, coeff::Number)Convert a QuTerm's coefficient (Number + Params) to a single Symbolics expression. Handles both real and complex coefficients.
UnitaryTransformations.clear_param_cache! — Function
clear_param_cache!()Clear the parameter to Symbolics variable cache. Useful when starting a new calculation with fresh variables.
Re-exported from QuantumAlgebra
The following functions are re-exported for convenience:
comm(A, B)- Compute commutator $[A, B] = AB - BA$normal_form(expr)- Normal-order an operator expressiona(),a'()- Bosonic annihilation/creation operatorsσx(),σy(),σz()- Pauli matricesσp(),σm()- Raising/lowering operators (whenuse_σpm(true))nlevel_ops(N, name)- N-level transition operators $|i\rangle\langle j|$su_generators(N, name)- SU(N) generators (generalized Gell-Mann matrices)
Symbolic Parameters
Use Symbolics.jl @variables to define symbolic parameters:
using Symbolics
@variables Δ g ω # Define symbolic parametersFor N-level systems with indexed parameters:
# Create ω₁, ω₂, ..., ωₙ
ω = [Symbolics.variable(Symbol("ω", i)) for i in 1:N]Types
SWResult
The schrieffer_wolff function returns a named tuple:
result = schrieffer_wolff(H, P; order=2)
result.S # Generator of the transformation
result.H_eff # Block-diagonal effective Hamiltonian
result.H_P # H_eff projected onto subspace PSubspace
# Single constraint
P = Subspace(σz() => -1)
# Multiple constraints
P = Subspace(σz() => -1, a'()*a() => 0)
# N-level constraint
P = Subspace(a'()*a() => 0) # zero photonsClassification Enums
The package uses classification enums for operator analysis:
DIAGONAL # Operator preserves the subspace
RAISING # Operator raises out of subspace P
LOWERING # Operator lowers into subspace P
MIXED # Operator has mixed characterPerformance Tips
Parallel Computation
For high-order SW transformations, enable multi-threading:
# Start Julia with 4 threads
julia -t 4# Enable parallel BCH term computation
result = schrieffer_wolff(H, P; order=5, parallel=true)Benchmarks (Jaynes-Cummings model, 4 threads)
| Order | simplify_mode=:none | simplify_mode=:fast |
|---|---|---|
| 4 | 0.4 s | 0.6 s |
| 5 | 1.7 s | 1.7 s |
| 6 | 50 s | 80 s |
Recommended Workflow
- Explore with
simplify_mode=:nonefor speed - Verify with
simplify_mode=:fast(default) - Simplify for publication with
simplify_coefficients(expr; mode=:standard)
Internal Functions
These functions are not exported but may be useful for advanced users:
Lie Algebra Support
# Get generators for detected Lie algebra
get_generators_for_lie_system(lie_info::NamedTuple)
# Convert between bases
gellmann_to_cartan_weyl(V_od, N, algebra_id)
cartan_weyl_to_gellmann(transitions, N, generators)Operator Classification
# Classify a single term
classify_term(term::QuTerm, coeff, constraints)
# Check if operator contains only specific types
has_only_bosons(term::QuTerm)
has_only_tls(term::QuTerm)