def _apply_unitary_strat( val: Any, args: 'ApplyMixtureArgs', is_density_matrix: bool ) -> Optional[np.ndarray]: """Attempt to use `apply_unitary` and return the result. If `val` does not support `apply_unitary` returns None. """ left_args = ApplyUnitaryArgs( target_tensor=args.target_tensor, available_buffer=args.auxiliary_buffer0, axes=args.left_axes, ) left_result = apply_unitary(val, left_args, None) if left_result is None: return None if not is_density_matrix: return left_result # cast is ok, is_density_matrix being false tells us right_axes isn't None. right_args = ApplyUnitaryArgs( target_tensor=np.conjugate(left_result), available_buffer=args.auxiliary_buffer0, axes=cast(Tuple[int], args.right_axes), ) right_result = apply_unitary(val, right_args) np.conjugate(right_result, out=right_result) return right_result
def _apply_unitary(val: Any, args: 'ApplyChannelArgs') -> Optional[np.ndarray]: """Attempt to use `apply_unitary` and return the result. If `val` does not support `apply_unitary` returns None. """ left_args = ApplyUnitaryArgs(target_tensor=args.target_tensor, available_buffer=args.auxiliary_buffer0, axes=args.left_axes) left_result = apply_unitary(val, left_args, None) if left_result is None: return None right_args = ApplyUnitaryArgs(target_tensor=np.conjugate(left_result), available_buffer=args.out_buffer, axes=args.right_axes) right_result = apply_unitary(val, right_args) np.conjugate(right_result, out=right_result) return right_result
def _strat_has_unitary_from_apply_unitary(val: Any) -> Optional[bool]: """Attempts to infer a value's unitary-ness via its _apply_unitary_ method.""" method = getattr(val, '_apply_unitary_', None) if method is None: return None val_qid_shape = qid_shape_protocol.qid_shape(val, None) if val_qid_shape is None: return None state = qis.one_hot(shape=val_qid_shape, dtype=np.complex64) buffer = np.empty_like(state) result = method(ApplyUnitaryArgs(state, buffer, range(len(val_qid_shape)))) if result is NotImplemented: return None return result is not None
def _strat_unitary_from_decompose(val: Any) -> Optional[np.ndarray]: """Attempts to compute a value's unitary via its _decompose_ method.""" # Check if there's a decomposition. operations, qubits, val_qid_shape = _try_decompose_into_operations_and_qubits( val) if operations is None: return NotImplemented # Apply sub-operations' unitary effects to an identity matrix. state = qis.eye_tensor(val_qid_shape, dtype=np.complex128) buffer = np.empty_like(state) result = apply_unitaries( operations, qubits, ApplyUnitaryArgs(state, buffer, range(len(val_qid_shape))), None) # Package result. if result is None: return None state_len = np.prod(val_qid_shape, dtype=np.int64) return result.reshape((state_len, state_len))
def _strat_unitary_from_apply_unitary(val: Any) -> Optional[np.ndarray]: """Attempts to compute a value's unitary via its _apply_unitary_ method.""" # Check for the magic method. method = getattr(val, '_apply_unitary_', None) if method is None: return NotImplemented # Get the qid_shape. val_qid_shape = qid_shape_protocol.qid_shape(val, None) if val_qid_shape is None: return NotImplemented # Apply unitary effect to an identity matrix. state = qis.eye_tensor(val_qid_shape, dtype=np.complex128) buffer = np.empty_like(state) result = method(ApplyUnitaryArgs(state, buffer, range(len(val_qid_shape)))) if result is NotImplemented or result is None: return result state_len = np.prod(val_qid_shape, dtype=np.int64) return result.reshape((state_len, state_len))