|
| 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