Adjoint / inverse nufft

20 views (last 30 days)
Victor Churchill
Victor Churchill on 13 Oct 2023
Commented: Paul on 16 Oct 2023
Here's a simple example of the behavior based on the documentation for nufft:
t = [0:300 500.5:700.5];
S = 2*sin(2*pi*0.02*t) + sin(2*pi*0.1*t);
X = abs(S + rand(size(t))); % true signal
n = length(t);
f = (0:n-1)/n;
Y = nufft(X,t,f);
X0 = real(nufft(Y,f,-t))/n; % reconstructed signal
figure,plot(t,X); hold on; plot(t,X0)
How can I compensate for the nonuniformity in t to get X0 to match X?
One answer to this post (link) mentions a "density compensation matrix", but no details and there are no other outputs from the nufft function. I assume this has something to do with the relationship (interpolation or whatever is going on behind the scenes) of the non-uniform to uniform grid.
This plot shows that the difference indeed differs over t.
figure,plot(t,abs(X-X0))

Accepted Answer

Vilnis Liepins
Vilnis Liepins on 13 Oct 2023
Hi Victor,
You can improve the inverse of NUFFT if take into account that the length of signal in time is 700.5 sec and choose, e.g,
n=701; You should also select frequencies that meet the Nyquist limit of 0.5 Hz, f=(-ceil((n-1)/2):floor((n-1)/2))/n;
However, the inverse of NUFFT will not match to X and if you apply a jitter to t = t + rand(1,length(t))/2; then the differences will get more visible.
If you want to get exactly the same signal back, I recommend trying the EDFT code in fileexchange https://se.mathworks.com/matlabcentral/fileexchange/11020-extended-dft , then you get picture
Moreover, you can apply Matlab IFFT to the result of EDFT and get the signal resampled on regular grid and the gap filled with interpolated values
My code
t = [0:300 500.5:700.5];
% t = t + rand(1,length(t))/2; % add jitter to t
S = 2*sin(2*pi*0.02*t) + sin(2*pi*0.1*t);
X = abs(S + rand(size(t)));
%n = length(t);
n=701; % The last sample taken at 700.5 sec
%f = (0:n-1)/n;
f=(-ceil((n-1)/2):floor((n-1)/2))/n; % Nyquist frequency = 0.5 Hz
% NUFFT
Y_NUFFT = nufft(X,t,f);
S_NUFFT=Y_NUFFT/length(X); % Power Spectrum
% EDFT
[Y_EDFT,S_EDFT,st]=edft(X,f,[],[],t);
figure(1) %Plot Power Spectrums
plot(f,abs(S_NUFFT)), hold on, plot(f,abs(S_EDFT)), hold off
X0 = real(nufft(Y_NUFFT,f,-t))/n; % reconstructed signal NUFFT
figure(2),plot(t,X), hold on, plot(t,X0), hold off
X1 = real(iedft(Y_EDFT,f,t)); % reconstructed signal IEDFT
figure(3),plot(t,X), hold on, plot(t,X1), hold off
X2 = real(ifft(ifftshift(Y_EDFT))); % reconstructed signal by IFFT on uniform grid
figure(4),plot(t,X), hold on, plot(0:length(f)-1,X2), hold off
I hope it helps. Don't hesitate to ask if you have any questions.
  9 Comments
Vilnis Liepins
Vilnis Liepins on 16 Oct 2023
Edited: Vilnis Liepins on 16 Oct 2023
In my previous comment, i suggest to calculate Sampling Frequency based on Mean Sampling Period and get the value Fs=10 Hz for your data. The second point you miss is that frequencies should be calculated as f = Fs*(-ceil((N-1)/2):floor((N-1)/2))/N; and the picture i got looks much better
rng(100)
t = [0 sort(rand(1,8)) 2];
Fs=10;
N=424;
f = Fs*(-ceil((N-1)/2):floor((N-1)/2))/N;
x = rand(1,numel(t));
x0 = nufft(nufft(x,t,f),f,-t)/N;
figure
plot(t,x,'-o',t,real(x0),'-o')
Paul
Paul on 16 Oct 2023
Ah yes. In this comment there was no explicit use of Fs in the expression for f, but now I see that Fs is used in this comment. In the former Fs=1 becasue of the nature of the data in the problem posted by @Victor Churchill. Thanks for pointing that out.

Sign in to comment.

More Answers (2)

Matt J
Matt J on 13 Oct 2023
Edited: Matt J on 13 Oct 2023
If these are your actual data sizes, an optimization approach seems to work not too badly:
t = [0:300 500.5:700.5];
S = 2*sin(2*pi*0.02*t) + sin(2*pi*0.1*t);
X = abs(S + rand(size(t))); % true signal
n = length(t);
f = (0:n-1)/n;
Y = nufft(X,t,f);
X0=fsolve(@(x)resFunc(x,t,f,Y), rand(size(X)) );
Warning: Trust-region-dogleg algorithm of FSOLVE cannot handle non-square systems; using Levenberg-Marquardt algorithm instead.
Equation solved. fsolve completed because the vector of function values is near zero as measured by the value of the function tolerance, and the problem appears regular as measured by the gradient.
plot(t,X,'--b',t,X0,'xr')
function r=resFunc(x,t,f,Y)
r=Y-nufft(x,t,f);
r=[real(r);imag(r)];
end

Matt J
Matt J on 13 Oct 2023
If your t,f sampling is going to be reused, it may be gainful to use an algebraic inversion with the help of this FEX download,
Note that the C matrix depends only on t and f and can be re-used.
t = [0:300 500.5:700.5];
S = 2*sin(2*pi*0.02*t) + sin(2*pi*0.1*t);
X = abs(S + rand(size(t))); % true signal
n = length(t);
f = (0:n-1)/n;
Y = nufft(X,t,f);
C=func2mat(@(z) nufft(z,t,f), X);
C=[real(C);imag(C)];
d=[real(Y(:));imag(Y(:))];
X0=C\d;
plot(t,X,'-bx',t,X0,'-r')
  1 Comment
Victor Churchill
Victor Churchill on 13 Oct 2023
Thanks for both of your answers, Matt J. While they indeed have expanded my understanding of the function, my priority here was inverting the nufft using the nufft function itself. Thanks again!

Sign in to comment.

Categories

Find more on Mathematics in Help Center and File Exchange

Tags

Products


Release

R2023b

Community Treasure Hunt

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

Start Hunting!