Skip to content

Commit

Permalink
Allow multiplication of SparsePauliOp and ParameterExpression (#10264)
Browse files Browse the repository at this point in the history
* Allow multiplication of SparsePauliOp and ParameterExpression

* Add unit tests for SparsePauliOp and ParameterExpression multiplication

* Add release note for the new feature
  • Loading branch information
SimoneGasperini authored Jun 26, 2023
1 parent 791a454 commit c693852
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 6 deletions.
4 changes: 2 additions & 2 deletions qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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 <https://github.com/Qiskit/qiskit-terra/issues/10185>`.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand All @@ -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:
Expand Down

0 comments on commit c693852

Please sign in to comment.