def broadcast(lh_expr, rh_expr): """Broacast the binary operator. """ lh_expr = Expression.cast_to_const(lh_expr) rh_expr = Expression.cast_to_const(rh_expr) if lh_expr.is_scalar() and not rh_expr.is_scalar(): lh_expr = cvxtypes.promote()(lh_expr, rh_expr.shape) elif rh_expr.is_scalar() and not lh_expr.is_scalar(): rh_expr = cvxtypes.promote()(rh_expr, lh_expr.shape) # Broadcasting. if lh_expr.ndim == 2 and rh_expr.ndim == 2: # Replicate dimensions of size 1. dims = [max(lh_expr.shape[i], rh_expr.shape[i]) for i in range(2)] # Broadcast along dim 0. if lh_expr.shape[0] == 1 and lh_expr.shape[0] < dims[0]: lh_expr = np.ones((dims[0], 1)) @ lh_expr if rh_expr.shape[0] == 1 and rh_expr.shape[0] < dims[0]: rh_expr = np.ones((dims[0], 1)) @ rh_expr # Broadcast along dim 1. if lh_expr.shape[1] == 1 and lh_expr.shape[1] < dims[1]: lh_expr = lh_expr @ np.ones((1, dims[1])) if rh_expr.shape[1] == 1 and rh_expr.shape[1] < dims[1]: rh_expr = rh_expr @ np.ones((1, dims[1])) return lh_expr, rh_expr
def __init__(self, x, y, z, alpha, constr_id=None) -> None: Expression = cvxtypes.expression() self.x = Expression.cast_to_const(x) self.y = Expression.cast_to_const(y) self.z = Expression.cast_to_const(z) for val in [self.x, self.y, self.z]: if not (val.is_affine() and val.is_real()): raise ValueError('All arguments must be affine and real.') alpha = Expression.cast_to_const(alpha) if alpha.is_scalar(): alpha = cvxtypes.promote()(alpha, self.x.shape) self.alpha = alpha if np.any(self.alpha.value <= 0) or np.any(self.alpha.value >= 1): msg = "Argument alpha must have entries in the open interval (0, 1)." raise ValueError(msg) arg_shapes = [self.x.shape, self.y.shape, self.z.shape, self.alpha.shape] if any(arg_shapes[0] != s for s in arg_shapes[1:]): msg = ("All arguments must have the same shapes. Provided arguments have" "shapes %s" % str(arg_shapes)) raise ValueError(msg) super(PowCone3D, self).__init__([self.x, self.y, self.z], constr_id)