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

Commit b435ae5

Browse files
committed
using lu-factorization
1 parent 9afc062 commit b435ae5

File tree

2 files changed

+69
-27
lines changed

2 files changed

+69
-27
lines changed

src/broyden.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ function SciMLBase.solve(prob::NonlinearProblem,
1616
x = float(prob.u0)
1717
fₙ = f(x)
1818
T = eltype(x)
19-
J⁻¹ = ArrayInterfaceCore.zeromatrix(x) + I
19+
J⁻¹ = init_J(x)
2020

2121
if SciMLBase.isinplace(prob)
2222
error("Broyden currently only supports out-of-place nonlinear problems")

src/klement.jl

Lines changed: 68 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Klement()
44
```
55
66
A low-overhead implementation of [Klement](https://jatm.com.br/jatm/article/view/373).
7-
This method is non-allocating on scalar and static array problems.
7+
This method is non-allocating on scalar problems.
88
"""
99
struct Klement <: AbstractSimpleNonlinearSolveAlgorithm end
1010

@@ -16,7 +16,7 @@ function SciMLBase.solve(prob::NonlinearProblem,
1616
x = float(prob.u0)
1717
fₙ = f(x)
1818
T = eltype(x)
19-
J = init_J(x)
19+
singular_tol = 1e-9
2020

2121
if SciMLBase.isinplace(prob)
2222
error("Klement currently only supports out-of-place nonlinear problems")
@@ -29,36 +29,78 @@ function SciMLBase.solve(prob::NonlinearProblem,
2929
xₙ = x
3030
xₙ₋₁ = x
3131
fₙ₋₁ = fₙ
32-
for _ in 1:maxiters
33-
tmp = J \ fₙ₋₁
34-
xₙ = xₙ₋₁ - tmp
35-
fₙ = f(xₙ)
36-
37-
iszero(fₙ) &&
38-
return SciMLBase.build_solution(prob, alg, xₙ, fₙ;
39-
retcode = ReturnCode.Success)
40-
41-
if isapprox(xₙ, xₙ₋₁, atol = atol, rtol = rtol)
42-
return SciMLBase.build_solution(prob, alg, xₙ, fₙ;
43-
retcode = ReturnCode.Success)
44-
end
4532

46-
Δxₙ = xₙ - xₙ₋₁
47-
Δfₙ = fₙ - fₙ₋₁
33+
# x is scalar
34+
if isa(x, Number)
35+
J = 1.0
36+
for _ in 1:maxiters
37+
38+
xₙ = xₙ₋₁ - fₙ₋₁/J
39+
fₙ = f(xₙ)
40+
41+
iszero(fₙ) &&
42+
return SciMLBase.build_solution(prob, alg, xₙ, fₙ;
43+
retcode = ReturnCode.Success)
44+
45+
if isapprox(xₙ, xₙ₋₁, atol = atol, rtol = rtol)
46+
return SciMLBase.build_solution(prob, alg, xₙ, fₙ;
47+
retcode = ReturnCode.Success)
48+
end
4849

49-
# Prevent division by 0
50-
denominator = max.(J' .^ 2 * Δxₙ .^ 2, 1e-9)
50+
Δxₙ = xₙ - xₙ₋₁
51+
Δfₙ = fₙ - fₙ₋₁
5152

52-
k = (Δfₙ - J * Δxₙ) ./ denominator
53-
J += (k * Δxₙ' .* J) * J
53+
# Prevent division by 0
54+
denominator = max(J ^ 2 * Δxₙ ^ 2, 1e-9)
5455

55-
# Singularity test
56-
if cond(J) > 1e9
57-
J = init_J(xₙ)
56+
k = (Δfₙ - J * Δxₙ) / denominator
57+
J += (k * Δxₙ * J) * J
58+
59+
# Singularity test
60+
if J < singular_tol
61+
J = 1.0
62+
end
63+
64+
xₙ₋₁ = xₙ
65+
fₙ₋₁ = fₙ
5866
end
67+
# x is a vector
68+
else
69+
J = init_J(x)
70+
F = lu(J, check = false)
71+
for _ in 1:maxiters
72+
tmp = F \ fₙ₋₁
73+
xₙ = xₙ₋₁ - tmp
74+
fₙ = f(xₙ)
75+
76+
iszero(fₙ) &&
77+
return SciMLBase.build_solution(prob, alg, xₙ, fₙ;
78+
retcode = ReturnCode.Success)
5979

60-
xₙ₋₁ = xₙ
61-
fₙ₋₁ = fₙ
80+
if isapprox(xₙ, xₙ₋₁, atol = atol, rtol = rtol)
81+
return SciMLBase.build_solution(prob, alg, xₙ, fₙ;
82+
retcode = ReturnCode.Success)
83+
end
84+
85+
Δxₙ = xₙ - xₙ₋₁
86+
Δfₙ = fₙ - fₙ₋₁
87+
88+
# Prevent division by 0
89+
denominator = max.(J' .^ 2 * Δxₙ .^ 2, 1e-9)
90+
91+
k = (Δfₙ - J * Δxₙ) ./ denominator
92+
J += (k * Δxₙ' .* J) * J
93+
F = lu(J, check = false)
94+
95+
# Singularity test
96+
if any(abs.(F.U[diagind(F.U)]) .< singular_tol)
97+
J = init_J(xₙ)
98+
F = lu(J, check = false)
99+
end
100+
101+
xₙ₋₁ = xₙ
102+
fₙ₋₁ = fₙ
103+
end
62104
end
63105

64106
return SciMLBase.build_solution(prob, alg, xₙ, fₙ; retcode = ReturnCode.MaxIters)

0 commit comments

Comments
 (0)