11import QuantumInterface: KetBraBasis, ChoiBasis
2+ using TensorCast
23
34const SuperKetType = Ket{<: KetBraBasis }
45
@@ -17,23 +18,29 @@ 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))
38+ # 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))
39+
40+ function sprepost (A:: Operator , B:: Operator )
41+ @cast C[(ν,μ), (n,m)] |= A. data[ν,n] * B. data[m,μ]
42+ Operator (KetBraBasis (basis_l (A), basis_r (B)), KetBraBasis (basis_r (A), basis_l (B)), C)
43+ end
3744
3845function _super_choi ((l1, l2), (r1, r2), data)
3946 data = Base. ReshapedArray (data, map (length, (l2, l1, r2, r1)), ())
@@ -43,19 +50,17 @@ function _super_choi((l1, l2), (r1, r2), data)
4350 return (l1, l2), (r1, r2), copy (data)
4451end
4552
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)
53+ # Sec IV.A. of https://arxiv.org/abs/1111.6950
54+ function _super_choi (basis_fn, op)
55+ l1, l2 = basis_l (basis_l (op)), basis_r (basis_l (op))
56+ r1, r2 = basis_l (basis_r (op)), basis_r (basis_r (op))
57+ d1, d2, d3, d4 = map (dimension, (l1, l2, r1, r2))
58+ @cast A[(ν,μ), (n,m)] |= op. data[(m,μ), (n,ν)] (m ∈ 1 : d1, μ ∈ 1 : d2, n ∈ 1 : d3, ν ∈ 1 : d4)
59+ return Operator (basis_fn (r2, l2), basis_fn (r1, l1), A)
5160end
5261
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
62+ choi (op:: SuperOperatorType ) = _super_choi (ChoiBasis, op)
63+ super (op:: ChoiStateType ) = _super_choi (KetBraBasis, op)
5964
6065dagger (a:: ChoiStateType ) = choi (dagger (super (a)))
6166
0 commit comments