Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
CramerInversion.icc
Go to the documentation of this file.
1// @(#)root/smatrix:$Id$
2// Authors: L. Moneta 2005
3
4
5/**********************************************************************
6 * *
7 * Copyright (c) 2005 , LCG ROOT MathLib Team *
8 * *
9 * *
10 **********************************************************************/
11//
12// Cramer optimized inversion for matrices up to size 5x5.
13// Code from ROOT TMatrixDCramerInv which originates from CLHEP
14// (original author Mark Fischler)
15//
16// Modified by L. Moneta 22/03/07: specialize only until 5x5 (before was up to 6x6)
17// tests show that on 64 machines (like on slc4) it is faster the general method
18//
19
20#ifndef ROOT_Math_CramerInversion_icc
21#define ROOT_Math_CramerInversion_icc
22
23#ifndef ROOT_Math_Dinv
24#error "Do not use CramerInversion.icc directly. #include \"Math/Dinv.h\" instead."
25#endif // ROOT_Math_Dinv
26
27#include <cmath>
28
29
30namespace ROOT {
31
32 namespace Math {
33
34
35
36//==============================================================================
37// Inversion for 3x3 matrices
38//==============================================================================
39
40/**
41 Inversion for a 3x3 matrix
42 */
43template <class MatrixRep>
45
46 typedef typename MatrixRep::value_type Scalar;
47
48 // check matrix sizes ??
49
50 // Scalar * pM = rhs.Array();
51
52 const Scalar c00 = rhs[4] * rhs[8] - rhs[5] * rhs[7];
53 const Scalar c01 = rhs[5] * rhs[6] - rhs[3] * rhs[8];
54 const Scalar c02 = rhs[3] * rhs[7] - rhs[4] * rhs[6];
55 const Scalar c10 = rhs[7] * rhs[2] - rhs[8] * rhs[1];
56 const Scalar c11 = rhs[8] * rhs[0] - rhs[6] * rhs[2];
57 const Scalar c12 = rhs[6] * rhs[1] - rhs[7] * rhs[0];
58 const Scalar c20 = rhs[1] * rhs[5] - rhs[2] * rhs[4];
59 const Scalar c21 = rhs[2] * rhs[3] - rhs[0] * rhs[5];
60 const Scalar c22 = rhs[0] * rhs[4] - rhs[1] * rhs[3];
61
62 const Scalar t0 = std::abs(rhs[0]);
63 const Scalar t1 = std::abs(rhs[3]);
64 const Scalar t2 = std::abs(rhs[6]);
65 Scalar det;
66 Scalar tmp;
67 if (t0 >= t1) {
68 if (t2 >= t0) {
69 tmp = rhs[6];
70 det = c12*c01-c11*c02;
71 } else {
72 tmp = rhs[0];
73 det = c11*c22-c12*c21;
74 }
75 } else if (t2 >= t1) {
76 tmp = rhs[6];
77 det = c12*c01-c11*c02;
78 } else {
79 tmp = rhs[3];
80 det = c02*c21-c01*c22;
81 }
82
83 if ( det == 0 || tmp == 0) {
84 return false;
85 }
86
87 const Scalar s = tmp/det;
88
89// if (determ)
90// *determ = 1./s;
91
92 rhs[0] = s*c00;
93 rhs[1] = s*c10;
94 rhs[2] = s*c20;
95 rhs[3] = s*c01;
96 rhs[4] = s*c11;
97 rhs[5] = s*c21;
98 rhs[6] = s*c02;
99 rhs[7] = s*c12;
100 rhs[8] = s*c22;
101
102 return true;
103}
104
105
106//==============================================================================
107// Inversion for 4x4 matrices
108//==============================================================================
109// Fij are indices for a 4x4 matrix.
110
111#define F00 0
112#define F01 1
113#define F02 2
114#define F03 3
115
116#define F10 4
117#define F11 5
118#define F12 6
119#define F13 7
120
121#define F20 8
122#define F21 9
123#define F22 10
124#define F23 11
125
126#define F30 12
127#define F31 13
128#define F32 14
129#define F33 15
130
131/**
132 Inversion for a 4x4 matrix
133 */
134template <class MatrixRep>
136
137 typedef typename MatrixRep::value_type Scalar;
138
139 // check matrix sizes ??
140
141 // Scalar * pM = rhs.Array();
142
143 // Find all NECESSARY 2x2 dets: (18 of them)
144
145 const Scalar det2_12_01 = rhs[F10]*rhs[F21] - rhs[F11]*rhs[F20];
146 const Scalar det2_12_02 = rhs[F10]*rhs[F22] - rhs[F12]*rhs[F20];
147 const Scalar det2_12_03 = rhs[F10]*rhs[F23] - rhs[F13]*rhs[F20];
148 const Scalar det2_12_13 = rhs[F11]*rhs[F23] - rhs[F13]*rhs[F21];
149 const Scalar det2_12_23 = rhs[F12]*rhs[F23] - rhs[F13]*rhs[F22];
150 const Scalar det2_12_12 = rhs[F11]*rhs[F22] - rhs[F12]*rhs[F21];
151 const Scalar det2_13_01 = rhs[F10]*rhs[F31] - rhs[F11]*rhs[F30];
152 const Scalar det2_13_02 = rhs[F10]*rhs[F32] - rhs[F12]*rhs[F30];
153 const Scalar det2_13_03 = rhs[F10]*rhs[F33] - rhs[F13]*rhs[F30];
154 const Scalar det2_13_12 = rhs[F11]*rhs[F32] - rhs[F12]*rhs[F31];
155 const Scalar det2_13_13 = rhs[F11]*rhs[F33] - rhs[F13]*rhs[F31];
156 const Scalar det2_13_23 = rhs[F12]*rhs[F33] - rhs[F13]*rhs[F32];
157 const Scalar det2_23_01 = rhs[F20]*rhs[F31] - rhs[F21]*rhs[F30];
158 const Scalar det2_23_02 = rhs[F20]*rhs[F32] - rhs[F22]*rhs[F30];
159 const Scalar det2_23_03 = rhs[F20]*rhs[F33] - rhs[F23]*rhs[F30];
160 const Scalar det2_23_12 = rhs[F21]*rhs[F32] - rhs[F22]*rhs[F31];
161 const Scalar det2_23_13 = rhs[F21]*rhs[F33] - rhs[F23]*rhs[F31];
162 const Scalar det2_23_23 = rhs[F22]*rhs[F33] - rhs[F23]*rhs[F32];
163
164 // Find all NECESSARY 3x3 dets: (16 of them)
165
167 + rhs[F02]*det2_12_01;
169 + rhs[F03]*det2_12_01;
171 + rhs[F03]*det2_12_02;
173 + rhs[F03]*det2_12_12;
175 + rhs[F02]*det2_13_01;
177 + rhs[F03]*det2_13_01;
179 + rhs[F03]*det2_13_02;
181 + rhs[F03]*det2_13_12;
183 + rhs[F02]*det2_23_01;
185 + rhs[F03]*det2_23_01;
187 + rhs[F03]*det2_23_02;
189 + rhs[F03]*det2_23_12;
191 + rhs[F12]*det2_23_01;
193 + rhs[F13]*det2_23_01;
195 + rhs[F13]*det2_23_02;
197 + rhs[F13]*det2_23_12;
198
199 // Find the 4x4 det:
200
203
204// if (determ)
205// *determ = det;
206
207 if ( det == 0 ) {
208 return false;
209 }
210
211 // use 1.0f to remove warning C4244 on Windows when using float
212 const Scalar oneOverDet = 1.0f / det;
213 const Scalar mn1OverDet = - oneOverDet;
214
219
224
229
234
235 return true;
236}
237
238//==============================================================================
239// Inversion for 5x5 matrices
240//==============================================================================
241// Mij are indices for a 5x5 matrix.
242#define M00 0
243#define M01 1
244#define M02 2
245#define M03 3
246#define M04 4
247
248#define M10 5
249#define M11 6
250#define M12 7
251#define M13 8
252#define M14 9
253
254#define M20 10
255#define M21 11
256#define M22 12
257#define M23 13
258#define M24 14
259
260#define M30 15
261#define M31 16
262#define M32 17
263#define M33 18
264#define M34 19
265
266#define M40 20
267#define M41 21
268#define M42 22
269#define M43 23
270#define M44 24
271
272
273/**
274 Inversion for a 5x5 matrix
275 */
276template <class MatrixRep>
278
279 typedef typename MatrixRep::value_type Scalar;
280
281 // check matrix sizes ??
282
283 // Scalar * pM = rhs.Array();
284
285
286 // Find all NECESSARY 2x2 dets: (30 of them)
287
288 const Scalar det2_23_01 = rhs[M20]*rhs[M31] - rhs[M21]*rhs[M30];
289 const Scalar det2_23_02 = rhs[M20]*rhs[M32] - rhs[M22]*rhs[M30];
290 const Scalar det2_23_03 = rhs[M20]*rhs[M33] - rhs[M23]*rhs[M30];
291 const Scalar det2_23_04 = rhs[M20]*rhs[M34] - rhs[M24]*rhs[M30];
292 const Scalar det2_23_12 = rhs[M21]*rhs[M32] - rhs[M22]*rhs[M31];
293 const Scalar det2_23_13 = rhs[M21]*rhs[M33] - rhs[M23]*rhs[M31];
294 const Scalar det2_23_14 = rhs[M21]*rhs[M34] - rhs[M24]*rhs[M31];
295 const Scalar det2_23_23 = rhs[M22]*rhs[M33] - rhs[M23]*rhs[M32];
296 const Scalar det2_23_24 = rhs[M22]*rhs[M34] - rhs[M24]*rhs[M32];
297 const Scalar det2_23_34 = rhs[M23]*rhs[M34] - rhs[M24]*rhs[M33];
298 const Scalar det2_24_01 = rhs[M20]*rhs[M41] - rhs[M21]*rhs[M40];
299 const Scalar det2_24_02 = rhs[M20]*rhs[M42] - rhs[M22]*rhs[M40];
300 const Scalar det2_24_03 = rhs[M20]*rhs[M43] - rhs[M23]*rhs[M40];
301 const Scalar det2_24_04 = rhs[M20]*rhs[M44] - rhs[M24]*rhs[M40];
302 const Scalar det2_24_12 = rhs[M21]*rhs[M42] - rhs[M22]*rhs[M41];
303 const Scalar det2_24_13 = rhs[M21]*rhs[M43] - rhs[M23]*rhs[M41];
304 const Scalar det2_24_14 = rhs[M21]*rhs[M44] - rhs[M24]*rhs[M41];
305 const Scalar det2_24_23 = rhs[M22]*rhs[M43] - rhs[M23]*rhs[M42];
306 const Scalar det2_24_24 = rhs[M22]*rhs[M44] - rhs[M24]*rhs[M42];
307 const Scalar det2_24_34 = rhs[M23]*rhs[M44] - rhs[M24]*rhs[M43];
308 const Scalar det2_34_01 = rhs[M30]*rhs[M41] - rhs[M31]*rhs[M40];
309 const Scalar det2_34_02 = rhs[M30]*rhs[M42] - rhs[M32]*rhs[M40];
310 const Scalar det2_34_03 = rhs[M30]*rhs[M43] - rhs[M33]*rhs[M40];
311 const Scalar det2_34_04 = rhs[M30]*rhs[M44] - rhs[M34]*rhs[M40];
312 const Scalar det2_34_12 = rhs[M31]*rhs[M42] - rhs[M32]*rhs[M41];
313 const Scalar det2_34_13 = rhs[M31]*rhs[M43] - rhs[M33]*rhs[M41];
314 const Scalar det2_34_14 = rhs[M31]*rhs[M44] - rhs[M34]*rhs[M41];
315 const Scalar det2_34_23 = rhs[M32]*rhs[M43] - rhs[M33]*rhs[M42];
316 const Scalar det2_34_24 = rhs[M32]*rhs[M44] - rhs[M34]*rhs[M42];
317 const Scalar det2_34_34 = rhs[M33]*rhs[M44] - rhs[M34]*rhs[M43];
318
319 // Find all NECESSARY 3x3 dets: (40 of them)
320
361
362 // Find all NECESSARY 4x4 dets: (25 of them)
363
414
415 // Find the 5x5 det:
416
419
420// if (determ)
421// *determ = det;
422
423 if ( det == 0 ) {
424 //Error("Inv5x5","matrix is singular");
425 //m.Invalidate();
426 return false;
427 }
428
429 const Scalar oneOverDet = 1.0f / det;
430 const Scalar mn1OverDet = - oneOverDet;
431
437
443
449
455
461
462 return true;
463}
464
465
466 } // namespace Math
467
468} // namespace ROOT
469
470
471
472
473// undef macros to avoid conflicts
474
475// 4x4 indices
476
477#undef F00
478#undef F01
479#undef F02
480#undef F03
481
482#undef F10
483#undef F11
484#undef F12
485#undef F13
486
487#undef F20
488#undef F21
489#undef F22
490#undef F23
491
492#undef F30
493#undef F31
494#undef F32
495#undef F33
496
497// undef 5x5 indices
498
499#undef M00
500#undef M01
501#undef M02
502#undef M03
503#undef M04
504
505#undef M10
506#undef M11
507#undef M12
508#undef M13
509#undef M14
510
511#undef M20
512#undef M21
513#undef M22
514#undef M23
515#undef M24
516
517#undef M30
518#undef M31
519#undef M32
520#undef M33
521#undef M34
522
523#undef M40
524#undef M41
525#undef M42
526#undef M43
527#undef M44
528
529
530#endif
#define M00
#define M34
#define M03
#define M10
#define M41
#define M20
#define M42
#define M13
#define M33
#define M04
#define M23
#define M11
#define M44
#define M31
#define M02
#define M21
#define M01
#define M24
#define M12
#define M22
#define M43
#define M14
#define M30
#define M40
#define M32
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#define F01
Definition TEveTrans.cxx:23
#define F22
Definition TEveTrans.cxx:34
#define F00
Definition TEveTrans.cxx:22
#define F02
Definition TEveTrans.cxx:24
#define F31
Definition TEveTrans.cxx:38
#define F32
Definition TEveTrans.cxx:39
#define F21
Definition TEveTrans.cxx:33
#define F03
Definition TEveTrans.cxx:25
#define F30
Definition TEveTrans.cxx:37
#define F11
Definition TEveTrans.cxx:28
#define F10
Definition TEveTrans.cxx:27
#define F33
Definition TEveTrans.cxx:40
#define F20
Definition TEveTrans.cxx:32
#define F12
Definition TEveTrans.cxx:29
#define F23
Definition TEveTrans.cxx:35
#define F13
Definition TEveTrans.cxx:30
static bool Dinv(MatrixRep &rhs)
Definition Dinv.h:148
Namespace for new Math classes and functions.
Rotation3D::Scalar Scalar
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
auto * t1
Definition textangle.C:20