Skip to content

Add CollectiveTransition for symmetric-subspace collective atoms#117

Draft
oameye wants to merge 2 commits into
redesign-v2from
collective-transition
Draft

Add CollectiveTransition for symmetric-subspace collective atoms#117
oameye wants to merge 2 commits into
redesign-v2from
collective-transition

Conversation

@oameye

@oameye oameye commented May 1, 2026

Copy link
Copy Markdown
Member

Adds CollectiveTransition for N identical atoms with closed su(N) Lie-algebra arithmetic, paired with ManyBodyBasis numeric conversion for exact dynamics in the symmetric (bosonic) subspace.

This ports PR #102 onto the redesign-v2 architecture, with several improvements:

  • Concrete struct fields (passes CheckConcreteStructs); no metadata, no ClusterSpace dependency
  • Eager su(N) swap rule slot in _apply_ordering_swap!, mirroring the existing Spin pattern — same architecture, no new abstractions
  • Type-piracy-clean: expect aliases narrowed to QField (the original PR's Average type doesn't exist in v2)
  • A docs page that nails the "which one do I use?"

When this is the right tool

Both indexed Σ (already in v2) and CollectiveTransition describe N identical atoms in collective dynamics — they are complementary computational strategies, not different physics:

Indexed Σ (cumulant approach) CollectiveTransition (exact symmetric subspace)
Numerical strategy Cumulant / mean-field truncation Exact diagonalization on ManyBodyBasis
Hilbert space at numeric layer Single representative atom + symbolic site index Full symmetric subspace, dim \binom{N+n-1}{n-1}
Site-dependent parameters (e.g. g_i) Yes, via IndexedVariable No (atoms identical by construction)
N scaling Large N (truncation order at solve time) Modest N — tractable in the polynomial subspace
Output Mean-field / cumulant equations of motion State vector / density matrix on the symmetric subspace

CollectiveTransition's niche is the intersection of three properties that no other path in the package provides together:

  1. Symbolic algebra — derive Heisenberg equations or dissipators in closed su(N) form before going to numerics.
  2. Exact dynamics — no cumulant truncation; full state vector, finite-N corrections, entanglement entropy, etc.
  3. N too big for the full product space, small enough for the symmetric subspace (roughly N ∈ [5, ~thousands] for two-level atoms).

If you only need two of those, simpler tools cover the use case: indexed Σ for symbolic + cumulant (any N); plain QuantumOpticsBase.manybodyoperator for exact + numeric only (small N, no symbolic layer needed). The niche is real but narrow — the docs page is upfront about this.

Pick the one that matches your computational strategy, and don't mix them on the same NLevelSpace.

Design notes

  • Struct: CollectiveTransition <: QSym with concrete fields name, i, j, space_index, index (always NO_INDEX; carried for site-sort compatibility). No n_atoms field — N enters only at numeric-conversion time via ManyBodyBasis. Algebra stays Hilbert-space-decoupled.
  • Algebra: [S^{ij}, S^{kl}] = \delta_{jk} S^{il} - \delta_{li} S^{kj} fires eagerly under NormalOrder via a new branch in _apply_ordering_swap!. Convention _isordered_ct keeps the larger (i, j) on the left (descending lex).
  • Single-atom completeness skipped: for collective operators \sum_j S^{jj} = N \cdot I (note the N, not 1), so per-atom σ^{gg} → 1 − σ^{kk} rewriting doesn't apply. Deferred to numeric-conversion layer where N is known.
  • No IndexedOperator(::CollectiveTransition, ::Index): rejected with ArgumentErrorCollectiveTransition already represents the sum.
  • Numeric conversion: to_numeric(::CollectiveTransition, ::ManyBodyBasis) builds a many-body operator from the single-atom transition. Rejects non-NLevelBasis one-body bases.

References

oameye added a commit that referenced this pull request May 1, 2026
…ementation

This is a complete rewrite branch — line-level conflicts with main are an
artifact of git's three-way merge. The redesign-v2 tree is the authoritative
implementation. Substantive PRs that landed on main during development have
been ported separately:

  - #102 Collective transition ops  → ported in collective-transition branch (PR #117)
  - #103 QIO.jl code quality        → ported in 7271532

The remaining commits brought in by this merge (CI workflow bumps, typos
config, version bump 0.4.4→0.4.5) are skipped intentionally — redesign-v2 is
at 0.5.0 and uses its own CI configuration.

Conflicts: resolved by taking the redesign-v2 version everywhere (-s ours).
@oameye oameye requested review from ChristophHotter and Copilot May 3, 2026 13:28

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a new CollectiveTransition operator family for collective N-atom dynamics in the symmetric subspace, plus the numeric conversion and documentation needed to use it alongside the existing indexed-Σ workflow.

Changes:

  • Adds CollectiveTransition as a new exported QSym, including constructors, adjoint/equality/hash, ordering rules, printing, and LaTeX rendering.
  • Adds numeric support for converting CollectiveTransition to QuantumOpticsBase.ManyBodyBasis, and narrows the expect alias to QField.
  • Adds dedicated tests, a new collective-atoms docs page, and a Dicke/Tavis-Cummings example.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
test/numeric_test.jl Updates numeric-average/expect tests for the narrowed expect API.
test/collective_transition_test.jl Adds symbolic and numeric tests for the new collective-transition feature.
src/qadd.jl Registers sort order for CollectiveTransition terms.
src/printing.jl Adds plain-text display for collective transitions.
src/ordering.jl Adds eager normal-order swap/commutator handling for collective transitions.
src/numeric.jl Adds ManyBodyBasis numeric conversion and vector-state averaging paths; narrows expect.
src/nlevel.jl Defines CollectiveTransition and its constructors/basic behavior.
src/latexify_recipes.jl Adds LaTeX rendering for collective transitions.
src/SecondQuantizedAlgebra.jl Exports the new operator type.
examples/dicke_superradiance.jl Adds a runnable Dicke/Tavis-Cummings collective-atoms example.
examples/Project.toml Adds example dependency support for the new solver-based example.
docs/src/collective.md Adds user-facing guidance on when to use indexed Σ vs CollectiveTransition.
docs/src/API.md Publishes CollectiveTransition in the API docs.
docs/pages.jl Adds the new collective-atoms documentation page to the docs nav.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +183 to +192
# CT's index is NO_INDEX; Transition's user-supplied index differs.
# _same_site requires matching index, so Transition·CT never fires reductions.
σ(i, j) = Transition(h, :σ, i, j)
@test S(1, 2) != σ(1, 2)
@test hash(S(1, 2)) != hash(σ(1, 2))
# Product: stored as 2-op product (no algebra fires)
r = S(1, 2) * σ(2, 1)
@test length(r) == 1
ops, _ = only(collect(r))
@test length(ops) == 2
Comment thread docs/src/collective.md
Comment on lines +42 to +45
## Exact symmetric subspace — `CollectiveTransition`

Use this when you want **exact dynamics in the symmetric subspace** and `N` is small enough that the polynomial-size basis is tractable. Atoms are identical by construction (no site labels); the operator algebra is the closed ``\mathfrak{su}(N)`` Lie algebra; numeric simulation goes through `QuantumOpticsBase.ManyBodyBasis`.

Comment thread docs/pages.jl
"Symbolic Sums and Indices" => "symbolic_sums.md",
"Collective Atoms" => "collective.md",
"Examples" => [
"Schrieffer-Wolff Transformation" => "examples/schrieffer_wolff.md",
Comment thread src/printing.jl
Comment on lines +58 to +61
function Base.show(io::IO, x::CollectiveTransition)
print(io, x.name)
_write_subscript(io, x.i)
return _write_subscript(io, x.j)
Comment thread src/latexify_recipes.jl
Comment on lines +44 to +46
@latexrecipe function f(x::CollectiveTransition)
return Expr(:latexifymerge, "{$(x.name)}$(transition_idx_script[]){{$(x.i)$(x.j)}}")
end
Comment thread src/numeric.jl
Comment on lines +45 to +52
function to_numeric(op::CollectiveTransition, b::QuantumOpticsBase.ManyBodyBasis; kwargs...)
onebody = b.onebodybasis
onebody isa QuantumOpticsBase.NLevelBasis || throw(
ArgumentError(
"CollectiveTransition requires a ManyBodyBasis with NLevelBasis as the one-body basis; got $(typeof(onebody))"
)
)
return QuantumOpticsBase.manybodyoperator(b, QuantumOpticsBase.transition(onebody, op.i, op.j))
Comment thread src/nlevel.jl
Comment on lines +209 to +215
struct CollectiveTransition <: QSym
name::Symbol
i::Int
j::Int
space_index::Int
index::Index # always NO_INDEX; carried for site-sort compatibility
end
Comment thread src/numeric.jl
Comment on lines +316 to 321
For averaged `BasicSymbolic` expressions (returned by [`average`](@ref)) call
[`numeric_average`](@ref) directly — defining `expect` overloads on
`SymbolicUtils.BasicSymbolic` would be type-piracy.
"""
expect(op::QField, state; kwargs...) = numeric_average(op, state; kwargs...)
expect(op::QField, state, d::Dict; kwargs...) = numeric_average(op, state, d; kwargs...)
# faster than for `N` independent atoms thanks to the ``\sqrt{N}`` enhanced
# coupling.
#
# See [Collective Atoms — Two Regimes](@ref) for when to use
#
# In this example we:
# 1. Build the Tavis-Cummings Hamiltonian with collective atom operators,
# 2. Verify the ``\mathfrak{su}(N)`` Lie-algebra commutators that drive the
@oameye

oameye commented May 15, 2026

Copy link
Copy Markdown
Member Author

@ChristophHotter Can you leave a review?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants