Beruflich Dokumente
Kultur Dokumente
Rotation
Introduction
In the DSP signal processing, time varying amplitude and phase of RF vectors are
represented in rectangular coordinates {I,Q} or X = I + jQ in complex notation.
Often we would need to rotate a vector a phase [rad]:
I rot cos
=
Qrot sin
sin I
cos Q
Often we would need to compute a phase shift linearly dependant of frequency (phase
offset + cable delay, positive or negative, in which case we evaluate:
= 0 + tdelay = 0 + 2 f tdelay
The required polymonials required to obtain IEEE 32 bit float precision are (see analysis
in attached MATLAB routines sin_poly3.m and cos_poly3.m):
COS(X) = C0 + C2*X2 + C4*X4 + C6*X6
SIN(X) = S1*X + S3*X3 + S5*X5 + S7**X7 = X*( S1 + S3*X2 + S5*X4 + S7**X6)
Range of X: /4 < X < + /4
The second way of writing the sine polynomium makes a greater part of it similar to the
cosine polynomium (3rd order in X2) leading to simultaneous SIMD computation.
The polynomium can be rewritten in terms of a fractional quadrant argument Xq with
modified coefficients, which avoids converting back to radians after integer and
fractional quadrant computation:
COS(Xq) = CQ0 + CQ2*Xq2 + CQ4*Xq4 + CQ6*Xq6
SIN(Xq) = SQ1*Xq + SQ3*Xq3 + SQ5*Xq5 + SQ7**Xq7 = Xq*( SQ1 + SQ3*Xq2 +
SQ5*Xq4 + SQ7**Xq6)
Range of X: 0.5 < X < +0.5
= -4.6002309092153379e-003
= 7.9679708649230657e-002
= -6.4596348437163809e-001
= 1.5707963267948966e+000
The subroutine EXP_J(X) should put priority on speed and might look something like
this:
Subroutine to compute the Sine and Cosine values of a floating point
input.
Y1=COS(X) and
Y2=SIN(X)
Calling Registers
F0 = Input Value X=[radians]
Result Registers
F0 = Cosine of input Y=[-1,1] real part
F1 = Sine of input Y=[-1,1]
- imaginary part
Altered Registers
F0, F1, (to be determined)
IX (to be determined)
Compatible with register use in fast ISR, and, if possible with
register use in VisualDSP++ c environment such that it can also
be called from c (or make another version of code)
Computation Time
XX Cycles
PEx
Xq2*CQ6
CQ4+ Xq2*CQ6
Xq2(CQ4+ Xq2*CQ6)
CQ2+Xq2(CQ4+ Xq2*CQ6)
Xq2(CQ2+Xq2(CQ4+ Xq2*CQ6))
CQ0+Xq2(CQ2+Xq2(CQ4+ Xq2*CQ6)))
PEy
Xq2*SQ7
SQ5+ Xq2*SQ7
Xq2(SQ5+ Xq2*SQ7)
SQ3+ Xq2(SQ5+ Xq2*SQ7)
Xq2(SQ3+ Xq2(SQ5+ Xq2*SQ7))
SQ1+ Xq2(SQ3+ Xq2(SQ5+
Xq2*SQ7)))
6. This is almost the desired results; only the sine polynomium needs to be multiplied with
Xq to get the sine value:
Xq(SQ1+ Xq2(SQ3+ Xq2(SQ5+Xq2*SQ7))))
7. Restore the the cosine and sine results according to quadrant from appropriate Pex and Pey
registers:
quad_int
0 = 00
1 = 01
2 = 10
3 = 11
F0
COS
-SIN
-COS
SIN
F1
SIN
COS swap results, invert sine
-SIN invert signs
-COS swap results, invert cosine
Try to find a way to use the 2 LSB in a fast computed branch or test MSB to change signs
and test LSB to swap results around.
8. Reset the SIMD mode back to normal, restore saved registers if needed. We are done.
Return.
Two MATLAB functions has been written to evaluate the polynomium approximations
above: exp_jd.m using standard double precision arithmetic and exp_js.m, which is using
single precision polynomium coefficients (necessary to exploit SIMD architecture), single
precision rounding of input argument, a single precision constant for radian to quadrant
conversion (2/ ) and single precision rounding of final result. These functions require that
sin_poly3.m and cos_poly3.m have been run beforehand to generate the polynomium
coefficients in the MATLAB workspace.
A MATLAB script plot_functions.m is available to plot the errors for the two cases in the
argument range from 4 to + 4 as well as printing the numerical expected values out
on the MATLAB console. For large arguments (outside the first quadrant), clearly the single
precision rounding of input argument and the constant for radian to quadrant conversion
(2/ ) dominate the errors of the results.
Errors for sine (red) and cosine (blue) using double precision (64 bit floats) computations
Errors for sine (red) and cosine (blue) using single precision (32 bit floats) computations
phi
COS
COS_pol
SIN
SIN_pol