Skip to content

Commit

Permalink
bump major version for breaking changes (#287)
Browse files Browse the repository at this point in the history
* bump major version for breaking changes

* Bracketing cleanup (#288)

* update bisection: remove BisectionExact, Accelerated; rework assess_convergence, ...

* clean up alefeld potra shi; tolerances for FalsePosition(12)

* fix errors (#290)

* bracketing edits; change halley <: newton (#291)

* code cleanup (#292)

* Cleanup find zero (#293)

* change to iterator interface, could deprecate

* more consistent naming

* remove deprecated run_bisection

* change default solves for `solve(::ZeroProblem)`, update documentation

* remove maxfnevals from tolerances which is no longer used

* Cleanup convergence (#295)

* remove BisectionExact

* check for exact zero (#296)

* check f==0 and f~ 0 separately

* use different format string for printing values (#299)

* break out hybrid from Order0; fix logging bug (#298)

* Cleanup trace unicode (#300)

* use unicode subscripts when displaying trace

* clean up tracks, add generics, improve docs

* minor documentation edits (#301)

* special case bisection (#302)

* cleanup (#304)

* fix error seen in lith docs

* add test for v1.6; allow v1.0.X to fail (#306)

* testing fix

* Cleanup ci (#307)

* avoid inferred for < v1.6.0

* maxevals -> maxiters; allow old use

* add nan(T) method

* copy edit

* Mark deprecations (#289) (#310)
  • Loading branch information
jverzani committed Apr 8, 2022
1 parent a9f675b commit 01f4ec4
Show file tree
Hide file tree
Showing 45 changed files with 1,123 additions and 1,270 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ jobs:
fail-fast: false
matrix:
version:
- '1.0' # lowest supported version
- '1.0' # lowest supported version; though possibly with errors
- '1.6' # LTS support
- '1' # last released version
os:
- ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ docs/build
docs/site
test/benchmarks.json
Manifest.toml
TODO.md
TODO.md
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "Roots"
uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665"
version = "1.4.1"
version = "2.0.0"

[deps]
CommonSolve = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2"
Expand Down
31 changes: 20 additions & 11 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,17 @@ primary interface. It supports various algorithms through the
specification of a method. These include:

* Bisection-like algorithms. For functions where a bracketing interval
is known (one where ``f(a)`` and ``f(b)`` have alternate signs), the
`Bisection` method can be specified. For most floating point number
types, bisection occurs in a manner exploiting floating point
storage conventions. For others, an algorithm of Alefeld, Potra, and
Shi is used. These methods are guaranteed to converge. Methods
include `Bisection`, `Roots.A42`, `Roots.AlefeldPotraShi`,
`Roots.Brent`, and ``12``-flavors of `FalsePosition`.
is known (one where ``f(a)`` and ``f(b)`` have alternate signs),
there are several bracketing methods, including `Bisection`. For
most floating point number types, bisection occurs in a manner
exploiting floating point storage conventions leading to an exact
zero or a bracketing interval as small as floating point
computations allows. Other methods include `Roots.A42`,
`Roots.AlefeldPotraShi`, `Roots.Brent`, `Roots.Chandrapatlu`,
`Roots.ITP`, `Roots.Ridders`, and ``12``-flavors of
`FalsePosition`. The default bracketing method is `Bisection`, as it
is more robust to some inputs, but `A42` and `AlefeldPotraShi`
typically converge in a few iterations and are more performant.


* Several derivative-free methods are implemented. These are specified
Expand All @@ -34,10 +38,15 @@ specification of a method. These include:
multiplicity of the zero.


* There are historic methods that require a derivative or two:
`Roots.Newton` and `Roots.Halley`. `Roots.Schroder` provides a
quadratic method, like Newton's method, which is independent of the
multiplicity of the zero.
* There are methods that require a derivative or two: `Roots.Newton`,
`Roots.Halley` are classical ones, `Roots.QuadraticInverse`,
`Roots.ChebyshevLike`, `Roots.SuperHaller` are others.
`Roots.Schroder` provides a quadratic method, like Newton's method,
which is independent of the multiplicity of the zero. The
`Roots.ThukralXB`, `X=2`, `3`, `4`, or `5` are also multiplicity
three. The `X` denotes the number of derivatives that need
specifying. The `Roots.LithBoonkkampIJzerman{S,D}` methods remember
`S` steps and use `D` derivatives.



Expand Down
6 changes: 3 additions & 3 deletions docs/src/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ find_zero
find_zeros
```

### CommonSolve interface
## CommonSolve interface

The problem-algorithm-solve interface is a pattern popularized in `Julia` by the `DifferentialEquations.jl` suite of packages. This can be used as an alternative to `find_zero`. Unlike `find_zero`, `solve` will return `NaN` on non-convergence.

Expand Down Expand Up @@ -141,7 +141,7 @@ Roots.LithBoonkkampIJzermanBracket

The order of convergence for most methods is for *simple* zeros, values ``\alpha`` where ``f(x) = (x-\alpha) \cdot g(x)``, with ``g(\alpha)`` being non-zero. For methods which are of order ``k`` for non-simple zeros, usually an additional function call is needed per step. For example, this is the case for `Roots.Newton` as compared to `Roots.Schroder`.

Derivative-free methods for non-simple zeros have the following implemented
Derivative-free methods for non-simple zeros have the following implemented:

```@docs
Roots.King
Expand Down Expand Up @@ -258,7 +258,7 @@ When an algorithm returns a `NaN` value, it terminates. This can happen nea
The use of relative tolerances to check if ``f(x) \approx 0`` can lead to spurious answers where ``x`` is very large (and hence the relative tolerance is large). The return of very large solutions should be checked against expectations of the answer.


Deciding if an algorithm won't terminate is done through counting the number or iterations performed; the default adjusted through `maxevals`. As most algorithms are superlinear, convergence happens rapidly near the answer, but all the algorithms can take a while to get near an answer, even when progress is made. As such, the maximum must be large enough to consider linear cases, yet small enough to avoid too many steps when an algorithm is non-convergent.
Deciding if an algorithm won't terminate is done through counting the number or iterations performed; the default adjusted through `maxiters`. As most algorithms are superlinear, convergence happens rapidly near the answer, but all the algorithms can take a while to get near an answer, even when progress is made. As such, the maximum must be large enough to consider linear cases, yet small enough to avoid too many steps when an algorithm is non-convergent.


Convergence criteria are method dependent and are determined by the `Roots.assess_convergence` methods.
Expand Down
38 changes: 19 additions & 19 deletions docs/src/roots.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ julia> x0, M = (0, pi/2), Bisection()
julia> find_zero(g, x0, M) # as before, solve cos(x) - x = 0 using default p=1
0.7390851332151607
julia> find_zero(g, x0, M, p=2) # solves cos(x) - x/2 = 0
julia> find_zero(g, x0, M; p=2) # solves cos(x) - x/2 = 0
1.0298665293222589
```

Expand Down Expand Up @@ -121,25 +121,25 @@ julia> find_zero(x -> Inf*sign(x), (-Inf, Inf)) # Float64 only

The basic algorithm used for bracketing when the values are simple
floating point values is a modification of the bisection method, where
the midpoint is taken over the bit representation of `a` and `b`. For
big float values, an algorithm due to Alefeld, Potra, and Shi is used.
the midpoint is taken over the bit representation of `a` and `b`.

```jldoctest roots
julia> find_zero(sin, (big(3), big(4))) # uses a different algorithm than for (3,4)
3.141592653589793238462643383279502884197169399375105820974944592307816406286198
```
For big float values, bisection is the default (with non-zero
tolerances), but its use is definitely not suggested. Simple
bisection over `BigFloat` values can take *many* more
iterations. For the problem of finding a zero of `sin` in the interval
`(big(3), big(4))`, the default bisection takes ``252`` iterations,
whereas the `A42` method takes ``4``.

(Simple bisection over `BigFloat` values can take *many* steps.)

The algorithms of Alefeld, Potra, and Shi and the well known algorithm of Brent, also start with a bracketing algorithm. For many problems these will take far fewer steps than the bisection algorithm to reach convergence. These may be called directly. For example,
The algorithms of Alefeld, Potra, and Shi and the well known algorithm
of Brent, also start with a bracketing algorithm. For many problems
these will take far fewer steps than the bisection algorithm to reach
convergence. These may be called directly. For example,

```jldoctest roots
julia> find_zero(sin, (3,4), A42())
3.141592653589793
```

The above call takes ``9`` function evaluations, the default method takes ``53``.


By default, bisection will converge to machine tolerance. This may
provide more accuracy than desired. A tolerance may be specified to
Expand Down Expand Up @@ -274,14 +274,14 @@ To investigate an algorithm and its convergence, the argument
For some functions, adjusting the default tolerances may be necessary
to achieve convergence. The tolerances include `atol` and `rtol`, which are
used to check if $f(x_n) \approx 0$;
`xatol` and `xrtol`, to check if $x_n \approx x_{n-1}$; and `maxevals` to limit the
number of steps in the algorithm.
`xatol` and `xrtol`, to check if $x_n \approx x_{n-1}$; and `maxiters` to limit the
number of iterations in the algorithm.



## Classical methods

The package provides some classical methods for root finding:
The package provides some classical methods for root finding, such as
`Roots.Newton`, `Roots.Halley`, and `Roots.Schroder`. (Currently
these are not exported, so must be prefixed with the package name to
be used.) We can see how each works on a problem studied by Newton.
Expand Down Expand Up @@ -401,10 +401,10 @@ julia> g(x, p=1) = cos(x) - x/p;
julia> Z = ZeroProblem(g, (0.0, pi/2))
ZeroProblem{typeof(g), Tuple{Float64, Float64}}(g, (0.0, 1.5707963267948966))
julia> solve(Z, Secant(), 2) # uses p=2
julia> solve(Z, Secant(); p=2) # uses p=2
1.0298665293222589
julia> solve(Z, Bisection(), 3, xatol=1/16) # p=3; uses keywords for tolerances
julia> solve(Z, Bisection(); p=3, xatol=1/16) # p=3; uses keywords for tolerances
1.1959535058744393
```

Expand Down Expand Up @@ -1007,7 +1007,7 @@ julia> function Roots.update_state(::Chandrapatla, F, o, options, l=NullTracks()
b, a, c = o.xn1, o.xn0, o.c
fb, fa, fc = o.fxn1, o.fxn0, o.fc

# encoding: a = xₙ, b=xₙ₋₁, c= xₙ₋₂
# encoding: a = xₙ, b = xₙ₋₁, c = xₙ₋₂
ξ = (a - b) / (c - b)
ϕ = (fa - fb) / (fc - fb)
ϕ² = ϕ^2
Expand Down Expand Up @@ -1038,7 +1038,7 @@ end

```

This algorithm chooses between an inverse quadratic step or a bisection step depending on the relationship between the computed `ξ` and `Φ`. The tolerances are from the default for `AbstractAcceleratedBisection`, which choose `eps(T)^2` for the absolute ``x``-tolerance and `eps(t)` for the relative ``x``-tolerance.
This algorithm chooses between an inverse quadratic step or a bisection step depending on the relationship between the computed `ξ` and `Φ`. The tolerances are from the default for `AbstractBracketingMethod`.


To see that the algorithm works, we have:
Expand Down
23 changes: 0 additions & 23 deletions src/Bracketing/accelerated_bisection.jl

This file was deleted.

2 comments on commit 01f4ec4

@jverzani
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/58152

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v2.0.0 -m "<description of version>" 01f4ec4306cb05952092733bfcadd6b10089a913
git push origin v2.0.0

Please sign in to comment.