Skip to content

Commit

Permalink
add tests for entanglement entropy
Browse files Browse the repository at this point in the history
  • Loading branch information
araujoms committed Jul 17, 2024
1 parent c8e6fbe commit e25c44b
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 10 deletions.
4 changes: 3 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,16 @@ JuMP = "1.22"
LinearAlgebra = "1"
Nemo = "0.39 - 0.45"
Quadmath = "0.5.10"
Random = "1"
Requires = "1"
Test = "1"
julia = "1.9"

[extras]
DoubleFloats = "497a8b3b-efae-58df-a0af-a86822472b78"
Quadmath = "be4d8f0f-7fa4-5f49-b795-2f01399ab2dd"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["CyclotomicNumbers", "DoubleFloats", "Quadmath", "Test"]
test = ["CyclotomicNumbers", "DoubleFloats", "Quadmath", "Random", "Test"]
37 changes: 36 additions & 1 deletion src/entanglement.jl
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ function entanglement_entropy(ρ::AbstractMatrix{T}, dims::AbstractVector) where
JuMP.set_optimizer(model, Hypatia.Optimizer{Rs})
JuMP.set_attribute(model, "verbose", false)
JuMP.optimize!(model)
return JuMP.objective_value(model), JuMP.value.(σ)
return JuMP.objective_value(model), LA.Hermitian(JuMP.value.(σ))
end

"""
Expand All @@ -113,3 +113,38 @@ function _svec(M::AbstractMatrix, ::Type{R}) where {R} #the weird stuff here is
end
return v
end

"""
_test_entanglement_entropy_qubit(h::Real, ρ::AbstractMatrix, σ::AbstractMatrix)
Tests whether `ρ` is indeed a entangled state whose closest separable state is `σ`.
Reference: Miranowicz and Ishizaka, [arXiv:0805.3134](https://arxiv.org/abs/0805.3134)
"""
function _test_entanglement_entropy_qubit(h, ρ, σ)
R = typeof(h)
λ, U = LA.eigen(σ)
g = zeros(R, 4, 4)
for j = 1:4
for i = 1:j-1
g[i, j] = (λ[i] - λ[j]) / log(λ[i] / λ[j])
end
g[j, j] = λ[j]
end
g = LA.Hermitian(g)
σT = partial_transpose(σ, 2, [2, 2])
λ2, U2 = LA.eigen(σT)
phi = partial_transpose(ketbra(U2[:, 1]), 2, [2, 2])
G = zero(U)
for i = 1:4
for j = 1:4
G += g[i, j] * ketbra(U[:, i]) * phi * ketbra(U[:, j])
end
end
G = LA.Hermitian(G)
x = real(LA.pinv(vec(G)) * vec- ρ))
ρ2 = σ - x * G
ρ_matches = isapprox(ρ2, ρ; rtol = sqrt(Base.rtoldefault(R)))
h_matches = isapprox(h, relative_entropy(ρ2, σ); rtol = sqrt(Base.rtoldefault(R)))
return ρ_matches && h_matches
end
34 changes: 26 additions & 8 deletions test/entanglement.jl
Original file line number Diff line number Diff line change
@@ -1,11 +1,29 @@
@testset "Entanglement " begin
for R in [Float64, Double64, Float128, BigFloat]
T = Complex{R}
ψ = random_state_ket(T, 6)
λ, U, V = schmidt_decomposition(ψ, [2, 3])
@test vec(Diagonal(λ)) kron(U', V') * ψ
ψ = random_state_ket(T, 4)
λ, U, V = schmidt_decomposition(ψ)
@test vec(Diagonal(λ)) kron(U', V') * ψ
@testset "Schmidt decomposition" begin
for R in [Float64, Double64, Float128, BigFloat]
T = Complex{R}
ψ = random_state_ket(T, 6)
λ, U, V = schmidt_decomposition(ψ, [2, 3])
@test vec(Diagonal(λ)) kron(U', V') * ψ
ψ = random_state_ket(T, 4)
λ, U, V = schmidt_decomposition(ψ)
@test vec(Diagonal(λ)) kron(U', V') * ψ
end
end
@testset "Entanglement entropy" begin
for R in [Float64, Double64] #Float128 and BigFloat take too long
Random.seed!(8) #makes all states entangled
ψ = random_state_ket(R, 6)
@test entanglement_entropy(ψ, [2, 3]) entanglement_entropy(ketbra(ψ), [2, 3])[1] atol = 1e-3 rtol = 1e-3
ρ = random_state(R, 4)
h, σ = entanglement_entropy(ρ)
@test Ket._test_entanglement_entropy_qubit(h, ρ, σ)
T = Complex{R}
ψ = random_state_ket(T, 6)
@test entanglement_entropy(ψ, [2, 3]) entanglement_entropy(ketbra(ψ), [2, 3])[1] atol = 1e-3 rtol = 1e-3
ρ = random_state(T, 4)
h, σ = entanglement_entropy(ρ)
@test Ket._test_entanglement_entropy_qubit(h, ρ, σ)
end
end
end

0 comments on commit e25c44b

Please sign in to comment.