-
Notifications
You must be signed in to change notification settings - Fork 15
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
Separate normalized and unnormalized objects #50
Changes from 3 commits
a0f17e7
e1f433a
8e421a6
3d058f8
62d01f8
bd64b32
eb3b604
5c50963
1b07957
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -568,7 +568,7 @@ Fields: | |
|
||
$FIELDS | ||
|
||
Generate symbolic object for the spin-spin density matrix for a | ||
Generate symbolic object for the unnormalized spin-spin density matrix for a | ||
cascaded source swapped with emissive spin memories. The cascaded | ||
source from papers [prajit2022heralded](@cite) and [kevin2023zero](@cite) | ||
is stored in spin memories as discussed in [prajit2023entangling](@cite). | ||
|
@@ -589,12 +589,12 @@ It takes the following parameters: | |
```jldoctest | ||
julia> r = Register(2) | ||
|
||
julia> initialize!(r[1:2], ZALMSpinPair(1e-3, 0.5, 0.5, 1, 1, 1, 1, 0.9, 1e-8, 1e-8, 1e-8, 0.99)) | ||
julia> initialize!(r[1:2], ZALMSpinPairU(1e-3, 0.5, 0.5, 1, 1, 1, 1, 0.9, 1e-8, 1e-8, 1e-8, 0.99)) | ||
|
||
juilia> observable(r[1:2], Z⊗Z) | ||
``` | ||
""" | ||
@withmetadata struct ZALMSpinPair <: AbstractTwoQubitState | ||
@withmetadata struct ZALMSpinPairU <: AbstractTwoQubitState | ||
Ns::Float64 | ||
gA::Float64 | ||
gB::Float64 | ||
|
@@ -609,9 +609,70 @@ juilia> observable(r[1:2], Z⊗Z) | |
VisF::Float64 | ||
end | ||
|
||
symbollabel(x::ZALMSpinPair) = "ρᶻᵃˡᵐ" | ||
symbollabel(x::ZALMSpinPairU) = "ρᶻᵃˡᵐᵁ" | ||
|
||
function express_nolookup(x::ZALMSpinPair, ::QuantumOpticsRepr) | ||
|
||
""" | ||
$TYPEDEF | ||
|
||
Fields: | ||
|
||
$FIELDS | ||
|
||
Generate symbolic object for the normalized spin-spin density matrix for a | ||
cascaded source swapped with emissive spin memories. The cascaded | ||
source from papers [prajit2022heralded](@cite) and [kevin2023zero](@cite) | ||
is stored in spin memories as discussed in [prajit2023entangling](@cite). | ||
It takes the following parameters: | ||
- Ns: mean photon number per mode of the cascaded source model | ||
- gA: qubit initialization parameter on Alice's side | ||
- gB: qubit initialization parameter on Bob's side | ||
- eAm: memory out-coupling efficiency for Alice's side (Allowed range: [0,1]) | ||
- eBm: memory out-coupling efficiency for Bob's side (Allowed range: [0,1]) | ||
- eAs: source out-coupling efficiency for Alice's side (Allowed range: [0,1]) | ||
- eBs: source out-coupling efficiency for Bob's side (Allowed range: [0,1]) | ||
- eD: detector efficiency (Allowed range: [0,1]) | ||
- Pd: dark click probability per photonic mode on source's swap | ||
- Pdo1: dark click probability per photonic mode on Alice side swap | ||
- Pdo2: dark click probability per photonic mode on Bob side swap | ||
- VisF: product of visibilities of all three interferometers (Allowed range: [0,1]) | ||
|
||
```jldoctest | ||
julia> r = Register(2) | ||
|
||
julia> initialize!(r[1:2], ZALMSpinPairN(1e-3, 0.5, 0.5, 1, 1, 1, 1, 0.9, 1e-8, 1e-8, 1e-8, 0.99)) | ||
|
||
juilia> observable(r[1:2], Z⊗Z) | ||
``` | ||
""" | ||
@withmetadata struct ZALMSpinPairN <: AbstractTwoQubitState | ||
Ns::Float64 | ||
gA::Float64 | ||
gB::Float64 | ||
eAm::Float64 | ||
eBm::Float64 | ||
eAs::Float64 | ||
eBs::Float64 | ||
eD::Float64 | ||
Pd::Float64 | ||
Pdo1::Float64 | ||
Pdo2::Float64 | ||
VisF::Float64 | ||
end | ||
|
||
symbollabel(x::ZALMSpinPairN) = "ρᶻᵃˡᵐᴺ" | ||
|
||
## express | ||
|
||
function express_nolookup(x::ZALMSpinPairU, ::QuantumOpticsRepr) | ||
data = cascaded_source_spin(x.Ns, x.gA, x.gB, x.eAm, x.eBm, x.eAs, x.eBs, x.eD, x.Pd, x.Pdo1, x.Pdo2, x.VisF) | ||
return SparseOperator(_bspin⊗_bspin, Complex.(data)) | ||
end | ||
end | ||
|
||
function express_nolookup(x::ZALMSpinPairN, ::QuantumOpticsRepr) | ||
data = cascaded_source_spin(x.Ns, x.gA, x.gB, x.eAm, x.eBm, x.eAs, x.eBs, x.eD, x.Pd, x.Pdo1, x.Pdo2, x.VisF) | ||
return SparseOperator(_bspin⊗_bspin, Complex.(data/tr(data))) | ||
end | ||
|
||
## trace | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here |
||
tr(x::ZALMSpinPairU) = Float64(tr(express(x).data)) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,44 @@ | ||
using QuantumSavory | ||
using QuantumSavory.StatesZoo: ZALMSpinPair, SingleRailMidSwapBell, DualRailMidSwapBell | ||
using QuantumSavory.StatesZoo: ZALMSpinPairU, ZALMSpinPairN, SingleRailMidSwapBellU, SingleRailMidSwapBellN, DualRailMidSwapBellU, DualRailMidSwapBellN | ||
using LinearAlgebra | ||
using Test | ||
|
||
r_zalm = Register(2) | ||
initialize!(r_zalm[1:2], ZALMSpinPair(1e-3, 0.5, 0.5, 1, 1, 1, 1, 0.9, 1e-8, 1e-8, 1e-8, 0.99)) | ||
@test ! iszero(observable(r_zalm[1:2], Z⊗Z)) | ||
zalmU = ZALMSpinPairU(1e-3, 0.5, 0.5, 1, 1, 1, 1, 0.9, 1e-8, 1e-8, 1e-8, 0.99) | ||
zalmN = ZALMSpinPairN(1e-3, 0.5, 0.5, 1, 1, 1, 1, 0.9, 1e-8, 1e-8, 1e-8, 0.99) | ||
srmsU = SingleRailMidSwapBellU(0.9, 0.9, 0.5, 0.5, 1e-8, 0.99) | ||
srmsN = SingleRailMidSwapBellN(0.9, 0.9, 0.5, 0.5, 1e-8, 0.99) | ||
drmsU = DualRailMidSwapBellU(0.9, 0.9, 0.5, 0.5, 1e-8, 0.99) | ||
drmsN = DualRailMidSwapBellN(0.9, 0.9, 0.5, 0.5, 1e-8, 0.99) | ||
|
||
r_srms = Register(2) | ||
initialize!(r_srms[1:2], SingleRailMidSwapBell(0.9, 0.9, 0.5, 0.5, 1e-8, 0.99)) | ||
@test ! iszero(observable(r_srms[1:2], Z⊗Z)) | ||
r_zalmU = Register(2) | ||
initialize!(r_zalmU[1:2], zalmU) | ||
@test ! iszero(observable(r_zalmU[1:2], Z⊗Z)) | ||
|
||
r_drms = Register(2) | ||
initialize!(r_drms[1:2], DualRailMidSwapBell(0.9, 0.9, 0.5, 0.5, 1e-8, 0.99)) | ||
@test ! iszero(observable(r_drms[1:2], Z⊗Z)) | ||
r_zalmN = Register(2) | ||
initialize!(r_zalmN[1:2], zalmN) | ||
@test ! iszero(observable(r_zalmN[1:2], Z⊗Z)) | ||
|
||
r_srmsU = Register(2) | ||
initialize!(r_srmsU[1:2], srmsU) | ||
@test ! iszero(observable(r_srmsU[1:2], Z⊗Z)) | ||
|
||
r_srmsN = Register(2) | ||
initialize!(r_srmsN[1:2], srmsN) | ||
@test ! iszero(observable(r_srmsN[1:2], Z⊗Z)) | ||
|
||
r_drmsU = Register(2) | ||
initialize!(r_drmsU[1:2], drmsU) | ||
@test ! iszero(observable(r_drmsU[1:2], Z⊗Z)) | ||
|
||
r_drmsN = Register(2) | ||
initialize!(r_drmsN[1:2], drmsN) | ||
@test ! iszero(observable(r_drmsN[1:2], Z⊗Z)) | ||
|
||
@test tr(zalmU) < 1.0 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. on the other hand, these should be exactly equal to 1 thanks to a special dispatch rule (so that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wouldn't we still need to use express to convert it to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would prefer if we do not rely on quantumoptics.jl at all for that. In symbolic CAS tools usually 1 and 0 are treated more specially than other numbers. For the normalized density matrices here it is guaranteed that the trace is 1, so I would like to have a special-cased method for them that completely shortcuts any expression functionality.
Please add these special-cased methods for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Abhishek-1Bhatt , bump |
||
@test tr(express(zalmN).data) ≈ 1 | ||
|
||
@test tr(srmsU) < 1.0 | ||
@test tr(express(srmsN).data) ≈ 1.0 | ||
|
||
@test tr(drmsU) < 1.0 | ||
@test tr(express(drmsN).data) ≈ 1.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lets remove these -- unless it is some special constant, it does not make sense to implicitly turn a symbolic object into a float