def __mul__(self, other): """Handles logic of multiplying signs. Cases: ZERO * ANYTHING = ZERO UNKNOWN * NON-ZERO = UNKNOWN POSITIVE * NEGATIVE = NEGATIVE POSITIVE * POSITIVE = POSITIVE NEGATIVE * NEGATIVE = POSITIVE Args: self: The Sign of the left-hand multiplier. other: The Sign of the right-hand multiplier. Returns: The Sign of the product. """ neg_mat = bu.dot(self.neg_mat, other.pos_mat) | \ bu.dot(self.pos_mat, other.neg_mat) pos_mat = bu.dot(self.neg_mat, other.neg_mat) | \ bu.dot(self.pos_mat, other.pos_mat) # Reduce 1x1 matrices to scalars. neg_mat = bu.to_scalar(neg_mat) pos_mat = bu.to_scalar(pos_mat) return Sign(neg_mat, pos_mat)
def sign_mul(sign, curv): """Handles logic of sign by curvature multiplication. Cases: ZERO * ANYTHING = CONSTANT NON-ZERO * AFFINE/CONSTANT = AFFINE/CONSTANT UNKNOWN * NON-AFFINE = UNKNOWN POSITIVE * ANYTHING = ANYTHING NEGATIVE * CONVEX = CONCAVE NEGATIVE * CONCAVE = CONVEX Args: sign: The Sign of the left-hand multiplier. curv: The Curvature of the right-hand multiplier. Returns: The Curvature of the product. """ cvx_mat = bu.dot(sign.pos_mat, curv.cvx_mat) | \ bu.dot(sign.neg_mat, curv.conc_mat) conc_mat = bu.dot(sign.pos_mat, curv.conc_mat) | \ bu.dot(sign.neg_mat, curv.cvx_mat) nonconst_mat = bu.dot(sign.pos_mat, curv.nonconst_mat) | \ bu.dot(sign.neg_mat, curv.nonconst_mat) # Simplify 1x1 matrices to scalars. cvx_mat = bu.to_scalar(cvx_mat) conc_mat = bu.to_scalar(conc_mat) nonconst_mat = bu.to_scalar(nonconst_mat) return Curvature(cvx_mat, conc_mat, nonconst_mat)
def __getitem__(self, key): """Determines the DCP attributes of an index/slice. Args: key: A (slice, slice) tuple. Returns: The DCPAttr of the index/slice into the matrix expression. """ shape = Shape(*ku.size(key, self.shape)) # Reduce 1x1 matrices to scalars. neg_mat = bu.to_scalar(bu.index(self.sign.neg_mat, key)) pos_mat = bu.to_scalar(bu.index(self.sign.pos_mat, key)) cvx_mat = bu.to_scalar(bu.index(self.curvature.cvx_mat, key)) conc_mat = bu.to_scalar(bu.index(self.curvature.conc_mat, key)) nonconst_mat = bu.to_scalar(bu.index(self.curvature.nonconst_mat, key)) return DCPAttr(Sign(neg_mat, pos_mat), Curvature(cvx_mat, conc_mat, nonconst_mat), shape)