Skip to content

Add lazy field to QuantumOpticsRepr (qojulia/QuantumOptics.jl#521)#86

Open
mk0dz wants to merge 1 commit into
qojulia:mainfrom
mk0dz:feat/521-quantumopticsrepr-lazy
Open

Add lazy field to QuantumOpticsRepr (qojulia/QuantumOptics.jl#521)#86
mk0dz wants to merge 1 commit into
qojulia:mainfrom
mk0dz:feat/521-quantumopticsrepr-lazy

Conversation

@mk0dz

@mk0dz mk0dz commented Jun 16, 2026

Copy link
Copy Markdown

Part 1 of 2 for qojulia/QuantumOptics.jl#521 (lazy operator support).

The ask

Add a lazy::Bool=false keyword to QuantumOpticsRepr so that
express(x, QuantumOpticsRepr(lazy=true)) produces structure-preserving lazy
operators: symbolic sum → LazySum, product → LazyProduct,
tensor → LazyTensor, with dense(lazy) ≈ eager and backward compatibility
for QuantumOpticsRepr() / QuantumOpticsRepr(cutoff).

The key insights

QuantumSymbolics expresses a composite symbolic expression via
operation(s)(express.(arguments(s))...) — it applies the symbolic operation
(+, *, ) to the eagerly-expressed arguments. Making it lazy = swap the
operation for its lazy constructor.
operation() is + for SAdd, * for
SMulOperator/SScaled, for STensor (verified in source), so a single
dispatch on the operation suffices.

Changes (2 repos → 2 coordinated PRs)

1. QuantumInterface.jlsrc/express.jl

Base.@kwdef struct QuantumOpticsRepr <: AbstractRepresentation
    cutoff::Int = 2
    lazy::Bool = false          # NEW
end
QuantumOpticsRepr(cutoff::Int) = QuantumOpticsRepr(cutoff, false)  # keep 1-arg ctor

The explicit 1-arg constructor is required because @kwdef with two fields makes
the positional constructor need both args — without it, QuantumOpticsRepr(2)
(a documented usage) would break.

2. QuantumSymbolics.jlext/QuantumOpticsExt/QuantumOpticsExt.jl QuantumSavory/QuantumSymbolics.jl#201

A express_nolookup(s, repr::QuantumOpticsRepr) method that, when repr.lazy,
maps the operation to its lazy constructor (and otherwise reproduces the eager
behaviour exactly). Guards ensure ket/bra cases (which also carry operation===*)
fall through to eager, and that LazyTensor (which needs densifiable factors)
collapses any lazy factor while keeping the tensor product itself lazy.
Plus test/general/express_lazy_tests.jl (auto-discovered) and a paragraph in
docs/src/express.md.

Validation (local, Julia 1.12.6, dev-linked QuantumInterface)

test result
new express_lazy_tests.jl (constructor, backcompat, sum/product/tensor, dense≈eager, scalar, nesting, eager-unchanged) 12/12 pass
existing express_opt_tests.jl (eager sums/products/tensors/mixed) 15/15 pass — no regression
basis_consistency_tests.jl pass

Files changed (PR contents)

QuantumInterface.jl:
  src/express.jl                                   (+ lazy field, + 1-arg ctor)
QuantumSymbolics.jl:
  ext/QuantumOpticsExt/QuantumOpticsExt.jl         (+ lazy express method)
  test/general/express_lazy_tests.jl               (new)
  docs/src/express.md                              (+ lazy paragraph)

AI Acknowledgment: i want to thank claude opus 4.6 for making me understand code base of both repos and helpin me running testing and validations

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.

1 participant