Prev Tutorial: SuperOp
Next Tutorial: PTM
Introduction
Pauli basis Chi-matrix representation of a quantum channel.
The Chi-matrix representation of an n-qubit quantum channel \(\mathcal{E}\) is a matrix χ such that the evolution of a DensityMatrix \(\rho\) is given by
\[
\mathcal{E}(\rho)=\frac{1}{2^{n}} \sum_{i, j} \chi_{i, j} P_{i} \rho P_{j}
\]
where
\[
\left[P_{0}, P_{1}, \ldots, P_{4^{n}-1}\right]
\]
is the n-qubit Pauli basis in lexicographic order. It is related to the Choi representation by a change of basis of the Choi-matrix into the Pauli basis. The
\[
\frac{1}{2^{n}}
\]
in the definition above is a normalization factor that arises from scaling the Pauli basis to make it orthonormal.
Please refer: C.J. Wood, J.D. Biamonte, D.G. Cory, Tensor networks and graphical calculus for open quantum systems, Quant. Inf. Comp. 15, 0579-0811 (2015). arXiv:1111.6950 [quant-ph]
In QPanda3 Quantum Information
Constructing a Chi object
Here is API doc
From Choi
Generate another Chi object from a Choi object
Please refer to Choi
Python
import numpy as np
def test_construct_from_choi():
K0 = np.array([[0, 1], [1+0.j, 0]])
K1 = np.array([[1, 0], [0+0.j, -1]])
K2 = np.array([[0+0.j, -1.j], [1.j, 0]])
Ks1 = [K0, K1, K2]
Ks2 = [K1]
Kra3 = Kraus(Ks1, Ks2)
choi = Choi(Kra3)
chi = Chi(choi)
print("chi:",chi)
if __name__ == "__main__":
test_construct_from_choi()
Output
chi: {
{
{(0,0)},{(0,0)},{(0,0)},{(0,0)},
}
{
{(0,0)},{(2,0)},{(0,0)},{(0,0)},
}
{
{(0,0)},{(0,0)},{(2,0)},{(0,0)},
}
{
{(0,0)},{(0,0)},{(0,0)},{(2,0)},
}
}
From Chi
Generate another Chi object from a Chi object
Python
import numpy as np
def test_construct_from_chi():
K0 = np.array([[0, 1], [1+0.j, 0]])
K1 = np.array([[1, 0], [0+0.j, -1]])
K2 = np.array([[0+0.j, -1.j], [1.j, 0]])
Ks1 = [K0, K1, K2]
Ks2 = [K1]
Kra3 = Kraus(Ks1, Ks2)
chi = Chi(Kra3)
chi2 = Chi(chi)
print("chi2:", chi2)
if __name__ == "__main__":
test_construct_from_chi()
Output
chi2: {
{
{(0,0)},{(0,0)},{(0,0)},{(0,0)},
}
{
{(0,0)},{(2,0)},{(0,0)},{(0,0)},
}
{
{(0,0)},{(0,0)},{(2,0)},{(0,0)},
}
{
{(0,0)},{(0,0)},{(0,0)},{(2,0)},
}
}
From SuperOp
Generate another Chi object from a SuperOp object
Please refer to SuperOp
Python
import numpy as np
def test_construct_from_superop():
K0 = np.array([[0, 1], [1+0.j, 0]])
K1 = np.array([[1, 0], [0+0.j, -1]])
K2 = np.array([[0+0.j, -1.j], [1.j, 0]])
Ks1 = [K0, K1, K2]
Ks2 = [K1]
Kra3 = Kraus(Ks1, Ks2)
sop = SuperOp(Kra3)
chi = Chi(sop)
print("chi:", chi)
if __name__ == "__main__":
test_construct_from_superop()
Output
chi: {
{
{(0,0)},{(0,0)},{(0,0)},{(0,0)},
}
{
{(0,0)},{(2,0)},{(0,0)},{(0,0)},
}
{
{(0,0)},{(0,0)},{(2,0)},{(0,0)},
}
{
{(0,0)},{(0,0)},{(0,0)},{(2,0)},
}
}
From Kraus
Generate another Chi object from a Kraus object
Please refer to Kraus
Python
import numpy as np
def test_construct_from_kraus():
K0 = np.array([[0, 1], [1+0.j, 0]])
K1 = np.array([[1, 0], [0+0.j, -1]])
K2 = np.array([[0+0.j, -1.j], [1.j, 0]])
Ks1 = [K0, K1, K2]
Ks2 = [K1]
Kra3 = Kraus(Ks1, Ks2)
chi = Chi(Kra3)
print("chi:",chi)
if __name__ == "__main__":
test_construct_from_kraus()
Output
chi: {
{
{(0,0)},{(0,0)},{(0,0)},{(0,0)},
}
{
{(0,0)},{(2,0)},{(0,0)},{(0,0)},
}
{
{(0,0)},{(0,0)},{(2,0)},{(0,0)},
}
{
{(0,0)},{(0,0)},{(0,0)},{(2,0)},
}
}
From PTM
Generate another SuperOp object from a PTM object
Please refer to PTM
Python
import numpy as np
def test_construct_from_ptm():
K0 = np.array([[0, 1], [1+0.j, 0]])
K1 = np.array([[1, 0], [0+0.j, -1]])
K2 = np.array([[0+0.j, -1.j], [1.j, 0]])
Ks1 = [K0, K1, K2]
Ks2 = [K1]
Kra3 = Kraus(Ks1, Ks2)
ptm = PTM(Kra3)
chi = Chi(ptm)
print("chi:", chi)
if __name__ == "__main__":
test_construct_from_ptm()
Output
chi: {
{
{(0,0)},{(0,0)},{(0,0)},{(0,0)},
}
{
{(0,0)},{(2,0)},{(0,0)},{(0,0)},
}
{
{(0,0)},{(0,0)},{(2,0)},{(0,0)},
}
{
{(0,0)},{(0,0)},{(0,0)},{(2,0)},
}
}
Obtain internal data
Input and outut dim
Obtain the input dimension input_dim and output dimension output_dim of the quantum channel
Here is API doc for Chi.get_input_dim
Here is API doc for Chi.get_output_dim
Python
import numpy as np
def test_dim():
K0 = np.array([[0, 1], [1+0.j, 0]])
K1 = np.array([[1, 0], [0+0.j, -1]])
K2 = np.array([[0+0.j, -1.j], [1.j, 0]])
Ks1 = [K0, K1, K2]
Ks2 = [K1]
Kra3 = Kraus(Ks1, Ks2)
chi = Chi(Kra3)
input_dim = chi.get_input_dim()
output_dim = chi.get_output_dim()
print("input_dim:",input_dim)
print("output_dim:",output_dim)
if __name__ == "__main__":
test_dim()
Output
input_dim: 2
output_dim: 2
Evolution of quantum states
Here is API doc for Chi.evolve
DensityMatrix
Evolution of a DensityMatrix object, and the evolution result is returned as a DensityMatrix object. The dimension of the density matrix is obtained by the member method dim() and should be equal to the input dimension of the Chi object
Please refer to DensityMatrix.
Python
import numpy as np
def test_evolve():
data = np.array(
[[0.69272168 + 0.j,0.38338527 - 0.17772383j],
[0.38338527 + 0.17772383j,0.30727832 + 0.j]]
)
dm = DensityMatrix(data)
K0 = np.array([[0, 1], [1+0.j, 0]])
K1 = np.array([[1, 0], [0+0.j, -1]])
K2 = np.array([[0+0.j, -1.j], [1.j, 0]])
Ks1 = [K0, K1, K2]
Ks2 = [K1]
Kra3 = Kraus(Ks1, Ks2)
chi = Chi(Kra3)
res = chi.evolve(dm)
print("res:", res)
if __name__ == "__main__":
test_evolve()
Output
res: {
{
{(1.30728,0)},{(-0.383385,0.177724)},
}
{
{(-0.383385,-0.177724)},{(1.69272,0)},
}
}
StateVector
Evolution of the StateVector object is performed, and the result is returned as a DensityMatrix object. The dimension of the StateVector object is obtained by the member method dim() and should be equal to the input dimension of the Chi object
Please refer to DensityMatrix
Please refer to StateVector
Python
import numpy as np
def test_evolve():
stv = StateVector()
K0 = np.array([[0, 1], [1+0.j, 0]])
K1 = np.array([[1, 0], [0+0.j, -1]])
K2 = np.array([[0+0.j, -1.j], [1.j, 0]])
Ks1 = [K0, K1, K2]
Ks2 = [K1]
Kra3 = Kraus(Ks1, Ks2)
chi = Chi(Kra3)
res = chi.evolve(stv)
print("res:",res)
if __name__ == "__main__":
test_evolve()
output
res: {
{
{(1,0)},{(0,0)},
}
{
{(0,0)},{(2,0)},
}
}
Boolean function
Equal
Determine whether the internal data of two Chi objects are equal
Here is API doc
Python
import numpy as np
def test_equal():
K0 = np.array([[0, 1], [1+0.j, 0]])
K1 = np.array([[1, 0], [0+0.j, -1]])
K2 = np.array([[0+0.j, -1.j], [1.j, 0]])
Ks1 = [K0, K1, K2]
Ks2 = [K1]
Kra3 = Kraus(Ks1, Ks2)
chi = Chi(Kra3)
chi2 = chi
print(chi2==chi)
if __name__ == "__main__":
test_equal()
Output