@@ -178,3 +178,51 @@ function fft!(out::AbstractVector{T}, in::AbstractVector{U}, start_out::Int, sta
178
178
s_out = root. s_out
179
179
fft_pow4! (out, in, N, start_out, s_out, start_in, s_in, d)
180
180
end
181
+
182
+ function fft_pow3! (out:: AbstractVector{T} , in:: AbstractVector{U} , N:: Int , start_out:: Int , stride_out:: Int , start_in:: Int , stride_in:: Int , d:: Direction , plus120:: T , minus120:: T ) where {T, U}
183
+ if N == 3
184
+ @muladd out[start_out + 0 ] = in[start_in] + in[start_in + stride_in] + in[start_in + 2 * stride_in]
185
+ @muladd out[start_out + stride_out] = in[start_in] + in[start_in + stride_in]* plus120 + in[start_in + 2 * stride_in]* minus120
186
+ @muladd out[start_out + 2 * stride_out] = in[start_in] + in[start_in + stride_in]* minus120 + in[start_in + 2 * stride_in]* plus120
187
+ return
188
+ end
189
+
190
+ # Size of subproblem
191
+ Nprime = N/ 3
192
+
193
+ ds = direction_sign (d)
194
+
195
+ # Dividing into subproblems
196
+ fft_pow3! (out, in, Nprime, start_out, stride_out, start_in, stride_in* 3 , d, plus120, minus120)
197
+ fft_pow3! (out, in, Nprime, start_out + N_prime* stride_out, stride_out, start_in + stride_in, stride_in* 3 , d, plus120, minus120)
198
+ fft_pow3! (out, in, Nprime, start_out + 2 * N_prime* stride_out, stride_out, start_in + 2 * stride_in, stride_in* 3 , d, plus120, minus120)
199
+
200
+ w1 = convert (T, cispi (ds* 2 / N))
201
+ w2 = convert (T, cispi (ds* 4 / N))
202
+ wk1 = wk2 = one (T)
203
+ for k in 0 : Nprime- 1
204
+ @muladd k0 = start_out + k* stride_out
205
+ @muladd k1 = start_out + (k+ Nprime)* stride_out
206
+ @muladd k2 = start_out + (k+ 2 * Nprime)* stride_out
207
+ y_k0, y_k1, y_k2 = out[k0], out[k1], out[k2]
208
+ @muladd out[k0] = y_k0 + y_k1* wk1 + y_k2* wk2
209
+ @muladd out[k1] = y_k0 + y_k1* wk1* plus120 + y_k2* wk2* minus120
210
+ @muladd out[k2] = y_k0 + y_k1* wk1* minus120 + y_k2* wk2* plus120
211
+ wk1 *= w1
212
+ wk2 *= w2
213
+ end
214
+ end
215
+
216
+ function fft! (out:: AbstractVector{T} , in:: AbstractVector{U} , start_out:: Int , start_in:: Int , d:: Direction , :: Pow3FFT , g:: CallGraph{T} , idx:: Int ) where {T,U}
217
+ root = g[idx]
218
+ N = root. sz
219
+ s_in = root. s_in
220
+ s_out = root. s_out
221
+ p_120 = convert (T, cispi (2 / 3 ))
222
+ m_120 = convert (T, cispi (4 / 3 ))
223
+ if d == FFT_FORWARD
224
+ fft_pow3! (out, in, N, start_out, s_out, start_in, s_in, d, m_120, p_120)
225
+ else
226
+ fft_pow3! (out, in, N, start_out, s_out, start_in, s_in, d, p_120, m_120)
227
+ end
228
+ end
0 commit comments