Phase retrieval of a periodic signal, not working well
1 Ansicht (letzte 30 Tage)
Ältere Kommentare anzeigen
Tual monfort
am 14 Jun. 2024
Beantwortet: Mathieu NOE
am 14 Jun. 2024
Hello,
I am trying solve something I thought would be straigfoward, but is not so far ^^.
Let assume we have a perriodic signal as such:
x=0:400;
T=39.5;
PhiO=0.43;
y=5+cos((2*pi/T).*x+PhiO);
And the aim is to get the phase and period of this signal.
Here is for the code for the period retriaval:
%period
[pks,locs] = findpeaks(y,'MinPeakDistance',20) ;
Px_av=mean(diff(locs));
Here is the code for the phase retrieval:
h=fft(y);
plot(abs(h)) % the eleventh element is the frequency of my signal so the eleventh element of the phase "angle(h)" should be the phase of my signal. But if I plot the original signal and the retrieved one, it doesn't match well:
Phi=angle(h);
plot(x,max(y).*cos((2*pi/Px_av).*x+Phi(1,11)));hold on;plot(x,y)
Given that PhiO and Px_av are different, I tried to use interp Phi to match the right frequency, but it doesn't work either.
Do you understand what I do wrong, please ?
0 Kommentare
Akzeptierte Antwort
Mathieu NOE
am 14 Jun. 2024
here a better solution without the need for fft
you should not use the first peak in your code , as it does not correspond to the max amplitude
I prefer to make a "zero crossing" detection a mid y amplitude for both period and phase computation
notice now the period is more accurate
the phase accuracy can be improved if you choose a finer sampling rate
x=0:400;
T=39.5;
PhiO=0.43;
y=5+cos((2*pi/T).*x+PhiO);
%period
[ZxP,ZxN] = find_zc(x,y,mean(y));
Px_av=mean(diff(ZxP))
% phase
yc = interp1(x,y,ZxP);
theta = 2*pi*(1-ZxP(1)/Px_av) - pi/2
% theta = 2*pi*(ZxP(1)/Px_av) + pi/2
plot(x,y,ZxP,yc,'dr');
function [ZxP,ZxN] = find_zc(x,y,threshold)
% put data in rows
x = x(:);
y = y(:);
% positive slope "zero" crossing detection, using linear interpolation
y = y - threshold;
zci = @(data) find(diff(sign(data))>0); %define function: returns indices of +ZCs
ix=zci(y); %find indices of + zero crossings of x
ZeroX = @(x0,y0,x1,y1) x0 - (y0.*(x0 - x1))./(y0 - y1); % Interpolated x value for Zero-Crossing
ZxP = ZeroX(x(ix),y(ix),x(ix+1),y(ix+1));
% negative slope "zero" crossing detection, using linear interpolation
zci = @(data) find(diff(sign(data))<0); %define function: returns indices of +ZCs
ix=zci(y); %find indices of + zero crossings of x
ZeroX = @(x0,y0,x1,y1) x0 - (y0.*(x0 - x1))./(y0 - y1); % Interpolated x value for Zero-Crossing
ZxN = ZeroX(x(ix),y(ix),x(ix+1),y(ix+1));
end
0 Kommentare
Weitere Antworten (0)
Siehe auch
Kategorien
Mehr zu Parametric Spectral Estimation 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!