CoreModelCoupled.jl 9.81 KB
Newer Older
1
"""
2
3
4
5
6
7
8
9
10
11
12
13
    add_reactions(
        m::CoreModelCoupled,
        s::V1,
        b::V2,
        c::AbstractFloat,
        xl::AbstractFloat,
        xu::AbstractFloat;
        check_consistency = false,
    ) where {V1<:VecType,V2<:VecType}

Add reaction(s) to a `CoreModelCoupled` model `m`.

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
"""
function add_reactions(
    m::CoreModelCoupled,
    s::V1,
    b::V2,
    c::AbstractFloat,
    xl::AbstractFloat,
    xu::AbstractFloat;
    check_consistency = false,
) where {V1<:VecType,V2<:VecType}
    new_lm = add_reactions(
                m.lm,
                s,
                b,
                c,
                xl,
                xu,
                check_consistency = check_consistency,
            )
    return CoreModelCoupled(
        new_lm,
        hcat(m.C, spzeros(size(m.C, 1), n_reactions(new_lm)-n_reactions(m.lm))),
        m.cl,
        m.cu
    )
end

41
42
43
44
45
46
47
48
49
50
51
52
53
54
"""
    add_reactions(
        m::CoreModelCoupled,
        s::V1,
        b::V2,
        c::AbstractFloat,
        xl::AbstractFloat,
        xu::AbstractFloat,
        rxn::String,
        mets::K;
        check_consistency = false,
    ) where {V1<:VecType,V2<:VecType,K<:StringVecType}

"""
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
function add_reactions(
    m::CoreModelCoupled,
    s::V1,
    b::V2,
    c::AbstractFloat,
    xl::AbstractFloat,
    xu::AbstractFloat,
    rxn::String,
    mets::K;
    check_consistency = false,
) where {V1<:VecType,V2<:VecType,K<:StringVecType}
    new_lm = add_reactions(
                m.lm,
                s,
                b,
                c,
                xl,
                xu,
                rxn,
                mets,
                check_consistency = check_consistency
            )
    return CoreModelCoupled(
        new_lm,
        hcat(m.C, spzeros(size(m.C, 1), n_reactions(new_lm)-n_reactions(m.lm))),
        m.cl,
        m.cu
    )
end

85
86
87
88
89
90
91
92
93
94
95
96
"""
    add_reactions(
        m::CoreModelCoupled,
        Sp::M,
        b::V,
        c::V,
        xl::V,
        xu::V;
        check_consistency = false,
    ) where {M<:MatType,V<:VecType}

"""
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
function add_reactions(
    m::CoreModelCoupled,
    Sp::M,
    b::V,
    c::V,
    xl::V,
    xu::V;
    check_consistency = false,
) where {M<:MatType,V<:VecType}
    new_lm = add_reactions(
                m.lm,
                Sp,
                b,
                c,
                xl,
                xu,
                check_consistency = check_consistency,
            )
    return CoreModelCoupled(
        new_lm,
        hcat(m.C, spzeros(size(m.C, 1), n_reactions(new_lm)-n_reactions(m.lm))),
        m.cl,
        m.cu
    )
end

123
124
125
126
127
128
"""
    add_reactions(m1::CoreModelCoupled, m2::CoreModel; check_consistency = false)

Add all reactions from `m2` to `m1`.

"""
129
130
131
132
133
134
135
136
137
138
139
140
141
142
function add_reactions(m1::CoreModelCoupled, m2::CoreModel; check_consistency = false)
    new_lm = add_reactions(
                m1.lm,
                m2,
                check_consistency=check_consistency
            )
    return CoreModelCoupled(
        new_lm,
        hcat(m1.C, spzeros(size(m1.C, 1), n_reactions(new_lm)-n_reactions(m1.lm))),
        m1.cl,
        m1.cu
    )
end

143
144
145
146
147
148
149
150
151
152
153
154
155
156
"""
    add_reactions(
        m::CoreModelCoupled,
        Sp::M,
        b::V,
        c::V,
        xl::V,
        xu::V,
        rxns::K,
        mets::K;
        check_consistency = false,
    ) where {M<:MatType,V<:VecType,K<:StringVecType}

"""
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
function add_reactions(
    m::CoreModelCoupled,
    Sp::M,
    b::V,
    c::V,
    xl::V,
    xu::V,
    rxns::K,
    mets::K;
    check_consistency = false,
) where {M<:MatType,V<:VecType,K<:StringVecType}
    new_lm = add_reactions(
            m.lm,
            Sp,
            b,
            c,
            xl,
            xu,
            rxns,
            mets,
            check_consistency = check_consistency
        )
    return CoreModelCoupled(
        new_lm,
        hcat(m.C, spzeros(size(m.C, 1), n_reactions(new_lm)-n_reactions(m.lm))),
        m.cl,
        m.cu
    )
end

187
"""
188
189
190
191
192
    remove_reactions(m::CoreModelCoupled, rxns::Vector{Int})

Remove reaction(s) from a `CoreModelCoupled`.

Also removes any metabolites not involved in any reaction after the deletion.
193
194
195
196
197
198
199
200
201
202
203

"""
function remove_reactions(m::CoreModelCoupled, rxns::Vector{Int})
    return CoreModelCoupled(
                remove_reactions(m.lm, rxns),
                m.C[:, filter(e -> e  rxns, 1:n_reactions(m))],
                m.cl,
                m.cu
            )
end

204
205
206
207
"""
    remove_reactions(m::CoreModelCoupled, rxn::Integer)

"""
208
209
210
211
function remove_reactions(m::CoreModelCoupled, rxn::Integer)
    return remove_reactions(m, [rxn])
end

212
213
214
215
"""
    remove_reactions(m::CoreModelCoupled, rxn::String)

"""
216
217
218
219
function remove_reactions(m::CoreModelCoupled, rxn::String)
    return remove_reactions(m, [rxn])
end

220
221
222
223
"""
    remove_reactions(m::CoreModelCoupled, rxns::Vector{String})

"""
224
225
226
227
228
229
230
231
function remove_reactions(m::CoreModelCoupled, rxns::Vector{String})
    rxn_indices = [findfirst(isequal(name), m.lm.rxns) for name in intersect(rxns, m.lm.rxns)]
    if isempty(rxn_indices)
        return m
    else
        return remove_reactions(m, rxn_indices)
    end
end
232

Sylvain Arreckx's avatar
Sylvain Arreckx committed
233
"""
234
Add constraints of the following form to a CoreModelCoupled and return a modified one.
Sylvain Arreckx's avatar
Sylvain Arreckx committed
235

236
237
238
Add constraints to a [`CoreModelCoupled`](@ref) and return a modified one.

The arguments are same as for in-place [`add_coupling_constraints!`](@ref).
239
"""
240
function add_coupling_constraints(m::CoreModelCoupled, args...)
241
242
243
    new_lp = deepcopy(m)
    add_coupling_constraints!(new_lp, args...)
    return new_lp
Sylvain Arreckx's avatar
Sylvain Arreckx committed
244
245
end

246
"""
247
248
249
250
    add_coupling_constraints(m::CoreModel, args...)

Add coupling constraints to a plain [`CoreModel`](@ref) (returns a
[`CoreModelCoupled`](@ref)).
251
"""
252
add_coupling_constraints(m::CoreModel, args...) =
253
    add_coupling_constraints(convert(CoreModelCoupled, m), args...)
254

255
"""
256
257
258
259
260
261
262
263
    add_coupling_constraints!(
        m::CoreModelCoupled,
        c::VecType,
        cl::AbstractFloat,
        cu::AbstractFloat,
    )

Overload for adding a single coupling constraint.
264
"""
265
function add_coupling_constraints!(
266
    m::CoreModelCoupled,
267
    c::VecType,
268
269
    cl::AbstractFloat,
    cu::AbstractFloat,
270
)
271
    return add_coupling_constraints!(
272
273
274
275
276
        m,
        sparse(reshape(c, (1, length(c)))),
        sparse([cl]),
        sparse([cu]),
    )
Sylvain Arreckx's avatar
Sylvain Arreckx committed
277
278
279
end


280
281
282
283
284
285
286
287
288
289
290
291
292
"""
    add_coupling_constraints!(
        m::CoreModelCoupled,
        C::MatType,
        cl::V,
        cu::V,
    ) where {V<:VecType}

In-place add a single coupling constraint in form
```
    cₗ ≤ C x ≤ cᵤ
```
"""
293
function add_coupling_constraints!(
294
    m::CoreModelCoupled,
295
    C::MatType,
296
297
    cl::V,
    cu::V,
298
) where {V<:VecType}
Sylvain Arreckx's avatar
Sylvain Arreckx committed
299

300
301
    all([length(cu), length(cl)] .== size(C, 1)) ||
        throw(DimensionMismatch("mismatched numbers of constraints"))
302
    size(C, 2) == n_reactions(m) ||
303
        throw(DimensionMismatch("mismatched number of reactions"))
Sylvain Arreckx's avatar
Sylvain Arreckx committed
304

305
306
307
    m.C = vcat(m.C, sparse(C))
    m.cl = vcat(m.cl, sparse(cl))
    m.cu = vcat(m.cu, sparse(cu))
Sylvain Arreckx's avatar
Sylvain Arreckx committed
308
309
310
311
end


"""
312
    remove_coupling_constraints(m::CoreModelCoupled, args...)
Sylvain Arreckx's avatar
Sylvain Arreckx committed
313

314
315
316
Remove coupling constraints from the linear model, and return the modified
model. Arguments are the same as for in-place version
[`remove_coupling_constraints!`](@ref).
317
"""
318
function remove_coupling_constraints(m::CoreModelCoupled, args...)
319
320
321
    new_model = deepcopy(m)
    remove_coupling_constraints!(new_model, args...)
    return new_model
Sylvain Arreckx's avatar
Sylvain Arreckx committed
322
323
324
end


325
"""
326
327
328
329
    remove_coupling_constraints!(m::CoreModelCoupled, constraint::Int)

Removes a single coupling constraints from a [`CoreModelCoupled`](@ref)
in-place.
330
"""
331
remove_coupling_constraints!(m::CoreModelCoupled, constraint::Int) =
332
    remove_coupling_constraints!(m, [constraint])
Sylvain Arreckx's avatar
Sylvain Arreckx committed
333
334


335
336
337
338
339
340
"""
    remove_coupling_constraints!(m::CoreModelCoupled, constraints::Vector{Int})

Removes a set of coupling constraints from a [`CoreModelCoupled`](@ref)
in-place.
"""
341
function remove_coupling_constraints!(m::CoreModelCoupled, constraints::Vector{Int})
342
343
344
345
    to_be_kept = filter(e -> e  constraints, 1:n_coupling_constraints(m))
    m.C = m.C[to_be_kept, :]
    m.cl = m.cl[to_be_kept]
    m.cu = m.cu[to_be_kept]
Sylvain Arreckx's avatar
Sylvain Arreckx committed
346
347
348
349
end


"""
350
351
352
353
354
355
356
357
358
    change_coupling_bounds!(
        model::CoreModelCoupled,
        constraints::Vector{Int};
        cl::V = Float64[],
        cu::V = Float64[],
    ) where {V<:VecType}

Change the lower and/or upper bounds (`cl` and `cu`) for the given list of
coupling constraints.
Sylvain Arreckx's avatar
Sylvain Arreckx committed
359
"""
360
function change_coupling_bounds!(
361
    model::CoreModelCoupled,
362
    constraints::Vector{Int};
Miroslav Kratochvil's avatar
Miroslav Kratochvil committed
363
364
    cl::V = Float64[],
    cu::V = Float64[],
365
) where {V<:VecType}
366
367
    found = [index  1:n_coupling_constraints(model) for index in constraints]
    red_constraints = constraints[found]
Sylvain Arreckx's avatar
Sylvain Arreckx committed
368

369
    length(red_constraints) == length(unique(red_constraints)) ||
370
        error("`constraints` appears to contain duplicates")
Sylvain Arreckx's avatar
Sylvain Arreckx committed
371
    if !isempty(cl)
372
373
        length(constraints) == length(cl) ||
            throw(DimensionMismatch("`constraints` size doesn't match with `cl`"))
374
        model.cl[red_constraints] = cl[found]
Sylvain Arreckx's avatar
Sylvain Arreckx committed
375
376
377
    end

    if !isempty(cu)
378
379
        length(constraints) == length(cu) ||
            throw(DimensionMismatch("`constraints` size doesn't match with `cu`"))
380
        model.cu[red_constraints] = cu[found]
Sylvain Arreckx's avatar
Sylvain Arreckx committed
381
382
    end
end
383

384
"""
385
386
387
388
389
390
391
392
393
    change_bounds!(
        model::CoreModelCoupled,
        rxns::Vector{Int};
        xl::V = Float64[],
        xu::V = Float64[],
    )

Change the lower and/or upper bounds ('xl' and 'xu') for given reactions.

394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
"""
function change_bounds!(
    model::CoreModelCoupled,
    rxns::Vector{Int};
    xl::V = Float64[],
    xu::V = Float64[],
) where {V<:VecType}
    change_bounds!(
        model.lm,
        rxns,
        xl = xl,
        xu = xu
    )
end

409
410
411
412
413
414
415
416
417
"""
    change_bounds!(
        model::CoreModelCoupled,
        rxns::Vector{String};
        xl::V = Float64[],
        xu::V = Float64[],
    ) where {V<:VecType}

"""
418
419
420
421
422
423
424
425
426
427
428
429
430
function change_bounds!(
    model::CoreModelCoupled,
    rxns::Vector{String};
    xl::V = Float64[],
    xu::V = Float64[],
) where {V<:VecType}
    change_bounds!(
        model.lm,
        rxns,
        xl = xl,
        xu = xu
    )
end