@@ -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
@@ -163,9 +164,10 @@ The Renyi α-entropy of a density operator is defined as
163164S_α(ρ) = 1/(1-α) \\ log(Tr(ρ^α))
164165```
165166"""
166- function entropy_renyi (rho:: DenseOpType{B,B} , α:: Integer = 2 ) where B
167+ function entropy_renyi (rho:: Operator , α:: Integer = 2 )
167168 α < 0 && throw (ArgumentError (" α-Renyi entropy is defined for α≥0, α≂̸1" ))
168169 α == 1 && throw (ArgumentError (" α-Renyi entropy is defined for α≥0, α≂̸1" ))
170+ check_multiplicable (rho,rho)
169171
170172 return 1 / (1 - α) * log (tr (rho^ α))
171173end
@@ -185,7 +187,12 @@ F(ρ, σ) = Tr\\left(\\sqrt{\\sqrt{ρ}σ\\sqrt{ρ}}\\right),
185187
186188where ``\\ sqrt{ρ}=\\ sum_n\\ sqrt{λ_n}|ψ⟩⟨ψ|``.
187189"""
188- fidelity (rho:: DenseOpType{B,B} , sigma:: DenseOpType{B,B} ) where {B} = tr (sqrt (sqrt (rho. data)* sigma. data* sqrt (rho. data)))
190+ function fidelity (rho:: DenseOpType , sigma:: DenseOpType )
191+ check_multiplicable (rho,rho)
192+ check_multiplicable (sigma,sigma)
193+ check_multiplicable (rho,sigma)
194+ tr (sqrt (sqrt (rho. data)* sigma. data* sqrt (rho. data)))
195+ end
189196
190197
191198"""
@@ -195,7 +202,9 @@ Partial transpose of rho with respect to subsystem specified by indices.
195202
196203The `indices` argument can be a single integer or a collection of integers.
197204"""
198- function ptranspose (rho:: DenseOpType{B,B} , indices= 1 ) where B<: CompositeBasis
205+ function ptranspose (rho:: DenseOpType , indices= 1 )
206+ length (basis_l (rho)) == length (basis_r (rho)) || throw (ArgumentError ())
207+ length (basis_l (rho)) > 1 || throw (ArgumentError ())
199208 # adapted from qutip.partial_transpose (https://qutip.org/docs/4.0.2/modules/qutip/partial_transpose.html)
200209 # works as long as QuantumOptics.jl doesn't change the implementation of `tensor`, i.e. tensor(a,b).data = kron(b.data,a.data)
201210 nsys = length (basis_l (rho))
217226
218227Peres-Horodecki criterion of partial transpose.
219228"""
220- PPT (rho:: DenseOpType{B,B} , index) where B <: CompositeBasis = all (real .(eigvals (ptranspose (rho, index). data)) .>= 0.0 )
229+ PPT (rho:: DenseOpType , index) = all (real .(eigvals (ptranspose (rho, index). data)) .>= 0.0 )
221230
222231
223232"""
@@ -232,7 +241,7 @@ N(ρ) = \\frac{\\|ρᵀ\\|-1}{2},
232241```
233242where `ρᵀ` is the partial transpose.
234243"""
235- negativity (rho:: DenseOpType{B,B} , index) where B <: CompositeBasis = 0.5 * (tracenorm (ptranspose (rho, index)) - 1.0 )
244+ negativity (rho:: DenseOpType , index) = 0.5 * (tracenorm (ptranspose (rho, index)) - 1.0 )
236245
237246
238247"""
@@ -245,7 +254,7 @@ N(ρ) = \\log₂\\|ρᵀ\\|,
245254```
246255where `ρᵀ` is the partial transpose.
247256"""
248- logarithmic_negativity (rho:: DenseOpType{B,B} , index) where B <: CompositeBasis = log (2 , tracenorm (ptranspose (rho, index)))
257+ logarithmic_negativity (rho:: DenseOpType , index) = log (2 , tracenorm (ptranspose (rho, index)))
249258
250259
251260"""
@@ -277,35 +286,16 @@ entanglement_entropy(dm(ket)) = 2 * entanglement_entropy(ket)
277286By default the computed entropy is the Von-Neumann entropy, but a different
278287function can be provided (for example to compute the entanglement-renyi entropy).
279288"""
280- function entanglement_entropy (psi:: Ket{B} , partition, entropy_fun= entropy_vn) where B<: CompositeBasis
281- # check that sites are within the range
282- @assert all (partition .<= length (psi. basis))
283-
284- rho = ptrace (psi, partition)
285- return entropy_fun (rho)
286- end
289+ entanglement_entropy (psi:: Ket , partition, entropy_fun= entropy_vn) = entropy_fun (ptrace (psi, partition))
287290
288- function entanglement_entropy (rho:: DenseOpType{B,B} , partition, args... ) where {B<: CompositeBasis }
289- # check that sites is within the range
290- hilb = rho. basis_l
291- N = length (hilb)
292- all (partition .<= N) || throw (ArgumentError (" Indices in partition must be within the bounds of the composite basis." ))
293- length (partition) <= N || throw (ArgumentError (" Partition cannot include the whole system." ))
291+ function entanglement_entropy (rho:: DenseOpType , partition, args... )
292+ check_multiplicable (rho,rho)
293+ N = length (basis_l (rho))
294294
295295 # build the doubled hilbert space for the vectorised dm, normalized like a Ket.
296- b_doubled = hilb^ 2
297- rho_vec = normalize! (Ket (b_doubled, vec (rho. data)))
298-
299- if partition isa Tuple
300- partition_ = tuple (partition... , (partition.+ N). .. )
301- else
302- partition_ = vcat (partition, partition.+ N)
303- end
304-
305- return entanglement_entropy (rho_vec,partition_,args... )
296+ rho_vec = normalize! (Ket (basis_l (rho)^ 2 , vec (rho. data)))
297+ entanglement_entropy (rho_vec, [partition... , (partition.+ N). .. ], args... )
306298end
307299
308- entanglement_entropy (state:: Ket{B} , partition:: Number , args... ) where B<: CompositeBasis =
309- entanglement_entropy (state, [partition], args... )
310- entanglement_entropy (state:: DenseOpType{B,B} , partition:: Number , args... ) where B<: CompositeBasis =
311- entanglement_entropy (state, [partition], args... )
300+ entanglement_entropy (state:: Ket , partition:: Integer , args... ) = entanglement_entropy (state, [partition], args... )
301+ entanglement_entropy (state:: DenseOpType , partition:: Integer , args... ) = entanglement_entropy (state, [partition], args... )
0 commit comments