CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
CholeskyDecomp.h
Go to the documentation of this file.
1 // Author: M. Schiller 2009
2 #error "CholeskyDecomp is now in ROOT"
3 #ifndef ROOT_Math_CholeskyDecomp
4 #define ROOT_Math_CholeskyDecomp
5 
20 namespace ROOT {
21 
22  namespace Math {
23 
25 namespace CholeskyDecompHelpers {
26  // forward decls
27  template<class F, unsigned N, class M> struct _decomposer;
28  template<class F, unsigned N, class M> struct _inverter;
29  template<class F, unsigned N, class V> struct _solver;
30 }
31 
33 
62 template<class F, unsigned N> class CholeskyDecomp
63 {
64 private:
66 
68  F fL[N * (N + 1) / 2];
70  bool fOk;
72  template<typename G> class PackedArrayAdapter
73  {
74  private:
75  G* fArr;
76  public:
78  PackedArrayAdapter(G* arr) : fArr(arr) {}
80  const G operator()(unsigned i, unsigned j) const
81  { return fArr[((i * (i + 1)) / 2) + j]; }
83  G& operator()(unsigned i, unsigned j)
84  { return fArr[((i * (i + 1)) / 2) + j]; }
85  };
86 public:
88 
95  template<class M> CholeskyDecomp(const M& m)
96  {
98  fOk = _decomposer<F, N, M>()(fL, m);
99  }
100 
102 
112  template<typename G> CholeskyDecomp(G* m)
113  {
115  fOk = _decomposer<F, N, PackedArrayAdapter<G> >()(
117  }
118 
120 
121  bool ok() const { return fOk; }
123 
124  operator bool() const { return fOk; }
125 
127 
135  template<class V> bool Solve(V& rhs) const
136  {
138  if (fOk) _solver<F,N,V>()(rhs, fL); return fOk;
139  }
140 
142 
148  template<class M> bool Invert(M& m) const
149  {
151  if (fOk) _inverter<F,N,M>()(m, fL); return fOk;
152  }
153 
155 
165  template<typename G> bool Invert(G* m) const
166  {
168  if (fOk) {
169  PackedArrayAdapter<G> adapted(m);
170  _inverter<F,N,PackedArrayAdapter<G> >()(adapted, fL);
171  }
172  return fOk;
173  }
174 };
175 
176 
177 namespace CholeskyDecompHelpers {
179  template<class F, unsigned N, class M> struct _decomposer
180  {
182 
183  bool operator()(F* dst, const M& src) const
184  {
185  // perform Cholesky decomposition of matrix: M = L L^T
186  // only thing that can go wrong: trying to take square
187  // root of negative number or zero (matrix is
188  // ill-conditioned or singular in these cases)
189 
190  // element L(i,j) is at array position (i * (i+1)) / 2 + j
191 
192  // quirk: we may need to invert L later anyway, so we can
193  // invert elements on diagonale straight away (we only
194  // ever need their reciprocals!)
195 
196  // cache starting address of rows of L for speed reasons
197  F *base1 = &dst[0];
198  for (unsigned i = 0; i < N; base1 += ++i) {
199  F tmpdiag = F(0); // for element on diagonale
200  // calculate off-diagonal elements
201  F *base2 = &dst[0];
202  for (unsigned j = 0; j < i; base2 += ++j) {
203  F tmp = src(i, j);
204  for (unsigned k = j; k--; )
205  tmp -= base1[k] * base2[k];
206  base1[j] = tmp *= base2[j];
207  // keep track of contribution to element on diagonale
208  tmpdiag += tmp * tmp;
209  }
210  // keep truncation error small
211  tmpdiag = src(i, i) - tmpdiag;
212  // check if positive definite
213  if (tmpdiag <= F(0)) return false;
214  else base1[i] = std::sqrt(F(1) / tmpdiag);
215  }
216  return true;
217  }
218  };
219 
221  template<class F, unsigned N, class M> struct _inverter
222  {
224  void operator()(M& dst, const F* src) const
225  {
226  // make working copy
227  F l[N * (N + 1) / 2];
228  std::copy(src, src + ((N * (N + 1)) / 2), l);
229  // ok, next step: invert off-diagonal part of matrix
230  F* base1 = &l[1];
231  for (unsigned i = 1; i < N; base1 += ++i) {
232  for (unsigned j = 0; j < i; ++j) {
233  F tmp = F(0);
234  const F *base2 = &l[(i * (i - 1)) / 2];
235  for (unsigned k = i; k-- > j; base2 -= k)
236  tmp -= base1[k] * base2[j];
237  base1[j] = tmp * base1[i];
238  }
239  }
240 
241  // Li = L^(-1) formed, now calculate M^(-1) = Li^T Li
242  for (unsigned i = N; i--; ) {
243  for (unsigned j = i + 1; j--; ) {
244  F tmp = F(0);
245  base1 = &l[(N * (N - 1)) / 2];
246  for (unsigned k = N; k-- > i; base1 -= k)
247  tmp += base1[i] * base1[j];
248  dst(i, j) = tmp;
249  }
250  }
251  }
252  };
253 
255  template<class F, unsigned N, class V> struct _solver
256  {
258  void operator()(V& rhs, const F* l) const
259  {
260  // solve Ly = rhs
261  for (unsigned k = 0; k < N; ++k) {
262  const unsigned base = (k * (k + 1)) / 2;
263  F sum = F(0);
264  for (unsigned i = k; i--; )
265  sum += rhs[i] * l[base + i];
266  // elements on diagonale are pre-inverted!
267  rhs[k] = (rhs[k] - sum) * l[base + k];
268  }
269  // solve L^Tx = y
270  for (unsigned k = N; k--; ) {
271  F sum = F(0);
272  for (unsigned i = N; --i > k; )
273  sum += rhs[i] * l[(i * (i + 1)) / 2 + k];
274  // elements on diagonale are pre-inverted!
275  rhs[k] = (rhs[k] - sum) * l[(k * (k + 1)) / 2 + k];
276  }
277  }
278  };
279 
281  template<class F, class M> struct _decomposer<F, 6, M>
282  {
284  bool operator()(F* dst, const M& src) const
285  {
286  if (src(0,0) <= F(0)) return false;
287  dst[0] = std::sqrt(F(1) / src(0,0));
288  dst[1] = src(1,0) * dst[0];
289  dst[2] = src(1,1) - dst[1] * dst[1];
290  if (dst[2] <= F(0)) return false;
291  else dst[2] = std::sqrt(F(1) / dst[2]);
292  dst[3] = src(2,0) * dst[0];
293  dst[4] = (src(2,1) - dst[1] * dst[3]) * dst[2];
294  dst[5] = src(2,2) - (dst[3] * dst[3] + dst[4] * dst[4]);
295  if (dst[5] <= F(0)) return false;
296  else dst[5] = std::sqrt(F(1) / dst[5]);
297  dst[6] = src(3,0) * dst[0];
298  dst[7] = (src(3,1) - dst[1] * dst[6]) * dst[2];
299  dst[8] = (src(3,2) - dst[3] * dst[6] - dst[4] * dst[7]) * dst[5];
300  dst[9] = src(3,3) - (dst[6] * dst[6] + dst[7] * dst[7] + dst[8] * dst[8]);
301  if (dst[9] <= F(0)) return false;
302  else dst[9] = std::sqrt(F(1) / dst[9]);
303  dst[10] = src(4,0) * dst[0];
304  dst[11] = (src(4,1) - dst[1] * dst[10]) * dst[2];
305  dst[12] = (src(4,2) - dst[3] * dst[10] - dst[4] * dst[11]) * dst[5];
306  dst[13] = (src(4,3) - dst[6] * dst[10] - dst[7] * dst[11] - dst[8] * dst[12]) * dst[9];
307  dst[14] = src(4,4) - (dst[10]*dst[10]+dst[11]*dst[11]+dst[12]*dst[12]+dst[13]*dst[13]);
308  if (dst[14] <= F(0)) return false;
309  else dst[14] = std::sqrt(F(1) / dst[14]);
310  dst[15] = src(5,0) * dst[0];
311  dst[16] = (src(5,1) - dst[1] * dst[15]) * dst[2];
312  dst[17] = (src(5,2) - dst[3] * dst[15] - dst[4] * dst[16]) * dst[5];
313  dst[18] = (src(5,3) - dst[6] * dst[15] - dst[7] * dst[16] - dst[8] * dst[17]) * dst[9];
314  dst[19] = (src(5,4) - dst[10] * dst[15] - dst[11] * dst[16] - dst[12] * dst[17] - dst[13] * dst[18]) * dst[14];
315  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]);
316  if (dst[20] <= F(0)) return false;
317  else dst[20] = std::sqrt(F(1) / dst[20]);
318  return true;
319  }
320  };
322  template<class F, class M> struct _decomposer<F, 5, M>
323  {
325  bool operator()(F* dst, const M& src) const
326  {
327  if (src(0,0) <= F(0)) return false;
328  dst[0] = std::sqrt(F(1) / src(0,0));
329  dst[1] = src(1,0) * dst[0];
330  dst[2] = src(1,1) - dst[1] * dst[1];
331  if (dst[2] <= F(0)) return false;
332  else dst[2] = std::sqrt(F(1) / dst[2]);
333  dst[3] = src(2,0) * dst[0];
334  dst[4] = (src(2,1) - dst[1] * dst[3]) * dst[2];
335  dst[5] = src(2,2) - (dst[3] * dst[3] + dst[4] * dst[4]);
336  if (dst[5] <= F(0)) return false;
337  else dst[5] = std::sqrt(F(1) / dst[5]);
338  dst[6] = src(3,0) * dst[0];
339  dst[7] = (src(3,1) - dst[1] * dst[6]) * dst[2];
340  dst[8] = (src(3,2) - dst[3] * dst[6] - dst[4] * dst[7]) * dst[5];
341  dst[9] = src(3,3) - (dst[6] * dst[6] + dst[7] * dst[7] + dst[8] * dst[8]);
342  if (dst[9] <= F(0)) return false;
343  else dst[9] = std::sqrt(F(1) / dst[9]);
344  dst[10] = src(4,0) * dst[0];
345  dst[11] = (src(4,1) - dst[1] * dst[10]) * dst[2];
346  dst[12] = (src(4,2) - dst[3] * dst[10] - dst[4] * dst[11]) * dst[5];
347  dst[13] = (src(4,3) - dst[6] * dst[10] - dst[7] * dst[11] - dst[8] * dst[12]) * dst[9];
348  dst[14] = src(4,4) - (dst[10]*dst[10]+dst[11]*dst[11]+dst[12]*dst[12]+dst[13]*dst[13]);
349  if (dst[14] <= F(0)) return false;
350  else dst[14] = std::sqrt(F(1) / dst[14]);
351  return true;
352  }
353  };
355  template<class F, class M> struct _decomposer<F, 4, M>
356  {
358  bool operator()(F* dst, const M& src) const
359  {
360  if (src(0,0) <= F(0)) return false;
361  dst[0] = std::sqrt(F(1) / src(0,0));
362  dst[1] = src(1,0) * dst[0];
363  dst[2] = src(1,1) - dst[1] * dst[1];
364  if (dst[2] <= F(0)) return false;
365  else dst[2] = std::sqrt(F(1) / dst[2]);
366  dst[3] = src(2,0) * dst[0];
367  dst[4] = (src(2,1) - dst[1] * dst[3]) * dst[2];
368  dst[5] = src(2,2) - (dst[3] * dst[3] + dst[4] * dst[4]);
369  if (dst[5] <= F(0)) return false;
370  else dst[5] = std::sqrt(F(1) / dst[5]);
371  dst[6] = src(3,0) * dst[0];
372  dst[7] = (src(3,1) - dst[1] * dst[6]) * dst[2];
373  dst[8] = (src(3,2) - dst[3] * dst[6] - dst[4] * dst[7]) * dst[5];
374  dst[9] = src(3,3) - (dst[6] * dst[6] + dst[7] * dst[7] + dst[8] * dst[8]);
375  if (dst[9] <= F(0)) return false;
376  else dst[9] = std::sqrt(F(1) / dst[9]);
377  return true;
378  }
379  };
381  template<class F, class M> struct _decomposer<F, 3, M>
382  {
384  bool operator()(F* dst, const M& src) const
385  {
386  if (src(0,0) <= F(0)) return false;
387  dst[0] = std::sqrt(F(1) / src(0,0));
388  dst[1] = src(1,0) * dst[0];
389  dst[2] = src(1,1) - dst[1] * dst[1];
390  if (dst[2] <= F(0)) return false;
391  else dst[2] = std::sqrt(F(1) / dst[2]);
392  dst[3] = src(2,0) * dst[0];
393  dst[4] = (src(2,1) - dst[1] * dst[3]) * dst[2];
394  dst[5] = src(2,2) - (dst[3] * dst[3] + dst[4] * dst[4]);
395  if (dst[5] <= F(0)) return false;
396  else dst[5] = std::sqrt(F(1) / dst[5]);
397  return true;
398  }
399  };
401  template<class F, class M> struct _decomposer<F, 2, M>
402  {
404  bool operator()(F* dst, const M& src) const
405  {
406  if (src(0,0) <= F(0)) return false;
407  dst[0] = std::sqrt(F(1) / src(0,0));
408  dst[1] = src(1,0) * dst[0];
409  dst[2] = src(1,1) - dst[1] * dst[1];
410  if (dst[2] <= F(0)) return false;
411  else dst[2] = std::sqrt(F(1) / dst[2]);
412  return true;
413  }
414  };
416  template<class F, class M> struct _decomposer<F, 1, M>
417  {
419  bool operator()(F* dst, const M& src) const
420  {
421  if (src(0,0) <= F(0)) return false;
422  dst[0] = std::sqrt(F(1) / src(0,0));
423  return true;
424  }
425  };
427  template<class F, class M> struct _decomposer<F, 0, M>
428  {
429  private:
430  _decomposer() { };
431  bool operator()(F* dst, const M& src) const;
432  };
433 
435  template<class F, class M> struct _inverter<F,6,M>
436  {
438  inline void operator()(M& dst, const F* src) const
439  {
440  const F li21 = -src[1] * src[0] * src[2];
441  const F li32 = -src[4] * src[2] * src[5];
442  const F li31 = (src[1] * src[4] * src[2] - src[3]) * src[0] * src[5];
443  const F li43 = -src[8] * src[9] * src[5];
444  const F li42 = (src[4] * src[8] * src[5] - src[7]) * src[2] * src[9];
445  const F li41 = (-src[1] * src[4] * src[8] * src[2] * src[5] +
446  src[1] * src[7] * src[2] + src[3] * src[8] * src[5] - src[6]) * src[0] * src[9];
447  const F li54 = -src[13] * src[14] * src[9];
448  const F li53 = (src[13] * src[8] * src[9] - src[12]) * src[5] * src[14];
449  const F li52 = (-src[4] * src[8] * src[13] * src[5] * src[9] +
450  src[4] * src[12] * src[5] + src[7] * src[13] * src[9] - src[11]) * src[2] * src[14];
451  const F li51 = (src[1]*src[4]*src[8]*src[13]*src[2]*src[5]*src[9] -
452  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] +
453  src[11]*src[1]*src[2] + src[12]*src[3]*src[5] + src[13]*src[6]*src[9] -src[10]) * src[0] * src[14];
454  const F li65 = -src[19] * src[20] * src[14];
455  const F li64 = (src[19] * src[13] * src[14] - src[18]) * src[9] * src[20];
456  const F li63 = (-src[8] * src[13] * src[19] * src[9] * src[14] +
457  src[8] * src[18] * src[9] + src[12] * src[19] * src[14] - src[17]) * src[5] * src[20];
458  const F li62 = (src[4]*src[8]*src[13]*src[19]*src[5]*src[9]*src[14] -
459  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] +
460  src[17]*src[4]*src[5] + src[18]*src[7]*src[9] + src[19]*src[11]*src[14] - src[16]) * src[2] * src[20];
461  const F li61 = (-src[19]*src[13]*src[8]*src[4]*src[1]*src[2]*src[5]*src[9]*src[14] +
462  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] +
463  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] -
464  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] -
465  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] +
466  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]) *
467  src[0] * src[20];
468 
469  dst(0,0) = li61*li61 + li51*li51 + li41*li41 + li31*li31 + li21*li21 + src[0]*src[0];
470  dst(1,0) = li61*li62 + li51*li52 + li41*li42 + li31*li32 + li21*src[2];
471  dst(1,1) = li62*li62 + li52*li52 + li42*li42 + li32*li32 + src[2]*src[2];
472  dst(2,0) = li61*li63 + li51*li53 + li41*li43 + li31*src[5];
473  dst(2,1) = li62*li63 + li52*li53 + li42*li43 + li32*src[5];
474  dst(2,2) = li63*li63 + li53*li53 + li43*li43 + src[5]*src[5];
475  dst(3,0) = li61*li64 + li51*li54 + li41*src[9];
476  dst(3,1) = li62*li64 + li52*li54 + li42*src[9];
477  dst(3,2) = li63*li64 + li53*li54 + li43*src[9];
478  dst(3,3) = li64*li64 + li54*li54 + src[9]*src[9];
479  dst(4,0) = li61*li65 + li51*src[14];
480  dst(4,1) = li62*li65 + li52*src[14];
481  dst(4,2) = li63*li65 + li53*src[14];
482  dst(4,3) = li64*li65 + li54*src[14];
483  dst(4,4) = li65*li65 + src[14]*src[14];
484  dst(5,0) = li61*src[20];
485  dst(5,1) = li62*src[20];
486  dst(5,2) = li63*src[20];
487  dst(5,3) = li64*src[20];
488  dst(5,4) = li65*src[20];
489  dst(5,5) = src[20]*src[20];
490  }
491  };
493  template<class F, class M> struct _inverter<F,5,M>
494  {
496  inline void operator()(M& dst, const F* src) const
497  {
498  const F li21 = -src[1] * src[0] * src[2];
499  const F li32 = -src[4] * src[2] * src[5];
500  const F li31 = (src[1] * src[4] * src[2] - src[3]) * src[0] * src[5];
501  const F li43 = -src[8] * src[9] * src[5];
502  const F li42 = (src[4] * src[8] * src[5] - src[7]) * src[2] * src[9];
503  const F li41 = (-src[1] * src[4] * src[8] * src[2] * src[5] +
504  src[1] * src[7] * src[2] + src[3] * src[8] * src[5] - src[6]) * src[0] * src[9];
505  const F li54 = -src[13] * src[14] * src[9];
506  const F li53 = (src[13] * src[8] * src[9] - src[12]) * src[5] * src[14];
507  const F li52 = (-src[4] * src[8] * src[13] * src[5] * src[9] +
508  src[4] * src[12] * src[5] + src[7] * src[13] * src[9] - src[11]) * src[2] * src[14];
509  const F li51 = (src[1]*src[4]*src[8]*src[13]*src[2]*src[5]*src[9] -
510  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] +
511  src[11]*src[1]*src[2] + src[12]*src[3]*src[5] + src[13]*src[6]*src[9] -src[10]) * src[0] * src[14];
512 
513  dst(0,0) = li51*li51 + li41*li41 + li31*li31 + li21*li21 + src[0]*src[0];
514  dst(1,0) = li51*li52 + li41*li42 + li31*li32 + li21*src[2];
515  dst(1,1) = li52*li52 + li42*li42 + li32*li32 + src[2]*src[2];
516  dst(2,0) = li51*li53 + li41*li43 + li31*src[5];
517  dst(2,1) = li52*li53 + li42*li43 + li32*src[5];
518  dst(2,2) = li53*li53 + li43*li43 + src[5]*src[5];
519  dst(3,0) = li51*li54 + li41*src[9];
520  dst(3,1) = li52*li54 + li42*src[9];
521  dst(3,2) = li53*li54 + li43*src[9];
522  dst(3,3) = li54*li54 + src[9]*src[9];
523  dst(4,0) = li51*src[14];
524  dst(4,1) = li52*src[14];
525  dst(4,2) = li53*src[14];
526  dst(4,3) = li54*src[14];
527  dst(4,4) = src[14]*src[14];
528  }
529  };
531  template<class F, class M> struct _inverter<F,4,M>
532  {
534  inline void operator()(M& dst, const F* src) const
535  {
536  const F li21 = -src[1] * src[0] * src[2];
537  const F li32 = -src[4] * src[2] * src[5];
538  const F li31 = (src[1] * src[4] * src[2] - src[3]) * src[0] * src[5];
539  const F li43 = -src[8] * src[9] * src[5];
540  const F li42 = (src[4] * src[8] * src[5] - src[7]) * src[2] * src[9];
541  const F li41 = (-src[1] * src[4] * src[8] * src[2] * src[5] +
542  src[1] * src[7] * src[2] + src[3] * src[8] * src[5] - src[6]) * src[0] * src[9];
543 
544  dst(0,0) = li41*li41 + li31*li31 + li21*li21 + src[0]*src[0];
545  dst(1,0) = li41*li42 + li31*li32 + li21*src[2];
546  dst(1,1) = li42*li42 + li32*li32 + src[2]*src[2];
547  dst(2,0) = li41*li43 + li31*src[5];
548  dst(2,1) = li42*li43 + li32*src[5];
549  dst(2,2) = li43*li43 + src[5]*src[5];
550  dst(3,0) = li41*src[9];
551  dst(3,1) = li42*src[9];
552  dst(3,2) = li43*src[9];
553  dst(3,3) = src[9]*src[9];
554  }
555  };
557  template<class F, class M> struct _inverter<F,3,M>
558  {
560  inline void operator()(M& dst, const F* src) const
561  {
562  const F li21 = -src[1] * src[0] * src[2];
563  const F li32 = -src[4] * src[2] * src[5];
564  const F li31 = (src[1] * src[4] * src[2] - src[3]) * src[0] * src[5];
565 
566  dst(0,0) = li31*li31 + li21*li21 + src[0]*src[0];
567  dst(1,0) = li31*li32 + li21*src[2];
568  dst(1,1) = li32*li32 + src[2]*src[2];
569  dst(2,0) = li31*src[5];
570  dst(2,1) = li32*src[5];
571  dst(2,2) = src[5]*src[5];
572  }
573  };
575  template<class F, class M> struct _inverter<F,2,M>
576  {
578  inline void operator()(M& dst, const F* src) const
579  {
580  const F li21 = -src[1] * src[0] * src[2];
581 
582  dst(0,0) = li21*li21 + src[0]*src[0];
583  dst(1,0) = li21*src[2];
584  dst(1,1) = src[2]*src[2];
585  }
586  };
588  template<class F, class M> struct _inverter<F,1,M>
589  {
591  inline void operator()(M& dst, const F* src) const
592  {
593  dst(0,0) = src[0]*src[0];
594  }
595  };
597  template<class F, class M> struct _inverter<F,0,M>
598  {
599  private:
600  _inverter();
601  void operator()(M& dst, const F* src) const;
602  };
603 
605  template<class F, class V> struct _solver<F,6,V>
606  {
608  void operator()(V& rhs, const F* l) const
609  {
610  // solve Ly = rhs
611  const F y0 = rhs[0] * l[0];
612  const F y1 = (rhs[1]-l[1]*y0)*l[2];
613  const F y2 = (rhs[2]-(l[3]*y0+l[4]*y1))*l[5];
614  const F y3 = (rhs[3]-(l[6]*y0+l[7]*y1+l[8]*y2))*l[9];
615  const F y4 = (rhs[4]-(l[10]*y0+l[11]*y1+l[12]*y2+l[13]*y3))*l[14];
616  const F y5 = (rhs[5]-(l[15]*y0+l[16]*y1+l[17]*y2+l[18]*y3+l[19]*y4))*l[20];
617  // solve L^Tx = y, and put x into rhs
618  rhs[5] = y5 * l[20];
619  rhs[4] = (y4-l[19]*rhs[5])*l[14];
620  rhs[3] = (y3-(l[18]*rhs[5]+l[13]*rhs[4]))*l[9];
621  rhs[2] = (y2-(l[17]*rhs[5]+l[12]*rhs[4]+l[8]*rhs[3]))*l[5];
622  rhs[1] = (y1-(l[16]*rhs[5]+l[11]*rhs[4]+l[7]*rhs[3]+l[4]*rhs[2]))*l[2];
623  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];
624  }
625  };
627  template<class F, class V> struct _solver<F,5,V>
628  {
630  void operator()(V& rhs, const F* l) const
631  {
632  // solve Ly = rhs
633  const F y0 = rhs[0] * l[0];
634  const F y1 = (rhs[1]-l[1]*y0)*l[2];
635  const F y2 = (rhs[2]-(l[3]*y0+l[4]*y1))*l[5];
636  const F y3 = (rhs[3]-(l[6]*y0+l[7]*y1+l[8]*y2))*l[9];
637  const F y4 = (rhs[4]-(l[10]*y0+l[11]*y1+l[12]*y2+l[13]*y3))*l[14];
638  // solve L^Tx = y, and put x into rhs
639  rhs[4] = (y4)*l[14];
640  rhs[3] = (y3-(l[13]*rhs[4]))*l[9];
641  rhs[2] = (y2-(l[12]*rhs[4]+l[8]*rhs[3]))*l[5];
642  rhs[1] = (y1-(l[11]*rhs[4]+l[7]*rhs[3]+l[4]*rhs[2]))*l[2];
643  rhs[0] = (y0-(l[10]*rhs[4]+l[6]*rhs[3]+l[3]*rhs[2]+l[1]*rhs[1]))*l[0];
644  }
645  };
647  template<class F, class V> struct _solver<F,4,V>
648  {
650  void operator()(V& rhs, const F* l) const
651  {
652  // solve Ly = rhs
653  const F y0 = rhs[0] * l[0];
654  const F y1 = (rhs[1]-l[1]*y0)*l[2];
655  const F y2 = (rhs[2]-(l[3]*y0+l[4]*y1))*l[5];
656  const F y3 = (rhs[3]-(l[6]*y0+l[7]*y1+l[8]*y2))*l[9];
657  // solve L^Tx = y, and put x into rhs
658  rhs[3] = (y3)*l[9];
659  rhs[2] = (y2-(l[8]*rhs[3]))*l[5];
660  rhs[1] = (y1-(l[7]*rhs[3]+l[4]*rhs[2]))*l[2];
661  rhs[0] = (y0-(l[6]*rhs[3]+l[3]*rhs[2]+l[1]*rhs[1]))*l[0];
662  }
663  };
665  template<class F, class V> struct _solver<F,3,V>
666  {
668  void operator()(V& rhs, const F* l) const
669  {
670  // solve Ly = rhs
671  const F y0 = rhs[0] * l[0];
672  const F y1 = (rhs[1]-l[1]*y0)*l[2];
673  const F y2 = (rhs[2]-(l[3]*y0+l[4]*y1))*l[5];
674  // solve L^Tx = y, and put x into rhs
675  rhs[2] = (y2)*l[5];
676  rhs[1] = (y1-(l[4]*rhs[2]))*l[2];
677  rhs[0] = (y0-(l[3]*rhs[2]+l[1]*rhs[1]))*l[0];
678  }
679  };
681  template<class F, class V> struct _solver<F,2,V>
682  {
684  void operator()(V& rhs, const F* l) const
685  {
686  // solve Ly = rhs
687  const F y0 = rhs[0] * l[0];
688  const F y1 = (rhs[1]-l[1]*y0)*l[2];
689  // solve L^Tx = y, and put x into rhs
690  rhs[1] = (y1)*l[2];
691  rhs[0] = (y0-(l[1]*rhs[1]))*l[0];
692  }
693  };
695  template<class F, class V> struct _solver<F,1,V>
696  {
698  void operator()(V& rhs, const F* l) const
699  {
700  // solve LL^T x = rhs, put y into rhs
701  rhs[0] *= l[0] * l[0];
702  }
703  };
705  template<class F, class V> struct _solver<F,0,V>
706  {
707  private:
708  _solver();
709  void operator()(V& rhs, const F* l) const;
710  };
711 }
712 
713 
714  } // namespace Math
715 
716 } // namespace ROOT
717 
718 #endif // ROOT_Math_CHOLESKYDECOMP
719 
tuple base
Main Program
Definition: newFWLiteAna.py:92
int i
Definition: DBlmapReader.cc:9
F fL[N *(N+1)/2]
lower triangular matrix L
bool Invert(M &m) const
place the inverse into m
bool operator()(F *dst, const M &src) const
method to do the decomposition
const G operator()(unsigned i, unsigned j) const
read access to elements (make sure that j &lt;= i)
CholeskyDecomp(G *m)
perform a Cholesky decomposition
void operator()(M &dst, const F *src) const
method to do the inversion
bool fOk
flag indicating a successful decomposition
class to compute the Cholesky decomposition of a matrix
bool operator()(F *dst, const M &src) const
method to do the decomposition
G * fArr
pointer to first array element
G & operator()(unsigned i, unsigned j)
write access to elements (make sure that j &lt;= i)
void operator()(M &dst, const F *src) const
method to do the inversion
void operator()(M &dst, const F *src) const
method to do the inversion
adapter for packed arrays (to SMatrix indexing conventions)
void operator()(V &rhs, const F *l) const
method to solve the linear system
void operator()(M &dst, const F *src) const
method to do the inversion
T sqrt(T t)
Definition: SSEVec.h:48
bool operator()(F *dst, const M &src) const
method to do the decomposition
struct to obtain the inverse from a Cholesky decomposition
int j
Definition: DBlmapReader.cc:9
struct to do a Cholesky decomposition
bool operator()(F *dst, const M &src) const
method to do the decomposition
void operator()(V &rhs, const F *l) const
method to solve the linear system
bool Solve(V &rhs) const
solves a linear system for the given right hand side
bool Invert(G *m) const
place the inverse into m
void operator()(M &dst, const F *src) const
method to do the inversion
int k[5][pyjets_maxn]
bool operator()(F *dst, const M &src) const
method to do the decomposition
#define N
Definition: blowfish.cc:9
void operator()(V &rhs, const F *l) const
method to solve the linear system
CholeskyDecomp(const M &m)
perform a Cholesky decomposition
bool operator()(F *dst, const M &src) const
method to do the decomposition
void operator()(V &rhs, const F *l) const
method to solve the linear system
void operator()(V &rhs, const F *l) const
method to solve the linear system
std::vector< std::vector< double > > tmp
Definition: MVATrainer.cc:100
void operator()(V &rhs, const F *l) const
method to solve the linear system
void operator()(V &rhs, const F *l) const
method to solve the linear system
void operator()(M &dst, const F *src) const
method to do the inversion
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
Definition: blowfish.cc:281
bool operator()(F *dst, const M &src) const
method to do the decomposition
bool ok() const
returns true if decomposition was successful
void operator()(M &dst, const F *src) const
method to do the inversion
struct to solve a linear system using its Cholesky decomposition