Can MATLAB do a 2-D FFT on a uniform parallelogram grid of measured points?
144 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Jerry Guern
el 18 de Nov. de 2024 a las 23:16
Comentada: Chris Turnes
hace alrededor de 13 horas
I have some measurements in slant coordinates, and I need to project them into the ground plane. When I just project the slant grid into ground coords, it ends up a uniform parallelogram grid. In order to form an image, I need to Fourier Transform my parallelogram grid of measured values into ground freq domain, the Inv FT that into ground time domain. The code below does this successfully, using a toy function f(x,y) = cos(3x-4y) in place of measurements. But in this code, I calculated non-fast Four Transform coefficients one at a time.
EDIT: I want to emphasize, this code does what I need, calculating the varialbe 'pfd' in Figure 41, I just need to know if some MATLAB function can somehow do it with a Fast Fourier Transform.
dim1 = 29; % Resolution of image we're creating
dim2 = 31;
% This block just creates xs & ys, coords of a random parallelogram of
% measured sample points.
theta1 = rand * pi/4;
theta2 = theta1 * (.5 + rand);
M = [2*(1+rand)/3 * [cos(theta1) sin(theta1)]; 2*(1+rand)/3 * [-sin(theta2) cos(theta2)]];
[Xs, Ys] = meshgrid(linspace(-3,3,300),linspace(-3,3,300));
gpt = M * [Xs(:)';Ys(:)']; %These points sprawl out all around the image area.
% Find the measured points that fall within the image.
keep = gpt(1,:)>-1/(2*dim1) & gpt(1,:)<1-1/(2*dim1) & gpt(2,:)>-1/(2*dim2) & gpt(2,:)<1-1/(2*dim2);
xs = gpt(1,keep);
ys = gpt(2,keep);
figure(1); scatter(xs,ys,.5); title('measured points within image')
% Create image pixels
[Xq, Yq] = meshgrid(linspace(0,1-1/(dim1),dim1),linspace(0,1-1/(dim2),dim2));
%Ratio of measured points within image to image pixels.
oversample = sum(keep) / (dim1 * dim2)
% Wave numbers for Fourier Transform
kx = [0 [1:floor(dim1/2)] [-floor(dim1/2) : -1]];
ky = [0 [1:floor(dim2/2)] [-floor(dim2/2) : -1]]';
% For this toy problem, use a closed form function in place of measured
% data. Calclate this function first for our image points.
td = cos(3*Xq-4*Yq);
% Calculate the frequency domain, from our td above and for our toy
% measured data.
jfd = zeros(size(td));
nufd = zeros(size(td));
for j = 1:dim1
for k = 1:dim2
% Calculate the non-fast FFT, just for comparison
jfd(k,j) = sum(sum(td .* exp(-1i*2*pi*(kx(j)*Xq+ky(k)*Yq))));
% Calculate same terms, but from our measured samples.
pfd(k,j) = sum(cos(3*xs-4*ys) .* exp(-1i*2*pi*(kx(j)*xs+ky(k)*ys)));
end
end
pfd = pfd / oversample;
figure(39); surf(Xq,Yq,td); title('orig function');
figure(40); surf(Xq,Yq,ifft2(jfd)); title('ifft2 of non-fast FT for comparison');
figure(41); surf(Xq,Yq,real(ifft2(pfd))); title('real of ifft2 of pfd');
So, is there any MATLAB function that do the same thing, calculate that pfd, but using an FFT?
I thought at one time that nufftn() did this, but I honestly couldn’t make any sense of the vague documentation or the comments in the code.
2 comentarios
Paul
el 19 de Nov. de 2024 a las 3:22
Hi Jerry,
If I'm following correctly, it seems that xs and ys define 1956 pairs of non-gridded points (xs and ys are both 1 x 1956). Is that the intent of the code? If so, my reading of nufftn is the "time" variables don't have to be equally spaced in each dimension, but they still have to be gridded, i.e., they can't be scattered points. In other words, we can have
t1 = sort(rand(1,N));
t2 = sort(rand(1,M));
and the function to be evaluated would be something like
z = cos(t1) + sin(t2');
Same thing for the frequency variables, i.e., they define a non-uniformly spaced grid (in general).
I'd try running some code here, but Answers doesn't seem to executing code right now (at least not for me).
Respuesta aceptada
Chris Turnes
el 19 de Nov. de 2024 a las 17:20
Yes, nufftn can compute those two loops:
jfd2 = reshape(nufftn(td, { Yq(:,1), Xq(1,:) }, { ky kx }), dim2, dim1);
pfd2 = reshape(nufftn(cos(3*xs-4*ys), [ys(:) xs(:)], { ky kx }), dim2, dim1) / oversample;
If you compute norm(jfd - jfd2) and norm(pfd - pfd2) you'll find they match to within around 1e-12, 1e-13 in value.
25 comentarios
Paul
hace alrededor de 13 horas
I was wondering if my example was the problem. Thanks for pointing that out. I was more focused on the fact that Z1 and Z2 had different dimensions but nufftn didn't seem to care.
In summary, to make sure I'm clear:
If the input sample points are specified as a cell array {} of D vectors, then the input array must be either
a) an N-D array as would be formed from operating on the ndgrid of those D vectors, or
b) the same as (a) and then reshaped into a vector
x = 0:5; y = 0:7; z = 0:.1:1; f1 = (0:10)/11; f2 = (0:11)/12; f3 = (0:4)/5; f = {f1,f2,f3};
[X1,Y1,Z1] = ndgrid(x,y,z);
A1 = X1.^2 + Y1 + 5*Z1;
out1 = nufftn(A1,{x,y,z},f);
out2 = nufftn(A1(:),{x,y,z},f);
out3 = nufftn(A1(:).',{x,y,z},f);
isequal(out1,out2,out3)
I'll still suggest that if the sample points are specified with {} and the input array is a matrix or N-D array, then nufftn should throw an error if the dimensions of the input array don't line up with the lengths of the sample point vectors.
If the query points are specified as a cell array {} of D vectors, then the output will be a column vector formed (approximately) as if we are first forming the N-D array from an ndgrid of query points and then reshaping into a column vector
[F1,F2,F3] = ndgrid(f1,f2,f3);
out1 = nufftn(A1,{x,y,z},f);
out2 = nufftn(A1,{x,y,z},[F1(:),F2(:),F3(:)]);
isequal(out1,out2)
norm(out1-out2)
out1 and out2 are slightly different because nufftn goes down different code paths? (similarly for nz1a and nz1c in your first example?)
"Generally, because of the confusion that can result with meshgrid, ndgrid is simpler to use."
I think I'd stay away from meshgrid altogether when dealing with nufftn.
Chris Turnes
hace alrededor de 13 horas
Yes, your understanding is correct. Thanks for pointing out the inconsistencies between the doc and behavior, and I'll definitely pass on your feedback.
Más respuestas (1)
Matt J
el 19 de Nov. de 2024 a las 15:41
Editada: Matt J
el 19 de Nov. de 2024 a las 15:54
I need to Fourier Transform my parallelogram grid of measured values into ground freq domain, the Inv FT that into ground time domain.
I don't know what "ground time/freq" domain means.
I think if you just pretend the samples are Cartesian and take the FFT and IFFT, you will obtain the non-Fourier domain result sampled on your original parallelgoram. You can then just use griddata or scatteredInterpolant to reample that, if needed.
2 comentarios
Matt J
el 19 de Nov. de 2024 a las 17:10
I mean,
slanted = ifft2( some_transform( fft2(td) ) );
ground = griddata(___,slanted,___)
Ver también
Categorías
Más información sobre Signal Generation and Preprocessing en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!