def compare(obj1, constraint_type, obj2): """ Compares obj1 with obj2. :param obj1: Left hand side obejct. :param constraint_type: Keyword (See cvxpy.defs.). :param obj2: Right hand side object. """ # Both scalars if ((np.isscalar(obj1) or type(obj1).__name__ in SCALAR_OBJS) and (np.isscalar(obj2) or type(obj2).__name__ in SCALAR_OBJS)): # Upgrade scalars to cvxpy_obj if np.isscalar(obj1): obj1 = cvxpy_obj(CONSTANT, obj1, str(obj1)) if np.isscalar(obj2): obj2 = cvxpy_obj(CONSTANT, obj2, str(obj2)) # Construct and return constraint return cvxpy_constr(obj1, constraint_type, obj2) # Upgrate scalars to arrays if ((type(obj1) is cvxpy_matrix or type(obj1).__name__ in ARRAY_OBJS) and (np.isscalar(obj2) or type(obj2).__name__ in SCALAR_OBJS)): (m, n) = obj1.shape new_ar = cvxpy_array(m, n) for i in range(0, m, 1): for j in range(0, n, 1): new_ar[i, j] = obj2 obj2 = new_ar if ((type(obj2) is cvxpy_matrix or type(obj2).__name__ in ARRAY_OBJS) and (np.isscalar(obj1) or type(obj1).__name__ in SCALAR_OBJS)): (m, n) = obj2.shape new_ar = cvxpy_array(m, n) for i in range(0, m, 1): for j in range(0, n, 1): new_ar[i, j] = obj1 obj1 = new_ar # Both arrays if ((type(obj1) is cvxpy_matrix or type(obj1).__name__ in ARRAY_OBJS) and (type(obj2) is cvxpy_matrix or type(obj2).__name__ in ARRAY_OBJS)): constr = [] if obj1.shape != obj2.shape: raise ValueError('Invalid dimensions') (m, n) = obj1.shape for i in range(0, m, 1): for j in range(0, n, 1): constr += [compare(obj1[i, j], constraint_type, obj2[i, j])] return cvxpy_list(constr) # Invalid arguments raise TypeError('Objects not comparable')
def compare(obj1,constraint_type,obj2): """ Compares obj1 with obj2. :param obj1: Left hand side obejct. :param constraint_type: Keyword (See cvxpy.defs.). :param obj2: Right hand side object. """ # Both scalars if ((np.isscalar(obj1) or type(obj1).__name__ in SCALAR_OBJS) and (np.isscalar(obj2) or type(obj2).__name__ in SCALAR_OBJS)): # Upgrade scalars to cvxpy_obj if np.isscalar(obj1): obj1 = cvxpy_obj(CONSTANT,obj1,str(obj1)) if np.isscalar(obj2): obj2 = cvxpy_obj(CONSTANT,obj2,str(obj2)) # Construct and return constraint return cvxpy_constr(obj1,constraint_type,obj2) # Upgrate scalars to arrays if ((type(obj1) is cvxpy_matrix or type(obj1).__name__ in ARRAY_OBJS) and (np.isscalar(obj2) or type(obj2).__name__ in SCALAR_OBJS)): (m,n) = obj1.shape new_ar = cvxpy_array(m,n) for i in range(0,m,1): for j in range(0,n,1): new_ar[i,j] = obj2 obj2 = new_ar if ((type(obj2) is cvxpy_matrix or type(obj2).__name__ in ARRAY_OBJS) and (np.isscalar(obj1) or type(obj1).__name__ in SCALAR_OBJS)): (m,n) = obj2.shape new_ar = cvxpy_array(m,n) for i in range(0,m,1): for j in range(0,n,1): new_ar[i,j] = obj1 obj1 = new_ar # Both arrays if ((type(obj1) is cvxpy_matrix or type(obj1).__name__ in ARRAY_OBJS) and (type(obj2) is cvxpy_matrix or type(obj2).__name__ in ARRAY_OBJS)): constr = [] if obj1.shape != obj2.shape: raise ValueError('Invalid dimensions') (m,n) = obj1.shape for i in range(0,m,1): for j in range(0,n,1): constr += [compare(obj1[i,j],constraint_type,obj2[i,j])] return cvxpy_list(constr) # Invalid arguments raise TypeError('Objects not comparable')
def __call__(self, *arg): # Check number of arguments if len(arg) != 1: raise ValueError("Invalid number of arguments") # Extract argument if type(arg[0]) is list: x = hstack(arg[0]) else: x = arg[0] # Process if type(x).__name__ in SCALAR_OBJS: return x elif type(x).__name__ in ARRAY_OBJS: (m, n) = x.shape if m != 1 and n != 1: raise ValueError("Argument must be 1-Dimensional") children = [] for i in range(0, m, 1): for j in range(0, n, 1): if np.isscalar(x[i, j]): children += [cvxpy_obj(CONSTANT, x[i, j], str(x[i, j]))] else: children += [x[i, j]] return cvxpy_tree(self, children) else: return np.max(x)
def prog(pair, constr=[], params=[], opt=None, name='prog'): """ Create an optimization program. :param pair: (MAXIMIZE or MINIMIZE, objective) :param constr: List of :class:`cvxpy_constr` or :class:`cvxpy_list`. :param params: List of :class:`cvxpy_scalar_param` or :class:`cvxpy_param`. This list must match the number of parameters present in the program. :param opt: Dictionary of options. :param name: Program name string. :rtype: :class:`cvxpy_program`. """ # Parameters action = pair[0] obj = pair[1] # Verify objective if ((not np.isscalar(obj)) and (not type(obj) is cvxpy_obj) and type(obj).__name__ not in SCALAR_OBJS): raise ValueError('Invalid Objective') # Upgrade numeric objective to scalar object if (np.isscalar(obj)): obj = cvxpy_obj(CONSTANT, obj, str(obj)) # Return program return cvxpy_program(action, obj, constr, params, opt, name)
def __call__(self, *arg): # Check number of arguments if (len(arg) != 1): raise ValueError('Invalid number of arguments') # Extract argument if (type(arg[0]) is list): x = hstack(arg[0]) else: x = arg[0] # Process if (type(x).__name__ in SCALAR_OBJS): return x elif (type(x).__name__ in ARRAY_OBJS): (m, n) = x.shape if (m != 1 and n != 1): raise ValueError('Argument must be 1-Dimensional') children = [] for i in range(0, m, 1): for j in range(0, n, 1): if (np.isscalar(x[i, j])): children += [ cvxpy_obj(CONSTANT, x[i, j], str(x[i, j])) ] else: children += [x[i, j]] return cvxpy_tree(self, children) else: return np.max(x)
def prog(pair,constr=[],params=[],opt=None,name='prog'): """ Create an optimization program. :param pair: (MAXIMIZE or MINIMIZE, objective) :param constr: List of :class:`cvxpy_constr` or :class:`cvxpy_list`. :param params: List of :class:`cvxpy_scalar_param` or :class:`cvxpy_param`. This list must match the number of parameters present in the program. :param opt: Dictionary of options. :param name: Program name string. :rtype: :class:`cvxpy_program`. """ # Parameters action = pair[0] obj = pair[1] # Verify objective if((not np.isscalar(obj)) and (not type(obj) is cvxpy_obj) and type(obj).__name__ not in SCALAR_OBJS): raise ValueError('Invalid Objective') # Upgrade numeric objective to scalar object if(np.isscalar(obj)): obj = cvxpy_obj(CONSTANT,obj,str(obj)) # Return program return cvxpy_program(action,obj,constr,params,opt,name)
def compare(obj1, op, obj2): # Both scalars if ((np.isscalar(obj1) or type(obj1).__name__ in SCALAR_OBJS) and (np.isscalar(obj2) or type(obj2).__name__ in SCALAR_OBJS)): # Upgrade scalars to cvxpy_obj if (np.isscalar(obj1)): obj1 = cvxpy_obj(CONSTANT, obj1, str(obj1)) if (np.isscalar(obj2)): obj2 = cvxpy_obj(CONSTANT, obj2, str(obj2)) # Construct and return constraint return cvxpy_constr(obj1, op, obj2) # Upgrate scalars to arrays if ((type(obj1) is cvxpy_matrix or type(obj1).__name__ in ARRAY_OBJS) and (np.isscalar(obj2) or type(obj2).__name__ in SCALAR_OBJS)): (m, n) = obj1.shape new_exp = cvxpy_expression(m, n) for i in range(0, m, 1): for j in range(0, n, 1): new_exp[i, j] = obj2 obj2 = new_exp if ((type(obj2) is cvxpy_matrix or type(obj2).__name__ in ARRAY_OBJS) and (np.isscalar(obj1) or type(obj1).__name__ in SCALAR_OBJS)): (m, n) = obj2.shape new_exp = cvxpy_expression(m, n) for i in range(0, m, 1): for j in range(0, n, 1): new_exp[i, j] = obj1 obj1 = new_exp # Both arrays if ((type(obj1) is cvxpy_matrix or type(obj1).__name__ in ARRAY_OBJS) and (type(obj2) is cvxpy_matrix or type(obj2).__name__ in ARRAY_OBJS)): constr = [] if (obj1.shape != obj2.shape): raise ValueError('Invalid dimensions') (m, n) = obj1.shape for i in range(0, m, 1): for j in range(0, n, 1): constr += [compare(obj1[i, j], op, obj2[i, j])] return cvxpy_list(constr) # Invalid arguments raise ValueError('Objects not comparable')
def compare(obj1,op,obj2): # Both scalars if((np.isscalar(obj1) or type(obj1).__name__ in SCALAR_OBJS) and (np.isscalar(obj2) or type(obj2).__name__ in SCALAR_OBJS)): # Upgrade scalars to cvxpy_obj if(np.isscalar(obj1)): obj1 = cvxpy_obj(CONSTANT,obj1,str(obj1)) if(np.isscalar(obj2)): obj2 = cvxpy_obj(CONSTANT,obj2,str(obj2)) # Construct and return constraint return cvxpy_constr(obj1,op,obj2) # Upgrate scalars to arrays if((type(obj1) is cvxpy_matrix or type(obj1).__name__ in ARRAY_OBJS) and (np.isscalar(obj2) or type(obj2).__name__ in SCALAR_OBJS)): (m,n) = obj1.shape new_exp = cvxpy_expression(m,n) for i in range(0,m,1): for j in range(0,n,1): new_exp[i,j] = obj2 obj2 = new_exp if((type(obj2) is cvxpy_matrix or type(obj2).__name__ in ARRAY_OBJS) and (np.isscalar(obj1) or type(obj1).__name__ in SCALAR_OBJS)): (m,n) = obj2.shape new_exp = cvxpy_expression(m,n) for i in range(0,m,1): for j in range(0,n,1): new_exp[i,j] = obj1 obj1 = new_exp # Both arrays if((type(obj1) is cvxpy_matrix or type(obj1).__name__ in ARRAY_OBJS) and (type(obj2) is cvxpy_matrix or type(obj2).__name__ in ARRAY_OBJS)): constr = [] if(obj1.shape != obj2.shape): raise ValueError('Invalid dimensions') (m,n) = obj1.shape for i in range(0,m,1): for j in range(0,n,1): constr += [compare(obj1[i,j],op,obj2[i,j])] return cvxpy_list(constr) # Invalid arguments raise ValueError('Objects not comparable')
def expand(arg): # Constant if(type(arg) is cvxpy_obj): return arg,cvxpy_list([]) # Scalar variable elif(type(arg) is cvxpy_scalar_var): return arg,cvxpy_list([]) # Summation elif(type(arg) is cvxpy_tree and arg.item.name == '+'): # Get item and children item = arg.item children = arg.children # New var v = var() # Expand children new_children = [] new_constr = cvxpy_list([]) for child in children: # Multiplication if(child.type == TREE and child.item.name == '*'): child_var,child_constr = expand(child.children[1]) new_children += [child.children[0].data*child_var] new_constr += child_constr # Else else: child_var,child_constr = expand(child) new_children += [child_var] new_constr += child_constr # Return (Always right side is the new variable) new_tree = cvxpy_tree(item,new_children) return v,cvxpy_list([equal(new_tree,v)])+new_constr # Multiplication elif(type(arg) is cvxpy_tree and arg.item.name == '*'): # Get item and children item = arg.item children = arg.children # New var v = var() # Apply expand to second operand (first is a constant) child_var,child_constr = expand(children[1]) # Return result (Always right side is the new variable) new_tree = cvxpy_tree(item,[children[0],child_var]) new_eq = cvxpy_list([equal(new_tree,v)]) new_eq += child_constr return v,new_eq # Function elif(type(arg) is cvxpy_tree and arg.item.type == FUNCTION): # Get item and children item = arg.item children = arg.children # New var v = var() # Analyze children new_children = [] new_constr = cvxpy_list([]) for child in children: child_var,child_constr = expand(child) new_children += [child_var] new_constr += child_constr # Return (Always right side is the new variable) new_tree = cvxpy_tree(item,new_children) new_constr += item._range_constr(v) new_constr += item._dom_constr(new_children) return v,cvxpy_list([equal(new_tree,v)])+new_constr # Constraint elif(type(arg) is cvxpy_constr): # Not set membership if(arg.op != 'in'): # Apply expand to left and right side obj1,constr_list1 = expand(arg.left) obj2,constr_list2 = expand(arg.right) # Return new constraints new_constr = cvxpy_constr(obj1,arg.op,obj2) new_list = cvxpy_list([new_constr]) new_list += constr_list1 new_list += constr_list2 return new_list # Set membership else: obj, constr_list = expand(arg.left) new_constr = cvxpy_constr(obj,arg.op,arg.right) return cvxpy_list([new_constr])+constr_list # Array elif(type(arg) is cvxpy_expression or type(arg) is cvxpy_var): (m,n) = arg.shape new_list = cvxpy_list([]) new_exp = cvxpy_expression(m,n) for i in range(0,m,1): for j in range(0,n,1): # Number: Upgrade if(np.isscalar(arg[i,j])): new_exp[i,j] = cvxpy_obj(CONSTANT,arg[i,j],str(arg[i,j])) # Not a number else: obj,constr_list = expand(arg[i,j]) new_exp[i,j] = obj new_list += constr_list return new_exp,new_list # List of constraints elif(type(arg) is cvxpy_list): # Empty list if(len(arg) == 0): return cvxpy_list([]) else: new_list = map(expand,arg) return reduce(lambda x,y:x+y,new_list) # Invalid else: raise ValueError('Invalid argument')
def expand(arg): # Constant if (type(arg) is cvxpy_obj): return arg, cvxpy_list([]) # Scalar variable elif (type(arg) is cvxpy_scalar_var): return arg, cvxpy_list([]) # Summation elif (type(arg) is cvxpy_tree and arg.item.name == '+'): # Get item and children item = arg.item children = arg.children # New var v = var() # Expand children new_children = [] new_constr = cvxpy_list([]) for child in children: # Multiplication if (child.type == TREE and child.item.name == '*'): child_var, child_constr = expand(child.children[1]) new_children += [child.children[0].data * child_var] new_constr += child_constr # Else else: child_var, child_constr = expand(child) new_children += [child_var] new_constr += child_constr # Return (Always right side is the new variable) new_tree = cvxpy_tree(item, new_children) return v, cvxpy_list([equal(new_tree, v)]) + new_constr # Multiplication elif (type(arg) is cvxpy_tree and arg.item.name == '*'): # Get item and children item = arg.item children = arg.children # New var v = var() # Apply expand to second operand (first is a constant) child_var, child_constr = expand(children[1]) # Return result (Always right side is the new variable) new_tree = cvxpy_tree(item, [children[0], child_var]) new_eq = cvxpy_list([equal(new_tree, v)]) new_eq += child_constr return v, new_eq # Function elif (type(arg) is cvxpy_tree and arg.item.type == FUNCTION): # Get item and children item = arg.item children = arg.children # New var v = var() # Analyze children new_children = [] new_constr = cvxpy_list([]) for child in children: child_var, child_constr = expand(child) new_children += [child_var] new_constr += child_constr # Return (Always right side is the new variable) new_tree = cvxpy_tree(item, new_children) new_constr += item._range_constr(v) new_constr += item._dom_constr(new_children) return v, cvxpy_list([equal(new_tree, v)]) + new_constr # Constraint elif (type(arg) is cvxpy_constr): # Not set membership if (arg.op != 'in'): # Apply expand to left and right side obj1, constr_list1 = expand(arg.left) obj2, constr_list2 = expand(arg.right) # Return new constraints new_constr = cvxpy_constr(obj1, arg.op, obj2) new_list = cvxpy_list([new_constr]) new_list += constr_list1 new_list += constr_list2 return new_list # Set membership else: obj, constr_list = expand(arg.left) new_constr = cvxpy_constr(obj, arg.op, arg.right) return cvxpy_list([new_constr]) + constr_list # Array elif (type(arg) is cvxpy_expression or type(arg) is cvxpy_var): (m, n) = arg.shape new_list = cvxpy_list([]) new_exp = cvxpy_expression(m, n) for i in range(0, m, 1): for j in range(0, n, 1): # Number: Upgrade if (np.isscalar(arg[i, j])): new_exp[i, j] = cvxpy_obj(CONSTANT, arg[i, j], str(arg[i, j])) # Not a number else: obj, constr_list = expand(arg[i, j]) new_exp[i, j] = obj new_list += constr_list return new_exp, new_list # List of constraints elif (type(arg) is cvxpy_list): # Empty list if (len(arg) == 0): return cvxpy_list([]) else: new_list = map(expand, arg) return reduce(lambda x, y: x + y, new_list) # Invalid else: raise ValueError('Invalid argument')
def __call__(self, *args): """ Description ----------- Call program with specified arguments. Parameters are substituted with arguments. If all arguments are numeric, the resulting optimization program is solved. If some arguments are object, a tree is returned. Arguments --------- args: List of arguments. (Can be numbers or objects) """ # Process input if (len(args) != 0 and type(args[0]) is list): args = args[0] # Create argument list arg_list = [] for arg in args: if (np.isscalar(arg) or type(arg).__name__ in SCALAR_OBJS): arg_list += [arg] elif (type(arg) is cvxpy_matrix or type(arg).__name__ in ARRAY_OBJS): (m, n) = arg.shape for i in range(0, m, 1): for j in range(0, n, 1): arg_list += [arg[i, j]] else: raise ValueError('Invalid argument type') # Check number of arguments if (len(arg_list) != len(self.params)): raise ValueError('Invalid argument syntax') # Solve if numeric if (len(arg_list) == 0 or reduce(lambda x, y: x and y, map(lambda x: np.isscalar(x), arg_list))): # Substitute parameters with arguments p1_map = {} for k in range(0, len(arg_list), 1): p1_map[self.params[k]] = arg_list[k] new_p = prog((self.action, re_eval(self.obj, p1_map)), re_eval(self.constr, p1_map), [], self.options, self.name) # Solve program obj, lagrange_mul_eq = solve_prog(new_p) return obj # Upgrade numbers to objects for i in range(0, len(arg_list), 1): if (np.isscalar(arg_list[i])): arg_list[i] = cvxpy_obj(CONSTANT, arg_list[i], str(arg_list[i])) # Return tree return cvxpy_tree(self, arg_list)
def __call__(self,*args): """ Description ----------- Call program with specified arguments. Parameters are substituted with arguments. If all arguments are numeric, the resulting optimization program is solved. If some arguments are object, a tree is returned. Arguments --------- args: List of arguments. (Can be numbers or objects) """ # Process input if(len(args) != 0 and type(args[0]) is list): args = args[0] # Create argument list arg_list = [] for arg in args: if(np.isscalar(arg) or type(arg).__name__ in SCALAR_OBJS): arg_list += [arg] elif(type(arg) is cvxpy_matrix or type(arg).__name__ in ARRAY_OBJS): (m,n) = arg.shape for i in range(0,m,1): for j in range(0,n,1): arg_list += [arg[i,j]] else: raise ValueError('Invalid argument type') # Check number of arguments if(len(arg_list) != len(self.params)): raise ValueError('Invalid argument syntax') # Solve if numeric if(len(arg_list) == 0 or reduce(lambda x,y: x and y, map(lambda x: np.isscalar(x),arg_list))): # Substitute parameters with arguments p1_map = {} for k in range(0,len(arg_list),1): p1_map[self.params[k]] = arg_list[k] new_p = prog((self.action,re_eval(self.obj,p1_map)), re_eval(self.constr,p1_map),[], self.options,self.name) # Solve program obj,lagrange_mul_eq = solve_prog(new_p) return obj # Upgrade numbers to objects for i in range(0,len(arg_list),1): if(np.isscalar(arg_list[i])): arg_list[i] = cvxpy_obj(CONSTANT, arg_list[i], str(arg_list[i])) # Return tree return cvxpy_tree(self,arg_list)