You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This issue is part of unitaryHACK26. You have to be registered to complete this issue.
Learn more about the PR submission process here and about unitaryHACK rules here!
A note about AI Slop: while we are open to collaboration with LLMs for unitaryHACK, fully AI-generated PRs are not acceptable. It is at the maintainers' discretion whether or not LLM-generated PRs are the right fit for the issues, and those that appear fully AI-generated may be immediately rejected. Read unitaryHACK's full AI Policy here.
Note from the maintainer: If you have not contributed before to open source projects, no AI agent use is permitted for this issue.
Context
QuantumOpticsBase.jl has two related concepts today:
embed(...), which embeds an operator into a larger composite basis.
LazyTensor, which can represent local tensor-product structure without
materializing the full matrix.
For dense and sparse operators, embed(...) currently builds the embedded
operator eagerly. That is often much more expensive than necessary when the
embedded operator will be applied to a state or used as one term in a Hamiltonian.
For example, embedding a one-site operator in a many-site spin chain should not
need to allocate the full 2^n x 2^n sparse matrix if a lazy representation can
do the same application directly.
embed_lazy(b::Basis, i, op::AbstractOperator) =LazyTensor(b, i, op)
functionembed_lazy(b::Basis, i, op::LazySum)
_embed_ops(b, i, ops::Tuple) = ((embed_lazy(b, i, o) for o in ops)...,)
_embed_ops(b, i, ops) = [embed_lazy(b, i, o) for o in ops]
LazySum(b, b, op.factors, _embed_ops(b, i, op.operators))
endembed_lazy(b::Basis, indices, op::LazyTensor) =LazyTensor(b, b, indices, op.operators, op.factor)
This issue is to turn that idea into a robust, tested, documented API.
Local operators embedded into composite Hilbert spaces are a common pattern in
quantum optics and spin-chain simulations. The eager embed path is correct and
useful, but it can allocate large sparse matrices that are avoidable for many
workflows.
An efficient lazy embedding API would let users write:
H =embed_lazy(basis, 1, sx) +embed_lazy(basis, 2, sz)
and get a structure-preserving lazy operator suitable for multiplication by
kets, use inside LazySum, and eventual dense/sparse conversion only when
explicitly requested.
Add a public API for lazy embedding. The exact name can be decided by
maintainers, but embed_lazy is the historical name from PR Codecov #88 and is a good
starting point.
Export the public API from QuantumOpticsBase.jl.
Implement lazy embedding for:
AbstractOperator / DataOperator, returning a LazyTensor when possible,
LazyTensor, re-embedding the existing lazy tensor into the larger basis,
LazySum, preserving the LazySum and lazily embedding each term,
TimeDependentSum, if straightforward, preserving coefficients while
lazily embedding the static operator terms.
Support both single-index and multi-index embedding, matching the existing embed behavior where possible.
Preserve basis checks and error behavior: incompatible bases should fail
clearly rather than silently constructing invalid lazy operators.
Add tests showing that lazy embedding agrees with eager embed under dense(...) and under application to Ket.
Add documentation near the existing lazy-operator docs.
Add at least small allocation/time checks or benchmarks that demonstrate the
lazy path avoids materializing the full embedded matrix for representative
local operators.
Out of scope:
Changing the default behavior of embed(...).
Replacing LazyTensor, LazySum, or LazyProduct.
Supporting every possible AbstractOperator subtype if the subtype cannot be
represented lazily without materialization.
GPU-specific behavior.
API considerations
Please address these points in the PR:
Should the public function be named embed_lazy, lazyembed, or should there
be a LazyEmbed constructor/type?
Should embed_lazy live next to embed in the docs, or in the lazy-operator
section?
Should embed_lazy(basis_l, basis_r, indices, op) be supported in addition to embed_lazy(basis, indices, op)?
What should happen for a LazyProduct? It may be enough to document that this
is unsupported initially, or to embed each factor lazily when bases make that
unambiguous.
The implementation should prefer a simple, maintainable API over broad
coverage. It is acceptable to support the common local-operator and LazySum
cases first.
Acceptance criteria
embed_lazy or the chosen public API exists and is exported.
Embedding a one-site dense or sparse operator into a composite basis returns a
lazy operator, not an eager embedded sparse matrix.
Embedding a LazySum preserves a LazySum of lazy embedded terms.
Embedding a LazyTensor into a larger composite basis preserves the existing
suboperators and factor.
The lazy result agrees with eager embed for representative dense conversion
and Ket application tests.
Tests cover single-index and multi-index embedding, dense and sparse local
operators, LazySum, and at least one incompatible-basis failure.
Documentation includes a short example and explains how this differs from embed(...) and from directly constructing LazyTensor.
Difficulty
Intermediate. The core implementation can be small, but the hard part is making
the API precise, preserving existing basis semantics, and adding enough tests to
avoid another under-specified lazy embedding helper.
This issue is part of unitaryHACK26. You have to be registered to complete this issue.
Learn more about the PR submission process here and about unitaryHACK rules here!
A note about AI Slop: while we are open to collaboration with LLMs for unitaryHACK, fully AI-generated PRs are not acceptable. It is at the maintainers' discretion whether or not LLM-generated PRs are the right fit for the issues, and those that appear fully AI-generated may be immediately rejected. Read unitaryHACK's full AI Policy here.
Note from the maintainer: If you have not contributed before to open source projects, no AI agent use is permitted for this issue.
Context
QuantumOpticsBase.jlhas two related concepts today:embed(...), which embeds an operator into a larger composite basis.LazyTensor, which can represent local tensor-product structure withoutmaterializing the full matrix.
For dense and sparse operators,
embed(...)currently builds the embeddedoperator eagerly. That is often much more expensive than necessary when the
embedded operator will be applied to a state or used as one term in a Hamiltonian.
For example, embedding a one-site operator in a many-site spin chain should not
need to allocate the full
2^n x 2^nsparse matrix if a lazy representation cando the same application directly.
There was an old starting-point PR for this idea:
That PR proposed a small
embed_lazyhelper:This issue is to turn that idea into a robust, tested, documented API.
Relevant current code:
embedimplementation forDataOperator:LazySumembed support:LazyTensorimplementation:Why this matters
Local operators embedded into composite Hilbert spaces are a common pattern in
quantum optics and spin-chain simulations. The eager
embedpath is correct anduseful, but it can allocate large sparse matrices that are avoidable for many
workflows.
An efficient lazy embedding API would let users write:
and get a structure-preserving lazy operator suitable for multiplication by
kets, use inside
LazySum, and eventual dense/sparse conversion only whenexplicitly requested.
Minimal target example
After this change, the following should work:
Scope
In scope:
maintainers, but
embed_lazyis the historical name from PR Codecov #88 and is a goodstarting point.
QuantumOpticsBase.jl.AbstractOperator/DataOperator, returning aLazyTensorwhen possible,LazyTensor, re-embedding the existing lazy tensor into the larger basis,LazySum, preserving theLazySumand lazily embedding each term,TimeDependentSum, if straightforward, preserving coefficients whilelazily embedding the static operator terms.
embedbehavior where possible.clearly rather than silently constructing invalid lazy operators.
embedunderdense(...)and under application toKet.lazy path avoids materializing the full embedded matrix for representative
local operators.
Out of scope:
embed(...).LazyTensor,LazySum, orLazyProduct.AbstractOperatorsubtype if the subtype cannot berepresented lazily without materialization.
API considerations
Please address these points in the PR:
embed_lazy,lazyembed, or should therebe a
LazyEmbedconstructor/type?embed_lazylive next toembedin the docs, or in the lazy-operatorsection?
embed_lazy(basis_l, basis_r, indices, op)be supported in addition toembed_lazy(basis, indices, op)?LazyProduct? It may be enough to document that thisis unsupported initially, or to embed each factor lazily when bases make that
unambiguous.
The implementation should prefer a simple, maintainable API over broad
coverage. It is acceptable to support the common local-operator and
LazySumcases first.
Acceptance criteria
embed_lazyor the chosen public API exists and is exported.lazy operator, not an eager embedded sparse matrix.
LazySumpreserves aLazySumof lazy embedded terms.LazyTensorinto a larger composite basis preserves the existingsuboperators and factor.
embedfor representative dense conversionand
Ketapplication tests.operators,
LazySum, and at least one incompatible-basis failure.embed(...)and from directly constructingLazyTensor.Difficulty
Intermediate. The core implementation can be small, but the hard part is making
the API precise, preserving existing basis semantics, and adding enough tests to
avoid another under-specified lazy embedding helper.