Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transition to MOI #103

Merged
merged 1 commit into from
Jul 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,38 +1,35 @@
name = "COBRA"
uuid = "58298e0b-d05c-52ec-a210-0694647ebfc7"
version = "0.4.1"
version = "0.4.2"

[deps]
CPLEX = "a076750e-1247-5638-91d2-ce28b192dca0"
Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b"
GLPK = "60bf3e95-4087-53dc-ae20-288a0d20c6a6"
GLPKMathProgInterface = "3c7084bd-78ad-589a-b5bb-dbd673274bea"
HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
MAT = "23992714-dd62-5051-b70f-ba57cb901cac"
MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee"
MathProgBase = "fdba3010-5040-5b88-9595-932c9decdf73"
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
JuMP = "4076af6c-e467-56ae-b986-b466b2749572"

[compat]
CPLEX = "0.9"
GLPK = "1.0"
GLPKMathProgInterface = "0.5"
HTTP = "0.9"
MAT = "0.10"
MathOptInterface = "0.10, 1.1"
MathProgBase = "0.7"
julia = "1"
JuMP = "1.0"

[extras]
CPLEX = "a076750e-1247-5638-91d2-ce28b192dca0"
GLPK = "60bf3e95-4087-53dc-ae20-288a0d20c6a6"
GLPKMathProgInterface = "3c7084bd-78ad-589a-b5bb-dbd673274bea"
Gurobi = "2e9cd046-0924-5485-92f1-d5272153d98b"
MAT = "23992714-dd62-5051-b70f-ba57cb901cac"
MATLAB = "10e44e05-a98a-55b3-a45b-ba969058deb6"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["GLPKMathProgInterface", "GLPK", "Test"]
test = ["GLPK", "Test"]
2 changes: 1 addition & 1 deletion src/COBRA.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ module COBRA
# include the load file to load a model of .mat format
import Pkg
using SparseArrays, Distributed, LinearAlgebra
using MAT, MathProgBase
using MAT, MathOptInterface, JuMP
if "MATLAB" in keys(Pkg.installed())
using MATLAB
end
Expand Down
2 changes: 1 addition & 1 deletion src/connect.jl
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ function createPool(localWorkers::Int, connectSSH::Bool=false, connectionFile::S
end

try
if !is_windows()
if !(Sys.iswindows())
# try logging in quietly to defined node using SSH
successConnect = success(`ssh -T -o BatchMode=yes -o ConnectTimeout=1 $(sshWorkers[i]["usernode"]) $(sshWorkers[i]["flags"])`)

Expand Down
9 changes: 4 additions & 5 deletions src/distributedFBA.jl
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,14 @@ function preFBA!(model, solver, optPercentage::Float64=0.0, osenseStr::String="m
hasObjective = true

# solve the original LP problem
fbaSolution = solveCobraLP(model, solver)
status, objval, sol = solveCobraLP(model, solver)

if fbaSolution.status == :Optimal
if status == MathOptInterface.TerminationStatusCode(1)
# retrieve the solution to the initial LP
FBAobj = fbaSolution.objval
FBAobj = objval

# retrieve the solution vector
fbaSol = fbaSolution.sol
fbaSol = sol

if osenseStr == "max"
objValue = floor(FBAobj/tol) * tol * optPercentage / 100.0
Expand Down Expand Up @@ -124,7 +124,6 @@ function preFBA!(model, solver, optPercentage::Float64=0.0, osenseStr::String="m
end

end

#-------------------------------------------------------------------------------------------
"""
splitRange(model, rxnsList, nWorkers, strategy, printLevel)
Expand Down
128 changes: 107 additions & 21 deletions src/solve.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
=#

#-------------------------------------------------------------------------------------------

"""
SolverConfig(name, handle)

Expand All @@ -22,10 +23,90 @@ mutable struct SolverConfig
end

#-------------------------------------------------------------------------------------------

"""
buildlp(c, A, sense, b, l, u, solver)

Function used to build a model using JuMP.

# INPUTS

- `c`: The objective vector, always in the sense of minimization
- `A`: Constraint matrix
- `sense`: Vector of constraint sense characters '<', '=', and '>'
- `b`: Right-hand side vector
- `l`: Vector of lower bounds on the variables
- `u`: Vector of upper bounds on the variables
- `solver`: A `::SolverConfig` object that contains a valid `handle`to the solver

# OUTPUTS

- `model`: An `::LPproblem` object that has been built using the JuMP.
- `x`: Primal solution vector

# EXAMPLES

```julia
julia> model, x = buildlp(c, A, sense, b, l, u, solver)
```

"""

function buildlp(c, A, sense, b, l, u, solver)
N = length(c)
model = Model(solver)
x = @variable(model, l[i] <= x[i=1:N] <= u[i])
@objective(model, Min, c' * x)
eq_rows, ge_rows, le_rows = sense .== '=', sense .== '>', sense .== '<'
@constraint(model, A[eq_rows, :] * x .== b[eq_rows])
@constraint(model, A[ge_rows, :] * x .>= b[ge_rows])
@constraint(model, A[le_rows, :] * x .<= b[le_rows])
return model, x
end

#-------------------------------------------------------------------------------------------

"""
solvelp(model, x)

Function used to solve a LPproblem using JuMP.

# INPUTS

- `model`: An `::LPproblem` object that has been built using the JuMP.
- `x`: Primal solution vector

# OUTPUTS

- `status`: Termination status
- `objval`: Optimal objective value
- `sol`: Primal solution vector

# EXAMPLES

```julia
julia> status, objval, sol = solvelp(model, x)
```

"""

function solvelp(model, x)
#println(x)
optimize!(model)
return (
status = termination_status(model),
objval = objective_value(model),
sol = value.(x)
)
end

#-------------------------------------------------------------------------------------------


"""
buildCobraLP(model, solver)

Build a model by interfacing directly with the CPLEX solver
Build a model by interfacing directly with the GLPK solver

# INPUTS

Expand All @@ -35,15 +116,16 @@ Build a model by interfacing directly with the CPLEX solver

# OUTPUTS

- `m`: A MathProgBase.LinearQuadraticModel object with `inner` field
- `model`: An `::LPproblem` object that has been built using the JuMP.
- `x`: primal solution vector

# EXAMPLES

```julia
julia> m = buildCobraLP(model, solver)
julia> model, x = buildCobraLP(model, solver)
```

See also: `MathProgBase.LinearQuadraticModel()`, `MathProgBase.HighLevelInterface.buildlp()`
See also: `buildlp()`
"""

function buildCobraLP(model, solver::SolverConfig)
Expand All @@ -55,8 +137,7 @@ function buildCobraLP(model, solver::SolverConfig)
if model.csense[i] == 'G' model.csense[i] = '>' end
if model.csense[i] == 'L' model.csense[i] = '<' end
end

return MathProgBase.HighLevelInterface.buildlp(model.osense * model.c, model.S, model.csense, model.b, model.lb, model.ub, solver.handle)
return buildlp(model.osense * model.c, model.S, model.csense, model.b, model.lb, model.ub, solver.handle)
else
error("The solver is not supported. Please set solver name to one the supported solvers.")
end
Expand Down Expand Up @@ -89,7 +170,12 @@ Minimum working example (for the CPLEX solver)
julia> changeCobraSolver("CPLEX", cpxControl)
```

See also: `MathProgBase.jl`
Minimum working example (for the GLPK solver)
```julia
julia> solverName = :GLPK
julia> solver = changeCobraSolver(solverName)
```

"""

function changeCobraSolver(name, params=[]; printLevel::Int=1)
Expand All @@ -113,12 +199,12 @@ function changeCobraSolver(name, params=[]; printLevel::Int=1)
error("The solver `CPLEX` cannot be set using `changeCobraSolver()`.")
end

elseif name == "GLPKMathProgInterface" || name == "GLPK"
elseif name == "GLPK"
try
if length(params) > 1
solver.handle = GLPKSolverLP(method=params[1], presolve=params[2])
solver.handle = GLPK.Optimizer
else
solver.handle = GLPKSolverLP()
solver.handle = GLPK.Optimizer
end
catch
error("The solver `GLPK` or `GLPKMathProgInterface` cannot be set using `changeCobraSolver()`.")
Expand Down Expand Up @@ -188,33 +274,33 @@ LP problem must have the form:

# OUTPUTS

- `solutionLP`: Solution object of type `LPproblem`
- `status`: Termination status
- `objval`: Optimal objective value
- `sol`: Primal solution vector

# EXAMPLES

Minimum working example
```julia
julia> solveCobraLP(model, solver)
julia> status, objval, sol = solveCobraLP(model, solver)
```

See also: `MathProgBase.linprog()`,
See also: `solvelp()`,
"""

function solveCobraLP(model, solver)

if solver.handle != -1

# retrieve the solution
m = buildCobraLP(model, solver)
solutionLP = MathProgBase.HighLevelInterface.solvelp(m)
m, x = buildCobraLP(model, solver)
status, objval, sol = solvelp(m, x)

# adapt the objective value
if solutionLP.status == :Optimal
solutionLP.objval = model.osense * solutionLP.objval
if status == :Optimal
objval = model.osense * objval
end

return solutionLP

return status, objval, sol
else
error("The solver handle is not set properly using `changeCobraSolver()`.")
end
Expand Down Expand Up @@ -256,6 +342,6 @@ function autoTuneSolver(m, nMets, nRxns, solver, pid::Int=1)
end
end

export buildCobraLP, changeCobraSolver, solveCobraLP, autoTuneSolver
export buildlp, solvelp, buildCobraLP, changeCobraSolver, solveCobraLP, autoTuneSolver

#-------------------------------------------------------------------------------------------