Skip to content

Commit f2c9bbe

Browse files
Reuse Arpack in order to compute norm of Bk
1 parent b84a2b1 commit f2c9bbe

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
@@ -14,7 +14,7 @@ ProximalOperators = "a725b495-10eb-56fe-b38b-717eba820537"
1414
RegularizedProblems = "ea076b23-609f-44d2-bb12-a4ae45328278"
1515
ShiftedProximalOperators = "d4fd37fa-580c-4e43-9b30-361c21aae263"
1616
SolverCore = "ff4d7338-4cf1-434d-91df-b86cb86fb843"
17-
TSVD = "9449cd9e-2762-5aa3-a617-5413e99d722e"
17+
Arpack = "7d9fca2a-8960-54d3-9f78-7d1dccf2cb97"
1818

1919
[compat]
2020
LinearOperators = "2.7"
@@ -24,7 +24,7 @@ ProximalOperators = "0.15"
2424
RegularizedProblems = "0.1.1"
2525
ShiftedProximalOperators = "0.2"
2626
SolverCore = "0.3.0"
27-
TSVD = "0.4"
27+
Arpack = "0.5"
2828
julia = "^1.6.0"
2929

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

750
ShiftedProximalOperators.iprox!(

0 commit comments

Comments
 (0)