Skip to content

Commit a4839af

Browse files
committed
Add chebyshev u transform
1 parent 312e017 commit a4839af

File tree

4 files changed

+69
-20
lines changed

4 files changed

+69
-20
lines changed

examples/chebyshev.jl

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
# explaining precisely the normalization and points
44
#############
55

6+
using FastTransforms
7+
68
# first kind points -> first kind polynomials
79
n = 20
810
p_1 = [sinpi((n-2k-1)/2n) for k=0:n-1]
@@ -12,6 +14,9 @@ f̌ = chebyshevtransform(f; kind=1)
1214
= x -> [cos(k*acos(x)) for k=0:n-1]' *
1315
(0.1) exp(0.1)
1416

17+
# first kind polynomials -> first kind points
18+
ichebyshevtransform(f̌; kind=1) exp.(p_1)
19+
1520
# second kind points -> first kind polynomials
1621
p_2 = [cospi(k/(n-1)) for k=0:n-1]
1722
f = exp.(p_2)
@@ -20,8 +25,28 @@ f̌ = chebyshevtransform(f; kind=2)
2025
= x -> [cos(k*acos(x)) for k=0:n-1]' *
2126
(0.1) exp(0.1)
2227

23-
# first kind polynomials -> first kind points
24-
ichebyshevtransform(f̌; kind=1) exp.(p_1)
25-
2628
# first kind polynomials -> second kind points
2729
ichebyshevtransform(f̌; kind=2) exp.(p_2)
30+
31+
32+
# first kind points -> second kind polynomials
33+
n = 20
34+
p_1 = [sinpi((n-2k-1)/2n) for k=0:n-1]
35+
f = exp.(p_1)
36+
= chebyshevutransform(f; kind=1)
37+
= x -> [sin((k+1)*acos(x))/sin(acos(x)) for k=0:n-1]' *
38+
(0.1) exp(0.1)
39+
40+
# second kind polynomials -> first kind points
41+
ichebyshevutransform(f̌; kind=1) exp.(p_1)
42+
43+
44+
# second kind points -> second kind polynomials
45+
p_2 = [cospi(k/(n-1)) for k=1:n-2]
46+
f = exp.(p_2)
47+
= chebyshevutransform(f; kind=2)
48+
= x -> [sin((k+1)*acos(x))/sin(acos(x)) for k=0:n-3]' *
49+
(0.1) exp(0.1)
50+
51+
# second kind polynomials -> second kind points
52+
ichebyshevutransform(f̌; kind=2) exp.(p_2)

src/FastTransforms.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import HierarchicalMatrices: mul!, At_mul_B!, Ac_mul_B!
3434
import HierarchicalMatrices: ThreadSafeVector, threadsafezeros
3535
import LowRankApprox: ColPerm
3636
import AbstractFFTs: Plan
37-
import Compat: range, transpose, adjoint
37+
import Compat: range, transpose, adjoint, axes
3838

3939
export cjt, icjt, jjt, plan_cjt, plan_icjt
4040
export leg2cheb, cheb2leg, leg2chebu, ultra2ultra, jac2jac

src/chebyshevtransform.jl

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ ChebyshevUTransformPlan{k,inp}(plan) where {k,inp} =
187187

188188
function plan_chebyshevutransform!(x::AbstractVector{T}; kind::Integer=1) where T<:fftwNumber
189189
if kind == 1
190-
plan = plan_r2r!(x, REDFT10)
190+
plan = plan_r2r!(x, RODFT10)
191191
ChebyshevUTransformPlan{1,true}(plan)
192192
elseif kind == 2
193193
if length(x) 1
@@ -205,13 +205,10 @@ end
205205

206206
function *(P::ChebyshevUTransformPlan{T,1,true},x::AbstractVector{T}) where T
207207
n = length(x)
208-
if n == 1
209-
x
210-
else
211-
x = P.plan*x
212-
x[1]/=2
213-
lmul!(inv(convert(T,n)), x)
208+
for k=1:n # sqrt(1-x_j^2) weight
209+
x[k] *= sinpi(one(T)/(2n) + (k-one(T))/n)/n
214210
end
211+
P.plan * x
215212
end
216213

217214
function *(P::ChebyshevUTransformPlan{T,2,true},x::AbstractVector{T}) where T
@@ -242,28 +239,42 @@ function plan_ichebyshevutransform!(x::AbstractVector{T};kind::Integer=1) where
242239
if length(x) == 0
243240
error("Cannot create a length 0 inverse chebyshevu transform")
244241
end
245-
plan = plan_r2r!(x, REDFT01)
242+
plan = plan_r2r!(x, RODFT01)
246243
IChebyshevUTransformPlan{T,1,true,typeof(plan)}(plan)
247244
elseif kind == 2
248245
if length(x) 1
249246
error("Cannot create a length $(length(x)) inverse chebyshevu transform")
250247
end
251-
plan = plan_chebyshevutransform!(x;kind=2)
248+
plan = plan_r2r!(x, RODFT00)
252249
IChebyshevUTransformPlan{T,2,true,typeof(plan)}(plan)
253250
end
254251
end
255252

256-
function plan_ichebyshevutransform(x::AbstractVector{T};kind::Integer=1) where T<:fftwNumber
257-
plan = plan_ichebyshevutransform!(similar(Vector{T},axes(x));kind=kind)
253+
function plan_ichebyshevutransform(x::AbstractVector{T}; kind::Integer=1) where T<:fftwNumber
254+
plan = plan_ichebyshevutransform!(similar(Vector{T},axes(x)); kind=kind)
258255
IChebyshevUTransformPlan{T,kind,false,typeof(plan)}(plan)
259256
end
260257

261-
function *(P::IChebyshevUTransformPlan{T,1,true},x::AbstractVector{T}) where T<:fftwNumber
262-
error("Not implemented")
258+
function *(P::IChebyshevUTransformPlan{T,1,true}, x::AbstractVector{T}) where T<:fftwNumber
259+
n = length(x)
260+
x = P.plan * x
261+
for k=1:n # sqrt(1-x_j^2) weight
262+
x[k] /= 2sinpi(one(T)/(2n) + (k-one(T))/n)
263+
end
264+
x
263265
end
264266

265-
function *(P::IChebyshevUTransformPlan{T,2,true},x::AbstractVector{T}) where T<:fftwNumber
266-
error("Not implemented")
267+
268+
269+
function *(P::IChebyshevUTransformPlan{T,2,true}, x::AbstractVector{T}) where T<:fftwNumber
270+
n = length(x)
271+
c = one(T)/ (n+1)
272+
lmul!((n+1)/(2n+2*one(T)), x)
273+
x = P.plan * x
274+
for k=1:n # sqrt(1-x_j^2) weight
275+
x[k] /= sinpi(k*c)
276+
end
277+
x
267278
end
268279

269280
ichebyshevutransform!(x::AbstractVector{T};kind::Integer=1) where {T<:fftwNumber} =

test/chebyshevtests.jl

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,19 @@ using FastTransforms, Compat, Compat.Test
2626
end
2727
end
2828

29+
@testset "Chebyshev first kind points <-> second kind coefficients" begin
30+
for T in (Float32, Float64, ComplexF32, ComplexF64)
31+
n = 20
32+
p_1 = chebyshevpoints(T, n, kind=1)
33+
f = exp.(p_1)
34+
= chebyshevutransform(f; kind=1)
35+
36+
= x -> [sin((k+1)*acos(x))/sin(acos(x)) for k=0:n-1]' *
37+
@test (0.1) exp(T(0.1))
38+
@test ichebyshevutransform(f̌; kind=1) exp.(p_1)
39+
end
40+
end
41+
2942
@testset "Chebyshev second kind points <-> second kind coefficients" begin
3043
for T in (Float32, Float64, ComplexF32, ComplexF64)
3144
n = 20
@@ -35,7 +48,7 @@ using FastTransforms, Compat, Compat.Test
3548

3649
= x -> [sin((k+1)*acos(x))/sin(acos(x)) for k=0:n-3]' *
3750
@test (0.1) exp(T(0.1))
38-
# @test ichebyshevtransform(f̌; kind=2) ≈ exp.(p_2)
51+
@test ichebyshevutransform(f̌; kind=2) exp.(p_2)
3952
end
4053
end
4154
end

0 commit comments

Comments
 (0)