Skip to content

Commit fa238d3

Browse files
add 2D nufft of type II-II
framework should allow other types a-b to be implemented too.
1 parent 6315ae6 commit fa238d3

File tree

2 files changed

+106
-14
lines changed

2 files changed

+106
-14
lines changed

src/nufft.jl

Lines changed: 80 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ function plan_nufft3{T<:AbstractFloat}(x::AbstractVector{T}, ω::AbstractVector{
7777
NUFFTPlan{3, eltype(U), typeof(p)}(U, V, p, t, temp, temp2, Ones)
7878
end
7979

80-
function (*){N,T,V}(p::NUFFTPlan{N,T}, x::AbstractVector{V})
81-
A_mul_B!(zeros(promote_type(T,V), length(x)), p, x)
80+
function (*){N,T,V}(p::NUFFTPlan{N,T}, c::AbstractArray{V})
81+
A_mul_B!(zeros(promote_type(T,V), size(c)), p, c)
8282
end
8383

8484
function Base.A_mul_B!{T}(f::AbstractVector{T}, P::NUFFTPlan{1,T}, c::AbstractVector{T})
@@ -96,13 +96,24 @@ function Base.A_mul_B!{T}(f::AbstractVector{T}, P::NUFFTPlan{1,T}, c::AbstractVe
9696
f
9797
end
9898

99-
function Base.A_mul_B!{T}(F::Matrix{T}, P::NUFFTPlan{1,T}, C::Matrix{T})
99+
function Base.A_mul_B!{N,T}(F::Matrix{T}, P::NUFFTPlan{N,T}, C::Matrix{T})
100100
for J = 1:size(F, 2)
101101
A_mul_B_col_J!(F, P, C, J)
102102
end
103103
F
104104
end
105105

106+
function broadcast_col_J!(f, temp::Matrix, C::Matrix, U::Matrix, J::Int)
107+
N = size(C, 1)
108+
COLSHIFT = N*(J-1)
109+
@inbounds for j = 1:size(temp, 2)
110+
for i = 1:N
111+
temp[i,j] = f(C[i+COLSHIFT],U[i,j])
112+
end
113+
end
114+
temp
115+
end
116+
106117
function A_mul_B_col_J!{T}(F::Matrix{T}, P::NUFFTPlan{1,T}, C::Matrix{T}, J::Int)
107118
U, V, p, t, temp, temp2, Ones = P.U, P.V, P.p, P.t, P.temp, P.temp2, P.Ones
108119

@@ -119,17 +130,6 @@ function A_mul_B_col_J!{T}(F::Matrix{T}, P::NUFFTPlan{1,T}, C::Matrix{T}, J::Int
119130
F
120131
end
121132

122-
function broadcast_col_J!(f, temp::Matrix, C::Matrix, U::Matrix, J::Int)
123-
N = size(C, 1)
124-
COLSHIFT = N*(J-1)
125-
@inbounds for j = 1:size(temp, 2)
126-
for i = 1:N
127-
temp[i,j] = f(C[i+COLSHIFT],U[i,j])
128-
end
129-
end
130-
temp
131-
end
132-
133133
function Base.A_mul_B!{T}(f::AbstractVector{T}, P::NUFFTPlan{2,T}, c::AbstractVector{T})
134134
U, V, p, t, temp, temp2, Ones = P.U, P.V, P.p, P.t, P.temp, P.temp2, P.Ones
135135

@@ -142,6 +142,19 @@ function Base.A_mul_B!{T}(f::AbstractVector{T}, P::NUFFTPlan{2,T}, c::AbstractVe
142142
f
143143
end
144144

145+
function A_mul_B_col_J!{T}(F::Matrix{T}, P::NUFFTPlan{2,T}, C::Matrix{T}, J::Int)
146+
U, V, p, t, temp, temp2, Ones = P.U, P.V, P.p, P.t, P.temp, P.temp2, P.Ones
147+
148+
broadcast_col_J!(*, temp, C, V, J)
149+
p*temp
150+
reindex_temp!(temp, t, temp2)
151+
broadcast!(*, temp, U, temp2)
152+
COLSHIFT = size(C, 1)*(J-1)
153+
A_mul_B!(F, temp, Ones, 1+COLSHIFT, 1)
154+
155+
F
156+
end
157+
145158
function Base.A_mul_B!{T}(f::AbstractVector{T}, P::NUFFTPlan{3,T}, c::AbstractVector{T})
146159
U, V, p, t, temp, temp2, Ones = P.U, P.V, P.p, P.t, P.temp, P.temp2, P.Ones
147160

@@ -202,6 +215,59 @@ nufft3{T<:AbstractFloat}(c::AbstractVector, x::AbstractVector{T}, ω::AbstractVe
202215
const nufft = nufft3
203216
const plan_nufft = plan_nufft3
204217

218+
219+
doc"""
220+
Pre-computes a 2D nonuniform fast Fourier transform.
221+
222+
For best performance, choose the right number of threads by `FFTW.set_num_threads(4)`, for example.
223+
"""
224+
immutable NUFFT2DPlan{T,P1,P2} <: Base.DFT.Plan{T}
225+
p1::P1
226+
p2::P2
227+
temp::Vector{T}
228+
end
229+
230+
doc"""
231+
Pre-computes a 2D nonuniform fast Fourier transform of type II-II.
232+
"""
233+
function plan_nufft2{T<:AbstractFloat}(x::AbstractVector{T}, y::AbstractVector{T}, ϵ::T)
234+
p1 = plan_nufft2(x, ϵ)
235+
p2 = plan_nufft2(y, ϵ)
236+
temp = zeros(Complex{T}, length(y))
237+
238+
NUFFT2DPlan(p1, p2, temp)
239+
end
240+
241+
function (*){T,V}(p::NUFFT2DPlan{T}, C::Matrix{V})
242+
A_mul_B!(zeros(promote_type(T,V), size(C)), p, C)
243+
end
244+
245+
function Base.A_mul_B!{T}(F::Matrix{T}, P::NUFFT2DPlan{T}, C::Matrix{T})
246+
p1, p2, temp = P.p1, P.p2, P.temp
247+
248+
# Apply 1D x-plan to all columns
249+
A_mul_B!(F, p1, C)
250+
251+
# Apply 1D y-plan to all rows
252+
for i = 1:size(C, 1)
253+
@inbounds for j = 1:size(F, 2) temp[j] = F[i,j] end
254+
A_mul_B!(temp, p2, temp)
255+
@inbounds for j = 1:size(F, 2) F[i,j] = temp[j] end
256+
end
257+
258+
F
259+
end
260+
261+
doc"""
262+
Computes a 2D nonuniform fast Fourier transform of type II-II:
263+
264+
```math
265+
f_{j_1,j_2} = \sum_{k_1=1}^M\sum_{k_2=1}^N C_{k_1,k_2} e^{-2\pi{\rm i} (x_{j_1}(k_1-1) + x_{j_2}(k_2-1))},\quad{\rm for}\quad 1 \le j_1 \le M,\quad 1 \le j_2 \le N.
266+
```
267+
"""
268+
nufft2{T<:AbstractFloat}(C::Matrix, x::AbstractVector{T}, y::AbstractVector{T}, ϵ::T) = plan_nufft2(x, y, ϵ)*C
269+
270+
205271
FindK{T<:AbstractFloat}::T, ϵ::T) = Int(ceil(5*γ*exp(lambertw(log(10/ϵ)/γ/7))))
206272
AssignClosestEquispacedGridpoint{T<:AbstractFloat}(x::AbstractVector{T})::AbstractVector{T} = round.([Int], size(x, 1)*x)
207273
AssignClosestEquispacedFFTpoint{T<:AbstractFloat}(x::AbstractVector{T})::Array{Int,1} = mod.(round.([Int], size(x, 1)*x), size(x, 1)) + 1

test/nuffttests.jl

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,30 @@ using FastTransforms, Base.Test
6767
fast = nufft3(c, x, ω, ϵ)
6868
@test norm(exact - fast, Inf) < err_bnd
6969
end
70+
71+
function nudft2{T<:AbstractFloat}(C::Matrix{Complex{T}}, x::AbstractVector{T}, y::AbstractVector{T})
72+
# Nonuniform discrete Fourier transform of type II-II
73+
74+
M, N = size(C)
75+
output = zeros(C)
76+
@inbounds for j1 = 1:M, j2 = 1:N
77+
for k1 = 1:M, k2 = 1:N
78+
output[j1,j2] += exp(-2*T(π)*im*(x[j1]*(k1-1)+y[j2]*(k2-1)))*C[k1,k2]
79+
end
80+
end
81+
return output
82+
end
83+
84+
N = round.([Int],logspace(1,1.7,5))
85+
86+
for n in N, ϵ in (1e-4,1e-8,1e-12,eps(Float64))
87+
C = complex(rand(n,n))
88+
err_bnd = 500*ϵ*n*norm(C)
89+
90+
x = (collect(0:n-1) + 0.25*rand(n))/n
91+
y = (collect(0:n-1) + 0.25*rand(n))/n
92+
exact = nudft2(C, x, y)
93+
fast = nufft2(C, x, y, ϵ)
94+
@test norm(exact - fast, Inf) < err_bnd
95+
end
7096
end

0 commit comments

Comments
 (0)