File indexing completed on 2025-01-18 10:10:16
0001
0002
0003
0004 #ifndef ROOT_Math_Dsinv
0005 #define ROOT_Math_Dsinv
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 #include "Math/SMatrixDfwd.h"
0032
0033 namespace ROOT {
0034
0035 namespace Math {
0036
0037
0038
0039
0040
0041
0042
0043 template <class T, int n, int idim>
0044 class SInverter
0045 {
0046
0047 public:
0048 template <class MatrixRep>
0049 inline static bool Dsinv(MatrixRep& rhs) {
0050
0051
0052 int i, j, k, l;
0053 T s31, s32;
0054 int jm1, jp1;
0055
0056
0057 const int arrayOffset = -1*(idim + 1);
0058
0059
0060
0061 if (idim < n || n <= 1) {
0062 return false;
0063 }
0064
0065
0066 for (j = 1; j <= n; ++j) {
0067 const int ja = j * idim;
0068 const int jj = j + ja;
0069 const int ja1 = ja + idim;
0070
0071
0072 if (rhs[jj + arrayOffset] <= 0.) { return false; }
0073 rhs[jj + arrayOffset] = 1. / rhs[jj + arrayOffset];
0074 if (j == n) { break; }
0075
0076 for (l = j + 1; l <= n; ++l) {
0077 rhs[j + (l * idim) + arrayOffset] = rhs[jj + arrayOffset] * rhs[l + ja + arrayOffset];
0078 const int lj = l + ja1;
0079 for (i = 1; i <= j; ++i) {
0080 rhs[lj + arrayOffset] -= rhs[l + (i * idim) + arrayOffset] * rhs[i + ja1 + arrayOffset];
0081 }
0082 }
0083 }
0084
0085
0086
0087
0088 rhs[((idim << 1) + 1) + arrayOffset] = -rhs[((idim << 1) + 1) + arrayOffset];
0089 rhs[idim + 2 + arrayOffset] = rhs[((idim << 1)) + 1 + arrayOffset] * rhs[((idim << 1)) + 2 + arrayOffset];
0090
0091 if(n > 2) {
0092
0093 for (j = 3; j <= n; ++j) {
0094 const int jm2 = j - 2;
0095 const int ja = j * idim;
0096 const int jj = j + ja;
0097 const int j1 = j - 1 + ja;
0098
0099 for (k = 1; k <= jm2; ++k) {
0100 s31 = rhs[k + ja + arrayOffset];
0101
0102 for (i = k; i <= jm2; ++i) {
0103 s31 += rhs[k + ((i + 1) * idim) + arrayOffset] * rhs[i + 1 + ja + arrayOffset];
0104 }
0105 rhs[k + ja + arrayOffset] = -s31;
0106 rhs[j + (k * idim) + arrayOffset] = -s31 * rhs[jj + arrayOffset];
0107 }
0108 rhs[j1 + arrayOffset] *= -1;
0109
0110 rhs[jj - idim + arrayOffset] = rhs[j1 + arrayOffset] * rhs[jj + arrayOffset];
0111 }
0112 }
0113
0114 j = 1;
0115 do {
0116 const int jad = j * idim;
0117 const int jj = j + jad;
0118
0119 jp1 = j + 1;
0120 for (i = jp1; i <= n; ++i) {
0121 rhs[jj + arrayOffset] += rhs[j + (i * idim) + arrayOffset] * rhs[i + jad + arrayOffset];
0122 }
0123
0124 jm1 = j;
0125 j = jp1;
0126 const int ja = j * idim;
0127
0128 for (k = 1; k <= jm1; ++k) {
0129 s32 = 0.;
0130 for (i = j; i <= n; ++i) {
0131 s32 += rhs[k + (i * idim) + arrayOffset] * rhs[i + ja + arrayOffset];
0132 }
0133
0134 rhs[k + ja + arrayOffset] = s32;
0135 }
0136 } while(j < n);
0137
0138 return true;
0139 }
0140
0141
0142
0143
0144 static bool Dsinv(MatRepSym<T,n> & rhs) {
0145
0146
0147 MatRepStd<T,n,n> tmp;
0148 for (int i = 0; i< n*n; ++i)
0149 tmp[i] = rhs[i];
0150
0151 if (! SInverter<T,n,n>::Dsinv(tmp) ) return false;
0152
0153
0154 for (int i = 0; i< n*n; ++i)
0155 rhs[i] = tmp[i];
0156
0157 return true;
0158
0159 }
0160
0161 };
0162
0163
0164
0165 }
0166
0167 }
0168
0169
0170 #endif