Skip to content

Commit a389fa5

Browse files
add an option to store the hessian in sparse format for R2N
1 parent 9bb4a9a commit a389fa5

File tree

4 files changed

+49
-11
lines changed

4 files changed

+49
-11
lines changed

Project.toml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ author = ["Robert Baraldi <[email protected]> and Dominique Orban <dominique.orban
44
version = "0.1.0"
55

66
[deps]
7+
Arpack = "7d9fca2a-8960-54d3-9f78-7d1dccf2cb97"
78
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
89
LinearOperators = "5c8ed15e-5a4c-59e4-a42b-c7e8811fb125"
910
Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
@@ -15,18 +16,19 @@ ProximalOperators = "a725b495-10eb-56fe-b38b-717eba820537"
1516
RegularizedProblems = "ea076b23-609f-44d2-bb12-a4ae45328278"
1617
ShiftedProximalOperators = "d4fd37fa-580c-4e43-9b30-361c21aae263"
1718
SolverCore = "ff4d7338-4cf1-434d-91df-b86cb86fb843"
18-
Arpack = "7d9fca2a-8960-54d3-9f78-7d1dccf2cb97"
19+
SparseMatricesCOO = "fa32481b-f100-4b48-8dc8-c62f61b13870"
1920

2021
[compat]
22+
Arpack = "0.5"
2123
LinearOperators = "2.10.0"
22-
NLPModels = "0.19, 0.20"
24+
NLPModels = "0.19, 0.20, 0.21"
2325
NLPModelsModifiers = "0.7"
2426
Percival = "0.7.2"
2527
ProximalOperators = "0.15"
2628
RegularizedProblems = "0.1.1"
2729
ShiftedProximalOperators = "0.2"
2830
SolverCore = "0.3.0"
29-
Arpack = "0.5"
31+
SparseMatricesCOO = "0.2.4"
3032
julia = "^1.6.0"
3133

3234
[extras]

src/R2N.jl

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ mutable struct R2NSolver{
1818
s::V
1919
s1::V
2020
has_bnds::Bool
21+
store_h::Bool
2122
l_bound::V
2223
u_bound::V
2324
l_bound_m_x::V
@@ -32,6 +33,7 @@ function R2NSolver(
3233
reg_nlp::AbstractRegularizedNLPModel{T, V};
3334
subsolver = R2Solver,
3435
m_monotone::Int = 1,
36+
store_h = false
3537
) where {T, V}
3638
x0 = reg_nlp.model.meta.x0
3739
l_bound = reg_nlp.model.meta.lvar
@@ -60,7 +62,15 @@ function R2NSolver(
6062
has_bnds ? shifted(reg_nlp.h, xk, l_bound_m_x, u_bound_m_x, reg_nlp.selected) :
6163
shifted(reg_nlp.h, xk)
6264

63-
Bk = hess_op(reg_nlp.model, x0)
65+
store_h = isa(reg_nlp.model, QuasiNewtonModel) ? false : store_h
66+
67+
if !store_h
68+
Bk = hess_op(reg_nlp.model, x0)
69+
else
70+
rows, cols = hess_structure(reg_nlp.model)
71+
vals = hess_coord(reg_nlp.model, x0)
72+
Bk = SparseMatrixCOO(reg_nlp.model.meta.nvar, reg_nlp.model.meta.nvar, rows, cols, vals)
73+
end
6474
sub_nlp = R2NModel(Bk, ∇fk, T(1), x0)
6575
subpb = RegularizedNLPModel(sub_nlp, ψ)
6676
substats = RegularizedExecutionStats(subpb)
@@ -76,6 +86,7 @@ function R2NSolver(
7686
s,
7787
s1,
7888
has_bnds,
89+
store_h,
7990
l_bound,
8091
u_bound,
8192
l_bound_m_x,
@@ -215,7 +226,7 @@ function SolverCore.solve!(
215226
γ::T = T(3),
216227
β::T = 1 / eps(T),
217228
θ::T = 1/(1 + eps(T)^(1 / 5)),
218-
sub_kwargs::Dict{Symbol} = Dict(),
229+
sub_kwargs::Dict{Symbol, T} = Dict{Symbol, T}(),
219230
) where {T, V, G}
220231
reset!(stats)
221232

@@ -287,7 +298,11 @@ function SolverCore.solve!(
287298

288299
quasiNewtTest = isa(nlp, QuasiNewtonModel)
289300
λmax::T = T(1)
290-
solver.subpb.model.B = hess_op(nlp, xk)
301+
if !solver.store_h
302+
solver.subpb.model.B = hess_op(nlp, xk)
303+
else
304+
hess_coord!(nlp, xk, solver.subpb.model.B.vals)
305+
end
291306

292307
λmax, found_λ = opnorm(solver.subpb.model.B)
293308
found_λ || error("operator norm computation failed")
@@ -417,7 +432,11 @@ function SolverCore.solve!(
417432
@. ∇fk⁻ = ∇fk - ∇fk⁻
418433
push!(nlp, s, ∇fk⁻)
419434
end
420-
solver.subpb.model.B = hess_op(nlp, xk)
435+
if !solver.store_h
436+
solver.subpb.model.B = hess_op(nlp, xk)
437+
else
438+
hess_coord!(nlp, xk, solver.subpb.model.B.vals)
439+
end
421440

422441
λmax, found_λ = opnorm(solver.subpb.model.B)
423442
found_λ || error("operator norm computation failed")

src/R2NModel.jl

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ this model represents the smooth R2N subproblem:
1414
where `B` is either an approximation of the Hessian of `f` or the Hessian itself and `∇f` represents the gradient of `f` at `x0`.
1515
`σ > 0` is a regularization parameter and `v` is a vector of the same size as `x0` used for intermediary computations.
1616
"""
17-
mutable struct R2NModel{T <: Real, V <: AbstractVector{T}, G <: AbstractLinearOperator{T}} <:
17+
mutable struct R2NModel{T <: Real, V <: AbstractVector{T}, G <: Union{AbstractLinearOperator{T}, AbstractMatrix{T}}} <:
1818
AbstractNLPModel{T, V}
1919
B::G
2020
∇f::V
@@ -34,14 +34,21 @@ function R2NModel(B::G, ∇f::V, σ::T, x0::V) where {T, V, G}
3434
return R2NModel(B::G, ∇f::V, v::V, σ::T, meta, Counters())
3535
end
3636

37-
function NLPModels.obj(nlp::R2NModel, x::AbstractVector)
37+
function NLPModels.obj(nlp::R2NModel{T, V, M}, x::V) where{T, V, M <: AbstractLinearOperator{T}}
3838
@lencheck nlp.meta.nvar x
3939
increment!(nlp, :neval_obj)
4040
mul!(nlp.v, nlp.B, x)
4141
return dot(nlp.v, x)/2 + dot(nlp.∇f, x) + nlp.σ * dot(x, x) / 2
4242
end
4343

44-
function NLPModels.grad!(nlp::R2NModel, x::AbstractVector, g::AbstractVector)
44+
function NLPModels.obj(nlp::R2NModel{T, V, M}, x::V) where{T, V, M <: AbstractMatrix{T}}
45+
@lencheck nlp.meta.nvar x
46+
increment!(nlp, :neval_obj)
47+
mul!(nlp.v, Symmetric(nlp.B,:L), x)
48+
return dot(nlp.v, x)/2 + dot(nlp.∇f, x) + nlp.σ * dot(x, x) / 2
49+
end
50+
51+
function NLPModels.grad!(nlp::R2NModel{T, V, M}, x::V, g::V) where{T, V, M <: AbstractLinearOperator{T}}
4552
@lencheck nlp.meta.nvar x
4653
@lencheck nlp.meta.nvar g
4754
increment!(nlp, :neval_grad)
@@ -50,3 +57,13 @@ function NLPModels.grad!(nlp::R2NModel, x::AbstractVector, g::AbstractVector)
5057
g .+= nlp.σ .* x
5158
return g
5259
end
60+
61+
function NLPModels.grad!(nlp::R2NModel{T, V, M}, x::V, g::V) where{T, V, M <: AbstractMatrix{T}}
62+
@lencheck nlp.meta.nvar x
63+
@lencheck nlp.meta.nvar g
64+
increment!(nlp, :neval_grad)
65+
mul!(g, Symmetric(nlp.B,:L), x)
66+
g .+= nlp.∇f
67+
g .+= nlp.σ .* x
68+
return g
69+
end

src/RegularizedOptimization.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ using Arpack, ProximalOperators
88

99
# dependencies from us
1010
using LinearOperators,
11-
NLPModels, NLPModelsModifiers, RegularizedProblems, ShiftedProximalOperators, SolverCore
11+
NLPModels, NLPModelsModifiers, RegularizedProblems, ShiftedProximalOperators, SolverCore, SparseMatricesCOO
1212
using Percival: AugLagModel, update_y!, update_μ!
1313

1414
include("utils.jl")

0 commit comments

Comments
 (0)