@@ -26,9 +26,9 @@ function plan_nufft1{T<:AbstractFloat}(ω::AbstractVector{T}, ϵ::T)
26
26
t = AssignClosestEquispacedFFTpoint (ωdN)
27
27
γ = PerturbationParameter (ωdN, AssignClosestEquispacedGridpoint (ωdN))
28
28
K = FindK (γ, ϵ)
29
- U = constructU ( ωdN, K)
30
- V = constructV ( ωdN , K)
31
- p = plan_ifft ! (V, 1 )
29
+ U = constructU (ωdN, K)
30
+ V = constructV (linspace ( zero (T), N - 1 , N) , K)
31
+ p = plan_bfft ! (V, 1 )
32
32
temp = zeros (Complex{T}, N, K)
33
33
temp2 = zeros (Complex{T}, N, K)
34
34
Ones = ones (Complex{T}, K)
@@ -49,7 +49,7 @@ function plan_nufft2{T<:AbstractFloat}(x::AbstractVector{T}, ϵ::T)
49
49
γ = PerturbationParameter (x, AssignClosestEquispacedGridpoint (x))
50
50
K = FindK (γ, ϵ)
51
51
U = constructU (x, K)
52
- V = constructV (x , K)
52
+ V = constructV (linspace ( zero (T), N - 1 , N) , K)
53
53
p = plan_fft! (U, 1 )
54
54
temp = zeros (Complex{T}, N, K)
55
55
temp2 = zeros (Complex{T}, N, K)
@@ -58,6 +58,37 @@ function plan_nufft2{T<:AbstractFloat}(x::AbstractVector{T}, ϵ::T)
58
58
NUFFTPlan {2, eltype(U), typeof(p)} (U, V, p, t, temp, temp2, Ones)
59
59
end
60
60
61
+ doc"""
62
+ Computes a nonuniform fast Fourier transform of type III:
63
+
64
+ ```math
65
+ f_j = \s um_{k=1}^N c_k e^{-2\p i{\r m i} x_j \o mega_k},\q uad{\r m for}\q uad 1 \l e j \l e N.
66
+ ```
67
+ """
68
+ function plan_nufft3 {T<:AbstractFloat} (x:: AbstractVector{T} , ω:: AbstractVector{T} , ϵ:: T )
69
+ N = length (x)
70
+ s = AssignClosestEquispacedGridpoint (x)
71
+ t = AssignClosestEquispacedFFTpoint (x)
72
+ γ = PerturbationParameter (x, s)
73
+ K = FindK (γ, ϵ)
74
+ u = constructU (x, K)
75
+ v = constructV (ω, K)
76
+
77
+ p = plan_nufft1 (ω, ϵ)
78
+
79
+ D1 = Diagonal (1 - (s- t+ 1 )/ N)
80
+ D2 = Diagonal ((s- t+ 1 )/ N)
81
+ D3 = Diagonal (exp .(- 2 * im* T (π)* ω))
82
+ U = hcat (D1* u, D2* u)
83
+ V = hcat (v, D3* v)
84
+
85
+ temp = zeros (Complex{T}, N, 2 K)
86
+ temp2 = zeros (Complex{T}, N, 2 K)
87
+ Ones = ones (Complex{T}, 2 K)
88
+
89
+ NUFFTPlan {3, eltype(U), typeof(p)} (U, V, p, t, temp, temp2, Ones)
90
+ end
91
+
61
92
function (* ){N,T,V}(p:: NUFFTPlan{N,T} , x:: AbstractVector{V} )
62
93
A_mul_B! (zeros (promote_type (T,V), length (x)), p, x)
63
94
end
@@ -75,11 +106,44 @@ function Base.A_mul_B!{T}(y::AbstractVector{T}, P::NUFFTPlan{1,T}, c::AbstractVe
75
106
conj! (temp2)
76
107
broadcast! (* , temp, V, temp2)
77
108
A_mul_B! (y, temp, Ones)
78
- scale! (length (c), y)
79
109
80
110
y
81
111
end
82
112
113
+ function Base. A_mul_B! {T} (Y:: Matrix{T} , P:: NUFFTPlan{1,T} , C:: Matrix{T} )
114
+ for J = 1 : size (Y, 2 )
115
+ A_mul_B_col_J! (Y, P, C, J)
116
+ end
117
+ Y
118
+ end
119
+
120
+ function A_mul_B_col_J! {T} (Y:: Matrix{T} , P:: NUFFTPlan{1,T} , C:: Matrix{T} , J:: Int )
121
+ U, V, p, t, temp, temp2, Ones = P. U, P. V, P. p, P. t, P. temp, P. temp2, P. Ones
122
+
123
+ broadcast_col_J! (* , temp, C, U, J)
124
+ conj! (temp)
125
+ fill! (temp2, zero (T))
126
+ recombine_rows! (temp, t, temp2)
127
+ p* temp2
128
+ conj! (temp2)
129
+ broadcast! (* , temp, V, temp2)
130
+ COLSHIFT = size (C, 1 )* (J- 1 )
131
+ A_mul_B! (Y, temp, Ones, 1 + COLSHIFT, 1 )
132
+
133
+ Y
134
+ end
135
+
136
+ function broadcast_col_J! (f, temp:: Matrix , C:: Matrix , U:: Matrix , J:: Int )
137
+ N = size (C, 1 )
138
+ COLSHIFT = N* (J- 1 )
139
+ @inbounds for j = 1 : size (temp, 2 )
140
+ for i = 1 : N
141
+ temp[i,j] = f (C[i+ COLSHIFT],U[i,j])
142
+ end
143
+ end
144
+ temp
145
+ end
146
+
83
147
function Base. A_mul_B! {T} (y:: AbstractVector{T} , P:: NUFFTPlan{2,T} , c:: AbstractVector{T} )
84
148
U, V, p, t, temp, temp2, Ones = P. U, P. V, P. p, P. t, P. temp, P. temp2, P. Ones
85
149
@@ -94,6 +158,18 @@ function Base.A_mul_B!{T}(y::AbstractVector{T}, P::NUFFTPlan{2,T}, c::AbstractVe
94
158
y
95
159
end
96
160
161
+ function Base. A_mul_B! {T} (y:: AbstractVector{T} , P:: NUFFTPlan{3,T} , c:: AbstractVector{T} )
162
+ U, V, p, t, temp, temp2, Ones = P. U, P. V, P. p, P. t, P. temp, P. temp2, P. Ones
163
+
164
+ broadcast! (* , temp2, c, V)
165
+ A_mul_B! (temp, p, temp2)
166
+ reindex_temp! (temp, t, temp2)
167
+ broadcast! (* , temp, U, temp2)
168
+ A_mul_B! (y, temp, Ones)
169
+
170
+ y
171
+ end
172
+
97
173
function reindex_temp! {T} (temp:: Matrix{T} , t:: Vector{Int} , temp2:: Matrix{T} )
98
174
@inbounds for j = 1 : size (temp, 2 )
99
175
for i = 1 : size (temp, 1 )
@@ -122,6 +198,14 @@ Pre-compute a nonuniform fast Fourier transform of type II.
122
198
"""
123
199
nufft2 {T<:AbstractFloat} (c:: AbstractVector , x:: AbstractVector{T} , ϵ:: T ) = plan_nufft2 (x, ϵ)* c
124
200
201
+ doc"""
202
+ Pre-compute a nonuniform fast Fourier transform of type III.
203
+ """
204
+ nufft3 {T<:AbstractFloat} (c:: AbstractVector , x:: AbstractVector{T} , ω:: AbstractVector{T} , ϵ:: T ) = plan_nufft3 (x, ω, ϵ)* c
205
+
206
+ const nufft = nufft3
207
+ const plan_nufft = plan_nufft3
208
+
125
209
FindK {T<:AbstractFloat} (γ:: T , ϵ:: T ) = Int (ceil (5 * γ* exp (lambertw (log (10 / ϵ)/ γ/ 7 ))))
126
210
AssignClosestEquispacedGridpoint {T<:AbstractFloat} (x:: AbstractVector{T} ):: AbstractVector{T} = round .([Int], size (x, 1 )* x)
127
211
AssignClosestEquispacedFFTpoint {T<:AbstractFloat} (x:: AbstractVector{T} ):: Array{Int,1} = mod .(round .([Int], size (x, 1 )* x), size (x, 1 )) + 1
@@ -130,18 +214,15 @@ PerturbationParameter{T<:AbstractFloat}(x::AbstractVector{T}, s_vec::AbstractVec
130
214
function constructU {T<:AbstractFloat} (x:: AbstractVector{T} , K:: Int )
131
215
# Construct a low rank approximation, using Chebyshev expansions
132
216
# for AK = exp(-2*pi*1im*(x[j]-j/N)*k):
133
- N = size (x, 1 )
134
- # (s_vec, t, γ) = FindAlgorithmicParameters( x )
135
- s_vec = AssignClosestEquispacedGridpoint (x)
136
- er = N* x - s_vec
217
+ N = length (x)
218
+ s = AssignClosestEquispacedGridpoint (x)
219
+ er = N* x - s
137
220
γ = norm (er, Inf )
138
- # colspace vectors:
139
- Diagonal (exp .(- im* (pi * er)))* ChebyshevP (K- 1 , er/ γ)* Bessel_coeffs (K, γ)
221
+ Diagonal (exp .(- im* (π* er)))* ChebyshevP (K- 1 , er/ γ)* Bessel_coeffs (K, γ)
140
222
end
141
223
142
- function constructV {T<:AbstractFloat} (x:: AbstractVector{T} , K:: Int )
143
- N = size (x, 1 )
144
- complex (ChebyshevP (K- 1 , two (T)* collect (0 : N- 1 )/ N - ones (N) ))
224
+ function constructV {T<:AbstractFloat} (ω:: AbstractVector{T} , K:: Int )
225
+ complex (ChebyshevP (K- 1 , ω* (two (T)/ length (ω)) - 1 ))
145
226
end
146
227
147
228
function Bessel_coeffs {T<:AbstractFloat} (K:: Int , γ:: T )
0 commit comments