Garfield++ v1r0
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
14//#include "wcpplib/list/AbsArr.h"
15//#include "wcpplib/math/DoubleAc.h"
16
17/*
18template<class M, class X>
19void abstract_inverse(M& mi, M& mr, long q, int& serr)
20 // Both arrays are changed.
21 // If can not inverse (diagonal elements get zero) serr=1, if all OK - serr=0
22 // M any matrix class supporting access to elements by the function
23 // M.ac(nrow, ncol), both indexes start from 0.
24 // X - class of type of element if this array.
25 // It should support fabs(X) and ariphmetic operations.
26{
27 long nr, nr1, nc;
28 for(nr=0; nr<q; nr++)
29 {
30 long nmax=0;
31 double d=0;
32 for(nr1=nr; nr1<q; nr1++)
33 {
34 if(fabs(mi.ac(nr1,nr)) > d)
35 {
36 d = fabs(mi.ac(nr1,nr));
37 nmax = nr1;
38 }
39 }
40 //mcout<<"d="<<d<<'\n';
41 //mcout<<"nmax="<<nmax<<'\n';
42 if(d == 0)
43 {
44 serr = 1;
45 return;
46 }
47 if(nmax > nr)
48 {
49 for(nc=nr; nc<q; nc++)
50 {
51 X t(mi.ac(nr,nc));
52 mi.ac(nr,nc) = mi.ac(nmax,nc);
53 mi.ac(nmax,nc) = t;
54 }
55 for(nc=0; nc<q; nc++)
56 {
57 X t(mr.ac(nr,nc));
58 mr.ac(nr,nc) = mr.ac(nmax,nc);
59 mr.ac(nmax,nc) = t;
60 }
61 //long tl=order[nr];
62 //order[nr] = order[nmax];
63 //order[nmax] = tl;
64 }
65 X t=mi.ac(nr,nr);
66 for(nr1=0; nr1<q; nr1++)
67 {
68 if(nr1 != nr)
69 {
70 X k(mi.ac(nr1,nr)/t);
71 //mcout<<"nr1="<<nr1<<" nr="<<nr<<'\n';
72 //mcout<<"k="<<k<<'\n';
73 for(nc=nr; nc<q; nc++)
74 {
75 mi.ac(nr1,nc) -= k * mi.ac(nr,nc);
76 }
77 for(nc=0; nc<q; nc++)
78 {
79 mr.ac(nr1,nc) -= k * mr.ac(nr,nc);
80 }
81 }
82 }
83 for(nc=nr; nc<q; nc++)
84 {
85 mi.ac(nr,nc) /= t;
86 }
87 for(nc=0; nc<q; nc++)
88 {
89 mr.ac(nr,nc) /= t;
90 }
91 }
92}
93*/
94
95#define ALWAYS_USE_TEMPLATE_PAR_AS_FUN_PAR // required by sun Solaris,
96// unknown version
97#ifndef ALWAYS_USE_TEMPLATE_PAR_AS_FUN_PAR
98
99template <class M, class X>
100X abstract_determinant(M& mi, long q)
101
102#else
103 template <class M, class X>
104X abstract_determinant(M& mi, long q,
105 X /*fict*/) // fict - fictitious parameters,
106// any value
107#endif
108
109 //X abstract_determinant(M& mi, long q, int& serr)
110 // array mi is changed.
111 // If can not calc (diagonal elements get zero) serr=1, if all OK - serr=0
112 // M any matrix class supporting access to elements by the function
113 // M.ac(nrow, ncol), both indexes start from 0.
114 // X - class of type of element if this array.
115 // It should support fabs(X) and ariphmetic operations.
116 {
117 if (q == 1) {
118 return mi.ac(0, 0);
119 } else if (q == 2) {
120 return mi.ac(0, 0) * mi.ac(1, 1) - mi.ac(0, 1) * mi.ac(1, 0);
121 } else if (q == 3) {
122 return mi.ac(0, 0) * mi.ac(1, 1) * mi.ac(2, 2) +
123 mi.ac(0, 2) * mi.ac(1, 0) * mi.ac(2, 1) +
124 mi.ac(0, 1) * mi.ac(1, 2) * mi.ac(2, 0) -
125 mi.ac(0, 2) * mi.ac(1, 1) * mi.ac(2, 0) -
126 mi.ac(0, 0) * mi.ac(1, 2) * mi.ac(2, 1) -
127 mi.ac(0, 1) * mi.ac(1, 0) * mi.ac(2, 2);
128 } else {
129 long nr, nr1, nc;
130 X koef = 1;
131 for (nr = 0; nr < q; nr++) {
132 long nmax = 0;
133 double d = 0;
134 for (nr1 = nr; nr1 < q; nr1++) {
135 if (fabs(mi.ac(nr1, nr)) > d) {
136 d = fabs(mi.ac(nr1, nr));
137 nmax = nr1;
138 }
139 }
140 //mcout<<"d="<<d<<'\n';
141 //mcout<<"nmax="<<nmax<<'\n';
142 if (d == 0) {
143 //serr = 1;
144 return koef * mi.ac(nmax, nr);
145 }
146 if (nmax > nr) {
147 for (nc = nr; nc < q; nc++) {
148 X t(mi.ac(nr, nc));
149 mi.ac(nr, nc) = mi.ac(nmax, nc);
150 mi.ac(nmax, nc) = t;
151 }
152 koef *= -1; // trancposition of rows: determinant changes sign
153 }
154 X t = mi.ac(nr, nr);
155 for (nr1 = nr + 1; nr1 < q; nr1++) {
156 X k(mi.ac(nr1, nr) / t);
157 //mcout<<"nr1="<<nr1<<" nr="<<nr<<'\n';
158 //mcout<<"k="<<k<<'\n';
159 for (nc = nr; nc < q; nc++) {
160 mi.ac(nr1, nc) -= k * mi.ac(nr, nc);
161 } // add elements of another row: the main value of
162 // determinant is not affected (proven in linear algebra)
163 // But the resolution gets worser.
164 }
165 for (nc = nr; nc < q; nc++) {
166 mi.ac(nr, nc) /= t;
167 }
168 koef *= t;
169 }
170 return koef;
171 }
172}
173
174#endif
DoubleAc fabs(const DoubleAc &f)
Definition: DoubleAc.h:616
X abstract_determinant(M &mi, long q, X)
Definition: abs_inverse.h:104