Repository: Qiskit/qiskit

Issue:
Opflow Evolutions don't work on PauliSumOp
<!-- ⚠️ If you do not respect this template, your issue will be closed -->
<!-- ⚠️ Make sure to browse the opened and closed issues -->

### Information

- **Qiskit Terra version**:
- **Python version**:
- **Operating system**:

### What is the current behavior?

The evolution converters in Opflow do a typecheck for a `SummedOp` and break if passed `PauliSumOp`. This is a problem because we implicitly return a `PauliSumOp` for expressions that used to be a `SummedOp`, e.g for `X + Z`.

### Steps to reproduce the problem

```python
from qiskit.opflow import Suzuki

operator = (X ^ X ^ I) + (Z ^ Z ^ I)

evo = Suzuki()
evolution = evo.convert(operator)  # breaks, type is PauliSumOp
evolution = evo.convert(operator.to_pauli_op())  # works, type is SummedOp
```

### What is the expected behavior?

Allow passing `PauliSumOp` to the evolutions.




Opflow Evolutions don't work on PauliSumOp
<!-- ⚠️ If you do not respect this template, your issue will be closed -->
<!-- ⚠️ Make sure to browse the opened and closed issues -->

### Information

- **Qiskit Terra version**:
- **Python version**:
- **Operating system**:

### What is the current behavior?

The evolution converters in Opflow do a typecheck for a `SummedOp` and break if passed `PauliSumOp`. This is a problem because we implicitly return a `PauliSumOp` for expressions that used to be a `SummedOp`, e.g for `X + Z`.

### Steps to reproduce the problem

```python
from qiskit.opflow import Suzuki

operator = (X ^ X ^ I) + (Z ^ Z ^ I)

evo = Suzuki()
evolution = evo.convert(operator)  # breaks, type is PauliSumOp
evolution = evo.convert(operator.to_pauli_op())  # works, type is SummedOp
```

### What is the expected behavior?

Allow passing `PauliSumOp` to the evolutions.






Discussion:

Resolving patch:
diff --git a/qiskit/opflow/evolutions/trotterizations/suzuki.py b/qiskit/opflow/evolutions/trotterizations/suzuki.py
--- a/qiskit/opflow/evolutions/trotterizations/suzuki.py
+++ b/qiskit/opflow/evolutions/trotterizations/suzuki.py
@@ -19,6 +19,7 @@
 from ...operator_base import OperatorBase
 from ...list_ops.composed_op import ComposedOp
 from ...list_ops.summed_op import SummedOp
+from ...primitive_ops.pauli_sum_op import PauliSumOp
 from ...primitive_ops.primitive_op import PrimitiveOp
 
 
@@ -53,8 +54,12 @@ def order(self, order: int) -> None:
         self._order = order
 
     def convert(self, operator: OperatorBase) -> OperatorBase:
-        if not isinstance(operator, SummedOp):
-            raise TypeError('Trotterization converters can only convert SummedOps.')
+        if not isinstance(operator, (SummedOp, PauliSumOp)):
+            raise TypeError('Trotterization converters can only convert SummedOps or PauliSumOp.')
+
+        # TODO: implement direct way
+        if isinstance(operator, PauliSumOp):
+            operator = operator.to_pauli_op()
 
         composition_list = Suzuki._suzuki_recursive_expansion(
             cast(List[List[Union[complex, Pauli]]], operator.oplist),


Test patch:
diff --git a/test/python/opflow/test_evolution.py b/test/python/opflow/test_evolution.py
--- a/test/python/opflow/test_evolution.py
+++ b/test/python/opflow/test_evolution.py
@@ -268,6 +268,19 @@ def test_reps(self):
         qdrift = QDrift(reps=reps)
         self.assertEqual(qdrift.reps, reps)
 
+    def test_suzuki_directly(self):
+        """ Test for Suzuki converter """
+        operator = X + Z
+
+        evo = Suzuki()
+        evolution = evo.convert(operator)
+
+        matrix = np.array([
+            [0.29192658 - 0.45464871j, -0.84147098j],
+            [-0.84147098j, 0.29192658 + 0.45464871j]
+        ])
+        np.testing.assert_array_almost_equal(evolution.to_matrix(), matrix)
+
 
 if __name__ == '__main__':
     unittest.main()