FEDRA emulsion software from the OPERA Collaboration
Dsinv.hh File Reference

Go to the source code of this file.

Functions

template<class T , int n, int idim>
bool Dsinv (T *a)
 

Function Documentation

◆ Dsinv()

template<class T , int n, int idim>
bool Dsinv ( T *  a)

Dsinv. Compute inverse of a symmetric, positive definite matrix of dimension $idim$ and order $n$.

Author
T. Glebe
35 {
36
37 /* Local variables */
38 static int i, j, k, l;
39 static T s31, s32;
40 static int jm1, jp1;
41
42 /* Parameter adjustments */
43 a -= idim + 1;
44
45 /* Function Body */
46 if (idim < n || n <= 1) {
47 return false;
48 }
49
50 /* sfact.inc */
51 for (j = 1; j <= n; ++j) {
52 const int ja = j * idim;
53 const int jj = j + ja;
54 const int ja1 = ja + idim;
55
56 if (a[jj] <= 0.) { return false; }
57 a[jj] = 1. / a[jj];
58 if (j == n) { break; }
59
60 for (l = j + 1; l <= n; ++l) {
61 a[j + l * idim] = a[jj] * a[l + ja];
62 const int lj = l + ja1;
63 for (i = 1; i <= j; ++i) {
64 a[lj] -= a[l + i * idim] * a[i + ja1];
65 }
66 }
67 }
68
69 /* sfinv.inc */
70 // idim << 1 is equal to idim * 2
71 // compiler will compute the arguments!
72 a[(idim << 1) + 1] = -a[(idim << 1) + 1];
73 a[idim + 2] = a[(idim << 1) + 1] * a[(idim << 1) + 2];
74
75 if(n > 2) {
76
77 for (j = 3; j <= n; ++j) {
78 const int jm2 = j - 2;
79 const int ja = j * idim;
80 const int jj = j + ja;
81 const int j1 = j - 1 + ja;
82
83 for (k = 1; k <= jm2; ++k) {
84 s31 = a[k + ja];
85
86 for (i = k; i <= jm2; ++i) {
87 s31 += a[k + (i + 1) * idim] * a[i + 1 + ja];
88 } // for i
89 a[k + ja] = -s31;
90 a[j + k * idim] = -s31 * a[jj];
91 } // for k
92 a[j1] *= -1;
93 // a[j1] = -a[j1];
94 a[jj - idim] = a[j1] * a[jj];
95 } // for j
96 } // if (n>2)
97
98 j = 1;
99 do {
100 const int jad = j * idim;
101 const int jj = j + jad;
102
103 jp1 = j + 1;
104 for (i = jp1; i <= n; ++i) {
105 a[jj] += a[j + i * idim] * a[i + jad];
106 } // for i
107
108 jm1 = j;
109 j = jp1;
110 const int ja = j * idim;
111
112 for (k = 1; k <= jm1; ++k) {
113 s32 = 0.;
114 for (i = j; i <= n; ++i) {
115 s32 += a[k + i * idim] * a[i + ja];
116 } // for i
117 a[k + ja] = a[j + k * idim] = s32;
118 } // for k
119 } while(j < n);
120
121 return true;
122} // end of Dsinv
void a()
Definition: check_aligned.C:59