"BRG" <br*@nowhere.org> wrote in message

news:44**********************@ptn-nntp-reader01.plus.net...

Robert Mabee wrote: BRG wrote: Mr. Ken wrote:

I am calculating the phase of an IQ signal, which are polluted by AWGN

gaussian noise.

As well as having the function atan(x), your system is likely to have

atan2(y, x) which eliminates the ambiguity except when x and y are both

zero.

atan2 avoids infinity, and I think gives a full +/-pi range, but there's

still a massive jump in the number that represents phase, so you can't

just average that number to remove noise.

[snip]

You can at +pi/2 and -pi/2, the points to which the original poster

specifically referred.

When two quadrature signals I and Q are available, atan2(Q, I) is better

than atan(Q/I) since it not only eliminates the division by zero problem

but also eliminates the artificial phase ambiguity _introduced_ by

atan(Q/I) at +pi/2 and -pi/2.

Noise will still be an issue at +pi and -pi but at least atan2(Q, I)

won't produce the incorrect results given by atan(Q/I) near +pi/2 and

-pi/2 caused by essentially ignoring a good sign on Q when I is small.

Hmm... Let's see how much of this mess it cleans up:

float CalcTheta( const JVEC2 Point1, const JVEC2 Point2 )

{

float Theta;

if ( Point2.x - Point1.x == 0 )

if ( Point2.y > Point1.y )

Theta = 0;

else

Theta = static_cast<float>( PI );

else

{

Theta = std::atan( (Point2.y - Point1.y) / (Point2.x - Point1.x) );

if ( Point2.x > Point1.x )

Theta = static_cast<float>( PI ) / 2.0f - Theta;

else

Theta = static_cast<float>( PI ) * 1.5f - Theta;

};

return Theta;

}

would become...

float CalcTheta( const JVEC2 Point1, const JVEC2 Point2 )

{

float Theta;

Theta = std::atan2( (Point2.y - Point1.y) / (Point2.x - Point1.x) );

if ( Point2.x > Point1.x )

Theta = static_cast<float>( PI ) / 2.0f - Theta;

else

Theta = static_cast<float>( PI ) * 1.5f - Theta;

};

return Theta;

}

Is that all that can be simplified?