Skip to content

Commit

Permalink
feat: support sum(LinearMixin) (#8722)
Browse files Browse the repository at this point in the history
* feat: support sum(LinearMixin)

This enables the use of `sum(...)` for subclasses of the `LinearMixin`
class. It also adds the reflective operand dunder methods `__radd__` and
`__rsub__`.

* Add crossreferences to release note

Co-authored-by: Jake Lishman <jake.lishman@ibm.com>
  • Loading branch information
mrossinek and jakelishman authored Sep 9, 2022
1 parent 686ba34 commit e8001f5
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 0 deletions.
16 changes: 16 additions & 0 deletions qiskit/quantum_info/operators/mixins/linear.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,29 @@ class LinearMixin(MultiplyMixin, ABC):
"""

def __add__(self, other):
# enable easy use of sum(...)
if not isinstance(other, type(self)) and other == 0:
return self

qargs = getattr(other, "qargs", None)
return self._add(other, qargs=qargs)

def __radd__(self, other):
# enable easy use of sum(...)
if not isinstance(other, type(self)) and other == 0:
return self

qargs = getattr(other, "qargs", None)
return self._add(other, qargs=qargs)

def __sub__(self, other):
qargs = getattr(other, "qargs", None)
return self._add(-other, qargs=qargs)

def __rsub__(self, other):
qargs = getattr(other, "qargs", None)
return (-self)._add(other, qargs=qargs)

@abstractmethod
def _add(self, other, qargs=None):
"""Return the CLASS self + other.
Expand Down
5 changes: 5 additions & 0 deletions releasenotes/notes/base-operators-sums-d331e78a9fa4b5d8.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
features:
- |
``qiskit.quantum_info.BaseOperator`` subclasses (like :class:`.ScalarOp`,
:class:`.SparsePauliOp` and :class:`.PauliList`) can now be used with ``sum``.
32 changes: 32 additions & 0 deletions test/python/quantum_info/operators/test_scalar_op.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,27 @@ def test_add(self, coeff1, coeff2):
target = coeff1 + coeff2
self.assertScalarOp(val, dims, target)

@combine(coeff1=[0, 1, -3.1, 1 + 3j])
def test_radd(self, coeff1):
"""Test right-side addition with ScalarOp."""
dims = (3, 2)
op1 = ScalarOp(dims, coeff=coeff1)

val = op1 + 0
self.assertScalarOp(val, dims, coeff1)

@combine(coeff1=[0, 1, -3.1, 1 + 3j], coeff2=[-1, -5.1 - 2j])
def test_sum(self, coeff1, coeff2):
"""Test add operation with ScalarOp. ({coeff1} + {coeff2})"""
# Add two ScalarOps
dims = (3, 2)
op1 = ScalarOp(dims, coeff=coeff1)
op2 = ScalarOp(6, coeff=coeff2)

val = sum([op1, op2])
target = coeff1 + coeff2
self.assertScalarOp(val, dims, target)

@combine(coeff1=[0, 1, -3.1, 1 + 3j], coeff2=[-1, -5.1 - 2j])
def test_subtract(self, coeff1, coeff2):
"""Test add operation with ScalarOp. ({coeff1} - {coeff2})"""
Expand All @@ -179,6 +200,17 @@ def test_subtract(self, coeff1, coeff2):
target = coeff1 - coeff2
self.assertScalarOp(val, dims, target)

@combine(coeff1=[0, 1, -3.1, 1 + 3j], coeff2=[-1, -5.1 - 2j])
def test_rsub(self, coeff1, coeff2):
"""Test right-side subtraction with ScalarOp."""
dims = (3, 2)
op1 = ScalarOp(dims, coeff=coeff1)
op2 = ScalarOp(dims, coeff=coeff2)

val = op2.__rsub__(op1)
target = coeff1 - coeff2
self.assertScalarOp(val, dims, target)

@combine(
coeff1=[0, 1, -3.1, 1 + 3j],
coeff2=[-1, -5.1 - 2j],
Expand Down

0 comments on commit e8001f5

Please sign in to comment.