:py:mod:`pygsti.processors.random_compilation` ============================================== .. py:module:: pygsti.processors.random_compilation .. autoapi-nested-parse:: Randomized circuit compilation via random compiling and central Pauli propagation. Module Contents --------------- Classes ~~~~~~~ .. autoapisummary:: pygsti.processors.random_compilation.RandomCompilation Functions ~~~~~~~~~ .. autoapisummary:: pygsti.processors.random_compilation.pauli_randomize_circuit pygsti.processors.random_compilation.randomize_central_pauli pygsti.processors.random_compilation.update_u3_parameters pygsti.processors.random_compilation.mod_2pi pygsti.processors.random_compilation.pauli_vector_to_u3_layer pygsti.processors.random_compilation.haar_random_u3_layer pygsti.processors.random_compilation.haar_random_u3 pygsti.processors.random_compilation.u3_cx_cz_inv pygsti.processors.random_compilation.gate_inverse pygsti.processors.random_compilation.inverse_u3 pygsti.processors.random_compilation.pad_layer .. py:class:: RandomCompilation(rc_strategy: Optional[Literal['rc', 'cp']] = None, return_bs: Optional[bool] = False, testing: Optional[bool] = False, rand_state: Optional[numpy.random.RandomState] = None) Bases: :py:obj:`object` A class for performing randomized circuit compilation. Attributes ---------- rc_strategy : str The strategy used for randomized compilation. Currently, 'pauli_rc' (pauli randomized compiling on a U3-CX-CZ gate set) and 'central_pauli' (central Pauli propagation for a U3-CX-CZ gate set) are supported. return_bs : bool If True, the `compile` method will return the target bitstring for the randomly compiled circuit. testing : bool Flag for unit testing. If True, the user can provide test Pauli layers for random compilation instead of the layers being randomly generated. rand_state : np.random.RandomState A random state for reproducibility of random operations. Initialize the RandomCompilation object. Parameters ---------- rc_strategy : str The strategy used for randomized compilation. Currently, 'pauli_rc' (pauli randomized compiling on a U3-CX-CZ gate set, see https://arxiv.org/abs/2204.07568) and 'central_pauli' (central Pauli propagation for a U3-CX-CZ gate set, see https://www.nature.com/articles/s41567-021-01409-7) are supported. Defaults to 'pauli_rc'. return_bs : bool If True, the `compile` method will return the target bitstring for the randomly compiled circuit. Default is False. testing : bool Flag for unit testing. If True, the user can provide test Pauli layers for random compilation instead of the layers being randomly generated. Default is False. rand_state : np.random.RandomState A random state for reproducibility of random operations. Default is None. .. py:attribute:: rc_strategy :value: 'None' .. py:attribute:: return_bs :value: 'False' .. py:attribute:: testing :value: 'False' .. py:method:: compile(circ: pygsti.circuits.circuit.Circuit, test_layers: Optional[Union[List[numpy.ndarray], numpy.ndarray]] = None) -> pygsti.circuits.circuit.Circuit Compiles the given circuit using the specified randomized compilation strategy. Parameters ------------- circ : pygsti.circuits.Circuit The n-qubit circuit to be compiled. test_layers : list[np.ndarray[int]], optional A list of test layers to be used in the random compilation if `self.testing` is True. Layers are specified by a length-2*n array whose entries are either 0 or 2. Indices 0:n correspond to Pauli Z errors: a 2 indicates the presence an error. Likewise indices n:2*n indicate a Pauli Z error. If using central Pauli, only one layer must be provided. If using random compilation, a number of layers equal to the number of layers of single-qubit gates must be provided. Default is None. Returns -------- list[pygsti.circuits.Circuit, str (optional), np.ndarray (optional)] A list containing the randomized circuit, and optionally the bitstring and target Pauli vector. .. py:function:: pauli_randomize_circuit(circ: pygsti.circuits.circuit.Circuit, rand_state: Optional[numpy.random.RandomState] = None, return_bs: bool = False, return_target_pauli: bool = False, insert_test_layers: bool = False, test_layers: Optional[List[numpy.ndarray]] = None) -> pygsti.circuits.circuit.Circuit Performs random compilation on a given circuit by inserting Pauli gates between layers. Parameters ------------- circ : pygsti.circuits.Circuit The circuit to be randomized. rand_state : np.random.RandomState, optional A random state for reproducibility. Default is None, which initializes a new random state. return_bs : bool, optional If True, returns the target bitstring for the randomly compiled circuit. Default is False. return_target_pauli : bool, optional If True, returns the target Pauli vector for the circuit. Default is False. insert_test_layers : bool, optional If True, uses `test_layers` as the Pauli layers to randomly compile instead of randomly generating Pauli layers. test_layers : list[np.ndarray[int]], optional A list of length-2*n arrays representing the test layers to be inserted if `insert_test_layers `is True. The number of test layers must equal the number of U3 layers in the circuit. Default is None. Returns -------- list[pygsti.circuits.Circuit, str (optional), np.ndarray (optional)] A list containing the randomized circuit, and optionally the bitstring and target Pauli vector if specified. .. py:function:: randomize_central_pauli(circ: pygsti.circuits.circuit.Circuit, rand_state: Optional[numpy.random.RandomState] = None, return_bs: bool = False, return_target_pauli: bool = False, insert_test_layer: bool = False, test_layer: Optional[numpy.ndarray] = None) -> pygsti.circuits.circuit.Circuit Perform circuit randomization by propagating a central Pauli layer through the circuit. This function is designed to handle the "back half" of the mirror circuit: i.e., given a circuit C whose fidelity is to be estimated using central Pauli mirroring, this function should be passed C_inv + L_inv, where L_inv is Haar-random U3 layer. Refer to `make_mirror_edesign` in `protocols/mirror_design.py` for more information. Parameters ------------- circ : Circuit The circuit through which the central Pauli layer is to be propagated. rand_state : np.random.RandomState, optional A random state for reproducibility. Default is None, which initializes a new random state. return_bs : bool, optional If True, returns the target bitstring for the full mirror central Pauli circuit. Default is False. return_target_pauli : bool, optional If True, returns the target Pauli vector that has been propagated through the circuit. Default is False. insert_test_layer : bool, optional If True, uses `test_layer` as the central Pauli layer instead of randomly generating a central Pauli layer. test_layer : np.ndarray[int], optional A length-2*n array representing the test layer to be inserted if `insert_test_layer `is True. Default is None. Returns -------- list[pygsti.circuits.Circuit, str (optional), np.ndarray (optional)] A list containing the randomized circuit, and optionally the bitstring and target Pauli vector if specified. .. py:function:: update_u3_parameters(layer: Iterable[pygsti.baseobjs.label.Label], p: numpy.ndarray, q: numpy.ndarray, qubit_map: Union[Dict[str, int], Dict[int, int]]) -> List[pygsti.baseobjs.label.Label] Updates the parameters of U3 gates in a given layer based on the provided Pauli random compiling vectors. Parameters ------------- layer : iterable[pygsti.baseobjs.Label] A list of gate labels representing the layer containing U3 gates. p : np.ndarray[int] A vector describing the Pauli gates preceding the layer. For an n-qubit layer, p is a length-2n array. p[0:n] indicates Pauli-Z (2 is yes Z, 0 is no Z), p[n:2*n] is Pauli-X (2 yes, 0 no). E.g., if n = 5, p[3] = 2, and p[8] = 2, then there is a Y gate on qubit 3. p : np.ndarray[int] A vector describing the Pauli gates foloowing the layer. For an n-qubit layer, q is a length-2n array. q[0:n] indicates Pauli-Z (2 is yes Z, 0 is no Z), q[n:2*n] is Pauli-X (2 yes, 0 no). E.g., if n = 5, p[1] = 0, and p[6] = 2, then there is an X gate on qubit 3. qubit_map : dict[str, int] A mapping of qubit labels to their corresponding indices. Returns -------- list A new layer containing updated U3 gates based on the applied Pauli gates. .. py:function:: mod_2pi(theta: float) -> float Modifies an angle to be within the range of -π to π. Parameters ------------- theta : float The angle in radians to be modified. Returns -------- float The modified angle within the range of -π to π. .. py:function:: pauli_vector_to_u3_layer(p: numpy.ndarray, qubits: Union[List[str], List[int]]) -> pygsti.baseobjs.label.Label Converts a Pauli vector into a corresponding layer of U3 gates. Parameters ------------- p : np.ndarray[int] A vector representing the Pauli gates to be converted. For an n-qubit layer, p is a length-2n array. p[0:n] indicates Pauli-Z (2 is yes Z, 0 is no Z), p[n:2*n] is Pauli-X (2 yes, 0 no). E.g., if n = 5, p[3] = 2, and p[8] = 2, then there is a Y gate on qubit 3. qubits : list[str] A list of qubit labels corresponding to the Pauli vector. Returns -------- pygsti.baseobjs.Label Label containing the layer of U3 gates derived from the Pauli vector. .. py:function:: haar_random_u3_layer(qubits: Union[List[str], List[int]], rand_state: Optional[numpy.random.RandomState] = None) -> pygsti.baseobjs.label.Label Generates a layer of Haar-random U3 gates. Parameters ------------- qubits : list[str] A list of qubit labels for which to generate U3 gates. rand_state : np.random.RandomState, optional A random state for reproducibility. Default is None, which initializes a new random state. Returns -------- pygsti.baseobjs.Label A label containing the layer of randomly generated U3 gates. .. py:function:: haar_random_u3(q: Union[str, int], rand_state: Optional[numpy.random.RandomState] = None) -> pygsti.baseobjs.label.Label Generates a Haar-random U3 gate. Parameters ------------- q : str The qubit label for which to generate the U3 gate. rand_state : np.random.RandomState, optional A random state for reproducibility. Default is None, which initializes a new random state. Returns -------- pygsti.baseobjs.Label A label representing the randomly generated U3 gate for the specified qubit. .. py:function:: u3_cx_cz_inv(circ: pygsti.circuits.circuit.Circuit) -> pygsti.circuits.circuit.Circuit Computes the inverse of a circuit composed of U3, CX and CZ gates. Parameters ------------- circ : pygsti.circuits.Circuit The circuit for which to compute the inverse. Returns -------- pygsti.circuits.Circuit A new circuit representing the inverse of the input circuit. .. py:function:: gate_inverse(label: pygsti.baseobjs.label.Label) -> pygsti.baseobjs.label.Label Computes the inverse of a given gate label. Parameters ------------- label : pygsti.baseobjs.Label The gate label for which to compute the inverse. Returns -------- pygsti.baseobjs.Label A new label representing the inverse of the input gate. .. py:function:: inverse_u3(args: Tuple[float, float, float]) -> Tuple[float, float, float] Computes the inverse parameters for a U3 gate given its parameters. Parameters ------------- args : tuple[float] A tuple containing the parameters (theta, phi, lambda) of the U3 gate. Returns -------- tuple[float] A tuple containing the parameters of the inverse U3 gate. .. py:function:: pad_layer(layer: Iterable[pygsti.baseobjs.label.Label], qubits: Union[List[str], List[int]]) -> List[pygsti.baseobjs.label.Label] Pads a layer of gates with idle gates for any unused qubits. Parameters ------------- layer : list[pygsti.baseobjs.Label] A list of gate labels representing the layer to be padded. qubits : list[str] A list of qubit labels to ensure all qubits are represented in the padded layer. Returns -------- list[pygsti.baseobjs.Label] A new layer containing the original gates and idle gates for unused qubits.