Skip to content

Commit 729cf18

Browse files
committed
WIP
1 parent 02bfbe6 commit 729cf18

File tree

3 files changed

+22
-174
lines changed

3 files changed

+22
-174
lines changed

src/QuantumOpticsBase.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import QuantumInterface: Basis, GenericBasis, CompositeBasis, basis, basis_l, ba
99
addible, check_addible, multiplicable, check_multiplicable, reduced, ptrace, permutesystems,
1010
dagger, directsum, , dm, embed, nsubsystems, expect, identityoperator, identitysuperoperator,
1111
permutesystems, projector, ptrace, reduced, tensor, , variance, apply!,
12-
super, choi, kraus, vec, spre, spost, sprepost, liouvillian
12+
vec, unvec, super, choi, kraus, stinespring, pauli, chi, spre, spost, sprepost, liouvillian
1313

1414
# index helpers
1515
import QuantumInterface: complement, remove, shiftremove, reducedindices!, check_indices, check_sortedindices, check_embed_indices
@@ -39,7 +39,8 @@ export Basis, GenericBasis, CompositeBasis, basis, basis_l, basis_r,
3939
AbstractTimeDependentOperator, TimeDependentSum, set_time!,
4040
current_time, time_shift, time_stretch, time_restrict, static_operator,
4141
#superoperators
42-
KetBraBasis, ChoiBasis, super, choi, kraus, vec,
42+
KetBraBasis, ChoiBasis, PauliBasis,
43+
vec, unvec, super, choi, kraus, stinespring, pauli, chi,
4344
spre, spost, sprepost, liouvillian, identitysuperoperator,
4445
SuperOperatorType, DenseSuperOpType, SparseSuperOpType,
4546
#fock
@@ -68,8 +69,7 @@ export Basis, GenericBasis, CompositeBasis, basis, basis_l, basis_r,
6869
tracedistance, tracedistance_h, tracedistance_nh,
6970
entropy_vn, entropy_renyi, fidelity, ptranspose, PPT,
7071
negativity, logarithmic_negativity, entanglement_entropy,
71-
PauliBasis, PauliTransferMatrix, DensePauliTransferMatrix,
72-
ChiMatrix, DenseChiMatrix, avg_gate_fidelity,
72+
avg_gate_fidelity,
7373
SumBasis, directsum, , LazyDirectSum, getblock, setblock!,
7474
qfunc, wigner, coherentspinstate, qfuncsu2, wignersu2
7575
#apply

src/pauli.jl

Lines changed: 0 additions & 170 deletions
Original file line numberDiff line numberDiff line change
@@ -1,167 +1,6 @@
11
import Base: isapprox
22

3-
"""
4-
Base class for Pauli transfer matrix classes.
5-
"""
6-
abstract type PauliTransferMatrix{B1, B2} end
7-
8-
9-
"""
10-
DensePauliTransferMatrix(B1, B2, data)
11-
12-
DensePauliTransferMatrix stored as a dense matrix.
13-
"""
14-
mutable struct DensePauliTransferMatrix{B1,B2,T<:Matrix} <: PauliTransferMatrix{B1, B2}
15-
basis_l::B1
16-
basis_r::B2
17-
data::T
18-
function DensePauliTransferMatrix(basis_l::BL, basis_r::BR, data::T) where {BL,
19-
BR,
20-
T<:Matrix}
21-
if length(basis_l[1])*length(basis_l[2]) != size(data, 1) ||
22-
length(basis_r[1])*length(basis_r[2]) != size(data, 2)
23-
throw(DimensionMismatch())
24-
end
25-
new{BL, BR, T}(basis_l, basis_r, data)
26-
end
27-
end
28-
29-
PauliTransferMatrix(ptm::DensePauliTransferMatrix) = ptm
30-
31-
function *(ptm0::DensePauliTransferMatrix{B, B},ptm1::DensePauliTransferMatrix{B, B}) where B
32-
return DensePauliTransferMatrix(ptm0.basis_l, ptm1.basis_r, ptm0.data*ptm1.data)
33-
end
34-
35-
"""
36-
Base class for χ (process) matrix classes.
37-
"""
38-
abstract type ChiMatrix{B1, B2} end
39-
40-
"""
41-
DenseChiMatrix(b, b, data)
42-
43-
DenseChiMatrix stored as a dense matrix.
44-
"""
45-
mutable struct DenseChiMatrix{B1,B2,T<:Matrix} <: PauliTransferMatrix{B1, B2}
46-
basis_l::B1
47-
basis_r::B2
48-
data::T
49-
function DenseChiMatrix(basis_l::BL, basis_r::BR, data::T) where {BL,BR,T<:Matrix}
50-
if length(basis_l[1])*length(basis_l[2]) != size(data, 1) ||
51-
length(basis_r[1])*length(basis_r[2]) != size(data, 2)
52-
throw(DimensionMismatch())
53-
end
54-
new{BL, BR, T}(basis_l, basis_r, data)
55-
end
56-
end
57-
58-
ChiMatrix(chi_matrix::DenseChiMatrix) = chi_matrix
59-
60-
"""
61-
A dictionary that represents the Pauli algebra - for a pair of Pauli operators
62-
σᵢσⱼ information about their product is given under the key "ij". The first
63-
element of the dictionary value is the Pauli operator, and the second is the
64-
scalar multiplier. For example, σ₀σ₁ = σ₁, and `"01" => ("1", 1)`.
65-
"""
66-
const pauli_multiplication_dict = Dict(
67-
"00" => ("0", 1.0+0.0im),
68-
"23" => ("1", 0.0+1.0im),
69-
"30" => ("3", 1.0+0.0im),
70-
"22" => ("0", 1.0+0.0im),
71-
"21" => ("3", -0.0-1.0im),
72-
"10" => ("1", 1.0+0.0im),
73-
"31" => ("2", 0.0+1.0im),
74-
"20" => ("2", 1.0+0.0im),
75-
"01" => ("1", 1.0+0.0im),
76-
"33" => ("0", 1.0+0.0im),
77-
"13" => ("2", -0.0-1.0im),
78-
"32" => ("1", -0.0-1.0im),
79-
"11" => ("0", 1.0+0.0im),
80-
"03" => ("3", 1.0+0.0im),
81-
"12" => ("3", 0.0+1.0im),
82-
"02" => ("2", 1.0+0.0im),
83-
)
84-
85-
"""
86-
multiply_pauli_matirices(i4::String, j4::String)
87-
88-
A function to algebraically determine result of multiplying two
89-
(N-qubit) Pauli matrices. Each Pauli matrix is represented by a string
90-
in base 4. For example, σ₃⊗σ₀⊗σ₂ would be "302". The product of any pair of
91-
Pauli matrices will itself be a Pauli matrix multiplied by any of the 1/4 roots
92-
of 1.
93-
"""
94-
cache_multiply_pauli_matrices() = begin
95-
local pauli_multiplication_cache = Dict()
96-
function _multiply_pauli_matirices(i4, j4)
97-
if (i4, j4) keys(pauli_multiplication_cache)
98-
pauli_multiplication_cache[(i4, j4)] = mapreduce(x -> pauli_multiplication_dict[prod(x)],
99-
(x,y) -> (x[1] * y[1], x[2] * y[2]),
100-
zip(i4, j4))
101-
end
102-
return pauli_multiplication_cache[(i4, j4)]
103-
end
104-
end
105-
multiply_pauli_matirices = cache_multiply_pauli_matrices()
106-
107-
function *(chi_matrix0::DenseChiMatrix{B, B},chi_matrix1::DenseChiMatrix{B, B}) where B
108-
109-
num_qubits = length(chi_matrix0.basis_l[1].shape)
110-
sop_dim = 2 ^ prod(chi_matrix0.basis_l[1].shape)
111-
ret = zeros(ComplexF64, (sop_dim, sop_dim))
1123

113-
for ijkl in Iterators.product(0:(sop_dim-1),
114-
0:(sop_dim-1),
115-
0:(sop_dim-1),
116-
0:(sop_dim-1))
117-
i, j, k, l = ijkl
118-
if (chi_matrix0.data[i+1, j+1] != 0.0) & (chi_matrix1.data[k+1, l+1] != 0.0)
119-
i4, j4, k4, l4 = map(x -> string(x, base=4, pad=2), ijkl)
120-
121-
pauli_product_ik = multiply_pauli_matirices(i4, k4)
122-
pauli_product_lj = multiply_pauli_matirices(l4, j4)
123-
124-
ret[parse(Int, pauli_product_ik[1], base=4)+1,
125-
parse(Int, pauli_product_lj[1], base=4)+1] += (pauli_product_ik[2] * pauli_product_lj[2] * chi_matrix0.data[i+1, j+1] * chi_matrix1.data[k+1, l+1])
126-
end
127-
end
128-
return DenseChiMatrix(chi_matrix0.basis_l, chi_matrix0.basis_r, ret / 2^num_qubits)
129-
end
130-
131-
132-
# TODO MAKE A GENERATOR FUNCTION
133-
"""
134-
pauli_operators(num_qubits::Integer)
135-
136-
Generate a list of N-qubit Pauli operators.
137-
"""
138-
function pauli_operators(num_qubits::Integer)
139-
pauli_funcs = (identityoperator, sigmax, sigmay, sigmaz)
140-
po = []
141-
for paulis in Iterators.product((pauli_funcs for _ in 1:num_qubits)...)
142-
basis_vector = reduce(, f(SpinBasis(1//2)) for f in paulis)
143-
push!(po, basis_vector)
144-
end
145-
return po
146-
end
147-
148-
"""
149-
pauli_basis_vectors(num_qubits::Integer)
150-
151-
Generate a matrix of basis vectors in the Pauli representation given a number
152-
of qubits.
153-
"""
154-
function pauli_basis_vectors(num_qubits::Integer)
155-
po = pauli_operators(num_qubits)
156-
sop_dim = 4 ^ num_qubits
157-
return mapreduce(x -> sparse(reshape(x.data, sop_dim)), (x, y) -> [x y], po)
158-
end
159-
160-
"""
161-
PauliTransferMatrix(sop::DenseSuperOpType)
162-
163-
Convert a superoperator to its representation as a Pauli transfer matrix.
164-
"""
1654
function PauliTransferMatrix(sop::DenseSuperOpType)
1665
num_qubits = nsubsystems(sop.basis_l[1])
1676
pbv = pauli_basis_vectors(num_qubits)
@@ -253,12 +92,3 @@ SuperOperator(chi_matrix::DenseChiMatrix) = SuperOperator(PauliTransferMatrix(ch
25392
Convert a Pauli transfer matrix to its representation as a χ matrix.
25493
"""
25594
ChiMatrix(ptm::DensePauliTransferMatrix) = ChiMatrix(SuperOperator(ptm))
256-
257-
"""Equality for all varieties of superoperators."""
258-
==(sop1::T, sop2::T) where T<:Union{DensePauliTransferMatrix, DenseSuperOpType, DenseChiMatrix} = sop1.data == sop2.data
259-
==(sop1::Union{DensePauliTransferMatrix, DenseSuperOpType, DenseChiMatrix}, sop2::Union{DensePauliTransferMatrix, DenseSuperOpType, DenseChiMatrix}) = false
260-
261-
"""Approximate equality for all varieties of superoperators."""
262-
function isapprox(sop1::T, sop2::T; kwargs...) where T<:Union{DensePauliTransferMatrix, DenseSuperOpType, DenseChiMatrix}
263-
return isapprox(sop1.data, sop2.data; kwargs...)
264-
end

src/superoperators.jl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,21 @@ identitysuperoperator(op::DenseSuperOpType) =
8888

8989
identitysuperoperator(op::SparseSuperOpType) =
9090
Operator(op.basis_l, op.basis_r, sparse(one(eltype(op.data))I, size(op.data)))
91+
92+
function pauli_to_ket_bra(N)
93+
b = SpinBasis(1//2)
94+
paulis = Iterators.repeated([identityoperator(b), sigmax(b), sigmaz(b), sigmay(b)], N)
95+
reduce(hcat, [vec(tensor(p)) for p in Iterators.product(paulis...)])
96+
end
97+
98+
function pauli(op::SuperOperatorType; tol=1e-9)
99+
bl, br = basis_l(op), basis_r(op)
100+
((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"))
101+
((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"))
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 = Ul*op.data*dagger(Ur) # # TODO figure out normalization
106+
@assert isapprox(imag.(data), zero(data), atol=tol)
107+
Operator(PauliBasis()^Nl, PauliBasis()^Nr, real.(data))
108+
end

0 commit comments

Comments
 (0)