Symbolic Coefficients and Phases
The coefficients of a quantum expression can contain symbolic parameters, complex amplitudes, trigonometric functions, and exact unit phases. They participate in operator arithmetic without changing the operator algebra.
Symbolic parameters are created with @variables, which is re-exported from Symbolics.jl:
using SecondQuantizedAlgebra
h = FockSpace(:resonator)
@qnumbers a::Destroy(h)
@variables ω g t
H = ω * a' * a + g * (a + a')\[g a + g a^{\dagger} + \omega a^{\dagger}a\]
Variables are real unless another symbolic type is specified. This means ω is unchanged by conjugation. Complex-valued amplitudes can be declared with ::Number:
@variables η::Number
drive = η * a + conj(η) * a'\[\eta a + \mathrm{conj}\left( \eta \right) a^{\dagger}\]
See Symbolic parameters for the distinction between real, atomic complex, and split complex variables.
Exact unit phases
expim(x) represents the unit phase $e^{ix}$ for a provably real argument. It stays compact under multiplication, integer powers, inversion, conjugation, substitution, and differentiation.
using SecondQuantizedAlgebra
import Symbolics
import SecondQuantizedAlgebra: expim, exponential_form, trigonometric_form
h = FockSpace(:phase_example)
@qnumbers a::Destroy(h)
@variables θ ω t
p = expim(ω * t)
p * conj(p)1Arguments add canonically when independently constructed phases are multiplied. Integer powers scale the argument, while division and conjugation subtract it:
expim(θ) * expim(ω * t)
expim(θ)^3 / expim(ω * t)
expim(ω * t) * expim(-ω * t) * a\[a\]
Arguments are expanded when a phase is constructed or merged. Thus equivalent expressions such as (ω + 2θ)*t and ω*t + 2θ*t produce the same stored phase. This is algebraic normalization only; arguments are not guessed modulo $2π$.
Substitution rebuilds the canonical phase and differentiation applies the usual chain rule:
substitute(p, Dict(ω => 2ω))
Symbolics.derivative(p, t)exp(im*t*ω)*im*ωFor a coefficient that is exactly one unit phase, its elementary projections are available:
(real(p), imag(p), abs(p), abs2(p))(cos(t*ω), sin(t*ω), 1, 1)Only real arguments are accepted because the identities $\overline{e^{ix}}=e^{-ix}$ and $|e^{ix}|=1$ require real $x$. A complex symbolic argument should instead be represented with the ordinary symbolic exp function. Fractional powers are deliberately not rewritten: sqrt(expim(θ)) and expim(θ)^(1//2) are unsupported because replacing either by expim(θ/2) would choose a branch. Integer powers, including negative powers, are branch-safe and remain supported.
Choosing an exponential or trigonometric form
Unit phases are printed as exponentials, including when positive- and negative-frequency terms occur together:
(expim(ω * t) + expim(-ω * t)) * a\[\left(e^{i t ~ \omega} + e^{-i t ~ \omega}\right) a\]
This preserves the representation selected by the user. Conversion between phase and trigonometric forms is available explicitly.
exponential_form rewrites algebraic occurrences of cos and sin using expim:
exponential_form(cos(ω * t) * a)
exponential_form(exp(im * θ))
exponential_form(cis(θ))exp(im*θ)trigonometric_form performs the reverse conversion:
trigonometric_form((expim(ω * t) + expim(-ω * t)) * a)\[2 ~ \cos\left( t ~ \omega \right) a\]
Both functions act termwise on quantum expressions and leave their operator products unchanged. They are representation changes: ordinary display and simplify do not invoke them automatically. In particular, expim(cos(θ)) means $e^{i\cos\theta}$; it is not a request to convert a cosine.
Automatic coefficient identities
simplify reduces exact trigonometric and hyperbolic identities in operator coefficients:
using SecondQuantizedAlgebra
h = FockSpace(:simplification_example)
@qnumbers a::Destroy(h)
@variables ω t r
simplify((cos(ω * t)^2 + sin(ω * t)^2) * a' * a)\[a^{\dagger}a\]
simplify((cosh(r)^2 - sinh(r)^2) * (a + a'))\[a + a^{\dagger}\]
Composite arguments such as ω*t are supported. Reduction is exact and conservative: if an identity cannot be applied safely without excessive expression growth, the original coefficient is returned unchanged.