View Raw SPL
/*****************************************************************************
* *
* PHASEDIFF.SPL Copyright (C) 2015 DSP Development Corporation *
* All Rights Reserved *
* *
* Author: Randy Race *
* *
* Synopsis: Computes the phase difference between two sinusoids *
* *
* Revisions: 28 Dec 2015 RRR Creation *
* *
*****************************************************************************/
#if @HELP_PHASEDIFF
PHASEDIFF
Purpose: Computes the phase difference between two sinusoids.
Syntax: PHASEDIFF(s1, s2, freq)
(p, f, mag1, mag2) = PHASEDIFF(s1, s2, freq)
s1 - A series, the first input sinusoid.
s2 - A series, the second input sinusoid.
freq - Optional. A real, the known frequency. Defaults to
-1, estimate the frequency.
Returns: A real, the phase difference in radians.
(p, f, mag1, mag2) = PHASEDIFF(s1, s2, freq) returns the
phase difference, frequency and magnitudes of the two
sinusoids.
Example:
W1: gcos(1000, 1/1000, 4)
W2: gcos(1000, 1/1000, 4, -pi/3)
W3: {phasediff(w1, w2)}
W3 == -1.047198 or -pi/3.
Example:
W1: gcos(1000, 1/1000, 4) + gnorm(1000, 1/1000, 4) / 10
W2: gcos(1000, 1/1000, 4, -pi/3) + gnorm(1000, 1/1000, 4) / 10
W3: {phasediff(w1, w2)}
W3 == -1.044738 or approximately -pi/3.
Example:
W1: 10 * gcos(1000, 1/1000, 4)
W2: 3 * gcos(1000, 1/1000, 4, -pi)
W3: (p, f, m1, m2) = phasediff(w1, w2);{p, f, m1, m2}
W3 == {-3.141593, 4, 10, 3} the phase difference,
frequency and magnitudes of the input sinusoids in W1
and W2.
Remarks:
PHASEDIFF uses SINFIT3 to compute the least squares fit
of a sinusoid to a known frequency as per the IEEE 1241
Standard. If the input frequency is unspecified, the
frequency is estimated by locating the dominant
frequency of the FFT and using analytical rectangular
window interpolation to determine the precise frequency.
The FFT interpolation handles estimated frequencies that
do not lie on a unique FFT bin.
The phase difference is always negative and expressed in
radians.
See Also:
Addphase
Angle
Fft
Phase
Sinfit3
#endif
/* phase difference in radians of two sinusoids with the same frequency */
ITERATE phasediff(s1, s2, f)
{
local fit1, fit2, coef1, coef2, p;
if (argc < 3)
{
if (argc < 2)
{
if (argc < 1) error("phasediff - input series required");
s2 = {};
}
else if (isscalar(s2))
{
f = s2;
s2 = {};
}
else
{
f = -1;
}
}
/* sin fit */
(fit1, coef1) = sinfit3(s1, f);
if (iscomplex(coef1))
{
/* can't fit a sin */
coef1 = zeros(length(coef1), 1);
}
if (length(s2) > 0)
{
/* phase difference, use frequency of s1 */
(fit2, coef2) = sinfit3(s2, coef1[2]);
if (iscomplex(coef2))
{
/* can't fit a sin */
coef2 = zeros(length(coef2), 1);
}
}
else
{
/* set coef2 to find phase of input */
coef2 = coef1;
/* phase */
coef2[3] = 0;
}
/* phase difference in radians */
p = coef2[3] - coef1[3];
/* force difference to be negative */
if (p > 0) p -= 2 * pi;
if (outargc > 1)
{
/* phase difference, frequency, magnitudes */
return(p, coef1[2], coef1[1], coef2[1]);
}
else
{
/* just phase difference */
return(p);
}
}