Skip to content

Commit 34f3dc5

Browse files
committed
Add citations and a simple example
1 parent 08d07a8 commit 34f3dc5

File tree

10 files changed

+162
-9
lines changed

10 files changed

+162
-9
lines changed

docs/Project.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
[deps]
22
CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0"
33
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
4+
DocumenterCitations = "daee34ce-89f3-4625-b898-19384cb65244"
45
Krylov = "ba0b0d4f-ebba-5204-a429-3ac8c609bfb7"
56
KrylovPreconditioners = "45d422c2-293f-44ce-8315-2cb988662dec"
67
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"

docs/make.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ using NewtonKrylov
44
using Documenter
55
import Documenter.Remotes: GitHub
66
using Literate
7+
using DocumenterCitations
78

89
DocMeta.setdocmeta!(NewtonKrylov, :DocTestSetup, :(using NewtonKrylov); recursive = true)
910

@@ -17,6 +18,8 @@ const OUTPUT_DIR = joinpath(@__DIR__, "src/generated")
1718

1819
examples = [
1920
"Bratu 1D" => "bratu",
21+
"Simple" => "simple",
22+
"BVP" => "bvp",
2023
]
2124

2225
for (_, name) in examples
@@ -26,6 +29,8 @@ end
2629

2730
examples = [title => joinpath("generated", string(name, ".md")) for (title, name) in examples]
2831

32+
bib = CitationBibliography(joinpath(@__DIR__, "src", "refs.bib"))
33+
2934
makedocs(;
3035
modules = [NewtonKrylov],
3136
authors = "Valentin Churavy",
@@ -40,6 +45,7 @@ makedocs(;
4045
class = :js,
4146
attributes = Dict(Symbol("data-domain") => "vchuravy.dev", :defer => "")
4247
),
48+
"assets/citations.css",
4349
],
4450
mathengine = MathJax3(),
4551
),
@@ -49,6 +55,7 @@ makedocs(;
4955
],
5056
doctest = true,
5157
linkcheck = true,
58+
plugins = [bib]
5259
)
5360

5461
deploydocs(;

docs/src/assets/citations.css

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
.citation dl {
2+
display: grid;
3+
grid-template-columns: max-content auto; }
4+
.citation dt {
5+
grid-column-start: 1; }
6+
.citation dd {
7+
grid-column-start: 2;
8+
margin-bottom: 0.75em; }
9+
.citation ul {
10+
padding: 0 0 2.25em 0;
11+
margin: 0;
12+
list-style: none !important;}
13+
.citation ul li {
14+
text-indent: -2.25em;
15+
margin: 0.33em 0.5em 0.5em 2.25em;}
16+
.citation ol li {
17+
padding-left:0.75em;}

docs/src/index.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# NewtonKrylov.jl
22

3-
3+
Newton Method using Krylov.jl (montoison-orban-2023)[@cite]
44

55
## API
66

@@ -21,4 +21,9 @@ NewtonKrylov.EisenstatWalker
2121

2222
```@docs
2323
NewtonKrylov.JacobianOperator
24+
```
25+
26+
## Bibliography
27+
28+
```@bibliography
2429
```

docs/src/refs.bib

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
@BOOK{Kelley2022
2+
title = {Solving nonlinear equations with iterative methods: Solvers and
3+
examples in Julia},
4+
author = {Kelley, C T},
5+
publisher = {Society for Industrial and Applied Mathematics},
6+
location = {Philadelphia, PA},
7+
date = {2022-01},
8+
doi = {10.1137/1.9781611977271},
9+
isbn = {9781611977264,9781611977271},
10+
urldate = {2024-11-15},
11+
language = {en}
12+
}
13+
14+
@BOOK{Kelley2003,
15+
title = {Solving nonlinear equations with Newton's method},
16+
author = {Kelley, C T},
17+
publisher = {Society for Industrial and Applied Mathematics},
18+
location = {Philadelphia, Pa.},
19+
date = {2003},
20+
doi = {10.1137/1.9780898718898},
21+
isbn = {9780898715460,9780898718898},
22+
series = {Fundamentals of algorithms},
23+
urldate = {2024-11-12},
24+
language = {en}
25+
}
26+
27+
@article{montoison-orban-2023,
28+
author = {Montoison, Alexis and Orban, Dominique},
29+
title = {{Krylov.jl: A Julia basket of hand-picked Krylov methods}},
30+
journal = {Journal of Open Source Software},
31+
volume = {8},
32+
number = {89},
33+
pages = {5187},
34+
year = {2023},
35+
doi = {10.21105/joss.05187}
36+
}
37+
38+
@ARTICLE{Kan2022-ko,
39+
title = {Extension of complex step finite difference method to
40+
Jacobian-free {Newton–Krylov​} method},
41+
author = {Kan, Ziyun and Song, Ningning and Peng, Haijun and Chen,
42+
Biaosong},
43+
journaltitle = {Journal of computational and applied mathematics},
44+
publisher = {Elsevier BV},
45+
volume = {399},
46+
issue = {113732},
47+
pages = {113732},
48+
date = {2022-01-01},
49+
doi = {10.1016/j.cam.2021.113732},
50+
issn = {0377-0427,1879-1778},
51+
urldate = {2024-10-21},
52+
language = {en}
53+
}

examples/bratu.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# # 1D bratu equation
1+
# # 1D bratu equation from (Kan2022-ko)[@cite]
22

33
# ## Necessary packages
44
using NewtonKrylov, Krylov

examples/bvp.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# BVP from Solving Nonlinear Equations with Iterative Methods:
1+
# BVP from (Kelley2022)[@cite]
22

33
using NewtonKrylov, Krylov, LinearAlgebra
44

examples/simple.jl

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
## Simple 2D example from (Kelley2003)[@cite]
2+
3+
using NewtonKrylov, LinearAlgebra
4+
using CairoMakie
5+
6+
function F!(res, x)
7+
res[1] = x[1]^2 + x[2]^2 - 2
8+
return res[2] = exp(x[1] - 1) + x[2]^2 - 2
9+
end
10+
11+
function F(x)
12+
res = similar(x)
13+
F!(res, x)
14+
return res
15+
end
16+
17+
18+
xs = LinRange(-3, 8, 1000)
19+
ys = LinRange(-15, 10, 1000)
20+
21+
levels = [0.1, 0.25, 0.5:2:10..., 10.0:10:200..., 200:100:4000...]
22+
23+
fig, ax = contour(xs, ys, (x, y) -> norm(F([x, y])); levels)
24+
25+
trace_1 = let x₀ = [2.0, 0.5]
26+
xs = Vector{Tuple{Float64, Float64}}(undef, 0)
27+
hist(x, res, n_res) = (push!(xs, (x[1], x[2])); nothing)
28+
x, stats = newton_krylov!(F!, x₀, callback = hist)
29+
xs
30+
end
31+
lines!(ax, trace_1)
32+
33+
trace_2 = let x₀ = [2.5, 3.0]
34+
xs = Vector{Tuple{Float64, Float64}}(undef, 0)
35+
hist(x, res, n_res) = (push!(xs, (x[1], x[2])); nothing)
36+
x, stats = newton_krylov!(F!, x₀, callback = hist)
37+
xs
38+
end
39+
lines!(ax, trace_2)
40+
41+
trace_3 = let x₀ = [3.0, 4.0]
42+
xs = Vector{Tuple{Float64, Float64}}(undef, 0)
43+
hist(x, res, n_res) = (push!(xs, (x[1], x[2])); nothing)
44+
x, stats = newton_krylov!(F!, x₀, callback = hist, forcing = NewtonKrylov.EisenstatWalker(η_max = 0.68949), verbose = 1)
45+
@show stats.solved
46+
xs
47+
end
48+
lines!(ax, trace_3)
49+
50+
fig

src/NewtonKrylov.jl

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -121,12 +121,12 @@ function (F::EisenstatWalker)(η, tol, n_res, n_res_prior)
121121
end
122122
inital(F::EisenstatWalker) = F.η_max
123123

124-
function newton_krylov(F, u₀, M::Int = length(u₀); kwargs...)
124+
function newton_krylov(F, u₀::AbstractArray, M::Int = length(u₀); kwargs...)
125125
F!(res, u) = (res .= F(u); nothing)
126126
return newton_krylov!(F!, u₀, M; kwargs...)
127127
end
128128

129-
function newton_krylov!(F!, u₀, M::Int = length(u₀); kwargs...)
129+
function newton_krylov!(F!, u₀::AbstractArray, M::Int = length(u₀); kwargs...)
130130
res = similar(u₀, M)
131131
return newton_krylov!(F!, u₀, res; kwargs...)
132132
end
@@ -156,20 +156,23 @@ end
156156
If `nothing` an exact Newton method is used.
157157
"""
158158
function newton_krylov!(
159-
F!, u, res;
159+
F!, u::AbstractArray, res::AbstractArray;
160160
tol_rel = 1.0e-6,
161161
tol_abs = 1.0e-12,
162162
max_niter = 50,
163163
forcing::Union{Forcing, Nothing} = EisenstatWalker(),
164164
verbose = 0,
165-
Solver = CgSolver,
165+
Solver = GmresSolver,
166166
M = nothing,
167167
N = nothing,
168-
krylov_kwargs = (;)
168+
krylov_kwargs = (;),
169+
callback = (args...) -> nothing,
169170
)
170171
t₀ = time_ns()
171172
F!(res, u) # res = F(u)
172173
n_res = norm(res)
174+
callback(u, res, n_res)
175+
173176
tol = tol_rel * n_res + tol_abs
174177

175178
if forcing !== nothing
@@ -208,9 +211,11 @@ function newton_krylov!(
208211
u .+= s .* d
209212

210213
# Update residual and norm
211-
F!(res, u) # res = F(u)
212214
n_res_prior = n_res
215+
216+
F!(res, u) # res = F(u)
213217
n_res = norm(res)
218+
callback(u, res, n_res)
214219

215220
if isinf(n_res) || isnan(n_res)
216221
@error "Inner solver blew up" stats

test/runtests.jl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,17 @@
11
using Test
22
using NewtonKrylov
3+
4+
function F!(res, x)
5+
res[1] = x[1]^2 + x[2]^2 - 2
6+
return res[2] = exp(x[1] - 1) + x[2]^2 - 2
7+
end
8+
9+
let x₀ = [2.0, 0.5]
10+
x, stats = newton_krylov!(F!, x₀)
11+
@test stats.solved
12+
end
13+
14+
let x₀ = [3.0, 5.0]
15+
x, stats = newton_krylov!(F!, x₀)
16+
@test stats.solved
17+
end

0 commit comments

Comments
 (0)