Skip to content

Implementing lazy operators in express #125

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/src/express.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ julia> express(σʸ, CliffordRepr(), UseAsOperation())
sY
```

Another edge case is translations with `QuantumOpticsRepr`, where we can additionally define a finite cutoff for bosonic states and operators, as discussed in the [quantum harmonic oscillators page](@ref Quantum-Harmonic-Oscillators). The default cutoff for such objects is 2, however a different cutoff can be specified by passing an integer to `QuantumOpticsRepr` in an `express` call. Let us see an example with the number operator:
Another edge case is translations with `QuantumOpticsRepr`, where we can additionally define a finite cutoff for bosonic states and operators, as discussed in the [quantum harmonic oscillators page](@ref Quantum-Harmonic-Oscillators). The default cutoff for such objects is 2, however a different cutoff can be specified by passing an integer to `QuantumOpticsRepr` in an `express` call. We can also set the lazy parameter so that the conversion (as done by the express API) should preferentially create LazyTensor and LazySum objects. These semi-symbolic semi-numeric objects are particularly convenient for avoiding redundant computation or the creation of particularly large objects. Let us see an example with the number operator:

```jldoctest
julia> express(N) |> dense
Expand Down
44 changes: 33 additions & 11 deletions ext/QuantumOpticsExt/QuantumOpticsExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,34 @@ const _ad₂ = create(_bf2)
const _a₂ = destroy(_bf2)
const _n₂ = number(_bf2)

express_nolookup(::HGate, ::QuantumOpticsRepr) = _hadamard
express_nolookup(::XGate, ::QuantumOpticsRepr) = _x
express_nolookup(::YGate, ::QuantumOpticsRepr) = _y
express_nolookup(::ZGate, ::QuantumOpticsRepr) = _z
express_nolookup(::CPHASEGate, ::QuantumOpticsRepr) = _cphase
express_nolookup(::CNOTGate, ::QuantumOpticsRepr) = _cnot
const lazy_σ₊ = LazyPrePost(_σ₊, _σ₊)
const lazy_σ₋ = LazyPrePost(_σ₋, _σ₋)
const lazy_id = LazyPrePost(_id, _id)
const lazy_x = LazyPrePost(_x, _x)
const lazy_y = LazyPrePost(_y, _y)
const lazy_z = LazyPrePost(_z, _z)
const lazy_hadamard = LazyPrePost(_hadamard, _hadamard)

const lazy_cnot = LazyPrePost(_cnot, _cnot)
const lazy_cphase = LazyPrePost(_cphase, _cphase)
const lazy_phase = LazyPrePost(_phase, _phase)
const lazy_iphase = LazyPrePost(_iphase, _iphase)

const lazy_a₂ = LazyPrePost(_a₂, _a₂)
const lazy_ad₂ = LazyPrePost(_ad₂, _ad₂)
const lazy_n₂ = LazyPrePost(_n₂, _n₂)

const lazy_s₊ = LazySuperSum(_b2, [1/√2, 1/√2], [_l0, _l1])
const lazy_s₋ = LazySuperSum(_b2, [1/√2, -1/√2], [_l0, _l1])
const lazy_i₊ = LazySuperSum(_b2, [1/√2, 1im/√2], [_l0, _l1])
const lazy_i₋ = LazySuperSum(_b2, [1/√2, -1im/√2], [_l0, _l1])

express_nolookup(::HGate, repr::QuantumOpticsRepr) = repr.lazy ? lazy_hadamard : _hadamard
express_nolookup(::XGate, repr::QuantumOpticsRepr) = repr.lazy ? lazy_x : _x
express_nolookup(::YGate, repr::QuantumOpticsRepr) = repr.lazy ? lazy_y : _y
express_nolookup(::ZGate, repr::QuantumOpticsRepr) = repr.lazy ? lazy_z : _z
express_nolookup(::CPHASEGate, repr::QuantumOpticsRepr) = repr.lazy ? lazy_cphase : _cphase
express_nolookup(::CNOTGate, repr::QuantumOpticsRepr) = repr.lazy ? lazy_cnot : _cnot

const xyzopdict = Dict(:X=>_x, :Y=>_y, :Z=>_z)
const xyzstatedict = Dict(:X=>(_s₊,_s₋),:Y=>(_i₊,_i₋),:Z=>(_l0,_l1))
Expand All @@ -64,12 +86,12 @@ for control in (:X, :Y, :Z)
end
end

express_nolookup(::PauliM, ::QuantumOpticsRepr) = _σ₋
express_nolookup(::PauliP, ::QuantumOpticsRepr) = _σ₊
express_nolookup(::PauliM, repr::QuantumOpticsRepr) = repr.lazy ? lazy_σ₊ : _σ₋
express_nolookup(::PauliP, repr::QuantumOpticsRepr) = repr.lazy ? lazy_σ₊ : _σ₊

express_nolookup(s::XBasisState, ::QuantumOpticsRepr) = (_s₊,_s₋)[s.idx]
express_nolookup(s::YBasisState, ::QuantumOpticsRepr) = (_i₊,_i₋)[s.idx]
express_nolookup(s::ZBasisState, ::QuantumOpticsRepr) = (_l0,_l1)[s.idx]
express_nolookup(s::XBasisState, repr::QuantumOpticsRepr) = repr.lazy ? (lazy_s₊, lazy_s₋)[s.idx] : (_s₊, _s₋)[s.idx]
express_nolookup(s::YBasisState, repr::QuantumOpticsRepr) = repr.lazy ? (lazy_i₊, lazy_i₋)[s.idx] : (_i₊, _i₋)[s.idx]
express_nolookup(s::ZBasisState, repr::QuantumOpticsRepr) = repr.lazy ? (lazy_l0, lazy_l1)[s.idx] : (_l0, _l1)[s.idx]

function finite_basis(s,r)
if isfinite(length(basis(s)))
Expand Down
14 changes: 14 additions & 0 deletions test/test_express_lazy.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@testitem "Express Lazy" begin
using QuantumOpticsBase

state = 1im*X2⊗Z1+2*Y1⊗(Z2+X2)+StabilizerState("XZ YY")
repr = QuantumOpticsExt()
repr_lazy = QuantumOpticsExt(lazy=true)

isequal(express(X1, repr_lazy), express(X1, repr))
isequal(express(X2, repr_lazy), express(X2, repr))
isequal(express(Y1, repr_lazy), express(Y1, repr))
isequal(express(Y2, repr_lazy), express(Y2, repr))
isequal(express(Z1, repr_lazy), express(Z1, repr))
isequal(express(Z2, repr_lazy), express(Z2, repr))
end
Loading