|
| 1 | +############# |
| 2 | +# This example confirms numerically that |
| 3 | +# |
| 4 | +# [P₄(z⋅y) - P₄(x⋅y)]/(z⋅y - x⋅y), |
| 5 | +# |
| 6 | +# is actually a degree-3 polynomial on 𝕊², where P₄ is the degree-4 |
| 7 | +# Legendre polynomial, and x,y,z ∈ 𝕊². |
| 8 | +# To verify, we sample the function on a 5×9 tensor product grid |
| 9 | +# at equispaced points-in-angle defined by: |
| 10 | +# |
| 11 | +# θₙ = (n+1/2)π/N, for 0 ≤ n < N, |
| 12 | +# |
| 13 | +# and |
| 14 | +# |
| 15 | +# φₘ = 2π m/M, for 0 ≤ m < M; |
| 16 | +# |
| 17 | +# we convert the function samples to Fourier coefficients using |
| 18 | +# `FastTransforms.plan_analysis`; and finally, we transform |
| 19 | +# the Fourier coefficients to spherical harmonic coefficients using |
| 20 | +# `plan_sph2fourier`. |
| 21 | +# |
| 22 | +# In the basis of spherical harmonics, it is plain to see the |
| 23 | +# addition theorem in action, since P₄(x⋅y) should only consist of |
| 24 | +# exact-degree-4 harmonics. |
| 25 | +# |
| 26 | +# For the storage pattern of the arrays, please consult the documentation. |
| 27 | +############# |
| 28 | + |
| 29 | +using FastTransforms |
| 30 | + |
| 31 | +# The colatitudinal grid (mod π): |
| 32 | +N = 5 |
| 33 | +θ = (0.5:N-0.5)/N |
| 34 | + |
| 35 | +# The longitudinal grid (mod π): |
| 36 | +M = 2*N-1 |
| 37 | +φ = (0:M-1)*2/M |
| 38 | + |
| 39 | +# Arbitrarily, we place x at the North pole: |
| 40 | +x = [0,0,1] |
| 41 | + |
| 42 | +# Another vector is completely free: |
| 43 | +y = normalize([.123,.456,.789]) |
| 44 | + |
| 45 | +# Thus z ∈ 𝕊² is our variable vector, parameterized in spherical coordinates: |
| 46 | +z = (θ,φ) -> [sinpi(θ)*cospi(φ), sinpi(θ)*sinpi(φ), cospi(θ)] |
| 47 | + |
| 48 | +# The degree-4 Legendre polynomial is: |
| 49 | +P4 = x -> (35*x^4-30*x^2+3)/8 |
| 50 | + |
| 51 | +# On the tensor product grid, our function samples are: |
| 52 | +F = [(P4(z(θ,φ)⋅y) - P4(x⋅y))/(z(θ,φ)⋅y - x⋅y) for θ in θ, φ in φ] |
| 53 | + |
| 54 | +P = plan_sph2fourier(F); |
| 55 | +PA = FastTransforms.plan_analysis(F); |
| 56 | + |
| 57 | +# Its spherical harmonic coefficients demonstrate that it is degree-3: |
| 58 | +V = zero(F); |
| 59 | +A_mul_B!(V, PA, F); |
| 60 | +U3 = P\V |
| 61 | + |
| 62 | +# Similarly, on the tensor product grid, the Legendre polynomial P₄(z⋅y) is: |
| 63 | +F = [P4(z(θ,φ)⋅y) for θ in θ, φ in φ] |
| 64 | + |
| 65 | +# Its spherical harmonic coefficients demonstrate that it is exact-degree-4: |
| 66 | +A_mul_B!(V, PA, F); |
| 67 | +U4 = P\V |
| 68 | + |
| 69 | +nrm1 = vecnorm(U4); |
| 70 | + |
| 71 | +# Finally, the Legendre polynomial P₄(z⋅x) is aligned with the grid: |
| 72 | +F = [P4(z(θ,φ)⋅x) for θ in θ, φ in φ] |
| 73 | + |
| 74 | +# It only has one nonnegligible spherical harmonic coefficient. |
| 75 | +# Can you spot it? |
| 76 | +A_mul_B!(V, PA, F); |
| 77 | +U4 = P\V |
| 78 | + |
| 79 | +# That nonnegligible coefficient should be approximately √(2π/(4+1/2)), |
| 80 | +# since the convention in this library is to orthonormalize. |
| 81 | + |
| 82 | +nrm2 = vecnorm(U4); |
| 83 | + |
| 84 | +# Note that the integrals of both functions P₄(z⋅y) and P₄(z⋅x) and their |
| 85 | +# L²(𝕊²) norms are the same because of rotational invariance. The integral of |
| 86 | +# either is perhaps not interesting as it is mathematically zero, but the norms |
| 87 | +# of either should be approximately the same. |
| 88 | + |
| 89 | +@show nrm1 |
| 90 | +@show nrm2 |
| 91 | +@show nrm1 ≈ nrm2 |
0 commit comments