Garfield++ 4.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
abs_inverse.h
Go to the documentation of this file.
1#ifndef ABS_INVERSE_H
2#define ABS_INVERSE_H
3/*
4Copyright (c) 2001 I. B. Smirnov
5
6Permission to use, copy, modify, distribute and sell this file
7and its documentation for any purpose is hereby granted without fee,
8provided that the above copyright notice, this permission notice,
9and notices about any modifications of the original text
10appear in all copies and in supporting documentation.
11It is provided "as is" without express or implied warranty.
12*/
13
14namespace Heed {
15
16// X abstract_determinant(M& mi, long q, int& serr)
17// The array mi is changed.
18// If can not calc (diagonal elements get zero) serr=1, if all OK - serr=0
19// M any matrix class supporting access to elements by the function
20// M.ac(nrow, ncol), both indexes start from 0.
21// X - class of type of element if this array.
22// It should support fabs(X) and arithmetic operations.
23
24#define ALWAYS_USE_TEMPLATE_PAR_AS_FUN_PAR // required by sun Solaris
25#ifndef ALWAYS_USE_TEMPLATE_PAR_AS_FUN_PAR
26
27template <class M, class X>
28X abstract_determinant(M& mi, long q) {
29
30#else
31template <class M, class X>
32X abstract_determinant(M& mi, long q, X /*dummy*/) {
33#endif
34
35 if (q == 1) {
36 return mi.ac(0, 0);
37 } else if (q == 2) {
38 return mi.ac(0, 0) * mi.ac(1, 1) - mi.ac(0, 1) * mi.ac(1, 0);
39 } else if (q == 3) {
40 return mi.ac(0, 0) * mi.ac(1, 1) * mi.ac(2, 2) +
41 mi.ac(0, 2) * mi.ac(1, 0) * mi.ac(2, 1) +
42 mi.ac(0, 1) * mi.ac(1, 2) * mi.ac(2, 0) -
43 mi.ac(0, 2) * mi.ac(1, 1) * mi.ac(2, 0) -
44 mi.ac(0, 0) * mi.ac(1, 2) * mi.ac(2, 1) -
45 mi.ac(0, 1) * mi.ac(1, 0) * mi.ac(2, 2);
46 }
47 X koef = 1;
48 for (long nr = 0; nr < q; nr++) {
49 long nmax = 0;
50 double d = 0;
51 for (long nr1 = nr; nr1 < q; nr1++) {
52 if (fabs(mi.ac(nr1, nr)) > d) {
53 d = fabs(mi.ac(nr1, nr));
54 nmax = nr1;
55 }
56 }
57 // mcout<<"d="<<d<<'\n';
58 // mcout<<"nmax="<<nmax<<'\n';
59 if (d == 0) {
60 // serr = 1;
61 return koef * mi.ac(nmax, nr);
62 }
63 if (nmax > nr) {
64 for (long nc = nr; nc < q; nc++) {
65 X t(mi.ac(nr, nc));
66 mi.ac(nr, nc) = mi.ac(nmax, nc);
67 mi.ac(nmax, nc) = t;
68 }
69 // transposition of rows: determinant changes sign
70 koef *= -1;
71 }
72 X t = mi.ac(nr, nr);
73 for (long nr1 = nr + 1; nr1 < q; nr1++) {
74 X k(mi.ac(nr1, nr) / t);
75 // mcout<<"nr1="<<nr1<<" nr="<<nr<<'\n';
76 // mcout<<"k="<<k<<'\n';
77 // add elements of another row: the main value of
78 // determinant is not affected (proven in linear algebra)
79 // But the resolution gets worser.
80 for (long nc = nr; nc < q; nc++) {
81 mi.ac(nr1, nc) -= k * mi.ac(nr, nc);
82 }
83 }
84 for (long nc = nr; nc < q; nc++) {
85 mi.ac(nr, nc) /= t;
86 }
87 koef *= t;
88 }
89 return koef;
90}
91
92}
93
94#endif
Definition: BGMesh.cpp:6
X abstract_determinant(M &mi, long q, X)
Definition: abs_inverse.h:32
DoubleAc fabs(const DoubleAc &f)
Definition: DoubleAc.h:615