Skip to content

Commit

Permalink
allow initial-guess methods to solve for lambda
Browse files Browse the repository at this point in the history
  • Loading branch information
jjstickel committed Jan 14, 2022
1 parent aa8ed39 commit 5ca099f
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 9 deletions.
26 changes: 20 additions & 6 deletions src/solvers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -184,20 +184,34 @@ function solve(
Ψ::RegularizationProblem,
b::AbstractVector;
alg = :gcv_svd,
method = Brent(),
λ₁ = 0.0001,
λ₂ = 1000.0,
λ₀ = 1.0,
kwargs...
)
= @>> b to_standard_form(Ψ)
L1, L2, κ = Lcurve_functions(Ψ, b̄)

solution = @match alg begin
:gcv_tr => @_ optimize(gcv_tr(Ψ, b̄, _), λ₁, λ₂)
:gcv_svd => @_ optimize(gcv_svd(Ψ, b̄, _), λ₁, λ₂)
:L_curve => @_ optimize(1.0 - κ(_), λ₁, λ₂)
optfunc(x) = @match alg begin
:gcv_tr => gcv_tr(Ψ, b̄, x)
:gcv_svd => gcv_svd(Ψ, b̄, x)
:L_curve => 1.0 - κ(x)
_ => throw("Unknown algorithm, use :gcv_tr, :gcv_svd, or :L_curve")
end

λ = @> solution Optim.minimizer
if method in [Brent(), GoldenSection()] # univariate methods with bounds
solution = optimize(optfunc, log10(λ₁), log10(λ₂), method; kwargs...)
log10λ = @> solution Optim.minimizer
else # methods that use an intitial guess; gradient-free and gradient methods via
# default finite-difference work Ok, but `autodiff=:forward` is not working
solution = optimize(x->optfunc(first(x)), [log10(λ₀)], method,
Optim.Options(; kwargs...))
# alternative method call, but cautioned against in the docs
#solution = optimize(x->optfunc(first(x)), [log10(λ₀)]; method=method, kwargs...)
log10λ = @> solution Optim.minimizer first
end
λ = 10^log10λ

= solve(Ψ, b̄, λ)
x = @>>to_general_form(Ψ, b)

Expand Down
9 changes: 6 additions & 3 deletions src/validators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ Vλ = gcv_tr(Ψ, b̄, 0.1) # V(λ) single λ value
Vλ = @_ map(gcv_tr(Ψ, b̄, _), [0.1, 1.0, 10.0]) # V(λ) for array of λ
```
"""
function gcv_tr::RegularizationProblem, b̄::AbstractVector, λ::AbstractFloat)
function gcv_tr::RegularizationProblem, b̄::AbstractVector, log10λ::AbstractFloat)
λ = 10^log10λ
n = size.Ā, 1)
= Ψ.* inv.ĀĀ + λ^2.0 * Ψ.Iₚ) * Ψ.'
Iₙ = Matrix{Float64}(I, length(b̄), length(b̄))
Expand Down Expand Up @@ -82,7 +83,8 @@ Vλ = gcv_svd(Ψ, b̄, x̄₀, 0.1) # V(λ) single λ value
Vλ = @_ map(gcv_svd(Ψ, b̄, _), [0.1, 1.0, 10.0]) # V(λ) for array of λ
```
"""
function gcv_svd::RegularizationProblem, b̄::AbstractVector, λ::AbstractFloat)
function gcv_svd::RegularizationProblem, b̄::AbstractVector, log10λ::AbstractFloat)
λ = 10^log10λ
F = Ψ.
n, p = size(F.U)
z = F.U' *
Expand Down Expand Up @@ -148,7 +150,8 @@ function curvature_functions(x̄::Function, L1::Function, L2::Function)
ρ⁰::AbstractFloat) = (log.(L1.(λ) .^ 2.0))[1]
ηᵖ::AbstractFloat) = (derivative(η⁰, λ))[1]

function κ::AbstractFloat)
function κ(log10λ::AbstractFloat)
λ = 10^log10λ
nᵖ = ηᵖ(λ)
η = η⁰(λ)
ρ = ρ⁰(λ)
Expand Down

0 comments on commit 5ca099f

Please sign in to comment.