Skip to content

Commit 82ef997

Browse files
committed
Move pauli stuff
1 parent cffe1cd commit 82ef997

File tree

2 files changed

+43
-134
lines changed

2 files changed

+43
-134
lines changed

src/pauli.jl

Lines changed: 43 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,94 +1,62 @@
1-
import Base: isapprox
21

2+
const PauliTransferType = Operator{<:ChoiBasis,<:ChoiBasis}
33

4-
function PauliTransferMatrix(sop::DenseSuperOpType)
5-
num_qubits = nsubsystems(sop.basis_l[1])
6-
pbv = pauli_basis_vectors(num_qubits)
7-
sop_dim = 4 ^ num_qubits
8-
data = real.(pbv' * sop.data * pbv / sop_dim)
9-
return DensePauliTransferMatrix(sop.basis_l, sop.basis_r, data)
10-
end
11-
12-
SuperOperator(unitary::DenseOpType) = spre(unitary) * spost(unitary')
13-
SuperOperator(sop::DenseSuperOpType) = sop
14-
15-
"""
16-
SuperOperator(ptm::DensePauliTransferMatrix)
174

18-
Convert a Pauli transfer matrix to its representation as a superoperator.
19-
"""
20-
function SuperOperator(ptm::DensePauliTransferMatrix)
21-
num_qubits = nsubsystems(ptm.basis_l[1])
22-
pbv = pauli_basis_vectors(num_qubits)
23-
sop_dim = 4 ^ num_qubits
24-
data = pbv * ptm.data * pbv' / sop_dim
25-
return DenseSuperOperator(ptm.basis_l, ptm.basis_r, data)
5+
# TODO this should maybe be exported?
6+
# TODO also maybe more efficient to super-tensor product vec'd single qubit transformation
7+
function _ketbra_to_pauli()
8+
b = SpinBasis(1//2)
9+
pvec(fn) = vec(fn(b)).data
10+
kb2p = sparse(hcat(map(pvec, [identityoperator, sigmax, sigmay, sigmaz])...)')
2611
end
2712

28-
"""
29-
PauliTransferMatrix(unitary::DenseOpType)
13+
_Ukb2p = _ketbra_to_pauli()
3014

31-
Convert an operator, presumably a unitary operator, to its representation as a
32-
Pauli transfer matrix.
33-
"""
34-
PauliTransferMatrix(unitary::DenseOpType) = PauliTransferMatrix(SuperOperator(unitary))
15+
function pauli(op::SuperOperatorType; tol=1e-9)
16+
bl, br = basis_l(op), basis_r(op)
17+
((basis_l(bl) == basis_r(bl)) && (basis_l(br) == basis_r(br))) || throw(ArgumentError("Superoperator must map between square operators in order to be converted to pauli represenation"))
3518

36-
"""
37-
ChiMatrix(unitary::DenseOpType)
19+
for b in (basis_l(bl), basis_l(br))
20+
for i=1:length(b)
21+
(b[i] isa SpinBasis && dimension(b[i]) == 2) || throw(ArgumentError("Superoperator must be over systems composed of SpinBasis(1//2) to be converted to pauli representation"))
22+
end
23+
end
3824

39-
Convert an operator, presumably a unitary operator, to its representation as a χ matrix.
40-
"""
41-
function ChiMatrix(unitary::DenseOpType)
42-
num_qubits = nsubsystems(unitary.basis_l)
43-
pbv = pauli_basis_vectors(num_qubits)
44-
aj = pbv' * reshape(unitary.data, 4 ^ num_qubits)
45-
return DenseChiMatrix((unitary.basis_l, unitary.basis_l), (unitary.basis_r, unitary.basis_r), aj * aj' / (2 ^ num_qubits))
25+
Nl, Nr = length(basis_l(bl)), length(basis_l(br))
26+
Ul = ket_bra_to_pauli(Nl)
27+
Ur = Nl == Nr ? Ul : ket_bra_to_pauli(Nr)
28+
data = dagger(Ul)*op.data*Ur # TODO figure out normalization
29+
@assert isapprox(imag.(data), zero(data), atol=tol)
30+
Operator(PauliBasis()^Nl, PauliBasis()^Nr, real.(data))
4631
end
4732

48-
"""
49-
ChiMatrix(sop::DenseSuperOpType)
33+
function chi(op::ChoiStateType; tol=1e-9)
34+
(basis_l(op) == basis_r(op)) || throw(ArgumentError("Choi state must map between square operators in order to be converted to chi represenation"))
5035

51-
Convert a superoperator to its representation as a Chi matrix.
52-
"""
53-
function ChiMatrix(sop::DenseSuperOpType{B, B, T}) where {B, T}
54-
num_qubits = length(sop.basis_l)
55-
sop_dim = 4 ^ num_qubits
56-
po = pauli_operators(num_qubits)
57-
data = Matrix{eltype(T)}(undef, (sop_dim, sop_dim))
58-
for (idx, jdx) in Iterators.product(1:sop_dim, 1:sop_dim)
59-
data[idx, jdx] = tr((spre(po[idx]) * spost(po[jdx])).data' * sop.data) / sop_dim
36+
bl, br = basis_l(basis_l(op)), basis_r(basis_l(op))
37+
for b in (bl, br)
38+
for i=1:length(b)
39+
(b[i] isa NLevelBasis) || throw(ArgumentError("Choi state must be over systems composed of SpinBasis(1//2) to be converted to chi representation"))
40+
end
6041
end
61-
return DenseChiMatrix(sop.basis_l, sop.basis_r, data)
42+
43+
Nl, Nr = length(bl), length(br)
44+
Ul = ket_bra_to_pauli(Nl)
45+
Ur = Nl == Nr ? Ul : ket_bra_to_pauli(Nr)
46+
data = dagger(Ul)*op.data*Ur # TODO figure out normalization
47+
@assert isapprox(imag.(data), zero(data), atol=tol)
48+
Operator(PauliBasis()^Nl, PauliBasis()^Nr, real.(data))
6249
end
6350

6451
"""
65-
PauliTransferMatrix(chi_matrix::DenseChiMatrix)
52+
function pauli(op::SuperOperatorType; tol=1e-9)
53+
bl, br = basis_l(op), basis_r(op)
54+
((basis_l(bl) == basis_r(bl)) && (basis_l(br) == basis_r(br))) || throw(ArgumentError("Superoperator must map between square operators in order to be converted to pauli represenation"))
6655
67-
Convert a χ matrix to its representation as a Pauli transfer matrix.
68-
"""
69-
function PauliTransferMatrix(chi_matrix::DenseChiMatrix{B, B, T}) where {B, T}
70-
num_qubits = length(chi_matrix.basis_l)
71-
sop_dim = 4 ^ num_qubits
72-
po = pauli_operators(num_qubits)
73-
data = Matrix{real(eltype(T))}(undef, (sop_dim, sop_dim))
74-
for (idx, jdx) in Iterators.product(1:sop_dim, 1:sop_dim)
75-
data[idx, jdx] = tr(mapreduce(x -> po[idx] * po[x[1]] * po[jdx] * po[x[2]] * chi_matrix.data[x[1], x[2]],
76-
+,
77-
Iterators.product(1:16, 1:16)).data) / sop_dim |> real
56+
for b in (basis_l(bl), basis_l(br))
57+
for i=1:length(b)
58+
(b[i] isa NLevelBasis) || throw(ArgumentError("Superoperator must be defined only systems composed of NLevelBasis to be converted to pauli representation"))
59+
end
7860
end
79-
return DensePauliTransferMatrix(chi_matrix.basis_l, chi_matrix.basis_r, data)
8061
end
81-
82-
"""
83-
SuperOperator(chi_matrix::DenseChiMatrix)
84-
85-
Convert a χ matrix to its representation as a superoperator.
86-
"""
87-
SuperOperator(chi_matrix::DenseChiMatrix) = SuperOperator(PauliTransferMatrix(chi_matrix))
88-
89-
"""
90-
ChiMatrix(ptm::DensePauliTransferMatrix)
91-
92-
Convert a Pauli transfer matrix to its representation as a χ matrix.
9362
"""
94-
ChiMatrix(ptm::DensePauliTransferMatrix) = ChiMatrix(SuperOperator(ptm))

src/superoperators.jl

Lines changed: 0 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ const SparseSuperOpType{BL,BR} = Union{SparseOpPureType{<:KetBraBasis,<:KetBraBa
1212

1313
const SuperOperatorType = Operator{<:KetBraBasis,<:KetBraBasis}
1414
const ChoiStateType = Operator{<:ChoiBasis,<:ChoiBasis}
15-
const PauliTransferType = Operator{<:ChoiBasis,<:ChoiBasis}
1615

1716
#const ChoiBasisType = Union{CompositeBasis{ChoiBasis,T} where {T}, CompositeBasis{ChoiBasis{B},T} where {B,T}}
1817
#const ChoiStateType = Operator{ChoiBasisType,ChoiBasisType}
@@ -69,61 +68,3 @@ identitysuperoperator(op::DenseSuperOpType) =
6968
identitysuperoperator(op::SparseSuperOpType) =
7069
Operator(op.basis_l, op.basis_r, sparse(one(eltype(op.data))I, size(op.data)))
7170

72-
# TODO this should maybe be exported?
73-
# TODO also maybe more efficient to super-tensor product vec'd single qubit transformation
74-
function _ketbra_to_pauli()
75-
b = SpinBasis(1//2)
76-
pvec(fn) = vec(fn(b)).data
77-
kb2p = sparse(hcat(map(pvec, [identityoperator, sigmax, sigmay, sigmaz])...)')
78-
end
79-
80-
#_Ukb2p = _ketbra_to_pauli()
81-
82-
function pauli(op::SuperOperatorType; tol=1e-9)
83-
bl, br = basis_l(op), basis_r(op)
84-
((basis_l(bl) == basis_r(bl)) && (basis_l(br) == basis_r(br))) || throw(ArgumentError("Superoperator must map between square operators in order to be converted to pauli represenation"))
85-
86-
for b in (basis_l(bl), basis_l(br))
87-
for i=1:length(b)
88-
(b[i] isa SpinBasis && dimension(b[i]) == 2) || throw(ArgumentError("Superoperator must be over systems composed of SpinBasis(1//2) to be converted to pauli representation"))
89-
end
90-
end
91-
92-
Nl, Nr = length(basis_l(bl)), length(basis_l(br))
93-
Ul = ket_bra_to_pauli(Nl)
94-
Ur = Nl == Nr ? Ul : ket_bra_to_pauli(Nr)
95-
data = dagger(Ul)*op.data*Ur # TODO figure out normalization
96-
@assert isapprox(imag.(data), zero(data), atol=tol)
97-
Operator(PauliBasis()^Nl, PauliBasis()^Nr, real.(data))
98-
end
99-
100-
function chi(op::ChoiStateType; tol=1e-9)
101-
(basis_l(op) == basis_r(op)) || throw(ArgumentError("Choi state must map between square operators in order to be converted to chi represenation"))
102-
103-
bl, br = basis_l(basis_l(op)), basis_r(basis_l(op))
104-
for b in (bl, br)
105-
for i=1:length(b)
106-
(b[i] isa NLevelBasis) || throw(ArgumentError("Choi state must be over systems composed of SpinBasis(1//2) to be converted to chi representation"))
107-
end
108-
end
109-
110-
Nl, Nr = length(bl), length(br)
111-
Ul = ket_bra_to_pauli(Nl)
112-
Ur = Nl == Nr ? Ul : ket_bra_to_pauli(Nr)
113-
data = dagger(Ul)*op.data*Ur # TODO figure out normalization
114-
@assert isapprox(imag.(data), zero(data), atol=tol)
115-
Operator(PauliBasis()^Nl, PauliBasis()^Nr, real.(data))
116-
end
117-
118-
"""
119-
function pauli(op::SuperOperatorType; tol=1e-9)
120-
bl, br = basis_l(op), basis_r(op)
121-
((basis_l(bl) == basis_r(bl)) && (basis_l(br) == basis_r(br))) || throw(ArgumentError("Superoperator must map between square operators in order to be converted to pauli represenation"))
122-
123-
for b in (basis_l(bl), basis_l(br))
124-
for i=1:length(b)
125-
(b[i] isa NLevelBasis) || throw(ArgumentError("Superoperator must be defined only systems composed of NLevelBasis to be converted to pauli representation"))
126-
end
127-
end
128-
end
129-
"""

0 commit comments

Comments
 (0)