Source code for cobra.test.test_util.test_solver

"""Test functions of solver.py"""

import numpy as np
import pytest

from cobra.exceptions import OptimizationError
from cobra.util import solver as su


[docs]stable_optlang = ["glpk", "cplex", "gurobi"]
[docs]optlang_solvers = ["optlang-" + s for s in stable_optlang if s in su.solvers]
[docs]def test_solver_list(): assert len(su.solvers) >= 1 assert "glpk" in su.solvers
[docs]def test_interface_str(): assert su.interface_to_str("nonsense") == "nonsense" assert su.interface_to_str("optlang.glpk_interface") == "glpk" assert su.interface_to_str("optlang-cplex") == "cplex"
[docs]def test_solver_name(): assert su.get_solver_name() == "glpk"
[docs]def test_choose_solver(model): so = su.choose_solver(model, "glpk") assert su.interface_to_str(so) == "glpk" if any(s in su.solvers for s in su.qp_solvers): qp_choice = su.choose_solver(model, qp=True) assert su.interface_to_str(qp_choice) in su.qp_solvers else: with pytest.raises(su.SolverNotFound): su.choose_solver(model, qp=True)
[docs]def test_linear_reaction_coefficients(model): coefficients = su.linear_reaction_coefficients(model) assert coefficients == {model.reactions.Biomass_Ecoli_core: 1}
@pytest.mark.parametrize("solver", optlang_solvers)
[docs]def test_fail_non_linear_reaction_coefficients(model, solver): model.solver = solver try: model.objective = model.problem.Objective( model.reactions.ATPM.flux_expression ** 2 ) except ValueError: pass else: coefficients = su.linear_reaction_coefficients(model) assert coefficients == {} with pytest.raises(ValueError): model.reactions.ACALD.objective_coefficient = 1
[docs]def test_add_remove(model): v = model.variables new_var = model.problem.Variable("test_var", lb=-10, ub=-10) new_constraint = model.problem.Constraint( v.PGK - new_var, name="test_constraint", lb=0 ) su.add_cons_vars_to_problem(model, [new_var, new_constraint]) assert "test_var" in model.variables.keys() assert "test_constraint" in model.constraints.keys() su.remove_cons_vars_from_problem(model, [new_var, new_constraint]) assert "test_var" not in model.variables.keys() assert "test_constraint" not in model.constraints.keys()
[docs]def test_add_remove_in_context(model): v = model.variables new_var = model.problem.Variable("test_var", lb=-10, ub=-10) with model: su.add_cons_vars_to_problem(model, [new_var]) su.remove_cons_vars_from_problem(model, [v.PGM]) assert "test_var" in model.variables.keys() assert "PGM" not in model.variables.keys() assert "test_var" not in model.variables.keys() assert "PGM" in model.variables.keys()
[docs]def test_absolute_expression(model): v = model.variables with model: parts = su.add_absolute_expression(model, 2 * v.PGM, name="test", ub=100) assert len(parts) == 3 assert "test" in model.variables.keys() assert "abs_pos_test" in model.constraints.keys() assert "abs_neg_test" in model.constraints.keys() assert "test" not in model.variables.keys() assert "abs_pos_test" not in model.constraints.keys() assert "abs_neg_test" not in model.constraints.keys()
@pytest.mark.parametrize("solver", optlang_solvers)
[docs]def test_fix_objective_as_constraint(solver, model): model.solver = solver with model as m: su.fix_objective_as_constraint(model, 1.0) constraint_name = m.constraints[-1] assert abs(m.constraints[-1].expression - m.objective.expression) < 1e-6 assert constraint_name not in m.constraints su.fix_objective_as_constraint(model) constraint_name = model.constraints[-1] assert abs(model.constraints[-1].expression - model.objective.expression) < 1e-6 assert constraint_name in model.constraints
@pytest.mark.parametrize("solver", optlang_solvers)
[docs]def test_fix_objective_as_constraint_minimize(model, solver): model.solver = solver model.reactions.Biomass_Ecoli_core.bounds = (0.1, 0.1) minimize_glucose = model.problem.Objective( model.reactions.EX_glc__D_e.flux_expression, direction="min" ) su.set_objective(model, minimize_glucose) su.fix_objective_as_constraint(model) fx_name = "fixed_objective_{}".format(model.objective.name) constr = model.constraints # Ensure that a solution exists on non-GLPK solvers. model.slim_optimize() assert (constr[fx_name].lb, constr[fx_name].ub) == ( None, model.solver.objective.value,
) @pytest.mark.parametrize("solver", optlang_solvers)
[docs]def test_add_lp_feasibility(model, solver): model.solver = solver with model: with model: su.add_lp_feasibility(model) assert "s_plus_succoa_c" in model.variables assert np.isclose(model.slim_optimize(), 0.0) model.reactions.EX_glc__D_e.lower_bound = 1 assert np.isnan(model.slim_optimize()) assert "s_plus_succoa_c" not in model.variables su.add_lp_feasibility(model) assert np.isclose(model.slim_optimize(), 1.3872307692307695)
@pytest.mark.parametrize("solver", optlang_solvers)
[docs]def test_add_lexicographic_constraints(model, solver): model.solver = solver rxns = ["Biomass_Ecoli_core", "EX_glc__D_e", "EX_o2_e"] with model: out = su.add_lexicographic_constraints(model, rxns, ["max", "min", "max"]) print(model.reactions.Biomass_Ecoli_core.bounds) assert np.isclose(model.constraints[-3].lb, out[rxns[0]]) assert np.isclose(model.constraints[-2].ub, out[rxns[1]]) assert np.isclose(model.constraints[-1].lb, out[rxns[2]]) with model: su.add_lexicographic_constraints(model, rxns, "max") with model: su.add_lexicographic_constraints(model, rxns)
[docs]def test_time_limit(large_model): if su.interface_to_str(large_model.problem) != "glpk": pytest.skip("requires GLPK") # It is done like this since optlang accepts inputs in seconds # whereas GLPK accepts milliseconds large_model.solver.configuration._smcp.tm_lim = 1 with pytest.warns(UserWarning): sol = large_model.optimize() assert sol.fluxes is not None with pytest.raises(OptimizationError): sol = large_model.optimize(raise_error=True)