Skip to content

Commit

Permalink
Merge pull request #86 from qognitive/bug/helpers_typo
Browse files Browse the repository at this point in the history
[BUG] Fixing typing in helpers function
  • Loading branch information
jamesETsmith authored Nov 21, 2024
2 parents f9e94d0 + 5846981 commit 078beed
Show file tree
Hide file tree
Showing 6 changed files with 174 additions and 23 deletions.
15 changes: 12 additions & 3 deletions docs/cpp_api.rst
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
C++ API
=======

.. toctree::
:maxdepth: 2

Pauli
-----
Expand All @@ -27,4 +25,15 @@ SummedPauliOp
-------------
.. doxygenstruct:: fast_pauli::SummedPauliOp
:project: fast_pauli
:members:
:members:

Helpers
-------
.. doxygenfunction:: fast_pauli::get_nontrivial_paulis
:project: fast_pauli
.. doxygenfunction:: fast_pauli::calculate_pauli_strings
:project: fast_pauli
.. doxygenfunction:: fast_pauli::calculate_pauli_strings_max_weight
:project: fast_pauli
.. doxygenfunction:: fast_pauli::get_sparse_repr
:project: fast_pauli
14 changes: 10 additions & 4 deletions docs/python_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@ Python API
==========


.. automodule:: fast_pauli


Pauli
-----

Expand Down Expand Up @@ -33,4 +30,13 @@ SummedPauliOp

.. autoclass:: fast_pauli.SummedPauliOp
:members:
:special-members:
:special-members:


Helpers
-------

.. autofunction:: fast_pauli.helpers.calculate_pauli_strings
.. autofunction:: fast_pauli.helpers.calculate_pauli_strings_max_weight
.. autofunction:: fast_pauli.helpers.pauli_string_sparse_repr
.. autofunction:: fast_pauli.helpers.get_nontrivial_paulis
18 changes: 9 additions & 9 deletions fast_pauli/cpp/include/__pauli_helpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ namespace fast_pauli
/**
* @brief Get the nontrivial sets of pauli matrices given a weight.
*
* @param weight
* @param weight The Pauli weight to get the nontrivial paulis for.
* @return std::vector<std::string>
*/
std::vector<std::string> get_nontrivial_paulis(size_t const weight)
Expand Down Expand Up @@ -62,8 +62,8 @@ std::vector<std::string> get_nontrivial_paulis(size_t const weight)
/**
* @brief Get all the combinations of k indices for a given array of size n.
*
* @param n
* @param k
* @param n The size of the array to get the combinations of.
* @param k The number of indices to choose.
* @return std::vector<std::vector<size_t>>
*/
std::vector<std::vector<size_t>> idx_combinations(size_t const n, size_t const k)
Expand Down Expand Up @@ -92,11 +92,11 @@ std::vector<std::vector<size_t>> idx_combinations(size_t const n, size_t const k
* @brief Calculate all possible PauliStrings for a given number of qubits and
* weight and return them in lexicographical order.
*
* @param n_qubits
* @param weight
* @param n_qubits The number of qubits.
* @param weight The Pauli weight.
* @return std::vector<PauliString>
*/
std::vector<PauliString> calcutate_pauli_strings(size_t const n_qubits, size_t const weight)
std::vector<PauliString> calculate_pauli_strings(size_t const n_qubits, size_t const weight)
{
// base case
if (weight == 0)
Expand Down Expand Up @@ -137,16 +137,16 @@ std::vector<PauliString> calcutate_pauli_strings(size_t const n_qubits, size_t c
* @brief Calculate all possible PauliStrings for a given number of qubits and
* all weights less than or equal to a given weight.
*
* @param n_qubits
* @param weight
* @param n_qubits The number of qubits.
* @param weight The Pauli weight.
* @return std::vector<PauliString>
*/
std::vector<PauliString> calculate_pauli_strings_max_weight(size_t n_qubits, size_t weight)
{
std::vector<PauliString> result;
for (size_t i = 0; i <= weight; ++i)
{
auto ps = calcutate_pauli_strings(n_qubits, i);
auto ps = calculate_pauli_strings(n_qubits, i);
result.insert(result.end(), ps.begin(), ps.end());
}
return result;
Expand Down
63 changes: 59 additions & 4 deletions fast_pauli/cpp/src/fast_pauli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1135,9 +1135,64 @@ SummedPauliOp
// Helpers
//
auto helpers_m = m.def_submodule("helpers");
helpers_m.def("get_nontrivial_paulis", &fp::get_nontrivial_paulis, "weight"_a);
helpers_m.def("calcutate_pauli_strings", &fp::calcutate_pauli_strings, "n_qubits"_a, "weight"_a);
helpers_m.def("get_nontrivial_paulis", &fp::get_nontrivial_paulis, "weight"_a,
R"%(Get all nontrivial Pauli strings up to a given weight.
Parameters
----------
weight : int
Maximum weight of Pauli strings to return
Returns
-------
List[str]
List of PauliStrings as strings
)%");

helpers_m.def("calculate_pauli_strings", &fp::calculate_pauli_strings, "n_qubits"_a, "weight"_a,
R"%(Calculate all Pauli strings for a given weight.
Parameters
----------
n_qubits : int
Number of qubits
weight : int
Weight of Pauli strings to return
Returns
-------
List[PauliString]
List of PauliStrings
)%");

helpers_m.def("calculate_pauli_strings_max_weight", &fp::calculate_pauli_strings_max_weight, "n_qubits"_a,
"weight"_a);
helpers_m.def("pauli_string_sparse_repr", &fp::get_sparse_repr<float_type>, "paulis"_a);
"weight"_a,
R"%(Calculate all Pauli strings up to and including a given weight.
Parameters
----------
n_qubits : int
Number of qubits
weight : int
Maximum weight of Pauli strings to return
Returns
-------
List[PauliString]
List of PauliStrings
)%");

helpers_m.def("pauli_string_sparse_repr", &fp::get_sparse_repr<float_type>, "paulis"_a,
R"%(Get a sparse representation of a list of Pauli strings.
Parameters
----------
paulis : List[PauliString]
List of PauliStrings
Returns
-------
List[Tuple[int, int]]
List of tuples representing the Pauli string in a sparse format
)%");
}
6 changes: 3 additions & 3 deletions fast_pauli/cpp/tests/test_pauli_helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,13 @@ TEST_CASE("idx combinations")
TEST_CASE("calculate pauli strings")
{
{
auto res = calcutate_pauli_strings(4, 0);
auto res = calculate_pauli_strings(4, 0);
CHECK(res.size() == 1);
CHECK(res[0] == PauliString("IIII"));
}

{
auto res = calcutate_pauli_strings(2, 1);
auto res = calculate_pauli_strings(2, 1);
CHECK(res.size() == 6);
CHECK(res[0] == PauliString("XI"));
CHECK(res[1] == PauliString("IX"));
Expand All @@ -127,7 +127,7 @@ TEST_CASE("calculate pauli strings")
}

{
auto res = calcutate_pauli_strings(4, 2);
auto res = calculate_pauli_strings(4, 2);
CHECK(res.size() == 54);
CHECK(res[0] == PauliString("XXII"));
CHECK(res[1] == PauliString("XIXI"));
Expand Down
81 changes: 81 additions & 0 deletions tests/fast_pauli/test_helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
"""Test the helpers module."""

import itertools

import pytest

import fast_pauli as fp


def calculate_trusted_pauli_strings(n_qubits: int, weight: int) -> list[str]:
"""Calculate all possible Pauli strings for a given number of qubits and weight.
Parameters
----------
n_qubits : int
The number of qubits.
weight : int
The Pauli weight.
Returns
-------
list[str]
All possible Pauli strings for the given number of qubits and weight.
"""
strings = []
nontrivial_matrix_elements = list(itertools.product(["X", "Y", "Z"], repeat=weight))
for indices in itertools.combinations(range(n_qubits), weight): # n(n-1)/2 terms
for elements in nontrivial_matrix_elements:
pauli_string = []
for qbit in range(n_qubits):
for el_position, i in enumerate(indices):
if i == qbit:
pauli_string.append(elements[el_position])
break
else:
pauli_string.append("I")
strings.append("".join(pauli_string))
return strings


@pytest.mark.parametrize("weight", [0, 1, 2, 3])
def test_get_nontrivial_paulis(weight: int) -> None:
"""Test the get_nontrivial_paulis function."""
res = fp.helpers.get_nontrivial_paulis(weight)
trusted = [
"".join(x) for x in itertools.product("XYZ", repeat=weight) if len(x) > 0
]
assert len(res) == len(trusted)
assert set(res) == set(trusted)


@pytest.mark.parametrize("n_qubits", [1, 2, 3, 4], ids=lambda x: f"nq={x}")
@pytest.mark.parametrize("weight", [1, 2, 3], ids=lambda x: f"w={x}")
def test_calculate_pauli_strings(n_qubits: int, weight: int) -> None:
"""Test the calculate_pauli_strings function."""
if n_qubits < weight:
pytest.skip("n_qubits must be greater than or equal to weight")

res = [str(x) for x in fp.helpers.calculate_pauli_strings(n_qubits, weight)]
trusted = calculate_trusted_pauli_strings(n_qubits, weight)

assert len(res) == len(trusted)
assert set(res) == set(trusted)


@pytest.mark.parametrize("n_qubits", [1, 2, 3, 4], ids=lambda x: f"nq={x}")
@pytest.mark.parametrize("weight", [1, 2, 3], ids=lambda x: f"w={x}")
def test_calculate_pauli_strings_max_weight(n_qubits: int, weight: int) -> None:
"""Test the calculate_pauli_strings_max_weight function."""
if n_qubits < weight:
pytest.skip("n_qubits must be greater than or equal to weight")

res = [
str(x) for x in fp.helpers.calculate_pauli_strings_max_weight(n_qubits, weight)
]
trusted = ["I" * n_qubits]
for i in range(1, weight + 1):
trusted.extend(calculate_trusted_pauli_strings(n_qubits, i))

assert len(res) == len(trusted)
assert set(res) == set(trusted)

0 comments on commit 078beed

Please sign in to comment.