def _pm_expand(self, constr): # Get objects v = constr.left v = vstack([v[i, 0] for i in range(0, v.shape[0])]) n = v.shape[0] - 1 x = vstack([v[0:n, 0]]) y = v[n, 0] z = variable() # One element if n == 1: return cvxpy_list([greater_equals(x, 0), greater_equals(x, y)]) # Get power of 2 size m = 0 while np.log2(n + m) % 1 != 0: m += 1 # Copy elements of x on a list and restrict them constr_list = [] el_list = [] for i in range(0, n, 1): el_list += [x[i, 0]] if (not np.isscalar(x[i, 0]) and type(x[i, 0]) is not cvxpy_obj): constr_list += [greater_equals(x[i, 0], 0)] # Construct expansion for i in range(0, m, 1): el_list += [z] while len(el_list) > 2: new_list = [] for i in range(0, int(len(el_list) / 2)): x1 = el_list[2 * i] x2 = el_list[2 * i + 1] w = variable() constr_list += [ belongs(vstack((hstack((x1, w)), hstack((w, x2)))), semidefinite_cone) ] new_list += [w] el_list = new_list x1 = el_list[0] x2 = el_list[1] constr_list += [ belongs(vstack((hstack((x1, z)), hstack((z, x2)))), semidefinite_cone) ] constr_list += [greater_equals(z, 0), greater_equals(z, y)] return cvxpy_list(constr_list)
def _pm_expand(self,constr): # Get objects v = constr.left v = vstack([v[i,0] for i in range(0,v.shape[0])]) n = v.shape[0]-1 x = vstack([v[0:n,0]]) y = v[n,0] z = variable() # One element if n==1: return cvxpy_list([greater_equals(x,0), greater_equals(x,y)]) # Get power of 2 size m = 0 while np.log2(n+m) % 1 != 0: m += 1 # Copy elements of x on a list and restrict them constr_list = [] el_list = [] for i in range(0,n,1): el_list+=[x[i,0]] if (not np.isscalar(x[i,0]) and type(x[i,0]) is not cvxpy_obj): constr_list += [greater_equals(x[i,0],0)] # Construct expansion for i in range(0,m,1): el_list += [z] while len(el_list) > 2: new_list = [] for i in range(0,int(len(el_list)/2)): x1 = el_list[2*i] x2 = el_list[2*i+1] w = variable() constr_list += [belongs(vstack((hstack((x1,w)), hstack((w,x2)))), semidefinite_cone)] new_list += [w] el_list = new_list x1 = el_list[0] x2 = el_list[1] constr_list += [belongs(vstack((hstack((x1,z)), hstack((z,x2)))), semidefinite_cone)] constr_list += [greater_equals(z,0),greater_equals(z,y)] return cvxpy_list(constr_list)
def _pm_expand(self,constr): # Get shape v = constr.left n = v.shape[0]-1 x = v[0:n,0] y = v[n,0] z = var() # Get power of 2 size m = 0 while (np.log2(n+m) % 1 != 0): m = m + 1 # Copy elements of x on a list and restrict them constr_list = [] el_list = [] for i in range(0,n,1): el_list+=[x[i,0]] if(not np.isscalar(x[i,0]) and type(x[i,0]) is not cvxpy_obj): constr_list += [greater(x[i,0],0)] # Construct expansion z = var() for i in range(0,m,1): el_list += [z] while(len(el_list) > 2): new_list = [] for i in range(0,len(el_list)/2): x1 = el_list[2*i] x2 = el_list[2*i+1] w = var() constr_list += [belongs(vstack((hstack((x1,w)), hstack((w,x2)))), sdc(2))] new_list += [w] el_list = new_list x1 = el_list[0] x2 = el_list[1] constr_list += [belongs(vstack((hstack((x1,z)), hstack((z,x2)))), sdc(2))] constr_list += [greater(z,0),greater(z,y)] return cvxpy_list(constr_list)
def _pm_expand(self, constr): # Get shape v = constr.left n = v.shape[0] - 1 x = v[0:n, 0] y = v[n, 0] z = var() # Get power of 2 size m = 0 while np.log2(n + m) % 1 != 0: m = m + 1 # Copy elements of x on a list and restrict them constr_list = [] el_list = [] for i in range(0, n, 1): el_list += [x[i, 0]] if not np.isscalar(x[i, 0]) and type(x[i, 0]) is not cvxpy_obj: constr_list += [greater(x[i, 0], 0)] # Construct expansion z = var() for i in range(0, m, 1): el_list += [z] while len(el_list) > 2: new_list = [] for i in range(0, len(el_list) / 2): x1 = el_list[2 * i] x2 = el_list[2 * i + 1] w = var() constr_list += [belongs(vstack((hstack((x1, w)), hstack((w, x2)))), sdc(2))] new_list += [w] el_list = new_list x1 = el_list[0] x2 = el_list[1] constr_list += [belongs(vstack((hstack((x1, z)), hstack((z, x2)))), sdc(2))] constr_list += [greater(z, 0), greater(z, y)] return cvxpy_list(constr_list)
def re_eval(arg,replace_map): """ Re-evaluates argument. :param replace_map: Dictionary. """ # Number if np.isscalar(arg): return arg # Constant object elif type(arg) is cvxpy_obj: return arg.value # Scalar variable elif type(arg) is cvxpy_scalar_var: if arg in replace_map.keys(): return re_eval(replace_map[arg],replace_map) else: return arg # Scalar param elif type(arg) is cvxpy_scalar_param: if arg in replace_map.keys(): return re_eval(replace_map[arg],replace_map) else: return arg # Summation elif (type(arg) is cvxpy_tree and arg.item.type == OPERATOR and arg.item.name == SUMMATION): new_children = list(map(lambda x:re_eval(x,replace_map),arg.children)) return sum(new_children) # Multiplication elif (type(arg) is cvxpy_tree and arg.item.type == OPERATOR and arg.item.name == MULTIPLICATION): child1 = re_eval(arg.children[0],replace_map) child2 = re_eval(arg.children[1],replace_map) return child1*child2 # Function elif (type(arg) is cvxpy_tree and arg.item.type == FUNCTION): new_children = list(map(lambda x:re_eval(x,replace_map),arg.children)) return arg.item(new_children) # Constraint elif type(arg) is cvxpy_constr: # Not set membership if arg.type != BELONGS: left = re_eval(arg.left ,replace_map) right= re_eval(arg.right,replace_map) if arg.type == EQUALS: return equals(left,right) elif arg.type == LESS_EQUALS: return less_equals(left,right) elif arg.type == GREATER_EQUALS: return greater_equals(left,right) else: raise TypeError('Invalid constraint') # Set membership else: left = re_eval(arg.left,replace_map) return belongs(left,arg.right) # Array elif (type(arg) is cvxpy_array or type(arg) is cvxpy_var or type(arg) is cvxpy_param): (m,n) = arg.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] = re_eval(arg[i,j],replace_map) return new_ar # List elif (type(arg) is list or type(arg) is cvxpy_list): new_list = [] for c in arg: new_list += [re_eval(c,replace_map)] return cvxpy_list(new_list) # Invalid else: raise TypeError('Invalid argument')
def re_eval(arg,param_map): """ Description ----------- Replaces parameters found in arg using the param_map and re-evaluates the resulting object. Arguments --------- arg: Argument to be re-evaluated. param_map: Dictionery that maps the parameters to objects. """ # Number if(np.isscalar(arg)): return arg # Constant object elif(type(arg) is cvxpy_obj): return arg.get_value() # Scalar variable elif(type(arg) is cvxpy_scalar_var): return arg # Scalar param elif(type(arg) is cvxpy_scalar_param): return re_eval(param_map[arg],param_map) # Summation elif(type(arg) is cvxpy_tree and arg.item.name == '+'): new_children = map(lambda x:re_eval(x,param_map),arg.children) return sum(new_children) # Multiplication elif(type(arg) is cvxpy_tree and arg.item.name == '*'): child1 = re_eval(arg.children[0],param_map) child2 = re_eval(arg.children[1],param_map) return child1*child2 # Function elif(type(arg) is cvxpy_tree and arg.item.type == FUNCTION): new_children = map(lambda x:re_eval(x,param_map),arg.children) return arg.item(new_children) # Constraint elif(type(arg) is cvxpy_constr): # Not set membership if(arg.op != 'in'): left = re_eval(arg.left ,param_map) right= re_eval(arg.right,param_map) if(arg.op == '=='): return equal(left,right) elif(arg.op == '<='): return less(left,right) else: return greater(left,right) # Set membership else: left = re_eval(arg.left,param_map) return belongs(left,arg.right) # Array elif(type(arg) is cvxpy_expression or type(arg) is cvxpy_var or type(arg) is cvxpy_param): (m,n) = arg.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] = re_eval(arg[i,j],param_map) return new_exp # List elif(type(arg) is cvxpy_list): new_list = cvxpy_list([]) for c in arg: new_list += cvxpy_list([re_eval(c,param_map)]) return new_list # Invalid else: raise ValueError('Invalid argument')