Skip to content

Commit bc0d4d4

Browse files
add GramMatrix approach
1 parent 18d12a7 commit bc0d4d4

File tree

1 file changed

+45
-2
lines changed

1 file changed

+45
-2
lines changed

examples/semiclassical.jl

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@ P1 = plan_jac2cheb(Float64, n+1, α, β; normjac = true)
2828

2929
# We compute the Chebyshev series for the degree-$k\le n$ modified polynomial and its values at the Chebyshev points:
3030
q = k -> lmul!(P1, lmul!(P, [zeros(k); 1.0; zeros(n-k)]))
31-
qvals = k-> ichebyshevtransform(q(k))
31+
qvals = k -> ichebyshevtransform(q(k))
3232

3333
# 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):
3434
x = Fun(x->x, NormalizedJacobi(β, α))
35-
XP = SymTridiagonal(Symmetric(Multiplication(x, space(x))[1:n, 1:n]))
35+
XP = SymTridiagonal(Symmetric(Multiplication(x, space(x))[1:n+1, 1:n+1]))
3636
XQ = FastTransforms.modified_jacobi_matrix(P, XP)
3737
SymTridiagonal(XQ.dv[1:10], XQ.ev[1:9])
3838

@@ -64,3 +64,46 @@ P′ = plan_modifiedjac2jac(Float64, n+1, α+1, β+1, v.coefficients)
6464
DP = UpperTriangular(diagm(1=>[sqrt(n*(n+α+β+1)) for n in 1:n])) # The classical differentiation matrix representing 𝒟 P^{(α,β)}(y) = P^{(α+1,β+1)}(y) D_P.
6565
DQ = UpperTriangular(threshold!(P′\(DP*(P*I)), 100eps())) # The semi-classical differentiation matrix representing 𝒟 Q(y) = Q̂(y) D_Q.
6666
UpperTriangular(DQ[1:10,1:10])
67+
68+
# A faster method now exists via the `GramMatrix` architecture and its associated displacement equation. We compute `U`:
69+
U = Symmetric(Multiplication(u, space(u))[1:n+1, 1:n+1])
70+
71+
# Then we form a `GramMatrix` together with the Jacobi matrix:
72+
G = GramMatrix(U, XP)
73+
74+
# And compute its cholesky factorization. The upper-triangular Cholesky factor represents the connection between original Jacobi and semi-classical Jacobi as ${\bf P}^{(\alpha,\beta)}(x) = {\bf Q}(x) R$.
75+
R = cholesky(G).U
76+
77+
# Every else works almost as before, including evaluation on a Chebyshev grid:
78+
q = k -> lmul!(P1, ldiv!(R, [zeros(k); 1.0; zeros(n-k)]))
79+
qvals = k -> ichebyshevtransform(q(k))
80+
81+
# Computation of the modified Jacobi matrix:
82+
XQ1 = FastTransforms.modified_jacobi_matrix(R, XP)
83+
norm(XQ-XQ1)/norm(XQ)
84+
85+
# Plotting:
86+
x = chebyshevpoints(Float64, n+1, Val(1))
87+
p = plot(x, qvals(0); linewidth=2.0, legend = false, xlim=(-1,1), xlabel=L"x",
88+
ylabel=L"Q_n(x)", title="Semi-classical Jacobi Polynomials and Their Roots",
89+
extra_plot_kwargs = KW(:include_mathjax => "cdn"))
90+
for k in 1:10
91+
λ = eigvals(SymTridiagonal(XQ1.dv[1:k], XQ1.ev[1:k-1]))
92+
plot!(x, qvals(k); linewidth=2.0, color=palette(:default)[k+1])
93+
scatter!(λ, zero(λ); markersize=2.5, color=palette(:default)[k+1])
94+
end
95+
p
96+
savefig(joinpath(GENFIGS, "semiclassical1.html"))
97+
###```@raw html
98+
###<object type="text/html" data="../semiclassical1.html" style="width:100%;height:400px;"></object>
99+
###```
100+
101+
# And banded differentiation:
102+
V = Symmetric(Multiplication(v, space(v))[1:n+1, 1:n+1])
103+
x = Fun(x->x, NormalizedJacobi+1, α+1))
104+
XP′ = SymTridiagonal(Symmetric(Multiplication(x, space(x))[1:n+1, 1:n+1]))
105+
G′ = GramMatrix(V, XP′)
106+
R′ = cholesky(G′).U
107+
DP = UpperTriangular(diagm(1=>[sqrt(n*(n+α+β+1)) for n in 1:n])) # The classical differentiation matrix representing 𝒟 P^{(α,β)}(y) = P^{(α+1,β+1)}(y) D_P.
108+
DQ = UpperTriangular(threshold!(R′*(DP*(R\I)), 100eps())) # The semi-classical differentiation matrix representing 𝒟 Q(y) = Q̂(y) D_Q.
109+
UpperTriangular(DQ[1:10,1:10])

0 commit comments

Comments
 (0)