PSD estimation via FFT - matlab

I estimate Power Spectral Density (PSD) for Gaussian monopulse in UWB band. I have two codes, using fft. But there is a problem with y axes, since I don't know its dimension (I need PSD in dBm/MHz). And also it should be a mistake in the first code, since it shows only one value at the y axes.
Code1
fs=1e11;
g=0.1e-9;
tmax=1e-9;
fftl=2048;
t=(-tmax:1./fs:tmax)';
s=t./(g.^3.*sqrt(2.*pi)).*exp(-t.^2./(2.*g.^2))./2.5e19;
figure(1)
plot(t,s);
xlabel('Time, s');
ylabel('Amplitude, V');
ffts=abs(fft(s,fftl));
ffts=2.*ffts./fftl;
fftp=abs(ffts.*conj(ffts))./2;
fftps=(fftp-30)./1e-6;
f=0:fs./fftl:fs./2-fs./fftl;
figure(2)
plot(f,fftps(1:length(f))),grid;
xlabel('Frequency, Hz');
Code2
fs=1e11;
g=0.1e-9;
tmax=1e-9;
t=(-tmax:1./fs:tmax)';
s=t./(g.^3.*sqrt(2.*pi)).*exp(-t.^2./(2.*g.^2))./2.5e19;
figure(1)
plot(t,s);
xlabel('Time, s');
ylabel('Amplitude, V');
S=fft(s,8192);
f=fs.*(0:4095)./8192;
Pss=S.*conj(S)./8192;
figure(2)
plot(f,Pss(1:4096));
Thank you so much for any help!

Your second plot should give you a plot with units V^2/Hz.
dBm units are measure of power relative to 1 mW, so you have to know the impedance of your measurement.
So to get to mW/Hz you would want to multiply by 1e6/R, where R is your impedance. Then take 10*log10 of the result and you have dBm/Hz.

Related

Why i am getting same output and plot for spline and cubic?

Input of digital systems is usually analog but after processing signals in digital form they give back output in analog form
I am trying to write a code for reconstruction of signal in matlab using interpolation technique but i am getting same output/plot for both interpolation types as shown in last plot of code.
My code is below:
t= 0:0.001:1;
fm= 10
fs= 8*48
x= sin(2*pi*fm*t) % Message Signal
% Plotting discrete time sampled signal x[n]
% Pulse Traain
d= 0:1/50:1;
y= pulstran(t,d,'rectpuls',0.001)
% Sampling
z= x.*y
% Non-uniformly quantize the discrete time signal using u-law companding
% method, u= 100 and number of bits= 8.
% Quantization
N= 8
V= max(x)
u= 100
compsig= compand(x,u,V,'mu/compressor');
L= 2.^N
D= [max(compsig)-min(compsig)]./(L-1);
quants= quant(compsig,D);
xq= compand(quants,u,max(quants),'mu/expander')
% Encode the Signal into discrete levels.
H_e= dsp.UniformEncoder(max(xq),N);
encoder= step(H_e,xq)
% Decoding the signal from discrete level and reconstruct using spline and cubic
% interpolation to reconstruct the analog signal x'(t) from the
% discrete time signal using $t= 0.001.
H_d= dsp.UniformDecoder(max(xq),N);
decoder= step(H_d,encoder)
% Cubic Interpolation
time= 0:0.0001:1;
ci= interp1(t,decoder,time,'cubic')
% Spline interpolation
time=0:0.0001:1
si= interp1(t,decoder,time,'spline')
figure(01)
subplot(2,1,1)
plot(t,x,'R','LineWidth',2)
xlabel('Time')
ylabel('Amplitude')
legend('x')
title('Message Signal')
subplot(2,1,2)
plot(t,y,'B','LineWidth',2)
xlabel('Time')
ylabel('Amplitude')
legend('y')
title('Pulse Train')
figure(02)
subplot(2,1,1)
plot(t,z,'C','LineWidth',2)
xlabel('Time')
ylabel('Amplitude')
legend('z')
title('Sampled Signal')
subplot(2,1,2)
plot(t,xq,'G','LineWidth',2)
xlabel('Time')
ylabel('Amplitude')
legend('xq')
title('Quantized Signal')
figure(03)
subplot(2,1,1)
plot(t,encoder,'M','LineWidth',2)
xlabel('Time')
ylabel('Amplitude')
legend('encoder')
title('Encoded Signal')
subplot(2,1,2)
plot(t,decoder,'K','LineWidth',2)
ylim([-1 1])
xlabel('Time')
ylabel('Amplitude')
legend('decoder')
title('Decoded Signal')
figure(04)
subplot(2,1,1)
plot(time,ci,'B','LineWidth',2)
ylim([-1 1])
xlabel('Time')
ylabel('Amplitude')
legend('ci')
title('Cubic Interpolation')
subplot(2,1,2)
plot(time,ci,'R',time,si,'G')
xlabel('Time')
ylabel('Amplitude')
legend('si')
title('Spline & cubic Interpolation')
How can i see difference in output/plots of both types of interpolation?
There's only one correct reconstructed result, and both interpolation methods are trying to approximate that.
Your input is such that they both do a good job, so you just can't see any difference.
You will need some signal content near Fs/2 in order to see any difference, and even then it might be very difficult by eye to see which is better.
The reason both interpolators are working will is that they function like low-pass filters with cut-off frequency around Fs/2. They both have good response far below that frequency and not-so-good response near that frequency.
You can do a better job of reconstructing signals with content near Fs/2 by first interpolating with a good digital low-pass filter to multiply the sampling frequency by 8 or so, and then you can use cubic interpolation to get any values for any points between those new samples. You can even adjust your digital low-pass to correct for the small errors that cubic interpolation will eventually cause, to produce a very accurate result.

Plotting the magnitude and phase spectra of a wav file in the range of -fs/2 to fs/2

I'm having problems plotting the FFT of a wav file. I managed to plot the magnitude and phase spectrums of the signal, however I need to repeat this in range -fs/2:fs/2.
%read sound files
%'y' is the vector holding the original samples & 'fs' refers to the sampling frequency
[y,fs] = wavread('handel.wav');
ydft = fft(y); %fft to transform the original signal into frequency domain
n = length (y); %length of the original signal
% y has even length
ydft = ydft(1:length(y)/2+1);
% create a frequency vector
freq = 0:fs/length(y):fs/2;
shiftfreq = fftshift(freq);
%plot original signal in time domain;
figure;
plot ((1:n)/fs, y);
title('handel.wav in time domain');
xlabel ('second');
grid on;
% plot magnitude in frequency domain
figure;
plot(freq,abs(ydft));
title('handel.wav in frequency domain');
xlabel ('Hz');
ylabel('Magnitude');
grid on;
% plot phase in frequency domain
figure;
plot(freq,unwrap(angle(ydft)));
title ('handel.wav in frequency domain');
xlabel ('Hz');
ylabel ('Phase');
grid on;
What you are currently doing now is plotting the half spectrum, so from 0 <= f < fs/2 where fs is the sampling frequency of your signal, and so fs/2 is the Nyquist frequency. Take note that considering the half spectrum is only valid if the signal is real. This means that the negative spectra is symmetric to the positive spectra and so you don't really need to consider the negative spectra here.
However, you would like to plot the full spectrum of the magnitude and phase. Take note that when calculating the fft using MATLAB, it uses the Cooley-Tukey algorithm so when computing the N point FFT, half of result is for the frequencies from 0 Hz inclusive up to fs/2 Hz exclusive and the other half is for the frequencies from -fs/2 Hz inclusive up to 0 Hz exclusive.
As such, to plot the full spectrum, simply perform a fftshift on the full signal so that the right half and left half of the spectrum is swapped so that the 0 Hz frequency is located in the centre of the signal. Also, you must generate frequencies between -fs/2 to fs/2 to cover the full spectrum. Specifically, you need to generate N points linearly spaced between -fs/2 to fs/2. However, take note that the Nyquist frequency at fs/2 Hz is being excluded at the end, so you need to generate N+1 points between -fs/2 to fs/2 and remove the last point in order for the right step size between each frequency bin to be correct. The easiest way to generate this linear array of points is by using the linspace command where the start frequency is -fs/2, the ending frequency is fs/2 and you want N+1 points between this range and remove the last point:
freq = linspace(-fs/2, fs/2, n+1);
freq(end) = [];
As such, borrowing some parts of your code, this is what the modified code looks like to plot the full spectrum of the magnitude and phase:
%// Read in sound file
[y,fs] = wavread('handel.wav');
%// Take N-point FFT where N is the length of the signal
ydft = fft(y);
n = numel(y); %// Get N - length of signal
%// Create frequency vector - make sure you remove last point
freq = linspace(-fs/2, fs/2, n+1);
freq(end) = [];
%// Shift the spectrum
shiftSpectrum = fftshift(ydft);
%//plot original signal in time domain;
figure;
plot ((0:n-1)/fs, y); %// Note you should start from time = 0, not time = 1/fs
title('handel.wav in time domain');
xlabel ('second');
grid on;
%// plot magnitude in frequency domain
figure;
plot(freq,abs(shiftSpectrum));
title('handel.wav in frequency domain');
xlabel ('Hz');
ylabel('Magnitude');
grid on;
%// plot phase in frequency domain
figure;
plot(freq,unwrap(angle(shiftSpectrum)));
title('handel.wav in frequency domain');
xlabel('Hz');
ylabel('Phase');
grid on;
I don't have access to your handel.wav file, but I'll be using the one provided with MATLAB. You can load this in with load handel;. The sampling frequency is stored in a variable called Fs, so I had to do fs = Fs; before the code I wrote above could work. The sampling frequency for this particular file is 8192 Hz, and this is approximately a 9 second long file (numel(y) / fs = 8.9249 seconds). With that file, this is the magnitude and phase that I get:
For the discrete Fourier transform (DFT) as well as its fast implementations (FFTs), the frequencies are normalized with the sampling frequency fs, i.e., the original range -fs/2:fs/2 is changed to -pi:pi.
Besides, the DFT/FFT always starts with 0, and you can use fftshift() to shift the 0 frequency to the center. Therefore, after fftshift(), the range is -pi:pi, then, you can scale to -fs/2:fs/2.
look at the following Matlab function, it can calculate phase spectrum as well as amplitude spectrum with a perfect accuracy:
https://www.mathworks.com/matlabcentral/fileexchange/63965-amplitude-and-phase-spectra-of-a-signal--fourier-transform-
This program calculates amplitude and phase spectra of an input signal with acceptable accuracy especially in the calculation of phase spectrum.The code does three main jobs for calculation amplitude and phase spectra. First of all, it extends the input signal to infinity; because for calculation Fourier transform(FT) (fft function in Matlab), we consider our signal is periodic with an infinite wavelength, the code creates a super_signal by putting original signal next to itself until the length of super_signal is around 1000000 samples, why did I choose 1000000 samples? Actually, it is just based on try and error!! For most signals that I have tried, a supper signal with 1000000 samples has the best output.
Second, for calculating fft in Matlab you can choose different resolutions, the Mathwork document and help use NFFT=2^nextpow2(length(signal)), it definitely isn't enough for one that wants high accuracy output. Here, I choose the resolution of NFFT=100000 that works for most signals.
Third, the code filters result of FT by thresholding, it is very important step! For calculating phase spectrum, its result is very noisy because of floating rounding off error, it causes during calculation "arctan" even small rounding off error produces significant noise in the result of phase spectrum, for suppressing this kind of noise you can define a threshold value. It means if amplitude of specific frequency is less than predefined threshold value (you must define it) it put zero instead of it.
These three steps help to improve the result of amplitude and phase spectra significantly.
IF YOU USE THIS PROGRAM IN YOUR RESEARCH, PLEASE CITE THE FOLLOWING PAPER:
Afshin Aghayan, Priyank Jaiswal, and Hamid Reza Siahkoohi (2016). "Seismic denoising using the redundant lifting scheme." GEOPHYSICS, 81(3), V249-V260. https://doi.org/10.1190/geo2015-0601.1

FFT of Gaussian Pulse

I'm trying to get Fourier transform of a gaussian pulse. Here's a sample code I found on the Internet.
fs=80; %sampling frequency
sigma=180;
t=-0.5:10/fs:0.5; %time base
variance=sigma^2;
x=1/(sqrt(2*pi*variance))*(exp(-t.^2/(2*variance)));
subplot(2,1,1)
plot(t,x,'b');
title(['Gaussian Pulse \sigma=', num2str(sigma),'s']);
xlabel('Time(s)');
ylabel('Amplitude');
L=length(x);
NFFT = 1024;
X = fftshift(fft(x,NFFT));
Pxx=X.*conj(X)/(NFFT*NFFT); %computing power with proper scaling
f = fs*(-NFFT/2:NFFT/2-1)/NFFT; %Frequency Vector
subplot(2,1,2)
plot(f,abs(X)/(L),'r');
title('Magnitude of FFT');
xlabel('Frequency (Hz)')
ylabel('Magnitude |X(f)|');
xlim([-10 10])
I need an explanation. Assume that I'm trying to get Fourier transform of 100 femtosecond gaussian pulse. How can I calculate the sampling frequency, sigma and t variables.
http://www.gaussianwaves.com/2014/07/generating-basic-signals-gaussian-pulse-and-power-spectral-density-using-fft/
A gaussian pulse has infinite support so there's no such thing as a "100 femtosecond gaussian pulse", you can however have a gaussian pulse with a sigma of 100 femtoseconds which is probably what you want. For your sampling frequency, you probably want to choose something such that you actually capture interesting information about the pulse. Your sampling period hence be less than a sigma (the original code (not the one you posted) from the blog used sigma/8). As for t, if you want to capture most of the energy in the pulse, you need to go several sigmas to the left and right of 0 which is where the pulse is centered in time.

MATLAB: FFT a signal to frequency and IFFT back to time domain, not exactly the first signal

I am trying to reproduce the changes on a ~30 femtosecond laser pulse. I create and display this pulse in time just fine. Also, the fft of this pulse apperas fine on matlab (central frequency and width are very fine). But when I backtransform the transformed one using the ifft() function, the pulse is moved in time (posssibly due to phase change?? I don't know) and also the peak maxima are different.. What could be the cause of this? I am using ifft the wrong way?
The code I am using is this :
atto=1e-18;
c = 299792458;
femto=1e-15;
lamda0=800e-9;
f_0=c/lamda0;
omega0=2*pi*c/lamda0;
T=2*pi/omega0;
a=2*log(2)/((36.32*femto)^2);
Fs=3/atto; %samplying rate
t=-200*femto:1/Fs:200*femto;
Efield=exp(-a.*(t-T).^2).*exp(1j.*omega0.*(t-T));
nfft=2^nextpow2(length(Efield));
Efieldfft=fft(Efield,nfft);
f=(0:nfft-1)*Fs/nfft;
omega=2*pi*f;
figure(1)
plot(t,Efield)
xlabel('s [fs]')
ylabel('Amplitude')
figure(2)
plot(omega,abs(Efieldfft))
xlim([2e15 2.8e15])
xlabel('omega [rad]')
ylabel('Amplitude')
figure(3)
plot(f,abs(Efieldfft))
xlim([3.3e14 4.1e14])
xlabel('frequency [Hz]')
ylabel('Power')
test=ifft(Efieldfft,length(t));
figure(4)
plot(t,test)
xlabel('s[fs]')
ylabel('amplitude')
That's because you are modifying the length of the FFT compared with the length of your time axis. To see this, replace
nfft=2^nextpow2(length(Efield));
by
nfft=length(Efield);
You'll find that figures 1 and 4 are now equal, up to numerical precision errors.

Trouble doing fourier transform of ASK using MATLAB

We have a ASK modulated signal. We need the Fourier Transform, therefore I used FFT, but do I need to abs() for only one side? And is my code complete? I'm also not sure how to transfer from time domain (t) to frequency domain (f) in order to do the matlab.
clear all;
clc;
close all;
F1=input('Enter the frequency of carrier=');
F2=input('Enter the frequency of pulse=');
A=3;
t=0:0.001:1;
x=A.*sin(2*pi*F1*t);
u=A/2.*square(2*pi*F2*t)+(A/2);
v=x.*u;
figure
subplot(4,1,1);
plot(t,x);
xlabel('Time');
ylabel('Amplitude');
title('Carrier');
grid on;
subplot(4,1,2);
plot(t,u);
xlabel('Time');
ylabel('Amplitude');
title('Square Pulses');
grid on;
subplot(4,1,3);
plot(t,v);
xlabel('Time');
ylabel('Amplitude');
title('ASK Signal');
grid on;
fs=100;
q=fft(v);
subplot(4,1,4);
plot(fs,q);
grid on;
If you are not sure if you should use abs() or not, use it. For more info.
fs=100;
q=abs(fft(v));
subplot(4,1,4);
plot(q);
Depends on how you want to look at the resulting FFT.
The function fft(v) is usually complex.
There are two ways to examine a FFT.
One the most used, is phase/magnitude plot and the other is I and Q representation, which are the coefficients of the sine and cosine harmonics.
If you want to look at the magnitude and phase, then you ask this.
abs(fft(v)) for magnitude, and angle(fft(v)) for phase
If you instead want to look at in form the I and Q channels, then ask this:
real(fft(v)) and imag(fft(v))
Shift is a good idea to move the spectrum to zero center. It makes a spectrum more comprehensible.