Adjoint / inverse nufft
25 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
Victor Churchill
am 13 Okt. 2023
Kommentiert: Paul
am 16 Okt. 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))
0 Kommentare
Akzeptierte Antwort
Vilnis Liepins
am 13 Okt. 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 Kommentare
Vilnis Liepins
am 16 Okt. 2023
Bearbeitet: Vilnis Liepins
am 16 Okt. 2023
The answer on your comment https://se.mathworks.com/matlabcentral/answers/2032659-adjoint-inverse-nufft#comment_2923034
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
am 16 Okt. 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.
Weitere Antworten (2)
Matt J
am 13 Okt. 2023
Bearbeitet: Matt J
am 13 Okt. 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)) );
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
0 Kommentare
Matt J
am 13 Okt. 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')
Siehe auch
Kategorien
Mehr zu Fourier Analysis and Filtering finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!