This is my code:
T
F = 1/T
y
L = length(y)
Y=fft(y);
f=(0:F:(L-1)*F)
plot(f, Y)
T is the sampling time (with its value), F is the frequency and y is the discrete signal.
Is it the correct way to compute DFT using Matlab? I haven't passed F or T to the function so I'm not sure if the results Y correspond to their respective multiple frequencies of F stored in f.
F = 1/T
L = length(y)
t = linspace(0,L/F,L);
NFFT = 2^nextpow2(L);
f = F/2*linspace(0,1,NFFT/2+1);
fft_y = fft(y, NFFT)/L;
magnitude_y = = 2*abs(fft_y(1:NFFT/2+1));
plot(f, magnitude_y);
This is the correct way.
Related
This is my code for finding the centered coefficients for lagrange polynomial interpolation:
% INPUT
% f f scalar - valued function
% interval interpolation interval [a, b]
% n interpolation order
%
% OUTPUT
% coeff centered coefficients of Lagrange interpolant
function coeff = lagrangeInterp (f, interval , n)
a = interval(1);
b = interval(2);
x = linspace(a,b,n+1);
y = f(x);
coeff(1,:) = polyfit(x,y,n);
end
Which is called in the following script
%Plot lagrangeInterp and sin(x) together
hold on
x = 0:0.1*pi:2*pi;
for n = 1:1:4
coeff = lagrangeInterp(#(x)sin(x),[0,2*pi],n);
plot(x,polyval(coeff,x,'-'));
end
y = sin(x);
plot(x,y);
legend('1st order','2nd order','3rd order','4th order','sin(x)');
To check for stability I would like to perturb the function (eg g(x) = f(x) + epsilon). How would I go about this?
Well, a little trick for you.
You know randn([m,n]) in matlab generate a m*n random matrix. The point is to generate a random vector, and interp1 to a function of x. Like this:
x = linspace(a,b,n+1); % Your range of input
g = #(ep,xx)f(xx)+interp1(x,ep*randn([length(x),1]),xx);
I want to understand the discrete fourier transform by implementing it by myself.
While the result returned by my DFT is not correct the in matlab included version returns the correct frequencies of the original signal.
So the question is, where went I wrong. Is it a math or a implementation problem?
%% Initialisation
samples=2000;
nfft = 1024;
K = nfft / 2 + 1;
c = 264;
e = 330;
t = -1:1/samples:1-1/samples;
[~, N] = size(t);
f = (sin(2*c*pi*t)+cos(2*e*pi*t)).*exp(-pi*(2*t-1).^2);
X = zeros(nfft, 1);
%% Discrete Fourier Transform
if true
for k=1:nfft
for n=1:nfft
X(k) = X(k) + f(n)*exp(-j*2*pi*(k-1)*(n-1)/N);
end
end
else
X=fft(f, nfft);
end
R = abs(X(1:K));
[V,I] = sort(R,'descend');
F1 = samples*(I(1)-1)/nfft;
F2 = samples*(I(2)-1)/nfft;
disp(F1)
disp(F2)
plot(1:K, R, 1:K, real(X(1:K)), 1:K, imag(X(1:K)))
The issue lies in the number of samples for which the transform is done.
Xall = fft(f);
plot(abs(Xall(1:500)),'b');
hold on
plot(abs(X(1:500)),'r');
What you compute matches the result from the FFT done on all samples (i.e. with 4000 real samples in and 4000 complex values out).
Now, if you read the documentation of FFT with doc fft you will see that the signal is truncated if the output size is smaller than the input size. If you try:
Y = zeros(nfft, 1);
for k=1:nfft
for n=1:nfft
Y(k) = Y(k) + f(n)*exp(-1j*2*pi*(k-1)*(n-1)/nfft);
end
end
Y2 = fft(f(:),nfft); %make it a column
abs(sum(Y-Y2)) %6.0380e-12 , result within precision of the double float format
The formula for the discrete double Fourier series that I'm attempting to code in MATLAB is:
The coefficient in front of the trigonometric sum (Fourier amplitude) is what I'm trying to extract from the fitting of the data through the double Fourier series seen above. Using my current code, the original function is not reconstructed, therefore my coefficients cannot be correct. I'm not certain if this is of any significance or insight, but the second term for the A coefficients (Akn(1))) is 13 orders of magnitude larger than any other coefficient.
Any suggestions, modifications, or comments about my program would be greatly appreciated.
%data = csvread('digitized_plot_data.csv',1);
%xdata = data(:,1);
%ydata = data(:,2);
%x0 = xdata(1);
lambda = 20; %km
tau = 20; %s
vs = 7.6; %k/s (velocity of CHAMP satellite)
L = 4; %S
% Number of terms to use:
N = 100;
% set up matrices:
M = zeros(length(xdata),1+2*N);
M(:,1) = 1;
for k=1:N
for n=1:N %error using *, inner matrix dimensions must agree...
M(:,2*n) = cos(2*pi/lambda*k*vs*xdata).*cos(2*pi/tau*n*xdata);
M(:,2*n+1) = sin(2*pi/lambda*k*vs*xdata).*sin(2*pi/tau*n*xdata);
end
end
C = M\ydata;
%least squares coefficients:
A0 = C(1);
Akn = C(2:2:end);
Bkn = C(3:2:end);
% reconstruct original function values (verification check):
y = A0;
for k=1:length(Akn)
y = y + Akn(k)*cos(2*pi/lambda*k*vs*xdata).*cos(2*pi/tau*n*xdata) + Bkn(k)*sin(2*pi/lambda*k*vs*xdata).*sin(2*pi/tau*n*xdata);
end
% plotting
hold on
plot(xdata,ydata,'ko')
plot(xdata,yk,'b--')
legend('Data','Least Squares','location','northeast')
xlabel('Centered Time Event [s]'); ylabel('J[\muA/m^2]'); title('Single FAC Event (50 Hz)')
How can I get the correct frequency vector to plot using the FFT of MATLAB?
My problem:
N = 64;
n = 0:N-1;
phi1 = 2*(rand-0.5)*pi;
omega1 = pi/6;
phi2 = 2*(rand-0.5)*pi;
omega2 = 5*pi/6;
w = randn(1,N); % noise
x = 2*exp(1i*(n*omega1+phi1))+4*sin(n*omega2+phi2);
h = rectwin(N).';
x = x.*h;
X = abs(fft(x));
Normally I'd do this :
f = f = Fs/Nsamples*(0:Nsamples/2-1); % Prepare freq data for plot
The problem is this time I do not have a Fs (sample frequency).
How can I do it correctly in this case?
If you don't have a Fs, simply set it to 1 (as in one sample per sample). This is the typical solution I've always used and seen everybody else use. Your frequencies will run from 0 to 1 (or -0.5 to 0.5), without units. This will be recognized by everyone as meaning "periods per sample".
Edit
From your comment I conclude that you are interested in radial frequencies. In that case you want to set your plot x-axis to
omega = 2*pi*f;
My MATLAB code for fft and ifft below has a problem with the inverse Fourier signal y not matching the in put signal x. Is there any solution to resolve this?
N = 1000;
t0 = 1e-13;
tau = 2*1e-14;
n = [0:t0/40:2*1e-13-t0/40];
f0 = 3*1e8/(150*1e-9);
x = cos(2*pi*f0*n);
x = x.*exp((-(n-t0).^2)./(tau^2));
X = abs(fft(x,N));
F = [-N/2 : N/2 - 1]/N;
X = fftshift(X);
y=ifft(X,80);
figure(3)
plot(n,y)
I see a number of issues here:
N = 1000;
t0 = 1e-13;
tau = 2*1e-14;
n = [0:t0/40:2*1e-13-t0/40];
f0 = 3*1e8/(150*1e-9);
x = cos(2*pi*f0*n);
x = x.*exp((-(n-t0).^2)./(tau^2));
% X = abs(fft(x,N)); <-- Not seen this technique before, and why N=1000?
% try something more like:
X = fft(x);
F = [-N/2 : N/2 - 1]/N;
% this is fine to shift and plot the function
Xshifted = fftshift(X);
plot( abs( Xshifted ) )
% now you're taking the inverse of the shifted function, not what you want
% y=ifft(X,80); also not sure about the 80
y = ifft(X);
figure(3)
plot(n,y)
figure(4)
plot( n, x ); hold on; plot( n, y, 'o' )
That's all I see at first. HTH!
If you take the absolute value of the fft, you destroy the phase information needed to reconstruct the original signal, i.e. the moment you compute
X = abs(fft(x,N));
You cannot go back via ifft, because now you only have the magnitude.
Also, the inverse transformation only works if you use the same number of FFT bins with NFFT>=length(x).
y=ifft(fft(x));
should be exactly the same as x.