Skip to content

Commit

Permalink
v1.0.0: Add RCpair copy! for complex. Rename region->dims. Remove…
Browse files Browse the repository at this point in the history
… deprecation. (#17)

* add RCpair copy! for complex

* version bump

* Update CI.yml

* remove deprecated func

* `region` -> `dims`

* breaking change version bump

* fix PR coverage

* fixes

* suggestions
  • Loading branch information
IanButterworth authored Apr 29, 2024
1 parent 4245504 commit d97bd79
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 25 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ jobs:
fail-fast: false
matrix:
version:
- '1.1'
# - 'nightly'
- '1.6'
- '1'
os:
- ubuntu-latest
- windows-latest
- macOS-latest
arch:
- x64
steps:
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

Manifest.toml
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "RFFT"
uuid = "3bd9afcd-55df-531a-9b34-dc642dce7b95"
authors = ["Tim Holy <[email protected]>"]
version = "0.1.0"
version = "1.0.0"

[deps]
FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341"
Expand Down
1 change: 0 additions & 1 deletion REQUIRE

This file was deleted.

35 changes: 17 additions & 18 deletions src/RFFT.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,66 +9,65 @@ import Base: real, complex, copy, copy!
mutable struct RCpair{T<:AbstractFloat,N,RType<:AbstractArray{T,N},CType<:AbstractArray{Complex{T},N}}
R::RType
C::CType
region::Vector{Int}
dims::Vector{Int}
end

function RCpair{T}(::UndefInitializer, realsize::Dims{N}, region=1:length(realsize)) where {T<:AbstractFloat,N}
function RCpair{T}(::UndefInitializer, realsize::Dims{N}, dims=1:length(realsize)) where {T<:AbstractFloat,N}
sz = [realsize...]
firstdim = region[1]
firstdim = dims[1]
sz[firstdim] = realsize[firstdim]>>1 + 1
sz2 = copy(sz)
sz2[firstdim] *= 2
R = Array{T,N}(undef, (sz2...,)::Dims{N})
C = unsafe_wrap(Array, convert(Ptr{Complex{T}}, pointer(R)), (sz...,)::Dims{N}) # work around performance problems of reinterpretarray
RCpair(view(R, map(n->1:n, realsize)...), C, [region...])
RCpair(view(R, map(n->1:n, realsize)...), C, [dims...])
end

RCpair(A::Array{T}, region=1:ndims(A)) where {T<:AbstractFloat} = copy!(RCpair{T}(undef, size(A), region), A)
RCpair(A::Array{T}, dims=1:ndims(A)) where {T<:AbstractFloat} = copy!(RCpair{T}(undef, size(A), dims), A)

real(RC::RCpair) = RC.R
complex(RC::RCpair) = RC.C

copy!(RC::RCpair, A::AbstractArray{T}) where {T<:Real} = (copy!(RC.R, A); RC)
copy!(RC::RCpair, A::AbstractArray{T}) where {T<:Complex} = (copy!(RC.C, A); RC)
function copy(RC::RCpair{T,N}) where {T,N}
C = copy(RC.C)
R = reshape(reinterpret(T, C), size(parent(RC.R)))
RCpair(view(R, RC.R.indices...), C, copy(RC.region))
RCpair(view(R, RC.R.indices...), C, copy(RC.dims))
end

# New API
rplan_fwd(R, C, region, flags, tlim) =
FFTW.rFFTWPlan{eltype(R),FFTW.FORWARD,true,ndims(R)}(R, C, region, flags, tlim)
rplan_inv(R, C, region, flags, tlim) =
FFTW.rFFTWPlan{eltype(R),FFTW.BACKWARD,true,ndims(R)}(R, C, region, flags, tlim)
rplan_fwd(R, C, dims, flags, tlim) =
FFTW.rFFTWPlan{eltype(R),FFTW.FORWARD,true,ndims(R)}(R, C, dims, flags, tlim)
rplan_inv(R, C, dims, flags, tlim) =
FFTW.rFFTWPlan{eltype(R),FFTW.BACKWARD,true,ndims(R)}(R, C, dims, flags, tlim)
function plan_rfft!(RC::RCpair{T}; flags::Integer = FFTW.ESTIMATE, timelimit::Real = FFTW.NO_TIMELIMIT) where T
p = rplan_fwd(RC.R, RC.C, RC.region, flags, timelimit)
p = rplan_fwd(RC.R, RC.C, RC.dims, flags, timelimit)
return Z::RCpair -> begin
FFTW.assert_applicable(p, Z.R, Z.C)
FFTW.unsafe_execute!(p, Z.R, Z.C)
return Z
end
end
function plan_irfft!(RC::RCpair{T}; flags::Integer = FFTW.ESTIMATE, timelimit::Real = FFTW.NO_TIMELIMIT) where T
p = rplan_inv(RC.C, RC.R, RC.region, flags, timelimit)
p = rplan_inv(RC.C, RC.R, RC.dims, flags, timelimit)
return Z::RCpair -> begin
FFTW.assert_applicable(p, Z.C, Z.R)
FFTW.unsafe_execute!(p, Z.C, Z.R)
rmul!(Z.R, 1 / prod(size(Z.R)[Z.region]))
rmul!(Z.R, 1 / prod(size(Z.R)[Z.dims]))
return Z
end
end
function rfft!(RC::RCpair{T}) where T
p = rplan_fwd(RC.R, RC.C, RC.region, FFTW.ESTIMATE, FFTW.NO_TIMELIMIT)
p = rplan_fwd(RC.R, RC.C, RC.dims, FFTW.ESTIMATE, FFTW.NO_TIMELIMIT)
FFTW.unsafe_execute!(p, RC.R, RC.C)
return RC
end
function irfft!(RC::RCpair{T}) where T
p = rplan_inv(RC.C, RC.R, RC.region, FFTW.ESTIMATE, FFTW.NO_TIMELIMIT)
p = rplan_inv(RC.C, RC.R, RC.dims, FFTW.ESTIMATE, FFTW.NO_TIMELIMIT)
FFTW.unsafe_execute!(p, RC.C, RC.R)
rmul!(RC.R, 1 / prod(size(RC.R)[RC.region]))
rmul!(RC.R, 1 / prod(size(RC.R)[RC.dims]))
return RC
end

@deprecate RCpair(realtype::Type{T}, realsize, region=1:length(realsize)) where T<:AbstractFloat RCpair{T}(undef, realsize, region)

end
8 changes: 5 additions & 3 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import RFFT
using Test, FFTW, LinearAlgebra

@testset begin
for region in (1:2, 1, 2)
@testset "RFFT.jl" begin
for dims in (1:2, 1, 2)
for sz in ((5,6), (6,5))
pair = RFFT.RCpair{Float64}(undef, sz, region)
pair = RFFT.RCpair{Float64}(undef, sz, dims)
r = @inferred(real(pair))
c = @inferred(complex(pair))
b = rand(eltype(r), size(r))
pair = RFFT.RCpair(b, dims)
copyto!(r, b)
copy!(pair, c) # for coverage
RFFT.rfft!(pair)
RFFT.irfft!(pair)
@test r b
Expand Down

0 comments on commit d97bd79

Please sign in to comment.