@@ -32,7 +32,8 @@ T(ρ) = Tr\\{\\sqrt{ρ^† ρ}\\} = \\sum_i |λ_i|
3232
3333where ``λ_i`` are the eigenvalues of `rho`.
3434"""
35- function tracenorm_h (rho:: DenseOpType{B,B} ) where B
35+ function tracenorm_h (rho:: DenseOpType )
36+ check_multiplicable (rho,rho)
3637 s = eigvals (Hermitian (rho. data))
3738 sum (abs .(s))
3839end
@@ -77,7 +78,7 @@ T(ρ,σ) = \\frac{1}{2} Tr\\{\\sqrt{(ρ - σ)^† (ρ - σ)}\\}.
7778It calls [`tracenorm`](@ref) which in turn either uses [`tracenorm_h`](@ref)
7879or [`tracenorm_nh`](@ref) depending if ``ρ-σ`` is hermitian or not.
7980"""
80- tracedistance (rho:: DenseOpType{B,B} , sigma:: DenseOpType{B,B} ) where {B} = 0.5 * tracenorm (rho - sigma)
81+ tracedistance (rho:: DenseOpType , sigma:: DenseOpType ) = ( check_addible (rho,sigma); check_multiplicable (rho,rho); 0.5 * tracenorm (rho - sigma) )
8182function tracedistance (rho:: AbstractOperator , sigma:: AbstractOperator )
8283 throw (ArgumentError (" tracedistance not implemented for $(typeof (rho)) and $(typeof (sigma)) . Use dense operators instead." ))
8384end
@@ -95,7 +96,7 @@ T(ρ,σ) = \\frac{1}{2} Tr\\{\\sqrt{(ρ - σ)^† (ρ - σ)}\\} = \\frac{1}{2} \
9596
9697where ``λ_i`` are the eigenvalues of `rho` - `sigma`.
9798"""
98- tracedistance_h (rho:: DenseOpType{B,B} , sigma:: DenseOpType{B,B} ) where {B} = 0.5 * tracenorm_h (rho - sigma)
99+ tracedistance_h (rho:: DenseOpType , sigma:: DenseOpType ) = ( check_addible (rho,sigma); check_multiplicable (rho,rho); 0.5 * tracenorm_h (rho - sigma) )
99100function tracedistance_h (rho:: AbstractOperator , sigma:: AbstractOperator )
100101 throw (ArgumentError (" tracedistance_h not implemented for $(typeof (rho)) and $(typeof (sigma)) . Use dense operators instead." ))
101102end
@@ -117,12 +118,11 @@ It uses the identity
117118
118119where ``σ_i`` are the singular values of `rho` - `sigma`.
119120"""
120- tracedistance_nh (rho:: DenseOpType{B1,B2} , sigma:: DenseOpType{B1,B2} ) where {B1,B2} = 0.5 * tracenorm_nh (rho - sigma)
121+ tracedistance_nh (rho:: DenseOpType , sigma:: DenseOpType ) = ( check_addible (rho, sigma); 0.5 * tracenorm_nh (rho - sigma) )
121122function tracedistance_nh (rho:: AbstractOperator , sigma:: AbstractOperator )
122123 throw (ArgumentError (" tracedistance_nh not implemented for $(typeof (rho)) and $(typeof (sigma)) . Use dense operators instead." ))
123124end
124125
125-
126126"""
127127 entropy_vn(rho)
128128
@@ -141,7 +141,8 @@ natural logarithm and ``0\\log(0) ≡ 0``.
141141* `rho`: Density operator of which to calculate Von Neumann entropy.
142142* `tol=1e-15`: Tolerance for rounding errors in the computed eigenvalues.
143143"""
144- function entropy_vn (rho:: DenseOpType{B,B} ; tol= 1e-15 ) where B
144+ function entropy_vn (rho:: DenseOpType ; tol= 1e-15 )
145+ check_multiplicable (rho, rho)
145146 evals:: Vector{ComplexF64} = eigvals (rho. data)
146147 entr = zero (eltype (rho))
147148 for d ∈ evals
@@ -164,9 +165,10 @@ The Renyi α-entropy of a density operator is defined as
164165S_α(ρ) = 1/(1-α) \\ log(Tr(ρ^α))
165166```
166167"""
167- function entropy_renyi (rho:: DenseOpType{B,B} , α:: Integer = 2 ) where B
168+ function entropy_renyi (rho:: Operator , α:: Integer = 2 )
168169 α < 0 && throw (ArgumentError (" α-Renyi entropy is defined for α≥0, α≂̸1" ))
169170 α == 1 && throw (ArgumentError (" α-Renyi entropy is defined for α≥0, α≂̸1" ))
171+ check_multiplicable (rho,rho)
170172
171173 return 1 / (1 - α) * log (tr (rho^ α))
172174end
@@ -186,7 +188,12 @@ F(ρ, σ) = Tr\\left(\\sqrt{\\sqrt{ρ}σ\\sqrt{ρ}}\\right),
186188
187189where ``\\ sqrt{ρ}=\\ sum_n\\ sqrt{λ_n}|ψ⟩⟨ψ|``.
188190"""
189- fidelity (rho:: DenseOpType{B,B} , sigma:: DenseOpType{B,B} ) where {B} = tr (sqrt (sqrt (rho. data)* sigma. data* sqrt (rho. data)))
191+ function fidelity (rho:: DenseOpType , sigma:: DenseOpType )
192+ check_multiplicable (rho,rho)
193+ check_multiplicable (sigma,sigma)
194+ check_multiplicable (rho,sigma)
195+ tr (sqrt (sqrt (rho. data)* sigma. data* sqrt (rho. data)))
196+ end
190197
191198
192199"""
@@ -196,7 +203,9 @@ Partial transpose of rho with respect to subsystem specified by indices.
196203
197204The `indices` argument can be a single integer or a collection of integers.
198205"""
199- function ptranspose (rho:: DenseOpType{B,B} , indices= 1 ) where B<: CompositeBasis
206+ function ptranspose (rho:: DenseOpType , indices= 1 )
207+ length (basis_l (rho)) == length (basis_r (rho)) || throw (ArgumentError ())
208+ length (basis_l (rho)) > 1 || throw (ArgumentError ())
200209 # adapted from qutip.partial_transpose (https://qutip.org/docs/4.0.2/modules/qutip/partial_transpose.html)
201210 # works as long as QuantumOptics.jl doesn't change the implementation of `tensor`, i.e. tensor(a,b).data = kron(b.data,a.data)
202211 nsys = length (basis_l (rho))
218227
219228Peres-Horodecki criterion of partial transpose.
220229"""
221- PPT (rho:: DenseOpType{B,B} , index) where B <: CompositeBasis = all (real .(eigvals (ptranspose (rho, index). data)) .>= 0.0 )
230+ PPT (rho:: DenseOpType , index) = all (real .(eigvals (ptranspose (rho, index). data)) .>= 0.0 )
222231
223232
224233"""
@@ -233,7 +242,7 @@ N(ρ) = \\frac{\\|ρᵀ\\|-1}{2},
233242```
234243where `ρᵀ` is the partial transpose.
235244"""
236- negativity (rho:: DenseOpType{B,B} , index) where B <: CompositeBasis = 0.5 * (tracenorm (ptranspose (rho, index)) - 1.0 )
245+ negativity (rho:: DenseOpType , index) = 0.5 * (tracenorm (ptranspose (rho, index)) - 1.0 )
237246
238247
239248"""
@@ -246,7 +255,7 @@ N(ρ) = \\log₂\\|ρᵀ\\|,
246255```
247256where `ρᵀ` is the partial transpose.
248257"""
249- logarithmic_negativity (rho:: DenseOpType{B,B} , index) where B <: CompositeBasis = log (2 , tracenorm (ptranspose (rho, index)))
258+ logarithmic_negativity (rho:: DenseOpType , index) = log (2 , tracenorm (ptranspose (rho, index)))
250259
251260
252261"""
@@ -278,35 +287,16 @@ entanglement_entropy(dm(ket)) = 2 * entanglement_entropy(ket)
278287By default the computed entropy is the Von-Neumann entropy, but a different
279288function can be provided (for example to compute the entanglement-renyi entropy).
280289"""
281- function entanglement_entropy (psi:: Ket{B} , partition, entropy_fun= entropy_vn) where B<: CompositeBasis
282- # check that sites are within the range
283- @assert all (partition .<= length (psi. basis))
284-
285- rho = ptrace (psi, partition)
286- return entropy_fun (rho)
287- end
290+ entanglement_entropy (psi:: Ket , partition, entropy_fun= entropy_vn) = entropy_fun (ptrace (psi, partition))
288291
289- function entanglement_entropy (rho:: DenseOpType{B,B} , partition, args... ) where {B<: CompositeBasis }
290- # check that sites is within the range
291- hilb = rho. basis_l
292- N = length (hilb)
293- all (partition .<= N) || throw (ArgumentError (" Indices in partition must be within the bounds of the composite basis." ))
294- length (partition) <= N || throw (ArgumentError (" Partition cannot include the whole system." ))
292+ function entanglement_entropy (rho:: DenseOpType , partition, args... )
293+ check_multiplicable (rho,rho)
294+ N = length (basis_l (rho))
295295
296296 # build the doubled hilbert space for the vectorised dm, normalized like a Ket.
297- b_doubled = hilb^ 2
298- rho_vec = normalize! (Ket (b_doubled, vec (rho. data)))
299-
300- if partition isa Tuple
301- partition_ = tuple (partition... , (partition.+ N). .. )
302- else
303- partition_ = vcat (partition, partition.+ N)
304- end
305-
306- return entanglement_entropy (rho_vec,partition_,args... )
297+ rho_vec = normalize! (Ket (basis_l (rho)^ 2 , vec (rho. data)))
298+ entanglement_entropy (rho_vec, [partition... , (partition.+ N). .. ], args... )
307299end
308300
309- entanglement_entropy (state:: Ket{B} , partition:: Number , args... ) where B<: CompositeBasis =
310- entanglement_entropy (state, [partition], args... )
311- entanglement_entropy (state:: DenseOpType{B,B} , partition:: Number , args... ) where B<: CompositeBasis =
312- entanglement_entropy (state, [partition], args... )
301+ entanglement_entropy (state:: Ket , partition:: Integer , args... ) = entanglement_entropy (state, [partition], args... )
302+ entanglement_entropy (state:: DenseOpType , partition:: Integer , args... ) = entanglement_entropy (state, [partition], args... )
0 commit comments