def compose(self, other, qargs=None, front=False): """Return the composed operator. Args: other (BaseOperator): an operator object. qargs (list or None): a list of subsystem positions to apply other on. If None apply on all subsystems [default: None]. front (bool): If True compose using right operator multiplication, instead of left multiplication [default: False]. Returns: BaseOperator: The operator self @ other. Raises: QiskitError: if other has incompatible dimensions for specified subsystems. Additional Information: Composition (``@``) is defined as `left` matrix multiplication for matrix operators. That is that ``A @ B`` is equal to ``B * A``. Setting ``front=True`` returns `right` matrix multiplication ``A * B`` and is equivalent to the :meth:`dot` method. """ if qargs is None: qargs = getattr(other, 'qargs', None) if not isinstance(other, BaseOperator): other = Operator(other) new_shape = self._op_shape.compose(other._op_shape, qargs, front) # If other is also an ScalarOp we only need to # update the coefficient and dimensions if isinstance(other, ScalarOp): ret = copy.copy(self) ret._coeff = self.coeff * other.coeff ret._op_shape = new_shape return ret # If we are composing on the full system we return the # other operator with reshaped dimensions if qargs is None: ret = copy.copy(other) ret._op_shape = new_shape # Other operator might not support scalar multiplication # so we treat the identity as a special case to avoid a # possible error if self.coeff == 1: return ret return self.coeff * ret # For qargs composition we initialize the scalar operator # as an instance of the other BaseOperators subclass. We then # perform subsystem qargs composition using the BaseOperator # subclasses compose method. # Note that this will raise an error if the other operator does # not support initialization from a ScalarOp or the ScalarOps # `to_operator` method). return other.__class__(self).compose(other, qargs=qargs, front=front)
def compose(self, other, qargs=None, front=False): if qargs is None: qargs = getattr(other, "qargs", None) if not isinstance(other, BaseOperator): other = Operator(other) new_shape = self._op_shape.compose(other._op_shape, qargs, front) # If other is also an ScalarOp we only need to # update the coefficient and dimensions if isinstance(other, ScalarOp): ret = copy.copy(self) ret._coeff = self.coeff * other.coeff ret._op_shape = new_shape return ret # If we are composing on the full system we return the # other operator with reshaped dimensions if qargs is None: ret = copy.copy(other) ret._op_shape = new_shape # Other operator might not support scalar multiplication # so we treat the identity as a special case to avoid a # possible error if self.coeff == 1: return ret return self.coeff * ret # For qargs composition we initialize the scalar operator # as an instance of the other BaseOperators subclass. We then # perform subsystem qargs composition using the BaseOperator # subclasses compose method. # Note that this will raise an error if the other operator does # not support initialization from a ScalarOp or the ScalarOps # `to_operator` method). return other.__class__(self).compose(other, qargs=qargs, front=front)