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