Skip to content

Commit e885626

Browse files
convert remaining examples
remove stale references add generated folder to gitignore
1 parent 783b6dc commit e885626

File tree

10 files changed

+172
-121
lines changed

10 files changed

+172
-121
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
docs/build/
2-
docs/site/
2+
docs/src/generated
33
deps/build.log
44
deps/libfasttransforms.*
55
.DS_Store

README.md

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -157,18 +157,8 @@ julia> @time norm(ipaduatransform(paduatransform(v)) - v)/norm(v)
157157

158158
# References:
159159

160-
[1] B. Alpert and V. Rokhlin. <a href="http://dx.doi.org/10.1137/0912009">A fast algorithm for the evaluation of Legendre expansions</a>, *SIAM J. Sci. Stat. Comput.*, **12**:158—179, 1991.
160+
[1] D. Ruiz—Antolín and A. Townsend. <a href="https://doi.org/10.1137/17M1134822">A nonuniform fast Fourier transform based on low rank approximation</a>, *SIAM J. Sci. Comput.*, **40**:A529–A547, 2018.
161161

162-
[2] N. Hale and A. Townsend. <a href="http://dx.doi.org/10.1137/130932223">A fast, simple, and stable Chebyshev—Legendre transform using an asymptotic formula</a>, *SIAM J. Sci. Comput.*, **36**:A148—A167, 2014.
162+
[2] R. M. Slevinsky. <a href="https://doi.org/10.1016/j.acha.2017.11.001">Fast and backward stable transforms between spherical harmonic expansions and bivariate Fourier series</a>, *Appl. Comput. Harmon. Anal.*, **47**:585—606, 2019.
163163

164-
[3] J. Keiner. <a href="http://dx.doi.org/10.1137/070703065">Computing with expansions in Gegenbauer polynomials</a>, *SIAM J. Sci. Comput.*, **31**:2151—2171, 2009.
165-
166-
[4] D. Ruiz—Antolín and A. Townsend. <a href="https://arxiv.org/abs/1701.04492">A nonuniform fast Fourier transform based on low rank approximation</a>, arXiv:1701.04492, 2017.
167-
168-
[5] R. M. Slevinsky. <a href="https://doi.org/10.1093/imanum/drw070">On the use of Hahn's asymptotic formula and stabilized recurrence for a fast, simple, and stable Chebyshev—Jacobi transform</a>, *IMA J. Numer. Anal.*, **38**:102—124, 2018.
169-
170-
[6] R. M. Slevinsky. <a href="https://doi.org/10.1016/j.acha.2017.11.001">Fast and backward stable transforms between spherical harmonic expansions and bivariate Fourier series</a>, *Appl. Comput. Harmon. Anal.*, **47**:585—606, 2019.
171-
172-
[7] R. M. Slevinsky, <a href="https://arxiv.org/abs/1711.07866">Conquering the pre-computation in two-dimensional harmonic polynomial transforms</a>, arXiv:1711.07866, 2017.
173-
174-
[8] A. Townsend, M. Webb, and S. Olver. <a href="https://doi.org/10.1090/mcom/3277">Fast polynomial transforms based on Toeplitz and Hankel matrices</a>, in press at *Math. Comp.*, 2017.
164+
[3] R. M. Slevinsky, <a href="https://arxiv.org/abs/1711.07866">Conquering the pre-computation in two-dimensional harmonic polynomial transforms</a>, arXiv:1711.07866, 2017.

docs/make.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,13 @@ const EXAMPLES_DIR = joinpath(@__DIR__, "..", "examples")
44
const OUTPUT_DIR = joinpath(@__DIR__, "src/generated")
55

66
examples = [
7+
"chebyshev.jl",
8+
"disk.jl",
9+
"nonlocaldiffusion.jl",
10+
"padua.jl",
711
"sphere.jl",
12+
"spinweighted.jl",
13+
"triangle.jl",
814
]
915

1016
for example in examples
@@ -20,7 +26,13 @@ makedocs(
2026
pages = Any[
2127
"Home" => "index.md",
2228
"Examples" => [
29+
"generated/chebyshev.md",
30+
"generated/disk.md",
31+
"generated/nonlocaldiffusion.md",
32+
"generated/padua.md",
2333
"generated/sphere.md",
34+
"generated/spinweighted.md",
35+
"generated/triangle.md",
2436
],
2537
]
2638
)

examples/chebyshev.jl

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,46 @@
1-
#############
1+
# # Chebyshev transform
22
# This demonstrates the Chebyshev transform and inverse transform,
33
# explaining precisely the normalization and points
4-
#############
54

65
using FastTransforms
7-
8-
# first kind points -> first kind polynomials
96
n = 20
7+
8+
# First kind points $\to$ first kind polynomials
109
p_1 = chebyshevpoints(Float64, n, Val(1))
1110
f = exp.(p_1)
1211
= chebyshevtransform(f, Val(1))
13-
1412
= x -> [cos(k*acos(x)) for k=0:n-1]' *
1513
(0.1) exp(0.1)
1614

17-
# first kind polynomials -> first kind points
15+
# First kind polynomials $\to$ first kind points
1816
ichebyshevtransform(f̌, Val(1)) exp.(p_1)
1917

20-
# second kind points -> first kind polynomials
18+
# Second kind points $\to$ first kind polynomials
2119
p_2 = chebyshevpoints(Float64, n, Val(2))
2220
f = exp.(p_2)
2321
= chebyshevtransform(f, Val(2))
24-
2522
= x -> [cos(k*acos(x)) for k=0:n-1]' *
2623
(0.1) exp(0.1)
2724

28-
# first kind polynomials -> second kind points
25+
# First kind polynomials $\to$ second kind points
2926
ichebyshevtransform(f̌, Val(2)) exp.(p_2)
3027

31-
32-
# first kind points -> second kind polynomials
33-
n = 20
28+
# First kind points $\to$ second kind polynomials
3429
p_1 = chebyshevpoints(Float64, n, Val(1))
3530
f = exp.(p_1)
3631
= chebyshevutransform(f, Val(1))
3732
= x -> [sin((k+1)*acos(x))/sin(acos(x)) for k=0:n-1]' *
3833
(0.1) exp(0.1)
3934

40-
# second kind polynomials -> first kind points
35+
# Second kind polynomials $\to$ first kind points
4136
ichebyshevutransform(f̌, Val(1)) exp.(p_1)
4237

43-
44-
# second kind points -> second kind polynomials
38+
# Second kind points $\to$ second kind polynomials
4539
p_2 = chebyshevpoints(Float64, n, Val(2))[2:n-1]
4640
f = exp.(p_2)
4741
= chebyshevutransform(f, Val(2))
4842
= x -> [sin((k+1)*acos(x))/sin(acos(x)) for k=0:n-3]' *
4943
(0.1) exp(0.1)
5044

51-
# second kind polynomials -> second kind points
45+
# Second kind polynomials $\to$ second kind points
5246
ichebyshevutransform(f̌, Val(2)) exp.(p_2)

examples/disk.jl

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,56 @@
1-
#############
1+
# Holomorphic integration
22
# In this example, we explore integration of a harmonic function:
3-
#
4-
# f(x,y) = (x^2-y^2+1)/[(x^2-y^2+1)^2+(2xy+1)^2],
5-
#
3+
# ```math
4+
# f(x,y) = \frac{x^2-y^2+1}{(x^2-y^2+1)^2+(2xy+1)^2},
5+
# ```
66
# over the unit disk. In this case, we know from complex analysis that the
7-
# integral of a holomorphic function is equal to π × f(0,0).
8-
# We analyze the function on an N×M tensor product grid defined by:
9-
#
10-
# rₙ = cos[(n+1/2)π/2N], for 0 ≤ n < N, and
11-
#
12-
# θₘ = 2π m/M, for 0 ≤ m < M;
13-
#
7+
# integral of a holomorphic function is equal to $\pi \times f(0,0)$.
8+
# We analyze the function on an $N\times M$ tensor product grid defined by:
9+
# ```math
10+
# \begin{aligned}
11+
# r_n & = \cos\left[(n+\tfrac{1}{2})\pi/2N],\quad{\rm for} 0\le n < N,\quad{\rm and}\\
12+
# \theta_m & = 2\pi m/M,\quad{\rm for}\quad 0\le m < M;
13+
# \end{aligned}
14+
# ```
1415
# we convert the function samples to Chebyshev×Fourier coefficients using
1516
# `plan_disk_analysis`; and finally, we transform the Chebyshev×Fourier
16-
# coefficients to disk harmonic coefficients using `plan_disk2cxf`.
17+
# coefficients to Zernike polynomial coefficients using `plan_disk2cxf`.
1718
#
18-
# For the storage pattern of the arrays, please consult the documentation.
19-
#############
19+
# For the storage pattern of the arrays, please consult the
20+
# [documentation](https://MikaelSlevinsky.github.io/FastTransforms).
2021

2122
using FastTransforms, LinearAlgebra
2223

24+
# Our function $f$ on the disk:
2325
f = (x,y) -> (x^2-y^2+1)/((x^2-y^2+1)^2+(2x*y+1)^2)
2426

27+
# The Zernike polynomial degree:
2528
N = 5
2629
M = 4N-3
2730

31+
# The radial grid:
2832
r = [sinpi((N-n-0.5)/(2N)) for n in 0:N-1]
29-
θ = (0:M-1)*2/M # mod π.
33+
34+
# The angular grid (mod $\pi$):
35+
θ = (0:M-1)*2/M
3036

3137
# On the mapped tensor product grid, our function samples are:
3238
F = [f(r*cospi(θ), r*sinpi(θ)) for r in r, θ in θ]
3339

40+
# We precompute a Zernike--Chebyshev×Fourier plan:
3441
P = plan_disk2cxf(F)
42+
43+
# And an FFTW Chebyshev×Fourier analysis plan on the disk:
3544
PA = plan_disk_analysis(F)
3645

3746
# Its Zernike coefficients are:
3847
U = P\(PA*F)
3948

40-
# The Zernike coefficients are useful for integration. The integral of f(x,y)
41-
# over the disk should be π/2 by harmonicity. The coefficient of Z_0^0
42-
# multiplied by √π is:
49+
# The Zernike coefficients are useful for integration. The integral of $f(x,y)$
50+
# over the disk should be $\pi/2$ by harmonicity. The coefficient of $Z_0^0$
51+
# multiplied by `√π` is:
4352
U[1, 1]*sqrt(π)
4453

45-
# Using an orthonormal basis, the integral of [f(x,y)]^2 over the disk is
54+
# Using an orthonormal basis, the integral of $[f(x,y)]^2$ over the disk is
4655
# approximately the square of the 2-norm of the coefficients:
4756
norm(U)^2

examples/nonlocaldiffusion.jl

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,39 @@
1+
# # Nonlocal diffusion on $\mathbb{S}^2$
2+
# This example calculates the spectrum of the nonlocal diffusion operator:
3+
# ```math
4+
# \mathcal{L}_\delta u = \int_{\mathbb{S}^2} \rho_\delta(|\mathbf{x}-\mathbf{y}|)\left[u(\mathbf{x}) - u(\mathbf{y})\right] \,\mathrm{d}\Omega(\mathbf{y}),
5+
# ```
6+
# defined in Eq. (2) of
7+
#
8+
# R. M. Slevinsky, H. Montanelli, and Q. Du, [A spectral method for nonlocal diffusion operators on the sphere](https://doi.org/10.1016/j.jcp.2018.06.024), *J. Comp. Phys.*, **372**:893--911, 2018.
9+
#
10+
# In the above, $0<\delta<2$, $-1<\alpha<1$, and the kernel:
11+
# ```math
12+
# \rho_\delta(|\mathbf{x}-\mathbf{y}|) = \frac{4(1+\alpha)}{\pi \delta^{2+2\alpha}} \frac{\chi_{[0,\delta]}(|\mathbf{x}-\mathbf{y}|)}{|\mathbf{x}-\mathbf{y}|^{2-2\alpha}},
13+
# ```
14+
# where $\chi_I(\cdot)$ is the indicator function on the set $I$.
15+
#
16+
# This nonlocal operator is diagonalized by spherical harmonics:
17+
# ```math
18+
# \mathcal{L}_\delta Y_\ell^m(\mathbf{x}) = \lambda_\ell(\alpha, \delta) Y_\ell^m(\mathbf{x}),
19+
# ```
20+
# and its eigenfunctions are given by the generalized Funk--Hecke formula:
21+
# ```math
22+
# \lambda_\ell(\alpha, \delta) = \frac{(1+\alpha) 2^{2+\alpha}}{\delta^{2+2\alpha}}\int_{1-\delta^2/2}^1 \left[P_\ell(t)-1\right] (1-t)^{\alpha-1} \,\mathrm{d} t.
23+
# ```
24+
# In the paper, the authors use Clenshaw--Curtis quadrature and asymptotic evaluation of Legendre polynomials to achieve $\mathcal{O}(n^2\log n)$ complexity for the evaluation of the first $n$ eigenvalues. With a change of basis, this complexity can be reduced to $\mathcal{O}(n\log n)$.
25+
#
26+
# First, we represent:
27+
# ```math
28+
# P_n(t) - 1 = \sum_{j=0}^{n-1} \left[P_{j+1}(t) - P_j(t)\right] = -\sum_{j=0}^{n-1} (1-t) P_j^{(1,0)}(t).
29+
# ```
30+
# Then, we represent $P_j^{(1,0)}(t)$ with Jacobi polynomials $P_i^{(\alpha,0)}(t)$ and we integrate using [DLMF 18.9.16](https://dlmf.nist.gov/18.9.16):
31+
# ```math
32+
# \int_x^1 P_i^{(\alpha,0)}(t)(1-t)^\alpha\,\mathrm{d}t = \left\{ \begin{array}{cc} \frac{(1-x)^{\alpha+1}}{\alpha+1} & \mathrm{for~}i=0,\\ \frac{1}{2i}(1-x)^{\alpha+1}(1+x)P_{i-1}^{(\alpha+1,1)}(x), & \mathrm{for~}i>0.\end{array}\right.
33+
# ```
34+
# The code below implements this algorithm, making use of the Jacobi--Jacobi transform `plan_jac2jac`.
35+
# For numerical stability, the conversion from Jacobi polynomials $P_j^{(1,0)}(t)$ to $P_i^{(\alpha,0)}(t)$ is divided into conversion from $P_j^{(1,0)}(t)$ to $P_k^{(0,0)}(t)$, before conversion from $P_k^{(0,0)}(t)$ to $P_i^{(\alpha,0)}(t)$.
36+
137
using FastTransforms, LinearAlgebra
238

339
function oprec!(n::Integer, v::AbstractVector, alpha::Real, delta2::Real)
@@ -13,19 +49,6 @@ function oprec!(n::Integer, v::AbstractVector, alpha::Real, delta2::Real)
1349
return v
1450
end
1551

16-
"""
17-
This example calculates the spectrum of the nonlocal diffusion operator:
18-
19-
```math
20-
ℒ_δ u = ∫_𝕊² ρ_δ(|𝐱-𝐲|)[u(𝐱) - u(𝐲)] dΩ(𝐲),
21-
```
22-
23-
defined in Eq. (2) of
24-
25-
R. M. Slevinsky, H. Montanelli, and Q. Du, A spectral method for nonlocal diffusion operators on the sphere, J. Comp. Phys., 372:893--911, 2018.
26-
27-
available at https://doi.org/10.1016/j.jcp.2018.06.024
28-
"""
2952
function evaluate_lambda(n::Integer, alpha::T, delta::T) where T
3053
delta2 = delta*delta
3154
scl = (1+alpha)*(2-delta2/2)
@@ -60,7 +83,11 @@ function evaluate_lambda(n::Integer, alpha::T, delta::T) where T
6083
return lambda
6184
end
6285

63-
lambda = evaluate_lambda(1024, -0.5, 1.0)
64-
lambdabf = evaluate_lambda(1024, parse(BigFloat, "-0.5"), parse(BigFloat, "1.0"))
86+
# The spectrum in `Float64`:
87+
lambda = evaluate_lambda(10, -0.5, 1.0)
88+
89+
# The spectrum in `BigFloat`:
90+
lambdabf = evaluate_lambda(10, parse(BigFloat, "-0.5"), parse(BigFloat, "1.0"))
6591

92+
# The $\infty$-norm relative error:
6693
norm(lambda-lambdabf, Inf)/norm(lambda, Inf)

examples/padua.jl

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
1-
#############
1+
# # Padua transform
22
# This demonstrates the Padua transform and inverse transform,
33
# explaining precisely the normalization and points
4-
#############
54

65
using FastTransforms
76

7+
# We define the Padua points and extract Cartesian components:
88
N = 15
99
pts = paduapoints(N)
10-
x = pts[:,1]; y = pts[:,2]
10+
x = pts[:,1];
11+
y = pts[:,2];
1112

13+
# We take the Padua transform of the function:
1214
f = (x,y) -> exp(x + cos(y))
13-
= paduatransform(f.(x , y))
15+
= paduatransform(f.(x , y));
16+
17+
# and use the coefficients to create an approximation to the function $f$:
1418
= (x,y) -> begin
1519
j = 1
1620
ret = 0.0
@@ -21,6 +25,8 @@ f̃ = (x,y) -> begin
2125
ret
2226
end
2327

28+
# At a particular point, is the function well-approximated?
2429
(0.1,0.2) f(0.1,0.2)
2530

31+
# Does the inverse transform bring us back to the grid?
2632
ipaduatransform(f̌) .(x,y)

examples/sphere.jl

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
# # Spherical harmonic addition theorem
22
# This example confirms numerically that
33
# ```math
4-
# \frac{P_4(z\cdot y) - P_4(x\cdot y)}{z\cdot y - x\cdot y},
4+
# f(z) = \frac{P_4(z\cdot y) - P_4(x\cdot y)}{z\cdot y - x\cdot y},
55
# ```
6-
#
76
# is actually a degree-$3$ polynomial on $\mathbb{S}^2$, where $P_4$ is the degree-$4$
87
# Legendre polynomial, and $x,y,z \in \mathbb{S}^2$.
98
# To verify, we sample the function on a $5\times9$ equiangular grid
109
# defined by:
1110
# ```math
12-
# \theta_n = (n+\frac{1}{2})\pi/N,\quad{\rm for}\quad 0\le n < N,\quad{\rm and}
13-
# ```
14-
# ```math
15-
# \varphi_m = 2\pi m/M,\quad{\rm for}\quad 0\le m < M;
11+
# \begin{aligned}
12+
# \theta_n & = (n+\tfrac{1}{2})\pi/N,\quad{\rm for}\quad 0\le n < N,\quad{\rm and}\\
13+
# \varphi_m & = 2\pi m/M,\quad{\rm for}\quad 0\le m < M;
14+
# \end{aligned}
1615
# ```
1716
# we convert the function samples to Fourier coefficients using
1817
# `plan_sph_analysis`; and finally, we transform
@@ -88,12 +87,10 @@ U4 = threshold!(P\V, 3*eps())
8887

8988
# That nonnegligible coefficient should be approximately `√(2π/(4+1/2))`,
9089
# since the convention in this library is to orthonormalize.
91-
9290
nrm2 = norm(U4)
9391

9492
# Note that the integrals of both functions $P_4(z\cdot y)$ and $P_4(z\cdot x)$ and their
9593
# $L^2(\mathbb{S}^2)$ norms are the same because of rotational invariance. The integral of
9694
# either is perhaps not interesting as it is mathematically zero, but the norms
9795
# of either should be approximately the same.
98-
9996
nrm1 nrm2

0 commit comments

Comments
 (0)