1
1
"""
2
2
Pre-plan an Inverse Padua Transform.
3
3
"""
4
- immutable IPaduaTransformPlan{IDCTPLAN,T}
4
+ # lex indicates if its lexigraphical (i.e., x, y) or reverse (y, x)
5
+ immutable IPaduaTransformPlan{lex,IDCTPLAN,T}
5
6
cfsmat:: Matrix{T}
6
7
padvals:: Vector{T}
7
8
idctplan:: IDCTPLAN
8
9
end
9
10
10
- function plan_ipaduatransform {T} (:: Type{T} ,N:: Integer )
11
+ IPaduaTransformPlan {T,lex} (cfsmat:: Matrix{T} ,padvals:: Vector{T} ,idctplan,:: Type{Val{lex}} ) =
12
+ IPaduaTransformPlan {lex,typeof(idctplan),T} (cfsmat,padvals,idctplan)
13
+
14
+ function plan_ipaduatransform {T} (:: Type{T} ,N:: Integer ,lex)
11
15
n= Int (cld (- 3 + sqrt (1 + 8 N),2 ))
12
16
if N ≠ div ((n+ 1 )* (n+ 2 ),2 )
13
17
error (" Padua transforms can only be applied to vectors of length (n+1)*(n+2)/2." )
14
18
end
15
19
IPaduaTransformPlan (Array {T} (n+ 2 ,n+ 1 ),Array {T} (N),
16
- FFTW. plan_r2r! (Array {T} (n+ 2 ,n+ 1 ),FFTW. REDFT00))
20
+ FFTW. plan_r2r! (Array {T} (n+ 2 ,n+ 1 ),FFTW. REDFT00),lex )
17
21
end
18
22
19
- plan_ipaduatransform {T} (v:: AbstractVector{T} ) = plan_ipaduatransform (eltype (v),length (v))
23
+
24
+ plan_ipaduatransform {T} (:: Type{T} ,N:: Integer ) = plan_ipaduatransform (T,N,Val{true })
25
+
26
+ plan_ipaduatransform {T} (v:: AbstractVector{T} ,lex... ) = plan_ipaduatransform (eltype (v),length (v),lex... )
20
27
21
28
"""
22
29
Inverse Padua Transform maps the 2D Chebyshev coefficients to the values of the interpolation polynomial at the Padua points.
@@ -31,12 +38,12 @@ function *{T}(P::IPaduaTransformPlan,v::AbstractVector{T})
31
38
return paduavals
32
39
end
33
40
34
- ipaduatransform (v:: AbstractVector ) = plan_ipaduatransform (v)* v
41
+ ipaduatransform (v:: AbstractVector ,lex ... ) = plan_ipaduatransform (v,lex ... )* v
35
42
36
43
"""
37
44
Creates (n+2)x(n+1) Chebyshev coefficient matrix from triangle coefficients.
38
45
"""
39
- function trianglecfsmat (P:: IPaduaTransformPlan ,cfs:: AbstractVector )
46
+ function trianglecfsmat (P:: IPaduaTransformPlan{true} ,cfs:: AbstractVector )
40
47
N= length (cfs)
41
48
n= Int (cld (- 3 + sqrt (1 + 8 N),2 ))
42
49
cfsmat= fill! (P. cfsmat,0 )
@@ -55,6 +62,25 @@ function trianglecfsmat(P::IPaduaTransformPlan,cfs::AbstractVector)
55
62
return cfsmat
56
63
end
57
64
65
+ function trianglecfsmat (P:: IPaduaTransformPlan{false} ,cfs:: AbstractVector )
66
+ N= length (cfs)
67
+ n= Int (cld (- 3 + sqrt (1 + 8 N),2 ))
68
+ cfsmat= fill! (P. cfsmat,0 )
69
+ m= 1
70
+ for d= 1 : n+ 1
71
+ @inbounds for k= d: - 1 : 1
72
+ j= d- k+ 1
73
+ cfsmat[k,j]= cfs[m]
74
+ if m== N
75
+ return cfsmat
76
+ else
77
+ m+= 1
78
+ end
79
+ end
80
+ end
81
+ return cfsmat
82
+ end
83
+
58
84
"""
59
85
Vectorizes the function values at the Padua points.
60
86
"""
77
103
"""
78
104
Pre-plan a Padua Transform.
79
105
"""
80
- immutable PaduaTransformPlan{DCTPLAN,T}
106
+ immutable PaduaTransformPlan{lex, DCTPLAN,T}
81
107
vals:: Matrix{T}
82
108
retvec:: Vector{T}
83
109
dctplan:: DCTPLAN
84
110
end
85
111
86
- function plan_paduatransform {T} (:: Type{T} ,N:: Integer )
112
+ PaduaTransformPlan {T,lex} (vals:: Matrix{T} ,retvec:: Vector{T} ,dctplan,:: Type{Val{lex}} ) =
113
+ PaduaTransformPlan {lex,typeof(dctplan),T} (vals,retvec,dctplan)
114
+
115
+ function plan_paduatransform {T} (:: Type{T} ,N:: Integer ,lex)
87
116
n= Int (cld (- 3 + sqrt (1 + 8 N),2 ))
88
117
if N ≠ ((n+ 1 )* (n+ 2 ))÷ 2
89
118
error (" Padua transforms can only be applied to vectors of length (n+1)*(n+2)/2." )
90
119
end
91
120
PaduaTransformPlan (Array {T} (n+ 2 ,n+ 1 ),Array {T} (N),
92
- FFTW. plan_r2r! (Array {T} (n+ 2 ,n+ 1 ),FFTW. REDFT00))
121
+ FFTW. plan_r2r! (Array {T} (n+ 2 ,n+ 1 ),FFTW. REDFT00),lex )
93
122
end
94
123
95
- plan_paduatransform {T} (v:: AbstractVector{T} ) = plan_paduatransform (eltype (v),length (v))
124
+ plan_paduatransform {T} (:: Type{T} ,N:: Integer ) = plan_paduatransform (T,N,Val{true })
125
+ plan_paduatransform {T} (v:: AbstractVector{T} ,lex... ) = plan_paduatransform (eltype (v),length (v),lex... )
96
126
97
127
"""
98
128
Padua Transform maps from interpolant values at the Padua points to the 2D Chebyshev coefficients.
@@ -112,7 +142,7 @@ function *{T}(P::PaduaTransformPlan,v::AbstractVector{T})
112
142
return cfs
113
143
end
114
144
115
- paduatransform (v:: AbstractVector ) = plan_paduatransform (v)* v
145
+ paduatransform (v:: AbstractVector ,lex ... ) = plan_paduatransform (v,lex ... )* v
116
146
117
147
"""
118
148
Creates (n+2)x(n+1) matrix of interpolant values on the tensor grid at the (n+1)(n+2)/2 Padua points.
137
167
"""
138
168
Creates length (n+1)(n+2)/2 vector from matrix of triangle Chebyshev coefficients.
139
169
"""
140
- function trianglecfsvec (P:: PaduaTransformPlan ,cfs:: Matrix )
170
+ function trianglecfsvec (P:: PaduaTransformPlan{true} ,cfs:: Matrix )
141
171
m= size (cfs,2 )
142
172
l= 1
143
173
for d= 1 : m
@@ -150,6 +180,19 @@ function trianglecfsvec(P::PaduaTransformPlan,cfs::Matrix)
150
180
return P. retvec
151
181
end
152
182
183
+ function trianglecfsvec (P:: PaduaTransformPlan{false} ,cfs:: Matrix )
184
+ m= size (cfs,2 )
185
+ l= 1
186
+ for d= 1 : m
187
+ @inbounds for k= d: - 1 : 1
188
+ j= d- k+ 1
189
+ P. retvec[l]= cfs[k,j]
190
+ l+= 1
191
+ end
192
+ end
193
+ return P. retvec
194
+ end
195
+
153
196
"""
154
197
Returns coordinates of the (n+1)(n+2)/2 Padua points.
155
198
"""
0 commit comments