how to determine the wavelengths of an fft of a non-dimensional sequence
3 views (last 30 days)
Show older comments
Andreas Baas
on 10 May 2025
Edited: David Goodmanson
on 11 May 2025
I have a simple sequence of values (in my case from a spatial transect). I can take the FFT to look for dominant 'wavelengths' in this sequence.
How can I convert the 'frequency' axis of the fft into values of 'wavelength' or scale? The data is not a time-series where I define a sampling frequency or an associated speed or anything like this, it's just a sequence of values at integer spacing without any physical dimensions attached.
Example code, with a sequence of 48 values:
data = [0.35, 1.06, 1.1, 0.82, 1.6, 0.66, -1.81, -2.57, -1.62, -0.39,...
1.02, 0.99, -0.21, -0.75, -0.43, -0.25, -0.09, 0.45, 1.82, 1.64,...
0.13, -1.39, -0.67, 0.58, 0.51, 0.39, 0.49, 0.28, -0.6, -1.11,...
-0.56, -0.7, -0.28, 0.36, 0.62, 0.71, 0.7, -0.37, -1.3, -0.73,...
-0.08, -0.14, 0.46, 1.09, 1.28, 0.73, -0.28, -0.81];
F = fft(data); % take the FFT of data
P2=abs(F); % take only the real part (amplitude)
P1=P2(1:25); % take only the one-sided part
bar(P1); % plot as bar chart
produces this:

I want to know: how can I interpret/convert the x-axis into values of 'length' scale?
E.g. what length scale does the peak at x=12 represent?
2 Comments
Matt J
on 10 May 2025
it's just a sequence of values at integer spacing without any physical dimensions attached.
If the input data domain has no units, how can it gain units after the FFT transformation?
Accepted Answer
William Rose
on 10 May 2025
Edited: William Rose
on 10 May 2025
When the interval between samples (which could be an interval of time or space or something else) is not specified, then the frequency values for the discrete Fourier transform are often expressed in radians per sample:
or cycles per sample:
.


N=20; x=rand(1,N); X=fft(x);
w=2*pi*(0:N-1)/N; % frequency vector (radians/sample)
f=(0:N-1)/N; % frequency vector (cycles/sample)
subplot(211); plot(w,abs(X),'-r.')
grid on; ylabel('|X|'); xlabel('Freq. (radians/sample)')
title('|X| vs. frequency in radians/sample')
xlim([0,2*pi]); xticks(pi*(0:.5:2));
xticklabels({'0','\pi/2','\pi','3\pi/2','2\pi'})
subplot(212); plot(f,abs(X),'-r.')
grid on; ylabel('|X|'); xlabel('Freq. (cycles/sample)')
title('|X| vs. frequency in cycles/sample')
2 Comments
William Rose
on 10 May 2025
You can define the dominant frequency as the frequency where power is maximal. The dominant wavelength is the reciprocal of the dominant frequency. The units for the dominant wavelength are samples, if you don't specify the sampling interval.
Using your data:
data = [0.35, 1.06, 1.1, 0.82, 1.6, 0.66, -1.81, -2.57, -1.62, -0.39,...
1.02, 0.99, -0.21, -0.75, -0.43, -0.25, -0.09, 0.45, 1.82, 1.64,...
0.13, -1.39, -0.67, 0.58, 0.51, 0.39, 0.49, 0.28, -0.6, -1.11,...
-0.56, -0.7, -0.28, 0.36, 0.62, 0.71, 0.7, -0.37, -1.3, -0.73,...
-0.08, -0.14, 0.46, 1.09, 1.28, 0.73, -0.28, -0.81];
N=length(data);
F = fft(data); % take the FFT of data
f=(0:N-1)/N; % frequency vector (cycles/s)
[maxabsF,idx]=max(abs(F(1:N/2))); % find max value of F in the lower half of the spectrum
fmax=f(idx);
fprintf('Dominant frequency=%.3f cycles/sample.\n',fmax)
fprintf('Dominant wavelength=%.2f samples.\n',1/fmax)
plot(f(1:N/2),abs(F(1:N/2)),'-b.',fmax,maxabsF,'ro');
grid on; xlabel('Frequency (cycles/sample)'); ylabel('|F|')
I plot the amplitude spectrum up to the Nyquist frequency. The other half is just the mirror image.
William Rose
on 10 May 2025
Edited: William Rose
on 10 May 2025
[edit: posted too soon]
You can compute and plot the best-fit sinusoid (corresponding the dominant frequency) along with the original data, to see how good it looks.
data = [0.35, 1.06, 1.1, 0.82, 1.6, 0.66, -1.81, -2.57, -1.62, -0.39,...
1.02, 0.99, -0.21, -0.75, -0.43, -0.25, -0.09, 0.45, 1.82, 1.64,...
0.13, -1.39, -0.67, 0.58, 0.51, 0.39, 0.49, 0.28, -0.6, -1.11,...
-0.56, -0.7, -0.28, 0.36, 0.62, 0.71, 0.7, -0.37, -1.3, -0.73,...
-0.08, -0.14, 0.46, 1.09, 1.28, 0.73, -0.28, -0.81];
data=data-mean(data); % subtract mean value
N=length(data);
X = fft(data); % take the FFT of data
f=(0:N-1)/N; % frequency vector (cycles/s)
[~,idx]=max(abs(X(1:N/2))); % find max value of X in the lower half of the spectrum
fmax=f(idx);
Xmax=X(idx);
bestFitSinusoid=...
(Xmax*exp(1i*2*pi*fmax*(0:N-1))+conj(Xmax)*exp(-1i*2*pi*fmax*(0:N-1)))/N;
fprintf('Dominant frequency=%.3f cycles/sample.\n',fmax)
fprintf('Dominant wavelength=%.2f samples.\n',1/fmax)
figure
subplot(211)
plot(0:N-1,data,'-kx',0:N-1,bestFitSinusoid,'-r');
grid on; xlabel('Sample Number'); ylabel('x(n)')
legend('data','best fit sinusoid','Location','southeast')
subplot(212)
plot(f(1:N/2),abs(X(1:N/2)),'-b.',fmax,abs(Xmax),'ro');
grid on; xlabel('Frequency (cycles/sample)'); ylabel('|X(f)|')
More Answers (2)
Matt J
on 10 May 2025
Edited: Matt J
on 10 May 2025
Perhaps as follows?
%Example
N=100;
t=linspace(0,2*pi,N+1); t(end)=[];
x1=sin(t) ; %Wavelength N=100
x2=sin(2*t) ; %Wavelength N/2 =50
data=3*x1+2*x2; %data set with 2 harmonics
figure; plot(1:N,x1,1:N,x2); legend 'Wavelength=100' 'Wavelength=50'
F=2*abs(fft(data))/N;
F(end/2+1:end)=0;
w=N./(0:N-1);
figure; stem(w,F); axis padded
xlabel Wavelength; ylabel Amplitude
xlim([0,105]);
0 Comments
David Goodmanson
on 10 May 2025
Edited: David Goodmanson
on 11 May 2025
Hi Andreas,
For a fourier transform, time and frequency, or length and wave number, or [before-fourier-transform] independent variable and [after-fourier-transform] independent variable, have an inverse realationship. So if you give the 1:48 variable units of 'pongs', then the post-fft independent variable has units of 'inverse pongs'. More common might be 'arbitrary units' and 'inverse arbitrary units'. The reason is that a fourier transform is the integral
g(b) = Integral f(a) exp(2pi i a b) da
and for the argument of the exponential to be dimensionless, a and b have inverse units.
The signal can always be checked regardless of what the units might be. The output array an fft (looking at its numerical index) represents the number of oscillations across the entire input window (except that index 1 represents 'frequency' 0 so everything is offset by 1). You have mentioned already the 6 oscillations across the input window. The histogram peaks out at 7 (meaning 6) as you would expect.
The peak at 11 and 12 (actually 10 and 11) implies something is going on with aboout 10.5 oscillations across the window. Easier for the fft to see than by eye.
0 Comments
See Also
Categories
Find more on Transforms in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!