2. Solvers¶
multitfa model offers two different ways to solve the tMFA problem (Please refer to manuscript),
Univariate type, where each group/component is allowed to vary in 95% confidence interval from respective mean. This is formulated as a mixed integer linear programming problem (MILP)
Multivariate, where group/component are drawn from multivariate normal distribution subjected to the associated linear constraints. This is a mixed integer quadratic constraint program (MIQCP). In general, MIQCP are computationally expensive.
multitfa supports multiple solvers using optlang
. We use this to solve the MILP problems mentioned above. Unfortunately, optlang
doesnt support quadratic constraints yet, so we use Cplex
and Gurobi
to solve the MIQC type problems.
Lets see how to use different solvers with E. coli core model example
[1]:
import sys
sys.path.insert(0, "../../examples")
from paper_data_example import build_core_model
Downloading package metadata...
Fragments already downloaded
Downloading package metadata...
Fragments already downloaded
Downloading package metadata...
Fragments already downloaded
[2]:
tfa_model = build_core_model()
We can check which solver tfa_model
using now
[3]:
print(tfa_model.solver.interface)
<module 'optlang.cplex_interface' from '/home/moritz/.pyenv/versions/3.6.12/envs/tmfa/lib/python3.6/site-packages/optlang/cplex_interface.py'>
Now lets change to cplex
. Changing the solver is as simple as
[4]:
tfa_model.solver = 'cplex'
print(tfa_model.solver.interface)
<module 'optlang.cplex_interface' from '/home/moritz/.pyenv/versions/3.6.12/envs/tmfa/lib/python3.6/site-packages/optlang/cplex_interface.py'>
tfa_model
has two separate solver interfaces as properties.
cplex_interface
gurobi_interface
Depending on what solver is installed in your environment and what solver you have selected (as shown in previous section), one of the two interfaces above will be active. These are the Model
containers of respective solvers. You can access them the following way,
[5]:
tfa_model.cplex_interface
Selected objective sense: MINIMIZE
Selected objective name: aeb0183b-5dba-11eb-bac2-c1c11d7a5b17
Selected RHS name: rhs
Selected bound name: bnd
[5]:
<cplex.Cplex at 0x7f05ee229c88>
2.1 Solving a multiTFA model¶
Once, we populate the model with thermodynamic constraints as described in section 1.1
, it is time to solve the model. We demonstrate how to solve the model using both univariate and multivariate methods.
First lets solve using univariate method, lets call it box
method.
[6]:
solution_box = tfa_model.optimize(solve_method='mip') # Solve using MILP method
print(solution_box)
<Solution 0.874 at 0x7f05ef657ba8>
Solution for the optimization is stored in the solution_box
, which is instance of the Solution
class. You can access the attributes like fluxes
, Gibbs_energies
and metabolite_concentrations
.
[7]:
print(solution_box.fluxes,"\n")
print(solution_box.Gibbs_energies)
PFK 7.477382
PFL 0.000000
PGI 4.860861
PGK -16.023526
PGL 4.959985
...
NADH16 38.534610
NADTRHD 0.000000
NH4t 4.765319
O2t 21.799493
PDH 9.282533
Name: fluxes, Length: 95, dtype: float64
dG_err_glc__D_e -1.565741
dG_err_gln__L_c -2.667186
dG_err_gln__L_e -2.667186
dG_err_glu__L_c -2.189853
dG_err_glu__L_e -2.189853
...
dG_NADTRHD_reverse_49725 0.368593
dG_NH4t 9.161904
dG_NH4t_reverse_551ee -9.161904
dG_PDH -6.724673
dG_PDH_reverse_ca160 6.724673
Name: Gibbs_energies, Length: 216, dtype: float64
Now, lets solve the model with MIQC problem with cplex interface.
[8]:
solution_miqc = tfa_model.optimize() # In this case we are solving the MIQCP
print(solution_miqc)
<Solution -0.874 at 0x7f05ef657a20>
Attributes of solution_miqc
can be accessed as described above.
Please note, there is a bug in cplex
that reads the model objective in reverse when creating a new model. For example,
max a
is read as min -a
So, when reading cplex_interface
solution please reverse the sign.