Skip to content

Commit 33400a1

Browse files
committed
merge models
ensure a model and the corresponding nonlinear least-squares formulation represent the same problem and are based on the same data.
1 parent 0e53614 commit 33400a1

3 files changed

Lines changed: 29 additions & 72 deletions

File tree

src/bpdn_model.jl

Lines changed: 12 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@ bpdn_data(compound::Int = 1, args...) =
1616
bpdn_data(200 * compound, 512 * compound, 10 * compound, args...)
1717

1818
"""
19-
model, sol = bpdn_model(args...)
20-
model, sol = bpdn_model(compound = 1, args...)
19+
model, nls_model, sol = bpdn_model(args...)
20+
model, nls_model, sol = bpdn_model(compound = 1, args...)
2121
22-
Return an instance of an `NLPModel` representing the basis-pursuit denoise
23-
problem, i.e., the under-determined linear least-squares objective
22+
Return an instance of an `NLPModel` and an instance of an `NLSModel` representing
23+
the same basis-pursuit denoise problem, i.e., the under-determined linear
24+
least-squares objective
2425
2526
½ ‖Ax - b‖₂²,
2627
@@ -32,7 +33,7 @@ vector following a normal distribution with mean zero and standard deviation σ.
3233
* `m :: Int`: the number of rows of A
3334
* `n :: Int`: the number of columns of A (with `n` ≥ `m`)
3435
* `k :: Int`: the number of nonzero elements in x̄
35-
* `noise :: Float64`: noise amount ϵ (default: 0.01).
36+
* `noise :: Float64`: noise standard deviation σ (default: 0.01).
3637
3738
The second form calls the first form with arguments
3839
@@ -42,8 +43,8 @@ The second form calls the first form with arguments
4243
4344
## Return Value
4445
45-
An instance of a `FirstOrderModel` that represents the basis-pursuit denoise problem
46-
and the exact solution x̄.
46+
An instance of a `FirstOrderModel` and of a `FirstOrderNLSModel` that represent the same
47+
basis-pursuit denoise problem, and the exact solution x̄.
4748
"""
4849
function bpdn_model(args...)
4950
A, b, b0, x0 = bpdn_data(args...)
@@ -55,6 +56,9 @@ function bpdn_model(args...)
5556
r
5657
end
5758

59+
jprod_resid!(Jv, x, v) = mul!(Jv, A, v)
60+
jtprod_resid!(Jtv, x, v) = mul!(Jtv, A', v)
61+
5862
function obj(x)
5963
resid!(r, x)
6064
dot(r, r) / 2
@@ -66,32 +70,6 @@ function bpdn_model(args...)
6670
g
6771
end
6872

69-
FirstOrderModel(obj, grad!, zero(x0), name = "BPDN"), x0
73+
FirstOrderModel(obj, grad!, zero(x0), name = "BPDN"), FirstOrderNLSModel(resid!, jprod_resid!, jtprod_resid!, size(A, 1), zero(x0), name = "BPDN-LS"), x0
7074
end
7175

72-
"""
73-
model, sol = bpdn_nls_model(args...)
74-
model, sol = bpdn_nls_model(compound = 1, args...)
75-
76-
Return an instance of a `FirstOrderNLSModel` that represents the basis-pursuit
77-
denoise problem explicitly as a least-squares problem and the exact solution x̄.
78-
79-
See the documentation of `bpdn_model()` for more information and a
80-
description of the arguments.
81-
"""
82-
function bpdn_nls_model(args...)
83-
A, b, b0, x0 = bpdn_data(args...)
84-
r = similar(b)
85-
86-
function resid!(r, x)
87-
mul!(r, A, x)
88-
r .-= b
89-
r
90-
end
91-
92-
jprod_resid!(Jv, x, v) = mul!(Jv, A, v)
93-
jtprod_resid!(Jtv, x, v) = mul!(Jtv, A', v)
94-
95-
FirstOrderNLSModel(resid!, jprod_resid!, jtprod_resid!, size(A, 1), zero(x0), name = "BPDN-LS"),
96-
x0
97-
end

src/fh_model.jl

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,9 @@ end
6464
"""
6565
fh_model(; kwargs...)
6666
67-
Return an instance of an `NLPModel` representing the Fitzhugh-Nagumo problem,
68-
i.e., the over-determined nonlinear least-squares objective
67+
Return an instance of an `NLPModel` and an instance of an `NLSModel` representing
68+
the same Fitzhugh-Nagumo problem, i.e., the over-determined nonlinear
69+
least-squares objective
6970
7071
½ ‖F(x)‖₂²,
7172
@@ -80,24 +81,12 @@ constructure, e.g., to set the automatic differentiation backend.
8081
8182
## Return Value
8283
83-
An instance of an `ADNLPModel` that represents the Fitzhugh-Nagumo problem.
84+
An instance of an `ADNLPModel` that represents the Fitzhugh-Nagumo problem, an instance
85+
of an `ADNLSModel` that represents the same problem, and the exact solution.
8486
"""
8587
function fh_model(; kwargs...)
86-
data, simulate, resid, misfit, x0 = FH_smooth_term()
87-
ADNLPModels.ADNLPModel(misfit, ones(5); kwargs...), x0
88-
end
89-
90-
"""
91-
fh_nls_model(; kwargs...)
92-
93-
Return an instance of an `ADNLSModel` that represents the Fitzhugh-Nagumo
94-
problem explicitly as a nonlinear least-squares problem.
95-
96-
See the documentation of `fh_model()` for more information and a
97-
description of the arguments.
98-
"""
99-
function fh_nls_model(; kwargs...)
10088
data, simulate, resid, misfit, x0 = FH_smooth_term()
10189
nequ = 202
102-
ADNLPModels.ADNLSModel(resid, ones(5), nequ; kwargs...), x0
90+
ADNLPModels.ADNLPModel(misfit, ones(5); kwargs...), ADNLPModels.ADNLSModel(resid, ones(5), nequ; kwargs...), x0
10391
end
92+

test/runtests.jl

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,39 +3,29 @@ using ADNLPModels, DifferentialEquations
33
using RegularizedProblems
44

55
@testset "BPDN" begin
6-
model, sol = bpdn_model()
6+
model, nls_model, sol = bpdn_model()
77
@test typeof(model) <: FirstOrderModel
88
@test typeof(sol) == Vector{Float64}
99
@test model.meta.nvar == 512
1010
@test all(model.meta.x0 .== 0)
1111
@test length(findall(x -> x .!= 0, sol)) == 10
12-
end
1312

14-
@testset "BPDN-LS" begin
15-
model, sol = bpdn_nls_model()
16-
@test typeof(model) <: FirstOrderNLSModel
17-
@test typeof(sol) == Vector{Float64}
18-
@test model.meta.nvar == 512
19-
@test model.nls_meta.nequ == 200
20-
@test all(model.meta.x0 .== 0)
21-
@test length(findall(x -> x .!= 0, sol)) == 10
13+
@test typeof(nls_model) <: FirstOrderNLSModel
14+
@test nls_model.meta.nvar == 512
15+
@test nls_model.nls_meta.nequ == 200
16+
@test all(nls_model.meta.x0 .== 0)
2217
end
2318

2419
@testset "FH" begin
25-
model, sol = fh_model()
20+
model, nls_model, sol = fh_model()
2621
@test typeof(model) <: ADNLPModel
2722
@test typeof(sol) == Vector{Float64}
2823
@test model.meta.nvar == 5
2924
@test all(model.meta.x0 .== 1)
3025
@test length(findall(x -> x .!= 0, sol)) == 2
31-
end
3226

33-
@testset "FH-NLS" begin
34-
model, sol = fh_nls_model()
35-
@test typeof(model) <: ADNLSModel
36-
@test typeof(sol) == Vector{Float64}
37-
@test model.meta.nvar == 5
38-
@test model.nls_meta.nequ == 202
39-
@test all(model.meta.x0 .== 1)
40-
@test length(findall(x -> x .!= 0, sol)) == 2
27+
@test typeof(nls_model) <: ADNLSModel
28+
@test nls_model.meta.nvar == 5
29+
@test nls_model.nls_meta.nequ == 202
30+
@test all(nls_model.meta.x0 .== 1)
4131
end

0 commit comments

Comments
 (0)