Skip to content

Commit f15a9c1

Browse files
geoffroylecontedpo
authored andcommitted
update tests, add doc
1 parent 061fe55 commit f15a9c1

File tree

2 files changed

+24
-6
lines changed

2 files changed

+24
-6
lines changed

src/presolve/presolve.jl

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,33 @@ mutable struct PresolvedQuadraticModel{T, S, M1, M2} <: AbstractQuadraticModel{T
88
end
99

1010
"""
11-
psqm = presolve(qm::QuadraticModel{T, S}; kwargs...)
11+
stats_ps = presolve(qm::QuadraticModel{T, S}; kwargs...)
1212
13-
Apply a presolve routine to `qm` and returns a `PresolvedQuadraticModel{T, S} <: AbstractQuadraticModel{T, S}`.
13+
Apply a presolve routine to `qm` and returns a
14+
[`GenericExecutionStats`](https://juliasmoothoptimizers.github.io/SolverCore.jl/stable/reference/#SolverCore.GenericExecutionStats)
15+
from the package [`SolverCore.jl`](https://github.com/JuliaSmoothOptimizers/SolverCore.jl).
1416
The presolve operations currently implemented are:
1517
16-
- [`remove_ifix!`](@ref)
18+
- [`remove_ifix!`](@ref) : remove fixed variables
1719
20+
The `PresolvedQuadraticModel{T, S} <: AbstractQuadraticModel{T, S}` is located in the `solver_specific` field:
21+
22+
psqm = stats_ps.solver_specific[:presolvedQM]
23+
24+
and should be used to call [`postsolve!`](@ref).
25+
26+
If the presolved problem has 0 variables, `stats_ps` contains a solution such that `stats_ps.solution` minimizes the primal problem,
27+
`stats_ps.multipliers` is a `SparseVector` full of zeros, and, with
28+
29+
s = qm.data.c + qm.data.H * stats_ps.solution
30+
31+
`stats_ps.multipliers_L` is the positive part of `s` and `stats_ps.multipliers_U` is the opposite of the negative part of `s`.
1832
"""
1933
function presolve(
2034
qm::QuadraticModel{T, S, M1, M2};
2135
kwargs...,
2236
) where {T <: Real, S, M1 <: SparseMatrixCOO, M2 <: SparseMatrixCOO}
2337
start_time = time()
24-
elapsed_time = 0.0
2538
psqm = deepcopy(qm)
2639
psdata = psqm.data
2740
lvar, uvar = psqm.meta.lvar, psqm.meta.uvar
@@ -63,14 +76,14 @@ function presolve(
6376

6477
if nvarps == 0
6578
feasible = all(qm.meta.lcon .<= qm.data.A * xrm .<= qm.meta.ucon)
66-
s = qm.data.c .+ qm.data.Q * xrm
79+
s = qm.data.c .+ Symmetric(qm.data.H, :L) * xrm
6780
i_l = findall(s .> zero(T))
6881
s_l = sparsevec(i_l, s[i_l])
6982
i_u = findall(s .< zero(T))
7083
s_u = sparsevec(i_u, .-s[i_u])
7184
return GenericExecutionStats(
7285
feasible ? :acceptable : :infeasible,
73-
ps,
86+
qm,
7487
solution = xrm,
7588
objective = obj(qm, xrm),
7689
multipliers = zeros(T, qm.meta.nvar),

test/test_presolve.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,9 @@
5656
x_out = zeros(3)
5757
postsolve!(qp, psqp, x_in, x_out)
5858
@test x_out == [4.0; 2.0; 7.0]
59+
60+
# test that solves the problem
61+
qp2 = QuadraticModel(zeros(2), SparseMatrixCOO(zeros(2,2)), A = SparseMatrixCOO(zeros(0, 2)), lvar = zeros(2), uvar = zeros(2))
62+
stats_ps2 = presolve(qp2)
63+
@test stats_ps2.status == :acceptable
5964
end

0 commit comments

Comments
 (0)