diff --git a/src/QuantumOpticsBase.jl b/src/QuantumOpticsBase.jl index fd5a11df..1ee5694e 100644 --- a/src/QuantumOpticsBase.jl +++ b/src/QuantumOpticsBase.jl @@ -3,7 +3,7 @@ module QuantumOpticsBase using SparseArrays, LinearAlgebra, LRUCache, Strided, UnsafeArrays, FillArrays import LinearAlgebra: mul!, rmul! -import QuantumInterface: dagger, directsum, ⊕, dm, embed, expect, identityoperator, +import QuantumInterface: dagger, directsum, ⊕, dm, embed, expect, identityoperator, identitysuperoperator, permutesystems, projector, ptrace, reduced, tensor, ⊗, variance, apply!, basis, AbstractSuperOperator # index helpers @@ -34,6 +34,7 @@ export Basis, GenericBasis, CompositeBasis, basis, #superoperators SuperOperator, DenseSuperOperator, DenseSuperOpType, SparseSuperOperator, SparseSuperOpType, spre, spost, sprepost, liouvillian, + identitysuperoperator, #fock FockBasis, number, destroy, create, fockstate, coherentstate, coherentstate!, diff --git a/src/superoperators.jl b/src/superoperators.jl index 48c1b699..2d3457f3 100644 --- a/src/superoperators.jl +++ b/src/superoperators.jl @@ -97,6 +97,19 @@ end -(a::SuperOperator) = SuperOperator(a.basis_l, a.basis_r, -a.data) -(a::SuperOperator, b::SuperOperator) = throw(IncompatibleBases()) +identitysuperoperator(b::Basis) = + SuperOperator((b,b), (b,b), Eye{ComplexF64}(length(b)^2)) + +identitysuperoperator(op::DenseSuperOpType) = + SuperOperator(op.basis_l, op.basis_r, Matrix(one(eltype(op.data))I, size(op.data))) + +identitysuperoperator(op::SparseSuperOpType) = + SuperOperator(op.basis_l, op.basis_r, sparse(one(eltype(op.data))I, size(op.data))) + +dagger(x::DenseSuperOpType) = SuperOperator(x.basis_r, x.basis_l, copy(adjoint(x.data))) +dagger(x::SparseSuperOpType) = SuperOperator(x.basis_r, x.basis_l, sparse(adjoint(x.data))) + + """ spre(op) diff --git a/test/test_aqua.jl b/test/test_aqua.jl index d6b49a57..b3ecf9ad 100644 --- a/test/test_aqua.jl +++ b/test/test_aqua.jl @@ -9,6 +9,6 @@ using FillArrays piracy=(broken=true,) ) # manual piracy check to exclude identityoperator - pirates = [pirate for pirate in Aqua.Piracy.hunt(QuantumOpticsBase) if pirate.name != :identityoperator] + pirates = [pirate for pirate in Aqua.Piracy.hunt(QuantumOpticsBase) if pirate.name ∉ [:identityoperator,:identitysuperoperator]] @test isempty(pirates) end # testset diff --git a/test/test_superoperators.jl b/test/test_superoperators.jl index 4cdf9aa0..75a45940 100644 --- a/test/test_superoperators.jl +++ b/test/test_superoperators.jl @@ -120,7 +120,6 @@ x = -s1 @test x.basis_l == (b1, b2) @test x.basis_r == (b3, b4) - # TODO: Clean-up this part ωc = 1.2 ωa = 0.9 @@ -153,6 +152,9 @@ J = [Ja, Jc] Ψ₀ = spinup(spinbasis) ⊗ fockstate(fockbasis, 5) ρ₀ = dm(Ψ₀) +@test identitysuperoperator(spinbasis)*sx == sx +@test identitysuperoperator(sparse(spre(sx)))*sx == sparse(sx) +@test identitysuperoperator(dense(spre(sx)))*sx == dense(sx) op1 = DenseOperator(spinbasis, [1.2+0.3im 0.7+1.2im;0.3+0.1im 0.8+3.2im]) op2 = DenseOperator(spinbasis, [0.2+0.1im 0.1+2.3im; 0.8+4.0im 0.3+1.4im]) @@ -161,6 +163,8 @@ op2 = DenseOperator(spinbasis, [0.2+0.1im 0.1+2.3im; 0.8+4.0im 0.3+1.4im]) @test spre(sparse(op1))*op2 == op1*op2 @test spost(sparse(op1))*op2 == op2*op1 +@test spre(sparse(dagger(op1)))*op2 == dagger(op1)*op2 +@test spre(dense(dagger(op1)))*op2 ≈ dagger(op1)*op2 @test sprepost(sparse(op1), op1)*op2 ≈ op1*op2*op1 @test spre(sparse(op1))*sparse(op2) == sparse(op1*op2)