Added the ctrl_state parameter to mcx() function (#12050)

* Added the ctrl_state parameter to mcx() function

* Fixing the Linting issue

* Fixed the Linting Issue

* Fixing Linting issue

* Added unit tests for mcx() func for ctrl_state param

* Fixed Linting Issue

* Added releasenotes for ctrl_state in mcx()

* Resolved Minor Changes
This commit is contained in:
Siddhant 2024-03-27 23:33:14 +05:30 committed by GitHub
parent df59ab0c63
commit 2427a3f9bf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 48 additions and 7 deletions

View File

@ -4203,6 +4203,7 @@ class QuantumCircuit:
target_qubit: QubitSpecifier, target_qubit: QubitSpecifier,
ancilla_qubits: QubitSpecifier | Sequence[QubitSpecifier] | None = None, ancilla_qubits: QubitSpecifier | Sequence[QubitSpecifier] | None = None,
mode: str = "noancilla", mode: str = "noancilla",
ctrl_state: str | int | None = None,
) -> InstructionSet: ) -> InstructionSet:
"""Apply :class:`~qiskit.circuit.library.MCXGate`. """Apply :class:`~qiskit.circuit.library.MCXGate`.
@ -4221,6 +4222,9 @@ class QuantumCircuit:
target_qubit: The qubit(s) targeted by the gate. target_qubit: The qubit(s) targeted by the gate.
ancilla_qubits: The qubits used as the ancillae, if the mode requires them. ancilla_qubits: The qubits used as the ancillae, if the mode requires them.
mode: The choice of mode, explained further above. mode: The choice of mode, explained further above.
ctrl_state:
The control state in decimal, or as a bitstring (e.g. '1'). Defaults to controlling
on the '1' state.
Returns: Returns:
A handle to the instructions created. A handle to the instructions created.
@ -4234,14 +4238,16 @@ class QuantumCircuit:
num_ctrl_qubits = len(control_qubits) num_ctrl_qubits = len(control_qubits)
available_implementations = { available_implementations = {
"noancilla": MCXGrayCode(num_ctrl_qubits), "noancilla": MCXGrayCode(num_ctrl_qubits, ctrl_state=ctrl_state),
"recursion": MCXRecursive(num_ctrl_qubits), "recursion": MCXRecursive(num_ctrl_qubits, ctrl_state=ctrl_state),
"v-chain": MCXVChain(num_ctrl_qubits, False), "v-chain": MCXVChain(num_ctrl_qubits, False, ctrl_state=ctrl_state),
"v-chain-dirty": MCXVChain(num_ctrl_qubits, dirty_ancillas=True), "v-chain-dirty": MCXVChain(num_ctrl_qubits, dirty_ancillas=True, ctrl_state=ctrl_state),
# outdated, previous names # outdated, previous names
"advanced": MCXRecursive(num_ctrl_qubits), "advanced": MCXRecursive(num_ctrl_qubits, ctrl_state=ctrl_state),
"basic": MCXVChain(num_ctrl_qubits, dirty_ancillas=False), "basic": MCXVChain(num_ctrl_qubits, dirty_ancillas=False, ctrl_state=ctrl_state),
"basic-dirty-ancilla": MCXVChain(num_ctrl_qubits, dirty_ancillas=True), "basic-dirty-ancilla": MCXVChain(
num_ctrl_qubits, dirty_ancillas=True, ctrl_state=ctrl_state
),
} }
# check ancilla input # check ancilla input

View File

@ -0,0 +1,18 @@
---
features:
- |
Added `ctrl_state` parameter to :func:`QuantumCircuit.mcx()`.
The :func:`QuantumCircuit.mcx()` function in the quantum circuit library has
been enhanced to include a `ctrl_state` parameter, allowing users to specify
the control state of the multi-controlled X gate. This parameter can accept
either a decimal value or a bitstring and defaults to controlling the '1'
state if not provided.
.. code-block:: python
from qiskit import QuantumCircuit
qc = QuantumCircuit(3, 3)
qc.mcx([0, 1], 2, ctrl_state="00")

View File

@ -970,6 +970,23 @@ class TestControlledGate(QiskitTestCase):
ref_circuit.append(ccx, [qreg[0], qreg[1], qreg[2]]) ref_circuit.append(ccx, [qreg[0], qreg[1], qreg[2]])
self.assertEqual(qc, ref_circuit) self.assertEqual(qc, ref_circuit)
@data((4, [0, 1, 2], 3, "010"), (4, [2, 1, 3], 0, 2))
@unpack
def test_multi_control_x_ctrl_state_parameter(
self, num_qubits, ctrl_qubits, target_qubit, ctrl_state
):
"""To check the consistency of parameters ctrl_state in MCX"""
qc = QuantumCircuit(num_qubits)
qc.mcx(ctrl_qubits, target_qubit, ctrl_state=ctrl_state)
operator_qc = Operator(qc)
qc1 = QuantumCircuit(num_qubits)
gate = MCXGate(num_ctrl_qubits=len(ctrl_qubits), ctrl_state=ctrl_state)
qc1.append(gate, ctrl_qubits + [target_qubit])
operator_qc1 = Operator(qc1)
self.assertEqual(operator_qc, operator_qc1)
def test_open_control_composite_unrolling(self): def test_open_control_composite_unrolling(self):
"""test unrolling of open control gates when gate is in basis""" """test unrolling of open control gates when gate is in basis"""
# create composite gate # create composite gate