Exemple #1
0
    def __init__(self, problem=None, *args, **kwargs):

        super(Model, self).__init__(*args, **kwargs)

        if problem is None:
            self.problem = gurobipy.Model()
            self.problem.params.OutputFlag = 0
            if self.name is not None:
                self.problem.setAttr('ModelName', self.name)
                self.problem.update()

        elif isinstance(problem, gurobipy.Model):
            self.problem = problem
            variables = []
            for gurobi_variable in self.problem.getVars():
                variables.append(Variable(
                    gurobi_variable.getAttr("VarName"),
                    lb=gurobi_variable.getAttr("lb"),
                    ub=gurobi_variable.getAttr("ub"),
                    problem=self,
                    type=_GUROBI_VTYPE_TO_VTYPE[gurobi_variable.getAttr("vType")]
                ))
            super(Model, self)._add_variables(variables)
            constraints = []
            for gurobi_constraint in self.problem.getConstrs():
                sense = gurobi_constraint.Sense
                name = gurobi_constraint.getAttr("ConstrName")
                rhs = gurobi_constraint.RHS
                row = self.problem.getRow(gurobi_constraint)
                lhs = _unevaluated_Add(
                    *[sympy.RealNumber(row.getCoeff(i)) * self.variables[row.getVar(i).VarName] for i in
                      range(row.size())])

                if sense == '=':
                    constraint = Constraint(lhs, name=name, lb=rhs, ub=rhs, problem=self)
                elif sense == '>':
                    constraint = Constraint(lhs, name=name, lb=rhs, ub=None, problem=self)
                elif sense == '<':
                    constraint = Constraint(lhs, name=name, lb=None, ub=rhs, problem=self)
                else:
                    raise ValueError('{} is not a valid sense'.format(sense))
                constraints.append(constraint)
            super(Model, self)._add_constraints(constraints, sloppy=True)

            gurobi_objective = self.problem.getObjective()
            linear_expression = _unevaluated_Add(
                *[sympy.RealNumber(gurobi_objective.getCoeff(i)) * self.variables[gurobi_objective.getVar(i).VarName]
                  for i in range(gurobi_objective.size())])

            self._objective = Objective(
                linear_expression,
                problem=self,
                direction={1: 'min', -1: 'max'}[self.problem.getAttr('ModelSense')]
            )
        else:
            raise TypeError("Provided problem is not a valid Gurobi model.")

        self.configuration = Configuration(problem=self, verbosity=0)
Exemple #2
0
 def _get_expression(self):
     if self.problem is not None:
         cplex_problem = self.problem.problem
         cplex_row = cplex_problem.linear_constraints.get_rows(self.name)
         variables = self.problem._variables
         expression = sympy.Add._from_args(
             [sympy.Mul._from_args((sympy.RealNumber(cplex_row.val[i]), variables[ind])) for i, ind in
              enumerate(cplex_row.ind)])
         self._expression = expression
     return self._expression
Exemple #3
0
def _sympy_converter(var_map, exp, target, expand_pow=False):
    rv = None
    assert isinstance(exp, sp.Expr) and target is not None

    if isinstance(exp, sp.Symbol):
        rv = var_map.get(exp.name, None)
    elif isinstance(exp, sp.Number):
        try:
            rv = RealVal(exp) if target == TARGET_Z3 else sp.RealNumber(exp)
        except:  # Z3 parser error
            rep = sp.Float(exp, len(str(exp)))
            rv = RealVal(rep)
    elif isinstance(exp, sp.Add):
        # Add(exp_0, ...)
        rv = _sympy_converter(var_map,
                              exp.args[0],
                              target,
                              expand_pow=expand_pow)  # eval this expression
        for e in exp.args[1:]:  # add it to all other remaining expressions
            rv += _sympy_converter(var_map, e, target, expand_pow=expand_pow)
    elif isinstance(exp, sp.Mul):
        rv = _sympy_converter(var_map,
                              exp.args[0],
                              target,
                              expand_pow=expand_pow)
        for e in exp.args[1:]:
            rv *= _sympy_converter(var_map, e, target, expand_pow=expand_pow)
    elif isinstance(exp, sp.Pow):
        x = _sympy_converter(var_map,
                             exp.args[0],
                             target,
                             expand_pow=expand_pow)
        e = _sympy_converter(var_map,
                             exp.args[1],
                             target,
                             expand_pow=expand_pow)
        if expand_pow:
            try:
                i = float(e.sexpr())
                assert i.is_integer()
                i = int(i) - 1
                rv = x
                for _ in range(i):
                    rv *= x
            except:  # fallback
                _sympy_converter(var_map, exp, target, expand_pow=False)
        else:
            rv = x**e

    assert rv is not None
    return rv
Exemple #4
0
 def _get_expression(self):
     if self.problem is not None:
         gurobi_problem = self.problem.problem
         gurobi_constraint = self._internal_constraint
         row = gurobi_problem.getRow(gurobi_constraint)
         terms = []
         for i in range(row.size()):
             internal_var_name = row.getVar(i).VarName
             if internal_var_name == self.name + '_aux':
                 continue
             variable = self.problem._variables[internal_var_name]
             coeff = sympy.RealNumber(row.getCoeff(i))
             terms.append(sympy.Mul._from_args((coeff, variable)))
         sympy.Add._from_args(terms)
         self._expression = sympy.Add._from_args(terms)
     return self._expression
 def _get_expression(self):
     if self.problem is not None:
         col_num = glp_get_num_cols(self.problem.problem)
         ia = intArray(col_num + 1)
         da = doubleArray(col_num + 1)
         nnz = glp_get_mat_row(self.problem.problem, self._index, ia, da)
         constraint_variables = [
             self.problem._variables[glp_get_col_name(
                 self.problem.problem, ia[i])] for i in range(1, nnz + 1)
         ]
         expression = sympy.Add._from_args([
             sympy.Mul._from_args(
                 (sympy.RealNumber(da[i]), constraint_variables[i - 1]))
             for i in range(1, nnz + 1)
         ])
         self._expression = expression
     return self._expression
    def __init__(self, problem=None, *args, **kwargs):

        super(Model, self).__init__(*args, **kwargs)

        self.configuration = Configuration()

        if problem is None:
            self.problem = glp_create_prob()
            glp_create_index(self.problem)
            if self.name is not None:
                glp_set_prob_name(self.problem, str(self.name))

        else:
            try:
                self.problem = problem
                glp_create_index(self.problem)
            except TypeError:
                raise TypeError("Provided problem is not a valid GLPK model.")
            row_num = glp_get_num_rows(self.problem)
            col_num = glp_get_num_cols(self.problem)
            for i in range(1, col_num + 1):
                var = Variable(glp_get_col_name(self.problem, i),
                               lb=glp_get_col_lb(self.problem, i),
                               ub=glp_get_col_ub(self.problem, i),
                               problem=self,
                               type=_GLPK_VTYPE_TO_VTYPE[glp_get_col_kind(
                                   self.problem, i)])
                # This avoids adding the variable to the glpk problem
                super(Model, self)._add_variables([var])
            variables = self.variables

            for j in range(1, row_num + 1):
                ia = intArray(col_num + 1)
                da = doubleArray(col_num + 1)
                nnz = glp_get_mat_row(self.problem, j, ia, da)
                constraint_variables = [
                    variables[ia[i] - 1] for i in range(1, nnz + 1)
                ]

                # Since constraint expressions are lazily retrieved from the solver they don't have to be built here
                # lhs = _unevaluated_Add(*[da[i] * constraint_variables[i - 1]
                #                         for i in range(1, nnz + 1)])
                lhs = 0

                glpk_row_type = glp_get_row_type(self.problem, j)
                if glpk_row_type == GLP_FX:
                    row_lb = glp_get_row_lb(self.problem, j)
                    row_ub = row_lb
                elif glpk_row_type == GLP_LO:
                    row_lb = glp_get_row_lb(self.problem, j)
                    row_ub = None
                elif glpk_row_type == GLP_UP:
                    row_lb = None
                    row_ub = glp_get_row_ub(self.problem, j)
                elif glpk_row_type == GLP_DB:
                    row_lb = glp_get_row_lb(self.problem, j)
                    row_ub = glp_get_row_ub(self.problem, j)
                elif glpk_row_type == GLP_FR:
                    row_lb = None
                    row_ub = None
                else:
                    raise Exception(
                        "Currently, optlang does not support glpk row type %s"
                        % str(glpk_row_type))
                    log.exception()
                if isinstance(lhs, int):
                    lhs = sympy.Integer(lhs)
                elif isinstance(lhs, float):
                    lhs = sympy.RealNumber(lhs)
                constraint_id = glp_get_row_name(self.problem, j)
                for variable in constraint_variables:
                    try:
                        self._variables_to_constraints_mapping[
                            variable.name].add(constraint_id)
                    except KeyError:
                        self._variables_to_constraints_mapping[
                            variable.name] = set([constraint_id])

                super(Model, self)._add_constraints([
                    Constraint(lhs,
                               lb=row_lb,
                               ub=row_ub,
                               name=constraint_id,
                               problem=self,
                               sloppy=True)
                ],
                                                    sloppy=True)

            term_generator = ((glp_get_obj_coef(self.problem,
                                                index), variables[index - 1])
                              for index in range(1,
                                                 glp_get_num_cols(problem) +
                                                 1))
            self._objective = Objective(_unevaluated_Add(*[
                _unevaluated_Mul(sympy.RealNumber(term[0]), term[1])
                for term in term_generator if term[0] != 0.
            ]),
                                        problem=self,
                                        direction={
                                            GLP_MIN: 'min',
                                            GLP_MAX: 'max'
                                        }[glp_get_obj_dir(self.problem)])
        glp_scale_prob(self.problem, GLP_SF_AUTO)
 def term_generator():
     for index in range(1,
                        glp_get_num_cols(self.problem.problem) + 1):
         coeff = glp_get_obj_coef(self.problem.problem, index)
         if coeff != 0.:
             yield (sympy.RealNumber(coeff), variables[index - 1])
Exemple #8
0
    def __init__(self, problem=None, *args, **kwargs):

        super(Model, self).__init__(*args, **kwargs)

        if problem is None:
            self.problem = cplex.Cplex()

        elif isinstance(problem, cplex.Cplex):
            self.problem = problem
            zipped_var_args = zip(
                self.problem.variables.get_names(),
                self.problem.variables.get_lower_bounds(),
                self.problem.variables.get_upper_bounds(),
                # self.problem.variables.get_types(), # TODO uncomment when cplex is fixed
            )
            for name, lb, ub in zipped_var_args:
                var = Variable(name, lb=lb, ub=ub,
                               problem=self)  # Type should also be in there
                super(Model, self)._add_variables([
                    var
                ])  # This avoids adding the variable to the glpk problem
            zipped_constr_args = zip(
                self.problem.linear_constraints.get_names(),
                self.problem.linear_constraints.get_rows(),
                self.problem.linear_constraints.get_senses(),
                self.problem.linear_constraints.get_rhs())
            variables = self._variables
            for name, row, sense, rhs in zipped_constr_args:
                constraint_variables = [variables[i - 1] for i in row.ind]

                # Since constraint expressions are lazily retrieved from the solver they don't have to be built here
                # lhs = _unevaluated_Add(*[val * variables[i - 1] for i, val in zip(row.ind, row.val)])
                lhs = 0
                if isinstance(lhs, int):
                    lhs = sympy.Integer(lhs)
                elif isinstance(lhs, float):
                    lhs = sympy.RealNumber(lhs)
                if sense == 'E':
                    constr = Constraint(lhs,
                                        lb=rhs,
                                        ub=rhs,
                                        name=name,
                                        problem=self)
                elif sense == 'G':
                    constr = Constraint(lhs, lb=rhs, name=name, problem=self)
                elif sense == 'L':
                    constr = Constraint(lhs, ub=rhs, name=name, problem=self)
                elif sense == 'R':
                    range_val = self.problem.linear_constraints.get_rhs(name)
                    if range_val > 0:
                        constr = Constraint(lhs,
                                            lb=rhs,
                                            ub=rhs + range_val,
                                            name=name,
                                            problem=self)
                    else:
                        constr = Constraint(lhs,
                                            lb=rhs + range_val,
                                            ub=rhs,
                                            name=name,
                                            problem=self)
                else:
                    raise Exception(
                        '%s is not a recognized constraint sense.' % sense)

                for variable in constraint_variables:
                    try:
                        self._variables_to_constraints_mapping[
                            variable.name].add(name)
                    except KeyError:
                        self._variables_to_constraints_mapping[
                            variable.name] = set([name])

                super(Model, self)._add_constraints([constr], sloppy=True)
            try:
                objective_name = self.problem.objective.get_name()
            except cplex.exceptions.CplexSolverError as e:
                if 'CPLEX Error  1219:' not in str(e):
                    raise e
            else:
                linear_expression = _unevaluated_Add(*[
                    _unevaluated_Mul(sympy.RealNumber(coeff), variables[index])
                    for index, coeff in enumerate(
                        self.problem.objective.get_linear()) if coeff != 0.
                ])

                try:
                    quadratic = self.problem.objective.get_quadratic()
                except IndexError:
                    quadratic_expression = Zero
                else:
                    quadratic_expression = self._get_quadratic_expression(
                        quadratic)

                self._objective = Objective(
                    linear_expression + quadratic_expression,
                    problem=self,
                    direction={
                        self.problem.objective.sense.minimize: 'min',
                        self.problem.objective.sense.maximize: 'max'
                    }[self.problem.objective.get_sense()],
                    name=objective_name)
        else:
            raise TypeError("Provided problem is not a valid CPLEX model.")
        self.configuration = Configuration(problem=self, verbosity=0)
Exemple #9
0
import sympy as y
from . import hz

# driver parameters
sD, Qts, Qms, Qes, Re, Le, Vas, fs, Xmax = y.symbols(
    'sD Qts Qms Qes Re Le Vas fs Xmax')  #cm2, unitless, l, hz, mm

# T/S derived quantities
Cms = Vas / (y.RealNumber(1.42) * sD**2
             )  # 1.42 is adiabatic bulk modulus of air (fun fact)
Mms = ((2 * y.pi * fs)**-2) / Cms
Rms = (1 / Qms) * y.sqrt(Mms / Cms)
Bl = y.sqrt(2 * y.pi * fs * Mms * Re / Qes)
Mmd = Mms - (y.RealNumber(2.67) *
             (y.sqrt(1e-2 * sD) / y.pi)**3 * y.RealNumber(1.225e-3))
Exemple #10
0
def _sympy_converter(var_map, exp, target, expand_pow=False):
    rv = None
    assert isinstance(exp, sp.Expr) and target is not None

    if isinstance(exp, sp.Symbol):
        rv = var_map.get(exp.name, None)
    elif isinstance(exp, sp.Number):
        try:
            rv = RealVal(exp) if isinstance(target, Z3Verifier) else sp.RealNumber(exp)
        except:  # Z3 parser error
            rep = sp.Float(exp, len(str(exp)))
            rv = RealVal(rep)
    elif isinstance(exp, sp.Add):
        # Add(exp_0, ...)
        rv = _sympy_converter(var_map, exp.args[0], target, expand_pow=expand_pow)  # eval this expression
        for e in exp.args[1:]:  # add it to all other remaining expressions
            rv += _sympy_converter(var_map, e, target, expand_pow=expand_pow)
    elif isinstance(exp, sp.Mul):
        rv = _sympy_converter(var_map, exp.args[0], target, expand_pow=expand_pow)
        for e in exp.args[1:]:
            rv *= _sympy_converter(var_map, e, target, expand_pow=expand_pow)
    elif isinstance(exp, sp.Pow):
        x = _sympy_converter(var_map, exp.args[0], target, expand_pow=expand_pow)
        e = _sympy_converter(var_map, exp.args[1], target, expand_pow=expand_pow)
        if expand_pow:
            try:
                i = float(e.sexpr())
                assert i.is_integer()
                i = int(i) - 1
                rv = x
                for _ in range(i):
                    rv *= x
            except:  # fallback
                rv = _sympy_converter(var_map, exp, target, expand_pow=False)
        else:
            rv = x ** e
    elif isinstance(exp, sp.Max):
        x = _sympy_converter(var_map, exp.args[1], target, expand_pow=expand_pow)
        zero = exp.args[0]
        if target == Z3Verifier:
            rv = z3.If(x >= 0.0, x, 0.0)
        else:
            rv = dr.max(x, 0.0)
    elif isinstance(exp, sp.Heaviside):
        x = _sympy_converter(var_map, exp.args[0], target, expand_pow=False)
        if target == Z3Verifier:
            rv = z3.If(x > 0.0, 1.0, 0.0)
        else:
            rv = dr.if_then_else(x>0.0, 1.0, 0.0)
    elif isinstance(exp, sp.Function):
        # check various activation types ONLY FOR DREAL
        if isinstance(exp, sp.tanh):
            rv = dr.tanh(_sympy_converter(var_map, exp.args[0], target, expand_pow=expand_pow))
        elif isinstance(exp, sp.sin):
            rv = dr.sin(_sympy_converter(var_map, exp.args[0], target, expand_pow=expand_pow))
        elif isinstance(exp, sp.cos):
            rv = dr.cos(_sympy_converter(var_map, exp.args[0], target, expand_pow=expand_pow))
        elif isinstance(exp, sp.exp):
            rv = dr.exp(_sympy_converter(var_map, exp.args[0], target, expand_pow=expand_pow))
    else:
        ValueError('Term ' + str(exp) + ' not recognised')

    assert rv is not None
    return rv
Exemple #11
0
    def _populate_solver(self, reaction_list):
        """Populate attached solver with constraints and variables that model the provided reactions."""
        constr_terms = dict()
        objective_terms = list()
        metabolites = {}
        for reaction in reaction_list:
            if reaction.reversibility:
                forward_variable = self.solver.interface.Variable(
                    reaction._get_forward_id(), lb=0, ub=reaction._upper_bound)
                reverse_variable = self.solver.interface.Variable(
                    reaction._get_reverse_id(),
                    lb=0,
                    ub=-1 * reaction._lower_bound)
            elif 0 == reaction.lower_bound and reaction.upper_bound == 0:
                forward_variable = self.solver.interface.Variable(
                    reaction._get_forward_id(), lb=0, ub=0)
                reverse_variable = self.solver.interface.Variable(
                    reaction._get_reverse_id(), lb=0, ub=0)
            elif reaction.lower_bound >= 0:
                forward_variable = self.solver.interface.Variable(
                    reaction.id,
                    lb=reaction._lower_bound,
                    ub=reaction._upper_bound)
                reverse_variable = self.solver.interface.Variable(
                    reaction._get_reverse_id(), lb=0, ub=0)
            elif reaction.upper_bound <= 0:
                forward_variable = self.solver.interface.Variable(reaction.id,
                                                                  lb=0,
                                                                  ub=0)
                reverse_variable = self.solver.interface.Variable(
                    reaction._get_reverse_id(),
                    lb=-1 * reaction._upper_bound,
                    ub=-1 * reaction._lower_bound)
            self.solver._add_variable(forward_variable)
            self.solver._add_variable(reverse_variable)

            for metabolite, coeff in six.iteritems(reaction.metabolites):
                if metabolite.id in constr_terms:
                    constr_terms[metabolite.id].append(
                        sympy.Mul._from_args(
                            [sympy.RealNumber(coeff), forward_variable]))
                else:
                    constr_terms[metabolite.id] = [
                        sympy.Mul._from_args(
                            [sympy.RealNumber(coeff), forward_variable])
                    ]
                    metabolites[metabolite.id] = metabolite
                constr_terms[metabolite.id].append(
                    sympy.Mul._from_args(
                        [sympy.RealNumber(-1 * coeff), reverse_variable]))

            if reaction.objective_coefficient != 0.:
                objective_terms.append(reaction.objective_coefficient *
                                       reaction.flux_expression)

        for met_id, terms in six.iteritems(constr_terms):
            expr = sympy.Add._from_args(terms)
            try:
                self.solver.constraints[met_id] += expr
            except KeyError:
                self.solver._add_constraint(self.solver.interface.Constraint(
                    expr, name=met_id, lb=0, ub=0),
                                            sloppy=True)

        objective_expression = sympy.Add(*objective_terms)
        if self.solver.objective is None:
            self.solver.objective = self.solver.interface.Objective(
                objective_expression, name='obj', direction='max')
        else:
            self.solver.objective.variables  # TODO: remove this weird hack. Looks like some weird issue with lazy objective expressions in CPLEX and GLPK interface in optlang.
            self.solver.objective += objective_expression