1
1
"""
2
2
Pre-plan an Inverse Padua Transform.
3
3
"""
4
- immutable IPaduaTransformPlan{DCTPLAN}
5
- cfsmat:: Matrix{Float64}
6
- tensorvals:: Matrix{Float64}
7
- padvals:: Vector{Float64}
8
- dctplan:: DCTPLAN
4
+ immutable IPaduaTransformPlan{IDCTPLAN,T}
5
+ cfsmat:: Matrix{T}
6
+ padvals:: Vector{T}
7
+ idctplan:: IDCTPLAN
9
8
end
10
9
11
- function plan_ipaduatransform (v:: AbstractVector )
10
+ function plan_ipaduatransform {T} (v:: AbstractVector{T} )
12
11
N= length (v)
13
12
n= Int (cld (- 3 + sqrt (1 + 8 N),2 ))
14
13
@assert N== div ((n+ 1 )* (n+ 2 ),2 )
15
- IPaduaTransformPlan (zeros (Float64, n+ 2 ,n+ 1 ),Array (Float64,n + 2 ,n + 1 ),
16
- Array (Float64,N), FFTW. plan_r2r (Array ( eltype (v), n+ 2 ,n+ 1 ),FFTW. REDFT00))
14
+ IPaduaTransformPlan (Array {T} ( n+ 2 ,n+ 1 ),Array {T} (N ),
15
+ FFTW. plan_r2r! (Array {T} ( n+ 2 ,n+ 1 ),FFTW. REDFT00))
17
16
end
18
17
19
18
"""
20
19
Inverse Padua Transform maps the 2D Chebyshev coefficients to the values of the interpolation polynomial at the Padua points.
21
20
"""
22
- function ipaduatransform (P:: IPaduaTransformPlan ,v:: AbstractVector )
21
+ function ipaduatransform {T} (P:: IPaduaTransformPlan ,v:: AbstractVector{T} )
23
22
cfsmat= trianglecfsmat (P,v)
24
- tensorvals = P . tensorvals
25
- cfsmat[:, 2 : end - 1 ] = scale! (cfsmat[ :,2 : end - 1 ] ,0.5 )
26
- cfsmat[ 2 : end - 1 ,:] = scale! (cfsmat[ 2 : end - 1 ,:] ,0.5 )
27
- tensorvals= P. dctplan * cfsmat
23
+ n,m = size (cfsmat)
24
+ scale! (view ( cfsmat, :,2 : m - 1 ) ,0.5 )
25
+ scale! (view ( cfsmat, 2 : n - 1 ,:) ,0.5 )
26
+ tensorvals= P. idctplan * cfsmat
28
27
paduavals= paduavec (P,tensorvals)
29
28
return paduavals
30
29
end
31
30
32
- function ipaduatransform (v:: AbstractVector )
33
- cfsmat= trianglecfsmat (v)
34
- n= size (cfsmat,2 )- 1
35
- tensorvals= Array (Float64,n+ 2 ,n+ 1 )
36
- cfsmat[:,2 : end - 1 ]= scale! (cfsmat[:,2 : end - 1 ],0.5 )
37
- cfsmat[2 : end - 1 ,:]= scale! (cfsmat[2 : end - 1 ,:],0.5 )
38
- tensorvals= FFTW. r2r (cfsmat,FFTW. REDFT00)
39
- paduavals= paduavec (tensorvals)
40
- return paduavals
41
- end
42
31
"""
43
32
Creates (n+2)x(n+1) Chebyshev coefficient matrix from triangle coefficients.
44
33
"""
45
34
function trianglecfsmat (P:: IPaduaTransformPlan ,cfs:: AbstractVector )
46
35
N= length (cfs)
47
36
n= Int (cld (- 3 + sqrt (1 + 8 N),2 ))
48
- cfsmat= P. cfsmat
49
- m= 1
50
- for d= 1 : n+ 1 , k= 1 : d
51
- j= d- k+ 1
52
- cfsmat[k,j]= cfs[m]
53
- if m== N
54
- return cfsmat
55
- else
56
- m+= 1
57
- end
58
- end
59
- return cfsmat
60
- end
61
-
62
- function trianglecfsmat (cfs:: AbstractVector )
63
- N= length (cfs)
64
- n= Int (cld (- 3 + sqrt (1 + 8 N),2 ))
65
- @assert N== div ((n+ 1 )* (n+ 2 ),2 )
66
- cfsmat= zeros (Float64,n+ 2 ,n+ 1 )
37
+ cfsmat= fill! (P. cfsmat,0 )
67
38
m= 1
68
- for d= 1 : n+ 1 , k= 1 : d
39
+ @inbounds for d= 1 : n+ 1 , k= 1 : d
69
40
j= d- k+ 1
70
41
cfsmat[k,j]= cfs[m]
71
42
if m== N
81
52
Vectorizes the function values at the Padua points.
82
53
"""
83
54
function paduavec (P:: IPaduaTransformPlan ,padmat:: Matrix )
84
- n= size (padmat,2 )- 1
85
- padvals= P. padvals
86
- if iseven (n)> 0
87
- d= div (n+ 2 ,2 )
88
- m= 0
89
- for i= 1 : n+ 1
90
- padvals[m+ 1 : m+ d]= padmat[1 + mod (i,2 ): 2 : end - 1 + mod (i,2 ),i]
91
- m+= d
92
- end
93
- else
94
- padvals= padmat[1 : 2 : end - 1 ]
95
- end
96
- return padvals
97
- end
98
-
99
- function paduavec (padmat:: Matrix )
100
55
n= size (padmat,2 )- 1
101
56
N= div ((n+ 1 )* (n+ 2 ),2 )
102
- padvals= Array (Float64,N)
103
57
if iseven (n)> 0
104
58
d= div (n+ 2 ,2 )
105
59
m= 0
106
- for i= 1 : n+ 1
107
- padvals[m+ 1 : m+ d]= padmat[ 1 + mod (i,2 ): 2 : end - 1 + mod (i,2 ),i]
108
- m+= d
109
- end
60
+ @inbounds for i= 1 : n+ 1
61
+ P . padvals[m+ 1 : m+ d]= view ( padmat, 1 + mod (i,2 ): 2 : N - 1 + mod (i,2 ),i)
62
+ m+= d
63
+ end
110
64
else
111
- padvals= padmat[1 : 2 : end - 1 ]
65
+
66
+ @inbounds P. padvals[:]= view (padmat,1 : 2 : N- 1 )
112
67
end
113
- return padvals
68
+ return P . padvals
114
69
end
115
70
116
71
"""
117
72
Pre-plan a Padua Transform.
118
73
"""
119
- immutable PaduaTransformPlan{IDCTPLAN}
120
- vals:: Matrix{Float64}
121
- tensorcfs:: Matrix{Float64}
122
- retvec:: Vector{Float64}
123
- idctplan:: IDCTPLAN
74
+ immutable PaduaTransformPlan{DCTPLAN,T}
75
+ vals:: Matrix{T}
76
+ retvec:: Vector{T}
77
+ dctplan:: DCTPLAN
124
78
end
125
79
126
- function plan_paduatransform (v:: AbstractVector )
80
+ function plan_paduatransform {T} (v:: AbstractVector{T} )
127
81
N= length (v)
128
82
n= Int (cld (- 3 + sqrt (1 + 8 N),2 ))
129
83
@assert N== div ((n+ 1 )* (n+ 2 ),2 )
130
- PaduaTransformPlan (zeros (Float64, n+ 2 ,n+ 1 ),Array (Float64,n + 2 ,n + 1 ),
131
- zeros (Float64,N), FFTW. plan_r2r (Array ( eltype (v), n+ 2 ,n+ 1 ),FFTW. REDFT00))
84
+ PaduaTransformPlan (Array {T} ( n+ 2 ,n+ 1 ),Array {T} (N ),
85
+ FFTW. plan_r2r! (Array {T} ( n+ 2 ,n+ 1 ),FFTW. REDFT00))
132
86
end
133
87
134
88
"""
135
89
Padua Transform maps from interpolant values at the Padua points to the 2D Chebyshev coefficients.
136
90
"""
137
- function paduatransform (P:: PaduaTransformPlan ,v:: AbstractVector )
91
+ function paduatransform {T} (P:: PaduaTransformPlan ,v:: AbstractVector{T} )
138
92
N= length (v)
139
93
n= Int (cld (- 3 + sqrt (1 + 8 N),2 ))
140
- tensorcfs= P. tensorcfs
141
94
vals= paduavalsmat (P,v)
142
- tensorcfs= P. idctplan* vals
143
- tensorcfs= scale! (tensorcfs,2. / (n* (n+ 1. )))
144
- tensorcfs[1 ,:]= scale! (tensorcfs[1 ,:],0.5 )
145
- tensorcfs[:,1 ]= scale! (tensorcfs[:,1 ],0.5 )
146
- tensorcfs[end ,:]= scale! (tensorcfs[end ,:],0.5 )
147
- tensorcfs[:,end ]= scale! (tensorcfs[:,end ],0.5 )
95
+ tensorcfs= P. dctplan* vals
96
+ m,l= size (tensorcfs)
97
+ scale! (tensorcfs,T (2 )/ (n* (n+ 1 )))
98
+ scale! (view (tensorcfs,1 ,:),0.5 )
99
+ scale! (view (tensorcfs,:,1 ),0.5 )
100
+ scale! (view (tensorcfs,m,:),0.5 )
101
+ scale! (view (tensorcfs,:,l),0.5 )
148
102
cfs= trianglecfsvec (P,tensorcfs)
149
103
return cfs
150
104
end
151
105
152
- function paduatransform (v:: AbstractVector )
153
- N= length (v)
154
- n= Int (cld (- 3 + sqrt (1 + 8 N),2 ))
155
- tensorcfs= Array (Float64,n+ 2 ,n+ 1 )
156
- vals= paduavalsmat (v)
157
- tensorcfs= FFTW. r2r (vals,FFTW. REDFT00)
158
- tensorcfs= scale! (tensorcfs,2. / (n* (n+ 1. )))
159
- tensorcfs[1 ,:]= scale! (tensorcfs[1 ,:],0.5 )
160
- tensorcfs[:,1 ]= scale! (tensorcfs[:,1 ],0.5 )
161
- tensorcfs[end ,:]= scale! (tensorcfs[end ,:],0.5 )
162
- tensorcfs[:,end ]= scale! (tensorcfs[:,end ],0.5 )
163
- cfsvec= trianglecfsvec (tensorcfs)
164
- return cfsvec
165
- end
166
-
167
106
"""
168
107
Creates (n+2)x(n+1) matrix of interpolant values on the tensor grid at the (n+1)(n+2)/2 Padua points.
169
108
"""
170
109
function paduavalsmat (P:: PaduaTransformPlan ,v:: AbstractVector )
171
110
N= length (v)
172
111
n= Int (cld (- 3 + sqrt (1 + 8 N),2 ))
173
- vals= P. vals
174
- if iseven (n)> 0
175
- d= div (n+ 2 ,2 )
176
- m= 0
177
- for i= 1 : n+ 1
178
- vals[1 + mod (i,2 ): 2 : end - 1 + mod (i,2 ),i]= v[m+ 1 : m+ d]
179
- m+= d
180
- end
181
- else
182
- vals[1 : 2 : end ]= v
183
- end
184
- return vals
185
- end
186
-
187
- function paduavalsmat (v:: AbstractVector )
188
- N= length (v)
189
- n= Int (cld (- 3 + sqrt (1 + 8 N),2 ))
190
- @assert N== div ((n+ 1 )* (n+ 2 ),2 )
191
- vals= zeros (Float64,n+ 2 ,n+ 1 )
112
+ vals= fill! (P. vals,0. )
192
113
if iseven (n)> 0
193
114
d= div (n+ 2 ,2 )
194
115
m= 0
195
- for i= 1 : n+ 1
196
- vals[1 + mod (i,2 ): 2 : end - 1 + mod (i,2 ),i]= v[ m+ 1 : m+ d]
116
+ @inbounds for i= 1 : n+ 1
117
+ vals[1 + mod (i,2 ): 2 : end - 1 + mod (i,2 ),i]= view (v, m+ 1 : m+ d)
197
118
m+= d
198
119
end
199
120
else
200
- vals[1 : 2 : end ]= v
121
+ @inbounds vals[1 : 2 : end ]= view (v,:)
201
122
end
202
123
return vals
203
124
end
@@ -207,67 +128,43 @@ Creates length (n+1)(n+2)/2 vector from matrix of triangle Chebyshev coefficient
207
128
"""
208
129
function trianglecfsvec (P:: PaduaTransformPlan ,cfs:: Matrix )
209
130
m= size (cfs,2 )
210
- ret= P. retvec
211
131
l= 1
212
- for d= 1 : m,k= 1 : d
132
+ @inbounds for d= 1 : m,k= 1 : d
213
133
j= d- k+ 1
214
- ret [l]= cfs[k,j]
134
+ P . retvec [l]= cfs[k,j]
215
135
l+= 1
216
136
end
217
- return ret
218
- end
219
-
220
- function trianglecfsvec (cfs:: Matrix )
221
- n,m= size (cfs)
222
- N= div (n* m,2 )
223
- ret= Array (Float64,N)
224
- l= 1
225
- for d= 1 : m,k= 1 : d
226
- j= d- k+ 1
227
- ret[l]= cfs[k,j]
228
- l+= 1
229
- end
230
- return ret
137
+ return P. retvec
231
138
end
232
139
233
140
"""
234
141
Returns coordinates of the (n+1)(n+2)/2 Padua points.
235
142
"""
236
- function paduapoints ( n:: Integer )
143
+ function paduapoints {T} ( :: Type{T} , n:: Integer )
237
144
N= div ((n+ 1 )* (n+ 2 ),2 )
238
- MM= Array (Float64 ,N,2 )
145
+ MM= Array (T ,N,2 )
239
146
m= 0
240
147
delta= 0
241
148
NN= fld (n+ 2 ,2 )
242
- for k= n: - 1 : 0
149
+ @inbounds for k= n: - 1 : 0
243
150
if isodd (n)> 0
244
151
delta= mod (k,2 )
245
152
end
246
- for j= NN+ delta: - 1 : 1
153
+ @inbounds for j= NN+ delta: - 1 : 1
247
154
m+= 1
248
- MM[m,1 ]= sinpi (1. * k / n- 0.5 )
155
+ MM[m,1 ]= sinpi (T (k) / n- T ( 0.5 ) )
249
156
if isodd (n- k)> 0
250
- MM[m,2 ]= sinpi ((2 j- 1. ) / (n+ 1. ) - 0.5 )
157
+ MM[m,2 ]= sinpi ((2 j- one (T)) / (n+ 1 ) - T ( 0.5 ) )
251
158
else
252
- MM[m,2 ]= sinpi ((2 j- 2. )/ (n+ 1. ) - 0.5 )
159
+ MM[m,2 ]= sinpi (T (2 j- 2 )/ (n+ 1 ) - T ( 0.5 ) )
253
160
end
254
161
end
255
162
end
256
163
return MM
257
164
end
258
165
259
- """
260
- Interpolates a 2d function at a given point using 2d Chebyshev series.
261
- """
262
- function paduaeval (f:: Function ,x:: Float64 ,y:: Float64 ,m:: Integer )
263
- M= div ((m+ 1 )* (m+ 2 ),2 )
264
- pvals= Array (Float64,M)
265
- p= paduapoints (m)
266
- pvals= map (f,p[:,1 ],p[:,2 ])
267
- plan= plan_paduatransform (pvals)
268
- coeffs= paduatransform (plan,pvals)
269
- cfs_mat= trianglecfsmat (coeffs)
270
- cfs_mat= cfs_mat[1 : end - 1 ,:]
271
- f_x= sum ([cfs_mat[k,j]* cos ((j- 1 )* acos (x))* cos ((k- 1 )* acos (y)) for k= 1 : m+ 1 , j= 1 : m+ 1 ])
272
- return f_x
273
- end
166
+ # v=collect(1.:6.)
167
+ # P=plan_ipaduatransform(v)
168
+ # @code_warntype ipaduatransform(P,v)
169
+ # M=plan_paduatransform(v)
170
+ # @code_warntype paduatransform(M,v)
0 commit comments