From 3890c0e8396ba88f5e9adeb42924f0bd5950df25 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Thu, 18 Aug 2022 10:16:26 -0400 Subject: [PATCH 1/3] Add plan_inv for ScaledPlan's --- src/definitions.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/definitions.jl b/src/definitions.jl index ac9a4ba..4532650 100644 --- a/src/definitions.jl +++ b/src/definitions.jl @@ -279,6 +279,8 @@ plan_ifft(x::AbstractArray, region; kws...) = plan_ifft!(x::AbstractArray, region; kws...) = ScaledPlan(plan_bfft!(x, region; kws...), normalization(x, region)) +plan_inv(p::ScaledPlan) = ScaledPlan(plan_inv(p.p), inv(p.scale)) +# Don't cache inverse of scaled plan (only inverse of inner plan) inv(p::ScaledPlan) = ScaledPlan(inv(p.p), inv(p.scale)) LinearAlgebra.mul!(y::AbstractArray, p::ScaledPlan, x::AbstractArray) = From 57abba2f67c3fe6d553d1c23f2919116628dda5f Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Thu, 18 Aug 2022 10:38:14 -0400 Subject: [PATCH 2/3] Add tests of plan_inv behaviour --- test/runtests.jl | 52 +++++++++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index 623d625..4d402c5 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -56,11 +56,15 @@ end dims = ndims(x) y = AbstractFFTs.fft(x, dims) @test y ≈ fftw_fft - P = plan_fft(x, dims) - @test eltype(P) === ComplexF64 - @test P * x ≈ fftw_fft - @test P \ (P * x) ≈ x - @test fftdims(P) == dims + # test plan_fft and also inv and plan_inv of plan_ifft, which should all give + # functionally identical plans + for P in [plan_fft(x, dims), inv(plan_ifft(x, dims)), + AbstractFFTs.plan_inv(plan_ifft(x, dims))] + @test eltype(P) === ComplexF64 + @test P * x ≈ fftw_fft + @test P \ (P * x) ≈ x + @test fftdims(P) == dims + end fftw_bfft = complex.(size(x, dims) .* x) @test AbstractFFTs.bfft(y, dims) ≈ fftw_bfft @@ -71,10 +75,14 @@ end fftw_ifft = complex.(x) @test AbstractFFTs.ifft(y, dims) ≈ fftw_ifft - P = plan_ifft(x, dims) - @test P * y ≈ fftw_ifft - @test P \ (P * y) ≈ y - @test fftdims(P) == dims + # test plan_ifft and also inv and plan_inv of plan_fft, which should all give + # functionally identical plans + for P in [plan_ifft(x, dims), inv(plan_fft(x, dims)), + AbstractFFTs.plan_inv(plan_fft(x, dims))] + @test P * y ≈ fftw_ifft + @test P \ (P * y) ≈ y + @test fftdims(P) == dims + end # real FFT fftw_rfft = fftw_fft[ @@ -83,11 +91,15 @@ end ] ry = AbstractFFTs.rfft(x, dims) @test ry ≈ fftw_rfft - P = plan_rfft(x, dims) - @test eltype(P) === Int - @test P * x ≈ fftw_rfft - @test P \ (P * x) ≈ x - @test fftdims(P) == dims + # test plan_rfft and also inv and plan_inv of plan_irfft, which should all give + # functionally identical plans + for P in [plan_rfft(x, dims), inv(plan_irfft(ry, size(x, dims), dims)), + AbstractFFTs.plan_inv(plan_irfft(ry, size(x, dims), dims))] + @test eltype(P) <: Real + @test P * x ≈ fftw_rfft + @test P \ (P * x) ≈ x + @test fftdims(P) == dims + end fftw_brfft = complex.(size(x, dims) .* x) @test AbstractFFTs.brfft(ry, size(x, dims), dims) ≈ fftw_brfft @@ -98,10 +110,14 @@ end fftw_irfft = complex.(x) @test AbstractFFTs.irfft(ry, size(x, dims), dims) ≈ fftw_irfft - P = plan_irfft(ry, size(x, dims), dims) - @test P * ry ≈ fftw_irfft - @test P \ (P * ry) ≈ ry - @test fftdims(P) == dims + # test plan_rfft and also inv and plan_inv of plan_irfft, which should all give + # functionally identical plans + for P in [plan_irfft(ry, size(x, dims), dims), inv(plan_rfft(x, dims)), + AbstractFFTs.plan_inv(plan_rfft(x, dims))] + @test P * ry ≈ fftw_irfft + @test P \ (P * ry) ≈ ry + @test fftdims(P) == dims + end end end From a93d5a4a65da97ea7855d0f27fef8f091478ffe2 Mon Sep 17 00:00:00 2001 From: Gaurav Arya Date: Tue, 16 Aug 2022 19:03:24 -0400 Subject: [PATCH 3/3] Get type T more correct for real FFT test plans --- test/testplans.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/testplans.jl b/test/testplans.jl index 7abecfe..31609a9 100644 --- a/test/testplans.jl +++ b/test/testplans.jl @@ -92,11 +92,11 @@ Base.:*(p::InverseTestPlan, x::AbstractArray) = mul!(similar(x, complex(float(el mutable struct TestRPlan{T,N} <: Plan{T} region sz::NTuple{N,Int} - pinv::Plan{T} + pinv::Plan{Complex{T}} TestRPlan{T}(region, sz::NTuple{N,Int}) where {T,N} = new{T,N}(region, sz) end -mutable struct InverseTestRPlan{T,N} <: Plan{T} +mutable struct InverseTestRPlan{T,N} <: Plan{Complex{T}} d::Int region sz::NTuple{N,Int} @@ -107,10 +107,10 @@ mutable struct InverseTestRPlan{T,N} <: Plan{T} end end -function AbstractFFTs.plan_rfft(x::AbstractArray{T}, region; kwargs...) where {T} +function AbstractFFTs.plan_rfft(x::AbstractArray{T}, region; kwargs...) where {T<:Real} return TestRPlan{T}(region, size(x)) end -function AbstractFFTs.plan_brfft(x::AbstractArray{T}, d, region; kwargs...) where {T} +function AbstractFFTs.plan_brfft(x::AbstractArray{Complex{T}}, d, region; kwargs...) where {T} return InverseTestRPlan{T}(d, region, size(x)) end function AbstractFFTs.plan_inv(p::TestRPlan{T,N}) where {T,N}