Example #1
0
def von_neumann_entropy(
    state: 'cirq.QUANTUM_STATE_LIKE',
    qid_shape: Optional[Tuple[int, ...]] = None,
    validate: bool = True,
    atol: float = 1e-7,
) -> float:
    """Calculates the von Neumann entropy of a quantum state in bits.

    If `state` is a square matrix, it is assumed to be a density matrix rather
    than a (pure) state tensor.

    Args:
        state: The quantum state.
        qid_shape: The qid shape of the given state.
        validate: Whether to check if the given state is a valid quantum state.
        atol: Absolute numerical tolerance to use for validation.

    Returns:
        The calculated von Neumann entropy.

    Raises:
        ValueError: Invalid quantum state.
    """
    if isinstance(state, QuantumState) and state._is_density_matrix():
        state = state.data
    if isinstance(state, np.ndarray) and state.ndim == 2 and state.shape[0] == state.shape[1]:
        if validate:
            if qid_shape is None:
                qid_shape = (state.shape[0],)
            validate_density_matrix(state, qid_shape=qid_shape, dtype=state.dtype, atol=atol)
        eigenvalues = np.linalg.eigvalsh(state)
        return stats.entropy(np.abs(eigenvalues), base=2)
    if validate:
        _ = quantum_state(state, qid_shape=qid_shape, copy=False, validate=True, atol=atol)
    return 0.0
Example #2
0
def fidelity(
    state1: 'cirq.QUANTUM_STATE_LIKE',
    state2: 'cirq.QUANTUM_STATE_LIKE',
    qid_shape: Optional[Tuple[int, ...]] = None,
    validate: bool = True,
    atol: float = 1e-7,
) -> float:
    """Fidelity of two quantum states.

    The fidelity of two density matrices ρ and σ is defined as

        trace(sqrt(sqrt(ρ) σ sqrt(ρ)))^2.

    The given states can be state vectors or density matrices.

    Args:
        state1: The first state.
        state2: The second state.
        qid_shape: The qid shape of the given states.
        validate: Whether to check if the given states are valid quantum states.
        atol: Absolute numerical tolerance to use for validation.

    Returns:
        The fidelity.

    Raises:
        ValueError: The qid shape of the given states was not specified and
            could not be inferred.
        ValueError: Invalid quantum state.
    """
    # Two ints
    if isinstance(state1, int) and isinstance(state2, int):
        if validate:
            _validate_int_state(state1, qid_shape)
            _validate_int_state(state2, qid_shape)
        return float(state1 == state2)

    # Two ProductStates
    if isinstance(state1, value.ProductState) and isinstance(state2, value.ProductState):
        if len(state1) != len(state2):
            raise ValueError(
                'Mismatched number of qubits in product states: '
                f'{len(state1)} and {len(state2)}.'
            )
        if validate:
            _validate_product_state(state1, qid_shape)
            _validate_product_state(state2, qid_shape)
        prod = 1.0
        for q, s1 in state1:
            s2 = state2[q]
            prod *= np.abs(np.vdot(s1.state_vector(), s2.state_vector()))
        return prod**2

    # Two numpy arrays that are either state vector, state tensor, or
    # density matrix
    if (
        isinstance(state1, np.ndarray)
        and state1.dtype.kind == 'c'
        and isinstance(state2, np.ndarray)
        and state2.dtype.kind == 'c'
    ):
        state1, state2 = _numpy_arrays_to_state_vectors_or_density_matrices(
            state1, state2, qid_shape=qid_shape, validate=validate, atol=atol
        )
        return _fidelity_state_vectors_or_density_matrices(state1, state2)

    # Use QuantumState machinery for the general case
    if qid_shape is None:
        try:
            qid_shape = infer_qid_shape(state1, state2)
        except:
            raise ValueError(
                'Failed to infer the qid shape of the given states. '
                'Please specify the qid shape explicitly using the `qid_shape` argument.'
            )
    state1 = quantum_state(state1, qid_shape=qid_shape, validate=validate, atol=atol)
    state2 = quantum_state(state2, qid_shape=qid_shape, validate=validate, atol=atol)
    state1_arr = state1.state_vector_or_density_matrix()
    state2_arr = state2.state_vector_or_density_matrix()
    return _fidelity_state_vectors_or_density_matrices(state1_arr, state2_arr)