Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

identifying phase shift between signals

Tags:

I have generated three identical waves with a phase shift in each. For example:

t = 1:10800; % generate time vector fs = 1; % sampling frequency (seconds) A = 2; % amplitude P = 1000; % period (seconds), the time it takes for the signal to repeat itself f1 = 1/P; % number of cycles per second (i.e. how often the signal repeats itself every second). y1 = A*sin(2*pi*f1*t); % signal 1 phi = 10; % phase shift y2 = A*sin(2*pi*f1*t + phi); % signal 2 phi = 15; % phase shift y3 = A*sin(2*pi*f1*t + phi); % signal 3  YY = [y1',y2',y3'];  plot(t,YY) 

enter image description here

I would now like to use a method for detecting this phase shift between the waves. The point of doing this is so that I can eventually apply the method to real data and identify phase shifts between signals.

So far I have been thinking of computing the cross spectra between each wave and the first wave (i.e. without the phase shift):

for i = 1:3;     [Pxy,Freq] = cpsd(YY(:,1),YY(:,i));     coP = real(Pxy);     quadP = imag(Pxy);     phase(:,i) = atan2(coP,quadP); end 

but I'm not sure if this makes any sense.

Has anyone else done something similar to this? The desired outcome should show a phase shift at 10 and 15 for waves 2 and 3 respectively.

Any advice would be appreciated.

like image 254
Emma Tebbs Avatar asked Dec 18 '14 11:12

Emma Tebbs


People also ask

How do you find the phase shift between two signals?

The phase shift equation is ps = 360 * td / p, where ps is the phase shift in degrees, td is the time difference between waves and p is the wave period. Continuing the example, 360 * -0.001 / 0.01 gives a phase shift of -36 degrees.

What is phase shift in signals?

Phase shift simply means that the two signals are at different points of their cycle at a given time. Phase shift is measured as the angle (in degrees or radians) between two points on a circle at the same time, demonstrating the progress of each wave through its cycle.

How do you know if a phase shift is positive or negative?

If b>0 , the phase shift is negative. If b<0 , the phase shift is positive. For this argument type, the horizontal stretch/shrink is applied first; this doesn't move the original curve's starting point. Then, the curve is shifted right/left.


2 Answers

There are several ways that you can measure the phase shift between signals. Between your response, the comments below your response, and the other answers, you've gotten most of the options. The specific choice of technique is usually based on issues such as:

  • Noisy or Clean: Is there noise in your signal?
  • Multi-Component or Single-Component: Are there more than one type of signal within your recording (multiple tones at multiple frequencies moving in different directions)? Or, is there just a single signal, like in your sine-wave example?
  • Instantaneous or Averaged: Are you looking for the average phase lag across your entire recording, or are you looking to track how the phase changes throughout the recording?

Depending on your answer to these questions, you could consider the following techniques:

  • Cross-Correlation: Use the a command like [c,lag]=xcorr(y1,y2); to get the cross-correlation between the two signals. This works on the original time-domain signals. You look for the index where c is maximum ([maxC,I]=max(c);) and then you get your lag value in units of samples lag = lag(I);. This approach gives you the average phase lag for the entire recording. It requires that your signal of interest in the recording be stronger than anything else in your recording...in other words, it is sensitive to noise and other interference.

  • Frequency Domain: Here you convert your signals into the frequency domain (using fft or cpsd or whatever). Then, you'd find the bin that corresponds to the frequency that you care about and get the angle between the two signals. So, for example, if bin #18 corresponds to your signal's frequency, you'd get the phase lag in radians via phase_rad = angle(fft_y1(18)/fft_y2(18));. If your signals have a constant frequency, this is an excellent approach because it naturally rejects all noise and interference at other frequencies. You can have really strong interference at one frequency, but you can still cleanly get your signal at another frequency. This technique is not the best for signals that change frequency during the fft analysis window.

  • Hilbert Transform: A third technique, often overlooked, is to convert your time-domain signal into an analytic signal via the Hilbert transform: y1_h = hilbert(y1);. Once you do this, your signal is a vector of complex numbers. A vector holding a simple sine wave in the time domain will now be a vector of complex numbers whose magnitude is constant and whose phase is changing in sync with your original sine wave. This technique allows you to get the instantaneous phase lag between two signals...it's powerful: phase_rad = angle(y1_h ./ y2_h); or phase_rad = wrap(angle(y1_h) - angle(y2_h));. The major limitation to this approach is that your signal needs to be mono-component, meaning that your signal of interest must dominate your recording. Therefore, you may have to filter out any substantial interference that might exist.

like image 86
chipaudette Avatar answered Oct 26 '22 01:10

chipaudette


For two sinusoidal signal the phase of the complex correlation coefficient gives you what you want. I can only give you an python example (using scipy) as I don't have a matlab to test it.

x1 = sin( 0.1*arange(1024) ) x2 = sin( 0.1*arange(1024) + 0.456) x1h = hilbert(x1) x2h = hilbert(x2) c = inner( x1h, conj(x2h) ) / sqrt( inner(x1h,conj(x1h)) * inner(x2h,conj(x2h)) ) phase_diff = angle(c) 

There is a function corrcoeff in matlab, that should work, too (The python one discard the imaginary part). I.e. c = corrcoeff(x1h,x2h) should work in matlab.

like image 31
André Bergner Avatar answered Oct 26 '22 00:10

André Bergner