Add CollectiveTransition for symmetric-subspace collective atoms#117
Draft
oameye wants to merge 2 commits into
Draft
Add CollectiveTransition for symmetric-subspace collective atoms#117oameye wants to merge 2 commits into
oameye wants to merge 2 commits into
Conversation
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).
There was a problem hiding this comment.
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
CollectiveTransitionas a new exportedQSym, including constructors, adjoint/equality/hash, ordering rules, printing, and LaTeX rendering. - Adds numeric support for converting
CollectiveTransitiontoQuantumOpticsBase.ManyBodyBasis, and narrows theexpectalias toQField. - 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 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`. | ||
|
|
| "Symbolic Sums and Indices" => "symbolic_sums.md", | ||
| "Collective Atoms" => "collective.md", | ||
| "Examples" => [ | ||
| "Schrieffer-Wolff Transformation" => "examples/schrieffer_wolff.md", |
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 on lines
+44
to
+46
| @latexrecipe function f(x::CollectiveTransition) | ||
| return Expr(:latexifymerge, "{$(x.name)}$(transition_idx_script[]){{$(x.i)$(x.j)}}") | ||
| end |
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 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 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 |
Member
Author
|
@ChristophHotter Can you leave a review? |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds
CollectiveTransitionforNidentical atoms with closedsu(N)Lie-algebra arithmetic, paired withManyBodyBasisnumeric conversion for exact dynamics in the symmetric (bosonic) subspace.This ports PR #102 onto the redesign-v2 architecture, with several improvements:
CheckConcreteStructs); nometadata, noClusterSpacedependencysu(N)swap rule slot in_apply_ordering_swap!, mirroring the existingSpinpattern — same architecture, no new abstractionsexpectaliases narrowed toQField(the original PR'sAveragetype doesn't exist in v2)When this is the right tool
Both indexed
Σ(already in v2) andCollectiveTransitiondescribeNidentical atoms in collective dynamics — they are complementary computational strategies, not different physics:Σ(cumulant approach)CollectiveTransition(exact symmetric subspace)ManyBodyBasis\binom{N+n-1}{n-1}g_i)IndexedVariableNscalingN(truncation order at solve time)N— tractable in the polynomial subspaceCollectiveTransition's niche is the intersection of three properties that no other path in the package provides together:su(N)form before going to numerics.Ncorrections, entanglement entropy, etc.Ntoo big for the full product space, small enough for the symmetric subspace (roughlyN ∈ [5, ~thousands]for two-level atoms).If you only need two of those, simpler tools cover the use case: indexed
Σfor symbolic + cumulant (anyN); plainQuantumOpticsBase.manybodyoperatorfor exact + numeric only (smallN, 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
CollectiveTransition <: QSymwith concrete fieldsname, i, j, space_index, index(alwaysNO_INDEX; carried for site-sort compatibility). Non_atomsfield —Nenters only at numeric-conversion time viaManyBodyBasis. Algebra stays Hilbert-space-decoupled.[S^{ij}, S^{kl}] = \delta_{jk} S^{il} - \delta_{li} S^{kj}fires eagerly underNormalOrdervia a new branch in_apply_ordering_swap!. Convention_isordered_ctkeeps the larger(i, j)on the left (descending lex).\sum_j S^{jj} = N \cdot I(note theN, not1), so per-atomσ^{gg} → 1 − σ^{kk}rewriting doesn't apply. Deferred to numeric-conversion layer whereNis known.IndexedOperator(::CollectiveTransition, ::Index): rejected withArgumentError—CollectiveTransitionalready represents the sum.to_numeric(::CollectiveTransition, ::ManyBodyBasis)builds a many-body operator from the single-atomtransition. Rejects non-NLevelBasisone-body bases.References