Skip to content

Commit

Permalink
Merge pull request #132 from ytdHuang/dev/fidelity
Browse files Browse the repository at this point in the history
  • Loading branch information
ytdHuang authored May 26, 2024
2 parents 6c0f46d + fe1d450 commit a75ba1a
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 2 deletions.
2 changes: 2 additions & 0 deletions docs/src/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ issuper
size
eltype
length
sqrtm
LinearAlgebra.tr
LinearAlgebra.svdvals
LinearAlgebra.norm
Expand All @@ -55,6 +56,7 @@ negativity
entropy_vn
entanglement
expect
fidelity
wigner
get_coherence
n_th
Expand Down
33 changes: 32 additions & 1 deletion src/general_functions.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export get_data, get_coherence, expect, ptrace
export mat2vec, vec2mat
export entropy_vn, entanglement, tracedist
export entropy_vn, entanglement, tracedist, fidelity
export gaussian, n_th

export row_major_reshape, tidyup, tidyup!, meshgrid, sparse_to_dense, dense_to_sparse
Expand Down Expand Up @@ -311,6 +311,37 @@ function expect(
return ishermitian(O) ? real(tr(O * ρ)) : tr(O * ρ)
end

@doc raw"""
fidelity(ρ::QuantumObject, σ::QuantumObject)
Calculate the fidelity of two [`QuantumObject`](@ref):
``F(\rho, \sigma) = \textrm{Tr} \sqrt{\sqrt{\rho} \sigma \sqrt{\rho}}``
Here, the definition is from Nielsen & Chuang, "Quantum Computation and Quantum Information". It is the square root of the fidelity defined in R. Jozsa, Journal of Modern Optics, 41:12, 2315 (1994).
Note that `ρ` and `σ` must be either [`Ket`](@ref) or [`Operator`](@ref).
"""
function fidelity(
ρ::QuantumObject{<:AbstractArray{T1},OperatorQuantumObject},
σ::QuantumObject{<:AbstractArray{T2},OperatorQuantumObject},
) where {T1,T2}
sqrt_ρ = sqrt(ρ)
eigval = abs.(eigvals(sqrt_ρ * σ * sqrt_ρ))
return sum(sqrt, eigval)
end
fidelity(
ρ::QuantumObject{<:AbstractArray{T1},OperatorQuantumObject},
ψ::QuantumObject{<:AbstractArray{T2},KetQuantumObject},
) where {T1,T2} = sqrt(abs(expect(ρ, ψ)))
fidelity(
ψ::QuantumObject{<:AbstractArray{T1},KetQuantumObject},
σ::QuantumObject{<:AbstractArray{T2},OperatorQuantumObject},
) where {T1,T2} = fidelity(σ, ψ)
fidelity(
ψ::QuantumObject{<:AbstractArray{T1},KetQuantumObject},
ϕ::QuantumObject{<:AbstractArray{T2},KetQuantumObject},
) where {T1,T2} = abs(dot(ψ, ϕ))

@doc raw"""
get_coherence(ψ::QuantumObject)
Expand Down
13 changes: 12 additions & 1 deletion src/quantum_object.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export QuantumObjectType,
export Bra, Ket, Operator, OperatorBra, OperatorKet, SuperOperator

export isket, isbra, isoper, isoperbra, isoperket, issuper, ket2dm
export sqrtm
export tensor,

abstract type AbstractQuantumObject end
Expand Down Expand Up @@ -741,7 +742,17 @@ LinearAlgebra.rmul!(B::QuantumObject{<:AbstractArray}, a::Number) = (rmul!(B.dat
@inline LinearAlgebra.mul!(y::AbstractVector{Ty}, A::QuantumObject{<:AbstractMatrix{Ta}}, x, α, β) where {Ty,Ta} =
mul!(y, A.data, x, α, β)

LinearAlgebra.sqrt(A::QuantumObject{<:AbstractArray{T}}) where {T} = QuantumObject(sqrt(A.data), A.type, A.dims)
LinearAlgebra.sqrt(A::QuantumObject{<:AbstractArray{T}}) where {T} =
QuantumObject(sqrt(sparse_to_dense(A.data)), A.type, A.dims)

@doc raw"""
sqrtm(A::QuantumObject)
Matrix square root of [`Operator`](@ref) type of [`QuantumObject`](@ref)
Note that for other types of [`QuantumObject`](@ref) use `sprt(A)` instead.
"""
sqrtm(A::QuantumObject{<:AbstractArray{T},OperatorQuantumObject}) where {T} = sqrt(A)

LinearAlgebra.exp(A::QuantumObject{<:AbstractMatrix{T}}) where {T} =
QuantumObject(dense_to_sparse(exp(A.data)), A.type, A.dims)
Expand Down
10 changes: 10 additions & 0 deletions test/quantum_objects.jl
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,16 @@
@test tracedist(ψz1, ρz0) 1.0
@test tracedist(ρz0, ρz1) 1.0

# sqrtm (sqrt) and fidelity
M = sprand(ComplexF64, 5, 5, 0.5)
M0 = Qobj(M * M')
ψ1 = Qobj(rand(ComplexF64, 5))
ψ2 = Qobj(rand(ComplexF64, 5))
M1 = ψ1 * ψ1'
@test sqrtm(M0) sqrtm(sparse_to_dense(M0))
@test isapprox(fidelity(M0, M1), fidelity(ψ1, M0); atol = 1e-6)
@test isapprox(fidelity(ψ1, ψ2), fidelity(ket2dm(ψ1), ket2dm(ψ2)); atol = 1e-6)

# Broadcasting
a = destroy(20)
for op in ((+), (-), (*), (^))
Expand Down

0 comments on commit a75ba1a

Please sign in to comment.