FEDRA emulsion software from the OPERA Collaboration
Dfactir.hh
Go to the documentation of this file.
1 #ifndef __DFACTIR_HH
2 #define __DFACTIR_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, needed for Dfinv()
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 
35 template <class Matrix, unsigned int n, unsigned int idim>
36 bool Dfactir(Matrix& rhs, typename Matrix::value_type& det, unsigned int* ir)
37  // int *n, float *a, int *idim, int *ir, int *ifail, float *det, int *jfail)
38 {
39 
40 #ifdef XXX
41  if (idim < n || n <= 0) {
42  return false;
43  }
44 #endif
45 
46 
47  /* Initialized data */
48  typename Matrix::value_type* a = rhs.Array();
49 
50  /* Local variables */
51  static unsigned int nxch, i, j, k, l;
52  static typename Matrix::value_type p, q, tf;
53 
54  /* Parameter adjustments */
55  a -= idim + 1;
56  --ir;
57 
58  /* Function Body */
59 
60  // fact.inc
61  nxch = 0;
62  det = 1.;
63  for (j = 1; j <= n; ++j) {
64  const unsigned int ji = j * idim;
65  const unsigned int jj = j + ji;
66 
67  k = j;
68  p = fabs(a[jj]);
69 
70  if (j != n) {
71  for (i = j + 1; i <= n; ++i) {
72  q = fabs(a[i + ji]);
73  if (q > p) {
74  k = i;
75  p = q;
76  }
77  } // for i
78 
79  if (k != j) {
80  for (l = 1; l <= n; ++l) {
81  const unsigned int li = l*idim;
82  const unsigned int jli = j + li;
83  const unsigned int kli = k + li;
84  tf = a[jli];
85  a[jli] = a[kli];
86  a[kli] = tf;
87  } // for l
88  ++nxch;
89  ir[nxch] = (j << 12) + k;
90  } // if k != j
91  } // if j!=n
92 
93  if (p <= 0.) {
94  det = 0;
95  return false;
96  }
97 
98  det *= a[jj];
99 #ifdef XXX
100  t = fabs(det);
101  if (t < 1e-19 || t > 1e19) {
102  det = 0;
103  return false;
104  }
105 #endif
106 
107  a[jj] = 1. / a[jj];
108  if (j == n) {
109  continue;
110  }
111 
112  const unsigned int jm1 = j - 1;
113  const unsigned int jpi = (j + 1) * idim;
114  const unsigned int jjpi = j + jpi;
115 
116  for (k = j + 1; k <= n; ++k) {
117  const unsigned int ki = k * idim;
118  const unsigned int jki = j + ki;
119  const unsigned int kji = k + jpi;
120  if (j != 1) {
121  for (i = 1; i <= jm1; ++i) {
122  const unsigned int ii = i * idim;
123  a[jki] -= a[i + ki] * a[j + ii];
124  a[kji] -= a[i + jpi] * a[k + ii];
125  } // for i
126  }
127  a[jki] *= a[jj];
128  a[kji] -= a[jjpi] * a[k + ji];
129  } // for k
130  } // for j
131 
132  if (nxch % 2 != 0) {
133  det = -(det);
134  }
135  ir[n] = nxch;
136  return true;
137 } // end of Dfact
138 
139 #endif
bool Dfactir(Matrix &rhs, typename Matrix::value_type &det, unsigned int *ir)
Definition: Dfactir.hh:36
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