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 //==============================================================================
45 template <unsigned int idim, unsigned int n = idim>
46 class Invert {
47 public:
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 //==============================================================================
84 template <>
85 class Invert<0> {
86 public:
88  template <class Matrix>
89  inline static bool Dinv(Matrix& rhs) { return true; }
90 };
91 
92 
98 //==============================================================================
99 // Invert<1>
100 //==============================================================================
101 template <>
102 class Invert<1> {
103 public:
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 //==============================================================================
126 template <>
127 class Invert<2> {
128 public:
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 //==============================================================================
158 template <>
159 class Invert<3> {
160 public:
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
EdbSegP * s
Definition: tlg2pattern.C:32