Commit 5318cf8f authored by Sylvain Arreckx's avatar Sylvain Arreckx Committed by Laurent Heirendt
Browse files

squash of 153 commits

parent b1752b49
*.mat filter=lfs diff=lfs merge=lfs -text
......@@ -6,8 +6,6 @@ stages:
test:
stage: test
before_script:
- git lfs pull
script:
- julia --project=@. -e "import Pkg; Pkg.test(; coverage = true)"
......
name = "***REMOVED***"
name = "COBREXA"
uuid = "babc4406-5200-4a30-9033-bf5ae714c842"
authors = ["Some people"]
version = "0.1.0"
[deps]
Clp = "e2554f3b-3117-50c0-817c-e040a3ddf72d"
DelimitedFiles = "8bb1440f-4735-579b-a4ab-409b98df4dab"
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
GLPK = "60bf3e95-4087-53dc-ae20-288a0d20c6a6"
HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f"
JuMP = "4076af6c-e467-56ae-b986-b466b2749572"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
MAT = "23992714-dd62-5051-b70f-ba57cb901cac"
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
# exaCOBRA.jl
<div align="center">
<img src="docs/src/assets/header.svg?maxAge=0" width="80%">
</div>
<br>
# Constraint-Based Reconstruction and EXascale Analysis
\ No newline at end of file
using Documenter, ***REMOVED***
using Documenter, COBREXA
makedocs(sitename="My Documentation")
makedocs(modules = [COBREXA],
clean = false,
sitename = "COBREXA.jl",
format = Documenter.HTML(
# Use clean URLs, unless built as a "local" build
prettyurls = !("local" in ARGS),
assets = ["assets/favicon.ico"],
highlights = ["yaml"],
),
authors = "The developers of COBREXA.jl",
linkcheck = !("skiplinks" in ARGS),
pages = [
"Home" => "index.md",
"Functions" => "functions.md",
"How to contribute" => "howToContribute.md",
],
)
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 469.0243 73.5502">
<title>cobrexa</title>
<g>
<path d="M35.9118,68.7843A37.4981,37.4981,0,0,1,23.49,66.798a25.7336,25.7336,0,0,1-16.13-15.7246,37.8209,37.8209,0,0,1-2.25-13.5762,37.4205,37.4205,0,0,1,2.148-13.01A27.79,27.79,0,0,1,13.5,14.4777a26.4455,26.4455,0,0,1,9.7471-6.2012A35.7912,35.7912,0,0,1,35.9524,6.088a50.12,50.12,0,0,1,6.8691.4258,47.5887,47.5887,0,0,1,5.6538,1.1143A40.24,40.24,0,0,1,53.4,9.3507q2.2083.9522,3.87,1.7627v14.63H55.4865q-1.1352-.9668-2.8574-2.2978a37.887,37.887,0,0,0-3.9106-2.6211,27.1577,27.1577,0,0,0-4.8228-2.1778,17.0631,17.0631,0,0,0-5.5522-.8867,18.8216,18.8216,0,0,0-6.2412,1.0313,15.19,15.19,0,0,0-5.4712,3.4179,16.7734,16.7734,0,0,0-3.87,6.1065,25.473,25.473,0,0,0-1.4794,9.2217,24.4646,24.4646,0,0,0,1.6005,9.4638,16.4781,16.4781,0,0,0,4.0328,5.9854,14.7319,14.7319,0,0,0,5.5117,3.1748,20.0153,20.0153,0,0,0,5.998.9512,19.1461,19.1461,0,0,0,5.6128-.8467,21.8364,21.8364,0,0,0,5.127-2.2989,33.8712,33.8712,0,0,0,3.688-2.5q1.7021-1.33,2.7963-2.2978H57.27V63.5968q-2.27,1.0122-4.3364,1.9043a35.5376,35.5376,0,0,1-4.3364,1.54,52.3044,52.3044,0,0,1-5.5523,1.2968A44.3961,44.3961,0,0,1,35.9118,68.7843Z" style="fill: #252525"/>
<path d="M127.382,37.4562q0,14.4286-8.2675,22.918-8.2677,8.4917-22.8575,8.49-14.55,0-22.8169-8.49t-8.2675-22.918q0-14.5488,8.2675-22.999T96.257,6.007q14.5078,0,22.8169,8.45Q127.381,22.9064,127.382,37.4562ZM106.7536,52.7355a18.0657,18.0657,0,0,0,3.3638-6.5049,31.6257,31.6257,0,0,0,1.0942-8.8154,29.745,29.745,0,0,0-1.2563-9.24,17.9524,17.9524,0,0,0-3.2827-6.16,12.2909,12.2909,0,0,0-4.7622-3.5254,15.1106,15.1106,0,0,0-11.1856-.041,13.06,13.06,0,0,0-4.8022,3.4863,17.1528,17.1528,0,0,0-3.3033,6.2608,30.4681,30.4681,0,0,0-1.2763,9.2607,29.8032,29.8032,0,0,0,1.2363,9.18,18.142,18.142,0,0,0,3.2622,6.18,12.4575,12.4575,0,0,0,4.7417,3.5263,14.66,14.66,0,0,0,5.7144,1.1348,14.4427,14.4427,0,0,0,5.7143-1.1553A12.5037,12.5037,0,0,0,106.7536,52.7355Z" style="fill: #252525"/>
<path d="M190.8884,49.1281a16.9323,16.9323,0,0,1-1.7627,7.8222,16.1312,16.1312,0,0,1-4.8433,5.7139,22.6235,22.6235,0,0,1-7.8423,3.81,43.1916,43.1916,0,0,1-10.8408,1.1348H139.2565V7.2628h23.4249a83.3265,83.3265,0,0,1,10.6787.4864,21.9446,21.9446,0,0,1,6.7075,2.1484,11.8847,11.8847,0,0,1,5.1264,4.6807,13.2635,13.2635,0,0,1,1.6822,6.708,13.2445,13.2445,0,0,1-2.31,7.72,15.1348,15.1348,0,0,1-6.5249,5.208v.3242a17.0169,17.0169,0,0,1,9.3823,4.8633A13.6306,13.6306,0,0,1,190.8884,49.1281ZM170.9489,24.3253a6.6558,6.6558,0,0,0-.75-2.999,4.6663,4.6663,0,0,0-2.6543-2.2295,12.8972,12.8972,0,0,0-4.2353-.709q-2.5328-.06-7.1123-.06h-1.459V31.0929H157.17q3.687,0,6.2818-.1211a11.2578,11.2578,0,0,0,4.0932-.8105,5.0119,5.0119,0,0,0,2.7559-2.4111A8.4769,8.4769,0,0,0,170.9489,24.3253Zm3.7691,24.56a7.5665,7.5665,0,0,0-1.1128-4.4375,6.7435,6.7435,0,0,0-3.7808-2.331,19.7184,19.7184,0,0,0-5.0151-.5664q-3.1956-.0411-6.6738-.0411H154.738V56.5441H155.87q6.5523,0,9.3833-.04a13.7114,13.7114,0,0,0,5.2178-1.0538,6.3757,6.3757,0,0,0,3.3364-2.6953A7.9972,7.9972,0,0,0,174.718,48.8849Z" style="fill: #252525"/>
<path d="M260.5959,67.6086H241.5881L225.17,45.4806h-7.2094v22.128H202.4792V7.2628h26.0991a60,60,0,0,1,9.2012.6084,19.8582,19.8582,0,0,1,7.2129,2.6338,15.7429,15.7429,0,0,1,5.41,5.2491,15.0359,15.0359,0,0,1,2.0059,8.0849q0,6.687-3.1,10.9024a23.3985,23.3985,0,0,1-8.8555,7.0107ZM236.3205,25.7433a7.6851,7.6851,0,0,0-.9336-3.8906A6.2479,6.2479,0,0,0,232.1857,19.3a11.7993,11.7993,0,0,0-3.6875-.79q-2.1093-.1421-4.9042-.1416h-5.6333v16.251h4.7822a44.7363,44.7363,0,0,0,6.2417-.3643,8.9493,8.9493,0,0,0,4.2148-1.6621,8.099,8.099,0,0,0,2.3711-2.7763A9.3117,9.3117,0,0,0,236.3205,25.7433Z" style="fill: #252525"/>
<path d="M311.051,67.6086H267.4035V7.2628H311.051V18.9347H282.885v10.416h26.1406V41.0226H282.885V55.9367h28.166Z" style="fill: #252525"/>
<path d="M464.9738,67.6086H448.9025l-4.2041-12.1993h-22.331l-4.2041,12.1993H402.4807l22.29-60.3458h17.9131ZM440.9572,44.3459l-7.4238-21.6192-7.4258,21.6192Z" style="fill: #252525"/>
</g>
<g>
<path d="M358.0573,57.0955l3.7726-5.0271,1.9267-2.5674,3.4006-4.5313a1.6715,1.6715,0,0,0,.0055-1.9992l-1.6166-2.1786a1.6713,1.6713,0,0,0-2.6741-.0137l-2.2026,2.9058-2.5574,3.3738L354.3281,52.05l-6.5405,8.6286a1.6714,1.6714,0,0,1-1.332.6618H332.3573l12.1906-15.9982a1.6712,1.6712,0,0,0,.0148-2.0063l-1.5618-2.1133a1.6714,1.6714,0,0,0-2.6786-.0128l-17.6969,23.47A1.6714,1.6714,0,0,0,323.96,67.357h25.5612a1.6715,1.6715,0,0,0,1.3368-.6682l1.42-1.8925Z" style="fill: #b890c2;stroke: #a673b1;stroke-linejoin: round"/>
<path d="M362.349,21.9811h0l6.44-8.4521a1.6714,1.6714,0,0,1,1.3294-.6583H384.026l-11.95,15.7655a1.6713,1.6713,0,0,0-.0128,2.0022l1.5669,2.1227a1.6713,1.6713,0,0,0,2.6815.0106l5.7607-7.6761L393.7545,9.5284a1.6714,1.6714,0,0,0-1.3368-2.6746H367.06a1.6714,1.6714,0,0,0-1.3345.6651l-7.1007,9.4171-8.9708,11.8972-.1218.1615a1.6713,1.6713,0,0,0-.0077,2.0022l1.613,2.1739a1.6713,1.6713,0,0,0,2.6716.0171l4.7749-6.2662,3.7647-4.9406" style="fill: #df796f;stroke: #d75544;stroke-miterlimit: 10"/>
<path d="M365.9009,36.7823h0L369.58,41.741,384.1229,61.34H369.5505a1.6714,1.6714,0,0,1-1.3422-.6755l-3.3815-4.5572a1.6713,1.6713,0,0,0-2.679-.0073l-1.6844,2.2445a1.6712,1.6712,0,0,0-.0073,1.9966l4.684,6.3378a1.6713,1.6713,0,0,0,1.3441.678H392.531a1.6714,1.6714,0,0,0,1.3447-2.664l-20.588-27.8923h0l-3.6512-4.9466-4.31-5.8388a1.6714,1.6714,0,0,0-2.6741-.02l-1.6479,2.1626a1.6715,1.6715,0,0,0-.0128,2.009Z" style="fill: #7e96cd;stroke: #5b78bb;stroke-miterlimit: 10"/>
<path d="M350.7751,37.17l-3.6736-4.951L332.7451,12.8707h14.5722a1.6715,1.6715,0,0,1,1.3423.6754l3.2178,4.3367a1.6714,1.6714,0,0,0,2.6768.01l1.6634-2.2061a1.6712,1.6712,0,0,0,.01-1.9988l-4.5436-6.1556a1.6713,1.6713,0,0,0-1.3447-.6788h-26.1a1.6713,1.6713,0,0,0-1.3441,2.6647L343.35,37.1947l3.6467,4.9343,2.6848,3.6328,1.0347,1.4.6043.8176.0244.033a1.6714,1.6714,0,0,0,2.6761.0163l1.6744-2.209a1.6715,1.6715,0,0,0,.01-2.0056l-4.93-6.6442Z" style="fill: #71b964;stroke: #49a648;stroke-miterlimit: 10"/>
</g>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 176.4426 148.4338">
<title>cobrexa</title>
<line x1="69.5239" y1="140.1331" x2="69.5239" y2="140.1331" style="fill: none"/>
<g>
<path d="M87.7693,122.2541l9.0657-12.08,4.63-6.17,8.1718-10.889a4.0163,4.0163,0,0,0,.0131-4.8041l-3.8846-5.2353a4.0164,4.0164,0,0,0-6.4262-.0329l-5.2929,6.9826L87.9007,98.133l-9.0928,11.9957L63.0907,130.8638a4.0165,4.0165,0,0,1-3.2008,1.59H26.011L55.3056,94.01a4.0162,4.0162,0,0,0,.0354-4.8214L51.588,84.11a4.0164,4.0164,0,0,0-6.4369-.0309L2.6247,140.4784a4.0163,4.0163,0,0,0,3.2069,6.4344H67.2564a4.0164,4.0164,0,0,0,3.2124-1.6056l3.4128-4.5477Z" style="fill: #b890c2;stroke: #a673b1;stroke-linejoin: round"/>
<path d="M98.0825,37.8725h0l15.4768-20.3106a4.0161,4.0161,0,0,1,3.1946-1.5821h33.4192L121.4561,53.865a4.0163,4.0163,0,0,0-.0307,4.8113l3.7652,5.1011a4.0164,4.0164,0,0,0,6.4438.0256l13.8432-18.4463L173.5513,7.9481a4.0164,4.0164,0,0,0-3.2124-6.4272h-60.935a4.0163,4.0163,0,0,0-3.2069,1.5983l-17.0633,22.63-21.5572,28.59-.2928.3883a4.0163,4.0163,0,0,0-.0186,4.8113l3.8762,5.2239a4.0164,4.0164,0,0,0,6.42.0411L89.0356,49.7449l9.0468-11.8724" style="fill: #df796f;stroke: #d75544;stroke-miterlimit: 10"/>
<path d="M106.6178,73.44h0l8.8417,11.916,34.9466,47.0975H115.388a4.0165,4.0165,0,0,1-3.2254-1.6231L104.0367,119.88a4.0163,4.0163,0,0,0-6.4378-.0175l-4.0477,5.3936a4.0164,4.0164,0,0,0-.0176,4.7979l11.2558,15.23a4.0164,4.0164,0,0,0,3.23,1.6292h62.5917a4.0163,4.0163,0,0,0,3.2314-6.4015L124.3686,73.4848h0l-8.774-11.8869L105.238,47.5669a4.0163,4.0163,0,0,0-6.426-.0491l-3.96,5.1968a4.0165,4.0165,0,0,0-.0308,4.8276Z" style="fill: #7e96cd;stroke: #5b78bb;stroke-miterlimit: 10"/>
<path d="M70.27,74.3718,61.4418,62.4742,26.9429,15.98H61.9606a4.0164,4.0164,0,0,1,3.2255,1.6231l7.7326,10.4213a4.0164,4.0164,0,0,0,6.4323.0248l3.9974-5.3014a4.0164,4.0164,0,0,0,.0246-4.8033L72.4545,3.1521a4.0165,4.0165,0,0,0-3.2314-1.6312H6.5031a4.0163,4.0163,0,0,0-3.23,6.4035L52.4257,74.4315,61.189,86.2889l6.4517,8.73,2.4863,3.3642,1.4521,1.9648.0587.0794a4.0163,4.0163,0,0,0,6.4307.0391l4.0238-5.3084a4.0163,4.0163,0,0,0,.0247-4.8194L70.27,74.3718Z" style="fill: #71b964;stroke: #49a648;stroke-miterlimit: 10"/>
</g>
</svg>
# Functions
## Base and header modules
```@autodocs
Modules = [COBREXA]
Pages = ["header/types.jl", "base/types,jl", "base/solver.jl", "base/utilities.jl"]
```
## I/O module
```@autodocs
Modules = [COBREXA]
Pages = ["io/reader.jl"]
```
## Reconstruction module
```@autodocs
Modules = [COBREXA]
Pages = ["reconstruction/coupling.jl", "reconstruction/microbiome.jl","reconstruction/modeling.jl"]
```
## Analysis module
```@autodocs
Modules = [COBREXA]
Pages = ["analysis/fba.jl", "analysis/fva.jl"]
```
# How to contribute to/develop COBREXA
If you want to contribute to the `COBREXA` package, please fork the present
repository by following [these instructions](https://docs.github.com/en/github/getting-started-with-github/fork-a-repo).
## Step 1: Retrieve a local version of COBREXA
There are two ways that you can retrieve a local copy of the package: one is to
manually clone the forked repository, and the second one is to use the
intergrated Julia package manager.
### Option 1: Manually clone your fork
:warning: Please make sure you have _forked_ the repository, as described above.
You can do this as follows from the command line:
```bash
$ git clone git@github.com:yourUsername/COBREXA.jl.git COBREXA.jl
$ cd COBREXA.jl
$ git checkout -b yourNewBranch origin/develop
```
where `yourUsername` is your Github username and `yourNewBranch` is the name of a new branch.
Then, in order to develop the package, you can install your cloned version as
follows (make sure you are in the `COBREXA.jl` directory):
```julia
(v1.1) pkg> add .
```
(press `]` to get into the packaging environment)
This adds the `COBREXA.jl` package and all its dependencies. You can verify
that the installation worked by typing:
```julia
(v1.1) pkg> status
```
If everything went smoothly, this should print something similar to:
```julia
(v1.1) pkg> status
Status `~/.julia/environments/v1.1/Project.toml`
[babc4406] COBREXA v0.1.0 #yourNewBranch (.)
```
Now, you can readily start using the `COBREXA` module:
```julia
julia> using COBREXA
```
### Option 2: Use the Julia package manager
When you are used to using the Julia package manager for developing or
contributing to packages, you can type:
```julia
(v1.1) pkg> dev COBREXA
```
This will install the `COBREXA` package locally and check it out for
development. You can check the location of the package with:
```julia
(v1.1) pkg> status
Status `~/.julia/environments/v1.4/Project.toml`
[a03a9c34] COBREXA v0.0.5 [`~/.julia/dev/COBREXA`]
```
The default location of the package is `~/.julia/dev/COBREXA`.
You can then set your remote by executing these commands in a regular shell:
```bash
$ cd ~/.julia/dev/COBREXA
$ git remote rename origin upstream # renames the origin as upstream
$ git remote add origin git@github.com:yourUsername/COBREXA.jl.git
$ git fetch origin
```
where `yourUsername` is your Github username.
:warning: Make sure that your fork exists under `github.com/yourUsername/COBREXA.jl`.
Then, checkout a branch `yourNewBranch`:
```bash
$ cd ~/.julia/dev/COBREXA
$ git checkout -b yourNewBranch origin/develop
```
Then, you can readily use the `COBREXA` package:
```julia
julia> using COBREXA
```
After making changes, precompile the package:
```julia
(v1.1) pkg> precompile
```
## Step 2: Activate COBREXA
:warning: Please note that you cannot use the dependencies of COBREXA directly,
unless they are installed separately or the environment has been activated:
```julia
(v1.1) pkg> activate .
(COBREXA) pkg> instantiate
```
Now, the environment is activated (you can see it with the prompt change
`(COBREXA) pkg>`). Now, you can use the dependency. For instance:
```julia
julia> using DataFrames
```
:warning: If you do not `activate` the environment before using any of the dependencies, you will see a red error messages prompting you to install the dependency explicity.
# Documentation
```@raw html
<br>
<div align="center">
<img src="assets/header.svg?maxAge=0" width="80%">
</div>
<br>
```
# Constraint-Based Reconstruction and EXascale Analysis
# Functions
A full reference to all functions is given here:
```@contents
Pages = ["functions.md"]
```
# How to contribute?
If you want to contribute, please read these guidelines first:
```@contents
Pages = ["howToContribute.md"]
```
\ No newline at end of file
module COBREXA
using Logging
using SparseArrays
using DelimitedFiles
using LinearAlgebra
using JuMP
using MAT
import Pkg
# import src files
include(joinpath("header", "header.jl"))
include(joinpath("header", "types.jl"))
const PKG_ROOT_DIR = normpath(joinpath(@__DIR__, ".."))
include_dependency(joinpath(PKG_ROOT_DIR, "Project.toml"))
const COBREXA_VERSION = VersionNumber(Pkg.TOML.parsefile(joinpath(PKG_ROOT_DIR, "Project.toml"))["version"])
c = Base.text_colors
tx = c[:normal] # text
b = c[:bold] * c[:blue]
r = c[:bold] * c[:red]
g = c[:bold] * c[:green]
m = c[:bold] * c[:magenta]
banner = "
____ ___ ____ ____ _____$(g)__$(tx) $(r)__$(tx) _ |
/ ___/ _ \\| __ )| _ \\| ____$(g)\\ \\$(tx)$(r)/ /$(tx) / \\ | Constraint-Based Reconstruction
| | | | | | _ \\| |_) | _| $(g)\\$(tx) $(r)/$(tx) / _ \\ | and EXascale Analysis in Julia
| |__| |_| | |_) | _ <| |___ $(m)/$(tx) $(b)\\$(tx) / ___ \\ |
\\____\\___/|____/|_| \\_\\_____$(m)/_/$(tx)$(b)\\_\\$(tx)/_/ \\_\\ | Version: v$(COBREXA_VERSION)
|
"
print(banner)
loadSource(["base", "io", "reconstruction", "analysis"], @__DIR__)
# export functions
export speye, LinearModel, nReactions, nMetabolites, nCouplingConstraints,
addReaction, addReactions, removeReactions, changeBounds!,
addCouplingConstraints!, addCouplingConstraints,
removeCouplingConstraints!, removeCouplingConstraints,
changeCouplingBounds!, changeCouplingBounds,
verifyConsistency, findExchangeReactions, findExchangeMetabolites,
solveLP, loadModel, fluxBalanceAnalysis, fluxVariabilityAnalysis,
writeModel, convertToExportable
end
module ***REMOVED***
export LinearModel, addReaction, addReactions, solveLP, loadModel,
nReactions, nMetabolites
include("modeling.jl")
include("solveLP.jl")
include("io/matReader.jl")
end
"""
Flux Balance Analysis
```
max cᵀx
s.t. S x = b
xₗ ≤ x ≤ xᵤ
```
"""
function fluxBalanceAnalysis(model::LinearModel, optimizer)
m, n = size(model.S)
optimization_model = JuMP.Model(optimizer)
@variable(optimization_model, x[i=1:n], lower_bound=model.xl[i], upper_bound=model.xu[i])
@objective(optimization_model, Max, model.c' * x)
@constraint(optimization_model, model.S * x .== model.b)
JuMP.optimize!(optimization_model)
return (optimization_model, x)
end
"""
Flux variability analysis (FVA)
FVA solves the pair of optimization problems for each flux xᵢ
```
min/max xᵢ
s.t. S x = b
xₗ ≤ x ≤ xᵤ
cᵀx ≥ γ Z₀
```
where Z₀:= cᵀx₀ is the objective value of an optimal solution to the associated
FBA problem
"""
function fluxVariabilityAnalysis(model::LinearModel, optimizer)
(m, n) = size(model.S)
return fluxVariabilityAnalysis(model, collect(1:n), optimizer)
end
function fluxVariabilityAnalysis(model::LinearModel, reactions::Array{Int64, 1}, optimizer)
(maximum(reactions) > length(model.rxns)) && error("Index exceeds number of reactions.")
γ = 1.
fluxes = zeros(length(reactions), 2)
(optimization_model, x₀) = fluxBalanceAnalysis(model::LinearModel, optimizer)
Z₀ = JuMP.objective_value(optimization_model)
x = all_variables(optimization_model)
@constraint(optimization_model, model.c' * x γ * Z₀)
for i in eachindex(reactions)
sense = MOI.MIN_SENSE
@objective(optimization_model, sense, x[reactions[i]])
JuMP.optimize!(optimization_model)
fluxes[i, 1] = JuMP.objective_value(optimization_model)
sense = MOI.MAX_SENSE
JuMP.set_objective_sense(optimization_model, sense)
JuMP.optimize!(optimization_model)
fluxes[i, 2] = JuMP.objective_value(optimization_model)
end
return fluxes
end
import ..LinearModel
using JuMP
using GLPK
"""
Use JuMP to solve an instance of LinearModel
"""
function solveLP(model::LinearModel)
function solveLP(model::LinearModel, optimizer)
m, n = size(model.S)
optimization_model = JuMP.Model(GLPK.Optimizer)
@variable(optimization_model, x[i=1:n], lower_bound=model.lb[i], upper_bound=model.ub[i])
optimization_model = JuMP.Model(optimizer)
@variable(optimization_model, x[i=1:n], lower_bound=model.xl[i], upper_bound=model.xu[i])
@objective(optimization_model, Min, model.c' * x)
@constraint(optimization_model, model.S * x .== model.b)
......
"""
`n` by `n` sparse identity matrix.
"""
speye(n) = sparse(1.0I, n, n)
function Base.isequal(model1::LinearModel, model2::LinearModel)
return model1.S == model2.S && model1.b == model2.b && model1.C == model2.C &&
model1.cl == model2.cl && model1.cu == model2.cu &&
model1.c == model2.c &&
model1.xl == model2.xl && model1.xu == model2.xu &&
model1.rxns == model2.rxns && model1.mets == model2.mets
end
function Base.copy(model::LinearModel)
return LinearModel(model.S, model.b, model.C, model.cl, model.cu,
model.c, model.xl, model.xu, model.rxns, model.mets)
end
"""
loadSource(srcDirs, root=@__DIR__)
Load source files
"""
function loadSource(srcDirs, rootDir=@__DIR__, testMode=false)
returnFlag = []
for d in srcDirs
srcDir = joinpath(rootDir, d)
if testMode
println(" > srcDir = $srcDir")
end
for file in filter(f -> endswith(f, ".jl"), readdir(srcDir))
if file != "header.jl"
srcFile = joinpath(rootDir, d, file)
if !testMode
include(srcFile)
else
println(" > srcFile = $srcFile")
end
push!(returnFlag, true)
end
end
end
return returnFlag
end
\ No newline at end of file
const VT = Union{Array{Float64,1}, SparseVector{Float64,Int64}}
const MT = Union{AbstractMatrix, SparseMatrixCSC{Float64,Int64}}
const ST = Union{Array{String,1}, SparseVector{String,Int64}}
"""
A linear optimization problem of the form:
```
min c^T x
s.t. S x = b
cₗ ≤ C x ≤ cᵤ
xₗ ≤ x ≤ xᵤ
```
"""
mutable struct LinearModel{M<:MT, V<:VT, K<:ST}
S ::M
b ::V
C ::M
cl ::V
cu ::V
c ::V
xl ::V
xu ::V
rxns ::K
mets ::K
function LinearModel(
S ::M,
b ::V,
c ::V,
xl ::V,
xu ::V,
rxns ::K,
mets ::K) where {V<:VT,M<:MT,K<:ST}
sS = sparse(S)
sb = sparse(b)
sC = spzeros(0, length(c))
scl = spzeros(0)
scu = spzeros(0)
sc = sparse(c)
sxl = sparse(xl)
sxu = sparse(xu)
LinearModel(sS, sb, sC, scl, scu, sc, sxl, sxu, rxns, mets)
end
function LinearModel(
S ::M1,
b ::V,
C ::M2,
cl ::V,
cu ::V,
c ::V,
xl ::V,
xu ::V,
rxns ::K,
mets ::K) where {V<:VT,M1<:MT,M2<:MT,K<:ST}
checkInputDimensions(S, b, C, cl, cu, c, xl, xu, rxns, mets)
sS = sparse(S)
sb = sparse(b)
sC = sparse(C)
scl = sparse(cl)
scu = sparse(cu)
sc = sparse(c)
sxl = sparse(xl)
sxu = sparse(xu)
new{SparseMatrixCSC{Float64,Int64}, SparseVector{Float64,Int64}, Array{String,1}}(sS, sb, sC, scl, scu, sc, sxl, sxu, rxns, mets)
end
end
mutable struct ReactionStatus
alreadyPresent::Bool
index::Int
info::String
end
import ..LinearModel
using MAT
"""
Load a model in MAT (Matlab) format and returns a `LinearModel`
......@@ -13,27 +9,10 @@ function loadModel(filePath::String, varName::String)
file = matopen(filePath)
vars = matread(filePath)
if exists(file, varName)
model = vars[varName]
modelKeys = ["S", "b", "c", "ub", "lb"]
for key = modelKeys
if !(key in keys(model))
error("No variable $key found in the MAT file.")
end
end
S = model["S"]
b = vec(model["b"])
c = vec(model["c"])
ub = vec(model["ub"])
lb = vec(model["lb"])
# rxns and mets get loaded as Array{Any,2} need to convert
rxns = conversionMetRxns(model["rxns"])
mets = conversionMetRxns(model["mets"])
if exists(file, varName)
return LinearModel(S, b, c, lb, ub, rxns, mets)
return convertToLinearModel(vars[varName])
else
error("Variable `varName` does not exist in the specified MAT file.")
......@@ -41,10 +20,25 @@ function loadModel(filePath::String, varName::String)
close(file)
end
function conversionMetRxns(x)
if x isa Array{Any, 2}
return convert(Array{String, 1}, vec(x))
else
return vec(x)
"""
Convert a dictionary read from a MAT file to LinearModel
"""
function convertToLinearModel(model::Dict)
modelKeys = ["S", "b", "c", "ub", "lb"]
for key = modelKeys
if !(key in keys(model))
error("No variable $key found in the MAT file.")
end
end
S = model["S"]
b = vec(model["b"])
c = vec(model["c"])
ub = vec(model["ub"])
lb = vec(model["lb"])
rxns = vec(string.(model["rxns"]))
mets = vec(string.(model["mets"]))
return LinearModel(S, b, c, lb, ub, rxns, mets)
end