From 13071e115e6aa866b37a855dc2f7597b74db51fe Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Thu, 20 Feb 2025 16:02:44 +0900 Subject: [PATCH 1/8] introduce `hilbert_dist` --- docs/src/resources/api.md | 3 +- docs/src/users_guide/states_and_operators.md | 2 +- src/metrics.jl | 48 ++++++++++++++------ 3 files changed, 38 insertions(+), 15 deletions(-) diff --git a/docs/src/resources/api.md b/docs/src/resources/api.md index 4a5ead010..d1a714142 100644 --- a/docs/src/resources/api.md +++ b/docs/src/resources/api.md @@ -259,8 +259,9 @@ entropy_linear entropy_mutual entropy_conditional entanglement -tracedist fidelity +tracedist +hilbert_dist ``` ## [Spin Lattice](@id doc-API:Spin-Lattice) diff --git a/docs/src/users_guide/states_and_operators.md b/docs/src/users_guide/states_and_operators.md index 913f640af..1444eb4fd 100644 --- a/docs/src/users_guide/states_and_operators.md +++ b/docs/src/users_guide/states_and_operators.md @@ -161,7 +161,7 @@ coherent_dm(5, 1.25) thermal_dm(5, 1.25) ``` -`QuantumToolbox` also provides a set of distance metrics for determining how close two density matrix distributions are to each other. Included are the [`fidelity`](@ref), and trace distance ([`tracedist`](@ref)). +`QuantumToolbox` also provides a set of distance metrics (see section [Entropy and Metrics](@ref doc-API:Entropy-and-Metrics) in API page) for determining how close two density matrix distributions are to each other. Included are the [`fidelity`](@ref), and trace distance ([`tracedist`](@ref)). ```@example states_and_operators x = coherent_dm(5, 1.25) diff --git a/src/metrics.jl b/src/metrics.jl index 39ff1e3ad..e49c40778 100644 --- a/src/metrics.jl +++ b/src/metrics.jl @@ -2,7 +2,27 @@ Functions for calculating metrics (distance measures) between states and operators. =# -export tracedist, fidelity +export fidelity +export tracedist, hilbert_dist + +@doc raw""" + fidelity(ρ::QuantumObject, σ::QuantumObject) + +Calculate the fidelity of two [`QuantumObject`](@ref): +``F(\hat{\rho}, \hat{\sigma}) = \textrm{Tr} \sqrt{\sqrt{\hat{\rho}} \hat{\sigma} \sqrt{\hat{\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{OperatorQuantumObject}, σ::QuantumObject{OperatorQuantumObject}) + sqrt_ρ = sqrt(ρ) + eigval = abs.(eigvals(sqrt_ρ * σ * sqrt_ρ)) + return sum(sqrt, eigval) +end +fidelity(ρ::QuantumObject{OperatorQuantumObject}, ψ::QuantumObject{KetQuantumObject}) = sqrt(abs(expect(ρ, ψ))) +fidelity(ψ::QuantumObject{KetQuantumObject}, σ::QuantumObject{OperatorQuantumObject}) = fidelity(σ, ψ) +fidelity(ψ::QuantumObject{KetQuantumObject}, ϕ::QuantumObject{KetQuantumObject}) = abs(dot(ψ, ϕ)) @doc raw""" tracedist(ρ::QuantumObject, σ::QuantumObject) @@ -21,20 +41,22 @@ tracedist( } = norm(ket2dm(ρ) - ket2dm(σ), 1) / 2 @doc raw""" - fidelity(ρ::QuantumObject, σ::QuantumObject) + hilbert_dist(ρ::QuantumObject, σ::QuantumObject) -Calculate the fidelity of two [`QuantumObject`](@ref): -``F(\hat{\rho}, \hat{\sigma}) = \textrm{Tr} \sqrt{\sqrt{\hat{\rho}} \hat{\sigma} \sqrt{\hat{\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). +Calculates the Hilbert-Schmidt distance between two [`QuantumObject`](@ref): +``D_{HS}(\hat{\rho}, \hat{\sigma}) = \textrm{Tr}\left[\hat{A}^\dagger \hat{A}\right]``, where ``\hat{A} = \hat{\rho} - \hat{\sigma}``. Note that `ρ` and `σ` must be either [`Ket`](@ref) or [`Operator`](@ref). """ -function fidelity(ρ::QuantumObject{OperatorQuantumObject}, σ::QuantumObject{OperatorQuantumObject}) - sqrt_ρ = sqrt(ρ) - eigval = abs.(eigvals(sqrt_ρ * σ * sqrt_ρ)) - return sum(sqrt, eigval) +function hilbert_dist( + ρ::QuantumObject{ObjType1}, + σ::QuantumObject{ObjType2}, +) where { + ObjType1<:Union{KetQuantumObject,OperatorQuantumObject}, + ObjType2<:Union{KetQuantumObject,OperatorQuantumObject}, +} + check_dimensions(ρ, σ) + + A = ket2dm(ρ) - ket2dm(σ) + return tr(A' * A) end -fidelity(ρ::QuantumObject{OperatorQuantumObject}, ψ::QuantumObject{KetQuantumObject}) = sqrt(abs(expect(ρ, ψ))) -fidelity(ψ::QuantumObject{KetQuantumObject}, σ::QuantumObject{OperatorQuantumObject}) = fidelity(σ, ψ) -fidelity(ψ::QuantumObject{KetQuantumObject}, ϕ::QuantumObject{KetQuantumObject}) = abs(dot(ψ, ϕ)) From c30cdfcccf83256dcad1a0ac285fe24e002f4bb6 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Thu, 20 Feb 2025 16:06:35 +0900 Subject: [PATCH 2/8] add reference for `hilbert_dist` --- docs/src/resources/bibliography.bib | 15 +++++++++++++++ src/metrics.jl | 3 +++ 2 files changed, 18 insertions(+) diff --git a/docs/src/resources/bibliography.bib b/docs/src/resources/bibliography.bib index e8386a703..cfe103337 100644 --- a/docs/src/resources/bibliography.bib +++ b/docs/src/resources/bibliography.bib @@ -81,3 +81,18 @@ @book{Wiseman2009Quantum year={2009}, month=nov } + +@article{Vedral-Plenio1998, + title = {Entanglement measures and purification procedures}, + author = {Vedral, V. and Plenio, M. B.}, + journal = {Phys. Rev. A}, + volume = {57}, + issue = {3}, + pages = {1619--1633}, + numpages = {0}, + year = {1998}, + month = {Mar}, + publisher = {American Physical Society}, + doi = {10.1103/PhysRevA.57.1619}, + url = {https://link.aps.org/doi/10.1103/PhysRevA.57.1619} +} diff --git a/src/metrics.jl b/src/metrics.jl index e49c40778..044c11b38 100644 --- a/src/metrics.jl +++ b/src/metrics.jl @@ -47,6 +47,9 @@ Calculates the Hilbert-Schmidt distance between two [`QuantumObject`](@ref): ``D_{HS}(\hat{\rho}, \hat{\sigma}) = \textrm{Tr}\left[\hat{A}^\dagger \hat{A}\right]``, where ``\hat{A} = \hat{\rho} - \hat{\sigma}``. Note that `ρ` and `σ` must be either [`Ket`](@ref) or [`Operator`](@ref). + +# References +- [Vedral-Plenio1998](@citet) """ function hilbert_dist( ρ::QuantumObject{ObjType1}, From 47e37e32776bb8e5e7d0251b4825435785c119e9 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Thu, 20 Feb 2025 16:27:44 +0900 Subject: [PATCH 3/8] introduce `bures_dist` and `bures_angle` --- docs/src/resources/api.md | 2 ++ src/metrics.jl | 27 ++++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/docs/src/resources/api.md b/docs/src/resources/api.md index d1a714142..b37687d1a 100644 --- a/docs/src/resources/api.md +++ b/docs/src/resources/api.md @@ -262,6 +262,8 @@ entanglement fidelity tracedist hilbert_dist +bures_dist +bures_angle ``` ## [Spin Lattice](@id doc-API:Spin-Lattice) diff --git a/src/metrics.jl b/src/metrics.jl index 044c11b38..a4a400dda 100644 --- a/src/metrics.jl +++ b/src/metrics.jl @@ -4,6 +4,7 @@ Functions for calculating metrics (distance measures) between states and operato export fidelity export tracedist, hilbert_dist +export bures_dist, bures_angle @doc raw""" fidelity(ρ::QuantumObject, σ::QuantumObject) @@ -11,7 +12,7 @@ export tracedist, hilbert_dist Calculate the fidelity of two [`QuantumObject`](@ref): ``F(\hat{\rho}, \hat{\sigma}) = \textrm{Tr} \sqrt{\sqrt{\hat{\rho}} \hat{\sigma} \sqrt{\hat{\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). +Here, the definition is from [Nielsen-Chuang2011](@citet). It is the square root of the fidelity defined in [Jozsa1994](@citet). Note that `ρ` and `σ` must be either [`Ket`](@ref) or [`Operator`](@ref). """ @@ -63,3 +64,27 @@ function hilbert_dist( A = ket2dm(ρ) - ket2dm(σ) return tr(A' * A) end + +@doc raw""" + bures_dist(ρ::QuantumObject, σ::QuantumObject) + +Calculate the [Bures distance](https://en.wikipedia.org/wiki/Bures_metric) between two [`QuantumObject`](@ref): +``D_B(\hat{\rho}, \hat{\sigma}) = \sqrt{2 \left(1 - F(\hat{\rho}, \hat{\sigma}) \right)}`` + +Here, the definition of [`fidelity`](@ref) ``F`` is from [Nielsen-Chuang2011](@citet). It is the square root of the fidelity defined in [Jozsa1994](@citet). + +Note that `ρ` and `σ` must be either [`Ket`](@ref) or [`Operator`](@ref). +""" +bures_dist(ρ::QuantumObject, σ::QuantumObject) = sqrt(2 * (1 - fidelity(ρ, σ))) + +@doc raw""" + bures_angle(ρ::QuantumObject, σ::QuantumObject) + +Calculate the [Bures angle](https://en.wikipedia.org/wiki/Bures_metric) between two [`QuantumObject`](@ref): +``D_A(\hat{\rho}, \hat{\sigma}) = \arccos\left(F(\hat{\rho}, \hat{\sigma})\right)`` + +Here, the definition of [`fidelity`](@ref) ``F`` is from [Nielsen-Chuang2011](@citet). It is the square root of the fidelity defined in [Jozsa1994](@citet). + +Note that `ρ` and `σ` must be either [`Ket`](@ref) or [`Operator`](@ref). +""" +bures_angle(ρ::QuantumObject, σ::QuantumObject) = acos(fidelity(ρ, σ)) From 93a24a85817a55e1f2168c9ed0cb317e7df70a62 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Thu, 20 Feb 2025 16:57:00 +0900 Subject: [PATCH 4/8] introduce `hellinger_dist` --- docs/src/resources/api.md | 1 + docs/src/resources/bibliography.bib | 8 ++++++++ src/metrics.jl | 29 ++++++++++++++++++++++++++++- 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/docs/src/resources/api.md b/docs/src/resources/api.md index b37687d1a..c7003d428 100644 --- a/docs/src/resources/api.md +++ b/docs/src/resources/api.md @@ -262,6 +262,7 @@ entanglement fidelity tracedist hilbert_dist +hellinger_dist bures_dist bures_angle ``` diff --git a/docs/src/resources/bibliography.bib b/docs/src/resources/bibliography.bib index cfe103337..2f55bbf57 100644 --- a/docs/src/resources/bibliography.bib +++ b/docs/src/resources/bibliography.bib @@ -96,3 +96,11 @@ @article{Vedral-Plenio1998 doi = {10.1103/PhysRevA.57.1619}, url = {https://link.aps.org/doi/10.1103/PhysRevA.57.1619} } + +@article{Spehner2017, + title={Geometric measures of quantum correlations with Bures and Hellinger distances}, + author={D. Spehner and F. Illuminati and M. Orszag and W. Roga}, + year={2017}, + journal={arXiv:1611.03449}, + url={https://arxiv.org/abs/1611.03449}, +} diff --git a/src/metrics.jl b/src/metrics.jl index a4a400dda..7e391b7aa 100644 --- a/src/metrics.jl +++ b/src/metrics.jl @@ -3,7 +3,7 @@ Functions for calculating metrics (distance measures) between states and operato =# export fidelity -export tracedist, hilbert_dist +export tracedist, hilbert_dist, hellinger_dist export bures_dist, bures_angle @doc raw""" @@ -65,6 +65,33 @@ function hilbert_dist( return tr(A' * A) end +@doc raw""" + hellinger_dist(ρ::QuantumObject, σ::QuantumObject) + +Calculates the [Hellinger distance](https://en.wikipedia.org/wiki/Hellinger_distance) between two [`QuantumObject`](@ref): +``D_H(\hat{\rho}, \hat{\sigma}) = \sqrt{2 - 2 \textrm{Tr}\left(\sqrt{\hat{\rho}}\sqrt{\hat{\sigma}}\right)}`` + +Note that `ρ` and `σ` must be either [`Ket`](@ref) or [`Operator`](@ref). + +# References +- [Spehner2017](@citet) +""" +function hellinger_dist( + ρ::QuantumObject{ObjType1}, + σ::QuantumObject{ObjType2}, +) where { + ObjType1<:Union{KetQuantumObject,OperatorQuantumObject}, + ObjType2<:Union{KetQuantumObject,OperatorQuantumObject}, +} + # Ket (pure state) doesn't need to do square root + sqrt_ρ = (ρ isa KetQuantumObject) ? ket2dm(ρ) : sqrt(ρ) + sqrt_σ = (σ isa KetQuantumObject) ? ket2dm(σ) : sqrt(σ) + + # `max` is to avoid numerical instabilities + # it happens when ρ = σ, sum(eigvals) might be slightly larger than 1 + return sqrt(2.0 * max(0.0, 1.0 - sum(real, eigvals(sqrt_ρ * sqrt_σ)))) +end + @doc raw""" bures_dist(ρ::QuantumObject, σ::QuantumObject) From 350caae1818156aa8f4e28ad678364d1d28c38cc Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Thu, 20 Feb 2025 18:25:31 +0900 Subject: [PATCH 5/8] fix typo in `hellinger_dist` --- src/metrics.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/metrics.jl b/src/metrics.jl index 7e391b7aa..d9462682f 100644 --- a/src/metrics.jl +++ b/src/metrics.jl @@ -84,8 +84,8 @@ function hellinger_dist( ObjType2<:Union{KetQuantumObject,OperatorQuantumObject}, } # Ket (pure state) doesn't need to do square root - sqrt_ρ = (ρ isa KetQuantumObject) ? ket2dm(ρ) : sqrt(ρ) - sqrt_σ = (σ isa KetQuantumObject) ? ket2dm(σ) : sqrt(σ) + sqrt_ρ = isket(ρ) ? ket2dm(ρ) : sqrt(ρ) + sqrt_σ = isket(σ) ? ket2dm(σ) : sqrt(σ) # `max` is to avoid numerical instabilities # it happens when ρ = σ, sum(eigvals) might be slightly larger than 1 From 7dcbf35b111f85588fb730f19be118b0298f5f65 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Thu, 20 Feb 2025 18:25:52 +0900 Subject: [PATCH 6/8] add tests for new metric functions --- test/core-test/entropy_and_metric.jl | 69 +++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 7 deletions(-) diff --git a/test/core-test/entropy_and_metric.jl b/test/core-test/entropy_and_metric.jl index 5225c5ea2..b9fc345b1 100644 --- a/test/core-test/entropy_and_metric.jl +++ b/test/core-test/entropy_and_metric.jl @@ -65,7 +65,7 @@ end end end -@testset "trace distance" begin +@testset "trace and Hilbert-Schmidt distance" begin ψz0 = basis(2, 0) ψz1 = basis(2, 1) ρz0 = to_sparse(ket2dm(ψz0)) @@ -76,26 +76,81 @@ end @test tracedist(ψz1, ρz0) ≈ 1.0 @test tracedist(ρz0, ρz1) ≈ 1.0 + ψ = rand_ket(10) + ϕ = rand_ket(10) + @test isapprox(tracedist(ψ, ϕ)^2, hilbert_dist(ψ, ϕ) / 2; atol = 1e-6) + @testset "Type Inference (trace distance)" begin @inferred tracedist(ψz0, ψx0) @inferred tracedist(ρz0, ψz1) @inferred tracedist(ψz1, ρz0) @inferred tracedist(ρz0, ρz1) end + + @testset "Type Inference (Hilbert-Schmidt distance)" begin + @inferred hilbert_dist(ψz0, ψx0) + @inferred hilbert_dist(ρz0, ψz1) + @inferred hilbert_dist(ψz1, ρz0) + @inferred hilbert_dist(ρz0, ρz1) + end end -@testset "fidelity" begin - M = sprand(ComplexF64, 5, 5, 0.5) - M0 = Qobj(M * M') - ψ1 = Qobj(rand(ComplexF64, 5)) - ψ2 = Qobj(rand(ComplexF64, 5)) - M1 = ψ1 * ψ1' +@testset "fidelity, Bures metric, and Hellinger distance" begin + M0 = rand_dm(5) + ψ1 = rand_ket(5) + ψ2 = rand_ket(5) + M1 = ket2dm(ψ1) + b00 = bell_state(Val(0), Val(0)) + b01 = bell_state(Val(0), Val(1)) @test isapprox(fidelity(M0, M1), fidelity(ψ1, M0); atol = 1e-6) @test isapprox(fidelity(ψ1, ψ2), fidelity(ket2dm(ψ1), ket2dm(ψ2)); atol = 1e-6) + @test isapprox(fidelity(b00, b00), 1; atol = 1e-6) + @test isapprox(bures_dist(b00, b00) + 1, 1; atol = 1e-6) + @test isapprox(bures_angle(b00, b00) + 1, 1; atol = 1e-6) + @test isapprox(hellinger_dist(b00, b00) + 1, 1; atol = 1e-6) + @test isapprox(fidelity(b00, b01) + 1, 1; atol = 1e-6) + @test isapprox(bures_dist(b00, b01), √2; atol = 1e-6) + @test isapprox(bures_angle(b00, b01), π / 2; atol = 1e-6) + @test isapprox(hellinger_dist(b00, b01), √2; atol = 1e-6) + + # some relations between Bures and Hellinger dintances + # together with some monotonicity under tensor products + # [see arXiv:1611.03449 (2017); section 4.2] + ρA = rand_dm(5) + ρB = rand_dm(6) + ρAB = tensor(ρA, ρB) + σA = rand_dm(5) + σB = rand_dm(6) + σAB = tensor(σA, σB) + d_Bu_A = bures_dist(ρA, σA) + d_Bu_AB = bures_dist(ρAB, σAB) + d_He_A = hellinger_dist(ρA, σA) + d_He_AB = hellinger_dist(ρAB, σAB) + @test isapprox(fidelity(ρAB, σAB), fidelity(ρA, σA) * fidelity(ρB, σB); atol = 1e-6) + @test d_He_AB >= d_Bu_AB + @test d_Bu_AB >= d_Bu_A + @test isapprox(bures_dist(ρAB, tensor(σA, ρB)), d_Bu_A; atol = 1e-6) + @test d_He_AB >= d_He_A + @test isapprox(hellinger_dist(ρAB, tensor(σA, ρB)), d_He_A; atol = 1e-6) @testset "Type Inference (fidelity)" begin @inferred fidelity(M0, M1) @inferred fidelity(ψ1, M0) @inferred fidelity(ψ1, ψ2) end + + @testset "Type Inference (Hellinger distance)" begin + @inferred hellinger_dist(M0, M1) + @inferred hellinger_dist(ψ1, M0) + @inferred hellinger_dist(ψ1, ψ2) + end + + @testset "Type Inference (Bures metric)" begin + @inferred bures_dist(M0, M1) + @inferred bures_dist(ψ1, M0) + @inferred bures_dist(ψ1, ψ2) + @inferred bures_angle(M0, M1) + @inferred bures_angle(ψ1, M0) + @inferred bures_angle(ψ1, ψ2) + end end From d777c064b87ea32ebf8337b095995a07c36af3b6 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Thu, 20 Feb 2025 18:34:09 +0900 Subject: [PATCH 7/8] minor change in docs --- docs/src/users_guide/states_and_operators.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/users_guide/states_and_operators.md b/docs/src/users_guide/states_and_operators.md index 1444eb4fd..f52c1e978 100644 --- a/docs/src/users_guide/states_and_operators.md +++ b/docs/src/users_guide/states_and_operators.md @@ -161,7 +161,7 @@ coherent_dm(5, 1.25) thermal_dm(5, 1.25) ``` -`QuantumToolbox` also provides a set of distance metrics (see section [Entropy and Metrics](@ref doc-API:Entropy-and-Metrics) in API page) for determining how close two density matrix distributions are to each other. Included are the [`fidelity`](@ref), and trace distance ([`tracedist`](@ref)). +`QuantumToolbox` also provides a set of distance metrics for determining how close two density matrix distributions are to each other. For example, [`fidelity`](@ref), and trace distance ([`tracedist`](@ref)) are included. For more metric functions, see section [Entropy and Metrics](@ref doc-API:Entropy-and-Metrics) in the API page. ```@example states_and_operators x = coherent_dm(5, 1.25) From dc6454fa7096d9cd8008571e73f1407b344e7c25 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Fri, 21 Feb 2025 11:16:09 +0900 Subject: [PATCH 8/8] update changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7226dbdc2..e47df2f05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `entropy_conditional` - `entropy_relative` - Fix `entanglement` and introduce `concurrence`. ([#414], [#418], [#419]) +- Introduce some metric functions. ([#414], [#420]) + - `hilbert_dist` + - `hellinger_dist` + - `bures_dist` + - `bures_angle` ## [v0.27.0] Release date: 2025-02-14 @@ -159,3 +164,4 @@ Release date: 2024-11-13 [#416]: https://github.com/qutip/QuantumToolbox.jl/issues/416 [#418]: https://github.com/qutip/QuantumToolbox.jl/issues/418 [#419]: https://github.com/qutip/QuantumToolbox.jl/issues/419 +[#420]: https://github.com/qutip/QuantumToolbox.jl/issues/420