Repository: quantumlib/OpenFermion
Pull request #115 (2017-11-28 17:56:35)

Commutator function
For Numpy arrays, `*` actually means element-wise multiplication, so I think the description is incorrect. I simply changed the description, but an alternative way to fix this issue is to add support for Numpy arrays, which I would be glad to do.

googlebot: So there's good news and bad news.

:thumbsup: The good news is that everyone that needs to sign a CLA (the pull request submitter and all commit authors) have done so.  Everything is all good there.

:confused: The bad news is that it appears that one or more commits were authored by someone other than the pull request submitter.  We need to confirm that all authors are ok with their commits being contributed to this project.  Please have them confirm that here in the pull request.

*Note to project maintainer: This is a terminal state, meaning the `cla/google` commit status will not change from this State. It's up to you to confirm consent of the commit author(s) and merge this pull request when appropriate.*

<!-- need_author_consent -->
jarrodmcc: This is a correct change, well spotted.  If you would be willing to add a line to support 2D numpy arrays I think that would be a good update, as well.  Will merge either way once you let me know.
googlebot: So there's good news and bad news.

:thumbsup: The good news is that everyone that needs to sign a CLA (the pull request submitter and all commit authors) have done so.  Everything is all good there.

:confused: The bad news is that it appears that one or more commits were authored by someone other than the pull request submitter.  We need to confirm that all authors are ok with their commits being contributed to this project.  Please have them confirm that here in the pull request.

*Note to project maintainer: This is a terminal state, meaning the `cla/google` commit status will not change from this State. It's up to you to confirm consent of the commit author(s) and merge this pull request when appropriate.*

<!-- need_author_consent -->
kevinsung: I added support for Numpy arrays.
jarrodmcc: Looks great, thanks for the addition!

Patch:
diff --git a/src/openfermion/utils/_operator_utils.py b/src/openfermion/utils/_operator_utils.py
index beeff34..1090428 100644
--- a/src/openfermion/utils/_operator_utils.py
+++ b/src/openfermion/utils/_operator_utils.py
@@ -76,15 +76,20 @@ def commutator(operator_a, operator_b):
     Args:
         operator_a, operator_b: Operators in commutator. Any operators
             are accepted so long as implicit subtraction and multiplication are
-            supported; e.g. QubitOperators, FermionOperators or numpy arrays.
+            supported; e.g. QubitOperators, FermionOperators or Scipy sparse
+            matrices. 2D Numpy arrays are also supported.
 
     Raises:
         TypeError: operator_a and operator_b are not of the same type.
     """
     if type(operator_a) != type(operator_b):
         raise TypeError('operator_a and operator_b are not of the same type.')
-    result = operator_a * operator_b
-    result -= operator_b * operator_a
+    if isinstance(operator_a, numpy.ndarray):
+        result = operator_a.dot(operator_b)
+        result -= operator_b.dot(operator_a)
+    else:
+        result = operator_a * operator_b
+        result -= operator_b * operator_a
     return result
 
 


Test patch:
diff --git a/src/openfermion/utils/_operator_utils_test.py b/src/openfermion/utils/_operator_utils_test.py
index d4fa182..ca3d838 100644
--- a/src/openfermion/utils/_operator_utils_test.py
+++ b/src/openfermion/utils/_operator_utils_test.py
@@ -23,6 +23,7 @@ from openfermion.ops import *
 from openfermion.transforms import jordan_wigner, get_interaction_operator
 from openfermion.utils import Grid
 from openfermion.utils._operator_utils import *
+from openfermion.utils._sparse_tools import pauli_matrix_map
 
 
 class OperatorUtilsTest(unittest.TestCase):
@@ -208,6 +209,13 @@ class CommutatorTest(unittest.TestCase):
             self.qubit_operator * operator_b -
             operator_b * self.qubit_operator))
 
+    def test_ndarray_input(self):
+        """Test when the inputs are Numpy arrays."""
+        X = pauli_matrix_map['X'].toarray()
+        Y = pauli_matrix_map['Y'].toarray()
+        Z = pauli_matrix_map['Z'].toarray()
+        self.assertTrue(numpy.allclose(commutator(X, Y), 2.j * Z))
+
     def test_commutator_operator_a_bad_type(self):
         with self.assertRaises(TypeError):
             commutator(1, self.fermion_operator)