import sys
sys.path.insert(0, '..')
import numpy as np
import qutip as qt
import src
from src import (utils, paulialg, stabilizer, circuit)

2.1. Construct Clifford Maps#

identity_map(N) constructs an identity Clifford map on \(N\) qubits.

stabilizer.identity_map(4)
CliffordMap(
  X0-> +XIII
  Z0-> +ZIII
  X1-> +IXII
  Z1-> +IZII
  X2-> +IIXI
  Z2-> +IIZI
  X3-> +IIIX
  Z3-> +IIIZ)

random_pauli_map(N) samples a random Clifford map made of random single-qubit Clifford gates on \(N\) qubits, i.e. \(U=\prod_i U_i\in\mathrm{Cl}(2)^N\). Each realization specifies a random local Pauli basis.

stabilizer.random_pauli_map(4)
CliffordMap(
  X0-> -YIII
  Z0-> -ZIII
  X1-> +IZII
  Z1-> +IXII
  X2-> +IIZI
  Z2-> -IIYI
  X3-> +IIIZ
  Z3-> +IIIX)

random_clifford_map(N) samples a globally random Clifford map on \(N\) qubits, i.e. \(U\in\mathrm{Cl}(2^N)\). Each realization specifies a random global stabilizer basis.

stabilizer.random_clifford_map(4)
CliffordMap(
  X0-> -XXIX
  Z0-> +IXXY
  X1-> +ZZXX
  Z1-> -IYYY
  X2-> +YXYZ
  Z2-> +YIIY
  X3-> -XZIZ
  Z3-> +ZIZZ)

clifford_rotation_map(N) constructs a Clifford map based for a Clifford rotation given its generator.

stabilizer.clifford_rotation_map('-XXYZ')
CliffordMap(
  X0-> +XIII
  Z0-> +YXYZ
  X1-> +IXII
  Z1-> +XYYZ
  X2-> +XXZZ
  Z2-> -XXXZ
  X3-> -XXYY
  Z3-> +IIIZ)

2.2. Construct Stabilizer States#

maximally_mixed_state(N) constructs a \(N\)-qubit maximally mixed state (by setting the density matrix to full rank). $\(\rho=2^{-N}\mathbb{1}.\)$

stabilizer.maximally_mixed_state(4)
StabilizerState()

zero_state(N) constructs a \(N\)-qubit all-zero state $\(\rho=|0\cdots0\rangle\langle 0\cdots0|=\prod_{i}\frac{1+Z_i}{2}.\)$

stabilizer.zero_state(4)
StabilizerState(
   +ZIII
   +IZII
   +IIZI
   +IIIZ)

one_state(N) constructs a \(N\)-qubit all-one state $\(\rho=|1\cdots1\rangle\langle 1\cdots1|=\prod_{i}\frac{1-Z_i}{2}.\)$

stabilizer.zero_state(4).ps
array([0, 0, 0, 0, 0, 0, 0, 0])

ghz_state(N) constructs a \(N\)-qubit GHZ state $\(\rho = |\Psi\rangle\langle\Psi|, \qquad \text{with }|\Psi\rangle=\frac{1}{\sqrt{2}}(|0\cdots0\rangle+|1\cdots1\rangle).\)$

stabilizer.ghz_state(4)
StabilizerState(
   +ZZII
   +IZZI
   +IIZZ
   +XXXX)

random_pauli_map(N) samples a \(N\) qubit random Pauli state. $\(\rho=U|0\cdots0\rangle\langle 0\cdots0|U^\dagger,\qquad\text{with }U\in \mathrm{Cl}(2)^N.\)$

stabilizer.random_pauli_map(4)
CliffordMap(
  X0-> -ZIII
  Z0-> +YIII
  X1-> +IZII
  Z1-> +IXII
  X2-> -IIZI
  Z2-> +IIXI
  X3-> -IIIY
  Z3-> +IIIZ)

random_clifford_map(N) samples a \(N\) qubit random Clifford (random stabilizer) state. $\(\rho=U|0\cdots0\rangle\langle 0\cdots0|U^\dagger,\qquad\text{with }U\in \mathrm{Cl}(2^N).\)$

stabilizer.random_clifford_state(4)
StabilizerState(
   +IIIY
   +XXXI
   +IXXY
   +XIXI)

stabilizer_state(...) is a universal constructor of stabilizer state by specifying all stabilizers.

stabilizer.stabilizer_state('XXY','ZZI','IZZ')
StabilizerState(
   +XXY
   +ZZI
   +IZZ)

2.3. Construct Stabilizer States by Checker Matrix#

The user can also construct stabilizer state by low-level constructor StabilizerState(gs, ps, r=0):

Parameters

  • gs: int (2*N, 2*N): strings of Pauli operators in the stabilizer tableau.

  • ps: int (2*N): phase indicators (should only be 0 or 2).

  • r:  int: number of logical qubits (log2 rank of density matrix)’’’

Returns

  • Object of StabilizerState

tmp_state = stabilizer.random_clifford_state(3)
print(tmp_state)
StabilizerState(
   +YXY
   +XYY
   +ZIZ)
gs = tmp_state.gs
ps = tmp_state.ps
stabilizer.StabilizerState(gs=gs,ps=ps)
StabilizerState(
   +YXY
   +XYY
   +ZIZ)

A hack to inspect the full stabilizer tableau is by converting StabilizerState to PauliList by

stabilizer.stabilizer_state('XXY','ZZI','IZZ')[:]
 +XXY
 +ZZI
 +IZZ
 +ZII
 +ZXX
 +ZIX

2.4. State-Map convertion#

Stabilizer states and Clifford maps can be mapped to each other.

rho = stabilizer.stabilizer_state('XXX','ZZI','IZZ')
print("quantum state: \n", rho)
quantum state: 
 StabilizerState(
   +XXX
   +ZZI
   +IZZ)
rho.to_map()
CliffordMap(
  X0-> +ZII
  Z0-> +XXX
  X1-> +IXX
  Z1-> +ZZI
  X2-> +IIX
  Z2-> +IZZ)

And Clifford map can be converted back to the stabilizer state.

rho.to_map().to_state()
StabilizerState(
   +XXX
   +ZZI
   +IZZ)
  • .to_map() and .to_state() will make new copies of Pauli string data in the memory.

The information about the rank of the density matrix is lost in the Clifford map, so the back conversion will result in a zero rank stabilizer state.