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 (
from qiskit.synthesis.linear_phase import synth_cz_depth_line_mr
from qiskit.synthesis.clifford.clifford_decompose_layers import (

[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