Skip to content

Commit 36e9cfa

Browse files
authored
ContinuousSpace{-1} (#58)
* Support Spline{-1} * Use ArrowheadMatrix in diff(::ContinuousPloy) * Update arrowhead.jl * Update piecewisepolynomial.jl * tests pass * start backslash * expansions work * differentiation * Update test_arrowhead.jl
1 parent ee28bd8 commit 36e9cfa

File tree

5 files changed

+79
-5
lines changed

5 files changed

+79
-5
lines changed

src/PiecewiseOrthogonalPolynomials.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@ import BlockArrays: BlockSlice, block, blockindex, blockvec
77
import BlockBandedMatrices: _BandedBlockBandedMatrix, AbstractBandedBlockBandedMatrix, subblockbandwidths, blockbandwidths, AbstractBandedBlockBandedLayout, layout_replace_in_print_matrix
88
import ClassicalOrthogonalPolynomials: grid, plotgrid, ldiv, pad, adaptivetransform_ldiv, Plan, singularities, basis_singularities, singularitiesbroadcast
99
import ContinuumArrays: @simplify, factorize, TransformFactorization, AbstractBasisLayout, MemoryLayout, layout_broadcasted, ExpansionLayout, basis, plan_transform, plan_grid_transform, grammatrix, weaklaplacian, MulPlan, InvPlan
10-
import LazyArrays: paddeddata
10+
import LazyArrays: paddeddata, AbstractLazyLayout
1111
import LazyBandedMatrices: BlockBroadcastMatrix, BlockVec, BandedLazyLayouts, AbstractLazyBandedBlockBandedLayout, UpperOrLowerTriangular
1212
import Base: size, axes, getindex, +, -, *, /, ==, \, OneTo, oneto, replace_in_print_matrix, copy, diff, getproperty, adjoint, transpose, tail, _sum, inv, show, summary
1313
import LinearAlgebra: BlasInt
1414
import InfiniteArrays: OneToInf
1515
import FillArrays: AbstractFill
1616
import MatrixFactorizations: reversecholcopy
17+
import FillArrays: SquareEye
1718

1819
export PiecewisePolynomial, ContinuousPolynomial, DirichletPolynomial, Derivative, Block, weaklaplacian, grammatrix
1920

src/arrowhead.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ struct ArrowheadMatrix{T, AA<:AbstractMatrix{T}, BB, CC, DD} <: AbstractBandedBl
1616
ArrowheadMatrix{T, AA, BB, CC, DD}(A, B, C, D) where {T,AA,BB,CC,DD} = new{T,AA,BB,CC,DD}(A, B, C, D)
1717
end
1818

19-
ArrowheadMatrix{T}(A, B, C, D) where T = ArrowheadMatrix{T, typeof(A), typeof(B), typeof(C), typeof(D)}(A, B, C, D)
19+
ArrowheadMatrix{T}(A::AbstractMatrix{T}, B, C, D) where T = ArrowheadMatrix{T, typeof(A), typeof(B), typeof(C), typeof(D)}(A, B, C, D)
20+
ArrowheadMatrix{T}(A, B, C, D) where T = ArrowheadMatrix(convert(AbstractMatrix{T}, A), B, C, D)
2021

2122
const ArrowheadMatrices = Union{ArrowheadMatrix,Symmetric{<:Any,<:ArrowheadMatrix},Hermitian{<:Any,<:ArrowheadMatrix},
2223
UpperOrLowerTriangular{<:Any,<:ArrowheadMatrix}}
@@ -109,6 +110,7 @@ ArrowheadLayouts = Union{ArrowheadLayout,LazyArrowheadLayout,
109110
TriangularLayout{'U', 'U', LazyArrowheadLayout}, TriangularLayout{'L', 'U', LazyArrowheadLayout}}
110111
arrowheadlayout(_) = ArrowheadLayout()
111112
arrowheadlayout(::BandedLazyLayouts) = LazyArrowheadLayout()
113+
arrowheadlayout(::DiagonalLayout{<:AbstractLazyLayout}) = LazyArrowheadLayout()
112114
symmetriclayout(lay::ArrowheadLayouts) = SymmetricLayout{typeof(lay)}()
113115

114116
MemoryLayout(::Type{<:ArrowheadMatrix{<:Any,<:Any,<:Any,<:Any,<:AbstractVector{D}}}) where D = arrowheadlayout(MemoryLayout(D))

src/continuouspolynomial.jl

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
"""
2+
ContinuousPolynomial{0} is piecewise Legendre
3+
ContinuousPolynomial{1} is hat functions in first block and rest are bubble functions Ultraspherical(-1/2)
4+
ContinuousPolynomial{-1} is delta functions (non-boundary) and rest are Ultraspherical(1/2) == diff(Legendre())[:,2:end] in the interior of the elements.
5+
Between elements we are consistent with differentiating Legendre: we have delta functions of (-1)^k on the left and -1 on the right.
6+
"""
17
struct ContinuousPolynomial{order,T,P<:AbstractVector} <: AbstractPiecewisePolynomial{order,T,P}
28
points::P
39
end
@@ -11,8 +17,8 @@ ContinuousPolynomial{o}(P::ContinuousPolynomial) where {o} = ContinuousPolynomia
1117
PiecewisePolynomial(P::ContinuousPolynomial{o,T}) where {o,T} = PiecewisePolynomial(Legendre{T}(), P.points)
1218

1319
axes(B::ContinuousPolynomial{0}) = axes(PiecewisePolynomial(B))
14-
axes(B::ContinuousPolynomial{1}) =
15-
(Inclusion(first(B.points) .. last(B.points)), blockedrange(Vcat(length(B.points), Fill(length(B.points) - 1, ∞))))
20+
axes(B::ContinuousPolynomial{1}) = (Inclusion(first(B.points) .. last(B.points)), blockedrange(Vcat(length(B.points), Fill(length(B.points) - 1, ∞))))
21+
axes(B::ContinuousPolynomial{-1}) = (Inclusion(first(B.points) .. last(B.points)), blockedrange(Vcat(length(B.points)-2, Fill(length(B.points) - 1, ∞))))
1622

1723
show(io::IO, Q::ContinuousPolynomial{λ}) where λ = summary(io, Q)
1824
summary(io::IO, Q::ContinuousPolynomial{λ}) where λ = print(io, "ContinuousPolynomial{}($(Q.points))")
@@ -45,6 +51,21 @@ function getindex(P::ContinuousPolynomial{1,T}, x::Number, Kk::BlockIndex{1}) wh
4551
end
4652
end
4753

54+
function getindex(P::ContinuousPolynomial{-1,T}, x::Number, Kk::BlockIndex{1}) where {T}
55+
K, k = block(Kk), blockindex(Kk)
56+
if K == Block(1)
57+
Spline{-1,T}(P.points)[x, k]
58+
else
59+
b = searchsortedlast(P.points, x)
60+
if b == k
61+
α, β = convert(T, P.points[b]), convert(T, P.points[b+1])
62+
Ultraspherical{T}(3one(real(T))/2)[affine.. β, ChebyshevInterval{real(T)}())[x], Int(K)-1]
63+
else
64+
zero(T)
65+
end
66+
end
67+
end
68+
4869

4970

5071
factorize(V::SubQuasiArray{T,N,<:ContinuousPolynomial{0},<:Tuple{Inclusion,BlockSlice}}, dims...) where {T,N} =
@@ -214,6 +235,22 @@ function \(P::ContinuousPolynomial{0}, C::ContinuousPolynomial{1})
214235
end
215236

216237

238+
@simplify function \(D::ContinuousPolynomial{-1}, P::ContinuousPolynomial{0})
239+
T = promote_type(eltype(D), eltype(P))
240+
@assert D.points == P.points
241+
N = length(P.points)
242+
R = Ultraspherical{T}(3one(T)/2)\Legendre{T}()
243+
244+
# The basis for D is defined in each element a..b as diff(legendre(a..b)) with delta functions. But note that
245+
# the delta functions don't change! We need to kill off the deltas in conversion.
246+
ArrowheadMatrix(_BandedMatrix(Vcat(Fill(-one(T),1,N-1), Fill(one(T),1,N-1)), N-2, 0, 1),
247+
(_BandedMatrix(Ones{T}(2,N-1), N-2, 0, 1),),
248+
(SquareEye{T}(N-1),),
249+
Fill(R[:,2:end], N-1))
250+
end
251+
252+
253+
217254

218255
######
219256
# Gram matrix
@@ -279,7 +316,7 @@ end
279316
#####
280317

281318
function diff(C::ContinuousPolynomial{1,T}; dims=1) where T
282-
# Legendre() \ (D*Weighted(Jacobi(1,1)))
319+
# Legendre() \ (D*Ultraspherical(3/2)))
283320
r = C.points
284321
N = length(r)
285322
s = one(T) ./ (r[2:end]-r[1:end-1])
@@ -296,6 +333,18 @@ function diff(C::ContinuousPolynomial{1,T,<:AbstractRange}; dims=1) where T
296333
Fill(-2s*Eye{T}(∞), N-1))
297334
end
298335

336+
function diff(P::ContinuousPolynomial{0,T,<:AbstractRange}; dims=1) where T
337+
r = P.points
338+
N = length(r)
339+
s = step(r)
340+
341+
ContinuousPolynomial{-1}(r) * ArrowheadMatrix(_BandedMatrix(Vcat(Fill(one(T),1,N-1), Fill(-one(T),1,N-1)), N-2, 0, 1),
342+
(),
343+
(),
344+
Fill(Eye{T}(∞) * (2/s), N-1))
345+
end
346+
347+
299348
function weaklaplacian(C::ContinuousPolynomial{1,T,<:AbstractRange}) where T
300349
r = C.points
301350
N = length(r)

test/test_arrowhead.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ import Base: oneto, OneTo
66

77

88
@testset "ArrowheadMatrix" begin
9+
@testset "Constructor" begin
10+
n = 4; p = 5;
11+
@test ArrowheadMatrix{Float64}(BandedMatrix(0 => 1:n, 1 => 1:n-1, -1 => 1:n-1),
12+
ntuple(_ -> BandedMatrix((0 => randn(n-1), -1 => randn(n-1)), (n,n-1)), 2),
13+
ntuple(_ -> BandedMatrix((0 => randn(n), 1 => randn(n-1)), (n-1,n)), 3),
14+
fill(BandedMatrix((0 => randn(p) .+ 10, 2 => randn(p-2), -1=> randn(p-1)), (p, p)), n-1)) isa ArrowheadMatrix{Float64}
15+
end
16+
917
@testset "Algebra" begin
1018
n = 4; p = 5;
1119
A = ArrowheadMatrix(BandedMatrix(0 => randn(n) .+ 10, 1 => randn(n-1), -1 => randn(n-1)),

test/test_continuouspolynomial.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,4 +209,18 @@ using ContinuumArrays: plan_grid_transform
209209

210210
@test F_xy f_xy.(x, reshape(y,1,1,size(y)...))
211211
end
212+
213+
@testset "Dirac" begin
214+
r = range(-1,1; length=4)
215+
C = ContinuousPolynomial{1}(r)
216+
P = ContinuousPolynomial{0}(r)
217+
H = ContinuousPolynomial{-1}(r)
218+
219+
f = expand(P, exp)
220+
@test (H/H\f)[0.1] exp(0.1)
221+
@test diff(f)[0.1] exp(0.1)
222+
223+
f = expand(C,exp)
224+
@test diff(diff(f))[0.1] exp(0.1)
225+
end
212226
end

0 commit comments

Comments
 (0)