예제 #1
0
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')
예제 #2
0
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')    
예제 #3
0
    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)
예제 #4
0
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)
예제 #5
0
    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)
예제 #6
0
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)
예제 #7
0
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')
예제 #8
0
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')    
예제 #9
0
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')
예제 #10
0
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')
예제 #11
0
    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)
예제 #12
0
    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)