FEDRA emulsion software from the OPERA Collaboration
Dinv.hh
Go to the documentation of this file.
1#ifndef __DINV_HH
2#define __DINV_HH
3// ********************************************************************
4//
5// source:
6//
7// type: source code
8//
9// created: 03. Apr 2001
10//
11// author: Thorsten Glebe
12// HERA-B Collaboration
13// Max-Planck-Institut fuer Kernphysik
14// Saupfercheckweg 1
15// 69117 Heidelberg
16// Germany
17// E-mail: T.Glebe@mpi-hd.mpg.de
18//
19// Description: square Matrix inversion
20// Code was taken from CERNLIB::kernlib dfinv function, translated
21// from FORTRAN to C++ and optimized.
22// n: Order of the square matrix
23// idim: First dimension of array A
24//
25// changes:
26// 03 Apr 2001 (TG) creation
27//
28// ********************************************************************
29#include "Dfactir.hh"
30#include "Dfinv.hh"
31
42//==============================================================================
43// Invert class
44//==============================================================================
45template <unsigned int idim, unsigned int n = idim>
46class Invert {
47public:
49 template <class Matrix>
50 static bool Dinv(Matrix& rhs) {
51
52#ifdef XXX
53 if (n < 1 || n > idim) {
54 return false;
55 }
56#endif
57
58 /* Initialized data */
59 static unsigned int work[n];
60 for(unsigned int i=0; i<n; ++i) work[i] = 0;
61
62 static typename Matrix::value_type det = 0;
63
64 /* Function Body */
65
66 /* N.GT.3 CASES. FACTORIZE MATRIX AND INVERT. */
67 if (Dfactir<Matrix,n,idim>(rhs,det,work) == false) {
68 cerr << "Dfactir failed!!" << endl;
69 return false;
70 }
71 return Dfinv<Matrix,n,idim>(rhs,work);
72 } // Dinv
73}; // class Invert
74
75
81//==============================================================================
82// Invert<0>
83//==============================================================================
84template <>
85class Invert<0> {
86public:
88 template <class Matrix>
89 inline static bool Dinv(Matrix& rhs) { return true; }
90};
91
92
98//==============================================================================
99// Invert<1>
100//==============================================================================
101template <>
102class Invert<1> {
103public:
105 template <class Matrix>
106 static bool Dinv(Matrix& rhs) {
107 typename Matrix::value_type* a = rhs.Array();
108
109 if (a[0] == 0.) {
110 return false;
111 }
112 a[0] = 1. / a[0];
113 return true;
114 }
115};
116
117
123//==============================================================================
124// Invert<2>: Cramers rule
125//==============================================================================
126template <>
127class Invert<2> {
128public:
130 template <class Matrix>
131 static bool Dinv(Matrix& rhs) {
132
133 typename Matrix::value_type* a = rhs.Array();
134 typename Matrix::value_type det = a[0] * a[3] - a[2] * a[1];
135
136 if (det == 0.) { return false; }
137
138 typename Matrix::value_type s = 1. / det;
139 typename Matrix::value_type c11 = s * a[3];
140
141 a[2] = -s * a[2];
142 a[1] = -s * a[1];
143 a[3] = s * a[0];
144 a[0] = c11;
145 return true;
146 }
147};
148
149
155//==============================================================================
156// Invert<3>
157//==============================================================================
158template <>
159class Invert<3> {
160public:
162 template <class Matrix>
163 static bool Dinv(Matrix& rhs) {
164
165 typename Matrix::value_type* a = rhs.Array();
166
167 static typename Matrix::value_type t1, t2, t3, temp, s;
168 static typename Matrix::value_type c11, c12, c13, c21, c22, c23, c31, c32, c33, det;
169
170
171 /* COMPUTE COFACTORS. */
172 c11 = a[4] * a[8] - a[7] * a[5];
173 c12 = a[7] * a[2] - a[1] * a[8];
174 c13 = a[1] * a[5] - a[4] * a[2];
175 c21 = a[5] * a[6] - a[8] * a[3];
176 c22 = a[8] * a[0] - a[2] * a[6];
177 c23 = a[2] * a[3] - a[5] * a[0];
178 c31 = a[3] * a[7] - a[6] * a[4];
179 c32 = a[6] * a[1] - a[0] * a[7];
180 c33 = a[0] * a[4] - a[3] * a[1];
181
182 t1 = fabs(a[0]);
183 t2 = fabs(a[1]);
184 t3 = fabs(a[2]);
185
186 /* (SET TEMP=PIVOT AND DET=PIVOT*DET.) */
187 if(t1 < t2) {
188 if (t3 < t2) {
189 /* (PIVOT IS A21) */
190 temp = a[1];
191 det = c13 * c32 - c12 * c33;
192 } else {
193 /* (PIVOT IS A31) */
194 temp = a[2];
195 det = c23 * c12 - c22 * c13;
196 }
197 } else {
198 if(t3 < t1) {
199 /* (PIVOT IS A11) */
200 temp = a[0];
201 det = c22 * c33 - c23 * c32;
202 } else {
203 /* (PIVOT IS A31) */
204 temp = a[2];
205 det = c23 * c12 - c22 * c13;
206 }
207 }
208
209 if (det == 0.) {
210 return false;
211 }
212
213 /* SET ELEMENTS OF INVERSE IN A. */
214 s = temp / det;
215 a[0] = s * c11;
216 a[3] = s * c21;
217 a[6] = s * c31;
218 a[1] = s * c12;
219 a[4] = s * c22;
220 a[7] = s * c32;
221 a[2] = s * c13;
222 a[5] = s * c23;
223 a[8] = s * c33;
224 return true;
225 }
226};
227
228#endif
Expr< UnaryOp< Fabs< T >, Expr< A, T, D >, T >, T, D > fabs(const Expr< A, T, D > &rhs)
Definition: UnaryOperators.hh:96
void a()
Definition: check_aligned.C:59
static bool Dinv(Matrix &rhs)
Definition: Dinv.hh:89
static bool Dinv(Matrix &rhs)
Definition: Dinv.hh:106
static bool Dinv(Matrix &rhs)
Definition: Dinv.hh:131
static bool Dinv(Matrix &rhs)
Definition: Dinv.hh:163
Definition: Dinv.hh:46
static bool Dinv(Matrix &rhs)
Definition: Dinv.hh:50
s
Definition: check_shower.C:55