Skip to content

Commit 4ecf694

Browse files
committed
introduce concurrence
1 parent 46b98de commit 4ecf694

File tree

3 files changed

+59
-12
lines changed

3 files changed

+59
-12
lines changed

docs/src/resources/api.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,8 @@ entropy_linear
259259
entropy_mutual
260260
entropy_conditional
261261
entanglement
262+
concurrence
263+
negativity
262264
tracedist
263265
fidelity
264266
```
@@ -282,7 +284,6 @@ BlockDiagonalForm
282284

283285
```@docs
284286
wigner
285-
negativity
286287
```
287288

288289
## [Linear Maps](@id doc-API:Linear-Maps)

src/entropy.jl

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Entropy related functions.
33
=#
44

55
export entropy_vn, entropy_relative, entropy_linear, entropy_mutual, entropy_conditional
6-
export entanglement
6+
export entanglement, concurrence
77

88
@doc raw"""
99
entropy_vn(ρ::QuantumObject; base::Int=0, tol::Real=1e-15)
@@ -121,7 +121,7 @@ function entropy_relative(
121121

122122
# the relative entropy is guaranteed to be ≥ 0
123123
# so we calculate the value to 0 to avoid small violations of the lower bound.
124-
return max(0.0, dot(p_vals, log_p) - dot(p, P, log_q))
124+
return max(0.0, dot(p_vals, log_p) - dot(p, P, log_q)) # use 0.0 to make sure it always return value in Float-type
125125
end
126126

127127
@doc raw"""
@@ -209,3 +209,28 @@ function entanglement(
209209
val = entropy_vn(ρ_tr; kwargs...)
210210
return (val > 0) * val
211211
end
212+
213+
@doc raw"""
214+
concurrence(ρ::QuantumObject)
215+
216+
Calculate the [concurrence](https://en.wikipedia.org/wiki/Concurrence_(quantum_computing)) for a two-qubit state.
217+
218+
# Notes
219+
220+
- `ρ` can be either a [`Ket`](@ref) or an [`Operator`](@ref).
221+
"""
222+
function concurrence::QuantumObject{OpType}) where {OpType<:Union{KetQuantumObject,OperatorQuantumObject}}
223+
.dimensions == Dimensions((Space(2), Space(2)))) || throw(ArgumentError("The `concurrence` only support for a two-qubit state, invalid dims = $(_get_dims_string.dimensions))."))
224+
225+
= ket2dm(ρ).data
226+
σy = sigmay()
227+
σyσy = kron(σy, σy).data
228+
ρ_tilde = σyσy * conj(_ρ) * σyσy
229+
230+
# we use the alternative way to calculate concurrence (more efficient)
231+
# calculate the square root of each eigenvalues (in decreasing order) of the non-Hermitian matrix: ρ * ρ_tilde
232+
# note that we add abs here to avoid problems with sqrt for very small negative numbers
233+
λ = sqrt.(abs.(real(eigvals(_ρ * ρ_tilde; sortby = x -> -real(x)))))
234+
235+
return max(0.0, λ[1] - λ[2] - λ[3] - λ[4]) # use 0.0 to make sure it always return value in Float-type
236+
end

test/core-test/entropy_and_metric.jl

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,17 +51,38 @@
5151
end
5252
end
5353

54-
@testset "Entanglement" begin
55-
g = fock(2, 1)
56-
e = fock(2, 0)
57-
state = normalize(kron(g, e) + kron(e, g))
58-
rho = state * state'
59-
@test entanglement(state, 1) / log(2) 1
60-
@test entanglement(rho, 1) / log(2) 1
54+
@testset "entanglement and concurrence" begin
55+
# bell state
56+
ψb = bell_state(Val(1), Val(0))
57+
ρb = ket2dm(ψb)
58+
@test entanglement(ψb, 1) / log(2) 1
59+
@test entanglement(ρb, 1) / log(2) 1
60+
@test concurrence(ψb) 1
61+
@test concurrence(ρb) 1
62+
63+
# separable pure state
64+
ψs = kron(rand_ket(2), rand_ket(2))
65+
@test entanglement(ψs, 1) + 1 1
66+
@test entanglement(ψs, 2) + 1 1
67+
@test concurrence(ψs) + 1 1
68+
69+
# this only works for "pure" two-qubit states
70+
ψr = rand_ket((2, 2)) # might be an entangled two-qubit state
71+
val = concurrence(ψr)
72+
@test isapprox(val, sqrt(2 * entropy_linear(ptrace(ψr, 1))); atol = 1e-5) # √(2 * (1 - Tr(ρA^2)))
73+
@test isapprox(val, sqrt(2 * entropy_linear(ptrace(ψr, 2))); atol = 1e-5) # √(2 * (1 - Tr(ρB^2)))
74+
75+
@test_throws ArgumentError concurrence(rand_dm(4))
76+
@test_throws ArgumentError concurrence(rand_dm((2, 3)))
6177

6278
@testset "Type Stability (entanglement)" begin
63-
@inferred entanglement(state, 1)
64-
@inferred entanglement(rho, 1)
79+
@inferred entanglement(ψb, 1)
80+
@inferred entanglement(ρb, 1)
81+
end
82+
83+
@testset "Type Stability (concurrence)" begin
84+
@inferred concurrence(ψb)
85+
@inferred concurrence(ρb)
6586
end
6687
end
6788

0 commit comments

Comments
 (0)