Fix RecursionError in SummedOp.to_pauli_op() and enhance PauliOp.tensor(), PauliSumOp.tensor() (#6111)

* fix #6099 part 2

* fix #6099 first part

Co-authored-by: Julien Gacon <gaconju@gmail.com>
This commit is contained in:
Ikko Hamamura 2021-03-31 00:02:39 +09:00 committed by GitHub
parent f34c0dad26
commit 4a4d38f1af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 41 additions and 15 deletions

View File

@ -184,6 +184,8 @@ class SummedOp(ListOp):
coeff=self.coeff,
abelian=self.abelian,
).reduce()
if isinstance(pauli_sum, SummedOp):
return pauli_sum
return pauli_sum.to_pauli_op() # type: ignore
def equals(self, other: OperatorBase) -> bool:

View File

@ -99,11 +99,14 @@ class PauliOp(PrimitiveOp):
def tensor(self, other: OperatorBase) -> OperatorBase:
# Both Paulis
if isinstance(other, PauliOp):
# Copying here because Terra's Pauli kron is in-place.
op_copy = Pauli((other.primitive.z, other.primitive.x))
return PauliOp(self.primitive.tensor(op_copy), coeff=self.coeff * other.coeff)
return PauliOp(self.primitive.tensor(other.primitive), coeff=self.coeff * other.coeff)
# pylint: disable=cyclic-import
from .pauli_sum_op import PauliSumOp
if isinstance(other, PauliSumOp):
new_primitive = SparsePauliOp(self.primitive).tensor(other.primitive)
return PauliSumOp(new_primitive, coeff=self.coeff * other.coeff)
from .circuit_op import CircuitOp
if isinstance(other, CircuitOp):
return self.to_circuit_op().tensor(other)

View File

@ -162,6 +162,11 @@ class PauliSumOp(PrimitiveOp):
self.primitive.tensor(other.primitive),
coeff=self.coeff * other.coeff,
)
if isinstance(other, PauliOp):
return PauliSumOp(
self.primitive.tensor(other.primitive),
coeff=self.coeff * other.coeff,
)
return TensoredOp([self, other])

View File

@ -397,6 +397,11 @@ class TestOpConstruction(QiskitOpflowTestCase):
with self.subTest('SummedOp test 9'):
self.assertEqual(sum_op.reduce(), sum_op)
sum_op = ((Z + I) ^ Z) + (Z ^ X)
with self.subTest('SummedOp test 10'):
expected = SummedOp([PauliOp(Pauli('ZZ')), PauliOp(Pauli('IZ')), PauliOp(Pauli('ZX'))])
self.assertEqual(sum_op.to_pauli_op(), expected)
def test_compose_op_of_different_dim(self):
"""
Test if smaller operator expands to correct dim when composed with bigger operator.

View File

@ -127,18 +127,29 @@ class TestPauliSumOp(QiskitOpflowTestCase):
def test_tensor(self):
""" Test for tensor operation """
pauli_sum = ((I - Z) ^ (I - Z)) + ((X - Y) ^ (X + Y))
expected = (
(I ^ I)
- (I ^ Z)
- (Z ^ I)
+ (Z ^ Z)
+ (X ^ X)
+ (X ^ Y)
- (Y ^ X)
- (Y ^ Y)
)
self.assertEqual(pauli_sum, expected)
with self.subTest("Test 1"):
pauli_sum = ((I - Z) ^ (I - Z)) + ((X - Y) ^ (X + Y))
expected = (
(I ^ I)
- (I ^ Z)
- (Z ^ I)
+ (Z ^ Z)
+ (X ^ X)
+ (X ^ Y)
- (Y ^ X)
- (Y ^ Y)
)
self.assertEqual(pauli_sum, expected)
with self.subTest("Test 2"):
pauli_sum = ((Z + I) ^ Z)
expected = (Z ^ Z) + (I ^ Z)
self.assertEqual(pauli_sum, expected)
with self.subTest("Test 3"):
pauli_sum = (Z ^ (Z + I))
expected = (Z ^ Z) + (Z ^ I)
self.assertEqual(pauli_sum, expected)
def test_permute(self):
""" permute test """