How can find the Fourier Coefficents of this DFT? - matlab

I have a data which contains 16 elements:
x=[8.57837e-08, 2.07482e-06, 4.43796e-06, 7.66462e-06, 1.10232e-05, 1.35811e-05, 1.27958e-05, 5.94217e-06, 2.49168e-08, -6.58389e-06, -1.30551e-05, -1.345e-05, -1.07471e-05, -7.38637e-06, -4.42876e-06, -1.88811e-06 ];
A = length(x)
I do DTFT-DFT like dirac signals:
n=0:A;
syms w
X_w=0;
for i=1:length(x)
X_w=X_w+x(i)*exp(-j*w*n(i));
end
figure;fplot(angle(X_w),[0 2*pi]),title('DTFT phase graph')
figure;fplot(abs(X_w),[0 2*pi]),title('DTFT amplitude graph')
hold on
%DFT
N=50;
k=0:N-1;
DFT_X=[];
for k=0:N-1
Xk=0;
for i=1:length(x)
Xk=Xk+x(i).*exp(-j*(2*pi/N).*k.*n(i));
end
DFT_X=[DFT_X Xk];
end
w=2*pi/N*(0:N-1);
stem(w,abs(DFT_X))`
The problem is I want to write this signal with cosinus and sinus components. But I don't really know how can I do.
Thank you all,
Emre.

Direct computation of the Fourier coefficients might be a better option than trying to relate the DFT to the DFS. Looking at the continuous time formulas:
all you'd need to do is sum the input signal x multiplied (element wise) by a cosine over it's domain for the real coefficient and sum the input signal x multiplied (element wise) by a sine over its domain for the imaginary coefficients.
Secondly, you could potentially use conjugate symmetry and these formulas to calculate the relationship between your Xk and the desired An and Bn coefficients.
Xk = (An-j*Bn)/2
and
Xk* = (An+j*Bn)/2)

Related

Unexpected result with DFT in MATLAB

I have a problem when calculate discrete Fourier transform in MATLAB, apparently get the right result but when plot the amplitude of the frequencies obtained you can see values very close to zero which should be exactly zero. I use my own implementation:
function [y] = Discrete_Fourier_Transform(x)
N=length(x);
y=zeros(1,N);
for k = 1:N
for n = 1:N
y(k) = y(k) + x(n)*exp( -1j*2*pi*(n-1)*(k-1)/N );
end;
end;
end
I know it's better to use fft of MATLAB, but I need to use my own implementation as it is for college.
The code I used to generate the square wave:
x = [ones(1,8), -ones(1,8)];
for i=1:63
x = [x, ones(1,8), -ones(1,8)];
end
MATLAB version: R2013a(8.1.0.604) 64 bits
I have tried everything that has happened to me but I do not have much experience using MATLAB and I have not found information relevant to this issue in forums. I hope someone can help me.
Thanks in advance.
This will be a numerical problem. The values are in the range of 1e-15, while the DFT of your signal has values in the range of 1e+02. Most likely this won't lead to any errors when doing further processing. You can calculate the total squared error between your DFT and the MATLAB fft function by
y = fft(x);
yh = Discrete_Fourier_Transform(x);
sum(abs(yh - y).^2)
ans =
3.1327e-20
which is basically zero. I would therefore conclude: your DFT function works just fine.
Just one small remark: You can easily vectorize the DFT.
n = 0:1:N-1;
k = 0:1:N-1;
y = exp(-1j*2*pi/N * n'*k) * x(:);
With n'*k you create a matrix with all combinations of n and k. You then take the exp(...) of each of those matrix elements. With x(:) you make sure x is a column vector, so you can do the matrix multiplication (...)*x which automatically sums over all k's. Actually, I just notice, this is exactly the well-known matrix form of the DFT.

calculate discrete S transform for given discrete time series

let us consider following Page :
http://djj.ee.ntu.edu.tw/S_Transform.pdf
paragraph 2.3 The Discrete S Transform
let say that we have sampled version of signal x, and given sampling frequency fs,i have calculated discrete Fourier transform using following code
function y=DFT(x);
N=length(x);
D=zeros(N,N);
for k=1:N
for n=1: N
D(k,n)=exp((-j*(k-1)*2*pi*(n-1))/N);
end
end
y=D*x'/N;
end
and started to estimate discrete S transform
function [S]=discrete_s_transform(x,fs);
%compute discrete s transform
%fs-sampling frequency
N=length(x); % length of signal
T=1/fs; % sampling period
Y=DFT(X);
how can i continue related to this part ?
clearly loops are not problem to implement,just they go from 1 to N instead of 0 to N-1 because of matlab vectors are 1 based,but what about main code?multiplication to exponential? coudl you please help me to finish S transform ?
Your sum depends only on m so I assume that other parameters as well as function H((m+n)/(NT)) are defined. Via for-loops the simplest one is:
function [S]=discrete_s_transform(x);
N=length(x); % length of signal
S=0;
m=0;
for i=1:N
S=S+H((m+n)/(NT))*exp(a)*exp(b*m/N);
m=m+1;
end
Hope that helps!

find RMS value in frequency domain

i would like to find RMS value in frequency domain,i used this site for help
http://www.dsprelated.com/showmessage/123177/1.php
but there it is calculated using FFT,but what if i am using periodgram?instead of this code
X = fft(x)
Parseval's Theorem
sum(x.^2) = sum(abs(X).^2)/N
RMS == sqrt(sum(x.^2))/N) = sqrt(sum(abs(X/N).^2))
how does code change in case of periodogram?thanks in advance
The periodogram P = P(f) expresses how the power of a signal x = x(t) is distributed across the different frequencies. As such, it can be seen as a function which associates to a frequency f the squared of the absolute value of the Fourier transform of x evaluated at f.
In other words, in terms of your notation, the periodogram of x = x(t) goes as P(f) = |X|^2(f).
As a consequence, the RMS satisfies
RMS = sqrt(sum(P))/N.
CAVEAT:
I am not quite convinced on your normalization factors. In principle, Parseval's theorem states that the Fourier transform is isometric isomorphism of L^2 to itself. Hence the norm of a signal is preserved once a Fourier transform is done.
Nonetheless, different definition of such transformations can lead to different normalization factors (e.g. your 1/N). In a nutshell, attention should be paid to that constant.
It is a very old case, but i did a simple program which calculates the power in time domain and frequency domain. For the calculating RMS value of a signal in frequency domain only the integration of periodogram give the same result as in time domain
Below ist the code with comments in polish but variables are in english so You should guess what each line does.
clear all
clc
N=1024; %liczba próbek sygna?u
f1=5; %cz?stotliwo?ci sk?adowych sinusoidalnych sygna?u
f2=15;
f3=30;
fs=1000; %czestotliwosc próbkowania
td=1/fs; %okres sygnalu
t=(0:N-1)*td;
war=0.8; %wariancja zak?ócenia
sig=sqrt(war); %odchylenie standardowe zak?ócenia
Nf=1024; %liczba próbek transformaty Fouriera
%sygna? losowy i deterministyczny
for i=1:N
%yn(i)=randn;
%y(i)=sin(2*pi*f1*td*i) + 0.5*sin(2*pi*f2*td*i) + ...
%0.25*sin(2*pi*f3*td*i) +sig*randn;
y(i)=5*sin(2*pi*f1*td*i)+sin(2*pi*f2*td*i);
end
%Obliczenie wartosci skutecznej sygnału
RMS_calc_by_hand=sqrt((1/Nf)*sum(y.^2));
RMS_time_domain=rms(y);
%transformata Fouriera
Y=2*abs(fft(y,Nf))/Nf;
Y=Y(1:Nf/2);
df=fs/Nf;
f=0:df:fs/2-df;
%Inna forma zapisu
%f=df*(0:Nf/2-1);
% wykres sygnału rzeczywistego
subplot(3,2,1);
plot(t,y);
title('a(t)');
xlabel('t [s]');
ylabel('a [mm/s]');
subplot(3,2,2);
plot(f,Y);
% formatowanie wykresu
title('a(f)');
xlabel('f [Hz]');
ylabel('a [mm/s]');
%gestosc widmowa mocy
subplot(3,2,3);
%PSD
[P,w] = periodogram(y,[],Nf,fs);
plot (w,P);
title('gestosc widmowa mocy periodogram');
RMS_freq_domain =sqrt(trapz(w,P));

FFTW and fft with MatLab

I have a weird problem with the discrete fft. I know that the Fourier Transform of a Gauss function exp(-x^2/2) is again the same Gauss function exp(-k^2/2). I tried to test that with some simple code in MatLab and FFTW but I get strange results.
First, the imaginary part of the result is not zero (in MatLab) as it should be.
Second, the absolute value of the real part is a Gauss curve but without the absolute value half of the modes have a negative coefficient. More precisely, every second mode has a coefficient that is the negative of that what it should be.
Third, the peak of the resulting Gauss curve (after taking the absolute value of the real part) is not at one but much higher. Its height is proportional to the number of points on the x-axis. However, the proportionality factor is not 1 but nearly 1/20.
Could anyone explain me what I am doing wrong?
Here is the MatLab code that I used:
function [nooutput,M] = fourier_test
Nx = 512; % number of points in x direction
Lx = 50; % width of the window containing the Gauss curve
x = linspace(-Lx/2,Lx/2,Nx); % creating an equidistant grid on the x-axis
input_1d = exp(-x.^2/2); % Gauss function as an input
input_1d_hat = fft(input_1d); % computing the discrete FFT
input_1d_hat = fftshift(input_1d_hat); % ordering the modes such that the peak is centred
plot(real(input_1d_hat), '-')
hold on
plot(imag(input_1d_hat), 'r-')
The answer is basically what Paul R suggests in his second comment, you introduce a phase shift (linearly dependent on the frequency) because the center of the Gaussian described by input_1d_hat is effectively at k>0, where k+1 is the index into input_1d_hat. Instead if you center your data (such that input_1d_hat(1) corresponds to the center) as follows you get a phase-corrected Gaussian in the frequency domain:
Nx = 512; % number of points in x direction
Lx = 50; % width of the window containing the Gauss curve
x = linspace(-Lx/2,Lx/2,Nx); % creating an equidistant grid on the x-axis
%%%%%%%%%%%%%%%%
x=fftshift(x); % <-- center
%%%%%%%%%%%%%%%%
input_1d = exp(-x.^2/2); % Gauss function as an input
input_1d_hat = fft(input_1d); % computing the discrete FFT
input_1d_hat = fftshift(input_1d_hat); % ordering the modes such that the peak is centered
plot(real(input_1d_hat), '-')
hold on
plot(imag(input_1d_hat), 'r-')
From the definition of the DFT, if the Gaussian is not centered such that maximum occurs at k=0, you will see a phase twist. The effect off fftshift is to perform a circular shift or swapping of left and right sides of the dataset, which is equivalent to shifting the center of the peak to k=0.
As for the amplitude scaling, that is an issue with the definition of the DFT implemented in Matlab. From the documentation for the FFT:
For length N input vector x, the DFT is a length N vector X,
with elements
N
X(k) = sum x(n)*exp(-j*2*pi*(k-1)*(n-1)/N), 1 <= k <= N.
n=1
The inverse DFT (computed by IFFT) is given by
N
x(n) = (1/N) sum X(k)*exp( j*2*pi*(k-1)*(n-1)/N), 1 <= n <= N.
k=1
Note that in the forward step the summation is not normalized by N. Therefore if you increase the number of points Nx in the summation while keeping the width Lx of the Gaussian function constant you will increase X(k) proportionately.
As for signal leaking into the imaginary frequency dimension, that is due to the discrete form of the DFT, which results in truncation and other effects, as noted again by Paul R. If you reduce Lx while keeping Nx constant, you should see a reduction in the amount of signal in the imaginary dimension relative to the real dimension (compare the spectra while keeping peak intensities in the real dimension equal).
You'll find additional answers to similar questions here and here.

Calculate autocorrelation using FFT in Matlab

I've read some explanations of how autocorrelation can be more efficiently calculated using the fft of a signal, multiplying the real part by the complex conjugate (Fourier domain), then using the inverse fft, but I'm having trouble realizing this in Matlab because at a detailed level.
Just like you stated, take the fft and multiply pointwise by its complex conjugate, then use the inverse fft (or in the case of cross-correlation of two signals: Corr(x,y) <=> FFT(x)FFT(y)*)
x = rand(100,1);
len = length(x);
%# autocorrelation
nfft = 2^nextpow2(2*len-1);
r = ifft( fft(x,nfft) .* conj(fft(x,nfft)) );
%# rearrange and keep values corresponding to lags: -(len-1):+(len-1)
r = [r(end-len+2:end) ; r(1:len)];
%# compare with MATLAB's XCORR output
all( (xcorr(x)-r) < 1e-10 )
In fact, if you look at the code of xcorr.m, that's exactly what it's doing (only it has to deal with all the cases of padding, normalizing, vector/matrix input, etc...)
By the Wiener–Khinchin theorem, the power-spectral density (PSD) of a function is the Fourier transform of the autocorrelation. For deterministic signals, the PSD is simply the magnitude-squared of the Fourier transform. See also the convolution theorem.
When it comes to discrete Fourier transforms (i.e. using FFTs), you actually get the cyclic autocorrelation. In order to get proper (linear) autocorrelation, you must zero-pad the original data to twice its original length before taking the Fourier transform. So something like:
x = [ ... ];
x_pad = [x zeros(size(x))];
X = fft(x_pad);
X_psd = abs(X).^2;
r_xx = ifft(X_psd);