Pauli Algebra
Contents
import sys
sys.path.insert(0, '..')
import numpy as np
import qutip as qt
import src
from src import (utils, paulialg, stabilizer, circuit)
1.4. Pauli Algebra#
1.4.1. Dot Productor (Matrix Multiplication)#
Dot productor (composition) of Pauli operators is implemented as the matrix multiplication matmul
, which can be implemented using the operand @
.
paulialg.pauli('X') @ paulialg.pauli('Y'), paulialg.pauli('Y') @ paulialg.pauli('X')
(+iZ, -iZ)
Dot product of Pauli polynomials will be expanded.
poly = paulialg.pauli('XX') + paulialg.pauli('YY') - 0.5 * paulialg.pauli('ZZ')
poly @ poly
0.25000 II +0.50000 YY +0.50000 XX +0.50000 YY +1 II -1 ZZ +0.50000 XX -1 ZZ +1 II
Terms will not be combined automatically. To combine them, the .reduce()
method should be explicitly called.
(poly @ poly).reduce()
2.25000 II -2 ZZ +1 XX +1 YY
1.4.2. Trace of Pauli operators#
Pauli.trace()
will return the trace of a Pauli operatorPauliList.trace()
will return the trace of a list of Pauli operatorsPauliPolynomial.trace()
will return the trace of a Pauli polynomial
paulialg.pauli('II').trace()
4
paulialg.paulis('II','YY').trace()
array([4, 0])
(3*paulialg.pauli('II')).trace()
(12+0j)
(3*paulialg.pauli('II')+(3+2.5j)*paulialg.pauli('II')).trace()
(24+10j)
1.4.3. Weight (number of non-identity support)#
Pauli.weight()
will return the weight (the support of non identity operators) of a Pauli operatorPauliList.weight()
will return the weight of a list of Pauli operators
paulialg.pauli('IXIYZII').weight()
3
paulialg.paulis('IXIYZII','IXIIIII').weight()
array([3, 1])
1.4.4. Type conversion#
Automatic type conversion enables the algebra to be carried out among different classes with great flexibiliity.
When
Pauli
is multiplied (*
) by a generic number (beyond powers of the imaginary unit), it is converted toPauliMonomial
.When
Pauli
orPauliMonomial
is added (+
) or subtracted (-
) with other Pauli objects, they are converted toPauliPolynomial
.The dot product (
@
) generally returnsPauliPolynomial
, unless the two Pauli objects are bothPauli
, in which case it returnsPauli
.
1.5. Clifford Transformation#
PauliList
provides useful methods to implement Clifford transformations efficiently on all Pauli operators together. The same methods are available to all its subclasses (including PauliPolynomial
, CliffordMap
, StabilizerState
).
1.5.1. Clifford Rotation#
A Clifford rotation is a \(\mathbb{Z}_4\) rotation in the Clifford group generated by a single Pauli operator, which takes the form of
$\(
U=e^{\frac{i\pi}{4}\sigma}=\frac{1}{\sqrt{2}}(1+i \sigma)
\)\(
Every Pauli operator is transformed by \)\sigma \to U^\dagger \sigma U$. The Clifford rotation can be applied by the method .rotate_by(gen)
(given the generator gen
). The operation is in-place (meaning that the operators in the Pauli list will be modified).
paulialg.paulis('II','XX','YY','ZZ').rotate_by(paulialg.pauli('XI'))
+II
+XX
+ZY
-YZ
1.5.2. Clifford Map#
A Clifford map is a generic clifford transformation by specifying how each single Pauli operator gets mapped to. It can be listed as a table
cmap = stabilizer.random_clifford_map(2)
cmap
CliffordMap(
X0-> -IZ
Z0-> +YY
X1-> -ZZ
Z1-> -XZ)
It can be applied by the method .transform_by(cmap)
(given the Clifford map cmap
).
paulialg.paulis('II','XX','YY','ZZ').transform_by(cmap)
+II
+ZI
+IX
-ZX
1.5.3. Masked Transformation#
Clifford transformation can be applied to a subsystem of qubits specified by a mask.
mask = np.array([True,False,False,True])
paulialg.paulis('IIII','XXXX','YYYY','ZZZZ').rotate_by(paulialg.pauli('XY'), mask)
+IIII
-IXXZ
+ZYYI
+ZZZZ
mask = np.array([True,False,False,True])
paulialg.paulis('IIII','XXXX','YYYY','ZZZZ').transform_by(cmap, mask)
+IIII
+ZXXI
+IYYX
-ZZZX