Example #1
0
    def __init__(self,
                 matrices: Iterable[np.ndarray],
                 display_name: str = "KR"):

        for matrix in matrices:
            verify_quantum_operator_matrix_dimensions(matrix)
            if not int(np.log2(matrix.shape[0])) == int(
                    np.log2(matrices[0].shape[0])):
                raise ValueError(
                    f"all matrices in {matrices} must have the same shape")
        self._matrices = [
            np.array(matrix, dtype=complex) for matrix in matrices
        ]
        self._display_name = display_name
        qubit_count = int(np.log2(self._matrices[0].shape[0]))
        if qubit_count > 2:
            raise ValueError(
                "Kraus operators with more than two qubits are not supported.")
        if len(matrices) > 2**(2 * qubit_count):
            raise ValueError("The number of Kraus operators is beyond limit.")

        if not is_cptp(self._matrices):
            raise ValueError(
                "The input matrices do not define a completely-positive trace-preserving map."
            )

        super().__init__(qubit_count=qubit_count,
                         ascii_symbols=[display_name] * qubit_count)
Example #2
0
    def __init__(self, matrix: np.ndarray, display_name: str = "Hermitian"):
        """
        Args:
            matrix (numpy.ndarray): Hermitian matrix that defines the observable.
            display_name (str): Name to use for an instance of this Hermitian matrix
                observable for circuit diagrams. Defaults to `Hermitian`.

        Raises:
            ValueError: If `matrix` is not a two-dimensional square matrix,
                or has a dimension length that is not a positive power of 2,
                or is not Hermitian.

        Examples:
            >>> Observable.Hermitian(matrix=np.array([[0, 1],[1, 0]]))
        """
        verify_quantum_operator_matrix_dimensions(matrix)
        self._matrix = np.array(matrix, dtype=complex)
        if not is_hermitian(self._matrix):
            raise ValueError(f"{self._matrix} is not hermitian")

        qubit_count = int(np.log2(self._matrix.shape[0]))
        eigendecomposition = Hermitian._get_eigendecomposition(self._matrix)
        self._eigenvalues = eigendecomposition["eigenvalues"]
        self._diagonalizing_gates = (Gate.Unitary(
            matrix=eigendecomposition["eigenvectors"].conj().T), )

        super().__init__(qubit_count=qubit_count,
                         ascii_symbols=[display_name] * qubit_count)
Example #3
0
    def __init__(self, matrix: np.ndarray, display_name: str = "U"):
        verify_quantum_operator_matrix_dimensions(matrix)
        self._matrix = np.array(matrix, dtype=complex)
        qubit_count = int(np.log2(self._matrix.shape[0]))

        if not is_unitary(self._matrix):
            raise ValueError(f"{self._matrix} is not unitary")

        super().__init__(qubit_count=qubit_count, ascii_symbols=[display_name] * qubit_count)
Example #4
0
def test_verify_quantum_operator_matrix_dimensions_value_error(matrix):
    verify_quantum_operator_matrix_dimensions(matrix)
Example #5
0
def test_verify_quantum_operator_matrix_dimensions():
    assert verify_quantum_operator_matrix_dimensions(
        valid_unitary_hermitian_matrix) is None