Skip to content

Commit 0b0bbb2

Browse files
add semiclassical example
1 parent 7d91fc3 commit 0b0bbb2

File tree

3 files changed

+69
-0
lines changed

3 files changed

+69
-0
lines changed

docs/Project.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
[deps]
2+
ApproxFun = "28f2ccd6-bb30-5033-b560-165f7b14dc2f"
23
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
34
FastTransforms = "057dd010-8810-581a-b7be-e3fc3b93f78c"
45
LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"

docs/make.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ examples = [
1313
"halfrange.jl",
1414
"nonlocaldiffusion.jl",
1515
"padua.jl",
16+
"semiclassical.jl",
1617
"sphere.jl",
1718
"spinweighted.jl",
1819
"subspaceangles.jl",
@@ -47,6 +48,7 @@ makedocs(
4748
"generated/halfrange.md",
4849
"generated/nonlocaldiffusion.md",
4950
"generated/padua.md",
51+
"generated/semiclassical.md",
5052
"generated/sphere.md",
5153
"generated/spinweighted.md",
5254
"generated/subspaceangles.md",

examples/semiclassical.jl

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# # Semi-classical Jacobi polynomials
2+
# In this example, we will consider the semi-classical orthogonal polynomials with respect to the inner product:
3+
# ```math
4+
# \langle f, g \rangle = \int_{-1}^1 f(x) g(x) w(x){\rm d} x,
5+
# ```
6+
# where $w(x) = w^{(\alpha,\beta,\gamma,\delta,\epsilon)}(x) = (1-x)^\alpha(1+x)^\beta(2+x)^\gamma(3+x)^\delta(5-x)^\epsilon$ is a modification of the Jacobi weight.
7+
# We shall use results from [this paper](https://arxiv.org/abs/2302.08448) to consider these semi-classical orthogonal polynomials as modifications of the Jacobi polynomials $P_n^{(\alpha,\beta)}(x)$.
8+
9+
using ApproxFun, FastTransforms, LinearAlgebra, Plots, LaTeXStrings
10+
const GENFIGS = joinpath(pkgdir(FastTransforms), "docs/src/generated")
11+
!isdir(GENFIGS) && mkdir(GENFIGS)
12+
plotlyjs()
13+
14+
# We set the five parameters:
15+
α,β,γ,δ,ϵ = -0.125, -0.25, 0.123, 0.456, 0.789
16+
17+
# We use `ApproxFun` to construct a finite normalized Jacobi series as a proxy for $(2+x)^\gamma(3+x)^\delta(5-x)^\epsilon$.
18+
u = Fun(x->(2+x)^γ*(3+x)^δ*(5-x)^ϵ, NormalizedJacobi(β, α))
19+
20+
# Our working polynomial degree will be:
21+
n = 100
22+
23+
# We compute the connection coefficients between the modified orthogonal polynomials and the Jacobi polynomials:
24+
P = plan_modifiedjac2jac(Float64, n+1, α, β, u.coefficients)
25+
26+
# We store the connection to first kind Chebyshev polynomials:
27+
P1 = plan_jac2cheb(Float64, n+1, α, β; normjac = true)
28+
29+
# We compute the Chebyshev series for the degree-$k\le n$ modified polynomial and its values at the Chebyshev points:
30+
q = k -> lmul!(P1, lmul!(P, [zeros(k); 1.0; zeros(n-k)]))
31+
qvals = k-> ichebyshevtransform(q(k))
32+
33+
# With the symmetric Jacobi matrix for $P_n^{(\alpha, \beta)}(x)$ and the modified plan, we may compute the modified Jacobi matrix and the corresponding roots (as eigenvalues):
34+
x = Fun(x->x, NormalizedJacobi(β, α))
35+
XP = SymTridiagonal(Symmetric(Multiplication(x, space(x))[1:n, 1:n]))
36+
XQ = FastTransforms.modified_jacobi_matrix(P, XP)
37+
SymTridiagonal(XQ.dv[1:10], XQ.ev[1:9])
38+
39+
# And we plot:
40+
x = chebyshevpoints(Float64, n+1, Val(1))
41+
p = plot(x, qvals(0); linewidth=2.0, legend = false, xlim=(-1,1), xlabel=L"x",
42+
ylabel=L"Q_n(x)", title="Semi-classical Jacobi Polynomials and Their Roots",
43+
extra_plot_kwargs = KW(:include_mathjax => "cdn"))
44+
for k in 1:10
45+
λ = eigvals(SymTridiagonal(XQ.dv[1:k], XQ.ev[1:k-1]))
46+
plot!(x, qvals(k); linewidth=2.0, color=palette(:default)[k+1])
47+
scatter!(λ, zero(λ); markersize=2.5, color=palette(:default)[k+1])
48+
end
49+
p
50+
savefig(joinpath(GENFIGS, "semiclassical.html"))
51+
###```@raw html
52+
###<object type="text/html" data="../semiclassical.html" style="width:100%;height:400px;"></object>
53+
###```
54+
55+
# By [Theorem 2.20](https://arxiv.org/abs/2302.08448) it turns out that the *derivatives* of these particular semi-classical Jacobi polynomials are a linear combination of at most four polynomials orthogonal with respect to $(1-x)^{\alpha+1}(1+x)^{\beta+1}(2+x)^{\gamma+1}(3+x)^{\delta+1}(5-x)^{\epsilon+1}$ on $(-1,1)$. This fact enables us to compute the banded differentiation matrix:
56+
v = Fun(x->(2+x)^+1)*(3+x)^+1)*(5-x)^+1), NormalizedJacobi+1, α+1))
57+
function threshold!(A::AbstractArray, ϵ)
58+
for i in eachindex(A)
59+
if abs(A[i]) < ϵ A[i] = 0 end
60+
end
61+
A
62+
end
63+
P′ = plan_modifiedjac2jac(Float64, n+1, α+1, β+1, v.coefficients)
64+
DP = UpperTriangular(diagm(1=>[sqrt(n*(n+α+β+1)) for n in 1:n])) # The classical differentiation matrix representing 𝒟 P^{(-1/2,0)}(y) = P^{(1/2,1)}(y) D_P.
65+
DQ = UpperTriangular(threshold!(P′\(DP*(P*I)), 100eps())) # The semi-classical differentiation matrix representing 𝒟 Q(y) = Q̂(y) D_Q.
66+
UpperTriangular(DQ[1:10,1:10])

0 commit comments

Comments
 (0)