Usage

All types and functions of the SFFT library are defined in the header sfft.h. Include it at the beginning of your program.

Computing Sparse DFTs

Creating Plans

SFFT executions consist of two seperate steps: planning and execution. The planning phase is only executed once for specific input parameters. After that, many Sparse DFTs with these input parameters can be computed (on different input vectors). This concept is similar to FFTW’s concept of plans.

You can create a plan with a call to sfft_plan:

sfft_plan* sfft_make_plan(int n, int k, sfft_version version,
                          int fftw_optimization);

The call returns a pointer to a struct of type sfft_plan, which has to be manually freed with sfft_free_plan. Parameters of sfft_make_plan are:

n
The size of the input vector.
k
The number of frequencies in the signal, i.e. the signal’s sparsity.
version
The SFFT algorithm version to use. Either SFFT_VERSION_1, SFFT_VERSION_2, or SFFT_VERSION_3.
fftw_optimization
FFTW optimization level. Usually one of FFTW_MEASURE and FFTW_ESTIMATE. Since experiments showed that there is little benefit in using the more expensive FFTW_MEASURE, the best choice is typically FFTW_ESTIMATE.

Creating Input Vectors

The storage for SFFT input vectors has to allocated using sfft_malloc:

void* sfft_malloc(size_t s);

The reason for this is that the implementation requires a specific memory alignment on the input vectors. You can use sfft_malloc as a drop-in replacement for malloc.

Input vectors should be of type complex_t, which is a typedef to the C standard library’s type double complex.

Storage allocated with sfft_malloc must be freed with this function:

void sfft_free(void*);

Creating the Output Datastructure

The output of the SFFT is stored in an associative array that maps frequency coordinates to coefficients. The array should be of type sfft_output, which is a typedef to an std::unordered_map. Before executing the SFFT plans, you need to create the output datastructure. A pointer to it is passed to the SFFT execution call and the datastructure filled with the result.

Computing a Single Sparse DFT

Once a plan is created, input vectors are created filled with data, and an output object was allocated, the SFFT plans can be executed. The function for this is:

void sfft_exec(sfft_plan* plan, complex_t* in, sfft_output* out);

Parameters should be self-explanatory. After execution of this function, the output of the DFT is stored in *out.

Computing Multiple Sparse DFTs

If you want to run multiple SFFT calls on different inputs (but with the same input sizes), you can use sfft_exec_many to run the calls in parallel:

void sfft_exec_many(sfft_plan* plan,
                    int num, complex_t** in, sfft_output* out);

The function is very similar to sfft_exec, but you can pass it put num input-vectors and num output-objects. The SFFT library used OpenMP for parallelization; thus, you can use either the environment variable OMP_NUM_THREADS or OpenMP library functions to adjust the number of threads. Be careful: do not use different thread number configuration for the call to sfft_make_plan and sfft_exec_many. Otherwise your program will crash!

SFFT Versions

Currently, three different SFFT versions are implemented: SFFT v1, v2, and v3.

SFFT v3 is the algorithm of choice when your input signals are exactly-sparse; that is, there is no additional noise in the signals. SFFT v3 will not work with noisy signals.

SFFT v1 and v2 can also be applied to noisy signals, but they only work with certain input parameter combinations. Valid input parameters combinations:

Signal Size Sparsity
8192 50
16384 50
32768 50
65536 50
131072 50
262144 50
524288 50
1048576 50
2097152 50
4194304 50
8388608 50
16777216 50
4194304 50
4194304 100
4194304 200
4194304 500
4194304 1000
4194304 2000
4194304 2500
4194304 4000