Skip to content

Commit 9dead75

Browse files
authored
Merge pull request #242 from jishnub/scalepermdim
Remove uses of PermutedDimsArray in pre and post-scaling
2 parents 17f3e59 + da5f214 commit 9dead75

File tree

3 files changed

+68
-82
lines changed

3 files changed

+68
-82
lines changed

src/chebyshevtransform.jl

Lines changed: 56 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -53,22 +53,34 @@ _maybemutablecopy(x::StridedArray{T}, ::Type{T}) where {T} = x
5353
_maybemutablecopy(x, T) = Array{T}(x)
5454
@inline _plan_mul!(y::AbstractArray{T}, P::Plan{T}, x::AbstractArray) where T = mul!(y, P, _maybemutablecopy(x, T))
5555

56+
function applydim!(op!, X::AbstractArray, Rpre, Rpost, ind)
57+
for Ipost in Rpost, Ipre in Rpre
58+
v = view(X, Ipre, ind, Ipost)
59+
op!(v)
60+
end
61+
X
62+
end
63+
function applydim!(op!, X::AbstractArray, d::Integer, ind)
64+
Rpre = CartesianIndices(axes(X)[1:d-1])
65+
Rpost = CartesianIndices(axes(X)[d+1:end])
66+
applydim!(op!, X, Rpre, Rpost, ind)
67+
end
5668

5769
for op in (:ldiv, :lmul)
58-
op_dim_begin! = Symbol(string(op) * "_dim_begin!")
59-
op_dim_end! = Symbol(string(op) * "_dim_end!")
60-
op! = Symbol(string(op) * "!")
70+
op_dim_begin! = Symbol(op, :_dim_begin!)
71+
op_dim_end! = Symbol(op, :_dim_end!)
72+
op! = Symbol(op, :!)
6173
@eval begin
62-
function $op_dim_begin!(α, d::Number, y::AbstractArray{<:Any,N}) where N
74+
function $op_dim_begin!(α, d::Number, y::AbstractArray)
6375
# scale just the d-th dimension by permuting it to the first
64-
= PermutedDimsArray(y, _permfirst(d, N))
65-
$op!(α, view(ỹ, 1, ntuple(_ -> :, Val(N-1))...))
76+
d 1:ndims(y) || throw(ArgumentError("dimension $d must lie between 1 and $(ndims(y))"))
77+
applydim!(v -> $op!(α, v), y, d, 1)
6678
end
6779

68-
function $op_dim_end!(α, d::Number, y::AbstractArray{<:Any,N}) where N
80+
function $op_dim_end!(α, d::Number, y::AbstractArray)
6981
# scale just the d-th dimension by permuting it to the first
70-
= PermutedDimsArray(y, _permfirst(d, N))
71-
$op!(α, view(ỹ, size(ỹ,1), ntuple(_ -> :, Val(N-1))...))
82+
d 1:ndims(y) || throw(ArgumentError("dimension $d must lie between 1 and $(ndims(y))"))
83+
applydim!(v -> $op!(α, v), y, d, size(y, d))
7284
end
7385
end
7486
end
@@ -363,35 +375,34 @@ function plan_chebyshevutransform(x::AbstractArray{T,N}, ::Val{2}, dims...; kws.
363375
ChebyshevUTransformPlan{T,2}(FFTW.plan_r2r(x, USECONDKIND, dims...; kws...))
364376
end
365377

366-
367-
_permfirst(d, N) = [d; 1:d-1; d+1:N]
368-
369-
@inline function _chebu1_prescale!(d::Number, X::AbstractArray{T,N}) where {T,N}
370-
= PermutedDimsArray(X, _permfirst(d, N))
371-
m = size(X̃,1)
372-
X̃ .= (sinpi.(one(T)/(2m) .+ ((1:m) .- one(T))/m) ./ m) .*
373-
X
374-
end
375-
376-
@inline function _chebu1_prescale!(d, y::AbstractArray)
377-
for k in d
378-
_chebu1_prescale!(k, y)
378+
for f in [:_chebu1_prescale!, :_chebu1_postscale!, :_chebu2_prescale!, :_chebu2_postscale!,
379+
:_ichebu1_postscale!]
380+
_f = Symbol(:_, f)
381+
@eval begin
382+
@inline function $f(d::Number, X::AbstractArray)
383+
d 1:ndims(X) || throw("dimension $d must lie between 1 and $(ndims(X))")
384+
$_f(d, X)
385+
X
386+
end
387+
@inline function $f(d, y::AbstractArray)
388+
for k in d
389+
$f(k, y)
390+
end
391+
y
392+
end
379393
end
380-
y
381394
end
382395

383-
@inline function _chebu1_postscale!(d::Number, X::AbstractArray{T,N}) where {T,N}
384-
= PermutedDimsArray(X, _permfirst(d, N))
385-
m = size(X̃,1)
386-
X̃ .=./ (sinpi.(one(T)/(2m) .+ ((1:m) .- one(T))/m) ./ m)
387-
X
396+
function __chebu1_prescale!(d::Number, X::AbstractArray{T}) where {T}
397+
m = size(X,d)
398+
r = one(T)/(2m) .+ ((1:m) .- one(T))./m
399+
applydim!(v -> v .*= sinpi.(r) ./ m, X, d, :)
388400
end
389401

390-
@inline function _chebu1_postscale!(d, y::AbstractArray)
391-
for k in d
392-
_chebu1_postscale!(k, y)
393-
end
394-
y
402+
@inline function __chebu1_postscale!(d::Number, X::AbstractArray{T}) where {T}
403+
m = size(X,d)
404+
r = one(T)/(2m) .+ ((1:m) .- one(T))./m
405+
applydim!(v -> v ./= sinpi.(r) ./ m, X, d, :)
395406
end
396407

397408
function *(P::ChebyshevUTransformPlan{T,1,K,true,N}, x::AbstractArray{T,N}) where {T,K,N}
@@ -413,35 +424,18 @@ function mul!(y::AbstractArray{T}, P::ChebyshevUTransformPlan{T,1,K,false}, x::A
413424
end
414425

415426

416-
@inline function _chebu2_prescale!(d::Number, X::AbstractArray{T,N}) where {T,N}
417-
= PermutedDimsArray(X, _permfirst(d, N))
418-
m = size(X̃,1)
427+
@inline function __chebu2_prescale!(d, X::AbstractArray{T}) where {T}
428+
m = size(X,d)
419429
c = one(T)/ (m+1)
420-
X̃ .= sinpi.((1:m) .* c) .*
421-
X
430+
r = (1:m) .* c
431+
applydim!(v -> v .*= sinpi.(r), X, d, :)
422432
end
423433

424-
@inline function _chebu2_prescale!(d, y::AbstractArray)
425-
for k in d
426-
_chebu2_prescale!(k, y)
427-
end
428-
y
429-
end
430-
431-
432-
@inline function _chebu2_postscale!(d::Number, X::AbstractArray{T,N}) where {T,N}
433-
= PermutedDimsArray(X, _permfirst(d, N))
434-
m = size(X̃,1)
434+
@inline function __chebu2_postscale!(d::Number, X::AbstractArray{T}) where {T}
435+
m = size(X,d)
435436
c = one(T)/ (m+1)
436-
X̃ .=./ sinpi.((1:m) .* c)
437-
X
438-
end
439-
440-
@inline function _chebu2_postscale!(d, y::AbstractArray)
441-
for k in d
442-
_chebu2_postscale!(k, y)
443-
end
444-
y
437+
r = (1:m) .* c
438+
applydim!(v -> v ./= sinpi.(r), X, d, :)
445439
end
446440

447441
function *(P::ChebyshevUTransformPlan{T,2,K,true,N}, x::AbstractArray{T,N}) where {T,K,N}
@@ -525,19 +519,10 @@ inv(P::IChebyshevUTransformPlan{T,2}) where {T} = ChebyshevUTransformPlan{T,2}(P
525519
inv(P::ChebyshevUTransformPlan{T,1}) where {T} = IChebyshevUTransformPlan{T,1}(inv(P.plan).p)
526520
inv(P::IChebyshevUTransformPlan{T,1}) where {T} = ChebyshevUTransformPlan{T,1}(inv(P.plan).p)
527521

528-
@inline function _ichebu1_postscale!(d::Number, X::AbstractArray{T,N}) where {T,N}
529-
= PermutedDimsArray(X, _permfirst(d, N))
530-
m = size(X̃,1)
531-
X̃ .=./ (2 .* sinpi.(one(T)/(2m) .+ ((1:m) .- one(T))/m))
532-
X
533-
end
534-
535-
536-
@inline function _ichebu1_postscale!(d, y::AbstractArray)
537-
for k in d
538-
_ichebu1_postscale!(k, y)
539-
end
540-
y
522+
@inline function __ichebu1_postscale!(d::Number, X::AbstractArray{T}) where {T}
523+
m = size(X,d)
524+
r = one(T)/(2m) .+ ((1:m) .- one(T))/m
525+
applydim!(v -> v ./= 2 .* sinpi.(r), X, d, :)
541526
end
542527

543528
function *(P::IChebyshevUTransformPlan{T,1,K,true}, x::AbstractArray{T}) where {T<:fftwNumber,K}

src/toeplitzhankel.jl

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -137,26 +137,28 @@ function *(P::ChebyshevToLegendrePlanTH, v::AbstractVector{S}) where S
137137
v
138138
end
139139

140-
function _cheb2leg_rescale1!(V::AbstractArray{S}) where S
141-
m = size(V,1)
142-
for j = CartesianIndices(tail(axes(V)))
140+
function _cheb2leg_rescale1!(V::AbstractArray{S}, Rpre, Rpost, d) where S
141+
m = size(V,d)
142+
for Ipost in Rpost, Ipre in Rpre
143143
ret = zero(S)
144144
@inbounds for k = 1:2:m
145-
ret += -V[k,j]/(k*(k-2))
145+
ret += -V[Ipre,k,Ipost]/(k*(k-2))
146146
end
147-
V[1,j] = ret
147+
V[Ipre,1,Ipost] = ret
148148
end
149149
V
150150
end
151151

152152
_dropfirstdim(d::Int) = ()
153153
_dropfirstdim(d::Int, m, szs...) = ((d == 1 ? 2 : 1):m, _dropfirstdim(d-1, szs...)...)
154154

155-
function *(P::ChebyshevToLegendrePlanTH, V::AbstractArray{<:Any,N}) where N
155+
function *(P::ChebyshevToLegendrePlanTH, V::AbstractArray)
156156
m,n = size(V)
157157
tmp = P.toeplitzhankel.tmp
158158
for (d,R,L,T) in zip(P.toeplitzhankel.dims,P.toeplitzhankel.R,P.toeplitzhankel.L,P.toeplitzhankel.T)
159-
_cheb2leg_rescale1!(PermutedDimsArray(V, _permfirst(d, N)))
159+
Rpre = CartesianIndices(axes(V)[1:d-1])
160+
Rpost = CartesianIndices(axes(V)[d+1:end])
161+
_cheb2leg_rescale1!(V, Rpre, Rpost, d)
160162
_th_applymul!(d, view(V, _dropfirstdim(d, size(V)...)...), T, L, R, tmp)
161163
end
162164
V
@@ -729,4 +731,4 @@ th_cheb2jac(v, α, β, dims...) = plan_th_cheb2jac!(eltype(v), size(v), α, β,
729731

730732
plan_th_jac2cheb!(::Type{T}, mn, α, β, dims...) where T = Jac2ChebPlanTH(plan_th_jac2jac!(T, mn, α, β, -one(α)/2, -one(α)/2, dims...))
731733
plan_th_jac2cheb!(arr::AbstractArray{T}, α, β, dims...) where T = plan_th_jac2cheb!(T, size(arr), α, β, dims...)
732-
th_jac2cheb(v, α, β, dims...) = plan_th_jac2cheb!(eltype(v), size(v), α, β, dims...)*copy(v)
734+
th_jac2cheb(v, α, β, dims...) = plan_th_jac2cheb!(eltype(v), size(v), α, β, dims...)*copy(v)

src/toeplitzplans.jl

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,11 @@ function *(A::ToeplitzPlan{T,N}, X::AbstractArray{T,N}) where {T,N}
6161

6262
# Fourier transform each dimension
6363
dft * Y
64-
64+
6565
# Multiply by a diagonal matrix along each dimension by permuting
6666
# to first dimension
6767
for (vc,d) in zip(vcs,dims)
68-
= PermutedDimsArray(Y, _permfirst(d, N))
69-
Ỹ .= vc .*
68+
applydim!(v -> v .= vc .* v, Y, d, :)
7069
end
7170

7271
# Transform back

0 commit comments

Comments
 (0)