Skip to content

Commit 70c54d0

Browse files
authored
Start Kronecker product of OPs (#130)
* Start Kronecker product of OPs * Basic tests * Rectangle PDE solve * Update rect.jl * add recttests * Update test_rect.jl
1 parent 5b55d9d commit 70c54d0

File tree

5 files changed

+113
-8
lines changed

5 files changed

+113
-8
lines changed

Project.toml

Lines changed: 5 additions & 5 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.3"
3+
version = "0.3.0"
44

55
[deps]
66
ArrayLayouts = "4c555306-a7a7-4459-81d9-ec55ddd5c99a"
@@ -25,19 +25,19 @@ Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
2525

2626
[compat]
2727
ArrayLayouts = "0.8.6"
28-
BandedMatrices = "0.16, 0.17"
28+
BandedMatrices = "0.17"
2929
BlockArrays = "0.16.14"
3030
BlockBandedMatrices = "0.11.5"
31-
ClassicalOrthogonalPolynomials = "0.5.1, 0.6"
31+
ClassicalOrthogonalPolynomials = "0.6"
3232
ContinuumArrays = "0.10.2"
3333
DomainSets = "0.5"
3434
FastTransforms = "0.13, 0.14"
3535
FillArrays = "0.12, 0.13"
36-
HarmonicOrthogonalPolynomials = "0.2.4"
36+
HarmonicOrthogonalPolynomials = "0.2.7"
3737
InfiniteArrays = "0.12"
3838
InfiniteLinearAlgebra = "0.6.6"
3939
LazyArrays = "0.22.10"
40-
LazyBandedMatrices = "0.7.15"
40+
LazyBandedMatrices = "0.8"
4141
QuasiArrays = "0.9"
4242
SpecialFunctions = "1, 2"
4343
StaticArrays = "1"

src/MultivariateOrthogonalPolynomials.jl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ import Base: axes, in, ==, *, ^, \, copy, copyto!, OneTo, getindex, size, oneto,
1010
import Base.Broadcast: Broadcasted, broadcasted, DefaultArrayStyle
1111
import DomainSets: boundary
1212

13-
import QuasiArrays: LazyQuasiMatrix, LazyQuasiArrayStyle
13+
import QuasiArrays: LazyQuasiMatrix, LazyQuasiArrayStyle, domain
1414
import ContinuumArrays: @simplify, Weight, weight, grid, plotgrid, TransformFactorization, ExpansionLayout, plotvalues, unweighted
1515

1616
import ArrayLayouts: MemoryLayout, sublayout, sub_materialize
1717
import BlockArrays: block, blockindex, BlockSlice, viewblock, blockcolsupport, AbstractBlockStyle, BlockStyle
1818
import BlockBandedMatrices: _BandedBlockBandedMatrix, AbstractBandedBlockBandedMatrix, _BandedMatrix, blockbandwidths, subblockbandwidths
1919
import LinearAlgebra: factorize
2020
import LazyArrays: arguments, paddeddata, LazyArrayStyle, LazyLayout
21-
import LazyBandedMatrices: LazyBandedBlockBandedLayout, AbstractBandedBlockBandedLayout, AbstractLazyBandedBlockBandedLayout
21+
import LazyBandedMatrices: LazyBandedBlockBandedLayout, AbstractBandedBlockBandedLayout, AbstractLazyBandedBlockBandedLayout, _krontrav_axes
2222
import InfiniteArrays: InfiniteCardinal
2323

2424
import ClassicalOrthogonalPolynomials: jacobimatrix, Weighted, orthogonalityweight, HalfWeighted, WeightedBasis
@@ -31,9 +31,10 @@ export MultivariateOrthogonalPolynomial, BivariateOrthogonalPolynomial,
3131
DunklXuDisk, DunklXuDiskWeight, WeightedDunklXuDisk,
3232
Zernike, ZernikeWeight, zerniker, zernikez,
3333
PartialDerivative, Laplacian, AbsLaplacianPower, AngularMomentum,
34-
RadialCoordinate, Weighted, Block, jacobimatrix
34+
RadialCoordinate, Weighted, Block, jacobimatrix, KronPolynomial, RectPolynomial
3535

3636
include("ModalInterlace.jl")
37+
include("rect.jl")
3738
include("disk.jl")
3839
include("rectdisk.jl")
3940
include("triangle.jl")

src/rect.jl

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
struct KronPolynomial{d, T, PP} <: MultivariateOrthogonalPolynomial{d, T}
2+
args::PP
3+
end
4+
5+
KronPolynomial{d,T}(a::Vararg{Any,d}) where {d,T} = KronPolynomial{d,T,typeof(a)}(a)
6+
KronPolynomial{d}(a::Vararg{Any,d}) where d = KronPolynomial{d,mapreduce(eltype, promote_type, a)}(a...)
7+
KronPolynomial(a::Vararg{Any,d}) where d = KronPolynomial{d}(a...)
8+
9+
const RectPolynomial{T, PP} = KronPolynomial{2, T, PP}
10+
11+
12+
axes(P::KronPolynomial) = (Inclusion(×(map(domain, axes.(P.args, 1))...)), _krontrav_axes(axes.(P.args, 2)...))
13+
function getindex(P::RectPolynomial{T}, xy::StaticVector{2}, Jj::BlockIndex{1})::T where T
14+
a,b = P.args
15+
J,j = Int(block(Jj)),blockindex(Jj)
16+
x,y = xy
17+
a[x,J-j+1]b[y,j]
18+
end
19+
getindex(P::RectPolynomial, xy::StaticVector{2}, B::Block{1}) = [P[xy, B[j]] for j=1:Int(B)]
20+
getindex(P::RectPolynomial, xy::StaticVector{2}, JR::BlockOneTo) = mortar([P[xy,Block(J)] for J = 1:Int(JR[end])])
21+
22+
@simplify function *(Dx::PartialDerivative{1}, P::RectPolynomial)
23+
A,B = P.args
24+
U,M = (Derivative(axes(A,1))*A).args
25+
# We want I ⊗ D² as A ⊗ B means B * X * A'
26+
RectPolynomial(U,B) * KronTrav(Eye{eltype(M)}(∞), M)
27+
end
28+
29+
@simplify function *(Dx::PartialDerivative{2}, P::RectPolynomial)
30+
A,B = P.args
31+
U,M = (Derivative(axes(B,1))*B).args
32+
RectPolynomial(A,U) * KronTrav(M, Eye{eltype(M)}(∞))
33+
end
34+
35+
function \(P::RectPolynomial, Q::RectPolynomial)
36+
PA,PB = P.args
37+
QA,QB = Q.args
38+
KronTrav(PA\QA, PB\QB)
39+
end

test/runtests.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using MultivariateOrthogonalPolynomials, Test
22

3+
4+
include("test_rect.jl")
35
include("test_modalinterlace.jl")
46
include("test_disk.jl")
57
include("test_rectdisk.jl")

test/test_rect.jl

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
using MultivariateOrthogonalPolynomials, ClassicalOrthogonalPolynomials, StaticArrays, LinearAlgebra, Test
2+
3+
@testset "RectPolynomial" begin
4+
@testset "Evaluation" begin
5+
T = ChebyshevT()
6+
= RectPolynomial(T, T)
7+
xy = SVector(0.1,0.2)
8+
@test T²[xy, Block(1)[1]] == T²[xy, 1]
9+
@test T²[xy, Block(1)] == T²[xy, Block.(1:1)]
10+
@test T²[xy, Block(2)] == [0.1,0.2]
11+
@test T²[xy, Block(3)] [cos(2*acos(0.1)), 0.1*0.2, cos(2*acos(0.2))]
12+
13+
U = ChebyshevU()
14+
V = KronPolynomial(T, U)
15+
@test V[xy, Block(1)[1]] == V[xy, 1]
16+
@test V[xy, Block(1)] == V[xy, Block.(1:1)]
17+
@test V[xy, Block(2)] == [0.1,2*0.2]
18+
@test V[xy, Block(3)] [cos(2*acos(0.1)), 2*0.1*0.2, sin(3*acos(0.2))/sin(acos(0.2))]
19+
end
20+
21+
@testset "Conversion" begin
22+
T = ChebyshevT()
23+
U = ChebyshevU()
24+
= RectPolynomial(T, T)
25+
= RectPolynomial(U, U)
26+
\
27+
end
28+
29+
@testset "Derivatives" begin
30+
T = ChebyshevT()
31+
U = ChebyshevU()
32+
C = Ultraspherical(2)
33+
= RectPolynomial(T, T)
34+
= RectPolynomial(U, U)
35+
= RectPolynomial(C, C)
36+
xy = axes(T²,1)
37+
D_x,D_y = PartialDerivative{1}(xy),PartialDerivative{2}(xy)
38+
D_x*
39+
D_y*
40+
\D_x*
41+
\D_y*
42+
43+
\(D_x + D_y)*
44+
A =\D_x^2*
45+
B =\D_y^2*
46+
\(D_x^2 + D_y^2)*
47+
end
48+
49+
@testset "PDEs" begin
50+
Q = Jacobi(1,1)
51+
W = Weighted(Q)
52+
P = Legendre()
53+
= RectPolynomial(W, W)
54+
= RectPolynomial(P, P)
55+
= RectPolynomial(Q, Q)
56+
xy = axes(W²,1)
57+
D_x,D_y = PartialDerivative{1}(xy),PartialDerivative{2}(xy)
58+
Δ =\(D_x^2 + D_y^2)*
59+
60+
K = Block.(1:200); @time L = Δ[K,K]; @time qr(L);
61+
\(qr(Δ), [1; zeros(∞)]; tolerance=1E-1)
62+
end
63+
end

0 commit comments

Comments
 (0)