LogicalQ.Logical ================ .. py:module:: LogicalQ.Logical Classes ------- .. autoapisummary:: LogicalQ.Logical.LogicalCircuit LogicalQ.Logical.LogicalQubit LogicalQ.Logical.LogicalRegister LogicalQ.Logical.LogicalStatevector LogicalQ.Logical.LogicalDensityMatrix Functions --------- .. autoapisummary:: LogicalQ.Logical.logical_state_fidelity Module Contents --------------- .. py:class:: LogicalCircuit(n_logical_qubits, label, stabilizer_tableau, name = None) Bases: :py:obj:`qiskit.QuantumCircuit` Core LogicalQ representation of a logical quantum circuit. .. py:attribute:: n_logical_qubits .. py:attribute:: stabilizer_tableau .. py:attribute:: n_stabilizers .. py:attribute:: label .. py:attribute:: n_physical_qubits .. py:attribute:: logical_qubit_type :value: 'qec' .. py:attribute:: n_ancilla_qubits .. py:attribute:: n_measure_qubits .. py:attribute:: flagged_stabilizers_1 :value: [] .. py:attribute:: flagged_stabilizers_2 :value: [] .. py:attribute:: x_stabilizers :value: [] .. py:attribute:: z_stabilizers :value: [] .. py:attribute:: qed_cycle_indices_initial .. py:attribute:: qed_cycle_indices_final .. py:attribute:: qec_cycle_indices_initial .. py:attribute:: qec_cycle_indices_final .. py:attribute:: logical_qregs :value: [] .. py:attribute:: ancilla_qregs :value: [] .. py:attribute:: logical_op_qregs :value: [] .. py:attribute:: enc_verif_cregs :value: [] .. py:attribute:: curr_syndrome_cregs :value: [] .. py:attribute:: prev_syndrome_cregs :value: [] .. py:attribute:: flagged_syndrome_diff_cregs :value: [] .. py:attribute:: unflagged_syndrome_diff_cregs :value: [] .. py:attribute:: pauli_frame_cregs :value: [] .. py:attribute:: logical_op_meas_cregs :value: [] .. py:attribute:: final_measurement_cregs :value: [] .. py:attribute:: qreg_lists .. py:attribute:: creg_lists .. py:attribute:: output_creg .. py:attribute:: cbit_setter_qreg .. py:attribute:: data_without_qec .. py:attribute:: data_without_qed .. py:method:: from_physical_circuit(physical_circuit, label, stabilizer_tableau, name = None, max_iterations = 1) :classmethod: Construct a LogicalCircuit from a physical qiskit circuit. :param physical_circuit: The QuantumCircuit to construct from. :param label: The QECC label. :param stabilizer_tableau: The set of stabilizers for the QECC. :param name: An optional name for the circuit. :param max_iterations: Number of times, to attempt to encod qubits. :returns: The LogicalCircuit constructed from the physical. .. py:method:: add_logical_qubits(logical_qubit_count, logical_qubit_types = 'qec') Add logical qubit(s) to the LogicalCircuit. :param logical_qubit_count: The number of logical qubits to add. .. py:method:: group_stabilizers() Generate the stabilizers for the code. .. py:method:: generate_code() Generate the encoding circuit and logical operators for the selected tableau. .. py:method:: encode(*qubits, max_iterations = 1, initial_states = None) Prepare logical qubit(s) in the specified initial state(s). :param qubits: Indices of logical qubits to be encoded. :param max_iterations: Maximum number of encoding attempts. :param initial_states: Initial states in which to encode each qubit. .. py:method:: initialize(statevector, logical_qubit_indices = None, normalize = False) Initialize qubits in a specific state. Qubit initialization is done by first resetting the qubits to :math:`|0\rangle` followed by calling :class:`~qiskit.circuit.library.StatePreparation` class to prepare the qubits in a specified state. Both these steps are included in the :class:`~qiskit.circuit.library.Initialize` instruction. :param params: The state to initialize to, can be either of the following. * Statevector or vector of complex amplitudes to initialize to. * Labels of basis states of the Pauli eigenstates Z, X, Y. See :meth:`.Statevector.from_label`. Notice the order of the labels is reversed with respect to the qubit index to be applied to. Example label ``'01'`` initializes the qubit zero to :math:`|1\rangle` and the qubit one to :math:`|0\rangle`. * An integer that is used as a bitmap indicating which qubits to initialize to :math:`|1\rangle`. Example: setting params to 5 would initialize qubit 0 and qubit 2 to :math:`|1\rangle` and qubit 1 to :math:`|0\rangle`. :param qubits: Qubits to initialize. If ``None`` the initialization is applied to all qubits in the circuit. :param normalize: Whether to normalize an input array to a unit vector. :returns: A handle to the instructions created. .. rubric:: Examples Prepare a qubit in the state :math:`(|0\rangle - |1\rangle) / \sqrt{2}`. .. plot:: :include-source: :nofigs: import numpy as np from qiskit import QuantumCircuit circuit = QuantumCircuit(1) circuit.initialize([1/np.sqrt(2), -1/np.sqrt(2)], 0) circuit.draw() output: .. code-block:: text ┌──────────────────────────────┐ q_0: ┤ Initialize(0.70711,-0.70711) ├ └──────────────────────────────┘ Initialize from a string two qubits in the state :math:`|10\rangle`. The order of the labels is reversed with respect to qubit index. More information about labels for basis states are in :meth:`.Statevector.from_label`. .. plot:: :include-source: :nofigs: import numpy as np from qiskit import QuantumCircuit circuit = QuantumCircuit(2) circuit.initialize('01', circuit.qubits) circuit.draw() output: .. code-block:: text ┌──────────────────┐ q_0: ┤0 ├ │ Initialize(0,1) │ q_1: ┤1 ├ └──────────────────┘ Initialize two qubits from an array of complex amplitudes. .. plot:: :include-source: :nofigs: import numpy as np from qiskit import QuantumCircuit circuit = QuantumCircuit(2) circuit.initialize([0, 1/np.sqrt(2), -1.j/np.sqrt(2), 0], circuit.qubits) circuit.draw() output: .. code-block:: text ┌────────────────────────────────────┐ q_0: ┤0 ├ │ Initialize(0,0.70711,-0.70711j,0) │ q_1: ┤1 ├ └────────────────────────────────────┘ .. py:method:: reset(logical_qubit_indices = None, reset_ancillas = False) Reset all physical qubits associated with specified logical qubits, optionally including ancillas. :param logical_qubit_indices: Indices of logical qubits to reset. If None, then reset all. :param reset_ancillas: Specifies whether to reset (both general and logical operation) ancilla qubits associated with each logical qubit. .. py:method:: reset_ancillas(logical_qubit_indices = None) Reset all ancillas associated with specified logical qubits. :param logical_qubit_indices: Indices of logical qubits to reset. If None, then reset all. .. py:method:: steane_flagged_circuit1(logical_qubit_indices) Measure first set of flagged syndromes for the Steane code. .. py:method:: steane_flagged_circuit2(logical_qubit_indices) Measure second set of flagged syndromes for the Steane code. .. py:method:: measure_stabilizers(logical_qubit_indices = None, stabilizer_indices = None) Measure specified stabilizers to the circuit as controlled Pauli operators. :param logical_qubit_indices: Indices of logical qubits for which to measure stabilizers. :param stabilizer_indices: Indices of stabilizers to measure. .. py:method:: measure_syndrome_diff(logical_qubit_indices = None, stabilizer_indices = None, flagged = False, steane_flag_1 = False, steane_flag_2 = False) Measure flagged or unflagged syndrome differences for specified logical qubits and stabilizers. :param logical_qubit_indices: Logical qubits for which to measure indices. :param stabilizer_indices: Stabilizers for which to measure indices. :param flagged: Whether to measure flagged or unflagged differences. :param steane_flag_1: Whether to measure the first Steane code syndrome. Takes priority over `steane_flag_2`. :param steane_flag_2: Whether to measure the second Steane code syndrome. Ignored if `steane_flag_1` is True. .. py:method:: optimize_qec_cycle_indices(logical_qubit_indices = None, constraint_model = None, ignore_existing_qec = False, clear_existing_qec = False) Compute optimal QEC cycle indices. :param logical_qubit_indices: Logical qubits for which to compute optimal QEC cycle indices. :param constraint_model: Constraint model, i.e., dictionary of gadget costs for the circuit. :param ignore_existing_qec: Whether to ignore QEC-related parameters in the constraint model. :param clear_existing_qec: Whether to remove existing QEC cycles. :returns: Dictionary with optimal QEC cycle indices for each requested qubit. .. py:method:: insert_qec_cycles(logical_qubit_indices = None, qec_cycle_indices = None, clear_existing_qec = False) Insert QEC cycles at specified indices in the circuit data. :param logical_qubit_indices: Logical qubits for which to insert QEC cycles. :param qec_cycle_indices: Indices at which to insert QEC cycles for each logical qubit. :param clear_existing_qec: Whether to clear the existing QEC cycles. :returns: Original circuit data and data after appending QEC cycles. .. py:method:: append_qed_cycle(logical_qubit_indices = None, perform_flagged_syndrome_measurements = True) Append a QED cycle to the end of the circuit. :param logical_qubit_indices: Logical qubits for which to add QED cycles. :returns: Qubits and indices with QED cycles, before and after appending. .. py:method:: append_qec_cycle(logical_qubit_indices = None, perform_flagged_syndrome_measurements = True) Append a QEC cycle to the end of the circuit. :param logical_qubit_indices: Logical qubits for which to add QEC cycles. :returns: Qubits and indices with QEC cycles, before and after appending. .. py:method:: clear_qec_cycles(logical_qubit_indices = None, qec_cycle_indices = None) Clear QEC cycles (either specified or all) on specified logical qubits. :param logical_qubit_indices: Logical qubits from which to clear QEC cycles. Clears all if :py:type:`None`. :param qec_cycle_indices: QEC cycles to clear. Clears all if :py:type:`None` :returns: This method is not yet implemented. .. py:method:: apply_decoding(logical_qubit_indices, stabilizer_indices, with_flagged) Decode the syndrome measurements to determine the correction to apply. :param logical_qubit_indices: Logical qubits to apply decoding to. :param stabilizer_indices: Stabilizers for which to decode syndromes. :param with_flagged: Whether to decode with flagged or unflagged syndrome differences. .. py:method:: measure(logical_qubit_indices, cbit_indices, with_error_detection = True, with_error_correction = True) Measure specified qubits (in the Z basis) into classical bits. :param logical_qubit_indices: Logical qubits to measure. :param cbit_indices: Classical bits to which to record measurements. :param with_error_detection: Whether to measure syndromes after measurement. :param with_error_correction: Whether to measure and correct syndromes after measurement. :raises ValueError: if `logical_qubit_indices` or `cbit_indices` is not an iterable or if number of qubits and cbits does not match. .. py:method:: measure_all(inplace = True, with_error_correction = True) Add measurements to all qubits. :param inplace: Whether to perform measurements on this circuit or a copy. If `False`, a new circuit is returned. :param with_error_correction: Whether to perform measurements with QEC. :returns: Circuit with measurements, if `inplace = False`. .. py:method:: remove_final_measurements(inplace = False) Remove final measurements from circuit. :param inplace: Whether to remove measurements in place, i.e., for this circuit (not supported). :raises NotImplementedError: if in-place measurement is attempted. :returns: The circuit without measurements. .. py:method:: get_logical_counts(physical_counts, logical_qubit_indices = None) Get logical counts from physical counts. :param physical_counts: Physical counts to convert to logical counts. :param logical_qubit_indices: Logical qubits to get counts for. If `None`, then get counts for all. :returns: Logical qubit counts. .. py:method:: h(*targets, method='Coherent_Feedback') Logical single-qubit Hadamard (:math:`\hat H`) gate .. py:method:: x(*targets) Logical single-qubit Pauli-X (:math:`\hat X`) gate .. py:method:: y(*targets) Logical single-qubit Pauli-Y (:math:`\hat Y`) gate .. py:method:: z(*targets) Logical single-qubit Pauli-Z (:math:`\hat Z`) gate .. py:method:: s(*targets, method='Coherent_Feedback') Logical single-qubit S (:math:`\hat S`) gate Definition: [1 0] [0 i] .. py:method:: sdg(*targets, method='Coherent_Feedback') Logical S^dagger gate Definition: [1 0] [0 -i] .. py:method:: t(*targets, method='Coherent_Feedback') Logical T gate Definition: [1 0 ] [0 e^(ipi/4)] .. py:method:: tdg(*targets, method='Coherent_Feedback') Logical T^dagger gate Definition: [1 0 ] [0 e^(-ipi/4)] .. py:method:: cx(control, *_targets, method='Ancilla_Assisted') Logical Controlled-PauliX gate .. py:method:: cz(control, *_targets, method='Ancilla_Assisted') Logical Controlled-PauliZ gate .. py:method:: cy(control, *_targets, method='Ancilla_Assisted') Logical Controlled-PauliY gate .. py:method:: mcmt(gate, controls, targets) Logical Multi-Control Multi-Target gate .. py:method:: append_sk_decomposition(circuit, targets, label=None, recursion_degree=1, basis_gates=None, depth=10, return_discretized_subcircuit=False) Append the Solovay-Kitaev decomposition of a circuit in terms of logical basis gates. .. py:method:: u(theta, phi, lam, targets, method='Rotation') Apply :class:`~qiskit.circuit.library.UGate`. For the full matrix form of this gate, see the underlying gate documentation. :param theta: The :math:`\theta` rotation angle of the gate. :param phi: The :math:`\phi` rotation angle of the gate. :param lam: The :math:`\lambda` rotation angle of the gate. :param qubit: The qubit(s) to apply the gate to. :returns: A handle to the instructions created. .. py:method:: r(axis, theta, targets, label = 'R', method = 'S-K', recursion_degree = 1, depth = 10) Logical single-qubit rotation (:math:`R`) gate :param theta: Rotation angle in radians :param method: Gate realization method; options: "S-K" (Solovay-Kitaev algorithm) (Default: `"S-K"`) .. py:method:: rx(theta, targets, method = 'S-K', recursion_degree = 1, depth = 10) Logical single-qubit X rotation (:math:`RX`) gate :param theta: Rotation angle in radians :param method: Gate realization method; options: "S-K" (Solovay-Kitaev algorithm) (Default: `"S-K"`) .. py:method:: ry(theta, targets, method='S-K', recursion_degree=1, depth=10) Logical single-qubit Y rotation (:math:`RY`) gate :param theta: Rotation angle in radians :param method: Gate realization method; options: "S-K" (Solovay-Kitaev algorithm) (Default: `"S-K"`) .. py:method:: rz(phi, targets, method='S-K', recursion_degree=1, depth=10) Logical single-qubit Z rotation (:math:`RZ`) gate :param theta: Rotation angle in radians :param method: Gate realization method; options: "S-K" (Solovay-Kitaev algorithm) (Default: `"S-K"`) .. py:method:: rxx(theta, targets, method='S-K', recursion_degree=1, depth=10) Apply :class:`~qiskit.circuit.library.RXXGate`. For the full matrix form of this gate, see the underlying gate documentation. :param theta: The angle of the rotation. :param qubit1: The qubit(s) to apply the gate to. :param qubit2: The qubit(s) to apply the gate to. :returns: A handle to the instructions created. .. py:method:: ryy(theta, targets, method='S-K', recursion_degree=1, depth=10) Apply :class:`~qiskit.circuit.library.RYYGate`. For the full matrix form of this gate, see the underlying gate documentation. :param theta: The rotation angle of the gate. :param qubit1: The qubit(s) to apply the gate to. :param qubit2: The qubit(s) to apply the gate to. :returns: A handle to the instructions created. .. py:method:: rzz(theta, targets, method='S-K', recursion_degree=1, depth=10) Apply :class:`~qiskit.circuit.library.RZZGate`. For the full matrix form of this gate, see the underlying gate documentation. :param theta: The rotation angle of the gate. :param qubit1: The qubit(s) to apply the gate to. :param qubit2: The qubit(s) to apply the gate to. :returns: A handle to the instructions created. .. py:method:: sx(target, **kwargs) Logical single-qubit SQRT(X) (:math:`\sqrt{X}`) gate .. py:method:: sxdg(target, **kwargs) Logical single-qubit SQRT(X)-adjoint (:math:`\sqrt{X}^\dagger`) gate .. py:method:: append(instruction, qargs=None, cargs=None, copy=True) Append instruction to LogicalCircuit .. py:method:: add_error(l_ind, p_ind, error_type) .. py:method:: set_cbit(cbit, value) .. py:method:: cbit_not(cbit) .. py:method:: cbit_and(cbits, values) .. py:method:: cbit_xor(cbits) .. py:method:: draw(output=None, scale=None, filename=None, style=None, interactive=False, plot_barriers=True, reverse_bits=None, justify=None, vertical_compression='medium', idle_wires=None, with_layout=True, fold=None, ax=None, initial_state=False, cregbundle=None, wire_order=None, expr_len=30, fold_qec=True, fold_qed=True, fold_logicalop=True) LogicalCircuit drawer based on Qiskit circuit drawer .. py:class:: LogicalQubit(regs=None, qregs=None, cregs=None) Bases: :py:obj:`list` A LogicalQubit .. py:attribute:: _data :value: [] .. py:attribute:: qregs :value: [] .. py:attribute:: cregs :value: [] .. py:class:: LogicalRegister(qregs=None, cregs=None) Bases: :py:obj:`list` A register containing LogicalQubits .. py:attribute:: qregs :value: None .. py:attribute:: cregs :value: None .. py:class:: LogicalStatevector(data, n_logical_qubits = None, label = None, stabilizer_tableau = None, logical_circuit = None, basis = None, dims = None) Bases: :py:obj:`qiskit.quantum_info.Statevector` A LogicalStatevector .. py:attribute:: _logical_decomposition :value: None .. py:method:: from_counts(counts, n_logical_qubits, label, stabilizer_tableau, basis = 'physical') :classmethod: Construct a LogicalStatevector from measurement counts. :param counts: The set of counts measured from a circuit execution. :type counts: dict :param n_logical_qubits: The number of logical qubits. :type n_logical_qubits: int :param label: The quantum error correction code [[n,k,d]] (given as a tuple). :type label: tuple :param stabilizer_tableau: The set of stabilizers for the QECC. :type stabilizer_tableau: Iterable[str] :param basis: The basis in which each respective count's vector is given, physical or logical. :type basis: str :returns: The normalized LogicalStatevector constructed from the counts. :raises ValueError: if the counts format could not be parsed or if `basis` is invalid. .. py:method:: from_basis_str(basis_str, n_logical_qubits, label, stabilizer_tableau, basis='physical') :classmethod: Construct a LogicalStatevector from a string in the logical computational basis. :param basis_str: Either a binary bitstring or its hex equivalent to identify the basis. :param n_logical_qubits: Number of logical qubits. :param label: The label of the quantum error correction code [[n,k,d]]. :param stabilizer_tableau: The set of stabilizers for the QECC. :param basis: The basis in which each respective count's vector is given, physical or logical. :returns: The LogicalStatevector of the given basis state. :rtype: :py:class:`~LogicalQ.Logical.LogicalStatevector` :raises ValueError: if the `basis_str` could not be parsed due to improper format. .. py:property:: logical_decomposition Compute the decomposition of the LogicalStatevector in the logical basis. :param atol: Tolerance within which to set probability amplitude to zero. :returns: The set of coefficients :math:`\alpha_i, \delta`, where :math:`|\psi\rangle = \sum_{x=0}^{2^n - 1}\alpha_x|x\rangle + \delta|\psi^\perp\rangle`, where :math:`|\psi^\perp\rangle` is the component of the state vector not in the codespace. Note that coefficients are returned in ascending order of value, e.g., 000, 001, 010, 011, 100, 101, etc. :rtype: :py:type:`np.ndarray` .. py:method:: __array__(basis='physical', dtype=None, copy=_numpy_compat.COPY_ONLY_IF_NEEDED) Return an array representation of the object. :param basis: The basis, physical or logical, in which to represent the vector. :param dtype: The desired data-type for the array. :param copy: If `True`, then the array data is copied :returns: The :py:meth:`~LogicalQ.Logical.LogicalStatevector.logical_decomposition` if basis is logical and the statevector data otherwise. :rtype: :py:type:`np.ndarray` :raises ValueError: if the basis is invalid. .. py:method:: __repr__(basis='logical') Return a string representation of the statevector. :param basis: The basis, logical or physical, in which to return the array. :returns: String representation of the statevector in the requested basis. :rtype: :py:type:`np.ndarray` :raises ValueError: if the basis is invalid. .. py:method:: draw(output=None) Return a visual representation of the statevector in the logical basis. :param output: The method in which to draw. Valid choices are `text`, `latex`, and `latex_source`. :returns: string or LaTeX representation of the statevector. :rtype: `str` or :py:class:`IPython.display.Latex` :raises ValueError: if the draw method is invalid. .. py:class:: LogicalDensityMatrix(data, n_logical_qubits=None, label=None, stabilizer_tableau=None, dims=None) Bases: :py:obj:`qiskit.quantum_info.DensityMatrix` A LogicalDensityMatrix .. py:attribute:: _logical_decomposition :value: None .. py:property:: logical_decomposition :abstractmethod: .. py:method:: __repr__(basis='logical') .. py:function:: logical_state_fidelity(state1, state2)