11import QuantumInterface: KetBraBasis, ChoiBasis
2- # using TensorCast
32
43const SuperOperatorType{BL,BR,T} = Operator{BL,BR,T} where {BL<: KetBraBasis ,BR<: KetBraBasis }
54const ChoiStateType{BL,BR,T} = Operator{BL,BR,T} where {BR<: ChoiBasis ,BL<: ChoiBasis }
65
76# const ChannelType = Union{SuperOperatorType, ChoiStateType, PauliTransferType, ChiType}
87
9- # const SOpBasis = Union{KetBraBasis, PauliBasis}
10- # const SuperOperatorType{BL,BR,T} = Operator{BL,BR,T} where {BL<:SOpBasis,BR<:SOpBasis}
11- # const SOpKetBraType{BL,BR,T} = Operator{BL,BR,T} where {BL<:KetBraBasis,BR<:KetBraBasis}
12- # const SOpPauliType{BL,BR,T} = Operator{BL,BR,T} where {BL<:PauliBasis,BR<:PauliBasis}
13- # const ChoiStateType{BL,BR,T} = Operator{BL,BR,T} where {BR<:ChoiBasis,BL<:ChoiBasis}
14- # const ChannelType = Union{SOpKetBraType, SOpPauliType, ChoiStateType, ChiType}
15-
16- # const DenseSuperOpPureType{BL,BR} = SuperOperatorType{BL,BR,<:Matrix}
17- # const DenseSuperOpAdjType{BL,BR} = SuperOperatorType{BL,BR,<:Adjoint{<:Number,<:Matrix}}
18- # const DenseSuperOpType{BL,BR} = Union{DenseOpPureType{BL,BL},DenseOpAdjType{BL,BR}}
19- # const SparseSuperOpPureType{BL,BR} = SuperOperatorType{BL,BR,<:SparseMatrixCSC}
20- # const SparseSuperOpAdjType{BL,BR} = SuperOperatorType{BL,BR,<:Adjoint{<:Number,<:SparseMatrixCSC}}
21- # const SparseSuperOpType{BL,BR} = Union{SparseOpPureType{BL,BR},SparseOpAdjType{BL,BR}}
22-
238vec (op:: Operator ) = Ket (KetBraBasis (basis_l (op), basis_r (op)), vec (op. data))
249function unvec (k:: Ket{<:KetBraBasis} )
2510 bl, br = basis_l (basis (k)), basis_r (basis (k))
2611 Operator (bl, br, reshape (k. data, dimension (bl), dimension (br)))
12+ # @cast A[n,m] |= k.data[(n,m)] (n ∈ 1:dimension(bl), m ∈ 1:dimension(br))
2713end
2814# function unvec(k::Ket{<:KetBraBasis})
2915# bl, br = basis_l(basis(k)), basis_r(basis(k))
30- # @cast A[n,m] |= k.data[(n,m)] (n ∈ 1:dimension(bl), m ∈ 1:dimension(br))
3116# return Operator(bl, br, A)
3217# end
3318
@@ -42,29 +27,8 @@ function spost(op::Operator)
4227end
4328
4429sprepost (A:: Operator , B:: Operator ) = Operator (KetBraBasis (basis_l (A), basis_r (B)), KetBraBasis (basis_r (A), basis_l (B)), kron (permutedims (B. data), A. data))
45- # function sprepost(A::Operator, B::Operator)
46- # @cast C[(ν,μ), (n,m)] |= A.data[ν,n] * B.data[m,μ]
47- # Operator(KetBraBasis(basis_l(A), basis_r(B)), KetBraBasis(basis_r(A), basis_l(B)), C)
48- # end
30+ # @cast C[(ν,μ), (n,m)] |= A.data[ν,n] * B.data[m,μ]
4931
50- # function super_tensor(A, B)
51- # a1, a2 = basis_l(A), basis_r(A)
52- # b1, b2 = basis_l(B), basis_r(B)
53- # #da1, da2, db1, db2 = map(dimension, (a1, a2, b1, b2))
54- # #@cast C[(ν,μ), (n,m)] |= A.data[m,μ] * B.data[n,ν] (m ∈ 1:da1, μ ∈ 1:da2, n ∈ 1:db1, ν ∈ 1:db2)
55- # #data = kron(B.data, A.data)
56- # #data = reshape(data, map(dimension, (a1, a2, b1, b2)))
57- # #data = PermutedDimsArray(data, (4, 2, 3, 1))
58- # #data = reshape(data, map(dimension, (a2⊗b2, a1⊗b1)))
59- # #return Operator(a1⊗b1, a2⊗b2, data)
60- # data = kron(B.data, A.data)
61- # data = reshape(data, map(dimension, (a1, a2, b1, b2)))
62- # data = PermutedDimsArray(data, (1, 3, 2, 4))
63- # data = reshape(data, map(dimension, (a1⊗b1, a2⊗b2)))
64- # return Operator(a1⊗b1, a2⊗b2, data)
65- # end
66-
67- # https://discourse.julialang.org/t/permuteddimsarray-slower-than-permutedims/46401
6832function super_tensor (A, B)
6933 all, alr = basis_l (basis_l (A)), basis_r (basis_l (A))
7034 arl, arr = basis_l (basis_r (A)), basis_r (basis_r (A))
@@ -77,42 +41,25 @@ function super_tensor(A, B)
7741 return Operator (basis_l (A)⊗ basis_l (B), basis_r (A)⊗ basis_r (B), data)
7842end
7943
80- # function _sch(data, l1, l2, r1, r2)
81- # data = reshape(data, map(dimension, (l1, l2, r1, r2)))
82- # data = permutedims(data, (4, 2, 3, 1))
83- # reshape(data, map(dimension, (l2⊗r2, l1⊗r1)))
84- # end
85- #
86- # function _sch(data::SparseMatrixCSC, l1, l2, r1, r2)
87- # #data = reshape(sparse(data), map(dimension, (l1, l2, r1, r2)), ())
88- # #data = _permutedims(sparse(data), size(data), (4, 2, 3, 1))
89- # data = _permutedims(sparse(data), map(dimension, (l1, l2, r1, r2)), (4, 2, 3, 1))
90- # sparse(reshape(data, map(dimension, (l2⊗r2, l1⊗r1))))
91- # # sparse(::ReshapedArray) only works when ndims == 2
92- # end
93-
94- # sprepost(A::Operator, B::Operator) = Operator(KetBraBasis(basis_l(A), basis_r(B)), KetBraBasis(basis_r(A), basis_l(B)), kron(permutedims(B.data), A.data))
95-
96- # function _super_choi((l1, l2), (r1, r2), data)
97- # data = Base.ReshapedArray(data, map(length, (l2, l1, r2, r1)), ())
98- # (l1, l2), (r1, r2) = (r2, l2), (r1, l1)
99- # data = PermutedDimsArray(data, (1, 3, 2, 4))
100- # data = Base.ReshapedArray(data, map(length, (l1⊗l2, r1⊗r2)), ())
101- # return (l1, l2), (r1, r2), copy(data)
102- # end
103-
44+ # copy at end is necessary to not fall back on generic gemm routines later
45+ # https://discourse.julialang.org/t/permuteddimsarray-slower-than-permutedims/46401
46+ # which suggetst usig something like Tullio might speed things up further
10447# Sec IV.A. of https://arxiv.org/abs/1111.6950
10548function _super_choi (basis_fn, op)
10649 l1, l2 = basis_l (basis_l (op)), basis_r (basis_l (op))
10750 r1, r2 = basis_l (basis_r (op)), basis_r (basis_r (op))
108- # data = _sch(op.data, l1, l2, r1, r2)
10951 # dl1, dl2, dr1, dr2 = map(dimension, (l1, l2, r1, r2))
11052 # @cast A[(ν,μ), (n,m)] |= op.data[(m,μ), (n,ν)] (m ∈ 1:dl1, μ ∈ 1:dl2, n ∈ 1:dr1, ν ∈ 1:dr2)
11153
11254 # data = reshape(op.data, map(dimension, (l1, l2, r1, r2)))
11355 # data = PermutedDimsArray(data, (4, 2, 3, 1))
11456 # data = reshape(data, map(dimension, (r2⊗l2, r1⊗l1)))
11557 # return Operator(basis_fn(r2, l2), basis_fn(r1, l1), data)
58+ # data = Base.ReshapedArray(data, map(length, (l2, l1, r2, r1)), ())
59+ # (l1, l2), (r1, r2) = (r2, l2), (r1, l1)
60+ # data = PermutedDimsArray(data, (1, 3, 2, 4))
61+ # data = Base.ReshapedArray(data, map(length, (l1⊗l2, r1⊗r2)), ())
62+ # return (l1, l2), (r1, r2), copy(data)
11663
11764 data = reshape (op. data, map (dimension, (l1, l2, r1, r2)))
11865 data = PermutedDimsArray (data, (1 , 3 , 2 , 4 ))
@@ -138,7 +85,6 @@ dagger(a::ChoiStateType) = choi(dagger(super(a)))
13885* (a:: ChoiStateType , b:: SuperOperatorType ) = super (a)* b
13986* (a:: SuperOperatorType , b:: ChoiStateType ) = a* super (b)
14087
141-
14288identitysuperoperator (b:: Basis ) = Operator (KetBraBasis (b,b), KetBraBasis (b,b), Eye {ComplexF64} (dimension (b)^ 2 ))
14389
14490identitysuperoperator (op:: DenseOpType{BL,BR} ) where {BL<: KetBraBasis , BR<: KetBraBasis } =
0 commit comments