Skip to content

Commit 2de9924

Browse files
authored
Introduce ArrowheadMatrix (#32)
* start arrowhead * Work on LeftArrowhead * change order for LeftArrowHead * start symarrowhead * Forget SymArrowhead * more general arrowhead * Update Project.toml * LeftArrowhead -> Arrowhrad * update tests * Start reversecholesky for ArrowheadMatrix * B blocks updated * reversecholesky! works! * tests bandwidths * increase cov * Use Arrowhead for building operators * start explicit weaklaplacian * Add mass matrix * grammatrix * Fast cholesky works! * Update test_arrowhead.jl * Getting tests to pass * Update test_arrowhead.jl * Update Project.toml * Start UpperTriangular * adjtrans for Arrowhead * add algebra tests
1 parent b8486b9 commit 2de9924

File tree

6 files changed

+595
-44
lines changed

6 files changed

+595
-44
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ jobs:
1010
fail-fast: false
1111
matrix:
1212
version:
13-
- '1.7'
14-
- '1'
13+
- '1.9'
1514
os:
1615
- ubuntu-latest
1716
- macOS-latest

Project.toml

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
name = "PiecewiseOrthogonalPolynomials"
22
uuid = "4461d12d-4663-4550-8580-cb764c85e20f"
33
authors = ["Sheehan Olver <[email protected]>"]
4-
version = "0.0.3"
4+
version = "0.1.0"
55

66
[deps]
7+
ArrayLayouts = "4c555306-a7a7-4459-81d9-ec55ddd5c99a"
8+
BandedMatrices = "aae01518-5342-5314-be14-df237901396f"
79
BlockArrays = "8e7c35d0-a365-5155-bbbb-fb81a777f24e"
810
BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0"
911
ClassicalOrthogonalPolynomials = "b30e2e7b-c4ee-47da-9d5f-2c5c27239acd"
@@ -14,25 +16,29 @@ InfiniteLinearAlgebra = "cde9dba0-b1de-11e9-2c62-0bab9446c55c"
1416
LazyArrays = "5078a376-72f3-5289-bfd5-ec5146d43c02"
1517
LazyBandedMatrices = "d7e5e226-e90b-4449-9968-0f923699bf6f"
1618
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
19+
MatrixFactorizations = "a3b82374-2e81-5b9e-98ce-41277c0e4c87"
1720
QuasiArrays = "c4ea9172-b204-11e9-377d-29865faadc5c"
1821

1922
[compat]
2023
BlockArrays = "0.16.25"
21-
BlockBandedMatrices = "0.11.10, 0.12"
22-
ClassicalOrthogonalPolynomials = "0.7, 0.8, 0.9"
23-
ContinuumArrays = "0.12"
24-
FillArrays = "0.13, 1.0"
24+
BlockBandedMatrices = "0.12"
25+
ClassicalOrthogonalPolynomials = "0.11"
26+
ContinuumArrays = "0.14"
27+
FillArrays = "1.0"
2528
InfiniteArrays = "0.12.6"
2629
InfiniteLinearAlgebra = "0.6.16"
27-
LazyArrays = "0.22.9, 1"
28-
LazyBandedMatrices = "0.8.7"
29-
QuasiArrays = "0.9"
30-
julia = "1.7"
30+
LazyArrays = "1.0"
31+
LazyBandedMatrices = "0.8.13"
32+
MatrixFactorizations = "2.0"
33+
QuasiArrays = "0.11"
34+
julia = "1.9"
3135

3236
[extras]
37+
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
3338
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
39+
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
3440
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
3541
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
3642

3743
[targets]
38-
test = ["Test", "StaticArrays", "ForwardDiff"]
44+
test = ["Base64", "ForwardDiff", "Random", "StaticArrays", "Test"]

src/PiecewiseOrthogonalPolynomials.jl

Lines changed: 83 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
module PiecewiseOrthogonalPolynomials
2-
using ClassicalOrthogonalPolynomials, LinearAlgebra, BlockArrays, BlockBandedMatrices, ContinuumArrays, QuasiArrays, LazyArrays, LazyBandedMatrices, FillArrays
2+
using ClassicalOrthogonalPolynomials, LinearAlgebra, BlockArrays, BlockBandedMatrices, BandedMatrices, ContinuumArrays, QuasiArrays, LazyArrays, LazyBandedMatrices, FillArrays, MatrixFactorizations, ArrayLayouts
33

4+
import ArrayLayouts: sublayout, sub_materialize, symmetriclayout, transposelayout, SymmetricLayout, HermitianLayout, TriangularLayout, layout_getindex, materialize!, MatLdivVec, AbstractStridedLayout, triangulardata
5+
import BandedMatrices: _BandedMatrix
46
import BlockArrays: BlockSlice, block, blockindex, blockvec
5-
import BlockBandedMatrices: _BandedBlockBandedMatrix
6-
import ClassicalOrthogonalPolynomials: grid, massmatrix, ldiv, pad, adaptivetransform_ldiv
7-
import ContinuumArrays: @simplify, factorize, TransformFactorization, AbstractBasisLayout, MemoryLayout, layout_broadcasted, ExpansionLayout, basis, plan_grid_transform
7+
import BlockBandedMatrices: _BandedBlockBandedMatrix, AbstractBandedBlockBandedMatrix, subblockbandwidths, blockbandwidths, AbstractBandedBlockBandedLayout, layout_replace_in_print_matrix
8+
import ClassicalOrthogonalPolynomials: grid, ldiv, pad, adaptivetransform_ldiv, grammatrix
9+
import ContinuumArrays: @simplify, factorize, TransformFactorization, AbstractBasisLayout, MemoryLayout, layout_broadcasted, ExpansionLayout, basis, plan_grid_transform, grammatrix
810
import LazyArrays: paddeddata
9-
import LazyBandedMatrices: BlockBroadcastMatrix, BlockVec
10-
import Base: axes, getindex, ==, \, OneTo
11+
import LazyBandedMatrices: BlockBroadcastMatrix, BlockVec, BandedLazyLayouts, AbstractLazyBandedBlockBandedLayout, UpperOrLowerTriangular
12+
import Base: axes, getindex, +, -, *, /, ==, \, OneTo, oneto, replace_in_print_matrix, copy, diff, getproperty, adjoint, transpose, tail
13+
import LinearAlgebra: BlasInt
14+
import MatrixFactorizations: reversecholcopy
1115

12-
export PiecewisePolynomial, ContinuousPolynomial, Derivative, Block
16+
export PiecewisePolynomial, ContinuousPolynomial, Derivative, Block, weaklaplacian, grammatrix
1317

1418
abstract type AbstractPiecewisePolynomial{order,T,P<:AbstractVector} <: Basis{T} end
1519

@@ -204,35 +208,83 @@ function \(P::ContinuousPolynomial{0}, C::ContinuousPolynomial{1})
204208
_BandedBlockBandedMatrix(dat, axes(P, 2), (1, 1), (0, 1))
205209
end
206210

211+
function \(P::ContinuousPolynomial{0, <:Any, <:AbstractRange}, C::ContinuousPolynomial{1, <:Any, <:AbstractRange})
212+
T = promote_type(eltype(P), eltype(C))
213+
@assert P.points == C.points
214+
v = (convert(T, 2):2:∞) ./ (3:2:∞)
215+
N = length(P.points)
216+
L = ArrowheadMatrix(_BandedMatrix(Ones{T}(2, N)/2, oneto(N-1), 0, 1),
217+
(_BandedMatrix(Fill(v[1], 1, N-1), oneto(N-1), 0, 0),),
218+
(_BandedMatrix(Vcat(Ones{T}(1, N)/2, -Ones{T}(1, N)/2), oneto(N-1), 0, 1),),
219+
Fill(_BandedMatrix(Hcat(v, Zeros{T}(∞), -v)', axes(v,1), 1, 1), N-1))
220+
end
221+
222+
223+
207224
######
208225
# Gram matrix
209226
######
210227

211-
@simplify function *(Ac::QuasiAdjoint{<:Any,<:ContinuousPolynomial{0}}, B::ContinuousPolynomial{0})
212-
A = Ac'
213-
T = promote_type(eltype(A), eltype(B))
228+
function grammatrix(A::ContinuousPolynomial{0,T}) where T
229+
r = A.points
230+
N = length(r) - 1
231+
hs = diff(r)
232+
M = grammatrix(Legendre{T}())
233+
ArrowheadMatrix{T}(Diagonal(Fill(hs[1], N)), (), (), [Diagonal(M.diag[2:end] * h/2) for h in hs])
234+
end
235+
236+
function grammatrix(A::ContinuousPolynomial{0,T, <:AbstractRange}) where T
214237
r = A.points
215-
@assert r == B.points
216238
N = length(r)
217-
M = massmatrix(Legendre{T}())
239+
M = grammatrix(Legendre{T}())
218240
Diagonal(mortar(Fill.((step(r) / 2) .* M.diag, N - 1)))
219241
end
220242

243+
function grammatrix(C::ContinuousPolynomial{1, T, <:AbstractRange}) where T
244+
r = C.points
245+
246+
N = length(r) - 1
247+
h = step(r) # 2/N
248+
a = ((convert(T,4):4:∞) .* (convert(T,-2):2:∞)) ./ ((1:2:∞) .* (3:2:∞) .* (-1:2:∞))
249+
b = (((convert(T,2):2:∞) ./ (3:2:∞)).^2 .* (convert(T,2) ./ (1:2:∞) .+ convert(T,2) ./ (5:2:∞)))
250+
251+
a11 = LazyBandedMatrices.Bidiagonal(Vcat(h/3, Fill(2h/3, N-1), h/3), Fill(h/6, N), :U)
252+
a21 = _BandedMatrix(Fill(h/3, 2, N), N+1, 1, 0)
253+
a31 = _BandedMatrix(Vcat(Fill(-2h/15, 1, N), Fill(2h/15, 1, N)), N+1, 1, 0)
254+
255+
Symmetric(ArrowheadMatrix(a11, (a21, a31), (),
256+
Fill(_BandedMatrix(Vcat((-h*a/2)',
257+
Zeros(1,∞),
258+
(h*b/2)'), ∞, 0, 2), N)))
259+
end
260+
261+
262+
function grammatrix(C::ContinuousPolynomial)
263+
P = ContinuousPolynomial{0}(C)
264+
L = P \ C
265+
L' * grammatrix(P) * L
266+
end
221267

222268
@simplify function *(Ac::QuasiAdjoint{<:Any,<:ContinuousPolynomial}, B::ContinuousPolynomial)
223269
A = Ac'
270+
A == B && return grammatrix(A)
224271
P = ContinuousPolynomial{0}(A)
225-
Q = ContinuousPolynomial{0}(B)
226-
(P \ A)' * (P'Q) * (Q \ B)
272+
(P \ A)' * grammatrix(P) * (P \ B)
273+
end
274+
275+
@simplify function *(Ac::QuasiAdjoint{<:Any,<:ContinuousPolynomial{0}}, B::ContinuousPolynomial{0})
276+
A = Ac'
277+
@assert A == B
278+
grammatrix(A)
227279
end
228280

281+
282+
229283
#####
230284
# Derivative
231285
#####
232286

233-
@simplify function *(D::Derivative, C::ContinuousPolynomial{1})
234-
T = promote_type(eltype(D), eltype(C))
235-
287+
function diff(C::ContinuousPolynomial{1,T}; dims=1) where T
236288
# Legendre() \ (D*Weighted(Jacobi(1,1)))
237289
r = C.points
238290
N = length(r)
@@ -242,7 +294,18 @@ end
242294
H = BlockBroadcastArray(hcat, z, v)
243295
M = BlockVcat(Hcat(Ones{T}(N) .* [zero(T); s] , -Ones{T}(N) .* [s; zero(T)] ), H)
244296
P = ContinuousPolynomial{0}(C)
245-
P * _BandedBlockBandedMatrix(M', (axes(P, 2), axes(C, 2)), (0, 0), (0, 1))
297+
ApplyQuasiMatrix(*, P, _BandedBlockBandedMatrix(M', (axes(P, 2), axes(C, 2)), (0, 0), (0, 1)))
298+
end
299+
300+
function weaklaplacian(C::ContinuousPolynomial{1,T,<:AbstractRange}) where T
301+
r = C.points
302+
N = length(r)
303+
s = step(r)
304+
si = inv(s)
305+
t1 = Vcat(-si, Fill(-2si, N-2), -si)
306+
t2 = Fill(si, N-1)
307+
Symmetric(ArrowheadMatrix(LazyBandedMatrices.Bidiagonal(t1, t2, :U), (), (),
308+
Fill(Diagonal(convert(T, -16) .* (1:∞) .^ 2 ./ (s .* ((2:2:∞) .+ 1))), N-1)))
246309
end
247310

248311

@@ -268,5 +331,7 @@ function layout_broadcasted(::Tuple{ExpansionLayout{PiecewisePolynomialLayout{0}
268331
(a .* P) * (P \ C)
269332
end
270333

334+
include("arrowhead.jl")
335+
271336

272337
end # module

0 commit comments

Comments
 (0)