Skip to content

Commit 7c79d30

Browse files
committed
add VI API
1 parent 6fae135 commit 7c79d30

File tree

4 files changed

+160
-56
lines changed

4 files changed

+160
-56
lines changed

Project.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ authors = ["Tangi Migot [email protected]"]
44
version = "0.1.0"
55

66
[deps]
7+
CaNNOLeS = "5a1c9e79-9c58-5ec0-afc4-3298fdea2875"
78
FastClosures = "9aa1b823-49e4-5ca5-8b0f-3971ec8bab6a"
89
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
910
NLPModels = "a4795742-8479-5a88-8948-cc11e1c8c1a6"

src/VariationalInequalitySolver.jl

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,42 +2,55 @@ module VariationalInequalitySolver
22

33
using FastClosures, LinearAlgebra, NLPModels
44

5-
abstract type AbstractVIModel{S, T} end
5+
abstract type AbstractVIModel{T, S} end
66

7-
abstract type AbstractVIMeta{S, T} end
7+
abstract type AbstractVIMeta{T, S} end
88

9-
mutable struct VIMeta{S, T} <: AbstractVIMeta{S, T}
9+
mutable struct VIMeta{T, S} <: AbstractVIMeta{T, S}
1010
x0::S
1111
nvar
1212
nnzj
1313
nnzh
1414
end
1515

1616
#largely inspired from https://github.com/JuliaSmoothOptimizers/NLPModels.jl/blob/main/src/nls/api.jl
17-
include("api.jl")
17+
include("projector/proj_nls.jl")
18+
include("model/api.jl")
1819

19-
#=
20-
mutable struct VIModel{S, T} <: AbstractVIModel{S, T}
21-
meta::AbstractVIMeta{S, T}
22-
F::Function # in-place function
23-
JF # in-place Jacobian-function
24-
ProjX::Function # in-place function
25-
end
20+
export NLSVIModel
2621

27-
function residual!(Fx::AbstractVector{T}, model::VIModel, x::AbstractVector{T}) where {T}
28-
@lencheck model.n x Fx
29-
VIModel.F(Fx, x)
30-
return Fx
22+
mutable struct NLSVIModel{S, T, NLP <: AbstractNLSModel{T, S}} <: AbstractVIModel{T, S}
23+
meta::VIMeta{T, S}
24+
nls::NLP
25+
function NLSVIModel(nls::AbstractNLSModel{T, S}) where {T, S}
26+
@lencheck nls.nls_meta.nequ nls.meta.x0 #test that nls.meta.nvar == nls.nls_meta.nequ
27+
return new{S, T, typeof(nls)}(
28+
VIMeta{T, S}(nls.meta.x0, nls.meta.nvar, nls.nls_meta.nnzj, nls.nls_meta.nnzh),
29+
nls
30+
)
31+
end
3132
end
3233

33-
function project!(Px::AbstractVector{T}, model::AbstractVIModel, d::AbstractVector{T}) where {T}
34-
return Px
34+
for meth in [:residual!, :jac_structure_residual!, :jac_coord_residual!, :jprod_residual!, :jtprod_residual!, :jac_op_residual!, :hess_structure_residual!, :hess_coord_residual!, :hprod_residual!, :hess_op_residual!]
35+
@eval begin
36+
$meth(model::NLSVIModel, args...; kwargs...) = $meth(model.nls, args...; kwargs...)
37+
end
3538
end
3639

37-
mutable struct NLSVIModel{T <: AbstractNLSModel} <: AbstractVIModel
38-
nls::NLP
40+
using CaNNOLeS
41+
42+
function project!(model::NLSVIModel, d::AbstractVector{T}, Px::AbstractVector{T}) where {T, S}
43+
# Here we need to solve the optimization problem
44+
proj = NLSProjector(model.nls, d)
45+
stats = cannoles(proj)
46+
if stats.status != :first_order
47+
@warn "There was an error in the projection computation"
48+
end
49+
Px .= stats.solution
50+
return Px
3951
end
4052

53+
#=
4154
include("projector/ProjNLP.jl")
4255
include("solvers/penalizedVI.jl")
4356
=#

src/api.jl renamed to src/model/api.jl

Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ export project!, project
1111
Computes ``F(x)``, the residual at x.
1212
"""
1313
function residual(model::AbstractVIModel{T, S}, x::AbstractVector{T}) where {T, S}
14-
@lencheck model.nvar x
15-
Fx = S(undef, model.nvar)
14+
@lencheck model.meta.nvar x
15+
Fx = S(undef, model.meta.nvar)
1616
residual!(model, x, Fx)
1717
end
1818

@@ -27,10 +27,10 @@ function residual! end
2727
Computes ``J(x)``, the Jacobian of the residual at x.
2828
"""
2929
function jac_residual(model::AbstractVIModel, x::AbstractVector)
30-
@lencheck model.nvar x
30+
@lencheck model.meta.nvar x
3131
rows, cols = jac_structure_residual(model)
3232
vals = jac_coord_residual(model, x)
33-
sparse(rows, cols, vals, model.nvar, model.nvar)
33+
sparse(rows, cols, vals, model.meta.nvar, model.meta.nvar)
3434
end
3535

3636
"""
@@ -61,7 +61,7 @@ function jac_coord_residual! end
6161
Computes the Jacobian of the residual at `x` in sparse coordinate format.
6262
"""
6363
function jac_coord_residual(model::AbstractVIModel, x::AbstractVector)
64-
@lencheck model.nvar x
64+
@lencheck model.meta.nvar x
6565
vals = Vector{eltype(x)}(undef, model.nnzj)
6666
jac_coord_residual!(model, x, vals)
6767
end
@@ -75,8 +75,8 @@ function jprod_residual(
7575
x::AbstractVector{T},
7676
v::AbstractVector,
7777
) where {T, S}
78-
@lencheck model.nvar x v
79-
Jv = S(undef, model.nvar)
78+
@lencheck model.meta.nvar x v
79+
Jv = S(undef, model.meta.nvar)
8080
jprod_residual!(model, x, v, Jv)
8181
end
8282

@@ -100,7 +100,7 @@ function jprod_residual!(
100100
Jv::AbstractVector,
101101
)
102102
@lencheck model.nnzj rows cols vals
103-
@lencheck model.nvar v Jv
103+
@lencheck model.meta.nvar v Jv
104104
increment!(model, :neval_jprod_residual)
105105
coo_prod!(rows, cols, vals, v, Jv)
106106
end
@@ -118,7 +118,7 @@ function jprod_residual!(
118118
v::AbstractVector,
119119
Jv::AbstractVector,
120120
)
121-
@lencheck model.nvar x v Jv
121+
@lencheck model.meta.nvar x v Jv
122122
@lencheck model.nnzj rows cols
123123
jprod_residual!(model, x, v, Jv)
124124
end
@@ -132,8 +132,8 @@ function jtprod_residual(
132132
x::AbstractVector{T},
133133
v::AbstractVector,
134134
) where {T, S}
135-
@lencheck model.nvar x v
136-
Jtv = S(undef, model.nvar)
135+
@lencheck model.meta.nvar x v
136+
Jtv = S(undef, model.meta.nvar)
137137
jtprod_residual!(model, x, v, Jtv)
138138
end
139139

@@ -157,7 +157,7 @@ function jtprod_residual!(
157157
Jtv::AbstractVector,
158158
)
159159
@lencheck model.nnzj rows cols vals
160-
@lencheck model.nvar v Jtv
160+
@lencheck model.meta.nvar v Jtv
161161
increment!(model, :neval_jtprod_residual)
162162
coo_prod!(cols, rows, vals, v, Jtv)
163163
end
@@ -175,7 +175,7 @@ function jtprod_residual!(
175175
v::AbstractVector,
176176
Jtv::AbstractVector,
177177
)
178-
@lencheck model.nvar x v Jtv
178+
@lencheck model.meta.nvar x v Jtv
179179
@lencheck model.nnzj rows cols
180180
jtprod_residual!(model, x, v, Jtv)
181181
end
@@ -185,9 +185,9 @@ end
185185
Computes ``J(x)``, the Jacobian of the residual at x, in linear operator form.
186186
"""
187187
function jac_op_residual(model::AbstractVIModel{T, S}, x::AbstractVector{T}) where {T, S}
188-
@lencheck model.nvar x
189-
Jv = S(undef, model.nvar)
190-
Jtv = S(undef, model.nvar)
188+
@lencheck model.meta.nvar x
189+
Jv = S(undef, model.meta.nvar)
190+
Jtv = S(undef, model.meta.nvar)
191191
return jac_op_residual!(model, x, Jv, Jtv)
192192
end
193193

@@ -202,7 +202,7 @@ function jac_op_residual!(
202202
Jv::AbstractVector,
203203
Jtv::AbstractVector,
204204
)
205-
@lencheck model.nvar x Jv Jtv
205+
@lencheck model.meta.nvar x Jv Jtv
206206
prod! = @closure (res, v, α, β) -> begin
207207
jprod_residual!(model, x, v, Jv)
208208
if β == 0
@@ -222,8 +222,8 @@ function jac_op_residual!(
222222
return res
223223
end
224224
return LinearOperator{eltype(x)}(
225-
model.nvar,
226-
model.nvar,
225+
model.meta.nvar,
226+
model.meta.nvar,
227227
false,
228228
false,
229229
prod!,
@@ -246,7 +246,7 @@ function jac_op_residual!(
246246
Jtv::AbstractVector,
247247
)
248248
@lencheck model.nnzj rows cols vals
249-
@lencheck model.nvar Jv Jtv
249+
@lencheck model.meta.nvar Jv Jtv
250250
prod! = @closure (res, v, α, β) -> begin
251251
jprod_residual!(model, rows, cols, vals, v, Jv)
252252
if β == 0
@@ -266,8 +266,8 @@ function jac_op_residual!(
266266
return res
267267
end
268268
return LinearOperator{eltype(vals)}(
269-
model.nvar,
270-
model.nvar,
269+
model.meta.nvar,
270+
model.meta.nvar,
271271
false,
272272
false,
273273
prod!,
@@ -290,7 +290,7 @@ function jac_op_residual!(
290290
Jv::AbstractVector,
291291
Jtv::AbstractVector,
292292
)
293-
@lencheck model.nvar x Jv Jtv
293+
@lencheck model.meta.nvar x Jv Jtv
294294
@lencheck model.nnzj rows cols
295295
vals = jac_coord_residual(model, x)
296296
decrement!(model, :neval_jac_residual)
@@ -304,10 +304,10 @@ Computes the linear combination of the Hessians of the residuals at `x` with coe
304304
A `Symmetric` object wrapping the lower triangle is returned.
305305
"""
306306
function hess_residual(model::AbstractVIModel, x::AbstractVector, v::AbstractVector)
307-
@lencheck model.nvar x v
307+
@lencheck model.meta.nvar x v
308308
rows, cols = hess_structure_residual(model)
309309
vals = hess_coord_residual(model, x, v)
310-
Symmetric(sparse(rows, cols, vals, model.nvar, model.nvar), :L)
310+
Symmetric(sparse(rows, cols, vals, model.meta.nvar, model.meta.nvar), :L)
311311
end
312312

313313
"""
@@ -339,7 +339,7 @@ Computes the linear combination of the Hessians of the residuals at `x` with coe
339339
`v` in sparse coordinate format.
340340
"""
341341
function hess_coord_residual(model::AbstractVIModel, x::AbstractVector, v::AbstractVector)
342-
@lencheck model.nvar x v
342+
@lencheck model.meta.nvar x v
343343
vals = Vector{eltype(x)}(undef, model.nnzh)
344344
hess_coord_residual!(model, x, v, vals)
345345
end
@@ -349,10 +349,10 @@ end
349349
Computes the Hessian of the j-th residual at x.
350350
"""
351351
function jth_hess_residual(model::AbstractVIModel, x::AbstractVector, j::Int)
352-
@lencheck model.nvar x
352+
@lencheck model.meta.nvar x
353353
increment!(model, :neval_jhess_residual)
354354
decrement!(model, :neval_hess_residual)
355-
v = [i == j ? one(eltype(x)) : zero(eltype(x)) for i = 1:(model.nvar)]
355+
v = [i == j ? one(eltype(x)) : zero(eltype(x)) for i = 1:(model.meta.nvar)]
356356
return hess_residual(model, x, v)
357357
end
358358

@@ -366,8 +366,8 @@ function hprod_residual(
366366
i::Int,
367367
v::AbstractVector,
368368
) where {T, S}
369-
@lencheck model.nvar x
370-
Hv = S(undef, model.nvar)
369+
@lencheck model.meta.nvar x
370+
Hv = S(undef, model.meta.nvar)
371371
hprod_residual!(model, x, i, v, Hv)
372372
end
373373

@@ -382,8 +382,8 @@ function hprod_residual! end
382382
Computes the Hessian of the i-th residual at x, in linear operator form.
383383
"""
384384
function hess_op_residual(model::AbstractVIModel{T, S}, x::AbstractVector{T}, i::Int) where {T, S}
385-
@lencheck model.nvar x
386-
Hiv = S(undef, model.nvar)
385+
@lencheck model.meta.nvar x
386+
Hiv = S(undef, model.meta.nvar)
387387
return hess_op_residual!(model, x, i, Hiv)
388388
end
389389

@@ -392,7 +392,7 @@ end
392392
Computes the Hessian of the i-th residual at x, in linear operator form. The vector `Hiv` is used as preallocated storage for the operation.
393393
"""
394394
function hess_op_residual!(model::AbstractVIModel, x::AbstractVector, i::Int, Hiv::AbstractVector)
395-
@lencheck model.nvar x Hiv
395+
@lencheck model.meta.nvar x Hiv
396396
prod! = @closure (res, v, α, β) -> begin
397397
hprod_residual!(model, x, i, v, Hiv)
398398
if β == 0
@@ -403,8 +403,8 @@ function hess_op_residual!(model::AbstractVIModel, x::AbstractVector, i::Int, Hi
403403
return res
404404
end
405405
return LinearOperator{eltype(x)}(
406-
model.nvar,
407-
model.nvar,
406+
model.meta.nvar,
407+
model.meta.nvar,
408408
true,
409409
true,
410410
prod!,
@@ -435,7 +435,7 @@ Compute the projection of d over X, i.e.,
435435
```
436436
"""
437437
function project(model::AbstractVIModel{T, S}, x::AbstractVector{T}) where {T, S}
438-
@lencheck model.nvar x
439-
Px = S(undef, model.nvar)
438+
@lencheck model.meta.nvar x
439+
Px = S(undef, model.meta.nvar)
440440
project!(model, x, Px)
441441
end

0 commit comments

Comments
 (0)