Código fuente para qiskit.synthesis.stabilizer.stabilizer_decompose

# This code is part of Qiskit.
#
# (C) Copyright IBM 2023.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.
"""
Circuit synthesis for a stabilizer state preparation circuit.
"""
# pylint: disable=invalid-name

import numpy as np
from qiskit.circuit import QuantumCircuit
from qiskit.exceptions import QiskitError
from qiskit.quantum_info.states import StabilizerState
from qiskit.synthesis.linear.linear_matrix_utils import (
    calc_inverse_matrix,
)
from qiskit.synthesis.linear_phase import synth_cz_depth_line_mr
from qiskit.synthesis.clifford.clifford_decompose_layers import (
    _default_cz_synth_func,
    _reverse_clifford,
    _create_graph_state,
    _decompose_graph_state,
)


[documentos]def synth_stabilizer_layers( stab, cz_synth_func=_default_cz_synth_func, cz_func_reverse_qubits=False, validate=False, ): """Synthesis of a stabilizer state into layers. It provides a similar decomposition to the synthesis described in Lemma 8 of Bravyi and Maslov, without the initial Hadamard-free sub-circuit which do not affect the stabilizer state. For example, a 5-qubit stabilizer state is decomposed into the following layers: .. parsed-literal:: ┌─────┐┌─────┐┌─────┐┌─────┐┌────────┐ q_0: ┤0 ├┤0 ├┤0 ├┤0 ├┤0 ├ │ ││ ││ ││ ││ │ q_1: ┤1 ├┤1 ├┤1 ├┤1 ├┤1 ├ │ ││ ││ ││ ││ │ q_2: ┤2 H2 ├┤2 S1 ├┤2 CZ ├┤2 H1 ├┤2 Pauli ├ │ ││ ││ ││ ││ │ q_3: ┤3 ├┤3 ├┤3 ├┤3 ├┤3 ├ │ ││ ││ ││ ││ │ q_4: ┤4 ├┤4 ├┤4 ├┤4 ├┤4 ├ └─────┘└─────┘└─────┘└─────┘└────────┘ Args: stab (StabilizerState): a stabilizer state. cz_synth_func (Callable): a function to decompose the CZ sub-circuit. It gets as input a boolean symmetric matrix, and outputs a QuantumCircuit. validate (Boolean): if True, validates the synthesis process. cz_func_reverse_qubits (Boolean): True only if cz_synth_func is synth_cz_depth_line_mr, since this function returns a circuit that reverts the order of qubits. Return: QuantumCircuit: a circuit implementation of the stabilizer state. Raises: QiskitError: if the input is not a StabilizerState. Reference: 1. S. Bravyi, D. Maslov, *Hadamard-free circuits expose the structure of the Clifford group*, `arXiv:2003.09412 [quant-ph] <https://arxiv.org/abs/2003.09412>`_ """ if not isinstance(stab, StabilizerState): raise QiskitError("The input is not a StabilizerState.") cliff = stab.clifford num_qubits = cliff.num_qubits if cz_func_reverse_qubits: cliff0 = _reverse_clifford(cliff) else: cliff0 = cliff H1_circ, cliff1 = _create_graph_state(cliff0, validate=validate) H2_circ, CZ1_circ, S1_circ, _ = _decompose_graph_state( cliff1, validate=validate, cz_synth_func=cz_synth_func ) qubit_list = list(range(num_qubits)) layeredCircuit = QuantumCircuit(num_qubits) layeredCircuit.append(H2_circ, qubit_list) layeredCircuit.append(S1_circ, qubit_list) layeredCircuit.append(CZ1_circ, qubit_list) if cz_func_reverse_qubits: H1_circ = H1_circ.reverse_bits() layeredCircuit.append(H1_circ, qubit_list) # Add Pauli layer to fix the Clifford phase signs # pylint: disable=cyclic-import from qiskit.quantum_info.operators.symplectic import Clifford clifford_target = Clifford(layeredCircuit) pauli_circ = _calc_pauli_diff_stabilizer(cliff, clifford_target) layeredCircuit.append(pauli_circ, qubit_list) return layeredCircuit
def _calc_pauli_diff_stabilizer(cliff, cliff_target): """Given two Cliffords whose stabilizers differ by a Pauli, we find this Pauli.""" # pylint: disable=cyclic-import from qiskit.quantum_info.operators.symplectic import Pauli num_qubits = cliff.num_qubits if cliff.num_qubits != cliff_target.num_qubits: raise QiskitError("num_qubits is not the same for the original clifford and the target.") # stabilizer generators of the original clifford stab_gen = StabilizerState(cliff).clifford.to_dict()["stabilizer"] # stabilizer state of the target clifford ts = StabilizerState(cliff_target) phase_destab = [False] * num_qubits phase_stab = [ts.expectation_value(Pauli(stab_gen[i])) == -1 for i in range(num_qubits)] phase = [] phase.extend(phase_destab) phase.extend(phase_stab) phase = np.array(phase, dtype=int) A = cliff.symplectic_matrix.astype(int) Ainv = calc_inverse_matrix(A) # By carefully writing how X, Y, Z gates affect each qubit, all we need to compute # is A^{-1} * (phase) C = np.matmul(Ainv, phase) % 2 # Create the Pauli pauli_circ = QuantumCircuit(num_qubits, name="Pauli") for k in range(num_qubits): destab = C[k] stab = C[k + num_qubits] if stab and destab: pauli_circ.y(k) elif stab: pauli_circ.x(k) elif destab: pauli_circ.z(k) return pauli_circ
[documentos]def synth_stabilizer_depth_lnn(stab): """Synthesis of an n-qubit stabilizer state for linear-nearest neighbour connectivity, in 2-qubit depth 2*n+2 and two distinct CX layers, using CX and phase gates (S, Sdg or Z). Args: stab (StabilizerState): a stabilizer state. Return: QuantumCircuit: a circuit implementation of the stabilizer state. Reference: 1. S. Bravyi, D. Maslov, *Hadamard-free circuits expose the structure of the Clifford group*, `arXiv:2003.09412 [quant-ph] <https://arxiv.org/abs/2003.09412>`_ 2. Dmitri Maslov, Martin Roetteler, *Shorter stabilizer circuits via Bruhat decomposition and quantum circuit transformations*, `arXiv:1705.09176 <https://arxiv.org/abs/1705.09176>`_. """ circ = synth_stabilizer_layers( stab, cz_synth_func=synth_cz_depth_line_mr, cz_func_reverse_qubits=True, ) return circ