Skip to content

Commit 69f8736

Browse files
authored
Merge branch 'develop' into master
2 parents 72ce32e + a245f73 commit 69f8736

File tree

7 files changed

+75
-28
lines changed

7 files changed

+75
-28
lines changed

src/COBRA.jl

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ module COBRA
1919
import Pkg
2020
using SparseArrays, Distributed, LinearAlgebra
2121
using MAT, MathOptInterface, JuMP
22-
using MATLAB
22+
#using MATLAB
2323

2424
include("checkSetup.jl")
2525
checkSysConfig(0)
@@ -29,6 +29,7 @@ module COBRA
2929
include("distributedFBA.jl")
3030
include("tools.jl")
3131
include("PALM.jl")
32+
include("connect.jl")
3233

3334
end
3435

src/checkSetup.jl

+3-3
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ end
4646
"""
4747
checkSysConfig(printLevel)
4848
49-
Function evaluates whether the LP solvers of MathProgBase are installed on the system or not and
50-
returns a list of these packages. `MathProgBase.jl` must be installed.
49+
Function evaluates whether the LP solvers of JuMP are installed on the system or not and
50+
returns a list of these packages. `JuMP.jl` must be installed.
5151
5252
# OPTIONAL INPUTS
5353
@@ -57,7 +57,7 @@ returns a list of these packages. `MathProgBase.jl` must be installed.
5757
5858
- packages: A list of solver packages installed on the system
5959
60-
See also: `MathProgBase`, `checkPackage()`
60+
See also: `JuMP`, `checkPackage()`
6161
6262
"""
6363

src/distributedFBA.jl

+13-11
Original file line numberDiff line numberDiff line change
@@ -288,15 +288,17 @@ end
288288

289289
#-------------------------------------------------------------------------------------------
290290
"""
291-
loopFBA(m, rxnsList, nRxns, rxnsOptMode, iRound, pid, resultsDir, logFiles, onlyFluxes, printLevel)
291+
loopFBA(m, x, c, rxnsList, nRxns, rxnsOptMode, iRound, pid, resultsDir, logFiles, onlyFluxes, printLevel)
292292
293293
Function used to perform a loop of a series of FBA problems using the CPLEX solver
294294
Generally, `loopFBA` is called in a loop over multiple workers and makes use of the
295295
`CPLEX.jl` module.
296296
297297
# INPUTS
298298
299-
- `m`: A MathProgBase.LinearQuadraticModel object with `inner` field
299+
- `m`: An `::LPproblem` object that has been built using the JuMP.
300+
- `x`: Primal solution vector
301+
- `c`: The objective vector, always in the sense of minimization
300302
- `solver`: A `::SolverConfig` object that contains a valid `handle`to the solver
301303
- `rxnsList`: List of reactions to analyze (default: all reactions)
302304
- `nRxns`: Total number of reaction in the model `m.inner`
@@ -335,10 +337,10 @@ Generally, `loopFBA` is called in a loop over multiple workers and makes use of
335337
336338
- Minimum working example
337339
```julia
338-
julia> loopFBA(m, rxnsList, nRxns)
340+
julia> loopFBA(m, x, c, rxnsList, nRxns)
339341
```
340342
341-
See also: `distributeFBA()`, `MathProgBase.HighLevelInterface`
343+
See also: `distributeFBA()`, `solvelp()`
342344
343345
"""
344346

@@ -368,11 +370,11 @@ function loopFBA(m, x, c, rxnsList, nRxns::Int, rxnsOptMode=2 .+ zeros(Int, leng
368370
end
369371

370372
if performOptim
371-
373+
372374
# Set the objective vector coefficients
373375
c = zeros(nRxns)
374376
c[rxnsList[k]] = 1000.0 # set the coefficient of the current FBA to 1000
375-
377+
376378
# change the sense of the optimization
377379
if j == 1
378380
if iRound == 0
@@ -387,20 +389,20 @@ function loopFBA(m, x, c, rxnsList, nRxns::Int, rxnsOptMode=2 .+ zeros(Int, leng
387389
end
388390
end
389391
end
390-
392+
391393
if logFiles
392394
# save individual logFiles with the CPLEX solver
393395
if isdefined(m, :inner) && string(typeof(m.inner)) == "CPLEX.Model"
394396
CPLEX.set_logfile(m.inner.env, "$resultsDir/logs/$((iRound == 0 ) ? "min" : "max")-myLogFile-$(rxnsList[k]).log")
395397
end
396398
end
397399

398-
# solve the model using the general MathProgBase interface
400+
# solve the model
399401
status, objval, sol = solvelp(m, x)
400402

401403
# retrieve the solution status
402404
statLP = status
403-
405+
404406
# output the solution, save the minimum and maximum fluxes
405407
if statLP == MathOptInterface.TerminationStatusCode(1)
406408
# retrieve the objective value
@@ -674,13 +676,13 @@ function distributedFBA(model, solver; nWorkers::Int=1, optPercentage::Union{Flo
674676
@sync for (p, pid) in enumerate(workers())
675677
for iRound = 0:1
676678
@async R[p, iRound + 1] = @spawnat (p + 1) begin
677-
m = buildCobraLP(model, solver) # on each worker, the model must be built individually
679+
m, x, c = buildCobraLP(model, solver) # on each worker, the model must be built individually
678680

679681
# adjust the solver parameters based on the model
680682
autoTuneSolver(m, nMets, nRxns, solver, pid)
681683

682684
# start the loop of FBA
683-
loopFBA(m, rxnsList[rxnsKey[p]], nRxns, rxnsOptMode[rxnsKey[p]], iRound, pid, resultsDir, logFiles, onlyFluxes, printLevel)
685+
loopFBA(m, x, c, rxnsList[rxnsKey[p]], nRxns, rxnsOptMode[rxnsKey[p]], iRound, pid, resultsDir, logFiles, onlyFluxes, printLevel)
684686
end
685687
end
686688
end

src/solve.jl

+53-9
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ mutable struct SolverConfig
2323
end
2424

2525
#-------------------------------------------------------------------------------------------
26-
2726
"""
2827
buildlp(c, A, sense, b, l, u, solver)
2928
@@ -43,11 +42,12 @@ Function used to build a model using JuMP.
4342
4443
- `model`: An `::LPproblem` object that has been built using the JuMP.
4544
- `x`: Primal solution vector
45+
- `c`: The objective vector, always in the sense of minimization
4646
4747
# EXAMPLES
4848
4949
```julia
50-
julia> model, x = buildlp(c, A, sense, b, l, u, solver)
50+
julia> model, x, c = buildlp(c, A, sense, b, l, u, solver)
5151
```
5252
5353
"""
@@ -61,11 +61,10 @@ function buildlp(c, A, sense, b, l, u, solver)
6161
@constraint(model, A[eq_rows, :] * x .== b[eq_rows])
6262
@constraint(model, A[ge_rows, :] * x .>= b[ge_rows])
6363
@constraint(model, A[le_rows, :] * x .<= b[le_rows])
64-
return model, x
64+
return model, x, c
6565
end
6666

6767
#-------------------------------------------------------------------------------------------
68-
6968
"""
7069
solvelp(model, x)
7170
@@ -91,7 +90,6 @@ julia> status, objval, sol = solvelp(model, x)
9190
"""
9291

9392
function solvelp(model, x)
94-
#println(x)
9593
optimize!(model)
9694
return (
9795
status = termination_status(model),
@@ -101,8 +99,53 @@ function solvelp(model, x)
10199
end
102100

103101
#-------------------------------------------------------------------------------------------
102+
"""
103+
linprog(c, A, sense, b, l, u, solver)
104+
105+
Function used to build and solve a LPproblem using JuMP.
106+
107+
# INPUTS
108+
109+
- `c`: The objective vector, always in the sense of minimization
110+
- `A`: Constraint matrix
111+
- `sense`: Vector of constraint sense characters '<', '=', and '>'
112+
- `b`: Right-hand side vector
113+
- `l`: Vector of lower bounds on the variables
114+
- `u`: Vector of upper bounds on the variables
115+
- `solver`: A `::SolverConfig` object that contains a valid `handle`to the solver
116+
117+
# OUTPUTS
118+
119+
- `status`: Termination status
120+
- `objval`: Optimal objective value
121+
- `sol`: Primal solution vector
104122
123+
# EXAMPLES
124+
125+
```julia
126+
julia> status, objval, sol = linprog(c, A, sense, b, l, u, solver)
127+
```
128+
129+
"""
105130

131+
function linprog(c, A, sense, b, l, u, solver)
132+
N = length(c)
133+
model = Model(solver)
134+
@variable(model, l[i] <= x[i=1:N] <= u[i])
135+
@objective(model, Min, c' * x)
136+
eq_rows, ge_rows, le_rows = sense .== '=', sense .== '>', sense .== '<'
137+
@constraint(model, A[eq_rows, :] * x .== b[eq_rows])
138+
@constraint(model, A[ge_rows, :] * x .>= b[ge_rows])
139+
@constraint(model, A[le_rows, :] * x .<= b[le_rows])
140+
optimize!(model)
141+
return (
142+
status = termination_status(model),
143+
objval = objective_value(model),
144+
sol = value.(x)
145+
)
146+
end
147+
148+
#-------------------------------------------------------------------------------------------
106149
"""
107150
buildlp(c, A, sense, b, l, u, solver)
108151
@@ -240,11 +283,12 @@ Build a model by interfacing directly with the GLPK solver
240283
241284
- `model`: An `::LPproblem` object that has been built using the JuMP.
242285
- `x`: primal solution vector
286+
- `c`: The objective vector, always in the sense of minimization
243287
244288
# EXAMPLES
245289
246290
```julia
247-
julia> model, x = buildCobraLP(model, solver)
291+
julia> model, x, c = buildCobraLP(model, solver)
248292
```
249293
250294
See also: `buildlp()`
@@ -437,7 +481,7 @@ Function to auto-tune the parameter of a solver based on model size (only CPLEX)
437481
438482
# INPUTS
439483
440-
- `m`: A MathProgBase.LinearQuadraticModel object with `inner` field
484+
- `m`: An `::LPproblem` object that has been built using the JuMP.
441485
- `nMets`: Total number of metabolites in the model `m.inner`
442486
- `nRxns`: Total number of reaction in the model `m.inner`
443487
- `solver`: A `::SolverConfig` object that contains a valid `handle`to the solver
@@ -453,7 +497,7 @@ Minimum working example
453497
julia> autoTuneSolver(env, nMets, nRxns, solver)
454498
```
455499
456-
See also: `MathProgBase.linprog()`
500+
See also: `linprog()`
457501
"""
458502

459503
function autoTuneSolver(m, nMets, nRxns, solver, pid::Int=1)
@@ -464,6 +508,6 @@ function autoTuneSolver(m, nMets, nRxns, solver, pid::Int=1)
464508
end
465509
end
466510

467-
export buildlp, solvelp, buildCobraLP, changeCobraSolver, solveCobraLP, autoTuneSolver
511+
export buildlp, solvelp, linprog, buildCobraLP, changeCobraSolver, solveCobraLP, autoTuneSolver
468512

469513
#-------------------------------------------------------------------------------------------

test/s_all.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ nWorkers = 1
2323
# create a pool and use the COBRA module if the testfile is run in a loop
2424
if includeCOBRA
2525
connectSSHWorkers = false
26-
include(pkgDir*"/src//connect.jl")
26+
include(pkgDir*"/src/connect.jl")
2727

2828
# create a parallel pool and determine its size
2929
if isdefined(:nWorkers) && isdefined(:connectSSHWorkers)

test/s_distinct.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ minFlux, maxFlux, optSol, fbaSol, fvamin, fvamax, statussolmin, statussolmax = d
6868
@test abs(optSol - optSol1) < 1e-9
6969

7070
#other solvers (e.g., CPLEX) might report alternate optimal solutions
71-
if solverName == "GLPKMathProgInterface"
71+
if solverName == "GLPK"
7272
# test minimum flux vectors
7373
@test norm(fvamin[:, 4:14] - fvamin1[:, 20:30]) < 1e-9
7474

test/z_all.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ solver.handle = -1
9797
# test if an infeasible solution status is returned
9898
solver = changeCobraSolver(solverName, solParams)
9999
m, x, c = buildlp([1.0, 0.0], [2.0 1.0], '<', -1.0, solver.handle)
100-
retObj, retFlux, retStat = loopFBA(m, 1, 2)
100+
retObj, retFlux, retStat = loopFBA(m, x, c, 1, 2)
101101
if solverName == "Clp" || solverName == "Gurobi" || solverName == "CPLEX" || solverName == "Mosek"
102102
@test retStat[1] == 0 # infeasible
103103
else
@@ -120,7 +120,7 @@ end
120120

121121
# solve an unbounded problem using loopFBA
122122
m, x, c = buildlp([0.0, -1.0], [-1.0 2.0], '<', [0.0], solver.handle)
123-
retObj, retFlux, retStat = loopFBA(m, 1, 2, 2, 1)
123+
retObj, retFlux, retStat = loopFBA(m, x, c, 1, 2, 2, 1)
124124
if solver.name == "Clp" || solver.name == "Gurobi" || solver.name == "GLPK" || solver.name == "Mosek"
125125
@test isequal(retStat, [2, NaN]) # unbounded and not solved
126126
elseif solver.name == "CPLEX"

0 commit comments

Comments
 (0)