Skip to content

Commit a2bcf53

Browse files
authored
Support more triangle gram matrices (#189)
* Support more triangle gram matrices * Update ci.yml * Add weightedgrammatrix overload * Weak formulation tests * tests should pass * Update test_triangle.jl
1 parent 2b994fe commit a2bcf53

File tree

5 files changed

+99
-11
lines changed

5 files changed

+99
-11
lines changed

.github/workflows/ci.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ jobs:
1313
- '1.10'
1414
os:
1515
- ubuntu-latest
16-
- macOS-latest
1716
- windows-latest
1817
arch:
1918
- x64

Project.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "MultivariateOrthogonalPolynomials"
22
uuid = "4f6956fd-4f93-5457-9149-7bfc4b2ce06d"
3-
version = "0.7"
3+
version = "0.7.1"
44

55
[deps]
66
ArrayLayouts = "4c555306-a7a7-4459-81d9-ec55ddd5c99a"
@@ -37,7 +37,7 @@ HarmonicOrthogonalPolynomials = "0.6"
3737
InfiniteArrays = "0.14"
3838
InfiniteLinearAlgebra = "0.8"
3939
LazyArrays = "2.0"
40-
LazyBandedMatrices = "0.10"
40+
LazyBandedMatrices = "0.10.3"
4141
QuasiArrays = "0.11"
4242
SpecialFunctions = "1, 2"
4343
StaticArrays = "1"

src/MultivariateOrthogonalPolynomials.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import LazyArrays: arguments, paddeddata, LazyArrayStyle, LazyLayout, PaddedLayo
2121
import LazyBandedMatrices: LazyBandedBlockBandedLayout, AbstractBandedBlockBandedLayout, AbstractLazyBandedBlockBandedLayout, _krontrav_axes, DiagTravLayout, invdiagtrav, ApplyBandedBlockBandedLayout
2222
import InfiniteArrays: InfiniteCardinal, OneToInf
2323

24-
import ClassicalOrthogonalPolynomials: jacobimatrix, Weighted, orthogonalityweight, HalfWeighted, WeightedBasis, pad, recurrencecoefficients, clenshaw
24+
import ClassicalOrthogonalPolynomials: jacobimatrix, Weighted, orthogonalityweight, HalfWeighted, WeightedBasis, pad, recurrencecoefficients, clenshaw, weightedgrammatrix
2525
import HarmonicOrthogonalPolynomials: BivariateOrthogonalPolynomial, MultivariateOrthogonalPolynomial, Plan,
2626
PartialDerivative, AngularMomentum, BlockOneTo, BlockRange1, interlace,
2727
MultivariateOPLayout, MAX_PLOT_BLOCKS

src/triangle.jl

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -188,15 +188,22 @@ end
188188
# _lap_mul(P, eltype(axes(P,1)))
189189
# end
190190

191-
# _BandedBlockBandedMatrix((@. exp(loggamma(n+k+b+c)+loggamma(n-k+a+1)+loggamma(k+b)+loggamma(k+c)-loggamma(n+k+a+b+c)-loggamma(k+b+c)-loggamma(n-k+1)-loggamma(k))/((2n+a+b+c)*(2k+b+c-1)))',
192-
# axes(k,1), (0,0), (0,0))
191+
193192

194193
function grammatrix(A::JacobiTriangle)
195194
@assert A == JacobiTriangle()
196195
n = mortar(Fill.(oneto(∞),oneto(∞)))
197196
k = mortar(Base.OneTo.(oneto(∞)))
198197
_BandedBlockBandedMatrix(BroadcastVector{eltype(A)}((n,k) -> exp(loggamma(n+k)+loggamma(n-k+1)+loggamma(k)+loggamma(k)-loggamma(n+k)-loggamma(k)-loggamma(n-k+1)-loggamma(k))/((2n)*(2k-1)), n, k)',
199-
axes(k,1), (0,0), (0,0))
198+
axes(k,1), (0,0), (0,0))
199+
end
200+
201+
function weightedgrammatrix(A::JacobiTriangle)
202+
n = mortar(Fill.(oneto(∞),oneto(∞)))
203+
a,b,c = A.a,A.b,A.c
204+
k = mortar(Base.OneTo.(oneto(∞)))
205+
_BandedBlockBandedMatrix(BroadcastVector{eltype(A)}((n,k,a,b,c) -> exp(loggamma(n+k+b+c)+loggamma(n-k+a+1)+loggamma(k+b)+loggamma(k+c)-loggamma(n+k+a+b+c)-loggamma(k+b+c)-loggamma(n-k+1)-loggamma(k))/((2n+a+b+c)*(2k+b+c-1)), n, k, a, b, c)',
206+
axes(k,1), (0,0), (0,0))
200207
end
201208

202209
"""
@@ -399,7 +406,7 @@ function \(w_A::WeightedTriangle, B::JacobiTriangle)
399406
w_A \ (TriangleWeight(0,0,0) .* B)
400407
end
401408

402-
function \(A::JacobiTriangle, B::JacobiTriangle)
409+
@simplify function \(A::JacobiTriangle, B::JacobiTriangle)
403410
if A == B
404411
Eye{promote_type(eltype(A),eltype(B))}((axes(B,2),))
405412
elseif A.a == B.a + 1 && A.b == B.b && A.c == B.c
@@ -742,6 +749,23 @@ end
742749
getindex(f::ApplyQuasiVector{T,typeof(*),<:Tuple{JacobiTriangle,AbstractVector}}, xys::AbstractArray{<:SVector{2}}) where T =
743750
[f[xy] for xy in xys]
744751

752+
####
753+
# Grammatrices
754+
####
755+
756+
"""
757+
legendre_triangle_grammatrix
758+
759+
computes the grammatrix by first re-expanding in Legendre
760+
"""
761+
function legendre_triangle_grammatrix(A, B)
762+
P = JacobiTriangle{eltype(B)}()
763+
(P\A)'*grammatrix(P)*(P\B)
764+
end
765+
766+
@simplify *(Ac::QuasiAdjoint{<:Any,<:JacobiTriangle}, B::Weighted{<:Any,<:JacobiTriangle}) = legendre_triangle_grammatrix(parent(Ac),B)
767+
768+
745769
# getindex(f::Expansion{T,<:JacobiTriangle}, x::AbstractVector{<:Number}) where T =
746770
# copyto!(Vector{T}(undef, length(x)), view(f, x))
747771

@@ -836,4 +860,12 @@ function plotvalues(u::ApplyQuasiVector{T,typeof(*),<:Tuple{JacobiTriangle, Abst
836860
F = TriIPlan{T}(Block(N), P.a, P.b, P.c)
837861
C = F * DiagTrav(invdiagtrav(c)[1:N,1:N]) # transform to grid
838862
C
863+
end
864+
865+
866+
867+
function Base._sum(P::JacobiTriangle{T}, dims) where T
868+
@assert dims == 1
869+
@assert P.a == P.b == P.c == 0
870+
Hcat(one(T)/2, Zeros{T}(1,∞))
839871
end

test/test_triangle.jl

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using MultivariateOrthogonalPolynomials, StaticArrays, BlockArrays, BlockBandedMatrices, ArrayLayouts,
22
QuasiArrays, Test, ClassicalOrthogonalPolynomials, BandedMatrices, FastTransforms, LinearAlgebra, ContinuumArrays
3-
import MultivariateOrthogonalPolynomials: tri_forwardrecurrence, grid, TriangleRecurrenceA, TriangleRecurrenceB, TriangleRecurrenceC, xy_muladd!, ExpansionLayout, Triangle, ApplyBandedBlockBandedLayout
3+
import MultivariateOrthogonalPolynomials: tri_forwardrecurrence, grid, TriangleRecurrenceA, TriangleRecurrenceB, TriangleRecurrenceC, xy_muladd!, ExpansionLayout, Triangle, ApplyBandedBlockBandedLayout, weightedgrammatrix
44

55
@testset "Triangle" begin
66
@testset "basics" begin
@@ -522,14 +522,71 @@ import MultivariateOrthogonalPolynomials: tri_forwardrecurrence, grid, TriangleR
522522
∂ʸ = PartialDerivative{2}(𝐱)
523523
Pfx = ∂ˣ * Pf
524524
Pfy = ∂ʸ * Pf
525-
for _ in 1:100
525+
526+
@test (coefficients(∂ˣ * P) * coefficients(Pf))[1:50] coefficients(Pfx)[1:50] coefficients(∂ˣ * P)[1:50,1:50] * coefficients(Pf)[1:50]
527+
for _ in 1:100
526528
u, v = minmax(rand(2)...)
527529
x, y = v - u, 1 - v # random point in the triangle
528530
@test Pfx[SVector(x, y)] dfx((x, y))
529531
@test Pfy[SVector(x, y)] dfy((x, y))
530532
end
531-
end
533+
end
532534
end
533535
end
534536
end
537+
538+
@testset "Weighted grammatrix" begin
539+
P = JacobiTriangle()
540+
D = weightedgrammatrix(P)
541+
542+
KR = Block.(1:10)
543+
@test D[KR,KR] == grammatrix(P)[KR,KR]
544+
for k = 1:5
545+
@test sum(P[:,k].^2) D[k,k]
546+
end
547+
548+
Q = JacobiTriangle(1,1,1)
549+
D = weightedgrammatrix(Q)
550+
551+
552+
553+
𝐱 = axes(P,1)
554+
x,y = first.(𝐱),last.(𝐱)
555+
for k = 1:5
556+
@test sum(x .* y .* (1 .- x .- y) .* Q[:,k].^2) D[k,k]
557+
end
558+
559+
560+
W = Weighted(Q)
561+
562+
PW = P'W
563+
WP = W'P
564+
for k = 1:5, j=1:5
565+
@test sum(W[:,j] .* P[:,k]) PW[k,j] atol=1E-14
566+
@test PW[k,j] WP[j,k] atol=1E-14
567+
end
568+
569+
f = expand(P, splat((x,y) -> exp(x*cos(y))))
570+
571+
c = W'f
572+
573+
for k = 1:5
574+
@test c[k] sum(expand(P, splat((x,y) -> (W[SVector(x,y),k]::Float64) * exp(x*cos(y)))))
575+
end
576+
end
577+
578+
@testset "Weak formulation" begin
579+
P = JacobiTriangle()
580+
W = Weighted(JacobiTriangle(1,1,1))
581+
𝐱 = axes(W,1)
582+
∂_x = PartialDerivative{1}(𝐱)
583+
∂_y = PartialDerivative{2}(𝐱)
584+
Δ = -((∂_x*W)'*(∂_x*W) + (∂_y*W)'*(∂_y*W))
585+
M = W'W
586+
f = expand(P, splat((x,y) -> exp(x*cos(y))))
587+
κ = 10
588+
A = Δ + κ^2*M
589+
c = \(A, W'f; tolerance=1E-4)
590+
@test (W*c)[SVector(0.1,0.2)] -0.005927539175184257 # empirical
591+
end
535592
end

0 commit comments

Comments
 (0)