This is the implementation guide for the Nuttall window. For theoretical background, including mathematical formula, frequency response, and spectral analysis, see the the article on Nuttall window.
All code examples are written in C for maximum performance and portability.
Direct Implementation
The following function computes the Nuttall window value for a given sample index n and total window length N. The Nuttall window is a 4-term cosine window with optimized coefficients for excellent sidelobe suppression.
#include <math.h>
/**
* Compute Nuttall window coefficient for a single sample.
*
* @param n Sample index (0 to N-1)
* @param N Total window length
* @return Window coefficient (0.0 to 1.0)
*/
double nuttall_window_sample(int n, int N) {
if (N <= 1) return 1.0;
if (n < 0 || n >= N) return 0.0;
/* Nuttall window coefficients (4-term) */
const double a0 = 0.355768;
const double a1 = 0.487396;
const double a2 = 0.144232;
const double a3 = 0.012604;
double angle = 2 * M_PI * n / (N - 1);
return a0
- a1 * cos(angle)
+ a2 * cos(2 * angle)
- a3 * cos(3 * angle);
}
Alternative Implementation (Blackman–Nuttall)
A common variant is the Blackman–Nuttall window, which has slightly different coefficients:
/**
* Compute Blackman–Nuttall window coefficient.
*
* @param n Sample index (0 to N-1)
* @param N Total window length
* @return Window coefficient
*/
double blackman_nuttall_window_sample(int n, int N) {
if (N <= 1) return 1.0;
if (n < 0 || n >= N) return 0.0;
/* Blackman–Nuttall window coefficients */
const double a0 = 0.3635819;
const double a1 = 0.4891775;
const double a2 = 0.1365995;
const double a3 = 0.0106411;
double angle = 2 * M_PI * n / (N - 1);
return a0
- a1 * cos(angle)
+ a2 * cos(2 * angle)
- a3 * cos(3 * angle);
}
Alternative Implementation (Minimum 4-Term)
This variant provides the minimum possible sidelobe level for a 4-term cosine window:
/**
* Compute minimum 4-term Nuttall window coefficient.
*
* @param n Sample index (0 to N-1)
* @param N Total window length
* @return Window coefficient
*/
double nuttall_min4_window_sample(int n, int N) {
if (N <= 1) return 1.0;
if (n < 0 || n >= N) return 0.0;
/* Minimum 4-term Nuttall coefficients */
const double a0 = 0.3635819;
const double a1 = 0.4891775;
const double a2 = 0.1365995;
const double a3 = 0.0106411;
double angle = 2 * M_PI * n / (N - 1);
return a0
- a1 * cos(angle)
+ a2 * cos(2 * angle)
- a3 * cos(3 * angle);
}
Full Array Implementation
For better performance when the entire window is needed, the following function fills a pre-allocated array with all coefficients at once.
#include <math.h>
#include <stdlib.h>
/**
* Generate full Nuttall window array.
*
* @param N Length of the window (number of samples)
* @param out Output array of length N (must be pre-allocated)
*/
void nuttall_window_array(int N, double *out) {
if (N <= 0) return;
if (N == 1) {
out[0] = 1.0;
return;
}
const double a0 = 0.355768;
const double a1 = 0.487396;
const double a2 = 0.144232;
const double a3 = 0.012604;
for (int i = 0; i < N; i++) {
double angle = 2 * M_PI * i / (N - 1);
out[i] = a0
- a1 * cos(angle)
+ a2 * cos(2 * angle)
- a3 * cos(3 * angle);
}
}
Full Array Implementation (Blackman–Nuttall)
/**
* Generate full Blackman–Nuttall window array.
*
* @param N Length of the window (number of samples)
* @param out Output array of length N (must be pre-allocated)
*/
void blackman_nuttall_window_array(int N, double *out) {
if (N <= 0) return;
if (N == 1) {
out[0] = 1.0;
return;
}
const double a0 = 0.3635819;
const double a1 = 0.4891775;
const double a2 = 0.1365995;
const double a3 = 0.0106411;
for (int i = 0; i < N; i++) {
double angle = 2 * M_PI * i / (N - 1);
out[i] = a0
- a1 * cos(angle)
+ a2 * cos(2 * angle)
- a3 * cos(3 * angle);
}
}
Usage Example
The following example demonstrates how to apply the Nuttall window to a real signal.
#include <stdio.h>
#include <math.h>
#define N 64
int main() {
double window[N];
double signal[N];
double windowed[N];
/* Generate Nuttall window */
nuttall_window_array(N, window);
/* Generate test signal (sinusoid) */
for (int i = 0; i < N; i++) {
signal[i] = sin(2 * M_PI * i / 9.5);
}
/* Apply window to signal */
for (int i = 0; i < N; i++) {
windowed[i] = signal[i] * window[i];
}
/* Print first 10 samples */
printf("n window signal windowed\n");
for (int i = 0; i < 10; i++) {
printf("%d %.6f %.6f %.6f\n",
i, window[i], signal[i], windowed[i]);
}
return 0;
}
Expected Output (first 5 samples, N=64)
n window signal windowed 0 0.000004 0.000000 0.000000 1 0.000018 0.647387 0.000012 2 0.000147 0.998351 0.000147 3 0.000453 0.907575 0.000411 4 0.001002 0.460073 0.000461
Implementation Notes
- Albert Nuttall: The window is named after Albert H. Nuttall, who published the optimal coefficients for cosine-sum windows.
- 4-term design: The Nuttall window uses 4 cosine terms, providing excellent sidelobe suppression.
- Sidelobe level: Approximately -93 dB (standard) or -98 dB (Blackman–Nuttall) – exceptional performance.
- Main lobe width: Approximately 0.16 normalized frequency – moderately wide.
- Continuous derivatives: The window has continuous first and second derivatives at the boundaries.
- Endpoints: Values at endpoints are very close to zero (not exactly zero).
- Symmetry: The window is perfectly symmetric:
w[n] = w[N-1-n]for all n. - Optimal coefficients: The coefficients are optimized to minimize the peak sidelobe level.
- Edge case N=1: The only coefficient is 1.0.
- Precomputation: For real-time applications, precompute the window once and reuse it for multiple signal blocks.
Alternative: Precomputed Lookup Table
For embedded systems or when speed is critical, precompute the window at compile time:
#define N 64
static const double NUTTALL_WINDOW[N] = {
0.000004, 0.000018, 0.000147, 0.000453, 0.001002, /* ... */
/* Full table would be generated by a script */
};
/* Usage */
for (int i = 0; i < N; i++) {
windowed[i] = signal[i] * NUTTALL_WINDOW[i];
}
Nuttall vs Other 4-Term Windows
The Nuttall family of windows includes several 4-term cosine windows:
Window a0 a1 a2 a3 Sidelobe (dB) Nuttall (standard) 0.355768 0.487396 0.144232 0.012604 -93.3 Blackman–Nuttall 0.363582 0.489178 0.136600 0.010641 -98.2 Minimum 4-term 0.363582 0.489178 0.136600 0.010641 -98.2
Comparison with Cosine Windows
Window Terms Sidelobe (dB) Main lobe Best for Hann 2 -31 ~0.08 General purpose Hamming 2 -41 ~0.08 General purpose Blackman 3 -58 ~0.12 Leakage suppression Blackman–Harris 4 -92 ~0.16 High dynamic range Nuttall 4 -93 ~0.16 High dynamic range Flat Top 5 -80 to -90 ~0.20 Amplitude accuracy
Comparison with Blackman–Harris
Characteristic Blackman–Harris Nuttall
Peak sidelobe -92.0 dB -93.3 dB
Roll-off rate ~6 dB/octave ~18 dB/octave
Main lobe width ~0.16 ~0.16
Coefficients (0.35875, 0.48829, (0.355768, 0.487396,
0.14128, 0.01168) 0.144232, 0.012604)
Best when Fast roll-off needed Minimum peak sidelobe
Practical Applications
Application Why Nuttall? High-dynamic-range spectrum Excellent sidelobe suppression EMI/EMC testing Needs low spectral leakage Precision metrology High measurement accuracy Scientific instrumentation Demands clean spectral estimation Audio analysis Good balance of properties
See also: The Nuttall Window in DSP