qpe_toolbox.circuit.serialize_circuits ====================================== .. py:module:: qpe_toolbox.circuit.serialize_circuits Functions --------- .. autoapisummary:: qpe_toolbox.circuit.serialize_circuits.apply_gate_qiskit qpe_toolbox.circuit.serialize_circuits.deserialize_to_qiskit_QuantumCircuit qpe_toolbox.circuit.serialize_circuits.serialize_from_quimb_Circuit qpe_toolbox.circuit.serialize_circuits.serialize_from_quimb_gates qpe_toolbox.circuit.serialize_circuits.deserialize_to_quimb_Circuit qpe_toolbox.circuit.serialize_circuits.deserialize_to_quimb_CircuitMPS qpe_toolbox.circuit.serialize_circuits.dump_quimb_Circuit_to_qasm qpe_toolbox.circuit.serialize_circuits.load_qasm_to_quimb_Circuit Module Contents --------------- .. py:function:: apply_gate_qiskit(qc, label, qubits, params) Apply a quantum gate to a ``qiskit`` :qiskit-api:`QuantumCircuit` using a string label. This function dispatches gate application based on: - the gate label (case-insensitive), - the number of target qubits (single- or two-qubit), - and whether the gate is parameterized. It is inspired in the :quimb-api:`Circuit.apply_gate` method from `quimb`'s :quimb-api:`Circuit`. The alias ``"cnot"`` is automatically mapped to ``"cx"``. :param qc: The quantum circuit to which the gate is applied. :type qc: :qiskit-api:`QuantumCircuit` :param label: Gate label identifying the quantum operation. The comparison is case-insensitive. For example, ``"RX"``, ``"rx"``, and ``"Rx"`` are treated identically. The label ``"cnot"`` is mapped internally to ``"cx"``. :type label: str :param qubits: List of qubit indices the gate acts on. Supported values are: - length 1 for single-qubit gates, - length 2 for two-qubit gates. Any other length raises a ``ValueError``. :type qubits: list[int] :param params: List of gate parameters. Use an empty list for non-parametrized gates. For parameterized gates, the number of parameters must match the gate definition (e.g. one parameter for ``rx``, three for ``u3``). :type params: list[float] :raises ValueError: If the number of qubits is not supported (i.e. not 1 or 2). :raises AttributeError: If the gate label does not correspond to a qiskit gate. .. rubric:: Notes - Qubit index bounds are not checked and must be valid for the circuit. .. rubric:: Examples Apply a single-qubit rotation: >>> apply_gate_qiskit(qc, "RX", [0], [np.pi / 2]) Apply a controlled-NOT gate: >>> apply_gate_qiskit(qc, "cnot", [0, 1], []) Apply a two-qubit parameterized gate: >>> apply_gate_qiskit(qc, "rxx", [0, 1], [0.3]) .. py:function:: deserialize_to_qiskit_QuantumCircuit(full_gate_dict, *, max_depth=np.inf, measure=False) Deserialize a gate dictionary into a ``qiskit`` :qiskit-api:`QuantumCircuit`. This function reconstructs a :qiskit-api:`QuantumCircuit` from a serialized gate representation, where gates are annotated with qubit indices, parameters, and a discrete circuit ``round`` (layer index). Gates are applied in the order they appear in ``full_gate_dict["gates"]``, subject to an optional depth cutoff. :param full_gate_dict: Dictionary encoding the quantum circuit. It must contain: - ``"n_qubits"`` : int Total number of qubits in the circuit. - ``"gates"`` : list[dict] List of gate specifications. Each gate dictionary must contain: - ``"name"`` : str Gate label (passed to :func:`apply_gate_qiskit`). - ``"qubits"`` : list[int] Target qubit indices. - ``"params"`` : list[float] Gate parameters (empty for non-parameterized gates). - ``"round"`` : int Layer index at which the gate is applied. :type full_gate_dict: dict :param max_depth: Maximum circuit depth (number of rounds) to load. Only gates with ``gate["round"] < max_depth`` are applied. If ``inf`` (default), the full circuit is reconstructed. :type max_depth: int or inf, optional :param measure: If ``True``, a classical register of size ``n_qubits`` is added and all qubits are measured at the end of the circuit. Default is ``False``. :type measure: bool, optional :returns: **qc** -- The reconstructed ``qiskit`` quantum circuit. :rtype: :qiskit-api:`QuantumCircuit` :raises KeyError: If required keys are missing from ``full_gate_dict`` or its gate entries. :raises ValueError: If invalid gate specifications are encountered during deserialization (propagated from :func:`apply_gate_qiskit`). .. rubric:: Notes - Gate ordering within the same round is preserved as given in the input. - No validation is performed on qubit index bounds. - Parameter consistency is delegated to :func:`apply_gate_qiskit` and ``qiskit``. .. py:function:: serialize_from_quimb_Circuit(qc) Serialize a ``quimb`` circuit into a ``JSON``-compatible dictionary. This function converts a :quimb-api:`Circuit` object into a plain ``python`` dictionary containing only ``JSON``-serializable types. The resulting dictionary can be safely stored, transmitted, or deserialized into other circuit representations (e.g. ``qiskit``). :param qc: The ``quimb`` circuit to be serialized. :type qc: :quimb-api:`Circuit` :returns: Dictionary representation of the circuit with the following keys: - ``"n_qubits"`` : int Number of qubits in the circuit. - ``"gates"`` : list of dict Ordered list of gate specifications. Each gate dictionary contains: - ``"name"`` : str Gate label as used by ``quimb``. - ``"qubits"`` : list of int Target qubit indices. - ``"controls"``: list Control qubits' indices. - ``"params"`` : list of float Gate parameters (rounded to 4 decimal places). - ``"round"`` : int Circuit round (layer index) in which the gate appears. :rtype: dict .. seealso:: :py:obj:`deserialize_to_quimb_Circuit` Reconstruct a ``quimb`` :quimb-api:`Circuit` from the serialized dictionary. :py:obj:`deserialize_to_qiskit_QuantumCircuit` Reconstruct a ``qiskit`` :qiskit-api:`QuantumCircuit` from the serialized dictionary. .. rubric:: Notes - All numerical values are explicitly cast to built-in ``python`` types (``int`` and ``float``) to ensure ``JSON`` compatibility. - The ordering of gates in ``qc.gates`` is preserved, allowing faithful reconstruction of the circuit. - The output format is designed to be compatible with downstream deserialization into other frameworks (e.g. ``qiskit``). .. py:function:: serialize_from_quimb_gates(n_qubits, gates_list) Serialize a list of ``quimb`` gates into a ``JSON``-compatible dictionary. This function converts a list of :quimb-api:`Gate` objects into a plain ``python`` dictionary containing only ``JSON``-serializable types. The resulting dictionary can be safely stored, transmitted, or deserialized into other circuit representations (e.g. ``qiskit``). :param n_qubits: Total number of qubits in the circuit. :type n_qubits: int :param gates_list: The list of ``quimb`` gates to be serialized. :type gates_list: list :returns: Dictionary representation of the circuit with the following keys: - ``"n_qubits"`` : int Number of qubits in the circuit. - ``"gates"`` : list of dict Ordered list of gate specifications. Each gate dictionary contains: - ``"name"`` : str Gate label as used by ``quimb``. - ``"qubits"`` : list of int Target qubit indices. - ``"controls"``: list Control qubits' indices. - ``"params"`` : list of float Gate parameters (rounded to 4 decimal places). - ``"round"`` : int Circuit round (layer index) in which the gate appears. :rtype: dict .. seealso:: :py:obj:`deserialize_to_quimb_Circuit` Reconstruct a ``quimb`` :quimb-api:`Circuit` from the serialized dictionary. :py:obj:`deserialize_to_qiskit_QuantumCircuit` Reconstruct a ``qiskit`` :qiskit-api:`QuantumCircuit` from the serialized dictionary. .. rubric:: Notes - All numerical values are explicitly cast to built-in ``python`` types (``int`` and ``float``) to ensure ``JSON`` compatibility. - The ordering of gates is preserved, allowing faithful reconstruction of the circuit. - The output format is designed to be compatible with downstream deserialization into other frameworks (e.g. ``qiskit``). .. py:function:: deserialize_to_quimb_Circuit(full_gate_dict, *, max_depth=np.inf, contract=False, **gate_opts) Deserialize a gate dictionary into a :quimb-api:`Circuit` up to a given depth. This function reconstructs a circuit from a serialized representation of a quantum circuit (i.e. the one that can be saved as JSON). Only gates whose ``round`` index is strictly smaller than ``max_depth`` are included, allowing for partial reconstruction of the circuit. :param full_gate_dict: Serialized circuit description. Must contain the following keys: - ``"n_qubits"`` : int or str Total number of qubits in the circuit. - ``"gates"`` : list of dict List of gate specifications. Each gate dictionary must contain: - ``"name"`` : str Gate identifier understood by :quimb-api:`Circuit.apply_gate`. - ``"params"`` : list Gate parameters (will be cast to ``float``). - ``"qubits"`` : list Qubit indices the gate acts on. - ``"controls"``: list Control qubits' indices. - ``"round"`` : int or str Layer / round index of the gate. :type full_gate_dict: dict :param max_depth: Maximum circuit depth to deserialize, i.e. if ``round >= depth`` the gate is ignored. Default is inf, the full circuit is deserialized. :type max_depth: int or inf, optional :param contract: Whether to contract the quimb Circuit. Default is False. :type contract: bool, optional :param \*\*gate_opts: Additional keyword arguments forwarded to :quimb-api:`Circuit.apply_gate`. Override any default gate options. :type \*\*gate_opts: dict :returns: **qc** -- A ``quimb`` circuit instance containing all gates up to the specified depth. :rtype: :quimb-api:`Circuit` .. rubric:: Notes - If the circuit is deserialized for plotting purposes, set ``contract=False``. - This function assumes the serialized gate names and parameters are compatible with :quimb-api:`Circuit.apply_gate`. - Useful when assessing the complexity of a circuit and its contraction layer-by-layer. .. py:function:: deserialize_to_quimb_CircuitMPS(full_gate_dict, max_bond, cutoff, *, max_depth=np.inf, perm=False, psi0=None) Deserialize a gate dictionary into a :quimb-api:`CircuitMPS` or :quimb-api:`CircuitPermMPS`. Accepts the same serialized format as saved in JSON. Only gates whose ``round`` index is strictly smaller than ``max_depth`` are applied, allowing for partial reconstruction of the circuit. :param full_gate_dict: Serialized circuit description. Must contain the following keys: - ``"n_qubits"`` : int or str Total number of qubits in the circuit. - ``"gates"`` : list List of gate specifications. Each gate dictionary must contain: - ``"name"`` : str Gate identifier understood by :quimb-api:`CircuitMPS.apply_gate` - ``"params"`` : list Gate parameters (will be cast to float). - ``"qubits"`` : list Qubit indices the gate acts on. - ``"controls"``: list Control qubits' indices. - ``"round"`` : int or str Layer/depth index of the gate. :type full_gate_dict: dict :param max_bond: Maximum bond dimension of the MPS. :type max_bond: int :param cutoff: Truncation cutoff for singular values when applying gates to the MPS. :type cutoff: float :param max_depth: Maximum circuit depth to deserialize, i.e. if ``round >= max_depth`` the gate is ignored. Default is inf, the full circuit is deserialized. :type max_depth: int or inf, optional :param perm: If ``True``, use :quimb-api:`CircuitPermMPS` instead of :quimb-api:`CircuitMPS`. Default is False. :type perm: bool, optional :param psi0: Initial MPS state. If ``None``, the all-zeros computational basis state is used. Default is None. :type psi0: :quimb-api:`MatrixProductState` or None, optional :returns: **cmps** -- An MPS representation of the reconstructed circuit containing all gates contracted up to the specified depth. :rtype: :quimb-api:`CircuitMPS` or :quimb-api:`CircuitPermMPS` .. py:function:: dump_quimb_Circuit_to_qasm(circ, savefile_base, *, save_rounds=True) Export a ``quimb`` circuit to an ``OpenQASM 2.0`` file. This function serializes a :quimb-api:`Circuit` into a QASM 2.0-compatible text file. Optionally, the circuit round (layer index) of each gate is stored in a separate sidecar file. :param circ: The ``quimb`` circuit to export. :type circ: :quimb-api:`Circuit` :param savefile_base: Base filename (without extension) for the output files. The function writes: - ``.qasm`` - ``_rounds.txt`` (if ``save_rounds=True``) :type savefile_base: str :param save_rounds: If ``True`` (default), write the circuit round of each gate to a separate text file, with one integer per line. :type save_rounds: bool, optional :raises ValueError: If a gate label is encountered that cannot be mapped to a supported OpenQASM 2.0 instruction. .. rubric:: Notes - Gate labels are converted to lowercase for QASM compatibility. - The gate label ``"cnot"`` is automatically mapped to ``"cx"``, which is the canonical OpenQASM name. - Gate parameters are converted to native Python ``float`` and formatted with limited precision to ensure portability. - Circuit round information is *not* part of the QASM standard and is therefore stored separately. .. py:function:: load_qasm_to_quimb_Circuit(filename, *, with_rounds=False, max_depth=np.inf, gate_contract=False, min_layout=False) Parse a QASM 2.0 file and reconstruct a :quimb-api:`Circuit`. Optionally, this function can restore circuit round (layer) information from a sidecar file and load only a truncated circuit depth. :param filename: Base filename (without extension) of the QASM file to load. :type filename: str :param with_rounds: If ``True``, load circuit round information from ``filename_rounds.txt`` and assign gates using ``gate_round``. Default is ``False``. :type with_rounds: bool, optional :param max_depth: Maximum circuit depth to load. Gates with ``gate_round >= max_depth`` are ignored. Default is inf, the full circuit is loaded. :type max_depth: int or inf, optional :param gate_contract: Whether to immediately contract gates into the tensor network when applying them. Passed directly to ``circ.apply_gate``. Default is ``False``. :type gate_contract: bool, optional :param min_layout: If ``True``, infer the number of qubits from the maximum qubit index appearing in the gates. If ``False`` (default), read the register size from the QASM header. :type min_layout: bool, optional :returns: **circ** -- The reconstructed quimb circuit. :rtype: :quimb-api:`Circuit` .. rubric:: Notes - The QASM file is parsed using ``parse_openqasm2_file``. - When ``with_rounds=False``, circuit round information is ignored and gates are loaded in sequential order. - When ``with_rounds=True``, a sidecar file ``_rounds.txt`` must exist and contain one integer per gate. - This function assumes that the QASM file uses gate labels compatible with quimb.