Fast Fourier transform in MATLAB - 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.

Related

Difference between fft points and fft in vector

Given a vector X of length L, what is the difference between fft(X) and fft(X,L)?
Does it mean we are taking the fft on L points when using fft(X) and the fft of vector L when doing fft(X,L)?
As per the documentation on fft:
Y = fft(X) computes the discrete Fourier transform (DFT) of X using a fast Fourier transform (FFT) algorithm.
If X is a vector, then fft(X) returns the Fourier transform of the vector.
Y = fft(X,n) returns the n-point DFT. If no value is specified, Y is the same size as X.
If X is a vector and the length of X is less than n, then X is padded with trailing zeros to length n.
If X is a vector and the length of X is greater than n, then X is truncated to length n.
Meaning that in case you have a vector X of length L, fft(X) and fft(X,L) are equivalent.
The interesting bit comes when you call fft(X,n) with n~=L.
If n<L your input vector X will be trucated, i.e. you will use less measurements and get a shorted Fourier sequence.
If n=L; discussed above
If n>L your vector X is zero-padded: X = [X zeros(L-n,1)] (for a row vector X). What this will do is interpolation in the frequency domain. This is most easily seen from the formulae at the bottom of the documentation:
if we increase n, we get a longer vector Y. However, since you padded zeros, and not a continuation of the signal, its Fourier transform will be an interpolation between frequencies. Normally you'd have the frequencies as given by W(n) running from your sampling frequency, f_s all the way up to f_n = Nyquist/2 in L steps, i.e. as many data points as you have: linspace(F_s,f_n,L). What you are doing when zero padding is putting more points into the same space: linspace(F_s,f_n,n), without adding information.

Why there is not dxdy factor in fft2() function of 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.

Using interpolation in matlab

I have two vectors (latg and ch4): latg is a 18225x1 vector, and ch4 is a 91269x1 vector. I want to size the latg vector so that it matches the size of the ch4 vector by interpolating between the data points.
How do I go about this? Do I use the interp1 function?
Yes indeed the interp1 function can be used. I assume you want to linearly interpolate extra datapoints between the limiting values of the smaller array.
% Vector to be upscaled
vector1 = latg;
% Number of elements in new vector (vector2, nr of elements same as in ch4)
n_vector2 = length(ch4);
vector2 = interp1( linspace(0,1,length(vector1)), vector1, linspace(0,1,n_vector2));
So now vector2 is the same of vector latg except that it contains the same amount of points as vector ch4 obtained by linear interpolation.
Kind regards,
Ernst Jan

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

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);