Exemple #1
0
def _qudit_values_to_state_tensor(*, state: np.ndarray, qid_shape: Tuple[int,
                                                                         ...],
                                  dtype: Type[np.number]) -> np.ndarray:

    for i in range(len(qid_shape)):
        s = state[i]
        q = qid_shape[i]
        if not 0 <= s < q:
            raise ValueError(
                f'Qudit value {s} at index {i} is out of bounds for '
                f'qudit dimension {q}.\n'
                f'\n'
                f'qid_shape={qid_shape!r}\n'
                f'state={state!r}\n')

    if state.dtype.kind[0] not in '?bBiu':
        raise ValueError(f'Expected a bool or int entry for each qudit in '
                         f'`state`, because len(state) == len(qid_shape), '
                         f'but got dtype {state.dtype}.'
                         f'\n'
                         f'qid_shape={qid_shape!r}\n'
                         f'state={state!r}\n')

    return linalg.one_hot(index=tuple(int(e) for e in state),
                          shape=qid_shape,
                          dtype=dtype)
def to_valid_state_vector(
        state_rep: Union[int, np.ndarray],
        num_qubits: int,
        *,  # Force keyword arguments
        qid_shape: Optional[Tuple[int, ...]] = None,
        dtype: Type[np.number] = np.complex64) -> np.ndarray:
    """Verifies the state_rep is valid and converts it to ndarray form.

    This method is used to support passing in an integer representing a
    computational basis state or a full wave function as a representation of
    a state.

    Args:
        state_rep: If an int, the state returned is the state corresponding to
            a computational basis state. If an numpy array this is the full
            wave function. Both of these are validated for the given number
            of qubits, and the state must be properly normalized and of the
            appropriate dtype.
        num_qubits: The number of qubits for the state. The state_rep must be
            valid for this number of qubits.
        qid_shape: The expected qid shape of the state vector.  Specify this
            argument when using qudits.
        dtype: The numpy dtype of the state, will be used when creating the
            state for a computational basis state, or validated against if
            state_rep is a numpy array.

    Returns:
        A numpy ndarray corresponding to the state on the given number of
        qubits.

    Raises:
        ValueError if the state is not valid or num_qubits != len(qid_shape).
    """
    if qid_shape is None:
        qid_shape = (2, ) * num_qubits
    if num_qubits != len(qid_shape):
        raise ValueError('num_qubits != len(qid_shape). num_qubits is <{!r}>. '
                         'qid_shape is <{!r}>.'.format(num_qubits, qid_shape))
    if isinstance(state_rep, np.ndarray):
        if len(state_rep) != np.prod(qid_shape, dtype=int):
            raise ValueError(
                'initial state was of size {} '
                'but expected state for {} qubits with qid shape {}'.format(
                    len(state_rep), num_qubits, qid_shape))
        state = state_rep
    elif isinstance(state_rep, int):
        if state_rep < 0:
            raise ValueError('initial_state must be positive')
        elif state_rep >= np.prod(qid_shape, dtype=int):
            raise ValueError(
                'initial state was {} but expected state for {} qubits'.format(
                    state_rep, num_qubits))
        else:
            state = linalg.one_hot(shape=np.prod(qid_shape, dtype=int),
                                   dtype=dtype,
                                   index=state_rep)
    else:
        raise TypeError('initial_state was not of type int or ndarray')
    validate_normalized_state(state, qid_shape=qid_shape, dtype=dtype)
    return state
Exemple #3
0
def _computational_basis_state_to_state_tensor(
        *, state: int, qid_shape: Tuple[int, ...],
        dtype: Type[np.number]) -> np.ndarray:
    n = np.prod(qid_shape, dtype=int)
    if not 0 <= state <= n:
        raise ValueError(f'Computational basis state is out of range.\n'
                         f'\n'
                         f'state={state!r}\n'
                         f'MIN_STATE=0\n'
                         f'MAX_STATE=product(qid_shape)-1={n-1}\n'
                         f'qid_shape={qid_shape!r}\n')
    return linalg.one_hot(index=state, shape=n, dtype=dtype).reshape(qid_shape)
Exemple #4
0
def to_valid_state_vector(state_rep: Union[int, np.ndarray],
                          num_qubits: int,
                          dtype: Type[np.number] = np.complex64) -> np.ndarray:
    """Verifies the state_rep is valid and converts it to ndarray form.

    This method is used to support passing in an integer representing a
    computational basis state or a full wave function as a representation of
    a state.

    Args:
        state_rep: If an int, the state returned is the state corresponding to
            a computational basis state. If an numpy array this is the full
            wave function. Both of these are validated for the given number
            of qubits, and the state must be properly normalized and of the
            appropriate dtype.
        num_qubits: The number of qubits for the state. The state_rep must be
            valid for this number of qubits.
        dtype: The numpy dtype of the state, will be used when creating the
            state for a computational basis state, or validated against if
            state_rep is a numpy array.

    Returns:
        A numpy ndarray corresponding to the state on the given number of
        qubits.

    Raises:
        ValueError if the state is not valid.
    """
    if isinstance(state_rep, np.ndarray):
        if len(state_rep) != 2 ** num_qubits:
            raise ValueError(
                'initial state was of size {} '
                'but expected state for {} qubits'.format(
                    len(state_rep), num_qubits))
        state = state_rep
    elif isinstance(state_rep, int):
        if state_rep < 0:
            raise ValueError('initial_state must be positive')
        elif state_rep >= 2 ** num_qubits:
            raise ValueError(
                'initial state was {} but expected state for {} qubits'.format(
                    state_rep, num_qubits))
        else:
            state = linalg.one_hot(shape=2**num_qubits,
                                   dtype=dtype,
                                   index=state_rep)
    else:
        raise TypeError('initial_state was not of type int or ndarray')
    validate_normalized_state(state, num_qubits, dtype)
    return state
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 = linalg.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
Exemple #6
0
def _strat_has_unitary_from_apply_unitary(val: Any) -> Optional[bool]:
    """Attempts to infer a value's unitary-ness via its _apply_unitary_ method.
    """
    from cirq.protocols.apply_unitary import ApplyUnitaryArgs
    from cirq import devices, linalg, ops

    method = getattr(val, '_apply_unitary_', None)
    if method is None:
        return None
    if isinstance(val, ops.Gate):
        val = val.on(*devices.LineQubit.range(val.num_qubits()))
    if not isinstance(val, ops.Operation):
        return None

    val_qid_shape = qid_shape_protocol.qid_shape(val)
    state = linalg.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
Exemple #7
0
    def default(
            num_qubits: Optional[int] = None,
            *,
            qid_shape: Optional[Tuple[int, ...]] = None) -> 'ApplyUnitaryArgs':
        """A default instance starting in state |0⟩.

        Specify exactly one argument.

        Args:
            num_qubits: The number of qubits to make space for in the state.
            qid_shape: The shape of the state, specifying the dimension of each
                qid."""
        if (num_qubits is None) == (qid_shape is None):
            raise TypeError('Specify exactly one of num_qubits or qid_shape.')
        if num_qubits is not None:
            qid_shape = (2, ) * num_qubits
        qid_shape = cast(Tuple[int, ...], qid_shape)  # Satisfy mypy
        num_qubits = len(qid_shape)
        state = linalg.one_hot(index=(0, ) * num_qubits,
                               shape=qid_shape,
                               dtype=np.complex128)
        return ApplyUnitaryArgs(state, np.empty_like(state), range(num_qubits))
Exemple #8
0
 def default(num_qubits: int) -> 'ApplyUnitaryArgs':
     """A default instance starting in state |0⟩."""
     state = linalg.one_hot(index=(0, ) * num_qubits,
                            shape=(2, ) * num_qubits,
                            dtype=np.complex128)
     return ApplyUnitaryArgs(state, np.empty_like(state), range(num_qubits))