Skip to content

Commit 53107c7

Browse files
committed
Add Cone
1 parent c29f402 commit 53107c7

File tree

4 files changed

+184
-1
lines changed

4 files changed

+184
-1
lines changed

src/Cone/Cone.jl

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
export Cone, DuffyCone, LegendreCone
2+
3+
struct Cone <: Domain{Vec{3,Float64}} end
4+
struct DuffyCone <: Space{Cone,Float64} end
5+
struct LegendreCone <: Space{Cone,Float64} end
6+
7+
@containsconstants DuffyCone
8+
@containsconstants LegendreCone
9+
10+
spacescompatible(::DuffyCone, ::DuffyCone) = true
11+
spacescompatible(::LegendreCone, ::LegendreCone) = true
12+
13+
domain(::DuffyCone) = Cone()
14+
domain(::LegendreCone) = Cone()
15+
16+
tensorizer(K::DuffyCone) = DiskTensorizer()
17+
tensorizer(K::LegendreCone) = DiskTensorizer()
18+
19+
rectspace(::DuffyCone) = NormalizedJacobi(0,1,Segment(1,0))*Fourier()
20+
21+
conepolar(t,θ) = Vec(t, t*cos(θ), t*sin(θ))
22+
conepolar(tθ) = ((t,θ) = tθ; conepolar(t,θ))
23+
24+
points(::Cone, n) = conepolar.(points(rectspace(DuffyCone()), n))
25+
checkpoints(::Cone) = conepolar.(checkpoints(rectspace(DuffyCone())))
26+
27+
28+
plan_transform(S::DuffyCone, n::AbstractVector) =
29+
TransformPlan(S, plan_transform(rectspace(S),n), Val{false})
30+
plan_itransform(S::DuffyCone, n::AbstractVector) =
31+
ITransformPlan(S, plan_itransform(rectspace(S),n), Val{false})
32+
33+
*(P::TransformPlan{<:Any,<:DuffyCone}, v::AbstractArray) = P.plan*v
34+
*(P::ITransformPlan{<:Any,<:DuffyCone}, v::AbstractArray) = P.plan*v
35+
36+
evaluate(cfs::AbstractVector, S::DuffyCone, txy) = evaluate(cfs, rectspace(S), ipolar(txy[Vec(2,3)]))
37+
evaluate(cfs::AbstractVector, S::LegendreCone, txy) = evaluate(coefficients(cfs, S, DuffyCone()), DuffyCone(), txy)
38+
39+
40+
# function transform(::DuffyCone, v)
41+
# n = (1 + isqrt(1+8*length(v))) ÷ 4
42+
# F = copy(reshape(v,n,2n-1))
43+
# Pt = plan_transform(NormalizedJacobi(0,1,Segment(1,0)), n)
44+
# Pθ = plan_transform(Fourier(), 2n-1)
45+
# for j = 1:size(F,2)
46+
# F[:,j] = Pt*F[:,j]
47+
# end
48+
# for k = 1:size(F,1)
49+
# F[k,:] = Pθ * F[k,:]
50+
# end
51+
# fromtensor(rectspace(DuffyCone()), F)
52+
# end
53+
54+
function evaluate(cfs::AbstractVector, S::DuffyCone, txy::Vec{3})
55+
t,x,y = txy
56+
@assert t sqrt(x^2+y^2)
57+
θ = atan(y,x)
58+
Fun(rectspace(S), cfs)(t,θ)
59+
end
60+
61+
62+
function _coefficients(triangleplan, v::AbstractVector{T}, ::DuffyCone, ::LegendreCone) where T
63+
F = totensor(rectspace(DuffyCone()), v)
64+
F = pad(F, :, 2size(F,1)-1)
65+
Fc = F[:,1:2:end]
66+
c_execute_tri_lo2hi(triangleplan, Fc)
67+
F[:,1:2:end] .= Fc
68+
# ignore first column
69+
Fc[:,2:end] .= F[:,2:2:end]
70+
c_execute_tri_lo2hi(triangleplan, Fc)
71+
F[:,2:2:end] .= Fc[:,2:end]
72+
fromtensor(LegendreCone(), F)
73+
end
74+
75+
function _coefficients(triangleplan, v::AbstractVector{T}, ::LegendreCone, ::DuffyCone) where T
76+
F = totensor(LegendreCone(), v)
77+
F = pad(F, :, 2size(F,1)-1)
78+
Fc = F[:,1:2:end]
79+
c_execute_tri_hi2lo(triangleplan, Fc)
80+
F[:,1:2:end] .= Fc
81+
# ignore first column
82+
Fc[:,2:end] .= F[:,2:2:end]
83+
c_execute_tri_hi2lo(triangleplan, Fc)
84+
F[:,2:2:end] .= Fc[:,2:end]
85+
fromtensor(DuffyCone(), F)
86+
end
87+
88+
function coefficients(cfs::AbstractVector{T}, CD::DuffyCone, ZD::LegendreCone) where T
89+
c = totensor(rectspace(DuffyCone()), cfs) # TODO: wasteful
90+
n = size(c,1)
91+
_coefficients(c_plan_rottriangle(n, zero(T), zero(T), zero(T)), cfs, CD, ZD)
92+
end
93+
94+
function coefficients(cfs::AbstractVector{T}, ZD::LegendreCone, CD::DuffyCone) where T
95+
c = tridevec(cfs) # TODO: wasteful
96+
n = size(c,1)
97+
_coefficients(c_plan_rottriangle(n, zero(T), zero(T), zero(T)), cfs, ZD, CD)
98+
end
99+
100+
struct LegendreConeTransformPlan{DUF,CHEB}
101+
duffyplan::DUF
102+
triangleplan::CHEB
103+
end
104+
105+
function LegendreConeTransformPlan(S::LegendreCone, v::AbstractVector{T}) where T
106+
D = plan_transform(DuffyCone(),v)
107+
F = totensor(rectspace(DuffyCone()), D*v) # wasteful, just use to figure out `size(F,1)`
108+
P = c_plan_rottriangle(size(F,1), zero(T), zero(T), zero(T))
109+
LegendreConeTransformPlan(D,P)
110+
end
111+
112+
113+
*(P::LegendreConeTransformPlan, v::AbstractVector) = _coefficients(P.triangleplan, P.duffyplan*v, DuffyCone(), LegendreCone())
114+
115+
plan_transform(K::LegendreCone, v::AbstractVector) = LegendreConeTransformPlan(K, v)
116+
117+
struct LegendreConeITransformPlan{DUF,CHEB}
118+
iduffyplan::DUF
119+
triangleplan::CHEB
120+
end
121+
122+
function LegendreConeITransformPlan(S::LegendreCone, v::AbstractVector{T}) where T
123+
F = fromtensor(LegendreCone(), v) # wasteful, just use to figure out `size(F,1)`
124+
P = c_plan_rottriangle(size(F,1), zero(T), zero(T), zero(T))
125+
D = plan_itransform(DuffyCone(), _coefficients(P, v, S, DuffyCone()))
126+
LegendreConeITransformPlan(D,P)
127+
end
128+
129+
130+
*(P::LegendreConeITransformPlan, v::AbstractVector) = P.iduffyplan*_coefficients(P.triangleplan, v, LegendreCone(), DuffyCone())
131+
132+
133+
plan_itransform(K::LegendreCone, v::AbstractVector) = LegendreConeITransformPlan(K, v)
134+

src/Disk/Disk.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ function points(S::ChebyshevDisk, N)
3737
polar.(pts)
3838
end
3939

40-
tensorizer(K::ChebyshevDisk) = Tensorizer((Ones{Int}(∞),Ones{Int}(∞)))
40+
DiskTensorizer() = Tensorizer((Ones{Int}(∞),Ones{Int}(∞)))
41+
42+
tensorizer(K::ChebyshevDisk) = DiskTensorizer()
4143

4244
# we have each polynomial
4345
blocklengths(K::ChebyshevDisk) = 1:

src/MultivariateOrthogonalPolynomials.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ include("c_transforms.jl")
6565

6666
include("Triangle/Triangle.jl")
6767
include("Disk/Disk.jl")
68+
include("Cone/Cone.jl")
6869

6970
include("clenshaw.jl")
7071

test/test_cone.jl

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
using Revise
2+
using ApproxFun, MultivariateOrthogonalPolynomials, Test
3+
import MultivariateOrthogonalPolynomials: rectspace, totensor
4+
5+
@testset "DuffyCone" begin
6+
f = Fun((t,x,y) -> 1, DuffyCone(), 10)
7+
@test f.coefficients [1; zeros(ncoefficients(f)-1)]
8+
@test f(sqrt(0.1^2+0.2^2),0.1,0.2) 1
9+
10+
f = Fun((t,x,y) -> t, DuffyCone(), 10)
11+
@test f(sqrt(0.1^2+0.2^2),0.1,0.2) sqrt(0.1^2+0.2^2)
12+
13+
f = Fun((t,x,y) -> x, DuffyCone(), 10)
14+
15+
@test f(sqrt(0.1^2+0.2^2),0.1,0.2) 0.1
16+
17+
f = Fun((t,x,y) -> exp(cos(t*x)*y), DuffyCone(), 1000)
18+
@test f(sqrt(0.1^2+0.2^2),0.1,0.2) exp(cos(sqrt(0.1^2+0.2^2)*0.1)*0.2)
19+
20+
f = Fun((t,x,y) -> exp(cos(t*x)*y), DuffyCone())
21+
@test f(sqrt(0.1^2+0.2^2),0.1,0.2) exp(cos(sqrt(0.1^2+0.2^2)*0.1)*0.2)
22+
end
23+
24+
@testset "Legendre<>DuffyCone" begin
25+
a = randn(10)
26+
F = totensor(rectspace(DuffyCone()), a)
27+
28+
29+
b = coefficients(a, LegendreCone(), DuffyCone())
30+
31+
coefficients(b, DuffyCone(), LegendreCone())
32+
end
33+
34+
@testset "LegendreCone" begin
35+
f = Fun((t,x,y) -> 1, LegendreCone(), 10)
36+
@test f.coefficients [1; zeros(ncoefficients(f)-1)]
37+
@test f(sqrt(0.1^2+0.2^2),0.1,0.2) 1
38+
39+
f = Fun((t,x,y) -> t, LegendreCone(), 10)
40+
@test f(sqrt(0.1^2+0.2^2),0.1,0.2) sqrt(0.1^2+0.2^2)
41+
f = Fun((t,x,y) -> 1+t+x+y, LegendreCone(), 10)
42+
@test f(sqrt(0.1^2+0.2^2),0.1,0.2) 1+sqrt(0.1^2+0.2^2)+0.1+0.2
43+
44+
45+
@time Fun((t,x,y) -> 1+t+x+y, LegendreCone(), 1000)
46+
end

0 commit comments

Comments
 (0)