Skip to content

Commit ec9c29a

Browse files
committed
adds NDCT, fixes small bug in wrapper #85
1 parent 41fa0fd commit ec9c29a

File tree

3 files changed

+93
-5
lines changed

3 files changed

+93
-5
lines changed

AbstractNFFTs/src/AbstractNFFTs.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export AnyNFFTPlan, AbstractNFFTPlan, AbstractNFCTPlan, AbstractNNFFTPlan,
1212
export apodization!, apodization_adjoint!, convolve!, convolve_adjoint!
1313

1414
# derived
15-
export nfft, nfft_adjoint, ndft, ndft_adjoint, nfct, nfct_transposed
15+
export nfft, nfft_adjoint, ndft, ndft_adjoint, nfct, nfct_transposed, ndct, ndct_transposed
1616

1717
# misc
1818
export TimingStats, accuracyParams, reltolToParams, paramsToReltol,

Wrappers/NFFT3.jl

+17-4
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@ function NFFT3Plan(x::Matrix{T}, N::NTuple{D,Int};
5151
f2 = UInt32(fftflags | NFFT3.FFTW_DESTROY_INPUT)
5252

5353
n = ntuple(d -> (ceil(Int,σ*N[d])÷2)*2, D) # ensure that n is an even integer
54-
σ = n[1] / N[1]
54+
#σ = n[1] / N[1]
5555

56-
parent = NFFT3.NFFT(Int32.(reverse(N)), size(x,2), Int32.(n), Int32(m), f1, f2)
56+
parent = NFFT3.NFFT(Int32.(reverse(N)), size(x,2), Int32.(reverse(n)), Int32(m), f1, f2)
5757

5858
xx = Float64.(reverse(x, dims=1))
5959
parent.x = D == 1 ? vec(xx) : xx
@@ -99,9 +99,9 @@ function NFCT3Plan(x::Matrix{T}, N::NTuple{D,Int};
9999
f2 = UInt32(fftflags | NFFT3.FFTW_DESTROY_INPUT)
100100

101101
n = ntuple(d -> (ceil(Int,σ*N[d])÷2)*2, D) # ensure that n is an even integer
102-
σ = n[1] / N[1]
102+
#σ = n[1] / N[1]
103103

104-
parent = NFFT3.NFCT(Int32.(reverse(N)), size(x,2), Int32.(n), Int32(m), f1, f2)
104+
parent = NFFT3.NFCT(Int32.(reverse(N)), size(x,2), Int32.(reverse(n)), Int32(m), f1, f2)
105105

106106
xx = Float64.(reverse(x, dims=1))
107107
parent.x = D == 1 ? vec(xx) : xx
@@ -135,6 +135,19 @@ function LinearAlgebra.mul!(fHat::StridedArray, p::NFFT3Plan{D}, f::AbstractArra
135135
return fHat
136136
end
137137

138+
function LinearAlgebra.mul!(f::StridedArray, pl::Adjoint{Complex{T},<:NFFT3Plan{T}}, fHat::AbstractArray;
139+
verbose=false, timing::Union{Nothing,TimingStats} = nothing) where T
140+
#consistencyCheck(p, f, fHat)
141+
p = pl.parent
142+
143+
p.parent.f = vec(fHat)
144+
p.parent.fhat = vec(f)
145+
tadjoint = fApprox = NFFT3.nfft_adjoint(p.parent)
146+
f[:] .= p.parent.fhat
147+
148+
return f
149+
end
150+
138151
function LinearAlgebra.mul!(fHat::StridedArray, p::NFCT3Plan{D}, f::AbstractArray;
139152
verbose=false, timing::Union{Nothing,TimingStats} = nothing) where {D}
140153
#consistencyCheck(p, f, fHat)

src/direct.jl

+75
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,15 @@ end
88
AbstractNFFTs.size_in(p::NDFTPlan) = p.N
99
AbstractNFFTs.size_out(p::NDFTPlan) = (p.M,)
1010

11+
mutable struct NDCTPlan{T,D} <: AbstractNFCTPlan{T,D,1}
12+
N::NTuple{D,Int64}
13+
M::Int64
14+
x::Matrix{T}
15+
end
16+
17+
AbstractNFFTs.size_in(p::NDCTPlan) = p.N
18+
AbstractNFFTs.size_out(p::NDCTPlan) = (p.M,)
19+
1120
mutable struct NNDFTPlan{T} <: AbstractNNFFTPlan{T,1,1}
1221
N::Int64
1322
M::Int64
@@ -31,6 +40,17 @@ function NDFTPlan(x::Matrix{T}, N::NTuple{D,Int}; kwargs...) where {T,D}
3140
return NDFTPlan{T,D}(N, M, x)
3241
end
3342

43+
function NDCTPlan(x::Matrix{T}, N::NTuple{D,Int}; kwargs...) where {T,D}
44+
45+
if D != size(x,1)
46+
throw(ArgumentError("Nodes x have dimension $(size(x,1)) != $D"))
47+
end
48+
49+
M = size(x, 2)
50+
51+
return NDCTPlan{T,D}(N, M, x)
52+
end
53+
3454
function NNDFTPlan(x::Matrix{T}, y::Matrix{T}; kwargs...) where {T}
3555

3656
M = size(x, 2)
@@ -47,6 +67,13 @@ ndft(x::AbstractArray, f::AbstractArray; kargs...) =
4767
ndft_adjoint(x, N, fHat::AbstractVector; kargs...) =
4868
adjoint(NDFTPlan(x, N; kargs...)) * fHat
4969

70+
ndct(x::AbstractArray, f::AbstractArray; kargs...) =
71+
NDCTPlan(x, size(f); kargs...) * f
72+
73+
ndct_transposed(x, N, fHat::AbstractVector; kargs...) =
74+
transpose(NDCTPlan(x, N; kargs...)) * fHat
75+
76+
5077

5178

5279
function LinearAlgebra.mul!(g::AbstractArray{Tg}, plan::NDFTPlan{Tp,D}, f::AbstractArray{T,D}) where {D,Tp,T,Tg}
@@ -99,7 +126,55 @@ function LinearAlgebra.mul!(g::AbstractArray{Tg,D}, pl::Adjoint{Complex{Tp},<:ND
99126
return g
100127
end
101128

129+
function LinearAlgebra.mul!(g::AbstractArray{Tg}, plan::NDCTPlan{Tp,D}, f::AbstractArray{T,D}) where {D,Tp,T,Tg}
130+
131+
plan.N == size(f) ||
132+
throw(DimensionMismatch("Data f is not consistent with NDFTPlan"))
133+
plan.M == length(g) ||
134+
throw(DimensionMismatch("Output g is inconsistent with NDFTPlan"))
135+
136+
g .= zero(Tg)
137+
138+
for l=1:prod(plan.N)
139+
idx = CartesianIndices(plan.N)[l]
140+
141+
for k=1:plan.M
142+
arg = one(T)
143+
for d=1:D
144+
arg *= cos( 2 * pi * plan.x[d,k] * ( idx[d] - 1 ) )
145+
end
146+
g[k] += f[l] * arg
147+
end
148+
end
149+
150+
return g
151+
end
152+
153+
154+
function LinearAlgebra.mul!(g::AbstractArray{Tg,D}, pl::Transpose{Tp,<:NDCTPlan{Tp,D}}, fHat::AbstractVector{T}) where {D,Tp,T,Tg}
155+
p = pl.parent
102156

157+
p.M == length(fHat) ||
158+
throw(DimensionMismatch("Data f inconsistent with NDFTPlan"))
159+
p.N == size(g) ||
160+
throw(DimensionMismatch("Output g inconsistent with NDFTPlan"))
161+
162+
g .= zero(Tg)
163+
164+
for l=1:prod(p.N)
165+
idx = CartesianIndices(p.N)[l]
166+
167+
for k=1:p.M
168+
arg = one(T)
169+
for d=1:D
170+
arg *= cos( 2 * pi * plan.x[d,k] * ( idx[d] - 1 ) )
171+
end
172+
g[l] += fHat[k] * arg
173+
end
174+
end
175+
176+
return g
177+
end
103178

104179

105180
function LinearAlgebra.mul!(g::AbstractArray{Tg}, plan::NNDFTPlan{Tp}, f::AbstractArray{T}) where {Tp,T,Tg}

0 commit comments

Comments
 (0)