Skip to content

Commit 81a9159

Browse files
committed
Add ChoiState superoperator representation
1 parent bb71f52 commit 81a9159

File tree

2 files changed

+51
-2
lines changed

2 files changed

+51
-2
lines changed

src/QuantumOpticsBase.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,9 @@ export Basis, GenericBasis, CompositeBasis, basis,
3535
current_time, time_shift, time_stretch, time_restrict,
3636
#superoperators
3737
SuperOperator, DenseSuperOperator, DenseSuperOpType,
38-
SparseSuperOperator, SparseSuperOpType, spre, spost, sprepost, liouvillian,
39-
identitysuperoperator,
38+
SparseSuperOperator, SparseSuperOpType,
39+
ChoiState,
40+
spre, spost, sprepost, liouvillian, identitysuperoperator,
4041
#fock
4142
FockBasis, number, destroy, create,
4243
fockstate, coherentstate, coherentstate!,

src/superoperators.jl

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,3 +316,51 @@ end
316316
}
317317
throw(IncompatibleBases())
318318
end
319+
320+
"""
321+
Base class for the Choi representation of superoperators.
322+
"""
323+
324+
mutable struct ChoiState{B1,B2,T} <: AbstractSuperOperator{B1,B2}
325+
basis_l::B1
326+
basis_r::B2
327+
data::T
328+
function ChoiState{BL,BR,T}(basis_l::BL, basis_r::BR, data::T) where {BL,BR,T}
329+
if (length(basis_l) != 2 || length(basis_r) != 2 ||
330+
length(basis_l[1])*length(basis_l[2]) != size(data, 1) ||
331+
length(basis_r[1])*length(basis_r[2]) != size(data, 2))
332+
throw(DimensionMismatch("Tried to assign data of size $(size(data)) to Hilbert spaces of sizes $(length.(basis_l)), $(length.(basis_r))"))
333+
end
334+
new(basis_l, basis_r, data)
335+
end
336+
end
337+
ChoiState{BL,BR}(b1::BL,b2::BR,data::T) where {BL,BR,T} = ChoiState{BL,BR,T}(b1,b2,data)
338+
ChoiState(b1::BL,b2::BR,data::T) where {BL,BR,T} = ChoiState{BL,BR,T}(b1,b2,data)
339+
ChoiState(b,data) = SuperOperator(b,b,data)
340+
341+
# reshape swaps within systems due to colum major ordering
342+
# https://docs.qojulia.org/quantumobjects/operators/#tensor_order
343+
function _super_choi((l1, l2), (r1, r2), data::Matrix)
344+
data = reshape(data, map(length, (l2, l1, r2, r1)))
345+
(l1, l2), (r1, r2) = (r2, l2), (r1, l1)
346+
data = permutedims(data, (1, 3, 2, 4))
347+
data = reshape(data, map(length, (l1l2, r1r2)))
348+
return (l1, l2), (r1, r2), data
349+
end
350+
351+
function _super_choi((r2, l2), (r1, l1), data::SparseMatrixCSC)
352+
data = _permutedims(data, map(length, (l2, r2, l1, r1)), (1, 3, 2, 4))
353+
data = reshape(data, map(length, (l1l2, r1r2)))
354+
# sparse(data) is necessary since reshape of a sparse array returns a
355+
# ReshapedSparseArray which is not a subtype of AbstractArray and so
356+
# _permutedims fails to acces the ".m" field
357+
# https://github.com/qojulia/QuantumOpticsBase.jl/pull/83
358+
# https://github.com/JuliaSparse/SparseArrays.jl/issues/24
359+
# permutedims in SparseArrays.jl only implements perm (2,1) and so
360+
# _permutedims should be upstreamed
361+
# https://github.com/JuliaLang/julia/issues/26534
362+
return (l1, l2), (r1, r2), sparse(data)
363+
end
364+
365+
ChoiState(op::SuperOperator) = ChoiState(_super_choi(op.basis_l, op.basis_r, op.data)...)
366+
SuperOperator(op::ChoiState) = SuperOperator(_super_choi(op.basis_l, op.basis_r, op.data)...)

0 commit comments

Comments
 (0)