@@ -6,14 +6,6 @@ size(P::ChebyshevPlan) = isdefined(P, :plan) ? size(P.plan) : (0,)
6
6
length (P:: ChebyshevPlan ) = isdefined (P, :plan ) ? length (P. plan) : 0
7
7
8
8
9
- # Check whether a ChebyshevPlan is applicable to a given input array, and
10
- # throw an informative error if not:
11
- function assert_applicable (p:: ChebyshevPlan{T} , X:: StridedArray{T} ) where T
12
- if size (X) != size (p)
13
- throw (ArgumentError (" Chebyshev plan applied to wrong-size array" ))
14
- end
15
- end
16
-
17
9
const FIRSTKIND = 5
18
10
const SECONDKIND = 3
19
11
@@ -36,7 +28,7 @@ function plan_chebyshevtransform!(x::AbstractArray{T,N}, ::Val{1}, dims...; kws.
36
28
ChebyshevTransformPlan {T,1,kindtuple(FIRSTKIND,N,dims...)} (FFTW. plan_r2r! (x, FFTW. REDFT10, dims... ; kws... ))
37
29
end
38
30
end
39
- function plan_chebyshevtransform! (x:: AbstractArray{T} , :: Val{2} , dims... ; kws... ) where T<: fftwNumber
31
+ function plan_chebyshevtransform! (x:: AbstractArray{T,N } , :: Val{2} , dims... ; kws... ) where { T<: fftwNumber ,N}
40
32
length (x) ≤ 1 && throw (ArgumentError (" Array must contain at least 2 entries" ))
41
33
ChebyshevTransformPlan {T,2,kindtuple(SECONDKIND,N,dims...)} (FFTW. plan_r2r! (x, FFTW. REDFT00, dims... ; kws... ))
42
34
end
@@ -49,7 +41,7 @@ function plan_chebyshevtransform(x::AbstractArray{T,N}, ::Val{1}, dims...; kws..
49
41
ChebyshevTransformPlan {T,1,kindtuple(FIRSTKIND,N,dims...)} (FFTW. plan_r2r (x, FFTW. REDFT10, dims... ; kws... ))
50
42
end
51
43
end
52
- function plan_chebyshevtransform (x:: AbstractArray{T} , :: Val{2} , dims... ; kws... ) where T<: fftwNumber
44
+ function plan_chebyshevtransform (x:: AbstractArray{T,N } , :: Val{2} , dims... ; kws... ) where { T<: fftwNumber ,N}
53
45
length (x) ≤ 1 && throw (ArgumentError (" Vector must contain at least 2 entries" ))
54
46
ChebyshevTransformPlan {T,2,kindtuple(SECONDKIND,N,dims...)} (FFTW. plan_r2r (x, FFTW. REDFT00, dims... ; kws... ))
55
47
end
83
75
84
76
function * (P:: ChebyshevTransformPlan{T,1,K,true} , x:: AbstractArray{T} ) where {T,K}
85
77
n = length (x)
86
- assert_applicable (P, x)
87
78
n == 0 && return x
88
79
89
80
y = P. plan* x # will be === x if in-place
93
84
function mul! (y:: AbstractArray{T} , P:: ChebyshevTransformPlan{T,1,K,false} , x:: AbstractArray ) where {T,K}
94
85
n = length (x)
95
86
length (y) == n || throw (DimensionMismatch (" output must match dimension" ))
96
- assert_applicable (P, x)
97
87
n == 0 && return y
98
88
_plan_mul! (y, P. plan, x)
99
89
_cheb1_rescale! (P. plan. region, y)
@@ -138,25 +128,25 @@ chebyshevtransform(x, dims...; kws...) = plan_chebyshevtransform(x, dims...; kws
138
128
# # Inverse transforms take Chebyshev coefficients and produce values at Chebyshev points of the first and second kinds
139
129
140
130
141
- const IFIRSTKIND = ( 4 ,)
131
+ const IFIRSTKIND = 4
142
132
143
- struct IChebyshevTransformPlan{T,kind,inplace,N,R} <: ChebyshevPlan{T}
144
- plan:: FFTW.r2rFFTWPlan{T,kind ,inplace,N,R}
145
- IChebyshevTransformPlan {T,kind,inplace,N,R} (plan) where {T,kind,inplace,N,R} = new {T,kind,inplace,N,R} (plan)
146
- IChebyshevTransformPlan {T,kind,inplace,N,R} () where {T,kind,inplace,N,R} = new {T,kind,inplace,N,R} ()
133
+ struct IChebyshevTransformPlan{T,kind,K, inplace,N,R} <: ChebyshevPlan{T}
134
+ plan:: FFTW.r2rFFTWPlan{T,K ,inplace,N,R}
135
+ IChebyshevTransformPlan {T,kind,K, inplace,N,R} (plan) where {T,kind,K, inplace,N,R} = new {T,kind,K ,inplace,N,R} (plan)
136
+ IChebyshevTransformPlan {T,kind,K, inplace,N,R} () where {T,kind,K, inplace,N,R} = new {T,kind,K ,inplace,N,R} ()
147
137
end
148
138
149
- IChebyshevTransformPlan {T,kind} (F:: FFTW.r2rFFTWPlan{T,kind ,inplace,N,R} ) where {T,kind,inplace,N,R} =
150
- IChebyshevTransformPlan {T,kind,inplace,N,R} (F)
139
+ IChebyshevTransformPlan {T,kind,K } (F:: FFTW.r2rFFTWPlan{T,K ,inplace,N,R} ) where {T,kind,K ,inplace,N,R} =
140
+ IChebyshevTransformPlan {T,kind,K, inplace,N,R} (F)
151
141
152
142
size (P:: IChebyshevTransformPlan ) = isdefined (P, :plan ) ? size (P. plan) : (0 ,)
153
143
length (P:: IChebyshevTransformPlan ) = isdefined (P, :plan ) ? length (P. plan) : 0
154
144
155
145
156
146
# second kind Chebyshev transforms share a plan with their inverse
157
147
# so we support this via inv
158
- inv (P:: ChebyshevTransformPlan{T,SECONDKIND } ) where {T} = IChebyshevTransformPlan {T,SECONDKIND } (P. plan)
159
- inv (P:: IChebyshevTransformPlan{T,SECONDKIND } ) where {T} = ChebyshevTransformPlan {T,SECONDKIND } (P. plan)
148
+ inv (P:: ChebyshevTransformPlan{T,2,K } ) where {T,K } = IChebyshevTransformPlan {T,2,K } (P. plan)
149
+ inv (P:: IChebyshevTransformPlan{T,2,K } ) where {T,K } = ChebyshevTransformPlan {T,2,K } (P. plan)
160
150
161
151
162
152
\ (P:: ChebyshevTransformPlan , x:: AbstractArray ) = inv (P) * x
@@ -165,9 +155,9 @@ inv(P::IChebyshevTransformPlan{T,SECONDKIND}) where {T} = ChebyshevTransformPlan
165
155
166
156
function plan_ichebyshevtransform! (x:: AbstractArray{T,N} , :: Val{1} , dims... ; kws... ) where {T<: fftwNumber ,N}
167
157
if isempty (x)
168
- IChebyshevTransformPlan {T,IFIRSTKIND,true,N,isempty(dims) ? UnitRange{Int} : typeof(dims)} ()
158
+ IChebyshevTransformPlan {T,1,kindtuple( IFIRSTKIND,N,dims...) ,true,N,isempty(dims) ? UnitRange{Int} : typeof(dims)} ()
169
159
else
170
- IChebyshevTransformPlan {T,IFIRSTKIND} (FFTW. plan_r2r! (x, FFTW. REDFT01, dims... ; kws... ))
160
+ IChebyshevTransformPlan {T,1,kindtuple( IFIRSTKIND,N,dims...) } (FFTW. plan_r2r! (x, FFTW. REDFT01, dims... ; kws... ))
171
161
end
172
162
end
173
163
177
167
178
168
function plan_ichebyshevtransform (x:: AbstractArray{T,N} , :: Val{1} , dims... ; kws... ) where {T<: fftwNumber ,N}
179
169
if isempty (x)
180
- IChebyshevTransformPlan {T,IFIRSTKIND,false,N,isempty(dims) ? UnitRange{Int} : typeof(dims)} ()
170
+ IChebyshevTransformPlan {T,1,kindtuple( IFIRSTKIND,N,dims...) ,false,N,isempty(dims) ? UnitRange{Int} : typeof(dims)} ()
181
171
else
182
- IChebyshevTransformPlan {T,IFIRSTKIND} (FFTW. plan_r2r (x, FFTW. REDFT01, dims... ; kws... ))
172
+ IChebyshevTransformPlan {T,1,kindtuple( IFIRSTKIND,N,dims...) } (FFTW. plan_r2r (x, FFTW. REDFT01, dims... ; kws... ))
183
173
end
184
174
end
185
175
@@ -191,20 +181,18 @@ plan_ichebyshevtransform!(x::AbstractArray, dims...; kws...) = plan_ichebyshevtr
191
181
plan_ichebyshevtransform (x:: AbstractArray , dims... ; kws... ) = plan_ichebyshevtransform (x, Val (1 ), dims... ; kws... )
192
182
193
183
194
- function * (P:: IChebyshevTransformPlan{T,IFIRSTKIND, true} , x:: AbstractVector{T} ) where T<: fftwNumber
184
+ function * (P:: IChebyshevTransformPlan{T,1,K, true} , x:: AbstractVector{T} ) where { T<: fftwNumber ,K}
195
185
n = length (x)
196
- assert_applicable (P, x)
197
186
n == 0 && return x
198
187
199
188
x[1 ] *= 2
200
189
x = lmul! (one (T)/ 2 , P. plan* x)
201
190
x
202
191
end
203
192
204
- function mul! (y:: AbstractVector{T} , P:: IChebyshevTransformPlan{T,IFIRSTKIND, false} , x:: AbstractVector{T} ) where T<: fftwNumber
193
+ function mul! (y:: AbstractVector{T} , P:: IChebyshevTransformPlan{T,1,K, false} , x:: AbstractVector{T} ) where { T<: fftwNumber ,K}
205
194
n = length (x)
206
195
length (y) == n || throw (DimensionMismatch (" output must match dimension" ))
207
- assert_applicable (P, x)
208
196
n == 0 && return y
209
197
210
198
x[1 ] *= 2 # Todo: don't mutate x
@@ -213,20 +201,18 @@ function mul!(y::AbstractVector{T}, P::IChebyshevTransformPlan{T,IFIRSTKIND,fals
213
201
lmul! (one (T)/ 2 , y)
214
202
end
215
203
216
- function * (P:: IChebyshevTransformPlan{T,SECONDKIND, true} , x:: AbstractVector{T} ) where T<: fftwNumber
204
+ function * (P:: IChebyshevTransformPlan{T,2,K, true} , x:: AbstractVector{T} ) where { T<: fftwNumber ,K}
217
205
n = length (x)
218
- assert_applicable (P, x)
219
206
220
207
x[1 ] *= 2 ; x[end ] *= 2
221
208
x = inv (P)* x
222
209
x[1 ] *= 2 ; x[end ] *= 2
223
210
lmul! (convert (T,n- 1 )/ 2 ,x)
224
211
end
225
212
226
- function mul! (y:: AbstractVector{T} , P:: IChebyshevTransformPlan{T,SECONDKIND, false} , x:: AbstractVector{T} ) where T<: fftwNumber
213
+ function mul! (y:: AbstractVector{T} , P:: IChebyshevTransformPlan{T,2,K, false} , x:: AbstractVector{T} ) where { T<: fftwNumber ,K}
227
214
n = length (x)
228
215
length (y) == n || throw (DimensionMismatch (" output must match dimension" ))
229
- assert_applicable (P, x)
230
216
231
217
x[1 ] *= 2 ; x[end ] *= 2
232
218
_plan_mul! (y, inv (P), x)
@@ -235,13 +221,9 @@ function mul!(y::AbstractVector{T}, P::IChebyshevTransformPlan{T,SECONDKIND,fals
235
221
lmul! (convert (T,(n- 1 ))/ 2 ,y)
236
222
end
237
223
238
- * (P:: IChebyshevTransformPlan{T,k,false} ,x:: AbstractVector{T} ) where {T,k} =
239
- mul! (similar (x), P, convert (Array,x))
240
-
241
- ichebyshevtransform! (x:: AbstractVector{T} , kind= Val (1 )) where T =
242
- plan_ichebyshevtransform! (x, kind)* x
243
-
244
- ichebyshevtransform (x, kind= Val (1 )) = ichebyshevtransform! (Array (x), kind)
224
+ * (P:: IChebyshevTransformPlan{T,kind,K,false} ,x:: AbstractVector{T} ) where {T,kind,K} = mul! (similar (x), P, convert (Array,x))
225
+ ichebyshevtransform! (x:: AbstractArray , dims... ; kwds... ) = plan_ichebyshevtransform! (x, dims... ; kwds... )* x
226
+ ichebyshevtransform (x, dims... ; kwds... ) = plan_ichebyshevtransform (x, dims... ; kwds... )* x
245
227
246
228
247
229
# # Chebyshev U
@@ -290,7 +272,6 @@ plan_chebyshevutransform(x::AbstractVector) = plan_chebyshevutransform(x, Val(1)
290
272
291
273
function * (P:: ChebyshevUTransformPlan{T,1,true} ,x:: AbstractVector{T} ) where T
292
274
n = length (x)
293
- assert_applicable (P, x)
294
275
n ≤ 1 && return x
295
276
296
277
for k= 1 : n # sqrt(1-x_j^2) weight
301
282
302
283
function * (P:: ChebyshevUTransformPlan{T,2,true} , x:: AbstractVector{T} ) where T
303
284
n = length (x)
304
- assert_applicable (P, x)
305
285
n ≤ 1 && return x
306
286
307
287
c = one (T)/ (n+ 1 )
@@ -370,7 +350,6 @@ plan_ichebyshevutransform(x::AbstractVector) = plan_ichebyshevutransform(x, Val(
370
350
371
351
function * (P:: IChebyshevUTransformPlan{T,1,true} , x:: AbstractVector{T} ) where T<: fftwNumber
372
352
n = length (x)
373
- assert_applicable (P, x)
374
353
n ≤ 1 && return x
375
354
376
355
x = P. plan * x
384
363
385
364
function * (P:: IChebyshevUTransformPlan{T,2,true} , x:: AbstractVector{T} ) where T<: fftwNumber
386
365
n = length (x)
387
- assert_applicable (P, x)
388
366
n ≤ 1 && return x
389
367
390
368
c = one (T)/ (n+ 1 )
0 commit comments