Skip to content

Commit fb23376

Browse files
Reuse Arpack in order to compute norm of Bk
1 parent 9109051 commit fb23376

File tree

6 files changed

+60
-11
lines changed

6 files changed

+60
-11
lines changed

Project.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ ProximalOperators = "a725b495-10eb-56fe-b38b-717eba820537"
1515
RegularizedProblems = "ea076b23-609f-44d2-bb12-a4ae45328278"
1616
ShiftedProximalOperators = "d4fd37fa-580c-4e43-9b30-361c21aae263"
1717
SolverCore = "ff4d7338-4cf1-434d-91df-b86cb86fb843"
18-
TSVD = "9449cd9e-2762-5aa3-a617-5413e99d722e"
18+
Arpack = "7d9fca2a-8960-54d3-9f78-7d1dccf2cb97"
1919

2020
[compat]
2121
LinearOperators = "2.9"
@@ -26,7 +26,7 @@ ProximalOperators = "0.15"
2626
RegularizedProblems = "0.1.1"
2727
ShiftedProximalOperators = "0.2"
2828
SolverCore = "0.3.0"
29-
TSVD = "0.4"
29+
Arpack = "0.5"
3030
julia = "^1.6.0"
3131

3232
[extras]

src/LMTR_alg.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,8 @@ function LMTR(
130130
JdFk = similar(Fk) # temporary storage
131131
Jt_Fk = similar(∇fk) # temporary storage
132132

133-
σmax = opnorm(Jk)
133+
σmax, found_σ = opnorm(Jk)
134+
found_σ || error("operator norm computation failed")
134135
νInv = (1 + θ) * σmax^2 # ‖J'J‖ = ‖J‖²
135136

136137
mν∇fk = -∇fk / νInv
@@ -252,7 +253,8 @@ function LMTR(
252253
shift!(ψ, xk)
253254
Jk = jac_op_residual(nls, xk)
254255
jtprod_residual!(nls, xk, Fk, ∇fk)
255-
σmax = opnorm(Jk)
256+
σmax, found_σ = opnorm(Jk)
257+
found_σ || error("operator norm computation failed")
256258
νInv = (1 + θ) * σmax^2 # ‖J'J‖ = ‖J‖²
257259
@. mν∇fk = -∇fk / νInv
258260
end

src/LM_alg.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,8 @@ function LM(
123123
JdFk = similar(Fk) # temporary storage
124124
Jt_Fk = similar(∇fk)
125125

126-
σmax = opnorm(Jk)
126+
σmax, found_σ = opnorm(Jk)
127+
found_σ || error("operator norm computation failed")
127128
νInv = (1 + θ) * (σmax^2 + σk) # ‖J'J + σₖ I‖ = ‖J‖² + σₖ
128129

129130
s = zero(xk)
@@ -243,7 +244,8 @@ function LM(
243244
Jk = jac_op_residual(nls, xk)
244245
jtprod_residual!(nls, xk, Fk, ∇fk)
245246

246-
σmax = opnorm(Jk)
247+
σmax, found_σ = opnorm(Jk)
248+
found_σ || error("operator norm computation failed")
247249

248250
Complex_hist[k] += 1
249251
end

src/RegularizedOptimization.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ module RegularizedOptimization
44
using LinearAlgebra, Logging, Printf
55

66
# external dependencies
7-
using ProximalOperators, TSVD
7+
using ProximalOperators, Arpack
88

99
# dependencies from us
1010
using LinearOperators,

src/TR_alg.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,8 @@ function TR(
131131
quasiNewtTest = isa(f, QuasiNewtonModel)
132132
Bk = hess_op(f, xk)
133133

134-
λmax = opnorm(Bk)
134+
λmax, found_λ = opnorm(Bk)
135+
found_λ || error("operator norm computation failed")
135136
α⁻¹Δ⁻¹ = 1 /* Δk)
136137
ν = 1 / (α⁻¹Δ⁻¹ + λmax * (α⁻¹Δ⁻¹ + 1))
137138
sqrt_ξ1_νInv = one(R)
@@ -241,7 +242,8 @@ function TR(
241242
push!(f, s, ∇fk - ∇fk⁻)
242243
end
243244
Bk = hess_op(f, xk)
244-
λmax = opnorm(Bk)
245+
λmax, found_λ = opnorm(Bk)
246+
found_λ || error("operator norm computation failed")
245247
∇fk⁻ .= ∇fk
246248
end
247249

src/utils.jl

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,51 @@ import SolverCore.GenericExecutionStats
44

55
# use Arpack to obtain largest eigenvalue in magnitude with a minimum of robustness
66
function LinearAlgebra.opnorm(B; kwargs...)
7-
_, s, _ = tsvd(B)
8-
return s[1]
7+
m, n = size(B)
8+
opnorm_fcn = m == n ? opnorm_eig : opnorm_svd
9+
return opnorm_fcn(B; kwargs...)
10+
end
11+
function opnorm_eig(B; max_attempts::Int = 3)
12+
have_eig = false
13+
attempt = 0
14+
λ = zero(eltype(B))
15+
success = false
16+
n = size(B, 1)
17+
nev = 1
18+
ncv = max(20, 2 * nev + 1)
19+
while !(have_eig || attempt > max_attempts)
20+
attempt += 1
21+
(d, nconv, niter, nmult, resid) = eigs(B; nev = nev, ncv = ncv, which = :LM, ritzvec = false, check = 1)
22+
have_eig = nconv == 1
23+
if (have_eig)
24+
λ = abs(d[1])
25+
success = true
26+
else
27+
ncv = min(2 * ncv, n)
28+
end
29+
end
30+
return λ, success
31+
end
32+
function opnorm_svd(J; max_attempts::Int = 3)
33+
have_svd = false
34+
attempt = 0
35+
σ = zero(eltype(J))
36+
success = false
37+
n = min(size(J)...)
38+
nsv = 1
39+
ncv = 10
40+
while !(have_svd || attempt > max_attempts)
41+
attempt += 1
42+
(s, nconv, niter, nmult, resid) = svds(J, nsv = nsv, ncv = ncv, ritzvec = false, check = 1)
43+
have_svd = nconv == 1
44+
if (have_svd)
45+
σ = maximum(s.S)
46+
success = true
47+
else
48+
ncv = min(2 * ncv, n)
49+
end
50+
end
51+
return σ, success
952
end
1053

1154
ShiftedProximalOperators.iprox!(

0 commit comments

Comments
 (0)