Skip to content

Commit 51271a6

Browse files
authored
Documenter 1 (#399)
* bump documenter version * documentation fixes for issues exposed bumping Documenter to v1.0
1 parent c0db446 commit 51271a6

File tree

15 files changed

+118
-54
lines changed

15 files changed

+118
-54
lines changed

docs/Project.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,7 @@ Roots = "f2b01f46-fcfa-551c-844a-d8ac1e96c665"
1313
SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6"
1414
UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228"
1515
Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"
16+
17+
18+
[compat]
19+
Documenter = "1"

docs/src/geometry-zero-finding.md

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ We illustrate the geometry behind a single step of several different, non-bracke
44

55
## Newton's method
66

7-
We load the `Plots`, `ForwardDiff`, and `Roots` packages:
7+
In addition to `Roots`, we use the `Plots` and `ForwardDiff` packages:
88

99
```@example geometry
10-
using Plots, ForwardDiff, Roots
10+
using Roots
11+
using Plots, ForwardDiff
1112
Base.adjoint(f::Function) = x -> ForwardDiff.derivative(f, float(x)) # f' will compute derivative
1213
```
1314

@@ -82,8 +83,10 @@ plot!(sl, color=:red, linewidth=3)
8283
scatter!([x0, x1, x2], [0,0,0]; markercolor=:blue)
8384
annotate!([(x0,0,"x0", :bottom), (x1, 0, "x1", :bottom), (x2,0,"x2", :bottom)])
8485
scatter!([x0, x1], [f(x0), f(x1)]; markercolor=:blue)
86+
8587
scatter!([α],[0]; markercolor=:blue)
8688
annotate!([(α, 0, "α", :top)])
89+
8790
p
8891
```
8992

@@ -192,6 +195,7 @@ scatter!(xs, zero.(xs); markercolor=:blue)
192195
193196
scatter!([α],[0]; markercolor=:blue)
194197
annotate!([(α, 0, "α", :top)])
198+
195199
p
196200
```
197201

@@ -218,8 +222,10 @@ for (i,x) ∈ enumerate(xs)
218222
end
219223
annotate!([(x4, 0, "x4", :bottom)])
220224
scatter!(xs, f.(xs); markercolor=:blue)
225+
221226
scatter!([α],[0]; markercolor=:blue)
222227
annotate!([(α, 0, "α", :top)])
228+
223229
p
224230
```
225231

@@ -266,16 +272,18 @@ x0 = 1.4
266272
x1 = x0 - 2 / (1 + sqrt(1 - 2L_f(x0))) * f(x0)/f'(x0)
267273
t2(x) = f(x0) + f'(x0)*(x-x0) + f''(x0)/2 * (x - x0)^2
268274
269-
270-
p = plot(f, 1.1, 1.5; legend=false, linewidth=3)
275+
a, b = 1.1, 1.5
276+
p = plot(f, a, b; legend=false, linewidth=3)
271277
plot!(zero)
272278
plot!(t2; color=:red, linewidth=3)
273279
274280
scatter!([x0, x1], [0,0]; markercolor=:blue)
275281
annotate!([(x0,0,"x0", :bottom), (x1, 0, "x1", :bottom)])
276282
scatter!([x0], [f(x0)]; markercolor=:blue)
283+
277284
scatter!([α],[0]; markercolor=:blue)
278285
annotate!([(α, 0, "α", :top)])
286+
279287
p
280288
```
281289

@@ -300,11 +308,11 @@ We can visualize, as follows, using a contour plot to represent the hyperbola.
300308
x1 = x0 - 2 / (2 - L_f(x0)) * f(x0)/f'(x0)
301309
F(x,y) = y - f(x0) - f'(x0)*(x-x0) - f''(x0)/(2f'(x0)) * (x-x0) * (y-f(x0))
302310
303-
304-
plot(f, 1.1, 1.5; legend=false, linewidth=3)
311+
a, b = 1.1, 1.5
312+
p = plot(f, a, b; legend=false, linewidth=3)
305313
plot!(zero)
306-
xs, ys = range(1.1, 1.5, length=50), range(f(1.1), f(1.5), length=50);
307-
zs = [F(x,y) for y ∈ ys, x ∈ xs];
314+
xs, ys = range(a, b, length=50), range(f(a), f(b), length=50);
315+
zs = [F(x,y) for y ∈ ys, x ∈ xs];
308316
contour!(xs, ys, zs; levels = [0], color=:red, linewidth=3)
309317
310318
scatter!([x0, x1], [0,0]; markercolor=:blue)
@@ -314,6 +322,7 @@ scatter!([x0], [f(x0)]; markercolor=:blue)
314322
315323
scatter!([α],[0]; markercolor=:blue)
316324
annotate!([(α, 0, "α", :top)])
325+
317326
p
318327
```
319328

@@ -336,13 +345,14 @@ x_{n+1} = x_n - (1 + \frac{1}{2} L_f(x_n)) \frac{f(x_n)}{f'(x_n)}.
336345
This is visualized in a similar manner as the last example:
337346

338347
```@example geometry
339-
x1 = x0 + (1 - 1/2 * L_f(x0)) * f(x0) / f'(x0)
348+
x1 = x0 - (1 + 1/2 * L_f(x0)) * f(x0) / f'(x0)
340349
F(x, y) = -f''(x0)/(2f'(x0)^2) * (y-f(x0))^2 + y - f(x0) - f'(x0) * (x- x0)
341350
342-
plot(f, 1.1, 1.5; legend=false, linewidth=3)
351+
a, b = 1.1, 1.5
352+
p = plot(f, a, b; legend=false, linewidth=3)
343353
plot!(zero)
344-
xs, ys = range(1.1, 1.5, length=50), range(f(1.1), f(1.5), length=50);
345-
zs = [F(x,y) for y ∈ ys, x ∈ xs];
354+
xs, ys = range(a, b, length=50), range(f(a), f(b), length=50);
355+
zs = [F(x,y) for y ∈ ys, x ∈ xs];
346356
contour!(xs, ys, zs; levels = [0], color=:red, linewidth=3)
347357
348358
scatter!([x0, x1], [0,0]; markermarkercolor=:blue)
@@ -352,6 +362,7 @@ scatter!([x0], [f(x0)]; markermarkercolor=:blue)
352362
353363
scatter!([α],[0]; markermarkercolor=:blue)
354364
annotate!([(α, 0, "α", :top)])
365+
355366
p
356367
```
357368

@@ -384,23 +395,27 @@ Newton's method is recovered by letting ``b_n \rightarrow 0``, Chebyshev's metho
384395
The super-Halley method is when ``b_n = -f''(x_n)/f'(x_n)``. We can visualize this:
385396

386397
```@example geometry
387-
cn = -f(x0)
398+
cn = -f'(x0)
388399
bn = -f''(x0)/f'(x0)
389-
an = -f''(x0)/(2f'(x0)) - bn/f'(x0)
390-
x1 = x0 - (1 + 1/2 * (L_f(x0) / (1 + bn * (f(x0)/f'(x0))))) * f(x0)/f'(x0)
400+
an = -f''(x0)/(2f'(x0)^2) - bn/f'(x0)
401+
x1 = x0 - (1 + 1/2 * (L_f(x0) / (1 + bn * f(x0) / f'(x0)))) * f(x0)/f'(x0)
391402
F(x, y) = x - x0 + (y-f(x0)) * (1 + an * (y - f(x0))) / (bn * (y - f(x0)) + cn)
392403
393-
plot(f, 1.1, 1.5; legend=false, linewidth=3)
404+
405+
a, b= 1.1, 1.5
406+
p = plot(f, a, b; legend=false, linewidth=3)
394407
plot!(zero)
395-
xs, ys = range(1.1, 1.5, length=50), range(f(1.1), f(1.5), length=50);
396-
zs = [F(x,y) for y ∈ ys, x ∈ xs];
408+
xs, ys = range(a, b, length=50), range(f(a), f(b), length=50);
409+
zs = [F(x,y) for y ∈ ys, x ∈ xs];
397410
contour!(xs, ys, zs; levels = [0], color=:red, linewidth=3)
398411
399412
scatter!([x0, x1], [0,0]; markercolor=:blue)
400413
annotate!([(x0,0,"x0", :bottom), (x1, 0, "x1", :bottom)])
401414
scatter!([x0], [f(x0)]; markercolor=:blue)
415+
402416
scatter!([α],[0]; markercolor=:blue)
403417
annotate!([(α, 0, "α", :top)])
418+
404419
p
405420
```
406421

docs/src/index.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ The `find_zero` function provides the
1212
primary interface. It supports various algorithms through the
1313
specification of a method. These include:
1414

15-
* Bisection-like algorithms. For functions where a bracketing interval
15+
* Bisection-like methods. For functions where a bracketing interval
1616
is known (one where ``f(a)`` and ``f(b)`` have alternate signs),
1717
there are several bracketing methods, including `Bisection`. For
1818
most floating point number types, bisection occurs in a manner
@@ -27,7 +27,7 @@ specification of a method. These include:
2727
iterations and are more performant.
2828

2929

30-
* Several derivative-free methods are implemented. These are specified
30+
* Several derivative-free methods. These are specified
3131
through the methods `Order0`, `Order1` (the secant method), `Order2`
3232
(the Steffensen method), `Order5`, `Order8`, and `Order16`. The
3333
number indicates, roughly, the order of convergence. The `Order0`
@@ -40,7 +40,7 @@ specification of a method. These include:
4040
multiplicity of the zero.
4141

4242

43-
* There are methods that require a derivative or two: `Roots.Newton`,
43+
* Methods requiring one or more derivatives: `Roots.Newton`,
4444
`Roots.Halley` are classical ones, `Roots.QuadraticInverse`,
4545
`Roots.ChebyshevLike`, `Roots.SuperHalley` are others.
4646
`Roots.Schroder` provides a quadratic method, like Newton's method,
@@ -78,7 +78,7 @@ true
7878

7979
The default algorithm is guaranteed to have an answer nearly as accurate as is possible given the limitations of floating point computations.
8080

81-
For the zeros "near" a point, a non-bracketing method is often used, as generally the algorithms are more efficient and can be used in cases where a zero does not cross the ``x`` axis. Passing just the initial point will dispatch to such a method:
81+
For the zeros "near" a point, a non-bracketing method is often used, as generally the algorithms are more efficient and can be used in cases where a zero does not cross the ``x`` axis. Passing just an initial guess will dispatch to such a method:
8282

8383
```jldoctest find_zero
8484
julia> find_zero(f, 0.6) ≈ 0.550606579334135

docs/src/reference.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ end
2121
CurrentModule = Roots
2222
```
2323

24+
```@docs
25+
Roots
26+
```
27+
2428
## The `find_zero` and `find_zeros` functions
2529

2630
There are two main functions: `find_zero` to identify a zero of ``f`` given some initial starting value or bracketing interval and `find_zeros` to heuristically identify all zeros in a specified interval.
@@ -37,6 +41,7 @@ The problem-algorithm-solve interface is a pattern popularized in `Julia` by the
3741

3842
```@docs
3943
Roots.solve!
44+
Roots.solve
4045
Roots.ZeroProblem
4146
```
4247

@@ -108,7 +113,9 @@ only requires one new function call per step so can be very effective. Often
108113

109114
```@docs
110115
Secant
116+
Order1
111117
Steffensen
118+
Order2
112119
Order5
113120
Order8
114121
Order16
@@ -148,7 +155,9 @@ Derivative-free methods for non-simple zeros have the following implemented:
148155

149156
```@docs
150157
Roots.King
158+
Roots.Order1B
151159
Roots.Esser
160+
Roots.Order2B
152161
```
153162

154163

@@ -300,12 +309,13 @@ Roots.dfree
300309
The initial naming scheme used `fzero` instead of `fzeros`, following the name of the MATLAB function [fzero](https://www.mathworks.com/help/matlab/ref/fzero.html). This interface is not recommended, but, for now, still maintained.
301310

302311
```@docs
303-
Roots.fzero
312+
fzero
313+
fzeros
304314
```
305315

306316
## Tracking iterations
307317

308-
It is possible to add the keyword argument `verbose=true` when calling the `find_zero` function to get detailed information about the solution and data from each iteration. To save this data a `Tracks` object may be passed in to `tracks`.
318+
It is possible to add the keyword argument `verbose=true` when calling the `find_zero` function to get detailed information about the solution and data from each iteration. To save this data a `Tracks`object may be passed in to `tracks`.
309319

310320
----
311321

src/Bracketing/alefeld_potra_shi.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
## --------------------------------------------------
99

10+
#=
1011
"""
1112
AbstractAlefeldPotraShi
1213
@@ -16,6 +17,7 @@ The `update_step` method calls a `calculateΔ` method that can be customized to
1617
1718
This implementation deviates slightly from the printed algorithm, as it may use an initial call to `_middle` rather than a secant step, depending on the signs of ``a`` and ``b``.
1819
"""
20+
=#
1921
abstract type AbstractAlefeldPotraShi <: AbstractBracketingMethod end
2022

2123
initial_fncalls(::AbstractAlefeldPotraShi) = 3 # worst case assuming fx₀, fx₁,fc must be computed

src/DerivativeFree/esser.jl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
### Order2B() Esser method
22
"""
3-
Roots.Order2B()
43
Roots.Esser()
54
65
Esser's method. This is a quadratically convergent method that, like
@@ -29,6 +28,12 @@ find_zero(g, x0, Roots.Order2B(), verbose=true) # 4 / 10
2928
```
3029
"""
3130
struct Esser <: AbstractSecantMethod end
31+
32+
"""
33+
Roots.Order2B()
34+
35+
[`Esser`](@ref) method with guarded secant step.
36+
"""
3237
struct Order2B <: AbstractSecantMethod end
3338

3439
function update_state(

src/DerivativeFree/king.jl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
"""
2-
Roots.Order1B()
32
Roots.King()
43
54
A superlinear (order `1.6...`) modification of the secant method for multiple roots.
@@ -15,6 +14,12 @@ The *asymptotic* error, `eᵢ = xᵢ - α`, is given by
1514
1615
"""
1716
struct King <: AbstractSecantMethod end
17+
18+
"""
19+
Roots.Order1B()
20+
21+
[`King`](@ref) method with guarded secant step.
22+
"""
1823
struct Order1B <: AbstractSecantMethod end
1924

2025
struct KingState{T,S} <: AbstractUnivariateZeroState{T,S}

src/DerivativeFree/steffensen.jl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
"""
22
Steffensen()
3-
Order2()
43
54
65
The quadratically converging
@@ -17,6 +16,12 @@ The error, `eᵢ - α`, satisfies
1716
`eᵢ₊₁ = f[xᵢ, xᵢ+fᵢ, α] / f[xᵢ,xᵢ+fᵢ] ⋅ (1 - f[xᵢ,α] ⋅ eᵢ²`
1817
"""
1918
struct Steffensen <: AbstractSecantMethod end
19+
20+
"""
21+
Order2
22+
23+
[`Steffensen`](@ref) with a guard on the secant step.
24+
"""
2025
struct Order2 <: AbstractSecantMethod end
2126

2227
function update_state(

src/Roots.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
"""
2+
`Roots`. A package for solving `f(x) = 0` for univariate, scalar functions.
3+
4+
The basic methods are
5+
* [`find_zero`](@ref) for using one of several methods to identify a zero
6+
* [`ZeroProblem`](@ref) for solving for a zero using the `CommonSolve` interface
7+
* [`find_zeros`](@ref) for heuristically identifying all zeros in a specified interval
8+
"""
19
module Roots
210

311
if isdefined(Base, :Experimental) && isdefined(Base.Experimental, Symbol("@optlevel"))

src/alternative_interfaces.jl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ See also `Roots.newton((f,fp), x0)` and `Roots.newton(fΔf, x0)` for simpler imp
2626
newton(f, fp, x0; kwargs...) = find_zero((f, fp), x0, Newton(); kwargs...)
2727

2828
## --------------------------------------------------
29-
29+
#=
3030
"""
3131
Roots.halley(f, fp, fpp, x0; kwargs...)
3232
@@ -50,8 +50,10 @@ Keyword arguments are passed to `find_zero` using the `Roots.Halley()` method.
5050
5151
5252
"""
53+
=#
5354
halley(f, fp, fpp, x0; kwargs...) = find_zero((f, fp, fpp), x0, Halley(); kwargs...)
5455

56+
#=
5557
"""
5658
Roots.quadratic_inverse(f, fp, fpp, x0; kwargs...)
5759
@@ -75,6 +77,7 @@ Keyword arguments are passed to `find_zero` using the `Roots.QuadraticInverse()`
7577
7678
7779
"""
80+
=#
7881
quadratic_inverse(f, fp, fpp, x0; kwargs...) =
7982
find_zero((f, fp, fpp), x0, QuadraticInverse(); kwargs...)
8083

@@ -245,17 +248,14 @@ end
245248

246249
## fzeros
247250
"""
248-
249-
`fzeros(f, a, b; kwargs...)`
251+
fzeros(f, a, b; kwargs...)
252+
fzeros(f, ab; kwargs...)
250253
251254
Searches for all zeros of `f` within an interval `(a,b)`. Assume neither `a` or `b` is a zero.
252255
253-
Dispatches to `find_zeros(f, a, b; kwargs...)`.
256+
Compatability interface for [`find_zeros`](@ref).
254257
"""
255258
function fzeros(f, a::Number, b::Number; kwargs...)
256259
find_zeros(FnWrapper(f), float(a), float(b); kwargs...)
257260
end
258-
fzeros(f, bracket::Vector{T}; kwargs...) where {T<:Number} =
259-
fzeros(f, bracket[1], bracket[2]; kwargs...)
260-
fzeros(f, bracket::Tuple{T,S}; kwargs...) where {T<:Number,S<:Number} =
261-
fzeros(f, bracket[1], bracket[2]; kwargs...)
261+
fzeros(f, ab; kwargs...) = fzeros(f, _extrema(ab)...; kwargs...)

0 commit comments

Comments
 (0)