Skip to content

Commit b963c6c

Browse files
authored
Start Disk (#59)
* UnitTriangle = UnitSimplex{2} * Start disk * add getindex for DISK * Update runtests.jl * Update Project.toml * add exact eval comparisons * test DiskTrav
1 parent 94ce2a4 commit b963c6c

File tree

6 files changed

+117
-266
lines changed

6 files changed

+117
-266
lines changed

Project.toml

Lines changed: 10 additions & 9 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.0.6"
3+
version = "0.0.7"
44

55
[deps]
66
ArrayLayouts = "4c555306-a7a7-4459-81d9-ec55ddd5c99a"
@@ -19,25 +19,26 @@ LazyArrays = "5078a376-72f3-5289-bfd5-ec5146d43c02"
1919
LazyBandedMatrices = "d7e5e226-e90b-4449-9968-0f923699bf6f"
2020
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
2121
QuasiArrays = "c4ea9172-b204-11e9-377d-29865faadc5c"
22+
SemiseparableMatrices = "f8ebbe35-cbfb-4060-bf7f-b10e4670cf57"
2223
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"
2324
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
2425
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
2526

2627
[compat]
27-
ArrayLayouts = "0.5.1, 0.6"
28+
ArrayLayouts = "0.6"
2829
BandedMatrices = "0.16"
29-
BlockArrays = "0.14.1"
30+
BlockArrays = "0.14.1, 0.15"
3031
BlockBandedMatrices = "0.10.1"
31-
ClassicalOrthogonalPolynomials = "0.1.1, 0.2"
32+
ClassicalOrthogonalPolynomials = "0.3"
3233
ContinuumArrays = "0.5, 0.6"
3334
DomainSets = "0.4"
3435
FastTransforms = "0.11, 0.12"
3536
FillArrays = "0.11"
36-
HarmonicOrthogonalPolynomials = "0.0.1, 0.0.2"
37-
InfiniteArrays = "0.9.5, 0.10"
38-
InfiniteLinearAlgebra = "0.4.5, 0.5"
39-
LazyArrays = "0.20.5"
40-
LazyBandedMatrices = "0.4.7, 0.5"
37+
HarmonicOrthogonalPolynomials = "0.0.3"
38+
InfiniteArrays = "0.10"
39+
InfiniteLinearAlgebra = "0.5"
40+
LazyArrays = "0.21"
41+
LazyBandedMatrices = "0.5"
4142
QuasiArrays = "0.4"
4243
SpecialFunctions = "0.10, 1"
4344
StaticArrays = "0.12, 1"

src/MultivariateOrthogonalPolynomials.jl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@ import LinearAlgebra: factorize
1616
import LazyArrays: arguments, paddeddata
1717

1818
import ClassicalOrthogonalPolynomials: jacobimatrix
19-
import HarmonicOrthogonalPolynomials: BivariateOrthogonalPolynomial, MultivariateOrthogonalPolynomial, PartialDerivative, BlockOneTo
19+
import HarmonicOrthogonalPolynomials: BivariateOrthogonalPolynomial, MultivariateOrthogonalPolynomial,
20+
PartialDerivative, BlockOneTo, interlace
2021

21-
export Triangle, JacobiTriangle, TriangleWeight, WeightedTriangle, PartialDerivative, Laplacian, MultivariateOrthogonalPolynomial, BivariateOrthogonalPolynomial
22+
export UnitTriangle, UnitDisk, JacobiTriangle, TriangleWeight, WeightedTriangle, PartialDerivative, Laplacian,
23+
MultivariateOrthogonalPolynomial, BivariateOrthogonalPolynomial, Zernike, RadialCoordinate
2224

2325
if VERSION < v"1.6-"
2426
oneto(n) = Base.OneTo(n)
@@ -28,7 +30,8 @@ end
2830

2931

3032

31-
include("Triangle/Triangle.jl")
33+
include("disk.jl")
34+
include("triangle.jl")
3235

3336

3437
end # module

src/disk.jl

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
"""
2+
DiskTrav(A::AbstractMatrix)
3+
4+
takes coefficients as provided by the Zernike polynomial layout of FastTransforms.jl and
5+
makes them accessible sorted such that in each block the m=0 entries are always in first place,
6+
followed by alternating sin and cos terms of increasing |m|.
7+
"""
8+
struct DiskTrav{T, AA<:AbstractMatrix{T}} <: AbstractBlockVector{T}
9+
matrix::AA
10+
function DiskTrav{T, AA}(matrix::AA) where {T,AA<:AbstractMatrix{T}}
11+
n,m = size(matrix)
12+
isodd(m) && n == m ÷ 4 + 1 || throw(ArgumentError("size must match"))
13+
new{T,AA}(matrix)
14+
end
15+
end
16+
17+
DiskTrav{T}(matrix::AbstractMatrix{T}) where T = DiskTrav{T,typeof(matrix)}(matrix)
18+
DiskTrav(matrix::AbstractMatrix{T}) where T = DiskTrav{T}(matrix)
19+
20+
axes(A::DiskTrav) = (blockedrange(oneto(div(size(A.matrix,2),2,RoundUp))),)
21+
22+
function getindex(A::DiskTrav, K::Block{1})
23+
k = Int(K)
24+
k == 1 && return A.matrix[1:1]
25+
k == 2 && return A.matrix[1,2:3]
26+
st = stride(A.matrix,2)
27+
if isodd(k)
28+
# nonnegative terms
29+
p = A.matrix[range(k÷2+1, step=4*st-1, length=k÷2+1)]
30+
# negative terms
31+
n = A.matrix[range(k÷2+3*st, step=4*st-1, length=k÷2)]
32+
interlace(p,n)
33+
else
34+
# negative terms
35+
n = A.matrix[range(st+k÷2, step=4*st-1, length=k÷2)]
36+
# positive terms
37+
p = A.matrix[range(2st+k÷2, step=4*st-1, length=k÷2)]
38+
interlace(n,p)
39+
end
40+
end
41+
42+
getindex(A::DiskTrav, k::Int) = A[findblockindex(axes(A,1), k)]
43+
44+
ClassicalOrthogonalPolynomials.checkpoints(d::UnitDisk{T}) where T = [SVector{2,T}(0.1,0.2), SVector{2,T}(0.2,0.3)]
45+
46+
47+
struct Zernike{T} <: BivariateOrthogonalPolynomial{T} end
48+
49+
Zernike() = Zernike{Float64}()
50+
51+
axes(P::Zernike{T}) where T = (Inclusion(UnitDisk{T}()),blockedrange(oneto(∞)))
52+
53+
copy(A::Zernike) = A
54+
55+
function getindex(Z::Zernike{T}, rθ::RadialCoordinate, B::BlockIndex{1}) where T
56+
r,θ =.r, rθ.θ
57+
= Int(block(B))-1
58+
k = blockindex(B)
59+
m = iseven(ℓ) ? k-isodd(k) : k-iseven(k)
60+
if iszero(m)
61+
sqrt(convert(T,2)/π) * Normalized(Legendre{T}())[2r^2-1, ℓ ÷ 2 + 1]
62+
else
63+
convert(T,2^((m+2)/2))/π * r^m * Normalized(Jacobi{T}(0, m))[2r^2-1,(ℓ-m) ÷ 2 + 1] * (isodd(k+ℓ) ? cos(m*θ) : sin(m*θ))
64+
end
65+
end
66+
67+
68+
getindex(Z::Zernike, xy::StaticVector{2}, B::BlockIndex{1}) = Z[RadialCoordinate(xy), B]
69+
getindex(Z::Zernike, xy::StaticVector{2}, B::Block{1}) = [Z[xy, B[j]] for j=1:Int(B)]
70+
getindex(Z::Zernike, xy::StaticVector{2}, JR::BlockOneTo) = mortar([Z[xy,Block(J)] for J = 1:Int(JR[end])])

src/Triangle/Triangle.jl renamed to src/triangle.jl

Lines changed: 4 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,6 @@
1-
## Triangle Def
2-
struct Triangle <: EuclideanDomain{2,Float64}
3-
a::SVector{2,Float64}
4-
b::SVector{2,Float64}
5-
c::SVector{2,Float64}
6-
end
7-
8-
Triangle() = Triangle(SVector(0,0), SVector(1,0), SVector(0,1))
9-
function in(p::SVector{2,Float64}, d::Triangle)
10-
x,y = p
11-
0  x  x + y  1
12-
end
13-
14-
15-
16-
# issubset(a::Segment{<:SVector{2}}, b::Triangle) = all(in.(endpoints(a), Ref(b)))
17-
18-
19-
#canonical is rectangle [0,1]^2
20-
# with the map (x,y)=(s,(1-s)*t)
21-
iduffy(st::SVector) = SVector(st[1],(1-st[1])*st[2])
22-
iduffy(s,t) = SVector(s,(1-s)*t)
23-
duffy(xy::SVector) = SVector(xy[1],xy[1]==1 ? zero(eltype(xy)) : xy[2]/(1-xy[1]))
24-
duffy(x::T,y::T) where T = SVector(x,x == 1 ? zero(Y) : y/(1-x))
25-
26-
boundary(d::Triangle) = PiecewiseSegment([d.a,d.b,d.c,d.a])
27-
28-
29-
Base.isnan(::Triangle) = false
30-
31-
function tocanonical(d::Triangle, xy::SVector{2})
32-
if all(iszero,d.a)
33-
[d.b d.c] \ xy
34-
else
35-
tocanonical(d-d.a, xy-d.a)
36-
end
37-
end
38-
39-
function fromcanonical(d::Triangle, xy::SVector{2})
40-
if all(iszero,d.a)
41-
[d.b d.c]*xy
42-
else
43-
fromcanonical(d-d.a, xy) + d.a
44-
end
45-
end
1+
const UnitTriangle{T} = UnitSimplex{2,T,:closed}
462

47-
ClassicalOrthogonalPolynomials.checkpoints(d::Triangle) = fromcanonical.(Ref(d), [SVector(0.1,0.2), SVector(0.2,0.3)])
3+
ClassicalOrthogonalPolynomials.checkpoints(d::UnitTriangle{T}) where T = [SVector{2,T}(0.1,0.2), SVector{2,T}(0.2,0.3)]
484

495
# expansion in OPs orthogonal to
506
# x^a*y^b*(1-x-y)^c
@@ -63,7 +19,7 @@ JacobiTriangle(a::T, b::T, c::T) where T = JacobiTriangle{float(T),T}(a, b, c)
6319
JacobiTriangle() = JacobiTriangle(0,0,0)
6420
==(K1::JacobiTriangle, K2::JacobiTriangle) = K1.a == K2.a && K1.b == K2.b && K1.c == K2.c
6521

66-
axes(P::JacobiTriangle) = (Inclusion(Triangle()),blockedrange(oneto(∞)))
22+
axes(P::JacobiTriangle{T}) where T = (Inclusion(UnitTriangle{T}()),blockedrange(oneto(∞)))
6723

6824
copy(A::JacobiTriangle) = A
6925

@@ -81,7 +37,7 @@ const WeightedTriangle{T} = WeightedBasis{T,<:TriangleWeight,<:JacobiTriangle}
8137

8238
WeightedTriangle(a, b, c) = TriangleWeight(a,b,c) .* JacobiTriangle(a,b,c)
8339

84-
axes(P::TriangleWeight) = (Inclusion(Triangle()),)
40+
axes(P::TriangleWeight{T}) where T = (Inclusion(UnitTriangle{T}()),)
8541

8642
Base.summary(io::IO, P::TriangleWeight) = print(io, "x^$(P.a)*y^$(P.b)*(1-x-y)^$(P.c) on the unit triangle")
8743

test/runtests.jl

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

3+
include("test_disk.jl")
34
include("test_triangle.jl")
45
# include("test_dirichlettriangle.jl")
56

0 commit comments

Comments
 (0)