{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 2. Solvers\n", "\n", "multitfa model offers two different ways to solve the tMFA problem (Please refer to manuscript), \n", "\n", "1. 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)\n", "\n", "2. 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.\n", "\n", "\n", "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.\n", "\n", "Lets see how to use different solvers with *E. coli* core model example\n" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Downloading package metadata...\n", "Fragments already downloaded\n", "Downloading package metadata...\n", "Fragments already downloaded\n", "Downloading package metadata...\n", "Fragments already downloaded\n" ] } ], "source": [ "import sys\n", "sys.path.insert(0, \"../../examples\")\n", "from paper_data_example import build_core_model" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "tfa_model = build_core_model()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can check which solver `tfa_model` using now" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "print(tfa_model.solver.interface)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now lets change to `cplex`. Changing the solver is as simple as" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "tfa_model.solver = 'cplex'\n", "print(tfa_model.solver.interface)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`tfa_model` has two separate solver interfaces as properties.\n", "\n", "1) `cplex_interface`\n", "\n", "2) `gurobi_interface`\n", "\n", "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," ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Selected objective sense: MINIMIZE\n", "Selected objective name: aeb0183b-5dba-11eb-bac2-c1c11d7a5b17\n", "Selected RHS name: rhs\n", "Selected bound name: bnd\n" ] }, { "data": { "text/plain": [ "" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tfa_model.cplex_interface" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 2.1 Solving a multiTFA model\n", "\n", "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. \n", "\n", "First lets solve using univariate method, lets call it `box` method.\n" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "solution_box = tfa_model.optimize(solve_method='mip') # Solve using MILP method\n", "print(solution_box)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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`. " ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "PFK 7.477382\n", "PFL 0.000000\n", "PGI 4.860861\n", "PGK -16.023526\n", "PGL 4.959985\n", " ... \n", "NADH16 38.534610\n", "NADTRHD 0.000000\n", "NH4t 4.765319\n", "O2t 21.799493\n", "PDH 9.282533\n", "Name: fluxes, Length: 95, dtype: float64 \n", "\n", "dG_err_glc__D_e -1.565741\n", "dG_err_gln__L_c -2.667186\n", "dG_err_gln__L_e -2.667186\n", "dG_err_glu__L_c -2.189853\n", "dG_err_glu__L_e -2.189853\n", " ... \n", "dG_NADTRHD_reverse_49725 0.368593\n", "dG_NH4t 9.161904\n", "dG_NH4t_reverse_551ee -9.161904\n", "dG_PDH -6.724673\n", "dG_PDH_reverse_ca160 6.724673\n", "Name: Gibbs_energies, Length: 216, dtype: float64\n" ] } ], "source": [ "print(solution_box.fluxes,\"\\n\")\n", "print(solution_box.Gibbs_energies)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now, lets solve the model with MIQC problem with cplex interface." ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "solution_miqc = tfa_model.optimize() # In this case we are solving the MIQCP\n", "print(solution_miqc)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Attributes of `solution_miqc` can be accessed as described above.\n", "\n", "Please note, there is a bug in `cplex` that reads the model objective in reverse when creating a new model. For example, \n", "\n", "`max a` is read as `min -a`\n", "\n", "So, when reading `cplex_interface` solution please reverse the sign." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.12" } }, "nbformat": 4, "nbformat_minor": 2 }