solver.jl 2.72 KB
Newer Older
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
1

Sylvain Arreckx's avatar
Sylvain Arreckx committed
2
"""
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
3
4
5
6
7
    make_optimization_model(
        model::MetabolicModel,
        optimizer;
        sense = MOI.MAX_SENSE,
    )
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
8

St. Elmo's avatar
St. Elmo committed
9
Convert `MetabolicModel`s to a JuMP model, place objectives and the equality
10
constraint.
Sylvain Arreckx's avatar
Sylvain Arreckx committed
11
"""
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
12
function make_optimization_model(model::MetabolicModel, optimizer; sense = MOI.MAX_SENSE)
13
14
15

    precache!(model)

16
17
    m, n = size(stoichiometry(model))
    xl, xu = bounds(model)
Sylvain Arreckx's avatar
Sylvain Arreckx committed
18

19
    optimization_model = Model(optimizer; bridge_constraints = false)
20
    @variable(optimization_model, x[i = 1:n])
21
    @objective(optimization_model, sense, objective(model)' * x)
St. Elmo's avatar
St. Elmo committed
22
23
24
    @constraint(optimization_model, mb, stoichiometry(model) * x .== balance(model)) # mass balance
    @constraint(optimization_model, lbs, xl .<= x) # lower bounds
    @constraint(optimization_model, ubs, x .<= xu) # upper bounds
Sylvain Arreckx's avatar
Sylvain Arreckx committed
25

St. Elmo's avatar
St. Elmo committed
26
    C = coupling(model) # empty if no coupling
St. Elmo's avatar
St. Elmo committed
27
    cl, cu = coupling_bounds(model)
cylon-x's avatar
cylon-x committed
28
29
    isempty(C) || @constraint(optimization_model, c_lbs, cl .<= coupling(model) * x) # coupling lower bounds
    isempty(C) || @constraint(optimization_model, c_ubs, coupling(model) * x .<= cu) # coupling upper bounds
cylon-x's avatar
cylon-x committed
30

St. Elmo's avatar
St. Elmo committed
31
32
    return optimization_model
end
St. Elmo's avatar
St. Elmo committed
33
34
35
36

"""
    is_solved(optmodel)

37
38
39
Return `true` if `optmodel` solved successfully (solution is optimal or locally
optimal).  Return `false` if any other termination status is reached.
Termination status is defined in the documentation of `JuMP`.
St. Elmo's avatar
St. Elmo committed
40
"""
St. Elmo's avatar
St. Elmo committed
41
function is_solved(optmodel)
42
    termination_status(optmodel) in [MOI.OPTIMAL, MOI.LOCALLY_SOLVED] ? true : false
St. Elmo's avatar
St. Elmo committed
43
44
end

45
46
47
48
49
50
"""
    optimize_objective(optmodel)::Union{Float64,Nothing}

Shortcut for running JuMP `optimize!` on a model and returning the objective
value, if solved.
"""
51
function optimize_objective(optmodel)::Maybe{Float64}
52
53
54
55
56
57
58
59
    optimize!(optmodel)
    if is_solved(optmodel)
        objective_value(optmodel)
    else
        nothing
    end
end

St. Elmo's avatar
St. Elmo committed
60
"""
61
    get_optmodel_bounds(opt_model)
St. Elmo's avatar
St. Elmo committed
62
63
64
65
66

Returns vectors of the lower and upper bounds of `opt_model` constraints, where
`opt_model` is a JuMP model constructed by e.g.
[`make_optimization_model`](@ref) or [`flux_balance_analysis`](@ref).
"""
67
get_optmodel_bounds(opt_model) = (
68
69
70
    [-normalized_rhs(lb) for lb in opt_model[:lbs]],
    [normalized_rhs(ub) for ub in opt_model[:ubs]],
)
St. Elmo's avatar
St. Elmo committed
71
72

"""
73
74
75
76
    set_optmodel_bound!(vidx, opt_model;
        ub::Maybe{Real} = nothing,
        lb::Maybe{Real} = nothing,
    )
St. Elmo's avatar
St. Elmo committed
77

78
79
80
Helper function to set the bounds of a variable in the model. Internally calls
`set_normalized_rhs` from JuMP. If the bounds are set to `nothing`, they will
not be changed.
St. Elmo's avatar
St. Elmo committed
81
"""
82
function set_optmodel_bound!(
83
    vidx,
St. Elmo's avatar
St. Elmo committed
84
    opt_model;
85
86
    lb::Maybe{Real} = nothing,
    ub::Maybe{Real} = nothing,
St. Elmo's avatar
St. Elmo committed
87
)
88
89
    isnothing(lb) || set_normalized_rhs(opt_model[:lbs][vidx], -lb)
    isnothing(ub) || set_normalized_rhs(opt_model[:ubs][vidx], ub)
St. Elmo's avatar
St. Elmo committed
90
end