Can MATLAB do a 2-D FFT on a uniform parallelogram grid of measured points?

144 visualizaciones (últimos 30 días)
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
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).
Jerry Guern
Jerry Guern el 19 de Nov. de 2024 a las 14:35
Thanks for the reply. xs and ys will always have the same length, but that length will be different in each run, because they're on a randomly oriented grid . But it is always a uniform grid, albeit a slanted parallelogram grid. If you run the code, Figure 1 will show you what I mean. I tried to use nufftn() for this, but I couldn't make any sense of the documentation or code comments.

Iniciar sesión para comentar.

Respuesta aceptada

Chris Turnes
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
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)
ans = logical
1
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)
ans = logical
0
norm(out1-out2)
ans = 7.2127e-11
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
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.

Iniciar sesión para comentar.

Más respuestas (1)

Matt J
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
Jerry Guern
Jerry Guern el 19 de Nov. de 2024 a las 16:38
I'm creating an image in ground plane coordinates. When I said ground time/freq domain, the time domain would be the values of the ground plane image I'm trying to create, and the freq domain is the fft of that. I said ground to contrast it with the slant plane, the coordionates I'm projecting into ground plane. I don't know what you meant by what you said. Could you show me in code?
Matt J
Matt J el 19 de Nov. de 2024 a las 17:10
I mean,
slanted = ifft2( some_transform( fft2(td) ) );
ground = griddata(___,slanted,___)

Iniciar sesión para comentar.

Categorías

Más información sobre Signal Generation and Preprocessing en Help Center y File Exchange.

Productos


Versión

R2024a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by