1- import QuantumInterface: KetBraBasis, ChoiBasis, PauliBasis, ChiBasis
2- using TensorCast
1+ import QuantumInterface: KetBraBasis, ChoiBasis
2+ # using TensorCast
33
4- const SOpBasis = Union{KetBraBasis, PauliBasis}
5- const SuperOperatorType{BL,BR,T} = Operator{BL,BR,T} where {BL<: SOpBasis ,BR<: SOpBasis }
6- const SOpKetBraType{BL,BR,T} = Operator{BL,BR,T} where {BL<: KetBraBasis ,BR<: KetBraBasis }
7- const SOpPauliType{BL,BR,T} = Operator{BL,BR,T} where {BL<: PauliBasis ,BR<: PauliBasis }
4+ const SuperOperatorType{BL,BR,T} = Operator{BL,BR,T} where {BL<: KetBraBasis ,BR<: KetBraBasis }
85const ChoiStateType{BL,BR,T} = Operator{BL,BR,T} where {BR<: ChoiBasis ,BL<: ChoiBasis }
9- const ChoiKetBraType{BL,BR,T} = Operator{ChoiBasis{BL,BR},ChoiBasis{BL,BR},T} where {BL<: KetBraBasis ,BR<: KetBraBasis }
10- const ChiType{BL,BR,T} = Operator{ChoiBasis{BL,BR},ChoiBasis{BL,BR},T} where {BL<: PauliBasis ,BR<: PauliBasis }
116
12- const DenseSuperOpPureType{BL,BR} = SuperOperatorType{BL,BR,<: Matrix }
13- const DenseSuperOpAdjType{BL,BR} = SuperOperatorType{BL,BR,<: Adjoint{<:Number,<:Matrix} }
14- const DenseSuperOpType{BL,BR} = Union{DenseOpPureType{BL,BL},DenseOpAdjType{BL,BR}}
15- const SparseSuperOpPureType{BL,BR} = SuperOperatorType{BL,BR,<: SparseMatrixCSC }
16- const SparseSuperOpAdjType{BL,BR} = SuperOperatorType{BL,BR,<: Adjoint{<:Number,<:SparseMatrixCSC} }
17- const SparseSuperOpType{BL,BR} = Union{SparseOpPureType{BL,BR},SparseOpAdjType{BL,BR}}
7+ # const SOpBasis = Union{KetBraBasis, PauliBasis}
8+ # const SuperOperatorType{BL,BR,T} = Operator{BL,BR,T} where {BL<:SOpBasis,BR<:SOpBasis}
9+ # const SOpKetBraType{BL,BR,T} = Operator{BL,BR,T} where {BL<:KetBraBasis,BR<:KetBraBasis}
10+ # const SOpPauliType{BL,BR,T} = Operator{BL,BR,T} where {BL<:PauliBasis,BR<:PauliBasis}
11+ # const ChoiStateType{BL,BR,T} = Operator{BL,BR,T} where {BR<:ChoiBasis,BL<:ChoiBasis}
12+ # const ChannelType = Union{SOpKetBraType, SOpPauliType, ChoiStateType, ChiType}
13+
14+ # const DenseSuperOpPureType{BL,BR} = SuperOperatorType{BL,BR,<:Matrix}
15+ # const DenseSuperOpAdjType{BL,BR} = SuperOperatorType{BL,BR,<:Adjoint{<:Number,<:Matrix}}
16+ # const DenseSuperOpType{BL,BR} = Union{DenseOpPureType{BL,BL},DenseOpAdjType{BL,BR}}
17+ # const SparseSuperOpPureType{BL,BR} = SuperOperatorType{BL,BR,<:SparseMatrixCSC}
18+ # const SparseSuperOpAdjType{BL,BR} = SuperOperatorType{BL,BR,<:Adjoint{<:Number,<:SparseMatrixCSC}}
19+ # const SparseSuperOpType{BL,BR} = Union{SparseOpPureType{BL,BR},SparseOpAdjType{BL,BR}}
1820
1921vec (op:: Operator ) = Ket (KetBraBasis (basis_l (op), basis_r (op)), vec (op. data))
2022function unvec (k:: Ket{<:KetBraBasis} )
@@ -43,15 +45,20 @@ sprepost(A::Operator, B::Operator) = Operator(KetBraBasis(basis_l(A), basis_r(B)
4345# Operator(KetBraBasis(basis_l(A), basis_r(B)), KetBraBasis(basis_r(A), basis_l(B)), C)
4446# end
4547
46- function tensor (A:: SuperOperatorType , B:: SuperOperatorType )
48+ function tensor (A:: T , B:: T ) where T <: Union{SuperOperatorType, ChoiStateType}
4749 a1, a2 = basis_l (A), basis_r (A)
4850 b1, b2 = basis_l (B), basis_r (B)
4951 # da1, da2, db1, db2 = map(dimension, (a1, a2, b1, b2))
5052 # @cast C[(ν,μ), (n,m)] |= A.data[m,μ] * B.data[n,ν] (m ∈ 1:da1, μ ∈ 1:da2, n ∈ 1:db1, ν ∈ 1:db2)
53+ # data = kron(B.data, A.data)
54+ # data = reshape(data, map(dimension, (a1, a2, b1, b2)))
55+ # data = PermutedDimsArray(data, (4, 2, 3, 1))
56+ # data = reshape(data, map(dimension, (a2⊗b2, a1⊗b1)))
57+ # return Operator(a1⊗b1, a2⊗b2, data)
5158 data = kron (B. data, A. data)
5259 data = reshape (data, map (dimension, (a1, a2, b1, b2)))
53- data = PermutedDimsArray (data, (4 , 2 , 3 , 1 ))
54- data = reshape (data, map (dimension, (a2 ⊗ b2, a1 ⊗ b1 )))
60+ data = PermutedDimsArray (data, (1 , 3 , 2 , 4 ))
61+ data = reshape (data, map (dimension, (a1 ⊗ b1, a2 ⊗ b2 )))
5562 return Operator (a1⊗ b1, a2⊗ b2, data)
5663end
5764
@@ -76,31 +83,42 @@ function _super_choi(basis_fn, op)
7683 # data = _sch(op.data, l1, l2, r1, r2)
7784 # dl1, dl2, dr1, dr2 = map(dimension, (l1, l2, r1, r2))
7885 # @cast A[(ν,μ), (n,m)] |= op.data[(m,μ), (n,ν)] (m ∈ 1:dl1, μ ∈ 1:dl2, n ∈ 1:dr1, ν ∈ 1:dr2)
86+
87+ # data = reshape(op.data, map(dimension, (l1, l2, r1, r2)))
88+ # data = PermutedDimsArray(data, (4, 2, 3, 1))
89+ # data = reshape(data, map(dimension, (r2⊗l2, r1⊗l1)))
90+ # return Operator(basis_fn(r2, l2), basis_fn(r1, l1), data)
91+
7992 data = reshape (op. data, map (dimension, (l1, l2, r1, r2)))
80- data = PermutedDimsArray (data, (4 , 2 , 3 , 1 ))
81- data = reshape (data, map (dimension, (l2 ⊗ r2, l1 ⊗ r1 )))
82- return Operator (basis_fn (r2, l2 ), basis_fn (r1, l1 ), data)
93+ data = PermutedDimsArray (data, (1 , 3 , 2 , 4 ))
94+ data = reshape (data, map (dimension, (l1 ⊗ r1, l2 ⊗ r2 )))
95+ return Operator (basis_fn (l1, r1 ), basis_fn (l2, r2 ), data)
8396end
8497
8598choi (op:: SuperOperatorType ) = _super_choi (ChoiBasis, op)
8699super (op:: ChoiStateType ) = _super_choi (KetBraBasis, op)
100+ super (op:: SuperOperatorType ) = op
101+ choi (op:: ChoiStateType ) = op
87102
88103# I'm not sure this is actually right... see sec V.C. of https://arxiv.org/abs/1111.6950
89104dagger (a:: ChoiStateType ) = choi (dagger (super (a)))
90105
91106# This method is necessary so we don't fall back to the method below it
92107* (a:: SuperOperatorType , b:: SuperOperatorType ) = (check_multiplicable (a,b); Operator (a. basis_l, b. basis_r, a. data* b. data))
93108* (a:: SuperOperatorType , b:: Operator ) = unvec (a* vec (b))
94- * (a:: ChoiStateType , b:: SuperOperatorType ) = super (a)* b
95- * (a:: SuperOperatorType , b:: ChoiStateType ) = a* super (b)
109+
96110* (a:: ChoiStateType , b:: ChoiStateType ) = choi (super (a)* super (b))
97111* (a:: ChoiStateType , b:: Operator ) = super (a)* b
98112
113+ * (a:: ChoiStateType , b:: SuperOperatorType ) = super (a)* b
114+ * (a:: SuperOperatorType , b:: ChoiStateType ) = a* super (b)
115+
116+
99117identitysuperoperator (b:: Basis ) = Operator (KetBraBasis (b,b), KetBraBasis (b,b), Eye {ComplexF64} (dimension (b)^ 2 ))
100118
101- identitysuperoperator (op:: DenseSuperOpType ) =
119+ identitysuperoperator (op:: DenseOpType{BL,BR} ) where {BL <: KetBraBasis , BR <: KetBraBasis } =
102120 Operator (op. basis_l, op. basis_r, Matrix (one (eltype (op. data))I, size (op. data)))
103121
104- identitysuperoperator (op:: SparseSuperOpType ) =
122+ identitysuperoperator (op:: SparseOpType{BL,BR} ) where {BL <: KetBraBasis , BR <: KetBraBasis } =
105123 Operator (op. basis_l, op. basis_r, sparse (one (eltype (op. data))I, size (op. data)))
106124
0 commit comments