Skip to content

Commit cfae853

Browse files
Update sphere.jl
1 parent 753531d commit cfae853

File tree

1 file changed

+70
-27
lines changed

1 file changed

+70
-27
lines changed

examples/sphere.jl

Lines changed: 70 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
# # Spherical harmonic addition theorem
22
# This example confirms numerically that
33
# ```math
4-
# f(z) = \frac{P_4(z\cdot y) - P_4(x\cdot y)}{z\cdot y - x\cdot y},
4+
# f(z) = \frac{P_n(z\cdot y) - P_n(x\cdot y)}{z\cdot y - x\cdot y},
55
# ```
6-
# is actually a degree-$3$ polynomial on $\mathbb{S}^2$, where $P_4$ is the degree-$4$
6+
# is actually a degree-$(n-1)$ polynomial on $\mathbb{S}^2$, where $P_n$ is the degree-$n$
77
# Legendre polynomial, and $x,y,z \in \mathbb{S}^2$.
8-
# To verify, we sample the function on a $5\times9$ equiangular grid
8+
# To verify, we sample the function on a $N\times M$ equiangular grid
99
# defined by:
1010
# ```math
1111
# \begin{aligned}
@@ -19,8 +19,8 @@
1919
# `plan_sph2fourier`.
2020
#
2121
# In the basis of spherical harmonics, it is plain to see the
22-
# addition theorem in action, since $P_4(x\cdot y)$ should only consist of
23-
# exact-degree-$4$ harmonics.
22+
# addition theorem in action, since $P_n(x\cdot y)$ should only consist of
23+
# exact-degree-$n$ harmonics.
2424
#
2525
# For the storage pattern of the arrays, please consult the
2626
# [documentation](https://MikaelSlevinsky.github.io/FastTransforms).
@@ -32,10 +32,13 @@ function threshold!(A::AbstractArray, ϵ)
3232
A
3333
end
3434

35-
using FastTransforms, LinearAlgebra
35+
using FastTransforms, LinearAlgebra, Plots
36+
const GENFIGS = joinpath(dirname(dirname(pathof(FastTransforms))), "docs/src/generated")
37+
!isdir(GENFIGS) && mkdir(GENFIGS)
38+
plotlyjs()
3639

3740
# The colatitudinal grid (mod $\pi$):
38-
N = 5
41+
N = 15
3942
θ = (0.5:N-0.5)/N
4043

4144
# The longitudinal grid (mod $\pi$):
@@ -51,45 +54,85 @@ y = normalize([.123,.456,.789])
5154
# Thus $z \in \mathbb{S}^2$ is our variable vector, parameterized in spherical coordinates:
5255
z = (θ,φ) -> [sinpi(θ)*cospi(φ), sinpi(θ)*sinpi(φ), cospi(θ)]
5356

54-
# The degree-$4$ Legendre polynomial is:
55-
P4 = x -> (35*x^4-30*x^2+3)/8
56-
57-
# On the tensor product grid, our function samples are:
58-
F = [(P4(z(θ,φ)y) - P4(xy))/(z(θ,φ)y - xy) for θ in θ, φ in φ]
59-
57+
# On the tensor product grid, the Legendre polynomial $P_n(z\cdot y)$ is:
58+
A = [(2k+1)/(k+1) for k in 0:N-1]
59+
B = zeros(N)
60+
C = [k/(k+1) for k in 0:N]
61+
c = zeros(N); c[N] = 1
62+
pts = vec([z(θ, φ)y for θ in θ, φ in φ])
63+
phi0 = ones(N*M)
64+
F = reshape(FastTransforms.clenshaw!(c, A, B, C, pts, phi0, zeros(N*M)), N, M)
65+
66+
# We superpose a surface plot of $f$ on top of the grid:
67+
X = [sinpi(θ)*cospi(φ) for θ in θ, φ in φ]
68+
Y = [sinpi(θ)*sinpi(φ) for θ in θ, φ in φ]
69+
Z = [cospi(θ) for θ in θ, φ in φ]
70+
scatter3d(vec(X), vec(Y), vec(Z); markersize=1.25, markercolor=:violetred)
71+
surface!(X, Y, Z; surfacecolor=F, legend=false, xlabel="x", ylabel="y", zlabel="f")
72+
savefig(joinpath(GENFIGS, "sphere1.html"))
73+
###```@raw html
74+
###<object type="text/html" data="../sphere1.html" style="width:100%;height:400px;"></object>
75+
###```
76+
77+
# We show the cut in the surface to help illustrate the definition of the grid.
78+
# In particular, we do not sample the poles.
79+
#
6080
# We precompute a spherical harmonic--Fourier plan:
6181
P = plan_sph2fourier(F)
6282

6383
# And an FFTW Fourier analysis plan on $\mathbb{S}^2$:
6484
PA = plan_sph_analysis(F)
6585

66-
# Its spherical harmonic coefficients demonstrate that it is degree-$3$:
86+
# Its spherical harmonic coefficients demonstrate that it is exact-degree-$n$:
6787
V = PA*F
68-
U3 = threshold!(P\V, 400*eps())
88+
U = threshold!(P\V, 400*eps())
89+
90+
# The $L^2(\mathbb{S}^2)$ norm of the function is:
91+
nrm1 = norm(U)
6992

70-
# Similarly, on the tensor product grid, the Legendre polynomial $P_4(z\cdot y)$ is:
71-
F = [P4(z(θ,φ)y) for θ in θ, φ in φ]
93+
# Similarly, on the tensor product grid, our function samples are:
94+
Pnxy = FastTransforms.clenshaw!(c, A, B, C, [xy], [1.0], [0.0])[1]
95+
F = [(F[n, m] - Pnxy)/(z(θ[n], φ[m])y - xy) for n in 1:N, m in 1:M]
7296

73-
# Its spherical harmonic coefficients demonstrate that it is exact-degree-$4$:
97+
# We superpose a surface plot of $f$ on top of the grid:
98+
scatter3d(vec(X), vec(Y), vec(Z); markersize=1.25, markercolor=:violetred)
99+
surface!(X, Y, Z; surfacecolor=F, legend=false, xlabel="x", ylabel="y", zlabel="f")
100+
savefig(joinpath(GENFIGS, "sphere2.html"))
101+
###```@raw html
102+
###<object type="text/html" data="../sphere2.html" style="width:100%;height:400px;"></object>
103+
###```
104+
105+
# Its spherical harmonic coefficients demonstrate that it is degree-$(n-1)$:
74106
V = PA*F
75-
U4 = threshold!(P\V, 3*eps())
107+
U = threshold!(P\V, 400*eps())
76108

77-
# The $L^2(\mathbb{S}^2)$ norm of the function is:
78-
nrm1 = norm(U4)
109+
# Finally, the Legendre polynomial $P_n(z\cdot x)$ is aligned with the grid:
110+
pts = vec([z(θ, φ)x for θ in θ, φ in φ])
111+
F = reshape(FastTransforms.clenshaw!(c, A, B, C, pts, phi0, zeros(N*M)), N, M)
79112

80-
# Finally, the Legendre polynomial $P_4(z\cdot x)$ is aligned with the grid:
81-
F = [P4(z(θ,φ)x) for θ in θ, φ in φ]
113+
# We superpose a surface plot of $f$ on top of the grid:
114+
scatter3d(vec(X), vec(Y), vec(Z); markersize=1.25, markercolor=:violetred)
115+
surface!(X, Y, Z; surfacecolor=F, legend=false, xlabel="x", ylabel="y", zlabel="f")
116+
savefig(joinpath(GENFIGS, "sphere3.html"))
117+
###```@raw html
118+
###<object type="text/html" data="../sphere3.html" style="width:100%;height:400px;"></object>
119+
###```
82120

83121
# It only has one nonnegligible spherical harmonic coefficient.
84122
# Can you spot it?
85123
V = PA*F
86-
U4 = threshold!(P\V, 3*eps())
124+
U = threshold!(P\V, 400*eps())
125+
126+
# That nonnegligible coefficient should be
127+
ret = eval("√(2π/($(N-1)+1/2))")
128+
129+
# which is approximately
130+
eval(Meta.parse(ret))
87131

88-
# That nonnegligible coefficient should be approximately `√(2π/(4+1/2))`,
89132
# since the convention in this library is to orthonormalize.
90-
nrm2 = norm(U4)
133+
nrm2 = norm(U)
91134

92-
# Note that the integrals of both functions $P_4(z\cdot y)$ and $P_4(z\cdot x)$ and their
135+
# Note that the integrals of both functions $P_n(z\cdot y)$ and $P_n(z\cdot x)$ and their
93136
# $L^2(\mathbb{S}^2)$ norms are the same because of rotational invariance. The integral of
94137
# either is perhaps not interesting as it is mathematically zero, but the norms
95138
# of either should be approximately the same.

0 commit comments

Comments
 (0)