Unverified Commit 8fcd8e19 authored by Miroslav Kratochvil's avatar Miroslav Kratochvil Committed by GitHub
Browse files

Merge pull request #513 from LCSB-BioCore/mk-dense-bounds

[breaking] avoid unnecessary sparsity in lower/upper flux bounds
parents cdc3ced9 71b79ec6
Pipeline #49552 passed with stages
in 18 minutes and 42 seconds
......@@ -73,8 +73,8 @@ function COBREXA.objective(m::CircularModel)
end
COBREXA.bounds(m::CircularModel) = (
spzeros(n_reactions(m)), # lower bounds
sparse(ones(n_reactions(m))), # upper bounds
zeros(n_reactions(m)), # lower bounds
ones(n_reactions(m)), # upper bounds
)
function COBREXA.stoichiometry(m::CircularModel)
......
......@@ -69,7 +69,7 @@ minimize_metabolic_adjustment(flux_ref::Vector{Float64}) =
end
"""
minimize_metabolic_adjustment(flux_ref_dict::Dict{String, Float64})
minimize_metabolic_adjustment(flux_ref_dict::Dict{String, Float64})
Overload of [`minimize_metabolic_adjustment`](@ref) that works with a
dictionary of fluxes.
......
......@@ -14,28 +14,27 @@ mutable struct CoreModel <: MetabolicModel
S::SparseMat
b::SparseVec
c::SparseVec
xl::SparseVec
xu::SparseVec
xl::Vector{Float64}
xu::Vector{Float64}
rxns::Vector{String}
mets::Vector{String}
function CoreModel(
S::M,
b::V,
c::V,
xl::V,
xu::V,
rxns::K,
mets::K,
) where {V<:VecType,M<:MatType,K<:StringVecType}
S::MatType,
b::VecType,
c::VecType,
xl::VecType,
xu::VecType,
rxns::StringVecType,
mets::StringVecType,
)
all([length(b), length(mets)] .== size(S, 1)) ||
throw(DimensionMismatch("inconsistent number of metabolites"))
all([length(c), length(xl), length(xu), length(rxns)] .== size(S, 2)) ||
throw(DimensionMismatch("inconsistent number of reactions"))
new(sparse(S), sparse(b), sparse(c), sparse(xl), sparse(xu), rxns, mets)
new(sparse(S), sparse(b), sparse(c), collect(xl), collect(xu), rxns, mets)
end
end
......@@ -61,11 +60,11 @@ metabolites(a::CoreModel)::Vector{String} = a.mets
stoichiometry(a::CoreModel)::SparseMat = a.S
"""
bounds(a::CoreModel)::Tuple{SparseVec,SparseVec}
bounds(a::CoreModel)::Tuple{Vector{Float64},Vector{Float64}}
`CoreModel` flux bounds.
"""
bounds(a::CoreModel)::Tuple{SparseVec,SparseVec} = (a.xl, a.xu)
bounds(a::CoreModel)::Tuple{Vector{Float64},Vector{Float64}} = (a.xl, a.xu)
"""
balance(a::CoreModel)::SparseVec
......
......@@ -10,22 +10,16 @@ The linear model with additional coupling constraints in the form
mutable struct CoreModelCoupled <: MetabolicModel
lm::CoreModel
C::SparseMat
cl::SparseVec
cu::SparseVec
function CoreModelCoupled(
lm::MetabolicModel,
C::M,
cl::V,
cu::V,
) where {V<:VecType,M<:MatType}
cl::Vector{Float64}
cu::Vector{Float64}
function CoreModelCoupled(lm::MetabolicModel, C::MatType, cl::VecType, cu::VecType)
length(cu) == length(cl) ||
throw(DimensionMismatch("`cl` and `cu` need to have the same size"))
size(C) == (length(cu), n_reactions(lm)) ||
throw(DimensionMismatch("wrong dimensions of `C`"))
new(convert(CoreModel, lm), sparse(C), sparse(cl), sparse(cu))
new(convert(CoreModel, lm), sparse(C), collect(cl), collect(cu))
end
end
......@@ -92,11 +86,11 @@ The number of coupling constraints in a `CoreModelCoupled`.
n_coupling_constraints(a::CoreModelCoupled)::Int = size(a.C, 1)
"""
coupling_bounds(a::CoreModelCoupled)::Tuple{SparseVec,SparseVec}
coupling_bounds(a::CoreModelCoupled)::Tuple{Vector{Float64},Vector{Float64}}
Coupling bounds for a `CoreModelCoupled`.
"""
coupling_bounds(a::CoreModelCoupled)::Tuple{SparseVec,SparseVec} = (a.cl, a.cu)
coupling_bounds(a::CoreModelCoupled)::Tuple{Vector{Float64},Vector{Float64}} = (a.cl, a.cu)
"""
reaction_stoichiometry(model::CoreModelCoupled, rid::String)::Dict{String, Float64}
......
......@@ -146,12 +146,8 @@ Get the bounds for reactions, assuming the information is stored in
`.lower_bound` and `.upper_bound`.
"""
bounds(model::JSONModel) = (
sparse([
get(rxn, "lower_bound", -_constants.default_reaction_bound) for rxn in model.rxns
]),
sparse([
get(rxn, "upper_bound", _constants.default_reaction_bound) for rxn in model.rxns
]),
[get(rxn, "lower_bound", -_constants.default_reaction_bound) for rxn in model.rxns],
[get(rxn, "upper_bound", _constants.default_reaction_bound) for rxn in model.rxns],
)
"""
......
......@@ -59,8 +59,8 @@ stoichiometry(m::MATModel) = sparse(m.mat["S"])
Extracts bounds from the MAT file, saved under `lb` and `ub`.
"""
bounds(m::MATModel) = (
sparse(reshape(get(m.mat, "lb", fill(-Inf, n_reactions(m), 1)), n_reactions(m))),
sparse(reshape(get(m.mat, "ub", fill(Inf, n_reactions(m), 1)), n_reactions(m))),
reshape(get(m.mat, "lb", fill(-Inf, n_reactions(m), 1)), n_reactions(m)),
reshape(get(m.mat, "ub", fill(Inf, n_reactions(m), 1)), n_reactions(m)),
)
"""
......
......@@ -47,12 +47,12 @@ function stoichiometry(model::SBMLModel)::SparseMat
end
"""
bounds(model::SBMLModel)::Tuple{SparseVec,SparseVec}
bounds(model::SBMLModel)::Tuple{Vector{Float64},Vector{Float64}}
Get the lower and upper flux bounds of model [`SBMLModel`](@ref). Throws `DomainError` in
case if the SBML contains mismatching units.
"""
function bounds(model::SBMLModel)::Tuple{SparseVec,SparseVec}
function bounds(model::SBMLModel)::Tuple{Vector{Float64},Vector{Float64}}
lbu, ubu = SBML.flux_bounds(model.sbml)
unit = lbu[1][2]
......@@ -67,7 +67,7 @@ function bounds(model::SBMLModel)::Tuple{SparseVec,SparseVec}
),
)
return sparse.((getvalue.(lbu), getvalue.(ubu)))
return (getvalue.(lbu), getvalue.(ubu))
end
"""
......
......@@ -144,29 +144,29 @@ function stoichiometry(model::StandardModel)::SparseMat
end
"""
lower_bounds(model::StandardModel)
lower_bounds(model::StandardModel)::Vector{Float64}
Return the lower bounds for all reactions in `model` in sparse format.
"""
lower_bounds(model::StandardModel)::SparseVec =
lower_bounds(model::StandardModel)::Vector{Float64} =
sparse([model.reactions[rxn].lb for rxn in reactions(model)])
"""
upper_bounds(model::StandardModel)
upper_bounds(model::StandardModel)::Vector{Float64}
Return the upper bounds for all reactions in `model` in sparse format.
Order matches that of the reaction ids returned in `reactions()`.
"""
upper_bounds(model::StandardModel)::SparseVec =
upper_bounds(model::StandardModel)::Vector{Float64} =
sparse([model.reactions[rxn].ub for rxn in reactions(model)])
"""
bounds(model::StandardModel)
bounds(model::StandardModel)::Tuple{Vector{Float64},Vector{Float64}}
Return the lower and upper bounds, respectively, for reactions in `model`.
Order matches that of the reaction ids returned in `reactions()`.
"""
bounds(model::StandardModel)::Tuple{SparseVec,SparseVec} =
bounds(model::StandardModel)::Tuple{Vector{Float64},Vector{Float64}} =
(lower_bounds(model), upper_bounds(model))
"""
......
......@@ -105,11 +105,11 @@ function stoichiometry(a::MetabolicModel)::SparseMat
end
"""
bounds(a::MetabolicModel)::Tuple{SparseVec,SparseVec}
bounds(a::MetabolicModel)::Tuple{Vector{Float64},Vector{Float64}}
Get the lower and upper flux bounds of a model.
"""
function bounds(a::MetabolicModel)::Tuple{SparseVec,SparseVec}
function bounds(a::MetabolicModel)::Tuple{Vector{Float64},Vector{Float64}}
_missing_impl_error(bounds, (a,))
end
......@@ -151,12 +151,12 @@ function n_coupling_constraints(a::MetabolicModel)::Int
end
"""
coupling_bounds(a::MetabolicModel)::Tuple{SparseVec,SparseVec}
coupling_bounds(a::MetabolicModel)::Tuple{Vector{Float64},Vector{Float64}}
Get the lower and upper bounds for each coupling bound in a model, as specified
by `coupling`. By default, the model does not have any coupling bounds.
"""
function coupling_bounds(a::MetabolicModel)::Tuple{SparseVec,SparseVec}
function coupling_bounds(a::MetabolicModel)::Tuple{Vector{Float64},Vector{Float64}}
return (spzeros(0), spzeros(0))
end
......
......@@ -26,8 +26,8 @@ function add_reactions!(model::CoreModel, rxns::Vector{Reaction})
Sadd = sparse(I, J, V, n_metabolites(model), length(rxns))
model.S = [model.S Sadd]
model.c = dropzeros([model.c; cs])
model.xu = sparse(ubs)
model.xl = sparse(lbs)
model.xu = ubs
model.xl = lbs
return nothing
end
......@@ -42,25 +42,25 @@ add_reaction!(model::CoreModel, rxn::Reaction) = add_reactions!(model, [rxn])
"""
add_reactions(
m::CoreModel,
s::V1,
b::V2,
s::VecType,
b::VecType,
c::AbstractFloat,
xl::AbstractFloat,
xu::AbstractFloat;
check_consistency = false,
) where {V1<:VecType,V2<:VecType}
)
Add reaction(s) to a `CoreModel` model `m`.
"""
function add_reactions(
m::CoreModel,
s::V1,
b::V2,
s::VecType,
b::VecType,
c::AbstractFloat,
xl::AbstractFloat,
xu::AbstractFloat;
check_consistency = false,
) where {V1<:VecType,V2<:VecType}
)
return add_reactions(
m,
sparse(reshape(s, (length(s), 1))),
......@@ -75,27 +75,27 @@ end
"""
add_reactions(
m::CoreModel,
s::V1,
b::V2,
s::VecType,
b::VecType,
c::AbstractFloat,
xl::AbstractFloat,
xu::AbstractFloat,
rxn::String,
mets::K;
check_consistency = false,
) where {V1<:VecType,V2<:VecType,K<:StringVecType}
)
"""
function add_reactions(
m::CoreModel,
s::V1,
b::V2,
s::VecType,
b::VecType,
c::AbstractFloat,
xl::AbstractFloat,
xu::AbstractFloat,
rxn::String,
mets::K;
mets::StringVecType;
check_consistency = false,
) where {V1<:VecType,V2<:VecType,K<:StringVecType}
)
return add_reactions(
m,
sparse(reshape(s, (length(s), 1))),
......@@ -112,23 +112,23 @@ end
"""
add_reactions(
m::CoreModel,
Sp::M,
b::V,
c::V,
xl::V,
xu::V;
Sp::MatType,
b::VecType,
c::VecType,
xl::VecType,
xu::VecType;
check_consistency = false,
) where {M<:MatType,V<:VecType}
)
"""
function add_reactions(
m::CoreModel,
Sp::M,
b::V,
c::V,
xl::V,
xu::V;
Sp::MatType,
b::VecType,
c::VecType,
xl::VecType,
xu::VecType;
check_consistency = false,
) where {M<:MatType,V<:VecType}
)
rxns = ["r$x" for x = length(m.rxns)+1:length(m.rxns)+length(xu)]
mets = ["m$x" for x = length(m.mets)+1:length(m.mets)+size(Sp)[1]]
return add_reactions(
......@@ -166,33 +166,32 @@ end
"""
add_reactions(
m::CoreModel,
Sp::M,
b::V,
c::V,
xl::V,
xu::V,
rxns::K,
mets::K;
Sp::MatType,
b::VecType,
c::VecType,
xl::VecType,
xu::VecType,
rxns::StringVecType,
mets::StringVecType;
check_consistency = false,
) where {M<:MatType,V<:VecType,K<:StringVecType}
)
"""
function add_reactions(
m::CoreModel,
Sp::M,
b::V,
c::V,
xl::V,
xu::V,
rxns::K,
mets::K;
Sp::MatType,
b::VecType,
c::VecType,
xl::VecType,
xu::VecType,
rxns::StringVecType,
mets::StringVecType;
check_consistency = false,
) where {M<:MatType,V<:VecType,K<:StringVecType}
)
Sp = sparse(Sp)
b = sparse(b)
c = sparse(c)
xl = sparse(xl)
xu = sparse(xu)
xl = collect(xl)
xu = collect(xu)
all([length(b), length(mets)] .== size(Sp, 1)) ||
throw(DimensionMismatch("inconsistent number of metabolites"))
......@@ -251,13 +250,13 @@ end
Sp::M,
b::V,
c::V,
xl::V,
xu::V,
xl::B,
xu::B,
names::K,
mets::K,
new_reactions,
new_metabolites,
) where {M<:MatType,V<:VecType,K<:StringVecType}
) where {M<:MatType,V<:VecType,B<:VecTypeK<:StringVecType}
Check the consistency of given reactions with existing reactions in `m`.
......@@ -268,13 +267,13 @@ function verify_consistency(
Sp::M,
b::V,
c::V,
xl::V,
xu::V,
xl::B,
xu::B,
names::K,
mets::K,
new_reactions,
new_metabolites,
) where {M<:MatType,V<:VecType,K<:StringVecType}
) where {M<:MatType,V<:VecType,B<:VecType,K<:StringVecType}
if !isempty(new_reactions)
statuses = Vector{ReactionStatus}(undef, length(names))
......
......@@ -202,12 +202,7 @@ function add_coupling_constraints!(
cl::AbstractFloat,
cu::AbstractFloat,
)
return add_coupling_constraints!(
m,
sparse(reshape(c, (1, length(c)))),
sparse([cl]),
sparse([cu]),
)
return add_coupling_constraints!(m, sparse(reshape(c, (1, length(c)))), [cl], [cu])
end
......@@ -237,8 +232,8 @@ function add_coupling_constraints!(
throw(DimensionMismatch("mismatched number of reactions"))
m.C = vcat(m.C, sparse(C))
m.cl = vcat(m.cl, sparse(cl))
m.cu = vcat(m.cu, sparse(cu))
m.cl = vcat(m.cl, collect(cl))
m.cu = vcat(m.cu, collect(cu))
end
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment