def __matmul__(self, other): """Expression : Matrix multiplication of two expressions. """ if self.shape == () or other.shape == (): raise ValueError( "Scalar operands are not allowed, use '*' instead") return cvxtypes.matmul_expr()(self, other)
def __rmatmul__(self, other): """Expression : Called for matrix @ Expression. """ if self.shape == () or other.shape == (): raise ValueError( "Scalar operands are not allowed, use '*' instead") return cvxtypes.matmul_expr()(other, self)
def __mul__(self, other): """Expression : The product of two expressions. """ if self.shape == () or other.shape == (): # Use one argument to apply a scaling to the remaining argument. # We accomplish this with elementwise multiplication, which # casts the scalar argument to match the size of the remaining # argument. return cvxtypes.elmul_expr()(self, other) elif self.shape[-1] != other.shape[0] and \ (self.is_scalar() or other.is_scalar()): # If matmul was intended, this gives a dimension mismatch. We # interpret the ``is_scalar`` results as implying that the user # simply wants to apply a scaling. return cvxtypes.elmul_expr()(self, other) else: # The only reasonable interpretation is that the user intends # to apply matmul. There might be a dimension mismatch, but we # don't check for that here. if not (self.is_constant() or other.is_constant()): if error.warnings_enabled(): warnings.warn("Forming a nonconvex expression.") # Because we want to discourage using ``*`` to call matmul, we # raise a warning to the user. warnings.resetwarnings() warnings.warn(__STAR_MATMUL_WARNING__, DeprecationWarning) warnings.resetwarnings() return cvxtypes.matmul_expr()(self, other)