FEDRA emulsion software from the OPERA Collaboration
Dfact.hh
Go to the documentation of this file.
1 #ifndef __DFACT_HH
2 #define __DFACT_HH
3 // ********************************************************************
4 //
5 // source:
6 //
7 // type: source code
8 //
9 // created: 02. 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: Determinant of a square matrix
20 // Code was taken from CERNLIB::kernlib dfact function, translated
21 // from FORTRAN to C++ and optimized.
22 //
23 // changes:
24 // 02 Apr 2001 (TG) creation
25 //
26 // ********************************************************************
27 
34 template <class Matrix, unsigned int n, unsigned int idim>
35 bool Dfact(Matrix& rhs, typename Matrix::value_type& det) {
36 
37 #ifdef XXX
38  if (idim < n || n <= 0) {
39  return false;
40  }
41 #endif
42 
43 
44  /* Initialized data */
45  // const typename Matrix::value_type* A = rhs.Array();
46  typename Matrix::value_type* a = rhs.Array();
47 
48  /* Local variables */
49  static unsigned int nxch, i, j, k, l;
50  static typename Matrix::value_type p, q, tf;
51 
52  /* Parameter adjustments */
53  a -= idim + 1;
54 
55  /* Function Body */
56 
57  // fact.inc
58 
59  nxch = 0;
60  det = 1.;
61  for (j = 1; j <= n; ++j) {
62  const unsigned int ji = j * idim;
63  const unsigned int jj = j + ji;
64 
65  k = j;
66  p = fabs(a[jj]);
67 
68  if (j != n) {
69  for (i = j + 1; i <= n; ++i) {
70  q = fabs(a[i + ji]);
71  if (q > p) {
72  k = i;
73  p = q;
74  }
75  } // for i
76  if (k != j) {
77  for (l = 1; l <= n; ++l) {
78  const unsigned int li = l*idim;
79  const unsigned int jli = j + li;
80  const unsigned int kli = k + li;
81  tf = a[jli];
82  a[jli] = a[kli];
83  a[kli] = tf;
84  } // for l
85  ++nxch;
86  } // if k != j
87  } // if j!=n
88 
89  if (p <= 0.) {
90  det = 0;
91  return false;
92  }
93 
94  det *= a[jj];
95 #ifdef XXX
96  t = fabs(det);
97  if (t < 1e-19 || t > 1e19) {
98  det = 0;
99  return false;
100  }
101 #endif
102 
103  a[jj] = 1. / a[jj];
104  if (j == n) {
105  continue;
106  }
107 
108  const unsigned int jm1 = j - 1;
109  const unsigned int jpi = (j + 1) * idim;
110  const unsigned int jjpi = j + jpi;
111 
112  for (k = j + 1; k <= n; ++k) {
113  const unsigned int ki = k * idim;
114  const unsigned int jki = j + ki;
115  const unsigned int kji = k + jpi;
116  if (j != 1) {
117  for (i = 1; i <= jm1; ++i) {
118  const unsigned int ii = i * idim;
119  a[jki] -= a[i + ki] * a[j + ii];
120  a[kji] -= a[i + jpi] * a[k + ii];
121  } // for i
122  }
123  a[jki] *= a[jj];
124  a[kji] -= a[jjpi] * a[k + ji];
125  } // for k
126  } // for j
127 
128  if (nxch % 2 != 0) {
129  det = -(det);
130  }
131  return true;
132 } // end of Dfact
133 
134 #endif
bool Dfact(Matrix &rhs, typename Matrix::value_type &det)
Definition: Dfact.hh:35
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
TTree * t
Definition: check_shower.C:4
q
Definition: testBGReduction_AllMethods.C:55
p
Definition: testBGReduction_AllMethods.C:8