Repository: quantumlib/OpenFermion
Pull request #500 (2019-01-07 22:49:05)

Add testing routine for generating random QubitOperators


Patch:
diff --git a/src/openfermion/utils/__init__.py b/src/openfermion/utils/__init__.py
index 6ed7457..07a5565 100644
--- a/src/openfermion/utils/__init__.py
+++ b/src/openfermion/utils/__init__.py
@@ -60,6 +60,7 @@ from ._testing_utils import (haar_random_vector,
                              random_hermitian_matrix,
                              random_interaction_operator,
                              random_quadratic_hamiltonian,
+                             random_qubit_operator,
                              random_unitary_matrix,
                              module_importable)
 
diff --git a/src/openfermion/utils/_bch_expansion.py b/src/openfermion/utils/_bch_expansion.py
index 0de8e9d..31732e3 100644
--- a/src/openfermion/utils/_bch_expansion.py
+++ b/src/openfermion/utils/_bch_expansion.py
@@ -13,7 +13,7 @@
 """Module to efficiently compute the Baker-Campbell-Hausdorff formula."""
 
 import itertools
-from scipy.misc import comb, factorial
+from scipy.special import comb, factorial
 
 
 def bch_expand(*ops, **kwargs):


Test patch:
diff --git a/src/openfermion/utils/_testing_utils.py b/src/openfermion/utils/_testing_utils.py
index b6b52e1..636ce6e 100644
--- a/src/openfermion/utils/_testing_utils.py
+++ b/src/openfermion/utils/_testing_utils.py
@@ -20,7 +20,27 @@ from scipy.linalg import qr
 
 from openfermion.ops import (DiagonalCoulombHamiltonian,
                              InteractionOperator,
-                             QuadraticHamiltonian)
+                             QuadraticHamiltonian,
+                             QubitOperator)
+
+
+def random_qubit_operator(n_qubits=16,
+                          max_num_terms=16,
+                          max_many_body_order=16,
+                          seed=None):
+    prng = numpy.random.RandomState(seed)
+    op = QubitOperator()
+    num_terms = prng.randint(1, max_num_terms+1)
+    for _ in range(num_terms):
+        many_body_order = prng.randint(max_many_body_order+1)
+        term = []
+        for _ in range(many_body_order):
+            index = prng.randint(n_qubits)
+            action = prng.choice(('X', 'Y', 'Z'))
+            term.append((index, action))
+        coefficient = prng.randn()
+        op += QubitOperator(term, coefficient)
+    return op
 
 
 def haar_random_vector(n, seed=None):
diff --git a/src/openfermion/utils/_testing_utils_test.py b/src/openfermion/utils/_testing_utils_test.py
index 6c7a59c..0ce0c0b 100644
--- a/src/openfermion/utils/_testing_utils_test.py
+++ b/src/openfermion/utils/_testing_utils_test.py
@@ -16,8 +16,9 @@ import unittest
 
 import numpy
 
+from openfermion.ops import QubitOperator
 from openfermion.transforms import get_fermion_operator
-from openfermion.utils import is_hermitian
+from openfermion.utils import count_qubits, is_hermitian
 from openfermion.utils._testing_utils import (
         EqualsTester,
         haar_random_vector,
@@ -26,9 +27,24 @@ from openfermion.utils._testing_utils import (
         random_hermitian_matrix,
         random_interaction_operator,
         random_quadratic_hamiltonian,
+        random_qubit_operator,
         random_unitary_matrix)
 
 
+def test_random_qubit_operator():
+    op = random_qubit_operator(
+        n_qubits=20,
+        max_num_terms=20,
+        max_many_body_order=20
+    )
+
+    assert isinstance(op, QubitOperator)
+    assert op.many_body_order() <= 20
+    assert len(op.terms) <= 20
+    assert count_qubits(op) <= 20
+
+
+
 class EqualsTesterTest(unittest.TestCase):
 
     def test_add_equality_group_correct(self):