Skip to content

Commit

Permalink
Add pyoptinterface_based_impl.py and integrate it (#104)
Browse files Browse the repository at this point in the history
* Add pyoptInterface_based_impl.py and integrate it

* Rename and improve pyoptinterface_based_impl.py
  • Loading branch information
KeShih authored Aug 21, 2024
1 parent 4a961e7 commit e2a7e4c
Show file tree
Hide file tree
Showing 21 changed files with 1,731 additions and 2,344 deletions.
66 changes: 15 additions & 51 deletions dingo/MetabolicNetwork.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

# Copyright (c) 2021 Apostolos Chalkis
# Copyright (c) 2021 Vissarion Fisikopoulos
# Copyright (c) 2024 Ke Shi

# Licensed under GNU LGPL.3, see LICENCE file

Expand All @@ -11,15 +12,7 @@
from typing import Dict
import cobra
from dingo.loading_models import read_json_file, read_mat_file, read_sbml_file, parse_cobra_model
from dingo.fva import slow_fva
from dingo.fba import slow_fba

try:
import gurobipy
from dingo.gurobi_based_implementations import fast_fba, fast_fva, fast_inner_ball
except ImportError as e:
pass

from dingo.pyoptinterface_based_impl import fba,fva,inner_ball,remove_redundant_facets

class MetabolicNetwork:
def __init__(self, tuple_args):
Expand All @@ -28,13 +21,7 @@ def __init__(self, tuple_args):
self._parameters["opt_percentage"] = 100
self._parameters["distribution"] = "uniform"
self._parameters["nullspace_method"] = "sparseQR"

try:
import gurobipy

self._parameters["fast_computations"] = True
except ImportError as e:
self._parameters["fast_computations"] = False
self._parameters["solver"] = None

if len(tuple_args) != 10:
raise Exception(
Expand Down Expand Up @@ -107,30 +94,18 @@ def from_cobra_model(cls, arg):
def fva(self):
"""A member function to apply the FVA method on the metabolic network."""

if self._parameters["fast_computations"]:
return fast_fva(
self._lb,
self._ub,
self._S,
self._objective_function,
self._parameters["opt_percentage"],
)
else:
return slow_fva(
self._lb,
self._ub,
self._S,
self._objective_function,
self._parameters["opt_percentage"],
)
return fva(
self._lb,
self._ub,
self._S,
self._objective_function,
self._parameters["opt_percentage"],
self._parameters["solver"]
)

def fba(self):
"""A member function to apply the FBA method on the metabolic network."""

if self._parameters["fast_computations"]:
return fast_fba(self._lb, self._ub, self._S, self._objective_function)
else:
return slow_fba(self._lb, self._ub, self._S, self._objective_function)
return fba(self._lb, self._ub, self._S, self._objective_function, self._parameters["solver"])

@property
def lb(self):
Expand Down Expand Up @@ -286,20 +261,9 @@ def set_active_bound(reaction: str, reac_index: int, bound: float) -> None:
set_active_bound(
rxn_id, reac_index, min(0.0, -self._lb[reac_index] if is_export else self._ub[reac_index])
)

def set_fast_mode(self):

try:
import gurobipy

self._parameters["fast_computations"] = True
except ImportError as e:
print("You have to install gurobi to use the fast computations.")
self._parameters["fast_computations"] = False

def set_slow_mode(self):

self._parameters["fast_computations"] = False

def set_solver(self, solver: str):
self._parameters["solver"] = solver

def set_nullspace_method(self, value):

Expand Down
108 changes: 25 additions & 83 deletions dingo/PolytopeSampler.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# dingo is part of GeomScale project

# Copyright (c) 2021 Apostolos Chalkis
# Copyright (c) 2024 Ke Shi

# Licensed under GNU LGPL.3, see LICENCE file

Expand All @@ -10,23 +11,13 @@
import warnings
import math
from dingo.MetabolicNetwork import MetabolicNetwork
from dingo.fva import slow_fva
from dingo.utils import (
map_samples_to_steady_states,
get_matrices_of_low_dim_polytope,
get_matrices_of_full_dim_polytope,
)

try:
import gurobipy
from dingo.gurobi_based_implementations import (
fast_fba,
fast_fva,
fast_inner_ball,
fast_remove_redundant_facets,
)
except ImportError as e:
pass
from dingo.pyoptinterface_based_impl import fba,fva,inner_ball,remove_redundant_facets

from volestipy import HPolytope

Expand All @@ -53,14 +44,8 @@ def __init__(self, metabol_net):
self._parameters["first_run_of_mmcs"] = True
self._parameters["remove_redundant_facets"] = True

try:
import gurobipy

self._parameters["fast_computations"] = True
self._parameters["tol"] = 1e-06
except ImportError as e:
self._parameters["fast_computations"] = False
self._parameters["tol"] = 1e-03
self._parameters["tol"] = 1e-06
self._parameters["solver"] = None

def get_polytope(self):
"""A member function to derive the corresponding full dimensional polytope
Expand All @@ -82,24 +67,18 @@ def get_polytope(self):
) = self._metabolic_network.fba()

if (
self._parameters["fast_computations"]
and self._parameters["remove_redundant_facets"]
self._parameters["remove_redundant_facets"]
):

A, b, Aeq, beq = fast_remove_redundant_facets(
A, b, Aeq, beq = remove_redundant_facets(
self._metabolic_network.lb,
self._metabolic_network.ub,
self._metabolic_network.S,
self._metabolic_network.objective_function,
self._parameters["opt_percentage"],
self._parameters["solver"],
)
else:
if (not self._parameters["fast_computations"]) and self._parameters[
"remove_redundant_facets"
]:
warnings.warn(
"We continue without redundancy removal (slow mode is ON)"
)

(
min_fluxes,
Expand Down Expand Up @@ -162,14 +141,9 @@ def generate_steady_states(

P = HPolytope(self._A, self._b)

if self._parameters["fast_computations"]:
self._A, self._b, Tr, Tr_shift, samples = P.fast_mmcs(
ess, psrf, parallel_mmcs, num_threads
)
else:
self._A, self._b, Tr, Tr_shift, samples = P.slow_mmcs(
ess, psrf, parallel_mmcs, num_threads
)
self._A, self._b, Tr, Tr_shift, samples = P.mmcs(
ess, psrf, parallel_mmcs, num_threads, self._parameters["solver"]
)

if self._parameters["first_run_of_mmcs"]:
steady_states = map_samples_to_steady_states(
Expand Down Expand Up @@ -207,7 +181,7 @@ def generate_steady_states_no_multiphase(
else:
bias_vector = bias_vector.astype('float64')

samples = P.generate_samples(method, n, burn_in, thinning, self._parameters["fast_computations"], variance, bias_vector)
samples = P.generate_samples(method, n, burn_in, thinning, variance, bias_vector, self._parameters["solver"])
samples_T = samples.T

steady_states = map_samples_to_steady_states(
Expand All @@ -218,7 +192,7 @@ def generate_steady_states_no_multiphase(

@staticmethod
def sample_from_polytope(
A, b, ess=1000, psrf=False, parallel_mmcs=False, num_threads=1
A, b, ess=1000, psrf=False, parallel_mmcs=False, num_threads=1, solver=None
):
"""A static function to sample from a full dimensional polytope.
Expand All @@ -233,22 +207,16 @@ def sample_from_polytope(

P = HPolytope(A, b)

try:
import gurobipy
A, b, Tr, Tr_shift, samples = P.mmcs(
ess, psrf, parallel_mmcs, num_threads, solver
)

A, b, Tr, Tr_shift, samples = P.fast_mmcs(
ess, psrf, parallel_mmcs, num_threads
)
except ImportError as e:
A, b, Tr, Tr_shift, samples = P.slow_mmcs(
ess, psrf, parallel_mmcs, num_threads
)

return samples

@staticmethod
def sample_from_polytope_no_multiphase(
A, b, method = 'billiard_walk', n=1000, burn_in=0, thinning=1, variance=1.0, bias_vector=None
A, b, method = 'billiard_walk', n=1000, burn_in=0, thinning=1, variance=1.0, bias_vector=None, solver=None
):
"""A static function to sample from a full dimensional polytope with an MCMC method.
Expand All @@ -267,25 +235,17 @@ def sample_from_polytope_no_multiphase(

P = HPolytope(A, b)

try:
import gurobipy
samples = P.generate_samples(method, n, burn_in, thinning, True, variance, bias_vector)
except ImportError as e:
samples = P.generate_samples(method, n, burn_in, thinning, False, variance, bias_vector)
samples = P.generate_samples(method, n, burn_in, thinning, variance, bias_vector, solver)

samples_T = samples.T
return samples_T

@staticmethod
def round_polytope(
A, b, method = "john_position"
A, b, method = "john_position", solver = None
):
P = HPolytope(A, b)
try:
import gurobipy
A, b, Tr, Tr_shift, round_value = P.rounding(method, True)
except ImportError as e:
A, b, Tr, Tr_shift, round_value = P.rounding(method, False)
A, b, Tr, Tr_shift, round_value = P.rounding(method, solver)

return A, b, Tr, Tr_shift

Expand All @@ -301,6 +261,7 @@ def sample_from_fva_output(
psrf=False,
parallel_mmcs=False,
num_threads=1,
solver = None
):
"""A static function to sample steady states when the output of FVA is given.
Expand Down Expand Up @@ -335,16 +296,9 @@ def sample_from_fva_output(

P = HPolytope(A, b)

try:
import gurobipy

A, b, Tr, Tr_shift, samples = P.fast_mmcs(
ess, psrf, parallel_mmcs, num_threads
)
except ImportError as e:
A, b, Tr, Tr_shift, samples = P.slow_mmcs(
ess, psrf, parallel_mmcs, num_threads
)
A, b, Tr, Tr_shift, samples = P.mmcs(
ess, psrf, parallel_mmcs, num_threads, solver
)

steady_states = map_samples_to_steady_states(samples, N, N_shift)

Expand Down Expand Up @@ -381,20 +335,8 @@ def metabolic_network(self):
def facet_redundancy_removal(self, value):
self._parameters["remove_redundant_facets"] = value

if (not self._parameters["fast_computations"]) and value:
warnings.warn(
"Since you are in slow mode the redundancy removal step is skipped (dingo does not currently support this functionality in slow mode)"
)

def set_fast_mode(self):

self._parameters["fast_computations"] = True
self._parameters["tol"] = 1e-06

def set_slow_mode(self):

self._parameters["fast_computations"] = False
self._parameters["tol"] = 1e-03
def set_solver(self, solver):
self._parameters["solver"] = solver

def set_distribution(self, value):

Expand Down
Loading

0 comments on commit e2a7e4c

Please sign in to comment.