Differentiating in one direction using FFT2
24 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Starting from a univariateL-periodic function u, sampled at
evenly-spaced points in
, and stored in the vector u, the following function approximates the first derivative
, using FFT
function du = FFTDiff(u,n,L)
% Frequency vector
k = (2*pi/L) * [0:n/2-1, -n/2:-1]';
% Compute FFT
uHat = fft(u);
% Compute the derivative in the frequency domain, and back to physical domain
du = ifft( 1i * k .* uHat, 'symmetric');
end
First of all, if you see any alternative ways on how to write the function above, your feedback is welcome. I am now in the process of writing a function that does the following: starting from a bivariate, periodic function u, sampled at
evenly spaced points in
, I want to write a function that approximates
(hence the partial derivative with respect to x), using FFT2. The main problem I have is that I don't quite know how FFT2 outputs the wavenumbers
and
. It's a bit tricky to understand from the documentation, and I wonder if you have some ideas on how to do that.
3 commentaires
Paul
le 19 Fév 2025
Hi Daniele,
Can you show how this code works with a simple input? I'm running into an error.
Is the code supposed to work for L even and L odd?
L = 20; % period of function
l = 0:L; % n + 1 equally spaced points in [0,L]
n = numel(l) - 1; % n
u = sin(2*pi/20*l).'; % u
du = FFTDiff(u,n,L);
figure
plot(l,du,'-o')
function du = FFTDiff(u,n,L)
% Frequency vector
k = (2*pi/L) * [0:n/2-1, -n/2:-1]';
% Compute FFT
uHat = fft(u);
% Compute the derivative in the frequency domain, and back to physical domain
du = ifft( 1i * k .* uHat, 'symmetric');
end
Walter Roberson
le 19 Fév 2025
k = (2*pi/L) * [0:n/2-1, -n/2:-1]';
should probably be
k = (2*pi/L) * [0:n/2-1, -n/2:-1/2]';
Réponse acceptée
Matt J
le 18 Fév 2025
Modifié(e) : Matt J
le 18 Fév 2025
fft2(u) is equivalent to fft( fft(u,[],1) ,[],2), if that helps at all.
Truthfully, it doesn't appear that you need to use fft2. Assuming the x-direction is column-oriented and the y-direction is row-oriented, you can just use your original function as is to differentiate along x.
2 commentaires
Plus de réponses (1)
Catalytic
le 18 Fév 2025
Modifié(e) : Catalytic
le 18 Fév 2025
How about this? It generalizes your original function to let you differentiate along any specified dimension dim for any nD array u -
function du = FFTDiff(u,L,dim)
arguments
u double {mustBeNonempty}
L (1,1) double
dim (1,1) double = find(size(u)>1,1) %default to first non-singleton dimension
end
n=size(u,dim);
% Frequency vector
k = (2*pi/L) * ifftshift( (0:n-1)-ceil((n-1)/2) );
e=ones(1,ndims(u)); e(dim)=n;
k=reshape(k,e);
% Compute FFT
uHat = fft(u,[],dim);
% Compute the derivative in the frequency domain, and back to physical domain
du = ifft( 1i * k .* uHat, [],dim,'symmetric');
end
2 commentaires
Walter Roberson
le 18 Fév 2025
I think your code might possibly have some trouble of u is empty. In that case, size(u, find(size(u)>1,1)) becomes size(u,[]) which returns [] . But [] cannot be stored in something size (1,1)
If you are successful in storing the [] into dim, then n=size(u,dim) would return empty, and I suspect that would lead to problems.
Voir également
Catégories
En savoir plus sur Fourier Analysis and Filtering dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!