def _get_on_gate_commands(self, node: GateNode) -> List[ICommand]: if not self._control_mapping: return [ GateCmd(node.gate, node.get_target_qubit_id(), params=node.params) ] negate_negative_commands: List[ICommand] = [] for qubit_id, mask in self._control_mapping.items(): if mask == 0: negate_negative_commands.append(GateCmd(X_GATE, qubit_id)) num_ancillas = 0 commands: List[ICommand] control_commands: List[ICommand] = [] control_qubit_ids = list(self._control_mapping) max_controls = 2 if node.gate == X_GATE else 1 # TODO(adsz): to be defined by gate / target architecture while len(control_qubit_ids) > max_controls: control_1 = control_qubit_ids.pop(0) control_2 = control_qubit_ids.pop(0) ancilla = self._rsrc.allocate_qubit() num_ancillas += 1 control_qubit_ids.append(ancilla) control_commands.append( GateCmd(X_GATE, ancilla, control_qubit_ids={control_1, control_2})) controlled_command = GateCmd(node.gate, node.get_target_qubit_id(), params=node.params, control_qubit_ids=set(control_qubit_ids)) commands = (control_commands + [controlled_command] + self._inversed(control_commands)) self._rsrc.free_qubits(num_ancillas) return (negate_negative_commands + commands + self._inversed(negate_negative_commands))
def H(target_qubit: QubitNode) -> GateNode: return GateNode(H_GATE, target_qubit)
def Z(target_qubit: QubitNode) -> GateNode: return GateNode(Z_GATE, target_qubit)
def Y(target_qubit: QubitNode) -> GateNode: return GateNode(Y_GATE, target_qubit)
def X(target_qubit: QubitNode) -> GateNode: return GateNode(X_GATE, target_qubit)
def CCX(control_qubit_1: QubitNode, control_qubit_2: QubitNode, target_qubit: QubitNode) -> IASTNode: return IfNode(All([control_qubit_1, control_qubit_2])).Then(GateNode(X_GATE, target_qubit))
def CX(control_qubit: QubitNode, target_qubit: QubitNode) -> IASTNode: return IfNode(All(control_qubit)).Then(GateNode(X_GATE, target_qubit))
def U3(target_qubit: QubitNode, arg1: float, arg2: float, arg3: float) -> IASTNode: return GateNode(U3_GATE, target_qubit, params=[arg1, arg2, arg3])
def U2(target_qubit: QubitNode, arg1: float, arg2: float) -> IASTNode: return GateNode(U3_GATE, target_qubit, params=[pi / 2, arg1, arg2])
def U1(target_qubit: QubitNode, arg1: float) -> IASTNode: return GateNode(U3_GATE, target_qubit, params=[0, 0, arg1])