[ANN] FFTIndexing.jl

FFTIndexing.jl is a small package I’ve written that provides a few types that you can use to index an array in a manner that exposes the underlying frequency bins from a Fourier transform.

This package accomplishes similar goals to FFTViews.jl, but does so without constructing any view objects. Instead, it provides types, FFTIndex and FFTIndices, similar to CartesianIndex and CartesianIndices in Julia Base, that can be used with any array that defines getindex and/or setindex!.


An index i::FFTIndex{D} type indexes an array A::AbstractArray{T,D} with the assumption that the array has periodic boundary conditions. Suppose A is a Array{Float32,3} which resulted from a multidimensional fast Fourier transform: FFTIndex(0, 0, 0) corresponds to the zero frequency component, located at firstindex(A), and FFTIndex(-1, -1, -1) corresponds to the last index.

The array is assumed to have periodic boundary conditions, and modulo math is used to interpret values in an FFTIndex as valid array indices. This allows for the elimination of bounds checks if this is the only type used to index an array. For example, if size(A) === (3, 3, 7):

julia> A[3, 3, 7] === A[FFTIndex(2, 2, 6)]

julia> A[3, 3, 7] === A[FFTIndex(-1, -1, -1)]

This also works for disparate FFTIndex dimensionalities, as long as the total dimensions indexed is equal to that of the array:

julia> A[3, 3, 7] === A[FFTIndex(2, 2), FFTIndex(6)]

The FFTIndices{D} type represents all of the valid FFTIndex{D} objects for a given array or other object that has a size.

Use case

In my research, I’ve needed to take fast Fourier transforms of datasets (which are Vector{Float32}) of disparate length. Using this package, I can combine FFTIndices with stack to fit all of the data into a contiguous Matrix{Float32} rather than a Vector{Vector{Float32}}:

julia> stack(v -> fft(v)[FFTIndices((256,))] for v in data)

This automatically truncates the high frequency components of longer datasets down to a fixed size so they all fit into the matrix.