Example #1
0
    def __init__(self, budget_membership_mat, rhs_vec):
        """
        BudgetSet constructor

        Args:
            budget_membership_mat: A matrix with 0-1 entries to designate which uncertain parameters participate in each budget constraint. Here, each row is associated with a separate budget constraint.
            rhs_vec: Vector (``list``) of right-hand side values for the budget constraints.
        """
        # === Non-zero number of columns
        mat = np.asarray(budget_membership_mat)
        rhs = np.asarray(rhs_vec)

        if len(mat.shape) == 1:
            cols = mat.shape
        else:
            cols = mat.shape[1]
        if cols == 0:
            raise AttributeError(
                "Budget membership matrix must have non-zero number of columns."
            )
        # === Assert is valid matrix (same number of columns across all rows
        if not all(len(row) == cols for row in budget_membership_mat):
            raise AttributeError(
                "Budget membership matrix must be a valid matrix, "
                "e.g. same number of column entries across rows.")
        # === Matrix dimension compatibility
        if mat.shape[0] != rhs.shape[0]:
            raise AttributeError(
                "Rows of lhs_coefficients_mat matrix must equal rows of rhs_vec lists."
            )
        # === Ensure a 0-1 matrix
        if any(not np.isclose(elem, 0) and not np.isclose(elem, 1)
               for row in budget_membership_mat for elem in row):
            raise AttributeError(
                "Budget membership matrix must be a matrix of 0's and 1's.")
        # === No all zero rows
        if all(elem == 0 for row in budget_membership_mat for elem in row):
            raise AttributeError(
                "All zero rows are not permitted in the budget membership matrix."
            )

        # === Ensure 0 <= rhs_i for all i
        if any(rhs_vec[i] < 0 for i in range(len(rhs_vec))):
            raise AttributeError("RHS vector entries must be >= 0.")
        # === Non-emptiness is implied by the set

        # === Add constraints such that uncertain params are >= 0
        # === This adds >=0 bound on all parameters in the set
        cols = mat.shape[1]
        identity = np.identity(cols) * -1
        for row in identity:
            budget_membership_mat.append(row.tolist())

        for i in range(identity.shape[0]):
            rhs_vec.append(0)

        self.coefficients_mat = budget_membership_mat
        self.rhs_vec = rhs_vec

        self.type = "budget"
Example #2
0
    def __init__(self, lhs_coefficients_mat, rhs_vec):
        """
        PolyhedralSet constructor

        Args:
            lhs_coefficients_mat: Matrix of left-hand side coefficients for the linear inequality constraints defining the polyhedral set.
            rhs_vec: Vector (``list``) of right-hand side values for the linear inequality constraints defining the polyhedral set.
        """

        # === Real valued data
        mat = np.asarray(lhs_coefficients_mat)
        if not all(
                isinstance(elem, (int, float)) for row in lhs_coefficients_mat
                for elem in row):
            raise AttributeError(
                "Matrix lhs_coefficients_mat must be real-valued and numeric.")
        if not all(isinstance(elem, (int, float)) for elem in rhs_vec):
            raise AttributeError(
                "Vector rhs_vec must be real-valued and numeric.")
        # === Check columns of A must be same length as rhs
        if mat.shape[0] != len(rhs_vec):
            raise AttributeError(
                "Rows of lhs_coefficients_mat matrix must equal length of rhs_vec list."
            )
        # === Columns are non-zero
        if mat.shape[1] == 0:
            raise AttributeError(
                "Columns of lhs_coefficients_mat must be non-zero.")
        # === Matrix is not all zeros
        if all(
                np.isclose(elem, 0) for row in lhs_coefficients_mat
                for elem in row):
            raise AttributeError(
                "Matrix lhs_coefficients_mat cannot be all zeroes.")
        # === Non-emptiness
        res = sp.optimize.linprog(c=np.zeros(mat.shape[1]),
                                  A_ub=mat,
                                  b_ub=rhs_vec,
                                  method="simplex")
        if not res.success:
            raise AttributeError(
                "User-defined PolyhedralSet was determined to be empty. "
                "Please check the set of constraints supplied during set construction."
            )
        # === Boundedness
        if res.status == 3:
            # scipy linprog status == 3 indicates unboundedness
            raise AttributeError(
                "User-defined PolyhedralSet was determined to be unbounded. "
                "Please augment the set of constraints supplied during set construction."
            )

        self.coefficients_mat = lhs_coefficients_mat
        self.rhs_vec = rhs_vec
        self.type = "polyhedral"
Example #3
0
    def __init__(self, origin, number_of_factors, psi_mat, beta):
        """
        FactorModelSet constructor

        Args:
            origin: Vector (``list``) of uncertain parameter values around which deviations are restrained.
            number_of_factors: Natural number representing the dimensionality of the space to which the set projects.
            psi: Matrix with non-negative entries designating each uncertain parameter's contribution to each factor. Here, each row is associated with a separate uncertain parameter and each column with a separate factor.
            beta: Number in [0,1] representing the fraction of the independent factors that can simultaneously attain their extreme values. Setting 'beta = 0' will enforce that as many factors will be above 0 as there will be below 0 (i.e., "zero-net-alpha" model). Setting 'beta = 1' produces the hyper-rectangle [origin - psi e, origin + psi e], where 'e' is the vector of ones.
        """
        mat = np.asarray(psi_mat)
        # === Numeric valued arrays
        if not all(isinstance(elem, (int, float)) for elem in origin):
            raise AttributeError(
                "All elements of origin vector must be numeric.")
        if not all(
                isinstance(elem, (int, float)) for row in psi_mat
                for elem in row):
            raise AttributeError(
                "All elements of psi_mat vector must be numeric.")
        if not isinstance(beta, (int, float)):
            raise AttributeError("Beta parameter must be numeric.")
        if not isinstance(number_of_factors, (int)):
            raise AttributeError("number_of_factors must be integer.")
        # === Ensure dimensions of psi are n x F
        if mat.shape != (len(origin), number_of_factors):
            raise AttributeError(
                "Psi matrix must be of dimensions n x F where n is dim(uncertain_params)"
                "and F is number_of_factors.")
        # === Ensure beta in [0,1]
        if beta > 1 or beta < 0:
            raise AttributeError("Beta parameter must be in [0,1].")
        # === No all zero columns of psi_mat
        for idx in range(mat.shape[1]):
            if all(np.isclose(elem, 0) for elem in mat[:, idx]):
                raise AttributeError(
                    "Psi matrix cannot have all zero columns.")
        # === Psi must be strictly positive entries
        for idx in range(mat.shape[1]):
            if any(elem < 0 for elem in mat[:, idx]):
                raise AttributeError(
                    "Psi matrix cannot have any negative entries. All factors must be non-negative."
                )

        self.origin = origin
        self.number_of_factors = number_of_factors
        self.psi_mat = psi_mat
        self.beta = beta
        self.type = "factor_model"