From ad49a55d318ede88b362d4e03577a31ecf817350 Mon Sep 17 00:00:00 2001 From: Julien Gacon Date: Thu, 4 Jan 2024 14:25:23 +0100 Subject: [PATCH 1/7] Fully deprecate extensions --- qiskit/circuit/quantumcircuit.py | 384 ++++++------------ qiskit/circuit/random/utils.py | 2 +- qiskit/extensions/__init__.py | 9 +- .../quantum_initializer/__init__.py | 2 - qiskit/extensions/quantum_initializer/squ.py | 163 -------- qiskit/extensions/simulator/__init__.py | 15 - qiskit/extensions/simulator/snapshot.py | 70 ---- qiskit/visualization/circuit/matplotlib.py | 4 +- ...ecate-extensions-046-2b98dce6fdfadc72.yaml | 5 + .../circuit/test_circuit_load_from_qpy.py | 4 +- .../python/circuit/test_circuit_operations.py | 22 - .../python/circuit/test_circuit_properties.py | 90 ---- test/python/circuit/test_controlled_gate.py | 8 +- test/python/circuit/test_diagonal_gate.py | 6 +- test/python/circuit/test_isometry.py | 4 +- test/python/circuit/test_operation.py | 4 +- test/python/circuit/test_squ.py | 65 --- test/python/circuit/test_uc.py | 2 +- test/python/circuit/test_ucx_y_z.py | 2 +- test/python/transpiler/test_unroller.py | 10 - .../visualization/test_circuit_latex.py | 6 - .../test_latex_plot_barriers_true.tex | 13 + 22 files changed, 162 insertions(+), 728 deletions(-) delete mode 100644 qiskit/extensions/quantum_initializer/squ.py delete mode 100644 qiskit/extensions/simulator/__init__.py delete mode 100644 qiskit/extensions/simulator/snapshot.py create mode 100644 releasenotes/notes/deprecate-extensions-046-2b98dce6fdfadc72.yaml delete mode 100644 test/python/circuit/test_squ.py create mode 100644 test/python/visualization/test_latex_plot_barriers_true.tex diff --git a/qiskit/circuit/quantumcircuit.py b/qiskit/circuit/quantumcircuit.py index 0ca191b771c5..223f20157b9b 100644 --- a/qiskit/circuit/quantumcircuit.py +++ b/qiskit/circuit/quantumcircuit.py @@ -66,6 +66,7 @@ import qiskit # pylint: disable=cyclic-import from qiskit.transpiler.layout import TranspileLayout # pylint: disable=cyclic-import from qiskit.quantum_info.operators.base_operator import BaseOperator + from qiskit.quantum_info.states.statevector import Statevector # pylint: disable=cyclic-import BitLocations = namedtuple("BitLocations", ("index", "registers")) @@ -2953,23 +2954,6 @@ def ch( CHGate(label=label, ctrl_state=ctrl_state), [control_qubit, target_qubit], [] ) - @deprecate_func( - since="0.45.0", - additional_msg="Use QuantumCircuit.id as direct replacement.", - ) - def i(self, qubit: QubitSpecifier) -> InstructionSet: - """Apply :class:`~qiskit.circuit.library.IGate`. - - For the full matrix form of this gate, see the underlying gate documentation. - - Args: - qubit: The qubit(s) to apply the gate to. - - Returns: - A handle to the instructions created. - """ - return self.id(qubit) - def id(self, qubit: QubitSpecifier) -> InstructionSet: # pylint: disable=invalid-name """Apply :class:`~qiskit.circuit.library.IGate`. @@ -3554,33 +3538,6 @@ def cswap( [], ) - @deprecate_func( - since="0.45.0", - additional_msg="Use QuantumCircuit.cswap as direct replacement.", - ) - def fredkin( - self, - control_qubit: QubitSpecifier, - target_qubit1: QubitSpecifier, - target_qubit2: QubitSpecifier, - ) -> InstructionSet: - """Apply :class:`~qiskit.circuit.library.CSwapGate`. - - For the full matrix form of this gate, see the underlying gate documentation. - - Args: - control_qubit: The qubit(s) used as the control. - target_qubit1: The qubit(s) targeted by the gate. - target_qubit2: The qubit(s) targeted by the gate. - - Returns: - A handle to the instructions created. - - See Also: - QuantumCircuit.cswap: the same function with a different name. - """ - return self.cswap(control_qubit, target_qubit1, target_qubit2) - def sx(self, qubit: QubitSpecifier) -> InstructionSet: """Apply :class:`~qiskit.circuit.library.SXGate`. @@ -3778,34 +3735,6 @@ def cx( CXGate(label=label, ctrl_state=ctrl_state), [control_qubit, target_qubit], [] ) - @deprecate_func(since="0.45.0", additional_msg="Use QuantumCircuit.cx as direct replacement.") - def cnot( - self, - control_qubit: QubitSpecifier, - target_qubit: QubitSpecifier, - label: str | None = None, - ctrl_state: str | int | None = None, - ) -> InstructionSet: - r"""Apply :class:`~qiskit.circuit.library.CXGate`. - - For the full matrix form of this gate, see the underlying gate documentation. - - Args: - control_qubit: The qubit(s) used as the control. - target_qubit: The qubit(s) targeted by the gate. - label: The string label of the gate in the circuit. - ctrl_state: - The control state in decimal, or as a bitstring (e.g. '1'). Defaults to controlling - on the '1' state. - - Returns: - A handle to the instructions created. - - See Also: - QuantumCircuit.cx: the same function with a different name. - """ - return self.cx(control_qubit, target_qubit, label, ctrl_state) - def dcx(self, qubit1: QubitSpecifier, qubit2: QubitSpecifier) -> InstructionSet: r"""Apply :class:`~qiskit.circuit.library.DCXGate`. @@ -3852,30 +3781,6 @@ def ccx( [], ) - @deprecate_func(since="0.45.0", additional_msg="Use QuantumCircuit.ccx as direct replacement.") - def toffoli( - self, - control_qubit1: QubitSpecifier, - control_qubit2: QubitSpecifier, - target_qubit: QubitSpecifier, - ) -> InstructionSet: - r"""Apply :class:`~qiskit.circuit.library.CCXGate`. - - For the full matrix form of this gate, see the underlying gate documentation. - - Args: - control_qubit1: The qubit(s) used as the first control. - control_qubit2: The qubit(s) used as the second control. - target_qubit: The qubit(s) targeted by the gate. - - Returns: - A handle to the instructions created. - - See Also: - QuantumCircuit.ccx: the same gate with a different name. - """ - return self.ccx(control_qubit1, control_qubit2, target_qubit) - def mcx( self, control_qubits: Sequence[QubitSpecifier], @@ -3954,44 +3859,6 @@ def mcx( return self.append(gate, control_qubits[:] + [target_qubit] + ancilla_qubits[:], []) - @deprecate_func(since="0.45.0", additional_msg="Use QuantumCircuit.mcx as direct replacement.") - def mct( - self, - control_qubits: Sequence[QubitSpecifier], - target_qubit: QubitSpecifier, - ancilla_qubits: QubitSpecifier | Sequence[QubitSpecifier] | None = None, - mode: str = "noancilla", - ) -> InstructionSet: - """Apply :class:`~qiskit.circuit.library.MCXGate`. - - The multi-cX gate can be implemented using different techniques, which use different numbers - of ancilla qubits and have varying circuit depth. These modes are: - - - ``'noancilla'``: Requires 0 ancilla qubits. - - ``'recursion'``: Requires 1 ancilla qubit if more than 4 controls are used, otherwise 0. - - ``'v-chain'``: Requires 2 less ancillas than the number of control qubits. - - ``'v-chain-dirty'``: Same as for the clean ancillas (but the circuit will be longer). - - For the full matrix form of this gate, see the underlying gate documentation. - - Args: - control_qubits: The qubits used as the controls. - target_qubit: The qubit(s) targeted by the gate. - ancilla_qubits: The qubits used as the ancillae, if the mode requires them. - mode: The choice of mode, explained further above. - - Returns: - A handle to the instructions created. - - Raises: - ValueError: if the given mode is not known, or if too few ancilla qubits are passed. - AttributeError: if no ancilla qubits are passed, but some are needed. - - See Also: - QuantumCircuit.mcx: the same gate with a different name. - """ - return self.mcx(control_qubits, target_qubit, ancilla_qubits, mode) - def y(self, qubit: QubitSpecifier) -> InstructionSet: r"""Apply :class:`~qiskit.circuit.library.YGate`. @@ -4128,6 +3995,121 @@ def pauli( return self.append(PauliGate(pauli_string), qubits, []) + def prepare_state( + self, + state: Statevector | Sequence[complex] | str | int, + qubits: Sequence[QubitSpecifier] | None = None, + label: str | None = None, + normalize: bool = False, + ) -> InstructionSet: + r"""Prepare qubits in a specific state. + + This class implements a state preparing unitary. Unlike + :meth:`.initialize` it does not reset the qubits first. + + Args: + state: + * Statevector: Statevector to initialize to. + * list: vector of complex amplitudes to initialize to. + * str: 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`. + * int: 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`. + + qubits: + * QuantumRegister: A list of qubits to be initialized [Default: None]. + * Qubit: Single qubit to be initialized [Default: None]. + * int: Index of qubit to be initialized [Default: None]. + * list: Indexes of qubits to be initialized [Default: None]. + label: An optional label for the gate + normalize: Whether to normalize an input array to a unit vector. + + Returns: + A handle to the instruction that was just initialized + + Examples: + Prepare a qubit in the state :math:`(|0\rangle - |1\rangle) / \sqrt{2}`. + + .. code-block:: + + import numpy as np + from qiskit import QuantumCircuit + + circuit = QuantumCircuit(1) + circuit.prepare_state([1/np.sqrt(2), -1/np.sqrt(2)], 0) + circuit.draw() + + output: + + .. parsed-literal:: + + ┌─────────────────────────────────────┐ + q_0: ┤ State Preparation(0.70711,-0.70711) ├ + └─────────────────────────────────────┘ + + + Prepare 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`. + + .. code-block:: + + import numpy as np + from qiskit import QuantumCircuit + + circuit = QuantumCircuit(2) + circuit.prepare_state('01', circuit.qubits) + circuit.draw() + + output: + + .. parsed-literal:: + + ┌─────────────────────────┐ + q_0: ┤0 ├ + │ State Preparation(0,1) │ + q_1: ┤1 ├ + └─────────────────────────┘ + + + Initialize two qubits from an array of complex amplitudes + .. code-block:: + + import numpy as np + from qiskit import QuantumCircuit + + circuit = QuantumCircuit(2) + circuit.prepare_state([0, 1/np.sqrt(2), -1.j/np.sqrt(2), 0], circuit.qubits) + circuit.draw() + + output: + + .. parsed-literal:: + + ┌───────────────────────────────────────────┐ + q_0: ┤0 ├ + │ State Preparation(0,0.70711,-0.70711j,0) │ + q_1: ┤1 ├ + └───────────────────────────────────────────┘ + """ + # pylint: disable=cyclic-import + from qiskit.circuit.library.data_preparation import StatePreparation + + if qubits is None: + qubits = self.qubits + elif isinstance(qubits, (int, np.integer, slice, Qubit)): + qubits = [qubits] + + num_qubits = len(qubits) if isinstance(state, int) else None + + return self.append( + StatePreparation(state, num_qubits, label=label, normalize=normalize), qubits + ) + def initialize( self, params: Sequence[complex] | str | int, @@ -4137,10 +4119,10 @@ def initialize( r"""Initialize qubits in a specific state. Qubit initialization is done by first resetting the qubits to :math:`|0\rangle` - followed by calling :class:`qiskit.extensions.StatePreparation` + 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.extensions.Initialize` instruction. + :class:`~qiskit.circuit.library.Initialize` instruction. Args: params: The state to initialize to, can be either of the following. @@ -4283,9 +4265,8 @@ def unitary( return self.append(gate, qubits, []) @deprecate_func( - since="0.45.0", + since="0.46.0", additional_msg="Instead, compose the circuit with a qiskit.circuit.library.Diagonal circuit.", - pending=True, ) def diagonal(self, diag, qubit): """Attach a diagonal gate to a circuit. @@ -4332,9 +4313,8 @@ def diagonal(self, diag, qubit): return self.append(DiagonalGate(diag), qubit) @deprecate_func( - since="0.45.0", + since="0.46.0", additional_msg="Instead, append a qiskit.circuit.library.Isometry to the circuit.", - pending=True, ) def iso( self, @@ -4402,9 +4382,8 @@ def iso( ) @deprecate_func( - since="0.45.0", + since="0.46.0", additional_msg="Instead, append a qiskit.circuit.library.HamiltonianGate to the circuit.", - pending=True, ) def hamiltonian(self, operator, time, qubits, label=None): """Apply hamiltonian evolution to qubits. @@ -4432,9 +4411,8 @@ def hamiltonian(self, operator, time, qubits, label=None): return self.append(HamiltonianGate(data=operator, time=time, label=label), qubits, []) @deprecate_func( - since="0.45.0", + since="0.46.0", additional_msg="Instead, append a qiskit.circuit.library.UCGate to the circuit.", - pending=True, ) def uc(self, gate_list, q_controls, q_target, up_to_diagonal=False): """Attach a uniformly controlled gates (also called multiplexed gates) to a circuit. @@ -4500,9 +4478,8 @@ def uc(self, gate_list, q_controls, q_target, up_to_diagonal=False): return self.append(UCGate(gate_list, up_to_diagonal), [q_target] + q_controls) @deprecate_func( - since="0.45.0", + since="0.46.0", additional_msg="Instead, append a qiskit.circuit.library.UCRXGate to the circuit.", - pending=True, ) def ucrx( self, @@ -4561,9 +4538,8 @@ def ucrx( return self.append(UCRXGate(angle_list), [q_target] + q_controls, []) @deprecate_func( - since="0.45.0", + since="0.46.0", additional_msg="Instead, append a qiskit.circuit.library.UCRYGate to the circuit.", - pending=True, ) def ucry( self, @@ -4622,9 +4598,8 @@ def ucry( return self.append(UCRYGate(angle_list), [q_target] + q_controls, []) @deprecate_func( - since="0.45.0", + since="0.46.0", additional_msg="Instead, append a qiskit.circuit.library.UCRZGate to the circuit.", - pending=True, ) def ucrz( self, @@ -4682,115 +4657,6 @@ def ucrz( ) return self.append(UCRZGate(angle_list), [q_target] + q_controls, []) - @deprecate_func( - since="0.45.0", additional_msg="Instead, use the QuantumCircuit.unitary method." - ) - def squ( - self, - unitary_matrix, - qubit, - mode="ZYZ", - up_to_diagonal=False, - ): - """Decompose an arbitrary 2*2 unitary into three rotation gates. - - Note that the decomposition is up to a global phase shift. - (This is a well known decomposition which can be found for example in Nielsen and Chuang's book - "Quantum computation and quantum information".) - - Args: - unitary_matrix (ndarray): 2*2 unitary (given as a (complex) ndarray). - qubit (QuantumRegister or Qubit): The qubit which the gate is acting on. - mode (string): determines the used decomposition by providing the rotation axes. - The allowed modes are: "ZYZ" (default) - up_to_diagonal (bool): if set to True, the single-qubit unitary is decomposed up to - a diagonal matrix, i.e. a unitary u' is implemented such that there exists a 2*2 - diagonal gate d with u = d.dot(u') - - Returns: - InstructionSet: The single-qubit unitary instruction attached to the circuit. - - Raises: - QiskitError: if the format is wrong; if the array u is not unitary - """ - # pylint: disable=cyclic-import - from qiskit.extensions.quantum_initializer.squ import SingleQubitUnitary - - if isinstance(qubit, QuantumRegister): - qubit = qubit[:] - if len(qubit) == 1: - qubit = qubit[0] - else: - raise QiskitError( - "The target qubit is a QuantumRegister containing more than one qubit." - ) - # Check if there is one target qubit provided - if not isinstance(qubit, Qubit): - raise QiskitError("The target qubit is not a single qubit from a QuantumRegister.") - - with warnings.catch_warnings(): - warnings.simplefilter("ignore", category=DeprecationWarning) - squ = SingleQubitUnitary(unitary_matrix, mode, up_to_diagonal) - - return self.append(squ, [qubit], []) - - @deprecate_func( - since="0.45.0", - additional_msg="The Snapshot instruction has been superseded by Qiskit Aer's save " - "instructions, see " - "https://qiskit.org/ecosystem/aer/apidocs/aer_library.html#saving-simulator-data.", - ) - def snapshot(self, label, snapshot_type="statevector", qubits=None, params=None): - """Take a statevector snapshot of the internal simulator representation. - Works on all qubits, and prevents reordering (like barrier). - - For other types of snapshots use the Snapshot extension directly. - - Args: - label (str): a snapshot label to report the result. - snapshot_type (str): the type of the snapshot. - qubits (list or None): the qubits to apply snapshot to [Default: None]. - params (list or None): the parameters for snapshot_type [Default: None]. - - Returns: - QuantumCircuit: with attached command - - Raises: - ExtensionError: malformed command - """ - # pylint: disable-cyclic-import - from qiskit.extensions.simulator.snapshot import Snapshot - from qiskit.extensions.exceptions import ExtensionError - - # If no qubits are specified we add all qubits so it acts as a barrier - # This is needed for full register snapshots like statevector - if isinstance(qubits, QuantumRegister): - qubits = qubits[:] - if not qubits: - tuples = [] - if isinstance(self, QuantumCircuit): - for register in self.qregs: - tuples.append(register) - if not tuples: - raise ExtensionError("no qubits for snapshot") - qubits = [] - for tuple_element in tuples: - if isinstance(tuple_element, QuantumRegister): - for j in range(tuple_element.size): - qubits.append(tuple_element[j]) - else: - qubits.append(tuple_element) - - # catch deprecation warning from instantiating the Snapshot instruction, - # as a warning is already triggered from this method - with warnings.catch_warnings(): - warnings.simplefilter("ignore", category=DeprecationWarning) - snap = Snapshot( - label, snapshot_type=snapshot_type, num_qubits=len(qubits), params=params - ) - - return self.append(snap, qubits) - def _push_scope( self, qubits: Iterable[Qubit] = (), diff --git a/qiskit/circuit/random/utils.py b/qiskit/circuit/random/utils.py index d8c863a81d6f..71809735aa8e 100644 --- a/qiskit/circuit/random/utils.py +++ b/qiskit/circuit/random/utils.py @@ -26,7 +26,7 @@ def random_circuit( """Generate random circuit of arbitrary size and form. This function will generate a random circuit by randomly selecting gates - from the set of standard gates in :mod:`qiskit.extensions`. For example: + from the set of standard gates in :mod:`qiskit.circuit.library.standard_gates`. For example: .. plot:: :include-source: diff --git a/qiskit/extensions/__init__.py b/qiskit/extensions/__init__.py index d0685f0a0d03..71ca9db57d27 100644 --- a/qiskit/extensions/__init__.py +++ b/qiskit/extensions/__init__.py @@ -53,18 +53,15 @@ from .exceptions import ExtensionError from .quantum_initializer import ( Initialize, - SingleQubitUnitary, UCPauliRotGate, UCRXGate, UCRYGate, UCRZGate, ) -from .simulator import Snapshot - warnings.warn( - "The qiskit.extensions module is pending deprecation since Qiskit 0.45.0. It will be deprecated " - "in a following release, no sooner than 3 months after the 0.45.0 release.", + "The qiskit.extensions module is deprecated since Qiskit 0.46.0. It will be deprecated " + "in a following release, no sooner than 3 months after the 0.46.0 release.", stacklevel=2, - category=PendingDeprecationWarning, + category=DeprecationWarning, ) diff --git a/qiskit/extensions/quantum_initializer/__init__.py b/qiskit/extensions/quantum_initializer/__init__.py index 27f24443bd02..640c781a4bfb 100644 --- a/qiskit/extensions/quantum_initializer/__init__.py +++ b/qiskit/extensions/quantum_initializer/__init__.py @@ -22,5 +22,3 @@ Isometry, Initialize, ) - -from .squ import SingleQubitUnitary diff --git a/qiskit/extensions/quantum_initializer/squ.py b/qiskit/extensions/quantum_initializer/squ.py deleted file mode 100644 index 8356dc86fb9f..000000000000 --- a/qiskit/extensions/quantum_initializer/squ.py +++ /dev/null @@ -1,163 +0,0 @@ -# This code is part of Qiskit. -# -# (C) Copyright IBM 2017, 2019. -# -# 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. - -"""Decompose an arbitrary 2*2 unitary into three rotation gates: U=R_zR_yR_z. - -Note that the decomposition is up to a global phase shift. -(This is a well known decomposition, which can be found for example in Nielsen and Chuang's book -"Quantum computation and quantum information".) -""" - -import cmath - -import numpy as np - -from qiskit.circuit import QuantumRegister, QuantumCircuit -from qiskit.circuit.gate import Gate -from qiskit.circuit.exceptions import CircuitError -from qiskit.quantum_info.operators.predicates import is_unitary_matrix -from qiskit.exceptions import QiskitError -from qiskit.utils.deprecation import deprecate_func - -_EPS = 1e-10 # global variable used to chop very small numbers to zero - - -class SingleQubitUnitary(Gate): - """Single-qubit unitary. - - Args: - unitary_matrix: :math:`2 \times 2` unitary (given as a (complex) ``numpy.ndarray``). - mode: determines the used decomposition by providing the rotation axes. - up_to_diagonal: the single-qubit unitary is decomposed up to a diagonal matrix, - i.e. a unitary :math:`U'` is implemented such that there exists a diagonal - matrix :math:`D` with :math:`U = D U'`. - """ - - @deprecate_func( - since="0.45.0", - additional_msg="Instead, you can use qiskit.circuit.library.UnitaryGate.", - ) - def __init__(self, unitary_matrix, mode="ZYZ", up_to_diagonal=False): - """Create a new single qubit gate based on the unitary ``u``.""" - if mode not in ["ZYZ"]: - raise QiskitError("The decomposition mode is not known.") - # Check if the matrix u has the right dimensions and if it is a unitary - if unitary_matrix.shape != (2, 2): - raise QiskitError("The dimension of the input matrix is not equal to (2,2).") - if not is_unitary_matrix(unitary_matrix): - raise QiskitError("The 2*2 matrix is not unitary.") - - self.mode = mode - self.up_to_diagonal = up_to_diagonal - self._diag = None - - # Create new gate - super().__init__("squ", 1, [unitary_matrix]) - - def inverse(self): - """Return the inverse. - - Note that the resulting gate has an empty ``params`` property. - """ - inverse_gate = Gate( - name=self.name + "_dg", num_qubits=self.num_qubits, params=[] - ) # removing the params because arrays are deprecated - - definition = QuantumCircuit(*self.definition.qregs) - for inst in reversed(self._definition): - definition._append(inst.replace(operation=inst.operation.inverse())) - inverse_gate.definition = definition - return inverse_gate - - @property - def diag(self): - """Returns the diagonal gate D up to which the single-qubit unitary u is implemented. - - I.e. u=D.u', where u' is the unitary implemented by the found circuit. - """ - if self._diag is None: - self._define() - return self._diag - - def _define(self): - """Define the gate using the decomposition.""" - - if self.mode == "ZYZ": - circuit, diag = self._zyz_circuit() - else: - raise QiskitError("The decomposition mode is not known.") - - self._diag = diag - - self.definition = circuit - - def _zyz_circuit(self): - """Get the circuit for the ZYZ decomposition.""" - q = QuantumRegister(self.num_qubits) - qc = QuantumCircuit(q, name=self.name) - - diag = [1.0, 1.0] - alpha, beta, gamma, _ = self._zyz_dec() - - if abs(alpha) > _EPS: - qc.rz(alpha, q[0]) - if abs(beta) > _EPS: - qc.ry(beta, q[0]) - if abs(gamma) > _EPS: - if self.up_to_diagonal: - diag = [np.exp(-1j * gamma / 2.0), np.exp(1j * gamma / 2.0)] - else: - qc.rz(gamma, q[0]) - - return qc, diag - - def _zyz_dec(self): - """Finds rotation angles (a,b,c,d) in the decomposition u=exp(id)*Rz(c).Ry(b).Rz(a). - - Note that where "." denotes matrix multiplication. - """ - unitary = self.params[0] - u00 = unitary.item(0, 0) - u01 = unitary.item(0, 1) - u10 = unitary.item(1, 0) - u11 = unitary.item(1, 1) - # Handle special case if the entry (0,0) of the unitary is equal to zero - if np.abs(u00) < _EPS: - # Note that u10 can't be zero, since u is unitary (and u00 == 0) - gamma = cmath.phase(-u01 / u10) - delta = cmath.phase(u01 * np.exp(-1j * gamma / 2)) - return 0.0, -np.pi, -gamma, delta - # Handle special case if the entry (0,1) of the unitary is equal to zero - if np.abs(u01) < _EPS: - # Note that u11 can't be zero, since u is unitary (and u01 == 0) - gamma = cmath.phase(u00 / u11) - delta = cmath.phase(u00 * np.exp(-1j * gamma / 2)) - return 0.0, 0.0, -gamma, delta - beta = 2 * np.arccos(np.abs(u00)) - if np.sin(beta / 2) - np.cos(beta / 2) > 0: - gamma = cmath.phase(-u00 / u10) - alpha = cmath.phase(u00 / u01) - else: - gamma = -cmath.phase(-u10 / u00) - alpha = -cmath.phase(u01 / u00) - delta = cmath.phase(u00 * np.exp(-1j * (alpha + gamma) / 2)) - # The decomposition works with another convention for the rotation gates - # (the one using negative angles). - # Therefore, we have to take the inverse of the angles at the end. - return -alpha, -beta, -gamma, delta - - def validate_parameter(self, parameter): - """Single-qubit unitary gate parameter has to be an ndarray.""" - if isinstance(parameter, np.ndarray): - return parameter - else: - raise CircuitError(f"invalid param type {type(parameter)} in gate {self.name}") diff --git a/qiskit/extensions/simulator/__init__.py b/qiskit/extensions/simulator/__init__.py deleted file mode 100644 index 069ec393979e..000000000000 --- a/qiskit/extensions/simulator/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# This code is part of Qiskit. -# -# (C) Copyright IBM 2017. -# -# 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. - -"""Instructions usable by simulator backends.""" - -from .snapshot import Snapshot diff --git a/qiskit/extensions/simulator/snapshot.py b/qiskit/extensions/simulator/snapshot.py deleted file mode 100644 index ca45e56354ac..000000000000 --- a/qiskit/extensions/simulator/snapshot.py +++ /dev/null @@ -1,70 +0,0 @@ -# This code is part of Qiskit. -# -# (C) Copyright IBM 2017. -# -# 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. -""" -Simulator command to snapshot internal simulator representation. -""" - -from qiskit.circuit.instruction import Instruction -from qiskit.extensions.exceptions import QiskitError, ExtensionError - -from qiskit.utils.deprecation import deprecate_func - - -class Snapshot(Instruction): - """Simulator snapshot instruction.""" - - _directive = True - - @deprecate_func( - since="0.45.0", - additional_msg="The Snapshot instruction has been superseded by Qiskit Aer's save " - "instructions, see " - "https://qiskit.org/ecosystem/aer/apidocs/aer_library.html#saving-simulator-data.", - ) - def __init__(self, label, snapshot_type="statevector", num_qubits=0, num_clbits=0, params=None): - """Create new snapshot instruction. - - Args: - label (str): the snapshot label for result data. - snapshot_type (str): the type of the snapshot. - num_qubits (int): the number of qubits for the snapshot type [Default: 0]. - num_clbits (int): the number of classical bits for the snapshot type - [Default: 0]. - params (list or None): the parameters for snapshot_type [Default: None]. - - Raises: - ExtensionError: if snapshot label is invalid. - """ - if not isinstance(label, str): - raise ExtensionError("Snapshot label must be a string.") - self._snapshot_type = snapshot_type - if params is None: - params = [] - super().__init__("snapshot", num_qubits, num_clbits, params, label=label) - - def assemble(self): - """Assemble a QasmQobjInstruction""" - instruction = super().assemble() - instruction.snapshot_type = self._snapshot_type - return instruction - - def inverse(self): - """Special case. Return self.""" - return Snapshot(self.num_qubits, self.num_clbits, self.params[0], self.params[1]) - - @property - def snapshot_type(self): - """Return snapshot type""" - return self._snapshot_type - - def c_if(self, classical, val): - raise QiskitError("Snapshots are simulator directives and cannot be conditional.") diff --git a/qiskit/visualization/circuit/matplotlib.py b/qiskit/visualization/circuit/matplotlib.py index f46561c6ed94..7d12d4fb0bd6 100644 --- a/qiskit/visualization/circuit/matplotlib.py +++ b/qiskit/visualization/circuit/matplotlib.py @@ -36,6 +36,7 @@ ) from qiskit.circuit.controlflow import condition_resources from qiskit.circuit.classical import expr +from qiskit.circuit.library import Initialize from qiskit.circuit.library.standard_gates import ( SwapGate, RZZGate, @@ -47,7 +48,6 @@ from qiskit.qasm3.exporter import QASM3Builder from qiskit.qasm3.printer import BasicPrinter -from qiskit.extensions import Initialize from qiskit.circuit.tools.pi_check import pi_check from qiskit.utils import optionals as _optionals @@ -627,7 +627,6 @@ def _set_bit_reg_info(self, wire_map, qubits_dict, clbits_dict, glob_data): idx = 0 pos = y_off = -len(self._qubits) + 1 for ii, wire in enumerate(wire_map): - # if it's a creg, register is the key and just load the index if isinstance(wire, ClassicalRegister): # If wire came from ControlFlowOp and not in clbits, don't draw it @@ -1168,7 +1167,6 @@ def _condition(self, node, node_data, wire_map, outer_circuit, cond_xy, glob_dat cond_pos = [] if isinstance(condition, expr.Expr): - # If fixing this, please update the docstrings of `QuantumCircuit.draw` and # `visualization.circuit_drawer` to remove warnings. diff --git a/releasenotes/notes/deprecate-extensions-046-2b98dce6fdfadc72.yaml b/releasenotes/notes/deprecate-extensions-046-2b98dce6fdfadc72.yaml new file mode 100644 index 000000000000..3e9b2f4644a3 --- /dev/null +++ b/releasenotes/notes/deprecate-extensions-046-2b98dce6fdfadc72.yaml @@ -0,0 +1,5 @@ +--- +deprecations: + - | + Deprecated the :mod:`qiskit.extensions` module, which has been pending deprecation since the 0.45 release. + Most objects have been moved to :mod:`qiskit.circuit.library`, see the release notes of 0.45 for more details. diff --git a/test/python/circuit/test_circuit_load_from_qpy.py b/test/python/circuit/test_circuit_load_from_qpy.py index 4f8523358dbd..90c20e36499e 100644 --- a/test/python/circuit/test_circuit_load_from_qpy.py +++ b/test/python/circuit/test_circuit_load_from_qpy.py @@ -1458,14 +1458,14 @@ def test_incomplete_owned_bits(self): def test_diagonal_gate(self): """Test that a `DiagonalGate` successfully roundtrips.""" qc = QuantumCircuit(2) - with self.assertWarns(PendingDeprecationWarning): + with self.assertWarns(DeprecationWarning): qc.diagonal([1, -1, -1, 1], [0, 1]) with io.BytesIO() as fptr: dump(qc, fptr) fptr.seek(0) new_circuit = load(fptr)[0] - # DiagonalGate (and a bunch of the qiskit.extensions gates) have non-deterministic + # DiagonalGate (and some of the qiskit.circuit.library gates) have non-deterministic # definitions with regard to internal instruction names, so cannot be directly compared for # equality. self.assertIs(type(qc.data[0].operation), type(new_circuit.data[0].operation)) diff --git a/test/python/circuit/test_circuit_operations.py b/test/python/circuit/test_circuit_operations.py index 3f773fb09abc..e6e6f8c29bdb 100644 --- a/test/python/circuit/test_circuit_operations.py +++ b/test/python/circuit/test_circuit_operations.py @@ -1259,28 +1259,6 @@ def instructions(): self.assertEqual(circuit, expected) self.assertEqual(circuit.name, "test") - def test_duplicated_methods_deprecation(self): - """Test the now deprecated, duplicated gate method emit a deprecation warning.""" - - # {duplicate: (use_this_instead, args)} - methods = { - "i": ("id", [0]), - "cnot": ("cx", [0, 1]), - "toffoli": ("ccx", [0, 1, 2]), - "mct": ("mcx", [[0, 1], 2]), - "fredkin": ("cswap", [0, 1, 2]), - } - - for old, (new, args) in methods.items(): - circuit = QuantumCircuit(3) - - with self.subTest(method=old): - - # check (1) the (pending) deprecation is raised - # and (2) the new method is documented there - with self.assertWarnsRegex(DeprecationWarning, new): - getattr(circuit, old)(*args) - class TestCircuitPrivateOperations(QiskitTestCase): """Direct tests of some of the private methods of QuantumCircuit. These do not represent diff --git a/test/python/circuit/test_circuit_properties.py b/test/python/circuit/test_circuit_properties.py index f2531954676e..da9af61367a8 100644 --- a/test/python/circuit/test_circuit_properties.py +++ b/test/python/circuit/test_circuit_properties.py @@ -19,7 +19,6 @@ from qiskit.circuit.library import RXGate, RYGate from qiskit.test import QiskitTestCase from qiskit.circuit.exceptions import CircuitError -from qiskit.extensions.simulator import Snapshot class TestCircuitProperties(QiskitTestCase): @@ -561,80 +560,6 @@ def test_circuit_depth_barriers3(self): circ.cx(2, 3) self.assertEqual(circ.depth(), 4) - def test_circuit_depth_snap1(self): - """Test circuit depth for snapshots #1.""" - - # ┌───┐ ░ - # q_0: ┤ H ├──■───░─────────── - # └───┘┌─┴─┐ ░ - # q_1: ─────┤ X ├─░─────────── - # └───┘ ░ ┌───┐ - # q_2: ───────────░─┤ H ├──■── - # ░ └───┘┌─┴─┐ - # q_3: ───────────░──────┤ X ├ - # ░ └───┘ - q = QuantumRegister(4, "q") - c = ClassicalRegister(4, "c") - circ = QuantumCircuit(q, c) - circ.h(0) - circ.cx(0, 1) - with self.assertWarns(DeprecationWarning): - circ.append(Snapshot("snap", num_qubits=4), [0, 1, 2, 3]) - circ.h(2) - circ.cx(2, 3) - self.assertEqual(circ.depth(), 4) - - def test_circuit_depth_snap2(self): - """Test circuit depth for snapshots #2.""" - - # ┌───┐ ░ ░ ░ - # q_0: ┤ H ├─░───■───░───────░────── - # └───┘ ░ ┌─┴─┐ ░ ░ - # q_1: ──────░─┤ X ├─░───────░────── - # ░ └───┘ ░ ┌───┐ ░ - # q_2: ──────░───────░─┤ H ├─░───■── - # ░ ░ └───┘ ░ ┌─┴─┐ - # q_3: ──────░───────░───────░─┤ X ├ - # ░ ░ ░ └───┘ - q = QuantumRegister(4, "q") - c = ClassicalRegister(4, "c") - circ = QuantumCircuit(q, c) - circ.h(0) - with self.assertWarns(DeprecationWarning): - circ.append(Snapshot("snap0", num_qubits=4), [0, 1, 2, 3]) - circ.cx(0, 1) - with self.assertWarns(DeprecationWarning): - circ.append(Snapshot("snap1", num_qubits=4), [0, 1, 2, 3]) - circ.h(2) - with self.assertWarns(DeprecationWarning): - circ.append(Snapshot("snap2", num_qubits=4), [0, 1, 2, 3]) - circ.cx(2, 3) - self.assertEqual(circ.depth(), 4) - - def test_circuit_depth_snap3(self): - """Test circuit depth for snapshots #3.""" - - # ┌───┐ ░ ░ - # q_0: ┤ H ├──■───░──░─────────── - # └───┘┌─┴─┐ ░ ░ - # q_1: ─────┤ X ├─░──░─────────── - # └───┘ ░ ░ ┌───┐ - # q_2: ───────────░──░─┤ H ├──■── - # ░ ░ └───┘┌─┴─┐ - # q_3: ───────────░──░──────┤ X ├ - # ░ ░ └───┘ - q = QuantumRegister(4, "q") - c = ClassicalRegister(4, "c") - circ = QuantumCircuit(q, c) - circ.h(0) - circ.cx(0, 1) - with self.assertWarns(DeprecationWarning): - circ.append(Snapshot("snap0", num_qubits=4), [0, 1, 2, 3]) - circ.append(Snapshot("snap1", num_qubits=4), [0, 1, 2, 3]) - circ.h(2) - circ.cx(2, 3) - self.assertEqual(circ.depth(), 4) - def test_circuit_depth_2qubit(self): """Test finding depth of two-qubit gates only.""" @@ -745,21 +670,6 @@ def test_circuit_size_2qubit(self): qc.rzz(0.1, q[1], q[2]) self.assertEqual(qc.size(lambda x: x.operation.num_qubits == 2), 2) - def test_circuit_size_ignores_barriers_snapshots(self): - """Circuit.size should not count barriers or snapshots.""" - q = QuantumRegister(4, "q") - c = ClassicalRegister(4, "c") - qc = QuantumCircuit(q, c) - - qc.h(q[0]) - qc.cx(q[0], q[1]) - self.assertEqual(qc.size(), 2) - qc.barrier(q) - self.assertEqual(qc.size(), 2) - with self.assertWarns(DeprecationWarning): - qc.append(Snapshot("snapshot_label", num_qubits=4), [0, 1, 2, 3]) - self.assertEqual(qc.size(), 2) - def test_circuit_count_ops(self): """Test circuit count ops.""" q = QuantumRegister(6, "q") diff --git a/test/python/circuit/test_controlled_gate.py b/test/python/circuit/test_controlled_gate.py index 7f3bcee95f12..34bf21f30e2e 100644 --- a/test/python/circuit/test_controlled_gate.py +++ b/test/python/circuit/test_controlled_gate.py @@ -1016,7 +1016,7 @@ def test_open_control_composite_unrolling(self): @data(*ControlledGate.__subclasses__()) def test_standard_base_gate_setting(self, gate_class): - """Test all gates in standard extensions which are of type ControlledGate + """Test all standard gates which are of type ControlledGate and have a base gate setting. """ if gate_class in {SingletonControlledGate, _SingletonControlledGateOverrides}: @@ -1044,9 +1044,7 @@ def test_standard_base_gate_setting(self, gate_class): ctrl_state=[None, 0, 1], ) def test_all_inverses(self, gate, num_ctrl_qubits, ctrl_state): - """Test all gates in standard extensions except those that cannot be controlled - or are being deprecated. - """ + """Test all standard gates except those that cannot be controlled.""" if not (issubclass(gate, ControlledGate) or issubclass(gate, allGates.IGate)): # only verify basic gates right now, as already controlled ones # will generate differing definitions @@ -1146,7 +1144,7 @@ def test_open_controlled_gate_raises(self): def test_base_gate_params_reference(self): """ - Test all gates in standard extensions which are of type ControlledGate and have a base gate + Test all standard gates which are of type ControlledGate and have a base gate setting have params which reference the one in their base gate. """ num_ctrl_qubits = 1 diff --git a/test/python/circuit/test_diagonal_gate.py b/test/python/circuit/test_diagonal_gate.py index c0379e4fd9c1..fcf2b832a72d 100644 --- a/test/python/circuit/test_diagonal_gate.py +++ b/test/python/circuit/test_diagonal_gate.py @@ -46,7 +46,7 @@ def test_diag_gate(self): num_qubits = int(np.log2(len(diag))) q = QuantumRegister(num_qubits) qc = QuantumCircuit(q) - with self.assertWarns(PendingDeprecationWarning): + with self.assertWarns(DeprecationWarning): qc.diagonal(diag, q[0:num_qubits]) # Decompose the gate qc = transpile(qc, basis_gates=["u1", "u3", "u2", "cx", "id"], optimization_level=0) @@ -62,7 +62,7 @@ def test_mod1_entries(self): from qiskit.quantum_info.operators.predicates import ATOL_DEFAULT, RTOL_DEFAULT with self.assertRaises(QiskitError): - with self.assertWarns(PendingDeprecationWarning): + with self.assertWarns(DeprecationWarning): DiagonalGate([1, 1 - 2 * ATOL_DEFAULT - RTOL_DEFAULT]) def test_npcomplex_params_conversion(self): @@ -70,7 +70,7 @@ def test_npcomplex_params_conversion(self): # ref: https://github.com/Qiskit/qiskit-aer/issues/696 diag = np.array([1 + 0j, 1 + 0j]) qc = QuantumCircuit(1) - with self.assertWarns(PendingDeprecationWarning): + with self.assertWarns(DeprecationWarning): qc.diagonal(diag.tolist(), [0]) params = qc.data[0].operation.params diff --git a/test/python/circuit/test_isometry.py b/test/python/circuit/test_isometry.py index 774e2368803f..3a14f7425be5 100644 --- a/test/python/circuit/test_isometry.py +++ b/test/python/circuit/test_isometry.py @@ -55,7 +55,7 @@ def test_isometry(self, iso): q = QuantumRegister(num_q_output) qc = QuantumCircuit(q) - with self.assertWarns(PendingDeprecationWarning): + with self.assertWarns(DeprecationWarning): qc.iso(iso, q[:num_q_input], q[num_q_input:]) # Verify the circuit can be decomposed @@ -97,7 +97,7 @@ def test_isometry_tolerance(self, iso): qc = QuantumCircuit(q) # Compute isometry with custom tolerance - with self.assertWarns(PendingDeprecationWarning): + with self.assertWarns(DeprecationWarning): qc.isometry(iso, q[:num_q_input], q[num_q_input:], epsilon=1e-3) # Verify the circuit can be decomposed diff --git a/test/python/circuit/test_operation.py b/test/python/circuit/test_operation.py index 7e98142ae612..92693b134ab1 100644 --- a/test/python/circuit/test_operation.py +++ b/test/python/circuit/test_operation.py @@ -102,7 +102,7 @@ def test_pauli_as_operation(self): def test_isometry_as_operation(self): """Test that we can instantiate an object of class - :class:`~qiskit.extensions.quantum_initializer.Isometry` and that + :class:`~qiskit.circuit.library.quantum_initializer.Isometry` and that it has the expected name, num_qubits and num_clbits. """ op = Isometry(np.eye(4, 4), 3, 2) @@ -113,7 +113,7 @@ def test_isometry_as_operation(self): def test_initialize_as_operation(self): """Test that we can instantiate an object of class - :class:`~qiskit.extensions.quantum_initializer.Initialize` and that + :class:`~qiskit.circuit.library.quantum_initializer.Initialize` and that it has the expected name, num_qubits and num_clbits. """ desired_vector = [0.5, 0.5, 0.5, 0.5] diff --git a/test/python/circuit/test_squ.py b/test/python/circuit/test_squ.py deleted file mode 100644 index e80a17e20b68..000000000000 --- a/test/python/circuit/test_squ.py +++ /dev/null @@ -1,65 +0,0 @@ -# This code is part of Qiskit. -# -# (C) Copyright IBM 2019. -# -# 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. - -# pylint: disable=invalid-name - -"""Single-qubit unitary tests.""" - -import unittest -from test import combine -import numpy as np -from ddt import ddt -from qiskit.quantum_info.random import random_unitary -from qiskit import BasicAer, QuantumCircuit, QuantumRegister -from qiskit.test import QiskitTestCase -from qiskit.extensions.quantum_initializer.squ import SingleQubitUnitary -from qiskit.compiler import transpile -from qiskit.quantum_info.operators.predicates import matrix_equal - -squs = [ - np.eye(2, 2), - np.array([[0.0, 1.0], [1.0, 0.0]]), - 1 / np.sqrt(2) * np.array([[1.0, 1.0], [-1.0, 1.0]]), - np.array([[np.exp(1j * 5.0 / 2), 0], [0, np.exp(-1j * 5.0 / 2)]]), - random_unitary(2, seed=42).data, -] - -up_to_diagonal_list = [True, False] - - -@ddt -class TestSingleQubitUnitary(QiskitTestCase): - """Qiskit ZYZ-decomposition tests.""" - - @combine(u=squs, up_to_diagonal=up_to_diagonal_list) - def test_squ(self, u, up_to_diagonal): - """Tests for single-qubit unitary decomposition.""" - qr = QuantumRegister(1, "qr") - qc = QuantumCircuit(qr) - with self.assertWarns(DeprecationWarning): - qc.squ(u, qr[0], up_to_diagonal=up_to_diagonal) - # Decompose the gate - qc = transpile(qc, basis_gates=["u1", "u3", "u2", "cx", "id"]) - # Simulate the decomposed gate - simulator = BasicAer.get_backend("unitary_simulator") - result = simulator.run(qc).result() - unitary = result.get_unitary(qc) - if up_to_diagonal: - with self.assertWarns(DeprecationWarning): - squ = SingleQubitUnitary(u, up_to_diagonal=up_to_diagonal) - unitary = np.dot(np.diagflat(squ.diag), unitary) - unitary_desired = u - self.assertTrue(matrix_equal(unitary_desired, unitary, ignore_phase=True)) - - -if __name__ == "__main__": - unittest.main() diff --git a/test/python/circuit/test_uc.py b/test/python/circuit/test_uc.py index 9a7b5757a769..a5f0fb33e0f2 100644 --- a/test/python/circuit/test_uc.py +++ b/test/python/circuit/test_uc.py @@ -59,7 +59,7 @@ def test_ucg(self, squs, up_to_diagonal): q = QuantumRegister(num_con + 1) qc = QuantumCircuit(q) - with self.assertWarns(PendingDeprecationWarning): + with self.assertWarns(DeprecationWarning): # TODO: change to directly appending UCGate once deprecation period of the method is over qc.uc(squs, q[1:], q[0], up_to_diagonal=up_to_diagonal) diff --git a/test/python/circuit/test_ucx_y_z.py b/test/python/circuit/test_ucx_y_z.py index 23ea57111fbb..08f296b447c9 100644 --- a/test/python/circuit/test_ucx_y_z.py +++ b/test/python/circuit/test_ucx_y_z.py @@ -57,7 +57,7 @@ def test_ucy(self, use_method): q = QuantumRegister(num_contr + 1) qc = QuantumCircuit(q) if use_method: - with self.assertWarns(PendingDeprecationWarning): + with self.assertWarns(DeprecationWarning): getattr(qc, methods[rot_axis])(angles, q[1 : num_contr + 1], q[0]) else: gate = gates[rot_axis](angles) diff --git a/test/python/transpiler/test_unroller.py b/test/python/transpiler/test_unroller.py index a69d7667ef2b..c43953f221d9 100644 --- a/test/python/transpiler/test_unroller.py +++ b/test/python/transpiler/test_unroller.py @@ -16,7 +16,6 @@ from numpy import pi from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit -from qiskit.extensions.simulator import Snapshot from qiskit.transpiler.passes import Unroller from qiskit.converters import circuit_to_dag, dag_to_circuit from qiskit.quantum_info import Operator @@ -774,15 +773,6 @@ def test_unroll_z(self): self.ref_circuit.append(U3Gate(0, 0, pi), [0]) self.compare_dags() - def test_unroll_snapshot(self): - """test unroll snapshot""" - num_qubits = self.circuit.num_qubits - with self.assertWarns(DeprecationWarning): - instr = Snapshot("0", num_qubits=num_qubits) - self.circuit.append(instr, range(num_qubits)) - self.ref_circuit.append(instr, range(num_qubits)) - self.compare_dags() - def test_unroll_measure(self): """test unroll measure""" self.circuit.measure(self.qr, self.cr) diff --git a/test/python/visualization/test_circuit_latex.py b/test/python/visualization/test_circuit_latex.py index 85f6e0c7c4e6..9f9de616d724 100644 --- a/test/python/visualization/test_circuit_latex.py +++ b/test/python/visualization/test_circuit_latex.py @@ -247,12 +247,6 @@ def test_plot_barriers(self): # check for other barrier like commands circuit.h(q[1]) - # this import appears to be unused, but is actually needed to get snapshot instruction - import qiskit.extensions.simulator # pylint: disable=unused-import - - with self.assertWarns(DeprecationWarning): - circuit.snapshot("sn 1") - # check the barriers plot properly when plot_barriers= True circuit_drawer(circuit, filename=filename1, output="latex_source", plot_barriers=True) diff --git a/test/python/visualization/test_latex_plot_barriers_true.tex b/test/python/visualization/test_latex_plot_barriers_true.tex new file mode 100644 index 000000000000..399e2ecd4ece --- /dev/null +++ b/test/python/visualization/test_latex_plot_barriers_true.tex @@ -0,0 +1,13 @@ +\documentclass[border=2px]{standalone} + +\usepackage[braket, qm]{qcircuit} +\usepackage{graphicx} + +\begin{document} +\scalebox{1.0}{ +\Qcircuit @C=1.0em @R=0.2em @!R { \\ + \nghost{{q}_{0} : } & \lstick{{q}_{0} : } & \gate{\mathrm{H}} \barrier[0em]{1} & \qw & \qw & \qw & \qw\\ + \nghost{{q}_{1} : } & \lstick{{q}_{1} : } & \qw & \qw & \gate{\mathrm{H}} & \qw & \qw\\ + \nghost{\mathrm{{c} : }} & \lstick{\mathrm{{c} : }} & \lstick{/_{_{2}}} \cw & \cw & \cw & \cw & \cw\\ +\\ }} +\end{document} \ No newline at end of file From ce170d3ec00fb034146e69e7d3874dcb858a78ba Mon Sep 17 00:00:00 2001 From: Julien Gacon Date: Fri, 5 Jan 2024 11:55:03 +0100 Subject: [PATCH 2/7] Detailed reno --- ...ecate-extensions-046-2b98dce6fdfadc72.yaml | 46 ++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/releasenotes/notes/deprecate-extensions-046-2b98dce6fdfadc72.yaml b/releasenotes/notes/deprecate-extensions-046-2b98dce6fdfadc72.yaml index 3e9b2f4644a3..a1b9707dea28 100644 --- a/releasenotes/notes/deprecate-extensions-046-2b98dce6fdfadc72.yaml +++ b/releasenotes/notes/deprecate-extensions-046-2b98dce6fdfadc72.yaml @@ -2,4 +2,48 @@ deprecations: - | Deprecated the :mod:`qiskit.extensions` module, which has been pending deprecation since the 0.45 release. - Most objects have been moved to :mod:`qiskit.circuit.library`, see the release notes of 0.45 for more details. + Most objects have been moved to :mod:`qiskit.circuit.library`, including: + + * :class:`~.library.DiagonalGate`, + * :class:`~.library.HamiltonianGateGate`, + * :class:`~.library.Initialize`, + * :class:`~.library.Isometry`, + * :class:`~.library.generalized_gates.mcg_up_diag.MCGupDiag`, + * :class:`~.library.UCGate`, + * :class:`~.library.UCPauliRotGate`, + * :class:`~.library.UCRXGate`, + * :class:`~.library.UCRYGate`, + * :class:`~.library.UCRZGate`, + * :class:`~.library.UnitaryGate`. + + With the deprecation of the objects, the following circuit methods have also been deprecated: + + * ``QuantumCircuit.diagonal``, + * ``QuantumCircuit.hamiltonian``, + * ``QuantumCircuit.isometry`` and ``QuantumCircuit.iso``, + * ``QuantumCircuit.uc``, + * ``QuantumCircuit.ucrx``, + * ``QuantumCircuit.ucry``, + * ``QuantumCircuit.ucrz``. + +upgrade: + - | + The following, deprecated circuit instructions have been removed: + + * ``SingleQubitUnitary`` (instead use :class:`.library.UnitaryGate`), + * ``Snapshot`` (superseded by Qiskit Aer's save instructions), + + along with their circuit methods: + + * ``QuantumCircuit.snapshot``, + * ``QuantumCircuit.squ``. + + - | + Removed deprecated, duplicated :class:`.QuantumCircuit` methods. These include + + * ``QuantumCircuit.cnot``, instead use :meth:`.QuantumCircuit.cx`, + * ``QuantumCircuit.toffoli``, instead use :meth:`.QuantumCircuit.ccx`, + * ``QuantumCircuit.fredkin``, instead use :meth:`.QuantumCircuit.cswap`, + * ``QuantumCircuit.mct``, instead use :meth:`.QuantumCircuit.mcx`, + * ``QuantumCircuit.i``, instead use :meth:`.QuantumCircuit.id`. + \ No newline at end of file From 5203872654e4df2e294da8a8016ba1fc675f1ba8 Mon Sep 17 00:00:00 2001 From: Julien Gacon Date: Fri, 5 Jan 2024 16:38:38 +0100 Subject: [PATCH 3/7] update figure --- .../circuit/references/plot_barriers_true.png | Bin 7784 -> 6940 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/test/visual/mpl/circuit/references/plot_barriers_true.png b/test/visual/mpl/circuit/references/plot_barriers_true.png index 2b712d8b1726a0e571a47c2a13fe83dea2b6b7c1..2c25d7774bc872ec0480c7d88ac67074248fa9f4 100644 GIT binary patch literal 6940 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

*8goj8)0W}-!(9fKrJueZ0? zJb?;QyDryO#$OVqusT#`9R}RA0~`xnn3&BM79jfz02Lt+2;y<(egrYIz=I7A!xNC& zr5AY(^gKK~KpJ)d?^g(t7gJyryFsRc7;hkv-Cu4b>fH|HrU)SA5)E<)Mt?(pT&k^1 z6!@)x^)6N8Qmdx`Y!e7L6a@Paa>8_GZAa91-42fZ@R(8-MF9~-mRiU$N?NsO!Rpxy zk$fZ&48)73mB4)w2HvUG`EB)y;Y_DMP8kHde)D1BJRXmjN%2yT=I|aT0gc}>6$(M0 zpERLewM5x^BLnyE0cCC0)YLQxE);m8Izejar80}|Lq6>ksW*V>?DsYa#CYZz4LcPN z6y$s{ufYvqfS8?G{8(iUKO=by;Ndp#ML25`DEc==@`y5i4X;t3T=T#K1c(dl!6;|D zayRJc|jQd0tkc-D2H)96(sIfb z*@+e`1uXfo$@y0i!{W64Z`^EPfw(uR?_#)3&;c`)n=2Ue)RGs}q#U=&pex72>}kqD z{w2HKsU+pUy=>HBhPI3P-jS9TRFJ%7AuZo&F*d*hSJ%<$ZhYr_3559fU*xfX`fy-R z>Bv}e?)l4sR1_(x zz5kx%xc)_?!w%$cw#j=ShOuu7Wt<xe_^vcDpJD>{k*?4OlGCi>Fh6>o$K0CF&UfcV z2KPeHxa^})#ZkW{*_wka&V!alb@0t&j`}Cv)@OCCZEOacIRp1g0T|;u*%(S+ZT_wi zmTLAR=VO-*9E)N4?r7D;VkmzK8kehN>b{z36>_gR0wK}f(z2Y#;AOB-T&hI8wja~0 z{*ip7(5n~pj7n#uJv9N9l}FaG=vo51Fm76kpOL}k>TrTFy;oIH(bwoeT!UiMIr;qw zI)bN>QDSf$n3X_ODx&H(jcX2ap=h z{PIOpcB4mccc&vz5bjGTCx&;~V+V^~)!(8u+9eLxI^=PojC?&M7V;p5;$G~~S=li) zqS~;K9wMy6b-Mp>yJxy{25Q&|PPckR%rFcL42)~NOJQ>^fqSn7>(*}pFkF_Gw*Ui; zs31Uwfet)Gf~4drHM6hjM&%UEXDG<~H~o|A>)kqze}vHcg6ItdBInx5(6${MV0h$q zuW2E_x7PR-{Me%TJZH~azj~EeCD^IHJeDG$XZUUxb%MEH?zLpzi^K6Th2>jdkVL$P zhK71H(umKt@|CPt_h_fc3}ha9Bg@a~hnAcvc04?=kU^a|8eOhmal!2CtA~CX85dRK zQd4t+ZAZSK>7aBIDqdHEqH=?!!!44hS-NIoo@fwLfO{=}-mjyq|HT&mJKxj$f4O~G bbV#?t{W`+7_wysb$PipbTN!oz?xX(z$~C%I From e1af4507a0787dd33f05e2cd3aaf0ba7b8bfe07a Mon Sep 17 00:00:00 2001 From: Julien Gacon Date: Fri, 5 Jan 2024 16:43:15 +0100 Subject: [PATCH 4/7] Fix Latex tests --- .../references/test_latex_plot_barriers_false.tex | 6 +++--- .../references/test_latex_plot_barriers_true.tex | 6 +++--- .../visualization/test_latex_plot_barriers_true.tex | 13 ------------- 3 files changed, 6 insertions(+), 19 deletions(-) delete mode 100644 test/python/visualization/test_latex_plot_barriers_true.tex diff --git a/test/python/visualization/references/test_latex_plot_barriers_false.tex b/test/python/visualization/references/test_latex_plot_barriers_false.tex index 06e3519367ad..8c256729101a 100644 --- a/test/python/visualization/references/test_latex_plot_barriers_false.tex +++ b/test/python/visualization/references/test_latex_plot_barriers_false.tex @@ -6,8 +6,8 @@ \begin{document} \scalebox{1.0}{ \Qcircuit @C=1.0em @R=0.2em @!R { \\ - \nghost{{q}_{0} : } & \lstick{{q}_{0} : } & \gate{\mathrm{H}} & \qw & \qw & \qw & \qw & \qw\\ - \nghost{{q}_{1} : } & \lstick{{q}_{1} : } & \qw & \qw & \gate{\mathrm{H}} & \qw & \qw & \qw\\ - \nghost{\mathrm{{c} : }} & \lstick{\mathrm{{c} : }} & \lstick{/_{_{2}}} \cw & \cw & \cw & \cw & \cw & \cw\\ + \nghost{{q}_{0} : } & \lstick{{q}_{0} : } & \gate{\mathrm{H}} & \qw & \qw & \qw & \qw\\ + \nghost{{q}_{1} : } & \lstick{{q}_{1} : } & \qw & \qw & \gate{\mathrm{H}} & \qw & \qw\\ + \nghost{\mathrm{{c} : }} & \lstick{\mathrm{{c} : }} & \lstick{/_{_{2}}} \cw & \cw & \cw & \cw & \cw\\ \\ }} \end{document} \ No newline at end of file diff --git a/test/python/visualization/references/test_latex_plot_barriers_true.tex b/test/python/visualization/references/test_latex_plot_barriers_true.tex index b7679d27cd39..399e2ecd4ece 100644 --- a/test/python/visualization/references/test_latex_plot_barriers_true.tex +++ b/test/python/visualization/references/test_latex_plot_barriers_true.tex @@ -6,8 +6,8 @@ \begin{document} \scalebox{1.0}{ \Qcircuit @C=1.0em @R=0.2em @!R { \\ - \nghost{{q}_{0} : } & \lstick{{q}_{0} : } & \gate{\mathrm{H}} \barrier[0em]{1} & \qw & \qw \barrier[0em]{1} & \cds{0}{^{\mathrm{sn\,1}}} & \qw & \qw\\ - \nghost{{q}_{1} : } & \lstick{{q}_{1} : } & \qw & \qw & \gate{\mathrm{H}} & \qw & \qw & \qw\\ - \nghost{\mathrm{{c} : }} & \lstick{\mathrm{{c} : }} & \lstick{/_{_{2}}} \cw & \cw & \cw & \cw & \cw & \cw\\ + \nghost{{q}_{0} : } & \lstick{{q}_{0} : } & \gate{\mathrm{H}} \barrier[0em]{1} & \qw & \qw & \qw & \qw\\ + \nghost{{q}_{1} : } & \lstick{{q}_{1} : } & \qw & \qw & \gate{\mathrm{H}} & \qw & \qw\\ + \nghost{\mathrm{{c} : }} & \lstick{\mathrm{{c} : }} & \lstick{/_{_{2}}} \cw & \cw & \cw & \cw & \cw\\ \\ }} \end{document} \ No newline at end of file diff --git a/test/python/visualization/test_latex_plot_barriers_true.tex b/test/python/visualization/test_latex_plot_barriers_true.tex deleted file mode 100644 index 399e2ecd4ece..000000000000 --- a/test/python/visualization/test_latex_plot_barriers_true.tex +++ /dev/null @@ -1,13 +0,0 @@ -\documentclass[border=2px]{standalone} - -\usepackage[braket, qm]{qcircuit} -\usepackage{graphicx} - -\begin{document} -\scalebox{1.0}{ -\Qcircuit @C=1.0em @R=0.2em @!R { \\ - \nghost{{q}_{0} : } & \lstick{{q}_{0} : } & \gate{\mathrm{H}} \barrier[0em]{1} & \qw & \qw & \qw & \qw\\ - \nghost{{q}_{1} : } & \lstick{{q}_{1} : } & \qw & \qw & \gate{\mathrm{H}} & \qw & \qw\\ - \nghost{\mathrm{{c} : }} & \lstick{\mathrm{{c} : }} & \lstick{/_{_{2}}} \cw & \cw & \cw & \cw & \cw\\ -\\ }} -\end{document} \ No newline at end of file From a31325a1041beaa4a899382e82f040f7dbf5c3e1 Mon Sep 17 00:00:00 2001 From: Julien Gacon Date: Mon, 8 Jan 2024 11:46:55 +0100 Subject: [PATCH 5/7] un-remove eagerly removed methods ... that still need one more release for removal --- qiskit/circuit/quantumcircuit.py | 363 ++++++++++++------ qiskit/extensions/__init__.py | 2 + .../quantum_initializer/__init__.py | 2 + qiskit/extensions/quantum_initializer/squ.py | 163 ++++++++ qiskit/extensions/simulator/__init__.py | 15 + qiskit/extensions/simulator/snapshot.py | 70 ++++ ...ecate-extensions-046-2b98dce6fdfadc72.yaml | 22 -- .../python/circuit/test_circuit_operations.py | 22 ++ .../python/circuit/test_circuit_properties.py | 90 +++++ test/python/circuit/test_squ.py | 65 ++++ test/python/transpiler/test_unroller.py | 10 + .../test_latex_plot_barriers_false.tex | 6 +- .../test_latex_plot_barriers_true.tex | 6 +- .../visualization/test_circuit_latex.py | 6 + .../circuit/references/plot_barriers_true.png | Bin 6940 -> 7784 bytes 15 files changed, 696 insertions(+), 146 deletions(-) create mode 100644 qiskit/extensions/quantum_initializer/squ.py create mode 100644 qiskit/extensions/simulator/__init__.py create mode 100644 qiskit/extensions/simulator/snapshot.py create mode 100644 test/python/circuit/test_squ.py diff --git a/qiskit/circuit/quantumcircuit.py b/qiskit/circuit/quantumcircuit.py index 223f20157b9b..f09477fff7cb 100644 --- a/qiskit/circuit/quantumcircuit.py +++ b/qiskit/circuit/quantumcircuit.py @@ -66,7 +66,6 @@ import qiskit # pylint: disable=cyclic-import from qiskit.transpiler.layout import TranspileLayout # pylint: disable=cyclic-import from qiskit.quantum_info.operators.base_operator import BaseOperator - from qiskit.quantum_info.states.statevector import Statevector # pylint: disable=cyclic-import BitLocations = namedtuple("BitLocations", ("index", "registers")) @@ -2954,6 +2953,23 @@ def ch( CHGate(label=label, ctrl_state=ctrl_state), [control_qubit, target_qubit], [] ) + @deprecate_func( + since="0.45.0", + additional_msg="Use QuantumCircuit.id as direct replacement.", + ) + def i(self, qubit: QubitSpecifier) -> InstructionSet: + """Apply :class:`~qiskit.circuit.library.IGate`. + + For the full matrix form of this gate, see the underlying gate documentation. + + Args: + qubit: The qubit(s) to apply the gate to. + + Returns: + A handle to the instructions created. + """ + return self.id(qubit) + def id(self, qubit: QubitSpecifier) -> InstructionSet: # pylint: disable=invalid-name """Apply :class:`~qiskit.circuit.library.IGate`. @@ -3538,6 +3554,33 @@ def cswap( [], ) + @deprecate_func( + since="0.45.0", + additional_msg="Use QuantumCircuit.cswap as direct replacement.", + ) + def fredkin( + self, + control_qubit: QubitSpecifier, + target_qubit1: QubitSpecifier, + target_qubit2: QubitSpecifier, + ) -> InstructionSet: + """Apply :class:`~qiskit.circuit.library.CSwapGate`. + + For the full matrix form of this gate, see the underlying gate documentation. + + Args: + control_qubit: The qubit(s) used as the control. + target_qubit1: The qubit(s) targeted by the gate. + target_qubit2: The qubit(s) targeted by the gate. + + Returns: + A handle to the instructions created. + + See Also: + QuantumCircuit.cswap: the same function with a different name. + """ + return self.cswap(control_qubit, target_qubit1, target_qubit2) + def sx(self, qubit: QubitSpecifier) -> InstructionSet: """Apply :class:`~qiskit.circuit.library.SXGate`. @@ -3735,6 +3778,34 @@ def cx( CXGate(label=label, ctrl_state=ctrl_state), [control_qubit, target_qubit], [] ) + @deprecate_func(since="0.45.0", additional_msg="Use QuantumCircuit.cx as direct replacement.") + def cnot( + self, + control_qubit: QubitSpecifier, + target_qubit: QubitSpecifier, + label: str | None = None, + ctrl_state: str | int | None = None, + ) -> InstructionSet: + r"""Apply :class:`~qiskit.circuit.library.CXGate`. + + For the full matrix form of this gate, see the underlying gate documentation. + + Args: + control_qubit: The qubit(s) used as the control. + target_qubit: The qubit(s) targeted by the gate. + label: The string label of the gate in the circuit. + ctrl_state: + The control state in decimal, or as a bitstring (e.g. '1'). Defaults to controlling + on the '1' state. + + Returns: + A handle to the instructions created. + + See Also: + QuantumCircuit.cx: the same function with a different name. + """ + return self.cx(control_qubit, target_qubit, label, ctrl_state) + def dcx(self, qubit1: QubitSpecifier, qubit2: QubitSpecifier) -> InstructionSet: r"""Apply :class:`~qiskit.circuit.library.DCXGate`. @@ -3781,6 +3852,30 @@ def ccx( [], ) + @deprecate_func(since="0.45.0", additional_msg="Use QuantumCircuit.ccx as direct replacement.") + def toffoli( + self, + control_qubit1: QubitSpecifier, + control_qubit2: QubitSpecifier, + target_qubit: QubitSpecifier, + ) -> InstructionSet: + r"""Apply :class:`~qiskit.circuit.library.CCXGate`. + + For the full matrix form of this gate, see the underlying gate documentation. + + Args: + control_qubit1: The qubit(s) used as the first control. + control_qubit2: The qubit(s) used as the second control. + target_qubit: The qubit(s) targeted by the gate. + + Returns: + A handle to the instructions created. + + See Also: + QuantumCircuit.ccx: the same gate with a different name. + """ + return self.ccx(control_qubit1, control_qubit2, target_qubit) + def mcx( self, control_qubits: Sequence[QubitSpecifier], @@ -3859,6 +3954,44 @@ def mcx( return self.append(gate, control_qubits[:] + [target_qubit] + ancilla_qubits[:], []) + @deprecate_func(since="0.45.0", additional_msg="Use QuantumCircuit.mcx as direct replacement.") + def mct( + self, + control_qubits: Sequence[QubitSpecifier], + target_qubit: QubitSpecifier, + ancilla_qubits: QubitSpecifier | Sequence[QubitSpecifier] | None = None, + mode: str = "noancilla", + ) -> InstructionSet: + """Apply :class:`~qiskit.circuit.library.MCXGate`. + + The multi-cX gate can be implemented using different techniques, which use different numbers + of ancilla qubits and have varying circuit depth. These modes are: + + - ``'noancilla'``: Requires 0 ancilla qubits. + - ``'recursion'``: Requires 1 ancilla qubit if more than 4 controls are used, otherwise 0. + - ``'v-chain'``: Requires 2 less ancillas than the number of control qubits. + - ``'v-chain-dirty'``: Same as for the clean ancillas (but the circuit will be longer). + + For the full matrix form of this gate, see the underlying gate documentation. + + Args: + control_qubits: The qubits used as the controls. + target_qubit: The qubit(s) targeted by the gate. + ancilla_qubits: The qubits used as the ancillae, if the mode requires them. + mode: The choice of mode, explained further above. + + Returns: + A handle to the instructions created. + + Raises: + ValueError: if the given mode is not known, or if too few ancilla qubits are passed. + AttributeError: if no ancilla qubits are passed, but some are needed. + + See Also: + QuantumCircuit.mcx: the same gate with a different name. + """ + return self.mcx(control_qubits, target_qubit, ancilla_qubits, mode) + def y(self, qubit: QubitSpecifier) -> InstructionSet: r"""Apply :class:`~qiskit.circuit.library.YGate`. @@ -3995,121 +4128,6 @@ def pauli( return self.append(PauliGate(pauli_string), qubits, []) - def prepare_state( - self, - state: Statevector | Sequence[complex] | str | int, - qubits: Sequence[QubitSpecifier] | None = None, - label: str | None = None, - normalize: bool = False, - ) -> InstructionSet: - r"""Prepare qubits in a specific state. - - This class implements a state preparing unitary. Unlike - :meth:`.initialize` it does not reset the qubits first. - - Args: - state: - * Statevector: Statevector to initialize to. - * list: vector of complex amplitudes to initialize to. - * str: 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`. - * int: 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`. - - qubits: - * QuantumRegister: A list of qubits to be initialized [Default: None]. - * Qubit: Single qubit to be initialized [Default: None]. - * int: Index of qubit to be initialized [Default: None]. - * list: Indexes of qubits to be initialized [Default: None]. - label: An optional label for the gate - normalize: Whether to normalize an input array to a unit vector. - - Returns: - A handle to the instruction that was just initialized - - Examples: - Prepare a qubit in the state :math:`(|0\rangle - |1\rangle) / \sqrt{2}`. - - .. code-block:: - - import numpy as np - from qiskit import QuantumCircuit - - circuit = QuantumCircuit(1) - circuit.prepare_state([1/np.sqrt(2), -1/np.sqrt(2)], 0) - circuit.draw() - - output: - - .. parsed-literal:: - - ┌─────────────────────────────────────┐ - q_0: ┤ State Preparation(0.70711,-0.70711) ├ - └─────────────────────────────────────┘ - - - Prepare 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`. - - .. code-block:: - - import numpy as np - from qiskit import QuantumCircuit - - circuit = QuantumCircuit(2) - circuit.prepare_state('01', circuit.qubits) - circuit.draw() - - output: - - .. parsed-literal:: - - ┌─────────────────────────┐ - q_0: ┤0 ├ - │ State Preparation(0,1) │ - q_1: ┤1 ├ - └─────────────────────────┘ - - - Initialize two qubits from an array of complex amplitudes - .. code-block:: - - import numpy as np - from qiskit import QuantumCircuit - - circuit = QuantumCircuit(2) - circuit.prepare_state([0, 1/np.sqrt(2), -1.j/np.sqrt(2), 0], circuit.qubits) - circuit.draw() - - output: - - .. parsed-literal:: - - ┌───────────────────────────────────────────┐ - q_0: ┤0 ├ - │ State Preparation(0,0.70711,-0.70711j,0) │ - q_1: ┤1 ├ - └───────────────────────────────────────────┘ - """ - # pylint: disable=cyclic-import - from qiskit.circuit.library.data_preparation import StatePreparation - - if qubits is None: - qubits = self.qubits - elif isinstance(qubits, (int, np.integer, slice, Qubit)): - qubits = [qubits] - - num_qubits = len(qubits) if isinstance(state, int) else None - - return self.append( - StatePreparation(state, num_qubits, label=label, normalize=normalize), qubits - ) - def initialize( self, params: Sequence[complex] | str | int, @@ -4119,10 +4137,10 @@ def initialize( r"""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` + followed by calling :class:`qiskit.extensions.StatePreparation` class to prepare the qubits in a specified state. Both these steps are included in the - :class:`~qiskit.circuit.library.Initialize` instruction. + :class:`qiskit.extensions.Initialize` instruction. Args: params: The state to initialize to, can be either of the following. @@ -4657,6 +4675,115 @@ def ucrz( ) return self.append(UCRZGate(angle_list), [q_target] + q_controls, []) + @deprecate_func( + since="0.45.0", additional_msg="Instead, use the QuantumCircuit.unitary method." + ) + def squ( + self, + unitary_matrix, + qubit, + mode="ZYZ", + up_to_diagonal=False, + ): + """Decompose an arbitrary 2*2 unitary into three rotation gates. + + Note that the decomposition is up to a global phase shift. + (This is a well known decomposition which can be found for example in Nielsen and Chuang's book + "Quantum computation and quantum information".) + + Args: + unitary_matrix (ndarray): 2*2 unitary (given as a (complex) ndarray). + qubit (QuantumRegister or Qubit): The qubit which the gate is acting on. + mode (string): determines the used decomposition by providing the rotation axes. + The allowed modes are: "ZYZ" (default) + up_to_diagonal (bool): if set to True, the single-qubit unitary is decomposed up to + a diagonal matrix, i.e. a unitary u' is implemented such that there exists a 2*2 + diagonal gate d with u = d.dot(u') + + Returns: + InstructionSet: The single-qubit unitary instruction attached to the circuit. + + Raises: + QiskitError: if the format is wrong; if the array u is not unitary + """ + # pylint: disable=cyclic-import + from qiskit.extensions.quantum_initializer.squ import SingleQubitUnitary + + if isinstance(qubit, QuantumRegister): + qubit = qubit[:] + if len(qubit) == 1: + qubit = qubit[0] + else: + raise QiskitError( + "The target qubit is a QuantumRegister containing more than one qubit." + ) + # Check if there is one target qubit provided + if not isinstance(qubit, Qubit): + raise QiskitError("The target qubit is not a single qubit from a QuantumRegister.") + + with warnings.catch_warnings(): + warnings.simplefilter("ignore", category=DeprecationWarning) + squ = SingleQubitUnitary(unitary_matrix, mode, up_to_diagonal) + + return self.append(squ, [qubit], []) + + @deprecate_func( + since="0.45.0", + additional_msg="The Snapshot instruction has been superseded by Qiskit Aer's save " + "instructions, see " + "https://qiskit.org/ecosystem/aer/apidocs/aer_library.html#saving-simulator-data.", + ) + def snapshot(self, label, snapshot_type="statevector", qubits=None, params=None): + """Take a statevector snapshot of the internal simulator representation. + Works on all qubits, and prevents reordering (like barrier). + + For other types of snapshots use the Snapshot extension directly. + + Args: + label (str): a snapshot label to report the result. + snapshot_type (str): the type of the snapshot. + qubits (list or None): the qubits to apply snapshot to [Default: None]. + params (list or None): the parameters for snapshot_type [Default: None]. + + Returns: + QuantumCircuit: with attached command + + Raises: + ExtensionError: malformed command + """ + # pylint: disable-cyclic-import + from qiskit.extensions.simulator.snapshot import Snapshot + from qiskit.extensions.exceptions import ExtensionError + + # If no qubits are specified we add all qubits so it acts as a barrier + # This is needed for full register snapshots like statevector + if isinstance(qubits, QuantumRegister): + qubits = qubits[:] + if not qubits: + tuples = [] + if isinstance(self, QuantumCircuit): + for register in self.qregs: + tuples.append(register) + if not tuples: + raise ExtensionError("no qubits for snapshot") + qubits = [] + for tuple_element in tuples: + if isinstance(tuple_element, QuantumRegister): + for j in range(tuple_element.size): + qubits.append(tuple_element[j]) + else: + qubits.append(tuple_element) + + # catch deprecation warning from instantiating the Snapshot instruction, + # as a warning is already triggered from this method + with warnings.catch_warnings(): + warnings.simplefilter("ignore", category=DeprecationWarning) + snap = Snapshot( + label, snapshot_type=snapshot_type, num_qubits=len(qubits), params=params + ) + + return self.append(snap, qubits) + def _push_scope( self, qubits: Iterable[Qubit] = (), diff --git a/qiskit/extensions/__init__.py b/qiskit/extensions/__init__.py index 71ca9db57d27..635ef4a0d7c5 100644 --- a/qiskit/extensions/__init__.py +++ b/qiskit/extensions/__init__.py @@ -53,11 +53,13 @@ from .exceptions import ExtensionError from .quantum_initializer import ( Initialize, + SingleQubitUnitary, UCPauliRotGate, UCRXGate, UCRYGate, UCRZGate, ) +from .simulator import Snapshot warnings.warn( "The qiskit.extensions module is deprecated since Qiskit 0.46.0. It will be deprecated " diff --git a/qiskit/extensions/quantum_initializer/__init__.py b/qiskit/extensions/quantum_initializer/__init__.py index 640c781a4bfb..27f24443bd02 100644 --- a/qiskit/extensions/quantum_initializer/__init__.py +++ b/qiskit/extensions/quantum_initializer/__init__.py @@ -22,3 +22,5 @@ Isometry, Initialize, ) + +from .squ import SingleQubitUnitary diff --git a/qiskit/extensions/quantum_initializer/squ.py b/qiskit/extensions/quantum_initializer/squ.py new file mode 100644 index 000000000000..8356dc86fb9f --- /dev/null +++ b/qiskit/extensions/quantum_initializer/squ.py @@ -0,0 +1,163 @@ +# This code is part of Qiskit. +# +# (C) Copyright IBM 2017, 2019. +# +# 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. + +"""Decompose an arbitrary 2*2 unitary into three rotation gates: U=R_zR_yR_z. + +Note that the decomposition is up to a global phase shift. +(This is a well known decomposition, which can be found for example in Nielsen and Chuang's book +"Quantum computation and quantum information".) +""" + +import cmath + +import numpy as np + +from qiskit.circuit import QuantumRegister, QuantumCircuit +from qiskit.circuit.gate import Gate +from qiskit.circuit.exceptions import CircuitError +from qiskit.quantum_info.operators.predicates import is_unitary_matrix +from qiskit.exceptions import QiskitError +from qiskit.utils.deprecation import deprecate_func + +_EPS = 1e-10 # global variable used to chop very small numbers to zero + + +class SingleQubitUnitary(Gate): + """Single-qubit unitary. + + Args: + unitary_matrix: :math:`2 \times 2` unitary (given as a (complex) ``numpy.ndarray``). + mode: determines the used decomposition by providing the rotation axes. + up_to_diagonal: the single-qubit unitary is decomposed up to a diagonal matrix, + i.e. a unitary :math:`U'` is implemented such that there exists a diagonal + matrix :math:`D` with :math:`U = D U'`. + """ + + @deprecate_func( + since="0.45.0", + additional_msg="Instead, you can use qiskit.circuit.library.UnitaryGate.", + ) + def __init__(self, unitary_matrix, mode="ZYZ", up_to_diagonal=False): + """Create a new single qubit gate based on the unitary ``u``.""" + if mode not in ["ZYZ"]: + raise QiskitError("The decomposition mode is not known.") + # Check if the matrix u has the right dimensions and if it is a unitary + if unitary_matrix.shape != (2, 2): + raise QiskitError("The dimension of the input matrix is not equal to (2,2).") + if not is_unitary_matrix(unitary_matrix): + raise QiskitError("The 2*2 matrix is not unitary.") + + self.mode = mode + self.up_to_diagonal = up_to_diagonal + self._diag = None + + # Create new gate + super().__init__("squ", 1, [unitary_matrix]) + + def inverse(self): + """Return the inverse. + + Note that the resulting gate has an empty ``params`` property. + """ + inverse_gate = Gate( + name=self.name + "_dg", num_qubits=self.num_qubits, params=[] + ) # removing the params because arrays are deprecated + + definition = QuantumCircuit(*self.definition.qregs) + for inst in reversed(self._definition): + definition._append(inst.replace(operation=inst.operation.inverse())) + inverse_gate.definition = definition + return inverse_gate + + @property + def diag(self): + """Returns the diagonal gate D up to which the single-qubit unitary u is implemented. + + I.e. u=D.u', where u' is the unitary implemented by the found circuit. + """ + if self._diag is None: + self._define() + return self._diag + + def _define(self): + """Define the gate using the decomposition.""" + + if self.mode == "ZYZ": + circuit, diag = self._zyz_circuit() + else: + raise QiskitError("The decomposition mode is not known.") + + self._diag = diag + + self.definition = circuit + + def _zyz_circuit(self): + """Get the circuit for the ZYZ decomposition.""" + q = QuantumRegister(self.num_qubits) + qc = QuantumCircuit(q, name=self.name) + + diag = [1.0, 1.0] + alpha, beta, gamma, _ = self._zyz_dec() + + if abs(alpha) > _EPS: + qc.rz(alpha, q[0]) + if abs(beta) > _EPS: + qc.ry(beta, q[0]) + if abs(gamma) > _EPS: + if self.up_to_diagonal: + diag = [np.exp(-1j * gamma / 2.0), np.exp(1j * gamma / 2.0)] + else: + qc.rz(gamma, q[0]) + + return qc, diag + + def _zyz_dec(self): + """Finds rotation angles (a,b,c,d) in the decomposition u=exp(id)*Rz(c).Ry(b).Rz(a). + + Note that where "." denotes matrix multiplication. + """ + unitary = self.params[0] + u00 = unitary.item(0, 0) + u01 = unitary.item(0, 1) + u10 = unitary.item(1, 0) + u11 = unitary.item(1, 1) + # Handle special case if the entry (0,0) of the unitary is equal to zero + if np.abs(u00) < _EPS: + # Note that u10 can't be zero, since u is unitary (and u00 == 0) + gamma = cmath.phase(-u01 / u10) + delta = cmath.phase(u01 * np.exp(-1j * gamma / 2)) + return 0.0, -np.pi, -gamma, delta + # Handle special case if the entry (0,1) of the unitary is equal to zero + if np.abs(u01) < _EPS: + # Note that u11 can't be zero, since u is unitary (and u01 == 0) + gamma = cmath.phase(u00 / u11) + delta = cmath.phase(u00 * np.exp(-1j * gamma / 2)) + return 0.0, 0.0, -gamma, delta + beta = 2 * np.arccos(np.abs(u00)) + if np.sin(beta / 2) - np.cos(beta / 2) > 0: + gamma = cmath.phase(-u00 / u10) + alpha = cmath.phase(u00 / u01) + else: + gamma = -cmath.phase(-u10 / u00) + alpha = -cmath.phase(u01 / u00) + delta = cmath.phase(u00 * np.exp(-1j * (alpha + gamma) / 2)) + # The decomposition works with another convention for the rotation gates + # (the one using negative angles). + # Therefore, we have to take the inverse of the angles at the end. + return -alpha, -beta, -gamma, delta + + def validate_parameter(self, parameter): + """Single-qubit unitary gate parameter has to be an ndarray.""" + if isinstance(parameter, np.ndarray): + return parameter + else: + raise CircuitError(f"invalid param type {type(parameter)} in gate {self.name}") diff --git a/qiskit/extensions/simulator/__init__.py b/qiskit/extensions/simulator/__init__.py new file mode 100644 index 000000000000..069ec393979e --- /dev/null +++ b/qiskit/extensions/simulator/__init__.py @@ -0,0 +1,15 @@ +# This code is part of Qiskit. +# +# (C) Copyright IBM 2017. +# +# 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. + +"""Instructions usable by simulator backends.""" + +from .snapshot import Snapshot diff --git a/qiskit/extensions/simulator/snapshot.py b/qiskit/extensions/simulator/snapshot.py new file mode 100644 index 000000000000..ca45e56354ac --- /dev/null +++ b/qiskit/extensions/simulator/snapshot.py @@ -0,0 +1,70 @@ +# This code is part of Qiskit. +# +# (C) Copyright IBM 2017. +# +# 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. +""" +Simulator command to snapshot internal simulator representation. +""" + +from qiskit.circuit.instruction import Instruction +from qiskit.extensions.exceptions import QiskitError, ExtensionError + +from qiskit.utils.deprecation import deprecate_func + + +class Snapshot(Instruction): + """Simulator snapshot instruction.""" + + _directive = True + + @deprecate_func( + since="0.45.0", + additional_msg="The Snapshot instruction has been superseded by Qiskit Aer's save " + "instructions, see " + "https://qiskit.org/ecosystem/aer/apidocs/aer_library.html#saving-simulator-data.", + ) + def __init__(self, label, snapshot_type="statevector", num_qubits=0, num_clbits=0, params=None): + """Create new snapshot instruction. + + Args: + label (str): the snapshot label for result data. + snapshot_type (str): the type of the snapshot. + num_qubits (int): the number of qubits for the snapshot type [Default: 0]. + num_clbits (int): the number of classical bits for the snapshot type + [Default: 0]. + params (list or None): the parameters for snapshot_type [Default: None]. + + Raises: + ExtensionError: if snapshot label is invalid. + """ + if not isinstance(label, str): + raise ExtensionError("Snapshot label must be a string.") + self._snapshot_type = snapshot_type + if params is None: + params = [] + super().__init__("snapshot", num_qubits, num_clbits, params, label=label) + + def assemble(self): + """Assemble a QasmQobjInstruction""" + instruction = super().assemble() + instruction.snapshot_type = self._snapshot_type + return instruction + + def inverse(self): + """Special case. Return self.""" + return Snapshot(self.num_qubits, self.num_clbits, self.params[0], self.params[1]) + + @property + def snapshot_type(self): + """Return snapshot type""" + return self._snapshot_type + + def c_if(self, classical, val): + raise QiskitError("Snapshots are simulator directives and cannot be conditional.") diff --git a/releasenotes/notes/deprecate-extensions-046-2b98dce6fdfadc72.yaml b/releasenotes/notes/deprecate-extensions-046-2b98dce6fdfadc72.yaml index a1b9707dea28..c6537cacc16e 100644 --- a/releasenotes/notes/deprecate-extensions-046-2b98dce6fdfadc72.yaml +++ b/releasenotes/notes/deprecate-extensions-046-2b98dce6fdfadc72.yaml @@ -25,25 +25,3 @@ deprecations: * ``QuantumCircuit.ucrx``, * ``QuantumCircuit.ucry``, * ``QuantumCircuit.ucrz``. - -upgrade: - - | - The following, deprecated circuit instructions have been removed: - - * ``SingleQubitUnitary`` (instead use :class:`.library.UnitaryGate`), - * ``Snapshot`` (superseded by Qiskit Aer's save instructions), - - along with their circuit methods: - - * ``QuantumCircuit.snapshot``, - * ``QuantumCircuit.squ``. - - - | - Removed deprecated, duplicated :class:`.QuantumCircuit` methods. These include - - * ``QuantumCircuit.cnot``, instead use :meth:`.QuantumCircuit.cx`, - * ``QuantumCircuit.toffoli``, instead use :meth:`.QuantumCircuit.ccx`, - * ``QuantumCircuit.fredkin``, instead use :meth:`.QuantumCircuit.cswap`, - * ``QuantumCircuit.mct``, instead use :meth:`.QuantumCircuit.mcx`, - * ``QuantumCircuit.i``, instead use :meth:`.QuantumCircuit.id`. - \ No newline at end of file diff --git a/test/python/circuit/test_circuit_operations.py b/test/python/circuit/test_circuit_operations.py index e6e6f8c29bdb..3f773fb09abc 100644 --- a/test/python/circuit/test_circuit_operations.py +++ b/test/python/circuit/test_circuit_operations.py @@ -1259,6 +1259,28 @@ def instructions(): self.assertEqual(circuit, expected) self.assertEqual(circuit.name, "test") + def test_duplicated_methods_deprecation(self): + """Test the now deprecated, duplicated gate method emit a deprecation warning.""" + + # {duplicate: (use_this_instead, args)} + methods = { + "i": ("id", [0]), + "cnot": ("cx", [0, 1]), + "toffoli": ("ccx", [0, 1, 2]), + "mct": ("mcx", [[0, 1], 2]), + "fredkin": ("cswap", [0, 1, 2]), + } + + for old, (new, args) in methods.items(): + circuit = QuantumCircuit(3) + + with self.subTest(method=old): + + # check (1) the (pending) deprecation is raised + # and (2) the new method is documented there + with self.assertWarnsRegex(DeprecationWarning, new): + getattr(circuit, old)(*args) + class TestCircuitPrivateOperations(QiskitTestCase): """Direct tests of some of the private methods of QuantumCircuit. These do not represent diff --git a/test/python/circuit/test_circuit_properties.py b/test/python/circuit/test_circuit_properties.py index da9af61367a8..f2531954676e 100644 --- a/test/python/circuit/test_circuit_properties.py +++ b/test/python/circuit/test_circuit_properties.py @@ -19,6 +19,7 @@ from qiskit.circuit.library import RXGate, RYGate from qiskit.test import QiskitTestCase from qiskit.circuit.exceptions import CircuitError +from qiskit.extensions.simulator import Snapshot class TestCircuitProperties(QiskitTestCase): @@ -560,6 +561,80 @@ def test_circuit_depth_barriers3(self): circ.cx(2, 3) self.assertEqual(circ.depth(), 4) + def test_circuit_depth_snap1(self): + """Test circuit depth for snapshots #1.""" + + # ┌───┐ ░ + # q_0: ┤ H ├──■───░─────────── + # └───┘┌─┴─┐ ░ + # q_1: ─────┤ X ├─░─────────── + # └───┘ ░ ┌───┐ + # q_2: ───────────░─┤ H ├──■── + # ░ └───┘┌─┴─┐ + # q_3: ───────────░──────┤ X ├ + # ░ └───┘ + q = QuantumRegister(4, "q") + c = ClassicalRegister(4, "c") + circ = QuantumCircuit(q, c) + circ.h(0) + circ.cx(0, 1) + with self.assertWarns(DeprecationWarning): + circ.append(Snapshot("snap", num_qubits=4), [0, 1, 2, 3]) + circ.h(2) + circ.cx(2, 3) + self.assertEqual(circ.depth(), 4) + + def test_circuit_depth_snap2(self): + """Test circuit depth for snapshots #2.""" + + # ┌───┐ ░ ░ ░ + # q_0: ┤ H ├─░───■───░───────░────── + # └───┘ ░ ┌─┴─┐ ░ ░ + # q_1: ──────░─┤ X ├─░───────░────── + # ░ └───┘ ░ ┌───┐ ░ + # q_2: ──────░───────░─┤ H ├─░───■── + # ░ ░ └───┘ ░ ┌─┴─┐ + # q_3: ──────░───────░───────░─┤ X ├ + # ░ ░ ░ └───┘ + q = QuantumRegister(4, "q") + c = ClassicalRegister(4, "c") + circ = QuantumCircuit(q, c) + circ.h(0) + with self.assertWarns(DeprecationWarning): + circ.append(Snapshot("snap0", num_qubits=4), [0, 1, 2, 3]) + circ.cx(0, 1) + with self.assertWarns(DeprecationWarning): + circ.append(Snapshot("snap1", num_qubits=4), [0, 1, 2, 3]) + circ.h(2) + with self.assertWarns(DeprecationWarning): + circ.append(Snapshot("snap2", num_qubits=4), [0, 1, 2, 3]) + circ.cx(2, 3) + self.assertEqual(circ.depth(), 4) + + def test_circuit_depth_snap3(self): + """Test circuit depth for snapshots #3.""" + + # ┌───┐ ░ ░ + # q_0: ┤ H ├──■───░──░─────────── + # └───┘┌─┴─┐ ░ ░ + # q_1: ─────┤ X ├─░──░─────────── + # └───┘ ░ ░ ┌───┐ + # q_2: ───────────░──░─┤ H ├──■── + # ░ ░ └───┘┌─┴─┐ + # q_3: ───────────░──░──────┤ X ├ + # ░ ░ └───┘ + q = QuantumRegister(4, "q") + c = ClassicalRegister(4, "c") + circ = QuantumCircuit(q, c) + circ.h(0) + circ.cx(0, 1) + with self.assertWarns(DeprecationWarning): + circ.append(Snapshot("snap0", num_qubits=4), [0, 1, 2, 3]) + circ.append(Snapshot("snap1", num_qubits=4), [0, 1, 2, 3]) + circ.h(2) + circ.cx(2, 3) + self.assertEqual(circ.depth(), 4) + def test_circuit_depth_2qubit(self): """Test finding depth of two-qubit gates only.""" @@ -670,6 +745,21 @@ def test_circuit_size_2qubit(self): qc.rzz(0.1, q[1], q[2]) self.assertEqual(qc.size(lambda x: x.operation.num_qubits == 2), 2) + def test_circuit_size_ignores_barriers_snapshots(self): + """Circuit.size should not count barriers or snapshots.""" + q = QuantumRegister(4, "q") + c = ClassicalRegister(4, "c") + qc = QuantumCircuit(q, c) + + qc.h(q[0]) + qc.cx(q[0], q[1]) + self.assertEqual(qc.size(), 2) + qc.barrier(q) + self.assertEqual(qc.size(), 2) + with self.assertWarns(DeprecationWarning): + qc.append(Snapshot("snapshot_label", num_qubits=4), [0, 1, 2, 3]) + self.assertEqual(qc.size(), 2) + def test_circuit_count_ops(self): """Test circuit count ops.""" q = QuantumRegister(6, "q") diff --git a/test/python/circuit/test_squ.py b/test/python/circuit/test_squ.py new file mode 100644 index 000000000000..e80a17e20b68 --- /dev/null +++ b/test/python/circuit/test_squ.py @@ -0,0 +1,65 @@ +# This code is part of Qiskit. +# +# (C) Copyright IBM 2019. +# +# 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. + +# pylint: disable=invalid-name + +"""Single-qubit unitary tests.""" + +import unittest +from test import combine +import numpy as np +from ddt import ddt +from qiskit.quantum_info.random import random_unitary +from qiskit import BasicAer, QuantumCircuit, QuantumRegister +from qiskit.test import QiskitTestCase +from qiskit.extensions.quantum_initializer.squ import SingleQubitUnitary +from qiskit.compiler import transpile +from qiskit.quantum_info.operators.predicates import matrix_equal + +squs = [ + np.eye(2, 2), + np.array([[0.0, 1.0], [1.0, 0.0]]), + 1 / np.sqrt(2) * np.array([[1.0, 1.0], [-1.0, 1.0]]), + np.array([[np.exp(1j * 5.0 / 2), 0], [0, np.exp(-1j * 5.0 / 2)]]), + random_unitary(2, seed=42).data, +] + +up_to_diagonal_list = [True, False] + + +@ddt +class TestSingleQubitUnitary(QiskitTestCase): + """Qiskit ZYZ-decomposition tests.""" + + @combine(u=squs, up_to_diagonal=up_to_diagonal_list) + def test_squ(self, u, up_to_diagonal): + """Tests for single-qubit unitary decomposition.""" + qr = QuantumRegister(1, "qr") + qc = QuantumCircuit(qr) + with self.assertWarns(DeprecationWarning): + qc.squ(u, qr[0], up_to_diagonal=up_to_diagonal) + # Decompose the gate + qc = transpile(qc, basis_gates=["u1", "u3", "u2", "cx", "id"]) + # Simulate the decomposed gate + simulator = BasicAer.get_backend("unitary_simulator") + result = simulator.run(qc).result() + unitary = result.get_unitary(qc) + if up_to_diagonal: + with self.assertWarns(DeprecationWarning): + squ = SingleQubitUnitary(u, up_to_diagonal=up_to_diagonal) + unitary = np.dot(np.diagflat(squ.diag), unitary) + unitary_desired = u + self.assertTrue(matrix_equal(unitary_desired, unitary, ignore_phase=True)) + + +if __name__ == "__main__": + unittest.main() diff --git a/test/python/transpiler/test_unroller.py b/test/python/transpiler/test_unroller.py index c43953f221d9..a69d7667ef2b 100644 --- a/test/python/transpiler/test_unroller.py +++ b/test/python/transpiler/test_unroller.py @@ -16,6 +16,7 @@ from numpy import pi from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit +from qiskit.extensions.simulator import Snapshot from qiskit.transpiler.passes import Unroller from qiskit.converters import circuit_to_dag, dag_to_circuit from qiskit.quantum_info import Operator @@ -773,6 +774,15 @@ def test_unroll_z(self): self.ref_circuit.append(U3Gate(0, 0, pi), [0]) self.compare_dags() + def test_unroll_snapshot(self): + """test unroll snapshot""" + num_qubits = self.circuit.num_qubits + with self.assertWarns(DeprecationWarning): + instr = Snapshot("0", num_qubits=num_qubits) + self.circuit.append(instr, range(num_qubits)) + self.ref_circuit.append(instr, range(num_qubits)) + self.compare_dags() + def test_unroll_measure(self): """test unroll measure""" self.circuit.measure(self.qr, self.cr) diff --git a/test/python/visualization/references/test_latex_plot_barriers_false.tex b/test/python/visualization/references/test_latex_plot_barriers_false.tex index 8c256729101a..06e3519367ad 100644 --- a/test/python/visualization/references/test_latex_plot_barriers_false.tex +++ b/test/python/visualization/references/test_latex_plot_barriers_false.tex @@ -6,8 +6,8 @@ \begin{document} \scalebox{1.0}{ \Qcircuit @C=1.0em @R=0.2em @!R { \\ - \nghost{{q}_{0} : } & \lstick{{q}_{0} : } & \gate{\mathrm{H}} & \qw & \qw & \qw & \qw\\ - \nghost{{q}_{1} : } & \lstick{{q}_{1} : } & \qw & \qw & \gate{\mathrm{H}} & \qw & \qw\\ - \nghost{\mathrm{{c} : }} & \lstick{\mathrm{{c} : }} & \lstick{/_{_{2}}} \cw & \cw & \cw & \cw & \cw\\ + \nghost{{q}_{0} : } & \lstick{{q}_{0} : } & \gate{\mathrm{H}} & \qw & \qw & \qw & \qw & \qw\\ + \nghost{{q}_{1} : } & \lstick{{q}_{1} : } & \qw & \qw & \gate{\mathrm{H}} & \qw & \qw & \qw\\ + \nghost{\mathrm{{c} : }} & \lstick{\mathrm{{c} : }} & \lstick{/_{_{2}}} \cw & \cw & \cw & \cw & \cw & \cw\\ \\ }} \end{document} \ No newline at end of file diff --git a/test/python/visualization/references/test_latex_plot_barriers_true.tex b/test/python/visualization/references/test_latex_plot_barriers_true.tex index 399e2ecd4ece..b7679d27cd39 100644 --- a/test/python/visualization/references/test_latex_plot_barriers_true.tex +++ b/test/python/visualization/references/test_latex_plot_barriers_true.tex @@ -6,8 +6,8 @@ \begin{document} \scalebox{1.0}{ \Qcircuit @C=1.0em @R=0.2em @!R { \\ - \nghost{{q}_{0} : } & \lstick{{q}_{0} : } & \gate{\mathrm{H}} \barrier[0em]{1} & \qw & \qw & \qw & \qw\\ - \nghost{{q}_{1} : } & \lstick{{q}_{1} : } & \qw & \qw & \gate{\mathrm{H}} & \qw & \qw\\ - \nghost{\mathrm{{c} : }} & \lstick{\mathrm{{c} : }} & \lstick{/_{_{2}}} \cw & \cw & \cw & \cw & \cw\\ + \nghost{{q}_{0} : } & \lstick{{q}_{0} : } & \gate{\mathrm{H}} \barrier[0em]{1} & \qw & \qw \barrier[0em]{1} & \cds{0}{^{\mathrm{sn\,1}}} & \qw & \qw\\ + \nghost{{q}_{1} : } & \lstick{{q}_{1} : } & \qw & \qw & \gate{\mathrm{H}} & \qw & \qw & \qw\\ + \nghost{\mathrm{{c} : }} & \lstick{\mathrm{{c} : }} & \lstick{/_{_{2}}} \cw & \cw & \cw & \cw & \cw & \cw\\ \\ }} \end{document} \ No newline at end of file diff --git a/test/python/visualization/test_circuit_latex.py b/test/python/visualization/test_circuit_latex.py index 9f9de616d724..85f6e0c7c4e6 100644 --- a/test/python/visualization/test_circuit_latex.py +++ b/test/python/visualization/test_circuit_latex.py @@ -247,6 +247,12 @@ def test_plot_barriers(self): # check for other barrier like commands circuit.h(q[1]) + # this import appears to be unused, but is actually needed to get snapshot instruction + import qiskit.extensions.simulator # pylint: disable=unused-import + + with self.assertWarns(DeprecationWarning): + circuit.snapshot("sn 1") + # check the barriers plot properly when plot_barriers= True circuit_drawer(circuit, filename=filename1, output="latex_source", plot_barriers=True) diff --git a/test/visual/mpl/circuit/references/plot_barriers_true.png b/test/visual/mpl/circuit/references/plot_barriers_true.png index 2c25d7774bc872ec0480c7d88ac67074248fa9f4..2b712d8b1726a0e571a47c2a13fe83dea2b6b7c1 100644 GIT binary patch literal 7784 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

*8goj8)0W}-!(9fKrJueZ0? zJb?;QyDryO#$OVqusT#`9R}RA0~`xnn3&BM79jfz02Lt+2;y<(egrYIz=I7A!xNC& zr5AY(^gKK~KpJ)d?^g(t7gJyryFsRc7;hkv-Cu4b>fH|HrU)SA5)E<)Mt?(pT&k^1 z6!@)x^)6N8Qmdx`Y!e7L6a@Paa>8_GZAa91-42fZ@R(8-MF9~-mRiU$N?NsO!Rpxy zk$fZ&48)73mB4)w2HvUG`EB)y;Y_DMP8kHde)D1BJRXmjN%2yT=I|aT0gc}>6$(M0 zpERLewM5x^BLnyE0cCC0)YLQxE);m8Izejar80}|Lq6>ksW*V>?DsYa#CYZz4LcPN z6y$s{ufYvqfS8?G{8(iUKO=by;Ndp#ML25`DEc==@`y5i4X;t3T=T#K1c(dl!6;|D zayRJc|jQd0tkc-D2H)96(sIfb z*@+e`1uXfo$@y0i!{W64Z`^EPfw(uR?_#)3&;c`)n=2Ue)RGs}q#U=&pex72>}kqD z{w2HKsU+pUy=>HBhPI3P-jS9TRFJ%7AuZo&F*d*hSJ%<$ZhYr_3559fU*xfX`fy-R z>Bv}e?)l4sR1_(x zz5kx%xc)_?!w%$cw#j=ShOuu7Wt<xe_^vcDpJD>{k*?4OlGCi>Fh6>o$K0CF&UfcV z2KPeHxa^})#ZkW{*_wka&V!alb@0t&j`}Cv)@OCCZEOacIRp1g0T|;u*%(S+ZT_wi zmTLAR=VO-*9E)N4?r7D;VkmzK8kehN>b{z36>_gR0wK}f(z2Y#;AOB-T&hI8wja~0 z{*ip7(5n~pj7n#uJv9N9l}FaG=vo51Fm76kpOL}k>TrTFy;oIH(bwoeT!UiMIr;qw zI)bN>QDSf$n3X_ODx&H(jcX2ap=h z{PIOpcB4mccc&vz5bjGTCx&;~V+V^~)!(8u+9eLxI^=PojC?&M7V;p5;$G~~S=li) zqS~;K9wMy6b-Mp>yJxy{25Q&|PPckR%rFcL42)~NOJQ>^fqSn7>(*}pFkF_Gw*Ui; zs31Uwfet)Gf~4drHM6hjM&%UEXDG<~H~o|A>)kqze}vHcg6ItdBInx5(6${MV0h$q zuW2E_x7PR-{Me%TJZH~azj~EeCD^IHJeDG$XZUUxb%MEH?zLpzi^K6Th2>jdkVL$P zhK71H(umKt@|CPt_h_fc3}ha9Bg@a~hnAcvc04?=kU^a|8eOhmal!2CtA~CX85dRK zQd4t+ZAZSK>7aBIDqdHEqH=?!!!44hS-NIoo@fwLfO{=}-mjyq|HT&mJKxj$f4O~G bbV#?t{W`+7_wysb$PipbTN!oz?xX(z$~C%I literal 6940 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 Date: Mon, 8 Jan 2024 16:07:39 +0100 Subject: [PATCH 6/7] update deprecation message --- qiskit/circuit/quantumcircuit.py | 7 +++++++ qiskit/extensions/__init__.py | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/qiskit/circuit/quantumcircuit.py b/qiskit/circuit/quantumcircuit.py index f09477fff7cb..72b6b75b3232 100644 --- a/qiskit/circuit/quantumcircuit.py +++ b/qiskit/circuit/quantumcircuit.py @@ -4285,6 +4285,7 @@ def unitary( @deprecate_func( since="0.46.0", additional_msg="Instead, compose the circuit with a qiskit.circuit.library.Diagonal circuit.", + removal_timeline="in the 1.0.0 release", ) def diagonal(self, diag, qubit): """Attach a diagonal gate to a circuit. @@ -4333,6 +4334,7 @@ def diagonal(self, diag, qubit): @deprecate_func( since="0.46.0", additional_msg="Instead, append a qiskit.circuit.library.Isometry to the circuit.", + removal_timeline="in the 1.0.0 release", ) def iso( self, @@ -4402,6 +4404,7 @@ def iso( @deprecate_func( since="0.46.0", additional_msg="Instead, append a qiskit.circuit.library.HamiltonianGate to the circuit.", + removal_timeline="in the 1.0.0 release", ) def hamiltonian(self, operator, time, qubits, label=None): """Apply hamiltonian evolution to qubits. @@ -4431,6 +4434,7 @@ def hamiltonian(self, operator, time, qubits, label=None): @deprecate_func( since="0.46.0", additional_msg="Instead, append a qiskit.circuit.library.UCGate to the circuit.", + removal_timeline="in the 1.0.0 release", ) def uc(self, gate_list, q_controls, q_target, up_to_diagonal=False): """Attach a uniformly controlled gates (also called multiplexed gates) to a circuit. @@ -4498,6 +4502,7 @@ def uc(self, gate_list, q_controls, q_target, up_to_diagonal=False): @deprecate_func( since="0.46.0", additional_msg="Instead, append a qiskit.circuit.library.UCRXGate to the circuit.", + removal_timeline="in the 1.0.0 release", ) def ucrx( self, @@ -4558,6 +4563,7 @@ def ucrx( @deprecate_func( since="0.46.0", additional_msg="Instead, append a qiskit.circuit.library.UCRYGate to the circuit.", + removal_timeline="in the 1.0.0 release", ) def ucry( self, @@ -4618,6 +4624,7 @@ def ucry( @deprecate_func( since="0.46.0", additional_msg="Instead, append a qiskit.circuit.library.UCRZGate to the circuit.", + removal_timeline="in the 1.0.0 release", ) def ucrz( self, diff --git a/qiskit/extensions/__init__.py b/qiskit/extensions/__init__.py index 635ef4a0d7c5..abf15f1325f5 100644 --- a/qiskit/extensions/__init__.py +++ b/qiskit/extensions/__init__.py @@ -62,8 +62,8 @@ from .simulator import Snapshot warnings.warn( - "The qiskit.extensions module is deprecated since Qiskit 0.46.0. It will be deprecated " - "in a following release, no sooner than 3 months after the 0.46.0 release.", + "The qiskit.extensions module is deprecated since Qiskit 0.46.0. It will be removed " + "in the Qiskit 1.0 release.", stacklevel=2, category=DeprecationWarning, ) From 5a32fc618f2063fc549f65fc266c039472333e62 Mon Sep 17 00:00:00 2001 From: Julien Gacon Date: Tue, 9 Jan 2024 11:51:05 +0100 Subject: [PATCH 7/7] Filter Aer's extensions deprecation warning --- qiskit/test/base.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/qiskit/test/base.py b/qiskit/test/base.py index 839e15b0191f..65ef6c3cce20 100644 --- a/qiskit/test/base.py +++ b/qiskit/test/base.py @@ -247,6 +247,9 @@ def setUpClass(cls): r"The method ``qiskit\.circuit\.quantumcircuit\.QuantumCircuit\.i\(\)`` is " r"deprecated as of qiskit 0\.45\.0\. It will be removed no earlier than 3 " r"months after the release date\. Use QuantumCircuit\.id as direct replacement\.", + # This warning will be fixed once Qiskit/qiskit-aer#2023 is released. + "The qiskit.extensions module is deprecated since Qiskit 0.46.0. It will be removed " + "in the Qiskit 1.0 release.", ] for msg in allow_aer_DeprecationWarning_message: