Skip to content

Commit e441ebb

Browse files
committed
_gate_to_circuit
1 parent a711f5f commit e441ebb

2 files changed

Lines changed: 34 additions & 59 deletions

File tree

qiskit/circuit/add_control.py

Lines changed: 0 additions & 32 deletions
This file was deleted.

qiskit/circuit/gate.py

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,8 @@ def control(
136136
if not annotated: # captures both None and False
137137
# pylint: disable=cyclic-import
138138

139-
cgate = self._control(
140-
num_ctrl_qubits=num_ctrl_qubits, label=label, ctrl_state=ctrl_state
139+
cgate = Gate._control(
140+
self, num_ctrl_qubits=num_ctrl_qubits, label=label, ctrl_state=ctrl_state
141141
)
142142
if self.label is not None:
143143
cgate.base_gate = cgate.base_gate.to_mutable()
@@ -148,8 +148,9 @@ def control(
148148
self, ControlModifier(num_ctrl_qubits=num_ctrl_qubits, ctrl_state=ctrl_state)
149149
)
150150

151+
@staticmethod
151152
def _control(
152-
self: Gate,
153+
operation: Gate,
153154
num_ctrl_qubits: int | None = 1,
154155
label: str | None = None,
155156
ctrl_state: str | int | None = None,
@@ -161,7 +162,7 @@ def _control(
161162
and `cx` gates.
162163
163164
Args:
164-
self: The gate used to create the ControlledGate.
165+
operation: The gate used to create the ControlledGate.
165166
num_ctrl_qubits: The number of controls to add to gate (default=1).
166167
label: An optional gate label.
167168
ctrl_state: The control state in decimal or as
@@ -185,24 +186,24 @@ def _control(
185186
ctrl_state = _ctrl_state_to_int(ctrl_state, num_ctrl_qubits)
186187

187188
q_control = QuantumRegister(num_ctrl_qubits, name="control")
188-
q_target = QuantumRegister(self.num_qubits, name="target")
189+
q_target = QuantumRegister(operation.num_qubits, name="target")
189190
q_ancillae = None # TODO: add
190-
controlled_circ = QuantumCircuit(q_control, q_target, name=f"c_{self.name}")
191-
if isinstance(self, controlledgate.ControlledGate):
192-
original_ctrl_state = self.ctrl_state
191+
controlled_circ = QuantumCircuit(q_control, q_target, name=f"c_{operation.name}")
192+
if isinstance(operation, controlledgate.ControlledGate):
193+
original_ctrl_state = operation.ctrl_state
193194
global_phase = 0
194-
if self.name == "x" or (
195-
isinstance(self, controlledgate.ControlledGate) and self.base_gate.name == "x"
195+
if operation.name == "x" or (
196+
isinstance(operation, controlledgate.ControlledGate) and operation.base_gate.name == "x"
196197
):
197198
controlled_circ.mcx(q_control[:] + q_target[:-1], q_target[-1], q_ancillae)
198-
if self.definition is not None and self.definition.global_phase:
199-
global_phase += self.definition.global_phase
199+
if operation.definition is not None and operation.definition.global_phase:
200+
global_phase += operation.definition.global_phase
200201
else:
201202
basis = ["p", "u", "x", "z", "rx", "ry", "rz", "cx"]
202-
if isinstance(self, controlledgate.ControlledGate):
203-
self = self.to_mutable()
204-
self.ctrl_state = None
205-
unrolled_gate = self._unroll_gate(basis_gates=basis)
203+
if isinstance(operation, controlledgate.ControlledGate):
204+
operation = operation.to_mutable()
205+
operation.ctrl_state = None
206+
unrolled_gate = operation._unroll_gate(basis_gates=basis)
206207
if unrolled_gate.definition.global_phase:
207208
global_phase += unrolled_gate.definition.global_phase
208209

@@ -305,17 +306,17 @@ def _control(
305306
controlled_circ.p(global_phase, q_control)
306307
else:
307308
controlled_circ.mcp(global_phase, q_control[:-1], q_control[-1])
308-
if isinstance(self, controlledgate.ControlledGate):
309-
self.ctrl_state = original_ctrl_state
310-
new_num_ctrl_qubits = num_ctrl_qubits + self.num_ctrl_qubits
311-
new_ctrl_state = self.ctrl_state << num_ctrl_qubits | ctrl_state
312-
base_name = self.base_gate.name
313-
base_gate = self.base_gate
309+
if isinstance(operation, controlledgate.ControlledGate):
310+
operation.ctrl_state = original_ctrl_state
311+
new_num_ctrl_qubits = num_ctrl_qubits + operation.num_ctrl_qubits
312+
new_ctrl_state = operation.ctrl_state << num_ctrl_qubits | ctrl_state
313+
base_name = operation.base_gate.name
314+
base_gate = operation.base_gate
314315
else:
315316
new_num_ctrl_qubits = num_ctrl_qubits
316317
new_ctrl_state = ctrl_state
317-
base_name = self.name
318-
base_gate = self
318+
base_name = operation.name
319+
base_gate = operation
319320
# In order to maintain some backward compatibility with gate names this
320321
# uses a naming convention where if the number of controls is <=2 the gate
321322
# is named like "cc<base_gate.name>", else it is named like
@@ -328,7 +329,7 @@ def _control(
328329
cgate = controlledgate.ControlledGate(
329330
new_name,
330331
controlled_circ.num_qubits,
331-
self.params,
332+
operation.params,
332333
label=label,
333334
num_ctrl_qubits=new_num_ctrl_qubits,
334335
definition=controlled_circ,
@@ -341,10 +342,16 @@ def _unroll_gate(self, basis_gates):
341342
"""Unrolls a gate, possibly composite, to the target basis"""
342343
from qiskit.transpiler import PassManager
343344
from qiskit.transpiler.passes.basis import BasisTranslator, UnrollCustomDefinitions
344-
from .add_control import _gate_to_circuit
345+
from qiskit import QuantumCircuit, QuantumRegister
345346
from qiskit.circuit.equivalence_library import SessionEquivalenceLibrary as sel
346347

347-
circ = _gate_to_circuit(self)
348+
if hasattr(self, "definition") and self.definition is not None:
349+
circ = self.definition
350+
else:
351+
qr = QuantumRegister(self.num_qubits)
352+
circ = QuantumCircuit(qr, name=self.name)
353+
circ.append(self, qr)
354+
348355
pm = PassManager(
349356
[
350357
UnrollCustomDefinitions(sel, basis_gates=basis_gates),

0 commit comments

Comments
 (0)