def _apply_unitary_(self, args: protocols.ApplyUnitaryArgs) -> np.ndarray: control = args.axes[0] rest = args.axes[1:] active = linalg.slice_for_qubits_equal_to([control], 1) sub_axes = [r - int(r > control) for r in rest] target_view = args.target_tensor[active] buffer_view = args.available_buffer[active] result = protocols.apply_unitary(self.sub_gate, protocols.ApplyUnitaryArgs( target_view, buffer_view, sub_axes), default=NotImplemented) if result is NotImplemented: return NotImplemented if result is target_view: return args.target_tensor if result is buffer_view: inactive = linalg.slice_for_qubits_equal_to([control], 0) args.available_buffer[inactive] = args.target_tensor[inactive] return args.available_buffer # HACK: assume they didn't somehow escape the slice view and edit the # rest of target_tensor. args.target_tensor[active] = result return args.target_tensor
def _apply_unitary_( self, args: protocols.ApplyUnitaryArgs) -> Optional[np.ndarray]: if self._exponent != 1: return NotImplemented zero = args.subspace_index(0) one = args.subspace_index(1) args.available_buffer[zero] = args.target_tensor[one] args.available_buffer[one] = args.target_tensor[zero] p = 1j**(2 * self._exponent * self._global_shift) if p != 1: args.available_buffer *= p return args.available_buffer
def _apply_unitary_( self, args: protocols.ApplyUnitaryArgs) -> Optional[np.ndarray]: if self._exponent != 1: return NotImplemented zero = args.subspace_index(0) one = args.subspace_index(1) args.target_tensor[one] -= args.target_tensor[zero] args.target_tensor[one] *= -0.5 args.target_tensor[zero] -= args.target_tensor[one] p = 1j**(2 * self._exponent * self._global_shift) args.target_tensor *= np.sqrt(2) * p return args.target_tensor
def _apply_unitary_(self, args: protocols.ApplyUnitaryArgs ) -> Optional[np.ndarray]: if self._exponent != 1: return None zo = args.subspace_index(0b01) oz = args.subspace_index(0b10) args.available_buffer[zo] = args.target_tensor[zo] args.target_tensor[zo] = args.target_tensor[oz] args.target_tensor[oz] = args.available_buffer[zo] p = 1j**(2 * self._exponent * self._global_shift) if p != 1: args.target_tensor *= p return args.target_tensor
def _apply_unitary_(self, args: protocols.ApplyUnitaryArgs) -> np.ndarray: n = len(self.controls) control_axes = args.axes[:n] sub_axes = args.axes[n:] active = linalg.slice_for_qubits_equal_to(control_axes, -1) view_axes = _positions_after_removals_at(initial_positions=sub_axes, removals=control_axes) target_view = args.target_tensor[active] buffer_view = args.available_buffer[active] result = protocols.apply_unitary(self.sub_operation, protocols.ApplyUnitaryArgs( target_view, buffer_view, view_axes), default=NotImplemented) if result is NotImplemented: return NotImplemented if result is target_view: return args.target_tensor # HACK: assume they didn't somehow escape the slice view and edit the # rest of target_tensor. args.target_tensor[active] = result return args.target_tensor
def _apply_unitary_(self, args: protocols.ApplyUnitaryArgs) -> np.ndarray: if protocols.is_parameterized(self): return NotImplemented ooo = args.subspace_index(0b111) args.target_tensor[ooo] *= np.exp(1j * self.exponent * np.pi) p = 1j**(2 * self._exponent * self._global_shift) if p != 1: args.target_tensor *= p return args.target_tensor
def _apply_unitary_(self, args: protocols.ApplyUnitaryArgs) -> np.ndarray: if self._is_parameterized_(): return NotImplemented for index, angle in enumerate(self._diag_angles_radians): little_endian_index = 4 * (index & 1) + 2 * ((index >> 1) & 1) + ( (index >> 2) & 1) subspace_index = args.subspace_index(little_endian_index) args.target_tensor[subspace_index] *= np.exp(1j * angle) return args.target_tensor
def _apply_unitary_( self, args: protocols.ApplyUnitaryArgs) -> Optional[np.ndarray]: if protocols.is_parameterized(self): return None one = args.subspace_index(1) c = 1j**(self._exponent * 2) args.target_tensor[one] *= c p = 1j**(2 * self._exponent * self._global_shift) if p != 1: args.target_tensor *= p return args.target_tensor
def _apply_unitary_( self, args: protocols.ApplyUnitaryArgs ) -> Union[np.ndarray, NotImplementedType]: if protocols.is_parameterized(self): return NotImplemented c = 1j**(2 * self._exponent) one_one = args.subspace_index(0b11) args.target_tensor[one_one] *= c p = 1j**(2 * self._exponent * self._global_shift) if p != 1: args.target_tensor *= p return args.target_tensor
def _apply_unitary_( self, args: protocols.ApplyUnitaryArgs) -> Optional[np.ndarray]: if protocols.is_parameterized(self): return None global_phase = 1j**(2 * self._exponent * self._global_shift) if global_phase != 1: args.target_tensor *= global_phase relative_phase = 1j**(2 * self.exponent) zo = args.subspace_index(0b01) oz = args.subspace_index(0b10) args.target_tensor[oz] *= relative_phase args.target_tensor[zo] *= relative_phase return args.target_tensor