File: eulerAngleComputation.tex

package info (click to toggle)
clhep 2.1.4.1%2Bdfsg-1.1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 10,012 kB
  • sloc: cpp: 50,094; sh: 6,694; makefile: 2,694; perl: 28
file content (403 lines) | stat: -rwxr-xr-x 16,248 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
% CLHEP/ZOOM Vector Package Euler Angle Computation

\documentclass[twoside,12pt]{article}
\flushbottom
\pagestyle{headings}

\setlength{\topmargin}{0.0in}
\setlength{\textwidth}{5.5in}
\setlength{\oddsidemargin}{.5in}
\setlength{\evensidemargin}{.5in}
\setlength{\textheight}{8.5in}

\addtolength{\parskip}{2pt}

\newcommand{\fpcl}{{\sc fpcl}}

\def \Point {{\tt Point3D}}
\def \Line {{\tt Line3D}}
\def \Direction {{\tt Direction}}
\def \UnitVector {{\tt UnitVector}}
\def \Plane {{\tt Plane3D}}
\def \SpaceVector {{\tt SpaceVector}}
\def \SV {{\tt Hep3Vector}}
\def \SVz {{\tt SpaceVector}}
\def \UV {{\tt UnitVector}}
\def \TangentVector {{\tt TangentVector}}
\def \TV {{\tt TangentVector}}
\def \Ro {{\tt HepRotation}}
\def \Ros {{\tt Rotation}}
\def \Rotation {{\tt Rotation}}
\def \RotationZ {{\tt HepRotationZ}}
\def \Transformation {{\tt Transformation}}
\def \Euclidean {{\tt EuclideanTransformation}}
\def \Angle {{\tt Angle}}
\def \LorentzVector {{\tt LorentzVector}}
\def \LorentzTransformation {{\tt LorentzTransformation}}
\def \LV {{\tt HepLorentzVector}}
\def \LVz {{\tt LorentzVector}}
\def \LT {{\tt HepLorentzRotation}}
\def \LTs {{\tt LorentzTransformation}}
\def \LB {{\tt HepBoost}}
\def \LBs {{\tt LorentzBoost}}
\def \PolarAngle {{\tt PolarAngle}}
\def \PAngle {{\tt PAngle}}
\def \AzimuthalAngle {{\tt AzimuthalAngle}}
\def \AAngle {{\tt AAngle}}
\def \EB {{\tt EBvector}}
\def \AV {{\tt Adjoint3Vector}}
\def \ALV {{\tt Adjoint4Vector}}
\def \Scalar {{\tt Scalar}}
\def \Ax {{\tt HepAxisAngle}}
\def \Es {{\tt HepEulerAngles}}

\newcommand {\see}[1] {\hfill$\triangleright$ see eqn.~#1}

\newenvironment{shortlist}{%
\begin{itemize}
\setlength{\itemsep}{0pt}
\setlength{\parskip}{0pt}
}{%
\end{itemize}
}

\setcounter{secnumdepth}{2}	% Number sub- but not subsubsections
\setcounter{tocdepth}{2}	% Only numbered section headings go in contents

\begin{document}

\title{Euler Angle Computation in the CLHEP {\bf Vector} Package}

\author{Mark Fischler}
\date{Version 1.0, April 24, 2003}
\maketitle

The naive (though algebraically sound) technique for extracting \Es\ 
from a \Ro\ is flawed when the \Ro\ represents a rotation very nearly 
around the Z axis, in the presence of small round-off induced errors 
in the values of the rotation matrix components.
By flawed, we mean that when the resulting Euler angles are used to 
reconstruct the \Ro, that reconstructed \Ro\ may be quite different 
from the original.

This document will illustrate the mechanism by which this flaw comes up,
and will derive and justify a superior algorithm for calculationg the proper
euler angles.

\tableofcontents

\section{The Naive Algorithm}

The relation between the Eueler Angles and a \Ro\ $R$ is given by:

\[  \vec{v}.\mbox{rotate}(\phi, \theta, \psi) \Longrightarrow  \]
\begin{equation}
\label{eq:eulerrot}
\left(
\begin{array}{ccc}
\cos \psi \cos \phi - \sin \psi \cos \theta \sin \phi &
\cos \psi \sin \phi + \sin \psi \cos \theta \cos \phi &
\sin \psi \sin \theta \\
- \sin \psi \cos \phi - \cos \psi \cos \theta \sin \phi &
- \sin \psi \sin \phi + \cos \psi \cos \theta \cos \phi &
\cos \psi \sin \theta \\
\sin \theta \sin \phi &
- \sin \theta \cos \phi &
\cos \theta
\end{array}
\right)
\left(
\begin{array}{c}
v_x\\
v_y\\
v_z
\end{array}
\right)
\end{equation}


As of CLHEP 1.8, the algorithm for comupting Euler angles 
$(\psi, \theta, \phi)$,
glossing over special cases, was as follows:

\begin{enumerate}
\item 
Find $\theta$ by taking $\cos^{-1} R_{zz}$ and  
$\sin \theta = \sqrt{1-R_{zz}^2}$.  By definition, 
$\theta$ is in quadrant I or II, and $\sin \theta \geq 0$.
\item 
Knowing the form of $R_{zy} = - \sin \theta \cos \phi$, extract 
$\cos | \phi | = - R_{zy} / \sin \theta$.  
\item
Similarly, 
$\cos | \psi | = + R_{yz} / \sin \theta$.
\item
Taking the arc cosine of the expressions just computed gives 
$|\phi|$ and $|\psi|$.  The signs of $\psi$ and $\phi$ 
are assigned so as to yield 
proper signs for $R_{zx}$ and $R_{xz}$ respectively; 
if one or both of those is zero then demand instead the proper sign for
$R_{zy}$ and/or $R_{yz}$. 
\item 
The case where $R_{zz} = \pm 1$ is treated specially.  In that case, there
is a freedom to tradeoff  values of $\psi$ and $\phi$, and an arbitrary rule is 
imposed:  $\psi = R_{zz} \phi$.
\end{enumerate}

\section{The Potential Flaw}

The above algorithm is analytically correct, but if one perturbs 
$R_{ij} \rightarrow R_{ij}+\epsilon_{ij}$ for some set of  
$\epsilon_{ij} << 1$, then $\psi \rightarrow \psi + \delta \psi$ and
$\phi \rightarrow \phi + \delta \phi$ where, if $\sin \theta << 1$
then $\delta \psi$ and $\delta \phi$ need not be small.

To illustrate:  Say $R$ represents a rotation by angle $\mu$ about the Z axis,
but $R_{zz}$ is perturbed to be $1 - \epsilon$ 
while none of the other components
in the Z row or column--the components with value 0 for a Z rotation--are 
perturbed.   Now a rotation by angle $\mu$ about the Z axis falls into the 
ambiguous case, where any answer with $\theta << 1$ and $\psi + \phi \sim \mu$
would be acceptable.  

However, the algorithm described above will assign
a tiny {\em but non-zero} value to $\sin \theta$.  So it will decide that the
divisions in $\cos | \psi | = - R_{zy} / \sin \theta$ and 
$\cos | \phi | = + R_{yz} / \sin \theta$ are valid operations.  
Of course, since the numerators are exactly zero, it does not matter that
the denominators are small; these will say that $ |\psi| = \pi /2$
and $ |\phi| = \pi /2$.  

Then the algorithm attempts to determine the signs of $\psi$ and $\phi$; 
and the actual code gets into futher trouble since it knows that $\sin \theta$
is non-zero, thus it is ``impossible'' (yet true) to have all four of 
$R_{xz}, R_{yz}, R_{zx}, R_{zy} = 0$.  
But no matter how clever the algorithm at that point, once it is decided that
$ |\psi| = |\phi| = \pi /2$ there is no way to recover the proper relationship
$\psi + \phi \sim \mu$.  And in fact, if you form a \Ro\ from the computed
Euler angles, you will either get something close to the identity matrix, or 
something close to a 180 degree 
rotation about the Z axis--neither of which resembles
the original matrix in the least!

In general, if the \Ro\ represents any rotation about some axis making an angle 
with the Z axis which is smaller than or comparable to the uncertainty in the
matrix elements, then the algorithm used in CLHEP 1.8 and earlier is flawed
in this way.

\section{Deriving The New Algorithm}

It is true that for $1 - |R_{zz}|$ small, the exact values of Euler angles 
depend  sensitively on the values of all the matrix components.  Thus
the problem of extracting Euler angles for such cases is numerically unstable.
But this is
not fatal; what we want is a set of Euler angles that comes very close to
properly representing the rotation matrix, 
and if other sets of Euler angles would
also come close, we don't mind not finding them.
 
Fortunately, the problem of extracting Euler angles in the presence of 
perturbations of the matrix elements, such that the reconstructed matrix will 
match the original up to differences of the same order as those perturbations,
is tractable and numerically stable, as we now show.  

We start with the observations that 
\begin{eqnarray}
R_{xx} + R_{yy} = + \cos ( \psi + \phi ) (1 + \cos \theta) \\
R_{xx} - R_{yy} = + \cos ( \psi - \phi ) (1 - \cos \theta) 
\end{eqnarray}
If $R_{zz}$ is non-negative, $(1 + \cos \theta) \geq 1$, while 
if $R_{zz}$ is negative, $(1 - \cos \theta) > 1$; so one of the
above equations can always be used to determine $|\psi \pm \phi|$ with no
risk of division by a small quantity.  And if $|R_{zz}|$ is not close to 1,
both equations are numerically stable so both combinations can be found. 

Still working in the X-Y sector, 
\begin{eqnarray}
R_{xy} - R_{yx} = + \sin ( \psi + \phi ) (1 + \cos \theta) \\
R_{xy} + R_{yx} = - \sin ( \psi - \phi ) (1 - \cos \theta) 
\end{eqnarray}

We also observe, in the Z sector, that
\begin{eqnarray}
R_{xz} R_{zx} - R_{yz} R_{zy} = + \cos ( \psi - \phi ) (\sin^2 \theta) \\
R_{xz} R_{zx} + R_{yz} R_{zy} = - \cos ( \psi + \phi ) (\sin^2 \theta)
\end{eqnarray}

And 
\begin{eqnarray}
R_{xz} R_{zy} + R_{yz} R_{zx} = - \sin ( \psi - \phi ) (\sin^2 \theta) \\
R_{xz} R_{zy} - R_{yz} R_{zx} = - \sin ( \psi + \phi ) (\sin^2 \theta)
\end{eqnarray}

Finally, we note that if we can determine cosine and sine of the sum and the 
difference of $\psi$ and $\phi$ in a numerically stable manner, then that
determines $\psi$ and $\phi$ in a stable manner. 

All the above relations are all stable except when $1- |R_{zz}| \sim 0$.
So except when $1- |R_{zz}| \sim 0$ we can use either the Z sector, 
or the X-Y sector, or for
that matter the simple $R_{xz}/\sin \theta$ and $R_{yz}/\sin \theta$ forms
used by the naive algortihm.

When $R_{zz} \sim 1$, the entire Z sector becomes numerically unstable, 
as do the relations determining $\cos ( \psi - \phi )$ and 
$\sin ( \psi - \phi )$ in the X-Y sector.  
That is not so terrible, since at $R_{zz} = 1$ only the value of 
$\psi + \phi$ is relevant; $\psi - \phi$ is moot.

Similarly, when $R_{zz} \sim -1$, the  Z sector is numerically unstable, 
and the relations determining $\cos ( \psi + \phi )$ and 
$\sin ( \psi + \phi )$ in the X-Y sector are useless, but only the value of 
$\psi - \phi$ is relevant; $\psi + \phi$ is moot.
 
So what is needed is some method which always gives the correct values
for meaningful quantities, and sensible values for the
moot quantities.
The way to accomplish this is to combine the relations determining $\sin$ and
$\cos$ of the ``moot'' quantities, so as to find (for the $R_{zz} \sim 1$ case)
$\psi - \phi = \tan^{-1} \frac{ -(R_{xy} + R_{yx}) }{ R_{xx} - R_{yy} }$. 
In this fraction, the factors of $1 - \cos \theta$ cancel one another. 

Computing $\psi - \phi $ as an $\arctan$ would force it to lie between $-\pi/2$
and $\pi/2$.  How can we detect when the correct value is outside that range?
We could look at the sign of $\sin (\psi - \phi)$, 
that is to say, the sign of $-(R_{xy} + R_{yx})$.  This would tell us
whether to use the result of $\arctan$ directly or to add or subtract $\pi$.
On the other hand, it is much easier to use the function {\em atan2(s/c)},
which does this work for you.

One would expect from the above reasoning that when $R$ is slightly perturbed
in a pseudo-random manner,
the formulae given would reproduce the original Euler angles more closely than 
the ``naive'' formulae described earlier.  A bit of mathematical experimentation
verifies that this is so--the new formulae are about an order of magnitude
less sensitive to fluctuations which violate the orthogonality of $R$.

Two improvements are tempting, but turn out to be harmful.  Both address the
issue of attempting to morph smoothly to the action taken when $|R_{zz}| = 1$
precisely (in which case we by fiat choose $\psi = R_{zz} \phi$).   Sometimes
in computing the potentially moot combination of $\psi$ and $\phi$, 
the magnitude of the value computed for 
$\cos (\psi \pm \phi) (1 \mp \cos \theta)$ exceeds $(1 \mp \cos \theta)$.  
It may then be thought that the arithmetic is telling you to consider that 
denominator as illogically large, and just treat the arctan of that 
combination as zero (that is, force $\psi = \pm \phi$).  This turns out to
introduce a flaw in the result (in the sense discussed above) most times that
this ``improvement'' is applied.  Similarly, one can check that the sign of the 
X-Y sector expression for $\sin(\psi \pm \phi)$ matches the sign of the
expression for the same $\sin(\psi \pm \phi)$ computed from components in the Z
sector, and if they do not match, treat this as an indication that the
combination is moot and set $\psi = \pm \phi$.  Again, most times this
opportunity presents itself, setting $\psi = \pm \phi$ introduces a flaw 
into the answer.  

However, one correction of significance must be applied:
The algorithm described will always impute values for $\psi \pm \phi$ 
which are in the range $(-\pi,\pi]$.  But clearly the actual values of 
$\psi$ and $\phi$ can can have a sum or difference anywhere in $(-2\pi,2\pi]$.
Getting this wrong will manifest itself as an error by $\pi$ in the
computed values of $\psi$ and $\phi$.

This can be dealt with by bringing in information in the Z-sector:
If $\psi$ (or $\phi$) has the wrong sign relative to that which can be read off
the last column or row, then one should add or subtract $\pi$ from {\em both} 
$\psi$ and $\phi$.
Here, when $|R_{zz}| \sim 1$, there is the potential for numerical instability;
fortunately, in such cases only the value of one combination $\psi \pm \phi$
is relevant when re-expressing the rotation matrix.  So as long as the
correction is applied to both $\psi$ and $\phi$ or neither, the result (in
such a case) is not truly flawed.

There are, of course, four possible terms in the Z-sector to use to ask whether
we have the wrong value for $\psi$ and $\phi$:
\begin{enumerate}
\item
$R_{xz}$: If $\sin \psi > 0$ then $\psi > 0$.
\item
$R_{yz}$: If $\cos \psi > 0$ then $|\psi| < \pi/2$.
\item
$R_{zx}$: If $\sin \phi > 0$ then $\phi > 0$.
\item
$R_{yz}$: If $-\cos \phi < 0$ then $|\psi| < \pi/2$.
\end{enumerate}

The most stable algorithm will use that quantity among those four which is
largest in absolute value.
 

\section{The New Algorithm}

The algorithm uses only the X-Y sector and $R_{zz}$.
$\cos \theta = R_{zz}$ and this determines $\theta$.
 
\noindent
If $ R_{zz} \geq 0$ the primary stable quantity is $\psi + \phi$:
\begin{enumerate}
\item
Compute $\psi + \phi = \tan^{-1} \frac{R_{xy} - R_{yx}}{R_{xx} + R_{yy}}$.
With the numerator and denominator in this form we can get the 
proper value of $\psi + \phi$ (including the proper quadrant) by using the
{\em atan2(s/c)} function.
\item
Compute $\psi - \phi = \tan^{-1} \frac{-(R_{xy} + R_{yx})}{R_{xx} - R_{yy}}$.
\end{enumerate}

\noindent
If $ R_{zz} < 0$ the primary stable quantity is $\psi - \phi$:
\begin{enumerate}
\item
Compute $\psi - \phi = \tan^{-1} \frac{-(R_{xy} + R_{yx})}{R_{xx} - R_{yy}}$.
We put the numerator and denominator in this form so that we can get the 
proper value of $\psi - \phi$ (including the proper quadrant) by using the
{\em atan2(s/c)} function.
\item
Compute $\psi + \phi = \tan^{-1} \frac{R_{xy} - R_{yx}}{R_{xx} + R_{yy}}$.
\end{enumerate}

\noindent
Then, in either case, compute
$\psi = \frac{1}{2} \left[ ( (\psi + \phi) + (\psi - \phi) \right]$ and
$\phi = \frac{1}{2} \left[ ( (\psi + \phi) - (\psi - \phi) \right]$.

\noindent
Finally, apply the potential $\pm \pi$ corrections, based on the largest of 
$|R_{xz}|,|R_{yz}|,|R_{zx}|,|R_{zy}|$: 
\begin{enumerate}
\item
$If R_{xz} > 0$ and $\psi < 0$ then correct $\psi$ and $\phi$.
\item
$If R_{yz} > 0$ and $|\psi| > \pi/2$ then correct $\psi$ and $\phi$.
\item
$If R_{zx} > 0$ and $\phi < 0$ then correct $\psi$ and $\phi$.
\item
$If R_{zy} < 0$ and $|\psi| > \pi/2$ then correct $\psi$ and $\phi$.
\end{enumerate}
\noindent
In each case, to ``correct'' a quantity means to add $\pi$ if negative, or to
subtract $\pi$ if positive.

\section{Accuracy of a Reconstricted R}

Ultimately,if one perturbs 
$R_{ij} \rightarrow R_{ij}+\epsilon_{ij}$ for some set of  
$\epsilon_{ij}$ each of which is of order $\epsilon << 1$,
then one has a non-orthogonal matrix.
There is no reason to believe that one can perfectly extract Euler angles
from such a matrix, and in fact, any manner of approximating the Euler angles
will have the following property:
A matrix reconstructed from those Euler angles will be perfectly orthogonal
(to within achine roundoff errors) and therefore {\em cannot precisely 
match the original matrix}.

The naive size of the resulting unavoidable ``flaw'' is of order 
$\epsilon$, but in fact (except in special cases such as $\theta \sim \pi/2$)
in general the flaw goes as $\sqrt{\epsilon}$.  This can easily be seen
from the fact that when $R_{zz} = \cos \theta $ 
is perturbed by $\epsilon$, unless
$R_{zz}$ is very small, $\sin \theta$ is perturbed by $O(\sqrt{\epsilon})$.
And $\sin \theta$  does appear multiplying terms in the Z row and column, 
so at least these terms are vulnerable to errors of order $O(\sqrt{\epsilon})$.
 
\end{document}