コード例 #1
0
ファイル: test_math.py プロジェクト: BQSKit/bqskit
class TestUnitaryLog:
    def test_invalid(self, not_a_seq_float: Any) -> None:
        with pytest.raises(TypeError):
            unitary_log_no_i(not_a_seq_float)

    @pytest.mark.parametrize(
        'reU',
        PauliMatrices(1).paulis
        + PauliMatrices(2).paulis
        + PauliMatrices(3).paulis
        + PauliMatrices(4).paulis
        + [unitary_group.rvs(16) for _ in range(100)],
    )
    def test_valid(self, reU: np.ndarray) -> None:
        H = unitary_log_no_i(reU)
        assert np.allclose(H, H.conj().T, rtol=0, atol=1e-15)
        U = sp.linalg.expm(1j * H)
        assert 1 - (np.abs(np.trace(U.conj().T @ reU)) / U.shape[0]) <= 1e-15
        assert np.allclose(
            U.conj().T @ U,
            np.identity(len(U)),
            rtol=0,
            atol=1e-14,
        )
        assert np.allclose(
            U @ U.conj().T,
            np.identity(len(U)),
            rtol=0,
            atol=1e-14,
        )
コード例 #2
0
ファイル: pauli.py プロジェクト: BQSKit/bqskit
    def __init__(self, size: int) -> None:
        """Create a PauliGate acting on `size` qubits."""

        if size <= 0:
            raise ValueError('Expected positive integer, got %d' % size)

        self.size = size
        self.paulis = PauliMatrices(self.size)
        self.num_params = len(self.paulis)
        self.sigmav = (-1j / self.get_dim()) * self.paulis.get_numpy()
コード例 #3
0
ファイル: test_math.py プロジェクト: BQSKit/bqskit
    def test_single(self, alpha: np.ndarray) -> None:
        paulis = PauliMatrices(2)
        H = paulis.dot_product(alpha)

        for p in paulis:
            F0, dF0 = dexpm_exact(H, p)
            F1, dF1 = dexpmv(H, p)

            assert np.allclose(F0, F1)
            assert np.allclose(dF0, dF1)
コード例 #4
0
ファイル: test_math.py プロジェクト: BQSKit/bqskit
    def test_vector(self, alpha: np.ndarray) -> None:
        paulis = PauliMatrices(2)
        H = paulis.dot_product(alpha)

        dFs0 = []
        for p in paulis:
            _, dF = dexpm_exact(H, p)
            dFs0.append(dF)

        dFs0_np = np.array(dFs0)

        _, dFs1 = dexpmv(H, paulis.get_numpy())

        assert np.allclose(dFs0_np, dFs1)
コード例 #5
0
ファイル: test_math.py プロジェクト: BQSKit/bqskit
class TestPauliExpansion:
    def test_invalid(self, not_a_seq_float: Any) -> None:
        with pytest.raises(TypeError):
            pauli_expansion(not_a_seq_float)

    @pytest.mark.parametrize(
        'reH',
        PauliMatrices(1).paulis
        + PauliMatrices(2).paulis
        + PauliMatrices(3).paulis
        + PauliMatrices(4).paulis,
    )
    def test_valid(self, reH: np.ndarray) -> None:
        alpha = pauli_expansion(reH)
        print(alpha)
        H = PauliMatrices(int(np.log2(reH.shape[0]))).dot_product(alpha)
        assert np.linalg.norm(H - reH) < 1e-16
コード例 #6
0
ファイル: pauli.py プロジェクト: BQSKit/bqskit
class PauliGate(QubitGate, DifferentiableUnitary, LocallyOptimizableUnitary):
    """A gate representing an arbitrary rotation."""
    def __init__(self, size: int) -> None:
        """Create a PauliGate acting on `size` qubits."""

        if size <= 0:
            raise ValueError('Expected positive integer, got %d' % size)

        self.size = size
        self.paulis = PauliMatrices(self.size)
        self.num_params = len(self.paulis)
        self.sigmav = (-1j / self.get_dim()) * self.paulis.get_numpy()

    def get_unitary(self, params: Sequence[float] = []) -> UnitaryMatrix:
        """Returns the unitary for this gate, see Unitary for more info."""
        self.check_parameters(params)

        H = dot_product(params, self.sigmav)
        eiH = sp.linalg.expm(H)
        return UnitaryMatrix(eiH, check_arguments=False)

    def get_grad(self, params: Sequence[float] = []) -> np.ndarray:
        """Returns the gradient for this gate, see Gate for more info."""
        self.check_parameters(params)

        H = dot_product(params, self.sigmav)
        _, dU = dexpmv(H, self.sigmav)
        return dU

    def get_unitary_and_grad(
        self,
        params: Sequence[float] = [],
    ) -> tuple[UnitaryMatrix, np.ndarray]:
        """Returns the unitary and gradient, see Gate for more info."""
        self.check_parameters(params)

        H = dot_product(params, self.sigmav)
        U, dU = dexpmv(H, self.sigmav)
        return UnitaryMatrix(U, check_arguments=False), dU

    def optimize(self, env_matrix: np.ndarray) -> list[float]:
        """Returns optimal parameters with respect to an environment matrix."""
        self.check_env_matrix(env_matrix)
        U, _, Vh = sp.linalg.svd(env_matrix)
        return list(pauli_expansion(unitary_log_no_i(
            Vh.conj().T @ U.conj().T)))
コード例 #7
0
ファイル: math.py プロジェクト: BQSKit/bqskit
def pauli_expansion(H: np.ndarray, tol: float = 1e-8) -> np.ndarray:
    """
    Computes a Pauli expansion of the hermitian matrix H.

    Args:
        H (np.ndarray): The hermitian matrix to expand.

    Returns:
        (np.ndarray): The coefficients of a Pauli expansion for H,
            i.e., X dot Sigma = H where Sigma is Pauli matrices of
            same size of H.
    """

    if not is_hermitian(H, tol):  # TODO: Re-evaluate check
        raise TypeError('Expected H to be hermitian, got %s.' % type(H))

    # Change basis of H to Pauli Basis (solve for coefficients -> X)
    n = int(np.log2(len(H)))
    paulis = PauliMatrices(n)
    flatten_paulis = [np.reshape(pauli, 4**n) for pauli in paulis]
    flatten_H = np.reshape(H, 4**n)
    A = np.stack(flatten_paulis, axis=-1)
    X = np.real(np.matmul(np.linalg.inv(A), flatten_H))
    return np.array(X)
コード例 #8
0
ファイル: test_math.py プロジェクト: BQSKit/bqskit
 def test_valid(self, reH: np.ndarray) -> None:
     alpha = pauli_expansion(reH)
     print(alpha)
     H = PauliMatrices(int(np.log2(reH.shape[0]))).dot_product(alpha)
     assert np.linalg.norm(H - reH) < 1e-16