Skip to content

Commit c46c504

Browse files
tknoppmischmi96
andauthored
NFCT/NFCT branch (#89)
* adds NFCT interface to AbstractNFFTs and implementation to NFFT3 wrapper #85 * adds NDCT, fixes small bug in wrapper #85 * generalize parts in AbstractNFFTs (less code) * implement NDST * implement NDST/NFST (NFFT3 wrapper) + tests * apodization->deconvolve + adjoint->transpose (where appropriate) * rename AnyNFFTPlan since the name was ambiguous Co-authored-by: Michael Schmischke <[email protected]>
1 parent d79020f commit c46c504

18 files changed

+689
-140
lines changed

AbstractNFFTs/src/AbstractNFFTs.jl

+7-4
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,17 @@ using LinearAlgebra
55
using Printf
66

77
# interface
8-
export AnyNFFTPlan, AbstractNFFTPlan, AbstractNNFFTPlan,
9-
plan_nfft, mul!, size_in, size_out, nodes!
8+
export AbstractFTPlan, AbstractRealFTPlan, AbstractComplexFTPlan,
9+
AbstractNFFTPlan, AbstractNFCTPlan, AbstractNFSTPlan, AbstractNNFFTPlan,
10+
plan_nfft, plan_nfct, plan_nfst, mul!, size_in, size_out, nodes!
1011

1112
# optional
12-
export apodization!, apodization_adjoint!, convolve!, convolve_adjoint!
13+
export deconvolve!, deconvolve_transpose!, convolve!, convolve_transpose!
1314

1415
# derived
15-
export nfft, nfft_adjoint, ndft, ndft_adjoint
16+
export nfft, nfft_adjoint, ndft, ndft_adjoint,
17+
nfct, nfct_transpose, ndct, ndct_transpose,
18+
nfst, nfst_transpose
1619

1720
# misc
1821
export TimingStats, accuracyParams, reltolToParams, paramsToReltol,

AbstractNFFTs/src/derived.jl

+104-34
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,102 @@
11

22
##########################
3-
# plan_nfft constructors
3+
# plan_* constructors
44
##########################
55

6-
# The following automatically call the plan_nfft version for type Array
76

8-
plan_nfft(x::AbstractArray, N::Union{Integer,NTuple{D,Int}}, args...; kargs...) where {D} =
9-
plan_nfft(Array, x, N, args...; kargs...)
7+
for op in [:nfft, :nfct, :nfst]
8+
planfunc = Symbol("plan_"*"$op")
9+
@eval begin
1010

11-
plan_nfft(x::AbstractArray, y::AbstractArray, args...; kargs...) where {D} =
12-
plan_nfft(Array, x, y, args...; kargs...)
11+
# The following automatically call the plan_* version for type Array
1312

14-
# The follow convert 1D parameters into the format required by the NFFT plan
13+
$(planfunc)(x::AbstractArray, N::Union{Integer,NTuple{D,Int}}, args...; kargs...) where {D} =
14+
$(planfunc)(Array, x, N, args...; kargs...)
1515

16-
plan_nfft(Q::Type, x::AbstractVector, N::Integer, rest...; kwargs...) where {D} =
17-
plan_nfft(Q, collect(reshape(x,1,length(x))), (N,), rest...; kwargs...)
16+
$(planfunc)(x::AbstractArray, y::AbstractArray, args...; kargs...) where {D} =
17+
$(planfunc)(Array, x, y, args...; kargs...)
1818

19-
plan_nfft(Q::Type, x::AbstractVector, N::NTuple{D,Int}, rest...; kwargs...) where {D} =
20-
plan_nfft(Q, collect(reshape(x,1,length(x))), N, rest...; kwargs...)
19+
# The follow convert 1D parameters into the format required by the plan
2120

22-
plan_nfft(Q::Type, x::AbstractMatrix, N::NTuple{D,Int}, rest...; kwargs...) where {D} =
23-
plan_nfft(Q, collect(x), N, rest...; kwargs...)
21+
$(planfunc)(Q::Type, x::AbstractVector, N::Integer, rest...; kwargs...) where {D} =
22+
$(planfunc)(Q, collect(reshape(x,1,length(x))), (N,), rest...; kwargs...)
2423

25-
plan_nfft(Q::Type, x::AbstractVector, y::AbstractVector, rest...; kwargs...) where {D} =
26-
plan_nfft(Q, collect(reshape(x,1,length(x))), collect(reshape(y,1,length(x))), rest...; kwargs...)
24+
$(planfunc)(Q::Type, x::AbstractVector, N::NTuple{D,Int}, rest...; kwargs...) where {D} =
25+
$(planfunc)(Q, collect(reshape(x,1,length(x))), N, rest...; kwargs...)
2726

27+
$(planfunc)(Q::Type, x::AbstractMatrix, N::NTuple{D,Int}, rest...; kwargs...) where {D} =
28+
$(planfunc)(Q, collect(x), N, rest...; kwargs...)
29+
30+
end
31+
end
32+
33+
## NNFFT constructor
34+
plan_nnfft(Q::Type, x::AbstractVector, y::AbstractVector, rest...; kwargs...) where {D} =
35+
plan_nnfft(Q, collect(reshape(x,1,length(x))), collect(reshape(y,1,length(x))), rest...; kwargs...)
2836

29-
##########################
30-
# Allocating nfft functions
31-
##########################
3237

38+
39+
###############################################
40+
# Allocating trafo functions with plan creation
41+
###############################################
42+
43+
for (op,trans) in zip([:nfft, :nfct, :nfst],
44+
[:adjoint, :transpose, :transpose])
45+
planfunc = Symbol("plan_$(op)")
46+
tfunc = Symbol("$(op)_$(trans)")
47+
@eval begin
48+
49+
# TODO fix comments (how?)
3350
"""
34-
nfft(x, f::AbstractArray{T,D}, rest...; kwargs...)
51+
nfft(x, f, rest...; kwargs...)
3552
36-
calculates the NFFT of the array `f` for the nodes contained in the matrix `x`
53+
calculates the nfft of the array `f` for the nodes contained in the matrix `x`
3754
The output is a vector of length M=`size(nodes,2)`
3855
"""
39-
function nfft(x, f::AbstractArray{T,D}; kargs...) where {T,D}
40-
p = plan_nfft(x, size(f); kargs... )
56+
function $(op)(x, f::AbstractArray; kargs...)
57+
p = $(planfunc)(x, size(f); kargs... )
4158
return p * f
4259
end
4360

4461
"""
45-
nfft_adjoint(x, N, fHat::AbstractArray{T,D}, rest...; kwargs...)
62+
nfft_adjoint(x, N, fHat, rest...; kwargs...)
4663
47-
calculates the adjoint NFFT of the vector `fHat` for the nodes contained in the matrix `x`.
64+
calculates the adjoint nfft of the vector `fHat` for the nodes contained in the matrix `x`.
4865
The output is an array of size `N`
4966
"""
50-
function nfft_adjoint(x, N, fHat::AbstractVector{T}; kargs...) where T
51-
p = plan_nfft(x, N; kargs...)
52-
return adjoint(p) * fHat
67+
function $(tfunc)(x, N, fHat; kargs...)
68+
p = $(planfunc)(x, N; kargs...)
69+
return $(trans)(p) * fHat
70+
end
71+
72+
end
5373
end
5474

75+
############################
76+
# Allocating trafo functions
77+
############################
5578

5679
"""
5780
*(p, f) -> fHat
5881
59-
For a **non**-directional `D` dimensional plan `p` this calculates the NFFT of a `D` dimensional array `f` of size `N`.
82+
For a **non**-directional `D` dimensional plan `p` this calculates the NFFT/NNFFT of a `D` dimensional array `f` of size `N`.
6083
`fHat` is a vector of length `M`.
6184
(`M` and `N` are defined in the plan creation)
6285
6386
For a **directional** `D` dimensional plan `p` both `f` and `fHat` are `D`
6487
dimensional arrays, and the dimension specified in the plan creation is
6588
affected.
6689
"""
67-
function Base.:*(p::AnyNFFTPlan{T}, f::AbstractArray{Complex{U},D}; kargs...) where {T,U,D}
90+
function Base.:*(p::AbstractComplexFTPlan{T}, f::AbstractArray{Complex{U},D}; kargs...) where {T,U,D}
6891
fHat = similar(f, Complex{T}, size_out(p))
6992
mul!(fHat, p, f; kargs...)
7093
return fHat
7194
end
7295

7396
"""
74-
*(p::Adjoint{T,<:AnyNFFTPlan{T}}, fHat) -> f
97+
*(p::Adjoint{T,<:AbstractFTPlan{T}}, fHat) -> f
7598
76-
For a **non**-directional `D` dimensional plan `p` this calculates the adjoint NFFT of a length `M` vector `fHat`
99+
For a **non**-directional `D` dimensional plan `p` this calculates the adjoint NFFT/NNFFT of a length `M` vector `fHat`
77100
`f` is a `D` dimensional array of size `N`.
78101
(`M` and `N` are defined in the plan creation)
79102
@@ -82,22 +105,69 @@ dimensional arrays, and the dimension specified in the plan creation is
82105
affected.
83106
"""
84107

85-
function Base.:*(p::Adjoint{Complex{T},<:AnyNFFTPlan{T}}, fHat::AbstractArray{Complex{U},D}; kargs...) where {T,U,D}
108+
function Base.:*(p::Adjoint{Complex{T},<:AbstractComplexFTPlan{T}}, fHat::AbstractArray{Complex{U},D}; kargs...) where {T,U,D}
86109
f = similar(fHat, Complex{T}, size_out(p))
87110
mul!(f, p, fHat; kargs...)
88111
return f
89112
end
90113

91114
# The following two methods are redundant but need to be defined because of a method ambiguity with Julia Base
92-
function Base.:*(p::Adjoint{Complex{T},<:AnyNFFTPlan{T}}, fHat::AbstractVector{Complex{U}}; kargs...) where {T,U}
115+
function Base.:*(p::Adjoint{Complex{T},<:AbstractComplexFTPlan{T}}, fHat::AbstractVector{Complex{U}}; kargs...) where {T,U}
93116
f = similar(fHat, Complex{T}, size_out(p))
94117
mul!(f, p, fHat; kargs...)
95118
return f
96119
end
97-
function Base.:*(p::Adjoint{Complex{T},<:AnyNFFTPlan{T}}, fHat::AbstractArray{Complex{U},2}; kargs...) where {T,U}
120+
function Base.:*(p::Adjoint{Complex{T},<:AbstractComplexFTPlan{T}}, fHat::AbstractArray{Complex{U},2}; kargs...) where {T,U}
98121
f = similar(fHat, Complex{T}, size_out(p))
99122
mul!(f, p, fHat; kargs...)
100123
return f
101124
end
102125

103126

127+
128+
"""
129+
*(p, f) -> fHat
130+
131+
For a **non**-directional `D` dimensional plan `p` this calculates the NFCT/NFST of a `D` dimensional array `f` of size `N`.
132+
`fHat` is a vector of length `M`.
133+
(`M` and `N` are defined in the plan creation)
134+
135+
For a **directional** `D` dimensional plan `p` both `f` and `fHat` are `D`
136+
dimensional arrays, and the dimension specified in the plan creation is
137+
affected.
138+
"""
139+
function Base.:*(p::AbstractRealFTPlan{T}, f::AbstractArray{U,D}; kargs...) where {T,U,D}
140+
fHat = similar(f, T, size_out(p))
141+
mul!(fHat, p, f; kargs...)
142+
return fHat
143+
end
144+
145+
"""
146+
*(p::Transpose{T,AbstractRealFTPlan{T}}, fHat) -> f
147+
148+
For a **non**-directional `D` dimensional plan `p` this calculates the adjoint NFCT/NFST of a length `M` vector `fHat`
149+
`f` is a `D` dimensional array of size `N`.
150+
(`M` and `N` are defined in the plan creation)
151+
152+
For a **directional** `D` dimensional plan `p` both `f` and `fHat` are `D`
153+
dimensional arrays, and the dimension specified in the plan creation is
154+
affected.
155+
"""
156+
157+
function Base.:*(p::Transpose{T,<:AbstractRealFTPlan{T}}, fHat::AbstractArray{U,D}; kargs...) where {T,U,D}
158+
f = similar(fHat, T, size_out(p))
159+
mul!(f, p, fHat; kargs...)
160+
return f
161+
end
162+
163+
# The following two methods are redundant but need to be defined because of a method ambiguity with Julia Base
164+
function Base.:*(p::Transpose{T,<:AbstractRealFTPlan{T}}, fHat::AbstractVector{U}; kargs...) where {T,U}
165+
f = similar(fHat, T, size_out(p))
166+
mul!(f, p, fHat; kargs...)
167+
return f
168+
end
169+
function Base.:*(p::Transpose{T,<:AbstractRealFTPlan{T}}, fHat::AbstractArray{U,2}; kargs...) where {T,U}
170+
f = similar(fHat, T, size_out(p))
171+
mul!(f, p, fHat; kargs...)
172+
return f
173+
end

0 commit comments

Comments
 (0)