00001
00002
00003
00004 #ifndef ROOT_Math_CholeskyDecomp
00005 #define ROOT_Math_CholeskyDecomp
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <cmath>
00022 #include <algorithm>
00023
00024 namespace ROOT {
00025
00026 namespace Math {
00027
00028
00029 namespace CholeskyDecompHelpers {
00030
00031 template<class F, unsigned N, class M> struct _decomposer;
00032 template<class F, unsigned N, class M> struct _inverter;
00033 template<class F, unsigned N, class V> struct _solver;
00034 }
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 template<class F, unsigned N> class CholeskyDecomp
00067 {
00068 private:
00069
00070
00071
00072 F fL[N * (N + 1) / 2];
00073
00074 bool fOk;
00075
00076 template<typename G> class PackedArrayAdapter
00077 {
00078 private:
00079 G* fArr;
00080 public:
00081
00082 PackedArrayAdapter(G* arr) : fArr(arr) {}
00083
00084 const G operator()(unsigned i, unsigned j) const
00085 { return fArr[((i * (i + 1)) / 2) + j]; }
00086
00087 G& operator()(unsigned i, unsigned j)
00088 { return fArr[((i * (i + 1)) / 2) + j]; }
00089 };
00090 public:
00091
00092
00093
00094
00095
00096
00097
00098
00099 template<class M> CholeskyDecomp(const M& m) :
00100 fL( ), fOk(false)
00101 {
00102 using CholeskyDecompHelpers::_decomposer;
00103 fOk = _decomposer<F, N, M>()(fL, m);
00104 }
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 template<typename G> CholeskyDecomp(G* m) :
00118 fL(), fOk(false)
00119 {
00120 using CholeskyDecompHelpers::_decomposer;
00121 fOk = _decomposer<F, N, PackedArrayAdapter<G> >()(
00122 fL, PackedArrayAdapter<G>(m));
00123 }
00124
00125
00126
00127 bool ok() const { return fOk; }
00128
00129
00130 operator bool() const { return fOk; }
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141 template<class V> bool Solve(V& rhs) const
00142 {
00143 using CholeskyDecompHelpers::_solver;
00144 if (fOk) _solver<F,N,V>()(rhs, fL); return fOk;
00145 }
00146
00147
00148
00149
00150
00151
00152
00153
00154 template<class M> bool Invert(M& m) const
00155 {
00156 using CholeskyDecompHelpers::_inverter;
00157 if (fOk) _inverter<F,N,M>()(m, fL); return fOk;
00158 }
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 template<typename G> bool Invert(G* m) const
00172 {
00173 using CholeskyDecompHelpers::_inverter;
00174 if (fOk) {
00175 PackedArrayAdapter<G> adapted(m);
00176 _inverter<F,N,PackedArrayAdapter<G> >()(adapted, fL);
00177 }
00178 return fOk;
00179 }
00180 };
00181
00182
00183 namespace CholeskyDecompHelpers {
00184
00185 template<class F, unsigned N, class M> struct _decomposer
00186 {
00187
00188
00189 bool operator()(F* dst, const M& src) const
00190 {
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 F *base1 = &dst[0];
00204 for (unsigned i = 0; i < N; base1 += ++i) {
00205 F tmpdiag = F(0);
00206
00207 F *base2 = &dst[0];
00208 for (unsigned j = 0; j < i; base2 += ++j) {
00209 F tmp = src(i, j);
00210 for (unsigned k = j; k--; )
00211 tmp -= base1[k] * base2[k];
00212 base1[j] = tmp *= base2[j];
00213
00214 tmpdiag += tmp * tmp;
00215 }
00216
00217 tmpdiag = src(i, i) - tmpdiag;
00218
00219 if (tmpdiag <= F(0)) return false;
00220 else base1[i] = std::sqrt(F(1) / tmpdiag);
00221 }
00222 return true;
00223 }
00224 };
00225
00226
00227 template<class F, unsigned N, class M> struct _inverter
00228 {
00229
00230 void operator()(M& dst, const F* src) const
00231 {
00232
00233 F l[N * (N + 1) / 2];
00234 std::copy(src, src + ((N * (N + 1)) / 2), l);
00235
00236 F* base1 = &l[1];
00237 for (unsigned i = 1; i < N; base1 += ++i) {
00238 for (unsigned j = 0; j < i; ++j) {
00239 F tmp = F(0);
00240 const F *base2 = &l[(i * (i - 1)) / 2];
00241 for (unsigned k = i; k-- > j; base2 -= k)
00242 tmp -= base1[k] * base2[j];
00243 base1[j] = tmp * base1[i];
00244 }
00245 }
00246
00247
00248 for (unsigned i = N; i--; ) {
00249 for (unsigned j = i + 1; j--; ) {
00250 F tmp = F(0);
00251 base1 = &l[(N * (N - 1)) / 2];
00252 for (unsigned k = N; k-- > i; base1 -= k)
00253 tmp += base1[i] * base1[j];
00254 dst(i, j) = tmp;
00255 }
00256 }
00257 }
00258 };
00259
00260
00261 template<class F, unsigned N, class V> struct _solver
00262 {
00263
00264 void operator()(V& rhs, const F* l) const
00265 {
00266
00267 for (unsigned k = 0; k < N; ++k) {
00268 const unsigned base = (k * (k + 1)) / 2;
00269 F sum = F(0);
00270 for (unsigned i = k; i--; )
00271 sum += rhs[i] * l[base + i];
00272
00273 rhs[k] = (rhs[k] - sum) * l[base + k];
00274 }
00275
00276 for (unsigned k = N; k--; ) {
00277 F sum = F(0);
00278 for (unsigned i = N; --i > k; )
00279 sum += rhs[i] * l[(i * (i + 1)) / 2 + k];
00280
00281 rhs[k] = (rhs[k] - sum) * l[(k * (k + 1)) / 2 + k];
00282 }
00283 }
00284 };
00285
00286
00287 template<class F, class M> struct _decomposer<F, 6, M>
00288 {
00289
00290 bool operator()(F* dst, const M& src) const
00291 {
00292 if (src(0,0) <= F(0)) return false;
00293 dst[0] = std::sqrt(F(1) / src(0,0));
00294 dst[1] = src(1,0) * dst[0];
00295 dst[2] = src(1,1) - dst[1] * dst[1];
00296 if (dst[2] <= F(0)) return false;
00297 else dst[2] = std::sqrt(F(1) / dst[2]);
00298 dst[3] = src(2,0) * dst[0];
00299 dst[4] = (src(2,1) - dst[1] * dst[3]) * dst[2];
00300 dst[5] = src(2,2) - (dst[3] * dst[3] + dst[4] * dst[4]);
00301 if (dst[5] <= F(0)) return false;
00302 else dst[5] = std::sqrt(F(1) / dst[5]);
00303 dst[6] = src(3,0) * dst[0];
00304 dst[7] = (src(3,1) - dst[1] * dst[6]) * dst[2];
00305 dst[8] = (src(3,2) - dst[3] * dst[6] - dst[4] * dst[7]) * dst[5];
00306 dst[9] = src(3,3) - (dst[6] * dst[6] + dst[7] * dst[7] + dst[8] * dst[8]);
00307 if (dst[9] <= F(0)) return false;
00308 else dst[9] = std::sqrt(F(1) / dst[9]);
00309 dst[10] = src(4,0) * dst[0];
00310 dst[11] = (src(4,1) - dst[1] * dst[10]) * dst[2];
00311 dst[12] = (src(4,2) - dst[3] * dst[10] - dst[4] * dst[11]) * dst[5];
00312 dst[13] = (src(4,3) - dst[6] * dst[10] - dst[7] * dst[11] - dst[8] * dst[12]) * dst[9];
00313 dst[14] = src(4,4) - (dst[10]*dst[10]+dst[11]*dst[11]+dst[12]*dst[12]+dst[13]*dst[13]);
00314 if (dst[14] <= F(0)) return false;
00315 else dst[14] = std::sqrt(F(1) / dst[14]);
00316 dst[15] = src(5,0) * dst[0];
00317 dst[16] = (src(5,1) - dst[1] * dst[15]) * dst[2];
00318 dst[17] = (src(5,2) - dst[3] * dst[15] - dst[4] * dst[16]) * dst[5];
00319 dst[18] = (src(5,3) - dst[6] * dst[15] - dst[7] * dst[16] - dst[8] * dst[17]) * dst[9];
00320 dst[19] = (src(5,4) - dst[10] * dst[15] - dst[11] * dst[16] - dst[12] * dst[17] - dst[13] * dst[18]) * dst[14];
00321 dst[20] = src(5,5) - (dst[15]*dst[15]+dst[16]*dst[16]+dst[17]*dst[17]+dst[18]*dst[18]+dst[19]*dst[19]);
00322 if (dst[20] <= F(0)) return false;
00323 else dst[20] = std::sqrt(F(1) / dst[20]);
00324 return true;
00325 }
00326 };
00327
00328 template<class F, class M> struct _decomposer<F, 5, M>
00329 {
00330
00331 bool operator()(F* dst, const M& src) const
00332 {
00333 if (src(0,0) <= F(0)) return false;
00334 dst[0] = std::sqrt(F(1) / src(0,0));
00335 dst[1] = src(1,0) * dst[0];
00336 dst[2] = src(1,1) - dst[1] * dst[1];
00337 if (dst[2] <= F(0)) return false;
00338 else dst[2] = std::sqrt(F(1) / dst[2]);
00339 dst[3] = src(2,0) * dst[0];
00340 dst[4] = (src(2,1) - dst[1] * dst[3]) * dst[2];
00341 dst[5] = src(2,2) - (dst[3] * dst[3] + dst[4] * dst[4]);
00342 if (dst[5] <= F(0)) return false;
00343 else dst[5] = std::sqrt(F(1) / dst[5]);
00344 dst[6] = src(3,0) * dst[0];
00345 dst[7] = (src(3,1) - dst[1] * dst[6]) * dst[2];
00346 dst[8] = (src(3,2) - dst[3] * dst[6] - dst[4] * dst[7]) * dst[5];
00347 dst[9] = src(3,3) - (dst[6] * dst[6] + dst[7] * dst[7] + dst[8] * dst[8]);
00348 if (dst[9] <= F(0)) return false;
00349 else dst[9] = std::sqrt(F(1) / dst[9]);
00350 dst[10] = src(4,0) * dst[0];
00351 dst[11] = (src(4,1) - dst[1] * dst[10]) * dst[2];
00352 dst[12] = (src(4,2) - dst[3] * dst[10] - dst[4] * dst[11]) * dst[5];
00353 dst[13] = (src(4,3) - dst[6] * dst[10] - dst[7] * dst[11] - dst[8] * dst[12]) * dst[9];
00354 dst[14] = src(4,4) - (dst[10]*dst[10]+dst[11]*dst[11]+dst[12]*dst[12]+dst[13]*dst[13]);
00355 if (dst[14] <= F(0)) return false;
00356 else dst[14] = std::sqrt(F(1) / dst[14]);
00357 return true;
00358 }
00359 };
00360
00361 template<class F, class M> struct _decomposer<F, 4, M>
00362 {
00363
00364 bool operator()(F* dst, const M& src) const
00365 {
00366 if (src(0,0) <= F(0)) return false;
00367 dst[0] = std::sqrt(F(1) / src(0,0));
00368 dst[1] = src(1,0) * dst[0];
00369 dst[2] = src(1,1) - dst[1] * dst[1];
00370 if (dst[2] <= F(0)) return false;
00371 else dst[2] = std::sqrt(F(1) / dst[2]);
00372 dst[3] = src(2,0) * dst[0];
00373 dst[4] = (src(2,1) - dst[1] * dst[3]) * dst[2];
00374 dst[5] = src(2,2) - (dst[3] * dst[3] + dst[4] * dst[4]);
00375 if (dst[5] <= F(0)) return false;
00376 else dst[5] = std::sqrt(F(1) / dst[5]);
00377 dst[6] = src(3,0) * dst[0];
00378 dst[7] = (src(3,1) - dst[1] * dst[6]) * dst[2];
00379 dst[8] = (src(3,2) - dst[3] * dst[6] - dst[4] * dst[7]) * dst[5];
00380 dst[9] = src(3,3) - (dst[6] * dst[6] + dst[7] * dst[7] + dst[8] * dst[8]);
00381 if (dst[9] <= F(0)) return false;
00382 else dst[9] = std::sqrt(F(1) / dst[9]);
00383 return true;
00384 }
00385 };
00386
00387 template<class F, class M> struct _decomposer<F, 3, M>
00388 {
00389
00390 bool operator()(F* dst, const M& src) const
00391 {
00392 if (src(0,0) <= F(0)) return false;
00393 dst[0] = std::sqrt(F(1) / src(0,0));
00394 dst[1] = src(1,0) * dst[0];
00395 dst[2] = src(1,1) - dst[1] * dst[1];
00396 if (dst[2] <= F(0)) return false;
00397 else dst[2] = std::sqrt(F(1) / dst[2]);
00398 dst[3] = src(2,0) * dst[0];
00399 dst[4] = (src(2,1) - dst[1] * dst[3]) * dst[2];
00400 dst[5] = src(2,2) - (dst[3] * dst[3] + dst[4] * dst[4]);
00401 if (dst[5] <= F(0)) return false;
00402 else dst[5] = std::sqrt(F(1) / dst[5]);
00403 return true;
00404 }
00405 };
00406
00407 template<class F, class M> struct _decomposer<F, 2, M>
00408 {
00409
00410 bool operator()(F* dst, const M& src) const
00411 {
00412 if (src(0,0) <= F(0)) return false;
00413 dst[0] = std::sqrt(F(1) / src(0,0));
00414 dst[1] = src(1,0) * dst[0];
00415 dst[2] = src(1,1) - dst[1] * dst[1];
00416 if (dst[2] <= F(0)) return false;
00417 else dst[2] = std::sqrt(F(1) / dst[2]);
00418 return true;
00419 }
00420 };
00421
00422 template<class F, class M> struct _decomposer<F, 1, M>
00423 {
00424
00425 bool operator()(F* dst, const M& src) const
00426 {
00427 if (src(0,0) <= F(0)) return false;
00428 dst[0] = std::sqrt(F(1) / src(0,0));
00429 return true;
00430 }
00431 };
00432
00433 template<class F, class M> struct _decomposer<F, 0, M>
00434 {
00435 private:
00436 _decomposer() { };
00437 bool operator()(F* dst, const M& src) const;
00438 };
00439
00440
00441 template<class F, class M> struct _inverter<F,6,M>
00442 {
00443
00444 inline void operator()(M& dst, const F* src) const
00445 {
00446 const F li21 = -src[1] * src[0] * src[2];
00447 const F li32 = -src[4] * src[2] * src[5];
00448 const F li31 = (src[1] * src[4] * src[2] - src[3]) * src[0] * src[5];
00449 const F li43 = -src[8] * src[9] * src[5];
00450 const F li42 = (src[4] * src[8] * src[5] - src[7]) * src[2] * src[9];
00451 const F li41 = (-src[1] * src[4] * src[8] * src[2] * src[5] +
00452 src[1] * src[7] * src[2] + src[3] * src[8] * src[5] - src[6]) * src[0] * src[9];
00453 const F li54 = -src[13] * src[14] * src[9];
00454 const F li53 = (src[13] * src[8] * src[9] - src[12]) * src[5] * src[14];
00455 const F li52 = (-src[4] * src[8] * src[13] * src[5] * src[9] +
00456 src[4] * src[12] * src[5] + src[7] * src[13] * src[9] - src[11]) * src[2] * src[14];
00457 const F li51 = (src[1]*src[4]*src[8]*src[13]*src[2]*src[5]*src[9] -
00458 src[13]*src[8]*src[3]*src[9]*src[5] - src[12]*src[4]*src[1]*src[2]*src[5] - src[13]*src[7]*src[1]*src[9]*src[2] +
00459 src[11]*src[1]*src[2] + src[12]*src[3]*src[5] + src[13]*src[6]*src[9] -src[10]) * src[0] * src[14];
00460 const F li65 = -src[19] * src[20] * src[14];
00461 const F li64 = (src[19] * src[13] * src[14] - src[18]) * src[9] * src[20];
00462 const F li63 = (-src[8] * src[13] * src[19] * src[9] * src[14] +
00463 src[8] * src[18] * src[9] + src[12] * src[19] * src[14] - src[17]) * src[5] * src[20];
00464 const F li62 = (src[4]*src[8]*src[13]*src[19]*src[5]*src[9]*src[14] -
00465 src[18]*src[8]*src[4]*src[9]*src[5] - src[19]*src[12]*src[4]*src[14]*src[5] -src[19]*src[13]*src[7]*src[14]*src[9] +
00466 src[17]*src[4]*src[5] + src[18]*src[7]*src[9] + src[19]*src[11]*src[14] - src[16]) * src[2] * src[20];
00467 const F li61 = (-src[19]*src[13]*src[8]*src[4]*src[1]*src[2]*src[5]*src[9]*src[14] +
00468 src[18]*src[8]*src[4]*src[1]*src[2]*src[5]*src[9] + src[19]*src[12]*src[4]*src[1]*src[2]*src[5]*src[14] +
00469 src[19]*src[13]*src[7]*src[1]*src[2]*src[9]*src[14] + src[19]*src[13]*src[8]*src[3]*src[5]*src[9]*src[14] -
00470 src[17]*src[4]*src[1]*src[2]*src[5] - src[18]*src[7]*src[1]*src[2]*src[9] - src[19]*src[11]*src[1]*src[2]*src[14] -
00471 src[18]*src[8]*src[3]*src[5]*src[9] - src[19]*src[12]*src[3]*src[5]*src[14] - src[19]*src[13]*src[6]*src[9]*src[14] +
00472 src[16]*src[1]*src[2] + src[17]*src[3]*src[5] + src[18]*src[6]*src[9] + src[19]*src[10]*src[14] - src[15]) *
00473 src[0] * src[20];
00474
00475 dst(0,0) = li61*li61 + li51*li51 + li41*li41 + li31*li31 + li21*li21 + src[0]*src[0];
00476 dst(1,0) = li61*li62 + li51*li52 + li41*li42 + li31*li32 + li21*src[2];
00477 dst(1,1) = li62*li62 + li52*li52 + li42*li42 + li32*li32 + src[2]*src[2];
00478 dst(2,0) = li61*li63 + li51*li53 + li41*li43 + li31*src[5];
00479 dst(2,1) = li62*li63 + li52*li53 + li42*li43 + li32*src[5];
00480 dst(2,2) = li63*li63 + li53*li53 + li43*li43 + src[5]*src[5];
00481 dst(3,0) = li61*li64 + li51*li54 + li41*src[9];
00482 dst(3,1) = li62*li64 + li52*li54 + li42*src[9];
00483 dst(3,2) = li63*li64 + li53*li54 + li43*src[9];
00484 dst(3,3) = li64*li64 + li54*li54 + src[9]*src[9];
00485 dst(4,0) = li61*li65 + li51*src[14];
00486 dst(4,1) = li62*li65 + li52*src[14];
00487 dst(4,2) = li63*li65 + li53*src[14];
00488 dst(4,3) = li64*li65 + li54*src[14];
00489 dst(4,4) = li65*li65 + src[14]*src[14];
00490 dst(5,0) = li61*src[20];
00491 dst(5,1) = li62*src[20];
00492 dst(5,2) = li63*src[20];
00493 dst(5,3) = li64*src[20];
00494 dst(5,4) = li65*src[20];
00495 dst(5,5) = src[20]*src[20];
00496 }
00497 };
00498
00499 template<class F, class M> struct _inverter<F,5,M>
00500 {
00501
00502 inline void operator()(M& dst, const F* src) const
00503 {
00504 const F li21 = -src[1] * src[0] * src[2];
00505 const F li32 = -src[4] * src[2] * src[5];
00506 const F li31 = (src[1] * src[4] * src[2] - src[3]) * src[0] * src[5];
00507 const F li43 = -src[8] * src[9] * src[5];
00508 const F li42 = (src[4] * src[8] * src[5] - src[7]) * src[2] * src[9];
00509 const F li41 = (-src[1] * src[4] * src[8] * src[2] * src[5] +
00510 src[1] * src[7] * src[2] + src[3] * src[8] * src[5] - src[6]) * src[0] * src[9];
00511 const F li54 = -src[13] * src[14] * src[9];
00512 const F li53 = (src[13] * src[8] * src[9] - src[12]) * src[5] * src[14];
00513 const F li52 = (-src[4] * src[8] * src[13] * src[5] * src[9] +
00514 src[4] * src[12] * src[5] + src[7] * src[13] * src[9] - src[11]) * src[2] * src[14];
00515 const F li51 = (src[1]*src[4]*src[8]*src[13]*src[2]*src[5]*src[9] -
00516 src[13]*src[8]*src[3]*src[9]*src[5] - src[12]*src[4]*src[1]*src[2]*src[5] - src[13]*src[7]*src[1]*src[9]*src[2] +
00517 src[11]*src[1]*src[2] + src[12]*src[3]*src[5] + src[13]*src[6]*src[9] -src[10]) * src[0] * src[14];
00518
00519 dst(0,0) = li51*li51 + li41*li41 + li31*li31 + li21*li21 + src[0]*src[0];
00520 dst(1,0) = li51*li52 + li41*li42 + li31*li32 + li21*src[2];
00521 dst(1,1) = li52*li52 + li42*li42 + li32*li32 + src[2]*src[2];
00522 dst(2,0) = li51*li53 + li41*li43 + li31*src[5];
00523 dst(2,1) = li52*li53 + li42*li43 + li32*src[5];
00524 dst(2,2) = li53*li53 + li43*li43 + src[5]*src[5];
00525 dst(3,0) = li51*li54 + li41*src[9];
00526 dst(3,1) = li52*li54 + li42*src[9];
00527 dst(3,2) = li53*li54 + li43*src[9];
00528 dst(3,3) = li54*li54 + src[9]*src[9];
00529 dst(4,0) = li51*src[14];
00530 dst(4,1) = li52*src[14];
00531 dst(4,2) = li53*src[14];
00532 dst(4,3) = li54*src[14];
00533 dst(4,4) = src[14]*src[14];
00534 }
00535 };
00536
00537 template<class F, class M> struct _inverter<F,4,M>
00538 {
00539
00540 inline void operator()(M& dst, const F* src) const
00541 {
00542 const F li21 = -src[1] * src[0] * src[2];
00543 const F li32 = -src[4] * src[2] * src[5];
00544 const F li31 = (src[1] * src[4] * src[2] - src[3]) * src[0] * src[5];
00545 const F li43 = -src[8] * src[9] * src[5];
00546 const F li42 = (src[4] * src[8] * src[5] - src[7]) * src[2] * src[9];
00547 const F li41 = (-src[1] * src[4] * src[8] * src[2] * src[5] +
00548 src[1] * src[7] * src[2] + src[3] * src[8] * src[5] - src[6]) * src[0] * src[9];
00549
00550 dst(0,0) = li41*li41 + li31*li31 + li21*li21 + src[0]*src[0];
00551 dst(1,0) = li41*li42 + li31*li32 + li21*src[2];
00552 dst(1,1) = li42*li42 + li32*li32 + src[2]*src[2];
00553 dst(2,0) = li41*li43 + li31*src[5];
00554 dst(2,1) = li42*li43 + li32*src[5];
00555 dst(2,2) = li43*li43 + src[5]*src[5];
00556 dst(3,0) = li41*src[9];
00557 dst(3,1) = li42*src[9];
00558 dst(3,2) = li43*src[9];
00559 dst(3,3) = src[9]*src[9];
00560 }
00561 };
00562
00563 template<class F, class M> struct _inverter<F,3,M>
00564 {
00565
00566 inline void operator()(M& dst, const F* src) const
00567 {
00568 const F li21 = -src[1] * src[0] * src[2];
00569 const F li32 = -src[4] * src[2] * src[5];
00570 const F li31 = (src[1] * src[4] * src[2] - src[3]) * src[0] * src[5];
00571
00572 dst(0,0) = li31*li31 + li21*li21 + src[0]*src[0];
00573 dst(1,0) = li31*li32 + li21*src[2];
00574 dst(1,1) = li32*li32 + src[2]*src[2];
00575 dst(2,0) = li31*src[5];
00576 dst(2,1) = li32*src[5];
00577 dst(2,2) = src[5]*src[5];
00578 }
00579 };
00580
00581 template<class F, class M> struct _inverter<F,2,M>
00582 {
00583
00584 inline void operator()(M& dst, const F* src) const
00585 {
00586 const F li21 = -src[1] * src[0] * src[2];
00587
00588 dst(0,0) = li21*li21 + src[0]*src[0];
00589 dst(1,0) = li21*src[2];
00590 dst(1,1) = src[2]*src[2];
00591 }
00592 };
00593
00594 template<class F, class M> struct _inverter<F,1,M>
00595 {
00596
00597 inline void operator()(M& dst, const F* src) const
00598 {
00599 dst(0,0) = src[0]*src[0];
00600 }
00601 };
00602
00603 template<class F, class M> struct _inverter<F,0,M>
00604 {
00605 private:
00606 _inverter();
00607 void operator()(M& dst, const F* src) const;
00608 };
00609
00610
00611 template<class F, class V> struct _solver<F,6,V>
00612 {
00613
00614 void operator()(V& rhs, const F* l) const
00615 {
00616
00617 const F y0 = rhs[0] * l[0];
00618 const F y1 = (rhs[1]-l[1]*y0)*l[2];
00619 const F y2 = (rhs[2]-(l[3]*y0+l[4]*y1))*l[5];
00620 const F y3 = (rhs[3]-(l[6]*y0+l[7]*y1+l[8]*y2))*l[9];
00621 const F y4 = (rhs[4]-(l[10]*y0+l[11]*y1+l[12]*y2+l[13]*y3))*l[14];
00622 const F y5 = (rhs[5]-(l[15]*y0+l[16]*y1+l[17]*y2+l[18]*y3+l[19]*y4))*l[20];
00623
00624 rhs[5] = y5 * l[20];
00625 rhs[4] = (y4-l[19]*rhs[5])*l[14];
00626 rhs[3] = (y3-(l[18]*rhs[5]+l[13]*rhs[4]))*l[9];
00627 rhs[2] = (y2-(l[17]*rhs[5]+l[12]*rhs[4]+l[8]*rhs[3]))*l[5];
00628 rhs[1] = (y1-(l[16]*rhs[5]+l[11]*rhs[4]+l[7]*rhs[3]+l[4]*rhs[2]))*l[2];
00629 rhs[0] = (y0-(l[15]*rhs[5]+l[10]*rhs[4]+l[6]*rhs[3]+l[3]*rhs[2]+l[1]*rhs[1]))*l[0];
00630 }
00631 };
00632
00633 template<class F, class V> struct _solver<F,5,V>
00634 {
00635
00636 void operator()(V& rhs, const F* l) const
00637 {
00638
00639 const F y0 = rhs[0] * l[0];
00640 const F y1 = (rhs[1]-l[1]*y0)*l[2];
00641 const F y2 = (rhs[2]-(l[3]*y0+l[4]*y1))*l[5];
00642 const F y3 = (rhs[3]-(l[6]*y0+l[7]*y1+l[8]*y2))*l[9];
00643 const F y4 = (rhs[4]-(l[10]*y0+l[11]*y1+l[12]*y2+l[13]*y3))*l[14];
00644
00645 rhs[4] = (y4)*l[14];
00646 rhs[3] = (y3-(l[13]*rhs[4]))*l[9];
00647 rhs[2] = (y2-(l[12]*rhs[4]+l[8]*rhs[3]))*l[5];
00648 rhs[1] = (y1-(l[11]*rhs[4]+l[7]*rhs[3]+l[4]*rhs[2]))*l[2];
00649 rhs[0] = (y0-(l[10]*rhs[4]+l[6]*rhs[3]+l[3]*rhs[2]+l[1]*rhs[1]))*l[0];
00650 }
00651 };
00652
00653 template<class F, class V> struct _solver<F,4,V>
00654 {
00655
00656 void operator()(V& rhs, const F* l) const
00657 {
00658
00659 const F y0 = rhs[0] * l[0];
00660 const F y1 = (rhs[1]-l[1]*y0)*l[2];
00661 const F y2 = (rhs[2]-(l[3]*y0+l[4]*y1))*l[5];
00662 const F y3 = (rhs[3]-(l[6]*y0+l[7]*y1+l[8]*y2))*l[9];
00663
00664 rhs[3] = (y3)*l[9];
00665 rhs[2] = (y2-(l[8]*rhs[3]))*l[5];
00666 rhs[1] = (y1-(l[7]*rhs[3]+l[4]*rhs[2]))*l[2];
00667 rhs[0] = (y0-(l[6]*rhs[3]+l[3]*rhs[2]+l[1]*rhs[1]))*l[0];
00668 }
00669 };
00670
00671 template<class F, class V> struct _solver<F,3,V>
00672 {
00673
00674 void operator()(V& rhs, const F* l) const
00675 {
00676
00677 const F y0 = rhs[0] * l[0];
00678 const F y1 = (rhs[1]-l[1]*y0)*l[2];
00679 const F y2 = (rhs[2]-(l[3]*y0+l[4]*y1))*l[5];
00680
00681 rhs[2] = (y2)*l[5];
00682 rhs[1] = (y1-(l[4]*rhs[2]))*l[2];
00683 rhs[0] = (y0-(l[3]*rhs[2]+l[1]*rhs[1]))*l[0];
00684 }
00685 };
00686
00687 template<class F, class V> struct _solver<F,2,V>
00688 {
00689
00690 void operator()(V& rhs, const F* l) const
00691 {
00692
00693 const F y0 = rhs[0] * l[0];
00694 const F y1 = (rhs[1]-l[1]*y0)*l[2];
00695
00696 rhs[1] = (y1)*l[2];
00697 rhs[0] = (y0-(l[1]*rhs[1]))*l[0];
00698 }
00699 };
00700
00701 template<class F, class V> struct _solver<F,1,V>
00702 {
00703
00704 void operator()(V& rhs, const F* l) const
00705 {
00706
00707 rhs[0] *= l[0] * l[0];
00708 }
00709 };
00710
00711 template<class F, class V> struct _solver<F,0,V>
00712 {
00713 private:
00714 _solver();
00715 void operator()(V& rhs, const F* l) const;
00716 };
00717 }
00718
00719
00720 }
00721
00722 }
00723
00724 #endif // ROOT_Math_CHOLESKYDECOMP
00725