Skip to content

Commit 9bfab48

Browse files
Make ChebyshevTransformPlan compatible with FFTW v1.6 (#193)
* r2rFFTWPlan compatible with FFTW v1.6 * Add tests * Use explicit type in kindtuple --------- Co-authored-by: Mikael Slevinsky <[email protected]>
1 parent 0ea4539 commit 9bfab48

File tree

3 files changed

+188
-108
lines changed

3 files changed

+188
-108
lines changed

Project.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "FastTransforms"
22
uuid = "057dd010-8810-581a-b7be-e3fc3b93f78c"
3-
version = "0.14.10"
3+
version = "0.14.11"
44

55
[deps]
66
AbstractFFTs = "621f4979-c628-5d54-868e-fcf4e3e8185c"
@@ -18,7 +18,7 @@ ToeplitzMatrices = "c751599d-da0a-543b-9d20-d0a503d91d24"
1818

1919
[compat]
2020
AbstractFFTs = "1.0"
21-
FFTW = "1 - 1.5"
21+
FFTW = "1.6"
2222
FastGaussQuadrature = "0.4, 0.5"
2323
FastTransforms_jll = "0.6.2"
2424
FillArrays = "0.9, 0.10, 0.11, 0.12, 0.13"

src/chebyshevtransform.jl

Lines changed: 43 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -15,35 +15,35 @@ struct ChebyshevTransformPlan{T,kind,K,inplace,N,R} <: ChebyshevPlan{T}
1515
ChebyshevTransformPlan{T,kind,K,inplace,N,R}() where {T,kind,K,inplace,N,R} = new{T,kind,K,inplace,N,R}()
1616
end
1717

18-
ChebyshevTransformPlan{T,kind,K}(plan::FFTW.r2rFFTWPlan{T,K,inplace,N,R}) where {T,kind,K,inplace,N,R} =
18+
ChebyshevTransformPlan{T,kind}(plan::FFTW.r2rFFTWPlan{T,K,inplace,N,R}) where {T,kind,K,inplace,N,R} =
1919
ChebyshevTransformPlan{T,kind,K,inplace,N,R}(plan)
2020

2121
# jump through some hoops to make inferrable
22-
@inline kindtuple(KIND,N) = ntuple(_ -> KIND,N)
23-
@inline kindtuple(KIND,N,::Integer) = (KIND,)
22+
@inline kindtuple(N) = NTuple{N,Int32}
23+
@inline kindtuple(N,region...) = Vector{Int32}
2424
function plan_chebyshevtransform!(x::AbstractArray{T,N}, ::Val{1}, dims...; kws...) where {T<:fftwNumber,N}
2525
if isempty(x)
26-
ChebyshevTransformPlan{T,1,kindtuple(FIRSTKIND,N,dims...),true,N,isempty(dims) ? UnitRange{Int} : typeof(dims)}()
26+
ChebyshevTransformPlan{T,1,kindtuple(N,dims...),true,N,isempty(dims) ? NTuple{N,Int} : typeof(dims[1])}()
2727
else
28-
ChebyshevTransformPlan{T,1,kindtuple(FIRSTKIND,N,dims...)}(FFTW.plan_r2r!(x, FIRSTKIND, dims...; kws...))
28+
ChebyshevTransformPlan{T,1}(FFTW.plan_r2r!(x, FIRSTKIND, dims...; kws...))
2929
end
3030
end
3131
function plan_chebyshevtransform!(x::AbstractArray{T,N}, ::Val{2}, dims...; kws...) where {T<:fftwNumber,N}
3232
any((1),size(x)) && throw(ArgumentError("Array must contain at least 2 entries"))
33-
ChebyshevTransformPlan{T,2,kindtuple(SECONDKIND,N,dims...)}(FFTW.plan_r2r!(x, SECONDKIND, dims...; kws...))
33+
ChebyshevTransformPlan{T,2}(FFTW.plan_r2r!(x, SECONDKIND, dims...; kws...))
3434
end
3535

3636

3737
function plan_chebyshevtransform(x::AbstractArray{T,N}, ::Val{1}, dims...; kws...) where {T<:fftwNumber,N}
3838
if isempty(x)
39-
ChebyshevTransformPlan{T,1,kindtuple(FIRSTKIND,N,dims...),false,N,isempty(dims) ? UnitRange{Int} : typeof(dims)}()
39+
ChebyshevTransformPlan{T,1,kindtuple(N,dims...),false,N,isempty(dims) ? NTuple{N,Int} : typeof(dims[1])}()
4040
else
41-
ChebyshevTransformPlan{T,1,kindtuple(FIRSTKIND,N,dims...)}(FFTW.plan_r2r(x, FIRSTKIND, dims...; kws...))
41+
ChebyshevTransformPlan{T,1}(FFTW.plan_r2r(x, FIRSTKIND, dims...; kws...))
4242
end
4343
end
4444
function plan_chebyshevtransform(x::AbstractArray{T,N}, ::Val{2}, dims...; kws...) where {T<:fftwNumber,N}
4545
any((1),size(x)) && throw(ArgumentError("Array must contain at least 2 entries"))
46-
ChebyshevTransformPlan{T,2,kindtuple(SECONDKIND,N,dims...)}(FFTW.plan_r2r(x, SECONDKIND, dims...; kws...))
46+
ChebyshevTransformPlan{T,2}(FFTW.plan_r2r(x, SECONDKIND, dims...; kws...))
4747
end
4848

4949
plan_chebyshevtransform!(x::AbstractArray, dims...; kws...) = plan_chebyshevtransform!(x, Val(1), dims...; kws...)
@@ -143,7 +143,7 @@ function _prod_size(sz, d)
143143
end
144144

145145

146-
@inline function _cheb1_rescale!(d::UnitRange, y::AbstractArray)
146+
@inline function _cheb1_rescale!(d, y::AbstractArray)
147147
for k in d
148148
ldiv_dim_begin!(2, k, y)
149149
end
@@ -175,7 +175,7 @@ function _cheb2_rescale!(d::Number, y::AbstractArray)
175175
end
176176

177177
# TODO: higher dimensional arrays
178-
function _cheb2_rescale!(d::UnitRange, y::AbstractArray)
178+
function _cheb2_rescale!(d, y::AbstractArray)
179179
for k in d
180180
ldiv_dim_begin!(2, k, y)
181181
ldiv_dim_end!(2, k, y)
@@ -229,18 +229,18 @@ struct IChebyshevTransformPlan{T,kind,K,inplace,N,R} <: ChebyshevPlan{T}
229229
IChebyshevTransformPlan{T,kind,K,inplace,N,R}() where {T,kind,K,inplace,N,R} = new{T,kind,K,inplace,N,R}()
230230
end
231231

232-
IChebyshevTransformPlan{T,kind,K}(F::FFTW.r2rFFTWPlan{T,K,inplace,N,R}) where {T,kind,K,inplace,N,R} =
232+
IChebyshevTransformPlan{T,kind}(F::FFTW.r2rFFTWPlan{T,K,inplace,N,R}) where {T,kind,K,inplace,N,R} =
233233
IChebyshevTransformPlan{T,kind,K,inplace,N,R}(F)
234234

235235

236236

237237
# second kind Chebyshev transforms share a plan with their inverse
238238
# so we support this via inv
239-
inv(P::ChebyshevTransformPlan{T,2,K}) where {T,K} = IChebyshevTransformPlan{T,2,K}(P.plan)
240-
inv(P::IChebyshevTransformPlan{T,2,K}) where {T,K} = ChebyshevTransformPlan{T,2,K}(P.plan)
239+
inv(P::ChebyshevTransformPlan{T,2}) where {T} = IChebyshevTransformPlan{T,2}(P.plan)
240+
inv(P::IChebyshevTransformPlan{T,2}) where {T} = ChebyshevTransformPlan{T,2}(P.plan)
241241

242-
inv(P::ChebyshevTransformPlan{T,1,K,inplace,N}) where {T,K,inplace,N} = IChebyshevTransformPlan{T,1,kindtuple(IFIRSTKIND,N,P.plan.region...)}(inv(P.plan).p)
243-
inv(P::IChebyshevTransformPlan{T,1,K,inplace,N}) where {T,K,inplace,N} = ChebyshevTransformPlan{T,1,kindtuple(FIRSTKIND,N,P.plan.region...)}(inv(P.plan).p)
242+
inv(P::ChebyshevTransformPlan{T,1}) where {T} = IChebyshevTransformPlan{T,1}(inv(P.plan).p)
243+
inv(P::IChebyshevTransformPlan{T,1}) where {T} = ChebyshevTransformPlan{T,1}(inv(P.plan).p)
244244

245245

246246

@@ -250,9 +250,9 @@ inv(P::IChebyshevTransformPlan{T,1,K,inplace,N}) where {T,K,inplace,N} = Chebysh
250250

251251
function plan_ichebyshevtransform!(x::AbstractArray{T,N}, ::Val{1}, dims...; kws...) where {T<:fftwNumber,N}
252252
if isempty(x)
253-
IChebyshevTransformPlan{T,1,kindtuple(IFIRSTKIND,N,dims...),true,N,isempty(dims) ? UnitRange{Int} : typeof(dims)}()
253+
IChebyshevTransformPlan{T,1,kindtuple(N,dims...),true,N,isempty(dims) ? NTuple{N,Int} : typeof(dims[1])}()
254254
else
255-
IChebyshevTransformPlan{T,1,kindtuple(IFIRSTKIND,N,dims...)}(FFTW.plan_r2r!(x, IFIRSTKIND, dims...; kws...))
255+
IChebyshevTransformPlan{T,1}(FFTW.plan_r2r!(x, IFIRSTKIND, dims...; kws...))
256256
end
257257
end
258258

@@ -262,9 +262,9 @@ end
262262

263263
function plan_ichebyshevtransform(x::AbstractArray{T,N}, ::Val{1}, dims...; kws...) where {T<:fftwNumber,N}
264264
if isempty(x)
265-
IChebyshevTransformPlan{T,1,kindtuple(IFIRSTKIND,N,dims...),false,N,isempty(dims) ? UnitRange{Int} : typeof(dims)}()
265+
IChebyshevTransformPlan{T,1,kindtuple(N,dims...),false,N,isempty(dims) ? NTuple{N,Int} : typeof(dims[1])}()
266266
else
267-
IChebyshevTransformPlan{T,1,kindtuple(IFIRSTKIND,N,dims...)}(FFTW.plan_r2r(x, IFIRSTKIND, dims...; kws...))
267+
IChebyshevTransformPlan{T,1}(FFTW.plan_r2r(x, IFIRSTKIND, dims...; kws...))
268268
end
269269
end
270270

@@ -279,7 +279,7 @@ plan_ichebyshevtransform(x::AbstractArray, dims...; kws...) = plan_ichebyshevtra
279279
lmul_dim_begin!(2, d, x)
280280
x
281281
end
282-
@inline function _icheb1_prescale!(d::UnitRange, x::AbstractArray)
282+
@inline function _icheb1_prescale!(d, x::AbstractArray)
283283
for k in d
284284
_icheb1_prescale!(k, x)
285285
end
@@ -290,7 +290,7 @@ end
290290
x
291291
end
292292

293-
@inline function _icheb1_postscale!(d::UnitRange, x::AbstractArray)
293+
@inline function _icheb1_postscale!(d, x::AbstractArray)
294294
for k in d
295295
_icheb1_postscale!(k, x)
296296
end
@@ -321,7 +321,7 @@ end
321321
lmul_dim_end!(2, d, x)
322322
x
323323
end
324-
@inline function _icheb2_prescale!(d::UnitRange, x::AbstractArray)
324+
@inline function _icheb2_prescale!(d, x::AbstractArray)
325325
for k in d
326326
_icheb2_prescale!(k, x)
327327
end
@@ -333,7 +333,7 @@ end
333333
ldiv_dim_end!(2, d, x)
334334
x
335335
end
336-
@inline function _icheb2_postrescale!(d::UnitRange, x::AbstractArray)
336+
@inline function _icheb2_postrescale!(d, x::AbstractArray)
337337
for k in d
338338
_icheb2_postrescale!(k, x)
339339
end
@@ -344,7 +344,7 @@ end
344344
lmul!(convert(T, size(y,d) - 1)/2, y)
345345
y
346346
end
347-
@inline function _icheb2_rescale!(d::UnitRange, y::AbstractArray{T}) where T
347+
@inline function _icheb2_rescale!(d, y::AbstractArray{T}) where T
348348
_icheb2_prescale!(d, y)
349349
lmul!(_prod_size(convert.(T, size(y) .- 1)./2, d), y)
350350
y
@@ -384,32 +384,32 @@ struct ChebyshevUTransformPlan{T,kind,K,inplace,N,R} <: ChebyshevPlan{T}
384384
ChebyshevUTransformPlan{T,kind,K,inplace,N,R}() where {T,kind,K,inplace,N,R} = new{T,kind,K,inplace,N,R}()
385385
end
386386

387-
ChebyshevUTransformPlan{T,kind,K}(plan::FFTW.r2rFFTWPlan{T,K,inplace,N,R}) where {T,kind,K,inplace,N,R} =
387+
ChebyshevUTransformPlan{T,kind}(plan::FFTW.r2rFFTWPlan{T,K,inplace,N,R}) where {T,kind,K,inplace,N,R} =
388388
ChebyshevUTransformPlan{T,kind,K,inplace,N,R}(plan)
389389

390390

391391
function plan_chebyshevutransform!(x::AbstractArray{T,N}, ::Val{1}, dims...; kws...) where {T<:fftwNumber,N}
392392
if isempty(x)
393-
ChebyshevUTransformPlan{T,1,kindtuple(UFIRSTKIND,N,dims...),true,N,isempty(dims) ? UnitRange{Int} : typeof(dims)}()
393+
ChebyshevUTransformPlan{T,1,kindtuple(N,dims...),true,N,isempty(dims) ? NTuple{N,Int} : typeof(dims[1])}()
394394
else
395-
ChebyshevUTransformPlan{T,1,kindtuple(UFIRSTKIND,N,dims...)}(FFTW.plan_r2r!(x, UFIRSTKIND, dims...; kws...))
395+
ChebyshevUTransformPlan{T,1}(FFTW.plan_r2r!(x, UFIRSTKIND, dims...; kws...))
396396
end
397397
end
398398
function plan_chebyshevutransform!(x::AbstractArray{T,N}, ::Val{2}, dims...; kws...) where {T<:fftwNumber,N}
399399
any((1),size(x)) && throw(ArgumentError("Array must contain at least 2 entries"))
400-
ChebyshevUTransformPlan{T,2,kindtuple(USECONDKIND,N,dims...)}(FFTW.plan_r2r!(x, USECONDKIND, dims...; kws...))
400+
ChebyshevUTransformPlan{T,2}(FFTW.plan_r2r!(x, USECONDKIND, dims...; kws...))
401401
end
402402

403403
function plan_chebyshevutransform(x::AbstractArray{T,N}, ::Val{1}, dims...; kws...) where {T<:fftwNumber,N}
404404
if isempty(x)
405-
ChebyshevUTransformPlan{T,1,kindtuple(UFIRSTKIND,N,dims...),false,N,isempty(dims) ? UnitRange{Int} : typeof(dims)}()
405+
ChebyshevUTransformPlan{T,1,kindtuple(N,dims...),false,N,isempty(dims) ? NTuple{N,Int} : typeof(dims[1])}()
406406
else
407-
ChebyshevUTransformPlan{T,1,kindtuple(UFIRSTKIND,N,dims...)}(FFTW.plan_r2r(x, UFIRSTKIND, dims...; kws...))
407+
ChebyshevUTransformPlan{T,1}(FFTW.plan_r2r(x, UFIRSTKIND, dims...; kws...))
408408
end
409409
end
410410
function plan_chebyshevutransform(x::AbstractArray{T,N}, ::Val{2}, dims...; kws...) where {T<:fftwNumber,N}
411411
any((1),size(x)) && throw(ArgumentError("Array must contain at least 2 entries"))
412-
ChebyshevUTransformPlan{T,2,kindtuple(USECONDKIND,N,dims...)}(FFTW.plan_r2r(x, USECONDKIND, dims...; kws...))
412+
ChebyshevUTransformPlan{T,2}(FFTW.plan_r2r(x, USECONDKIND, dims...; kws...))
413413
end
414414

415415
plan_chebyshevutransform!(x::AbstractArray, dims...; kws...) = plan_chebyshevutransform!(x, Val(1), dims...; kws...)
@@ -506,31 +506,31 @@ struct IChebyshevUTransformPlan{T,kind,K,inplace,N,R} <: ChebyshevPlan{T}
506506
IChebyshevUTransformPlan{T,kind,K,inplace,N,R}() where {T,kind,K,inplace,N,R} = new{T,kind,K,inplace,N,R}()
507507
end
508508

509-
IChebyshevUTransformPlan{T,kind,K}(F::FFTW.r2rFFTWPlan{T,K,inplace,N,R}) where {T,kind,K,inplace,N,R} =
509+
IChebyshevUTransformPlan{T,kind}(F::FFTW.r2rFFTWPlan{T,K,inplace,N,R}) where {T,kind,K,inplace,N,R} =
510510
IChebyshevUTransformPlan{T,kind,K,inplace,N,R}(F)
511511

512512
function plan_ichebyshevutransform!(x::AbstractArray{T,N}, ::Val{1}, dims...; kws...) where {T<:fftwNumber,N}
513513
if isempty(x)
514-
IChebyshevUTransformPlan{T,1,kindtuple(IUFIRSTKIND,N,dims...),true,N,isempty(dims) ? UnitRange{Int} : typeof(dims)}()
514+
IChebyshevUTransformPlan{T,1,kindtuple(N,dims...),true,N,isempty(dims) ? NTuple{N,Int} : typeof(dims[1])}()
515515
else
516-
IChebyshevUTransformPlan{T,1,kindtuple(IUFIRSTKIND,N,dims...)}(FFTW.plan_r2r!(x, IUFIRSTKIND, dims...; kws...))
516+
IChebyshevUTransformPlan{T,1}(FFTW.plan_r2r!(x, IUFIRSTKIND, dims...; kws...))
517517
end
518518
end
519519
function plan_ichebyshevutransform!(x::AbstractArray{T,N}, ::Val{2}, dims...; kws...) where {T<:fftwNumber,N}
520520
any((1),size(x)) && throw(ArgumentError("Array must contain at least 2 entries"))
521-
IChebyshevUTransformPlan{T,2,kindtuple(USECONDKIND,N,dims...)}(FFTW.plan_r2r!(x, USECONDKIND))
521+
IChebyshevUTransformPlan{T,2}(FFTW.plan_r2r!(x, USECONDKIND))
522522
end
523523

524524
function plan_ichebyshevutransform(x::AbstractArray{T,N}, ::Val{1}, dims...; kws...) where {T<:fftwNumber,N}
525525
if isempty(x)
526-
IChebyshevUTransformPlan{T,1,kindtuple(IUFIRSTKIND,N,dims...),false,N,isempty(dims) ? UnitRange{Int} : typeof(dims)}()
526+
IChebyshevUTransformPlan{T,1,kindtuple(N,dims...),false,N,isempty(dims) ? NTuple{N,Int} : typeof(dims[1])}()
527527
else
528-
IChebyshevUTransformPlan{T,1,kindtuple(IUFIRSTKIND,N,dims...)}(FFTW.plan_r2r(x, IUFIRSTKIND, dims...; kws...))
528+
IChebyshevUTransformPlan{T,1}(FFTW.plan_r2r(x, IUFIRSTKIND, dims...; kws...))
529529
end
530530
end
531531
function plan_ichebyshevutransform(x::AbstractArray{T,N}, ::Val{2}, dims...; kws...) where {T<:fftwNumber,N}
532532
any((1),size(x)) && throw(ArgumentError("Array must contain at least 2 entries"))
533-
IChebyshevUTransformPlan{T,2,kindtuple(USECONDKIND,N,dims...)}(FFTW.plan_r2r(x, USECONDKIND, dims...; kws...))
533+
IChebyshevUTransformPlan{T,2}(FFTW.plan_r2r(x, USECONDKIND, dims...; kws...))
534534
end
535535

536536

@@ -539,11 +539,11 @@ plan_ichebyshevutransform(x::AbstractArray, dims...; kws...) = plan_ichebyshevut
539539

540540
# second kind Chebyshev transforms share a plan with their inverse
541541
# so we support this via inv
542-
inv(P::ChebyshevUTransformPlan{T,2,K}) where {T,K} = IChebyshevUTransformPlan{T,2,K}(P.plan)
543-
inv(P::IChebyshevUTransformPlan{T,2,K}) where {T,K} = ChebyshevUTransformPlan{T,2,K}(P.plan)
542+
inv(P::ChebyshevUTransformPlan{T,2}) where {T} = IChebyshevUTransformPlan{T,2}(P.plan)
543+
inv(P::IChebyshevUTransformPlan{T,2}) where {T} = ChebyshevUTransformPlan{T,2}(P.plan)
544544

545-
inv(P::ChebyshevUTransformPlan{T,1,K,inplace,N}) where {T,K,inplace,N} = IChebyshevUTransformPlan{T,1,kindtuple(IUFIRSTKIND,N,P.plan.region...)}(inv(P.plan).p)
546-
inv(P::IChebyshevUTransformPlan{T,1,K,inplace,N}) where {T,K,inplace,N} = ChebyshevUTransformPlan{T,1,kindtuple(UFIRSTKIND,N,P.plan.region...)}(inv(P.plan).p)
545+
inv(P::ChebyshevUTransformPlan{T,1}) where {T} = IChebyshevUTransformPlan{T,1}(inv(P.plan).p)
546+
inv(P::IChebyshevUTransformPlan{T,1}) where {T} = ChebyshevUTransformPlan{T,1}(inv(P.plan).p)
547547

548548

549549
function _ichebyu1_postscale!(_, x::AbstractVector{T}) where T

0 commit comments

Comments
 (0)