# How to Configure and Use FFT Functions with FFTW and MKL Backends in Nelson

> Learn to configure and use FFT functions in Nelson with FFTW and MKL backends. Nelson automatically selects the optimal library for high performance.

- Repository: [The Nelson Programming Language/nelson](https://github.com/nelson-lang/nelson)
- Tags: how-to-guide
- Published: 2026-03-08

---

**Nelson provides high-performance Fast Fourier Transform (FFT) operations through the FFTW module, automatically selecting between the open-source FFTW3 library and Intel MKL's FFTW-compatible wrapper at runtime.**

The nelson-lang/nelson repository delivers MATLAB-compatible numerical computing with optimized spectral analysis capabilities. Understanding how to configure and use FFT functions with FFTW and MKL backends ensures you leverage the fastest available library for your platform, whether deploying the GPL-licensed FFTW3 or Intel's proprietary MKL implementation.

## Build-Time Configuration

Nelson's **CMake** build system automatically detects available linear algebra libraries before compilation. In `CMake/FindMKL.cmake`, the configuration searches for Intel MKL installations via the `MKL_DIR` environment variable or standard installation paths, defining `MKL_FOUND` when successful.

The top-level [`CMakeLists.txt`](https://github.com/nelson-lang/nelson/blob/main/CMakeLists.txt) (lines 392-401) implements the selection logic:

```cmake
find_package(MKL)
find_package(OpenBLAS)
find_package(BLAS)
find_package(LAPACK)
…
if(MKL_FOUND)
    set(NELSON_BLAS_LAPACKX_LIBRARIES ${MKL_LIBRARIES})
elseif(OpenBLAS_FOUND)
    …
else()
    …
endif()

```

When `MKL_FOUND` is true, Nelson links against Intel MKL libraries for BLAS/LAPACK operations. However, the FFTW module requires no compile-time linking; it loads libraries dynamically at runtime via the builtin **FFTWwrapper**.

## Runtime Backend Loading

When the FFTW module initializes via `modules/fftw/etc/startup.m`, it executes `FFTWwrapper('load')` to dynamically bind to available libraries. This builtin is implemented in [`modules/fftw/builtin/cpp/FFTWwrapperBuiltin.cpp`](https://github.com/nelson-lang/nelson/blob/main/modules/fftw/builtin/cpp/FFTWwrapperBuiltin.cpp).

### Automatic Backend Detection

The wrapper automatically selects the appropriate backend based on your operating system:

- **Windows with MKL**: If Intel MKL is present, `FFTWwrapper` detects and loads the MKL FFTW-compatible libraries (`fftw.dll` and `fftwf.dll`).
- **Linux/macOS**: The wrapper searches for system-installed FFTW shared libraries (`libfftw3.so` or `libfftw3.dylib`).

The initialization script in `modules/fftw/etc/startup.m` handles this automatically:

```matlab
addgateway(modulepath('fftw', 'builtin'), 'fftw');
if FFTWwrapper('load')
    addpath(modulepath('fftw', 'functions'), '-frozen');
else
    warning('Nelson:fftw:loadingFails', _('library fftw not loaded.'))
    removemodule('fftw');
end

```

### Manual Library Loading

For custom FFTW installations, explicitly load specific library paths using `FFTWwrapper`:

```matlab
% Load a specific library pair (double-precision, single-precision)
status = FFTWwrapper('load', '/opt/fftw/lib/libfftw3.so', '/opt/fftw/lib/libfftw3f.so');

```

This call unloads any current backend and binds to your specified shared libraries, returning a logical status indicating success or failure.

## Using FFT Functions

All user-level FFT routines reside in `modules/fftw/functions` and provide **MATLAB-compatible** interfaces. These functions delegate computations to the loaded backend for optimal performance.

Available functions include:

- `fft` – 1-D Fast Fourier Transform
- `fftn` – N-dimensional FFT
- `fft2` – 2-D FFT (implemented in pure Nelson code calling `fftn`)
- `ifft`, `ifftn`, `ifft2` – Inverse transforms
- `fftshift`, `ifftshift` – Zero-frequency component shifting

### 1-D FFT Example

Compute the frequency spectrum of a sinusoidal signal:

```matlab
% Create a sinusoid sampled at 150 Hz
Fs = 150;
t  = 0:1/Fs:1;                 % 1 s time vector
x  = sin(2*pi*5*t);            % 5 Hz sine wave

% Compute a 1024-point FFT (zero-padding)
X = fft(x, 1024);

% Keep only the positive-frequency half
Xpos = X(1:512);

% Frequency axis for plotting
f = (0:511) * Fs / 1024;
plot(f, abs(Xpos));
title('Magnitude spectrum (FFT)');
xlabel('Frequency (Hz)');
ylabel('|X|');

```

### 2-D FFT Example

Process image data using the 2-D transform:

```matlab
% Load an image (grayscale matrix)
A = imread('cameraman.tif');

% Compute the 2-D FFT and shift the zero-frequency to the centre
F = fftshift(fft2(A));

% Visualise the magnitude (log scale)
imshow(log(1+abs(F)), []);
title('2-D FFT magnitude');

```

The `fft2` implementation in `modules/fftw/functions/fft2.m` internally calls `fftn` to handle the transformation.

### Custom Library Loading Example

Override automatic detection to use a specific FFTW build:

```matlab
% Suppose you compiled FFTW into /opt/fftw/lib
status = FFTWwrapper('load', ...
    '/opt/fftw/lib/libfftw3.so', ...
    '/opt/fftw/lib/libfftw3f.so');

if status
    disp('Custom FFTW library loaded successfully.');
    y = fft([1,2,3,4]);   % Now uses the custom library
else
    error('Failed to load the requested FFTW library.');
end

```

## Summary

- **Build configuration**: CMake detects MKL via `CMake/FindMKL.cmake` and selects libraries in [`CMakeLists.txt`](https://github.com/nelson-lang/nelson/blob/main/CMakeLists.txt), though FFTW requires no compile-time linking.
- **Runtime loading**: `FFTWwrapper('load')` automatically chooses between MKL (Windows) and system FFTW (Linux/macOS), with manual override support via explicit library paths.
- **Function interface**: `fft`, `fftn`, `fft2`, and related functions provide MATLAB-compatible syntax while delegating to the loaded high-performance backend.
- **Performance optimization**: Using MKL on Windows or optimized FFTW builds on Unix systems delivers maximum computational efficiency for spectral analysis.

## Frequently Asked Questions

### How does Nelson choose between FFTW and MKL backends?

On Windows, Nelson's `FFTWwrapper` automatically detects and loads Intel MKL's FFTW-compatible libraries (`fftw.dll` and `fftwf.dll`) if available. On Linux and macOS, it searches for standard FFTW3 shared libraries (`libfftw3.so` or `libfftw3.dylib`). This detection occurs at runtime when the FFTW module starts via `modules/fftw/etc/startup.m`.

### Can I use a custom FFTW library instead of the system default?

Yes. Call `FFTWwrapper('load', double_precision_path, single_precision_path)` with explicit paths to your compiled FFTW libraries. This builtin, implemented in [`modules/fftw/builtin/cpp/FFTWwrapperBuiltin.cpp`](https://github.com/nelson-lang/nelson/blob/main/modules/fftw/builtin/cpp/FFTWwrapperBuiltin.cpp), unloads any current backend and binds to your specified shared libraries, returning a logical status indicating success or failure.

### Do I need to compile Nelson differently to use MKL for FFT operations?

No. While the CMake build system detects MKL in `CMake/FindMKL.cmake` for BLAS/LAPACK linking in [`CMakeLists.txt`](https://github.com/nelson-lang/nelson/blob/main/CMakeLists.txt), the FFTW module loads libraries dynamically at runtime. Ensure MKL is installed and accessible in your system path on Windows, or set `MKL_DIR` during build, but no specific FFT-related compile flags are required.

### Are the FFT functions in Nelson compatible with MATLAB code?

Yes. Functions like `fft`, `fftn`, `fft2`, `ifft`, `fftshift`, and `ifftshift` located in `modules/fftw/functions` follow MATLAB syntax and behavior exactly. They accept identical parameter signatures including dimension specification and zero-padding, making code porting straightforward while leveraging high-performance FFTW or MKL backends internally.