Skip to content

Commit d04256d

Browse files
authored
Add sprepost to superoperators (#113)
* Add sprepost to superoperators * Throw ArgumentError in spre and spost for non-square operators * Bump version number
1 parent a9bfd9a commit d04256d

File tree

6 files changed

+54
-8
lines changed

6 files changed

+54
-8
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "QuantumOpticsBase"
22
uuid = "4f57444f-1401-5e15-980d-4471b28d5678"
3-
version = "0.4.10"
3+
version = "0.4.11"
44

55
[deps]
66
Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"

docs/src/api.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ spre
122122
spost
123123
```
124124

125+
```@docs
126+
sprepost
127+
```
128+
125129
```@docs
126130
liouvillian
127131
```

src/QuantumOpticsBase.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export Basis, GenericBasis, CompositeBasis, basis,
3333
current_time, time_shift, time_stretch, time_restrict,
3434
#superoperators
3535
SuperOperator, DenseSuperOperator, DenseSuperOpType,
36-
SparseSuperOperator, SparseSuperOpType, spre, spost, liouvillian,
36+
SparseSuperOperator, SparseSuperOpType, spre, spost, sprepost, liouvillian,
3737
#fock
3838
FockBasis, number, destroy, create,
3939
fockstate, coherentstate, coherentstate!,

src/superoperators.jl

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,16 @@ For operators ``A``, ``B`` the relation
110110
111111
holds. `op` can be a dense or a sparse operator.
112112
"""
113-
spre(op::AbstractOperator) = SuperOperator((op.basis_l, op.basis_l), (op.basis_r, op.basis_r), tensor(op, identityoperator(op)).data)
113+
function spre(op::AbstractOperator)
114+
if !samebases(op.basis_l, op.basis_r)
115+
throw(ArgumentError("It's not clear what spre of a non-square operator should be. See issue #113"))
116+
end
117+
SuperOperator((op.basis_l, op.basis_l), (op.basis_r, op.basis_r), tensor(op, identityoperator(op)).data)
118+
end
114119

115120
"""
121+
spost(op)
122+
116123
Create a super-operator equivalent for left side operator multiplication.
117124
118125
For operators ``A``, ``B`` the relation
@@ -123,8 +130,27 @@ For operators ``A``, ``B`` the relation
123130
124131
holds. `op` can be a dense or a sparse operator.
125132
"""
126-
spost(op::AbstractOperator) = SuperOperator((op.basis_r, op.basis_r), (op.basis_l, op.basis_l), kron(permutedims(op.data), identityoperator(op).data))
133+
function spost(op::AbstractOperator)
134+
if !samebases(op.basis_l, op.basis_r)
135+
throw(ArgumentError("It's not clear what spost of a non-square operator should be. See issue #113"))
136+
end
137+
SuperOperator((op.basis_r, op.basis_r), (op.basis_l, op.basis_l), kron(permutedims(op.data), identityoperator(op).data))
138+
end
139+
140+
"""
141+
sprepost(op)
127142
143+
Create a super-operator equivalent for left and right side operator multiplication.
144+
145+
For operators ``A``, ``B``, ``C`` the relation
146+
147+
```math
148+
\\mathrm{sprepost}(A, B) C = A C B
149+
```
150+
151+
holds. `A` ond `B` can be dense or a sparse operators.
152+
"""
153+
sprepost(A::AbstractOperator, B::AbstractOperator) = SuperOperator((A.basis_l, B.basis_r), (A.basis_r, B.basis_l), kron(permutedims(B.data), A.data))
128154

129155
function _check_input(H::AbstractOperator{B1,B2}, J::Vector, Jdagger::Vector, rates) where {B1,B2}
130156
for j=J

test/test_apply.jl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,13 @@ b2 = FockBasis(2)
4343
k1 = coherentstate(b1, 0.39)
4444
k2 = coherentstate(b2, 1.4)
4545
op = projector(k1, k2')
46-
sOp2 = spre(op)
4746

4847
try
48+
sOp2 = spre(op)
4949
QuantumOpticsBase.apply!(st, 1, sOp2)
5050
catch e
51-
@test typeof(e) <: QuantumInterface.IncompatibleBases
51+
@test typeof(e) <: ArgumentError
52+
#@test typeof(e) <: QuantumInterface.IncompatibleBases
5253
end
5354

54-
end #testset
55+
end #testset

test/test_superoperators.jl

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,14 @@ s_dense = dense(s_)
3333

3434
# Test length
3535
b1 = GenericBasis(3)
36+
op = DenseOperator(b1, b1)
37+
S = spre(op)
38+
@test length(S) == length(S.data) == (3*3)^2
39+
S = spost(op)
40+
@test length(S) == length(S.data) == (3*3)^2
3641
b2 = GenericBasis(5)
3742
op = DenseOperator(b1, b2)
38-
S = spre(op)
43+
S = sprepost(dagger(op), op)
3944
@test length(S) == length(S.data) == (3*5)^2
4045

4146
# Test arithmetic
@@ -156,9 +161,19 @@ op2 = DenseOperator(spinbasis, [0.2+0.1im 0.1+2.3im; 0.8+4.0im 0.3+1.4im])
156161

157162
@test spre(sparse(op1))*op2 == op1*op2
158163
@test spost(sparse(op1))*op2 == op2*op1
164+
@test sprepost(sparse(op1), op1)*op2 op1*op2*op1
159165

160166
@test spre(sparse(op1))*sparse(op2) == sparse(op1*op2)
161167
@test spost(sparse(op1))*sparse(op2) == sparse(op2*op1)
168+
@test sprepost(sparse(op1), sparse(op1))*sparse(op2) sparse(op1*op2*op1)
169+
170+
@test sprepost(op1, op2) spre(op1)*spost(op2)
171+
b1 = FockBasis(1)
172+
b2 = FockBasis(5)
173+
op = fockstate(b1, 0) dagger(fockstate(b2, 0))
174+
@test sprepost(dagger(op), op)*dm(fockstate(b1, 0)) == dm(fockstate(b2, 0))
175+
@test_throws ArgumentError spre(op)
176+
@test_throws ArgumentError spost(op)
162177

163178
L = liouvillian(H, J)
164179
ρ = -1im*(H*ρ₀ - ρ₀*H)

0 commit comments

Comments
 (0)