Skip to content

Commit 0d91c32

Browse files
author
Adria Labay
committed
return list of mean occupation per dimension
1 parent ae029d4 commit 0d91c32

File tree

2 files changed

+66
-60
lines changed

2 files changed

+66
-60
lines changed

src/qobj/arithmetic_and_attributes.jl

Lines changed: 48 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -705,21 +705,13 @@ function get_coherence(ψ::QuantumObject{<:AbstractArray,KetQuantumObject})
705705
if length.dims) == 1
706706
return mapreduce(n -> sqrt(n - 1) * ψ.data[n] * conj.data[n-1]), +, 2:ψ.dims[1])
707707
else
708-
R = CartesianIndices((ψ.dims...,))
709-
off = circshift.dims, 1)
710-
off[end] = 1
711-
712-
x = sum(R) do j
713-
j_tuple = Tuple(j) .- 1
714-
if 0 in j_tuple
715-
return 0
716-
end
717-
718-
J = dot(j_tuple, off) + 1
719-
J2 = dot(j_tuple .- 1, off) + 1
720-
return prod(sqrt.(j_tuple)) * ψ[J] * conj(ψ[J2])
721-
end
708+
off = sum(cumprod(reverse.dims[2:end]))) + 1
709+
t = Tuple(reverse.dims))
722710

711+
x = 0.0im
712+
for J in off+2:length.data)
713+
x += ψ[J] * conj(ψ[J-off]) * prod(sqrt.(_ind2sub(t, J) .- 1))
714+
end
723715
return x
724716
end
725717
end
@@ -728,25 +720,26 @@ function get_coherence(ρ::QuantumObject{<:AbstractArray,OperatorQuantumObject})
728720
if length.dims) == 1
729721
return mapreduce(n -> sqrt(n - 1) * ρ.data[n, n-1], +, 2:ρ.dims[1])
730722
else
731-
R = CartesianIndices((ρ.dims...,))
732-
off = circshift.dims, 1)
733-
off[end] = 1
734-
735-
x = sum(R) do j
736-
j_tuple = Tuple(j) .- 1
737-
if 0 in j_tuple
738-
return 0
739-
end
740-
741-
J = dot(j_tuple, off) + 1
742-
J2 = dot(j_tuple .- 1, off) + 1
743-
return prod(sqrt.(j_tuple)) * ρ[J, J2]
744-
end
723+
off = sum(cumprod(reverse.dims[2:end]))) + 1
724+
t = Tuple(reverse.dims))
745725

726+
x = 0.0im
727+
for J in off+2:length.data[1, :])
728+
x += ρ[J, J-off] * prod(sqrt.(_ind2sub(t, J) .- 1))
729+
end
746730
return x
747731
end
748732
end
749733

734+
function get_coherence(v::QuantumObject{T,OperatorKetQuantumObject}) where {T}
735+
if length(v.dims) > 1
736+
throw(ArgumentError("Mean photon number not implemented for composite OPeratorKetQuantumObject"))
737+
end
738+
739+
d = v.dims[1]
740+
return mapreduce(n -> sqrt(n - 1) * v.data[(n-1)*d+n-1], +, 2:d)
741+
end
742+
750743
@doc raw"""
751744
remove_coherence(ψ::QuantumObject)
752745
@@ -773,42 +766,45 @@ Get the mean occupation number ``n`` by measuring the expectation value of the n
773766
774767
It returns the expectation value of the number operator.
775768
"""
776-
function mean_occupation::QuantumObject{T,KetQuantumObject}) where {T}
777-
if length.dims) == 1
778-
return mapreduce(k -> abs2(ψ[k]) * (k - 1), +, 1:ρ.dims[1])
779-
else
780-
t = Tuple.dims)
769+
function mean_occupation::QuantumObject{T,KetQuantumObject}; idx::Union{Int,Nothing} = nothing) where {T}
770+
t = Tuple(reverse.dims))
771+
mean_occ = zeros(length.dims))
781772

782-
x = 0.0
783-
for J in eachindex.data)
784-
x += abs2(ψ[J]) * prod(Base._ind2sub(t, J) .- 1)
785-
end
786-
return real(x)
773+
for J in eachindex.data)
774+
sub_indices = _ind2sub(t, J) .- 1
775+
mean_occ .+= abs2(ψ[J]) .* sub_indices
787776
end
777+
reverse!(mean_occ)
778+
779+
return isnothing(idx) ? mean_occ : mean_occ[idx]
788780
end
789781

790-
function mean_occupation::QuantumObject{T,OperatorQuantumObject}) where {T}
791-
if length.dims) == 1
792-
return real(mapreduce(k -> ρ[k, k] * (k - 1), +, 1:ρ.dims[1]))
793-
else
794-
t = Tuple.dims)
782+
mean_occupation::QuantumObject{T,KetQuantumObject,1}) where {T} = mapreduce(k -> abs2(ψ[k]) * (k - 1), +, 1:ψ.dims[1])
795783

796-
x = 0.0im
797-
for J in eachindex.data[:, 1])
798-
x += ρ[J, J] * prod(Base._ind2sub(t, J) .- 1)
799-
end
784+
function mean_occupation::QuantumObject{T,OperatorQuantumObject}; idx::Union{Int,Nothing} = nothing) where {T}
785+
t = Tuple(reverse.dims))
786+
mean_occ = zeros(eltype.data), length.dims))
800787

801-
return real(x)
788+
x = 0.0im
789+
for J in eachindex.data[:, 1])
790+
sub_indices = _ind2sub(t, J) .- 1
791+
mean_occ .+= ρ[J, J] .* sub_indices
802792
end
793+
reverse!(mean_occ)
794+
795+
return isnothing(idx) ? real.(mean_occ) : real(mean_occ[idx])
803796
end
804797

805-
function mean_occupation::QuantumObject{T,OperatorKetQuantumObject}) where {T}
806-
if length.dims) > 1
798+
mean_occupation::QuantumObject{T,OperatorQuantumObject,1}) where {T} =
799+
mapreduce(k -> ρ[k, k] * (k - 1), +, 1:ρ.dims[1])
800+
801+
function mean_occupation(v::QuantumObject{T,OperatorKetQuantumObject}) where {T}
802+
if length(v.dims) > 1
807803
throw(ArgumentError("Mean photon number not implemented for composite OPeratorKetQuantumObject"))
808804
end
809805

810-
d = ρ.dims[1]
811-
return real(mapreduce(k -> ρ[(k-1)*r+k] * (k - 1), +, 1:d))
806+
d = v.dims[1]
807+
return real(mapreduce(k -> v[(k-1)*d+k] * (k - 1), +, 1:d))
812808
end
813809

814810
@doc raw"""

test/core-test/quantum_objects.jl

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -476,13 +476,17 @@
476476
ρ1 = ket2dm(ψ1)
477477
v1 = mat2vec(ρ1)
478478

479-
@test mean_occupation(ψ) N1
480-
@test mean_occupation(ρ) N1
481-
@test mean_occupation(v) N1
479+
@test mean_occupation(ψ1) N1
480+
@test mean_occupation(ρ1) N1
481+
@test mean_occupation(v1) N1
482482

483483
N2 = 4.0
484484
Nc = N1 * N2
485+
Ns = [N1, N2]
485486
ψ2 = coherent(30, 2.0)
487+
ρ2 = ket2dm(ψ2)
488+
v2 = mat2vec(ρ2)
489+
486490
ψc = ψ1 ψ2
487491
ρc = ket2dm(ψc)
488492
vc = mat2vec(ρc)
@@ -491,13 +495,19 @@
491495
@test mean_occupation(ρ2) N2
492496
@test mean_occupation(v2) N2
493497

494-
@test mean_occupation(ψc) Nc
495-
@test mean_occupation(ρc) Nc
498+
@test mean_occupation(ψc) Ns
499+
@test mean_occupation(ρc) Ns
500+
@test prod(mean_occupation(ψc)) Nc
501+
@test prod(mean_occupation(ρc)) Nc
502+
@test mean_occupation(ψc, idx = 1) N1
503+
@test mean_occupation(ρc, idx = 1) N1
504+
@test mean_occupation(ψc, idx = 2) N2
505+
@test mean_occupation(ρc, idx = 2) N2
496506

497507
@testset "Type Inference (mean_occupation)" begin
498-
@inferred mean_occupation(ψ)
499-
@inferred mean_occupation(ρ)
500-
@inferred mean_occupation(v)
508+
@inferred mean_occupation(ψ1)
509+
@inferred mean_occupation(ρ1)
510+
@inferred mean_occupation(v1)
501511
end
502512
end
503513

0 commit comments

Comments
 (0)