Skip to content

Commit 1bb04f6

Browse files
committed
Update transform
1 parent 1ff9937 commit 1bb04f6

File tree

3 files changed

+99
-61
lines changed

3 files changed

+99
-61
lines changed

src/Disk/Disk.jl

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,15 @@ end
77
ZernikeDisk(d::Disk{V}) where V = ZernikeDisk{V,complex(eltype(V))}(d)
88
ZernikeDisk() = ZernikeDisk(Disk())
99

10+
spacescompatible(::ZernikeDisk, ::ZernikeDisk) = true
11+
1012
@containsconstants ZernikeDisk
1113

1214
points(K::ZernikeDisk, n::Integer) =
1315
fromcanonical.(Ref(K), points(ChebyshevDisk(), n))
1416

17+
evaluate(cfs::AbstractVector, Z::ZernikeDisk, xy) =
18+
Fun(Fun(Z, cfs), ChebyshevDisk())(xy)
1519

1620
struct ChebyshevDisk{V,T} <: Space{Disk{V},T}
1721
domain::Disk{V}
@@ -84,6 +88,33 @@ fromrectcfs(S, v) = fromtensor(S, checkerboard(totensor(rectspace(S),v)))
8488
evaluate(cfs::AbstractVector, S::ChebyshevDisk, x) = evaluate(torectcfs(S,cfs), rectspace(S), ipolar(x))
8589

8690

91+
function _coefficients(disk2cxf, v̂::AbstractVector, ::ChebyshevDisk, ::ZernikeDisk)
92+
F = totensor(ChebyshevDisk(), v̂)
93+
F *= sqrt(convert(T,π))
94+
n = size(F,1)
95+
= disk2cxf \ pad(F,n,4n-3)
96+
trivec(F̌)
97+
end
98+
99+
function _coefficients(disk2cxf, v::AbstractVector, ::ZernikeDisk, ::ChebyshevDisk)
100+
= tridevec(v)
101+
/= sqrt(convert(T,π))
102+
n = size(F,1)
103+
F = disk2cxf \ pad(F̌,n,4n-3)
104+
fromtensor(ChebyshevDisk(), F)
105+
end
106+
107+
function coefficients(cfs::AbstractVector, CD::ChebyshevDisk, ZD::ZernikeDisk)
108+
c = totensor(ChebyshevDisk(), cfs) # TODO: wasteful
109+
n = size(c,1)
110+
_coefficients(CDisk2CxfPlan(n), cfs, CD, ZD)
111+
end
112+
113+
function coefficients(cfs::AbstractVector, ZD::ZernikeDisk, CD::ChebyshevDisk)
114+
c = tridevec(cfs) # TODO: wasteful
115+
n = size(c,1)
116+
_coefficients(CDisk2CxfPlan(n), cfs, CD, ZD)
117+
end
87118

88119

89120
struct FastZernikeDiskTransformPlan{DUF,CHEB}
@@ -94,15 +125,14 @@ end
94125
function FastZernikeDiskTransformPlan(S::ZernikeDisk, v::AbstractVector{T}) where T
95126
# n = floor(Integer,sqrt(2length(v)) + 1/2)
96127
# v = Array{T}(undef, sum(1:n))
97-
FastZernikeDiskTransformPlan(plan_transform(ChebyshevDisk(),v), CDisk2CxfPlan(n))
128+
cxfplan = plan_transform(ChebyshevDisk(),v)
129+
c = totensor(ChebyshevDisk(), cxfplan*v) # TODO: wasteful
130+
n = size(c,1)
131+
FastZernikeDiskTransformPlan(cxfplan, CDisk2CxfPlan(n))
98132
end
99133

100-
function *(P::FastZernikeDiskTransformPlan, v)
101-
= P.cxfplan*v
102-
F = tridevec_trans(v̂)
103-
= P.disk2cheb \ F
104-
trivec(tridenormalize!(F̌))
105-
end
134+
*(P::FastZernikeDiskTransformPlan, v::AbstractVector) =
135+
_coefficients(P.disk2cxf, P.cxfplan*v, ChebyshevDisk(), ZernikeDisk())
106136

107137
plan_transform(K::ZernikeDisk, v::AbstractVector) = FastZernikeDiskTransformPlan(K, v)
108138

src/c_transforms.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ end
6666
CDisk2CxfPlan(n::Int) = CDisk2CxfPlan(c_plan_disk2cxf(n), n)
6767

6868
function *(C::CDisk2CxfPlan, A::Matrix{Float64})
69-
(size(A,1) == C.n+1 && size(A,2) == 4C.n+1) || throw(ArgumentError(A))
69+
(size(A,1) == C.n+1 && size(A,2) == 4C.n-3) || throw(ArgumentError(A))
7070
B = copy(A)
7171
c_disk2cxf(C.plan, B)
7272
B

test/test_disk.jl

Lines changed: 61 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,10 @@
11
using Revise, ApproxFun, MultivariateOrthogonalPolynomials
22
import MultivariateOrthogonalPolynomials: checkerboard, icheckerboard, CDisk2CxfPlan
33
import ApproxFunBase: totensor
4-
import ApproxFunOrthogonalPolynomials: jacobip, chebyshevt
4+
import ApproxFunOrthogonalPolynomials: jacobip
55

66

77

8-
9-
10-
f = (x,y) -> x*y+cos(y-0.1)+sin(x)+1;
11-
ff = Fun(f, ChebyshevDisk(), 1000)
12-
@test ff(0.1,0.2) f(0.1,0.2)
13-
14-
ff = Fun(f, ChebyshevDisk())
15-
@test ff(0.1,0.2) f(0.1,0.2)
16-
178
function chebydiskeval(c::AbstractMatrix{T}, r, θ) where T
189
ret = zero(T)
1910
for j = 1:2:size(c,2), k=1:size(c,1)
@@ -28,66 +19,83 @@ function chebydiskeval(c::AbstractMatrix{T}, r, θ) where T
2819
end
2920

3021

31-
for (m,ℓ) in ((0,1),(0,2),(0,3), (1,0), (1,1), (1,2), (2,0), (2,1),(3,0),(3,4))
32-
p1 = (r,θ) -> cos(m*θ) * cos((2+isodd(m))*acos(r))
33-
f = Fun((x,y) -> p1(sqrt(x^2+y^2), atan(y,x)), ChebyshevDisk())
34-
c = totensor(f.space, chop(f.coefficients,1E-12))
35-
@test c[ℓ+1, 2m+1] 1
36-
@test f(0.1cos(0.2),0.1sin(0.2)) chebydiskeval(c, 0.1, 0.2)
22+
@testset "ChebyshevDisk" begin
23+
f = (x,y) -> x*y+cos(y-0.1)+sin(x)+1;
24+
ff = Fun(f, ChebyshevDisk(), 1000)
25+
@test ff(0.1,0.2) f(0.1,0.2)
26+
27+
ff = Fun(f, ChebyshevDisk())
28+
@test ff(0.1,0.2) f(0.1,0.2)
29+
3730

38-
if m > 0
39-
p2 = (r,θ) -> sin(m*θ) * cos((2+isodd(m))*acos(r))
40-
f = Fun((x,y) -> p2(sqrt(x^2+y^2), atan(y,x)), ChebyshevDisk())
31+
for (m,ℓ) in ((0,1),(0,2),(0,3), (1,0), (1,1), (1,2), (2,0), (2,1),(3,0),(3,4))
32+
p1 = (r,θ) -> cos(m*θ) * cos((2+isodd(m))*acos(r))
33+
f = Fun((x,y) -> p1(sqrt(x^2+y^2), atan(y,x)), ChebyshevDisk())
4134
c = totensor(f.space, chop(f.coefficients,1E-12))
42-
@test c[ℓ+1, 2m] 1
35+
@test c[ℓ+1, 2m+1] 1
4336
@test f(0.1cos(0.2),0.1sin(0.2)) chebydiskeval(c, 0.1, 0.2)
37+
38+
if m > 0
39+
p2 = (r,θ) -> sin(m*θ) * cos((2+isodd(m))*acos(r))
40+
f = Fun((x,y) -> p2(sqrt(x^2+y^2), atan(y,x)), ChebyshevDisk())
41+
c = totensor(f.space, chop(f.coefficients,1E-12))
42+
@test c[ℓ+1, 2m] 1
43+
@test f(0.1cos(0.2),0.1sin(0.2)) chebydiskeval(c, 0.1, 0.2)
44+
end
4445
end
4546
end
4647

47-
f = Fun((x,y) -> 1, ChebyshevDisk()); n = 1;
48+
49+
@testset "disk transform" begin
50+
f = Fun((x,y) -> 1, ChebyshevDisk()); n = 1;
4851
c = totensor(f.space, f.coefficients)
4952
P = CDisk2CxfPlan(n)
5053
d = P \ c
5154
@test d [1/sqrt(2)]
52-
f = Fun((x,y) -> y, ChebyshevDisk()); n = 2;
55+
f = Fun((x,y) -> y, ChebyshevDisk()); n = 2;
5356
c = totensor(f.space, f.coefficients)
5457
c = pad(c, n, 4n-3)
5558
P = CDisk2CxfPlan(n)
5659
d = P \ c
57-
@test d [0.0 0.5 0.0 0.0 0.0; 0.0 0.0 0.0 0.0 0.0]
60+
@test d [0.0 0.5 0.0 0.0 0.0 ; 0.0 0.0 0.0 0.0 0.0]
5861

59-
f = Fun((x,y) -> x, ChebyshevDisk()); n = 2;
62+
f = Fun((x,y) -> x, ChebyshevDisk()); n = 2;
6063
c = totensor(f.space, f.coefficients)
6164
c = pad(c, n, 4n-3)
6265
P = CDisk2CxfPlan(n)
6366
d = P \ c
64-
@test d [0.0 0.0 0.5 0.0 0.0; 0.0 0.0 0.0 0.0 0.0]
65-
66-
67-
# m,ℓ = (0,2);
68-
# m,ℓ = (1,1);
69-
# m,ℓ = (2,2);
70-
71-
72-
m,ℓ = (2,4);
73-
p1 = (r,θ) -> sqrt(2+2)*r^m*jacobip((ℓ-m)÷2, m, 0, 2r^2-1)*cos(m*θ)/sqrt(2π)
74-
f = Fun((x,y) -> p1(sqrt(x^2+y^2), atan(y,x)), ChebyshevDisk());
75-
@test f(0.1*cos(0.2),0.1*sin(0.2)) p1(0.1,0.2)
76-
c = totensor(f.space, chop(f.coefficients,1E-12))
77-
@test chebydiskeval(c, 0.1, 0.2) p1(0.1,0.2)
78-
79-
80-
n = size(c,1); c = sqrt(2π)*pad(c,n,4n-3)
81-
P = CDisk2CxfPlan(n)
82-
d = P \ c
83-
@test d[(ℓ-m)÷2, 2m+1] 0
84-
@test d[(ℓ-m)÷2+1, 2m+1] 1
85-
86-
87-
88-
89-
90-
91-
92-
67+
@test d [0.0 0.0 0.5 0.0 0.0; 0.0 0.0 0.0 0.0 0.0]
68+
69+
70+
@testset "explicit polynomial" begin
71+
p1 = (r,θ) -> sqrt(10)*r^2*(4r^2-3)*cos(2θ)/sqrt(π)
72+
f = Fun((x,y) -> p1(sqrt(x^2+y^2), atan(y,x)), ChebyshevDisk());
73+
@test f(0.1*cos(0.2),0.1*sin(0.2)) p1(0.1,0.2)
74+
c = totensor(f.space, chop(f.coefficients,1E-12))
75+
@test chebydiskeval(c, 0.1, 0.2) p1(0.1,0.2)
76+
n = size(c,1); c = sqrt(π)*pad(c,n,4n-3)
77+
P = CDisk2CxfPlan(n)
78+
d = P \ c
79+
@test d[1,4] 0 atol=1E-13
80+
@test d[2,5] 1
81+
end
82+
@testset "different m and ℓ" begin
83+
for (m,ℓ) in ((0,2), (1,1), (2,2), (2,6), (3,3))
84+
p1 = (r,θ) -> sqrt(2+2)*r^m*jacobip((ℓ-m)÷2, 0, m, 2r^2-1)*cos(m*θ)/sqrt(π)
85+
f = Fun((x,y) -> p1(sqrt(x^2+y^2), atan(y,x)), ChebyshevDisk());
86+
@test f(0.1*cos(0.2),0.1*sin(0.2)) p1(0.1,0.2)
87+
c = totensor(f.space, chop(f.coefficients,1E-12))
88+
@test chebydiskeval(c, 0.1, 0.2) p1(0.1,0.2)
89+
90+
n = size(c,1); c = sqrt(π)*pad(c,n,4n-3)
91+
P = CDisk2CxfPlan(n)
92+
d = P \ c
93+
@test norm(d[:, 1:2m]) 0 atol = 1E-13
94+
@test norm(d[1:(ℓ-m)÷2, 2m+1]) 0 atol = 1E-13
95+
@test d[(ℓ-m)÷2+1, 2m+1] 1
96+
@test norm(d[(ℓ-m)÷2+2:end, 2m+1]) 0 atol = 1E-13
97+
@test norm(d[:, 2m+2:end]) 0 atol = 1E-13
98+
end
99+
end
100+
end
93101

0 commit comments

Comments
 (0)