diff --git a/qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py b/qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py index 503c29f94689..8ed37c400c9c 100644 --- a/qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +++ b/qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py @@ -366,8 +366,8 @@ def _add(self, other, qargs=None): return SparsePauliOp(paulis, coeffs, ignore_pauli_phase=True, copy=False) def _multiply(self, other): - if not isinstance(other, Number): - raise QiskitError("other is not a number") + if not isinstance(other, (Number, ParameterExpression)): + raise QiskitError("other is neither a Number nor a Parameter/ParameterExpression") if other == 0: # Check edge case that we deleted all Paulis # In this case we return an identity Pauli with a zero coefficient diff --git a/releasenotes/notes/support-SparsePauliOp-Parameter-multiplication-245173f0b232f59b.yaml b/releasenotes/notes/support-SparsePauliOp-Parameter-multiplication-245173f0b232f59b.yaml new file mode 100644 index 000000000000..a140e4aed629 --- /dev/null +++ b/releasenotes/notes/support-SparsePauliOp-Parameter-multiplication-245173f0b232f59b.yaml @@ -0,0 +1,15 @@ +features: + - | + Adds support for multiplication of :class:`.SparsePauliOp` objects + with :class:`.Parameter` objects by using the * operator, for example:: + + from qiskit.circuit import Parameter + from qiskit.quantum_info import SparsePauliOp + + param = Parameter("a") + op = SparsePauliOp("X") + param * op + +fixes: + - | + Fixes issue `#10185 `. diff --git a/test/python/quantum_info/operators/symplectic/test_sparse_pauli_op.py b/test/python/quantum_info/operators/symplectic/test_sparse_pauli_op.py index e9c5d6741bd2..afceedada3e3 100644 --- a/test/python/quantum_info/operators/symplectic/test_sparse_pauli_op.py +++ b/test/python/quantum_info/operators/symplectic/test_sparse_pauli_op.py @@ -20,7 +20,7 @@ from ddt import ddt from qiskit import QiskitError -from qiskit.circuit import Parameter, ParameterVector +from qiskit.circuit import ParameterExpression, Parameter, ParameterVector from qiskit.circuit.parametertable import ParameterView from qiskit.quantum_info.operators import Operator, Pauli, PauliList, PauliTable, SparsePauliOp from qiskit.test import QiskitTestCase @@ -588,14 +588,28 @@ def test_sub_qargs(self, num_qubits): self.assertEqual(value, target) np.testing.assert_array_equal(op.paulis.phase, np.zeros(op.size)) - @combine(num_qubits=[1, 2, 3], value=[0, 1, 1j, -3 + 4.4j, np.int64(2)], param=[None, "a"]) + @combine( + num_qubits=[1, 2, 3], + value=[ + 0, + 1, + 1j, + -3 + 4.4j, + np.int64(2), + Parameter("x"), + 0 * Parameter("x"), + (-2 + 1.7j) * Parameter("x"), + ], + param=[None, "a"], + ) def test_mul(self, num_qubits, value, param): """Test * method for {num_qubits} qubits and value {value}.""" spp_op = self.random_spp_op(num_qubits, 2**num_qubits, param) target = value * spp_op.to_matrix() op = value * spp_op value_mat = op.to_matrix() - if value != 0 and param is not None: + has_parameters = isinstance(value, ParameterExpression) or param is not None + if value != 0 and has_parameters: value_mat = bind_parameters_to_one(value_mat) target = bind_parameters_to_one(target) if value == 0: @@ -606,7 +620,7 @@ def test_mul(self, num_qubits, value, param): target = spp_op.to_matrix() * value op = spp_op * value value_mat = op.to_matrix() - if value != 0 and param is not None: + if value != 0 and has_parameters: value_mat = bind_parameters_to_one(value_mat) target = bind_parameters_to_one(target) if value == 0: