Skip to content

Commit 7740d0a

Browse files
authored
Update documents (#96)
* rename besselroots to approx_besselroots * add warning for compatibility of besselroots * use DocMeta.setdocmeta! instead of setup = * add test for besselroots * update benchmark.md to generate results automatically * fix typo in besselroots.jl * move some texts from README.md to docs/src/*.md * update ci.yml to trigger ci with release * update ci.yml for jldoctest * update ci.yml again for jldoctest * update autogeneration of benchmark * add more (a)repl block * bump version to v0.4.7
1 parent 770bdd6 commit 7740d0a

20 files changed

Lines changed: 109 additions & 173 deletions

.github/workflows/ci.yml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
name: CI
22
on:
3-
- push
4-
- pull_request
3+
pull_request:
4+
branches:
5+
- master
6+
push:
7+
branches:
8+
- master
9+
tags: '*'
510
jobs:
611
test:
712
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }}
@@ -56,8 +61,9 @@ jobs:
5661
Pkg.instantiate()'
5762
- run: |
5863
julia --project=docs -e '
59-
using Documenter: doctest
64+
using Documenter
6065
using FastGaussQuadrature
66+
DocMeta.setdocmeta!(FastGaussQuadrature, :DocTestSetup, :(using LinearAlgebra, SpecialFunctions, FastGaussQuadrature))
6167
doctest(FastGaussQuadrature)'
6268
- run: julia --project=docs docs/make.jl
6369
env:

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "FastGaussQuadrature"
22
uuid = "442a2c76-b920-505d-bb47-c5924d526838"
3-
version = "0.4.6"
3+
version = "0.4.7"
44

55
[deps]
66
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"

README.md

Lines changed: 0 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -17,93 +17,6 @@ For a quirky account on the history of computing Gauss-Legendre quadrature, see
1717
* The fastest Julia code for Gauss quadrature nodes and weights (without tabulation).
1818
* Change the perception that Gauss quadrature rules are expensive to compute.
1919

20-
## Examples
21-
Here we compute `100000` nodes and weights of the Gauss rules.
22-
Try a million or ten million.
23-
24-
```julia
25-
julia> @time gausschebyshev( 100000 );
26-
0.001788 seconds (4 allocations: 1.526 MiB)
27-
28-
julia> @time gausslegendre( 100000 );
29-
0.002976 seconds (10 allocations: 2.289 MiB)
30-
31-
julia> @time gaussjacobi( 100000, .9, -.1 );
32-
0.894373 seconds (3.59 k allocations: 1.255 GiB, 36.38% gc time)
33-
34-
julia> @time gaussradau( 100000 );
35-
0.684122 seconds (3.59 k allocations: 1.256 GiB, 21.71% gc time)
36-
37-
julia> @time gausslobatto( 100000 );
38-
0.748166 seconds (3.57 k allocations: 1.256 GiB, 27.78% gc time)
39-
40-
julia> @time gausslaguerre( 100000 );
41-
0.156867 seconds (7 allocations: 2.292 MiB)
42-
43-
julia> @time gausshermite( 100000 );
44-
0.175055 seconds (386 allocations: 67.916 MiB, 9.18% gc time)
45-
```
46-
47-
The paper [[1]](http://epubs.siam.org/doi/abs/10.1137/140954969) computed a billion Gauss-Legendre nodes.
48-
So here we will do a billion + 1.
49-
```julia
50-
julia> @time gausslegendre( 1000000001 );
51-
24.441304 seconds (10 allocations: 22.352 GiB, 2.08% gc time)
52-
```
53-
(The nodes near the endpoints coalesce in 16-digits of precision.)
54-
55-
## The algorithm for Gauss-Chebyshev
56-
There are four kinds of Gauss-Chebyshev quadrature rules, corresponding to four weight functions:
57-
58-
1. 1st kind, weight function `w(x) = 1/sqrt(1-x^2)`
59-
60-
2. 2nd kind, weight function `w(x) = sqrt(1-x^2)`
61-
62-
3. 3rd kind, weight function `w(x) = sqrt((1+x)/(1-x))`
63-
64-
4. 4th kind, weight function `w(x) = sqrt((1-x)/(1+x))`
65-
66-
They are all have explicit simple formulas for the nodes and weights [[4]](https://books.google.co.jp/books?id=8FHf0P3to0UC).
67-
68-
## The algorithm for Gauss-Legendre
69-
Gauss quadrature for the weight function `w(x) = 1`.
70-
71-
* For `n ≤ 5`: Use an analytic expression.
72-
* For `n ≤ 60`: Use Newton's method to solve `Pₙ(x)=0`. Evaluate Legendre polynomials `Pₙ` and their derivatives `Pₙ'` by 3-term recurrence. Weights are related to `Pₙ'`.
73-
* For `n > 60`: Use asymptotic expansions for the Legendre nodes and weights [[1]](http://epubs.siam.org/doi/abs/10.1137/140954969).
74-
75-
## The algorithm for Gauss-Jacobi
76-
Gauss quadrature for the weight functions `w(x) = (1-x)^a(1+x)^b`, `a,b > -1`.
77-
78-
* For `n ≤ 100`: Use Newton's method to solve `Pₙ(x)=0`. Evaluate `Pₙ` and `Pₙ'` by three-term recurrence.
79-
* For `n > 100`: Use Newton's method to solve `Pₙ(x)=0`. Evaluate `Pₙ` and `Pₙ'` by an asymptotic expansion (in the interior of `[-1,1]`) and the three-term recurrence `O(n^-2)` close to the endpoints. (This is a small modification to the algorithm described in [[3]](http://epubs.siam.org/doi/abs/10.1137/120889873).)
80-
* For `max(a,b) > 5`: Use the Golub-Welsch algorithm requiring `O(n^2)` operations.
81-
82-
## The algorithm for Gauss-Radau
83-
Gauss quadrature for the weight function `w(x)=1`, except the endpoint `-1` is included as a quadrature node.
84-
85-
The Gauss-Radau nodes and weights can be computed via the `(0,1)` Gauss-Jacobi nodes and weights[[3]](http://epubs.siam.org/doi/abs/10.1137/120889873).
86-
87-
## The algorithm for Gauss-Lobatto
88-
Gauss quadrature for the weight function `w(x)=1`, except the endpoints `-1` and `1` are included as nodes.
89-
90-
The Gauss-Lobatto nodes and weights can be computed via the `(1,1)` Gauss-Jacobi nodes and weights[[3]](http://epubs.siam.org/doi/abs/10.1137/120889873).
91-
92-
## The algorithm for Gauss-Laguerre
93-
Gauss quadrature for the weight function `w(x) = exp(-x)` on `[0,Inf)`
94-
95-
* For `n < 128`: Use the Golub-Welsch algorithm.
96-
* For `method=GLR`: Use the Glaser-Lui-Rohklin algorithm. Evaluate Laguerre polynomials `Lₙ` and their derivatives `Lₙ'` by using Taylor series expansions near roots generated by solving the second-order differential equation that `Lₙ` satisfies, see [[2]](http://epubs.siam.org/doi/pdf/10.1137/06067016X).
97-
* For `n ≥ 128`: Use a Newton procedure on Riemann-Hilbert asymptotics of Laguerre polynomials, see [5], based on [8]. There are some heuristics to decide which expression to use, it allows a general weight `w(x) = x^alpha exp(-q_m x^m)` and this is O(sqrt(n)) when allowed to stop when the weights are below the smallest positive floating point number.
98-
99-
## The algorithm for Gauss-Hermite
100-
Gauss quadrature for the weight function `w(x) = exp(-x^2)` on the real line.
101-
102-
* For `n < 200`: Use Newton's method to solve `Hₙ(x)=0`. Evaluate Hermite polynomials `Hₙ` and their derivatives `Hₙ'` by three-term recurrence.
103-
* For `n ≥ 200`: Use Newton's method to solve `Hₙ(x)=0`. Evaluate `Hₙ` and `Hₙ'` by a uniform asymptotic expansion, see [[7]](http://arxiv.org/abs/1410.5286).
104-
105-
The paper [[7]](http://arxiv.org/abs/1410.5286) also derives an `O(n)` algorithm for generalized Gauss-Hermite nodes and weights associated to weight functions of the form `exp(-V(x))`, where `V(x)` is a real polynomial.
106-
10720
## Example usage
10821
```julia
10922
julia> @time nodes, weights = gausslegendre( 100000 );
@@ -114,20 +27,3 @@ julia> @time dot( weights, nodes.^2 )
11427
0.000184 seconds (7 allocations: 781.422 KiB)
11528
0.6666666666666665
11629
```
117-
118-
## References:
119-
[1] I. Bogaert, ["Iteration-free computation of Gauss-Legendre quadrature nodes and weights"](http://epubs.siam.org/doi/abs/10.1137/140954969), SIAM J. Sci. Comput., 36(3), A1008-A1026, 2014.
120-
121-
[2] A. Glaser, X. Liu, and V. Rokhlin. ["A fast algorithm for the calculation of the roots of special functions."](http://epubs.siam.org/doi/pdf/10.1137/06067016X) SIAM J. Sci. Comput., 29 (2007), 1420-1438.
122-
123-
[3] N. Hale and A. Townsend, ["Fast and accurate computation of Gauss-Legendre and Gauss-Jacobi quadrature nodes and weights"](http://epubs.siam.org/doi/abs/10.1137/120889873), SIAM J. Sci. Comput., 2012.
124-
125-
[4] J. C. Mason and D. C. Handscomb, ["Chebyshev Polynomials"](https://books.google.co.jp/books?id=8FHf0P3to0UC), CRC Press, 2002.
126-
127-
[5] P. Opsomer, (in preparation).
128-
129-
[6] A. Townsend, [The race for high order Gauss-Legendre quadrature](http://pi.math.cornell.edu/~ajt/papers/QuadratureEssay.pdf), in SIAM News, March 2015.
130-
131-
[7] A. Townsend, T. Trogdon, and S. Olver, ["Fast computation of Gauss quadrature nodes and weights on the whole real line"](http://arxiv.org/abs/1410.5286), to appear in IMA Numer. Anal., 2014.
132-
133-
[8] M. Vanlessen, "Strong asymptotics of Laguerre-Type orthogonal polynomials and applications in Random Matrix Theory", Constr. Approx., 25:125-175, 2007.

docs/Project.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
[deps]
2+
BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
23
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
34
FastGaussQuadrature = "442a2c76-b920-505d-bb47-c5924d526838"
45
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"

docs/make.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
using Documenter
22
using FastGaussQuadrature
33

4+
# Setup for doctests in docstrings
5+
DocMeta.setdocmeta!(FastGaussQuadrature, :DocTestSetup, :(using LinearAlgebra, SpecialFunctions, FastGaussQuadrature))
6+
47
makedocs(;
58
modules = [FastGaussQuadrature],
69
format = Documenter.HTML(

docs/src/benchmark.md

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,23 @@
33
Here we compute `100000` nodes and weights of the Gauss rules.
44
Try a million or ten million.
55

6-
```julia
7-
julia> @time gausschebyshev( 100000 );
8-
0.001788 seconds (4 allocations: 1.526 MiB)
9-
10-
julia> @time gausslegendre( 100000 );
11-
0.002976 seconds (10 allocations: 2.289 MiB)
12-
13-
julia> @time gaussjacobi( 100000, .9, -.1 );
14-
0.894373 seconds (3.59 k allocations: 1.255 GiB, 36.38% gc time)
15-
16-
julia> @time gaussradau( 100000 );
17-
0.684122 seconds (3.59 k allocations: 1.256 GiB, 21.71% gc time)
18-
19-
julia> @time gausslobatto( 100000 );
20-
0.748166 seconds (3.57 k allocations: 1.256 GiB, 27.78% gc time)
21-
22-
julia> @time gausslaguerre( 100000 );
23-
0.156867 seconds (7 allocations: 2.292 MiB)
24-
25-
julia> @time gausshermite( 100000 );
26-
0.175055 seconds (386 allocations: 67.916 MiB, 9.18% gc time)
6+
```@repl
7+
using LinearAlgebra, BenchmarkTools, FastGaussQuadrature
8+
@btime gausschebyshev(100000);
9+
@btime gausslegendre(100000);
10+
@btime gaussjacobi(100000, 0.9, -0.1);
11+
@btime gaussradau(100000);
12+
@btime gausslobatto(100000);
13+
@btime gausslaguerre(100000);
14+
@btime gausshermite(100000);
2715
```
2816

2917
The paper [[1]](http://epubs.siam.org/doi/abs/10.1137/140954969) computed a billion Gauss-Legendre nodes.
3018
So here we will do a billion + 1.
19+
3120
```julia
32-
julia> @time gausslegendre( 1000000001 );
33-
24.441304 seconds (10 allocations: 22.352 GiB, 2.08% gc time)
21+
julia> @btime gausslegendre(1000000001);
22+
23.363 s (10 allocations: 22.35 GiB)
3423
```
24+
3525
(The nodes near the endpoints coalesce in 16-digits of precision.)

docs/src/besselroots.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# Roots of Bessel function
22

3-
Since [SpecialFunctions.jl](https://github.com/JuliaMath/SpecialFunctions.jl) doesn't have a method to calculate roots of [Bessel function](https://en.wikipedia.org/wiki/Bessel_function), we implemented `besselroots`.
3+
Since [SpecialFunctions.jl](https://github.com/JuliaMath/SpecialFunctions.jl) doesn't have a method to calculate roots of [Bessel function](https://en.wikipedia.org/wiki/Bessel_function), we implemented `approx_besselroots`.
44

55
```@docs
6-
besselroots(ν::Real, n::Integer)
6+
approx_besselroots(ν::Real, n::Integer)
77
```
88

9-
This method `besselroots` is used to calculate `gaussjacobi` and `gausslaguerre`.
9+
This method `approx_besselroots` is used to calculate `gaussjacobi` and `gausslaguerre`.

docs/src/gaussquadrature.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,36 @@
22

33

44
## Gauss-Legendre quadrature
5+
Gauss quadrature for the weight function ``w(x) = 1``.
6+
7+
* For ``n ≤ 5``: Use an analytic expression.
8+
* For ``n ≤ 60``: Use Newton's method to solve ``P_n(x)=0``. Evaluate Legendre polynomials ``P_n`` and their derivatives ``P_n'`` by 3-term recurrence. Weights are related to ``P_n'``.
9+
* For ``n > 60``: Use asymptotic expansions for the Legendre nodes and weights [[1]](http://epubs.siam.org/doi/abs/10.1137/140954969).
510

611
```@docs
712
gausslegendre(n::Integer)
813
```
914

1015

1116
## Gauss-Hermite quadrature
17+
Gauss quadrature for the weight function ``w(x) = \exp(-x^2)`` on the real line.
18+
19+
* For ``n < 200``: Use Newton's method to solve ``H_n(x)=0``. Evaluate Hermite polynomials ``H_n`` and their derivatives ``H_n'`` by three-term recurrence.
20+
* For ``n ≥ 200``: Use Newton's method to solve ``H_n(x)=0``. Evaluate ``H_n`` and ``H_n'`` by a uniform asymptotic expansion, see [[7]](http://arxiv.org/abs/1410.5286).
21+
22+
The paper [[7]](http://arxiv.org/abs/1410.5286) also derives an ``O(n)`` algorithm for generalized Gauss-Hermite nodes and weights associated to weight functions of the form ``\exp(-V(x))``, where ``V(x)`` is a real polynomial.
1223

1324
```@docs
1425
gausshermite(n::Integer)
1526
```
1627

1728

1829
## Gauss-Laguerre quadrature
30+
Gauss quadrature for the weight function ``w(x) = \exp(-x)`` on ``[0,+\infty)``
31+
32+
* For ``n < 128``: Use the Golub-Welsch algorithm.
33+
* For `method=GLR`: Use the Glaser-Lui-Rohklin algorithm. Evaluate Laguerre polynomials ``L_n`` and their derivatives ``L_n'`` by using Taylor series expansions near roots generated by solving the second-order differential equation that ``L_n`` satisfies, see [[2]](http://epubs.siam.org/doi/pdf/10.1137/06067016X).
34+
* For ``n ≥ 128``: Use a Newton procedure on Riemann-Hilbert asymptotics of Laguerre polynomials, see [5], based on [8]. There are some heuristics to decide which expression to use, it allows a general weight ``w(x) = x^\alpha \exp(-q_m x^m)`` and this is ``O(\sqrt{n})`` when allowed to stop when the weights are below the smallest positive floating point number.
1935

2036
```@docs
2137
gausslaguerre(n::Integer)
@@ -27,27 +43,46 @@ gausslaguerre(n::Integer, α::Real)
2743

2844

2945
## Gauss-Chebyshev quadrature
46+
There are four kinds of Gauss-Chebyshev quadrature rules, corresponding to four weight functions:
47+
48+
* 1st kind, weight function ``w(x) = 1/\sqrt{1-x^2}``
49+
* 2nd kind, weight function ``w(x) = \sqrt{1-x^2}``
50+
* 3rd kind, weight function ``w(x) = \sqrt{(1+x)/(1-x)}``
51+
* 4th kind, weight function ``w(x) = \sqrt{(1-x)/(1+x)}``
52+
53+
They are all have explicit simple formulas for the nodes and weights [[4]](https://books.google.co.jp/books?id=8FHf0P3to0UC).
3054

3155
```@docs
3256
gausschebyshev(n::Integer, kind::Integer)
3357
```
3458

3559

3660
## Gauss-Jacobi quadrature
61+
Gauss quadrature for the weight functions ``w(x) = (1-x)^\alpha(1+x)^\beta``, ``\alpha,\beta > -1``.
62+
63+
* For ``n ≤ 100``: Use Newton's method to solve ``P_n(x)=0``. Evaluate ``P_n`` and ``P_n'`` by three-term recurrence.
64+
* For ``n > 100``: Use Newton's method to solve ``P_n(x)=0``. Evaluate ``P_n`` and ``P_n'`` by an asymptotic expansion (in the interior of ``[-1,1]``) and the three-term recurrence ``O(n^{-2})`` close to the endpoints. (This is a small modification to the algorithm described in [[3]](http://epubs.siam.org/doi/abs/10.1137/120889873).)
65+
* For ``max(a,b) > 5``: Use the Golub-Welsch algorithm requiring ``O(n^2)`` operations.
3766

3867
```@docs
3968
gaussjacobi(n::Integer, α::Real, β::Real)
4069
```
4170

4271

4372
## Gauss-Radau quadrature
73+
Gauss quadrature for the weight function ``w(x)=1``, except the endpoint ``-1`` is included as a quadrature node.
74+
75+
The Gauss-Radau nodes and weights can be computed via the ``(0,1)`` Gauss-Jacobi nodes and weights[[3]](http://epubs.siam.org/doi/abs/10.1137/120889873).
4476

4577
```@docs
4678
gaussradau(n::Integer)
4779
```
4880

4981

5082
## Gauss-Lobatto quadrature
83+
Gauss quadrature for the weight function ``w(x)=1``, except the endpoints ``-1`` and ``1`` are included as nodes.
84+
85+
The Gauss-Lobatto nodes and weights can be computed via the ``(1,1)`` Gauss-Jacobi nodes and weights[[3]](http://epubs.siam.org/doi/abs/10.1137/120889873).
5186

5287
```@docs
5388
gausslobatto(n::Integer)

docs/src/index.md

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,11 @@ To check an integral
2020
\int_{-1}^{1} x^4 dx = \frac{2}{5}
2121
```
2222
by numerically, try following code.
23-
```julia
24-
julia> using FastGaussQuadrature, LinearAlgebra
2523

26-
julia> x, w = gausslegendre(3);
27-
28-
julia> f(x) = x^4;
29-
30-
julia> I = dot(w, f.(x));
31-
32-
julia> I 2/5
33-
true
24+
```@repl
25+
using FastGaussQuadrature, LinearAlgebra
26+
x, w = gausslegendre(3)
27+
f(x) = x^4
28+
I = dot(w, f.(x))
29+
I ≈ 2/5
3430
```

src/FastGaussQuadrature.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export gausshermite
1111
export gaussjacobi
1212
export gausslobatto
1313
export gaussradau
14+
export approx_besselroots
1415
export besselroots
1516

1617
import SpecialFunctions: besselj, airyai, airyaiprime

0 commit comments

Comments
 (0)