def on_gate(self, cmd: GateCmd) -> None: affected_qubit_ids: Set[int] = {cmd._target_qubit_id } | cmd._control_qubit_ids inverse_gate, inverse_params = invert_gate(cmd._gate, cmd._params) eliminate = True for qubit_id in affected_qubit_ids: if not self._commands_stack[qubit_id]: eliminate = False continue _, last_cmd = self._commands_stack[qubit_id][-1] if not isinstance(last_cmd, GateCmd): eliminate = False continue if last_cmd._control_qubit_ids != cmd._control_qubit_ids: eliminate = False if last_cmd._target_qubit_id != cmd._target_qubit_id: eliminate = False if last_cmd._gate != inverse_gate: eliminate = False if last_cmd._params != inverse_params: # TODO(adsz): Allow approx. eliminate = False if eliminate: for qubit_id in affected_qubit_ids: self._commands_stack[qubit_id].pop() else: for qubit_id in affected_qubit_ids: self._commands_stack[qubit_id].append((self._id, cmd))
def inverse_command(command: ICommand): if not isinstance(command, GateCmd): raise ValueError(f"Inverse of {type(command)} is impossible.") inv_gate, inv_params = invert_gate(command._gate, command._params) return GateCmd(inv_gate, command.get_target_qubit_id(), command.get_control_qubit_ids(), inv_params)
def test_inverse_u3(self) -> None: self.assertEqual(invert_gate(U3_GATE, [0, 0, 0]), (U3_GATE, [0, 0, 0])) self.assertEqual(invert_gate(U3_GATE, [2.2, 3.3, 4.4]), (U3_GATE, [-2.2, -4.4, -3.3]))
def test_inverse_h(self) -> None: self.assertEqual(invert_gate(H_GATE, []), (H_GATE, []))