Why does fft of non-integer number of cycles sin wave NOT have sidelobes?

As per the title, I have a simple sin wave at a single frequency, and am cutting it off at some time t such that the sin wave is cut off at a non-integer number of cycles. I would have expected that cutting it off at random times would result in a significant number of sidelobes when computing the fft, however this is not the case, typically I am only seeing a single peak at the frequency of the sin wave. In another programme which calculates the fourier transform of the signal I am seeing side lobes. My question is, why am I not seeing side lobes, is the MATLAB fft algorithm doing something clever?
Here is the code I am using:
N=7500;
f0 = 0.25*10^9;
blerg(:,1) = linspace(0,100*10^-9,N+1);
blerg(:,2) = sin(2*pi*f0*blerg(:,1));
input = blerg;
dt = (input(2,1)-input(1,1))
dt = 1.3333e-11
N = length(input);
Fs = 1/dt;
spectLen = isEven(N);
Unrecognized function or variable 'isEven'.
freqAxis = linspace(0,Fs/2,spectLen);
Y = fft(input(:,2))/N;
Ydb = mag2db(abs(Y));
plot(freqAxis/10^6,Ydb(1:spectLen));
xlim([0 1000]);

답변 (2개)

Matt J
Matt J 2025년 5월 15일
편집: Matt J 2025년 5월 15일
We don't know what you're doing since we haven't been shown your code. However, here is an example to show that you won't get perfect peaks in general.
m=5;N=5000;
f0=0.5;
df=f0/m;
dt=1/N/df; %duration of sine wave = m/f0
t=(0:N-1)*dt;
y=sin(2*pi*f0*t);
y(t>m/f0*0.7)=0; %cut off
M=2*N;
fAxis = ((0:M-1)-ceil((M-1)/2))*df*N/M;
plot(t,y)
plot(fAxis,fftshift(abs(fft(y,M)))*dt,'--.'); xlim([-3,+3]*f0)

댓글 수: 5

I have updated my question to include some code which is essentially what I am using.
Matt J
Matt J 2025년 5월 15일
편집: Matt J 2025년 5월 15일
Your code (see the Run output above) throws errors. One thing that might be worth mentioning, though, is that it is not possible for your freqAxis to include f0 unless your signal duration N*dt is equal to an integer multiple of the period 1/f0 of the sine wave.
That means that if you want the fft to see a truncated sine wave, but at the same time to sample the peak location f0, you must manually truncate portions of the input sine wave to zero (as I have). It doesn't appear that you are doing that in your code.
In regards to the code not working it will be due to the isEven function which just changes the length of the frequency axis depending on if the input length is even or odd, this could be replaced with N/2 I think for this.
You are right in that I am not truncating with zero, I am literally just cutting off some portion of the sin wave - I thought that a sin wave that does not end at zero after an integer number of cycles will cause side lobes due to the assumed periodicity of the window over which you take a Fourier Transform, but perhaps I have misunderstood this?
Matt J
Matt J 2025년 5월 15일
편집: Matt J 2025년 5월 15일
I thought that a sin wave that does not end at zero after an integer number of cycles will cause side lobes due to the assumed periodicity of the window over which you take a Fourier Transform,
It will, but this isn't the Fourier Transform. It's the Discrete Fourier Transform, which means you won't see the peak or the side lobes if you don't make sure frequency is discretized at the right locations. If your wave samples do not run for complete periods, it means again that your freqAxis sample points do not include f0. As for the side lobes, it is possible that you are sampling their zero-crossings only, instead of their peaks. We have to check at what your frequency sampling interval really is.
So, from the output below, it looks like your sine wave runs for almost exactly 25 periods. Since this is only slightly noninteger, It doesn't seem surprising that side lobes are absent. You can see how that changes when I insert truncation manually:
N=7500;
f0 = 0.25*10^9;
blerg(:,1) = linspace(0,100*10^-9,N+1);
blerg(:,2) = sin(2*pi*f0*blerg(:,1));
input = blerg;
dt = (input(2,1)-input(1,1))
dt = 1.3333e-11
N = height(input);
Fs = 1/dt;
df=1/N/dt
df = 9.9987e+06
numberOfPeriods = N*dt*f0
numberOfPeriods = 25.0033
%plot(input(:,1), input(:,2))
spectLen=floor(N/2);
freqAxis = (0:spectLen-1)*df;
Y = fft(input(:,2))/N;
Ydb = mag2db(abs(Y));
inTrunc=input(:,2); inTrunc(round(2*end/3):end)=0;
Ydbtrunc= mag2db(abs(fft(inTrunc)/N));
plot(freqAxis/1e6, Ydb(1:spectLen) , freqAxis/1e6, Ydbtrunc(1:spectLen),'--');
xlim([0 1000]); legend Given Truncated

댓글을 달려면 로그인하십시오.

Image Analyst
Image Analyst 2025년 5월 15일
As you know, the FT of an infinitely long pure sine wave is a delta function. However you don't have an infinitely long sine wave, you have a certain limited number of cycles in a window. So essentially your signal is a sine wave multiplied by a rect function. Now you know that the FT of a rect function is a sinc function, and the FT of two functions multiplied by each other is the convolution of the two FTs. A delta function convolved with anything is that thing, so the FT of the sine (the delta function) convolved with the FT of a rect function (the sinc) will just be sinc function. And as you know (or should know) the wider the rect function, the narrower the sinc function will be. So with many many cycles of the sine inside the rect, you will get a very narrow spectrum, where the side lobes might not be very well resolved. The sinc width varies inversely with the rect function width. If you make your rect function narrower to include fewer cycles, the sinc function will widen, and the side lobes will be more noticeable because of that.

카테고리

도움말 센터File Exchange에서 Fourier Analysis and Filtering에 대해 자세히 알아보기

제품

릴리스

R2021b

질문:

2025년 5월 15일

답변:

2025년 5월 15일

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by