Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 21 additions & 4 deletions qiskit/circuit/library/standard_gates/x.py
Original file line number Diff line number Diff line change
Expand Up @@ -826,11 +826,11 @@ class MCXGate(ControlledGate):
def __new__(cls, num_ctrl_qubits=None, label=None, ctrl_state=None):
"""Create a new MCX instance.

Depending on the number of controls, this creates an explicit CX, CCX, C3X or C4X
instance or a generic MCX gate.
Depending on the number of controls and which mode of the MCX, this creates an
explicit CX, CCX, C3X or C4X instance or a generic MCX gate.
"""
# these gates will always be implemented for all modes of the MCX if the number of control
# qubits matches this
# The CXGate and CCXGate will be implemented for all modes of the MCX, and
# the C3XGate and C4XGate will be implemented in the MCXGrayCode class.
explicit = {
1: CXGate,
2: CCXGate
Expand Down Expand Up @@ -909,6 +909,23 @@ class MCXGrayCode(MCXGate):

This delegates the implementation to the MCU1 gate, since :math:`X = H \cdot U1(\pi) \cdot H`.
"""
def __new__(cls, num_ctrl_qubits=None, label=None, ctrl_state=None):
"""Create a new MCXGrayCode instance
"""
# if 1 to 4 control qubits, create explicit gates
explicit = {
1: CXGate,
2: CCXGate,
3: C3XGate,
4: C4XGate
}
if num_ctrl_qubits in explicit.keys():
gate_class = explicit[num_ctrl_qubits]
gate = gate_class.__new__(gate_class, label=label, ctrl_state=ctrl_state)
# if __new__ does not return the same type as cls, init is not called
gate.__init__(label=label, ctrl_state=ctrl_state)
return gate
return super().__new__(cls)

def __init__(self, num_ctrl_qubits, label=None, ctrl_state=None):
super().__init__(num_ctrl_qubits, label=label, ctrl_state=ctrl_state, _name='mcx_gray')
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
upgrade:
- |
The class :class:`~qiskit.library.standard_gates.x.MCXGrayCode` will now create
a ``C3XGate`` if ``num_ctrl_qubits`` is 3 and a ``C4XGate`` if ``num_ctrl_qubits``
is 4. This is in addition to the previous functionality where for any of the
modes of the :class:'qiskit.library.standard_gates.x.MCXGate`, if ``num_ctrl_bits``
is 1, a ``CXGate`` is created, and if 2, a ``CCXGate`` is created.
8 changes: 8 additions & 0 deletions test/python/circuit/test_controlled_gate.py
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,14 @@ def test_mcx_gates_yield_explicit_gates(self, num_ctrl_qubits):
explicit = {1: CXGate, 2: CCXGate}
self.assertEqual(cls, explicit[num_ctrl_qubits])

@data(1, 2, 3, 4)
def test_mcxgraycode_gates_yield_explicit_gates(self, num_ctrl_qubits):
"""Test creating an mcx gate calls MCXGrayCode and yeilds explicit definition."""
qc = QuantumCircuit(num_ctrl_qubits+1)
qc.mcx(list(range(num_ctrl_qubits)), [num_ctrl_qubits])
explicit = {1: CXGate, 2: CCXGate, 3: C3XGate, 4: C4XGate}
self.assertEqual(type(qc[0][0]), explicit[num_ctrl_qubits])

@data(3, 4, 5, 8)
def test_mcx_gates(self, num_ctrl_qubits):
"""Test the mcx gates."""
Expand Down