LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

HELP: how do I correctly apply a phase shift to a waveform?

In a system simulation that I've been working on I am unsuccessfully attempting to apply a uniform
phase shift to a non-periodic waveform. What I've tried to do is take the Fourier transform of the
signal, apply an offset to the phase and then take the inverse transform of that. I thought the output
of this process should be my original waveform with all of its frequency components delayed by the same
number of radians (different amounts of time). However, I am not getting this result. I've tried this
in both LabVIEW and Matlab. Here's a Matlab implementation using a sine wave as the input:

t = [0:pi/128:4*pi];
x = sin(t);
X = fft(x);
MX = abs(X);
AX = angle(X);
UAX = unwrap(AX) - pi/2;
Y = MX .* exp(j*UAX);
y
= ifft(Y);
plot(real(y));

I've observed that with no phase offset the imaginary part of y is zero and the real part is
a replica of x. However, when I apply a phase offset (pi/2 in the above example) the imaginary
part becomes non-zero and the real part no longer resembles the input. What the heck am I doing
wrong?

TIA
Hugh
0 Kudos
Message 1 of 19
(8,266 Views)
Since they rewrote all the fft algorithms for LV 6.1, you can no longer use the realFFT for this for some reason. (It worked fine up to LV 6.0 IF the data was an integral power of two (and fast FFT could be used). It was always broken for the discrete FT that was use if the input had a random number of points).


What you should do is use the complex fft and ifft!


As input, you must build a complex waveform:

real part: your function
imaginary part: (hilbert transform) of your function

(The hilbert transform is a nothing more than your phase shift fixed at 90degrees)

After your phase shift and complex ifft, just extract the real part and you're done.

Good luck.
0 Kudos
Message 2 of 19
(8,266 Views)
Here is an example code (applied to a Lorentzian and a sine function).
Message 3 of 19
(8,266 Views)
"Hugh" wrote in message
news:3D2C4C06.2080607@hotmail.com...
> In a system simulation that I've been working on I am unsuccessfully
attempting to apply a uniform
> phase shift to a non-periodic waveform. What I've tried to do is take the
Fourier transform of the
> signal, apply an offset to the phase and then take the inverse transform
of that. I thought the output
> of this process should be my original waveform with all of its frequency
components delayed by the same
> number of radians (different amounts of time). However, I am not getting
this result. I've tried this
> in both LabVIEW and Matlab. Here's a Matlab implementation using a sine
wave as the input:
>
> t = [0:pi/128:4*pi];
> x = sin(t);
> X = fft(x);
> MX = abs(X);
> AX = angle(X);
> UAX = unwrap(AX) - pi/2;
> Y = MX .* exp(j*UAX);
> y = ifft(Y);
> plot(real(y));
>
> I've observed that with no phase offset the imaginary part of y is zero
and the real part is
> a replica of x. However, when I apply a phase offset (pi/2 in the above
example) the imaginary
> part becomes non-zero and the real part no longer resembles the input.
What the heck am I doing
> wrong?

Hugh,

Without fixing your code one way or another, here are a couple of things to
consider:

It looks like you're trying to solve a problem that's been dealt with often.
Take a look at Hilbert transformer design. That's another term for a 90
degree phase shifter. You will end up with a filter. You can design a
Hilbert transformer using the Parks-McClellan filter design program.

Some tutorial information that may be useful:

As a backdrop sort of viewpoint, a system yielding pure constant phase shift
of a general, multifrequency or broadband signal isn't physically
realizable. Also, consider a pure time delay which will not perturb the
waveform at all but does change the relative phase at all frequencies. The
time delay is the derivative of the phase shift. Note that a time delay is
also a perfect all-pass and a constant phase shifter would also might be
viewed as an all-pass.

The Fourier transform of a time delay is e^(-j*omega*delay). This is also
known as the time-shifting property and a useful Fourier transform pair. So
a pure delay gives a phase shift of omega*delay and the derivative with
respect to omega is "delay".

If you apply a constant to the phase terms [again emphasis on the plural] as
you have done, you are delaying each frequency differently. That means the
individual components can no longer add to reconstruct the original time
series.

You might also benefit from knowing a few transform pair identities:

A real and even function transforms into a real function.
A general real function transforms into a complex function.
An real and odd function transforms into an imaginary function.

So, by changing the phase term by a constant changes both the real and
imaginary parts while keeping the amplitude constant. The result is some
general complex function which will have a complex transform. Also probably
not what you want - to have a complex time series.

You might also look at your code to make sure it's doing what you want. I
would be suspicious of "unwrap" unless I'd tested it.
Also, it would help you get better answers if you tell us what you're trying
to do with this thing - more the system context.

Fred
0 Kudos
Message 4 of 19
(8,266 Views)
On Wed, 10 Jul 2002 09:00:22 -0600, Hugh wrote:

>In a system simulation that I've been working on I am unsuccessfully attempting to apply a uniform
>phase shift to a non-periodic waveform. What I've tried to do is take the Fourier transform of the
>signal, apply an offset to the phase and then take the inverse transform of that. I thought the output
>of this process should be my original waveform with all of its frequency components delayed by the same
>number of radians (different amounts of time). However, I am not getting this result. I've tried this
>in both LabVIEW and Matlab. Here's a Matlab implementation using a sine wave as the input:
>
>t = [0:pi/128:4*pi];
>x = sin(t);
>X = fft(x);
>MX = abs(X);
>AX = angle(X);
>UAX = unwrap(AX) -
pi/2;
>Y = MX .* exp(j*UAX);
>y = ifft(Y);
>plot(real(y));
>
>I've observed that with no phase offset the imaginary part of y is zero and the real part is
>a replica of x. However, when I apply a phase offset (pi/2 in the above example) the imaginary
>part becomes non-zero and the real part no longer resembles the input. What the heck am I doing
>wrong?
>
> TIA
> Hugh
>

Hi Hugh,
If you want a constant time delay, shift the phase of
the spectral components by values that are proportional
to their individual frequencies. That is if you shift
a 100 Hz component by 20 degrees, shift the 200 hz component
by 40 degrees. The amount of shift vs. freq should
look like this:


^ *
| | *
phase | *
shift | *
| *
-Fs/2 ------*-------- +Fs/2 ------> Freq
0 * |
* |
* |
* |

* |

The slope of that phase shift function (line) will
be proportional to the resultant time delay in the
time domain. (That "0" above means zero Hz.)

God Luck,
[-Rick-]
0 Kudos
Message 5 of 19
(8,266 Views)
Rick Lyons wrote:
>
> On Wed, 10 Jul 2002 09:00:22 -0600, Hugh wrote:
>
> >In a system simulation that I've been working on I am unsuccessfully attempting to apply a uniform
> >phase shift to a non-periodic waveform. What I've tried to do is take the Fourier transform of the
> >signal, apply an offset to the phase and then take the inverse transform of that. I thought the output
> >of this process should be my original waveform with all of its frequency components delayed by the same
> >number of radians (different amounts of time). However, I am not getting this result. I've tried this
> >in both LabVIEW and Matlab. Here's a Matlab implementation using a sine wave as the input:
> >
> >t = [0:pi/128:4*pi];
> >x = sin(t);
> >X = fft(x);
> >MX = abs(X);
> >AX = angle(X);
> >UAX = unwrap(AX) - pi/2;
> >Y = MX .* exp(j*UAX);
> >y = ifft(Y);
> >plot(real(y));
> >
> >I've observed that with no phase offset the imaginary part of y is zero and the real part is
> >a replica of x. However, when I apply a phase offset (pi/2 in the above example) the imaginary
> >part becomes non-zero and the real part no longer resembles the input. What the heck am I doing
> >wrong?
> >
> > TIA
> > Hugh
> >
>
> Hi Hugh,
> If you want a constant time delay, shift the phase of
> the spectral components by values that are proportional
> to their individual frequencies. That is if you shift
> a 100 Hz component by 20 degrees, shift the 200 hz component
> by 40 degrees. The amount of shift vs. freq should
> look like this:
>
>
> ^ *
> | | *
> phase | *
> shift | *
> | *
> -Fs/2 ------*-------- +Fs/2 ------> Freq
> 0 * |
> * |
> * |
> * |
> * |
>
> The slope of that phase shift function (line) will
> be proportional to the resultant time delay in the
> time domain. (That "0" above means zero Hz.)
>
> God Luck,
> [-Rick-]

Rick,

I think a careful reading will show that he wants the same phase shift
at all frequencies, and different time delays. For a 90-degree shift, a
Hilbert transformer does that in the time domain, and the real/imaginary
switch I mentioned earlier does it in the frequency domain. Mike's more
general frequency-domain transformation can be used for any angle.

Jerry
--
"The rights of the best of men are secured only as the
rights of the vilest and most abhorrent are protected."
-Chief Justice Charles Evans Hughes, around when I was born.

"They that give up essential liberty to obtain a little temporary
safety deserve neither liberty nor safety." -Benjamin Franklin, 1759
����������������������������������������������������������������������
0 Kudos
Message 6 of 19
(8,266 Views)
On Wed, 10 Jul 2002 20:05:53 -0400, Jerry Avins wrote:

(snipped)
>
>I think a careful reading will show that he wants the same phase shift
>at all frequencies, and different time delays. For a 90-degree shift, a
>Hilbert transformer does that in the time domain, and the real/imaginary
>switch I mentioned earlier does it in the frequency domain. Mike's more
>general frequency-domain transformation can be used for any angle.
>
>Jerry

Aarrggh! You're right.

However, monkeying with Hugh's code I see that
his results make sense. Using the following:

clear
t = [0:pi/128:4*pi];
x = sin(t);
figure(5)
subplot(3,1,1), plot(x,'-bo')
X = fft(x);
MX = abs(X);
AX = angle(X);
UAX = unwrap(AX) - pi/2;
Y = MX .* exp(j*UAX);
y = ifft(Y);
s
ubplot(3,1,2), plot(real(y));
subplot(3,1,3), plot(imag(y));

The final time-domain real part is just
computational errors on the order of
10^(-13). They should be all zeros.
The final time-domain imaginary part
is sinusoidal going negative right after t = 0.
This is correct. Think of Euler's equations for
a sinewave. After the -pi/2 phase shift, the
two complex exponentials, at t = 0, are no longer
pointing North and South, but are pointing East and
West. As time progresses beyond zero, the sum of
the two complex exponentials will sum to a
negative imaginary value.

Hugh started with a real-only time-domain sequence so
its spectral phases will be conjugate symmetrical.
That phase shift of -pi/2 made the spectral
phase asymetrical, which leads to a non-zero
imaginary part in the time domain.

[-Rick-]
0 Kudos
Message 8 of 19
(8,266 Views)
I haven't played with MATLAB for a quit long time. Could you tell what
the function unwrap(.) means? Generally, if you want to keep the
converted signal as real as the original one, you have to shift the
positive and negative frequency components by the phases of opposite
signs, like the Hilbert transform (pi/2 shift) in the special case.
Otherwise, the converted signal will be complex.

Ying

Hugh wrote in message news:<3D2C4C06.2080607@hotmail.com>...
> In a system simulation that I've been working on I am unsuccessfully attempting to apply a uniform
> phase shift to a non-periodic waveform. What I've tried to do is take the Fourier transform of the
> signal, apply an offset to the phase and then take the inverse transform of that. I thought
the output
> of this process should be my original waveform with all of its frequency components delayed by the same
> number of radians (different amounts of time). However, I am not getting this result. I've tried this
> in both LabVIEW and Matlab. Here's a Matlab implementation using a sine wave as the input:
>
> t = [0:pi/128:4*pi];
> x = sin(t);
> X = fft(x);
> MX = abs(X);
> AX = angle(X);
> UAX = unwrap(AX) - pi/2;
> Y = MX .* exp(j*UAX);
> y = ifft(Y);
> plot(real(y));
>
> I've observed that with no phase offset the imaginary part of y is zero and the real part is
> a replica of x. However, when I apply a phase offset (pi/2 in the above example) the imaginary
> part becomes non-zero and the real part no longer resembles the input. What the heck am I doing
> wrong?
>
> TIA
> Hugh
0 Kudos
Message 7 of 19
(8,266 Views)
On 11 Jul 2002 01:02:01 -0700, ying@omnexcontrols.com (Ying Xiong)
wrote:

>I haven't played with MATLAB for a quit long time. Could you tell what
>the function unwrap(.) means?

Hi Ying,
The "unwrap()" command removes the
discontinuities (of 2pi radians) in phase
angle values that occur when the arctan is
performed.

It turns a phase plot like this

* * * *
* * * *
* * * *
* * * *
freq -->

to this

*
*
*
*
*
*
*
*
*
*
*
*
freq -->


>Generally, if you want to kee
p the
>converted signal as real as the original one, you have to shift the
>positive and negative frequency components by the phases of opposite
>signs, like the Hilbert transform (pi/2 shift) in the special case.
>Otherwise, the converted signal will be complex.

You bet.

[-Rick-]
0 Kudos
Message 9 of 19
(8,266 Views)
On 11 Jul 2002 01:02:01 -0700, ying@omnexcontrols.com (Ying Xiong)
wrote:

Hi Ying,
check out page 19 of the document at:

http://klabs.org/richcontent/MAPLDCon00/Presentations/Session_A/A1_Bassett_S.PDF

Regards,
[-Rick-]
0 Kudos
Message 10 of 19
(8,266 Views)