pygsti.algorithms.compilers

Clifford circuit, CNOT circuit, and stabilizer state/measurement generation compilation routines

Module Contents

Functions

_create_standard_costfunction(name)

Creates the standard 'costfunctions' from an input string.

compile_clifford(s, p, pspec=None, absolute_compilation=None, paulieq_compilation=None, qubit_labels=None, iterations=20, algorithm='ROGGE', aargs=[], costfunction='2QGC:10:depth:1', prefixpaulis=False, paulirandomize=False, rand_state=None)

Compiles an n-qubit Clifford gate into a circuit over a given processor specification.

compile_symplectic(s, pspec=None, absolute_compilation=None, paulieq_compilation=None, qubit_labels=None, iterations=20, algorithms=['ROGGE'], costfunction='2QGC:10:depth:1', paulirandomize=False, aargs={}, check=True, rand_state=None)

Creates a Circuit that implements a Clifford gate given in the symplectic representation.

_compile_symplectic_using_rogge_algorithm(s, pspec=None, paulieq_compilation=None, qubit_labels=None, ctype='basic', costfunction='2QGC:10:depth:1', iterations=10, check=True, rand_state=None)

Creates a Circuit that implements a Clifford gate using the ROGGE algorithm.

_compile_symplectic_using_ogge_algorithm(s, eliminationorder, pspec=None, paulieq_compilation=None, qubit_labels=None, ctype='basic', check=True)

Creates a Circuit that implements a Clifford gate using the OGGE algorithm.

_compile_symplectic_using_gge_core(s, check=True)

Creates a Circuit that implements a Clifford gate using the GGE algorithm.

_compile_symplectic_using_ag_algorithm(s, pspec=None, qubit_labels=None, cnotmethod='PMH', check=False)

Creates a Circuit that implements a Clifford gate using the AG algorithm.

_compile_symplectic_using_riag_algoritm(s, pspec, paulieq_compilation, qubit_labels=None, iterations=20, cnotalg='COiCAGE', cargs=[], costfunction='2QGC:10:depth:1', check=True, rand_state=None)

Creates a Circuit that implements a Clifford gate using the RIAG algorithm.

_compile_symplectic_using_iag_algorithm(s, pspec, qubit_labels=None, cnotalg='COCAGE', cargs=[], check=True, rand_state=None)

Creates a Circuit that implements a Clifford gate using the IAG algorithm.

compile_cnot_circuit(s, pspec, compilation, qubit_labels=None, algorithm='COiCAGE', compile_to_native=False, check=True, aargs=[], rand_state=None)

A CNOT circuit compiler.

_compile_cnot_circuit_using_bge_algorithm(s, pspec, qubit_labels=None, compile_to_native=False, check=True)

Compile a CNOT circuit.

_add_cnot(qubitgraph, controllabel, targetlabel)

A helper function for CNOT circuit compilations.

_compile_cnot_circuit_using_ocage_algorithm(s, pspec, qubitorder, qubit_labels=None, check=True, respect_connectivity=True)

An ordered and connectivity-adjusted Gaussian-elimination (OCAGE) algorithm for compiling a CNOT circuit.

_compile_cnot_circuit_using_oicage_algorithm(s, pspec, qubitorder, qubit_labels=None, compile_to_native=False, check=True)

An improved, ordered and connectivity-adjusted Gaussian-elimination (OiCAGE) algorithm for compiling a CNOT circuit.

compile_stabilizer_state(s, p, pspec, absolute_compilation, paulieq_compilation, qubit_labels=None, iterations=20, paulirandomize=False, algorithm='COiCAGE', aargs=[], costfunction='2QGC:10:depth:1', rand_state=None)

Generates a circuit to create the stabilizer state from the standard input state |0,0,0,...>.

compile_stabilizer_measurement(s, p, pspec, absolute_compilation, paulieq_compilation, qubit_labels=None, iterations=20, paulirandomize=False, algorithm='COCAGE', aargs=[], costfunction='2QGC:10:depth:1', rand_state=None)

Generates a circuit to map the stabilizer state to the standard state |0,0,0,...>.

_convert_submatrix_to_echelon_form_using_cnots(s, optype, position, qubit_labels)

Converts a submatrix of s to row- or column-echelon form.

_submatrix_gaussian_elimination_using_cnots(s, optype, position, qubit_labels)

Converts a submatrix of s to the identity matrix using CNOTs.

_make_submatrix_invertable_using_hadamards(s, optype, position, qubit_labels, rand_state=None)

Uses row-action or column-action Hadamard gates to make a submatrix of s invertable.

_make_submatrix_invertable_using_phases_and_idsubmatrix(s, optype, position, qubit_labels)

Uses row-action or column-action Phase gates to make a submatrix of s invertable.

find_albert_factorization_transform_using_cnots(s, optype, position, qubit_labels)

Performs an Albert factorization transform on s.

_apply_phase_to_all_qubits(s, optype, qubit_labels)

Applies phase gates to all qubits

_apply_hadamard_to_all_qubits(s, optype, qubit_labels)

Applies Hadamard gates to all qubits

compile_conditional_symplectic(s, pspec, qubit_labels=None, calg='COiCAGE', cargs=[], check=True, rand_state=None)

Finds circuits that partially (conditional on the input) implement the Clifford given by s.

pygsti.algorithms.compilers._create_standard_costfunction(name)

Creates the standard ‘costfunctions’ from an input string.

This is used for calculating the “cost” of a circuit created by some compilation algorithms.

Parameters

name (str) –

Allowed values are:
  • ’2QGC’ : the cost of the circuit is the number of 2-qubit gates it contains.

  • ’depth’ : the cost of the circuit is the depth of the circuit.

  • ’2QGC:x:depth:y’the cost of the circuit is x * the number of 2-qubit gates in the circuit +

    y * the depth of the circuit, where x and y are integers.

Returns

function – A function that takes a circuit as the first argument, a QubitProcessorSpec as the second argument (or a “junk” input when a QubitProcessorSpec is not needed), and returns the cost of the circuit.

pygsti.algorithms.compilers.compile_clifford(s, p, pspec=None, absolute_compilation=None, paulieq_compilation=None, qubit_labels=None, iterations=20, algorithm='ROGGE', aargs=[], costfunction='2QGC:10:depth:1', prefixpaulis=False, paulirandomize=False, rand_state=None)

Compiles an n-qubit Clifford gate into a circuit over a given processor specification.

Compiles an n-qubit Clifford gate, described by the symplectic matrix s and vector p, into a circuit over the gates given by a processor specification or a standard processor. Clifford gates/circuits can be converted to, or sampled in, the symplectic representation using the functions in :module:`pygsti.tools.symplectic`.

The circuit created by this function will be over the gates in the given processor spec, respecting its connectivity, when a QubitProcessorSpec object is provided. Otherwise, it is over a canonical processor containing all-to-all CNOTs, Hadamard, Phase, 3 products of Hadamard and Phase, and the Pauli gates.

Parameters
  • s (array over [0,1]) – An (2n X 2n) symplectic matrix of 0s and 1s integers.

  • p (array over [0,1]) – A length-2n vector over [0,1,2,3] that, together with s, defines a valid n-qubit Clifford gate.

  • pspec (QubitProcessorSpec, optional) –

    An nbar-qubit QubitProcessorSpec object that encodes the device that the Clifford is being compiled for, where nbar >= n. If this is specified, the output circuit is over the gates available in this device. If this is None, the output circuit is over the “canonical” processor of CNOT gates between all qubits, consisting of “H”, “HP”, “PH”, “HPH”, “I”, “X”, “Y” and “Z”, which is the set used internally for the compilation. In most circumstances, the output will be more useful if a QubitProcessorSpec is provided.

    If nbar > n it is necessary to provide qubit_labels, that specifies which of the qubits in pspec the Clifford acts on. (All other qubits will not be part of the returned circuit, regardless of whether that means an over-head is required to avoid using gates that act on those qubits. If these additional qubits should be used, then the input Clifford needs to be ``padded’’ to be the identity on those qubits).

    The ordering of the indices in (s,`p`) is w.r.t to ordering of the qubit labels in pspec.qubit_labels, unless qubit_labels is specified. Then, the ordering is taken w.r.t the ordering of the list qubit_labels.

  • absolute_compilation (CompilationRules) – Rules for exactly (absolutely) compiling the “native” gates of pspec into clifford gates.

  • paulieq_compilation (CompilationRules) – Rules for compiling, up to single-qubit Pauli gates, the “native” gates of pspec into clifford gates.

  • qubit_labels (list, optional) – Required if the Clifford to compile is over less qubits than pspec. In this case this is a list of the qubits to compile the Clifford for; it should be a subset of the elements of pspec.qubit_labels. The ordering of the qubits in (s,`p`) is taken w.r.t the ordering of this list.

  • iterations (int, optional) – Some of the allowed algorithms are randomized. This is the number of iterations used in algorithm if it is a randomized algorithm specified. If any randomized algorithms are specified, the time taken by this function increases linearly with iterations. Increasing iterations will often improve the obtained compilation (the “cost” of the obtained circuit, as specified by costfunction may decrease towards some asymptotic value).

  • algorithm (str, optional) –

    Specifies the algorithm used for the core part of the compilation: finding a circuit that is a Clifford with s the symplectic matrix in its symplectic representation (a circuit that implements that desired Clifford up to Pauli operators). The allowed values of this are:

    • ’BGGE’: A basic, deterministic global Gaussian elimination algorithm. Circuits obtained from this algorithm

      contain, in expectation, O(n^2) 2-qubit gates. Although the returned circuit will respect device connectivity, this algorithm does not take connectivity into account in an intelligient way. More details on this algorithm are given in compile_symplectic_with_ordered_global_gaussian_elimination(); it is the algorithm described in that docstring but with the qubit ordering fixed to the order in the input s.

    • ’ROGGE’: A randomized elimination order global Gaussian elimination algorithm. This is the same algorithm as

      ’BGGE’ except that the order that the qubits are eliminated in is randomized. This results in significantly lower-cost circuits than the ‘BGGE’ method (given sufficiently many iterations). More details are given in the compile_symplectic_with_random_ordered_global_gaussian_elimination() docstring.

    • ’iAGvGE’: Our improved version of the Aaraonson-Gottesman method for compiling a Clifford circuit, which uses 3 CNOT circuits and 3 1Q-gate layers (rather than the 5 CNOT circuit used in the algorithm of AG in Phys. Rev. A 70 052328 (2004)), with the CNOT circuits compiled using Gaussian elimination. Note that this algorithm appears to perform substantially worse than ‘ROGGE’, even though with an upgraded CNOT compiler it is asymptotically optimal (unlike any of the GGE methods). Also, note that this algorithm is randomized: there are many possible CNOT circuits (with non-equivalent action, individually) for the 2 of the 3 CNOT stages, and we randomize over those possible circuits. This randomization is equivalent to the randomization used in the stabilizer state/measurement compilers.

  • aargs (list, optional) – If the algorithm can take optional arguments, not already specified as separate arguments above, then this list is passed to the compile_symplectic algorithm as its final arguments.

  • costfunction (function or string, optional) –

    If a function, it is a function that takes a circuit and pspec as the first and second inputs and returns a ‘cost’ (a float) for the circuit. The circuit input to this function will be over the gates in pspec, if a pspec has been provided, and as described above if not. This costfunction is used to decide between different compilations when randomized algorithms are used: the lowest cost circuit is chosen. If a string it must be one of:

    • ’2QGC’ : the cost of the circuit is the number of 2-qubit gates it contains.

    • ’depth’ : the cost of the circuit is the depth of the circuit.

    • ’2QGC:x:depth:y’the cost of the circuit is x * the number of 2-qubit gates in the circuit +

      y * the depth of the circuit, where x and y are integers.

  • prefixpaulis (bool, optional) – A Pauli layer is needed to compile the correct Clifford (and not just the correct Clifford up to Paulis). When prefixpaulis = True this Pauli layer is placed at the beginning of the circuit; when False, it is placed at the end. Note that the required Pauli layer depends on whether we pre-fix or post-fix it to the main symplectic-generating circuit.

  • paulirandomize (bool, optional) – If True then independent, uniformly random Pauli layers (a Pauli on each qubit) are inserted in between every layer in the circuit. These Paulis are then compiled into the gates in pspec, if pspec is provided. That is, this Pauli-frame-randomizes / Pauli-twirls the internal layers of this Clifford circuit. This can be useful for preventing coherent addition of errors in the circuit.

  • rand_state (RandomState, optional) – A np.random.RandomState object for seeding RNG

Returns

Circuit – A circuit implementing the input Clifford gate/circuit.

pygsti.algorithms.compilers.compile_symplectic(s, pspec=None, absolute_compilation=None, paulieq_compilation=None, qubit_labels=None, iterations=20, algorithms=['ROGGE'], costfunction='2QGC:10:depth:1', paulirandomize=False, aargs={}, check=True, rand_state=None)

Creates a Circuit that implements a Clifford gate given in the symplectic representation.

Returns an n-qubit circuit that implements an n-qubit Clifford gate that is described by the symplectic matrix s and some vector p. The circuit created by this function will be over the gates in the processor specification pspec, respecting any desired connectivity if a QubitProcessorSpec object is provided. Otherwise, the circuit is over the gates of a canonical processor containing all-to-all CNOTs, Hadamard, Phase, 3 products of Hadamard and Phase, and the Pauli gates.

Parameters
  • s (array over [0,1]) – An (2n X 2n) symplectic matrix of 0s and 1s integers.

  • pspec (QubitProcessorSpec, optional) –

    An nbar-qubit QubitProcessorSpec object that encodes the device that s is being compiled for, where nbar >= n. If this is specified, the output circuit is over the gates available in this device. If this is None, the output circuit is over the “canonical” processor of CNOT gates between all qubits, consisting of “H”, “HP”, “PH”, “HPH”, “I”, “X”, “Y” and “Z”, which is the set used internally for the compilation.

    If nbar > n it is necessary to provide qubit_labels, that specifies which of the qubits in pspec the Clifford acts on. (All other qubits will not be part of the returned circuit, regardless of whether that means an over-head is required to avoid using gates that act on those qubits. If these additional qubits should be used, then the input s needs to be ``padded’’ to be the identity on those qubits).

    The indexing s is assumed to be the same as that in the list pspec.qubit_labels, unless qubit_labels is specified. Then, the ordering is taken w.r.t the ordering of the list qubit_labels.

  • absolute_compilation (CompilationRules) – Rules for exactly (absolutely) compiling the “native” gates of pspec into clifford gates.

  • paulieq_compilation (CompilationRules) – Rules for compiling, up to single-qubit Pauli gates, the “native” gates of pspec into clifford gates.

  • qubit_labels (list, optional) – Required if the Clifford to compile is over less qubits than pspec. In this case this is a list of the qubits to compile the Clifford for; it should be a subset of the elements of pspec.qubit_labels. The ordering of the qubits in (s,`p`) is taken w.r.t the ordering of this list.

  • iterations (int, optional) – Some of the allowed algorithms are randomized. This is the number of iterations used in each algorithm specified that is a randomized algorithm.

  • algorithms (list of strings, optional) –

    Specifies the algorithms used. If more than one algorithm is specified, then all the algorithms are implemented and the lowest “cost” circuit obtained from all the algorithms (and iterations of those algorithms, if randomized) is returned.

    The allowed elements of this list are:

    • ’BGGE’: A basic, deterministic global Gaussian elimination algorithm. Circuits obtained from this algorithm

      contain, in expectation, O(n^2) 2-qubit gates. Although the returned circuit will respect device connectivity, this algorithm does not take connectivity into account in an intelligient way. More details on this algorithm are given in compile_symplectic_with_ordered_global_gaussian_elimination(); it is the algorithm described in that docstring but with the qubit ordering fixed to the order in the input s.

    • ’ROGGE’: A randomized elimination order global Gaussian elimination algorithm. This is the same algorithm as

      ’BGGE’ except that the order that the qubits are eliminated in is randomized. This results in significantly lower-cost circuits than the ‘BGGE’ method (given sufficiently many iterations). More details are given in the compile_symplectic_with_random_ordered_global_gaussian_elimination() docstring.

    • ’iAGvGE’: Our improved version of the Aaraonson-Gottesman method for compiling a symplectic matrix, which uses 3 CNOT circuits and 3 1Q-gate layers (rather than the 5 CNOT circuit used in the algorithm of AG in Phys. Rev. A 70 052328 (2004)), with the CNOT circuits compiled using Gaussian elimination. Note that this algorithm appears to perform substantially worse than ‘ROGGE’, even though with an upgraded CNOT compiler it is asymptotically optimal (unlike any of the GGE methods). Also, note that this algorithm is randomized: there are many possible CNOT circuits (with non-equivalent action, individually) for the 2 of the 3 CNOT stages, and we randomize over those possible circuits. This randomization is equivalent to the randomization used in the stabilizer state/measurement compilers.

  • costfunction (function or string, optional) –

    If a function, it is a function that takes a circuit and pspec as the first and second inputs and returns a cost (a float) for the circuit. The circuit input to this function will be over the gates in pspec, if a pspec has been provided, and as described above if not. This costfunction is used to decide between different compilations when randomized algorithms are used: the lowest cost circuit is chosen. If a string it must be one of:

    • ’2QGC’ : the cost of the circuit is the number of 2-qubit gates it contains.

    • ’depth’ : the cost of the circuit is the depth of the circuit.

    • ’2QGC:x:depth:y’the cost of the circuit is x * the number of 2-qubit gates in the circuit +

      y * the depth of the circuit, where x and y are integers.

  • paulirandomize (bool, optional) – If True then independent, uniformly random Pauli layers (a Pauli on each qubit) are inserted in between every layer in the circuit. These Paulis are then compiled into the gates in pspec, if pspec is provided. That is, this Pauli-frame-randomizes / Pauli-twirls the internal layers of this Clifford circuit. This can be useful for preventing coherent addition of errors in the circuit.

  • aargs (dict, optional) – If the algorithm can take optional arguments, not already specified as separate arguments above, then the list arrgs[algorithmname] is passed to the compile_symplectic algorithm as its final arguments, where algorithmname is the name of algorithm specified in the list algorithms.

  • check (bool, optional) – Whether to check that the output circuit implements the correct symplectic matrix (i.e., tests for algorithm success).

  • rand_state (RandomState, optional) – A np.random.RandomState object for seeding RNG

Returns

Circuit – A circuit implementing the input Clifford gate/circuit.

pygsti.algorithms.compilers._compile_symplectic_using_rogge_algorithm(s, pspec=None, paulieq_compilation=None, qubit_labels=None, ctype='basic', costfunction='2QGC:10:depth:1', iterations=10, check=True, rand_state=None)

Creates a Circuit that implements a Clifford gate using the ROGGE algorithm.

The order global Gaussian elimiation algorithm of _compile_symplectic_using_ogge_algorithm() with the qubit elimination order randomized. See that function for further details on the algorithm, This algorithm is more conveniently and flexibly accessed via the compile_symplectic() or compile_clifford() wrap-around functions.

Parameters
  • s (array over [0,1]) – An (2n X 2n) symplectic matrix of 0s and 1s integers.

  • pspec (QubitProcessorSpec, optional) –

    An nbar-qubit QubitProcessorSpec object that encodes the device that s is being compiled for, where nbar >= n. If this is specified, the output circuit is over the gates available in this device. If this is None, the output circuit is over the “canonical” processor of CNOT gates between all qubits, consisting of “H”, “HP”, “PH”, “HPH”, “I”, “X”, “Y” and “Z”, which is the set used internally for the compilation.

    If nbar > n it is necessary to provide qubit_labels, that specifies which of the qubits in pspec the Clifford acts on. (All other qubits will not be part of the returned circuit, regardless of whether that means an over-head is required to avoid using gates that act on those qubits. If these additional qubits should be used, then the input s needs to be ``padded’’ to be the identity on those qubits).

    The indexing s is assumed to be the same as that in the list pspec.qubit_labels, unless qubit_labels is specified. Then, the ordering is taken w.r.t the ordering of the list qubit_labels.

  • qubit_labels (list, optional) – Required if the Clifford to compile is over less qubits than pspec. In this case this is a list of the qubits to compile the Clifford for; it should be a subset of the elements of pspec.qubit_labels. The ordering of the qubits in (s,`p`) is taken w.r.t the ordering of this list.

  • ctype (str, optional) – The particular variant on the global Gaussian elimiation core algorithm. Currently there is only one such variant, corresponding to the string “basic”.

  • costfunction (function or string, optional) –

    If a function, it is a function that takes a circuit and pspec as the first and second inputs and returns a cost (a float) for the circuit. The circuit input to this function will be over the gates in pspec, if a pspec has been provided, and as described above if not. This costfunction is used to decide between different compilations when randomized algorithms are used: the lowest cost circuit is chosen. If a string it must be one of:

    • ’2QGC’ : the cost of the circuit is the number of 2-qubit gates it contains.

    • ’depth’ : the cost of the circuit is the depth of the circuit.

    • ’2QGC:x:depth:y’the cost of the circuit is x * the number of 2-qubit gates in the circuit +

      y * the depth of the circuit, where x and y are integers.

  • iterations (int, optional) – The number of different random orderings tried. The lowest “cost” circuit obtained from the different orderings is what is returned.

  • check (bool, optional) – Whether to check that the output circuit implements the correct symplectic matrix (i.e., tests for algorithm success).

  • rand_state (RandomState, optional) – A np.random.RandomState object for seeding RNG

Returns

Circuit – A circuit implementing the input symplectic matrix.

pygsti.algorithms.compilers._compile_symplectic_using_ogge_algorithm(s, eliminationorder, pspec=None, paulieq_compilation=None, qubit_labels=None, ctype='basic', check=True)

Creates a Circuit that implements a Clifford gate using the OGGE algorithm.

An ordered global Gaussian elimiation algorithm for creating a circuit that implements a Clifford that is represented by the symplectic matrix s (and some phase vector). This algorithm is more conveniently and flexibly accessed via the compile_symplectic() or compile_clifford() wrap-around functions.

The algorithm works as follows:

  1. The s matrix is permuted so that the index for the jth qubit to eliminate becomes index j.

  2. The “global Gaussian elimination” algorithm of E. Hostens, J. Dehaene, and B. De Moor, PRA 71 042315 (2015) is implemented, which can be used to decompose s into a circuit over CNOT, SWAP, H, and P. That algorithm is for d-dimensional qudits, and simplifies significantly for d=2 (qubits), which is the case implemented here. However, we are unware of anywhere else that this algorithm is clearly stated for the qubit case (although this basic algorithm is widely known).

Parameters
  • s (array over [0,1]) – An (2n X 2n) symplectic matrix of 0s and 1s integers.

  • eliminationorder (list) – The elimination order for the qubits. If pspec is specified, this should be a list consisting of the qubit labels that s is over (this can be a subset of all qubits in pspec is qubit_labels is None). If pspec is not specified this list should consist of the integers between 0 and n-1 in any order, corresponding to the indices of s.

  • pspec (QubitProcessorSpec, optional) –

    An nbar-qubit QubitProcessorSpec object that encodes the device that s is being compiled for, where nbar >= n. If this is specified, the output circuit is over the gates available in this device. If this is None, the output circuit is over the “canonical” processor of CNOT gates between all qubits, consisting of “H”, “HP”, “PH”, “HPH”, “I”, “X”, “Y” and “Z”, which is the set used internally for the compilation.

    If nbar > n it is necessary to provide qubit_labels, that specifies which of the qubits in pspec the Clifford acts on. (All other qubits will not be part of the returned circuit, regardless of whether that means an over-head is required to avoid using gates that act on those qubits. If these additional qubits should be used, then the input s needs to be ``padded’’ to be the identity on those qubits).

    The indexing s is assumed to be the same as that in the list pspec.qubit_labels, unless qubit_labels is specified. Then, the ordering is taken w.r.t the ordering of the list qubit_labels.

  • qubit_labels (list, optional) – Required if the Clifford to compile is over less qubits than pspec. In this case this is a list of the qubits to compile the Clifford for; it should be a subset of the elements of pspec.qubit_labels. The ordering of the qubits in (s,`p`) is taken w.r.t the ordering of this list.

  • ctype (str, optional) – The particular variant on the global Gaussian elimiation core algorithm. Currently there is only one such variant, corresponding to the string “basic”.

  • check (bool, optional) – Whether to check that the output circuit implements the correct symplectic matrix (i.e., tests for algorithm success).

Returns

Circuit – A circuit implementing the input symplectic matrix.

pygsti.algorithms.compilers._compile_symplectic_using_gge_core(s, check=True)

Creates a Circuit that implements a Clifford gate using the GGE algorithm.

Creates a circuit over ‘I’,’H’,’HP’,’PH’,’HPH’, and ‘CNOT’ that implements a Clifford gate with s as its symplectic matrix in the symplectic representation (and with any phase vector). This circuit is generated using a basic Gaussian elimination algorithm, which is described in more detail in _compile_symplectic_using_ogge_algorithm(), which is a wrap-around for this algorithm that implements a more flexible compilation method.

This algorithm is more conveniently accessed via the compile_symplectic() or compile_clifford() functions.

Parameters
  • s (array) – A 2n X 2n symplectic matrix over [0,1] for any positive integer n. The returned circuit is over n qubits.

  • check (bool, optional) – Whether to check that the generated circuit does implement s.

Returns

Circuit – A circuit that implements a Clifford that is represented by the symplectic matrix s.

pygsti.algorithms.compilers._compile_symplectic_using_ag_algorithm(s, pspec=None, qubit_labels=None, cnotmethod='PMH', check=False)

Creates a Circuit that implements a Clifford gate using the AG algorithm.

The Aaraonson-Gottesman method for compiling a symplectic matrix using 5 CNOT circuits + local layers. This algorithm is presented in PRA 70 052328 (2014).

  • If cnotmethod = GE then the CNOT circuits are compiled using Gaussian elimination (which is O(n^2)). There are multiple GE algorithms for compiling a CNOT in pyGSTi. This function has the over-all best variant of this algorithm hard-coded into this function.

  • If cnotmethod = PMH then the CNOT circuits are compiled using the asymptotically optimal O(n^2/logn) CNOT circuit algorithm of PMH.

* This function has not yet been implemented *

Parameters
  • s (array over [0,1]) – An (2n X 2n) symplectic matrix of 0s and 1s integers.

  • pspec (QubitProcessorSpec, optional) – An nbar-qubit QubitProcessorSpec object that encodes the device that s is being compiled for, where nbar >= n.

  • qubit_labels (list, optional) – Required if the Clifford to compile is over less qubits than pspec. In this case this is a list of the qubits to compile the Clifford for; it should be a subset of the elements of pspec.qubit_labels. The ordering of the qubits in (s,`p`) is taken w.r.t the ordering of this list.

  • ctype (str, optional) – The particular variant on the global Gaussian elimiation core algorithm. Currently there is only one such variant, corresponding to the string “basic”.

  • cnotmethod ({"GE", "PMH"}) – See above.

  • check (bool, optional) – Whether to check that the generated circuit does implement s.

Returns

Circuit – A circuit that implements a Clifford that is represented by the symplectic matrix s.

pygsti.algorithms.compilers._compile_symplectic_using_riag_algoritm(s, pspec, paulieq_compilation, qubit_labels=None, iterations=20, cnotalg='COiCAGE', cargs=[], costfunction='2QGC:10:depth:1', check=True, rand_state=None)

Creates a Circuit that implements a Clifford gate using the RIAG algorithm.

Our improved version of Aaraonson-Gottesman method [PRA 70 052328 (2014)] for compiling a symplectic matrix using 5 CNOT circuits + local layers. Our version of this algorithm uses 3 CNOT circuits, and 3 layers of 1-qubit gates. Also, note that this algorithm is randomized: there are many possible CNOT circuits (with non-equivalent action, individually) for the 2 of the 3 CNOT stages, and we randomize over those possible circuits. This randomization is equivalent to the randomization used in the stabilizer state/measurement compilers.

Note that this algorithm currently performs substantially worse than ‘ROGGE’, even though with an upgraded CNOT compiler it is asymptotically optimal (unlike any of the GGE methods).

Parameters
  • s (array over [0,1]) – An (2n X 2n) symplectic matrix of 0s and 1s integers.

  • pspec (QubitProcessorSpec) –

    An nbar-qubit QubitProcessorSpec object that encodes the device that s is being compiled for, where nbar >= n. If this is specified, the output circuit is over the gates available in this device. If this is None, the output circuit is over the “canonical” processor of CNOT gates between all qubits, consisting of “H”, “HP”, “PH”, “HPH”, “I”, “X”, “Y” and “Z”, which is the set used internally for the compilation.

    If nbar > n it is necessary to provide qubit_labels, that specifies which of the qubits in pspec the Clifford acts on. (All other qubits will not be part of the returned circuit, regardless of whether that means an over-head is required to avoid using gates that act on those qubits. If these additional qubits should be used, then the input s needs to be ``padded’’ to be the identity on those qubits).

    The indexing s is assumed to be the same as that in the list pspec.qubit_labels, unless qubit_labels is specified. Then, the ordering is taken w.r.t the ordering of the list qubit_labels.

  • paulieq_compilation (CompilationRules) – Rules for compiling, up to single-qubit Pauli gates, the “native” gates of pspec into clifford gates.

  • qubit_labels (List, optional) – Required if the Clifford to compile is over less qubits than pspec. In this case this is a list of the qubits to compile the Clifford for; it should be a subset of the elements of pspec.qubit_labels. The ordering of the qubits in (s,`p`) is taken w.r.t the ordering of this list.

  • iterations (int, optional) – The number of different random orderings tried. The lowest “cost” circuit obtained from the different orderings is what is returned.

  • cnotalg (str, optional) – The CNOT compiler to use. See compile_cnot_circuit() for the options. The default is probably the current best CNOT circuit compiler in pyGSTI.

  • cargs (list, optional) – Arguments handed to the CNOT compilation algorithm. For some choices of cnotalg this is not optional.

  • costfunction (function or string, optional) –

    If a function, it is a function that takes a circuit and pspec as the first and second inputs and returns a cost (a float) for the circuit. The circuit input to this function will be over the gates in pspec, if a pspec has been provided, and as described above if not. This costfunction is used to decide between different compilations when randomized algorithms are used: the lowest cost circuit is chosen. If a string it must be one of:

    • ’2QGC’ : the cost of the circuit is the number of 2-qubit gates it contains.

    • ’depth’ : the cost of the circuit is the depth of the circuit.

    • ’2QGC:x:depth:y’the cost of the circuit is x * the number of 2-qubit gates in the circuit +

      y * the depth of the circuit, where x and y are integers.

  • check (bool, optional) – Whether to check that the output circuit implements the correct symplectic matrix (i.e., tests for algorithm success).

  • rand_state (RandomState, optional) – A np.random.RandomState object for seeding RNG

Returns

Circuit – A circuit implementing the input symplectic matrix.

pygsti.algorithms.compilers._compile_symplectic_using_iag_algorithm(s, pspec, qubit_labels=None, cnotalg='COCAGE', cargs=[], check=True, rand_state=None)

Creates a Circuit that implements a Clifford gate using the IAG algorithm.

A single iteration of the algorithm in _compile_symplectic_using_riag_algoritm(). See that functions docstring for more information. Note that it is normallly better to access this algorithm through that function even when only a single iteration of the randomization is desired: this function does not change into the native gate library of pspec.

Parameters
  • s (array over [0,1]) – An (2n X 2n) symplectic matrix of 0s and 1s integers.

  • pspec (QubitProcessorSpec, optional) – An nbar-qubit QubitProcessorSpec object that encodes the device that s is being compiled for, where nbar >= n.

  • qubit_labels (list, optional) – Required if the Clifford to compile is over less qubits than pspec. In this case this is a list of the qubits to compile the Clifford for; it should be a subset of the elements of pspec.qubit_labels. The ordering of the qubits in (s,`p`) is taken w.r.t the ordering of this list.

  • cnotalg (str, optional) – The algorithm argument to pass internally to :function:`compile_cnot_circuit` when compiling CNOT gates.

  • cargs (various, optional) – The aargs argument to pass internally to :function:`compile_cnot_circuit` when compiling CNOT gates.

  • check (bool, optional) – Whether to check that the generated circuit does implement s.

  • rand_state (RandomState, optional) – A np.random.RandomState object for seeding RNG

Returns

Circuit – A circuit that implements a Clifford that is represented by the symplectic matrix s.

pygsti.algorithms.compilers.compile_cnot_circuit(s, pspec, compilation, qubit_labels=None, algorithm='COiCAGE', compile_to_native=False, check=True, aargs=[], rand_state=None)

A CNOT circuit compiler.

Takes an arbitrary CNOT circuit, input as a symplectic matrix s that corresponds to the matrix portion of the symplectic representation of this Clifford circuit, and decomposes it into a sequences of gates from the processor spec pspec.

Parameters
  • s (array over [0,1]) – An (2n X 2n) symplectic matrix of 0s and 1s integers that represents a Clifford circuit: so it must be block-diagonal. Specifically, it has the form s = ((A,0),(0,B)) where B is the inverse transpose of A (over [0,1] mod 2).

  • pspec (QubitProcessorSpec) –

    An nbar-qubit QubitProcessorSpec object that encodes the device that s is being compiled for, where nbar >= n. If this is specified, the output circuit is over the gates available in this device. If this is None, the output circuit is over the “canonical” processor of CNOT gates between all qubits, consisting of “H”, “HP”, “PH”, “HPH”, “I”, “X”, “Y” and “Z”, which is the set used internally for the compilation.

    If nbar > n it is necessary to provide qubit_labels, that specifies which of the qubits in pspec the Clifford acts on. (All other qubits will not be part of the returned circuit, regardless of whether that means an over-head is required to avoid using gates that act on those qubits. If these additional qubits should be used, then the input s needs to be ``padded’’ to be the identity on those qubits).

    The indexing s is assumed to be the same as that in the list pspec.qubit_labels, unless qubit_labels is specified. Then, the ordering is taken w.r.t the ordering of the list qubit_labels.

  • compilation (CompilationRules) – Rules for compiling the “native” gates of pspec into clifford gates, used if compile_to_native==True.

  • qubit_labels (list, optional) – Required if the Clifford to compile is over less qubits than pspec. In this case this is a list of the qubits to compile the Clifford for; it should be a subset of the elements of pspec.qubit_labels. The ordering of the qubits in (s,`p`) is taken w.r.t the ordering of this list.

  • algorithm (str, optional) –

    The algorithm to use. The optionas are:

    • ’BGE’A basic Gaussian elimination algorithm, that uses CNOT to perform row-reduction on the upper

      LHS (or lower RHS) of s. This algorithm does not take device connectivity into account.

    • ’OCAGE’User-ordered connectivity-adjusted Gaussian elimination. The qubits are eliminated in the

      specified order; the first element of arrgs must be a list specify this order. The algorithm is also “connectivity-adjusted” in the sense that it uses the connectivity graph (in pspec.qubit_graph) to try and avoid using CNOTs between unconnected pairs whenever possible, and to decide the order of various operations.

    • ’OiCAGE’The same as ‘OCAGE’ except that it has some improvements, and it requires connectivity

      graph of the remaining qubits, after each qubit has been ‘eliminated’, to be connected. In the current format this algorithm is only slightly better-performing than ‘OCAGE’, and only on average. (This algorithm will possibly be improved in the future, whereas ‘OCAGE’ will remain as-is for reproducability of previously obtained results.)

    • ’ROCAGE’: Same as ‘OCAGE’ except that the elimination order is chosen at random, rather than user-

      specified.

    • ’COCAGE’, ‘COiCAGE’The same as ‘OCAGE’ and ‘OiCAGE’, respectively, except that the elimination order

      is fixed to eliminate qubits with the worse connectivity before those with better connectivity.

  • compile_to_native (bool, optional) – Whether the circuit should be given in terms of the native gates of the processor defined in pspec.

  • check (bool, optional) – Whether to check the output is correct.

  • aargs (list, optional) – A list of arguments handed to the CNOT compiler algorithm. For some choices of algorithm (e.g., ‘OCAGE’) this list must not be empty. For algorithms where there are X non-optional arguements after s and pspec these are specified as the first X arguments of aargs. The remaining elements in aargs, if any, are handed to the algorithm as the arguments after the optional qubit_labels and check arguments (the first of which is set by the input qubit_labels in this function).

  • rand_state (RandomState, optional) – A np.random.RandomState object for seeding RNG

Returns

Circuit – A circuit that implements the same unitary as the CNOT circuit represented by s.

pygsti.algorithms.compilers._compile_cnot_circuit_using_bge_algorithm(s, pspec, qubit_labels=None, compile_to_native=False, check=True)

Compile a CNOT circuit.

Compilation uses a basic Gaussian elimination algorithm, that uses CNOT to perform row-reduction on the upper LHS (or lower RHS) of s. This algorithm does not take device connectivity into account.

See the docstring of compile_cnot_circuit() for information on the parameters. This function should normally be accessed via compile_cnot_circuit().

Parameters
  • s (array over [0,1]) – An (2n X 2n) symplectic matrix of 0s and 1s integers, that represents the CNOT circuit. This should be a (2x2) block-diagonal matrix, whereby the upper left block is any invertable transformation over [0,1]^n, and the lower right block is the inverse transpose of this transformation.

  • pspec (QubitProcessorSpec) – An nbar-qubit QubitProcessorSpec object that encodes the device that the CNOT circuit is being compiled for, where nbar >= n. The algorithm is takes into account the connectivity of the device as specified by pspec.qubit_graph. If nbar > n it is necessary to provide qubit_labels, to specify which qubits in pspec the CNOT circuit acts on (all other qubits will not be part of the returned circuit, regardless of whether that means an over-head is required to avoid using gates that act on those qubits. If these additional qubits should be used, then the input CNOT circuit needs to be ``padded’’ to be the identity on those qubits). The ordering of the qubits in s is assumed to be the same as that in the list pspec.qubit_labels, unless qubit_labels is specified. Then, the ordering is taken w.r.t the ordering of the list qubit_labels.

  • qubit_labels (list, optional) – Required if the CNOT circuit to compile is over less qubits than in pspec. In this case this is a list of the qubits to compile the CNOT circuit for; it should be a subset of the elements of pspec.qubit_labels. The ordering of the qubits in s is taken w.r.t the ordering of this list.

  • compile_to_native (bool, optional) – Unused.

  • check (bool, optional) – Whether to check the algorithm was successful.

Returns

Circuit – A circuit implementing the input CNOT circuit.

pygsti.algorithms.compilers._add_cnot(qubitgraph, controllabel, targetlabel)

A helper function for CNOT circuit compilations.

Returns an instruction list that is CNOTs along the shortest path from the qubits with label controlabel and targetlabel.

Parameters
  • qubitgraph (QubitGraph) – The qubit graph from which the shortest path between the qubits is extracted.

  • controllabel (str) – The label for the control qubit.

  • targetlabel (str) – The label for the target qubit.

Returns

list – The list of instructions for implementing the requested CNOT via the available CNOT gates, as specified by qubitgraph.

pygsti.algorithms.compilers._compile_cnot_circuit_using_ocage_algorithm(s, pspec, qubitorder, qubit_labels=None, check=True, respect_connectivity=True)

An ordered and connectivity-adjusted Gaussian-elimination (OCAGE) algorithm for compiling a CNOT circuit.

The algorithm takes as input a symplectic matrix s, that defines the action of a CNOT circuit, and it generates a CNOT circuit (converted to a native gate set, if requested) that implements the same unitary.

The algorithm works by mapping s -> identity using CNOTs acting from the LHS and RHS. I.e., it finds two CNOT circuits Ccnot1, Ccnot2 such that symp(Ccnot1) * s * symp(Ccnot2) = identity (where symp(c) is the symplectic matrix representing the circuit c). A circuit implementing s is then obtained as rev(Cnot1)rev(Cnot2) where rev(c) denotes the reverse of circuit c.

To find such circuits Ccnot1/2 we use the following algorithm. We eliminate the qubits in the order specified, whereby “eliminating” a qubit means mapping the column and row of s associated with that qubit to the identity column and row. To eliminate the ith qubit in the list we:

1. Look at the current value of s[i,i]. If s[i,i] = 1 continue. Else, find the closest qubit to do a CNOT between i and that qubit to make s[i,i] = 1. 2. List the remaining qubits to eliminate (the i+1th qubit onwards), and going from the qubit

in this list that is further from i to the closest implement the following steps:

2.1. Denote this qubit by ii. 2.1 If s[ii,i] = 0, pass. Else, map s[ii,i] -> 0 with the following method:

  1. find the shortest path from i -> ii,

  2. If the shortest path contains already eliminated qubits, using a LHS-action SWAP-like set of chains of CNOTs along the shortest path i -> ii to do a CNOT from i -> ii whilst leaving all other qubits unchanged. Then skip to 2.3.

  3. If the shortest path doesn’t contain already eliminated qubits, do LHS-action CNOTs between neighbouring qubits along this path to set all the s matrix elements in the column s[:,i] for the qubits along this path to 1.

  4. Use the qubit next to ii in this path to set s[ii,i] using a LHS-action CNOT, and don’t undo any of the changes to the other qubits along that path.

2.3. If s[i,ii] = 0, pass. Else, map s[i,ii] -> 0 as in step 2.3 except that now we use RHS-action

CNOTs.

Steps 1 - 3 do not change the already eliminated qubits, so after steps 1 - 2 are repeated for each of the yet-to-be-eliminated qubits, s should be some smaller matrix s’ between the yet-to-be-eliminated qubits embedded in a identity matrix on the already eliminated qubits.

Parameters
  • s (array over [0,1]) – An (2n X 2n) symplectic matrix of 0s and 1s integers, that represents the CNOT circuit. This should be a (2x2) block-diagonal matrix, whereby the upper left block is any invertable transformation over [0,1]^n, and the lower right block is the inverse transpose of this transformation.

  • pspec (QubitProcessorSpec) – An nbar-qubit QubitProcessorSpec object that encodes the device that the CNOT circuit is being compiled for, where nbar >= n. The algorithm is takes into account the connectivity of the device as specified by pspec.qubit_graph. The output circuit is over the gates available in this device is compile_to_native is True. If nbar > n it is necessary to provide qubit_labels, that specifies which of the qubits in pspec the CNOT circuit acts on (all other qubits will not be part of the returned circuit, regardless of whether that means an over-head is required to avoid using gates that act on those qubits. If these additional qubits should be used, then the input CNOT circuit needs to be ``padded’’ to be the identity on those qubits). The ordering of the qubits in s is assumed to be the same as that in the list pspec.qubit_labels, unless qubit_labels is specified. Then, the ordering is taken w.r.t the ordering of the list qubit_labels.

  • qubitorder (list) – A list of the qubit labels in the order in which they are to be eliminated. For auto-generated orderings use the compile_cnot_circuit() wrap-around function.

  • qubit_labels (list, optional) – Required if the CNOT circuit to compile is over less qubits than in pspec. In this case this is a list of the qubits to compile the CNOT circuit for; it should be a subset of the elements of pspec.qubit_labels. The ordering of the qubits in s is taken w.r.t the ordering of this list.

  • check (bool, optional) – Whether to check the algorithm was successful.

  • respect_connectivity (bool, optional) – This algorithm takes the connectivity into account, but sometimes resorts to ‘non-local’ CNOTs. If respect_connectivity is True these gates are re-expressed over the available gates using a SWAP-like decomposition. If False, the algorithm does not compile these gates automatically. However, they will still be converted to native gates from pspec if compile_to_native is True, using whatever the user specified algorithm for compiling non-local CNOT gates this implies.

Returns

Circuit – A circuit implementing the input CNOT circuit.

pygsti.algorithms.compilers._compile_cnot_circuit_using_oicage_algorithm(s, pspec, qubitorder, qubit_labels=None, compile_to_native=False, check=True)

An improved, ordered and connectivity-adjusted Gaussian-elimination (OiCAGE) algorithm for compiling a CNOT circuit.

This is a slight improvement (for some CNOT circuits), on the algorithm in :function:`_compile_cnot_circuit_using_ocage_algorithm()`, which is the meaning of the “improved”. See the docstring for that function for information on the parameters of this function and the basic outline of the algorithm.

Parameters
  • s (array over [0,1]) – An (2n X 2n) symplectic matrix of 0s and 1s integers, that represents the CNOT circuit. This should be a (2x2) block-diagonal matrix, whereby the upper left block is any invertable transformation over [0,1]^n, and the lower right block is the inverse transpose of this transformation.

  • pspec (QubitProcessorSpec) – An nbar-qubit QubitProcessorSpec object that encodes the device that the CNOT circuit is being compiled for, where nbar >= n. The algorithm is takes into account the connectivity of the device as specified by pspec.qubit_graph. If nbar > n it is necessary to provide qubit_labels, that specifies which of the qubits in pspec the CNOT circuit acts on (all other qubits will not be part of the returned circuit, regardless of whether that means an over-head is required to avoid using gates that act on those qubits. If these additional qubits should be used, then the input CNOT circuit needs to be ``padded’’ to be the identity on those qubits). The ordering of the qubits in s is assumed to be the same as that in the list pspec.qubit_labels, unless qubit_labels is specified. Then, the ordering is taken w.r.t the ordering of the list qubit_labels.

  • qubitorder (list) – A list of the qubit labels in the order in which they are to be eliminated. For auto-generated orderings use the compile_cnot_circuit() wrap-around function.

  • qubit_labels (list, optional) – Required if the CNOT circuit to compile is over less qubits than in pspec. In this case this is a list of the qubits to compile the CNOT circuit for; it should be a subset of the elements of pspec.qubit_labels. The ordering of the qubits in s is taken w.r.t the ordering of this list.

  • compile_to_native (bool, optional) – Unused.

  • check (bool, optional) – Whether to check the algorithm was successful.

Returns

Circuit – A circuit implementing the input CNOT circuit.

pygsti.algorithms.compilers.compile_stabilizer_state(s, p, pspec, absolute_compilation, paulieq_compilation, qubit_labels=None, iterations=20, paulirandomize=False, algorithm='COiCAGE', aargs=[], costfunction='2QGC:10:depth:1', rand_state=None)

Generates a circuit to create the stabilizer state from the standard input state |0,0,0,…>.

The stabilizer state is specified by s and p. The circuit returned is over the gates in the processor spec. See :function:`compile_stabilizer_state()` for the inverse of this.

Parameters
  • s (array over [0,1]) – An (2n X 2n) symplectic matrix of 0s and 1s integers. This is a symplectic matrix representing any Clifford gate that, when acting on |0,0,0,…>, generates the desired stabilizer state. So s is not unique.

  • p (array over [0,1]) – A length-2n vector over [0,1,2,3] that, together with s, defines a valid n-qubit Clifford gate. This phase vector matrix should, together with s, represent any Clifford gate that, when acting on |0,0,0,…>, generates the desired stabilizer state. So p is not unique.

  • pspec (QubitProcessorSpec, optional) –

    An nbar-qubit QubitProcessorSpec object that encodes the device that the stabilizer is being compiled for, where nbar >= n. If this is specified, the output circuit is over the gates available in this device. If this is None, the output circuit is over the “canonical” processor of CNOT gates between all qubits, consisting of “H”, “HP”, “PH”, “HPH”, “I”, “X”, “Y” and “Z”, which is the set used internally for the compilation. In most circumstances, the output will be more useful if a QubitProcessorSpec is provided.

    If nbar > n it is necessary to provide qubit_labels, that specifies which of the qubits in pspec the stabilizer is over. (All other qubits will not be part of the returned circuit, regardless of whether that means an over-head is required to avoid using gates that act on those qubits. If these additional qubits should be used, then the input (s,p) needs to be ``padded’’ to be the identity on those qubits).

    The ordering of the indices in (s,`p`) is w.r.t to ordering of the qubit labels in pspec.qubit_labels, unless qubit_labels is specified. Then, the ordering is taken w.r.t the ordering of the list qubit_labels.

  • pspec

    An nbar-qubit QubitProcessorSpec object that encodes the device that the stabilizer is being compiled for, where nbar >= n. If this is specified, the output circuit is over the gates available in this device. If this is None, the output circuit is over the “canonical” processor of CNOT gates between all qubits, consisting of “H”, “HP”, “PH”, “HPH”, “I”, “X”, “Y” and “Z”, which is the set used internally for the compilation. In most circumstances, the output will be more useful if a QubitProcessorSpec is provided.

    If nbar > n it is necessary to provide qubit_labels, that specifies which of the qubits in pspec the stabilizer is over. (All other qubits will not be part of the returned circuit, regardless of whether that means an over-head is required to avoid using gates that act on those qubits. If these additional qubits should be used, then the input (s,p) needs to be ``padded’’ to be the identity on those qubits).

    The ordering of the indices in (s,`p`) is w.r.t to ordering of the qubit labels in pspec.qubit_labels, unless qubit_labels is specified. Then, the ordering is taken w.r.t the ordering of the list qubit_labels.

  • absolute_compilation (CompilationRules) – Rules for exactly (absolutely) compiling the “native” gates of pspec into clifford gates.

  • paulieq_compilation (CompilationRules) – Rules for compiling, up to single-qubit Pauli gates, the “native” gates of pspec into clifford gates.

  • qubit_labels (List, optional) – Required if the stabilizer state is over less qubits than pspec. In this case this is a list of the qubits to compile the Clifford for; it should be a subset of the elements of pspec.qubit_labels. The ordering of the qubits in (s,`p`) is taken w.r.t the ordering of this list.

  • iterations (int, optional) – This algorithm is randomized. This is the number of iterations used in the algorithm. the time taken by this function increases linearly with iterations. Increasing iterations will often improve the obtained compilation (the “cost” of the obtained circuit, as specified by costfunction may decrease towards some asymptotic value).

  • paulirandomize (bool, optional) – If True then independent, uniformly random Pauli layers (a Pauli on each qubit) are inserted in between every layer in the circuit. These Paulis are then compiled into the gates in pspec, if pspec is provided. That is, this Pauli-frame-randomizes / Pauli-twirls the internal layers of this circuit. This can be useful for preventing coherent addition of errors in the circuit.

  • algorithm (str, optional) – Our algorithm finds a circuit consisting of 1Q-gates - a CNOT circuit - 1Q-gates. The CNOT circuit is found using Gaussian elimination, and it can then be recompiled using a CNOT-circuit compiler. algorithm specifies the CNOT-compilation algorithm to use. The allowe values are all those algorithms that permisable in the compile_cnot_circuit() function. See the docstring of that function for more information. The default is likely to be the best out of the in-built CNOT compilers under most circumstances.

  • aargs (list, optional) – If the CNOT compilation algorithm can take optional arguments, these are specified here. This is passed to compile_cnot_circuit() as aarg.

  • costfunction (function or string, optional) –

    If a function, it is a function that takes a circuit and pspec as the first and second inputs and returns a ‘cost’ (a float) for the circuit. The circuit input to this function will be over the gates in pspec, if a pspec has been provided, and as described above if not. This costfunction is used to decide between different compilations when randomized algorithms are used: the lowest cost circuit is chosen. If a string it must be one of:

    • ’2QGC’ : the cost of the circuit is the number of 2-qubit gates it contains.

    • ’depth’ : the cost of the circuit is the depth of the circuit.

    • ’2QGC:x:depth:y’the cost of the circuit is x * the number of 2-qubit gates in the circuit +

      y * the depth of the circuit, where x and y are integers.

  • rand_state (RandomState, optional) – A np.random.RandomState object for seeding RNG

Returns

Circuit – A circuit that creates the specified stabilizer state from |0,0,0,…>

pygsti.algorithms.compilers.compile_stabilizer_measurement(s, p, pspec, absolute_compilation, paulieq_compilation, qubit_labels=None, iterations=20, paulirandomize=False, algorithm='COCAGE', aargs=[], costfunction='2QGC:10:depth:1', rand_state=None)

Generates a circuit to map the stabilizer state to the standard state |0,0,0,…>.

The stabilizer state is specified by s and p. The circuit returned is over the gates in the processor spec pspec. See :function”compile_stabilizer_state() for the inverse of this. So, this circuit followed by a Z-basis measurement can be used to simulate a projection onto the stabilizer state C|0,0,0,…> where C is the Clifford represented by s and p.

Parameters
  • s (array over [0,1]) – An (2n X 2n) symplectic matrix of 0s and 1s integers. This is a symplectic matrix representing any Clifford gate that, when acting on |0,0,0,…>, generates the stabilizer state that we need to map to |0,0,0,…>. So s is not unique.

  • p (array over [0,1]) – A length-2n vector over [0,1,2,3] that, together with s, defines a valid n-qubit Clifford gate. This phase vector matrix should, together with s, represent any Clifford gate that, when acting on |0,0,0,…>, generates the stabilizer state that we need to map to |0,0,0,…>. So p is not unique.

  • pspec (QubitProcessorSpec, optional) –

    An nbar-qubit QubitProcessorSpec object that encodes the device that the stabilizer is being compiled for, where nbar >= n. If this is specified, the output circuit is over the gates available in this device. If this is None, the output circuit is over the “canonical” processor of CNOT gates between all qubits, consisting of “H”, “HP”, “PH”, “HPH”, “I”, “X”, “Y” and “Z”, which is the set used internally for the compilation. In most circumstances, the output will be more useful if a QubitProcessorSpec is provided.

    If nbar > n it is necessary to provide qubit_labels, that specifies which of the qubits in pspec the stabilizer is over. (All other qubits will not be part of the returned circuit, regardless of whether that means an over-head is required to avoid using gates that act on those qubits. If these additional qubits should be used, then the input (s,p) needs to be ``padded’’ to be the identity on those qubits).

    The ordering of the indices in (s,`p`) is w.r.t to ordering of the qubit labels in pspec.qubit_labels, unless qubit_labels is specified. Then, the ordering is taken w.r.t the ordering of the list qubit_labels.

  • absolute_compilation (CompilationRules) – Rules for exactly (absolutely) compiling the “native” gates of pspec into clifford gates.

  • paulieq_compilation (CompilationRules) – Rules for compiling, up to single-qubit Pauli gates, the “native” gates of pspec into clifford gates.

  • qubit_labels (List, optional) – Required if the stabilizer state is over less qubits than pspec. In this case this is a list of the qubits to compile the Clifford for; it should be a subset of the elements of pspec.qubit_labels. The ordering of the qubits in (s,`p`) is taken w.r.t the ordering of this list.

  • iterations (int, optional) – This algorithm is randomized. This is the number of iterations used in the algorithm. the time taken by this function increases linearly with iterations. Increasing iterations will often improve the obtained compilation (the “cost” of the obtained circuit, as specified by costfunction may decrease towards some asymptotic value).

  • paulirandomize (bool, optional) – If True then independent, uniformly random Pauli layers (a Pauli on each qubit) are inserted in between every layer in the circuit. These Paulis are then compiled into the gates in pspec, if pspec is provided. That is, this Pauli-frame-randomizes / Pauli-twirls the internal layers of this circuit. This can be useful for preventing coherent addition of errors in the circuit.

  • algorithm (str, optional) – Our algorithm finds a circuit consisting of 1Q-gates - a CNOT circuit - 1Q-gates. The CNOT circuit is found using Gaussian elimination, and it can then be recompiled using a CNOT-circuit compiler. algorithm specifies the CNOT-compilation algorithm to use. The allowe values are all those algorithms that permisable in the compile_cnot_circuit() function. See the docstring of that function for more information. The default is likely to be the best out of the in-built CNOT compilers under most circumstances.

  • aargs (list, optional) – If the CNOT compilation algorithm can take optional arguments, these are specified here. This is passed to compile_cnot_circuit() as aarg.

  • costfunction (function or string, optional) –

    If a function, it is a function that takes a circuit and pspec as the first and second inputs and returns a ‘cost’ (a float) for the circuit. The circuit input to this function will be over the gates in pspec, if a pspec has been provided, and as described above if not. This costfunction is used to decide between different compilations when randomized algorithms are used: the lowest cost circuit is chosen. If a string it must be one of:

    • ’2QGC’ : the cost of the circuit is the number of 2-qubit gates it contains.

    • ’depth’ : the cost of the circuit is the depth of the circuit.

    • ’2QGC:x:depth:y’the cost of the circuit is x * the number of 2-qubit gates in the circuit +

      y * the depth of the circuit, where x and y are integers.

  • rand_state (RandomState, optional) – A np.random.RandomState object for seeding RNG

Returns

Circuit – A circuit that maps the specified stabilizer state to |0,0,0,…>

pygsti.algorithms.compilers._convert_submatrix_to_echelon_form_using_cnots(s, optype, position, qubit_labels)

Converts a submatrix of s to row- or column-echelon form.

Converts one of the 4 submatrices of the symplectic matrix s to row- or column-echelon form, using a CNOT circuit acting after or before this circuit. The conversion is only performed if the submatrix is invertable, and otherwise the function reports that this submatrix is not invertable.

The function does not alter s, but rather returns an updated version of s.

Parameters
  • s (np.array) – The (2n,2n) matrix over [0,1] that we are transforming one of the 4 (n,n) submatrices of to row/column echolon form.

  • optype ('row' or 'column') – If ‘row’, we peform row-operation CNOTs (CNOTs from the LHS) to convert the the submatrix to row-echelon form, If ‘column’, we peform column-operation CNOTs (CNOTs from the RHS) to convert the submatrix to column-echelon form.

  • position ('UL', 'UR', 'LL', or 'LR') – The submatrix to perform the row/column reduction on. ‘UL’ and ‘UR’ correspond to the upper left and right submatrices, respecively. ‘LL’ and ‘LR’ correspond to the lower left and right submatrices, respecively.

  • qubit_labels (list) – The qubit labels corresponding to the indices of s. This is required because othewise it is ambigious as to what the ‘name’ of a qubit associated with each indices is, so it is not possible to return a suitable list of CNOTs.

Returns

  • np.array – The updated s matrix. If the submatrix is not invertable, then the updated s at the point at which this becomes apparent is returned.

  • bool – True if the row/column reduction has managed to create a matrix with 1s on the diagonal, or equivalently when the submatrix is invertable (over [0,1] mod 2)

  • list – A list of the CNOT instructions used to convert s to row/column echolon form. If optype`=’row’, this list is the CNOTs in the order that they should be applied *after* a unitary represented by `s so that the composite unitary has row-echolon form in the specified submatrix of its s matrix. If otptype `=’column’ then this list is the CNOTs in the order they should be applied *before* a unitary represented by `s so that the composite unitary has row-echolon form in the specified submatrix of its s matrix.

    When the returned bool is False, this list is None.

pygsti.algorithms.compilers._submatrix_gaussian_elimination_using_cnots(s, optype, position, qubit_labels)

Converts a submatrix of s to the identity matrix using CNOTs.

Converts one of the 4 submatrices of the symplectic matrix s to the identity matrix, using a CNOT circuit acting after or before this circuit. The CNOT circuit is found using Gaussian elimination. The CNOT circuit acts before this circuit if optype is ‘column’ and acts after this if optype is ‘row’. The conversion is only performed if the submatrix is invertable (otherwise it is not possible), and otherwise the function reports that this submatrix is not invertable.

The function does not alter s, but rather returns an updated version of s.

Parameters
  • s (np.array) – The (2n,2n) matrix over [0,1] that we are transforming one of the 4 (n,n) submatrices of to I.

  • optype ('row' or 'column') – If ‘row’, we peform row-operation CNOTs (CNOTs from the LHS) to convert the the submatrix to I, If ‘column’, we peform column-operation CNOTs (CNOTs from the RHS) to convert the submatrix to I.

  • position ('UL', 'UR', 'LL', or 'LR') – The submatrix to perform the transformation on. ‘UL’ and ‘UR’ correspond to the upper left and right submatrices, respecively. ‘LL’ and ‘LR’ correspond to the lower left and right submatrices, respecively.

  • qubit_labels (list) – The qubit labels corresponding to the indices of s. This is required because othewise it is ambigious as to what the ‘name’ of a qubit associated with each indices is, so it is not possible to return a suitable list of CNOTs.

Returns

  • np.array – The updated s matrix. If the submatrix is not invertable, then the updated s at the point at which this becomes apparent is returned.

  • bool – True if the transformation was successful (the submatrix was invertable)

  • list – A list of the CNOT instructions used to convert s to I. If optype`=’row’, this list is the CNOTs in the order that they should be applied *after* a unitary represented by `s so that the composite unitary has I as the specified submatrix of its s matrix. If otptype `=’column’ then this list is the CNOTs in the order they should be applied *before* a unitary represented by `s so that the composite unitary has I as the specified submatrix of its s matrix.

    When the returned bool is False, this list is None.

pygsti.algorithms.compilers._make_submatrix_invertable_using_hadamards(s, optype, position, qubit_labels, rand_state=None)

Uses row-action or column-action Hadamard gates to make a submatrix of s invertable.

The function does not alter s, but rather returns an updated version of s.

Parameters
  • s (np.array) – A (2n,2n) matrix over [0,1].

  • optype ('row' or 'column') – If ‘row’, we use row-operation Hadamards (Hs from the LHS). If ‘column’, we use column-operation Hadamards (Hs from the RHS).

  • position ('UL', 'UR', 'LL', or 'LR') – The submatrix to perform the transformation on. ‘UL’ and ‘UR’ correspond to the upper left and right submatrices, respecively. ‘LL’ and ‘LR’ correspond to the lower left and right submatrices, respecively.

  • qubit_labels (list) – The qubit labels corresponding to the indices of s. This is required because othewise it is ambigious as to what the ‘name’ of a qubit associated with each indices is, so it is not possible to return a suitable list of CNOTs.

  • rand_state (RandomState, optional) – A np.random.RandomState object for seeding RNG

Returns

  • np.array – The updated s matrix. If the submatrix is not invertable, then the updated s at the point at which this becomes apparent is returned.

  • list – A list of the Hadamards.

pygsti.algorithms.compilers._make_submatrix_invertable_using_phases_and_idsubmatrix(s, optype, position, qubit_labels)

Uses row-action or column-action Phase gates to make a submatrix of s invertable.

This uses an identity submatrix in s, and does not alter s, but rather returns an updated version of s.

Parameters
  • s (np.array) – A (2n,2n) matrix over [0,1].

  • optype ('row' or 'column') – If ‘row’, we use row-operation Ps (Ps from the LHS). In that case ‘position’ must be ‘LL’ or ‘LR’ and it is submatrix above optype that must be the identity for this function to have the desired action. If ‘column’, we use column-operation Ps (Ps from the RHS). In that case ‘position’ must be ‘UL’ or ‘LL’ and it is submatrix to the RHS of optype that must be the identity for this function to have the desired action.

  • position ('UL', 'UR', 'LL', or 'LR') – The submatrix to perform the transformation on. ‘UL’ and ‘UR’ correspond to the upper left and right submatrices, respecively. ‘LL’ and ‘LR’ correspond to the lower left and right submatrices, respecively.

  • qubit_labels (list) – The qubit labels corresponding to the indices of s. This is required because othewise it is ambigious as to what the ‘name’ of a qubit associated with each indices is, so it is not possible to return a suitable list of CNOTs.

Returns

  • np.array – The updated s matrix. If the submatrix is not invertable, then the updated s at the point at which this becomes apparent is returned.

  • list – A list of the phase gates.

pygsti.algorithms.compilers.find_albert_factorization_transform_using_cnots(s, optype, position, qubit_labels)

Performs an Albert factorization transform on s.

Given a symplectic s matrix of the form ((A,B),(C,D)) with the submatrix in the position specified by position symmetric, this function

1. Finds an invertable M such that F = M M.T where F is the submatrix in position position, i.e., F is one of A, B, C and D. (this is known as an albert factorization).

2. Applies a CNOT circuit from the LHS (if optype = ‘row’) or RHS (if optyp`=’colum’)) to `s so that F - > M.

For example, if s = ((A,I),(C,D)), position = ‘LR’ and optype = ‘column’ then it finds an M such that we may write s = ((A,I),(C,M M.T)) and it applies the CNOT circuit ((M,0),(0,M^(-1)^T) to the RHS of s, mapping s to s = ((AM,M),(CM^(-1)^T) ,M)), so that the upper RHS and lower RHS matrix of the new s are the same and are invertable.

This function returns a CNOT circuit that performs this action, with this CNOT circuit obtained from basic Gaussian elimination on M. Note that neither the returned s nor the CNOT circuit is deterministic: Both depend on M from albert factorisation, but this M is non-unique and our algorithm for finding such an M is randomized.

This function does not alter s, but rather returns an updated version of s.

Parameters
  • s (np.array) – A (2n,2n) matrix over [0,1].

  • optype ('row' or 'column') – If ‘row’, we use row-operation CNOTs (CNOTs from the LHS). If ‘column’, we use column-operation CNOTs (CNOTs from the RHS).

  • position ('UL', 'UR', 'LL', or 'LR') – The submatrix to perform the transformation on. ‘UL’ and ‘UR’ correspond to the upper left and right submatrices, respecively. ‘LL’ and ‘LR’ correspond to the lower left and right submatrices, respecively.

  • qubit_labels (list) – The qubit labels corresponding to the indices of s. This is required because othewise it is ambigious as to what the ‘name’ of a qubit associated with each indices is, so it is not possible to return a suitable list of CNOTs.

Returns

  • np.array – The updated s matrix.

  • list – A list of CNOT gates to implement the transformation requested.

pygsti.algorithms.compilers._apply_phase_to_all_qubits(s, optype, qubit_labels)

Applies phase gates to all qubits

Parameters
  • s (np.array) – A (2n,2n) matrix over [0,1].

  • optype ('row' or 'column') – If ‘row’, we use row-operation phase gates. If ‘column’, we use column-operation phase gates.

  • qubit_labels (list) – The qubit labels corresponding to the indices of s.

Returns

  • np.array – The updated s matrix.

  • list – A list containing phase gates on all the qubits.

pygsti.algorithms.compilers._apply_hadamard_to_all_qubits(s, optype, qubit_labels)

Applies Hadamard gates to all qubits

Parameters
  • s (np.array) – A (2n,2n) matrix over [0,1].

  • optype ('row' or 'column') – If ‘row’, we use row-operation Hadamard gates. If ‘column’, we use column-operation Hadamard gates.

  • qubit_labels (list) – The qubit labels corresponding to the indices of s.

Returns

  • np.array – The updated s matrix.

  • list – A list containing Hadamard gates on all the qubits.

pygsti.algorithms.compilers.compile_conditional_symplectic(s, pspec, qubit_labels=None, calg='COiCAGE', cargs=[], check=True, rand_state=None)

Finds circuits that partially (conditional on the input) implement the Clifford given by s.

The core of the compile_stabilizer_state() and compile_stabilizer_measurement() functions. Finds circuits C1 and C2 so that:

  1. C1 is a CNOT circuit

  2. C2 is a circuit with the form 1-qubit-gates – CNOT circuit – 1-qubit gates.

3. The symplectic rep of the circuit consisting of C1 followed by C2 has the form ((.,B)(.,D)) when s has the form ((A,B),(C,D)).

Therefore, the circuit C2 acting on |0,0,0,…> generates the same stabilizer state (up to Paulis) as a circuit that has the symplectic rep (s,p) for any valid p. The circuit is only “conditionally” equivalent to another circuit with the rep (s,p) – conditional on the input state – which is the meaning of the name compile_conditional_symplectic.

Parameters
  • s (array over [0,1]) – An (2n X 2n) symplectic matrix of 0s and 1s integers.

  • pspec (QubitProcessorSpec, optional) – An nbar-qubit QubitProcessorSpec object that encodes the device that s is being “conditionally” compiled for, where nbar >= n. If nbar > n it is necessary to provide qubit_labels, that specifies which of the qubits in pspec the stabilizer is over. (All other qubits will not be part of the returned circuit, regardless of whether that means an over-head is required to avoid using gates that act on those qubits. If these additional qubits should be used, then the input (s,p) needs to be ``padded’’ to be the identity on those qubits). The ordering of the indices in (s,`p`) is w.r.t to ordering of the qubit labels in pspec.qubit_labels, unless qubit_labels is specified. Then, the ordering is taken w.r.t the ordering of the list qubit_labels.

  • qubit_labels (List, optional) – Required if the s is over less qubits than pspec. In this case this is a list of the qubits to compile the Clifford for; it should be a subset of the elements of pspec.qubit_labels. The ordering of the qubits in (s,`p`) is taken w.r.t the ordering of this list.

  • calg (str, optional) – Our algorithm finds a circuit consisting of 1Q-gates - a CNOT circuit - 1Q-gates. The CNOT circuit is found using Gaussian elimination, and it can then be recompiled using a CNOT-circuit compiler. calg specifies the CNOT-compilation algorithm to use. The allowed values are all those algorithms that are permisable in the compile_cnot_circuit() function. See the docstring of that function for more information. The default is likely to be the best out of the in-built CNOT compilers under most circumstances. Note that this is only used to recompile the CNOT circuit in C2, because the main use for this function only needs C1 for reference, rather than as a part of a final output.

  • cargs (list, optional) – If the CNOT compilation algorithm can take optional arguments, these are specified here. This is passed to compile_cnot_circuit() as aarg.

  • check (bool, optional) – Whether to check that the output is correct.

  • rand_state (RandomState, optional) – A np.random.RandomState object for seeding RNG

Returns

  • Circuit – The circuit C2 described above.

  • Circuit – The circuit C1 described above.