The qecc package provides support for elements of the Pauli and Clifford groups in binary symplectic form, including support for algorithms acting on these representations. Note that all classes and functions documented here depend on the numpy package. For more information on the binary symplectic representation, read [CRSS96], Section 2.
The class qecc.BinarySymplecticVector provides a means of representing elements of the Pauli group (neglecting global phases) using binary vectors and such that an element of the Pauli group acting on qubits is . Binary symplectic vectors can be obtained from a single binary list, two binary lists, or converted from another Pauli instance (removing the phase):
>>> import qecc as q
>>> a=[1, 0, 1]; b=[0, 1, 1]
>>> q.BinarySymplecticVector(a,b)==q.BinarySymplecticVector(a+b)
True
>>> import qecc as q
>>> a=[1, 0, 1]; b=[0, 1, 1]
>>> q.BinarySymplecticVector(a,b)
( 1 0 1  0 1 1 )
>>> import qecc as q
>>> q.Pauli('XYIYIIZ',2).as_bsv()
( 1 1 0 1 0 0 0  0 1 0 1 0 0 1 )
Encapsulates a binary symplectic vector representing an element of the Pauli group on qubits.
A new BinarySymplecticVector can be constructed using either a single NumPy array containing both the and parts of the binary symplectic vector. Alternatively, a new vector can be instantiated using two NumPy arrays. For example, the following two invocations are equivalent:
>>> import qecc
>>> import numpy as np
>>> bsv = qecc.BinarySymplecticVector(np.array([1, 0, 0, 0, 0, 0]))
>>> bsv = qecc.BinarySymplecticVector(np.array([1, 0, 0]), np.array([0, 0, 0]))
The len of a BinarySymplecticVector is defined as the number of qubits upon which the represented Pauli operator acts, and is thus half of the length of a single array containing the same data.
Array containing the part of the binary symplectic vector.
Return type:  numpy.ndarray, shape (2 * nq, ). 

>>> import qecc as q
>>> q.BinarySymplecticVector([1,0,0,0,1,0]).x
array([1, 0, 0])
Array containing the part of the binary symplectic vector.
Return type:  numpy.ndarray, shape (nq, ). 

>>> import qecc as q
>>> q.BinarySymplecticVector([1,0,0,0,1,0]).z
array([0, 1, 0])
Returns a copy of the binary symplectic vector such that mutations of the copy do not affect this instance. For more details, see the numpy.ndarray.copy() method.
Returns an instance of qecc.Pauli representing the same Pauli operator as this vector. Note that phase information is not preserved by the binary symplectic representation of the Pauli group, and so P.as_bsv().as_pauli() need not equal P.
>>> import qecc as q
>>> pauli_with_phase=q.Pauli('IXXYZ',2)
>>> pauli_with_phase.as_bsv().as_pauli()
i^0 IXXYZ
Returns the binary symplectic inner product of this vector with another vector. Letting and , .
>>> import qecc as q
>>> vector_a = q.BinarySymplecticVector([1,0,1],[0,1,1])
>>> vector_b = q.Pauli('YYZ').as_bsv()
>>> vector_a.bsip(vector_b)
1
Lists all the Paulis on nq qubits according to their binary symplectic representations.
Parameters:  nq (int) – Number of qubits. 

Returns:  an iterator that yields the binary symplectic representations of each element of the Pauli group . 
>>> list(q.all_pauli_bsvs(1))
[( 0  0 ), ( 0  1 ), ( 1  0 ), ( 1  1 )]
Given a set of constraints of the form , with each a Pauli operator and each a bit, yields an iterator onto Pauli operators such that all constraints are satisfied.
Parameters: 


>>> import qecc as q
>>> list(q.constrained_set(map(lambda s: q.Pauli(s).as_bsv(), ['XY','ZZ']),[1,0]))
[( 0 0  0 1 ), ( 0 0  1 0 ), ( 1 1  0 0 ), ( 1 1  1 1 )]
Returns True if bsv1 and bsv2 commute by evaluating the symplectic inner product.
Return type:  bool 

Given a qecc.BinarySymplecticVector, returns a new vector whose and parts have been swapped.
Encapsulates a binary symplectic matrix representing an element of the Clifford group on qubits.
A new BinarySymplecticMatrix can be constructed using either a single NumPy 2D array containing the , , , and parts of the binary symplectic matrix. Alternatively, a new matrix can be instantiated using four NumPy arrays. For example, the following two invocations are equivalent:
>>> import qecc
>>> import numpy as np
>>> bsm = qecc.BinarySymplecticMatrix(np.array([[1, 0, 0, 0],[1, 1, 0, 0],[0, 0, 1, 1],[0, 0, 0, 1]]))
>>> bsm = qecc.BinarySymplecticMatrix(np.array([[1, 0],[1, 1]]), np.array([[0, 0],[0, 0]]), np.array([[0, 0],[0, 0]]), np.array([[1, 1],[0, 1]]))
Returns the number of qubits that the binary symplectic matrix acts upon.
Returns the left half of a binary symplectic matrix.
Returns the right half of a binary symplectic matrix.
Returns the top half of a binary symplectic matrix.
Returns the bottom half of a binary symplectic matrix.
Returns the upperleft quadrant of a binary symplectic matrix.
Returns the upperright quadrant of a binary symplectic matrix.
Returns the lowerleft quadrant of a binary symplectic matrix.
Returns the lowerright quadrant of a binary symplectic matrix.
Multiplies on the left by a Hadamard gate on the qubit. This method acts inplace, as opposed to acting on a copy of the binary symplectic matrix. In order to preserve the original matrix, use the copy() method:
>>> new_bsm = bsm.copy().left_H(idx)
Multiplies on the right by a Hadamard gate on the qubit. See left_H() for more details.
Multiplies on the right by a Hadamard gate on each qubit. See left_H() for more details.
Multiplies on the left by a SWAP gate between the and qubits. This method acts inplace, as opposed to acting on a copy of the binary symplectic matrix. In order to preserve the original matrix, use the copy() method:
>>> new_bsm = bsm.copy().left_SWAP(j, k)
Multiplies on the right by a SWAP gate between the and qubits. See left_SWAP() for more details.
Multiplies on the left by a CNOT gate controlled by the qubit and targeting the qubit. This method acts inplace, as opposed to acting on a copy of the binary symplectic matrix. In order to preserve the original matrix, use the copy() method:
>>> new_bsm = bsm.copy().left_CNOT(c, t)
Multiplies on the right by a CNOT gate controlled by the qubit and targeting the qubit. For more details, see left_CNOT().
Multiplies on the left by an gate acting on the qubit. This method acts inplace, as opposed to acting on a copy of the binary symplectic matrix. In order to preserve the original matrix, use the copy() method:
>>> new_bsm = bsm.copy().left_R_pi4(c, t)
Multiplies on the right by an gate acting on the qubit. For more details, see left_R_pi4().
Multiplies on the left by an controlled gate acting between the and qubits. This method acts inplace, as opposed to acting on a copy of the binary symplectic matrix. In order to preserve the original matrix, use the copy() method:
>>> new_bsm = bsm.copy().left_CZ(c, t)
Multiplies on the right by an controlled gate acting between the and qubits. For more details, see left_CZ().
Returns the inverse of this binary symplectic matrix, assuming that this matrix represents a valid Clifford gate.
Note that if the matrix does not represent a valid Clifford, this method will return a matrix such that is not the identity matrix.
Parameters:  check_validity (bool) – If True, then the matrix is first checked to ensure that it is a valid Clifford. 

Raises :  qecc.InvalidCliffordError if check_validity is True and the binary symplectic matrix being inverted does not represent a valid Clifford group element. 
Converts this binary symplectic matrix into a Clifford representation.
Parameters:  check_validity (bool) – If True, then the matrix is first checked to ensure that it is a valid Clifford. 

Return type:  qecc.Clifford 
Returns:  The same gate as this binary symplectic matrix, represented as an instance of qecc.Clifford. 
Checks the satisfaction of the symplectic condition on a qecc.BinarySymplecticMatrix object.
Returns a copy of this binary symplectic matrix, pointing to a distinct location in memory.
Returns a binary symplectic matrix on qubits, initialized to all zeros.
Parameters:  nq (int) – Number of qubits that the created matrix will act upon. 

Returns:  A binary symplectic matrix containing all zeros. 
Return type:  BinarySymplecticMatrix 
Function wrapper for type conversion from binary symplectic vector to qecc.Pauli. See qecc.BinarySymplecticVector.as_pauli().