@@ -671,21 +671,13 @@ function get_coherence(ψ::QuantumObject{<:AbstractArray,KetQuantumObject})
671671 if length (ψ. dims) == 1
672672 return mapreduce (n -> sqrt (n - 1 ) * ψ. data[n] * conj (ψ. data[n- 1 ]), + , 2 : ψ. dims[1 ])
673673 else
674- R = CartesianIndices ((ψ. dims... ,))
675- off = circshift (ψ. dims, 1 )
676- off[end ] = 1
677-
678- x = sum (R) do j
679- j_tuple = Tuple (j) .- 1
680- if 0 in j_tuple
681- return 0
682- end
683-
684- J = dot (j_tuple, off) + 1
685- J2 = dot (j_tuple .- 1 , off) + 1
686- return prod (sqrt .(j_tuple)) * ψ[J] * conj (ψ[J2])
687- end
674+ off = sum (cumprod (reverse (ψ. dims[2 : end ]))) + 1
675+ t = Tuple (reverse (ψ. dims))
688676
677+ x = 0.0im
678+ for J in off+ 2 : length (ψ. data)
679+ x += ψ[J] * conj (ψ[J- off]) * prod (sqrt .(_ind2sub (t, J) .- 1 ))
680+ end
689681 return x
690682 end
691683end
@@ -694,25 +686,26 @@ function get_coherence(ρ::QuantumObject{<:AbstractArray,OperatorQuantumObject})
694686 if length (ρ. dims) == 1
695687 return mapreduce (n -> sqrt (n - 1 ) * ρ. data[n, n- 1 ], + , 2 : ρ. dims[1 ])
696688 else
697- R = CartesianIndices ((ρ. dims... ,))
698- off = circshift (ρ. dims, 1 )
699- off[end ] = 1
700-
701- x = sum (R) do j
702- j_tuple = Tuple (j) .- 1
703- if 0 in j_tuple
704- return 0
705- end
706-
707- J = dot (j_tuple, off) + 1
708- J2 = dot (j_tuple .- 1 , off) + 1
709- return prod (sqrt .(j_tuple)) * ρ[J, J2]
710- end
689+ off = sum (cumprod (reverse (ρ. dims[2 : end ]))) + 1
690+ t = Tuple (reverse (ρ. dims))
711691
692+ x = 0.0im
693+ for J in off+ 2 : length (ρ. data[1 , :])
694+ x += ρ[J, J- off] * prod (sqrt .(_ind2sub (t, J) .- 1 ))
695+ end
712696 return x
713697 end
714698end
715699
700+ function get_coherence (v:: QuantumObject{T,OperatorKetQuantumObject} ) where {T}
701+ if length (v. dims) > 1
702+ throw (ArgumentError (" Mean photon number not implemented for composite OPeratorKetQuantumObject" ))
703+ end
704+
705+ d = v. dims[1 ]
706+ return mapreduce (n -> sqrt (n - 1 ) * v. data[(n- 1 )* d+ n- 1 ], + , 2 : d)
707+ end
708+
716709@doc raw """
717710 remove_coherence(ψ::QuantumObject)
718711
@@ -739,42 +732,45 @@ Get the mean occupation number ``n`` by measuring the expectation value of the n
739732
740733It returns the expectation value of the number operator.
741734"""
742- function mean_occupation (ψ:: QuantumObject{T,KetQuantumObject} ) where {T}
743- if length (ψ. dims) == 1
744- return mapreduce (k -> abs2 (ψ[k]) * (k - 1 ), + , 1 : ρ. dims[1 ])
745- else
746- t = Tuple (ψ. dims)
735+ function mean_occupation (ψ:: QuantumObject{T,KetQuantumObject} ; idx:: Union{Int,Nothing} = nothing ) where {T}
736+ t = Tuple (reverse (ψ. dims))
737+ mean_occ = zeros (length (ψ. dims))
747738
748- x = 0.0
749- for J in eachindex (ψ. data)
750- x += abs2 (ψ[J]) * prod (Base. _ind2sub (t, J) .- 1 )
751- end
752- return real (x)
739+ for J in eachindex (ψ. data)
740+ sub_indices = _ind2sub (t, J) .- 1
741+ mean_occ .+ = abs2 (ψ[J]) .* sub_indices
753742 end
743+ reverse! (mean_occ)
744+
745+ return isnothing (idx) ? mean_occ : mean_occ[idx]
754746end
755747
756- function mean_occupation (ρ:: QuantumObject{T,OperatorQuantumObject} ) where {T}
757- if length (ρ. dims) == 1
758- return real (mapreduce (k -> ρ[k, k] * (k - 1 ), + , 1 : ρ. dims[1 ]))
759- else
760- t = Tuple (ρ. dims)
748+ mean_occupation (ψ:: QuantumObject{T,KetQuantumObject,1} ) where {T} = mapreduce (k -> abs2 (ψ[k]) * (k - 1 ), + , 1 : ψ. dims[1 ])
761749
762- x = 0.0im
763- for J in eachindex (ρ. data[:, 1 ])
764- x += ρ[J, J] * prod (Base. _ind2sub (t, J) .- 1 )
765- end
750+ function mean_occupation (ρ:: QuantumObject{T,OperatorQuantumObject} ; idx:: Union{Int,Nothing} = nothing ) where {T}
751+ t = Tuple (reverse (ρ. dims))
752+ mean_occ = zeros (eltype (ρ. data), length (ρ. dims))
766753
767- return real (x)
754+ x = 0.0im
755+ for J in eachindex (ρ. data[:, 1 ])
756+ sub_indices = _ind2sub (t, J) .- 1
757+ mean_occ .+ = ρ[J, J] .* sub_indices
768758 end
759+ reverse! (mean_occ)
760+
761+ return isnothing (idx) ? real .(mean_occ) : real (mean_occ[idx])
769762end
770763
771- function mean_occupation (ρ:: QuantumObject{T,OperatorKetQuantumObject} ) where {T}
772- if length (ρ. dims) > 1
764+ mean_occupation (ρ:: QuantumObject{T,OperatorQuantumObject,1} ) where {T} =
765+ mapreduce (k -> ρ[k, k] * (k - 1 ), + , 1 : ρ. dims[1 ])
766+
767+ function mean_occupation (v:: QuantumObject{T,OperatorKetQuantumObject} ) where {T}
768+ if length (v. dims) > 1
773769 throw (ArgumentError (" Mean photon number not implemented for composite OPeratorKetQuantumObject" ))
774770 end
775771
776- d = ρ . dims[1 ]
777- return real (mapreduce (k -> ρ [(k- 1 )* r + k] * (k - 1 ), + , 1 : d))
772+ d = v . dims[1 ]
773+ return real (mapreduce (k -> v [(k- 1 )* d + k] * (k - 1 ), + , 1 : d))
778774end
779775
780776@doc raw """
0 commit comments