|
1 | | -import Base: isapprox |
2 | 1 |
|
| 2 | +const PauliTransferType = Operator{<:ChoiBasis,<:ChoiBasis} |
3 | 3 |
|
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) |
17 | 4 |
|
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])...)') |
26 | 11 | end |
27 | 12 |
|
28 | | -""" |
29 | | - PauliTransferMatrix(unitary::DenseOpType) |
| 13 | +_Ukb2p = _ketbra_to_pauli() |
30 | 14 |
|
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")) |
35 | 18 |
|
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 |
38 | 24 |
|
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)) |
46 | 31 | end |
47 | 32 |
|
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")) |
50 | 35 |
|
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 |
60 | 41 | 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)) |
62 | 49 | end |
63 | 50 |
|
64 | 51 | """ |
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")) |
66 | 55 |
|
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 |
78 | 60 | end |
79 | | - return DensePauliTransferMatrix(chi_matrix.basis_l, chi_matrix.basis_r, data) |
80 | 61 | 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. |
93 | 62 | """ |
94 | | -ChiMatrix(ptm::DensePauliTransferMatrix) = ChiMatrix(SuperOperator(ptm)) |
0 commit comments