|
285 | 285 | include("clenshaw.jl")
|
286 | 286 | include("ratios.jl")
|
287 | 287 | include("normalized.jl")
|
| 288 | +include("monic.jl") |
288 | 289 | include("lanczos.jl")
|
289 | 290 | include("choleskyQR.jl")
|
290 | 291 |
|
@@ -318,70 +319,50 @@ end
|
318 | 319 |
|
319 | 320 | golubwelsch(V::SubQuasiArray) = golubwelsch(parent(V), maximum(parentindices(V)[2]))
|
320 | 321 |
|
321 |
| -function gaussradau(P, n::Integer, endpt) |
322 |
| - ## See Thm 3.2 in Gautschi (2004)'s book |
323 |
| - # n is the number of interior points |
324 |
| - J = symtridiagonalize(jacobimatrix(P, n + 1)) |
325 |
| - α = diagonaldata(J) |
326 |
| - β = supdiagonaldata(J) |
327 |
| - T = eltype(P) |
| 322 | +function gaussradau(P::Monic{T}, n::Integer, endpt) where {T} |
| 323 | + ## See Thm 3.2 in Gautschi (2004)'s book |
| 324 | + # n is number of interior points |
| 325 | + J = jacobimatrix(P.P, n + 1) |
| 326 | + α, β = diagonaldata(J), supdiagonaldata(J) |
328 | 327 | endpt = T(endpt)
|
329 |
| - p0 = one(T) |
330 |
| - p1 = (endpt - α[1]) * p0 |
331 |
| - for i in 2:n |
332 |
| - # Evaluate the monic polynomials πₙ₋₁(endpt), πₙ(endpt) |
333 |
| - _p1 = p0 |
334 |
| - p0 = p1 |
335 |
| - p1 = (endpt - α[i]) * p0 - β[i - 1]^2 * _p1 |
336 |
| - end |
337 |
| - a = endpt - β[end]^2 * p0 / p1 |
| 328 | + p0 = P[endpt, n] # πₙ₋₁ |
| 329 | + p1 = P[endpt, n+1] # πₙ. Could be faster by computing p1 from p0 and πₙ₋₂, but the cost is tiny relative to eigen() |
| 330 | + a = (endpt - β[end]^2 * p0 / p1)::T |
338 | 331 | α′ = vcat(@view(α[begin:end-1]), a)
|
339 | 332 | J′ = SymTridiagonal(α′, β)
|
340 |
| - x, w = golubwelsch(J′) |
| 333 | + x, w = golubwelsch(J′) # not inferred |
341 | 334 | w .*= sum(orthogonalityweight(P))
|
342 | 335 | if endpt ≤ axes(P, 1)[begin]
|
343 | 336 | x[1] = endpt # avoid rounding errors
|
344 |
| - else |
345 |
| - x[end] = endpt |
| 337 | + else |
| 338 | + x[end] = endpt |
346 | 339 | end
|
347 | 340 | return x, w
|
348 | 341 | end
|
| 342 | +gaussradau(P, n::Integer, endpt) = gaussradau(Monic(P), n, endpt) |
349 | 343 |
|
350 |
| -function gausslobatto(P, n::Integer) |
351 |
| - ## See Thm 3.6 of Gautschi (2004)'s book |
| 344 | +function gausslobatto(P::Monic{T}, n::Integer) where {T} |
| 345 | + ## See Thm 3.6 of Gautschi (2004)'s book |
352 | 346 | # n is the number of interior points
|
353 | 347 | a, b = axes(P, 1)[begin], axes(P, 1)[end]
|
354 |
| - J = symtridiagonalize(jacobimatrix(P, n + 2)) |
355 |
| - α = diagonaldata(J) |
356 |
| - β = supdiagonaldata(J) |
357 |
| - T = eltype(P) |
358 |
| - a, b = T(a), T(b) |
359 |
| - p0a = one(T) |
360 |
| - p0b = one(T) |
361 |
| - p1a = (a - α[1]) * p0a |
362 |
| - p1b = (b - α[1]) * p0b |
363 |
| - for i in 2:(n+1) |
364 |
| - # Evaluate the monic polynomials πₙ₋₁(a), πₙ₋₁(b), πₙ(a), πₙ(b) |
365 |
| - _p1a = p0a |
366 |
| - _p1b = p0b |
367 |
| - p0a = p1a |
368 |
| - p0b = p1b |
369 |
| - p1a = (a - α[i]) * p0a - β[i - 1]^2 * _p1a |
370 |
| - p1b = (b - α[i]) * p0b - β[i - 1]^2 * _p1b |
371 |
| - end |
| 348 | + J = jacobimatrix(P.P, n + 2) |
| 349 | + α, β = diagonaldata(J), supdiagonaldata(J) |
| 350 | + p0a, p0b = P[a, n+1], P[b, n+1] |
| 351 | + p1a, p1b = P[a, n+2], P[b, n+2] |
372 | 352 | # Solve Eq. 3.1.2.8
|
373 | 353 | Δ = p1a * p0b - p1b * p0a # This could underflow/overflow for large n
|
374 |
| - aext = (a * p1a * p0b - b * p1b * p0a) / Δ |
375 |
| - bext = (b - a) * p1a * p1b / Δ |
| 354 | + aext = (a * p1a * p0b - b * p1b * p0a) / Δ |
| 355 | + bext = (b - a) * p1a * p1b / Δ |
376 | 356 | α′ = vcat(@view(α[begin:end-1]), aext)
|
377 | 357 | β′ = vcat(@view(β[begin:end-1]), sqrt(bext)) # LazyBandedMatrices doesn't like when we use Vcat(array, scalar) apparently
|
378 | 358 | J′ = LazyBandedMatrices.SymTridiagonal(α′, β′)
|
379 | 359 | x, w = golubwelsch(J′)
|
380 | 360 | w .*= sum(orthogonalityweight(P))
|
381 |
| - x[1] = a |
| 361 | + x[1] = a |
382 | 362 | x[end] = b # avoid rounding errors. Doesn't affect the actual result but avoids e.g. domain errors
|
383 |
| - return x, w |
| 363 | + return x, w |
384 | 364 | end
|
| 365 | +gausslobatto(P, n::Integer) = gausslobatto(Monic(P), n) |
385 | 366 |
|
386 | 367 | # Default is Golub–Welsch expansion
|
387 | 368 | # note this computes the grid an extra time.
|
|
0 commit comments