Skip to content

Commit 39d0026

Browse files
geoffroylecontedpo
authored andcommitted
add errors
1 parent 8c5b752 commit 39d0026

File tree

2 files changed

+53
-77
lines changed

2 files changed

+53
-77
lines changed

src/qpmodel.jl

Lines changed: 21 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -21,41 +21,22 @@ function convertQPData_toCOO(data::QPData{T, S, M1, M2}) where {T, S, M1 <: Abst
2121
return QPData(data.c0, data.c, HCOO, ACOO)
2222
end
2323

24-
function get_QPDataCOO(c0::T, c::S, H::SparseMatrixCSC{T}, A::AbstractMatrix{T}) where {T, S}
25-
ncon, nvar = size(A)
26-
tril!(H)
27-
nnzh, Hrows, Hcols, Hvals = nnz(H), findnz(H)...
28-
nnzj, Arows, Acols, Avals = if ncon == 0
29-
0, Int[], Int[], S(undef, 0)
30-
elseif issparse(A)
31-
nnz(A), findnz(A)...
32-
else
33-
I = ((i, j, A[i, j]) for i = 1:ncon, j = 1:nvar)
34-
nvar * ncon, getindex.(I, 1)[:], getindex.(I, 2)[:], getindex.(I, 3)[:]
35-
end
36-
data = QPData(
37-
c0,
38-
c,
39-
SparseMatrixCOO(nvar, nvar, Hrows, Hcols, Hvals),
40-
SparseMatrixCOO(ncon, nvar, Arows, Acols, Avals),
41-
)
42-
return data, nnzh, nnzj
43-
end
44-
45-
get_QPDataCOO(c0::T, c::S, H, A::AbstractMatrix{T}) where {T, S} =
46-
get_QPDataCOO(c0, c, sparse(H), A)
47-
4824
abstract type AbstractQuadraticModel{T, S} <: AbstractNLPModel{T, S} end
4925

5026
"""
5127
qp = QuadraticModel(c, Hrows, Hcols, Hvals; Arows = Arows, Acols = Acols, Avals = Avals,
52-
lcon = lcon, ucon = ucon, lvar = lvar, uvar = uvar)
28+
lcon = lcon, ucon = ucon, lvar = lvar, uvar = uvar, sortcols = false)
5329
54-
qp = QuadraticModel(c, H; A = A, lcon = lcon, ucon = ucon, lvar = lvar, uvar = uvar)
30+
qp = QuadraticModel(c, H; A = A, lcon = lcon, ucon = ucon, lvar = lvar, uvar = uvar, coo_matrices = true)
5531
5632
Create a Quadratic model ``min ~\\tfrac{1}{2} x^T Q x + c^T x + c_0`` with optional bounds
5733
`lvar ≦ x ≦ uvar` and optional linear constraints `lcon ≦ Ax ≦ ucon`.
5834
35+
With the first constructor, if `sortcols = true`, then `Hcols` and `Acols` are sorted in ascending order
36+
(`Hrows`, `Hvals` and `Arows`, `Avals` are then sorted accordingly).
37+
With the second constructor, if `coo_matrices = true`, `H` and/or `A` will be converted to SparseMatricesCOO
38+
(this will be ignored if they already are SparseMatricesCOO).
39+
5940
You can also use [`QPSReader.jl`](https://github.com/JuliaSmoothOptimizers/QPSReader.jl) to
6041
create a Quadratic model from a QPS file:
6142
@@ -285,20 +266,10 @@ function NLPModels.hess_structure!(
285266
rows::AbstractVector{<:Integer},
286267
cols::AbstractVector{<:Integer},
287268
)
288-
if typeof(qp.data.H) <: SparseMatrixCOO
289-
rows .= qp.data.H.rows
290-
cols .= qp.data.H.cols
291-
else
292-
nvar = qp.meta.nvar
293-
idx = 1
294-
for j = 1:nvar
295-
for i = j:nvar
296-
rows[idx] = i
297-
cols[idx] = j
298-
idx += 1
299-
end
300-
end
301-
end
269+
typeof(qp.data.H) <: SparseMatrixCOO ||
270+
error("hess_structure! should be used only if H is a SparseMatrixCOO")
271+
rows .= qp.data.H.rows
272+
cols .= qp.data.H.cols
302273
return rows, cols
303274
end
304275

@@ -308,19 +279,10 @@ function NLPModels.hess_coord!(
308279
vals::AbstractVector{T};
309280
obj_weight::Real = one(eltype(x)),
310281
) where {T}
282+
typeof(qp.data.H) <: SparseMatrixCOO ||
283+
error("hess_coord! should be used only if H is a SparseMatrixCOO")
311284
NLPModels.increment!(qp, :neval_hess)
312-
if typeof(qp.data.H) <: SparseMatrixCOO
313-
vals .= obj_weight * qp.data.H.vals
314-
else
315-
nvar = qp.meta.nvar
316-
idx = 1
317-
for j = 1:nvar
318-
for i = j:nvar
319-
vals[idx] = (i j) ? obj_weight * qp.data.H[i, j] : zero(T)
320-
idx += 1
321-
end
322-
end
323-
end
285+
vals .= obj_weight * qp.data.H.vals
324286
return vals
325287
end
326288

@@ -337,28 +299,18 @@ function NLPModels.jac_structure!(
337299
rows::AbstractVector{<:Integer},
338300
cols::AbstractVector{<:Integer},
339301
)
340-
if typeof(qp.data.A) <: SparseMatrixCOO
341-
rows .= qp.data.A.rows
342-
cols .= qp.data.A.cols
343-
else
344-
nvar, ncon = qp.meta.nvar, qp.meta.ncon
345-
for j = 1:nvar
346-
for i = 1:ncon
347-
rows[i + (j - 1) * ncon] = i
348-
cols[i + (j - 1) * ncon] = j
349-
end
350-
end
351-
end
302+
typeof(qp.data.A) <: SparseMatrixCOO ||
303+
error("jac_structure! should be used only if A is a SparseMatrixCOO")
304+
rows .= qp.data.A.rows
305+
cols .= qp.data.A.cols
352306
return rows, cols
353307
end
354308

355309
function NLPModels.jac_coord!(qp::QuadraticModel, x::AbstractVector, vals::AbstractVector)
310+
typeof(qp.data.A) <: SparseMatrixCOO ||
311+
error("jac_coord! should be used only if A is a SparseMatrixCOO")
356312
NLPModels.increment!(qp, :neval_jac)
357-
if typeof(qp.data.A) <: SparseMatrixCOO
358-
vals .= qp.data.A.vals
359-
else
360-
vals .= @views qp.data.A[:]
361-
end
313+
vals .= qp.data.A.vals
362314
return vals
363315
end
364316

test/runtests.jl

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -79,18 +79,42 @@ end
7979

8080
SlackModel!(qp)
8181
testSM(qp)
82+
end
83+
84+
@testset "dense QP" begin
85+
H = [
86+
6.0 2.0 1.0
87+
2.0 5.0 2.0
88+
1.0 2.0 4.0
89+
]
90+
c = [-8.0; -3; -3]
91+
A = [
92+
1.0 0.0 1.0
93+
0.0 2.0 1.0
94+
]
95+
b = [0.0; 3]
96+
l = [0.0; 0; 0]
97+
u = [Inf; Inf; Inf]
98+
T = eltype(c)
8299

83100
qpdense = QuadraticModel(
84101
c,
85-
H,
102+
tril(H),
86103
A = A,
87104
lcon = [-3.0; -4.0],
88105
ucon = [-2.0; Inf],
89106
lvar = l,
90107
uvar = u,
91108
c0 = 0.0,
92109
name = "QM1",
110+
coo_matrices = false,
93111
)
112+
113+
@test_throws Exception hess_structure(qpdense)
114+
@test_throws Exception hess_coord(qpdense)
115+
@test_throws Exception jac_structure(qpdense)
116+
@test_throws Exception jac_coord(qpdense)
117+
94118
smdense = SlackModel(qpdense)
95119
testSM(smdense)
96120
end
@@ -158,9 +182,9 @@ end
158182
name = "QMLO",
159183
)
160184
x = ones(10)
161-
@test obj(qp, x) == obj(qpLO, x)
162-
@test grad(qp, x) == grad(qpLO, x)
163-
@test cons(qp, x) == cons(qpLO, x)
185+
@test obj(qp, x) obj(qpLO, x)
186+
@test grad(qp, x) grad(qpLO, x)
187+
@test cons(qp, x) cons(qpLO, x)
164188

165189
SM = SlackModel(qp)
166190
SMLO = SlackModel(qpLO)
@@ -169,11 +193,11 @@ end
169193
x = rand(SM.meta.nvar)
170194
y = rand(SM.meta.ncon)
171195
@test SM.meta.nvar == qp.meta.nvar + ns
172-
@test obj(SM, x) == obj(SMLO, x)
196+
@test obj(SM, x) obj(SMLO, x)
173197
@test grad(SM, x) grad(SMLO, x)
174-
@test cons(SM, x) == cons(SMLO, x)
175-
@test hprod(SMLO, x, x) == hprod(SMLO, x, x)
176-
@test jtprod(SMLO, x, y) == jtprod(SM, x, y)
198+
@test cons(SM, x) cons(SMLO, x)
199+
@test hprod(SMLO, x, x) hprod(SMLO, x, x)
200+
@test jtprod(SMLO, x, y) jtprod(SM, x, y)
177201
@test objgrad(SMLO, x)[1] objgrad(SM, x)[1]
178202
@test objgrad(SMLO, x)[2] objgrad(SM, x)[2]
179203
end

0 commit comments

Comments
 (0)