Пример #1
0
    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
Пример #2
0
 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
Пример #3
0
    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
Пример #4
0
    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
Пример #5
0
    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
Пример #6
0
 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
Пример #7
0
 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
Пример #8
0
    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
Пример #9
0
    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
Пример #10
0
    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