Skip to content
This repository was archived by the owner on May 15, 2025. It is now read-only.

Commit 8e6bee0

Browse files
Merge pull request #106 from avik-pal/ap/klement
Update Klement to exploit the diagonal structure
2 parents 05d9f2e + 4a22588 commit 8e6bee0

File tree

3 files changed

+13
-43
lines changed

3 files changed

+13
-43
lines changed

src/nlsolve/klement.jl

Lines changed: 5 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ function SciMLBase.__solve(prob::NonlinearProblem, alg::SimpleKlement, args...;
1313
T = eltype(x)
1414
fx = _get_fx(prob, x)
1515

16-
singular_tol = eps(T)^(2 // 3)
17-
1816
abstol, reltol, tc_cache = init_termination_cache(abstol, reltol, fx, x,
1917
termination_condition)
2018

@@ -23,42 +21,14 @@ function SciMLBase.__solve(prob::NonlinearProblem, alg::SimpleKlement, args...;
2321
@bb xo = copy(x)
2422
@bb d = copy(x)
2523

26-
J = __init_identity_jacobian(fx, x)
27-
@bb J_cache = similar(J)
24+
J = one.(x)
2825
@bb δx² = similar(x)
29-
@bb J_cache2 = similar(J)
30-
@bb F = copy(J)
3126

3227
for _ in 1:maxiters
33-
if x isa Number
34-
J < singular_tol && (J = __init_identity_jacobian!!(J))
35-
F_ = J
36-
else
37-
@bb copyto!(F, J)
38-
if setindex_trait(F) === CanSetindex()
39-
F_ = lu!(F; check = false)
40-
else
41-
F_ = lu(F; check = false)
42-
end
28+
any(iszero, J) && (J = __init_identity_jacobian!!(J))
4329

44-
# Singularity test
45-
if !issuccess(F_)
46-
J = __init_identity_jacobian!!(J)
47-
@bb copyto!(F, J)
48-
if setindex_trait(J) === CanSetindex()
49-
F_ = lu!(F; check = false)
50-
else
51-
F_ = lu(F; check = false)
52-
end
53-
end
54-
end
30+
@bb @. δx = fprev / J
5531

56-
@bb copyto!(δx, fprev)
57-
if setindex_trait(δx) === CanSetindex()
58-
ldiv!(F_, _vec(δx))
59-
else
60-
δx = _restructure(δx, F_ \ _vec(δx))
61-
end
6232
@bb @. x = xo - δx
6333
fx = __eval_f(prob, fx, x)
6434

@@ -67,15 +37,8 @@ function SciMLBase.__solve(prob::NonlinearProblem, alg::SimpleKlement, args...;
6737
tc_sol !== nothing && return tc_sol
6838

6939
@bb δx .*= -1
70-
@bb J_cache .= transpose(J) .^ 2
71-
@bb @. δx² = δx^2
72-
@bb d = J_cache × vec(δx²)
73-
@bb δx² = J × vec(δx)
74-
@bb @. fprev = (fx - fprev - δx²) / ifelse(iszero(d), singular_tol, d)
75-
@bb J_cache = vec(fprev) × transpose(_vec(δx))
76-
@bb @. J_cache *= J
77-
@bb J_cache2 = J_cache × J
78-
@bb @. J += J_cache2
40+
@bb @. δx² = δx^2 * J^2
41+
@bb @. J += (fx - fprev - J * δx) / ifelse(iszero(δx²), T(1e-5), δx²) * δx * (J^2)
7942

8043
@bb copyto!(fprev, fx)
8144
@bb copyto!(xo, x)

src/utils.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,10 @@ function __init_identity_jacobian!!(J)
212212
J[diagind(J)] .= one(eltype(J))
213213
return J
214214
end
215+
function __init_identity_jacobian!!(J::AbstractVector)
216+
fill!(J, one(eltype(J)))
217+
return J
218+
end
215219
function __init_identity_jacobian(u::StaticArray, fu)
216220
S1, S2 = length(fu), length(u)
217221
J = SMatrix{S1, S2, eltype(u)}(I)
@@ -220,6 +224,9 @@ end
220224
function __init_identity_jacobian!!(J::SMatrix{S1, S2}) where {S1, S2}
221225
return SMatrix{S1, S2, eltype(J)}(I)
222226
end
227+
function __init_identity_jacobian!!(J::SVector{S1}) where {S1}
228+
return ones(SVector{S1, eltype(J)})
229+
end
223230

224231
function __init_low_rank_jacobian(u::StaticArray{S1, T1}, fu::StaticArray{S2, T2},
225232
::Val{threshold}) where {S1, S2, T1, T2, threshold}

test/23_test_problems.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ end
8282
alg_ops = (SimpleKlement(),)
8383

8484
broken_tests = Dict(alg => Int[] for alg in alg_ops)
85-
broken_tests[alg_ops[1]] = [1, 2, 4, 5, 6, 7, 11, 13, 22]
85+
broken_tests[alg_ops[1]] = [1, 2, 4, 5, 6, 11, 12, 22]
8686

8787
test_on_library(problems, dicts, alg_ops, broken_tests)
8888
end

0 commit comments

Comments
 (0)