ELAI S.r.l.

More points, the same data: what zero-padding cannot solve

More points, the same data: what zero-padding cannot solve A worked example explains assumptions and limits.

More points, the same data: what zero-padding cannot solve

A denser plot contains no new measurements

A sensor records vibrations for a tenth of a second. A broad peak hides whether two nearby oscillations exist. Adding zeros before the transform gives a smooth, dense plot. Does that actually improve separation? The question concerns observed information, not appearance. We compare padding and longer acquisition using synthetic 100 and 103 hertz tones.

First distinguish three quantities

Sampling at f_s=1000 Hz means one thousand samples per second; N=100 gives window T=N/f_s=0.1 s. Both sinusoids have unit arbitrary amplitude, zero initial phase and no noise. The discrete Fourier transform, DFT, compares samples with complex oscillations. FFT is an algorithm for computing it, not a source of observations. Sampling rate, duration and plot spacing are different quantities.

x[n] = cos(2π·100·n/f_s) + cos(2π·103·n/f_s), n=0,…,N−1

An N-point DFT samples frequencies k f_s/N, ten hertz apart here, so no point lands at 103 Hz. An off-grid component can appear attenuated and spread across neighbours. The sampled maximum need not be the only frequency present. To understand padding, evaluate the same sum at arbitrary f.

X(f) = Σ_(n=0..N−1) x[n] exp(−j 2π f n/f_s)

Padding changes where we evaluate the sum

Append zeros to M=1600 without changing the first hundred samples. Added terms are zero, so X(f) remains the same observed-signal function. Its sample grid becomes k f_s/M, 0.625 Hz apart. We did not observe 1.5 more seconds of vibration; we evaluated the original hundred samples at more frequencies, whatever the software calls “FFT resolution”.

The script checks that for M=16N every sixteenth padded DFT value matches the original within declared numerical tolerance. It is a denser sample of the same spectrum. Padding can help locate a resolvable peak and reduce grid error, but adds no independent equations about the unknown signal. Useful interpolation is not new information.

The observation window controls lobe width

An isolated complex exponential at f_0 under a rectangular N-sample window yields a geometric sum of magnitude |sin(πNδ/f_s)/sin(πδ/f_s)|, δ=f−f_0, with limit N at zero. First neighbouring zeros are ±f_s/N; null-to-null main-lobe width is 2f_s/N. This depends on the window, not plot length M. A real sinusoid also has a negative-frequency component.

At T=0.1 s the first zeros lie ten hertz from centre, while tones are three hertz apart. Larger M does not narrow lobes. Acquiring N=1000 at the same rate observes a second and brings first zeros to one hertz. That changes available data. The plot compares padded short and long records, normalising by observed sample count rather than M to avoid artificial amplitude reduction.

NMT (s)Spacing (Hz)
1001000.110
10016000.10.625
10001600010.0625
Both padded curves use the same tones but different observation durations. Look at separation, not point density. Synthetic signals.
Both padded curves use the same tones but different observation durations. Look at separation, not point density. Synthetic signals.

What this comparison does not prove

Lobe width is not a universal barrier for every estimator: parametric methods with strong assumptions can estimate closer frequencies, with noise, model order and identifiability becoming decisive. We compare deterministic DFTs, not super-resolution. Other windows trade main-lobe width against sidelobes. Separate peaks alone do not certify two faults or physical sources.

Code uses NumPy 2.5.3 and saves spectra and versions without device measurements. Longer FFTs consume computation and memory; longer observation adds acquisition latency, distinct from compute latency. First choose allowable observation time and the detail to distinguish. Zeros make existing observations easier to read; they do not extend the time spent observing.

SciPy 1.18.0 — Spectral analysis and zero-padding.

import numpy as np
import json,sys
from pathlib import Path
fs=1000.;runs=[]
for n in [100,1000]:
 t=np.arange(n)/fs;x=np.cos(2*np.pi*100*t)+np.cos(2*np.pi*103*t)
 small=np.fft.rfft(x);m=16*n;large=np.fft.rfft(x,n=m)
 assert np.allclose(large[::16],small,rtol=1e-12,atol=1e-10)
 f=np.fft.rfftfreq(m,1/fs);sel=(f>=80)&(f<=125)
 runs.append(dict(n=n,padded=m,duration=n/fs,spacing=fs/n,paddedSpacing=fs/m,frequency=f[sel].tolist(),amplitude=(2*np.abs(large[sel])/n).tolist()))
r=dict(python=sys.version.split()[0],numpy=np.__version__,seed=None,scope='Synthetic two-tone signals, not sensor or hardware measurements',fsHz=fs,tonesHz=[100,103],runs=runs)
Path(__file__).with_name('results.json').write_text(json.dumps(r,indent=2),encoding='utf8')

Code, data, and instructions · JSON. Educational calculations executed with Python 3.14.0; figures with Matplotlib 3.11.2. AI-assisted analysis, without claiming peer review or human review. Original illustrative ImageGen cover: it does not document EL-AI people, premises, or installations. Sources accessed 25 October 2026.