Skip to content

Commit 9a1122e

Browse files
Update utils.jl
Enhance robustness of Arpack usage by catching NCV-related errors Catch the XYAUPD_Exception error in Arpack calls and dynamically increase NCV as needed to handle convergence issues. This modification addresses instability in LSR1 computations due to insufficient NCV.
1 parent 441521f commit 9a1122e

File tree

1 file changed

+51
-19
lines changed

1 file changed

+51
-19
lines changed

src/utils.jl

Lines changed: 51 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,36 +11,68 @@ function opnorm_eig(B; max_attempts::Int = 3)
1111
n = size(B, 1)
1212
nev = 1
1313
ncv = max(20, 2 * nev + 1)
14-
while !(have_eig || attempt > max_attempts)
15-
attempt += 1
16-
(d, nconv, niter, nmult, resid) = eigs(B; nev = nev, ncv = ncv, which = :LM, ritzvec = false, check = 1)
17-
have_eig = nconv == 1
18-
if (have_eig)
19-
λ = abs(d[1])
20-
else
21-
ncv = min(2 * ncv, n)
22-
end
14+
15+
while !(have_eig || attempt >= max_attempts)
16+
attempt += 1
17+
try
18+
# Perform eigendecomposition
19+
d, nconv, niter, nmult, resid = eigs(B; nev = nev, ncv = ncv, which = :LM, ritzvec = false, check = 1)
20+
21+
# Check if eigenvalue has converged
22+
have_eig = nconv == 1
23+
if have_eig
24+
λ = abs(d[1]) # Take absolute value of the largest eigenvalue
25+
break # Exit loop if successful
26+
else
27+
# Increase NCV for the next attempt if convergence wasn't achieved
28+
ncv = min(2 * ncv, n)
29+
end
30+
catch e
31+
if occursin("XYAUPD_Exception", string(e))
32+
@warn "Arpack error: $e. Increasing NCV to $ncv and retrying."
33+
ncv = min(2 * ncv, n) # Increase NCV but don't exceed matrix size
34+
else
35+
rethrow(e) # Re-raise if it's a different error
36+
end
37+
end
2338
end
39+
2440
return λ, have_eig
2541
end
2642

2743
function opnorm_svd(J; max_attempts::Int = 3)
2844
have_svd = false
2945
attempt = 0
3046
σ = zero(eltype(J))
31-
n = min(size(J)...)
47+
n = min(size(J)...) # Minimum dimension of the matrix
3248
nsv = 1
3349
ncv = 10
34-
while !(have_svd || attempt > max_attempts)
35-
attempt += 1
36-
(s, nconv, niter, nmult, resid) = svds(J, nsv = nsv, ncv = ncv, ritzvec = false, check = 1)
37-
have_svd = nconv == 1
38-
if (have_svd)
39-
σ = maximum(s.S)
40-
else
41-
ncv = min(2 * ncv, n)
42-
end
50+
51+
while !(have_svd || attempt >= max_attempts)
52+
attempt += 1
53+
try
54+
# Perform singular value decomposition
55+
s, nconv, niter, nmult, resid = svds(J; nsv = nsv, ncv = ncv, ritzvec = false, check = 1)
56+
57+
# Check if singular value has converged
58+
have_svd = nconv >= 1
59+
if have_svd
60+
σ = maximum(s.S) # Take the largest singular value
61+
break # Exit loop if successful
62+
else
63+
# Increase NCV for the next attempt if convergence wasn't achieved
64+
ncv = min(2 * ncv, n)
65+
end
66+
catch e
67+
if occursin("XYAUPD_Exception", string(e))
68+
@warn "Arpack error: $e. Increasing NCV to $ncv and retrying."
69+
ncv = min(2 * ncv, n) # Increase NCV but don't exceed matrix size
70+
else
71+
rethrow(e) # Re-raise if it's a different error
72+
end
73+
end
4374
end
75+
4476
return σ, have_svd
4577
end
4678

0 commit comments

Comments
 (0)