Skip to content

Commit e519577

Browse files
committed
Move pauli stuff
1 parent f058c2d commit e519577

File tree

2 files changed

+43
-135
lines changed

2 files changed

+43
-135
lines changed

src/pauli.jl

Lines changed: 43 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,95 +1,62 @@
1-
import Base: isapprox
2-
import QuantumInterface: PauliBasis
31

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

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

19-
Convert a Pauli transfer matrix to its representation as a superoperator.
20-
"""
21-
function SuperOperator(ptm::DensePauliTransferMatrix)
22-
num_qubits = nsubsystems(ptm.basis_l[1])
23-
pbv = pauli_basis_vectors(num_qubits)
24-
sop_dim = 4 ^ num_qubits
25-
data = pbv * ptm.data * pbv' / sop_dim
26-
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])...)')
2711
end
2812

29-
"""
30-
PauliTransferMatrix(unitary::DenseOpType)
13+
_Ukb2p = _ketbra_to_pauli()
3114

32-
Convert an operator, presumably a unitary operator, to its representation as a
33-
Pauli transfer matrix.
34-
"""
35-
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"))
3618

37-
"""
38-
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
3924

40-
Convert an operator, presumably a unitary operator, to its representation as a χ matrix.
41-
"""
42-
function ChiMatrix(unitary::DenseOpType)
43-
num_qubits = nsubsystems(unitary.basis_l)
44-
pbv = pauli_basis_vectors(num_qubits)
45-
aj = pbv' * reshape(unitary.data, 4 ^ num_qubits)
46-
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))
4731
end
4832

49-
"""
50-
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"))
5135

52-
Convert a superoperator to its representation as a Chi matrix.
53-
"""
54-
function ChiMatrix(sop::DenseSuperOpType{B, B, T}) where {B, T}
55-
num_qubits = length(sop.basis_l)
56-
sop_dim = 4 ^ num_qubits
57-
po = pauli_operators(num_qubits)
58-
data = Matrix{eltype(T)}(undef, (sop_dim, sop_dim))
59-
for (idx, jdx) in Iterators.product(1:sop_dim, 1:sop_dim)
60-
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
6141
end
62-
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))
6349
end
6450

6551
"""
66-
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"))
6755
68-
Convert a χ matrix to its representation as a Pauli transfer matrix.
69-
"""
70-
function PauliTransferMatrix(chi_matrix::DenseChiMatrix{B, B, T}) where {B, T}
71-
num_qubits = length(chi_matrix.basis_l)
72-
sop_dim = 4 ^ num_qubits
73-
po = pauli_operators(num_qubits)
74-
data = Matrix{real(eltype(T))}(undef, (sop_dim, sop_dim))
75-
for (idx, jdx) in Iterators.product(1:sop_dim, 1:sop_dim)
76-
data[idx, jdx] = tr(mapreduce(x -> po[idx] * po[x[1]] * po[jdx] * po[x[2]] * chi_matrix.data[x[1], x[2]],
77-
+,
78-
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
7960
end
80-
return DensePauliTransferMatrix(chi_matrix.basis_l, chi_matrix.basis_r, data)
8161
end
82-
83-
"""
84-
SuperOperator(chi_matrix::DenseChiMatrix)
85-
86-
Convert a χ matrix to its representation as a superoperator.
87-
"""
88-
SuperOperator(chi_matrix::DenseChiMatrix) = SuperOperator(PauliTransferMatrix(chi_matrix))
89-
90-
"""
91-
ChiMatrix(ptm::DensePauliTransferMatrix)
92-
93-
Convert a Pauli transfer matrix to its representation as a χ matrix.
9462
"""
95-
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}
@@ -79,61 +78,3 @@ identitysuperoperator(op::DenseSuperOpType) =
7978
identitysuperoperator(op::SparseSuperOpType) =
8079
Operator(op.basis_l, op.basis_r, sparse(one(eltype(op.data))I, size(op.data)))
8180

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

0 commit comments

Comments
 (0)