11import QuantumInterface: KetBraBasis, ChoiBasis
2+ using TensorCast
23
34const SuperKetType = Ket{<: KetBraBasis }
45
@@ -17,45 +18,39 @@ const PauliTransferType = Operator{<:ChoiBasis,<:ChoiBasis}
1718# const ChoiStateType = Operator{ChoiBasisType,ChoiBasisType}
1819# const ChoiStateType = Union{Operator{CompositeBasis{ChoiBasis,S},CompositeBasis{ChoiBasis,T}} where {S,T}, Operator{CompositeBasis{ChoiBasis{BL},S},CompositeBasis{ChoiBasis{BR},T}} where {BL,BR,S,T}}
1920
20- vec (op:: Operator ) = Ket (KetBraBasis (basis_l (op), basis_r (op)), reshape (op. data, dimension (op . data) ))
21+ vec (op:: Operator ) = Ket (KetBraBasis (basis_l (op), basis_r (op)), vec (op. data))
2122function unvec (k:: SuperKetType )
2223 bl, br = basis_l (basis (k)), basis_r (basis (k))
23- return Operator (bl, br, reshape (k. data, dimension (bl), dimension (br)))
24+ @cast A[n,m] |= k. data[(n,m)] (n ∈ 1 : dimension (bl), m ∈ 1 : dimension (br))
25+ return Operator (bl, br, A)
2426end
2527
2628function spre (op:: Operator )
2729 multiplicable (op, op) || throw (ArgumentError (" It's not clear what spre of a non-square operator should be. See issue #113" ))
28- Operator ( KetBraBasis ( basis_l (op)), KetBraBasis ( basis_r (op)), tensor (op, identityoperator (op)) . data )
30+ sprepost (op, identityoperator (op))
2931end
3032
3133function spost (op:: Operator )
3234 multiplicable (op, op) || throw (ArgumentError (" It's not clear what spost of a non-square operator should be. See issue #113" ))
33- Operator ( KetBraBasis ( basis_r ( op)), KetBraBasis ( basis_l (op)), kron ( permutedims (op . data), identityoperator (op) . data) )
35+ sprepost ( identityoperator ( op), op )
3436end
3537
36- sprepost (A:: Operator , B:: Operator ) = Operator (KetBraBasis (A. basis_l, B. basis_r), KetBraBasis (A. basis_r, B. basis_l), kron (permutedims (B. data), A. data))
37-
38- function _super_choi ((l1, l2), (r1, r2), data)
39- data = reshape (data, map (dimension, (l2, l1, r2, r1)))
40- (l1, l2), (r1, r2) = (r2, l2), (r1, l1)
41- data = PermutedDimsArray (data, (1 , 3 , 2 , 4 ))
42- data = reshape (data, map (dimension, (l1⊗ l2, r1⊗ r2)))
43- return (l1, l2), (r1, r2), data
38+ function sprepost (A:: Operator , B:: Operator )
39+ @cast C[(ν,μ), (n,m)] |= A. data[ν,n] * B. data[m,μ]
40+ Operator (KetBraBasis (basis_l (A), basis_r (B)), KetBraBasis (basis_r (A), basis_l (B)), C)
4441end
4542
46- function choi (op:: SuperOperatorType )
47- bl, br = basis_l (op), basis_r (op)
48- (l1, l2), (r1, r2) = (basis_l (bl), basis_r (bl)), (basis_l (br), basis_r (br))
49- (l1, l2), (r1, r2), data = _super_choi ((l1, l2), (r1, r2), op. data)
50- return Operator (ChoiBasis (l1,l2), ChoiBasis (r1,r2), data)
43+ # Sec IV.A. of https://arxiv.org/abs/1111.6950
44+ function _super_choi (basis_fn, op)
45+ l1, l2 = basis_l (basis_l (op)), basis_r (basis_l (op))
46+ r1, r2 = basis_l (basis_r (op)), basis_r (basis_r (op))
47+ d1, d2, d3, d4 = map (dimension, (l1, l2, r1, r2))
48+ @cast A[(ν,μ), (n,m)] |= op. data[(m,μ), (n,ν)] (m ∈ 1 : d1, μ ∈ 1 : d2, n ∈ 1 : d3, ν ∈ 1 : d4)
49+ return Operator (basis_fn (r2, l2), basis_fn (r1, l1), A)
5150end
5251
53- function super (op:: ChoiStateType )
54- bl, br = basis_l (op), basis_r (op)
55- (l1, l2), (r1, r2) = (basis_l (bl), basis_r (bl)), (basis_l (br), basis_r (br))
56- (l1, l2), (r1, r2), data = _super_choi ((l1, l2), (r1, r2), op. data)
57- return Operator (KetBraBasis (l1,l2), KetBraBasis (r1,r2), data)
58- end
52+ choi (op:: SuperOperatorType ) = _super_choi (ChoiBasis, op)
53+ super (op:: ChoiStateType ) = _super_choi (KetBraBasis, op)
5954
6055dagger (a:: ChoiStateType ) = choi (dagger (super (a)))
6156
0 commit comments