Skip to content

Commit

Permalink
Train copilot to make ruff satisfied
Browse files Browse the repository at this point in the history
  • Loading branch information
stand-by committed Jul 18, 2024
1 parent 65c328b commit f2ed6c2
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 5 deletions.
1 change: 1 addition & 0 deletions .github/compiler_setup.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# noqa: D100
import os
import sys

Expand Down
1 change: 1 addition & 0 deletions benchmarks/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Benchmarking module to compare C++ implementation against numpy."""
1 change: 1 addition & 0 deletions fast_pauli/py/pypauli/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""pypauli module provides implementations to benchmark and test c++ library."""
26 changes: 26 additions & 0 deletions fast_pauli/py/pypauli/helpers.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
"""Separate file with helper functions for Pauli matrices."""

import numpy as np


def pauli_matrices() -> dict:
"""Provide a dictionary containing the Pauli matrices.
The Pauli matrices are a set of 2x2 matrices commonly used in quantum mechanics.
This function returns a dictionary with keys representing the matrix names
("I", "X", "Y", "Z", 0, 1, 2, 3) and values representing the corresponding matrix.
Returns
-------
dict: A dictionary containing the Pauli matrices.
"""
s0 = np.array([[1, 0], [0, 1]], dtype=np.complex128)
s1 = np.array([[0, 1], [1, 0]], dtype=np.complex128)
s2 = np.array([[0, -1j], [1j, 0]], dtype=np.complex128)
Expand All @@ -10,6 +23,19 @@ def pauli_matrices() -> dict:


def naive_pauli_converter(string: str) -> np.ndarray:
"""Convert Pauli string representation into corresponding dense matrix.
Parameters
----------
string : str
The string representation of Pauli string.
Returns
-------
np.ndarray
The matrix representation of the Pauli string.
"""
paulis = pauli_matrices()
matrix = paulis[string[-1]]
for p in reversed(string[:-1]):
Expand Down
47 changes: 47 additions & 0 deletions fast_pauli/py/pypauli/operations.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
"""Efficient operations on Pauli string using numpy."""

import numpy as np


class PauliString:
"""Class representing a Pauli string with efficient operations."""

def __init__(self, string: str) -> None:
"""Initialize the PauliString object.
Args:
----
string: The input string representing the Pauli string.
Must contain only I, X, Y, Z characters.
"""
if not all([c in "IXYZ" for c in string]):
raise ValueError(f"Invalid pauli string {string}")

Expand All @@ -11,13 +23,25 @@ def __init__(self, string: str) -> None:
self.weight = len(string) - string.count("I")

def dense(self) -> np.ndarray:
"""Return the dense matrix representation of the Pauli string."""
columns, values = compose_sparse_pauli(self.string)

matrix = np.zeros((columns.size, values.size), dtype=np.complex128)
matrix[np.arange(columns.size), columns] = values
return matrix

def multiply(self, state: np.ndarray) -> np.ndarray:
"""Efficient multiplication of Pauli string with a given state.
Args:
----
state: The input state as a numpy array.
Returns:
-------
The result of multiplying the Pauli string with the state.
"""
if state.shape[0] != self.dim or state.ndim > 2:
raise ValueError(f"Provided state has inconsistent shape {state.shape}")

Expand All @@ -30,6 +54,18 @@ def multiply(self, state: np.ndarray) -> np.ndarray:


def compose_sparse_pauli(string: str) -> tuple[np.ndarray, np.ndarray]:
"""Produce sparse representation of the pauli string.
Args:
----
string: The input string representing the Pauli string.
Must contain only I, X, Y, Z characters.
Returns:
-------
A tuple containing the column numbers and values of the sparse matrix.
"""
n_qubits = len(string)
n_vals = 1 << n_qubits
n_ys = string.count("Y")
Expand Down Expand Up @@ -78,6 +114,17 @@ def compose_sparse_pauli(string: str) -> tuple[np.ndarray, np.ndarray]:


def compose_sparse_diag_pauli(string) -> np.ndarray:
"""Produce sparse representation of diagonal pauli string.
Args:
----
string: A Pauli string containing only 'I' and 'Z' characters.
Returns:
-------
np.ndarray: diagonal values from resulting sparse matrix.
"""
if "X" in string or "Y" in string:
raise ValueError("Pauli string must contain only I and Z characters")

Expand Down
1 change: 1 addition & 0 deletions fast_pauli/py/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Unit tests for pypauli module."""
17 changes: 12 additions & 5 deletions fast_pauli/py/tests/test_operations.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
import pytest
import numpy as np
from itertools import permutations, chain
"""Tests for pauli string and related operations."""

from itertools import chain, permutations

import numpy as np
import pytest
from pypauli.helpers import naive_pauli_converter, pauli_matrices
from pypauli.operations import (
PauliString,
compose_sparse_pauli,
compose_sparse_diag_pauli,
compose_sparse_pauli,
)
from pypauli.helpers import pauli_matrices, naive_pauli_converter


@pytest.fixture
def paulis():
"""Fixture to provide dict with Pauli matrices."""
return pauli_matrices()


def test_pauli_string(paulis):
"""Test the PauliString class."""
for p in ["I", "X", "Y", "Z"]:
ps = PauliString(p)
assert ps.dim == 2
Expand Down Expand Up @@ -57,6 +61,7 @@ def test_pauli_string(paulis):


def test_sparse_pauli_composer(paulis):
"""Test sparsepauli composer functions."""
ps = PauliString("II")
assert ps.dim == 4
np.testing.assert_array_equal(ps.dense(), np.eye(4))
Expand Down Expand Up @@ -100,6 +105,7 @@ def test_sparse_pauli_composer(paulis):


def test_sparse_pauli_composer_equivalence():
"""Test the equivalence of sparse Pauli composer with naive method."""
for c in ["I", "X", "Y", "Z"]:
np.testing.assert_array_equal(
PauliString(c).dense(),
Expand Down Expand Up @@ -133,6 +139,7 @@ def test_sparse_pauli_composer_equivalence():


def test_sparse_pauli_multiply():
"""Test the equivalence of multiply method that relies on sparse Pauli composer."""
rng = np.random.default_rng(321)

for s in chain(
Expand Down
1 change: 1 addition & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Test module for testing C++ library against python implementation."""

0 comments on commit f2ed6c2

Please sign in to comment.