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