Why there is not dxdy factor in fft2() function of MATLAB? - matlab

In analytical 2D Fourier Transform, integrand is multiplied by dxdy.
In algorithm of MATLAB function fft2(), this is not done.
In discrete case, dx is Lx/Nx and dy = Ly/Ny,
where Lx,Ly are lengths in metres and Nx,Ny are number of samples in x,y directions.
https://in.mathworks.com/help/matlab/ref/fft2.html
Is it not correct to multiply by dxdy after using fft2() for user function i.e. matrix ?
Similarly for ifft2() function in MATLAB, there is no (dk_x)*(dk_y)
where dk_x = 1/Lx and dk_y = 1/Ly
https://in.mathworks.com/help/matlab/ref/ifft2.html
Any help will be appreciated.
Thanks.

Related

How can find the Fourier Coefficents of this DFT?

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)

DCT rows instead of columns

I was aquainted in using the fft in matlab with the code
fft(signal,[],n)
where n tells the dimension on which to apply the fft as from Matlab documentation:
http://www.mathworks.it/it/help/matlab/ref/fft.html
I would like to do the same with dct.
Is this possible? I could not find any useful information around.
Thanks for the help.
Luigi
dct does not have the option to pick a dimension like fft. You will have to either transpose your input to operate on rows or pick one vector from your signal and operate on that.
yep!
try it:
matrix = dctmtx(n);
signal_dct = matrix * signal;
Edit
Discrete cosine transform.
Y = dct(X) returns the discrete cosine transform of X.
The vector Y is the same size as X and contains the discrete cosine transform coefficients.
Y = dct(X,N) pads or truncates the vector X to length N before transforming.
If X is a matrix, the dct operation is applied to each column. This transform can be inverted using IDCT.
% Example:
% Find how many dct coefficients represent 99% of the energy
% in a sequence.
x = (1:100) + 50*cos((1:100)*2*pi/40); % Input Signal
X = dct(x); % Discrete cosine transform
[XX,ind] = sort(abs(X)); ind = fliplr(ind);
num_coeff = 1;
while (norm([X(ind(1:num_coeff)) zeros(1,100-num_coeff)])/norm(X)<.99)
num_coeff = num_coeff + 1;
end;
num_coeff

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.

How to get normal vector from position vector function in MATLAB

I have this equation:
f(t) = <x(t),y(t)>
What I would first like to do is figure out the normal vector at some point, t1. How do I do this in MATLAB?
I would then like to figure out the angle between the normal vector and the x-axis in MATLAB. If I can bypass finding the normal vector and just figure out the angle straight from f(t), that might be better.
it would be nice if there were some vector manipulation functions or something that I could use instead of manually taking the derivative of x(t) and y(t) and then finding the magnitude and all that stuff. Any help would be great!
With dx being the time derivative of x, i.e. (x(t+1)-x(t-1))/(2dt) (you can also use forward differentiation instead of central differences, of course), and dy the corresponding time derivative of y, you can find the angle between the normal and the x-axis easily from the vector [dx,dy], since its normal is just [-dy,dx].
Assuming n-by-1 arrays x and y with the coordinates, you do this as follows:
%# take the time derivative
dx = (x(3:end)-x(1:end-2))/2;
dy = (y(3:end)-y(1:end-2))/2;
%# create the normal vector
nvec = [-dy,dx];
%# normalize the normal vector
nvecN = bsxfun(#rdivide,nvec,sqrt(sum(nvec.^2,2)));
%# take the arc-cosine to get the angle in degrees (acos for radian)
%# of the projection of the normal vector onto the x-axis
angle = acosd(nvecN(:,1));

Fast Fourier transform in MATLAB

I have found a bit of code in MATLAB:
y = fft(y, nfft);
Where y is a 512x443 two-dimensional array and nfft = 512.
I thought that fft is for a one-dimensional array and for a two-dimensional array there should be fft2, but fft is working. How is that possible?
From the documentation (emphasis mine):
Y = fft(x) returns the discrete Fourier transform (DFT) of vector x, computed with a fast Fourier transform (FFT) algorithm.
If the input X is a matrix, Y = fft(X) returns the Fourier transform of each column of the matrix.
fft actually takes an (optional) third argument: dim. This tells it which dimension to perform the FFT on.
If you don't specify it, dim will default to the "first nonsingleton dimension". So you're getting a one-dimensional FFT of all the columns of your two-dimensional array.