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}
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
3333end
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:
5255z = (θ,φ) -> [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 (x⋅ y))/ (z (θ,φ)⋅ y - x⋅ y) for θ in θ, φ in φ]
59-
57+ # On the tensor product grid, the Legendre polynomial $P_n(z\cdot y)$ is:
58+ A = [(2 k+ 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:
6181P = plan_sph2fourier (F)
6282
6383# And an FFTW Fourier analysis plan on $\mathbb{S}^2$:
6484PA = 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 $:
6787V = 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, [x⋅ y], [1.0 ], [0.0 ])[1 ]
95+ F = [(F[n, m] - Pnxy)/ (z (θ[n], φ[m])⋅ y - x⋅ y) 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)$:
74106V = 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?
85123V = 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